Index: /applications/editors/josm/plugins/opendata/.classpath
===================================================================
--- /applications/editors/josm/plugins/opendata/.classpath	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/.classpath	(revision 28000)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry excluding="org/odftoolkit/odfdom/JarManifest.java|org/odftoolkit/simple/JarManifest.java|org/odftoolkit/simple/|org/jopendocument/dom/spreadsheet/SheetTest.java|org/jopendocument/dom/ChildCreatorTest.java|org/jopendocument/dom/ODSingleXMLDocumentTest.java|org/jopendocument/dom/OOXMLTest.java|org/jopendocument/dom/template/|org/jopendocument/sample/|org/jopendocument/util/cache/ICacheTest.java|org/jopendocument/panel/|org/jopendocument/tools/|org/jopendocument/print/|org/jopendocument/renderer/|org/jopendocument/util/BenchmarkUtilities.java|org/jopendocument/util/ImageUtilities.java|org/jopendocument/util/PrintUtilities.java|org/odftoolkit/odfdom/|org/jopendocument/util/CompareUtils.java|org/jopendocument/util/DummyGraphics2D.java|org/jopendocument/util/DummyFontMetrics.java|org/jopendocument/dom/spreadsheet/CalcNode.java|org/jopendocument/io/StyleTableProperties.java|org/jopendocument/util/ReflectUtils.java|org/jopendocument/util/cache/CacheWatcher.java|org/jopendocument/util/cache/CacheWatcherFactory.java|org/jopendocument/util/cache/ICache.java|org/jopendocument/util/cache/|org/jopendocument/util/cc/ExnTransformer.java|org/jopendocument/model/chart/ChartChart.java|org/jopendocument/model/ConfigConfigItem.java|org/jopendocument/dom/text/Heading.java|org/odftoolkit/" kind="src" path="includes"/>
+	<classpathentry kind="src" path="resources"/>
+	<classpathentry kind="src" path="modules/be.bruxelles/src"/>
+	<classpathentry kind="src" path="modules/be.datagovbe/src"/>
+	<classpathentry kind="src" path="modules/fr.cg41/src"/>
+	<classpathentry kind="src" path="modules/fr.datagouvfr/src"/>
+	<classpathentry kind="src" path="modules/fr.datagouvfr/resources"/>
+	<classpathentry kind="src" path="modules/fr.paris/src"/>
+	<classpathentry kind="src" path="modules/fr.sncf/src"/>
+	<classpathentry kind="src" path="modules/fr.toulouse/src"/>
+	<classpathentry kind="src" path="util"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/JOSM"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
Index: /applications/editors/josm/plugins/opendata/.project
===================================================================
--- /applications/editors/josm/plugins/opendata/.project	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/.project	(revision 28000)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>JOSM-OpenData</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: /applications/editors/josm/plugins/opendata/.settings/org.eclipse.core.resources.prefs
===================================================================
--- /applications/editors/josm/plugins/opendata/.settings/org.eclipse.core.resources.prefs	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/.settings/org.eclipse.core.resources.prefs	(revision 28000)
@@ -0,0 +1,3 @@
+#Tue Jan 10 13:17:16 CET 2012
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
Index: /applications/editors/josm/plugins/opendata/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- /applications/editors/josm/plugins/opendata/.settings/org.eclipse.jdt.core.prefs	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/.settings/org.eclipse.jdt.core.prefs	(revision 28000)
@@ -0,0 +1,82 @@
+#Mon Feb 06 20:04:14 CET 2012
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=ignore
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.6
Index: /applications/editors/josm/plugins/opendata/README
===================================================================
--- /applications/editors/josm/plugins/opendata/README	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/README	(revision 28000)
@@ -0,0 +1,30 @@
+README 
+======
+
+Readme for JOSM Open Data plugin
+
+    * Author: Don-vip
+    * License: GPL v3 (see gpl-3.0.txt) and others (see below for details)
+
+-------------------------------- DOCUMENTATION --------------------------------
+
+See http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData
+
+----------------------------------- LICENSE -----------------------------------
+
+The source code of this plugin is composed of the following folders, with distinct licenses:
+
+- src: main source code (GPL v3)
+
+- includes: several COTS, heavily truncated to fit only the plugin needs and reduce the JAR size:
+    - org/apache: three Apache COTS (Apache License 2.0, see LICENSE-2.0.txt)
+        - commons/collections: Apache Commons Collections 3.2.1 (used by jOpenDocument)
+        - commons/lang3: Apache Commons Lang 3.1 (stuff related to WordUtils, used by the plugin itself)
+        - poi: Apache POI 3.7 (Excel format support without styles, formulas and writing capabilities, used by the plugin itself)
+    - org/jopendocument: jOpenDocument 1.2 (ODS support without styles and writing capabilities, used by the plugin itself) (GPL v3, see gpl-3.0.txt)
+    - org/jdom: JDOM 1.1.2-hotfix1 (used by jOpenDocument & GeoTools) (custom license, see JDOM_LICENSE.txt)
+    - org/geotools, org/opengis: GeoTools 2.7.4 (ESRI Shapefile support, used by the plugin itself) (LGPL v2.1, see lgpl-2.1.txt)
+    - com/vividsolutions/jts: JTS 1.12 (used by GeoTools, http://sourceforge.net/projects/jts-topo-suite/) (LGPL v2.1, see lgpl-2.1.txt)
+    - javax/measure: JSR-275 1.0-beta2 (used by GeoTools)
+    - javax/vecmath: Vecmath 1.5.2 (used by GeoTools, http://java.net/projects/vecmath) (GPL v2, see gpl-2.0.txt)
+    
Index: /applications/editors/josm/plugins/opendata/build.xml
===================================================================
--- /applications/editors/josm/plugins/opendata/build.xml	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/build.xml	(revision 28000)
@@ -0,0 +1,297 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!--
+** This is the build file for the opendata plugin.
+**
+** Usage
+** =====
+** To build it run
+**
+**    > ant  dist
+**
+** To install the generated plugin locally (in you default plugin directory) run
+**
+**    > ant  install
+**
+** The generated plugin jar is not automatically available in JOSMs plugin configuration
+** dialog. You have to check it in first.
+**
+** Use the ant target 'publish' to check in the plugin and make it available to other
+** JOSM users:
+**    set the properties commit.message and plugin.main.version
+** and run
+**    > ant  publish
+**
+**
+-->
+<project name="opendata" default="dist" basedir=".">
+    <!-- enter the SVN commit message -->
+    <property name="commit.message" value="Commit message"/>
+    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
+    <property name="plugin.main.version" value="5040"/>
+    <!-- should not be necessary to change the following properties -->
+    <property name="josm" location="../../core/dist/josm-custom.jar"/>
+    <property name="plugin.build.dir" value="build"/>
+    <property name="plugin.src.dir" value="src"/>
+    <!-- this is the directory where the plugin jar is copied to -->
+    <property name="plugin.dist.dir" value="../../dist"/>
+    <property name="ant.build.javac.source" value="1.6"/>
+    <property name="ant.build.javac.target" value="1.6"/>
+    <property name="plugin.dist.dir" value="../../dist"/>
+    <property name="plugin.jar" value="${plugin.dist.dir}/${ant.project.name}.jar"/>
+    <!--<property name="xerces" location="lib/xerces-2_11_0"/>-->
+    <!--
+    **********************************************************
+    ** init - initializes the build
+    **********************************************************
+    -->
+    <target name="init">
+        <mkdir dir="${plugin.build.dir}"/>
+        <mkdir dir="${plugin.build.dir}/META-INF"/>
+    </target>
+    <!--
+    **********************************************************
+    ** compile_lang3 - compiles Apache Commons Lang 3 needed classes
+    **********************************************************
+    -->
+    <target name="compile_lang3" depends="init">
+        <echo message="compiling Apache Commons Lang 3 ... "/>
+        <javac srcdir="includes/org/apache/commons/lang3" debug="false" destdir="${plugin.build.dir}" includeAntRuntime="false" encoding="ISO-8859-1" />
+    </target>
+    <!--
+    **********************************************************
+    ** compile_poi - compiles Apache POI needed classes
+    **********************************************************
+    -->
+    <target name="compile_poi" depends="init">
+        <echo message="compiling Apache POI ... "/>
+        <javac srcdir="includes/org/apache/poi" debug="false" destdir="${plugin.build.dir}" includeAntRuntime="false" encoding="ISO-8859-1" />
+    </target>
+    <!--
+    **********************************************************
+    ** compile_collections - compiles Apache Collections needed classes
+    **********************************************************
+    -->
+    <target name="compile_collections" depends="init">
+        <echo message="compiling Apache Collections ... "/>
+        <javac srcdir="includes/org/apache/commons/collections" debug="false" destdir="${plugin.build.dir}" includeAntRuntime="false" encoding="ISO-8859-1" />
+    </target>
+    <!--
+    **********************************************************
+    ** compile_jopendoc - compiles JOpenDocument needed classes
+    **********************************************************
+    -->
+    <target name="compile_jopendoc" depends="init, compile_collections">
+        <echo message="compiling JDOM ... "/>
+        <javac srcdir="includes/org/jdom" debug="false" destdir="${plugin.build.dir}" includeAntRuntime="false" encoding="ISO-8859-1" />
+        <echo message="compiling JOpenDocument ... "/>
+        <javac srcdir="includes/org/jopendocument" debug="false" destdir="${plugin.build.dir}" includeAntRuntime="false" encoding="ISO-8859-1" />
+    </target>
+    <!--
+    **********************************************************
+    ** compile_geotools - compiles GeoTools needed classes
+    **********************************************************
+    -->
+    <target name="compile_geotools" depends="init">
+        <echo message="compiling JTS ... "/>
+        <javac srcdir="includes/com/vividsolutions/jts" debug="false" destdir="${plugin.build.dir}" includeAntRuntime="false" encoding="ISO-8859-1" />
+        <echo message="compiling JSR-275 ... "/>
+        <javac srcdir="includes/javax/measure" debug="false" destdir="${plugin.build.dir}" includeAntRuntime="false" encoding="UTF-8" />
+        <echo message="compiling Vecmath ... "/>
+        <javac srcdir="includes/javax/vecmath" debug="false" destdir="${plugin.build.dir}" includeAntRuntime="false" encoding="ISO-8859-1" />
+        <echo message="compiling GeoTools ... "/>
+        <javac debug="true" sourcepath="" srcdir="includes" destdir="${plugin.build.dir}" includeAntRuntime="false" encoding="ISO-8859-1">
+            <include name="org/geotools/**/*.java"/>
+        	<include name="org/opengis/**/*.java"/>
+        </javac>
+    </target>
+    <!--
+    **********************************************************
+    ** compile - compiles the source tree
+    **********************************************************
+    -->
+    <target name="compile" depends="init, compile_lang3, compile_poi, compile_jopendoc, compile_geotools">
+        <echo message="compiling sources for  ${plugin.jar} ... "/>
+        <javac srcdir="src/org/openstreetmap" debug="true" destdir="${plugin.build.dir}" includeAntRuntime="false">
+            <classpath>
+        	    <pathelement path="${plugin.build.dir}"/>
+                <pathelement location="${josm}"/>
+            </classpath>
+            <compilerarg value="-Xlint:deprecation"/>
+            <compilerarg value="-Xlint:unchecked"/>
+        </javac>
+    </target>
+    <!--
+    **********************************************************
+    ** dist - creates the plugin jar
+    **********************************************************
+    -->
+    <target name="dist" depends="compile,revision">
+        <echo message="creating ${ant.project.name}.jar ... "/>
+        <copy todir="${plugin.build.dir}">
+            <fileset dir="resources">
+                <exclude name="org/geotools/referencing/**/*_original.properties"/>
+            	<exclude name="org/geotools/referencing/factory/epsg/*.sql"/>
+            	<exclude name="org/geotools/referencing/factory/epsg/PrepareForHSQL.xml"/>
+            	<exclude name="org/geotools/referencing/factory/epsg/UpdateEPSGDatabase.txt"/>
+            </fileset>
+        </copy>
+        <copy todir="${plugin.build.dir}/images">
+            <fileset dir="images"/>
+        </copy>
+        <copy todir="${plugin.build.dir}">
+            <fileset dir=".">
+                <include name="README"/>
+            </fileset>
+            <fileset dir="licenses">
+                <include name="*.txt"/>
+            </fileset>
+        </copy>
+        <jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
+            <!--
+            ************************************************
+            ** configure these properties. Most of them will be copied to the plugins
+            ** manifest file. Property values will also show up in the list available
+            ** plugins: http://josm.openstreetmap.de/wiki/Plugins.
+            **
+            ************************************************
+            -->
+            <manifest>
+                <attribute name="Author" value="Don-vip"/>
+                <attribute name="Plugin-Class" value="org.openstreetmap.josm.plugins.opendata.OdPlugin"/>
+                <attribute name="Plugin-Date" value="${version.entry.commit.date}"/>
+                <attribute name="Plugin-Description" value="Convert data from Open Data portals to OSM layer"/>
+                <attribute name="Plugin-Early" value="false"/>
+                <attribute name="Plugin-Icon" value="images/dialogs/o24.png"/>
+                <attribute name="Plugin-Link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData"/>
+                <attribute name="Plugin-Mainversion" value="${plugin.main.version}"/>
+                <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
+            </manifest>
+        </jar>
+    </target>
+    <!--
+    **********************************************************
+    ** revision - extracts the current revision number for the
+    **    file build.number and stores it in the XML property
+    **    version.*
+    **********************************************************
+    -->
+    <target name="revision">
+        <exec append="false" output="REVISION" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="info"/>
+            <arg value="--xml"/>
+            <arg value="."/>
+        </exec>
+        <xmlproperty file="REVISION" prefix="version" keepRoot="false" collapseAttributes="true"/>
+        <delete file="REVISION"/>
+    </target>
+    <!--
+    **********************************************************
+    ** clean - clean up the build environment
+    **********************************************************
+    -->
+    <target name="clean">
+        <delete dir="${plugin.build.dir}"/>
+        <delete file="${plugin.jar}"/>
+    </target>
+    <!--
+    **********************************************************
+    ** install - install the plugin in your local JOSM installation
+    **********************************************************
+    -->
+    <target name="install" depends="dist">
+        <property environment="env"/>
+        <condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins">
+            <and>
+                <os family="windows"/>
+            </and>
+        </condition>
+        <copy file="${plugin.jar}" todir="${josm.plugins.dir}"/>
+    </target>
+    <!--
+    ************************** Publishing the plugin *********************************** 
+    -->
+    <!--
+    ** extracts the JOSM release for the JOSM version in ../core and saves it in the 
+    ** property ${coreversion.info.entry.revision}
+    -->
+    <target name="core-info">
+        <exec append="false" output="core.info.xml" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="info"/>
+            <arg value="--xml"/>
+            <arg value="../../core"/>
+        </exec>
+        <xmlproperty file="core.info.xml" prefix="coreversion" keepRoot="true" collapseAttributes="true"/>
+        <echo>Building against core revision ${coreversion.info.entry.revision}.</echo>
+        <echo>Plugin-Mainversion is set to ${plugin.main.version}.</echo>
+        <delete file="core.info.xml"/>
+    </target>
+    <!-- commits the source tree for this plugin -->
+    <target name="commit-current">
+        <echo>Commiting the plugin source with message '${commit.message}' ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="commit"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="."/>
+        </exec>
+    </target>
+    <!-- updates (svn up) the source tree for this plugin -->
+    <target name="update-current">
+        <echo>Updating plugin source ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="."/>
+        </exec>
+        <echo>Updating ${plugin.jar} ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="../dist/${plugin.jar}"/>
+        </exec>
+    </target>
+    <!-- commits the plugin.jar -->
+    <target name="commit-dist">
+        <echo>
+    ***** Properties of published ${plugin.jar} *****
+    Commit message    : '${commit.message}'                    
+    Plugin-Mainversion: ${plugin.main.version}
+    JOSM build version: ${coreversion.info.entry.revision}
+    Plugin-Version    : ${version.entry.commit.revision}
+    ***** / Properties of published ${plugin.jar} *****                    
+                        
+    Now commiting ${plugin.jar} ...
+    </echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="commit"/>
+            <arg value="${plugin.jar}"/>
+        </exec>
+    </target>
+    <!-- make sure svn is present as a command line tool -->
+    <target name="ensure-svn-present">
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false" failonerror="false" resultproperty="svn.exit.code">
+            <env key="LANG" value="C"/>
+            <arg value="--version"/>
+        </exec>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure svn is installed on your system.">
+            <!-- return code not set at all? Most likely svn isn't installed -->
+            <condition>
+                <not>
+                    <isset property="svn.exit.code"/>
+                </not>
+            </condition>
+        </fail>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure a working copy of svn is installed on your system.">
+            <!-- error code from SVN? Most likely svn is not what we are looking on this system -->
+            <condition>
+                <isfailure code="${svn.exit.code}"/>
+            </condition>
+        </fail>
+    </target>
+    <target name="publish" depends="ensure-svn-present,core-info,commit-current,update-current,clean,dist,commit-dist">
+    </target>
+</project>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/BoundaryNodeRule.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/BoundaryNodeRule.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/BoundaryNodeRule.java	(revision 28000)
@@ -0,0 +1,109 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.Lineal;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.operation.IsSimpleOp;
+import com.vividsolutions.jts.operation.relate.RelateOp;
+
+/**
+ * An interface for rules which determine whether node points
+ * which are in boundaries of {@link Lineal} geometry components
+ * are in the boundary of the parent geometry collection.
+ * The SFS specifies a single kind of boundary node rule,
+ * the {@link Mod2BoundaryNodeRule} rule.
+ * However, other kinds of Boundary Node Rules are appropriate
+ * in specific situations (for instance, linear network topology
+ * usually follows the {@link EndPointBoundaryNodeRule}.)
+ * Some JTS operations allow the BoundaryNodeRule to be specified,
+ * and respect this rule when computing the results of the operation.
+ *
+ * @author Martin Davis
+ * @version 1.7
+ *
+ * @see RelateOp
+ * @see IsSimpleOp
+ * @see PointLocator
+ */
+public interface BoundaryNodeRule
+{
+
+	/**
+	 * Tests whether a point that lies in <tt>boundaryCount</tt>
+	 * geometry component boundaries is considered to form part of the boundary
+	 * of the parent geometry.
+	 * 
+	 * @param boundaryCount the number of component boundaries that this point occurs in
+	 * @return true if points in this number of boundaries lie in the parent boundary
+	 */
+  boolean isInBoundary(int boundaryCount);
+
+  /**
+   * The Mod-2 Boundary Node Rule (which is the rule specified in the OGC SFS).
+   * @see Mod2BoundaryNodeRule
+   */
+  public static final BoundaryNodeRule MOD2_BOUNDARY_RULE = new Mod2BoundaryNodeRule();
+
+  /**
+   * The Boundary Node Rule specified by the OGC Simple Features Specification,
+   * which is the same as the Mod-2 rule.
+   * @see Mod2BoundaryNodeRule
+   */
+  public static final BoundaryNodeRule OGC_SFS_BOUNDARY_RULE = MOD2_BOUNDARY_RULE;
+
+  /**
+   * A {@link BoundaryNodeRule} specifies that points are in the
+   * boundary of a lineal geometry iff
+   * the point lies on the boundary of an odd number
+   * of components.
+   * Under this rule {@link LinearRing}s and closed
+   * {@link LineString}s have an empty boundary.
+   * <p>
+   * This is the rule specified by the <i>OGC SFS</i>,
+   * and is the default rule used in JTS.
+   *
+   * @author Martin Davis
+   * @version 1.7
+   */
+  public static class Mod2BoundaryNodeRule
+      implements BoundaryNodeRule
+  {
+    public boolean isInBoundary(int boundaryCount)
+    {
+      // the "Mod-2 Rule"
+      return boundaryCount % 2 == 1;
+    }
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/CGAlgorithms.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/CGAlgorithms.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/CGAlgorithms.java	(revision 28000)
@@ -0,0 +1,452 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.Location;
+
+/**
+ * Specifies and implements various fundamental Computational Geometric algorithms.
+ * The algorithms supplied in this class are robust for double-precision floating point.
+ *
+ * @version 1.7
+ */
+public class CGAlgorithms
+{
+
+  /**
+   * A value that indicates an orientation of clockwise, or a right turn.
+   */
+  public static final int CLOCKWISE     = -1;
+  /**
+   * A value that indicates an orientation of counterclockwise, or a left turn.
+   */
+  public static final int COUNTERCLOCKWISE  = 1;
+  /**
+   * A value that indicates an orientation of collinear, or no turn (straight).
+   */
+  public static final int COLLINEAR         = 0;
+
+  /**
+   * Returns the index of the direction of the point <code>q</code>
+   * relative to a
+   * vector specified by <code>p1-p2</code>.
+   *
+   * @param p1 the origin point of the vector
+   * @param p2 the final point of the vector
+   * @param q the point to compute the direction to
+   *
+   * @return 1 if q is counter-clockwise (left) from p1-p2
+   * @return -1 if q is clockwise (right) from p1-p2
+   * @return 0 if q is collinear with p1-p2
+   */
+  public static int orientationIndex(Coordinate p1, Coordinate p2, Coordinate q) 
+  {
+  	/**
+  	 * MD - 9 Aug 2010
+  	 * It seems that the basic algorithm is slightly orientation dependent,
+  	 * when computing the orientation of a point very close to a line.
+  	 * This is possibly due to the arithmetic in the translation to the origin.
+  	 * 
+  	 * For instance, the following situation produces identical results 
+  	 * in spite of the inverse orientation of the line segment:
+  	 * 
+  	 * Coordinate p0 = new Coordinate(219.3649559090992, 140.84159161824724);
+  	 * Coordinate p1 = new Coordinate(168.9018919682399, -5.713787599646864);
+  	 * 
+  	 * Coordinate p = new Coordinate(186.80814046338352, 46.28973405831556);
+  	 * int orient = orientationIndex(p0, p1, p);
+  	 * int orientInv = orientationIndex(p1, p0, p);
+
+  	 * A way to force consistent results is to normalize the orientation of the vector
+  	 * using the following code.
+  	 * However, this may make the results of orientationIndex inconsistent
+  	 * through the triangle of points, so it's not clear this is 
+  	 * an appropriate patch.
+  	 * 
+  	 */
+  	/*
+  	 // Normalize orientation of vector to provide consistent results
+    // This produces repeatable results for single cases, but does not fully solve robustness issues
+ 	   if (p2.x < p1.x || (p2.x == p1.x && p2.y < p1.y))
+			return -orientationIndex(p2, p1, q);
+	  //*/
+    double dx1 = p2.x - p1.x;
+    double dy1 = p2.y - p1.y;
+    double dx2 = q.x - p2.x;
+    double dy2 = q.y - p2.y;
+    return RobustDeterminant.signOfDet2x2(dx1, dy1, dx2, dy2);
+  }
+
+  public CGAlgorithms() {
+  }
+
+  /**
+   * Tests whether a point lies inside or on a ring.
+   * The ring may be oriented in either direction.
+   * A point lying exactly on the ring boundary is considered to be inside the ring.
+   * <p>
+   * This method does <i>not</i> first check the point against the envelope
+   * of the ring.
+   *
+   * @param p point to check for ring inclusion
+   * @param ring an array of coordinates representing the ring (which must have first point identical to last point)
+   * @return true if p is inside ring
+   * 
+   * @see locatePointInRing
+   */
+  public static boolean isPointInRing(Coordinate p, Coordinate[] ring) {
+  	return locatePointInRing(p, ring) != Location.EXTERIOR;
+  }
+  
+
+  /**
+   * Determines whether a point lies in the interior, on the boundary, or in the exterior
+   * of a ring.
+   * The ring may be oriented in either direction.
+   * <p>
+   * This method does <i>not</i> first check the point against the envelope
+   * of the ring.
+   *
+   * @param p point to check for ring inclusion
+   * @param ring an array of coordinates representing the ring (which must have first point identical to last point)
+   * @return the {@link Location} of p relative to the ring
+   */
+  public static int locatePointInRing(Coordinate p, Coordinate[] ring) 
+  {
+    return RayCrossingCounter.locatePointInRing(p, ring);
+  }
+  
+  /**
+   * Tests whether a point lies on the line segments defined by a
+   * list of coordinates.
+   *
+   * @return true if the point is a vertex of the line 
+   * or lies in the interior of a line segment in the linestring
+   */
+  public static boolean isOnLine(Coordinate p, Coordinate[] pt) {
+    LineIntersector lineIntersector = new RobustLineIntersector();
+    for (int i = 1; i < pt.length; i++) {
+      Coordinate p0 = pt[i - 1];
+      Coordinate p1 = pt[i];
+      lineIntersector.computeIntersection(p, p0, p1);
+      if (lineIntersector.hasIntersection()) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Computes whether a ring defined by an array of {@link Coordinate}s is
+   * oriented counter-clockwise.
+   * <ul>
+   * <li>The list of points is assumed to have the first and last points equal.
+   * <li>This will handle coordinate lists which contain repeated points.
+   * </ul>
+   * This algorithm is <b>only</b> guaranteed to work with valid rings.
+   * If the ring is invalid (e.g. self-crosses or touches),
+   * the computed result may not be correct.
+   *
+   * @param ring an array of Coordinates forming a ring
+   * @return true if the ring is oriented counter-clockwise.
+   * @throws IllegalArgumentException if there are too few points to determine orientation (< 3)
+   */
+  public static boolean isCCW(Coordinate[] ring) {
+    // # of points without closing endpoint
+    int nPts = ring.length - 1;
+    // sanity check
+    if (nPts < 3)
+    	throw new IllegalArgumentException("Ring has fewer than 3 points, so orientation cannot be determined");
+    
+    // find highest point
+    Coordinate hiPt = ring[0];
+    int hiIndex = 0;
+    for (int i = 1; i <= nPts; i++) {
+      Coordinate p = ring[i];
+      if (p.y > hiPt.y) {
+        hiPt = p;
+        hiIndex = i;
+      }
+    }
+
+    // find distinct point before highest point
+    int iPrev = hiIndex;
+    do {
+      iPrev = iPrev - 1;
+      if (iPrev < 0) iPrev = nPts;
+    } while (ring[iPrev].equals2D(hiPt) && iPrev != hiIndex);
+
+    // find distinct point after highest point
+    int iNext = hiIndex;
+    do {
+      iNext = (iNext + 1) % nPts;
+    } while (ring[iNext].equals2D(hiPt) && iNext != hiIndex);
+
+    Coordinate prev = ring[iPrev];
+    Coordinate next = ring[iNext];
+
+    /**
+     * This check catches cases where the ring contains an A-B-A configuration of points.
+     * This can happen if the ring does not contain 3 distinct points
+     * (including the case where the input array has fewer than 4 elements),
+     * or it contains coincident line segments.
+     */
+    if (prev.equals2D(hiPt) || next.equals2D(hiPt) || prev.equals2D(next))
+      return false;
+
+    int disc = computeOrientation(prev, hiPt, next);
+
+    /**
+     *  If disc is exactly 0, lines are collinear.  There are two possible cases:
+     *  (1) the lines lie along the x axis in opposite directions
+     *  (2) the lines lie on top of one another
+     *
+     *  (1) is handled by checking if next is left of prev ==> CCW
+     *  (2) will never happen if the ring is valid, so don't check for it
+     *  (Might want to assert this)
+     */
+    boolean isCCW = false;
+    if (disc == 0) {
+      // poly is CCW if prev x is right of next x
+      isCCW = (prev.x > next.x);
+    }
+    else {
+      // if area is positive, points are ordered CCW
+      isCCW = (disc > 0);
+    }
+    return isCCW;
+  }
+
+  /**
+   * Computes the orientation of a point q to the directed line segment p1-p2.
+   * The orientation of a point relative to a directed line segment indicates
+   * which way you turn to get to q after travelling from p1 to p2.
+   *
+   * @return 1 if q is counter-clockwise from p1-p2
+   * @return -1 if q is clockwise from p1-p2
+   * @return 0 if q is collinear with p1-p2
+   */
+  public static int computeOrientation(Coordinate p1, Coordinate p2, Coordinate q) {
+    return orientationIndex(p1, p2, q);
+  }
+
+
+  /**
+   * Computes the distance from a point p to a line segment AB
+   *
+   * Note: NON-ROBUST!
+   *
+   * @param p the point to compute the distance for
+   * @param A one point of the line
+   * @param B another point of the line (must be different to A)
+   * @return the distance from p to line segment AB
+   */
+  public static double distancePointLine(Coordinate p, Coordinate A, Coordinate B)
+  {
+    // if start = end, then just compute distance to one of the endpoints
+    if (  A.x == B.x && A.y == B.y ) return p.distance(A);
+
+    // otherwise use comp.graphics.algorithms Frequently Asked Questions method
+    /*(1)     	      AC dot AB
+                   r = ---------
+                         ||AB||^2
+		r has the following meaning:
+		r=0 P = A
+		r=1 P = B
+		r<0 P is on the backward extension of AB
+		r>1 P is on the forward extension of AB
+		0<r<1 P is interior to AB
+	*/
+
+    double r = ( (p.x - A.x) * (B.x - A.x) + (p.y - A.y) * (B.y - A.y) )
+              /
+            ( (B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y) );
+
+    if (r <= 0.0) return p.distance(A);
+    if (r >= 1.0) return p.distance(B);
+
+
+    /*(2)
+		     (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
+		s = -----------------------------
+		             	L^2
+
+		Then the distance from C to P = |s|*L.
+	*/
+
+    double s = ((A.y - p.y) *(B.x - A.x) - (A.x - p.x)*(B.y - A.y) )
+              /
+            ((B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y) );
+
+    return
+      Math.abs(s) *
+      Math.sqrt(((B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y)));
+  }
+  
+	
+  /**
+   * Computes the distance from a line segment AB to a line segment CD
+   *
+   * Note: NON-ROBUST!
+   *
+   * @param A a point of one line
+   * @param B the second point of  (must be different to A)
+   * @param C one point of the line
+   * @param D another point of the line (must be different to A)
+   */
+  public static double distanceLineLine(Coordinate A, Coordinate B, Coordinate C, Coordinate D)
+  {
+    // check for zero-length segments
+    if (  A.equals(B) )	return distancePointLine(A,C,D);
+    if (  C.equals(D) )	return distancePointLine(D,A,B);
+
+    // AB and CD are line segments
+    /* from comp.graphics.algo
+
+	Solving the above for r and s yields
+				(Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
+	           r = ----------------------------- (eqn 1)
+				(Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
+
+		 	(Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
+		s = ----------------------------- (eqn 2)
+			(Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
+	Let P be the position vector of the intersection point, then
+		P=A+r(B-A) or
+		Px=Ax+r(Bx-Ax)
+		Py=Ay+r(By-Ay)
+	By examining the values of r & s, you can also determine some other
+limiting conditions:
+		If 0<=r<=1 & 0<=s<=1, intersection exists
+		r<0 or r>1 or s<0 or s>1 line segments do not intersect
+		If the denominator in eqn 1 is zero, AB & CD are parallel
+		If the numerator in eqn 1 is also zero, AB & CD are collinear.
+
+	*/
+    double r_top = (A.y-C.y)*(D.x-C.x) - (A.x-C.x)*(D.y-C.y) ;
+    double r_bot = (B.x-A.x)*(D.y-C.y) - (B.y-A.y)*(D.x-C.x) ;
+
+    double s_top = (A.y-C.y)*(B.x-A.x) - (A.x-C.x)*(B.y-A.y);
+    double s_bot = (B.x-A.x)*(D.y-C.y) - (B.y-A.y)*(D.x-C.x);
+
+    if  ( (r_bot==0) || (s_bot == 0) ) {
+      return
+        Math.min(distancePointLine(A,C,D),
+	  Math.min(distancePointLine(B,C,D),
+	    Math.min(distancePointLine(C,A,B),
+	      distancePointLine(D,A,B)    ) ) );
+
+    }
+    double s = s_top/s_bot;
+    double r=  r_top/r_bot;
+
+    if ((r < 0) || ( r > 1) || (s < 0) || (s > 1) )	{
+      //no intersection
+      return
+        Math.min(distancePointLine(A,C,D),
+	  Math.min(distancePointLine(B,C,D),
+	    Math.min(distancePointLine(C,A,B),
+	      distancePointLine(D,A,B)    ) ) );
+    }
+    return 0.0; //intersection exists
+  }
+
+  /**
+   * Computes the signed area for a ring.      
+   * The signed area is:
+   * <ul>
+   * <li>positive if the ring is oriented CW
+   * <li>negative if the ring is oriented CCW
+   * <li>zero if the ring is degenerate or flat
+   * </ul> 
+   * 
+   * @param ring the coordinates forming the ring
+   * @return the signed area of the ring
+   */
+  public static double signedArea(CoordinateSequence ring)
+  {
+    int n = ring.size();
+    if (n < 3) return 0.0;
+    double sum = 0.0;
+    Coordinate p = new Coordinate();
+    ring.getCoordinate(0, p);
+    double bx = p.x;
+    double by = p.y;
+    for (int i = 1; i < n; i++) {
+      ring.getCoordinate(i, p);
+      double cx = p.x;
+      double cy = p.y;
+      sum += (bx + cx) * (cy - by);
+      bx = cx;
+      by = cy;
+    }
+    return -sum  / 2.0;
+  } 
+  
+  /**
+   * Computes the length of a linestring specified by a sequence of points.
+   *
+   * @param pts the points specifying the linestring
+   * @return the length of the linestring
+   */
+  public static double length(CoordinateSequence pts) 
+  {
+    // optimized for processing CoordinateSequences
+    int n = pts.size();
+    if (n <= 1) return 0.0;
+    
+    double len = 0.0;
+    
+    Coordinate p = new Coordinate();
+    pts.getCoordinate(0, p);
+    double x0 = p.x;
+    double y0 = p.y;
+    
+    for (int i = 1; i < n; i++) {
+      pts.getCoordinate(i, p);
+      double x1 = p.x;
+      double y1 = p.y;
+      double dx = x1 - x0;
+      double dy = y1 - y0;
+
+      len += Math.sqrt(dx * dx + dy * dy);
+      
+      x0 = x1;
+      y0 = y1;
+    }
+    return len;
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/CentralEndpointIntersector.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/CentralEndpointIntersector.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/CentralEndpointIntersector.java	(revision 28000)
@@ -0,0 +1,125 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+import com.vividsolutions.jts.geom.Coordinate;
+
+
+/**
+ * Computes an approximate intersection of two line segments
+ * by taking the most central of the endpoints of the segments.
+ * This is effective in cases where the segments are nearly parallel
+ * and should intersect at an endpoint.
+ * It is also a reasonable strategy for cases where the 
+ * endpoint of one segment lies on or almost on the interior of another one.
+ * Taking the most central endpoint ensures that the computed intersection
+ * point lies in the envelope of the segments.
+ * Also, by always returning one of the input points, this should result 
+ * in reducing segment fragmentation.
+ * Intended to be used as a last resort for 
+ * computing ill-conditioned intersection situations which 
+ * cause other methods to fail.
+ *
+ * @author Martin Davis
+ * @version 1.8
+ */
+public class CentralEndpointIntersector 
+{
+	public static Coordinate getIntersection(Coordinate p00, Coordinate p01,
+			Coordinate p10, Coordinate p11)
+	{
+		CentralEndpointIntersector intor = new CentralEndpointIntersector(p00, p01, p10, p11);
+		return intor.getIntersection();
+	}
+	
+	private Coordinate[] pts;
+	private Coordinate intPt = null;
+
+	public CentralEndpointIntersector(Coordinate p00, Coordinate p01,
+			Coordinate p10, Coordinate p11) 
+	{
+		pts = new Coordinate[] { p00, p01, p10, p11 };
+		compute();
+	}
+
+	private void compute() 
+	{
+		Coordinate centroid = average(pts);
+		intPt = findNearestPoint(centroid, pts);
+	}
+
+	public Coordinate getIntersection() {
+		return intPt;
+	}
+
+	private static Coordinate average(Coordinate[] pts)
+	{
+		Coordinate avg = new Coordinate();
+		int n = pts.length;
+		for (int i = 0; i < pts.length; i++) {
+			avg.x += pts[i].x;
+			avg.y += pts[i].y;
+		}
+		if (n > 0) {
+			avg.x /= n;
+			avg.y /= n;
+		}
+		return avg;
+	}
+	
+  /**
+   * Determines a point closest to the given point.
+   * 
+   * @param p the point to compare against
+   * @param p1 a potential result point
+   * @param p2 a potential result point
+   * @param q1 a potential result point
+   * @param q2 a potential result point
+   * @return the point closest to the input point p
+   */
+  private Coordinate findNearestPoint(Coordinate p, Coordinate[] pts)
+  {
+  	double minDist = Double.MAX_VALUE;
+  	Coordinate result = null;
+  	for (int i = 0; i < pts.length; i++) {
+  		double dist = p.distance(pts[i]);
+  		if (dist < minDist) {
+  			minDist = dist;
+  			result = pts[i];
+  		}
+  	}
+  	return result;
+  }
+  
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/ConvexHull.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/ConvexHull.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/ConvexHull.java	(revision 28000)
@@ -0,0 +1,525 @@
+
+
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Stack;
+import java.util.TreeSet;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateArrays;
+import com.vividsolutions.jts.geom.CoordinateList;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.util.Assert;
+import com.vividsolutions.jts.util.UniqueCoordinateArrayFilter;
+
+/**
+ * Computes the convex hull of a {@link Geometry}.
+ * The convex hull is the smallest convex Geometry that contains all the
+ * points in the input Geometry.
+ * <p>
+ * Uses the Graham Scan algorithm.
+ *
+ *@version 1.7
+ */
+public class ConvexHull
+{
+  private GeometryFactory geomFactory;
+  private Coordinate[] inputPts;
+
+  /**
+   * Create a new convex hull construction for the input {@link Geometry}.
+   */
+  public ConvexHull(Geometry geometry)
+  {
+    this(extractCoordinates(geometry), geometry.getFactory());
+  }
+  /**
+   * Create a new convex hull construction for the input {@link Coordinate} array.
+   */
+  public ConvexHull(Coordinate[] pts, GeometryFactory geomFactory)
+  {
+    inputPts = pts;
+    this.geomFactory = geomFactory;
+  }
+
+  private static Coordinate[] extractCoordinates(Geometry geom)
+  {
+    UniqueCoordinateArrayFilter filter = new UniqueCoordinateArrayFilter();
+    geom.apply(filter);
+    return filter.getCoordinates();
+  }
+
+  /**
+   * Returns a {@link Geometry} that represents the convex hull of the input
+   * geometry.
+   * The returned geometry contains the minimal number of points needed to
+   * represent the convex hull.  In particular, no more than two consecutive
+   * points will be collinear.
+   *
+   * @return if the convex hull contains 3 or more points, a {@link Polygon};
+   * 2 points, a {@link LineString};
+   * 1 point, a {@link Point};
+   * 0 points, an empty {@link GeometryCollection}.
+   */
+  public Geometry getConvexHull() {
+
+    if (inputPts.length == 0) {
+      return geomFactory.createGeometryCollection(null);
+    }
+    if (inputPts.length == 1) {
+      return geomFactory.createPoint(inputPts[0]);
+    }
+    if (inputPts.length == 2) {
+      return geomFactory.createLineString(inputPts);
+    }
+
+    Coordinate[] reducedPts = inputPts;
+    // use heuristic to reduce points, if large
+    if (inputPts.length > 50) {
+      reducedPts = reduce(inputPts);
+    }
+    // sort points for Graham scan.
+    Coordinate[] sortedPts = preSort(reducedPts);
+
+    // Use Graham scan to find convex hull.
+    Stack cHS = grahamScan(sortedPts);
+
+    // Convert stack to an array.
+    Coordinate[] cH = toCoordinateArray(cHS);
+
+    // Convert array to appropriate output geometry.
+    return lineOrPolygon(cH);
+  }
+
+  /**
+   * An alternative to Stack.toArray, which is not present in earlier versions
+   * of Java.
+   */
+  protected Coordinate[] toCoordinateArray(Stack stack) {
+    Coordinate[] coordinates = new Coordinate[stack.size()];
+    for (int i = 0; i < stack.size(); i++) {
+      Coordinate coordinate = (Coordinate) stack.get(i);
+      coordinates[i] = coordinate;
+    }
+    return coordinates;
+  }
+
+  /**
+   * Uses a heuristic to reduce the number of points scanned
+   * to compute the hull.
+   * The heuristic is to find a polygon guaranteed to
+   * be in (or on) the hull, and eliminate all points inside it.
+   * A quadrilateral defined by the extremal points
+   * in the four orthogonal directions
+   * can be used, but even more inclusive is
+   * to use an octilateral defined by the points in the 8 cardinal directions.
+   * <p>
+   * Note that even if the method used to determine the polygon vertices
+   * is not 100% robust, this does not affect the robustness of the convex hull.
+   * <p>
+   * To satisfy the requirements of the Graham Scan algorithm, 
+   * the returned array has at least 3 entries.
+   *
+   * @param pts the points to reduce
+   * @return the reduced list of points (at least 3)
+   */
+  private Coordinate[] reduce(Coordinate[] inputPts)
+  {
+    //Coordinate[] polyPts = computeQuad(inputPts);
+    Coordinate[] polyPts = computeOctRing(inputPts);
+    //Coordinate[] polyPts = null;
+
+    // unable to compute interior polygon for some reason
+    if (polyPts == null)
+      return inputPts;
+
+//    LinearRing ring = geomFactory.createLinearRing(polyPts);
+//    System.out.println(ring);
+
+    // add points defining polygon
+    TreeSet reducedSet = new TreeSet();
+    for (int i = 0; i < polyPts.length; i++) {
+      reducedSet.add(polyPts[i]);
+    }
+    /**
+     * Add all unique points not in the interior poly.
+     * CGAlgorithms.isPointInRing is not defined for points actually on the ring,
+     * but this doesn't matter since the points of the interior polygon
+     * are forced to be in the reduced set.
+     */
+    for (int i = 0; i < inputPts.length; i++) {
+      if (! CGAlgorithms.isPointInRing(inputPts[i], polyPts)) {
+        reducedSet.add(inputPts[i]);
+      }
+    }
+    Coordinate[] reducedPts = CoordinateArrays.toCoordinateArray(reducedSet);
+    
+    // ensure that computed array has at least 3 points (not necessarily unique)  
+    if (reducedPts.length < 3)
+      return padArray3(reducedPts); 
+    return reducedPts;
+  }
+
+  private Coordinate[] padArray3(Coordinate[] pts)
+  {
+    Coordinate[] pad = new Coordinate[3];
+    for (int i = 0; i < pad.length; i++) {
+      if (i < pts.length) {
+        pad[i] = pts[i];
+      }
+      else
+        pad[i] = pts[0];
+    }
+    return pad;
+  }
+    
+  private Coordinate[] preSort(Coordinate[] pts) {
+    Coordinate t;
+
+    // find the lowest point in the set. If two or more points have
+    // the same minimum y coordinate choose the one with the minimu x.
+    // This focal point is put in array location pts[0].
+    for (int i = 1; i < pts.length; i++) {
+      if ((pts[i].y < pts[0].y) || ((pts[i].y == pts[0].y) && (pts[i].x < pts[0].x))) {
+        t = pts[0];
+        pts[0] = pts[i];
+        pts[i] = t;
+      }
+    }
+
+    // sort the points radially around the focal point.
+    Arrays.sort(pts, 1, pts.length, new RadialComparator(pts[0]));
+
+    //radialSort(pts);
+    return pts;
+  }
+
+  /**
+   * Uses the Graham Scan algorithm to compute the convex hull vertices.
+   * 
+   * @param c a list of points, with at least 3 entries
+   * @return a Stack containing the ordered points of the convex hull ring
+   */
+  private Stack grahamScan(Coordinate[] c) {
+    Coordinate p;
+    Stack ps = new Stack();
+    p = (Coordinate) ps.push(c[0]);
+    p = (Coordinate) ps.push(c[1]);
+    p = (Coordinate) ps.push(c[2]);
+    for (int i = 3; i < c.length; i++) {
+      p = (Coordinate) ps.pop();
+      while (CGAlgorithms.computeOrientation((Coordinate) ps.peek(), p, c[i]) > 0) {
+        p = (Coordinate) ps.pop();
+      }
+      p = (Coordinate) ps.push(p);
+      p = (Coordinate) ps.push(c[i]);
+    }
+    p = (Coordinate) ps.push(c[0]);
+    return ps;
+  }
+
+  /**
+   *@return    whether the three coordinates are collinear and c2 lies between
+   *      c1 and c3 inclusive
+   */
+  private boolean isBetween(Coordinate c1, Coordinate c2, Coordinate c3) {
+    if (CGAlgorithms.computeOrientation(c1, c2, c3) != 0) {
+      return false;
+    }
+    if (c1.x != c3.x) {
+      if (c1.x <= c2.x && c2.x <= c3.x) {
+        return true;
+      }
+      if (c3.x <= c2.x && c2.x <= c1.x) {
+        return true;
+      }
+    }
+    if (c1.y != c3.y) {
+      if (c1.y <= c2.y && c2.y <= c3.y) {
+        return true;
+      }
+      if (c3.y <= c2.y && c2.y <= c1.y) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private Coordinate[] computeOctRing(Coordinate[] inputPts) {
+    Coordinate[] octPts = computeOctPts(inputPts);
+    CoordinateList coordList = new CoordinateList();
+    coordList.add(octPts, false);
+
+    // points must all lie in a line
+    if (coordList.size() < 3) {
+      return null;
+    }
+    coordList.closeRing();
+    return coordList.toCoordinateArray();
+  }
+
+  private Coordinate[] computeOctPts(Coordinate[] inputPts)
+  {
+    Coordinate[] pts = new Coordinate[8];
+    for (int j = 0; j < pts.length; j++) {
+      pts[j] = inputPts[0];
+    }
+    for (int i = 1; i < inputPts.length; i++) {
+      if (inputPts[i].x < pts[0].x) {
+        pts[0] = inputPts[i];
+      }
+      if (inputPts[i].x - inputPts[i].y < pts[1].x - pts[1].y) {
+        pts[1] = inputPts[i];
+      }
+      if (inputPts[i].y > pts[2].y) {
+        pts[2] = inputPts[i];
+      }
+      if (inputPts[i].x + inputPts[i].y > pts[3].x + pts[3].y) {
+        pts[3] = inputPts[i];
+      }
+      if (inputPts[i].x > pts[4].x) {
+        pts[4] = inputPts[i];
+      }
+      if (inputPts[i].x - inputPts[i].y > pts[5].x - pts[5].y) {
+        pts[5] = inputPts[i];
+      }
+      if (inputPts[i].y < pts[6].y) {
+        pts[6] = inputPts[i];
+      }
+      if (inputPts[i].x + inputPts[i].y < pts[7].x + pts[7].y) {
+        pts[7] = inputPts[i];
+      }
+    }
+    return pts;
+
+  }
+
+/*
+  // MD - no longer used, but keep for reference purposes
+  private Coordinate[] computeQuad(Coordinate[] inputPts) {
+    BigQuad bigQuad = bigQuad(inputPts);
+
+    // Build a linear ring defining a big poly.
+    ArrayList bigPoly = new ArrayList();
+    bigPoly.add(bigQuad.westmost);
+    if (! bigPoly.contains(bigQuad.northmost)) {
+      bigPoly.add(bigQuad.northmost);
+    }
+    if (! bigPoly.contains(bigQuad.eastmost)) {
+      bigPoly.add(bigQuad.eastmost);
+    }
+    if (! bigPoly.contains(bigQuad.southmost)) {
+      bigPoly.add(bigQuad.southmost);
+    }
+    // points must all lie in a line
+    if (bigPoly.size() < 3) {
+      return null;
+    }
+    // closing point
+    bigPoly.add(bigQuad.westmost);
+
+    Coordinate[] bigPolyArray = CoordinateArrays.toCoordinateArray(bigPoly);
+
+    return bigPolyArray;
+  }
+
+  private BigQuad bigQuad(Coordinate[] pts) {
+    BigQuad bigQuad = new BigQuad();
+    bigQuad.northmost = pts[0];
+    bigQuad.southmost = pts[0];
+    bigQuad.westmost = pts[0];
+    bigQuad.eastmost = pts[0];
+    for (int i = 1; i < pts.length; i++) {
+      if (pts[i].x < bigQuad.westmost.x) {
+        bigQuad.westmost = pts[i];
+      }
+      if (pts[i].x > bigQuad.eastmost.x) {
+        bigQuad.eastmost = pts[i];
+      }
+      if (pts[i].y < bigQuad.southmost.y) {
+        bigQuad.southmost = pts[i];
+      }
+      if (pts[i].y > bigQuad.northmost.y) {
+        bigQuad.northmost = pts[i];
+      }
+    }
+    return bigQuad;
+  }
+
+  private static class BigQuad {
+    public Coordinate northmost;
+    public Coordinate southmost;
+    public Coordinate westmost;
+    public Coordinate eastmost;
+  }
+  */
+
+  /**
+   *@param  vertices  the vertices of a linear ring, which may or may not be
+   *      flattened (i.e. vertices collinear)
+   *@return           a 2-vertex <code>LineString</code> if the vertices are
+   *      collinear; otherwise, a <code>Polygon</code> with unnecessary
+   *      (collinear) vertices removed
+   */
+  private Geometry lineOrPolygon(Coordinate[] coordinates) {
+
+    coordinates = cleanRing(coordinates);
+    if (coordinates.length == 3) {
+      return geomFactory.createLineString(new Coordinate[]{coordinates[0], coordinates[1]});
+//      return new LineString(new Coordinate[]{coordinates[0], coordinates[1]},
+//          geometry.getPrecisionModel(), geometry.getSRID());
+    }
+    LinearRing linearRing = geomFactory.createLinearRing(coordinates);
+    return geomFactory.createPolygon(linearRing, null);
+  }
+
+  /**
+   *@param  vertices  the vertices of a linear ring, which may or may not be
+   *      flattened (i.e. vertices collinear)
+   *@return           the coordinates with unnecessary (collinear) vertices
+   *      removed
+   */
+  private Coordinate[] cleanRing(Coordinate[] original) {
+    Assert.equals(original[0], original[original.length - 1]);
+    ArrayList cleanedRing = new ArrayList();
+    Coordinate previousDistinctCoordinate = null;
+    for (int i = 0; i <= original.length - 2; i++) {
+      Coordinate currentCoordinate = original[i];
+      Coordinate nextCoordinate = original[i+1];
+      if (currentCoordinate.equals(nextCoordinate)) {
+        continue;
+      }
+      if (previousDistinctCoordinate != null
+          && isBetween(previousDistinctCoordinate, currentCoordinate, nextCoordinate)) {
+        continue;
+      }
+      cleanedRing.add(currentCoordinate);
+      previousDistinctCoordinate = currentCoordinate;
+    }
+    cleanedRing.add(original[original.length - 1]);
+    Coordinate[] cleanedRingCoordinates = new Coordinate[cleanedRing.size()];
+    return (Coordinate[]) cleanedRing.toArray(cleanedRingCoordinates);
+  }
+
+
+  /**
+   * Compares {@link Coordinate}s for their angle and distance
+   * relative to an origin.
+   *
+   * @author Martin Davis
+   * @version 1.7
+   */
+  private static class RadialComparator
+      implements Comparator
+  {
+    private Coordinate origin;
+
+    public RadialComparator(Coordinate origin)
+    {
+      this.origin = origin;
+    }
+    public int compare(Object o1, Object o2)
+    {
+      Coordinate p1 = (Coordinate) o1;
+      Coordinate p2 = (Coordinate) o2;
+      return polarCompare(origin, p1, p2);
+    }
+
+    /**
+     * Given two points p and q compare them with respect to their radial
+     * ordering about point o.  First checks radial ordering.
+     * If points are collinear, the comparison is based
+     * on their distance to the origin.
+     * <p>
+     * p < q iff
+     * <ul>
+     * <li>ang(o-p) < ang(o-q) (e.g. o-p-q is CCW)
+     * <li>or ang(o-p) == ang(o-q) && dist(o,p) < dist(o,q)
+     * </ul>
+     *
+     * @param o the origin
+     * @param p a point
+     * @param q another point
+     * @return -1, 0 or 1 depending on whether p is less than,
+     * equal to or greater than q
+     */
+    private static int polarCompare(Coordinate o, Coordinate p, Coordinate q)
+    {
+      double dxp = p.x - o.x;
+      double dyp = p.y - o.y;
+      double dxq = q.x - o.x;
+      double dyq = q.y - o.y;
+
+/*
+      // MD - non-robust
+      int result = 0;
+      double alph = Math.atan2(dxp, dyp);
+      double beta = Math.atan2(dxq, dyq);
+      if (alph < beta) {
+        result = -1;
+      }
+      if (alph > beta) {
+        result = 1;
+      }
+      if (result !=  0) return result;
+      //*/
+
+      int orient = CGAlgorithms.computeOrientation(o, p, q);
+
+      if (orient == CGAlgorithms.COUNTERCLOCKWISE) return 1;
+      if (orient == CGAlgorithms.CLOCKWISE) return -1;
+
+      // points are collinear - check distance
+      double op = dxp * dxp + dyp * dyp;
+      double oq = dxq * dxq + dyq * dyq;
+      if (op < oq) {
+        return -1;
+      }
+      if (op > oq) {
+        return 1;
+      }
+      return 0;
+    }
+
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/HCoordinate.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/HCoordinate.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/HCoordinate.java	(revision 28000)
@@ -0,0 +1,105 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+import com.vividsolutions.jts.geom.Coordinate;
+
+/**
+ * Represents a homogeneous coordinate in a 2-D coordinate space.
+ * In JTS {@link HCoordinate}s are used as a clean way
+ * of computing intersections between line segments.
+ *
+ * @author David Skea
+ * @version 1.7
+ */
+public class HCoordinate
+{
+
+  /**
+   * Computes the (approximate) intersection point between two line segments
+   * using homogeneous coordinates.
+   * <p>
+   * Note that this algorithm is
+   * not numerically stable; i.e. it can produce intersection points which
+   * lie outside the envelope of the line segments themselves.  In order
+   * to increase the precision of the calculation input points should be normalized
+   * before passing them to this routine.
+   */
+  public static Coordinate intersection(
+      Coordinate p1, Coordinate p2,
+      Coordinate q1, Coordinate q2)
+      throws NotRepresentableException
+  {
+  	// unrolled computation
+    double px = p1.y - p2.y;
+    double py = p2.x - p1.x;
+    double pw = p1.x * p2.y - p2.x * p1.y;
+    
+    double qx = q1.y - q2.y;
+    double qy = q2.x - q1.x;
+    double qw = q1.x * q2.y - q2.x * q1.y;
+    
+    double x = py * qw - qy * pw;
+    double y = qx * pw - px * qw;
+    double w = px * qy - qx * py;
+    
+    double xInt = x/w;
+    double yInt = y/w;
+    
+    if ((Double.isNaN(xInt)) || (Double.isInfinite(xInt)
+    		|| Double.isNaN(yInt)) || (Double.isInfinite(yInt))) {
+      throw new NotRepresentableException();
+    }
+    
+    return new Coordinate(xInt, yInt);
+  }
+
+  /*
+  public static Coordinate OLDintersection(
+      Coordinate p1, Coordinate p2,
+      Coordinate q1, Coordinate q2)
+      throws NotRepresentableException
+  {
+    HCoordinate l1 = new HCoordinate(p1, p2);
+    HCoordinate l2 = new HCoordinate(q1, q2);
+    HCoordinate intHCoord = new HCoordinate(l1, l2);
+    Coordinate intPt = intHCoord.getCoordinate();
+    return intPt;
+  }
+  */
+
+  public HCoordinate() {
+  }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/LineIntersector.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/LineIntersector.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/LineIntersector.java	(revision 28000)
@@ -0,0 +1,326 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+/**
+ * @version 1.7
+ */
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.PrecisionModel;
+import com.vividsolutions.jts.io.WKTWriter;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * A LineIntersector is an algorithm that can both test whether
+ * two line segments intersect and compute the intersection point
+ * if they do.
+ * The intersection point may be computed in a precise or non-precise manner.
+ * Computing it precisely involves rounding it to an integer.  (This assumes
+ * that the input coordinates have been made precise by scaling them to
+ * an integer grid.)
+ *
+ * @version 1.7
+ */
+public abstract class LineIntersector 
+{
+  
+  /**
+   * Indicates that line segments do not intersect
+   */
+  public final static int NO_INTERSECTION = 0;
+  
+  /**
+   * Indicates that line segments intersect in a single point
+   */
+  public final static int POINT_INTERSECTION = 1;
+  
+  /**
+   * Indicates that line segments intersect in a line segment
+   */
+  public final static int COLLINEAR_INTERSECTION = 2;
+
+  /**
+   * Computes the "edge distance" of an intersection point p along a segment.
+   * The edge distance is a metric of the point along the edge.
+   * The metric used is a robust and easy to compute metric function.
+   * It is <b>not</b> equivalent to the usual Euclidean metric.
+   * It relies on the fact that either the x or the y ordinates of the
+   * points in the edge are unique, depending on whether the edge is longer in
+   * the horizontal or vertical direction.
+   * <p>
+   * NOTE: This function may produce incorrect distances
+   *  for inputs where p is not precisely on p1-p2
+   * (E.g. p = (139,9) p1 = (139,10), p2 = (280,1) produces distanct 0.0, which is incorrect.
+   * <p>
+   * My hypothesis is that the function is safe to use for points which are the
+   * result of <b>rounding</b> points which lie on the line,
+   * but not safe to use for <b>truncated</b> points.
+   */
+  public static double computeEdgeDistance(
+        Coordinate p,
+        Coordinate p0,
+        Coordinate p1)
+  {
+    double dx = Math.abs(p1.x - p0.x);
+    double dy = Math.abs(p1.y - p0.y);
+
+    double dist = -1.0;   // sentinel value
+    if (p.equals(p0)) {
+      dist = 0.0;
+    }
+    else if (p.equals(p1)) {
+      if (dx > dy)
+        dist = dx;
+      else
+        dist = dy;
+    }
+    else {
+      double pdx = Math.abs(p.x - p0.x);
+      double pdy = Math.abs(p.y - p0.y);
+      if (dx > dy)
+        dist = pdx;
+      else
+        dist = pdy;
+      // <FIX>
+      // hack to ensure that non-endpoints always have a non-zero distance
+      if (dist == 0.0 && ! p.equals(p0))
+      {
+        dist = Math.max(pdx, pdy);
+      }
+    }
+    Assert.isTrue(! (dist == 0.0 && ! p.equals(p0)), "Bad distance calculation");
+    return dist;
+  }
+
+
+  protected int result;
+  protected Coordinate[][] inputLines = new Coordinate[2][2];
+  protected Coordinate[] intPt = new Coordinate[2];
+  /**
+   * The indexes of the endpoints of the intersection lines, in order along
+   * the corresponding line
+   */
+  protected boolean isProper;
+  /**
+   * If makePrecise is true, computed intersection coordinates will be made precise
+   * using Coordinate#makePrecise
+   */
+  protected PrecisionModel precisionModel = null;
+//public int numIntersects = 0;
+
+  public LineIntersector() {
+    intPt[0] = new Coordinate();
+    intPt[1] = new Coordinate();
+    // alias the intersection points for ease of reference
+    result = 0;
+  }
+
+  /**
+   * Force computed intersection to be rounded to a given precision model.
+   * No getter is provided, because the precision model is not required to be specified.
+   * @param precisionModel
+   */
+  public void setPrecisionModel(PrecisionModel precisionModel)
+  {
+    this.precisionModel = precisionModel;
+  }
+  
+  /**
+   * Compute the intersection of a point p and the line p1-p2.
+   * This function computes the boolean value of the hasIntersection test.
+   * The actual value of the intersection (if there is one)
+   * is equal to the value of <code>p</code>.
+   */
+  public abstract void computeIntersection(
+        Coordinate p,
+        Coordinate p1, Coordinate p2);
+
+  protected boolean isCollinear() {
+    return result == COLLINEAR_INTERSECTION;
+  }
+
+  /**
+   * Computes the intersection of the lines p1-p2 and p3-p4.
+   * This function computes both the boolean value of the hasIntersection test
+   * and the (approximate) value of the intersection point itself (if there is one).
+   */
+  public void computeIntersection(
+                Coordinate p1, Coordinate p2,
+                Coordinate p3, Coordinate p4) {
+    inputLines[0][0] = p1;
+    inputLines[0][1] = p2;
+    inputLines[1][0] = p3;
+    inputLines[1][1] = p4;
+    result = computeIntersect(p1, p2, p3, p4);
+//numIntersects++;
+  }
+
+  protected abstract int computeIntersect(
+                Coordinate p1, Coordinate p2,
+                Coordinate q1, Coordinate q2);
+
+/*
+  public String toString() {
+    String str = inputLines[0][0] + "-"
+         + inputLines[0][1] + " "
+         + inputLines[1][0] + "-"
+         + inputLines[1][1] + " : "
+               + getTopologySummary();
+    return str;
+  }
+*/
+
+  public String toString() {
+    return WKTWriter.toLineString(inputLines[0][0], inputLines[0][1]) + " - "
+    + WKTWriter.toLineString(inputLines[1][0], inputLines[1][1])
+                 + getTopologySummary();
+  }
+
+  private String getTopologySummary()
+  {
+    StringBuffer catBuf = new StringBuffer();
+    if (isEndPoint()) catBuf.append(" endpoint");
+    if (isProper) catBuf.append(" proper");
+    if (isCollinear()) catBuf.append(" collinear");
+    return catBuf.toString();
+  }
+
+  protected boolean isEndPoint() {
+    return hasIntersection() && !isProper;
+  }
+
+  /**
+   * Tests whether the input geometries intersect.
+   *
+   * @return true if the input geometries intersect
+   */
+  public boolean hasIntersection() {
+    return result != NO_INTERSECTION;
+  }
+
+  /**
+   * Returns the number of intersection points found.  This will be either 0, 1 or 2.
+   */
+  public int getIntersectionNum() { return result; }
+
+  /**
+   * Returns the intIndex'th intersection point
+   *
+   * @param intIndex is 0 or 1
+   *
+   * @return the intIndex'th intersection point
+   */
+  public Coordinate getIntersection(int intIndex)  { return intPt[intIndex]; }
+
+
+  /**
+   * Test whether a point is a intersection point of two line segments.
+   * Note that if the intersection is a line segment, this method only tests for
+   * equality with the endpoints of the intersection segment.
+   * It does <b>not</b> return true if
+   * the input point is internal to the intersection segment.
+   *
+   * @return true if the input point is one of the intersection points.
+   */
+  public boolean isIntersection(Coordinate pt) {
+    for (int i = 0; i < result; i++) {
+      if (intPt[i].equals2D(pt)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Tests whether either intersection point is an interior point of one of the input segments.
+   *
+   * @return <code>true</code> if either intersection point is in the interior of one of the input segments
+   */
+  public boolean isInteriorIntersection()
+  {
+    if (isInteriorIntersection(0)) return true;
+    if (isInteriorIntersection(1)) return true;
+    return false;
+  }
+
+  /**
+   * Tests whether either intersection point is an interior point of the specified input segment.
+   *
+   * @return <code>true</code> if either intersection point is in the interior of the input segment
+   */
+  public boolean isInteriorIntersection(int inputLineIndex)
+  {
+    for (int i = 0; i < result; i++) {
+      if (! (   intPt[i].equals2D(inputLines[inputLineIndex][0])
+             || intPt[i].equals2D(inputLines[inputLineIndex][1]) )) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Tests whether an intersection is proper.
+   * <br>
+   * The intersection between two line segments is considered proper if
+   * they intersect in a single point in the interior of both segments
+   * (e.g. the intersection is a single point and is not equal to any of the
+   * endpoints).
+   * <p>
+   * The intersection between a point and a line segment is considered proper
+   * if the point lies in the interior of the segment (e.g. is not equal to
+   * either of the endpoints).
+   *
+   * @return true if the intersection is proper
+   */
+  public boolean isProper() {
+    return hasIntersection() && isProper;
+  }
+
+  /**
+   * Computes the "edge distance" of an intersection point along the specified input line segment.
+   *
+   * @param segmentIndex is 0 or 1
+   * @param intIndex is 0 or 1
+   *
+   * @return the edge distance of the intersection point
+   */
+  public double getEdgeDistance(int segmentIndex, int intIndex) {
+    double dist = computeEdgeDistance(intPt[intIndex], inputLines[segmentIndex][0],
+        inputLines[segmentIndex][1]);
+    return dist;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/MCPointInRing.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/MCPointInRing.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/MCPointInRing.java	(revision 28000)
@@ -0,0 +1,172 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.algorithm.locate.IndexedPointInAreaLocator;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateArrays;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.LineSegment;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.index.bintree.Bintree;
+import com.vividsolutions.jts.index.bintree.Interval;
+import com.vividsolutions.jts.index.chain.MonotoneChain;
+import com.vividsolutions.jts.index.chain.MonotoneChainBuilder;
+import com.vividsolutions.jts.index.chain.MonotoneChainSelectAction;
+
+/**
+ * Implements {@link PointInRing}
+ * using {@link MonotoneChain}s and a {@link Bintree} index to
+ * increase performance.
+ *
+ * @version 1.7
+ * 
+ * @see IndexedPointInAreaLocator for more general functionality
+ */
+public class MCPointInRing   implements PointInRing {
+
+  class MCSelecter extends MonotoneChainSelectAction
+  {
+    Coordinate p;
+
+    public MCSelecter(Coordinate p)
+    {
+      this.p = p;
+    }
+
+    public void select(LineSegment ls)
+    {
+      testLineSegment(p, ls);
+    }
+  }
+
+  private LinearRing ring;
+  private Bintree tree;
+  private int crossings = 0;  // number of segment/ray crossings
+
+  public MCPointInRing(LinearRing ring)
+  {
+    this.ring = ring;
+    buildIndex();
+  }
+
+  private void buildIndex()
+  {
+    //Envelope env = ring.getEnvelopeInternal();
+    tree = new Bintree();
+
+    Coordinate[] pts = CoordinateArrays.removeRepeatedPoints(ring.getCoordinates());
+    List mcList = MonotoneChainBuilder.getChains(pts);
+
+    for (int i = 0; i < mcList.size(); i++) {
+      MonotoneChain mc = (MonotoneChain) mcList.get(i);
+      Envelope mcEnv = mc.getEnvelope();
+      interval.min = mcEnv.getMinY();
+      interval.max = mcEnv.getMaxY();
+      tree.insert(interval, mc);
+    }
+  }
+
+  private Interval interval = new Interval();
+
+  public boolean isInside(Coordinate pt)
+  {
+    crossings = 0;
+
+    // test all segments intersected by ray from pt in positive x direction
+    Envelope rayEnv = new Envelope(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, pt.y, pt.y);
+
+    interval.min = pt.y;
+    interval.max = pt.y;
+    List segs = tree.query(interval);
+//System.out.println("query size = " + segs.size());
+
+    MCSelecter mcSelecter = new MCSelecter(pt);
+    for (Iterator i = segs.iterator(); i.hasNext(); ) {
+      MonotoneChain mc = (MonotoneChain) i.next();
+      testMonotoneChain(rayEnv, mcSelecter, mc);
+    }
+
+    /*
+     *  p is inside if number of crossings is odd.
+     */
+    if ((crossings % 2) == 1) {
+      return true;
+    }
+    return false;
+  }
+
+
+  private void testMonotoneChain(Envelope rayEnv, MCSelecter mcSelecter, MonotoneChain mc)
+  {
+    mc.select(rayEnv, mcSelecter);
+  }
+
+  private void testLineSegment(Coordinate p, LineSegment seg) {
+    double xInt;  // x intersection of segment with ray
+    double x1;    // translated coordinates
+    double y1;
+    double x2;
+    double y2;
+
+    /*
+     *  Test if segment crosses ray from test point in positive x direction.
+     */
+    Coordinate p1 = seg.p0;
+    Coordinate p2 = seg.p1;
+    x1 = p1.x - p.x;
+    y1 = p1.y - p.y;
+    x2 = p2.x - p.x;
+    y2 = p2.y - p.y;
+
+    if (((y1 > 0) && (y2 <= 0)) ||
+        ((y2 > 0) && (y1 <= 0))) {
+        /*
+         *  segment straddles x axis, so compute intersection.
+         */
+      xInt = RobustDeterminant.signOfDet2x2(x1, y1, x2, y2) / (y2 - y1);
+        //xsave = xInt;
+        /*
+         *  crosses ray if strictly positive intersection.
+         */
+      if (0.0 < xInt) {
+        crossings++;
+      }
+    }
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/NotRepresentableException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/NotRepresentableException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/NotRepresentableException.java	(revision 28000)
@@ -0,0 +1,51 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+/**
+ * Indicates that a {@link HCoordinate} has been computed which is
+ * not representable on the Cartesian plane.
+ *
+ * @version 1.7
+ * @see HCoordinate
+ */
+public class NotRepresentableException extends Exception {
+
+  public NotRepresentableException() {
+    super("Projective point not representable on the Cartesian plane.");
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/PointInRing.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/PointInRing.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/PointInRing.java	(revision 28000)
@@ -0,0 +1,50 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+import com.vividsolutions.jts.algorithm.locate.PointOnGeometryLocator;
+import com.vividsolutions.jts.geom.Coordinate;
+
+/**
+ * An interface for classes which test whether a {@link Coordinate} lies inside
+ * a ring.
+ *
+ * @version 1.7
+ * 
+ * @see PointOnGeometryLocator
+ */
+public interface PointInRing {
+
+  boolean isInside(Coordinate pt);
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/PointLocator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/PointLocator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/PointLocator.java	(revision 28000)
@@ -0,0 +1,218 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+import java.util.Iterator;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryCollectionIterator;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geom.MultiLineString;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+
+/**
+ * Computes the topological ({@link Location})
+ * of a single point to a {@link Geometry}.
+ * A {@link BoundaryNodeRule} may be specified 
+ * to control the evaluation of whether the point lies on the boundary or not
+ * The default rule is to use the the <i>SFS Boundary Determination Rule</i>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>{@link LinearRing}s do not enclose any area - points inside the ring are still in the EXTERIOR of the ring.
+ * </ul>
+ * Instances of this class are not reentrant.
+ *
+ * @version 1.7
+ */
+public class PointLocator
+{
+  // default is to use OGC SFS rule
+  private BoundaryNodeRule boundaryRule = 
+  	//BoundaryNodeRule.ENDPOINT_BOUNDARY_RULE; 
+  	BoundaryNodeRule.OGC_SFS_BOUNDARY_RULE;
+
+  private boolean isIn;         // true if the point lies in or on any Geometry element
+  private int numBoundaries;    // the number of sub-elements whose boundaries the point lies in
+
+  public PointLocator() {
+  }
+
+  /**
+   * Convenience method to test a point for intersection with
+   * a Geometry
+   * @param p the coordinate to test
+   * @param geom the Geometry to test
+   * @return <code>true</code> if the point is in the interior or boundary of the Geometry
+   */
+  public boolean intersects(Coordinate p, Geometry geom)
+  {
+    return locate(p, geom) != Location.EXTERIOR;
+  }
+
+  /**
+   * Computes the topological relationship ({@link Location}) of a single point
+   * to a Geometry.
+   * It handles both single-element
+   * and multi-element Geometries.
+   * The algorithm for multi-part Geometries
+   * takes into account the SFS Boundary Determination Rule.
+   *
+   * @return the {@link Location} of the point relative to the input Geometry
+   */
+  public int locate(Coordinate p, Geometry geom)
+  {
+    if (geom.isEmpty()) return Location.EXTERIOR;
+
+    if (geom instanceof LineString) {
+      return locate(p, (LineString) geom);
+    }
+    else if (geom instanceof Polygon) {
+      return locate(p, (Polygon) geom);
+    }
+
+    isIn = false;
+    numBoundaries = 0;
+    computeLocation(p, geom);
+    if (boundaryRule.isInBoundary(numBoundaries))
+      return Location.BOUNDARY;
+    if (numBoundaries > 0 || isIn)
+      return Location.INTERIOR;
+
+    return Location.EXTERIOR;
+  }
+
+  private void computeLocation(Coordinate p, Geometry geom)
+  {
+    if (geom instanceof Point) {
+      updateLocationInfo(locate(p, (Point) geom));
+    }
+    if (geom instanceof LineString) {
+      updateLocationInfo(locate(p, (LineString) geom));
+    }
+    else if (geom instanceof Polygon) {
+      updateLocationInfo(locate(p, (Polygon) geom));
+    }
+    else if (geom instanceof MultiLineString) {
+      MultiLineString ml = (MultiLineString) geom;
+      for (int i = 0; i < ml.getNumGeometries(); i++) {
+        LineString l = (LineString) ml.getGeometryN(i);
+        updateLocationInfo(locate(p, l));
+      }
+    }
+    else if (geom instanceof MultiPolygon) {
+      MultiPolygon mpoly = (MultiPolygon) geom;
+      for (int i = 0; i < mpoly.getNumGeometries(); i++) {
+        Polygon poly = (Polygon) mpoly.getGeometryN(i);
+        updateLocationInfo(locate(p, poly));
+      }
+    }
+    else if (geom instanceof GeometryCollection) {
+      Iterator geomi = new GeometryCollectionIterator(geom);
+      while (geomi.hasNext()) {
+        Geometry g2 = (Geometry) geomi.next();
+        if (g2 != geom)
+          computeLocation(p, g2);
+      }
+    }
+  }
+
+  private void updateLocationInfo(int loc)
+  {
+    if (loc == Location.INTERIOR) isIn = true;
+    if (loc == Location.BOUNDARY) numBoundaries++;
+  }
+
+  private int locate(Coordinate p, Point pt)
+  {
+  	// no point in doing envelope test, since equality test is just as fast
+  	
+    Coordinate ptCoord = pt.getCoordinate();
+    if (ptCoord.equals2D(p))
+      return Location.INTERIOR;
+    return Location.EXTERIOR;
+  }
+
+  private int locate(Coordinate p, LineString l)
+  {
+  	// bounding-box check
+  	if (! l.getEnvelopeInternal().intersects(p)) return Location.EXTERIOR;
+  	
+    Coordinate[] pt = l.getCoordinates();
+    if (! l.isClosed()) {
+      if (p.equals(pt[0])
+          || p.equals(pt[pt.length - 1]) ) {
+        return Location.BOUNDARY;
+      }
+    }
+    if (CGAlgorithms.isOnLine(p, pt))
+      return Location.INTERIOR;
+    return Location.EXTERIOR;
+  }
+
+  private int locateInPolygonRing(Coordinate p, LinearRing ring)
+  {
+  	// bounding-box check
+  	if (! ring.getEnvelopeInternal().intersects(p)) return Location.EXTERIOR;
+
+  	return CGAlgorithms.locatePointInRing(p, ring.getCoordinates());
+  }
+
+  private int locate(Coordinate p, Polygon poly)
+  {
+    if (poly.isEmpty()) return Location.EXTERIOR;
+
+    LinearRing shell = (LinearRing) poly.getExteriorRing();
+
+    int shellLoc = locateInPolygonRing(p, shell);
+    if (shellLoc == Location.EXTERIOR) return Location.EXTERIOR;
+    if (shellLoc == Location.BOUNDARY) return Location.BOUNDARY;
+    // now test if the point lies in or on the holes
+    for (int i = 0; i < poly.getNumInteriorRing(); i++) {
+      LinearRing hole = (LinearRing) poly.getInteriorRingN(i);
+      int holeLoc = locateInPolygonRing(p, hole);
+      if (holeLoc == Location.INTERIOR) return Location.EXTERIOR;
+      if (holeLoc == Location.BOUNDARY) return Location.BOUNDARY;
+    }
+    return Location.INTERIOR;
+  }
+
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/RayCrossingCounter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/RayCrossingCounter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/RayCrossingCounter.java	(revision 28000)
@@ -0,0 +1,214 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geom.Polygonal;
+
+/**
+ * Counts the number of segments crossed by a horizontal ray extending to the right
+ * from a given point, in an incremental fashion.
+ * This can be used to determine whether a point lies in a {@link Polygonal} geometry.
+ * The class determines the situation where the point lies exactly on a segment.
+ * When being used for Point-In-Polygon determination, this case allows short-circuiting
+ * the evaluation.
+ * <p>
+ * This class handles polygonal geometries with any number of shells and holes.
+ * The orientation of the shell and hole rings is unimportant.
+ * In order to compute a correct location for a given polygonal geometry, 
+ * it is essential that <b>all</b> segments are counted which
+ * <ul>
+ * <li>touch the ray 
+ * <li>lie in in any ring which may contain the point
+ * </ul>
+ * The only exception is when the point-on-segment situation is detected, in which
+ * case no further processing is required.
+ * The implication of the above rule is that segments 
+ * which can be a priori determined to <i>not</i> touch the ray
+ * (i.e. by a test of their bounding box or Y-extent) 
+ * do not need to be counted.  This allows for optimization by indexing.
+ * 
+ * @author Martin Davis
+ *
+ */
+public class RayCrossingCounter 
+{
+	/**
+	 * Determines the {@link Location} of a point in a ring.
+	 * This method is an exemplar of how to use this class.
+	 * 
+	 * @param p the point to test
+	 * @param ring an array of Coordinates forming a ring 
+	 * @return the location of the point in the ring
+	 */
+	public static int locatePointInRing(Coordinate p, Coordinate[] ring) 
+	{
+		RayCrossingCounter counter = new RayCrossingCounter(p);
+	
+    for (int i = 1; i < ring.length; i++) {
+      Coordinate p1 = ring[i];
+      Coordinate p2 = ring[i-1];
+      counter.countSegment(p1, p2);
+      if (counter.isOnSegment())
+      	return counter.getLocation();
+    }
+    return counter.getLocation();
+	}
+	
+	private Coordinate p;
+	private int crossingCount = 0;
+	// true if the test point lies on an input segment
+	private boolean isPointOnSegment = false;
+	
+	public RayCrossingCounter(Coordinate p)
+	{
+		this.p = p;
+	}
+	
+	/**
+	 * Counts a segment
+	 * 
+	 * @param p1 an endpoint of the segment
+	 * @param p2 another endpoint of the segment
+	 */
+	public void countSegment(Coordinate p1, Coordinate p2) {
+		/**
+		 * For each segment, check if it crosses 
+		 * a horizontal ray running from the test point in the positive x direction.
+		 */
+		
+		// check if the segment is strictly to the left of the test point
+		if (p1.x < p.x && p2.x < p.x)
+			return;
+		
+		// check if the point is equal to the current ring vertex
+		if (p.x == p2.x && p.y == p2.y) {
+			isPointOnSegment = true;
+			return;
+		}
+		/**
+		 * For horizontal segments, check if the point is on the segment.
+		 * Otherwise, horizontal segments are not counted.
+		 */
+		if (p1.y == p.y && p2.y == p.y) {
+			double minx = p1.x;
+			double maxx = p2.x;
+			if (minx > maxx) {
+				minx = p2.x;
+				maxx = p1.x;
+			}
+			if (p.x >= minx && p.x <= maxx) {
+				isPointOnSegment = true;
+			}
+			return;
+		}
+		/**
+		 * Evaluate all non-horizontal segments which cross a horizontal ray to the
+		 * right of the test pt. To avoid double-counting shared vertices, we use the
+		 * convention that
+		 * <ul>
+		 * <li>an upward edge includes its starting endpoint, and excludes its
+		 * final endpoint
+		 * <li>a downward edge excludes its starting endpoint, and includes its
+		 * final endpoint
+		 * </ul>
+		 */
+		if (((p1.y > p.y) && (p2.y <= p.y)) 
+				|| ((p2.y > p.y) && (p1.y <= p.y))) {
+			// translate the segment so that the test point lies on the origin
+			double x1 = p1.x - p.x;
+			double y1 = p1.y - p.y;
+			double x2 = p2.x - p.x;
+			double y2 = p2.y - p.y;
+
+			/**
+			 * The translated segment straddles the x-axis. Compute the sign of the
+			 * ordinate of intersection with the x-axis. (y2 != y1, so denominator
+			 * will never be 0.0)
+			 */
+			// double xIntSign = RobustDeterminant.signOfDet2x2(x1, y1, x2, y2) / (y2
+			// - y1);
+			// MD - faster & more robust computation?
+			double xIntSign = RobustDeterminant.signOfDet2x2(x1, y1, x2, y2);
+			if (xIntSign == 0.0) {
+				isPointOnSegment = true;
+				return;
+			}
+			if (y2 < y1)
+				xIntSign = -xIntSign;
+			// xsave = xInt;
+
+      //System.out.println("xIntSign(" + x1 + ", " + y1 + ", " + x2 + ", " + y2 + " = " + xIntSign);
+			// The segment crosses the ray if the sign is strictly positive.
+			if (xIntSign > 0.0) {
+				crossingCount++;
+			}
+		}
+	}
+	
+/**
+ * Reports whether the point lies exactly on one of the supplied segments.
+ * This method may be called at any time as segments are processed.
+ * If the result of this method is <tt>true</tt>, 
+ * no further segments need be supplied, since the result
+ * will never change again.
+ * 
+ * @return true if the point lies exactly on a segment
+ */
+	public boolean isOnSegment() { return isPointOnSegment; }
+	
+	/**
+	 * Gets the {@link Location} of the point relative to 
+	 * the ring, polygon
+	 * or multipolygon from which the processed segments were provided.
+	 * <p>
+	 * This method only determines the correct location 
+	 * if <b>all</b> relevant segments must have been processed. 
+	 * 
+	 * @return the Location of the point
+	 */
+	public int getLocation() 
+	{
+		if (isPointOnSegment)
+			return Location.BOUNDARY;
+		
+    // The point is in the interior of the ring if the number of X-crossings is
+		// odd.
+    if ((crossingCount % 2) == 1) {
+      return Location.INTERIOR;
+    }
+    return Location.EXTERIOR;
+	}
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/RobustDeterminant.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/RobustDeterminant.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/RobustDeterminant.java	(revision 28000)
@@ -0,0 +1,374 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+/**
+ * @version 1.7
+ */
+
+/**
+ * Implements an algorithm to compute the
+ * sign of a 2x2 determinant for double precision values robustly.
+ * It is a direct translation of code developed by Olivier Devillers.
+ * <p>
+ * The original code carries the following copyright notice:
+ *
+ * <pre>
+ *************************************************************************
+ * Author : Olivier Devillers
+ * Olivier.Devillers@sophia.inria.fr
+ * http:/www.inria.fr:/prisme/personnel/devillers/anglais/determinant.html
+ **************************************************************************
+ *
+ **************************************************************************
+ *              Copyright (c) 1995  by  INRIA Prisme Project
+ *                  BP 93 06902 Sophia Antipolis Cedex, France.
+ *                           All rights reserved
+ **************************************************************************
+ * </pre>
+ *
+ * @version 1.7
+ */
+public class RobustDeterminant {
+
+  //public static int callCount = 0; // debugging only
+
+  /*
+  // test point to allow injecting test code
+  public static int signOfDet2x2(double x1, double y1, double x2, double y2) 
+  {
+    int d1 = originalSignOfDet2x2(x1, y1, x2, y2); 
+    int d2 = -originalSignOfDet2x2(y1, x1, x2, y2); 
+    assert d1 == -d2;
+    return d1;
+  }
+   */
+  
+  /*
+   * Test code to force a standard ordering of input ordinates.
+   * A possible fix for a rare problem where evaluation is order-dependent.
+   */
+  /*
+  public static int signOfDet2x2(double x1, double y1, double x2, double y2) 
+  {
+    if (x1 > x2) {
+      return -signOfDet2x2ordX(x2, y2, x1, y1);
+    }
+    return signOfDet2x2ordX(x1, y1, x2, y2);
+  }
+    
+  private static int signOfDet2x2ordX(double x1, double y1, double x2, double y2) 
+  {
+    if (y1 > y2) {
+      return -originalSignOfDet2x2(y1, x1, y2, x2);
+    }
+    return originalSignOfDet2x2(x1, y1, x2, y2);
+  }
+  //  */
+  
+  /**
+   * Computes the sign of the determinant of the 2x2 matrix
+   * with the given entries, in a robust way.
+   * 
+   * @return -1 if the determinant is negative,
+   * @return  1 if the determinant is positive,
+   * @return  0 if the determinant is 0.
+   */
+   //private static int originalSignOfDet2x2(double x1, double y1, double x2, double y2) {
+   public static int signOfDet2x2(double x1, double y1, double x2, double y2) {
+    // returns -1 if the determinant is negative,
+    // returns  1 if the determinant is positive,
+    // returns  0 if the determinant is null.
+    int sign;
+    double swap;
+    double k;
+    long count = 0;
+
+    //callCount++; // debugging only
+
+    sign = 1;
+
+    /*
+     *  testing null entries
+     */
+    if ((x1 == 0.0) || (y2 == 0.0)) {
+      if ((y1 == 0.0) || (x2 == 0.0)) {
+        return 0;
+      }
+      else if (y1 > 0) {
+        if (x2 > 0) {
+          return -sign;
+        }
+        else {
+          return sign;
+        }
+      }
+      else {
+        if (x2 > 0) {
+          return sign;
+        }
+        else {
+          return -sign;
+        }
+      }
+    }
+    if ((y1 == 0.0) || (x2 == 0.0)) {
+      if (y2 > 0) {
+        if (x1 > 0) {
+          return sign;
+        }
+        else {
+          return -sign;
+        }
+      }
+      else {
+        if (x1 > 0) {
+          return -sign;
+        }
+        else {
+          return sign;
+        }
+      }
+    }
+
+    /*
+     *  making y coordinates positive and permuting the entries
+     */
+    /*
+     *  so that y2 is the biggest one
+     */
+    if (0.0 < y1) {
+      if (0.0 < y2) {
+        if (y1 <= y2) {
+        }
+        else {
+          sign = -sign;
+          swap = x1;
+          x1 = x2;
+          x2 = swap;
+          swap = y1;
+          y1 = y2;
+          y2 = swap;
+        }
+      }
+      else {
+        if (y1 <= -y2) {
+          sign = -sign;
+          x2 = -x2;
+          y2 = -y2;
+        }
+        else {
+          swap = x1;
+          x1 = -x2;
+          x2 = swap;
+          swap = y1;
+          y1 = -y2;
+          y2 = swap;
+        }
+      }
+    }
+    else {
+      if (0.0 < y2) {
+        if (-y1 <= y2) {
+          sign = -sign;
+          x1 = -x1;
+          y1 = -y1;
+        }
+        else {
+          swap = -x1;
+          x1 = x2;
+          x2 = swap;
+          swap = -y1;
+          y1 = y2;
+          y2 = swap;
+        }
+      }
+      else {
+        if (y1 >= y2) {
+          x1 = -x1;
+          y1 = -y1;
+          x2 = -x2;
+          y2 = -y2;
+        }
+        else {
+          sign = -sign;
+          swap = -x1;
+          x1 = -x2;
+          x2 = swap;
+          swap = -y1;
+          y1 = -y2;
+          y2 = swap;
+        }
+      }
+    }
+
+    /*
+     *  making x coordinates positive
+     */
+    /*
+     *  if |x2| < |x1| one can conclude
+     */
+    if (0.0 < x1) {
+      if (0.0 < x2) {
+        if (x1 <= x2) {
+        }
+        else {
+          return sign;
+        }
+      }
+      else {
+        return sign;
+      }
+    }
+    else {
+      if (0.0 < x2) {
+        return -sign;
+      }
+      else {
+        if (x1 >= x2) {
+          sign = -sign;
+          x1 = -x1;
+          x2 = -x2;
+        }
+        else {
+          return -sign;
+        }
+      }
+    }
+
+    /*
+     *  all entries strictly positive   x1 <= x2 and y1 <= y2
+     */
+    while (true) {
+      count = count + 1;
+      // MD - UNSAFE HACK for testing only!
+//      k = (int) (x2 / x1);
+      k = Math.floor(x2 / x1);
+      x2 = x2 - k * x1;
+      y2 = y2 - k * y1;
+
+      /*
+       *  testing if R (new U2) is in U1 rectangle
+       */
+      if (y2 < 0.0) {
+        return -sign;
+      }
+      if (y2 > y1) {
+        return sign;
+      }
+
+      /*
+       *  finding R'
+       */
+      if (x1 > x2 + x2) {
+        if (y1 < y2 + y2) {
+          return sign;
+        }
+      }
+      else {
+        if (y1 > y2 + y2) {
+          return -sign;
+        }
+        else {
+          x2 = x1 - x2;
+          y2 = y1 - y2;
+          sign = -sign;
+        }
+      }
+      if (y2 == 0.0) {
+        if (x2 == 0.0) {
+          return 0;
+        }
+        else {
+          return -sign;
+        }
+      }
+      if (x2 == 0.0) {
+        return sign;
+      }
+
+      /*
+       *  exchange 1 and 2 role.
+       */
+      // MD - UNSAFE HACK for testing only!
+//      k = (int) (x1 / x2);
+      k = Math.floor(x1 / x2);
+      x1 = x1 - k * x2;
+      y1 = y1 - k * y2;
+
+      /*
+       *  testing if R (new U1) is in U2 rectangle
+       */
+      if (y1 < 0.0) {
+        return sign;
+      }
+      if (y1 > y2) {
+        return -sign;
+      }
+
+      /*
+       *  finding R'
+       */
+      if (x2 > x1 + x1) {
+        if (y2 < y1 + y1) {
+          return -sign;
+        }
+      }
+      else {
+        if (y2 > y1 + y1) {
+          return sign;
+        }
+        else {
+          x1 = x2 - x1;
+          y1 = y2 - y1;
+          sign = -sign;
+        }
+      }
+      if (y1 == 0.0) {
+        if (x1 == 0.0) {
+          return 0;
+        }
+        else {
+          return sign;
+        }
+      }
+      if (x1 == 0.0) {
+        return -sign;
+      }
+    }
+
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/RobustLineIntersector.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/RobustLineIntersector.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/RobustLineIntersector.java	(revision 28000)
@@ -0,0 +1,372 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm;
+
+/**
+ *@version 1.7
+ */
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * A robust version of {@link LineIntersector}.
+ *
+ * @version 1.7
+ * @see RobustDeterminant
+ */
+public class RobustLineIntersector
+    extends LineIntersector
+{
+
+  public RobustLineIntersector() {
+  }
+
+  public void computeIntersection(Coordinate p, Coordinate p1, Coordinate p2) {
+    isProper = false;
+    // do between check first, since it is faster than the orientation test
+    if (Envelope.intersects(p1, p2, p)) {
+      if ((CGAlgorithms.orientationIndex(p1, p2, p) == 0)
+          && (CGAlgorithms.orientationIndex(p2, p1, p) == 0)) {
+        isProper = true;
+        if (p.equals(p1) || p.equals(p2)) {
+          isProper = false;
+        }
+        result = POINT_INTERSECTION;
+        return;
+      }
+    }
+    result = NO_INTERSECTION;
+  }
+
+  protected int computeIntersect(
+                Coordinate p1, Coordinate p2,
+                Coordinate q1, Coordinate q2  ) {
+    isProper = false;
+
+    // first try a fast test to see if the envelopes of the lines intersect
+    if (! Envelope.intersects(p1, p2, q1, q2))
+      return NO_INTERSECTION;
+
+    // for each endpoint, compute which side of the other segment it lies
+    // if both endpoints lie on the same side of the other segment,
+    // the segments do not intersect
+    int Pq1 = CGAlgorithms.orientationIndex(p1, p2, q1);
+    int Pq2 = CGAlgorithms.orientationIndex(p1, p2, q2);
+
+    if ((Pq1>0 && Pq2>0) || (Pq1<0 && Pq2<0)) {
+      return NO_INTERSECTION;
+    }
+
+    int Qp1 = CGAlgorithms.orientationIndex(q1, q2, p1);
+    int Qp2 = CGAlgorithms.orientationIndex(q1, q2, p2);
+
+    if ((Qp1>0 && Qp2>0) || (Qp1<0 && Qp2<0)) {
+        return NO_INTERSECTION;
+    }
+
+    boolean collinear = Pq1 == 0
+         && Pq2 == 0
+         && Qp1 == 0
+         && Qp2 == 0;
+    if (collinear) {
+      return computeCollinearIntersection(p1, p2, q1, q2);
+    }
+    
+    /**
+     * At this point we know that there is a single intersection point
+     * (since the lines are not collinear).
+     */
+    
+    /**
+     *  Check if the intersection is an endpoint. If it is, copy the endpoint as
+     *  the intersection point. Copying the point rather than computing it
+     *  ensures the point has the exact value, which is important for
+     *  robustness. It is sufficient to simply check for an endpoint which is on
+     *  the other line, since at this point we know that the inputLines must
+     *  intersect.
+     */
+    if (Pq1 == 0 || Pq2 == 0 || Qp1 == 0 || Qp2 == 0) {
+      isProper = false;
+      
+      /**
+       * Check for two equal endpoints.  
+       * This is done explicitly rather than by the orientation tests
+       * below in order to improve robustness.
+       * 
+       * [An example where the orientation tests fail to be consistent is
+       * the following (where the true intersection is at the shared endpoint
+       * POINT (19.850257749638203 46.29709338043669)
+       * 
+       * LINESTRING ( 19.850257749638203 46.29709338043669, 20.31970698357233 46.76654261437082 ) 
+       * and 
+       * LINESTRING ( -48.51001596420236 -22.063180333403878, 19.850257749638203 46.29709338043669 )
+       * 
+       * which used to produce the INCORRECT result: (20.31970698357233, 46.76654261437082, NaN)
+       * 
+       */
+      if (p1.equals2D(q1) 
+      		|| p1.equals2D(q2)) {
+      	intPt[0] = p1;
+      }
+      else if (p2.equals2D(q1) 
+      		|| p2.equals2D(q2)) {
+      	intPt[0] = p2;
+      }
+      
+      /**
+       * Now check to see if any endpoint lies on the interior of the other segment.
+       */
+      else if (Pq1 == 0) {
+        intPt[0] = new Coordinate(q1);
+      }
+      else if (Pq2 == 0) {
+        intPt[0] = new Coordinate(q2);
+      }
+      else if (Qp1 == 0) {
+        intPt[0] = new Coordinate(p1);
+      }
+      else if (Qp2 == 0) {
+        intPt[0] = new Coordinate(p2);
+      }
+    }
+    else {
+      isProper = true;
+      intPt[0] = intersection(p1, p2, q1, q2);
+    }
+    return POINT_INTERSECTION;
+  }
+
+  private int computeCollinearIntersection(Coordinate p1, Coordinate p2,
+      Coordinate q1, Coordinate q2) {
+    boolean p1q1p2 = Envelope.intersects(p1, p2, q1);
+    boolean p1q2p2 = Envelope.intersects(p1, p2, q2);
+    boolean q1p1q2 = Envelope.intersects(q1, q2, p1);
+    boolean q1p2q2 = Envelope.intersects(q1, q2, p2);
+
+    if (p1q1p2 && p1q2p2) {
+      intPt[0] = q1;
+      intPt[1] = q2;
+      return COLLINEAR_INTERSECTION;
+    }
+    if (q1p1q2 && q1p2q2) {
+      intPt[0] = p1;
+      intPt[1] = p2;
+      return COLLINEAR_INTERSECTION;
+    }
+    if (p1q1p2 && q1p1q2) {
+      intPt[0] = q1;
+      intPt[1] = p1;
+      return q1.equals(p1) && !p1q2p2 && !q1p2q2 ? POINT_INTERSECTION : COLLINEAR_INTERSECTION;
+    }
+    if (p1q1p2 && q1p2q2) {
+      intPt[0] = q1;
+      intPt[1] = p2;
+      return q1.equals(p2) && !p1q2p2 && !q1p1q2 ? POINT_INTERSECTION : COLLINEAR_INTERSECTION;
+    }
+    if (p1q2p2 && q1p1q2) {
+      intPt[0] = q2;
+      intPt[1] = p1;
+      return q2.equals(p1) && !p1q1p2 && !q1p2q2 ? POINT_INTERSECTION : COLLINEAR_INTERSECTION;
+    }
+    if (p1q2p2 && q1p2q2) {
+      intPt[0] = q2;
+      intPt[1] = p2;
+      return q2.equals(p2) && !p1q1p2 && !q1p1q2 ? POINT_INTERSECTION : COLLINEAR_INTERSECTION;
+    }
+    return NO_INTERSECTION;
+  }
+
+  /**
+   * This method computes the actual value of the intersection point.
+   * To obtain the maximum precision from the intersection calculation,
+   * the coordinates are normalized by subtracting the minimum
+   * ordinate values (in absolute value).  This has the effect of
+   * removing common significant digits from the calculation to
+   * maintain more bits of precision.
+   */
+  private Coordinate intersection(
+    Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2)
+  {
+    Coordinate intPt = intersectionWithNormalization(p1, p2, q1, q2);
+  	// testing only
+//    Coordinate intPt = safeHCoordinateIntersection(p1, p2, q1, q2);
+
+    /**
+     * Due to rounding it can happen that the computed intersection is
+     * outside the envelopes of the input segments.  Clearly this
+     * is inconsistent. 
+     * This code checks this condition and forces a more reasonable answer
+     * 
+     * MD - May 4 2005 - This is still a problem.  Here is a failure case:
+     *
+     * LINESTRING (2089426.5233462777 1180182.3877339689, 2085646.6891757075 1195618.7333999649)
+     * LINESTRING (1889281.8148903656 1997547.0560044837, 2259977.3672235999 483675.17050843034)
+     * int point = (2097408.2633752143,1144595.8008114607)
+     * 
+     * MD - Dec 14 2006 - This does not seem to be a failure case any longer
+     */
+    if (! isInSegmentEnvelopes(intPt)) {
+//      System.out.println("Intersection outside segment envelopes: " + intPt);
+//      System.out.println("Segments: " + this);
+      // compute a safer result
+      intPt = CentralEndpointIntersector.getIntersection(p1, p2, q1, q2);
+//      System.out.println("Snapped to " + intPt);
+    }
+
+    if (precisionModel != null) {
+      precisionModel.makePrecise(intPt);
+    }
+
+    return intPt;
+  }
+
+  private Coordinate intersectionWithNormalization(
+    Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2)
+    {
+      Coordinate n1 = new Coordinate(p1);
+      Coordinate n2 = new Coordinate(p2);
+      Coordinate n3 = new Coordinate(q1);
+      Coordinate n4 = new Coordinate(q2);
+      Coordinate normPt = new Coordinate();
+      normalizeToEnvCentre(n1, n2, n3, n4, normPt);
+
+      Coordinate intPt = safeHCoordinateIntersection(n1, n2, n3, n4);
+
+      intPt.x += normPt.x;
+      intPt.y += normPt.y;
+      
+      return intPt;
+  }
+  
+  /**
+   * Computes a segment intersection using homogeneous coordinates.
+   * Round-off error can cause the raw computation to fail, 
+   * (usually due to the segments being approximately parallel).
+   * If this happens, a reasonable approximation is computed instead.
+   * 
+   * @param p1 a segment endpoint
+   * @param p2 a segment endpoint
+   * @param q1 a segment endpoint
+   * @param q2 a segment endpoint
+   * @return the computed intersection point
+   */
+  private Coordinate safeHCoordinateIntersection(Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2)
+  {
+    Coordinate intPt = null;
+    try {
+      intPt = HCoordinate.intersection(p1, p2, q1, q2);
+    }
+    catch (NotRepresentableException e) {
+//    	System.out.println("Not calculable: " + this);
+      // compute an approximate result
+      intPt = CentralEndpointIntersector.getIntersection(p1, p2, q1, q2);
+ //     System.out.println("Snapped to " + intPt);
+    }
+    return intPt;
+  }
+
+  /**
+   * Normalize the supplied coordinates to
+   * so that the midpoint of their intersection envelope
+   * lies at the origin.
+   *
+   * @param n00
+   * @param n01
+   * @param n10
+   * @param n11
+   * @param normPt
+   */
+  private void normalizeToEnvCentre(
+    Coordinate n00,
+    Coordinate n01,
+    Coordinate n10,
+    Coordinate n11,
+    Coordinate normPt)
+  {
+    double minX0 = n00.x < n01.x ? n00.x : n01.x;
+    double minY0 = n00.y < n01.y ? n00.y : n01.y;
+    double maxX0 = n00.x > n01.x ? n00.x : n01.x;
+    double maxY0 = n00.y > n01.y ? n00.y : n01.y;
+
+    double minX1 = n10.x < n11.x ? n10.x : n11.x;
+    double minY1 = n10.y < n11.y ? n10.y : n11.y;
+    double maxX1 = n10.x > n11.x ? n10.x : n11.x;
+    double maxY1 = n10.y > n11.y ? n10.y : n11.y;
+
+    double intMinX = minX0 > minX1 ? minX0 : minX1;
+    double intMaxX = maxX0 < maxX1 ? maxX0 : maxX1;
+    double intMinY = minY0 > minY1 ? minY0 : minY1;
+    double intMaxY = maxY0 < maxY1 ? maxY0 : maxY1;
+
+    double intMidX = (intMinX + intMaxX) / 2.0;
+    double intMidY = (intMinY + intMaxY) / 2.0;
+    normPt.x = intMidX;
+    normPt.y = intMidY;
+
+    /*
+    // equilavalent code using more modular but slower method
+    Envelope env0 = new Envelope(n00, n01);
+    Envelope env1 = new Envelope(n10, n11);
+    Envelope intEnv = env0.intersection(env1);
+    Coordinate intMidPt = intEnv.centre();
+
+    normPt.x = intMidPt.x;
+    normPt.y = intMidPt.y;
+    */
+
+    n00.x -= normPt.x;    n00.y -= normPt.y;
+    n01.x -= normPt.x;    n01.y -= normPt.y;
+    n10.x -= normPt.x;    n10.y -= normPt.y;
+    n11.x -= normPt.x;    n11.y -= normPt.y;
+  }
+
+  /**
+   * Test whether a point lies in the envelopes of both input segments.
+   * A correctly computed intersection point should return <code>true</code>
+   * for this test.
+   * Since this test is for debugging purposes only, no attempt is
+   * made to optimize the envelope test.
+   *
+   * @return <code>true</code> if the input point lies within both input segment envelopes
+   */
+  private boolean isInSegmentEnvelopes(Coordinate intPt)
+  {
+    Envelope env0 = new Envelope(inputLines[0][0], inputLines[0][1]);
+    Envelope env1 = new Envelope(inputLines[1][0], inputLines[1][1]);
+    return env0.contains(intPt) && env1.contains(intPt);
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/locate/IndexedPointInAreaLocator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/locate/IndexedPointInAreaLocator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/locate/IndexedPointInAreaLocator.java	(revision 28000)
@@ -0,0 +1,156 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm.locate;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.algorithm.RayCrossingCounter;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.LineSegment;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geom.Polygonal;
+import com.vividsolutions.jts.geom.util.LinearComponentExtracter;
+import com.vividsolutions.jts.index.ItemVisitor;
+import com.vividsolutions.jts.index.intervalrtree.SortedPackedIntervalRTree;
+
+/**
+ * Determines the {@link Location} of {@link Coordinate}s relative to
+ * a {@link Polygonal} geometry, using indexing for efficiency.
+ * This algorithm is suitable for use in cases where
+ * many points will be tested against a given area.
+ * 
+ * @author Martin Davis
+ *
+ */
+public class IndexedPointInAreaLocator 
+  implements PointOnGeometryLocator
+{
+  private IntervalIndexedGeometry index;
+  
+  /**
+   * Creates a new locator for a given {@link Geometry}
+   * @param g the Geometry to locate in
+   */
+  public IndexedPointInAreaLocator(Geometry g)
+  {
+    if (! (g instanceof Polygonal))
+      throw new IllegalArgumentException("Argument must be Polygonal");
+    buildIndex(g);
+  }
+  
+  private void buildIndex(Geometry g)
+  {
+    index = new IntervalIndexedGeometry(g);
+  }
+    
+  /**
+   * Determines the {@link Location} of a point in an areal {@link Geometry}.
+   * 
+   * @param p the point to test
+   * @return the location of the point in the geometry  
+   */
+  public int locate(Coordinate p)
+  {
+    RayCrossingCounter rcc = new RayCrossingCounter(p);
+    
+    SegmentVisitor visitor = new SegmentVisitor(rcc);
+    index.query(p.y, p.y, visitor);
+  
+    /*
+     // MD - slightly slower alternative
+    List segs = index.query(p.y, p.y);
+    countSegs(rcc, segs);
+    */
+    
+    return rcc.getLocation();
+  }
+  
+  private static class SegmentVisitor
+    implements ItemVisitor
+  {
+    private RayCrossingCounter counter;
+    
+    public SegmentVisitor(RayCrossingCounter counter)
+    {
+      this.counter = counter;
+    }
+    
+    public void visitItem(Object item)
+    {
+      LineSegment seg = (LineSegment) item;
+      counter.countSegment(seg.getCoordinate(0), seg.getCoordinate(1));
+    }
+  }
+  
+  private static class IntervalIndexedGeometry
+  {
+    private SortedPackedIntervalRTree index= new SortedPackedIntervalRTree();
+
+    public IntervalIndexedGeometry(Geometry geom)
+    {
+      init(geom);
+    }
+    
+    private void init(Geometry geom)
+    {
+      List lines = LinearComponentExtracter.getLines(geom);
+      for (Iterator i = lines.iterator(); i.hasNext(); ) {
+        LineString line = (LineString) i.next();
+        Coordinate[] pts = line.getCoordinates();
+        addLine(pts);
+      }
+    }
+    
+    private void addLine(Coordinate[] pts)
+    {
+      for (int i = 1; i < pts.length; i++) {
+        LineSegment seg = new LineSegment(pts[i-1], pts[i]);
+        double min = Math.min(seg.p0.y, seg.p1.y);
+        double max = Math.max(seg.p0.y, seg.p1.y);
+        index.insert(min, max, seg);
+      }
+    }
+        
+    public void query(double min, double max, ItemVisitor visitor)
+    {
+      index.query(min, max, visitor);
+    }
+  }
+
+}
+
+
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/locate/PointOnGeometryLocator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/locate/PointOnGeometryLocator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/locate/PointOnGeometryLocator.java	(revision 28000)
@@ -0,0 +1,54 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm.locate;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.Location;
+
+/**
+ * An interface for classes which determine the {@link Location} of
+ * points in a {@link Geometry}.
+ * 
+ * @author Martin Davis
+ */
+public interface PointOnGeometryLocator 
+{
+  /**
+   * Determines the {@link Location} of a point in the {@link Geometry}.
+   * 
+   * @param p the point to test
+   * @return the location of the point in the geometry  
+   */
+	int locate(Coordinate p);
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/locate/SimplePointInAreaLocator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/locate/SimplePointInAreaLocator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/locate/SimplePointInAreaLocator.java	(revision 28000)
@@ -0,0 +1,136 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.algorithm.locate;
+
+import java.util.Iterator;
+
+import com.vividsolutions.jts.algorithm.CGAlgorithms;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryCollectionIterator;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geom.Polygonal;
+
+/**
+ * Computes the location of points
+ * relative to a {@link Polygonal} {@link Geometry},
+ * using a simple O(n) algorithm.
+ * This algorithm is suitable for use in cases where
+ * only one or a few points will be tested against a given area.
+ * <p>
+ * The algorithm used is only guaranteed to return correct results
+ * for points which are <b>not</b> on the boundary of the Geometry.
+ *
+ * @version 1.7
+ */
+public class SimplePointInAreaLocator
+	implements PointOnGeometryLocator
+{
+
+  /**
+   * Determines the {@link Location} of a point in an areal {@link Geometry}.
+   * Currently this will never return a value of BOUNDARY.  
+   * 
+   * @param p the point to test
+   * @param geom the areal geometry to test
+   * @return the Location of the point in the geometry  
+   */
+  public static int locate(Coordinate p, Geometry geom)
+  {
+    if (geom.isEmpty()) return Location.EXTERIOR;
+
+    if (containsPoint(p, geom))
+      return Location.INTERIOR;
+    return Location.EXTERIOR;
+  }
+
+  private static boolean containsPoint(Coordinate p, Geometry geom)
+  {
+    if (geom instanceof Polygon) {
+      return containsPointInPolygon(p, (Polygon) geom);
+    }
+    else if (geom instanceof GeometryCollection) {
+      Iterator geomi = new GeometryCollectionIterator(geom);
+      while (geomi.hasNext()) {
+        Geometry g2 = (Geometry) geomi.next();
+        if (g2 != geom)
+          if (containsPoint(p, g2))
+            return true;
+      }
+    }
+    return false;
+  }
+
+  public static boolean containsPointInPolygon(Coordinate p, Polygon poly)
+  {
+    if (poly.isEmpty()) return false;
+    LinearRing shell = (LinearRing) poly.getExteriorRing();
+    if (! isPointInRing(p, shell)) return false;
+    // now test if the point lies in or on the holes
+    for (int i = 0; i < poly.getNumInteriorRing(); i++) {
+      LinearRing hole = (LinearRing) poly.getInteriorRingN(i);
+      if (isPointInRing(p, hole)) return false;
+    }
+    return true;
+  }
+
+  /**
+   * Determines whether a point lies in a LinearRing,
+   * using the ring envelope to short-circuit if possible.
+   * 
+   * @param p the point to test
+   * @param ring a linear ring
+   * @return true if the point lies inside the ring
+   */
+  private static boolean isPointInRing(Coordinate p, LinearRing ring)
+  {
+  	// short-circuit if point is not in ring envelope
+  	if (! ring.getEnvelopeInternal().intersects(p))
+  		return false;
+  	return CGAlgorithms.isPointInRing(p, ring.getCoordinates());
+  }
+
+	private Geometry geom;
+
+	public SimplePointInAreaLocator(Geometry geom) {
+		this.geom = geom;
+	}
+
+	public int locate(Coordinate p) {
+		return SimplePointInAreaLocator.locate(p, geom);
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/locate/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/locate/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/locate/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Classes to determine the topological location of points in geometries.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/algorithm/package.html	(revision 28000)
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Contains classes and interfaces implementing fundamental computational geometry algorithms.
+
+<H3>Robustness</H3>
+
+Geometrical algorithms involve a combination of combinatorial and numerical computation.  As with
+all numerical computation using finite-precision numbers, the algorithms chosen are susceptible to
+problems of robustness.  A robustness problem occurs when a numerical calculation produces an
+incorrect answer for some inputs due to round-off errors.  Robustness problems are especially
+serious in geometric computation, since they can result in errors during topology building.
+<P>
+There are many approaches to dealing with the problem of robustness in geometrical computation.
+Not surprisingly, most robust algorithms are substantially more complex and less performant than
+the non-robust versions.  Fortunately, JTS is sensitive to robustness problems in only a few key
+functions (such as line intersection and the point-in-polygon test).  There are efficient robust
+algorithms available for these functions, and these algorithms are implemented in JTS.
+
+<H3>Computational Performance</H3>
+
+Runtime performance is an important consideration for a production-quality implementation of
+geometric algorithms.  The most computationally intensive algorithm used in JTS is intersection
+detection.  JTS methods need to determine both all intersection between the line segments in a
+single Geometry (self-intersection) and all intersections between the line segments of two different
+Geometries.
+<P>
+The obvious naive algorithm for intersection detection (comparing every segment with every other)
+has unacceptably slow performance.  There is a large literature of faster algorithms for intersection
+detection.  Unfortunately, many of them involve substantial code complexity.  JTS tries to balance code
+simplicity with performance gains.  It uses some simple techniques to produce substantial performance
+gains for common types of input data.
+
+
+<h2>Package Specification</h2>
+
+<ul>
+  <li>Java Topology Suite Technical Specifications
+  <li><A HREF="http://www.opengis.org/techno/specs.htm">
+      OpenGIS Simple Features Specification for SQL</A>
+</ul>
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Coordinate.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Coordinate.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Coordinate.java	(revision 28000)
@@ -0,0 +1,245 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import java.io.Serializable;
+
+import com.vividsolutions.jts.util.Assert;
+
+
+/**
+ * A lightweight class used to store coordinates
+ * on the 2-dimensional Cartesian plane.
+ * It is distinct from {@link Point}, which is a subclass of {@link Geometry}. 
+ * Unlike objects of type {@link Point} (which contain additional
+ * information such as an envelope, a precision model, and spatial reference
+ * system information), a <code>Coordinate</code> only contains ordinate values
+ * and accessor methods. <P>
+ *
+ * <code>Coordinate</code>s are two-dimensional points, with an additional Z-ordinate. 
+ * JTS does not support any operations on the Z-ordinate except the basic accessor functions. 
+ * If an Z-ordinate value is not specified or not defined, 
+ * constructed coordinates have a Z-ordinate of <code>NaN</code>
+ * (which is also the value of <code>NULL_ORDINATE</code>).  
+ * The standard comparison functions ignore the Z-ordinate.
+ *
+ *@version 1.7
+ */
+public class Coordinate implements Comparable<Coordinate>, Cloneable, Serializable {
+  private static final long serialVersionUID = 6683108902428366910L;
+  
+  /**
+   * The value used to indicate a null or missing ordinate value.
+   * In particular, used for the value of ordinates for dimensions 
+   * greater than the defined dimension of a coordinate.
+   */
+  public static final double NULL_ORDINATE = Double.NaN;
+  /**
+   *  The x-coordinate.
+   */
+  public double x;
+  /**
+   *  The y-coordinate.
+   */
+  public double y;
+  /**
+   *  The z-coordinate.
+   */
+  public double z;
+
+  /**
+   *  Constructs a <code>Coordinate</code> at (x,y,z).
+   *
+   *@param  x  the x-value
+   *@param  y  the y-value
+   *@param  z  the z-value
+   */
+  public Coordinate(double x, double y, double z) {
+    this.x = x;
+    this.y = y;
+    this.z = z;
+  }
+
+  /**
+   *  Constructs a <code>Coordinate</code> at (0,0,NaN).
+   */
+  public Coordinate() {
+    this(0.0, 0.0);
+  }
+
+  /**
+   *  Constructs a <code>Coordinate</code> having the same (x,y,z) values as
+   *  <code>other</code>.
+   *
+   *@param  c  the <code>Coordinate</code> to copy.
+   */
+  public Coordinate(Coordinate c) {
+    this(c.x, c.y, c.z);
+  }
+
+  /**
+   *  Constructs a <code>Coordinate</code> at (x,y,NaN).
+   *
+   *@param  x  the x-value
+   *@param  y  the y-value
+   */
+  public Coordinate(double x, double y) {
+    this(x, y, NULL_ORDINATE);
+  }
+
+  /**
+   *  Returns whether the planar projections of the two <code>Coordinate</code>s
+   *  are equal.
+   *
+   *@param  other  a <code>Coordinate</code> with which to do the 2D comparison.
+   *@return        <code>true</code> if the x- and y-coordinates are equal; the
+   *      z-coordinates do not have to be equal.
+   */
+  public boolean equals2D(Coordinate other) {
+    if (x != other.x) {
+      return false;
+    }
+
+    if (y != other.y) {
+      return false;
+    }
+
+    return true;
+  }
+
+  /**
+   *  Returns <code>true</code> if <code>other</code> has the same values for
+   *  the x and y ordinates.
+   *  Since Coordinates are 2.5D, this routine ignores the z value when making the comparison.
+   *
+   *@param  other  a <code>Coordinate</code> with which to do the comparison.
+   *@return        <code>true</code> if <code>other</code> is a <code>Coordinate</code>
+   *      with the same values for the x and y ordinates.
+   */
+  public boolean equals(Object other) {
+    if (!(other instanceof Coordinate)) {
+      return false;
+    }
+    return equals2D((Coordinate) other);
+  }
+
+  /**
+   *  Compares this {@link Coordinate} with the specified {@link Coordinate} for order.
+   *  This method ignores the z value when making the comparison.
+   *  Returns:
+   *  <UL>
+   *    <LI> -1 : this.x < other.x || ((this.x == other.x) && (this.y <
+   *    other.y))
+   *    <LI> 0 : this.x == other.x && this.y = other.y
+   *    <LI> 1 : this.x > other.x || ((this.x == other.x) && (this.y > other.y))
+   *
+   *  </UL>
+   *  Note: This method assumes that ordinate values
+   * are valid numbers.  NaN values are not handled correctly.
+   *
+   *@param  o  the <code>Coordinate</code> with which this <code>Coordinate</code>
+   *      is being compared
+   *@return    -1, zero, or 1 as this <code>Coordinate</code>
+   *      is less than, equal to, or greater than the specified <code>Coordinate</code>
+   */
+  public int compareTo(Coordinate o) {
+    Coordinate other = o;
+
+    if (x < other.x) return -1;
+    if (x > other.x) return 1;
+    if (y < other.y) return -1;
+    if (y > other.y) return 1;
+    return 0;
+  }
+
+  /**
+   *  Returns a <code>String</code> of the form <I>(x,y,z)</I> .
+   *
+   *@return    a <code>String</code> of the form <I>(x,y,z)</I>
+   */
+  public String toString() {
+    return "(" + x + ", " + y + ", " + z + ")";
+  }
+
+  public Object clone() {
+    try {
+      Coordinate coord = (Coordinate) super.clone();
+
+      return coord; // return the clone
+    } catch (CloneNotSupportedException e) {
+      Assert.shouldNeverReachHere(
+          "this shouldn't happen because this class is Cloneable");
+
+      return null;
+    }
+  }
+
+  /**
+   * Computes the 2-dimensional Euclidean distance to another location.
+   * The Z-ordinate is ignored.
+   * 
+   * @param p a point
+   * @return the 2-dimensional Euclidean distance between the locations
+   */
+  public double distance(Coordinate p) {
+    double dx = x - p.x;
+    double dy = y - p.y;
+
+    return Math.sqrt(dx * dx + dy * dy);
+  }
+
+  /**
+   * Gets a hashcode for this coordinate.
+   * 
+   * @return a hashcode for this coordinate
+   */
+  public int hashCode() {
+    //Algorithm from Effective Java by Joshua Bloch [Jon Aquino]
+    int result = 17;
+    result = 37 * result + hashCode(x);
+    result = 37 * result + hashCode(y);
+    return result;
+  }
+
+  /**
+   * Computes a hash code for a double value, using the algorithm from
+   * Joshua Bloch's book <i>Effective Java"</i>
+   * 
+   * @return a hashcode for the double value
+   */
+  public static int hashCode(double x) {
+    long f = Double.doubleToLongBits(x);
+    return (int)(f^(f>>>32));
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateArrays.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateArrays.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateArrays.java	(revision 28000)
@@ -0,0 +1,174 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import java.util.Collection;
+
+/**
+ * Useful utility functions for handling Coordinate arrays
+ *
+ * @version 1.7
+ */
+public class CoordinateArrays {
+
+  private final static Coordinate[] coordArrayType = new Coordinate[0];
+
+
+  /**
+   * Determines which orientation of the {@link Coordinate} array
+   * is (overall) increasing.
+   * In other words, determines which end of the array is "smaller"
+   * (using the standard ordering on {@link Coordinate}).
+   * Returns an integer indicating the increasing direction.
+   * If the sequence is a palindrome, it is defined to be
+   * oriented in a positive direction.
+   *
+   * @param pts the array of Coordinates to test
+   * @return <code>1</code> if the array is smaller at the start
+   * or is a palindrome,
+   * <code>-1</code> if smaller at the end
+   */
+  public static int increasingDirection(Coordinate[] pts) {
+    for (int i = 0; i < pts.length / 2; i++) {
+      int j = pts.length - 1 - i;
+      // skip equal points on both ends
+      int comp = pts[i].compareTo(pts[j]);
+      if (comp != 0)
+        return comp;
+    }
+    // array must be a palindrome - defined to be in positive direction
+    return 1;
+  }
+
+  /**
+   * Converts the given Collection of Coordinates into a Coordinate array.
+   */
+  public static Coordinate[] toCoordinateArray(Collection<Coordinate> coordList)
+  {
+    return coordList.toArray(coordArrayType);
+  }
+
+  /**
+   * Returns whether #equals returns true for any two consecutive Coordinates
+   * in the given array.
+   */
+  public static boolean hasRepeatedPoints(Coordinate[] coord)
+  {
+    for (int i = 1; i < coord.length; i++) {
+      if (coord[i - 1].equals(coord[i]) ) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * If the coordinate array argument has repeated points,
+   * constructs a new array containing no repeated points.
+   * Otherwise, returns the argument.
+   * @see #hasRepeatedPoints(Coordinate[])
+   */
+  public static Coordinate[] removeRepeatedPoints(Coordinate[] coord)
+  {
+    if (! hasRepeatedPoints(coord)) return coord;
+    CoordinateList coordList = new CoordinateList(coord, false);
+    return coordList.toCoordinateArray();
+  }
+
+  /**
+   * Reverses the coordinates in an array in-place.
+   */
+  public static void reverse(Coordinate[] coord)
+  {
+    int last = coord.length - 1;
+    int mid = last / 2;
+    for (int i = 0; i <= mid; i++) {
+      Coordinate tmp = coord[i];
+      coord[i] = coord[last - i];
+      coord[last - i] = tmp;
+    }
+  }
+
+  /**
+   *  Returns the minimum coordinate, using the usual lexicographic comparison.
+   *
+   *@param  coordinates  the array to search
+   *@return              the minimum coordinate in the array, found using <code>compareTo</code>
+   *@see Coordinate#compareTo(Object)
+   */
+  public static Coordinate minCoordinate(Coordinate[] coordinates)
+  {
+    Coordinate minCoord = null;
+    for (int i = 0; i < coordinates.length; i++) {
+      if (minCoord == null || minCoord.compareTo(coordinates[i]) > 0) {
+        minCoord = coordinates[i];
+      }
+    }
+    return minCoord;
+  }
+  /**
+   *  Shifts the positions of the coordinates until <code>firstCoordinate</code>
+   *  is first.
+   *
+   *@param  coordinates      the array to rearrange
+   *@param  firstCoordinate  the coordinate to make first
+   */
+  public static void scroll(Coordinate[] coordinates, Coordinate firstCoordinate) {
+    int i = indexOf(firstCoordinate, coordinates);
+    if (i < 0) return;
+    Coordinate[] newCoordinates = new Coordinate[coordinates.length];
+    System.arraycopy(coordinates, i, newCoordinates, 0, coordinates.length - i);
+    System.arraycopy(coordinates, 0, newCoordinates, coordinates.length - i, i);
+    System.arraycopy(newCoordinates, 0, coordinates, 0, coordinates.length);
+  }
+
+  /**
+   *  Returns the index of <code>coordinate</code> in <code>coordinates</code>.
+   *  The first position is 0; the second, 1; etc.
+   *
+   *@param  coordinate   the <code>Coordinate</code> to search for
+   *@param  coordinates  the array to search
+   *@return              the position of <code>coordinate</code>, or -1 if it is
+   *      not found
+   */
+  public static int indexOf(Coordinate coordinate, Coordinate[] coordinates) {
+    for (int i = 0; i < coordinates.length; i++) {
+      if (coordinate.equals(coordinates[i])) {
+        return i;
+      }
+    }
+    return -1;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateFilter.java	(revision 28000)
@@ -0,0 +1,59 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+
+/**
+ *  <code>Geometry</code> classes support the concept of applying a
+ *  coordinate filter to every coordinate in the <code>Geometry</code>. A
+ *  coordinate filter can either record information about each coordinate or
+ *  change the coordinate in some way. Coordinate filters implement the
+ *  interface <code>CoordinateFilter</code>. (<code>CoordinateFilter</code> is
+ *  an example of the Gang-of-Four Visitor pattern). Coordinate filters can be
+ *  used to implement such things as coordinate transformations, centroid and
+ *  envelope computation, and many other functions.
+ *
+ *@version 1.7
+ */
+public interface CoordinateFilter {
+
+  /**
+   *  Performs an operation with or on <code>coord</code>.
+   *
+   *@param  coord  a <code>Coordinate</code> to which the filter is applied.
+   */
+  void filter(Coordinate coord);
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateList.java	(revision 28000)
@@ -0,0 +1,198 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import java.util.ArrayList;
+
+/**
+ * A list of {@link Coordinate}s, which may
+ * be set to prevent repeated coordinates from occuring in the list.
+ *
+ *
+ * @version 1.7
+ */
+public class CoordinateList
+  extends ArrayList
+{
+  //With contributions from Markus Schaber [schabios@logi-track.com]
+  //[Jon Aquino 2004-03-25]
+  private final static Coordinate[] coordArrayType = new Coordinate[0];
+
+  /**
+   * Constructs a new list without any coordinates
+   */
+  public CoordinateList()
+  { super();
+  }
+
+  /**
+   * Constructs a new list from an array of Coordinates, allowing repeated points.
+   * (I.e. this constructor produces a {@link CoordinateList} with exactly the same set of points
+   * as the input array.)
+   * 
+   * @param coord the initial coordinates
+   */
+  public CoordinateList(Coordinate[] coord)
+  {
+  	ensureCapacity(coord.length);
+    add(coord, true);
+  }
+
+  /**
+   * Constructs a new list from an array of Coordinates,
+   * allowing caller to specify if repeated points are to be removed.
+   *
+   * @param coord the array of coordinates to load into the list
+   * @param allowRepeated if <code>false</code>, repeated points are removed
+   */
+  public CoordinateList(Coordinate[] coord, boolean allowRepeated)
+  {
+  	ensureCapacity(coord.length);
+    add(coord, allowRepeated);
+  }
+
+
+  /** 
+   * Adds an array of coordinates to the list.
+   * @param coord The coordinates
+   * @param allowRepeated if set to false, repeated coordinates are collapsed
+   * @param direction if false, the array is added in reverse order
+   * @return true (as by general collection contract)
+   */
+  public boolean add(Coordinate[] coord, boolean allowRepeated, boolean direction)
+  {
+    if (direction) {
+      for (int i = 0; i < coord.length; i++) {
+        add(coord[i], allowRepeated);
+      }
+    }
+    else {
+      for (int i = coord.length - 1; i >= 0; i--) {
+        add(coord[i], allowRepeated);
+      }
+    }
+    return true;
+  }
+
+
+  /** 
+   * Adds an array of coordinates to the list.
+   * @param coord The coordinates
+   * @param allowRepeated if set to false, repeated coordinates are collapsed
+   * @return true (as by general collection contract)
+   */
+  public boolean add(Coordinate[] coord, boolean allowRepeated)
+  {
+    add(coord, allowRepeated, true);
+    return true;
+  }
+
+
+  /**
+   * Adds a coordinate to the end of the list.
+   * 
+   * @param coord The coordinates
+   * @param allowRepeated if set to false, repeated coordinates are collapsed
+   */
+  public void add(Coordinate coord, boolean allowRepeated)
+  {
+    // don't add duplicate coordinates
+    if (! allowRepeated) {
+      if (size() >= 1) {
+        Coordinate last = (Coordinate) get(size() - 1);
+        if (last.equals2D(coord)) return;
+      }
+    }
+    super.add(coord);
+  }
+
+  /**
+   * Inserts the specified coordinate at the specified position in this list.
+   * 
+   * @param i the position at which to insert
+   * @param coord the coordinate to insert
+   * @param allowRepeated if set to false, repeated coordinates are collapsed
+   */
+  public void add(int i, Coordinate coord, boolean allowRepeated)
+  {
+    // don't add duplicate coordinates
+    if (! allowRepeated) {
+      int size = size();
+      if (size > 0) {
+        if (i > 0) {
+          Coordinate prev = (Coordinate) get(i - 1);
+          if (prev.equals2D(coord)) return;
+        }
+        if (i < size) {
+          Coordinate next = (Coordinate) get(i);
+          if (next.equals2D(coord)) return;
+        }
+      }
+    }
+    super.add(i, coord);
+  }
+
+
+  /**
+   * Ensure this coordList is a ring, by adding the start point if necessary
+   */
+  public void closeRing()
+  {
+    if (size() > 0)
+      add(new Coordinate((Coordinate) get(0)), false);
+  }
+
+  /** Returns the Coordinates in this collection.
+   *
+   * @return the coordinates
+   */
+  public Coordinate[] toCoordinateArray()
+  {
+    return (Coordinate[]) toArray(coordArrayType);
+  }
+
+  /**
+   * Returns a deep copy of this <tt>CoordinateList</tt> instance.
+   *
+   * @return a clone of this <tt>CoordinateList</tt> instance
+   */
+  public Object clone() {
+      CoordinateList clone = (CoordinateList) super.clone();
+      for (int i = 0; i < this.size(); i++) {
+          clone.add(i, ((Coordinate) this.get(i)).clone());
+      }
+      return clone;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequence.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequence.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequence.java	(revision 28000)
@@ -0,0 +1,178 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import com.vividsolutions.jts.geom.impl.CoordinateArraySequenceFactory;
+
+/**
+ * The internal representation of a list of coordinates inside a Geometry.
+ * <p>
+ * This allows Geometries to store their
+ * points using something other than the JTS {@link Coordinate} class. 
+ * For example, a storage-efficient implementation
+ * might store coordinate sequences as an array of x's
+ * and an array of y's. 
+ * Or a custom coordinate class might support extra attributes like M-values.
+ * <p>
+ * Implementing a custom coordinate storage structure
+ * requires implementing the {@link CoordinateSequence} and
+ * {@link CoordinateSequenceFactory} interfaces. 
+ * To use the custom CoordinateSequence, create a
+ * new {@link GeometryFactory} parameterized by the CoordinateSequenceFactory
+ * The {@link GeometryFactory} can then be used to create new {@link Geometry}s.
+ * The new Geometries
+ * will use the custom CoordinateSequence implementation.
+ * <p>
+ * For an example, see the code for
+ * {@link ExtendedCoordinateExample}.
+ *
+ * @see CoordinateArraySequenceFactory
+ * @see PackedCoordinateSequenceFactory
+ * @see ExtendedCoordinateExample
+ *
+ * @version 1.7
+ */
+public interface CoordinateSequence
+    extends Cloneable
+{
+  /**
+   * Standard ordinate index values
+   */
+  int X = 0;
+  int Y = 1;
+  int Z = 2;
+
+  /**
+   * Returns the dimension (number of ordinates in each coordinate)
+   * for this sequence.
+   *
+   * @return the dimension of the sequence.
+   */
+  int getDimension();
+
+  /**
+   * Returns (possibly a copy of) the i'th coordinate in this sequence.
+   * Whether or not the Coordinate returned is the actual underlying
+   * Coordinate or merely a copy depends on the implementation.
+   * <p>
+   * Note that in the future the semantics of this method may change
+   * to guarantee that the Coordinate returned is always a copy.
+   * Callers should not to assume that they can modify a CoordinateSequence by
+   * modifying the object returned by this method.
+   *
+   * @param i the index of the coordinate to retrieve
+   * @return the i'th coordinate in the sequence
+   */
+  Coordinate getCoordinate(int i);
+
+
+  /**
+   * Copies the i'th coordinate in the sequence to the supplied
+   * {@link Coordinate}.  Only the first two dimensions are copied.
+   *
+   * @param index the index of the coordinate to copy
+   * @param coord a {@link Coordinate} to receive the value
+   */
+  void getCoordinate(int index, Coordinate coord);
+
+  /**
+   * Returns ordinate X (0) of the specified coordinate.
+   *
+   * @param index
+   * @return the value of the X ordinate in the index'th coordinate
+   */
+  double getX(int index);
+
+  /**
+   * Returns ordinate Y (1) of the specified coordinate.
+   *
+   * @param index
+   * @return the value of the Y ordinate in the index'th coordinate
+   */
+  double getY(int index);
+
+  /**
+   * Returns the ordinate of a coordinate in this sequence.
+   * Ordinate indices 0 and 1 are assumed to be X and Y.
+   * Ordinates indices greater than 1 have user-defined semantics
+   * (for instance, they may contain other dimensions or measure values).
+   *
+   * @param index  the coordinate index in the sequence
+   * @param ordinateIndex the ordinate index in the coordinate (in range [0, dimension-1])
+   */
+  double getOrdinate(int index, int ordinateIndex);
+
+  /**
+   * Returns the number of coordinates in this sequence.
+   * @return the size of the sequence
+   */
+  int size();
+
+  /**
+   * Sets the value for a given ordinate of a coordinate in this sequence.
+   *
+   * @param index  the coordinate index in the sequence
+   * @param ordinateIndex the ordinate index in the coordinate (in range [0, dimension-1])
+   * @param value  the new ordinate value
+   */
+  void setOrdinate(int index, int ordinateIndex, double value);
+
+  /**
+   * Returns (possibly copies of) the Coordinates in this collection.
+   * Whether or not the Coordinates returned are the actual underlying
+   * Coordinates or merely copies depends on the implementation. Note that
+   * if this implementation does not store its data as an array of Coordinates,
+   * this method will incur a performance penalty because the array needs to
+   * be built from scratch.
+   *
+   * @return a array of coordinates containing the point values in this sequence
+   */
+  Coordinate[] toCoordinateArray();
+
+  /**
+   * Expands the given {@link Envelope} to include the coordinates in the sequence.
+   * Allows implementing classes to optimize access to coordinate values.
+   *
+   * @param env the envelope to expand
+   * @return a ref to the expanded envelope
+   */
+  Envelope expandEnvelope(Envelope env);
+
+  /**
+   * Returns a deep copy of this collection.
+   * Called by Geometry#clone.
+   *
+   * @return a copy of the coordinate sequence containing copies of all points
+   */
+  Object clone();
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequenceComparator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequenceComparator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequenceComparator.java	(revision 28000)
@@ -0,0 +1,120 @@
+package com.vividsolutions.jts.geom;
+
+import java.util.Comparator;
+
+/**
+ * Compares two {@link CoordinateSequence}s.
+ * For sequences of the same dimension, the ordering is lexicographic.
+ * Otherwise, lower dimensions are sorted before higher.
+ * The dimensions compared can be limited; if this is done
+ * ordinate dimensions above the limit will not be compared.
+ * <p>
+ * If different behaviour is required for comparing size, dimension, or
+ * coordinate values, any or all methods can be overridden.
+ *
+ */
+public class CoordinateSequenceComparator
+	implements Comparator<Object>
+{
+  /**
+   * Compare two <code>double</code>s, allowing for NaN values.
+   * NaN is treated as being less than any valid number.
+   *
+   * @param a a <code>double</code>
+   * @param b a <code>double</code>
+   * @return -1, 0, or 1 depending on whether a is less than, equal to or greater than b
+   */
+  public static int compare(double a, double b)
+  {
+    if (a < b) return -1;
+    if (a > b) return 1;
+
+    if (Double.isNaN(a)) {
+      if (Double.isNaN(b)) return 0;
+      return -1;
+    }
+
+    if (Double.isNaN(b)) return 1;
+    return 0;
+  }
+
+  /**
+   * The number of dimensions to test
+   */
+  protected int dimensionLimit;
+
+  /**
+   * Creates a comparator which will test all dimensions.
+   */
+  public CoordinateSequenceComparator()
+  {
+    dimensionLimit = Integer.MAX_VALUE;
+  }
+
+  /**
+   * Compares two {@link CoordinateSequence}s for relative order.
+   *
+   * @param o1 a {@link CoordinateSequence}
+   * @param o2 a {@link CoordinateSequence}
+   * @return -1, 0, or 1 depending on whether o1 is less than, equal to, or greater than o2
+   */
+  public int compare(Object o1, Object o2)
+  {
+    CoordinateSequence s1 = (CoordinateSequence) o1;
+    CoordinateSequence s2 = (CoordinateSequence) o2;
+
+    int size1 = s1.size();
+    int size2 = s2.size();
+
+    int dim1 = s1.getDimension();
+    int dim2 = s2.getDimension();
+
+    int minDim = dim1;
+    if (dim2 < minDim)
+      minDim = dim2;
+    boolean dimLimited = false;
+    if (dimensionLimit <= minDim) {
+      minDim = dimensionLimit;
+      dimLimited = true;
+    }
+
+    // lower dimension is less than higher
+    if (! dimLimited) {
+      if (dim1 < dim2) return -1;
+      if (dim1 > dim2) return 1;
+    }
+
+    // lexicographic ordering of point sequences
+    int i = 0;
+    while (i < size1 && i < size2) {
+      int ptComp = compareCoordinate(s1, s2, i, minDim);
+      if (ptComp != 0) return ptComp;
+      i++;
+    }
+    if (i < size1) return 1;
+    if (i < size2) return -1;
+
+    return 0;
+  }
+
+  /**
+   * Compares the same coordinate of two {@link CoordinateSequence}s
+   * along the given number of dimensions.
+   *
+   * @param s1 a {@link CoordinateSequence}
+   * @param s2 a {@link CoordinateSequence}
+   * @param i the index of the coordinate to test
+   * @param dimension the number of dimensiosn to test
+   * @return -1, 0, or 1 depending on whether s1[i] is less than, equal to, or greater than s2[i]
+   */
+  protected int compareCoordinate(CoordinateSequence s1, CoordinateSequence s2, int i, int dimension)
+  {
+    for (int d = 0; d < dimension; d++) {
+      double ord1 = s1.getOrdinate(i, d);
+      double ord2 = s2.getOrdinate(i, d);
+      int comp = compare(ord1, ord2);
+      if (comp != 0) return comp;
+    }
+    return 0;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequenceFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequenceFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequenceFactory.java	(revision 28000)
@@ -0,0 +1,67 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+/**
+ * A factory to create concrete instances of {@link CoordinateSequence}s.
+ * Used to configure {@link GeometryFactory}s
+ * to provide specific kinds of CoordinateSequences.
+ *
+ * @version 1.7
+ */
+public interface CoordinateSequenceFactory
+{
+
+  /**
+   * Returns a {@link CoordinateSequence} based on the given array.
+   * Whether the array is copied or simply referenced
+   * is implementation-dependent.
+   * This method must handle null arguments by creating an empty sequence.
+   *
+   * @param coordinates the coordinates
+   */
+  CoordinateSequence create(Coordinate[] coordinates);
+
+
+  /**
+   * Creates a {@link CoordinateSequence} of the specified size and dimension.
+   * For this to be useful, the {@link CoordinateSequence} implementation must
+   * be mutable.
+   *
+   * @param size the number of coordinates in the sequence
+   * @param dimension the dimension of the coordinates in the sequence (if user-specifiable,
+   * otherwise ignored)
+   */
+  CoordinateSequence create(int size, int dimension);
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequenceFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequenceFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequenceFilter.java	(revision 28000)
@@ -0,0 +1,89 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+
+/**
+ *  Interface for classes which provide operations that
+ *  can be applied to the coordinates in a {@link CoordinateSequence}. 
+ *  A CoordinateSequence filter can either record information about each coordinate or
+ *  change the coordinate in some way. CoordinateSequence filters can be
+ *  used to implement such things as coordinate transformations, centroid and
+ *  envelope computation, and many other functions.
+ *  For maximum efficiency, the execution of filters can be short-circuited.
+ *  {@link Geometry} classes support the concept of applying a
+ *  <code>CoordinateSequenceFilter</code> to each 
+ *  {@link CoordinateSequence}s they contain. 
+ *  <p>
+ *  <code>CoordinateSequenceFilter</code> is
+ *  an example of the Gang-of-Four Visitor pattern. 
+ *
+ *@see Geometry#apply(CoordinateSequenceFilter)
+ *@author Martin Davis
+ *@version 1.7
+ */
+public interface CoordinateSequenceFilter 
+{
+  /**
+   * Performs an operation on a coordinate in a {@link CoordinateSequence}.
+   *
+   *@param seq  the <code>CoordinateSequence</code> to which the filter is applied
+   *@param i the index of the coordinate to apply the filter to
+   */
+  void filter(CoordinateSequence seq, int i);
+  
+  /**
+   * Reports whether the application of this filter can be terminated.
+   * Once this method returns <tt>false</tt>, it should 
+   * continue to return <tt>false</tt> on every subsequent call.
+   * 
+   * @return true if the application of this filter can be terminated.
+   */
+  boolean isDone();
+  
+  /**
+   * Reports whether the execution of this filter
+   * has modified the coordinates of the geometry.
+   * If so, {@link Geometry#geometryChanged} will be executed
+   * after this filter has finished being executed.
+   * <p>
+   * Most filters can simply return a constant value reflecting
+   * whether they are able to change the coordinates.
+   * 
+   * @return true if this filter has changed the coordinates of the geometry
+   */
+  boolean isGeometryChanged();
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequences.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequences.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/CoordinateSequences.java	(revision 28000)
@@ -0,0 +1,74 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+
+/**
+ * Utility functions for manipulating {@link CoordinateSequence}s
+ *
+ * @version 1.7
+ */
+public class CoordinateSequences {
+
+  /**
+   * Reverses the coordinates in a sequence in-place.
+   */
+  public static void reverse(CoordinateSequence seq)
+  {
+    int last = seq.size() - 1;
+    int mid = last / 2;
+    for (int i = 0; i <= mid; i++) {
+      swap(seq, i, last - i);
+    }
+  }
+
+  /**
+   * Swaps two coordinates in a sequence.
+   *
+   * @param seq
+   * @param i
+   * @param j
+   */
+  public static void swap(CoordinateSequence seq, int i, int j)
+  {
+    if (i == j) return;
+    for (int dim = 0; dim < seq.getDimension(); dim++) {
+      double tmp = seq.getOrdinate(i, dim);
+      seq.setOrdinate(i, dim, seq.getOrdinate(j, dim));
+      seq.setOrdinate(j, dim, tmp);
+    }
+  }
+  
+  
+  
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/DefaultCoordinateSequence.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/DefaultCoordinateSequence.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/DefaultCoordinateSequence.java	(revision 28000)
@@ -0,0 +1,198 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+import java.io.Serializable;
+
+/**
+ * The CoordinateSequence implementation that Geometries use by default. In
+ * this implementation, Coordinates returned by #toArray and #get are live --
+ * parties that change them are actually changing the
+ * DefaultCoordinateSequence's underlying data.
+ *
+ * @version 1.7
+ *
+ * @deprecated no longer used
+ */
+class DefaultCoordinateSequence
+    implements CoordinateSequence, Serializable
+{
+  //With contributions from Markus Schaber [schabios@logi-track.com] 2004-03-26
+  private static final long serialVersionUID = -915438501601840650L;
+  private Coordinate[] coordinates;
+
+  /**
+   * Constructs a DefaultCoordinateSequence based on the given array (the
+   * array is not copied).
+   *
+   * @param coordinates the coordinate array that will be referenced.
+   */
+  public DefaultCoordinateSequence(Coordinate[] coordinates) {
+    if (Geometry.hasNullElements(coordinates)) {
+      throw new IllegalArgumentException("Null coordinate");
+    }
+    this.coordinates = coordinates;
+  }
+
+
+  /**
+   * Constructs a sequence of a given size, populated
+   * with new {@link Coordinate}s.
+   *
+   * @param size the size of the sequence to create
+   */
+  public DefaultCoordinateSequence(int size) {
+    coordinates = new Coordinate[size];
+    for (int i = 0; i < size; i++) {
+      coordinates[i] = new Coordinate();
+    }
+  }
+
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequence#getDimension()
+   */
+  public int getDimension() { return 3; }
+
+  /**
+   * Get the Coordinate with index i.
+   *
+   * @param i
+   *                  the index of the coordinate
+   * @return the requested Coordinate instance
+   */
+  public Coordinate getCoordinate(int i) {
+    return coordinates[i];
+  }
+
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequence#getX(int)
+   */
+  public void getCoordinate(int index, Coordinate coord) {
+    coord.x = coordinates[index].x;
+    coord.y = coordinates[index].y;
+  }
+
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequence#getX(int)
+   */
+  public double getX(int index) {
+    return coordinates[index].x;
+  }
+
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequence#getY(int)
+   */
+  public double getY(int index) {
+    return coordinates[index].y;
+  }
+
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequence#getOrdinate(int, int)
+   */
+  public double getOrdinate(int index, int ordinateIndex)
+  {
+    switch (ordinateIndex) {
+      case CoordinateSequence.X:  return coordinates[index].x;
+      case CoordinateSequence.Y:  return coordinates[index].y;
+      case CoordinateSequence.Z:  return coordinates[index].z;
+    }
+    return Double.NaN;
+  }
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequence#setOrdinate(int, int, double)
+   */
+  public void setOrdinate(int index, int ordinateIndex, double value)
+  {
+    switch (ordinateIndex) {
+      case CoordinateSequence.X:  coordinates[index].x = value; break;
+      case CoordinateSequence.Y:  coordinates[index].y = value; break;
+      case CoordinateSequence.Z:  coordinates[index].z = value; break;
+    }
+  }
+  /**
+   * Creates a deep copy of the Object
+   *
+   * @return The deep copy
+   */
+  public Object clone() {
+    Coordinate[] cloneCoordinates = new Coordinate[size()];
+    for (int i = 0; i < coordinates.length; i++) {
+      cloneCoordinates[i] = (Coordinate) coordinates[i].clone();
+    }
+    return new DefaultCoordinateSequence(cloneCoordinates);
+  }
+  /**
+   * Returns the size of the coordinate sequence
+   *
+   * @return the number of coordinates
+   */
+  public int size() {
+    return coordinates.length;
+  }
+  /**
+   * This method exposes the internal Array of Coordinate Objects
+   *
+   * @return the Coordinate[] array.
+   */
+  public Coordinate[] toCoordinateArray() {
+    return coordinates;
+  }
+
+  public Envelope expandEnvelope(Envelope env)
+  {
+    for (int i = 0; i < coordinates.length; i++ ) {
+      env.expandToInclude(coordinates[i]);
+    }
+    return env;
+  }
+
+  /**
+   * Returns the string Representation of the coordinate array
+   *
+   * @return The string
+   */
+  public String toString() {
+    if (coordinates.length > 0) {
+      StringBuffer strBuf = new StringBuffer(17 * coordinates.length);
+      strBuf.append('(');
+      strBuf.append(coordinates[0]);
+      for (int i = 1; i < coordinates.length; i++) {
+        strBuf.append(", ");
+        strBuf.append(coordinates[i]);
+      }
+      strBuf.append(')');
+      return strBuf.toString();
+    } else {
+      return "()";
+    }
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/DefaultCoordinateSequenceFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/DefaultCoordinateSequenceFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/DefaultCoordinateSequenceFactory.java	(revision 28000)
@@ -0,0 +1,86 @@
+
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import java.io.Serializable;
+
+/**
+ * Creates CoordinateSequences represented as an array of {@link Coordinate}s.
+ *
+ * @version 1.7
+ *
+ * @deprecated no longer used
+ */
+public class DefaultCoordinateSequenceFactory
+    implements CoordinateSequenceFactory, Serializable
+{
+  private static final long serialVersionUID = -4099577099607551657L;
+  private static final DefaultCoordinateSequenceFactory instanceObject = new DefaultCoordinateSequenceFactory();
+
+  public DefaultCoordinateSequenceFactory() {
+  }
+
+  private Object readResolve() {
+  	// see http://www.javaworld.com/javaworld/javatips/jw-javatip122.html
+    return DefaultCoordinateSequenceFactory.instance();
+  }
+
+  /**
+   * Returns the singleton instance of DefaultCoordinateSequenceFactory
+   */
+  public static DefaultCoordinateSequenceFactory instance() {
+    return instanceObject;
+  }
+
+
+
+  /**
+   * Returns a DefaultCoordinateSequence based on the given array (the array is
+   * not copied).
+   *
+   * @param coordinates
+   *            the coordinates, which may not be null nor contain null
+   *            elements
+   */
+  public CoordinateSequence create(Coordinate[] coordinates) {
+    return new DefaultCoordinateSequence(coordinates);
+  }
+
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequenceFactory#create(int, int)
+   */
+  public CoordinateSequence create(int size, int dimension) {
+    return new DefaultCoordinateSequence(size);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Dimension.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Dimension.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Dimension.java	(revision 28000)
@@ -0,0 +1,134 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+/**
+ * Provides constants representing the dimensions of a point, a curve and a surface.
+ * Also provides constants representing the dimensions of the empty geometry and
+ * non-empty geometries, and the wildcard constant {@link #DONTCARE} meaning "any dimension".
+ * These constants are used as the entries in {@link IntersectionMatrix}s.
+ * 
+ * @version 1.7
+ */
+public class Dimension {
+
+  /**
+   *  Dimension value of a point (0).
+   */
+  public final static int P = 0;
+
+  /**
+   *  Dimension value of a curve (1).
+   */
+  public final static int L = 1;
+
+  /**
+   *  Dimension value of a surface (2).
+   */
+  public final static int A = 2;
+
+  /**
+   *  Dimension value of the empty geometry (-1).
+   */
+  public final static int FALSE = -1;
+
+  /**
+   *  Dimension value of non-empty geometries (= {P, L, A}).
+   */
+  public final static int TRUE = -2;
+
+  /**
+   *  Dimension value for any dimension (= {FALSE, TRUE}).
+   */
+  public final static int DONTCARE = -3;
+
+  /**
+   *  Converts the dimension value to a dimension symbol, for example, <code>TRUE => 'T'</code>
+   *  .
+   *
+   *@param  dimensionValue  a number that can be stored in the <code>IntersectionMatrix</code>
+   *      . Possible values are <code>{TRUE, FALSE, DONTCARE, 0, 1, 2}</code>.
+   *@return                 a character for use in the string representation of
+   *      an <code>IntersectionMatrix</code>. Possible values are <code>{T, F, * , 0, 1, 2}</code>
+   *      .
+   */
+  public static char toDimensionSymbol(int dimensionValue) {
+    switch (dimensionValue) {
+      case FALSE:
+        return 'F';
+      case TRUE:
+        return 'T';
+      case DONTCARE:
+        return '*';
+      case P:
+        return '0';
+      case L:
+        return '1';
+      case A:
+        return '2';
+    }
+    throw new IllegalArgumentException("Unknown dimension value: " + dimensionValue);
+  }
+
+  /**
+   *  Converts the dimension symbol to a dimension value, for example, <code>'*' => DONTCARE</code>
+   *  .
+   *
+   *@param  dimensionSymbol  a character for use in the string representation of
+   *      an <code>IntersectionMatrix</code>. Possible values are <code>{T, F, * , 0, 1, 2}</code>
+   *      .
+   *@return a number that can be stored in the <code>IntersectionMatrix</code>
+   *      . Possible values are <code>{TRUE, FALSE, DONTCARE, 0, 1, 2}</code>.
+   */
+  public static int toDimensionValue(char dimensionSymbol) {
+    switch (Character.toUpperCase(dimensionSymbol)) {
+      case 'F':
+        return FALSE;
+      case 'T':
+        return TRUE;
+      case '*':
+        return DONTCARE;
+      case '0':
+        return P;
+      case '1':
+        return L;
+      case '2':
+        return A;
+    }
+    throw new IllegalArgumentException("Unknown dimension symbol: " + dimensionSymbol);
+  }
+}
+
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Envelope.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Envelope.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Envelope.java	(revision 28000)
@@ -0,0 +1,666 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import java.io.Serializable;
+
+/**
+ *  Defines a rectangular region of the 2D coordinate plane.
+ *  It is often used to represent the bounding box of a {@link Geometry},
+ *  e.g. the minimum and maximum x and y values of the {@link Coordinate}s.
+ *  <p>
+ *  Note that Envelopes support infinite or half-infinite regions, by using the values of
+ *  <code>Double.POSITIVE_INFINITY</code> and <code>Double.NEGATIVE_INFINITY</code>.
+ *  <p>
+ *  When Envelope objects are created or initialized,
+ *  the supplies extent values are automatically sorted into the correct order.
+ *
+ *@version 1.7
+ */
+public class Envelope
+    implements Serializable
+{
+    private static final long serialVersionUID = 5873921885273102420L;
+
+    public int hashCode() {
+        //Algorithm from Effective Java by Joshua Bloch [Jon Aquino]
+        int result = 17;
+        result = 37 * result + Coordinate.hashCode(minx);
+        result = 37 * result + Coordinate.hashCode(maxx);
+        result = 37 * result + Coordinate.hashCode(miny);
+        result = 37 * result + Coordinate.hashCode(maxy);
+        return result;
+    }
+
+  /**
+   * Test the point q to see whether it intersects the Envelope defined by p1-p2
+   * @param p1 one extremal point of the envelope
+   * @param p2 another extremal point of the envelope
+   * @param q the point to test for intersection
+   * @return <code>true</code> if q intersects the envelope p1-p2
+   */
+  public static boolean intersects(Coordinate p1, Coordinate p2, Coordinate q)
+  {
+	//OptimizeIt shows that Math#min and Math#max here are a bottleneck.
+    //Replace with direct comparisons. [Jon Aquino]
+    if (((q.x >= (p1.x < p2.x ? p1.x : p2.x)) && (q.x <= (p1.x > p2.x ? p1.x : p2.x))) &&
+        ((q.y >= (p1.y < p2.y ? p1.y : p2.y)) && (q.y <= (p1.y > p2.y ? p1.y : p2.y)))) {
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Test the envelope defined by p1-p2 for intersection
+   * with the envelope defined by q1-q2
+   * @param p1 one extremal point of the envelope P
+   * @param p2 another extremal point of the envelope P
+   * @param q1 one extremal point of the envelope Q
+   * @param q2 another extremal point of the envelope Q
+   * @return <code>true</code> if Q intersects P
+   */
+  public static boolean intersects(Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2)
+  {
+    double minq = Math.min(q1.x, q2.x);
+    double maxq = Math.max(q1.x, q2.x);
+    double minp = Math.min(p1.x, p2.x);
+    double maxp = Math.max(p1.x, p2.x);
+
+    if( minp > maxq )
+        return false;
+    if( maxp < minq )
+        return false;
+
+    minq = Math.min(q1.y, q2.y);
+    maxq = Math.max(q1.y, q2.y);
+    minp = Math.min(p1.y, p2.y);
+    maxp = Math.max(p1.y, p2.y);
+
+    if( minp > maxq )
+        return false;
+    if( maxp < minq )
+        return false;
+    return true;
+  }
+
+  /**
+   *  the minimum x-coordinate
+   */
+  private double minx;
+
+  /**
+   *  the maximum x-coordinate
+   */
+  private double maxx;
+
+  /**
+   *  the minimum y-coordinate
+   */
+  private double miny;
+
+  /**
+   *  the maximum y-coordinate
+   */
+  private double maxy;
+
+  /**
+   *  Creates a null <code>Envelope</code>.
+   */
+  public Envelope() {
+    init();
+  }
+
+  /**
+   *  Creates an <code>Envelope</code> for a region defined by maximum and minimum values.
+   *
+   *@param  x1  the first x-value
+   *@param  x2  the second x-value
+   *@param  y1  the first y-value
+   *@param  y2  the second y-value
+   */
+  public Envelope(double x1, double x2, double y1, double y2)
+  {
+    init(x1, x2, y1, y2);
+  }
+
+  /**
+   *  Creates an <code>Envelope</code> for a region defined by two Coordinates.
+   *
+   *@param  p1  the first Coordinate
+   *@param  p2  the second Coordinate
+   */
+  public Envelope(Coordinate p1, Coordinate p2)
+  {
+    init(p1.x, p2.x, p1.y, p2.y);
+  }
+
+  /**
+   *  Create an <code>Envelope</code> from an existing Envelope.
+   *
+   *@param  env  the Envelope to initialize from
+   */
+  public Envelope(Envelope env)
+  {
+    init(env);
+  }
+
+  /**
+   *  Initialize to a null <code>Envelope</code>.
+   */
+  public void init()
+  {
+    setToNull();
+  }
+
+  /**
+   *  Initialize an <code>Envelope</code> for a region defined by maximum and minimum values.
+   *
+   *@param  x1  the first x-value
+   *@param  x2  the second x-value
+   *@param  y1  the first y-value
+   *@param  y2  the second y-value
+   */
+  public void init(double x1, double x2, double y1, double y2)
+  {
+    if (x1 < x2) {
+      minx = x1;
+      maxx = x2;
+    }
+    else {
+      minx = x2;
+      maxx = x1;
+    }
+    if (y1 < y2) {
+      miny = y1;
+      maxy = y2;
+    }
+    else {
+      miny = y2;
+      maxy = y1;
+    }
+  }
+
+  /**
+   *  Initialize an <code>Envelope</code> to a region defined by two Coordinates.
+   *
+   *@param  p1  the first Coordinate
+   *@param  p2  the second Coordinate
+   */
+  public void init(Coordinate p1, Coordinate p2)
+  {
+    init(p1.x, p2.x, p1.y, p2.y);
+  }
+
+  /**
+   *  Initialize an <code>Envelope</code> from an existing Envelope.
+   *
+   *@param  env  the Envelope to initialize from
+   */
+  public void init(Envelope env)
+  {
+    this.minx = env.minx;
+    this.maxx = env.maxx;
+    this.miny = env.miny;
+    this.maxy = env.maxy;
+  }
+
+
+  /**
+   *  Makes this <code>Envelope</code> a "null" envelope, that is, the envelope
+   *  of the empty geometry.
+   */
+  public void setToNull() {
+    minx = 0;
+    maxx = -1;
+    miny = 0;
+    maxy = -1;
+  }
+
+  /**
+   *  Returns <code>true</code> if this <code>Envelope</code> is a "null"
+   *  envelope.
+   *
+   *@return    <code>true</code> if this <code>Envelope</code> is uninitialized
+   *      or is the envelope of the empty geometry.
+   */
+  public boolean isNull() {
+    return maxx < minx;
+  }
+
+  /**
+   *  Returns the difference between the maximum and minimum x values.
+   *
+   *@return    max x - min x, or 0 if this is a null <code>Envelope</code>
+   */
+  public double getWidth() {
+    if (isNull()) {
+      return 0;
+    }
+    return maxx - minx;
+  }
+
+  /**
+   *  Returns the difference between the maximum and minimum y values.
+   *
+   *@return    max y - min y, or 0 if this is a null <code>Envelope</code>
+   */
+  public double getHeight() {
+    if (isNull()) {
+      return 0;
+    }
+    return maxy - miny;
+  }
+
+  /**
+   *  Returns the <code>Envelope</code>s minimum x-value. min x > max x
+   *  indicates that this is a null <code>Envelope</code>.
+   *
+   *@return    the minimum x-coordinate
+   */
+  public double getMinX() {
+    return minx;
+  }
+
+  /**
+   *  Returns the <code>Envelope</code>s maximum x-value. min x > max x
+   *  indicates that this is a null <code>Envelope</code>.
+   *
+   *@return    the maximum x-coordinate
+   */
+  public double getMaxX() {
+    return maxx;
+  }
+
+  /**
+   *  Returns the <code>Envelope</code>s minimum y-value. min y > max y
+   *  indicates that this is a null <code>Envelope</code>.
+   *
+   *@return    the minimum y-coordinate
+   */
+  public double getMinY() {
+    return miny;
+  }
+
+  /**
+   *  Returns the <code>Envelope</code>s maximum y-value. min y > max y
+   *  indicates that this is a null <code>Envelope</code>.
+   *
+   *@return    the maximum y-coordinate
+   */
+  public double getMaxY() {
+    return maxy;
+  }
+
+  /**
+   * Gets the area of this envelope.
+   * 
+   * @return the area of the envelope
+   * @return 0.0 if the envelope is null
+   */
+  public double getArea()
+  {
+    return getWidth() * getHeight();
+  }
+    
+  /**
+   *  Enlarges this <code>Envelope</code> so that it contains
+   *  the given {@link Coordinate}. 
+   *  Has no effect if the point is already on or within the envelope.
+   *
+   *@param  p  the Coordinate to expand to include
+   */
+  public void expandToInclude(Coordinate p)
+  {
+    expandToInclude(p.x, p.y);
+  }
+
+  /**
+   * Expands this envelope by a given distance in all directions.
+   * Both positive and negative distances are supported.
+   *
+   * @param distance the distance to expand the envelope
+   */
+  public void expandBy(double distance)
+  {
+    expandBy(distance, distance);
+  }
+
+  /**
+   * Expands this envelope by a given distance in all directions.
+   * Both positive and negative distances are supported.
+   *
+   * @param deltaX the distance to expand the envelope along the the X axis
+   * @param deltaY the distance to expand the envelope along the the Y axis
+   */
+  public void expandBy(double deltaX, double deltaY)
+  {
+    if (isNull()) return;
+
+    minx -= deltaX;
+    maxx += deltaX;
+    miny -= deltaY;
+    maxy += deltaY;
+
+    // check for envelope disappearing
+    if (minx > maxx || miny > maxy)
+      setToNull();
+  }
+
+  /**
+   *  Enlarges this <code>Envelope</code> so that it contains
+   *  the given point. 
+   *  Has no effect if the point is already on or within the envelope.
+   *
+   *@param  x  the value to lower the minimum x to or to raise the maximum x to
+   *@param  y  the value to lower the minimum y to or to raise the maximum y to
+   */
+  public void expandToInclude(double x, double y) {
+    if (isNull()) {
+      minx = x;
+      maxx = x;
+      miny = y;
+      maxy = y;
+    }
+    else {
+      if (x < minx) {
+        minx = x;
+      }
+      if (x > maxx) {
+        maxx = x;
+      }
+      if (y < miny) {
+        miny = y;
+      }
+      if (y > maxy) {
+        maxy = y;
+      }
+    }
+  }
+
+  /**
+   *  Enlarges this <code>Envelope</code> so that it contains
+   *  the <code>other</code> Envelope. 
+   *  Has no effect if <code>other</code> is wholly on or
+   *  within the envelope.
+   *
+   *@param  other  the <code>Envelope</code> to expand to include
+   */
+  public void expandToInclude(Envelope other) {
+    if (other.isNull()) {
+      return;
+    }
+    if (isNull()) {
+      minx = other.getMinX();
+      maxx = other.getMaxX();
+      miny = other.getMinY();
+      maxy = other.getMaxY();
+    }
+    else {
+      if (other.minx < minx) {
+        minx = other.minx;
+      }
+      if (other.maxx > maxx) {
+        maxx = other.maxx;
+      }
+      if (other.miny < miny) {
+        miny = other.miny;
+      }
+      if (other.maxy > maxy) {
+        maxy = other.maxy;
+      }
+    }
+  }
+
+  /**
+   * Computes the coordinate of the centre of this envelope (as long as it is non-null
+   *
+   * @return the centre coordinate of this envelope
+   * <code>null</code> if the envelope is null
+   */
+  public Coordinate centre() {
+    if (isNull()) return null;
+    return new Coordinate(
+        (getMinX() + getMaxX()) / 2.0,
+        (getMinY() + getMaxY()) / 2.0);
+  }
+
+  /**
+   * Computes the intersection of two {@link Envelope}s.
+   *
+   * @param env the envelope to intersect with
+   * @return a new Envelope representing the intersection of the envelopes (this will be
+   * the null envelope if either argument is null, or they do not intersect
+   */
+  public Envelope intersection(Envelope env)
+  {
+    if (isNull() || env.isNull() || ! intersects(env)) return new Envelope();
+
+    double intMinX = minx > env.minx ? minx : env.minx;
+    double intMinY = miny > env.miny ? miny : env.miny;
+    double intMaxX = maxx < env.maxx ? maxx : env.maxx;
+    double intMaxY = maxy < env.maxy ? maxy : env.maxy;
+    return new Envelope(intMinX, intMaxX, intMinY, intMaxY);
+  }
+
+
+
+  /**
+   *  Check if the region defined by <code>other</code>
+   *  overlaps (intersects) the region of this <code>Envelope</code>.
+   *
+   *@param  other  the <code>Envelope</code> which this <code>Envelope</code> is
+   *          being checked for overlapping
+   *@return        <code>true</code> if the <code>Envelope</code>s overlap
+   */
+  public boolean intersects(Envelope other) {
+      if (isNull() || other.isNull()) { return false; }
+    return !(other.minx > maxx ||
+        other.maxx < minx ||
+        other.miny > maxy ||
+        other.maxy < miny);
+  }
+
+
+  /**
+   *  Check if the point <code>p</code>
+   *  overlaps (lies inside) the region of this <code>Envelope</code>.
+   *
+   *@param  p  the <code>Coordinate</code> to be tested
+   *@return        <code>true</code> if the point overlaps this <code>Envelope</code>
+   */
+  public boolean intersects(Coordinate p) {
+    return intersects(p.x, p.y);
+  }
+
+  /**
+   *  Check if the point <code>(x, y)</code>
+   *  overlaps (lies inside) the region of this <code>Envelope</code>.
+   *
+   *@param  x  the x-ordinate of the point
+   *@param  y  the y-ordinate of the point
+   *@return        <code>true</code> if the point overlaps this <code>Envelope</code>
+   */
+  public boolean intersects(double x, double y) {
+  	if (isNull()) return false;
+    return ! (x > maxx ||
+        x < minx ||
+        y > maxy ||
+        y < miny);
+  }
+
+  /**
+   * Tests if the <code>Envelope other</code>
+   * lies wholely inside this <code>Envelope</code> (inclusive of the boundary).
+   * <p>
+   * Note that this is <b>not</b> the same definition as the SFS <tt>contains</tt>,
+   * which would exclude the envelope boundary.
+   *
+   *@param  other the <code>Envelope</code> to check
+   *@return true if <code>other</code> is contained in this <code>Envelope</code>
+   *
+   *@see #covers(Envelope)
+   */
+  public boolean contains(Envelope other) {
+  	return covers(other);
+  }
+
+  /**
+   * Tests if the given point lies in or on the envelope.
+   * <p>
+   * Note that this is <b>not</b> the same definition as the SFS <tt>contains</tt>,
+   * which would exclude the envelope boundary.
+   *
+   *@param  p  the point which this <code>Envelope</code> is
+   *      being checked for containing
+   *@return    <code>true</code> if the point lies in the interior or
+   *      on the boundary of this <code>Envelope</code>.
+   *      
+   *@see #covers(Coordinate)
+   */
+  public boolean contains(Coordinate p) {
+    return covers(p);
+  }
+
+  /**
+   * Tests if the given point lies in or on the envelope.
+   * <p>
+   * Note that this is <b>not</b> the same definition as the SFS <tt>contains</tt>,
+   * which would exclude the envelope boundary.
+   *
+   *@param  x  the x-coordinate of the point which this <code>Envelope</code> is
+   *      being checked for containing
+   *@param  y  the y-coordinate of the point which this <code>Envelope</code> is
+   *      being checked for containing
+   *@return    <code>true</code> if <code>(x, y)</code> lies in the interior or
+   *      on the boundary of this <code>Envelope</code>.
+   *      
+   *@see #covers(double, double)
+   */
+  public boolean contains(double x, double y) {
+  	return covers(x, y);
+  }
+
+  /**
+   * Tests if the given point lies in or on the envelope.
+   *
+   *@param  x  the x-coordinate of the point which this <code>Envelope</code> is
+   *      being checked for containing
+   *@param  y  the y-coordinate of the point which this <code>Envelope</code> is
+   *      being checked for containing
+   *@return    <code>true</code> if <code>(x, y)</code> lies in the interior or
+   *      on the boundary of this <code>Envelope</code>.
+   */
+  public boolean covers(double x, double y) {
+  	if (isNull()) return false;
+    return x >= minx &&
+        x <= maxx &&
+        y >= miny &&
+        y <= maxy;
+  }
+
+  /**
+   * Tests if the given point lies in or on the envelope.
+   *
+   *@param  p  the point which this <code>Envelope</code> is
+   *      being checked for containing
+   *@return    <code>true</code> if the point lies in the interior or
+   *      on the boundary of this <code>Envelope</code>.
+   */
+  public boolean covers(Coordinate p) {
+    return covers(p.x, p.y);
+  }
+
+  /**
+   * Tests if the <code>Envelope other</code>
+   * lies wholely inside this <code>Envelope</code> (inclusive of the boundary).
+   *
+   *@param  other the <code>Envelope</code> to check
+   *@return true if this <code>Envelope</code> covers the <code>other</code> 
+   */
+  public boolean covers(Envelope other) {
+    if (isNull() || other.isNull()) { return false; }
+    return other.getMinX() >= minx &&
+        other.getMaxX() <= maxx &&
+        other.getMinY() >= miny &&
+        other.getMaxY() <= maxy;
+  }
+
+  /**
+   * Computes the distance between this and another
+   * <code>Envelope</code>.
+   * The distance between overlapping Envelopes is 0.  Otherwise, the
+   * distance is the Euclidean distance between the closest points.
+   */
+  public double distance(Envelope env)
+  {
+    if (intersects(env)) return 0;
+    
+    double dx = 0.0;
+    if (maxx < env.minx) 
+      dx = env.minx - maxx;
+    else if (minx > env.maxx) 
+      dx = minx - env.maxx;
+    
+    double dy = 0.0;
+    if (maxy < env.miny) 
+      dy = env.miny - maxy;
+    else if (miny > env.maxy) dy = miny - env.maxy;
+
+    // if either is zero, the envelopes overlap either vertically or horizontally
+    if (dx == 0.0) return dy;
+    if (dy == 0.0) return dx;
+    return Math.sqrt(dx * dx + dy * dy);
+  }
+
+  public boolean equals(Object other) {
+    if (!(other instanceof Envelope)) {
+      return false;
+    }
+    Envelope otherEnvelope = (Envelope) other;
+    if (isNull()) {
+      return otherEnvelope.isNull();
+    }
+    return maxx == otherEnvelope.getMaxX() &&
+        maxy == otherEnvelope.getMaxY() &&
+        minx == otherEnvelope.getMinX() &&
+        miny == otherEnvelope.getMinY();
+  }
+
+  public String toString()
+  {
+    return "Env[" + minx + " : " + maxx + ", " + miny + " : " + maxy + "]";
+  }
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Geometry.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Geometry.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Geometry.java	(revision 28000)
@@ -0,0 +1,1396 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+
+import com.vividsolutions.jts.algorithm.ConvexHull;
+import com.vividsolutions.jts.geom.util.GeometryCollectionMapper;
+import com.vividsolutions.jts.io.WKTWriter;
+import com.vividsolutions.jts.operation.IsSimpleOp;
+import com.vividsolutions.jts.operation.distance.DistanceOp;
+import com.vividsolutions.jts.operation.overlay.OverlayOp;
+import com.vividsolutions.jts.operation.overlay.snap.SnapIfNeededOverlayOp;
+import com.vividsolutions.jts.operation.predicate.RectangleContains;
+import com.vividsolutions.jts.operation.predicate.RectangleIntersects;
+import com.vividsolutions.jts.operation.relate.RelateOp;
+import com.vividsolutions.jts.operation.valid.IsValidOp;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * A representation of a planar, linear vector geometry.
+ * <P>
+ *
+ *  <H3>Binary Predicates</H3>
+ * Because it is not clear at this time
+ * what semantics for spatial
+ *  analysis methods involving <code>GeometryCollection</code>s would be useful,
+ *  <code>GeometryCollection</code>s are not supported as arguments to binary
+ *  predicates (other than <code>convexHull</code>) or the <code>relate</code>
+ *  method.
+ *
+ *  <H3>Overlay Methods</H3>
+ *
+ *  The overlay methods 
+ *  return the most specific class possible to represent the result. If the
+ *  result is homogeneous, a <code>Point</code>, <code>LineString</code>, or
+ *  <code>Polygon</code> will be returned if the result contains a single
+ *  element; otherwise, a <code>MultiPoint</code>, <code>MultiLineString</code>,
+ *  or <code>MultiPolygon</code> will be returned. If the result is
+ *  heterogeneous a <code>GeometryCollection</code> will be returned. <P>
+ *
+ *  Because it is not clear at this time what semantics for set-theoretic
+ *  methods involving <code>GeometryCollection</code>s would be useful,
+ * <code>GeometryCollections</code>
+ *  are not supported as arguments to the set-theoretic methods.
+ *
+ *  <H4>Representation of Computed Geometries </H4>
+ *
+ *  The SFS states that the result
+ *  of a set-theoretic method is the "point-set" result of the usual
+ *  set-theoretic definition of the operation (SFS 3.2.21.1). However, there are
+ *  sometimes many ways of representing a point set as a <code>Geometry</code>.
+ *  <P>
+ *
+ *  The SFS does not specify an unambiguous representation of a given point set
+ *  returned from a spatial analysis method. One goal of JTS is to make this
+ *  specification precise and unambiguous. JTS will use a canonical form for
+ *  <code>Geometry</code>s returned from spatial analysis methods. The canonical
+ *  form is a <code>Geometry</code> which is simple and noded:
+ *  <UL>
+ *    <LI> Simple means that the Geometry returned will be simple according to
+ *    the JTS definition of <code>isSimple</code>.
+ *    <LI> Noded applies only to overlays involving <code>LineString</code>s. It
+ *    means that all intersection points on <code>LineString</code>s will be
+ *    present as endpoints of <code>LineString</code>s in the result.
+ *  </UL>
+ *  This definition implies that non-simple geometries which are arguments to
+ *  spatial analysis methods must be subjected to a line-dissolve process to
+ *  ensure that the results are simple.
+ *
+ *  <H4> Constructed Points And The Precision Model </H4>
+ *
+ *  The results computed by the set-theoretic methods may
+ *  contain constructed points which are not present in the input <code>Geometry</code>
+ *  s. These new points arise from intersections between line segments in the
+ *  edges of the input <code>Geometry</code>s. In the general case it is not
+ *  possible to represent constructed points exactly. This is due to the fact
+ *  that the coordinates of an intersection point may contain twice as many bits
+ *  of precision as the coordinates of the input line segments. In order to
+ *  represent these constructed points explicitly, JTS must truncate them to fit
+ *  the <code>PrecisionModel</code>. <P>
+ *
+ *  Unfortunately, truncating coordinates moves them slightly. Line segments
+ *  which would not be coincident in the exact result may become coincident in
+ *  the truncated representation. This in turn leads to "topology collapses" --
+ *  situations where a computed element has a lower dimension than it would in
+ *  the exact result. <P>
+ *
+ *  When JTS detects topology collapses during the computation of spatial
+ *  analysis methods, it will throw an exception. If possible the exception will
+ *  report the location of the collapse. <P>
+ *
+ * <h3>Geometry Equality</h3>
+ * 
+ * JTS provides two ways of comparing geometries for equality: 
+ * <b>structural equality</b> and <b>topological equality</b>.
+ * 
+ * <h4>Structural Equality</h4>
+ *
+ * Structural Equality is provided by the 
+ * {@link #equalsExact(Geometry)} method.  
+ * This implements a comparison based on exact, structural pointwise
+ * equality. 
+ * The {@link #equals(Object)} is a synonym for this method, 
+ * to provide structural equality semantics for
+ * use in Java collections.
+ * It is important to note that structural pointwise equality
+ * is easily affected by things like
+ * ring order and component order.  In many situations
+ * it will be desirable to normalize geometries before
+ * comparing them (using the {@link #norm()} 
+ * or {@link #normalize()} methods).
+ * {@link #equalsNorm(Geometry)} is provided
+ * as a convenience method to compute equality over
+ * normalized geometries, but it is expensive to use.
+ * Finally, {@link #equalsExact(Geometry, double)}
+ * allows using a tolerance value for point comparison.
+ * 
+ * 
+ * <h4>Topological Equality</h4>
+ * 
+ * Topological Equality 
+ * implements the SFS definition of point-set equality
+ * defined in terms of the DE-9IM matrix.
+ * It is is provided by the 
+ * {@link #equalsTopo(Geometry)}
+ * method.  
+ * To support the SFS naming convention, the method
+ *  {@link #equals(Geometry)} is also provided as a synonym.  
+ *  However, due to the potential for confusion with {@link #equals(Geometry)}
+ *  its use is discouraged.
+ * <p>
+ *  Since #equals(Object) and #hashCode are overridden, 
+ *  Geometries can be used effectively in 
+ *  Java collections.
+ *
+ *@version 1.7
+ */
+public abstract class Geometry
+    implements Cloneable, Comparable, Serializable
+{
+  private static final long serialVersionUID = 8763622679187376702L;
+    
+  private static Class[] sortedClasses;  
+  
+  private final static GeometryComponentFilter geometryChangedFilter = new GeometryComponentFilter() {
+    public void filter(Geometry geom) {
+      geom.geometryChangedAction();
+    }
+  };
+
+  /**
+   *  The bounding box of this <code>Geometry</code>.
+   */
+  protected Envelope envelope;
+
+  /**
+   * The {@link GeometryFactory} used to create this Geometry
+   */
+  protected final GeometryFactory factory;
+
+  /**
+   * An object reference which can be used to carry ancillary data defined
+   * by the client.
+   */
+  private Object userData = null;
+
+  /**
+   * Creates a new <tt>Geometry</tt> via the specified GeometryFactory.
+   *
+   * @param factory
+   */
+  public Geometry(GeometryFactory factory) {
+    this.factory = factory;
+  }
+
+  /**
+   *  Returns the name of this object's <code>com.vivid.jts.geom</code>
+   *  interface.
+   *
+   *@return    the name of this <code>Geometry</code>s most specific <code>com.vividsolutions.jts.geom</code>
+   *      interface
+   */
+  public abstract String getGeometryType();
+
+  /**
+   *  Returns true if the array contains any non-empty <code>Geometry</code>s.
+   *
+   *@param  geometries  an array of <code>Geometry</code>s; no elements may be
+   *      <code>null</code>
+   *@return             <code>true</code> if any of the <code>Geometry</code>s
+   *      <code>isEmpty</code> methods return <code>false</code>
+   */
+  protected static boolean hasNonEmptyElements(Geometry[] geometries) {
+    for (int i = 0; i < geometries.length; i++) {
+      if (!geometries[i].isEmpty()) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   *  Returns true if the array contains any <code>null</code> elements.
+   *
+   *@param  array  an array to validate
+   *@return        <code>true</code> if any of <code>array</code>s elements are
+   *      <code>null</code>
+   */
+  protected static boolean hasNullElements(Object[] array) {
+    for (int i = 0; i < array.length; i++) {
+      if (array[i] == null) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Gets the factory which contains the context in which this geometry was created.
+   *
+   * @return the factory for this geometry
+   */
+  public GeometryFactory getFactory() {
+         return factory;
+  }
+
+  /**
+   * Gets the user data object for this geometry, if any.
+   *
+   * @return the user data object, or <code>null</code> if none set
+   */
+  public Object getUserData() {
+        return userData;
+  }
+
+  /**
+   * Returns the number of {@link Geometry}s in a {@link GeometryCollection}
+   * (or 1, if the geometry is not a collection).
+   *
+   * @return the number of geometries contained in this geometry
+   */
+  public int getNumGeometries() {
+    return 1;
+  }
+
+  /**
+   * Returns an element {@link Geometry} from a {@link GeometryCollection}
+   * (or <code>this</code>, if the geometry is not a collection).
+   *
+   * @param n the index of the geometry element
+   * @return the n'th geometry contained in this geometry
+   */
+  public Geometry getGeometryN(@SuppressWarnings("unused") int n) {
+    return this;
+  }
+
+
+  /**
+   * A simple scheme for applications to add their own custom data to a Geometry.
+   * An example use might be to add an object representing a Coordinate Reference System.
+   * <p>
+   * Note that user data objects are not present in geometries created by
+   * construction methods.
+   *
+   * @param userData an object, the semantics for which are defined by the
+   * application using this Geometry
+   */
+  public void setUserData(Object userData) {
+        this.userData = userData;
+  }
+
+
+  /**
+   *  Returns the <code>PrecisionModel</code> used by the <code>Geometry</code>.
+   *
+   *@return    the specification of the grid of allowable points, for this
+   *      <code>Geometry</code> and all other <code>Geometry</code>s
+   */
+  public PrecisionModel getPrecisionModel() {
+    return factory.getPrecisionModel();
+  }
+
+  /**
+   *  Returns a vertex of this <code>Geometry</code>
+   *  (usually, but not necessarily, the first one).
+   *  The returned coordinate should not be assumed
+   *  to be an actual Coordinate object used in
+   *  the internal representation.
+   *
+   *@return    a {@link Coordinate} which is a vertex of this <code>Geometry</code>.
+   *@return null if this Geometry is empty
+   */
+  public abstract Coordinate getCoordinate();
+  
+  /**
+   *  Returns an array containing the values of all the vertices for 
+   *  this geometry.
+   *  If the geometry is a composite, the array will contain all the vertices
+   *  for the components, in the order in which the components occur in the geometry.
+   *  <p>
+   *  In general, the array cannot be assumed to be the actual internal 
+   *  storage for the vertices.  Thus modifying the array
+   *  may not modify the geometry itself. 
+   *  Use the {@link CoordinateSequence#setOrdinate} method
+   *  (possibly on the components) to modify the underlying data.
+   *  If the coordinates are modified, 
+   *  {@link #geometryChanged} must be called afterwards.
+   *
+   *@return    the vertices of this <code>Geometry</code>
+   *@see #geometryChanged
+   *@see CoordinateSequence#setOrdinate
+   */
+  public abstract Coordinate[] getCoordinates();
+
+  /**
+   *  Returns the count of this <code>Geometry</code>s vertices. The <code>Geometry</code>
+   *  s contained by composite <code>Geometry</code>s must be
+   *  Geometry's; that is, they must implement <code>getNumPoints</code>
+   *
+   *@return    the number of vertices in this <code>Geometry</code>
+   */
+  public abstract int getNumPoints();
+
+  /**
+   * Tests whether this {@link Geometry} is simple.
+   * In general, the SFS specification of simplicity
+   * follows the rule:
+   *  <UL>
+   *    <LI> A Geometry is simple iff the only self-intersections are at
+   *    boundary points.
+   *  </UL>
+   * Simplicity is defined for each {@link Geometry} subclass as follows:
+   * <ul>
+   * <li>Valid polygonal geometries are simple by definition, so
+   * <code>isSimple</code> trivially returns true.
+   * <li>Linear geometries are simple iff they do not self-intersect at points
+   * other than boundary points.
+   * <li>Zero-dimensional geometries (points) are simple iff they have no
+   * repeated points.
+   * <li>Empty <code>Geometry</code>s are always simple
+   * <ul>
+   *
+   * @return    <code>true</code> if this <code>Geometry</code> has any points of
+   *      self-tangency, self-intersection or other anomalous points
+   * @see #isValid
+   */
+  public boolean isSimple()
+  {
+    checkNotGeometryCollection(this);
+    IsSimpleOp op = new IsSimpleOp(this);
+    return op.isSimple();
+  }
+
+  /**
+   *  Tests the validity of this <code>Geometry</code>.
+   *  Subclasses provide their own definition of "valid".
+   *
+   *@return    <code>true</code> if this <code>Geometry</code> is valid
+   *
+   * @see IsValidOp
+   */
+  public boolean isValid()
+  {
+  	return IsValidOp.isValid(this);
+  }
+
+  /**
+   *  Returns whether or not the set of points in this <code>Geometry</code> is
+   *  empty.
+   *
+   *@return    <code>true</code> if this <code>Geometry</code> equals the empty
+   *      geometry
+   */
+  public abstract boolean isEmpty();
+
+
+  /**
+   * Tests whether the distance from this <code>Geometry</code>
+   * to another is less than or equal to a specified value.
+   *
+   * @param geom the Geometry to check the distance to
+   * @param distance the distance value to compare
+   * @return <code>true</code> if the geometries are less than <code>distance</code> apart.
+   */
+  public boolean isWithinDistance(Geometry geom, double distance)
+  {
+    double envDist = getEnvelopeInternal().distance(geom.getEnvelopeInternal());
+    if (envDist > distance)
+      return false;
+    return DistanceOp.isWithinDistance(this, geom, distance);
+    /*
+    double geomDist = this.distance(geom);
+    if (geomDist > distance)
+      return false;
+    return true;
+    */
+  }
+
+  public boolean isRectangle()
+  {
+    // Polygon overrides to check for actual rectangle
+    return false;
+  }
+
+  /**
+   *  Returns the area of this <code>Geometry</code>.
+   *  Areal Geometries have a non-zero area.
+   *  They override this function to compute the area.
+   *  Others return 0.0
+   *
+   *@return the area of the Geometry
+   */
+  public double getArea()
+  {
+    return 0.0;
+  }
+
+  /**
+   *  Returns the length of this <code>Geometry</code>.
+   *  Linear geometries return their length.
+   *  Areal geometries return their perimeter.
+   *  They override this function to compute the area.
+   *  Others return 0.0
+   *
+   *@return the length of the Geometry
+   */
+  public double getLength()
+  {
+    return 0.0;
+  }
+
+  /**
+   * Returns the dimension of this geometry.
+   * The dimension of a geometry is is the topological 
+   * dimension of its embedding in the 2-D Euclidean plane.
+   * In the JTS spatial model, dimension values are in the set {0,1,2}.
+   * <p>
+   * Note that this is a different concept to the dimension of 
+   * the vertex {@link Coordinate}s.  
+   * The geometry dimension can never be greater than the coordinate dimension.
+   * For example, a 0-dimensional geometry (e.g. a Point) 
+   * may have a coordinate dimension of 3 (X,Y,Z). 
+   *
+   *@return the topological dimension of this geometry.
+   */
+  public abstract int getDimension();
+
+  /**
+   * Returns the boundary, or an empty geometry of appropriate dimension
+   * if this <code>Geometry</code>  is empty.
+   * (In the case of zero-dimensional geometries, '
+   * an empty GeometryCollection is returned.)
+   * For a discussion of this function, see the OpenGIS Simple
+   * Features Specification. As stated in SFS Section 2.1.13.1, "the boundary
+   * of a Geometry is a set of Geometries of the next lower dimension."
+   *
+   *@return    the closure of the combinatorial boundary of this <code>Geometry</code>
+   */
+  public abstract Geometry getBoundary();
+
+  /**
+   *  Returns the dimension of this <code>Geometry</code>s inherent boundary.
+   *
+   *@return    the dimension of the boundary of the class implementing this
+   *      interface, whether or not this object is the empty geometry. Returns
+   *      <code>Dimension.FALSE</code> if the boundary is the empty geometry.
+   */
+  public abstract int getBoundaryDimension();
+
+
+  /**
+   *  Returns the minimum and maximum x and y values in this <code>Geometry</code>
+   *  , or a null <code>Envelope</code> if this <code>Geometry</code> is empty.
+   *
+   *@return    this <code>Geometry</code>s bounding box; if the <code>Geometry</code>
+   *      is empty, <code>Envelope#isNull</code> will return <code>true</code>
+   */
+  public Envelope getEnvelopeInternal() {
+    if (envelope == null) {
+      envelope = computeEnvelopeInternal();
+    }
+    return envelope;
+  }
+
+  /**
+   * Notifies this geometry that its coordinates have been changed by an external
+   * party (for example, via a {@link CoordinateFilter}). 
+   * When this method is called the geometry will flush
+   * and/or update any derived information it has cached (such as its {@link Envelope} ).
+   */
+  public void geometryChanged() {
+    apply(geometryChangedFilter);
+  }
+
+  /**
+   * Notifies this Geometry that its Coordinates have been changed by an external
+   * party. When #geometryChanged is called, this method will be called for
+   * this Geometry and its component Geometries.
+   * @see #apply(GeometryComponentFilter)
+   */
+  protected void geometryChangedAction() {
+    envelope = null;
+  }
+
+  /**
+   * Tests whether this geometry is disjoint from the argument geometry.
+   * <p>
+   * The <code>disjoint</code> predicate has the following equivalent definitions:
+   * <ul>
+   * <li>The two geometries have no point in common
+   * <li>The DE-9IM Intersection Matrix for the two geometries matches 
+   * <code>[FF*FF****]</code>
+   * <li><code>! g.intersects(this) = true</code>
+   * <br>(<code>disjoint</code> is the inverse of <code>intersects</code>)
+   * </ul>
+   *
+   *@param  g  the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *@return        <code>true</code> if the two <code>Geometry</code>s are
+   *      disjoint
+   *
+   * @see Geometry#intersects
+   */
+  public boolean disjoint(Geometry g) {
+    return ! intersects(g);
+  }
+
+  /**
+   * Tests whether this geometry touches the
+   * argument geometry.
+   * <p>
+   * The <code>touches</code> predicate has the following equivalent definitions:
+   * <ul>
+   * <li>The geometries have at least one point in common, but their interiors do not intersect.
+   * <li>The DE-9IM Intersection Matrix for the two geometries matches
+   * at least one of the following patterns
+   *  <ul>
+   *   <li><code>[FT*******]</code>
+   *   <li><code>[F**T*****]</code>
+   *   <li><code>[F***T****]</code>
+   *  </ul>
+   * </ul>
+   * If both geometries have dimension 0, this predicate returns <code>false</code>.
+   * 
+   *
+   *@param  g  the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *@return        <code>true</code> if the two <code>Geometry</code>s touch;
+   *      Returns <code>false</code> if both <code>Geometry</code>s are points
+   */
+  public boolean touches(Geometry g) {
+    // short-circuit test
+    if (! getEnvelopeInternal().intersects(g.getEnvelopeInternal()))
+      return false;
+    return relate(g).isTouches(getDimension(), g.getDimension());
+  }
+
+  /**
+   * Tests whether this geometry intersects the argument geometry.
+   * <p>
+   * The <code>intersects</code> predicate has the following equivalent definitions:
+   * <ul>
+   * <li>The two geometries have at least one point in common
+   * <li>The DE-9IM Intersection Matrix for the two geometries matches
+   * at least one of the patterns
+   *  <ul>
+   *   <li><code>[T********]</code>
+   *   <li><code>[*T*******]</code>
+   *   <li><code>[***T*****]</code>
+   *   <li><code>[****T****]</code>
+   *  </ul>
+   * <li><code>! g.disjoint(this) = true</code>
+   * <br>(<code>intersects</code> is the inverse of <code>disjoint</code>)
+   * </ul>
+   *
+   *@param  g  the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *@return        <code>true</code> if the two <code>Geometry</code>s intersect
+   *
+   * @see Geometry#disjoint
+   */
+  public boolean intersects(Geometry g) {
+
+    // short-circuit envelope test
+    if (! getEnvelopeInternal().intersects(g.getEnvelopeInternal()))
+      return false;
+
+    /**
+     * TODO: (MD) Add optimizations:
+     *
+     * - for P-A case:
+     * If P is in env(A), test for point-in-poly
+     *
+     * - for A-A case:
+     * If env(A1).overlaps(env(A2))
+     * test for overlaps via point-in-poly first (both ways)
+     * Possibly optimize selection of point to test by finding point of A1
+     * closest to centre of env(A2).
+     * (Is there a test where we shouldn't bother - e.g. if env A
+     * is much smaller than env B, maybe there's no point in testing
+     * pt(B) in env(A)?
+     */
+
+    // optimization for rectangle arguments
+    if (isRectangle()) {
+      return RectangleIntersects.intersects((Polygon) this, g);
+    }
+    if (g.isRectangle()) {
+      return RectangleIntersects.intersects((Polygon) g, this);
+    }
+    // general case
+    return relate(g).isIntersects();
+  }
+
+  /**
+   * Tests whether this geometry crosses the
+   * argument geometry.
+   * <p>
+   * The <code>crosses</code> predicate has the following equivalent definitions:
+   * <ul>
+   * <li>The geometries have some but not all interior points in common.
+   * <li>The DE-9IM Intersection Matrix for the two geometries matches
+   * one of the following patterns:
+   *   <ul>
+   *    <li><code>[T*T******]</code> (for P/L, P/A, and L/A situations)
+   *    <li><code>[T*****T**]</code> (for L/P, A/P, and A/L situations)
+   *    <li><code>[0********]</code> (for L/L situations)
+   *   </ul>
+   * </ul>
+   * For any other combination of dimensions this predicate returns <code>false</code>.
+   * <p>
+   * The SFS defined this predicate only for P/L, P/A, L/L, and L/A situations.
+   * In order to make the relation symmetric,
+   * JTS extends the definition to apply to L/P, A/P and A/L situations as well.
+   *
+   *@param  g  the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *@return        <code>true</code> if the two <code>Geometry</code>s cross.
+   */
+  public boolean crosses(Geometry g) {
+    // short-circuit test
+    if (! getEnvelopeInternal().intersects(g.getEnvelopeInternal()))
+      return false;
+    return relate(g).isCrosses(getDimension(), g.getDimension());
+  }
+
+  /**
+   * Tests whether this geometry is within the
+   * specified geometry.
+   * <p>
+   * The <code>within</code> predicate has the following equivalent definitions:
+   * <ul>
+   * <li>Every point of this geometry is a point of the other geometry,
+   * and the interiors of the two geometries have at least one point in common.
+   * <li>The DE-9IM Intersection Matrix for the two geometries matches 
+   * <code>[T*F**F***]</code>
+   * <li><code>g.contains(this) = true</code>
+   * <br>(<code>within</code> is the converse of {@link #contains})
+   * </ul>
+   * An implication of the definition is that
+   * "The boundary of a Geometry is not within the Geometry".
+   * In other words, if a geometry A is a subset of
+   * the points in the boundary of a geomtry B, <code>A.within(B) = false</code>
+   * (As a concrete example, take A to be a LineString which lies in the boundary of a Polygon B.)
+   * For a predicate with similar behaviour but avoiding 
+   * this subtle limitation, see {@link #coveredBy}.
+   *
+   *@param  g  the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *@return        <code>true</code> if this <code>Geometry</code> is within
+   *      <code>g</code>
+   *
+   * @see Geometry#contains
+   * @see Geometry#coveredBy
+   */
+  public boolean within(Geometry g) {
+    return g.contains(this);
+  }
+
+  /**
+   * Tests whether this geometry contains the
+   * argument geometry.
+   * <p>
+   * The <code>contains</code> predicate has the following equivalent definitions:
+   * <ul>
+   * <li>Every point of the other geometry is a point of this geometry,
+   * and the interiors of the two geometries have at least one point in common.
+   * <li>The DE-9IM Intersection Matrix for the two geometries matches 
+   * the pattern
+   * <code>[T*****FF*]</code>
+   * <li><code>g.within(this) = true</code>
+   * <br>(<code>contains</code> is the converse of {@link #within} )
+   * </ul>
+   * An implication of the definition is that "Geometries do not
+   * contain their boundary".  In other words, if a geometry A is a subset of
+   * the points in the boundary of a geometry B, <code>B.contains(A) = false</code>.
+   * (As a concrete example, take A to be a LineString which lies in the boundary of a Polygon B.)
+   * For a predicate with similar behaviour but avoiding 
+   * this subtle limitation, see {@link #covers}.
+   *
+   *@param  g  the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *@return        <code>true</code> if this <code>Geometry</code> contains <code>g</code>
+   *
+   * @see Geometry#within
+   * @see Geometry#covers
+   */
+  public boolean contains(Geometry g) {
+    // short-circuit test
+    if (! getEnvelopeInternal().contains(g.getEnvelopeInternal()))
+      return false;
+    // optimization for rectangle arguments
+    if (isRectangle()) {
+      return RectangleContains.contains((Polygon) this, g);
+    }
+    // general case
+    return relate(g).isContains();
+  }
+
+  /**
+   * Tests whether this geometry overlaps the
+   * specified geometry.
+   * <p>
+   * The <code>overlaps</code> predicate has the following equivalent definitions:
+   * <ul>
+   * <li>The geometries have at least one point each not shared by the other
+   * (or equivalently neither covers the other),
+   * they have the same dimension,
+   * and the intersection of the interiors of the two geometries has
+   * the same dimension as the geometries themselves.
+   * <li>The DE-9IM Intersection Matrix for the two geometries matches
+   *   <code>[T*T***T**]</code> (for two points or two surfaces)
+   *   or <code>[1*T***T**]</code> (for two curves)
+   * </ul>
+   * If the geometries are of different dimension this predicate returns <code>false</code>.
+   *
+   *@param  g  the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *@return        <code>true</code> if the two <code>Geometry</code>s overlap.
+   */
+  public boolean overlaps(Geometry g) {
+    // short-circuit test
+    if (! getEnvelopeInternal().intersects(g.getEnvelopeInternal()))
+      return false;
+    return relate(g).isOverlaps(getDimension(), g.getDimension());
+  }
+
+  /**
+   * Tests whether this geometry covers the
+   * argument geometry.
+   * <p>
+   * The <code>covers</code> predicate has the following equivalent definitions:
+   * <ul>
+   * <li>Every point of the other geometry is a point of this geometry.
+   * <li>The DE-9IM Intersection Matrix for the two geometries matches
+   * at least one of the following patterns:
+   *  <ul> 
+   *   <li><code>[T*****FF*]</code>
+   *   <li><code>[*T****FF*]</code>
+   *   <li><code>[***T**FF*]</code>
+   *   <li><code>[****T*FF*]</code>
+   *  </ul>
+   * <li><code>g.coveredBy(this) = true</code>
+   * <br>(<code>covers</code> is the converse of {@link #coveredBy})
+   * </ul>
+   * If either geometry is empty, the value of this predicate is <tt>false</tt>.
+   * <p>
+   * This predicate is similar to {@link #contains},
+   * but is more inclusive (i.e. returns <tt>true</tt> for more cases).
+   * In particular, unlike <code>contains</code> it does not distinguish between
+   * points in the boundary and in the interior of geometries.
+   * For most situations, <code>covers</code> should be used in preference to <code>contains</code>.
+   * As an added benefit, <code>covers</code> is more amenable to optimization,
+   * and hence should be more performant.
+   *
+   *@param  g  the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *@return        <code>true</code> if this <code>Geometry</code> covers <code>g</code>
+   *
+   * @see Geometry#contains
+   * @see Geometry#coveredBy
+   */
+  public boolean covers(Geometry g) {
+    // short-circuit test
+    if (! getEnvelopeInternal().covers(g.getEnvelopeInternal()))
+      return false;
+    // optimization for rectangle arguments
+    if (isRectangle()) {
+    	// since we have already tested that the test envelope is covered
+      return true;
+    }
+    return relate(g).isCovers();
+  }
+
+
+  /**
+   * Tests whether the elements in the DE-9IM
+   * {@link IntersectionMatrix} for the two <code>Geometry</code>s match the elements in <code>intersectionPattern</code>.
+   * The pattern is a 9-character string, with symbols drawn from the following set:
+   *  <UL>
+   *    <LI> 0 (dimension 0)
+   *    <LI> 1 (dimension 1)
+   *    <LI> 2 (dimension 2)
+   *    <LI> T ( matches 0, 1 or 2)
+   *    <LI> F ( matches FALSE)
+   *    <LI> * ( matches any value)
+   *  </UL>
+   *  For more information on the DE-9IM, see the <i>OpenGIS Simple Features
+   *  Specification</i>.
+   *
+   *@param  g                the <code>Geometry</code> with which to compare
+   *      this <code>Geometry</code>
+   *@param  intersectionPattern  the pattern against which to check the
+   *      intersection matrix for the two <code>Geometry</code>s
+   *@return                      <code>true</code> if the DE-9IM intersection
+   *      matrix for the two <code>Geometry</code>s match <code>intersectionPattern</code>
+   * @see IntersectionMatrix
+   */
+  public boolean relate(Geometry g, String intersectionPattern) {
+    return relate(g).matches(intersectionPattern);
+  }
+
+  /**
+   *  Returns the DE-9IM {@link IntersectionMatrix} for the two <code>Geometry</code>s.
+   *
+   *@param  g  the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *@return        an {@link IntersectionMatrix} describing the intersections of the interiors,
+   *      boundaries and exteriors of the two <code>Geometry</code>s
+   */
+  public IntersectionMatrix relate(Geometry g) {
+    checkNotGeometryCollection(this);
+    checkNotGeometryCollection(g);
+    return RelateOp.relate(this, g);
+  }
+
+  /**
+  * Tests whether this geometry is 
+  * topologically equal to the argument geometry.
+   * <p>
+   * This method is included for backward compatibility reasons.
+   * It has been superseded by the {@link #equalsTopo(Geometry)} method,
+   * which has been named to clearly denote its functionality.
+   * <p>
+   * This method should NOT be confused with the method 
+   * {@link #equals(Object)}, which implements 
+   * an exact equality comparison.
+   *
+   *@param  g  the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *@return true if the two <code>Geometry</code>s are topologically equal
+   *
+   *@see #equalsTopo(Geometry)
+   */
+  public boolean equals(Geometry g) {
+    return equalsTopo(g);
+  }
+
+  /**
+   * Tests whether this geometry is topologically equal to the argument geometry
+   * as defined by the SFS <tt>equals</tt> predicate.
+   * <p>
+   * The SFS <code>equals</code> predicate has the following equivalent definitions:
+   * <ul>
+   * <li>The two geometries have at least one point in common,
+   * and no point of either geometry lies in the exterior of the other geometry.
+   * <li>The DE-9IM Intersection Matrix for the two geometries matches
+   * the pattern <tt>T*F**FFF*</tt> 
+   * <pre>
+   * T*F
+   * **F
+   * FF*
+   * </pre>
+   * </ul>
+   * <b>Note</b> that this method computes <b>topologically equality</b>. 
+   * For structural equality, see {@link #equalsExact(Geometry)}.
+   *
+   *@param g the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *@return <code>true</code> if the two <code>Geometry</code>s are topologically equal
+   *
+   *@see #equalsExact(Geometry) 
+   */
+  public boolean equalsTopo(Geometry g)
+  {
+    // short-circuit test
+    if (! getEnvelopeInternal().equals(g.getEnvelopeInternal()))
+      return false;
+    return relate(g).isEquals(getDimension(), g.getDimension());
+  }
+  
+  /**
+   * Tests whether this geometry is structurally and numerically equal
+   * to a given <tt>Object</tt>.
+   * If the argument <tt>Object</tt> is not a <tt>Geometry</tt>, 
+   * the result is <tt>false</tt>.
+   * Otherwise, the result is computed using
+   * {@link #equalsExact(Geometry)}.
+   * <p>
+   * This method is provided to fulfill the Java contract
+   * for value-based object equality. 
+   * In conjunction with {@link #hashCode()} 
+   * it provides semantics which are most useful 
+   * for using
+   * <tt>Geometry</tt>s as keys and values in Java collections.
+   * <p>
+   * Note that to produce the expected result the input geometries
+   * should be in normal form.  It is the caller's 
+   * responsibility to perform this where required
+   * (using {@link Geometry#norm()
+   * or {@link #normalize()} as appropriate).
+   * 
+   * @param o the Object to compare
+   * @return true if this geometry is exactly equal to the argument 
+   * 
+   * @see #equalsExact(Geometry)
+   * @see #hashCode()
+   * @see #norm()
+   * @see #normalize()
+   */
+  public boolean equals(Object o)
+  {
+    if (! (o instanceof Geometry)) return false;
+    Geometry g = (Geometry) o;
+    return equalsExact(g);
+  }
+  
+  public int hashCode()
+  {
+    return getEnvelopeInternal().hashCode();
+  }
+  
+  public String toString() {
+    return toText();
+  }
+
+  /**
+   *  Returns the Well-known Text representation of this <code>Geometry</code>.
+   *  For a definition of the Well-known Text format, see the OpenGIS Simple
+   *  Features Specification.
+   *
+   *@return    the Well-known Text representation of this <code>Geometry</code>
+   */
+  public String toText() {
+    WKTWriter writer = new WKTWriter();
+    return writer.write(this);
+  }
+
+
+
+  /**
+   *  Computes the smallest convex <code>Polygon</code> that contains all the
+   *  points in the <code>Geometry</code>. This obviously applies only to <code>Geometry</code>
+   *  s which contain 3 or more points; the results for degenerate cases are
+   *  specified as follows:
+   *  <TABLE>
+   *    <TR>
+   *      <TH>    Number of <code>Point</code>s in argument <code>Geometry</code>   </TH>
+   *      <TH>    <code>Geometry</code> class of result     </TH>
+   *    </TR>
+   *    <TR>
+   *      <TD>        0      </TD>
+   *      <TD>        empty <code>GeometryCollection</code>      </TD>
+   *    </TR>
+   *    <TR>  <TD>      1     </TD>
+   *      <TD>     <code>Point</code>     </TD>
+   *    </TR>
+   *    <TR>
+   *      <TD>      2     </TD>
+   *      <TD>     <code>LineString</code>     </TD>
+   *    </TR>
+   *    <TR>
+   *      <TD>       3 or more     </TD>
+   *      <TD>      <code>Polygon</code>     </TD>
+   *    </TR>
+   *  </TABLE>
+   *
+   *@return    the minimum-area convex polygon containing this <code>Geometry</code>'
+   *      s points
+   */
+  public Geometry convexHull() {
+    return (new ConvexHull(this)).getConvexHull();
+  }
+
+  /**
+   * Computes a new geometry which has all component coordinate sequences
+   * in reverse order (opposite orientation) to this one.
+   * 
+   * @return a reversed geometry
+   */
+  public abstract Geometry reverse();
+  
+  /**
+   * Computes a <code>Geometry</code> representing the points shared by this
+   * <code>Geometry</code> and <code>other</code>.
+   * <p>
+   * Intersection of {@link GeometryCollection}s is supported
+   * only for homogeneous collection types.
+   * The result is a {@link GeometryCollection} of the
+   * intersection of each element of the target with the argument. 
+   * <p>
+   * The intersection of two geometries of different dimension produces a result
+   * geometry of dimension equal to the minimum dimension of the input
+   * geometries. The result geometry is always a homogeneous
+   * {@link GeometryCollection}.
+   *
+   * @param  other the <code>Geometry</code> with which to compute the intersection
+   * @return the point-set common to the two <code>Geometry</code>s
+   * @throws TopologyException if a robustness error occurs
+   * @throws IllegalArgumentException if the argument is a non-empty heterogeneous GeometryCollection
+   */
+  public Geometry intersection(Geometry other)
+  {
+  	/**
+  	 * TODO: MD - add optimization for P-A case using Point-In-Polygon
+  	 */
+    // special case: if one input is empty ==> empty
+    if (this.isEmpty()) return this.getFactory().createGeometryCollection(null);
+    if (other.isEmpty()) return this.getFactory().createGeometryCollection(null);
+
+    // compute for GCs
+    if (isGeometryCollection(this)) {
+      final Geometry g2 = other;
+      return GeometryCollectionMapper.map(
+          (GeometryCollection) this,
+          new GeometryCollectionMapper.MapOp() {
+        public Geometry map(Geometry g) {
+          return g.intersection(g2);
+        }
+      });
+    }
+//    if (isGeometryCollection(other))
+//      return other.intersection(this);
+    
+    checkNotGeometryCollection(this);
+    checkNotGeometryCollection(other);
+    return SnapIfNeededOverlayOp.overlayOp(this, other, OverlayOp.INTERSECTION);
+  }
+
+  
+  /**
+   * Returns true if the two <code>Geometry</code>s are exactly equal,
+   * up to a specified distance tolerance.
+   * Two Geometries are exactly equal within a distance tolerance
+   * if and only if:
+   * <ul>
+   * <li>they have the same structure
+   * <li>they have the same values for their vertices,
+   * within the given tolerance distance, in exactly the same order.
+   * </ul>
+   * This method does <i>not</i>
+   * test the values of the <tt>GeometryFactory</tt>, the <tt>SRID</tt>, 
+   * or the <tt>userData</tt> fields.
+   * <p>
+   * To properly test equality between different geometries,
+   * it is usually necessary to {@link #normalize()} them first.
+   *
+   * @param other the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   * @param tolerance distance at or below which two <code>Coordinate</code>s
+   *   are considered equal
+   * @return <code>true</code> if this and the other <code>Geometry</code>
+   *   have identical structure and point values, up to the distance tolerance.
+   *   
+   * @see #equalsExact(Geometry)
+   * @see #normalize()
+   * @see #norm()
+   */
+  public abstract boolean equalsExact(Geometry other, double tolerance);
+
+  /**
+   * Returns true if the two <code>Geometry</code>s are exactly equal.
+   * Two Geometries are exactly equal iff:
+   * <ul>
+   * <li>they have the same structure
+   * <li>they have the same values for their vertices,
+   * in exactly the same order.
+   * </ul>
+   * This provides a stricter test of equality than
+   * {@link #equalsTopo(Geometry)}, which is more useful
+   * in certain situations
+   * (such as using geometries as keys in collections).
+   * <p>
+   * This method does <i>not</i>
+   * test the values of the <tt>GeometryFactory</tt>, the <tt>SRID</tt>, 
+   * or the <tt>userData</tt> fields.
+   * <p>
+   * To properly test equality between different geometries,
+   * it is usually necessary to {@link #normalize()} them first.
+   *
+   *@param  other  the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *@return <code>true</code> if this and the other <code>Geometry</code>
+   *      have identical structure and point values.
+   *      
+   * @see #equalsExact(Geometry, double)
+   * @see #normalize()
+   * @see #norm()
+   */
+  public boolean equalsExact(Geometry other) { return equalsExact(other, 0); }
+
+
+  /**
+   *  Performs an operation with or on this <code>Geometry</code>'s
+   *  coordinates. 
+   *  If this method modifies any coordinate values,
+   *  {@link #geometryChanged} must be called to update the geometry state. 
+   *  Note that you cannot use this method to
+   *  modify this Geometry if its underlying CoordinateSequence's #get method
+   *  returns a copy of the Coordinate, rather than the actual Coordinate stored
+   *  (if it even stores Coordinate objects at all).
+   *
+   *@param  filter  the filter to apply to this <code>Geometry</code>'s
+   *      coordinates
+   */
+  public abstract void apply(CoordinateFilter filter);
+
+  /**
+   *  Performs an operation on the coordinates in this <code>Geometry</code>'s
+   *  {@link CoordinateSequence}s. 
+   *  If the filter reports that a coordinate value has been changed, 
+   *  {@link #geometryChanged} will be called automatically.
+   *
+   *@param  filter  the filter to apply
+   */
+  public abstract void apply(CoordinateSequenceFilter filter);
+
+  /**
+   *  Performs an operation with or on this <code>Geometry</code> and its
+   *  subelement <code>Geometry</code>s (if any).
+   *  Only GeometryCollections and subclasses
+   *  have subelement Geometry's.
+   *
+   *@param  filter  the filter to apply to this <code>Geometry</code> (and
+   *      its children, if it is a <code>GeometryCollection</code>).
+   */
+  public abstract void apply(GeometryFilter filter);
+
+  /**
+   *  Performs an operation with or on this Geometry and its
+   *  component Geometry's.  Only GeometryCollections and
+   *  Polygons have component Geometry's; for Polygons they are the LinearRings
+   *  of the shell and holes.
+   *
+   *@param  filter  the filter to apply to this <code>Geometry</code>.
+   */
+  public abstract void apply(GeometryComponentFilter filter);
+
+  /**
+   * Creates and returns a full copy of this {@link Geometry} object
+   * (including all coordinates contained by it).
+   * Subclasses are responsible for overriding this method and copying
+   * their internal data.  Overrides should call this method first.
+   *
+   * @return a clone of this instance
+   */
+  public Object clone() {
+    try {
+      Geometry clone = (Geometry) super.clone();
+      if (clone.envelope != null) { clone.envelope = new Envelope(clone.envelope); }
+      return clone;
+    }
+    catch (CloneNotSupportedException e) {
+      Assert.shouldNeverReachHere();
+      return null;
+    }
+  }
+
+  /**
+   *  Converts this <code>Geometry</code> to <b>normal form</b> (or <b>
+   *  canonical form</b> ). Normal form is a unique representation for <code>Geometry</code>
+   *  s. It can be used to test whether two <code>Geometry</code>s are equal
+   *  in a way that is independent of the ordering of the coordinates within
+   *  them. Normal form equality is a stronger condition than topological
+   *  equality, but weaker than pointwise equality. The definitions for normal
+   *  form use the standard lexicographical ordering for coordinates. "Sorted in
+   *  order of coordinates" means the obvious extension of this ordering to
+   *  sequences of coordinates.
+   *  <p>
+   *  NOTE that this method mutates the value of this geometry in-place.
+   *  If this is not safe and/or wanted, the geometry should be
+   *  cloned prior to normalization.
+   */
+  public abstract void normalize();
+
+  
+  /**
+   *  Returns whether this <code>Geometry</code> is greater than, equal to,
+   *  or less than another <code>Geometry</code>. <P>
+   *
+   *  If their classes are different, they are compared using the following
+   *  ordering:
+   *  <UL>
+   *    <LI> Point (lowest)
+   *    <LI> MultiPoint
+   *    <LI> LineString
+   *    <LI> LinearRing
+   *    <LI> MultiLineString
+   *    <LI> Polygon
+   *    <LI> MultiPolygon
+   *    <LI> GeometryCollection (highest)
+   *  </UL>
+   *  If the two <code>Geometry</code>s have the same class, their first
+   *  elements are compared. If those are the same, the second elements are
+   *  compared, etc.
+   *
+   *@param  o  a <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *@return    a positive number, 0, or a negative number, depending on whether
+   *      this object is greater than, equal to, or less than <code>o</code>, as
+   *      defined in "Normal Form For Geometry" in the JTS Technical
+   *      Specifications
+   */
+  public int compareTo(Object o) {
+    Geometry other = (Geometry) o;
+    if (getClassSortIndex() != other.getClassSortIndex()) {
+      return getClassSortIndex() - other.getClassSortIndex();
+    }
+    if (isEmpty() && other.isEmpty()) {
+      return 0;
+    }
+    if (isEmpty()) {
+      return -1;
+    }
+    if (other.isEmpty()) {
+      return 1;
+    }
+    return compareToSameClass(o);
+  }
+
+
+  /**
+   *  Returns whether the two <code>Geometry</code>s are equal, from the point
+   *  of view of the <code>equalsExact</code> method. Called by <code>equalsExact</code>
+   *  . In general, two <code>Geometry</code> classes are considered to be
+   *  "equivalent" only if they are the same class. An exception is <code>LineString</code>
+   *  , which is considered to be equivalent to its subclasses.
+   *
+   *@param  other  the <code>Geometry</code> with which to compare this <code>Geometry</code>
+   *      for equality
+   *@return        <code>true</code> if the classes of the two <code>Geometry</code>
+   *      s are considered to be equal by the <code>equalsExact</code> method.
+   */
+  protected boolean isEquivalentClass(Geometry other) {
+    return this.getClass().getName().equals(other.getClass().getName());
+  }
+
+  /**
+   *  Throws an exception if <code>g</code>'s class is <code>GeometryCollection</code>
+   *  . (Its subclasses do not trigger an exception).
+   *
+   *@param  g                          the <code>Geometry</code> to check
+   *@throws  IllegalArgumentException  if <code>g</code> is a <code>GeometryCollection</code>
+   *      but not one of its subclasses
+   */
+  protected void checkNotGeometryCollection(Geometry g) {
+    //Don't use instanceof because we want to allow subclasses
+    if (g.getClass().getName().equals("com.vividsolutions.jts.geom.GeometryCollection")) {
+      throw new IllegalArgumentException("This method does not support GeometryCollection arguments");
+    }
+  }
+
+  protected boolean isGeometryCollection(Geometry g)
+  {
+    return g.getClass().equals(com.vividsolutions.jts.geom.GeometryCollection.class);
+  }
+
+  /**
+   *  Returns the minimum and maximum x and y values in this <code>Geometry</code>
+   *  , or a null <code>Envelope</code> if this <code>Geometry</code> is empty.
+   *  Unlike <code>getEnvelopeInternal</code>, this method calculates the <code>Envelope</code>
+   *  each time it is called; <code>getEnvelopeInternal</code> caches the result
+   *  of this method.
+   *
+   *@return    this <code>Geometry</code>s bounding box; if the <code>Geometry</code>
+   *      is empty, <code>Envelope#isNull</code> will return <code>true</code>
+   */
+  protected abstract Envelope computeEnvelopeInternal();
+
+  /**
+   *  Returns whether this <code>Geometry</code> is greater than, equal to,
+   *  or less than another <code>Geometry</code> having the same class.
+   *
+   *@param  o  a <code>Geometry</code> having the same class as this <code>Geometry</code>
+   *@return    a positive number, 0, or a negative number, depending on whether
+   *      this object is greater than, equal to, or less than <code>o</code>, as
+   *      defined in "Normal Form For Geometry" in the JTS Technical
+   *      Specifications
+   */
+  protected abstract int compareToSameClass(Object o);
+
+  /**
+   *  Returns whether this <code>Geometry</code> is greater than, equal to,
+   *  or less than another <code>Geometry</code> of the same class.
+   * using the given {@link CoordinateSequenceComparator}.
+   *
+   *@param  o  a <code>Geometry</code> having the same class as this <code>Geometry</code>
+   *@param comp a <code>CoordinateSequenceComparator</code>
+   *@return    a positive number, 0, or a negative number, depending on whether
+   *      this object is greater than, equal to, or less than <code>o</code>, as
+   *      defined in "Normal Form For Geometry" in the JTS Technical
+   *      Specifications
+   */
+  protected abstract int compareToSameClass(Object o, CoordinateSequenceComparator comp);
+
+  /**
+   *  Returns the first non-zero result of <code>compareTo</code> encountered as
+   *  the two <code>Collection</code>s are iterated over. If, by the time one of
+   *  the iterations is complete, no non-zero result has been encountered,
+   *  returns 0 if the other iteration is also complete. If <code>b</code>
+   *  completes before <code>a</code>, a positive number is returned; if a
+   *  before b, a negative number.
+   *
+   *@param  a  a <code>Collection</code> of <code>Comparable</code>s
+   *@param  b  a <code>Collection</code> of <code>Comparable</code>s
+   *@return    the first non-zero <code>compareTo</code> result, if any;
+   *      otherwise, zero
+   */
+  protected int compare(Collection a, Collection b) {
+    Iterator i = a.iterator();
+    Iterator j = b.iterator();
+    while (i.hasNext() && j.hasNext()) {
+      Comparable aElement = (Comparable) i.next();
+      Comparable bElement = (Comparable) j.next();
+      int comparison = aElement.compareTo(bElement);
+      if (comparison != 0) {
+        return comparison;
+      }
+    }
+    if (i.hasNext()) {
+      return 1;
+    }
+    if (j.hasNext()) {
+      return -1;
+    }
+    return 0;
+  }
+
+  protected boolean equal(Coordinate a, Coordinate b, double tolerance) {
+    if (tolerance == 0) { return a.equals(b); }
+    return a.distance(b) <= tolerance;
+  }
+
+  private int getClassSortIndex() {
+		if (sortedClasses == null)
+			initSortedClasses();
+
+		for (int i = 0; i < sortedClasses.length; i++) {
+			if (sortedClasses[i].isInstance(this))
+				return i;
+		}
+		Assert.shouldNeverReachHere("Class not supported: " + this.getClass());
+		return -1;
+	}
+
+  private static void initSortedClasses()
+  {
+		sortedClasses = new Class[] { 
+					Point.class, 
+					MultiPoint.class,
+					LineString.class, 
+					LinearRing.class, 
+					MultiLineString.class,
+					Polygon.class, 
+					MultiPolygon.class, 
+					GeometryCollection.class };
+  }
+  
+  private Point createPointFromInternalCoord(Coordinate coord, Geometry exemplar)
+  {
+    exemplar.getPrecisionModel().makePrecise(coord);
+    return exemplar.getFactory().createPoint(coord);
+  }
+
+
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryCollection.java	(revision 28000)
@@ -0,0 +1,298 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import java.util.Arrays;
+import java.util.TreeSet;
+
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * Models a collection of {@link Geometry}s of
+ * arbitrary type and dimension.
+ * 
+ *
+ *@version 1.7
+ */
+public class GeometryCollection extends Geometry {
+//  With contributions from Markus Schaber [schabios@logi-track.com] 2004-03-26
+  private static final long serialVersionUID = -5694727726395021467L;
+  /**
+   *  Internal representation of this <code>GeometryCollection</code>.
+   */
+  protected Geometry[] geometries;
+
+
+  /**
+   * @param geometries
+   *            the <code>Geometry</code>s for this <code>GeometryCollection</code>,
+   *            or <code>null</code> or an empty array to create the empty
+   *            geometry. Elements may be empty <code>Geometry</code>s,
+   *            but not <code>null</code>s.
+   */
+  public GeometryCollection(Geometry[] geometries, GeometryFactory factory) {
+    super(factory);
+    if (geometries == null) {
+      geometries = new Geometry[]{};
+    }
+    if (hasNullElements(geometries)) {
+      throw new IllegalArgumentException("geometries must not contain null elements");
+    }
+    this.geometries = geometries;
+  }
+
+  public Coordinate getCoordinate() {
+    if (isEmpty()) return null;
+    return geometries[0].getCoordinate();
+  }
+
+  /**
+   * Collects all coordinates of all subgeometries into an Array.
+   *
+   * Note that while changes to the coordinate objects themselves
+   * may modify the Geometries in place, the returned Array as such
+   * is only a temporary container which is not synchronized back.
+   *
+   * @return the collected coordinates
+   *    */
+  public Coordinate[] getCoordinates() {
+    Coordinate[] coordinates = new Coordinate[getNumPoints()];
+    int k = -1;
+    for (int i = 0; i < geometries.length; i++) {
+      Coordinate[] childCoordinates = geometries[i].getCoordinates();
+      for (int j = 0; j < childCoordinates.length; j++) {
+        k++;
+        coordinates[k] = childCoordinates[j];
+      }
+    }
+    return coordinates;
+  }
+
+  public boolean isEmpty() {
+    for (int i = 0; i < geometries.length; i++) {
+      if (!geometries[i].isEmpty()) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public int getDimension() {
+    int dimension = Dimension.FALSE;
+    for (int i = 0; i < geometries.length; i++) {
+      dimension = Math.max(dimension, geometries[i].getDimension());
+    }
+    return dimension;
+  }
+
+  public int getBoundaryDimension() {
+    int dimension = Dimension.FALSE;
+    for (int i = 0; i < geometries.length; i++) {
+      dimension = Math.max(dimension, geometries[i].getBoundaryDimension());
+    }
+    return dimension;
+  }
+
+  public int getNumGeometries() {
+    return geometries.length;
+  }
+
+  public Geometry getGeometryN(int n) {
+    return geometries[n];
+  }
+
+  public int getNumPoints() {
+    int numPoints = 0;
+    for (int i = 0; i < geometries.length; i++) {
+      numPoints += geometries[i].getNumPoints();
+    }
+    return numPoints;
+  }
+
+  public String getGeometryType() {
+    return "GeometryCollection";
+  }
+
+  public Geometry getBoundary() {
+    checkNotGeometryCollection(this);
+    Assert.shouldNeverReachHere();
+    return null;
+  }
+
+  /**
+   *  Returns the area of this <code>GeometryCollection</code>
+   *
+   * @return the area of the polygon
+   */
+  public double getArea()
+  {
+    double area = 0.0;
+    for (int i = 0; i < geometries.length; i++) {
+      area += geometries[i].getArea();
+    }
+    return area;
+  }
+
+  public double getLength()
+  {
+    double sum = 0.0;
+    for (int i = 0; i < geometries.length; i++) {
+      sum += (geometries[i]).getLength();
+    }
+    return sum;
+  }
+
+  public boolean equalsExact(Geometry other, double tolerance) {
+    if (!isEquivalentClass(other)) {
+      return false;
+    }
+    GeometryCollection otherCollection = (GeometryCollection) other;
+    if (geometries.length != otherCollection.geometries.length) {
+      return false;
+    }
+    for (int i = 0; i < geometries.length; i++) {
+      if (!geometries[i].equalsExact(otherCollection.geometries[i], tolerance)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public void apply(CoordinateFilter filter) {
+	    for (int i = 0; i < geometries.length; i++) {
+	      geometries[i].apply(filter);
+	    }
+	  }
+
+  public void apply(CoordinateSequenceFilter filter) {
+    if (geometries.length == 0)
+      return;
+    for (int i = 0; i < geometries.length; i++) {
+      geometries[i].apply(filter);
+      if (filter.isDone()) {
+        break;
+      }
+    }
+    if (filter.isGeometryChanged())
+      geometryChanged();
+  }
+
+  public void apply(GeometryFilter filter) {
+    filter.filter(this);
+    for (int i = 0; i < geometries.length; i++) {
+      geometries[i].apply(filter);
+    }
+  }
+
+  public void apply(GeometryComponentFilter filter) {
+    filter.filter(this);
+    for (int i = 0; i < geometries.length; i++) {
+      geometries[i].apply(filter);
+    }
+  }
+
+  /**
+   * Creates and returns a full copy of this {@link GeometryCollection} object.
+   * (including all coordinates contained by it).
+   *
+   * @return a clone of this instance
+   */
+  public Object clone() {
+    GeometryCollection gc = (GeometryCollection) super.clone();
+    gc.geometries = new Geometry[geometries.length];
+    for (int i = 0; i < geometries.length; i++) {
+      gc.geometries[i] = (Geometry) geometries[i].clone();
+    }
+    return gc;// return the clone
+  }
+
+  public void normalize() {
+    for (int i = 0; i < geometries.length; i++) {
+      geometries[i].normalize();
+    }
+    Arrays.sort(geometries);
+  }
+
+  protected Envelope computeEnvelopeInternal() {
+    Envelope envelope = new Envelope();
+    for (int i = 0; i < geometries.length; i++) {
+      envelope.expandToInclude(geometries[i].getEnvelopeInternal());
+    }
+    return envelope;
+  }
+
+  protected int compareToSameClass(Object o) {
+    TreeSet<Geometry> theseElements = new TreeSet<Geometry>(Arrays.asList(geometries));
+    TreeSet<Geometry> otherElements = new TreeSet<Geometry>(Arrays.asList(((GeometryCollection) o).geometries));
+    return compare(theseElements, otherElements);
+  }
+
+  protected int compareToSameClass(Object o, CoordinateSequenceComparator comp) {
+    GeometryCollection gc = (GeometryCollection) o;
+
+    int n1 = getNumGeometries();
+    int n2 = gc.getNumGeometries();
+    int i = 0;
+    while (i < n1 && i < n2) {
+      Geometry thisGeom = getGeometryN(i);
+      Geometry otherGeom = gc.getGeometryN(i);
+      int holeComp = thisGeom.compareToSameClass(otherGeom, comp);
+      if (holeComp != 0) return holeComp;
+      i++;
+    }
+    if (i < n1) return 1;
+    if (i < n2) return -1;
+    return 0;
+
+  }
+  
+  /**
+   * Creates a {@link GeometryCollection} with
+   * every component reversed.
+   * The order of the components in the collection are not reversed.
+   *
+   * @return a {@link GeometryCollection} in the reverse order
+   */
+  public Geometry reverse()
+  {
+    int n = geometries.length;
+    Geometry[] revGeoms = new Geometry[n];
+    for (int i = 0; i < geometries.length; i++) {
+      revGeoms[i] = geometries[i].reverse();
+    }
+    return getFactory().createGeometryCollection(revGeoms);
+  }
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryCollectionIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryCollectionIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryCollectionIterator.java	(revision 28000)
@@ -0,0 +1,153 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ *  Iterates over all {@link Geometry}s in a {@link Geometry},
+ *  (which may be either a collection or an atomic geometry).
+ *  The iteration sequence follows a pre-order, depth-first traversal of the 
+ *  structure of the <code>GeometryCollection</code>
+ *  (which may be nested). The original <code>Geometry</code> object is
+ *  returned as well (as the first object), as are all sub-collections and atomic elements. 
+ *  It is  simple to ignore the intermediate <code>GeometryCollection</code> objects if they are not
+ *  needed.
+ *
+ *@version 1.7
+ */
+public class GeometryCollectionIterator implements Iterator {
+
+  /**
+   *  The <code>Geometry</code> being iterated over.
+   */
+  private Geometry parent;
+  /**
+   *  Indicates whether or not the first element 
+   *  (the root <code>GeometryCollection</code>) has been returned.
+   */
+  private boolean atStart;
+  /**
+   *  The number of <code>Geometry</code>s in the the <code>GeometryCollection</code>.
+   */
+  private int max;
+  /**
+   *  The index of the <code>Geometry</code> that will be returned when <code>next</code>
+   *  is called.
+   */
+  private int index;
+  /**
+   *  The iterator over a nested <code>Geometry</code>, or <code>null</code>
+   *  if this <code>GeometryCollectionIterator</code> is not currently iterating
+   *  over a nested <code>GeometryCollection</code>.
+   */
+  private GeometryCollectionIterator subcollectionIterator;
+
+  /**
+   *  Constructs an iterator over the given <code>Geometry</code>.
+   *
+   *@param  parent  the geometry over which to iterate; also, the first
+   *      element returned by the iterator.
+   */
+  public GeometryCollectionIterator(Geometry parent) {
+    this.parent = parent;
+    atStart = true;
+    index = 0;
+    max = parent.getNumGeometries();
+  }
+
+  /**
+   * Tests whether any geometry elements remain to be returned.
+   * 
+   * @return true if more geometry elements remain
+   */
+  public boolean hasNext() {
+    if (atStart) {
+      return true;
+    }
+    if (subcollectionIterator != null) {
+      if (subcollectionIterator.hasNext()) {
+        return true;
+      }
+      subcollectionIterator = null;
+    }
+    if (index >= max) {
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Gets the next geometry in the iteration sequence.
+   * 
+   * @return the next geometry in the iteration
+   */
+  public Object next() {
+    // the parent GeometryCollection is the first object returned
+    if (atStart) {
+      atStart = false;
+      return parent;
+    }
+    if (subcollectionIterator != null) {
+      if (subcollectionIterator.hasNext()) {
+        return subcollectionIterator.next();
+      }
+      else {
+        subcollectionIterator = null;
+      }
+    }
+    if (index >= max) {
+      throw new NoSuchElementException();
+    }
+    Geometry obj = parent.getGeometryN(index++);
+    if (obj instanceof GeometryCollection) {
+      subcollectionIterator = new GeometryCollectionIterator(obj);
+      // there will always be at least one element in the sub-collection
+      return subcollectionIterator.next();
+    }
+    return obj;
+  }
+
+  /**
+   * Removal is not supported.
+   *
+   * @throws  UnsupportedOperationException  This method is not implemented.
+   */
+  public void remove() {
+    throw new UnsupportedOperationException(getClass().getName());
+  }
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryComponentFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryComponentFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryComponentFilter.java	(revision 28000)
@@ -0,0 +1,68 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+
+/**
+ *  <code>Geometry</code> classes support the concept of applying
+ *  a <code>GeometryComponentFilter</code>
+ *  filter to the <code>Geometry</code>.
+ *  The filter is applied to every component of the <code>Geometry</code>
+ *  which is itself a <code>Geometry</code>
+ *  and which does not itself contain any components.
+ * (For instance, all the {@link LinearRing}s in {@link Polygon}s are visited,
+ * but in a {@link MultiPolygon} the {@link Polygon}s themselves are not visited.)
+ * Thus the only classes of Geometry which must be 
+ * handled as arguments to {@link #filter}
+ * are {@link LineString}s, {@link LinearRing}s and {@link Point}s.
+ *  <p>
+ *  A <code>GeometryComponentFilter</code> filter can either
+ *  record information about the <code>Geometry</code>
+ *  or change the <code>Geometry</code> in some way.
+ *  <code>GeometryComponentFilter</code>
+ *  is an example of the Gang-of-Four Visitor pattern.
+ *
+ *@version 1.7
+ */
+public interface GeometryComponentFilter {
+
+  /**
+   *  Performs an operation with or on <code>geom</code>.
+   *
+   *@param  geom  a <code>Geometry</code> to which the filter is applied.
+   */
+  void filter(Geometry geom);
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryFactory.java	(revision 28000)
@@ -0,0 +1,392 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+
+import com.vividsolutions.jts.geom.impl.CoordinateArraySequenceFactory;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * Supplies a set of utility methods for building Geometry objects from lists
+ * of Coordinates.
+ * <p>
+ * Note that the factory constructor methods do <b>not</b> change the input coordinates in any way.
+ * In particular, they are not rounded to the supplied <tt>PrecisionModel</tt>.
+ * It is assumed that input Coordinates meet the given precision.
+ *
+ *
+ * @version 1.7
+ */
+public class GeometryFactory
+    implements Serializable
+{
+  private static final long serialVersionUID = -6820524753094095635L;
+  private PrecisionModel precisionModel;
+
+  private CoordinateSequenceFactory coordinateSequenceFactory;
+
+  /**
+   * Constructs a GeometryFactory that generates Geometries having the given
+   * PrecisionModel, spatial-reference ID, and CoordinateSequence implementation.
+   */
+  public GeometryFactory(PrecisionModel precisionModel, int SRID,
+                         CoordinateSequenceFactory coordinateSequenceFactory) {
+      this.precisionModel = precisionModel;
+      this.coordinateSequenceFactory = coordinateSequenceFactory;
+  }
+
+  /**
+   * Constructs a GeometryFactory that generates Geometries having the given
+   * CoordinateSequence implementation, a double-precision floating PrecisionModel and a
+   * spatial-reference ID of 0.
+   */
+  public GeometryFactory(CoordinateSequenceFactory coordinateSequenceFactory) {
+    this(new PrecisionModel(), 0, coordinateSequenceFactory);
+  }
+
+  /**
+   * Constructs a GeometryFactory that generates Geometries having the given
+   * {@link PrecisionModel} and spatial-reference ID, and the default CoordinateSequence
+   * implementation.
+   *
+   * @param precisionModel the PrecisionModel to use
+   * @param SRID the SRID to use
+   */
+  public GeometryFactory(PrecisionModel precisionModel, int SRID) {
+    this(precisionModel, SRID, getDefaultCoordinateSequenceFactory());
+  }
+
+  /**
+   * Constructs a GeometryFactory that generates Geometries having a floating
+   * PrecisionModel and a spatial-reference ID of 0.
+   */
+  public GeometryFactory() {
+    this(new PrecisionModel(), 0);
+  }
+
+  private static CoordinateSequenceFactory getDefaultCoordinateSequenceFactory()
+  {
+    return CoordinateArraySequenceFactory.instance();
+  }
+
+  /**
+   *  Converts the <code>List</code> to an array.
+   *
+   *@param  points  the <code>List</code> of Points to convert
+   *@return         the <code>List</code> in array format
+   */
+  public static Point[] toPointArray(Collection<? extends Geometry> points) {
+    Point[] pointArray = new Point[points.size()];
+    return points.toArray(pointArray);
+  }
+
+  /**
+   *  Converts the <code>List</code> to an array.
+   *
+   *@param  geometries  the list of <code>Geometry's</code> to convert
+   *@return            the <code>List</code> in array format
+   */
+  public static Geometry[] toGeometryArray(Collection<? extends Geometry> geometries) {
+    if (geometries == null) return null;
+    Geometry[] geometryArray = new Geometry[geometries.size()];
+    return geometries.toArray(geometryArray);
+  }
+
+  /**
+   *  Converts the <code>List</code> to an array.
+   *
+   *@param  lineStrings  the <code>List</code> of LineStrings to convert
+   *@return              the <code>List</code> in array format
+   */
+  public static LineString[] toLineStringArray(Collection<? extends Geometry> lineStrings) {
+    LineString[] lineStringArray = new LineString[lineStrings.size()];
+    return lineStrings.toArray(lineStringArray);
+  }
+
+  /**
+   *  Converts the <code>List</code> to an array.
+   *
+   *@param  polygons  the <code>List</code> of Polygons to convert
+   *@return           the <code>List</code> in array format
+   */
+  public static Polygon[] toPolygonArray(Collection<? extends Geometry> polygons) {
+    Polygon[] polygonArray = new Polygon[polygons.size()];
+    return polygons.toArray(polygonArray);
+  }
+
+
+  /**
+   * Returns the PrecisionModel that Geometries created by this factory
+   * will be associated with.
+   */
+  public PrecisionModel getPrecisionModel() {
+    return precisionModel;
+  }
+
+  /**
+   * Creates a Point using the given Coordinate; a null Coordinate will create
+   * an empty Geometry.
+   */
+  public Point createPoint(Coordinate coordinate) {
+    return createPoint(coordinate != null ? getCoordinateSequenceFactory().create(new Coordinate[]{coordinate}) : null);
+  }
+
+  /**
+   * Creates a Point using the given CoordinateSequence; a null or empty
+   * CoordinateSequence will create an empty Point.
+   */
+  public Point createPoint(CoordinateSequence coordinates) {
+  	return new Point(coordinates, this);
+  }
+
+  /**
+   * Creates a MultiLineString using the given LineStrings; a null or empty
+   * array will create an empty MultiLineString.
+   * @param lineStrings LineStrings, each of which may be empty but not null
+   */
+  public MultiLineString createMultiLineString(LineString[] lineStrings) {
+  	return new MultiLineString(lineStrings, this);
+  }
+
+  /**
+   * Creates a GeometryCollection using the given Geometries; a null or empty
+   * array will create an empty GeometryCollection.
+   * @param geometries Geometries, each of which may be empty but not null
+   */
+  public GeometryCollection createGeometryCollection(Geometry[] geometries) {
+  	return new GeometryCollection(geometries, this);
+  }
+
+  /**
+   * Creates a MultiPolygon using the given Polygons; a null or empty array
+   * will create an empty Polygon. The polygons must conform to the
+   * assertions specified in the <A
+   * HREF="http://www.opengis.org/techno/specs.htm">OpenGIS Simple Features
+   * Specification for SQL</A>.
+   *
+   * @param polygons
+   *            Polygons, each of which may be empty but not null
+   */
+  public MultiPolygon createMultiPolygon(Polygon[] polygons) {
+    return new MultiPolygon(polygons, this);
+  }
+
+  /**
+   * Creates a {@link LinearRing} using the given {@link Coordinate}s.
+   * A null or empty array will
+   * create an empty LinearRing. The points must form a closed and simple
+   * linestring. Consecutive points must not be equal.
+   * @param coordinates an array without null elements, or an empty array, or null
+   */
+  public LinearRing createLinearRing(Coordinate[] coordinates) {
+    return createLinearRing(coordinates != null ? getCoordinateSequenceFactory().create(coordinates) : null);
+  }
+
+  /**
+   * Creates a {@link LinearRing} using the given {@link CoordinateSequence}. 
+   * A null or empty CoordinateSequence will
+   * create an empty LinearRing. The points must form a closed and simple
+   * linestring. Consecutive points must not be equal.
+   * 
+   * @param coordinates a CoordinateSequence possibly empty, or null
+   * @throws IllegalArgumentException if the ring is not closed, or has too few points
+   */
+  public LinearRing createLinearRing(CoordinateSequence coordinates) {
+    return new LinearRing(coordinates, this);
+  }
+
+  /**
+   * Creates a {@link MultiPoint} using the given {@link Point}s.
+   * A null or empty array will create an empty MultiPoint.
+   *
+   * @param point an array of Points (without null elements), or an empty array, or <code>null</code>
+   * @return a MultiPoint object
+   */
+  public MultiPoint createMultiPoint(Point[] point) {
+  	return new MultiPoint(point, this);
+  }
+
+  /**
+   * Creates a {@link MultiPoint} using the given {@link Coordinate}s.
+   * A null or empty array will create an empty MultiPoint.
+   *
+   * @param coordinates an array (without null elements), or an empty array, or <code>null</code>
+   * @return a MultiPoint object
+   */
+  public MultiPoint createMultiPoint(Coordinate[] coordinates) {
+      return createMultiPoint(coordinates != null
+                              ? getCoordinateSequenceFactory().create(coordinates)
+                              : null);
+  }
+
+  /**
+   * Creates a MultiPoint using the given CoordinateSequence.
+   * A a null or empty CoordinateSequence will create an empty MultiPoint.
+   *
+   * @param coordinates a CoordinateSequence (possibly empty), or <code>null</code>
+   * @return a MultiPoint object
+   */
+  public MultiPoint createMultiPoint(CoordinateSequence coordinates) {
+    if (coordinates == null) {
+      return createMultiPoint(new Point[0]);
+    }
+    Point[] points = new Point[coordinates.size()];
+    for (int i = 0; i < coordinates.size(); i++) {
+      points[i] = createPoint(coordinates.getCoordinate(i));
+    }
+    return createMultiPoint(points);
+  }
+
+  /**
+   * Constructs a <code>Polygon</code> with the given exterior boundary and
+   * interior boundaries.
+   *
+   * @param shell
+   *            the outer boundary of the new <code>Polygon</code>, or
+   *            <code>null</code> or an empty <code>LinearRing</code> if
+   *            the empty geometry is to be created.
+   * @param holes
+   *            the inner boundaries of the new <code>Polygon</code>, or
+   *            <code>null</code> or empty <code>LinearRing</code> s if
+   *            the empty geometry is to be created.
+   * @throws IllegalArgumentException if a ring is invalid
+   */
+  public Polygon createPolygon(LinearRing shell, LinearRing[] holes) {
+    return new Polygon(shell, holes, this);
+  }
+
+  /**
+   *  Build an appropriate <code>Geometry</code>, <code>MultiGeometry</code>, or
+   *  <code>GeometryCollection</code> to contain the <code>Geometry</code>s in
+   *  it.
+   * For example:<br>
+   *
+   *  <ul>
+   *    <li> If <code>geomList</code> contains a single <code>Polygon</code>,
+   *    the <code>Polygon</code> is returned.
+   *    <li> If <code>geomList</code> contains several <code>Polygon</code>s, a
+   *    <code>MultiPolygon</code> is returned.
+   *    <li> If <code>geomList</code> contains some <code>Polygon</code>s and
+   *    some <code>LineString</code>s, a <code>GeometryCollection</code> is
+   *    returned.
+   *    <li> If <code>geomList</code> is empty, an empty <code>GeometryCollection</code>
+   *    is returned
+   *  </ul>
+   *
+   * Note that this method does not "flatten" Geometries in the input, and hence if
+   * any MultiGeometries are contained in the input a GeometryCollection containing
+   * them will be returned.
+   *
+   *@param  geomList  the <code>Geometry</code>s to combine
+   *@return           a <code>Geometry</code> of the "smallest", "most
+   *      type-specific" class that can contain the elements of <code>geomList</code>
+   *      .
+   */
+  public Geometry buildGeometry(Collection<? extends Geometry> geomList) {
+  	
+  	/**
+  	 * Determine some facts about the geometries in the list
+  	 */
+    Class<? extends Geometry> geomClass = null;
+    boolean isHeterogeneous = false;
+    boolean hasGeometryCollection = false;
+    for (Iterator<? extends Geometry> i = geomList.iterator(); i.hasNext(); ) {
+      Geometry geom = i.next();
+      Class<? extends Geometry> partClass = geom.getClass();
+      if (geomClass == null) {
+        geomClass = partClass;
+      }
+      if (partClass != geomClass) {
+        isHeterogeneous = true;
+      }
+      if (geom instanceof GeometryCollection)
+        hasGeometryCollection = true;
+    }
+    
+    /**
+     * Now construct an appropriate geometry to return
+     */
+    // for the empty geometry, return an empty GeometryCollection
+    if (geomClass == null) {
+      return createGeometryCollection(null);
+    }
+    if (isHeterogeneous || hasGeometryCollection) {
+      return createGeometryCollection(toGeometryArray(geomList));
+    }
+    // at this point we know the collection is hetereogenous.
+    // Determine the type of the result from the first Geometry in the list
+    // this should always return a geometry, since otherwise an empty collection would have already been returned
+    Geometry geom0 = geomList.iterator().next();
+    boolean isCollection = geomList.size() > 1;
+    if (isCollection) {
+      if (geom0 instanceof Polygon) {
+        return createMultiPolygon(toPolygonArray(geomList));
+      }
+      else if (geom0 instanceof LineString) {
+        return createMultiLineString(toLineStringArray(geomList));
+      }
+      else if (geom0 instanceof Point) {
+        return createMultiPoint(toPointArray(geomList));
+      }
+      Assert.shouldNeverReachHere("Unhandled class: " + geom0.getClass().getName());
+    }
+    return geom0;
+  }
+
+  /**
+   * Creates a LineString using the given Coordinates; a null or empty array will
+   * create an empty LineString. Consecutive points must not be equal.
+   * @param coordinates an array without null elements, or an empty array, or null
+   */
+  public LineString createLineString(Coordinate[] coordinates) {
+    return createLineString(coordinates != null ? getCoordinateSequenceFactory().create(coordinates) : null);
+  }
+  /**
+   * Creates a LineString using the given CoordinateSequence; a null or empty CoordinateSequence will
+   * create an empty LineString. Consecutive points must not be equal.
+   * @param coordinates a CoordinateSequence possibly empty, or null
+   */
+  public LineString createLineString(CoordinateSequence coordinates) {
+	return new LineString(coordinates, this);
+  }
+
+  public CoordinateSequenceFactory getCoordinateSequenceFactory() {
+    return coordinateSequenceFactory;
+  }
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/GeometryFilter.java	(revision 28000)
@@ -0,0 +1,58 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+
+/**
+ *  <code>GeometryCollection</code> classes support the concept of
+ *  applying a <code>GeometryFilter</code> to the <code>Geometry</code>.
+ *  The filter is applied to every element <code>Geometry</code>.
+ *  A <code>GeometryFilter</code> can either record information about the <code>Geometry</code>
+ *  or change the <code>Geometry</code> in some way.
+ *  <code>GeometryFilter</code>
+ *  is an example of the Gang-of-Four Visitor pattern.
+ *
+ *@version 1.7
+ */
+public interface GeometryFilter {
+
+  /**
+   *  Performs an operation with or on <code>geom</code>.
+   *
+   *@param  geom  a <code>Geometry</code> to which the filter is applied.
+   */
+  void filter(Geometry geom);
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/IntersectionMatrix.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/IntersectionMatrix.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/IntersectionMatrix.java	(revision 28000)
@@ -0,0 +1,444 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+/**
+ * Models a Dimensionally Extended Nine-Intersection Model (DE-9IM) matrix. 
+ * This class is used to represent intersection matrices (such as "212FF1FF2")
+ * capturing the topological relationship between two {@link Geometry}s. 
+ * It can also be represent patterns (such as "T*T******")for matching 
+ * existing matrices.
+ *
+ *  Methods are provided to:
+ *  <UL>
+ *    <LI> set and query the elements of the matrix in a convenient fashion
+ *    <LI> convert to and from the standard string representation (specified in
+ *    SFS Section 2.1.13.2).
+ *    <LI> test to see if a matrix matches a given pattern string.
+ *  </UL>
+ *  <P>
+ *
+ *  For a description of the DE-9IM, see the <A
+ *  HREF="http://www.opengis.org/techno/specs.htm">OpenGIS Simple Features
+ *  Specification for SQL</A>.
+ *  
+ * The entries of the matrix are defined by the constants in the {@link Dimension} class.
+ * The indices of the matrix represent the topological locations 
+ * that occur in a geometry (Interior, Boundary, Exterior).  
+ * These are provided as constants in the {@link Location} class.
+ *  
+ *
+ *@version 1.7
+ */
+public class IntersectionMatrix implements Cloneable {
+  /**
+   *  Internal representation of this <code>IntersectionMatrix</code>.
+   */
+  private int[][] matrix;
+
+  /**
+   *  Creates an <code>IntersectionMatrix</code> with <code>FALSE</code>
+   *  dimension values.
+   */
+  public IntersectionMatrix() {
+    matrix = new int[3][3];
+    setAll(Dimension.FALSE);
+  }
+
+  /**
+   *  Returns true if the dimension value satisfies the dimension symbol.
+   *
+   *@param  actualDimensionValue     a number that can be stored in the <code>IntersectionMatrix</code>
+   *      . Possible values are <code>{TRUE, FALSE, DONTCARE, 0, 1, 2}</code>.
+   *@param  requiredDimensionSymbol  a character used in the string
+   *      representation of an <code>IntersectionMatrix</code>. Possible values
+   *      are <code>{T, F, * , 0, 1, 2}</code>.
+   *@return                          true if the dimension symbol encompasses
+   *      the dimension value
+   */
+  public static boolean matches(int actualDimensionValue, char requiredDimensionSymbol) {
+    if (requiredDimensionSymbol == '*') {
+      return true;
+    }
+    if (requiredDimensionSymbol == 'T' && (actualDimensionValue >= 0 || actualDimensionValue
+         == Dimension.TRUE)) {
+      return true;
+    }
+    if (requiredDimensionSymbol == 'F' && actualDimensionValue == Dimension.FALSE) {
+      return true;
+    }
+    if (requiredDimensionSymbol == '0' && actualDimensionValue == Dimension.P) {
+      return true;
+    }
+    if (requiredDimensionSymbol == '1' && actualDimensionValue == Dimension.L) {
+      return true;
+    }
+    if (requiredDimensionSymbol == '2' && actualDimensionValue == Dimension.A) {
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   *  Changes the value of one of this <code>IntersectionMatrix</code>s
+   *  elements.
+   *
+   *@param  row             the row of this <code>IntersectionMatrix</code>,
+   *      indicating the interior, boundary or exterior of the first <code>Geometry</code>
+   *@param  column          the column of this <code>IntersectionMatrix</code>,
+   *      indicating the interior, boundary or exterior of the second <code>Geometry</code>
+   *@param  dimensionValue  the new value of the element
+   */
+  public void set(int row, int column, int dimensionValue) {
+    matrix[row][column] = dimensionValue;
+  }
+
+
+  /**
+   *  Changes the specified element to <code>minimumDimensionValue</code> if the
+   *  element is less.
+   *
+   *@param  row                    the row of this <code>IntersectionMatrix</code>
+   *      , indicating the interior, boundary or exterior of the first <code>Geometry</code>
+   *@param  column                 the column of this <code>IntersectionMatrix</code>
+   *      , indicating the interior, boundary or exterior of the second <code>Geometry</code>
+   *@param  minimumDimensionValue  the dimension value with which to compare the
+   *      element. The order of dimension values from least to greatest is
+   *      <code>{DONTCARE, TRUE, FALSE, 0, 1, 2}</code>.
+   */
+  public void setAtLeast(int row, int column, int minimumDimensionValue) {
+    if (matrix[row][column] < minimumDimensionValue) {
+      matrix[row][column] = minimumDimensionValue;
+    }
+  }
+
+  /**
+   *  If row >= 0 and column >= 0, changes the specified element to <code>minimumDimensionValue</code>
+   *  if the element is less. Does nothing if row <0 or column < 0.
+   *
+   *@param  row                    the row of this <code>IntersectionMatrix</code>
+   *      , indicating the interior, boundary or exterior of the first <code>Geometry</code>
+   *@param  column                 the column of this <code>IntersectionMatrix</code>
+   *      , indicating the interior, boundary or exterior of the second <code>Geometry</code>
+   *@param  minimumDimensionValue  the dimension value with which to compare the
+   *      element. The order of dimension values from least to greatest is
+   *      <code>{DONTCARE, TRUE, FALSE, 0, 1, 2}</code>.
+   */
+  public void setAtLeastIfValid(int row, int column, int minimumDimensionValue) {
+    if (row >= 0 && column >= 0) {
+      setAtLeast(row, column, minimumDimensionValue);
+    }
+  }
+
+  /**
+   *  For each element in this <code>IntersectionMatrix</code>, changes the
+   *  element to the corresponding minimum dimension symbol if the element is
+   *  less.
+   *
+   *@param  minimumDimensionSymbols  nine dimension symbols with which to
+   *      compare the elements of this <code>IntersectionMatrix</code>. The
+   *      order of dimension values from least to greatest is <code>{DONTCARE, TRUE, FALSE, 0, 1, 2}</code>
+   *      .
+   */
+  public void setAtLeast(String minimumDimensionSymbols) {
+    for (int i = 0; i < minimumDimensionSymbols.length(); i++) {
+      int row = i / 3;
+      int col = i % 3;
+      setAtLeast(row, col, Dimension.toDimensionValue(minimumDimensionSymbols.charAt(i)));
+    }
+  }
+
+  /**
+   *  Changes the elements of this <code>IntersectionMatrix</code> to <code>dimensionValue</code>
+   *  .
+   *
+   *@param  dimensionValue  the dimension value to which to set this <code>IntersectionMatrix</code>
+   *      s elements. Possible values <code>{TRUE, FALSE, DONTCARE, 0, 1, 2}</code>
+   *      .
+   */
+  public void setAll(int dimensionValue) {
+    for (int ai = 0; ai < 3; ai++) {
+      for (int bi = 0; bi < 3; bi++) {
+        matrix[ai][bi] = dimensionValue;
+      }
+    }
+  }
+
+
+  /**
+   *  Returns <code>true</code> if this <code>IntersectionMatrix</code> is
+   *  FF*FF****.
+   *
+   *@return    <code>true</code> if the two <code>Geometry</code>s related by
+   *      this <code>IntersectionMatrix</code> are disjoint
+   */
+  public boolean isDisjoint() {
+    return
+        matrix[Location.INTERIOR][Location.INTERIOR] == Dimension.FALSE &&
+        matrix[Location.INTERIOR][Location.BOUNDARY] == Dimension.FALSE &&
+        matrix[Location.BOUNDARY][Location.INTERIOR] == Dimension.FALSE &&
+        matrix[Location.BOUNDARY][Location.BOUNDARY] == Dimension.FALSE;
+  }
+
+  /**
+   *  Returns <code>true</code> if <code>isDisjoint</code> returns false.
+   *
+   *@return    <code>true</code> if the two <code>Geometry</code>s related by
+   *      this <code>IntersectionMatrix</code> intersect
+   */
+  public boolean isIntersects() {
+    return ! isDisjoint();
+  }
+
+  /**
+   *  Returns <code>true</code> if this <code>IntersectionMatrix</code> is
+   *  FT*******, F**T***** or F***T****.
+   *
+   *@param  dimensionOfGeometryA  the dimension of the first <code>Geometry</code>
+   *@param  dimensionOfGeometryB  the dimension of the second <code>Geometry</code>
+   *@return                       <code>true</code> if the two <code>Geometry</code>
+   *      s related by this <code>IntersectionMatrix</code> touch; Returns false
+   *      if both <code>Geometry</code>s are points.
+   */
+  public boolean isTouches(int dimensionOfGeometryA, int dimensionOfGeometryB) {
+    if (dimensionOfGeometryA > dimensionOfGeometryB) {
+      //no need to get transpose because pattern matrix is symmetrical
+      return isTouches(dimensionOfGeometryB, dimensionOfGeometryA);
+    }
+    if ((dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.A) ||
+        (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.L) ||
+        (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.A) ||
+        (dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.A) ||
+        (dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.L)) {
+      return matrix[Location.INTERIOR][Location.INTERIOR] == Dimension.FALSE &&
+          (matches(matrix[Location.INTERIOR][Location.BOUNDARY], 'T')
+           || matches(matrix[Location.BOUNDARY][Location.INTERIOR], 'T')
+           || matches(matrix[Location.BOUNDARY][Location.BOUNDARY], 'T'));
+    }
+    return false;
+  }
+
+  /**
+   * Tests whether this geometry crosses the
+   * specified geometry.
+   * <p>
+   * The <code>crosses</code> predicate has the following equivalent definitions:
+   * <ul>
+   * <li>The geometries have some but not all interior points in common.
+   * <li>The DE-9IM Intersection Matrix for the two geometries is
+   *   <ul>
+   *    <li>T*T****** (for P/L, P/A, and L/A situations)
+   *    <li>T*****T** (for L/P, L/A, and A/L situations)
+   *    <li>0******** (for L/L situations)
+   *   </ul>
+   * </ul>
+   * For any other combination of dimensions this predicate returns <code>false</code>.
+   * <p>
+   * The SFS defined this predicate only for P/L, P/A, L/L, and L/A situations.
+   * JTS extends the definition to apply to L/P, A/P and A/L situations as well.
+   * This makes the relation symmetric.
+   *
+   *@param  dimensionOfGeometryA  the dimension of the first <code>Geometry</code>
+   *@param  dimensionOfGeometryB  the dimension of the second <code>Geometry</code>
+   *@return                       <code>true</code> if the two <code>Geometry</code>s
+   *      related by this <code>IntersectionMatrix</code> cross.
+   */
+  public boolean isCrosses(int dimensionOfGeometryA, int dimensionOfGeometryB) {
+    if ((dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.L) ||
+        (dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.A) ||
+        (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.A)) {
+      return matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T') &&
+          matches(matrix[Location.INTERIOR][Location.EXTERIOR], 'T');
+    }
+    if ((dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.P) ||
+        (dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.P) ||
+        (dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.L)) {
+      return matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T') &&
+          matches(matrix[Location.EXTERIOR][Location.INTERIOR], 'T');
+    }
+    if (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.L) {
+      return matrix[Location.INTERIOR][Location.INTERIOR] == 0;
+    }
+    return false;
+  }
+
+  /**
+   *  Tests whether this <code>IntersectionMatrix</code> is
+   *  T*****FF*.
+   *
+   *@return    <code>true</code> if the first <code>Geometry</code> contains the
+   *      second
+   */
+  public boolean isContains() {
+    return matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T') &&
+        matrix[Location.EXTERIOR][Location.INTERIOR] == Dimension.FALSE &&
+        matrix[Location.EXTERIOR][Location.BOUNDARY] == Dimension.FALSE;
+  }
+
+  /**
+   *  Returns <code>true</code> if this <code>IntersectionMatrix</code> is
+   *    <code>T*****FF*</code>
+   * or <code>*T****FF*</code>
+   * or <code>***T**FF*</code>
+   * or <code>****T*FF*</code>
+   *
+   *@return    <code>true</code> if the first <code>Geometry</code> covers the
+   *      second
+   */
+  public boolean isCovers() {
+    boolean hasPointInCommon =
+        matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T')
+        || matches(matrix[Location.INTERIOR][Location.BOUNDARY], 'T')
+        || matches(matrix[Location.BOUNDARY][Location.INTERIOR], 'T')
+        || matches(matrix[Location.BOUNDARY][Location.BOUNDARY], 'T');
+
+    return hasPointInCommon &&
+        matrix[Location.EXTERIOR][Location.INTERIOR] == Dimension.FALSE &&
+        matrix[Location.EXTERIOR][Location.BOUNDARY] == Dimension.FALSE;
+  }
+
+
+  /**
+   *  Returns <code>true</code> if this <code>IntersectionMatrix</code> is
+   *  T*F**FFF*.
+   *
+   *@param  dimensionOfGeometryA  the dimension of the first <code>Geometry</code>
+   *@param  dimensionOfGeometryB  the dimension of the second <code>Geometry</code>
+   *@return                       <code>true</code> if the two <code>Geometry</code>
+   *      s related by this <code>IntersectionMatrix</code> are equal; the
+   *      <code>Geometry</code>s must have the same dimension for this function
+   *      to return <code>true</code>
+   */
+  public boolean isEquals(int dimensionOfGeometryA, int dimensionOfGeometryB) {
+    if (dimensionOfGeometryA != dimensionOfGeometryB) {
+      return false;
+    }
+    return matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T') &&
+        matrix[Location.EXTERIOR][Location.INTERIOR] == Dimension.FALSE &&
+        matrix[Location.INTERIOR][Location.EXTERIOR] == Dimension.FALSE &&
+        matrix[Location.EXTERIOR][Location.BOUNDARY] == Dimension.FALSE &&
+        matrix[Location.BOUNDARY][Location.EXTERIOR] == Dimension.FALSE;
+  }
+
+  /**
+   *  Returns <code>true</code> if this <code>IntersectionMatrix</code> is
+   *  <UL>
+   *    <LI> T*T***T** (for two points or two surfaces)
+   *    <LI> 1*T***T** (for two curves)
+   *  </UL>.
+   *
+   *@param  dimensionOfGeometryA  the dimension of the first <code>Geometry</code>
+   *@param  dimensionOfGeometryB  the dimension of the second <code>Geometry</code>
+   *@return                       <code>true</code> if the two <code>Geometry</code>s
+   *      related by this <code>IntersectionMatrix</code> overlap. For this
+   *      function to return <code>true</code>, the <code>Geometry</code>s must
+   *      be two points, two curves or two surfaces.
+   */
+  public boolean isOverlaps(int dimensionOfGeometryA, int dimensionOfGeometryB) {
+    if ((dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.P) ||
+        (dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.A)) {
+      return matches(matrix[Location.INTERIOR][Location.INTERIOR], 'T') &&
+          matches(matrix[Location.INTERIOR][Location.EXTERIOR], 'T') && matches(matrix[Location.EXTERIOR][Location.INTERIOR],
+          'T');
+    }
+    if (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.L) {
+      return matrix[Location.INTERIOR][Location.INTERIOR] == 1 &&
+          matches(matrix[Location.INTERIOR][Location.EXTERIOR], 'T') &&
+          matches(matrix[Location.EXTERIOR][Location.INTERIOR], 'T');
+    }
+    return false;
+  }
+
+  /**
+   *  Returns whether the elements of this <code>IntersectionMatrix</code>
+   *  satisfies the required dimension symbols.
+   *
+   *@param  requiredDimensionSymbols  nine dimension symbols with which to
+   *      compare the elements of this <code>IntersectionMatrix</code>. Possible
+   *      values are <code>{T, F, * , 0, 1, 2}</code>.
+   *@return                           <code>true</code> if this <code>IntersectionMatrix</code>
+   *      matches the required dimension symbols
+   */
+  public boolean matches(String requiredDimensionSymbols) {
+    if (requiredDimensionSymbols.length() != 9) {
+      throw new IllegalArgumentException("Should be length 9: " + requiredDimensionSymbols);
+    }
+    for (int ai = 0; ai < 3; ai++) {
+      for (int bi = 0; bi < 3; bi++) {
+        if (!matches(matrix[ai][bi], requiredDimensionSymbols.charAt(3 * ai +
+            bi))) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  /**
+   *  Transposes this IntersectionMatrix.
+   *
+   *@return    this <code>IntersectionMatrix</code> as a convenience
+   */
+  public IntersectionMatrix transpose() { // NO_UCD
+    int temp = matrix[1][0];
+    matrix[1][0] = matrix[0][1];
+    matrix[0][1] = temp;
+    temp = matrix[2][0];
+    matrix[2][0] = matrix[0][2];
+    matrix[0][2] = temp;
+    temp = matrix[2][1];
+    matrix[2][1] = matrix[1][2];
+    matrix[1][2] = temp;
+    return this;
+  }
+
+  /**
+   *  Returns a nine-character <code>String</code> representation of this <code>IntersectionMatrix</code>
+   *  .
+   *
+   *@return    the nine dimension symbols of this <code>IntersectionMatrix</code>
+   *      in row-major order.
+   */
+  public String toString() {
+    StringBuffer buf = new StringBuffer("123456789");
+    for (int ai = 0; ai < 3; ai++) {
+      for (int bi = 0; bi < 3; bi++) {
+        buf.setCharAt(3 * ai + bi, Dimension.toDimensionSymbol(matrix[ai][bi]));
+      }
+    }
+    return buf.toString();
+  }
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/LineSegment.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/LineSegment.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/LineSegment.java	(revision 28000)
@@ -0,0 +1,298 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import java.io.Serializable;
+
+import com.vividsolutions.jts.algorithm.CGAlgorithms;
+import com.vividsolutions.jts.algorithm.LineIntersector;
+import com.vividsolutions.jts.algorithm.RobustLineIntersector;
+
+/**
+ * Represents a line segment defined by two {@link Coordinate}s.
+ * Provides methods to compute various geometric properties
+ * and relationships of line segments.
+ * <p>
+ * This class is designed to be easily mutable (to the extent of
+ * having its contained points public).
+ * This supports a common pattern of reusing a single LineSegment
+ * object as a way of computing segment properties on the
+ * segments defined by arrays or lists of {@link Coordinate}s.
+ *
+ *@version 1.7
+ */
+public class LineSegment
+  implements Comparable<LineSegment>, Serializable
+{
+  private static final long serialVersionUID = 3252005833466256227L;
+
+  public Coordinate p0, p1;
+
+  public LineSegment(Coordinate p0, Coordinate p1) {
+    this.p0 = p0;
+    this.p1 = p1;
+  }
+
+
+  public LineSegment() {
+    this(new Coordinate(), new Coordinate());
+  }
+
+  public Coordinate getCoordinate(int i)
+  {
+    if (i == 0) return p0;
+    return p1;
+  }
+
+
+
+  /**
+   * Computes the distance between this line segment and a given point.
+   *
+   * @return the distance from this segment to the given point
+   */
+  public double distance(Coordinate p)
+  {
+    return CGAlgorithms.distancePointLine(p, p0, p1);
+  }
+
+
+
+  /**
+   * Computes the Projection Factor for the projection of the point p
+   * onto this LineSegment.  The Projection Factor is the constant r
+   * by which the vector for this segment must be multiplied to
+   * equal the vector for the projection of <tt>p<//t> on the line
+   * defined by this segment.
+   * <p>
+   * The projection factor returned will be in the range <tt>(-inf, +inf)</tt>.
+   * 
+   * @param p the point to compute the factor for
+   * @return the projection factor for the point
+   */
+  public double projectionFactor(Coordinate p)
+  {
+    if (p.equals(p0)) return 0.0;
+    if (p.equals(p1)) return 1.0;
+    // Otherwise, use comp.graphics.algorithms Frequently Asked Questions method
+    /*     	      AC dot AB
+                   r = ---------
+                         ||AB||^2
+                r has the following meaning:
+                r=0 P = A
+                r=1 P = B
+                r<0 P is on the backward extension of AB
+                r>1 P is on the forward extension of AB
+                0<r<1 P is interior to AB
+        */
+    double dx = p1.x - p0.x;
+    double dy = p1.y - p0.y;
+    double len2 = dx * dx + dy * dy;
+    double r = ( (p.x - p0.x) * dx + (p.y - p0.y) * dy )
+              / len2;
+    return r;
+  }
+
+
+  /**
+   * Compute the projection of a point onto the line determined
+   * by this line segment.
+   * <p>
+   * Note that the projected point
+   * may lie outside the line segment.  If this is the case,
+   * the projection factor will lie outside the range [0.0, 1.0].
+   */
+  public Coordinate project(Coordinate p)
+  {
+    if (p.equals(p0) || p.equals(p1)) return new Coordinate(p);
+
+    double r = projectionFactor(p);
+    Coordinate coord = new Coordinate();
+    coord.x = p0.x + r * (p1.x - p0.x);
+    coord.y = p0.y + r * (p1.y - p0.y);
+    return coord;
+  }
+
+  /**
+   * Computes the closest point on this line segment to another point.
+   * @param p the point to find the closest point to
+   * @return a Coordinate which is the closest point on the line segment to the point p
+   */
+  public Coordinate closestPoint(Coordinate p)
+  {
+    double factor = projectionFactor(p);
+    if (factor > 0 && factor < 1) {
+      return project(p);
+    }
+    double dist0 = p0.distance(p);
+    double dist1 = p1.distance(p);
+    if (dist0 < dist1)
+      return p0;
+    return p1;
+  }
+  /**
+   * Computes the closest points on two line segments.
+   * 
+   * @param line the segment to find the closest point to
+   * @return a pair of Coordinates which are the closest points on the line segments
+   */
+  public Coordinate[] closestPoints(LineSegment line)
+  {
+    // test for intersection
+    Coordinate intPt = intersection(line);
+    if (intPt != null) {
+      return new Coordinate[] { intPt, intPt };
+    }
+
+    /**
+     *  if no intersection closest pair contains at least one endpoint.
+     * Test each endpoint in turn.
+     */
+    Coordinate[] closestPt = new Coordinate[2];
+    double minDistance = Double.MAX_VALUE;
+    double dist;
+
+    Coordinate close00 = closestPoint(line.p0);
+    minDistance = close00.distance(line.p0);
+    closestPt[0] = close00;
+    closestPt[1] = line.p0;
+
+    Coordinate close01 = closestPoint(line.p1);
+    dist = close01.distance(line.p1);
+    if (dist < minDistance) {
+      minDistance = dist;
+      closestPt[0] = close01;
+      closestPt[1] = line.p1;
+    }
+
+    Coordinate close10 = line.closestPoint(p0);
+    dist = close10.distance(p0);
+    if (dist < minDistance) {
+      minDistance = dist;
+      closestPt[0] = p0;
+      closestPt[1] = close10;
+    }
+
+    Coordinate close11 = line.closestPoint(p1);
+    dist = close11.distance(p1);
+    if (dist < minDistance) {
+      minDistance = dist;
+      closestPt[0] = p1;
+      closestPt[1] = close11;
+    }
+
+    return closestPt;
+  }
+
+  /**
+   * Computes an intersection point between two line segments, if there is one.
+   * There may be 0, 1 or many intersection points between two segments.
+   * If there are 0, null is returned. If there is 1 or more, 
+   * exactly one of them is returned 
+   * (chosen at the discretion of the algorithm).  
+   * If more information is required about the details of the intersection,
+   * the {@link RobustLineIntersector} class should be used.
+   *
+   * @param line a line segment
+   * @return an intersection point, or <code>null</code> if there is none
+   * 
+   * @see RobustLineIntersector
+   */
+  public Coordinate intersection(LineSegment line)
+  {
+    LineIntersector li = new RobustLineIntersector();
+    li.computeIntersection(p0, p1, line.p0, line.p1);
+    if (li.hasIntersection())
+      return li.getIntersection(0);
+    return null;
+  }
+  
+  /**
+   *  Returns <code>true</code> if <code>other</code> has the same values for
+   *  its points.
+   *
+   *@param  o  a <code>LineSegment</code> with which to do the comparison.
+   *@return        <code>true</code> if <code>other</code> is a <code>LineSegment</code>
+   *      with the same values for the x and y ordinates.
+   */
+  public boolean equals(Object o) {
+    if (!(o instanceof LineSegment)) {
+      return false;
+    }
+    LineSegment other = (LineSegment) o;
+    return p0.equals(other.p0) && p1.equals(other.p1);
+  }
+
+  /**
+   * Gets a hashcode for this object.
+   * 
+   * @return a hashcode for this object
+   */
+  public int hashCode() {
+    long bits0 = java.lang.Double.doubleToLongBits(p0.x);
+    bits0 ^= java.lang.Double.doubleToLongBits(p0.y) * 31;
+    int hash0 = (((int) bits0) ^ ((int) (bits0  >> 32)));
+    
+    long bits1 = java.lang.Double.doubleToLongBits(p1.x);
+    bits1 ^= java.lang.Double.doubleToLongBits(p1.y) * 31;
+    int hash1 = (((int) bits1) ^ ((int) (bits1  >> 32)));
+
+    // XOR is supposed to be a good way to combine hashcodes
+    return hash0 ^ hash1;
+  }
+
+  /**
+   *  Compares this object with the specified object for order.
+   *  Uses the standard lexicographic ordering for the points in the LineSegment.
+   *
+   *@param  o  the <code>LineSegment</code> with which this <code>LineSegment</code>
+   *      is being compared
+   *@return    a negative integer, zero, or a positive integer as this <code>LineSegment</code>
+   *      is less than, equal to, or greater than the specified <code>LineSegment</code>
+   */
+  public int compareTo(LineSegment o) {
+    int comp0 = p0.compareTo(o.p0);
+    if (comp0 != 0) return comp0;
+    return p1.compareTo(o.p1);
+  }
+
+  public String toString()
+  {
+    return "LINESTRING( " +
+        p0.x + " " + p0.y
+        + ", " +
+        p1.x + " " + p1.y + ")";
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/LineString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/LineString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/LineString.java	(revision 28000)
@@ -0,0 +1,303 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import com.vividsolutions.jts.algorithm.CGAlgorithms;
+import com.vividsolutions.jts.operation.BoundaryOp;
+
+/**
+ *  Models an OGC-style <code>LineString</code>.
+ *  A LineString consists of a sequence of two or more vertices,
+ *  along with all points along the linearly-interpolated curves
+ *  (line segments) between each 
+ *  pair of consecutive vertices.
+ *  Consecutive vertices may be equal.
+ *  The line segments in the line may intersect each other (in other words, 
+ *  the linestring may "curl back" in itself and self-intersect.
+ *  Linestrings with exactly two identical points are invalid. 
+ *  <p> 
+ * A linestring must have either 0 or 2 or more points.  
+ * If these conditions are not met, the constructors throw 
+ * an {@link IllegalArgumentException}
+ *
+ *@version 1.7
+ */
+public class LineString 
+	extends Geometry 
+	implements Lineal
+{
+  private static final long serialVersionUID = 3110669828065365560L;
+  /**
+   *  The points of this <code>LineString</code>.
+   */
+  protected CoordinateSequence points;
+
+  /**
+   * Constructs a <code>LineString</code> with the given points.
+   *  
+   *@param  points          the points of the linestring, or <code>null</code>
+   *      to create the empty geometry. Consecutive points may not be equal.
+   * @throws IllegalArgumentException if too few points are provided
+   */
+  public LineString(CoordinateSequence points, GeometryFactory factory) {
+    super(factory);
+    init(points);
+  }
+
+  private void init(CoordinateSequence points)
+  {
+    if (points == null) {
+      points = getFactory().getCoordinateSequenceFactory().create(new Coordinate[]{});
+    }
+    if (points.size() == 1) {
+      throw new IllegalArgumentException("Invalid number of points in LineString (found " 
+      		+ points.size() + " - must be 0 or >= 2)");
+    }
+    this.points = points;
+  }
+  public Coordinate[] getCoordinates() {
+    return points.toCoordinateArray();
+  }
+
+  public CoordinateSequence getCoordinateSequence() {
+      return points;
+  }
+
+  public Coordinate getCoordinateN(int n) {
+      return points.getCoordinate(n);
+  }
+
+  public Coordinate getCoordinate()
+  {
+    if (isEmpty()) return null;
+    return points.getCoordinate(0);
+  }
+
+  public int getDimension() {
+    return 1;
+  }
+
+  public int getBoundaryDimension() {
+    if (isClosed()) {
+      return Dimension.FALSE;
+    }
+    return 0;
+  }
+
+  public boolean isEmpty() {
+      return points.size() == 0;
+  }
+
+  public int getNumPoints() {
+      return points.size();
+  }
+
+  public Point getPointN(int n) {
+      return getFactory().createPoint(points.getCoordinate(n));
+  }
+
+  public Point getStartPoint() {
+    if (isEmpty()) {
+      return null;
+    }
+    return getPointN(0);
+  }
+
+  public Point getEndPoint() {
+    if (isEmpty()) {
+      return null;
+    }
+    return getPointN(getNumPoints() - 1);
+  }
+
+  public boolean isClosed() {
+    if (isEmpty()) {
+      return false;
+    }
+    return getCoordinateN(0).equals2D(getCoordinateN(getNumPoints() - 1));
+  }
+
+  public String getGeometryType() {
+    return "LineString";
+  }
+
+  /**
+   *  Returns the length of this <code>LineString</code>
+   *
+   *@return the length of the linestring
+   */
+  public double getLength()
+  {
+   return CGAlgorithms.length(points);
+  }
+
+  /**
+   * Gets the boundary of this geometry.
+   * The boundary of a lineal geometry is always a zero-dimensional geometry (which may be empty).
+   *
+   * @return the boundary geometry
+   * @see Geometry#getBoundary
+   */
+  public Geometry getBoundary() {
+    return (new BoundaryOp(this)).getBoundary();
+  }
+
+  /**
+   * Creates a {@link LineString} whose coordinates are in the reverse
+   * order of this objects
+   *
+   * @return a {@link LineString} with coordinates in the reverse order
+   */
+  public Geometry reverse()
+  {
+    CoordinateSequence seq = (CoordinateSequence) points.clone();
+    CoordinateSequences.reverse(seq);
+    LineString revLine = getFactory().createLineString(seq);
+    return revLine;
+  }
+
+  protected Envelope computeEnvelopeInternal() {
+    if (isEmpty()) {
+      return new Envelope();
+    }
+    return points.expandEnvelope(new Envelope());
+  }
+
+  public boolean equalsExact(Geometry other, double tolerance) {
+    if (!isEquivalentClass(other)) {
+      return false;
+    }
+    LineString otherLineString = (LineString) other;
+    if (points.size() != otherLineString.points.size()) {
+      return false;
+    }
+    for (int i = 0; i < points.size(); i++) {
+      if (!equal(points.getCoordinate(i), otherLineString.points.getCoordinate(i), tolerance)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public void apply(CoordinateFilter filter) {
+      for (int i = 0; i < points.size(); i++) {
+        filter.filter(points.getCoordinate(i));
+      }
+  }
+
+  public void apply(CoordinateSequenceFilter filter) 
+  {
+    if (points.size() == 0)
+      return;
+    for (int i = 0; i < points.size(); i++) {
+      filter.filter(points, i);
+      if (filter.isDone())
+        break;
+    }
+    if (filter.isGeometryChanged())
+      geometryChanged();
+  }
+
+  public void apply(GeometryFilter filter) {
+    filter.filter(this);
+  }
+
+  public void apply(GeometryComponentFilter filter) {
+    filter.filter(this);
+  }
+
+  /**
+   * Creates and returns a full copy of this {@link LineString} object.
+   * (including all coordinates contained by it).
+   *
+   * @return a clone of this instance
+   */
+  public Object clone() {
+    LineString ls = (LineString) super.clone();
+    ls.points = (CoordinateSequence) points.clone();
+    return ls;
+  }
+
+  /**
+   * Normalizes a LineString.  A normalized linestring
+   * has the first point which is not equal to it's reflected point
+   * less than the reflected point.
+   */
+  public void normalize()
+  {
+      for (int i = 0; i < points.size() / 2; i++) {
+        int j = points.size() - 1 - i;
+        // skip equal points on both ends
+        if (!points.getCoordinate(i).equals(points.getCoordinate(j))) {
+          if (points.getCoordinate(i).compareTo(points.getCoordinate(j)) > 0) {
+            CoordinateArrays.reverse(getCoordinates());
+          }
+          return;
+        }
+      }
+  }
+
+  protected boolean isEquivalentClass(Geometry other) {
+    return other instanceof LineString;
+  }
+
+  protected int compareToSameClass(Object o)
+  {
+    LineString line = (LineString) o;
+    // MD - optimized implementation
+    int i = 0;
+    int j = 0;
+    while (i < points.size() && j < line.points.size()) {
+      int comparison = points.getCoordinate(i).compareTo(line.points.getCoordinate(j));
+      if (comparison != 0) {
+        return comparison;
+      }
+      i++;
+      j++;
+    }
+    if (i < points.size()) {
+      return 1;
+    }
+    if (j < line.points.size()) {
+      return -1;
+    }
+    return 0;
+  }
+
+  protected int compareToSameClass(Object o, CoordinateSequenceComparator comp)
+  {
+    LineString line = (LineString) o;
+    return comp.compare(this.points, line.points);
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Lineal.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Lineal.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Lineal.java	(revision 28000)
@@ -0,0 +1,12 @@
+package com.vividsolutions.jts.geom;
+
+/**
+ * Identifies {@link Geometry} subclasses which
+ * are 1-dimensional and have components which are {@link LineString}s. 
+ * 
+ * @author Martin Davis
+ *
+ */
+public interface Lineal {
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/LinearRing.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/LinearRing.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/LinearRing.java	(revision 28000)
@@ -0,0 +1,127 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+/**
+ * Models an OGC SFS <code>LinearRing</code>.
+ * A LinearRing is a LineString which is both closed and simple.
+ * In other words,
+ * the first and last coordinate in the ring must be equal,
+ * and the interior of the ring must not self-intersect.
+ * Either orientation of the ring is allowed.
+ * <p>
+ * A ring must have either 0 or 4 or more points.  
+ * The first and last points must be equal (in 2D).
+ * If these conditions are not met, the constructors throw 
+ * an {@link IllegalArgumentException}
+ *
+ * @version 1.7
+ */
+public class LinearRing extends LineString
+{
+  /**
+   * The minimum number of vertices allowed in a valid non-empty ring (= 4).
+   * Empty rings with 0 vertices are also valid.
+   */
+  public static final int MINIMUM_VALID_SIZE = 4;
+  
+  private static final long serialVersionUID = -4261142084085851829L;
+
+  /**
+   * Constructs a <code>LinearRing</code> with the vertices
+   * specifed by the given {@link CoordinateSequence}.
+   *
+   *@param  points  a sequence points forming a closed and simple linestring, or
+   *      <code>null</code> to create the empty geometry.
+   *      
+   * @throws IllegalArgumentException if the ring is not closed, or has too few points
+   *
+   */
+  public LinearRing(CoordinateSequence points, GeometryFactory factory) {
+    super(points, factory);
+    validateConstruction();
+  }
+
+  private void validateConstruction() {
+    if (!isEmpty() && ! super.isClosed()) {
+      throw new IllegalArgumentException("Points of LinearRing do not form a closed linestring");
+    }
+    if (getCoordinateSequence().size() >= 1 && getCoordinateSequence().size() < MINIMUM_VALID_SIZE) {
+      throw new IllegalArgumentException("Invalid number of points in LinearRing (found " 
+      		+ getCoordinateSequence().size() + " - must be 0 or >= 4)");
+    }
+  }
+
+  /**
+   * Returns <code>Dimension.FALSE</code>, since by definition LinearRings do
+   * not have a boundary.
+   *
+   * @return Dimension.FALSE
+   */
+  public int getBoundaryDimension() {
+    return Dimension.FALSE;
+  }
+
+  /**
+   * Returns <code>true</code>, since by definition LinearRings are always simple.
+   * @return <code>true</code>
+   *
+   * @see Geometry#isSimple
+   */
+  public boolean isSimple() {
+    return true;
+  }
+
+  public boolean isClosed() {
+    if (isEmpty()) {
+    	// empty LinearRings are closed by definition
+      return true;
+    }
+    return super.isClosed();
+  }
+
+
+  public String getGeometryType() {
+    return "LinearRing";
+  }
+
+  public Geometry reverse()
+  {
+    CoordinateSequence seq = (CoordinateSequence) points.clone();
+    CoordinateSequences.reverse(seq);
+    LinearRing rev = getFactory().createLinearRing(seq);
+    return rev;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Location.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Location.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Location.java	(revision 28000)
@@ -0,0 +1,92 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+/**
+ *  Constants representing the different topological locations
+ *  which can occur in a {@link Geometry}. 
+ *  The constants are also used as the row and column indices 
+ *  of DE-9IM {@link IntersectionMatrix}es. 
+ *
+ *@version 1.7
+ */
+public class Location {
+  /**
+   * The location value for the interior of a geometry.
+   * Also, DE-9IM row index of the interior of the first geometry and column index of
+   *  the interior of the second geometry. 
+   */
+  public final static int INTERIOR = 0;
+  /**
+   * The location value for the boundary of a geometry.
+   * Also, DE-9IM row index of the boundary of the first geometry and column index of
+   *  the boundary of the second geometry. 
+   */
+  public final static int BOUNDARY = 1;
+  /**
+   * The location value for the exterior of a geometry.
+   * Also, DE-9IM row index of the exterior of the first geometry and column index of
+   *  the exterior of the second geometry. 
+   */
+  public final static int EXTERIOR = 2;
+
+  /**
+   *  Used for uninitialized location values.
+   */
+  public final static int NONE = -1;
+
+  /**
+   *  Converts the location value to a location symbol, for example, <code>EXTERIOR => 'e'</code>
+   *  .
+   *
+   *@param  locationValue  either EXTERIOR, BOUNDARY, INTERIOR or NONE
+   *@return                either 'e', 'b', 'i' or '-'
+   */
+  public static char toLocationSymbol(int locationValue) {
+    switch (locationValue) {
+      case EXTERIOR:
+        return 'e';
+      case BOUNDARY:
+        return 'b';
+      case INTERIOR:
+        return 'i';
+      case NONE:
+        return '-';
+    }
+    throw new IllegalArgumentException("Unknown location value: " + locationValue);
+  }
+}
+
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/MultiLineString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/MultiLineString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/MultiLineString.java	(revision 28000)
@@ -0,0 +1,127 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import com.vividsolutions.jts.operation.BoundaryOp;
+
+/**
+ * Models a collection of (@link LineString}s.
+ * <p>
+ * Any collection of LineStrings is a valid MultiLineString.
+ *
+ *@version 1.7
+ */
+public class MultiLineString 
+	extends GeometryCollection
+	implements Lineal
+	{
+  private static final long serialVersionUID = 8166665132445433741L;
+
+  /**
+   * @param lineStrings
+   *            the <code>LineString</code>s for this <code>MultiLineString</code>,
+   *            or <code>null</code> or an empty array to create the empty
+   *            geometry. Elements may be empty <code>LineString</code>s,
+   *            but not <code>null</code>s.
+   */
+  public MultiLineString(LineString[] lineStrings, GeometryFactory factory) {
+    super(lineStrings, factory);
+  }
+
+  public int getDimension() {
+    return 1;
+  }
+
+  public int getBoundaryDimension() {
+    if (isClosed()) {
+      return Dimension.FALSE;
+    }
+    return 0;
+  }
+
+  public String getGeometryType() {
+    return "MultiLineString";
+  }
+
+  public boolean isClosed() {
+    if (isEmpty()) {
+      return false;
+    }
+    for (int i = 0; i < geometries.length; i++) {
+      if (!((LineString) geometries[i]).isClosed()) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Gets the boundary of this geometry.
+   * The boundary of a lineal geometry is always a zero-dimensional geometry (which may be empty).
+   *
+   * @return the boundary geometry
+   * @see Geometry#getBoundary
+   */
+  public Geometry getBoundary()
+  {
+    return (new BoundaryOp(this)).getBoundary();
+  }
+
+  /**
+   * Creates a {@link MultiLineString} in the reverse
+   * order to this object.
+   * Both the order of the component LineStrings
+   * and the order of their coordinate sequences
+   * are reversed.
+   *
+   * @return a {@link MultiLineString} in the reverse order
+   */
+  public Geometry reverse()
+  {
+    int nLines = geometries.length;
+    LineString[] revLines = new LineString[nLines];
+    for (int i = 0; i < geometries.length; i++) {
+      revLines[nLines - 1 - i] = (LineString)geometries[i].reverse();
+    }
+    return getFactory().createMultiLineString(revLines);
+  }
+
+  public boolean equalsExact(Geometry other, double tolerance) {
+    if (!isEquivalentClass(other)) {
+      return false;
+    }
+    return super.equalsExact(other, tolerance);
+  }
+
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/MultiPoint.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/MultiPoint.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/MultiPoint.java	(revision 28000)
@@ -0,0 +1,95 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+/**
+ * Models a collection of {@link Point}s.
+ * <p>
+ * Any collection of Points is a valid MultiPoint.
+ *
+ *@version 1.7
+ */
+public class MultiPoint
+  extends GeometryCollection
+  implements Puntal
+{
+
+  private static final long serialVersionUID = -8048474874175355449L;
+
+  /**
+   *@param  points          the <code>Point</code>s for this <code>MultiPoint</code>
+   *      , or <code>null</code> or an empty array to create the empty geometry.
+   *      Elements may be empty <code>Point</code>s, but not <code>null</code>s.
+   */
+  public MultiPoint(Point[] points, GeometryFactory factory) {
+    super(points, factory);
+  }
+
+  public int getDimension() {
+    return 0;
+  }
+
+  public int getBoundaryDimension() {
+    return Dimension.FALSE;
+  }
+
+  public String getGeometryType() {
+    return "MultiPoint";
+  }
+
+  /**
+   * Gets the boundary of this geometry.
+   * Zero-dimensional geometries have no boundary by definition,
+   * so an empty GeometryCollection is returned.
+   *
+   * @return an empty GeometryCollection
+   * @see Geometry#getBoundary
+   */
+  public Geometry getBoundary() {
+    return getFactory().createGeometryCollection(null);
+  }
+
+  public boolean isValid() {
+    return true;
+  }
+
+  public boolean equalsExact(Geometry other, double tolerance) {
+    if (!isEquivalentClass(other)) {
+      return false;
+    }
+    return super.equalsExact(other, tolerance);
+  }
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/MultiPolygon.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/MultiPolygon.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/MultiPolygon.java	(revision 28000)
@@ -0,0 +1,134 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import java.util.ArrayList;
+
+/**
+ * Models a collection of {@link Polygon}s.
+ * <p>
+ * As per the OGC SFS specification, 
+ * the Polygons in a MultiPolygon may not overlap, 
+ * and may only touch at single points.
+ * This allows the topological point-set semantics
+ * to be well-defined.
+ *  
+ *
+ *@version 1.7
+ */
+public class MultiPolygon 
+	extends GeometryCollection 
+	implements Polygonal
+{
+  private static final long serialVersionUID = -551033529766975875L;
+
+  /**
+   * @param polygons
+   *            the <code>Polygon</code>s for this <code>MultiPolygon</code>,
+   *            or <code>null</code> or an empty array to create the empty
+   *            geometry. Elements may be empty <code>Polygon</code>s, but
+   *            not <code>null</code>s. The polygons must conform to the
+   *            assertions specified in the <A
+   *            HREF="http://www.opengis.org/techno/specs.htm">OpenGIS Simple
+   *            Features Specification for SQL</A>.
+   */
+  public MultiPolygon(Polygon[] polygons, GeometryFactory factory) {
+    super(polygons, factory);
+  }
+
+  public int getDimension() {
+    return 2;
+  }
+
+  public int getBoundaryDimension() {
+    return 1;
+  }
+
+  public String getGeometryType() {
+    return "MultiPolygon";
+  }
+
+  public boolean isSimple() {
+    return true;
+  }
+
+  /**
+   * Computes the boundary of this geometry
+   *
+   * @return a lineal geometry (which may be empty)
+   * @see Geometry#getBoundary
+   */
+  public Geometry getBoundary() {
+    if (isEmpty()) {
+      return getFactory().createMultiLineString(null);
+    }
+    ArrayList allRings = new ArrayList();
+    for (int i = 0; i < geometries.length; i++) {
+      Polygon polygon = (Polygon) geometries[i];
+      Geometry rings = polygon.getBoundary();
+      for (int j = 0; j < rings.getNumGeometries(); j++) {
+        allRings.add(rings.getGeometryN(j));
+      }
+    }
+    LineString[] allRingsArray = new LineString[allRings.size()];
+    return getFactory().createMultiLineString((LineString[]) allRings.toArray(allRingsArray));
+  }
+
+  public boolean equalsExact(Geometry other, double tolerance) {
+    if (!isEquivalentClass(other)) {
+      return false;
+    }
+    return super.equalsExact(other, tolerance);
+  }
+  
+  /**
+   * Creates a {@link MultiPolygon} with
+   * every component reversed.
+   * The order of the components in the collection are not reversed.
+   *
+   * @return a MultiPolygon in the reverse order
+   */
+  public Geometry reverse()
+  {
+    int n = geometries.length;
+    Polygon[] revGeoms = new Polygon[n];
+    for (int i = 0; i < geometries.length; i++) {
+      revGeoms[i] = (Polygon) geometries[i].reverse();
+    }
+    return getFactory().createMultiPolygon(revGeoms);
+  }
+}
+
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Point.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Point.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Point.java	(revision 28000)
@@ -0,0 +1,215 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ *  Implementation of <code>Point</code>.
+ *
+ * A Point is valid iff:
+ * <ul>
+ * <li>the coordinate which defines it is a valid coordinate (i.e does not have an NaN X or Y ordinate)
+ * </ul>
+ * 
+ *@version 1.7
+ */
+public class Point 
+	extends Geometry
+	implements Puntal
+{
+  private static final long serialVersionUID = 4902022702746614570L;
+  /**
+   *  The <code>Coordinate</code> wrapped by this <code>Point</code>.
+   */
+  private CoordinateSequence coordinates;
+
+  /**
+   *@param  coordinates      contains the single coordinate on which to base this <code>Point</code>
+   *      , or <code>null</code> to create the empty geometry.
+   */
+  public Point(CoordinateSequence coordinates, GeometryFactory factory) {
+    super(factory);
+    init(coordinates);
+  }
+
+  private void init(CoordinateSequence coordinates)
+  {
+    if (coordinates == null) {
+      coordinates = getFactory().getCoordinateSequenceFactory().create(new Coordinate[]{});
+    }
+    Assert.isTrue(coordinates.size() <= 1);
+    this.coordinates = coordinates;
+  }
+
+  public Coordinate[] getCoordinates() {
+    return isEmpty() ? new Coordinate[]{} : new Coordinate[]{
+        getCoordinate()
+        };
+  }
+
+  public int getNumPoints() {
+    return isEmpty() ? 0 : 1;
+  }
+
+  public boolean isEmpty() {
+    return getCoordinate() == null;
+  }
+
+  public boolean isSimple() {
+    return true;
+  }
+
+  public int getDimension() {
+    return 0;
+  }
+
+  public int getBoundaryDimension() {
+    return Dimension.FALSE;
+  }
+
+  public double getX() {
+    if (getCoordinate() == null) {
+      throw new IllegalStateException("getX called on empty Point");
+    }
+    return getCoordinate().x;
+  }
+
+  public double getY() {
+    if (getCoordinate() == null) {
+      throw new IllegalStateException("getY called on empty Point");
+    }
+    return getCoordinate().y;
+  }
+
+  public Coordinate getCoordinate() {
+    return coordinates.size() != 0 ? coordinates.getCoordinate(0): null;
+  }
+
+  public String getGeometryType() {
+    return "Point";
+  }
+
+  /**
+   * Gets the boundary of this geometry.
+   * Zero-dimensional geometries have no boundary by definition,
+   * so an empty GeometryCollection is returned.
+   *
+   * @return an empty GeometryCollection
+   * @see Geometry#getBoundary
+   */
+  public Geometry getBoundary() {
+    return getFactory().createGeometryCollection(null);
+  }
+
+  protected Envelope computeEnvelopeInternal() {
+    if (isEmpty()) {
+      return new Envelope();
+    }
+    Envelope env = new Envelope();
+    env.expandToInclude(coordinates.getX(0), coordinates.getY(0));
+    return env;
+  }
+
+  public boolean equalsExact(Geometry other, double tolerance) {
+    if (!isEquivalentClass(other)) {
+      return false;
+    }
+    if (isEmpty() && other.isEmpty()) {
+      return true;
+    }
+    return equal(((Point) other).getCoordinate(), this.getCoordinate(), tolerance);
+  }
+
+  public void apply(CoordinateFilter filter) {
+	    if (isEmpty()) { return; }
+	    filter.filter(getCoordinate());
+	  }
+
+  public void apply(CoordinateSequenceFilter filter) 
+  {
+	    if (isEmpty())
+        return;
+	    filter.filter(coordinates, 0);
+      if (filter.isGeometryChanged())
+        geometryChanged();
+	  }
+
+  public void apply(GeometryFilter filter) {
+    filter.filter(this);
+  }
+
+  public void apply(GeometryComponentFilter filter) {
+    filter.filter(this);
+  }
+
+  /**
+   * Creates and returns a full copy of this {@link Point} object.
+   * (including all coordinates contained by it).
+   *
+   * @return a clone of this instance
+   */
+  public Object clone() {
+    Point p = (Point) super.clone();
+    p.coordinates = (CoordinateSequence) coordinates.clone();
+    return p;// return the clone
+  }
+
+  public Geometry reverse()
+  {
+    return (Geometry) clone();
+  }
+  
+  public void normalize() 
+  { 
+    // a Point is always in normalized form 
+  }
+
+  protected int compareToSameClass(Object other) {
+    Point point = (Point) other;
+    return getCoordinate().compareTo(point.getCoordinate());
+  }
+
+  protected int compareToSameClass(Object other, CoordinateSequenceComparator comp)
+  {
+    Point point = (Point) other;
+    return comp.compare(this.coordinates, point.coordinates);
+  }
+
+  public CoordinateSequence getCoordinateSequence() {
+    return coordinates;
+  }
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Polygon.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Polygon.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Polygon.java	(revision 28000)
@@ -0,0 +1,402 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import java.util.Arrays;
+
+import com.vividsolutions.jts.algorithm.CGAlgorithms;
+
+/**
+ * Represents a linear polygon, which may include holes.
+ * The shell and holes of the polygon are represented by {@link LinearRing}s.
+ * In a valid polygon, holes may touch the shell or other holes at a single point.
+ * However, no sequence of touching holes may split the polygon into two pieces.
+ * The orientation of the rings in the polygon does not matter.
+ * <p>
+ *  The shell and holes must conform to the assertions specified in the <A
+ *  HREF="http://www.opengis.org/techno/specs.htm">OpenGIS Simple Features
+ *  Specification for SQL</A> .
+ *
+ *@version 1.7
+ */
+public class Polygon 
+	extends Geometry
+	implements Polygonal
+{
+  private static final long serialVersionUID = -3494792200821764533L;
+
+  /**
+   *  The exterior boundary,
+   * or <code>null</code> if this <code>Polygon</code>
+   *  is empty.
+   */
+  protected LinearRing shell = null;
+
+  /**
+   * The interior boundaries, if any.
+   * This instance var is never null.
+   * If there are no holes, the array is of zero length.
+   */
+  protected LinearRing[] holes;
+
+  /**
+   *  Constructs a <code>Polygon</code> with the given exterior boundary and
+   *  interior boundaries.
+   *
+   *@param  shell           the outer boundary of the new <code>Polygon</code>,
+   *      or <code>null</code> or an empty <code>LinearRing</code> if the empty
+   *      geometry is to be created.
+   *@param  holes           the inner boundaries of the new <code>Polygon</code>
+   *      , or <code>null</code> or empty <code>LinearRing</code>s if the empty
+   *      geometry is to be created.
+   */
+  public Polygon(LinearRing shell, LinearRing[] holes, GeometryFactory factory) {
+    super(factory);
+    if (shell == null) {
+      shell = getFactory().createLinearRing((CoordinateSequence)null);
+    }
+    if (holes == null) {
+      holes = new LinearRing[]{};
+    }
+    if (hasNullElements(holes)) {
+      throw new IllegalArgumentException("holes must not contain null elements");
+    }
+    if (shell.isEmpty() && hasNonEmptyElements(holes)) {
+      throw new IllegalArgumentException("shell is empty but holes are not");
+    }
+    this.shell = shell;
+    this.holes = holes;
+  }
+
+  public Coordinate getCoordinate() {
+    return shell.getCoordinate();
+  }
+
+  public Coordinate[] getCoordinates() {
+    if (isEmpty()) {
+      return new Coordinate[]{};
+    }
+    Coordinate[] coordinates = new Coordinate[getNumPoints()];
+    int k = -1;
+    Coordinate[] shellCoordinates = shell.getCoordinates();
+    for (int x = 0; x < shellCoordinates.length; x++) {
+      k++;
+      coordinates[k] = shellCoordinates[x];
+    }
+    for (int i = 0; i < holes.length; i++) {
+      Coordinate[] childCoordinates = holes[i].getCoordinates();
+      for (int j = 0; j < childCoordinates.length; j++) {
+        k++;
+        coordinates[k] = childCoordinates[j];
+      }
+    }
+    return coordinates;
+  }
+
+  public int getNumPoints() {
+    int numPoints = shell.getNumPoints();
+    for (int i = 0; i < holes.length; i++) {
+      numPoints += holes[i].getNumPoints();
+    }
+    return numPoints;
+  }
+
+  public int getDimension() {
+    return 2;
+  }
+
+  public int getBoundaryDimension() {
+    return 1;
+  }
+
+  public boolean isEmpty() {
+    return shell.isEmpty();
+  }
+
+  /**
+   * Tests if a valid polygon is simple.
+   * This method always returns true, since a valid polygon is always simple
+   *
+   * @return <code>true</code>
+   */
+  public boolean isSimple() {
+    return true;
+  }
+
+  public boolean isRectangle()
+  {
+    if (getNumInteriorRing() != 0) return false;
+    if (shell == null) return false;
+    if (shell.getNumPoints() != 5) return false;
+
+    CoordinateSequence seq = shell.getCoordinateSequence();
+
+    // check vertices have correct values
+    Envelope env = getEnvelopeInternal();
+    for (int i = 0; i < 5; i++) {
+      double x = seq.getX(i);
+      if (! (x == env.getMinX() || x == env.getMaxX())) return false;
+      double y = seq.getY(i);
+      if (! (y == env.getMinY() || y == env.getMaxY())) return false;
+    }
+
+    // check vertices are in right order
+    double prevX = seq.getX(0);
+    double prevY = seq.getY(0);
+    for (int i = 1; i <= 4; i++) {
+      double x = seq.getX(i);
+      double y = seq.getY(i);
+      boolean xChanged = x != prevX;
+      boolean yChanged = y != prevY;
+      if (xChanged == yChanged)
+        return false;
+      prevX = x;
+      prevY = y;
+    }
+    return true;
+  }
+
+  public LineString getExteriorRing() {
+    return shell;
+  }
+
+  public int getNumInteriorRing() {
+    return holes.length;
+  }
+
+  public LineString getInteriorRingN(int n) {
+    return holes[n];
+  }
+
+  public String getGeometryType() {
+    return "Polygon";
+  }
+
+  /**
+   *  Returns the area of this <code>Polygon</code>
+   *
+   *@return the area of the polygon
+   */
+  public double getArea()
+  {
+    double area = 0.0;
+    area += Math.abs(CGAlgorithms.signedArea(shell.getCoordinateSequence()));
+    for (int i = 0; i < holes.length; i++) {
+      area -= Math.abs(CGAlgorithms.signedArea(holes[i].getCoordinateSequence()));
+    }
+    return area;
+  }
+
+  /**
+   *  Returns the perimeter of this <code>Polygon</code>
+   *
+   *@return the perimeter of the polygon
+   */
+  public double getLength()
+  {
+    double len = 0.0;
+    len += shell.getLength();
+    for (int i = 0; i < holes.length; i++) {
+      len += holes[i].getLength();
+    }
+    return len;
+  }
+
+  /**
+   * Computes the boundary of this geometry
+   *
+   * @return a lineal geometry (which may be empty)
+   * @see Geometry#getBoundary
+   */
+  public Geometry getBoundary() {
+    if (isEmpty()) {
+      return getFactory().createMultiLineString(null);
+    }
+    LinearRing[] rings = new LinearRing[holes.length + 1];
+    rings[0] = shell;
+    for (int i = 0; i < holes.length; i++) {
+      rings[i + 1] = holes[i];
+    }
+    // create LineString or MultiLineString as appropriate
+    if (rings.length <= 1)
+      return getFactory().createLinearRing(rings[0].getCoordinateSequence());
+    return getFactory().createMultiLineString(rings);
+  }
+
+  protected Envelope computeEnvelopeInternal() {
+    return shell.getEnvelopeInternal();
+  }
+
+  public boolean equalsExact(Geometry other, double tolerance) {
+    if (!isEquivalentClass(other)) {
+      return false;
+    }
+    Polygon otherPolygon = (Polygon) other;
+    Geometry thisShell = shell;
+    Geometry otherPolygonShell = otherPolygon.shell;
+    if (!thisShell.equalsExact(otherPolygonShell, tolerance)) {
+      return false;
+    }
+    if (holes.length != otherPolygon.holes.length) {
+      return false;
+    }
+    if (holes.length != otherPolygon.holes.length) {
+      return false;
+    }
+    for (int i = 0; i < holes.length; i++) {
+      if (!((Geometry) holes[i]).equalsExact(otherPolygon.holes[i], tolerance)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public void apply(CoordinateFilter filter) {
+	    shell.apply(filter);
+	    for (int i = 0; i < holes.length; i++) {
+	      holes[i].apply(filter);
+	    }
+	  }
+
+  public void apply(CoordinateSequenceFilter filter) 
+  {
+	    shell.apply(filter);
+      if (! filter.isDone()) {
+        for (int i = 0; i < holes.length; i++) {
+          holes[i].apply(filter);
+          if (filter.isDone()) 
+            break;
+        }
+      }
+      if (filter.isGeometryChanged())
+        geometryChanged();
+	  }
+
+  public void apply(GeometryFilter filter) {
+    filter.filter(this);
+  }
+
+  public void apply(GeometryComponentFilter filter) {
+    filter.filter(this);
+    shell.apply(filter);
+    for (int i = 0; i < holes.length; i++) {
+      holes[i].apply(filter);
+    }
+  }
+
+  /**
+   * Creates and returns a full copy of this {@link Polygon} object.
+   * (including all coordinates contained by it).
+   *
+   * @return a clone of this instance
+   */
+  public Object clone() {
+    Polygon poly = (Polygon) super.clone();
+    poly.shell = (LinearRing) shell.clone();
+    poly.holes = new LinearRing[holes.length];
+    for (int i = 0; i < holes.length; i++) {
+      poly.holes[i] = (LinearRing) holes[i].clone();
+    }
+    return poly;// return the clone
+  }
+
+  public Geometry convexHull() {
+    return getExteriorRing().convexHull();
+  }
+
+  public void normalize() {
+    normalize(shell, true);
+    for (int i = 0; i < holes.length; i++) {
+      normalize(holes[i], false);
+    }
+    Arrays.sort(holes);
+  }
+
+  protected int compareToSameClass(Object o) {
+    LinearRing thisShell = shell;
+    LinearRing otherShell = ((Polygon) o).shell;
+    return thisShell.compareToSameClass(otherShell);
+  }
+
+  protected int compareToSameClass(Object o, CoordinateSequenceComparator comp) {
+    Polygon poly = (Polygon) o;
+
+    LinearRing thisShell = shell;
+    LinearRing otherShell = poly.shell;
+    int shellComp = thisShell.compareToSameClass(otherShell, comp);
+    if (shellComp != 0) return shellComp;
+
+    int nHole1 = getNumInteriorRing();
+    int nHole2 = poly.getNumInteriorRing();
+    int i = 0;
+    while (i < nHole1 && i < nHole2) {
+      LinearRing thisHole = (LinearRing) getInteriorRingN(i);
+      LinearRing otherHole = (LinearRing) poly.getInteriorRingN(i);
+      int holeComp = thisHole.compareToSameClass(otherHole, comp);
+      if (holeComp != 0) return holeComp;
+      i++;
+    }
+    if (i < nHole1) return 1;
+    if (i < nHole2) return -1;
+    return 0;
+  }
+
+  private void normalize(LinearRing ring, boolean clockwise) {
+    if (ring.isEmpty()) {
+      return;
+    }
+    Coordinate[] uniqueCoordinates = new Coordinate[ring.getCoordinates().length - 1];
+    System.arraycopy(ring.getCoordinates(), 0, uniqueCoordinates, 0, uniqueCoordinates.length);
+    Coordinate minCoordinate = CoordinateArrays.minCoordinate(ring.getCoordinates());
+    CoordinateArrays.scroll(uniqueCoordinates, minCoordinate);
+    System.arraycopy(uniqueCoordinates, 0, ring.getCoordinates(), 0, uniqueCoordinates.length);
+    ring.getCoordinates()[uniqueCoordinates.length] = uniqueCoordinates[0];
+    if (CGAlgorithms.isCCW(ring.getCoordinates()) == clockwise) {
+      CoordinateArrays.reverse(ring.getCoordinates());
+    }
+  }
+
+  public Geometry reverse()
+  {
+    Polygon poly = (Polygon) super.clone();
+    poly.shell = (LinearRing) ((LinearRing) shell.clone()).reverse();
+    poly.holes = new LinearRing[holes.length];
+    for (int i = 0; i < holes.length; i++) {
+      poly.holes[i] = (LinearRing) ((LinearRing) holes[i].clone()).reverse();
+    }
+    return poly;// return the clone
+  }
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Polygonal.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Polygonal.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Polygonal.java	(revision 28000)
@@ -0,0 +1,14 @@
+package com.vividsolutions.jts.geom;
+
+/**
+ * Identifies {@link Geometry} subclasses which
+ * are 2-dimensional 
+ * and have components which have {@link Lineal} boundaries. 
+ * 
+ * @author Martin Davis
+ *
+ */
+public interface Polygonal 
+{
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/PrecisionModel.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/PrecisionModel.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/PrecisionModel.java	(revision 28000)
@@ -0,0 +1,311 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.vividsolutions.jts.io.WKTWriter;
+
+/**
+ * Specifies the precision model of the {@link Coordinate}s in a {@link Geometry}.
+ * In other words, specifies the grid of allowable
+ *  points for all <code>Geometry</code>s.
+ * <p>
+ * The {@link #makePrecise(Coordinate)} method allows rounding a coordinate to
+ * a "precise" value; that is, one whose
+ *  precision is known exactly.
+ *<p>
+ * Coordinates are assumed to be precise in geometries.
+ * That is, the coordinates are assumed to be rounded to the
+ * precision model given for the geometry.
+ * JTS input routines automatically round coordinates to the precision model
+ * before creating Geometries.
+ * All internal operations
+ * assume that coordinates are rounded to the precision model.
+ * Constructive methods (such as boolean operations) always round computed
+ * coordinates to the appropriate precision model.
+ * <p>
+ * Currently three types of precision model are supported:
+ * <ul>
+ * <li>FLOATING - represents full double precision floating point.
+ * This is the default precision model used in JTS
+ * <li>FLOATING_SINGLE - represents single precision floating point.
+ * <li>FIXED - represents a model with a fixed number of decimal places.
+ *  A Fixed Precision Model is specified by a scale factor.
+ *  The scale factor specifies the size of the grid which numbers are rounded to.
+ *  Input coordinates are mapped to fixed coordinates according to the following
+ *  equations:
+ *    <UL>
+ *      <LI> jtsPt.x = round( (inputPt.x * scale ) / scale
+ *      <LI> jtsPt.y = round( (inputPt.y * scale ) / scale
+ *    </UL>
+ * </ul>
+ * For example, to specify 3 decimal places of precision, use a scale factor
+ * of 1000. To specify -3 decimal places of precision (i.e. rounding to
+ * the nearest 1000), use a scale factor of 0.001.
+ * <p>
+ *  Coordinates are represented internally as Java double-precision values.
+ * Since Java uses the IEEE-394 floating point standard, this
+ *  provides 53 bits of precision. (Thus the maximum precisely representable
+ *  integer is 9,007,199,254,740,992).
+ *<p>
+ *  JTS methods currently do not handle inputs with different precision models.
+ *
+ *@version 1.7
+ */
+public class PrecisionModel implements Serializable, Comparable<PrecisionModel>
+{
+
+  private static final long serialVersionUID = 7777263578777803835L;
+
+  /**
+   * The types of Precision Model which JTS supports.
+   */
+  public static class Type
+      implements Serializable
+  {
+    private static final long serialVersionUID = -5528602631731589822L;
+    private static Map<String, Type> nameToTypeMap = new HashMap<String, Type>();
+    public Type(String name) {
+        this.name = name;
+        nameToTypeMap.put(name, this);
+    }
+    private String name;
+    public String toString() { return name; }
+    
+    
+    /*
+     * Ssee http://www.javaworld.com/javaworld/javatips/jw-javatip122.html
+     */
+    private Object readResolve() {
+        return nameToTypeMap.get(name);
+    }
+  }
+
+  /**
+   * Fixed Precision indicates that coordinates have a fixed number of decimal places.
+   * The number of decimal places is determined by the log10 of the scale factor.
+   */
+  public static final Type FIXED = new Type("FIXED");
+  /**
+   * Floating precision corresponds to the standard Java
+   * double-precision floating-point representation, which is
+   * based on the IEEE-754 standard
+   */
+  public static final Type FLOATING = new Type("FLOATING");
+  /**
+   * Floating single precision corresponds to the standard Java
+   * single-precision floating-point representation, which is
+   * based on the IEEE-754 standard
+   */
+  public static final Type FLOATING_SINGLE = new Type("FLOATING SINGLE");
+
+  /**
+   * The type of PrecisionModel this represents.
+   */
+  private Type modelType;
+  /**
+   * The scale factor which determines the number of decimal places in fixed precision.
+   */
+  private double scale;
+
+  /**
+   * Creates a <code>PrecisionModel</code> with a default precision
+   * of FLOATING.
+   */
+  public PrecisionModel() {
+    // default is floating precision
+    modelType = FLOATING;
+  }
+
+  /**
+   * Returns the maximum number of significant digits provided by this
+   * precision model.
+   * Intended for use by routines which need to print out 
+   * decimal representations of precise values (such as {@link WKTWriter}).
+   * <p>
+   * This method would be more correctly called
+   * <tt>getMinimumDecimalPlaces</tt>, 
+   * since it actually computes the number of decimal places
+   * that is required to correctly display the full
+   * precision of an ordinate value.
+   * <p>
+   * Since it is difficult to compute the required number of
+   * decimal places for scale factors which are not powers of 10,
+   * the algorithm uses a very rough approximation in this case.
+   * This has the side effect that for scale factors which are
+   * powers of 10 the value returned is 1 greater than the true value.
+   * 
+   *
+   * @return the maximum number of decimal places provided by this precision model
+   */
+  public int getMaximumSignificantDigits() {
+    int maxSigDigits = 16;
+    if (modelType == FLOATING) {
+      maxSigDigits = 16;
+    } else if (modelType == FLOATING_SINGLE) {
+      maxSigDigits = 6;
+    } else if (modelType == FIXED) {
+      maxSigDigits = 1 + (int) Math.ceil(Math.log(getScale()) / Math.log(10));
+    }
+    return maxSigDigits;
+  }
+
+  /**
+   * Returns the scale factor used to specify a fixed precision model.
+   * The number of decimal places of precision is 
+   * equal to the base-10 logarithm of the scale factor.
+   * Non-integral and negative scale factors are supported.
+   * Negative scale factors indicate that the places 
+   * of precision is to the left of the decimal point.  
+   *
+   *@return the scale factor for the fixed precision model
+   */
+  public double getScale() {
+    return scale;
+  }
+
+  /**
+   * Gets the type of this precision model
+   * @return the type of this precision model
+   * @see Type
+   */
+  public Type getType()
+  {
+    return modelType;
+  }
+
+  /**
+   * Rounds a numeric value to the PrecisionModel grid.
+   * Asymmetric Arithmetic Rounding is used, to provide
+   * uniform rounding behaviour no matter where the number is
+   * on the number line.
+   * <p>
+   * This method has no effect on NaN values.
+   * <p>
+   * <b>Note:</b> Java's <code>Math#rint</code> uses the "Banker's Rounding" algorithm,
+   * which is not suitable for precision operations elsewhere in JTS.
+   */
+  public double makePrecise(double val) 
+  {
+  	// don't change NaN values
+  	if (Double.isNaN(val)) return val;
+  	
+  	if (modelType == FLOATING_SINGLE) {
+  		float floatSingleVal = (float) val;
+  		return floatSingleVal;
+  	}
+  	if (modelType == FIXED) {
+            return Math.round(val * scale) / scale;
+//  		return Math.rint(val * scale) / scale;
+  	}
+  	// modelType == FLOATING - no rounding necessary
+  	return val;
+  }
+
+  /**
+   * Rounds a Coordinate to the PrecisionModel grid.
+   */
+  public void makePrecise(Coordinate coord)
+  {
+    // optimization for full precision
+    if (modelType == FLOATING) return;
+
+    coord.x = makePrecise(coord.x);
+    coord.y = makePrecise(coord.y);
+    //MD says it's OK that we're not makePrecise'ing the z [Jon Aquino]
+  }
+
+
+  public String toString() {
+  	String description = "UNKNOWN";
+  	if (modelType == FLOATING) {
+  		description = "Floating";
+  	} else if (modelType == FLOATING_SINGLE) {
+  		description = "Floating-Single";
+  	} else if (modelType == FIXED) {
+  		description = "Fixed (Scale=" + getScale() + ")";
+  	}
+  	return description;
+  }
+
+  public boolean equals(Object other) {
+    if (! (other instanceof PrecisionModel)) {
+      return false;
+    }
+    PrecisionModel otherPrecisionModel = (PrecisionModel) other;
+    return modelType == otherPrecisionModel.modelType
+        && scale == otherPrecisionModel.scale;
+  }
+  /**
+   *  Compares this {@link PrecisionModel} object with the specified object for order.
+   * A PrecisionModel is greater than another if it provides greater precision.
+   * The comparison is based on the value returned by the
+   * {@link #getMaximumSignificantDigits} method.
+   * This comparison is not strictly accurate when comparing floating precision models
+   * to fixed models; however, it is correct when both models are either floating or fixed.
+   *
+   *@param  o  the <code>PrecisionModel</code> with which this <code>PrecisionModel</code>
+   *      is being compared
+   *@return    a negative integer, zero, or a positive integer as this <code>PrecisionModel</code>
+   *      is less than, equal to, or greater than the specified <code>PrecisionModel</code>
+   */
+  public int compareTo(PrecisionModel o) {
+
+    int sigDigits = getMaximumSignificantDigits();
+    int otherSigDigits = o.getMaximumSignificantDigits();
+    return (new Integer(sigDigits)).compareTo(new Integer(otherSigDigits));
+//    if (sigDigits > otherSigDigits)
+//      return 1;
+//    else if
+//    if (modelType == FLOATING && other.modelType == FLOATING) return 0;
+//    if (modelType == FLOATING && other.modelType != FLOATING) return 1;
+//    if (modelType != FLOATING && other.modelType == FLOATING) return -1;
+//    if (modelType == FIXED && other.modelType == FIXED) {
+//      if (scale > other.scale)
+//        return 1;
+//      else if (scale < other.scale)
+//        return -1;
+//      else
+//        return 0;
+//    }
+//    Assert.shouldNeverReachHere("Unknown Precision Model type encountered");
+//    return 0;
+  }
+}
+
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Puntal.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Puntal.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/Puntal.java	(revision 28000)
@@ -0,0 +1,12 @@
+package com.vividsolutions.jts.geom;
+
+/**
+ * Identifies {@link Geometry} subclasses which
+ * are 0-dimensional and with components which are {@link Point}s. 
+ * 
+ * @author Martin Davis
+ *
+ */
+public interface Puntal {
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/TopologyException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/TopologyException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/TopologyException.java	(revision 28000)
@@ -0,0 +1,63 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom;
+
+/**
+ * Indicates an invalid or inconsistent topological situation encountered during processing
+ *
+ * @version 1.7
+ */
+public class TopologyException
+  extends RuntimeException
+{
+  private static String msgWithCoord(String msg, Coordinate pt)
+  {
+    if (pt != null)
+      return msg + " [ " + pt + " ]";
+    return msg;
+  }
+
+  public TopologyException(String msg)
+  {
+    super(msg);
+  }
+
+  public TopologyException(String msg, Coordinate pt)
+  {
+    super(msgWithCoord(msg, pt));
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/impl/CoordinateArraySequence.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/impl/CoordinateArraySequence.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/impl/CoordinateArraySequence.java	(revision 28000)
@@ -0,0 +1,213 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.impl;
+
+import java.io.Serializable;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * The {@link CoordinateSequence} implementation that {@link Geometry}s use by default.
+ * In this implementation, Coordinates returned by #toArray and #getCoordinate are live --
+ * modifications to them are actually changing the
+ * CoordinateSequence's underlying data.
+ *
+ * @version 1.7
+ */
+public class CoordinateArraySequence
+    implements CoordinateSequence, Serializable
+{
+  //With contributions from Markus Schaber [schabios@logi-track.com] 2004-03-26
+  private static final long serialVersionUID = -915438501601840650L;
+
+  private Coordinate[] coordinates;
+
+  /**
+   * Constructs a sequence based on the given array (the
+   * array is not copied).
+   *
+   * @param coordinates the coordinate array that will be referenced.
+   */
+  public CoordinateArraySequence(Coordinate[] coordinates) {
+    this.coordinates = coordinates;
+    if (coordinates == null)
+      this.coordinates = new Coordinate[0];
+  }
+
+  /**
+   * Constructs a sequence of a given size, populated
+   * with new {@link Coordinate}s.
+   *
+   * @param size the size of the sequence to create
+   */
+  public CoordinateArraySequence(int size) {
+    coordinates = new Coordinate[size];
+    for (int i = 0; i < size; i++) {
+      coordinates[i] = new Coordinate();
+    }
+  }
+
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequence#getDimension()
+   */
+  public int getDimension() { return 3; }
+
+  /**
+   * Get the Coordinate with index i.
+   *
+   * @param i
+   *                  the index of the coordinate
+   * @return the requested Coordinate instance
+   */
+  public Coordinate getCoordinate(int i) {
+    return coordinates[i];
+  }
+
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequence#getX(int)
+   */
+  public void getCoordinate(int index, Coordinate coord) {
+    coord.x = coordinates[index].x;
+    coord.y = coordinates[index].y;
+    coord.z = coordinates[index].z;
+  }
+
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequence#getX(int)
+   */
+  public double getX(int index) {
+    return coordinates[index].x;
+  }
+
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequence#getY(int)
+   */
+  public double getY(int index) {
+    return coordinates[index].y;
+  }
+
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequence#getOrdinate(int, int)
+   */
+  public double getOrdinate(int index, int ordinateIndex)
+  {
+    switch (ordinateIndex) {
+      case CoordinateSequence.X:  return coordinates[index].x;
+      case CoordinateSequence.Y:  return coordinates[index].y;
+      case CoordinateSequence.Z:  return coordinates[index].z;
+    }
+    return Double.NaN;
+  }
+
+  /**
+   * Creates a deep copy of the Object
+   *
+   * @return The deep copy
+   */
+  public Object clone() {
+    Coordinate[] cloneCoordinates = new Coordinate[size()];
+    for (int i = 0; i < coordinates.length; i++) {
+      cloneCoordinates[i] = (Coordinate) coordinates[i].clone();
+    }
+    return new CoordinateArraySequence(cloneCoordinates);
+  }
+  /**
+   * Returns the size of the coordinate sequence
+   *
+   * @return the number of coordinates
+   */
+  public int size() {
+    return coordinates.length;
+  }
+
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequence#setOrdinate(int, int, double)
+   */
+  public void setOrdinate(int index, int ordinateIndex, double value)
+  {
+    switch (ordinateIndex) {
+      case CoordinateSequence.X:
+        coordinates[index].x = value;
+        break;
+      case CoordinateSequence.Y:
+        coordinates[index].y = value;
+        break;
+      case CoordinateSequence.Z:
+        coordinates[index].z = value;
+        break;
+      default:
+          throw new IllegalArgumentException("invalid ordinateIndex");
+    }
+  }
+
+  /**
+   * This method exposes the internal Array of Coordinate Objects
+   *
+   * @return the Coordinate[] array.
+   */
+  public Coordinate[] toCoordinateArray() {
+    return coordinates;
+  }
+
+  public Envelope expandEnvelope(Envelope env)
+  {
+    for (int i = 0; i < coordinates.length; i++ ) {
+      env.expandToInclude(coordinates[i]);
+    }
+    return env;
+  }
+
+  /**
+   * Returns the string Representation of the coordinate array
+   *
+   * @return The string
+   */
+  public String toString() {
+    if (coordinates.length > 0) {
+      StringBuffer strBuf = new StringBuffer(17 * coordinates.length);
+      strBuf.append('(');
+      strBuf.append(coordinates[0]);
+      for (int i = 1; i < coordinates.length; i++) {
+        strBuf.append(", ");
+        strBuf.append(coordinates[i]);
+      }
+      strBuf.append(')');
+      return strBuf.toString();
+    } else {
+      return "()";
+    }
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/impl/CoordinateArraySequenceFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/impl/CoordinateArraySequenceFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/impl/CoordinateArraySequenceFactory.java	(revision 28000)
@@ -0,0 +1,89 @@
+/*
+* The JTS Topology Suite is a collection of Java classes that
+* implement the fundamental operations required to validate a given
+* geo-spatial data set to a known topological specification.
+*
+* Copyright (C) 2001 Vivid Solutions
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+* For more information, contact:
+*
+*     Vivid Solutions
+*     Suite #1A
+*     2328 Government Street
+*     Victoria BC  V8T 5G5
+*     Canada
+*
+*     (250)385-6040
+*     www.vividsolutions.com
+*/
+package com.vividsolutions.jts.geom.impl;
+
+import java.io.Serializable;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.CoordinateSequenceFactory;
+
+/**
+ * Creates {@link CoordinateSequence}s represented as an array of {@link Coordinate}s.
+ *
+ * @version 1.7
+ */
+public final class CoordinateArraySequenceFactory
+    implements CoordinateSequenceFactory, Serializable
+{
+  private static final long serialVersionUID = -4099577099607551657L;
+  private static CoordinateArraySequenceFactory instanceObject = new CoordinateArraySequenceFactory();
+
+  private CoordinateArraySequenceFactory() {
+  }
+
+  private Object readResolve() {
+  	// http://www.javaworld.com/javaworld/javatips/jw-javatip122.html
+    return CoordinateArraySequenceFactory.instance();
+  }
+
+  /**
+   * Returns the singleton instance of {@link CoordinateArraySequenceFactory}
+   */
+  public static CoordinateArraySequenceFactory instance() {
+    return instanceObject;
+  }
+
+  /**
+   * Returns a {@link CoordinateArraySequence} based on the given array (the array is
+   * not copied).
+   *
+   * @param coordinates
+   *            the coordinates, which may not be null nor contain null
+   *            elements
+   */
+  public CoordinateSequence create(Coordinate[] coordinates) {
+    return new CoordinateArraySequence(coordinates);
+  }
+
+  /**
+   * @see com.vividsolutions.jts.geom.CoordinateSequenceFactory#create(int, int)
+   *
+   * @throws IllegalArgumentException if the dimension is > 3
+   */
+  public CoordinateSequence create(int size, int dimension) {
+    if (dimension > 3)
+      throw new IllegalArgumentException("dimension must be <= 3");
+    return new CoordinateArraySequence(size);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/impl/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/impl/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/impl/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Implementations of interfaces for geometric structures.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/package.html	(revision 28000)
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Contains the <CODE>Geometry</CODE> interface hierarchy and supporting classes.
+<P>
+The Java Topology Suite (JTS) is a Java API that implements a core set of spatial data operations using an explicit precision model and robust geometric algorithms. JTS is intended to be used in the development of applications that support the validation, cleaning, integration and querying of spatial datasets.
+<P>
+JTS attempts to implement the OpenGIS Simple Features Specification (SFS) as accurately as possible.  In some cases the SFS is unclear or omits a specification; in this case JTS attempts to choose a reasonable and consistent alternative.  Differences from and elaborations of the SFS are documented in this specification.
+
+<h2>Package Specification</h2>
+
+<ul>
+  <li>Java Topology Suite Technical Specifications
+  <li><A HREF="http://www.opengis.org/techno/specs.htm">
+      OpenGIS Simple Features Specification for SQL</A>
+</ul>
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/AbstractPreparedPolygonContains.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/AbstractPreparedPolygonContains.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/AbstractPreparedPolygonContains.java	(revision 28000)
@@ -0,0 +1,248 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.prep;
+
+import java.util.List;
+
+import com.vividsolutions.jts.algorithm.LineIntersector;
+import com.vividsolutions.jts.algorithm.RobustLineIntersector;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geom.Polygonal;
+import com.vividsolutions.jts.noding.SegmentIntersectionDetector;
+import com.vividsolutions.jts.noding.SegmentStringUtil;
+
+/**
+ * A base class containing the logic for computes the <tt>contains</tt>
+ * and <tt>covers</tt> spatial relationship predicates
+ * for a {@link PreparedPolygon} relative to all other {@link Geometry} classes.
+ * Uses short-circuit tests and indexing to improve performance. 
+ * <p>
+ * Contains and covers are very similar, and differ only in how certain
+ * cases along the boundary are handled.  These cases require 
+ * full topological evaluation to handle, so all the code in 
+ * this class is common to both predicates.
+ * <p>
+ * It is not possible to short-circuit in all cases, in particular
+ * in the case where line segments of the test geometry touches the polygon linework.
+ * In this case full topology must be computed.
+ * (However, if the test geometry consists of only points, this 
+ * <i>can</i> be evaluated in an optimized fashion.
+ * 
+ * @author Martin Davis
+ *
+ */
+abstract class AbstractPreparedPolygonContains 
+	extends PreparedPolygonPredicate
+{
+	/**
+	 * This flag controls a difference between contains and covers.
+	 * 
+	 * For contains the value is true.
+	 * For covers the value is false.
+	 */
+	protected boolean requireSomePointInInterior = true; 
+	
+	// information about geometric situation
+	private boolean hasSegmentIntersection = false;
+  private boolean hasProperIntersection = false;
+  private boolean hasNonProperIntersection = false;
+	
+  /**
+   * Creates an instance of this operation.
+   * 
+   * @param prepPoly the PreparedPolygon to evaluate
+   */
+	public AbstractPreparedPolygonContains(PreparedPolygon prepPoly)
+	{
+		super(prepPoly);
+	}
+	
+	/**
+	 * Evaluate the <tt>contains</tt> or <tt>covers</tt> relationship
+	 * for the given geometry.
+	 * 
+	 * @param geom the test geometry
+	 * @return true if the test geometry is contained
+	 */
+	protected boolean eval(Geometry geom)
+	{
+		/**
+		 * Do point-in-poly tests first, since they are cheaper and may result
+		 * in a quick negative result.
+		 * 
+		 * If a point of any test components does not lie in target, result is false
+		 */
+		boolean isAllInTargetArea = isAllTestComponentsInTarget(geom);
+		if (! isAllInTargetArea) return false;
+		
+		/**
+		 * If the test geometry consists of only Points, 
+		 * then it is now sufficient to test if any of those
+		 * points lie in the interior of the target geometry.
+		 * If so, the test is contained.
+		 * If not, all points are on the boundary of the area,
+		 * which implies not contained.
+		 */
+		if (requireSomePointInInterior
+				&& geom.getDimension() == 0) {
+			boolean isAnyInTargetInterior = isAnyTestComponentInTargetInterior(geom);
+			return isAnyInTargetInterior;
+		}
+		
+		/**
+		 * Check if there is any intersection between the line segments
+		 * in target and test.
+		 * In some important cases, finding a proper interesection implies that the 
+		 * test geometry is NOT contained.
+		 * These cases are:
+		 * <ul>
+		 * <li>If the test geometry is polygonal
+		 * <li>If the target geometry is a single polygon with no holes
+		 * <ul>
+		 * In both of these cases, a proper intersection implies that there
+		 * is some portion of the interior of the test geometry lying outside
+		 * the target, which means that the test is not contained.
+		 */
+		boolean properIntersectionImpliesNotContained = isProperIntersectionImpliesNotContainedSituation(geom);
+		// MD - testing only
+//		properIntersectionImpliesNotContained = true;
+		
+    // find all intersection types which exist
+    findAndClassifyIntersections(geom);
+		
+		if (properIntersectionImpliesNotContained && hasProperIntersection)
+			return false;
+		
+    /**
+     * If all intersections are proper 
+     * (i.e. no non-proper intersections occur)
+     * we can conclude that the test geometry is not contained in the target area,
+     * by the Epsilon-Neighbourhood Exterior Intersection condition.
+     * In real-world data this is likely to be by far the most common situation, 
+     * since natural data is unlikely to have many exact vertex segment intersections.
+     * Thus this check is very worthwhile, since it avoid having to perform
+     * a full topological check.
+     * 
+     * (If non-proper (vertex) intersections ARE found, this may indicate
+     * a situation where two shells touch at a single vertex, which admits
+     * the case where a line could cross between the shells and still be wholely contained in them.
+     */
+		if (hasSegmentIntersection && ! hasNonProperIntersection)
+      return false;
+    
+		/**
+		 * If there is a segment intersection and the situation is not one
+		 * of the ones above, the only choice is to compute the full topological
+		 * relationship.  This is because contains/covers is very sensitive 
+		 * to the situation along the boundary of the target.
+		 */
+		if (hasSegmentIntersection) {
+			return fullTopologicalPredicate(geom);
+//			System.out.println(geom);
+		}
+				
+		/**
+		 * This tests for the case where a ring of the target lies inside
+		 * a test polygon - which implies the exterior of the Target
+		 * intersects the interior of the Test, and hence the result is false
+		 */
+		if (geom instanceof Polygonal) {
+			// TODO: generalize this to handle GeometryCollections
+			boolean isTargetInTestArea = isAnyTargetComponentInAreaTest(geom, prepPoly.getRepresentativePoints());
+			if (isTargetInTestArea) return false;
+		}
+		return true;
+	}
+	
+	private boolean isProperIntersectionImpliesNotContainedSituation(Geometry testGeom)
+	{
+    /**
+     * If the test geometry is polygonal we have the A/A situation.
+     * In this case, a proper intersection indicates that 
+     * the Epsilon-Neighbourhood Exterior Intersection condition exists.
+     * This condition means that in some small
+     * area around the intersection point, there must exist a situation
+     * where the interior of the test intersects the exterior of the target.
+     * This implies the test is NOT contained in the target. 
+     */
+		if (testGeom instanceof Polygonal) return true;
+    /**
+     * A single shell with no holes allows concluding that 
+     * a proper intersection implies not contained 
+     * (due to the Epsilon-Neighbourhood Exterior Intersection condition) 
+     */
+		if (isSingleShell(prepPoly.getGeometry())) return true;
+		return false;
+	}
+	
+  /**
+   * Tests whether a geometry consists of a single polygon with no holes.
+   *  
+   * @return true if the geometry is a single polygon with no holes
+   */
+	private boolean isSingleShell(Geometry geom)
+	{
+    // handles single-element MultiPolygons, as well as Polygons
+		if (geom.getNumGeometries() != 1) return false;
+		
+		Polygon poly = (Polygon) geom.getGeometryN(0);
+		int numHoles = poly.getNumInteriorRing();
+		if (numHoles == 0) return true;
+		return false;
+	}
+	
+	private void findAndClassifyIntersections(Geometry geom)
+	{
+    List lineSegStr = SegmentStringUtil.extractSegmentStrings(geom);
+    
+	  LineIntersector li = new RobustLineIntersector();
+		SegmentIntersectionDetector intDetector = new SegmentIntersectionDetector(li);
+		intDetector.setFindAllIntersectionTypes(true);
+		prepPoly.getIntersectionFinder().intersects(lineSegStr, intDetector);
+			
+		hasSegmentIntersection = intDetector.hasIntersection();
+    hasProperIntersection = intDetector.hasProperIntersection();
+    hasNonProperIntersection = intDetector.hasNonProperIntersection();
+	}
+			
+	/**
+	 * Computes the full topological predicate.
+	 * Used when short-circuit tests are not conclusive.
+	 * 
+	 * @param geom the test geometry
+	 * @return true if this prepared polygon has the relationship with the test geometry
+	 */
+	protected abstract boolean fullTopologicalPredicate(Geometry geom);
+	
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/BasicPreparedGeometry.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/BasicPreparedGeometry.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/BasicPreparedGeometry.java	(revision 28000)
@@ -0,0 +1,184 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.prep;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.algorithm.PointLocator;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.util.ComponentCoordinateExtracter;
+
+/**
+ * A base class for {@link PreparedGeometry} subclasses.
+ * Contains default implementations for methods, which simply delegate
+ * to the equivalent {@link Geometry} methods.
+ * This class may be used as a "no-op" class for Geometry types
+ * which do not have a corresponding {@link PreparedGeometry} implementation.
+ * 
+ * @author Martin Davis
+ *
+ */
+class BasicPreparedGeometry 
+  implements PreparedGeometry
+{
+  private Geometry baseGeom;
+  private List representativePts;  // List<Coordinate>
+
+  public BasicPreparedGeometry(Geometry geom) 
+  {
+    this.baseGeom = geom;
+    representativePts = ComponentCoordinateExtracter.getCoordinates(geom);
+  }
+
+  public Geometry getGeometry() { return baseGeom; }
+
+  /**
+   * Gets the list of representative points for this geometry.
+   * One vertex is included for every component of the geometry
+   * (i.e. including one for every ring of polygonal geometries) 
+   * 
+   * @return a List of Coordinate
+   */
+  public List getRepresentativePoints()
+  {
+    return representativePts;
+  }
+  
+	/**
+	 * Tests whether any representative of the target geometry 
+	 * intersects the test geometry.
+	 * This is useful in A/A, A/L, A/P, L/P, and P/P cases.
+	 * 
+	 * @param geom the test geometry
+	 * @param repPts the representative points of the target geometry
+	 * @return true if any component intersects the areal test geometry
+	 */
+	public boolean isAnyTargetComponentInTest(Geometry testGeom)
+	{
+		PointLocator locator = new PointLocator();
+    for (Iterator i = representativePts.iterator(); i.hasNext(); ) {
+      Coordinate p = (Coordinate) i.next();
+      if (locator.intersects(p, testGeom))
+        return true;
+    }
+		return false;
+	}
+
+  /**
+   * Determines whether a Geometry g interacts with 
+   * this geometry by testing the geometry envelopes.
+   *  
+   * @param g a Geometry
+   * @return true if the envelopes intersect
+   */
+  protected boolean envelopesIntersect(Geometry g)
+  {
+    if (! baseGeom.getEnvelopeInternal().intersects(g.getEnvelopeInternal()))
+      return false;
+    return true;
+  }
+  
+  /**
+   * Determines whether the envelope of 
+   * this geometry covers the Geometry g.
+   * 
+   *  
+   * @param g a Geometry
+   * @return true if g is contained in this envelope
+   */
+  protected boolean envelopeCovers(Geometry g)
+  {
+    if (! baseGeom.getEnvelopeInternal().covers(g.getEnvelopeInternal()))
+      return false;
+    return true;
+  }
+  
+  /**
+   * Default implementation.
+   */
+  public boolean contains(Geometry g)
+  {
+    return baseGeom.contains(g);
+  }
+
+  /**
+   * Default implementation.
+   */
+  public boolean containsProperly(Geometry g)
+  {
+  	// since raw relate is used, provide some optimizations
+  	
+    // short-circuit test
+    if (! baseGeom.getEnvelopeInternal().contains(g.getEnvelopeInternal()))
+      return false;
+  	
+    // otherwise, compute using relate mask
+    return baseGeom.relate(g, "T**FF*FF*");
+  }
+
+
+  /**
+   * Default implementation.
+   */
+  public boolean covers(Geometry g)
+  {
+    return baseGeom.covers(g);
+  }
+
+ 
+  /**
+   * Standard implementation for all geometries.
+   * Supports {@link GeometryCollection}s as input.
+   */
+  public boolean disjoint(Geometry g)
+  {
+    return ! intersects(g);
+  }
+  
+  /**
+   * Default implementation.
+   */
+  public boolean intersects(Geometry g)
+  {
+    return baseGeom.intersects(g);
+  }
+  
+  
+  public String toString()
+  {
+  	return baseGeom.toString();
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedGeometry.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedGeometry.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedGeometry.java	(revision 28000)
@@ -0,0 +1,96 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.prep;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+
+/**
+ * An interface for classes which prepare {@link Geometry}s 
+ * in order to optimize the performance 
+ * of repeated calls to specific geometric operations.
+ * <p>
+ * A given implementation may provide optimized implementations
+ * for only some of the specified methods, 
+ * and delegate the remaining methods to the original {@link Geometry} operations.
+ * An implementation may also only optimize certain situations,
+ * and delegate others. 
+ * See the implementing classes for documentation about which methods and situations
+ * they optimize.
+ * 
+ * @author Martin Davis
+ *
+ */
+public interface PreparedGeometry 
+{
+	
+	/**
+	 * Gets the original {@link Geometry} which has been prepared.
+	 * 
+	 * @return the base geometry
+	 */
+	Geometry getGeometry();
+
+	/**
+	 * Tests whether the base {@link Geometry} contains a given geometry.
+	 * 
+	 * @param geom the Geometry to test
+	 * @return true if this Geometry contains the given Geometry
+	 * 
+	 * @see Geometry#contains(Geometry)
+	 */
+	boolean contains(Geometry geom);
+
+
+	/**
+	 * Tests whether the base {@link Geometry} is disjoint from a given geometry.
+	 * This method supports {@link GeometryCollection}s as input
+	 * 
+	 * @param geom the Geometry to test
+	 * @return true if this Geometry is disjoint from the given Geometry
+	 * 
+	 * @see Geometry#disjoint(Geometry)
+	 */
+	boolean disjoint(Geometry geom);
+
+	/**
+	 * Tests whether the base {@link Geometry} intersects a given geometry.
+	 * This method supports {@link GeometryCollection}s as input
+	 * 
+	 * @param geom the Geometry to test
+	 * @return true if this Geometry intersects the given Geometry
+	 * 
+	 * @see Geometry#intersects(Geometry)
+	 */
+	boolean intersects(Geometry geom);
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedGeometryFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedGeometryFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedGeometryFactory.java	(revision 28000)
@@ -0,0 +1,77 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.prep;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.Lineal;
+import com.vividsolutions.jts.geom.Polygonal;
+import com.vividsolutions.jts.geom.Puntal;
+
+/**
+ * A factory for creating {@link PreparedGeometry}s.
+ * It chooses an appropriate implementation of PreparedGeometry
+ * based on the geoemtric type of the input geometry.
+ * <p>
+ * In the future, the factory may accept hints that indicate
+ * special optimizations which can be performed.
+ * 
+ * 
+ * @author Martin Davis
+ *
+ */
+public class PreparedGeometryFactory 
+{
+  public PreparedGeometryFactory() {
+  }
+
+  /**
+   * Creates a new {@link PreparedGeometry} appropriate for the argument {@link Geometry}.
+   * 
+   * @param geom the geometry to prepare
+   * @return the prepared geometry
+   */
+  public PreparedGeometry create(Geometry geom)
+  {
+    if (geom instanceof Polygonal) 
+      return new PreparedPolygon((Polygonal) geom);
+    if (geom instanceof Lineal) 
+      return new PreparedLineString((Lineal) geom);
+    if (geom instanceof Puntal) 
+      return new PreparedPoint((Puntal) geom);
+    
+    /**
+     * Default representation.
+     */
+    return new BasicPreparedGeometry(geom);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedLineString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedLineString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedLineString.java	(revision 28000)
@@ -0,0 +1,79 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.prep;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.Lineal;
+import com.vividsolutions.jts.noding.FastSegmentSetIntersectionFinder;
+import com.vividsolutions.jts.noding.SegmentStringUtil;
+
+/**
+ * A prepared version for {@link Lineal} geometries.
+ * 
+ * @author mbdavis
+ *
+ */
+public class PreparedLineString
+  extends BasicPreparedGeometry
+{
+  private FastSegmentSetIntersectionFinder segIntFinder = null;
+
+  public PreparedLineString(Lineal line) {
+    super((Geometry) line);
+  }
+
+  public FastSegmentSetIntersectionFinder getIntersectionFinder()
+  {
+  	/**
+  	 * MD - Another option would be to use a simple scan for 
+  	 * segment testing for small geometries.  
+  	 * However, testing indicates that there is no particular advantage 
+  	 * to this approach.
+  	 */
+  	if (segIntFinder == null)
+  		segIntFinder = new FastSegmentSetIntersectionFinder(SegmentStringUtil.extractSegmentStrings(getGeometry()));
+    return segIntFinder;
+  }
+  
+  public boolean intersects(Geometry g)
+  {
+  	if (! envelopesIntersect(g)) return false;
+    return PreparedLineStringIntersects.intersects(this, g);
+  }
+  
+  /**
+   * There's not much point in trying to optimize contains, since 
+   * contains for linear targets requires the entire test geometry 
+   * to exactly match the target linework.
+   */
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedLineStringIntersects.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedLineStringIntersects.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedLineStringIntersects.java	(revision 28000)
@@ -0,0 +1,143 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.prep;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.algorithm.PointLocator;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.util.ComponentCoordinateExtracter;
+import com.vividsolutions.jts.noding.SegmentStringUtil;
+
+/**
+ * Computes the <tt>intersects</tt> spatial relationship predicate
+ * for a target {@link PreparedLineString} relative to other {@link Geometry} classes.
+ * Uses short-circuit tests and indexing to improve performance. 
+ * 
+ * @author Martin Davis
+ *
+ */
+class PreparedLineStringIntersects 
+{
+	/**
+	 * Computes the intersects predicate between a {@link PreparedLineString}
+	 * and a {@link Geometry}.
+	 * 
+	 * @param prep the prepared linestring
+	 * @param geom a test geometry
+	 * @return true if the linestring intersects the geometry
+	 */
+	public static boolean intersects(PreparedLineString prep, Geometry geom)
+	{
+		PreparedLineStringIntersects op = new PreparedLineStringIntersects(prep);
+    return op.intersects(geom);
+	}
+
+	protected PreparedLineString prepLine;
+
+  /**
+   * Creates an instance of this operation.
+   * 
+   * @param prepPoly the target PreparedLineString
+   */
+	public PreparedLineStringIntersects(PreparedLineString prepLine)
+	{
+		this.prepLine = prepLine;
+	}
+	
+	/**
+	 * Tests whether this geometry intersects a given geometry.
+	 * 
+	 * @param geom the test geometry
+	 * @return true if the test geometry intersects
+	 */
+	public boolean intersects(Geometry geom)
+	{
+		/**
+		 * If any segments intersect, obviously intersects = true
+		 */
+    List lineSegStr = SegmentStringUtil.extractSegmentStrings(geom);
+		boolean segsIntersect = prepLine.getIntersectionFinder().intersects(lineSegStr);
+		// MD - performance testing
+//		boolean segsIntersect = false;
+		if (segsIntersect) 
+      return true;
+		
+		/**
+		 * For L/L case we are done
+		 */
+		if (geom.getDimension() == 1) return false;
+		
+		/**
+		 * For L/A case, need to check for proper inclusion of the target in the test
+		 */
+		if (geom.getDimension() == 2
+				&& prepLine.isAnyTargetComponentInTest(geom)) return true;
+		
+		/** 
+		 * For L/P case, need to check if any points lie on line(s)
+		 */
+		if (geom.getDimension() == 0)
+			return isAnyTestPointInTarget(geom);
+		
+//		return prepLine.getGeometry().intersects(geom);
+		return false;
+	}
+	  
+  /**
+   * Tests whether any representative point of the test Geometry intersects
+   * the target geometry.
+   * Only handles test geometries which are Puntal (dimension 0)
+   * 
+   * @param geom a Puntal geometry to test
+   * @return true if any point of the argument intersects the prepared geometry
+   */
+	protected boolean isAnyTestPointInTarget(Geometry testGeom)
+	{
+		/**
+		 * This could be optimized by using the segment index on the lineal target.
+		 * However, it seems like the L/P case would be pretty rare in practice.
+		 */
+		PointLocator locator = new PointLocator();
+    List coords = ComponentCoordinateExtracter.getCoordinates(testGeom);
+    for (Iterator i = coords.iterator(); i.hasNext(); ) {
+      Coordinate p = (Coordinate) i.next();
+      if (locator.intersects(p, prepLine.getGeometry()))
+        return true;
+    }
+		return false;
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPoint.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPoint.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPoint.java	(revision 28000)
@@ -0,0 +1,67 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.prep;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.Puntal;
+
+
+/**
+ * A prepared version for {@link Puntal} geometries.
+ * 
+ * @author Martin Davis
+ *
+ */
+public class PreparedPoint
+  extends BasicPreparedGeometry
+{
+  public PreparedPoint(Puntal point) {
+    super((Geometry) point);
+  }
+
+  /**
+   * Tests whether this point intersects a {@link Geometry}.
+   * <p>
+   * The optimization here is that computing topology for the test geometry
+   * is avoided.  This can be significant for large geometries.
+   */
+  public boolean intersects(Geometry g)
+  {
+  	if (! envelopesIntersect(g)) return false;
+  	
+  	/**
+  	 * This avoids computing topology for the test geometry
+  	 */
+    return isAnyTargetComponentInTest(g);
+  }  
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygon.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygon.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygon.java	(revision 28000)
@@ -0,0 +1,137 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.prep;
+
+
+import com.vividsolutions.jts.algorithm.locate.IndexedPointInAreaLocator;
+import com.vividsolutions.jts.algorithm.locate.PointOnGeometryLocator;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geom.Polygonal;
+import com.vividsolutions.jts.noding.FastSegmentSetIntersectionFinder;
+import com.vividsolutions.jts.noding.SegmentStringUtil;
+import com.vividsolutions.jts.operation.predicate.RectangleContains;
+import com.vividsolutions.jts.operation.predicate.RectangleIntersects;
+
+/**
+ * A prepared version for {@link Polygonal} geometries.
+ * This class supports both {@link Polygon}s and {@link MultiPolygon}s.
+ * <p>
+ * This class does <b>not</b> support MultiPolygons which are non-valid 
+ * (e.g. with overlapping elements). 
+ * 
+ * @author mbdavis
+ *
+ */
+public class PreparedPolygon
+  extends BasicPreparedGeometry
+{
+	private boolean isRectangle = false;
+	// create these lazily, since they are expensive
+  private FastSegmentSetIntersectionFinder segIntFinder = null;
+  private PointOnGeometryLocator pia = null;
+
+  public PreparedPolygon(Polygonal poly) {
+    super((Geometry) poly);
+    isRectangle = getGeometry().isRectangle();
+  }
+
+  public FastSegmentSetIntersectionFinder getIntersectionFinder()
+  {
+  	/**
+  	 * MD - Another option would be to use a simple scan for 
+  	 * segment testing for small geometries.  
+  	 * However, testing indicates that there is no particular advantage 
+  	 * to this approach.
+  	 */
+  	if (segIntFinder == null)
+  		segIntFinder = new FastSegmentSetIntersectionFinder(SegmentStringUtil.extractSegmentStrings(getGeometry()));
+   return segIntFinder;
+  }
+  
+  public PointOnGeometryLocator getPointLocator()
+  {
+  	if (pia == null)
+      pia = new IndexedPointInAreaLocator(getGeometry());
+ 		
+    return pia;
+  }
+  
+  public boolean intersects(Geometry g)
+  {
+  	// envelope test
+  	if (! envelopesIntersect(g)) return false;
+  	
+    // optimization for rectangles
+    if (isRectangle) {
+      return RectangleIntersects.intersects((Polygon) getGeometry(), g);
+    }
+    
+    return PreparedPolygonIntersects.intersects(this, g);
+  }
+  
+  public boolean contains(Geometry g)
+  {
+    // short-circuit test
+    if (! envelopeCovers(g)) 
+    	return false;
+  	
+    // optimization for rectangles
+    if (isRectangle) {
+      return RectangleContains.contains((Polygon) getGeometry(), g);
+    }
+
+    return PreparedPolygonContains.contains(this, g);
+  }
+  
+  public boolean containsProperly(Geometry g)
+  {
+    // short-circuit test
+    if (! envelopeCovers(g)) 
+    	return false;
+    return PreparedPolygonContainsProperly.containsProperly(this, g);
+  }
+  
+  public boolean covers(Geometry g)
+  {
+    // short-circuit test
+    if (! envelopeCovers(g)) 
+    	return false;
+    // optimization for rectangle arguments
+    if (isRectangle) {
+      return true;
+    }
+    return PreparedPolygonCovers.covers(this, g);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonContains.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonContains.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonContains.java	(revision 28000)
@@ -0,0 +1,101 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.prep;
+
+
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * Computes the <tt>contains</tt> spatial relationship predicate
+ * for a {@link PreparedPolygon} relative to all other {@link Geometry} classes.
+ * Uses short-circuit tests and indexing to improve performance. 
+ * <p>
+ * It is not possible to short-circuit in all cases, in particular
+ * in the case where the test geometry touches the polygon linework.
+ * In this case full topology must be computed.
+ * 
+ * @author Martin Davis
+ *
+ */
+class PreparedPolygonContains 
+	extends AbstractPreparedPolygonContains
+{
+	/**
+	 * Computes the </tt>contains</tt> predicate between a {@link PreparedPolygon}
+	 * and a {@link Geometry}.
+	 * 
+	 * @param prep the prepared polygon
+	 * @param geom a test geometry
+	 * @return true if the polygon contains the geometry
+	 */
+	public static boolean contains(PreparedPolygon prep, Geometry geom)
+	{
+    PreparedPolygonContains polyInt = new PreparedPolygonContains(prep);
+    return polyInt.contains(geom);
+	}
+
+  /**
+   * Creates an instance of this operation.
+   * 
+   * @param prepPoly the PreparedPolygon to evaluate
+   */
+	public PreparedPolygonContains(PreparedPolygon prepPoly)
+	{
+		super(prepPoly);
+	}
+		
+	/**
+	 * Tests whether this PreparedPolygon <tt>contains</tt> a given geometry.
+	 * 
+	 * @param geom the test geometry
+	 * @return true if the test geometry is contained
+	 */
+	public boolean contains(Geometry geom)
+	{
+		return eval(geom);
+	}
+	
+	/**
+	 * Computes the full topological <tt>contains</tt> predicate.
+	 * Used when short-circuit tests are not conclusive.
+	 * 
+	 * @param geom the test geometry
+	 * @return true if this prepared polygon contains the test geometry
+	 */
+	protected boolean fullTopologicalPredicate(Geometry geom)
+	{
+		boolean isContained = prepPoly.getGeometry().contains(geom);
+		return isContained;
+	}
+	
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonContainsProperly.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonContainsProperly.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonContainsProperly.java	(revision 28000)
@@ -0,0 +1,124 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.prep;
+
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.Polygonal;
+import com.vividsolutions.jts.noding.SegmentStringUtil;
+
+/**
+ * Computes the <tt>containsProperly</tt> spatial relationship predicate
+ * for {@link PreparedPolygon}s relative to all other {@link Geometry} classes.
+ * Uses short-circuit tests and indexing to improve performance. 
+ * <p>
+ * A Geometry A <tt>containsProperly</tt> another Geometry B iff
+ * all points of B are contained in the Interior of A.
+ * Equivalently, B is contained in A AND B does not intersect 
+ * the Boundary of A.
+ * <p>
+ * The advantage to using this predicate is that it can be computed
+ * efficiently, with no need to compute topology at individual points.
+ * In a situation with many geometries intersecting the boundary 
+ * of the target geometry, this can make a performance difference.
+ * 
+ * @author Martin Davis
+ */
+class PreparedPolygonContainsProperly 
+	extends PreparedPolygonPredicate
+{
+	/**
+	 * Computes the </tt>containsProperly</tt> predicate between a {@link PreparedPolygon}
+	 * and a {@link Geometry}.
+	 * 
+	 * @param prep the prepared polygon
+	 * @param geom a test geometry
+	 * @return true if the polygon properly contains the geometry
+	 */
+	public static boolean containsProperly(PreparedPolygon prep, Geometry geom)
+	{
+		PreparedPolygonContainsProperly polyInt = new PreparedPolygonContainsProperly(prep);
+    return polyInt.containsProperly(geom);
+	}
+
+  /**
+   * Creates an instance of this operation.
+   * 
+   * @param prepPoly the PreparedPolygon to evaluate
+   */
+	public PreparedPolygonContainsProperly(PreparedPolygon prepPoly)
+	{
+		super(prepPoly);
+	}
+	
+	/**
+	 * Tests whether this PreparedPolygon containsProperly a given geometry.
+	 * 
+	 * @param geom the test geometry
+	 * @return true if the test geometry is contained properly
+	 */
+	public boolean containsProperly(Geometry geom)
+	{
+		/**
+		 * Do point-in-poly tests first, since they are cheaper and may result
+		 * in a quick negative result.
+		 * 
+		 * If a point of any test components does not lie in the target interior, result is false
+		 */
+		boolean isAllInPrepGeomAreaInterior = isAllTestComponentsInTargetInterior(geom);
+		if (! isAllInPrepGeomAreaInterior) return false;
+		
+		/**
+		 * If any segments intersect, result is false.
+		 */
+    List lineSegStr = SegmentStringUtil.extractSegmentStrings(geom);
+		boolean segsIntersect = prepPoly.getIntersectionFinder().intersects(lineSegStr);
+		if (segsIntersect) 
+      return false;
+		
+		/**
+		 * Given that no segments intersect, if any vertex of the target
+		 * is contained in some test component.
+		 * the test is NOT properly contained.
+		 */
+		if (geom instanceof Polygonal) {
+			// TODO: generalize this to handle GeometryCollections
+			boolean isTargetGeomInTestArea = isAnyTargetComponentInAreaTest(geom, prepPoly.getRepresentativePoints());
+			if (isTargetGeomInTestArea) return false;
+		}
+		
+		return true;
+	}
+	
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonCovers.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonCovers.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonCovers.java	(revision 28000)
@@ -0,0 +1,101 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.prep;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * Computes the <tt>covers</tt> spatial relationship predicate
+ * for a {@link PreparedPolygon} relative to all other {@link Geometry} classes.
+ * Uses short-circuit tests and indexing to improve performance. 
+ * <p>
+ * It is not possible to short-circuit in all cases, in particular
+ * in the case where the test geometry touches the polygon linework.
+ * In this case full topology must be computed.
+ * 
+ * @author Martin Davis
+ *
+ */
+class PreparedPolygonCovers 
+	extends AbstractPreparedPolygonContains
+{
+	/**
+	 * Computes the </tt>covers</tt> predicate between a {@link PreparedPolygon}
+	 * and a {@link Geometry}.
+	 * 
+	 * @param prep the prepared polygon
+	 * @param geom a test geometry
+	 * @return true if the polygon covers the geometry
+	 */
+	public static boolean covers(PreparedPolygon prep, Geometry geom)
+	{
+    PreparedPolygonCovers polyInt = new PreparedPolygonCovers(prep);
+    return polyInt.covers(geom);
+	}
+
+  /**
+   * Creates an instance of this operation.
+   * 
+   * @param prepPoly the PreparedPolygon to evaluate
+   */
+	public PreparedPolygonCovers(PreparedPolygon prepPoly)
+	{
+		super(prepPoly);
+		requireSomePointInInterior = false;
+	}
+		
+	/**
+	 * Tests whether this PreparedPolygon <tt>covers</tt> a given geometry.
+	 * 
+	 * @param geom the test geometry
+	 * @return true if the test geometry is covered
+	 */
+	public boolean covers(Geometry geom)
+	{
+		return eval(geom);
+	}
+	
+	/**
+	 * Computes the full topological <tt>covers</tt> predicate.
+	 * Used when short-circuit tests are not conclusive.
+	 * 
+	 * @param geom the test geometry
+	 * @return true if this prepared polygon covers the test geometry
+	 */
+	protected boolean fullTopologicalPredicate(Geometry geom)
+	{
+		boolean result = prepPoly.getGeometry().covers(geom);
+		return result;
+	}
+	
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonIntersects.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonIntersects.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonIntersects.java	(revision 28000)
@@ -0,0 +1,114 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.prep;
+
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.noding.SegmentStringUtil;
+
+/**
+ * Computes the <tt>intersects</tt> spatial relationship predicate
+ * for {@link PreparedPolygon}s relative to all other {@link Geometry} classes.
+ * Uses short-circuit tests and indexing to improve performance. 
+ * 
+ * @author Martin Davis
+ *
+ */
+class PreparedPolygonIntersects 
+	extends PreparedPolygonPredicate
+{
+	/**
+	 * Computes the intersects predicate between a {@link PreparedPolygon}
+	 * and a {@link Geometry}.
+	 * 
+	 * @param prep the prepared polygon
+	 * @param geom a test geometry
+	 * @return true if the polygon intersects the geometry
+	 */
+	public static boolean intersects(PreparedPolygon prep, Geometry geom)
+	{
+    PreparedPolygonIntersects polyInt = new PreparedPolygonIntersects(prep);
+    return polyInt.intersects(geom);
+	}
+	
+  /**
+   * Creates an instance of this operation.
+   * 
+   * @param prepPoly the PreparedPolygon to evaluate
+   */
+	public PreparedPolygonIntersects(PreparedPolygon prepPoly)
+	{
+		super(prepPoly);
+	}
+	
+	/**
+	 * Tests whether this PreparedPolygon intersects a given geometry.
+	 * 
+	 * @param geom the test geometry
+	 * @return true if the test geometry intersects
+	 */
+	public boolean intersects(Geometry geom)
+	{
+		/**
+		 * Do point-in-poly tests first, since they are cheaper and may result
+		 * in a quick positive result.
+		 * 
+		 * If a point of any test components lie in target, result is true
+		 */
+		boolean isInPrepGeomArea = isAnyTestComponentInTarget(geom);
+		if (isInPrepGeomArea) return true;
+		
+		/**
+		 * If any segments intersect, result is true
+		 */
+    List lineSegStr = SegmentStringUtil.extractSegmentStrings(geom);
+		boolean segsIntersect = prepPoly.getIntersectionFinder().intersects(lineSegStr);
+		if (segsIntersect) 
+      return true;
+		
+		/**
+		 * If the test has dimension = 2 as well, it is necessary to
+		 * test for proper inclusion of the target.
+		 * Since no segments intersect, it is sufficient to test representative points.
+		 */
+		if (geom.getDimension() == 2) {
+			// TODO: generalize this to handle GeometryCollections
+			boolean isPrepGeomInArea = isAnyTargetComponentInAreaTest(geom, prepPoly.getRepresentativePoints());
+			if (isPrepGeomInArea) return true;
+		}
+		
+		return false;
+	}
+	  
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonPredicate.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonPredicate.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/PreparedPolygonPredicate.java	(revision 28000)
@@ -0,0 +1,136 @@
+package com.vividsolutions.jts.geom.prep;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.algorithm.locate.PointOnGeometryLocator;
+import com.vividsolutions.jts.algorithm.locate.SimplePointInAreaLocator;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geom.util.ComponentCoordinateExtracter;
+
+/**
+ * A base class for predicate operations on {@link PreparedPolygon}s.
+ * 
+ * @author mbdavis
+ *
+ */
+abstract class PreparedPolygonPredicate 
+{
+	protected PreparedPolygon prepPoly;
+  private PointOnGeometryLocator targetPointLocator;
+
+  /**
+   * Creates an instance of this operation.
+   * 
+   * @param prepPoly the PreparedPolygon to evaluate
+   */
+	public PreparedPolygonPredicate(PreparedPolygon prepPoly)
+	{
+		this.prepPoly = prepPoly;
+    targetPointLocator = prepPoly.getPointLocator();
+	}
+	
+  /**
+   * Tests whether all components of the test Geometry 
+	 * are contained in the target geometry.
+   * Handles both linear and point components.
+   * 
+   * @param geom a geometry to test
+   * @return true if all componenta of the argument are contained in the target geometry
+   */
+	protected boolean isAllTestComponentsInTarget(Geometry testGeom)
+	{
+    List coords = ComponentCoordinateExtracter.getCoordinates(testGeom);
+    for (Iterator i = coords.iterator(); i.hasNext(); ) {
+      Coordinate p = (Coordinate) i.next();
+      int loc = targetPointLocator.locate(p);
+      if (loc == Location.EXTERIOR)
+        return false;
+    }
+		return true;
+	}
+	
+  /**
+   * Tests whether all components of the test Geometry 
+	 * are contained in the interior of the target geometry.
+   * Handles both linear and point components.
+   * 
+   * @param geom a geometry to test
+   * @return true if all componenta of the argument are contained in the target geometry interior
+   */
+	protected boolean isAllTestComponentsInTargetInterior(Geometry testGeom)
+	{
+    List coords = ComponentCoordinateExtracter.getCoordinates(testGeom);
+    for (Iterator i = coords.iterator(); i.hasNext(); ) {
+      Coordinate p = (Coordinate) i.next();
+      int loc = targetPointLocator.locate(p);
+      if (loc != Location.INTERIOR)
+        return false;
+    }
+		return true;
+	}
+	
+  /**
+   * Tests whether any component of the test Geometry intersects
+   * the area of the target geometry.
+   * Handles test geometries with both linear and point components.
+   * 
+   * @param geom a geometry to test
+   * @return true if any component of the argument intersects the prepared area geometry
+   */
+	protected boolean isAnyTestComponentInTarget(Geometry testGeom)
+	{
+    List coords = ComponentCoordinateExtracter.getCoordinates(testGeom);
+    for (Iterator i = coords.iterator(); i.hasNext(); ) {
+      Coordinate p = (Coordinate) i.next();
+      int loc = targetPointLocator.locate(p);
+      if (loc != Location.EXTERIOR)
+        return true;
+    }
+		return false;
+	}
+
+  /**
+   * Tests whether any component of the test Geometry intersects
+   * the interior of the target geometry.
+   * Handles test geometries with both linear and point components.
+   * 
+   * @param geom a geometry to test
+   * @return true if any component of the argument intersects the prepared area geometry interior
+   */
+	protected boolean isAnyTestComponentInTargetInterior(Geometry testGeom)
+	{
+    List coords = ComponentCoordinateExtracter.getCoordinates(testGeom);
+    for (Iterator i = coords.iterator(); i.hasNext(); ) {
+      Coordinate p = (Coordinate) i.next();
+      int loc = targetPointLocator.locate(p);
+      if (loc == Location.INTERIOR)
+        return true;
+    }
+		return false;
+	}
+
+
+	/**
+	 * Tests whether any component of the target geometry 
+	 * intersects the test geometry (which must be an areal geometry) 
+	 * 
+	 * @param geom the test geometry
+	 * @param repPts the representative points of the target geometry
+	 * @return true if any component intersects the areal test geometry
+	 */
+	protected boolean isAnyTargetComponentInAreaTest(Geometry testGeom, List targetRepPts)
+	{
+		PointOnGeometryLocator piaLoc = new SimplePointInAreaLocator(testGeom);
+    for (Iterator i = targetRepPts.iterator(); i.hasNext(); ) {
+      Coordinate p = (Coordinate) i.next();
+      int loc = piaLoc.locate(p);
+      if (loc != Location.EXTERIOR)
+        return true;
+    }
+		return false;
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/prep/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Classes to perform optimized geometric operations on suitably prepared geometries.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/ComponentCoordinateExtracter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/ComponentCoordinateExtracter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/ComponentCoordinateExtracter.java	(revision 28000)
@@ -0,0 +1,89 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryComponentFilter;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.Point;
+
+/**
+ * Extracts a single representative {@link Coordinate} 
+ * from each connected component of a {@link Geometry}.
+ *
+ * @version 1.9
+ */
+public class ComponentCoordinateExtracter
+  implements GeometryComponentFilter
+{
+
+  /**
+   * Extracts the linear components from a single geometry.
+   * If more than one geometry is to be processed, it is more
+   * efficient to create a single {@link ComponentCoordinateExtracter} instance
+   * and pass it to multiple geometries.
+   *
+   * @param geom the Geometry from which to extract
+   * @return a list of Coordinates
+   */
+  public static List getCoordinates(Geometry geom)
+  {
+    List coords = new ArrayList();
+    geom.apply(new ComponentCoordinateExtracter(coords));
+    return coords;
+  }
+
+  private List coords;
+
+  /**
+   * Constructs a LineExtracterFilter with a list in which to store LineStrings found.
+   */
+  public ComponentCoordinateExtracter(List coords)
+  {
+    this.coords = coords;
+  }
+
+  public void filter(Geometry geom)
+  {
+    // add coordinates from connected components
+    if (geom instanceof LineString
+        || geom instanceof Point) 
+      coords.add(geom.getCoordinate());
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/GeometryCollectionMapper.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/GeometryCollectionMapper.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/GeometryCollectionMapper.java	(revision 28000)
@@ -0,0 +1,47 @@
+package com.vividsolutions.jts.geom.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryFactory;
+
+/**
+ * Maps the members of a {@link GeometryCollection}
+ * into another <tt>GeometryCollection</tt> via a defined
+ * mapping function.
+ * 
+ * @author Martin Davis
+ *
+ */
+public class GeometryCollectionMapper 
+{
+  public static GeometryCollection map(GeometryCollection gc, MapOp op)
+  {
+    GeometryCollectionMapper mapper = new GeometryCollectionMapper(op);
+    return mapper.map(gc);
+  }
+  
+  private MapOp mapOp = null;
+  
+  public GeometryCollectionMapper(MapOp mapOp) {
+    this.mapOp = mapOp;
+  }
+
+  public GeometryCollection map(GeometryCollection gc)
+  {
+    List mapped = new ArrayList();
+    for (int i = 0; i < gc.getNumGeometries(); i++) {
+      Geometry g = mapOp.map(gc.getGeometryN(i));
+      if (!g.isEmpty())
+        mapped.add(g);
+    }
+    return gc.getFactory().createGeometryCollection(
+        GeometryFactory.toGeometryArray(mapped));
+  }
+  
+  public interface MapOp {
+    Geometry map(Geometry g);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/GeometryTransformer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/GeometryTransformer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/GeometryTransformer.java	(revision 28000)
@@ -0,0 +1,260 @@
+package com.vividsolutions.jts.geom.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.MultiLineString;
+import com.vividsolutions.jts.geom.MultiPoint;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+
+/**
+ * A framework for processes which transform an input {@link Geometry} into
+ * an output {@link Geometry}, possibly changing its structure and type(s).
+ * This class is a framework for implementing subclasses
+ * which perform transformations on
+ * various different Geometry subclasses.
+ * It provides an easy way of applying specific transformations
+ * to given geometry types, while allowing unhandled types to be simply copied.
+ * Also, the framework ensures that if subcomponents change type
+ * the parent geometries types change appropriately to maintain valid structure.
+ * Subclasses will override whichever <code>transformX</code> methods
+ * they need to to handle particular Geometry types.
+ * <p>
+ * A typically usage would be a transformation class that transforms <tt>Polygons</tt> into
+ * <tt>Polygons</tt>, <tt>LineStrings</tt> or <tt>Points</tt>, depending on the geometry of the input
+ * (For instance, a simplification operation).  
+ * This class would likely need to override the {@link #transformMultiPolygon(MultiPolygon, Geometry)transformMultiPolygon}
+ * method to ensure that if input Polygons change type the result is a <tt>GeometryCollection</tt>,
+ * not a <tt>MultiPolygon</tt>.
+ * <p>
+ * The default behaviour of this class is simply to recursively transform
+ * each Geometry component into an identical object by deep copying down
+ * to the level of, but not including, coordinates.
+ * <p>
+ * All <code>transformX</code> methods may return <code>null</code>,
+ * to avoid creating empty or invalid geometry objects. This will be handled correctly
+ * by the transformer.   <code>transform<i>XXX</i></code> methods should always return valid
+ * geometry - if they cannot do this they should return <code>null</code>
+ * (for instance, it may not be possible for a transformLineString implementation
+ * to return at least two points - in this case, it should return <code>null</code>).
+ * The {@link #transform(Geometry)transform} method itself will always
+ * return a non-null Geometry object (but this may be empty).
+ *
+ * @version 1.7
+ *
+ * @see GeometryEditor
+ */
+public class GeometryTransformer
+{
+
+  /**
+   * Possible extensions:
+   * getParent() method to return immediate parent e.g. of LinearRings in Polygons
+   */
+
+  protected GeometryFactory factory = null;
+
+  // these could eventually be exposed to clients
+  /**
+   * <code>true</code> if empty geometries should not be included in the result
+   */
+  private boolean pruneEmptyGeometry = true;
+
+  /**
+   * <code>true</code> if a homogenous collection result
+   * from a {@link GeometryCollection} should still
+   * be a general GeometryCollection
+   */
+  private boolean preserveGeometryCollectionType = true;
+
+  /**
+   * <code>true</code> if the type of the input should be preserved
+   */
+  private boolean preserveType = false;
+
+  public GeometryTransformer() {
+  }
+
+
+  public final Geometry transform(Geometry inputGeom)
+  {
+    this.factory = inputGeom.getFactory();
+
+    if (inputGeom instanceof Point)
+      return transformPoint((Point) inputGeom);
+    if (inputGeom instanceof MultiPoint)
+      return transformMultiPoint((MultiPoint) inputGeom);
+    if (inputGeom instanceof LinearRing)
+      return transformLinearRing((LinearRing) inputGeom);
+    if (inputGeom instanceof LineString)
+      return transformLineString((LineString) inputGeom);
+    if (inputGeom instanceof MultiLineString)
+      return transformMultiLineString((MultiLineString) inputGeom);
+    if (inputGeom instanceof Polygon)
+      return transformPolygon((Polygon) inputGeom);
+    if (inputGeom instanceof MultiPolygon)
+      return transformMultiPolygon((MultiPolygon) inputGeom);
+    if (inputGeom instanceof GeometryCollection)
+      return transformGeometryCollection((GeometryCollection) inputGeom);
+
+    throw new IllegalArgumentException("Unknown Geometry subtype: " + inputGeom.getClass().getName());
+  }
+
+  
+
+  /**
+   * Convenience method which provides statndard way of copying {@link CoordinateSequence}s
+   * @param seq the sequence to copy
+   * @return a deep copy of the sequence
+   */
+  protected final CoordinateSequence copy(CoordinateSequence seq)
+  {
+    return (CoordinateSequence) seq.clone();
+  }
+
+  /**
+   * Transforms a {@link CoordinateSequence}.
+   * This method should always return a valid coordinate list for
+   * the desired result type.  (E.g. a coordinate list for a LineString
+   * must have 0 or at least 2 points).
+   * If this is not possible, return an empty sequence -
+   * this will be pruned out.
+   *
+   * @param coords the coordinates to transform
+   * @param parent the parent geometry
+   * @return the transformed coordinates
+   */
+  protected CoordinateSequence transformCoordinates(CoordinateSequence coords)
+  {
+    return copy(coords);
+  }
+
+  protected Geometry transformPoint(Point geom) {
+    return factory.createPoint(
+        transformCoordinates(geom.getCoordinateSequence()));
+  }
+
+  protected Geometry transformMultiPoint(MultiPoint geom) {
+    List transGeomList = new ArrayList();
+    for (int i = 0; i < geom.getNumGeometries(); i++) {
+      Geometry transformGeom = transformPoint((Point) geom.getGeometryN(i));
+      if (transformGeom == null) continue;
+      if (transformGeom.isEmpty()) continue;
+      transGeomList.add(transformGeom);
+    }
+    return factory.buildGeometry(transGeomList);
+  }
+
+  /**
+   * Transforms a LinearRing.
+   * The transformation of a LinearRing may result in a coordinate sequence
+   * which does not form a structurally valid ring (i.e. a degnerate ring of 3 or fewer points).
+   * In this case a LineString is returned. 
+   * Subclasses may wish to override this method and check for this situation
+   * (e.g. a subclass may choose to eliminate degenerate linear rings)
+   * 
+   * @param geom the ring to simplify
+   * @param parent the parent geometry
+   * @return a LinearRing if the transformation resulted in a structurally valid ring
+   * @return a LineString if the transformation caused the LinearRing to collapse to 3 or fewer points
+   */
+  protected Geometry transformLinearRing(LinearRing geom) {
+    CoordinateSequence seq = transformCoordinates(geom.getCoordinateSequence());
+    int seqSize = seq.size();
+    // ensure a valid LinearRing
+    if (seqSize > 0 && seqSize < 4 && ! preserveType)
+      return factory.createLineString(seq);
+    return factory.createLinearRing(seq);
+
+  }
+
+  /**
+   * Transforms a {@link LineString} geometry.
+   *
+   * @param geom
+   * @param parent
+   * @return
+   */
+  protected Geometry transformLineString(LineString geom) {
+    // should check for 1-point sequences and downgrade them to points
+    return factory.createLineString(
+        transformCoordinates(geom.getCoordinateSequence()));
+  }
+
+  protected Geometry transformMultiLineString(MultiLineString geom) {
+    List transGeomList = new ArrayList();
+    for (int i = 0; i < geom.getNumGeometries(); i++) {
+      Geometry transformGeom = transformLineString((LineString) geom.getGeometryN(i));
+      if (transformGeom == null) continue;
+      if (transformGeom.isEmpty()) continue;
+      transGeomList.add(transformGeom);
+    }
+    return factory.buildGeometry(transGeomList);
+  }
+
+  protected Geometry transformPolygon(Polygon geom) {
+    boolean isAllValidLinearRings = true;
+    Geometry shell = transformLinearRing((LinearRing) geom.getExteriorRing());
+
+    if (shell == null
+        || ! (shell instanceof LinearRing)
+        || shell.isEmpty() )
+      isAllValidLinearRings = false;
+//return factory.createPolygon(null, null);
+
+    ArrayList holes = new ArrayList();
+    for (int i = 0; i < geom.getNumInteriorRing(); i++) {
+      Geometry hole = transformLinearRing((LinearRing) geom.getInteriorRingN(i));
+      if (hole == null || hole.isEmpty()) {
+        continue;
+      }
+      if (! (hole instanceof LinearRing))
+        isAllValidLinearRings = false;
+
+      holes.add(hole);
+    }
+
+    if (isAllValidLinearRings)
+      return factory.createPolygon((LinearRing) shell,
+                                   (LinearRing[]) holes.toArray(new LinearRing[] {  }));
+    else {
+      List components = new ArrayList();
+      if (shell != null) components.add(shell);
+      components.addAll(holes);
+      return factory.buildGeometry(components);
+    }
+  }
+
+  protected Geometry transformMultiPolygon(MultiPolygon geom) {
+    List transGeomList = new ArrayList();
+    for (int i = 0; i < geom.getNumGeometries(); i++) {
+      Geometry transformGeom = transformPolygon((Polygon) geom.getGeometryN(i));
+      if (transformGeom == null) continue;
+      if (transformGeom.isEmpty()) continue;
+      transGeomList.add(transformGeom);
+    }
+    return factory.buildGeometry(transGeomList);
+  }
+
+  protected Geometry transformGeometryCollection(GeometryCollection geom) {
+    List transGeomList = new ArrayList();
+    for (int i = 0; i < geom.getNumGeometries(); i++) {
+      Geometry transformGeom = transform(geom.getGeometryN(i));
+      if (transformGeom == null) continue;
+      if (pruneEmptyGeometry && transformGeom.isEmpty()) continue;
+      transGeomList.add(transformGeom);
+    }
+    if (preserveGeometryCollectionType)
+      return factory.createGeometryCollection(GeometryFactory.toGeometryArray(transGeomList));
+    return factory.buildGeometry(transGeomList);
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/LinearComponentExtracter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/LinearComponentExtracter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/LinearComponentExtracter.java	(revision 28000)
@@ -0,0 +1,110 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryComponentFilter;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.LinearRing;
+
+/**
+ * Extracts all the 1-dimensional ({@link LineString}) components from a {@link Geometry}.
+ *
+ * @version 1.7
+ */
+public class LinearComponentExtracter
+  implements GeometryComponentFilter
+{
+  /**
+   * Extracts the linear components from a single geometry.
+   * If more than one geometry is to be processed, it is more
+   * efficient to create a single {@link LinearComponentExtracter} instance
+   * and pass it to multiple geometries.
+   *
+   * @param geom the geometry from which to extract linear components
+   * @return the list of linear components
+   */
+  public static List getLines(Geometry geom)
+  {
+    return getLines(geom, false);
+  }
+
+  /**
+   * Extracts the linear components from a single geometry.
+   * If more than one geometry is to be processed, it is more
+   * efficient to create a single {@link LinearComponentExtracter} instance
+   * and pass it to multiple geometries.
+   *
+   * @param geom the geometry from which to extract linear components
+   * @param forceToLineString true if LinearRings should be converted to LineStrings
+   * @return the list of linear components
+   */
+  public static List getLines(Geometry geom, boolean forceToLineString)
+  {
+    List lines = new ArrayList();
+    geom.apply(new LinearComponentExtracter(lines, forceToLineString));
+    return lines;
+  }
+
+  private Collection lines;
+  private boolean isForcedToLineString = false;
+
+  /**
+   * Constructs a LineExtracterFilter with a list in which to store LineStrings found.
+   */
+  public LinearComponentExtracter(Collection lines, boolean isForcedToLineString)
+  {
+    this.lines = lines;
+    this.isForcedToLineString = isForcedToLineString;
+  }
+
+  public void filter(Geometry geom)
+  {
+  	if (isForcedToLineString && geom instanceof LinearRing) {
+  		LineString line = geom.getFactory().createLineString( ((LinearRing) geom).getCoordinateSequence());
+  		lines.add(line);
+  		return;
+  	}
+  	// if not being forced, and this is a linear component
+  	if (geom instanceof LineString) 
+  		lines.add(geom);
+  	
+  	// else this is not a linear component, so skip it
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/PointExtracter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/PointExtracter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/PointExtracter.java	(revision 28000)
@@ -0,0 +1,98 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryFilter;
+import com.vividsolutions.jts.geom.Point;
+
+/**
+ * Extracts all the 0-dimensional ({@link Point}) components from a {@link Geometry}.
+ *
+ * @version 1.7
+ * @see GeometryExtracter
+ */
+public class PointExtracter
+  implements GeometryFilter
+{
+  /**
+   * Extracts the {@link Point} elements from a single {@link Geometry}
+   * and adds them to the provided {@link List}.
+   * 
+   * @param geom the geometry from which to extract
+   * @param list the list to add the extracted elements to
+   */
+  public static List getPoints(Geometry geom, List list)
+  {
+  	if (geom instanceof Point) {
+  		list.add(geom);
+  	}
+  	else if (geom instanceof GeometryCollection) {
+  		geom.apply(new PointExtracter(list));
+  	}
+  	// skip non-Polygonal elemental geometries
+  	
+    return list;
+  }
+
+  /**
+   * Extracts the {@link Point} elements from a single {@link Geometry}
+   * and returns them in a {@link List}.
+   * 
+   * @param geom the geometry from which to extract
+   */
+  public static List getPoints(Geometry geom)
+  {
+    return getPoints(geom, new ArrayList());
+  }
+
+  private List pts;
+  /**
+   * Constructs a PointExtracterFilter with a list in which to store Points found.
+   */
+  public PointExtracter(List pts)
+  {
+    this.pts = pts;
+  }
+
+  public void filter(Geometry geom)
+  {
+    if (geom instanceof Point) pts.add(geom);
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/PolygonExtracter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/PolygonExtracter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/PolygonExtracter.java	(revision 28000)
@@ -0,0 +1,98 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geom.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryFilter;
+import com.vividsolutions.jts.geom.Polygon;
+
+/**
+ * Extracts all the {@link Polygon} elements from a {@link Geometry}.
+ *
+ * @version 1.7
+ * @see GeometryExtracter
+ */
+public class PolygonExtracter
+  implements GeometryFilter
+{
+  /**
+   * Extracts the {@link Polygon} elements from a single {@link Geometry}
+   * and adds them to the provided {@link List}.
+   * 
+   * @param geom the geometry from which to extract
+   * @param list the list to add the extracted elements to
+   */
+  public static List getPolygons(Geometry geom, List list)
+  {
+  	if (geom instanceof Polygon) {
+  		list.add(geom);
+  	}
+  	else if (geom instanceof GeometryCollection) {
+  		geom.apply(new PolygonExtracter(list));
+  	}
+  	// skip non-Polygonal elemental geometries
+  	
+    return list;
+  }
+
+  /**
+   * Extracts the {@link Polygon} elements from a single {@link Geometry}
+   * and returns them in a {@link List}.
+   * 
+   * @param geom the geometry from which to extract
+   */
+  public static List getPolygons(Geometry geom)
+  {
+    return getPolygons(geom, new ArrayList());
+  }
+
+  private List comps;
+  /**
+   * Constructs a PolygonExtracterFilter with a list in which to store Polygons found.
+   */
+  public PolygonExtracter(List comps)
+  {
+    this.comps = comps;
+  }
+
+  public void filter(Geometry geom)
+  {
+    if (geom instanceof Polygon) comps.add(geom);
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/ShortCircuitedGeometryVisitor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/ShortCircuitedGeometryVisitor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/ShortCircuitedGeometryVisitor.java	(revision 28000)
@@ -0,0 +1,37 @@
+package com.vividsolutions.jts.geom.util;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+
+/**
+ * A visitor to {@link Geometry} elements which can
+ * be short-circuited by a given condition
+ *
+ * @version 1.7
+ */
+public abstract class ShortCircuitedGeometryVisitor
+{
+  private boolean isDone = false;
+
+  public ShortCircuitedGeometryVisitor() {
+  }
+
+  public void applyTo(Geometry geom) {
+    for (int i = 0; i < geom.getNumGeometries() && ! isDone; i++) {
+      Geometry element = geom.getGeometryN(i);
+      if (! (element instanceof GeometryCollection)) {
+        visit(element);
+        if (isDone()) {
+          isDone = true;
+          return;
+        }
+      }
+      else
+        applyTo(element);
+    }
+  }
+
+  protected abstract void visit(Geometry element);
+
+  protected abstract boolean isDone();
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geom/util/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides classes that parse and modify Geometry objects.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Depth.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Depth.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Depth.java	(revision 28000)
@@ -0,0 +1,146 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import com.vividsolutions.jts.geom.Location;
+
+/**
+ * A Depth object records the topological depth of the sides
+ * of an Edge for up to two Geometries.
+ * @version 1.7
+ */
+public class Depth {
+
+  private final static int NULL_VALUE = -1;
+
+  public static int depthAtLocation(int location)
+  {
+    if (location == Location.EXTERIOR) return 0;
+    if (location == Location.INTERIOR) return 1;
+    return NULL_VALUE;
+  }
+
+  private int[][] depth = new int[2][3];
+
+  public Depth() {
+    // initialize depth array to a sentinel value
+    for (int i = 0; i < 2; i++) {
+      for (int j = 0; j < 3; j++) {
+        depth[i][j] = NULL_VALUE;
+      }
+    }
+  }
+
+  public int getLocation(int geomIndex, int posIndex)
+  {
+    if (depth[geomIndex][posIndex] <= 0) return Location.EXTERIOR;
+    return Location.INTERIOR;
+  }
+
+  /**
+   * A Depth object is null (has never been initialized) if all depths are null.
+   */
+  public boolean isNull()
+  {
+    for (int i = 0; i < 2; i++) {
+      for (int j = 0; j < 3; j++) {
+        if (depth[i][j] != NULL_VALUE)
+          return false;
+      }
+    }
+    return true;
+  }
+  public boolean isNull(int geomIndex)
+  {
+    return depth[geomIndex][1] == NULL_VALUE;
+  }
+  public boolean isNull(int geomIndex, int posIndex)
+  {
+    return depth[geomIndex][posIndex] == NULL_VALUE;
+  }
+  public void add(Label lbl)
+  {
+    for (int i = 0; i < 2; i++) {
+      for (int j = 1; j < 3; j++) {
+        int loc = lbl.getLocation(i, j);
+        if (loc == Location.EXTERIOR || loc == Location.INTERIOR) {
+          // initialize depth if it is null, otherwise add this location value
+          if (isNull(i, j)) {
+            depth[i][j] = depthAtLocation(loc);
+          }
+          else
+            depth[i][j] += depthAtLocation(loc);
+        }
+      }
+    }
+  }
+  public int getDelta(int geomIndex)
+  {
+    return depth[geomIndex][Position.RIGHT] - depth[geomIndex][Position.LEFT];
+  }
+  /**
+   * Normalize the depths for each geometry, if they are non-null.
+   * A normalized depth
+   * has depth values in the set { 0, 1 }.
+   * Normalizing the depths
+   * involves reducing the depths by the same amount so that at least
+   * one of them is 0.  If the remaining value is > 0, it is set to 1.
+   */
+  public void normalize()
+  {
+    for (int i = 0; i < 2; i++) {
+      if (! isNull(i)) {
+        int minDepth = depth[i][1];
+        if (depth[i][2] < minDepth)
+          minDepth = depth[i][2];
+
+        if (minDepth < 0) minDepth = 0;
+        for (int j = 1; j < 3; j++) {
+          int newValue = 0;
+          if (depth[i][j] > minDepth)
+            newValue = 1;
+          depth[i][j] = newValue;
+        }
+      }
+    }
+  }
+
+  public String toString()
+  {
+    return
+        "A: " + depth[0][1] + "," + depth[0][2]
+      + " B: " + depth[1][1] + "," + depth[1][2];
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/DirectedEdge.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/DirectedEdge.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/DirectedEdge.java	(revision 28000)
@@ -0,0 +1,183 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import java.io.PrintStream;
+
+import com.vividsolutions.jts.geom.Location;
+
+
+/**
+ * @version 1.7
+ */
+public class DirectedEdge
+  extends EdgeEnd
+{
+
+
+  protected boolean isForward;
+  private boolean isInResult = false;
+  private boolean isVisited = false;
+
+  private DirectedEdge sym; // the symmetric edge
+  private DirectedEdge next;  // the next edge in the edge ring for the polygon containing this edge
+  private DirectedEdge nextMin;  // the next edge in the MinimalEdgeRing that contains this edge
+  private EdgeRing edgeRing;  // the EdgeRing that this edge is part of
+  private EdgeRing minEdgeRing;  // the MinimalEdgeRing that this edge is part of
+  /**
+   * The depth of each side (position) of this edge.
+   * The 0 element of the array is never used.
+   */
+  private int[] depth = { 0, -999, -999 };
+
+  public DirectedEdge(Edge edge, boolean isForward)
+  {
+    super(edge);
+    this.isForward = isForward;
+    if (isForward) {
+      init(edge.getCoordinate(0), edge.getCoordinate(1));
+    }
+    else {
+      int n = edge.getNumPoints() - 1;
+      init(edge.getCoordinate(n), edge.getCoordinate(n-1));
+    }
+    computeDirectedLabel();
+  }
+  public Edge getEdge() { return edge; }
+  public void setInResult(boolean isInResult) { this.isInResult = isInResult; }
+  public boolean isInResult() { return isInResult; }
+  public boolean isVisited() { return isVisited; }
+  public void setVisited(boolean isVisited) { this.isVisited = isVisited; }
+  public void setEdgeRing(EdgeRing edgeRing) { this.edgeRing = edgeRing; }
+  public EdgeRing getEdgeRing() { return edgeRing; }
+  public void setMinEdgeRing(EdgeRing minEdgeRing) { this.minEdgeRing = minEdgeRing; }
+  public EdgeRing getMinEdgeRing() { return minEdgeRing; }
+
+
+  public int getDepthDelta()
+  {
+    int depthDelta = edge.getDepthDelta();
+    if (! isForward) depthDelta = -depthDelta;
+    return depthDelta;
+  }
+
+  /**
+   * setVisitedEdge marks both DirectedEdges attached to a given Edge.
+   * This is used for edges corresponding to lines, which will only
+   * appear oriented in a single direction in the result.
+   */
+  public void setVisitedEdge(boolean isVisited)
+  {
+    setVisited(isVisited);
+    sym.setVisited(isVisited);
+  }
+  /**
+   * Each Edge gives rise to a pair of symmetric DirectedEdges, in opposite
+   * directions.
+   * @return the DirectedEdge for the same Edge but in the opposite direction
+   */
+  public DirectedEdge getSym() { return sym; }
+  public boolean isForward() { return isForward; }
+  public void setSym(DirectedEdge de)
+  {
+    sym = de;
+  }
+  public DirectedEdge getNext() { return next; }
+  public void setNext(DirectedEdge next) { this.next = next; }
+  public DirectedEdge getNextMin() { return nextMin; }
+  public void setNextMin(DirectedEdge nextMin) { this.nextMin = nextMin; }
+
+  /**
+   * This edge is a line edge if
+   * <ul>
+   * <li> at least one of the labels is a line label
+   * <li> any labels which are not line labels have all Locations = EXTERIOR
+   * </ul>
+   */
+  public boolean isLineEdge()
+  {
+    boolean isLine = label.isLine(0) || label.isLine(1);
+    boolean isExteriorIfArea0 =
+      ! label.isArea(0) || label.allPositionsEqual(0, Location.EXTERIOR);
+    boolean isExteriorIfArea1 =
+      ! label.isArea(1) || label.allPositionsEqual(1, Location.EXTERIOR);
+
+    return isLine && isExteriorIfArea0 && isExteriorIfArea1;
+  }
+  /**
+   * This is an interior Area edge if
+   * <ul>
+   * <li> its label is an Area label for both Geometries
+   * <li> and for each Geometry both sides are in the interior.
+   * </ul>
+   *
+   * @return true if this is an interior Area edge
+   */
+  public boolean isInteriorAreaEdge()
+  {
+    boolean isInteriorAreaEdge = true;
+    for (int i = 0; i < 2; i++) {
+      if (! ( label.isArea(i)
+            && label.getLocation(i, Position.LEFT ) == Location.INTERIOR
+            && label.getLocation(i, Position.RIGHT) == Location.INTERIOR) ) {
+        isInteriorAreaEdge = false;
+      }
+    }
+    return isInteriorAreaEdge;
+  }
+
+  /**
+   * Compute the label in the appropriate orientation for this DirEdge
+   */
+  private void computeDirectedLabel()
+  {
+    label = new Label(edge.getLabel());
+    if (! isForward)
+      label.flip();
+  }
+
+
+  public void print(PrintStream out)
+  {
+    super.print(out);
+    out.print(" " + depth[Position.LEFT] + "/" + depth[Position.RIGHT]);
+    out.print(" (" + getDepthDelta() + ")");
+    //out.print(" " + this.hashCode());
+    //if (next != null) out.print(" next:" + next.hashCode());
+    if (isInResult) out.print(" inResult");
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/DirectedEdgeStar.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/DirectedEdgeStar.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/DirectedEdgeStar.java	(revision 28000)
@@ -0,0 +1,322 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geom.TopologyException;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * A DirectedEdgeStar is an ordered list of <b>outgoing</b> DirectedEdges around a node.
+ * It supports labelling the edges as well as linking the edges to form both
+ * MaximalEdgeRings and MinimalEdgeRings.
+ *
+ * @version 1.7
+ */
+public class DirectedEdgeStar
+  extends EdgeEndStar
+{
+
+  /**
+   * A list of all outgoing edges in the result, in CCW order
+   */
+  private List resultAreaEdgeList;
+  private Label label;
+
+  public DirectedEdgeStar() {
+  }
+  /**
+   * Insert a directed edge in the list
+   */
+  public void insert(EdgeEnd ee)
+  {
+    DirectedEdge de = (DirectedEdge) ee;
+    insertEdgeEnd(de, de);
+  }
+
+  public Label getLabel() { return label; }
+
+  public int getOutgoingDegree(EdgeRing er)
+  {
+    int degree = 0;
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      DirectedEdge de = (DirectedEdge) it.next();
+      if (de.getEdgeRing() == er) degree++;
+    }
+    return degree;
+  }
+
+  /**
+   * Compute the labelling for all dirEdges in this star, as well
+   * as the overall labelling
+   */
+  public void computeLabelling(GeometryGraph[] geom)
+  {
+//Debug.print(this);
+    super.computeLabelling(geom);
+
+    // determine the overall labelling for this DirectedEdgeStar
+    // (i.e. for the node it is based at)
+    label = new Label(Location.NONE);
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEnd ee = (EdgeEnd) it.next();
+      Edge e = ee.getEdge();
+      Label eLabel = e.getLabel();
+      for (int i = 0; i < 2; i++) {
+        int eLoc = eLabel.getLocation(i);
+        if (eLoc == Location.INTERIOR || eLoc == Location.BOUNDARY)
+          label.setLocation(i, Location.INTERIOR);
+      }
+    }
+//Debug.print(this);
+  }
+
+  /**
+   * For each dirEdge in the star,
+   * merge the label from the sym dirEdge into the label
+   */
+  public void mergeSymLabels()
+  {
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      DirectedEdge de = (DirectedEdge) it.next();
+      Label label = de.getLabel();
+      label.merge(de.getSym().getLabel());
+    }
+  }
+
+  /**
+   * Update incomplete dirEdge labels from the labelling for the node
+   */
+  public void updateLabelling(Label nodeLabel)
+  {
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      DirectedEdge de = (DirectedEdge) it.next();
+      Label label = de.getLabel();
+      label.setAllLocationsIfNull(0, nodeLabel.getLocation(0));
+      label.setAllLocationsIfNull(1, nodeLabel.getLocation(1));
+    }
+  }
+
+  private List getResultAreaEdges()
+  {
+//print(System.out);
+    if (resultAreaEdgeList != null) return resultAreaEdgeList;
+    resultAreaEdgeList = new ArrayList();
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      DirectedEdge de = (DirectedEdge) it.next();
+      if (de.isInResult() || de.getSym().isInResult() )
+        resultAreaEdgeList.add(de);
+    }
+    return resultAreaEdgeList;
+  }
+
+  private final int SCANNING_FOR_INCOMING = 1;
+  private final int LINKING_TO_OUTGOING = 2;
+  /**
+   * Traverse the star of DirectedEdges, linking the included edges together.
+   * To link two dirEdges, the <next> pointer for an incoming dirEdge
+   * is set to the next outgoing edge.
+   * <p>
+   * DirEdges are only linked if:
+   * <ul>
+   * <li>they belong to an area (i.e. they have sides)
+   * <li>they are marked as being in the result
+   * </ul>
+   * <p>
+   * Edges are linked in CCW order (the order they are stored).
+   * This means that rings have their face on the Right
+   * (in other words,
+   * the topological location of the face is given by the RHS label of the DirectedEdge)
+   * <p>
+   * PRECONDITION: No pair of dirEdges are both marked as being in the result
+   */
+  public void linkResultDirectedEdges()
+  {
+    // make sure edges are copied to resultAreaEdges list
+    getResultAreaEdges();
+    // find first area edge (if any) to start linking at
+    DirectedEdge firstOut = null;
+    DirectedEdge incoming = null;
+    int state = SCANNING_FOR_INCOMING;
+    // link edges in CCW order
+    for (int i = 0; i < resultAreaEdgeList.size(); i++) {
+      DirectedEdge nextOut = (DirectedEdge) resultAreaEdgeList.get(i);
+      DirectedEdge nextIn = nextOut.getSym();
+
+      // skip de's that we're not interested in
+      if (! nextOut.getLabel().isArea()) continue;
+
+      // record first outgoing edge, in order to link the last incoming edge
+      if (firstOut == null && nextOut.isInResult()) firstOut = nextOut;
+      // assert: sym.isInResult() == false, since pairs of dirEdges should have been removed already
+
+      switch (state) {
+      case SCANNING_FOR_INCOMING:
+        if (! nextIn.isInResult()) continue;
+        incoming = nextIn;
+        state = LINKING_TO_OUTGOING;
+        break;
+      case LINKING_TO_OUTGOING:
+        if (! nextOut.isInResult()) continue;
+        incoming.setNext(nextOut);
+        state = SCANNING_FOR_INCOMING;
+        break;
+      }
+    }
+//Debug.print(this);
+    if (state == LINKING_TO_OUTGOING) {
+//Debug.print(firstOut == null, this);
+      if (firstOut == null)
+        throw new TopologyException("no outgoing dirEdge found", getCoordinate());
+      //Assert.isTrue(firstOut != null, "no outgoing dirEdge found (at " + getCoordinate() );
+      Assert.isTrue(firstOut.isInResult(), "unable to link last incoming dirEdge");
+      incoming.setNext(firstOut);
+    }
+  }
+  public void linkMinimalDirectedEdges(EdgeRing er)
+  {
+    // find first area edge (if any) to start linking at
+    DirectedEdge firstOut = null;
+    DirectedEdge incoming = null;
+    int state = SCANNING_FOR_INCOMING;
+    // link edges in CW order
+    for (int i = resultAreaEdgeList.size() - 1; i >= 0; i--) {
+      DirectedEdge nextOut = (DirectedEdge) resultAreaEdgeList.get(i);
+      DirectedEdge nextIn = nextOut.getSym();
+
+      // record first outgoing edge, in order to link the last incoming edge
+      if (firstOut == null && nextOut.getEdgeRing() == er) firstOut = nextOut;
+
+      switch (state) {
+      case SCANNING_FOR_INCOMING:
+        if (nextIn.getEdgeRing() != er) continue;
+        incoming = nextIn;
+        state = LINKING_TO_OUTGOING;
+        break;
+      case LINKING_TO_OUTGOING:
+        if (nextOut.getEdgeRing() != er) continue;
+        incoming.setNextMin(nextOut);
+        state = SCANNING_FOR_INCOMING;
+        break;
+      }
+    }
+//print(System.out);
+    if (state == LINKING_TO_OUTGOING) {
+      Assert.isTrue(firstOut != null, "found null for first outgoing dirEdge");
+      Assert.isTrue(firstOut.getEdgeRing() == er, "unable to link last incoming dirEdge");
+      incoming.setNextMin(firstOut);
+    }
+  }
+
+  /**
+   * Traverse the star of edges, maintaing the current location in the result
+   * area at this node (if any).
+   * If any L edges are found in the interior of the result, mark them as covered.
+   */
+  public void findCoveredLineEdges()
+  {
+//Debug.print("findCoveredLineEdges");
+//Debug.print(this);
+    // Since edges are stored in CCW order around the node,
+    // as we move around the ring we move from the right to the left side of the edge
+
+    /**
+     * Find first DirectedEdge of result area (if any).
+     * The interior of the result is on the RHS of the edge,
+     * so the start location will be:
+     * - INTERIOR if the edge is outgoing
+     * - EXTERIOR if the edge is incoming
+     */
+    int startLoc = Location.NONE ;
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      DirectedEdge nextOut  = (DirectedEdge) it.next();
+      DirectedEdge nextIn   = nextOut.getSym();
+      if (! nextOut.isLineEdge()) {
+        if (nextOut.isInResult()) {
+          startLoc = Location.INTERIOR;
+          break;
+        }
+        if (nextIn.isInResult()) {
+          startLoc = Location.EXTERIOR;
+          break;
+        }
+      }
+    }
+    // no A edges found, so can't determine if L edges are covered or not
+    if (startLoc == Location.NONE) return;
+
+    /**
+     * move around ring, keeping track of the current location
+     * (Interior or Exterior) for the result area.
+     * If L edges are found, mark them as covered if they are in the interior
+     */
+    int currLoc = startLoc;
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      DirectedEdge nextOut  = (DirectedEdge) it.next();
+      DirectedEdge nextIn   = nextOut.getSym();
+      if (nextOut.isLineEdge()) {
+        nextOut.getEdge().setCovered(currLoc == Location.INTERIOR);
+//Debug.println(nextOut);
+      }
+      else {  // edge is an Area edge
+        if (nextOut.isInResult())
+          currLoc = Location.EXTERIOR;
+        if (nextIn.isInResult())
+          currLoc = Location.INTERIOR;
+      }
+    }
+  }
+
+
+  public void print(PrintStream out)
+  {
+    System.out.println("DirectedEdgeStar: " + getCoordinate());
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      DirectedEdge de = (DirectedEdge) it.next();
+      out.print("out ");
+      de.print(out);
+      out.println();
+      out.print("in ");
+      de.getSym().print(out);
+      out.println();
+    }
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Edge.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Edge.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Edge.java	(revision 28000)
@@ -0,0 +1,239 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import com.vividsolutions.jts.algorithm.LineIntersector;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.IntersectionMatrix;
+import com.vividsolutions.jts.geomgraph.index.MonotoneChainEdge;
+
+
+/**
+ * @version 1.7
+ */
+public class Edge
+  extends GraphComponent
+{
+
+  /**
+   * Updates an IM from the label for an edge.
+   * Handles edges from both L and A geometries.
+   */
+  public static void updateIM(Label label, IntersectionMatrix im)
+  {
+    im.setAtLeastIfValid(label.getLocation(0, Position.ON), label.getLocation(1, Position.ON), 1);
+    if (label.isArea()) {
+      im.setAtLeastIfValid(label.getLocation(0, Position.LEFT),  label.getLocation(1, Position.LEFT),   2);
+      im.setAtLeastIfValid(label.getLocation(0, Position.RIGHT), label.getLocation(1, Position.RIGHT),  2);
+    }
+  }
+
+  Coordinate[] pts;
+  EdgeIntersectionList eiList = new EdgeIntersectionList(this);
+  private MonotoneChainEdge mce;
+  private boolean isIsolated = true;
+  private Depth depth = new Depth();
+  private int depthDelta = 0;   // the change in area depth from the R to L side of this edge
+
+  public Edge(Coordinate[] pts, Label label)
+  {
+    this.pts = pts;
+    this.label = label;
+  }
+
+  public int getNumPoints() { return pts.length; }
+  public Coordinate[] getCoordinates()  {    return pts;  }
+  public Coordinate getCoordinate(int i)
+  {
+    return pts[i];
+  }
+  public Coordinate getCoordinate()
+  {
+    if (pts.length > 0) return pts[0];
+    return null;
+  }
+
+  public Depth getDepth() { return depth; }
+
+  /**
+   * The depthDelta is the change in depth as an edge is crossed from R to L
+   * @return the change in depth as the edge is crossed from R to L
+   */
+  public int getDepthDelta()  { return depthDelta;  }
+
+  public int getMaximumSegmentIndex()
+  {
+    return pts.length - 1;
+  }
+  public EdgeIntersectionList getEdgeIntersectionList() { return eiList; }
+
+  public MonotoneChainEdge getMonotoneChainEdge()
+  {
+    if (mce == null) mce = new MonotoneChainEdge(this);
+    return mce;
+  }
+
+  public boolean isClosed()
+  {
+    return pts[0].equals(pts[pts.length - 1]);
+  }
+  /**
+   * An Edge is collapsed if it is an Area edge and it consists of
+   * two segments which are equal and opposite (eg a zero-width V).
+   */
+  public boolean isCollapsed()
+  {
+    if (! label.isArea()) return false;
+    if (pts.length != 3) return false;
+    if (pts[0].equals(pts[2]) ) return true;
+    return false;
+  }
+  public Edge getCollapsedEdge()
+  {
+    Coordinate newPts[] = new Coordinate[2];
+    newPts[0] = pts[0];
+    newPts[1] = pts[1];
+    Edge newe = new Edge(newPts, Label.toLineLabel(label));
+    return newe;
+  }
+
+  public void setIsolated(boolean isIsolated)
+  {
+    this.isIsolated = isIsolated;
+  }
+  public boolean isIsolated()
+  {
+    return isIsolated;
+  }
+
+  /**
+   * Adds EdgeIntersections for one or both
+   * intersections found for a segment of an edge to the edge intersection list.
+   */
+  public void addIntersections(LineIntersector li, int segmentIndex, int geomIndex)
+  {
+    for (int i = 0; i < li.getIntersectionNum(); i++) {
+      addIntersection(li, segmentIndex, geomIndex, i);
+    }
+  }
+  /**
+   * Add an EdgeIntersection for intersection intIndex.
+   * An intersection that falls exactly on a vertex of the edge is normalized
+   * to use the higher of the two possible segmentIndexes
+   */
+  public void addIntersection(LineIntersector li, int segmentIndex, int geomIndex, int intIndex)
+  {
+      Coordinate intPt = new Coordinate(li.getIntersection(intIndex));
+      int normalizedSegmentIndex = segmentIndex;
+      double dist = li.getEdgeDistance(geomIndex, intIndex);
+//Debug.println("edge intpt: " + intPt + " dist: " + dist);
+      // normalize the intersection point location
+      int nextSegIndex = normalizedSegmentIndex + 1;
+      if (nextSegIndex < pts.length) {
+        Coordinate nextPt = pts[nextSegIndex];
+//Debug.println("next pt: " + nextPt);
+
+        // Normalize segment index if intPt falls on vertex
+        // The check for point equality is 2D only - Z values are ignored
+        if (intPt.equals2D(nextPt)) {
+//Debug.println("normalized distance");
+            normalizedSegmentIndex = nextSegIndex;
+            dist = 0.0;
+        }
+      }
+      /**
+      * Add the intersection point to edge intersection list.
+      */
+      /*EdgeIntersection ei =*/ eiList.add(intPt, normalizedSegmentIndex, dist);
+//ei.print(System.out);
+
+  }
+
+  /**
+   * Update the IM with the contribution for this component.
+   * A component only contributes if it has a labelling for both parent geometries
+   */
+  public void computeIM(IntersectionMatrix im)
+  {
+    updateIM(label, im);
+  }
+
+  /**
+   * equals is defined to be:
+   * <p>
+   * e1 equals e2
+   * <b>iff</b>
+   * the coordinates of e1 are the same or the reverse of the coordinates in e2
+   */
+  public boolean equals(Object o)
+  {
+    if (! (o instanceof Edge)) return false;
+    Edge e = (Edge) o;
+
+    if (pts.length != e.pts.length) return false;
+
+    boolean isEqualForward = true;
+    boolean isEqualReverse = true;
+    int iRev = pts.length;
+    for (int i = 0; i < pts.length; i++) {
+      if (! pts[i].equals2D(e.pts[i])) {
+         isEqualForward = false;
+      }
+      if (! pts[i].equals2D(e.pts[--iRev])) {
+         isEqualReverse = false;
+      }
+      if (! isEqualForward && ! isEqualReverse) return false;
+    }
+    return true;
+  }
+
+  /**
+   * @return true if the coordinate sequences of the Edges are identical
+   */
+  public boolean isPointwiseEqual(Edge e)
+  {
+    if (pts.length != e.pts.length) return false;
+
+    for (int i = 0; i < pts.length; i++) {
+      if (! pts[i].equals2D(e.pts[i])) {
+         return false;
+      }
+    }
+    return true;
+  }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeEnd.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeEnd.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeEnd.java	(revision 28000)
@@ -0,0 +1,136 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import java.io.PrintStream;
+
+import com.vividsolutions.jts.algorithm.BoundaryNodeRule;
+import com.vividsolutions.jts.algorithm.CGAlgorithms;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * Models the end of an edge incident on a node.
+ * EdgeEnds have a direction
+ * determined by the direction of the ray from the initial
+ * point to the next point.
+ * EdgeEnds are comparable under the ordering
+ * "a has a greater angle with the x-axis than b".
+ * This ordering is used to sort EdgeEnds around a node.
+ * @version 1.7
+ */
+public class EdgeEnd
+  implements Comparable<EdgeEnd>
+{
+  protected Edge edge;  // the parent edge of this edge end
+  protected Label label;
+
+  private Node node;          // the node this edge end originates at
+  private Coordinate p0, p1;  // points of initial line segment
+  private double dx, dy;      // the direction vector for this edge from its starting point
+  private int quadrant;
+
+  protected EdgeEnd(Edge edge)
+  {
+    this.edge = edge;
+  }
+  public EdgeEnd(Edge edge, Coordinate p0, Coordinate p1, Label label) {
+    this(edge);
+    init(p0, p1);
+    this.label = label;
+  }
+
+  protected void init(Coordinate p0, Coordinate p1)
+  {
+    this.p0 = p0;
+    this.p1 = p1;
+    dx = p1.x - p0.x;
+    dy = p1.y - p0.y;
+    quadrant = Quadrant.quadrant(dx, dy);
+    Assert.isTrue(! (dx == 0 && dy == 0), "EdgeEnd with identical endpoints found");
+  }
+
+  public Edge getEdge() { return edge; }
+  public Label getLabel() { return label; }
+  public Coordinate getCoordinate() { return p0; }
+  public Coordinate getDirectedCoordinate() { return p1; }
+
+  public void setNode(Node node) { this.node = node; }
+  public Node getNode() { return node; }
+
+  public int compareTo(EdgeEnd obj)
+  {
+      return compareDirection(obj);
+  }
+  /**
+   * Implements the total order relation:
+   * <p>
+   *    a has a greater angle with the positive x-axis than b
+   * <p>
+   * Using the obvious algorithm of simply computing the angle is not robust,
+   * since the angle calculation is obviously susceptible to roundoff.
+   * A robust algorithm is:
+   * - first compare the quadrant.  If the quadrants
+   * are different, it it trivial to determine which vector is "greater".
+   * - if the vectors lie in the same quadrant, the computeOrientation function
+   * can be used to decide the relative orientation of the vectors.
+   */
+  public int compareDirection(EdgeEnd e)
+  {
+    if (dx == e.dx && dy == e.dy)
+      return 0;
+    // if the rays are in different quadrants, determining the ordering is trivial
+    if (quadrant > e.quadrant) return 1;
+    if (quadrant < e.quadrant) return -1;
+    // vectors are in the same quadrant - check relative orientation of direction vectors
+    // this is > e if it is CCW of e
+    return CGAlgorithms.computeOrientation(e.p0, e.p1, p1);
+  }
+
+  @SuppressWarnings("unused")
+public void computeLabel(BoundaryNodeRule boundaryNodeRule)
+  {
+    // subclasses should override this if they are using labels
+  }
+  public void print(PrintStream out)
+  {
+    double angle = Math.atan2(dy, dx);
+    String className = getClass().getName();
+    int lastDotPos = className.lastIndexOf('.');
+    String name = className.substring(lastDotPos + 1);
+    out.print("  " + name + ": " + p0 + " - " + p1 + " " + quadrant + ":" + angle + "   " + label);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeEndStar.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeEndStar.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeEndStar.java	(revision 28000)
@@ -0,0 +1,327 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.vividsolutions.jts.algorithm.BoundaryNodeRule;
+import com.vividsolutions.jts.algorithm.locate.SimplePointInAreaLocator;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geom.TopologyException;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * A EdgeEndStar is an ordered list of EdgeEnds around a node.
+ * They are maintained in CCW order (starting with the positive x-axis) around the node
+ * for efficient lookup and topology building.
+ *
+ * @version 1.7
+ */
+abstract public class EdgeEndStar
+{
+
+  /**
+   * A map which maintains the edges in sorted order around the node
+   */
+  protected Map edgeMap = new TreeMap();
+  /**
+   * A list of all outgoing edges in the result, in CCW order
+   */
+  protected List edgeList;
+  /**
+   * The location of the point for this star in Geometry i Areas
+   */
+  private int[] ptInAreaLocation = { Location.NONE, Location.NONE };
+
+  public EdgeEndStar()
+  {
+
+  }
+
+  /**
+   * Insert a EdgeEnd into this EdgeEndStar
+   */
+  abstract public void insert(EdgeEnd e);
+
+  /**
+   * Insert an EdgeEnd into the map, and clear the edgeList cache,
+   * since the list of edges has now changed
+   */
+  protected void insertEdgeEnd(EdgeEnd e, Object obj)
+  {
+    edgeMap.put(e, obj);
+    edgeList = null;  // edge list has changed - clear the cache
+  }
+
+  /**
+   * @return the coordinate for the node this star is based at
+   */
+  public Coordinate getCoordinate()
+  {
+    Iterator it = iterator();
+    if (! it.hasNext()) return null;
+    EdgeEnd e = (EdgeEnd) it.next();
+    return e.getCoordinate();
+  }
+  public int getDegree()
+  {
+    return edgeMap.size();
+  }
+
+  /**
+   * Iterator access to the ordered list of edges is optimized by
+   * copying the map collection to a list.  (This assumes that
+   * once an iterator is requested, it is likely that insertion into
+   * the map is complete).
+   */
+  public Iterator iterator()
+  {
+    return getEdges().iterator();
+  }
+  public List getEdges()
+  {
+    if (edgeList == null) {
+      edgeList = new ArrayList(edgeMap.values());
+    }
+    return edgeList;
+  }
+
+  public void computeLabelling(GeometryGraph[] geomGraph)
+  {
+    computeEdgeEndLabels(geomGraph[0].getBoundaryNodeRule());
+    // Propagate side labels  around the edges in the star
+    // for each parent Geometry
+//Debug.print(this);
+    propagateSideLabels(0);
+//Debug.print(this);
+//Debug.printIfWatch(this);
+    propagateSideLabels(1);
+//Debug.print(this);
+//Debug.printIfWatch(this);
+
+    /**
+     * If there are edges that still have null labels for a geometry
+     * this must be because there are no area edges for that geometry incident on this node.
+     * In this case, to label the edge for that geometry we must test whether the
+     * edge is in the interior of the geometry.
+     * To do this it suffices to determine whether the node for the edge is in the interior of an area.
+     * If so, the edge has location INTERIOR for the geometry.
+     * In all other cases (e.g. the node is on a line, on a point, or not on the geometry at all) the edge
+     * has the location EXTERIOR for the geometry.
+     * <p>
+     * Note that the edge cannot be on the BOUNDARY of the geometry, since then
+     * there would have been a parallel edge from the Geometry at this node also labelled BOUNDARY
+     * and this edge would have been labelled in the previous step.
+     * <p>
+     * This code causes a problem when dimensional collapses are present, since it may try and
+     * determine the location of a node where a dimensional collapse has occurred.
+     * The point should be considered to be on the EXTERIOR
+     * of the polygon, but locate() will return INTERIOR, since it is passed
+     * the original Geometry, not the collapsed version.
+     *
+     * If there are incident edges which are Line edges labelled BOUNDARY,
+     * then they must be edges resulting from dimensional collapses.
+     * In this case the other edges can be labelled EXTERIOR for this Geometry.
+     *
+     * MD 8/11/01 - NOT TRUE!  The collapsed edges may in fact be in the interior of the Geometry,
+     * which means the other edges should be labelled INTERIOR for this Geometry.
+     * Not sure how solve this...  Possibly labelling needs to be split into several phases:
+     * area label propagation, symLabel merging, then finally null label resolution.
+     */
+    boolean[] hasDimensionalCollapseEdge = { false, false };
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEnd e = (EdgeEnd) it.next();
+      Label label = e.getLabel();
+      for (int geomi = 0; geomi < 2; geomi++) {
+        if (label.isLine(geomi) && label.getLocation(geomi) == Location.BOUNDARY)
+          hasDimensionalCollapseEdge[geomi] = true;
+      }
+    }
+//Debug.print(this);
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEnd e = (EdgeEnd) it.next();
+      Label label = e.getLabel();
+//Debug.println(e);
+      for (int geomi = 0; geomi < 2; geomi++) {
+        if (label.isAnyNull(geomi)) {
+          int loc = Location.NONE;
+          if (hasDimensionalCollapseEdge[geomi]) {
+            loc = Location.EXTERIOR;
+          }
+          else {
+            Coordinate p = e.getCoordinate();
+            loc = getLocation(geomi, p, geomGraph);
+          }
+          label.setAllLocationsIfNull(geomi, loc);
+        }
+      }
+//Debug.println(e);
+    }
+//Debug.print(this);
+//Debug.printIfWatch(this);
+  }
+
+  private void computeEdgeEndLabels(BoundaryNodeRule boundaryNodeRule)
+  {
+    // Compute edge label for each EdgeEnd
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEnd ee = (EdgeEnd) it.next();
+      ee.computeLabel(boundaryNodeRule);
+    }
+  }
+  
+  private int getLocation(int geomIndex, Coordinate p, GeometryGraph[] geom)
+  {
+    // compute location only on demand
+    if (ptInAreaLocation[geomIndex] == Location.NONE) {
+      ptInAreaLocation[geomIndex] = SimplePointInAreaLocator.locate(p, geom[geomIndex].getGeometry());
+    }
+    return ptInAreaLocation[geomIndex];
+  }
+
+  public boolean isAreaLabelsConsistent(GeometryGraph geomGraph)
+  {
+    computeEdgeEndLabels(geomGraph.getBoundaryNodeRule());
+    return checkAreaLabelsConsistent(0);
+  }
+
+  private boolean checkAreaLabelsConsistent(int geomIndex)
+  {
+    // Since edges are stored in CCW order around the node,
+    // As we move around the ring we move from the right to the left side of the edge
+    List edges = getEdges();
+    // if no edges, trivially consistent
+    if (edges.size() <= 0)
+      return true;
+    // initialize startLoc to location of last L side (if any)
+    int lastEdgeIndex = edges.size() - 1;
+    Label startLabel = ((EdgeEnd) edges.get(lastEdgeIndex)).getLabel();
+    int startLoc = startLabel.getLocation(geomIndex, Position.LEFT);
+    Assert.isTrue(startLoc != Location.NONE, "Found unlabelled area edge");
+
+    int currLoc = startLoc;
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEnd e = (EdgeEnd) it.next();
+      Label label = e.getLabel();
+      // we assume that we are only checking a area
+      Assert.isTrue(label.isArea(geomIndex), "Found non-area edge");
+      int leftLoc   = label.getLocation(geomIndex, Position.LEFT);
+      int rightLoc  = label.getLocation(geomIndex, Position.RIGHT);
+//System.out.println(leftLoc + " " + rightLoc);
+//Debug.print(this);
+      // check that edge is really a boundary between inside and outside!
+      if (leftLoc == rightLoc) {
+        return false;
+      }
+      // check side location conflict
+      //Assert.isTrue(rightLoc == currLoc, "side location conflict " + locStr);
+      if (rightLoc != currLoc) {
+//Debug.print(this);
+        return false;
+      }
+      currLoc = leftLoc;
+    }
+    return true;
+  }
+  void propagateSideLabels(int geomIndex)
+  {
+    // Since edges are stored in CCW order around the node,
+    // As we move around the ring we move from the right to the left side of the edge
+    int startLoc = Location.NONE ;
+    
+    // initialize loc to location of last L side (if any)
+//System.out.println("finding start location");
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEnd e = (EdgeEnd) it.next();
+      Label label = e.getLabel();
+      if (label.isArea(geomIndex) && label.getLocation(geomIndex, Position.LEFT) != Location.NONE)
+        startLoc = label.getLocation(geomIndex, Position.LEFT);
+    }
+    
+    // no labelled sides found, so no labels to propagate
+    if (startLoc == Location.NONE) return;
+
+    int currLoc = startLoc;
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEnd e = (EdgeEnd) it.next();
+      Label label = e.getLabel();
+      // set null ON values to be in current location
+      if (label.getLocation(geomIndex, Position.ON) == Location.NONE)
+          label.setLocation(geomIndex, Position.ON, currLoc);
+      // set side labels (if any)
+      if (label.isArea(geomIndex)) {
+        int leftLoc   = label.getLocation(geomIndex, Position.LEFT);
+        int rightLoc  = label.getLocation(geomIndex, Position.RIGHT);
+        // if there is a right location, that is the next location to propagate
+        if (rightLoc != Location.NONE) {
+//Debug.print(rightLoc != currLoc, this);
+          if (rightLoc != currLoc)
+            throw new TopologyException("side location conflict", e.getCoordinate());
+          if (leftLoc == Location.NONE) {
+            Assert.shouldNeverReachHere("found single null side (at " + e.getCoordinate() + ")");
+          }
+          currLoc = leftLoc;
+        }
+        else {
+          /** RHS is null - LHS must be null too.
+           *  This must be an edge from the other geometry, which has no location
+           *  labelling for this geometry.  This edge must lie wholly inside or outside
+           *  the other geometry (which is determined by the current location).
+           *  Assign both sides to be the current location.
+           */
+          Assert.isTrue(label.getLocation(geomIndex, Position.LEFT) == Location.NONE, "found single null side");
+          label.setLocation(geomIndex, Position.RIGHT, currLoc);
+          label.setLocation(geomIndex, Position.LEFT, currLoc);
+        }
+      }
+    }
+  }
+
+  public void print(PrintStream out)
+  {
+    System.out.println("EdgeEndStar:   " + getCoordinate());
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEnd e = (EdgeEnd) it.next();
+      e.print(out);
+    }
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeIntersection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeIntersection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeIntersection.java	(revision 28000)
@@ -0,0 +1,89 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import com.vividsolutions.jts.geom.Coordinate;
+
+/**
+ * Represents a point on an
+ * edge which intersects with another edge.
+ * <p>
+ * The intersection may either be a single point, or a line segment
+ * (in which case this point is the start of the line segment)
+ * The intersection point must be precise.
+ *
+ * @version 1.7
+ */
+public class EdgeIntersection
+    implements Comparable
+{
+
+  public Coordinate coord;   // the point of intersection
+  public int segmentIndex;   // the index of the containing line segment in the parent edge
+  public double dist;        // the edge distance of this point along the containing line segment
+
+  public EdgeIntersection(Coordinate coord, int segmentIndex, double dist) {
+    this.coord = new Coordinate(coord);
+    this.segmentIndex = segmentIndex;
+    this.dist = dist;
+  }
+
+  public int compareTo(Object obj)
+  {
+    EdgeIntersection other = (EdgeIntersection) obj;
+    return compare(other.segmentIndex, other.dist);
+  }
+  /**
+   * @return -1 this EdgeIntersection is located before the argument location
+   * @return 0 this EdgeIntersection is at the argument location
+   * @return 1 this EdgeIntersection is located after the argument location
+   */
+  public int compare(int segmentIndex, double dist)
+  {
+    if (this.segmentIndex < segmentIndex) return -1;
+    if (this.segmentIndex > segmentIndex) return 1;
+    if (this.dist < dist) return -1;
+    if (this.dist > dist) return 1;
+    return 0;
+  }
+
+  public boolean isEndPoint(int maxSegmentIndex)
+  {
+    if (segmentIndex == 0 && dist == 0.0) return true;
+    if (segmentIndex == maxSegmentIndex) return true;
+    return false;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeIntersectionList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeIntersectionList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeIntersectionList.java	(revision 28000)
@@ -0,0 +1,163 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.vividsolutions.jts.geom.Coordinate;
+
+/**
+ * A list of edge intersections along an {@link Edge}.
+ * Implements splitting an edge with intersections
+ * into multiple resultant edges.
+ *
+ * @version 1.7
+ */
+public class EdgeIntersectionList
+{
+  // a Map <EdgeIntersection, EdgeIntersection>
+  private Map nodeMap = new TreeMap();
+  Edge edge;  // the parent edge
+
+  public EdgeIntersectionList(Edge edge)
+  {
+    this.edge = edge;
+  }
+
+  /**
+   * Adds an intersection into the list, if it isn't already there.
+   * The input segmentIndex and dist are expected to be normalized.
+   * @return the EdgeIntersection found or added
+   */
+  public EdgeIntersection add(Coordinate intPt, int segmentIndex, double dist)
+  {
+    EdgeIntersection eiNew = new EdgeIntersection(intPt, segmentIndex, dist);
+    EdgeIntersection ei = (EdgeIntersection) nodeMap.get(eiNew);
+    if (ei != null) {
+      return ei;
+    }
+    nodeMap.put(eiNew, eiNew);
+    return eiNew;
+  }
+
+  /**
+   * Returns an iterator of {@link EdgeIntersection}s
+   *
+   * @return an Iterator of EdgeIntersections
+   */
+  public Iterator iterator() { return nodeMap.values().iterator(); }
+
+  /**
+   * Tests if the given point is an edge intersection
+   *
+   * @param pt the point to test
+   * @return true if the point is an intersection
+   */
+  public boolean isIntersection(Coordinate pt)
+  {
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeIntersection ei = (EdgeIntersection) it.next();
+      if (ei.coord.equals(pt))
+       return true;
+    }
+    return false;
+  }
+
+  /**
+   * Adds entries for the first and last points of the edge to the list
+   */
+  public void addEndpoints()
+  {
+    int maxSegIndex = edge.pts.length - 1;
+    add(edge.pts[0], 0, 0.0);
+    add(edge.pts[maxSegIndex], maxSegIndex, 0.0);
+  }
+
+  /**
+   * Creates new edges for all the edges that the intersections in this
+   * list split the parent edge into.
+   * Adds the edges to the input list (this is so a single list
+   * can be used to accumulate all split edges for a Geometry).
+   *
+   * @param edgeList a list of EdgeIntersections
+   */
+  public void addSplitEdges(List edgeList)
+  {
+    // ensure that the list has entries for the first and last point of the edge
+    addEndpoints();
+
+    Iterator it = iterator();
+    // there should always be at least two entries in the list
+    EdgeIntersection eiPrev = (EdgeIntersection) it.next();
+    while (it.hasNext()) {
+      EdgeIntersection ei = (EdgeIntersection) it.next();
+      Edge newEdge = createSplitEdge(eiPrev, ei);
+      edgeList.add(newEdge);
+
+      eiPrev = ei;
+    }
+  }
+  /**
+   * Create a new "split edge" with the section of points between
+   * (and including) the two intersections.
+   * The label for the new edge is the same as the label for the parent edge.
+   */
+  Edge createSplitEdge(EdgeIntersection ei0, EdgeIntersection ei1)
+  {
+//Debug.print("\ncreateSplitEdge"); Debug.print(ei0); Debug.print(ei1);
+    int npts = ei1.segmentIndex - ei0.segmentIndex + 2;
+
+    Coordinate lastSegStartPt = edge.pts[ei1.segmentIndex];
+    // if the last intersection point is not equal to the its segment start pt,
+    // add it to the points list as well.
+    // (This check is needed because the distance metric is not totally reliable!)
+    // The check for point equality is 2D only - Z values are ignored
+    boolean useIntPt1 = ei1.dist > 0.0 || ! ei1.coord.equals2D(lastSegStartPt);
+    if (! useIntPt1) {
+      npts--;
+    }
+
+    Coordinate[] pts = new Coordinate[npts];
+    int ipt = 0;
+    pts[ipt++] = new Coordinate(ei0.coord);
+    for (int i = ei0.segmentIndex + 1; i <= ei1.segmentIndex; i++) {
+      pts[ipt++] = edge.pts[i];
+    }
+    if (useIntPt1) pts[ipt] = ei1.coord;
+    return new Edge(pts, new Label(edge.label));
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeList.java	(revision 28000)
@@ -0,0 +1,100 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.vividsolutions.jts.noding.OrientedCoordinateArray;
+
+/**
+ * A EdgeList is a list of Edges.  It supports locating edges
+ * that are pointwise equals to a target edge.
+ * @version 1.7
+ */
+public class EdgeList
+{
+  private List edges = new ArrayList();
+  /**
+   * An index of the edges, for fast lookup.
+   *
+   */
+  private Map ocaMap = new TreeMap();
+
+  public EdgeList() {
+  }
+
+  /**
+   * Insert an edge unless it is already in the list
+   */
+  public void add(Edge e)
+  {
+    edges.add(e);
+    OrientedCoordinateArray oca = new OrientedCoordinateArray(e.getCoordinates());
+    ocaMap.put(oca, e);
+  }
+
+  public void addAll(Collection edgeColl)
+  {
+    for (Iterator i = edgeColl.iterator(); i.hasNext(); ) {
+      add((Edge) i.next());
+    }
+  }
+
+  public List getEdges() { return edges; }
+
+  /**
+   * If there is an edge equal to e already in the list, return it.
+   * Otherwise return null.
+   * @return  equal edge, if there is one already in the list
+   *          null otherwise
+   */
+  public Edge findEqualEdge(Edge e)
+  {
+    OrientedCoordinateArray oca = new OrientedCoordinateArray(e.getCoordinates());
+    // will return null if no edge matches
+    Edge matchEdge = (Edge) ocaMap.get(oca);
+    return matchEdge; 
+  }
+  
+  public Iterator iterator() { return edges.iterator(); }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeNodingValidator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeNodingValidator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeNodingValidator.java	(revision 28000)
@@ -0,0 +1,102 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import com.vividsolutions.jts.geom.TopologyException;
+import com.vividsolutions.jts.noding.BasicSegmentString;
+import com.vividsolutions.jts.noding.FastNodingValidator;
+
+/**
+ * Validates that a collection of {@link Edge}s is correctly noded.
+ * Throws an appropriate exception if an noding error is found.
+ *
+ * @version 1.7
+ */
+public class EdgeNodingValidator 
+{  
+	/**
+   * Checks whether the supplied {@link Edge}s
+   * are correctly noded.  
+   * Throws a  {@link TopologyException} if they are not.
+   * 
+   * @param edges a collection of Edges.
+   * @throws TopologyException if the SegmentStrings are not correctly noded
+   *
+   */
+	public static void checkValid(Collection edges)
+	{
+		EdgeNodingValidator validator = new EdgeNodingValidator(edges);
+		validator.checkValid();
+	}
+	
+  public static Collection toSegmentStrings(Collection edges)
+  {
+    // convert Edges to SegmentStrings
+    Collection segStrings = new ArrayList();
+    for (Iterator i = edges.iterator(); i.hasNext(); ) {
+      Edge e = (Edge) i.next();
+      segStrings.add(new BasicSegmentString(e.getCoordinates(), e));
+    }
+    return segStrings;
+  }
+
+  private FastNodingValidator nv;
+
+  /**
+   * Creates a new validator for the given collection of {@link Edge}s.
+   * 
+   * @param edges a collection of Edges.
+   */
+  public EdgeNodingValidator(Collection edges)
+  {
+    nv = new FastNodingValidator(toSegmentStrings(edges));
+  }
+
+  /**
+   * Checks whether the supplied edges
+   * are correctly noded.  Throws an exception if they are not.
+   * 
+   * @throws TopologyException if the SegmentStrings are not correctly noded
+   *
+   */
+  public void checkValid()
+  {
+    nv.checkValid();
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeRing.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeRing.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/EdgeRing.java	(revision 28000)
@@ -0,0 +1,224 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vividsolutions.jts.algorithm.CGAlgorithms;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geom.TopologyException;
+import com.vividsolutions.jts.util.Assert;
+
+
+/**
+ * @version 1.7
+ */
+public abstract class EdgeRing {
+
+  protected DirectedEdge startDe; // the directed edge which starts the list of edges for this EdgeRing
+  private int maxNodeDegree = -1;
+  private List edges = new ArrayList(); // the DirectedEdges making up this EdgeRing
+  private List pts = new ArrayList();
+  private Label label = new Label(Location.NONE); // label stores the locations of each geometry on the face surrounded by this ring
+  private LinearRing ring;  // the ring created for this EdgeRing
+  private boolean isHole;
+  private EdgeRing shell;   // if non-null, the ring is a hole and this EdgeRing is its containing shell
+  private ArrayList holes = new ArrayList(); // a list of EdgeRings which are holes in this EdgeRing
+
+  protected GeometryFactory geometryFactory;
+
+  public EdgeRing(DirectedEdge start, GeometryFactory geometryFactory) {
+    this.geometryFactory = geometryFactory;
+    computePoints(start);
+    computeRing();
+  }
+
+  public boolean isHole()
+  {
+    //computePoints();
+    return isHole;
+  }
+
+  public Coordinate getCoordinate(int i) { return (Coordinate) pts.get(i);  }
+  public LinearRing getLinearRing() { return ring; }
+  public EdgeRing getShell() { return shell; }
+  public void setShell(EdgeRing shell)
+  {
+    this.shell = shell;
+    if (shell != null) shell.addHole(this);
+  }
+  public void addHole(EdgeRing ring) { holes.add(ring); }
+
+  public Polygon toPolygon(GeometryFactory geometryFactory)
+  {
+    LinearRing[] holeLR = new LinearRing[holes.size()];
+    for (int i = 0; i < holes.size(); i++) {
+      holeLR[i] = ((EdgeRing) holes.get(i)).getLinearRing();
+    }
+    Polygon poly = geometryFactory.createPolygon(getLinearRing(), holeLR);
+    return poly;
+  }
+  /**
+   * Compute a LinearRing from the point list previously collected.
+   * Test if the ring is a hole (i.e. if it is CCW) and set the hole flag
+   * accordingly.
+   */
+  public void computeRing()
+  {
+    if (ring != null) return;   // don't compute more than once
+    Coordinate[] coord = new Coordinate[pts.size()];
+    for (int i = 0; i < pts.size(); i++) {
+      coord[i] = (Coordinate) pts.get(i);
+    }
+    ring = geometryFactory.createLinearRing(coord);
+    isHole = CGAlgorithms.isCCW(ring.getCoordinates());
+//Debug.println( (isHole ? "hole - " : "shell - ") + WKTWriter.toLineString(new CoordinateArraySequence(ring.getCoordinates())));
+  }
+  abstract public DirectedEdge getNext(DirectedEdge de);
+  abstract public void setEdgeRing(DirectedEdge de, EdgeRing er);
+
+  /**
+   * Returns the list of DirectedEdges that make up this EdgeRing
+   */
+  public List getEdges() { return edges; }
+
+  /**
+   * Collect all the points from the DirectedEdges of this ring into a contiguous list
+   */
+  protected void computePoints(DirectedEdge start)
+  {
+//System.out.println("buildRing");
+    startDe = start;
+    DirectedEdge de = start;
+    boolean isFirstEdge = true;
+    do {
+//      Assert.isTrue(de != null, "found null Directed Edge");
+      if (de == null)
+        throw new TopologyException("Found null DirectedEdge");
+      if (de.getEdgeRing() == this)
+        throw new TopologyException("Directed Edge visited twice during ring-building at " + de.getCoordinate());
+
+      edges.add(de);
+//Debug.println(de);
+//Debug.println(de.getEdge());
+      Label label = de.getLabel();
+      Assert.isTrue(label.isArea());
+      mergeLabel(label);
+      addPoints(de.getEdge(), de.isForward(), isFirstEdge);
+      isFirstEdge = false;
+      setEdgeRing(de, this);
+      de = getNext(de);
+    } while (de != startDe);
+  }
+
+  public int getMaxNodeDegree()
+  {
+    if (maxNodeDegree < 0) computeMaxNodeDegree();
+    return maxNodeDegree;
+  }
+
+  private void computeMaxNodeDegree()
+  {
+    maxNodeDegree = 0;
+    DirectedEdge de = startDe;
+    do {
+      Node node = de.getNode();
+      int degree = ((DirectedEdgeStar) node.getEdges()).getOutgoingDegree(this);
+      if (degree > maxNodeDegree) maxNodeDegree = degree;
+      de = getNext(de);
+    } while (de != startDe);
+    maxNodeDegree *= 2;
+  }
+
+
+  public void setInResult()
+  {
+    DirectedEdge de = startDe;
+    do {
+      de.getEdge().setInResult(true);
+      de = de.getNext();
+    } while (de != startDe);
+  }
+
+  protected void mergeLabel(Label deLabel)
+  {
+    mergeLabel(deLabel, 0);
+    mergeLabel(deLabel, 1);
+  }
+  /**
+   * Merge the RHS label from a DirectedEdge into the label for this EdgeRing.
+   * The DirectedEdge label may be null.  This is acceptable - it results
+   * from a node which is NOT an intersection node between the Geometries
+   * (e.g. the end node of a LinearRing).  In this case the DirectedEdge label
+   * does not contribute any information to the overall labelling, and is simply skipped.
+   */
+  protected void mergeLabel(Label deLabel, int geomIndex)
+  {
+    int loc = deLabel.getLocation(geomIndex, Position.RIGHT);
+    // no information to be had from this label
+    if (loc == Location.NONE) return;
+    // if there is no current RHS value, set it
+    if (label.getLocation(geomIndex) == Location.NONE) {
+      label.setLocation(geomIndex, loc);
+      return;
+    }
+  }
+  protected void addPoints(Edge edge, boolean isForward, boolean isFirstEdge)
+  {
+    Coordinate[] edgePts = edge.getCoordinates();
+    if (isForward) {
+      int startIndex = 1;
+      if (isFirstEdge) startIndex = 0;
+      for (int i = startIndex; i < edgePts.length; i++) {
+        pts.add(edgePts[i]);
+      }
+    }
+    else { // is backward
+      int startIndex = edgePts.length - 2;
+      if (isFirstEdge) startIndex = edgePts.length - 1;
+      for (int i = startIndex; i >= 0; i--) {
+        pts.add(edgePts[i]);
+      }
+    }
+  }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/GeometryGraph.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/GeometryGraph.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/GeometryGraph.java	(revision 28000)
@@ -0,0 +1,424 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import com.vividsolutions.jts.algorithm.BoundaryNodeRule;
+import com.vividsolutions.jts.algorithm.CGAlgorithms;
+import com.vividsolutions.jts.algorithm.LineIntersector;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateArrays;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geom.MultiLineString;
+import com.vividsolutions.jts.geom.MultiPoint;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geomgraph.index.EdgeSetIntersector;
+import com.vividsolutions.jts.geomgraph.index.SegmentIntersector;
+import com.vividsolutions.jts.geomgraph.index.SimpleMCSweepLineIntersector;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * A GeometryGraph is a graph that models a given Geometry
+ * @version 1.7
+ */
+public class GeometryGraph
+  extends PlanarGraph
+{
+/**
+ * This method implements the Boundary Determination Rule
+ * for determining whether
+ * a component (node or edge) that appears multiple times in elements
+ * of a MultiGeometry is in the boundary or the interior of the Geometry
+ * <br>
+ * The SFS uses the "Mod-2 Rule", which this function implements
+ * <br>
+ * An alternative (and possibly more intuitive) rule would be
+ * the "At Most One Rule":
+ *    isInBoundary = (componentCount == 1)
+ */
+/*
+  public static boolean isInBoundary(int boundaryCount)
+  {
+    // the "Mod-2 Rule"
+    return boundaryCount % 2 == 1;
+  }
+  public static int determineBoundary(int boundaryCount)
+  {
+    return isInBoundary(boundaryCount) ? Location.BOUNDARY : Location.INTERIOR;
+  }
+*/
+
+  public static int determineBoundary(BoundaryNodeRule boundaryNodeRule, int boundaryCount)
+  {
+    return boundaryNodeRule.isInBoundary(boundaryCount)
+        ? Location.BOUNDARY : Location.INTERIOR;
+  }
+
+  private Geometry parentGeom;
+
+  /**
+   * The lineEdgeMap is a map of the linestring components of the
+   * parentGeometry to the edges which are derived from them.
+   * This is used to efficiently perform findEdge queries
+   */
+  private Map lineEdgeMap = new HashMap();
+
+  private BoundaryNodeRule boundaryNodeRule = null;
+
+  /**
+   * If this flag is true, the Boundary Determination Rule will used when deciding
+   * whether nodes are in the boundary or not
+   */
+  private boolean useBoundaryDeterminationRule = true;
+  private int argIndex;  // the index of this geometry as an argument to a spatial function (used for labelling)
+  private Collection boundaryNodes;
+  private boolean hasTooFewPoints = false;
+  private Coordinate invalidPoint = null;
+
+  // for use if geometry is not Polygonal
+  
+  private EdgeSetIntersector createEdgeSetIntersector()
+  {
+  // various options for computing intersections, from slowest to fastest
+
+  //private EdgeSetIntersector esi = new SimpleEdgeSetIntersector();
+  //private EdgeSetIntersector esi = new MonotoneChainIntersector();
+  //private EdgeSetIntersector esi = new NonReversingChainIntersector();
+  //private EdgeSetIntersector esi = new SimpleSweepLineIntersector();
+  //private EdgeSetIntersector esi = new MCSweepLineIntersector();
+
+    //return new SimpleEdgeSetIntersector();
+    return new SimpleMCSweepLineIntersector();
+  }
+
+  public GeometryGraph(int argIndex, Geometry parentGeom)
+  {
+    this(argIndex, parentGeom,
+         BoundaryNodeRule.OGC_SFS_BOUNDARY_RULE
+         );
+  }
+
+  public GeometryGraph(int argIndex, Geometry parentGeom, BoundaryNodeRule boundaryNodeRule) {
+    this.argIndex = argIndex;
+    this.parentGeom = parentGeom;
+    this.boundaryNodeRule = boundaryNodeRule;
+    if (parentGeom != null) {
+//      precisionModel = parentGeom.getPrecisionModel();
+//      SRID = parentGeom.getSRID();
+      add(parentGeom);
+    }
+  }
+
+  /**
+   * This constructor is used by clients that wish to add Edges explicitly,
+   * rather than adding a Geometry.  (An example is BufferOp).
+   */
+  // no longer used
+//  public GeometryGraph(int argIndex, PrecisionModel precisionModel, int SRID) {
+//    this(argIndex, null);
+//    this.precisionModel = precisionModel;
+//    this.SRID = SRID;
+//  }
+//  public PrecisionModel getPrecisionModel()
+//  {
+//    return precisionModel;
+//  }
+//  public int getSRID() { return SRID; }
+
+  public boolean hasTooFewPoints() { return hasTooFewPoints; }
+
+  public Coordinate getInvalidPoint() { return invalidPoint; }
+
+  public Geometry getGeometry() { return parentGeom; }
+
+  public BoundaryNodeRule getBoundaryNodeRule() { return boundaryNodeRule; }
+
+  public Collection getBoundaryNodes()
+  {
+    if (boundaryNodes == null)
+      boundaryNodes = nodes.getBoundaryNodes(argIndex);
+    return boundaryNodes;
+  }
+
+
+  public Edge findEdge(LineString line)
+  {
+    return (Edge) lineEdgeMap.get(line);
+  }
+
+  public void computeSplitEdges(List edgelist)
+  {
+    for (Iterator i = edges.iterator(); i.hasNext(); ) {
+      Edge e = (Edge) i.next();
+      e.eiList.addSplitEdges(edgelist);
+    }
+  }
+  private void add(Geometry g)
+  {
+    if (g.isEmpty()) return;
+
+    // check if this Geometry should obey the Boundary Determination Rule
+    // all collections except MultiPolygons obey the rule
+    if (g instanceof MultiPolygon)
+      useBoundaryDeterminationRule = false;
+
+    if (g instanceof Polygon)                 addPolygon((Polygon) g);
+                        // LineString also handles LinearRings
+    else if (g instanceof LineString)         addLineString((LineString) g);
+    else if (g instanceof Point)              addPoint((Point) g);
+    else if (g instanceof MultiPoint)         addCollection((MultiPoint) g);
+    else if (g instanceof MultiLineString)    addCollection((MultiLineString) g);
+    else if (g instanceof MultiPolygon)       addCollection((MultiPolygon) g);
+    else if (g instanceof GeometryCollection) addCollection((GeometryCollection) g);
+    else  throw new UnsupportedOperationException(g.getClass().getName());
+  }
+
+  private void addCollection(GeometryCollection gc)
+  {
+    for (int i = 0; i < gc.getNumGeometries(); i++) {
+      Geometry g = gc.getGeometryN(i);
+      add(g);
+    }
+  }
+  /**
+   * Add a Point to the graph.
+   */
+  private void addPoint(Point p)
+  {
+    Coordinate coord = p.getCoordinate();
+    insertPoint(argIndex, coord, Location.INTERIOR);
+  }
+  
+  /**
+   * Adds a polygon ring to the graph.
+   * Empty rings are ignored.
+   * 
+   * The left and right topological location arguments assume that the ring is oriented CW.
+   * If the ring is in the opposite orientation,
+   * the left and right locations must be interchanged.
+   */
+  private void addPolygonRing(LinearRing lr, int cwLeft, int cwRight)
+  {
+  	// don't bother adding empty holes
+  	if (lr.isEmpty()) return;
+  	
+    Coordinate[] coord = CoordinateArrays.removeRepeatedPoints(lr.getCoordinates());
+
+    if (coord.length < 4) {
+      hasTooFewPoints = true;
+      invalidPoint = coord[0];
+      return;
+    }
+
+    int left  = cwLeft;
+    int right = cwRight;
+    if (CGAlgorithms.isCCW(coord)) {
+      left = cwRight;
+      right = cwLeft;
+    }
+    Edge e = new Edge(coord,
+                        new Label(argIndex, Location.BOUNDARY, left, right));
+    lineEdgeMap.put(lr, e);
+
+    insertEdge(e);
+    // insert the endpoint as a node, to mark that it is on the boundary
+    insertPoint(argIndex, coord[0], Location.BOUNDARY);
+  }
+
+  private void addPolygon(Polygon p)
+  {
+    addPolygonRing(
+            (LinearRing) p.getExteriorRing(),
+            Location.EXTERIOR,
+            Location.INTERIOR);
+
+    for (int i = 0; i < p.getNumInteriorRing(); i++) {
+    	LinearRing hole = (LinearRing) p.getInteriorRingN(i);
+    	
+      // Holes are topologically labelled opposite to the shell, since
+      // the interior of the polygon lies on their opposite side
+      // (on the left, if the hole is oriented CW)
+      addPolygonRing(
+      		hole,
+          Location.INTERIOR,
+          Location.EXTERIOR);
+    }
+  }
+
+  private void addLineString(LineString line)
+  {
+    Coordinate[] coord = CoordinateArrays.removeRepeatedPoints(line.getCoordinates());
+
+    if (coord.length < 2) {
+      hasTooFewPoints = true;
+      invalidPoint = coord[0];
+      return;
+    }
+
+    // add the edge for the LineString
+    // line edges do not have locations for their left and right sides
+    Edge e = new Edge(coord, new Label(argIndex, Location.INTERIOR));
+    lineEdgeMap.put(line, e);
+    insertEdge(e);
+    /**
+     * Add the boundary points of the LineString, if any.
+     * Even if the LineString is closed, add both points as if they were endpoints.
+     * This allows for the case that the node already exists and is a boundary point.
+     */
+    Assert.isTrue(coord.length >= 2, "found LineString with single point");
+    insertBoundaryPoint(argIndex, coord[0]);
+    insertBoundaryPoint(argIndex, coord[coord.length - 1]);
+
+  }
+
+
+  /**
+   * Compute self-nodes, taking advantage of the Geometry type to
+   * minimize the number of intersection tests.  (E.g. rings are
+   * not tested for self-intersection, since they are assumed to be valid).
+   * @param li the LineIntersector to use
+   * @param computeRingSelfNodes if <false>, intersection checks are optimized to not test rings for self-intersection
+   * @return the SegmentIntersector used, containing information about the intersections found
+   */
+  public SegmentIntersector computeSelfNodes(LineIntersector li, boolean computeRingSelfNodes)
+  {
+    SegmentIntersector si = new SegmentIntersector(li, true, false);
+    EdgeSetIntersector esi = createEdgeSetIntersector();
+    // optimized test for Polygons and Rings
+    if (! computeRingSelfNodes
+        && (parentGeom instanceof LinearRing
+        || parentGeom instanceof Polygon
+        || parentGeom instanceof MultiPolygon)) {
+      esi.computeIntersections(edges, si, false);
+    }
+    else {
+      esi.computeIntersections(edges, si, true);
+    }
+//System.out.println("SegmentIntersector # tests = " + si.numTests);
+    addSelfIntersectionNodes(argIndex);
+    return si;
+  }
+
+  public SegmentIntersector computeEdgeIntersections(
+    GeometryGraph g,
+    LineIntersector li,
+    boolean includeProper)
+  {
+    SegmentIntersector si = new SegmentIntersector(li, includeProper, true);
+    si.setBoundaryNodes(this.getBoundaryNodes(), g.getBoundaryNodes());
+
+    EdgeSetIntersector esi = createEdgeSetIntersector();
+    esi.computeIntersections(edges, g.edges, si);
+/*
+for (Iterator i = g.edges.iterator(); i.hasNext();) {
+Edge e = (Edge) i.next();
+Debug.print(e.getEdgeIntersectionList());
+}
+*/
+    return si;
+  }
+
+  private void insertPoint(int argIndex, Coordinate coord, int onLocation)
+  {
+    Node n = nodes.addNode(coord);
+    Label lbl = n.getLabel();
+    if (lbl == null) {
+      n.label = new Label(argIndex, onLocation);
+    }
+    else
+      lbl.setLocation(argIndex, onLocation);
+  }
+
+  /**
+   * Adds candidate boundary points using the current {@link BoundaryNodeRule}.
+   * This is used to add the boundary
+   * points of dim-1 geometries (Curves/MultiCurves).
+   */
+  private void insertBoundaryPoint(int argIndex, Coordinate coord)
+  {
+    Node n = nodes.addNode(coord);
+    Label lbl = n.getLabel();
+    // the new point to insert is on a boundary
+    int boundaryCount = 1;
+    // determine the current location for the point (if any)
+    int loc = Location.NONE;
+    if (lbl != null) loc = lbl.getLocation(argIndex, Position.ON);
+    if (loc == Location.BOUNDARY) boundaryCount++;
+
+    // determine the boundary status of the point according to the Boundary Determination Rule
+    int newLoc = determineBoundary(boundaryNodeRule, boundaryCount);
+    lbl.setLocation(argIndex, newLoc);
+  }
+
+  private void addSelfIntersectionNodes(int argIndex)
+  {
+    for (Iterator i = edges.iterator(); i.hasNext(); ) {
+      Edge e = (Edge) i.next();
+      int eLoc = e.getLabel().getLocation(argIndex);
+      for (Iterator eiIt = e.eiList.iterator(); eiIt.hasNext(); ) {
+        EdgeIntersection ei = (EdgeIntersection) eiIt.next();
+        addSelfIntersectionNode(argIndex, ei.coord, eLoc);
+      }
+    }
+  }
+  /**
+   * Add a node for a self-intersection.
+   * If the node is a potential boundary node (e.g. came from an edge which
+   * is a boundary) then insert it as a potential boundary node.
+   * Otherwise, just add it as a regular node.
+   */
+  private void addSelfIntersectionNode(int argIndex, Coordinate coord, int loc)
+  {
+    // if this node is already a boundary node, don't change it
+    if (isBoundaryNode(argIndex, coord)) return;
+    if (loc == Location.BOUNDARY && useBoundaryDeterminationRule)
+        insertBoundaryPoint(argIndex, coord);
+    else
+      insertPoint(argIndex, coord, loc);
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/GraphComponent.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/GraphComponent.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/GraphComponent.java	(revision 28000)
@@ -0,0 +1,97 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.IntersectionMatrix;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * A GraphComponent is the parent class for the objects'
+ * that form a graph.  Each GraphComponent can carry a
+ * Label.
+ * @version 1.7
+ */
+abstract public class GraphComponent {
+
+  protected Label label;
+  /**
+   * isInResult indicates if this component has already been included in the result
+   */
+  private boolean isInResult = false;
+  private boolean isCovered = false;
+  private boolean isCoveredSet = false;
+
+  public GraphComponent() {
+  }
+
+  public Label getLabel() { return label; }
+  public void setInResult(boolean isInResult) { this.isInResult = isInResult; }
+  public boolean isInResult() { return isInResult; }
+  public void setCovered(boolean isCovered)
+  {
+    this.isCovered = isCovered;
+    this.isCoveredSet = true;
+  }
+  public boolean isCovered()    { return isCovered; }
+  public boolean isCoveredSet() { return isCoveredSet; }
+  /**
+   * @return a coordinate in this component (or null, if there are none)
+   */
+  abstract public Coordinate getCoordinate();
+  /**
+   * compute the contribution to an IM for this component
+   */
+  abstract protected void computeIM(IntersectionMatrix im);
+  /**
+   * An isolated component is one that does not intersect or touch any other
+   * component.  This is the case if the label has valid locations for
+   * only a single Geometry.
+   *
+   * @return true if this component is isolated
+   */
+  abstract public boolean isIsolated();
+  /**
+   * Update the IM with the contribution for this component.
+   * A component only contributes if it has a labelling for both parent geometries
+   */
+  public void updateIM(IntersectionMatrix im)
+  {
+    Assert.isTrue(label.getGeometryCount() >= 2, "found partial label");
+    computeIM(im);
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Label.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Label.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Label.java	(revision 28000)
@@ -0,0 +1,211 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import com.vividsolutions.jts.geom.Location;
+
+ /**
+ * A <code>Label</code> indicates the topological relationship of a component
+ * of a topology graph to a given <code>Geometry</code>.
+ * This class supports labels for relationships to two <code>Geometry</code>s,
+ * which is sufficient for algorithms for binary operations.
+ * <P>
+ * Topology graphs support the concept of labeling nodes and edges in the graph.
+ * The label of a node or edge specifies its topological relationship to one or
+ * more geometries.  (In fact, since JTS operations have only two arguments labels
+ * are required for only two geometries).  A label for a node or edge has one or
+ * two elements, depending on whether the node or edge occurs in one or both of the
+ * input <code>Geometry</code>s.  Elements contain attributes which categorize the
+ * topological location of the node or edge relative to the parent
+ * <code>Geometry</code>; that is, whether the node or edge is in the interior,
+ * boundary or exterior of the <code>Geometry</code>.  Attributes have a value
+ * from the set <code>{Interior, Boundary, Exterior}</code>.  In a node each
+ * element has  a single attribute <code>&lt;On&gt;</code>.  For an edge each element has a
+ * triplet of attributes <code>&lt;Left, On, Right&gt;</code>.
+ * <P>
+ * It is up to the client code to associate the 0 and 1 <code>TopologyLocation</code>s
+ * with specific geometries.
+ * @version 1.7
+ *
+ */
+public class Label {
+
+  // converts a Label to a Line label (that is, one with no side Locations)
+  public static Label toLineLabel(Label label)
+  {
+    Label lineLabel = new Label(Location.NONE);
+    for (int i = 0; i < 2; i++) {
+      lineLabel.setLocation(i, label.getLocation(i));
+    }
+    return lineLabel;
+  }
+
+  TopologyLocation elt[] = new TopologyLocation[2];
+
+  /**
+   * Construct a Label with a single location for both Geometries.
+   * Initialize the locations to Null
+   */
+  public Label(int onLoc)
+  {
+    elt[0] = new TopologyLocation(onLoc);
+    elt[1] = new TopologyLocation(onLoc);
+  }
+  /**
+   * Construct a Label with a single location for both Geometries.
+   * Initialize the location for the Geometry index.
+   */
+  public Label(int geomIndex, int onLoc)
+  {
+    elt[0] = new TopologyLocation(Location.NONE);
+    elt[1] = new TopologyLocation(Location.NONE);
+    elt[geomIndex].setLocation(onLoc);
+  }
+  /**
+   * Construct a Label with On, Left and Right locations for both Geometries.
+   * Initialize the locations for both Geometries to the given values.
+   */
+  public Label(int onLoc, int leftLoc, int rightLoc)
+  {
+    elt[0] = new TopologyLocation(onLoc, leftLoc, rightLoc);
+    elt[1] = new TopologyLocation(onLoc, leftLoc, rightLoc);
+  }
+  /**
+   * Construct a Label with On, Left and Right locations for both Geometries.
+   * Initialize the locations for the given Geometry index.
+   */
+  public Label(int geomIndex, int onLoc, int leftLoc, int rightLoc)
+  {
+    elt[0] = new TopologyLocation(Location.NONE, Location.NONE, Location.NONE);
+    elt[1] = new TopologyLocation(Location.NONE, Location.NONE, Location.NONE);
+    elt[geomIndex].setLocations(onLoc, leftLoc, rightLoc);
+  }
+  /**
+   * Construct a Label with the same values as the argument Label.
+   */
+  public Label(Label lbl)
+  {
+    elt[0] = new TopologyLocation(lbl.elt[0]);
+    elt[1] = new TopologyLocation(lbl.elt[1]);
+  }
+
+  public void flip()
+  {
+    elt[0].flip();
+    elt[1].flip();
+  }
+
+  public int getLocation(int geomIndex, int posIndex) { return elt[geomIndex].get(posIndex); }
+  public int getLocation(int geomIndex) { return elt[geomIndex].get(Position.ON); }
+  public void setLocation(int geomIndex, int posIndex, int location)
+  {
+    elt[geomIndex].setLocation(posIndex, location);
+  }
+  public void setLocation(int geomIndex, int location)
+  {
+    elt[geomIndex].setLocation(Position.ON, location);
+  }
+  public void setAllLocations(int geomIndex, int location)
+  {
+    elt[geomIndex].setAllLocations(location);
+  }
+  public void setAllLocationsIfNull(int geomIndex, int location)
+  {
+    elt[geomIndex].setAllLocationsIfNull(location);
+  }
+  /**
+   * Merge this label with another one.
+   * Merging updates any null attributes of this label with the attributes from lbl
+   */
+  public void merge(Label lbl)
+  {
+    for (int i = 0; i < 2; i++) {
+      if (elt[i] == null && lbl.elt[i] != null) {
+        elt[i] = new TopologyLocation(lbl.elt[i]);
+      }
+      else {
+        elt[i].merge(lbl.elt[i]);
+      }
+    }
+  }
+  public int getGeometryCount()
+  {
+    int count = 0;
+    if (! elt[0].isNull()) count++;
+    if (! elt[1].isNull()) count++;
+    return count;
+  }
+  public boolean isNull(int geomIndex) { return elt[geomIndex].isNull(); }
+  public boolean isAnyNull(int geomIndex) { return elt[geomIndex].isAnyNull(); }
+
+  public boolean isArea()               { return elt[0].isArea() || elt[1].isArea();   }
+  public boolean isArea(int geomIndex)  
+  {
+  	/*  Testing
+  	if (elt[0].getLocations().length != elt[1].getLocations().length) {
+  		System.out.println(this);
+  	}
+  		*/
+  	return elt[geomIndex].isArea();   
+  }
+  public boolean isLine(int geomIndex)  { return elt[geomIndex].isLine();   }
+
+  public boolean allPositionsEqual(int geomIndex, int loc)
+  {
+    return elt[geomIndex].allPositionsEqual(loc);
+  }
+  /**
+   * Converts one GeometryLocation to a Line location
+   */
+  public void toLine(int geomIndex)
+  {
+    if (elt[geomIndex].isArea())
+      elt[geomIndex] = new TopologyLocation(elt[geomIndex].location[0]);
+  }
+  public String toString()
+  {
+    StringBuffer buf = new StringBuffer();
+    if (elt[0] != null) {
+      buf.append("A:");
+      buf.append(elt[0].toString());
+    }
+    if (elt[1] != null) {
+      buf.append(" B:");
+      buf.append(elt[1].toString());
+    }
+    return buf.toString();
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Node.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Node.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Node.java	(revision 28000)
@@ -0,0 +1,128 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import java.util.Iterator;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.IntersectionMatrix;
+import com.vividsolutions.jts.geom.Location;
+
+
+/**
+ * @version 1.7
+ */
+public class Node
+  extends GraphComponent
+{
+  protected Coordinate coord; // only non-null if this node is precise
+  protected EdgeEndStar edges;
+
+  public Node(Coordinate coord, EdgeEndStar edges)
+  {
+    this.coord = coord;
+    this.edges = edges;
+    label = new Label(0, Location.NONE);
+  }
+
+  public Coordinate getCoordinate() { return coord; }
+  public EdgeEndStar getEdges() { return edges; }
+
+  /**
+   * Tests whether any incident edge is flagged as
+   * being in the result.
+   * This test can be used to determine if the node is in the result,
+   * since if any incident edge is in the result, the node must be in the result as well.
+   *
+   * @return <code>true</code> if any indicident edge in the in the result
+   */
+  public boolean isIncidentEdgeInResult()
+  {
+    for (Iterator it = getEdges().getEdges().iterator(); it.hasNext(); ) {
+      DirectedEdge de = (DirectedEdge) it.next();
+      if (de.getEdge().isInResult())
+        return true;
+    }
+    return false;
+  }
+
+  public boolean isIsolated()
+  {
+    return (label.getGeometryCount() == 1);
+  }
+  /**
+   * Basic nodes do not compute IMs
+   */
+  protected void computeIM(IntersectionMatrix im) {}
+  /**
+   * Add the edge to the list of edges at this node
+   */
+  public void add(EdgeEnd e)
+  {
+    // Assert: start pt of e is equal to node point
+    edges.insert(e);
+    e.setNode(this);
+  }
+
+  public void setLabel(int argIndex, int onLocation)
+  {
+    if (label == null) {
+      label = new Label(argIndex, onLocation);
+    }
+    else
+      label.setLocation(argIndex, onLocation);
+  }
+
+  /**
+   * Updates the label of a node to BOUNDARY,
+   * obeying the mod-2 boundaryDetermination rule.
+   */
+  public void setLabelBoundary(int argIndex)
+  {
+    // determine the current location for the point (if any)
+    int loc = Location.NONE;
+    if (label != null)
+      loc = label.getLocation(argIndex);
+    // flip the loc
+    int newLoc;
+    switch (loc) {
+    case Location.BOUNDARY: newLoc = Location.INTERIOR; break;
+    case Location.INTERIOR: newLoc = Location.BOUNDARY; break;
+    default: newLoc = Location.BOUNDARY;  break;
+    }
+    label.setLocation(argIndex, newLoc);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/NodeFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/NodeFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/NodeFactory.java	(revision 28000)
@@ -0,0 +1,50 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+import com.vividsolutions.jts.geom.Coordinate;
+
+
+/**
+ * @version 1.7
+ */
+public class NodeFactory {
+/**
+ * The basic node constructor does not allow for incident edges
+ */
+  public Node createNode(Coordinate coord)
+  {
+    return new Node(coord, null);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/NodeMap.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/NodeMap.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/NodeMap.java	(revision 28000)
@@ -0,0 +1,122 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Location;
+
+/**
+ * A map of nodes, indexed by the coordinate of the node
+ * @version 1.7
+ */
+public class NodeMap
+
+{
+  //Map nodeMap = new HashMap();
+  Map nodeMap = new TreeMap();
+  NodeFactory nodeFact;
+
+  public NodeMap(NodeFactory nodeFact) {
+    this.nodeFact = nodeFact;
+  }
+
+  /**
+   * Factory function - subclasses can override to create their own types of nodes
+   */
+   /*
+  protected Node createNode(Coordinate coord)
+  {
+    return new Node(coord);
+  }
+  */
+  /**
+   * This method expects that a node has a coordinate value.
+   */
+  public Node addNode(Coordinate coord)
+  {
+    Node node = (Node) nodeMap.get(coord);
+    if (node == null) {
+      node = nodeFact.createNode(coord);
+      nodeMap.put(coord, node);
+    }
+    return node;
+  }
+
+
+  /**
+   * Adds a node for the start point of this EdgeEnd
+   * (if one does not already exist in this map).
+   * Adds the EdgeEnd to the (possibly new) node.
+   */
+  public void add(EdgeEnd e)
+  {
+    Coordinate p = e.getCoordinate();
+    Node n = addNode(p);
+    n.add(e);
+  }
+  /**
+   * @return the node if found; null otherwise
+   */
+  public Node find(Coordinate coord)  {    return (Node) nodeMap.get(coord);  }
+
+  public Iterator iterator()
+  {
+    return nodeMap.values().iterator();
+  }
+  public Collection values()
+  {
+    return nodeMap.values();
+  }
+
+  public Collection getBoundaryNodes(int geomIndex)
+  {
+    Collection bdyNodes = new ArrayList();
+    for (Iterator i = iterator(); i.hasNext(); ) {
+      Node node = (Node) i.next();
+      if (node.getLabel().getLocation(geomIndex) == Location.BOUNDARY)
+        bdyNodes.add(node);
+    }
+    return bdyNodes;
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/PlanarGraph.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/PlanarGraph.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/PlanarGraph.java	(revision 28000)
@@ -0,0 +1,207 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+/**
+ * @version 1.7
+ */
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.algorithm.CGAlgorithms;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Location;
+
+/**
+ * The computation of the <code>IntersectionMatrix</code> relies on the use of a structure
+ * called a "topology graph".  The topology graph contains nodes and edges
+ * corresponding to the nodes and line segments of a <code>Geometry</code>. Each
+ * node and edge in the graph is labeled with its topological location relative to
+ * the source geometry.
+ * <P>
+ * Note that there is no requirement that points of self-intersection be a vertex.
+ * Thus to obtain a correct topology graph, <code>Geometry</code>s must be
+ * self-noded before constructing their graphs.
+ * <P>
+ * Two fundamental operations are supported by topology graphs:
+ * <UL>
+ *   <LI>Computing the intersections between all the edges and nodes of a single graph
+ *   <LI>Computing the intersections between the edges and nodes of two different graphs
+ * </UL>
+ *
+ * @version 1.7
+ */
+public class PlanarGraph
+{
+  /**
+   * For nodes in the Collection, link the DirectedEdges at the node that are in the result.
+   * This allows clients to link only a subset of nodes in the graph, for
+   * efficiency (because they know that only a subset is of interest).
+   */
+  public static void linkResultDirectedEdges(Collection nodes)
+  {
+    for (Iterator nodeit = nodes.iterator(); nodeit.hasNext(); ) {
+      Node node = (Node) nodeit.next();
+      ((DirectedEdgeStar) node.getEdges()).linkResultDirectedEdges();
+    }
+  }
+
+  protected List edges        = new ArrayList();
+  protected NodeMap nodes;
+  protected List edgeEndList  = new ArrayList();
+
+  public PlanarGraph(NodeFactory nodeFact) {
+    nodes = new NodeMap(nodeFact);
+  }
+
+  public PlanarGraph() {
+    nodes = new NodeMap(new NodeFactory());
+  }
+
+  public Iterator getEdgeIterator() { return edges.iterator(); }
+  public Collection getEdgeEnds() { return edgeEndList; }
+
+  public boolean isBoundaryNode(int geomIndex, Coordinate coord)
+  {
+    Node node = nodes.find(coord);
+    if (node == null) return false;
+    Label label = node.getLabel();
+    if (label != null && label.getLocation(geomIndex) == Location.BOUNDARY) return true;
+    return false;
+  }
+  protected void insertEdge(Edge e)
+  {
+    edges.add(e);
+  }
+  public void add(EdgeEnd e)
+  {
+    nodes.add(e);
+    edgeEndList.add(e);
+  }
+
+  public Iterator getNodeIterator() { return nodes.iterator(); }
+  public Collection getNodes() { return nodes.values(); }
+  public Node addNode(Coordinate coord) { return nodes.addNode(coord); }
+
+  /**
+   * Add a set of edges to the graph.  For each edge two DirectedEdges
+   * will be created.  DirectedEdges are NOT linked by this method.
+   */
+  public void addEdges(List edgesToAdd)
+  {
+    // create all the nodes for the edges
+    for (Iterator it = edgesToAdd.iterator(); it.hasNext(); ) {
+      Edge e = (Edge) it.next();
+      edges.add(e);
+
+      DirectedEdge de1 = new DirectedEdge(e, true);
+      DirectedEdge de2 = new DirectedEdge(e, false);
+      de1.setSym(de2);
+      de2.setSym(de1);
+
+      add(de1);
+      add(de2);
+    }
+  }
+
+  /**
+   * Link the DirectedEdges at the nodes of the graph.
+   * This allows clients to link only a subset of nodes in the graph, for
+   * efficiency (because they know that only a subset is of interest).
+   */
+  public void linkResultDirectedEdges()
+  {
+    for (Iterator nodeit = nodes.iterator(); nodeit.hasNext(); ) {
+      Node node = (Node) nodeit.next();
+      ((DirectedEdgeStar) node.getEdges()).linkResultDirectedEdges();
+    }
+  }
+  /**
+   * Returns the EdgeEnd which has edge e as its base edge
+   * (MD 18 Feb 2002 - this should return a pair of edges)
+   *
+   * @return the edge, if found
+   *    <code>null</code> if the edge was not found
+   */
+  public EdgeEnd findEdgeEnd(Edge e)
+  {
+    for (Iterator i = getEdgeEnds().iterator(); i.hasNext(); ) {
+      EdgeEnd ee = (EdgeEnd) i.next();
+      if (ee.getEdge() == e)
+        return ee;
+    }
+    return null;
+  }
+
+  /**
+   * Returns the edge which starts at p0 and whose first segment is
+   * parallel to p1
+   *
+   * @return the edge, if found
+   *    <code>null</code> if the edge was not found
+   */
+  public Edge findEdgeInSameDirection(Coordinate p0, Coordinate p1)
+  {
+    for (int i = 0; i < edges.size(); i++) {
+      Edge e = (Edge) edges.get(i);
+
+      Coordinate[] eCoord = e.getCoordinates();
+      if (matchInSameDirection(p0, p1, eCoord[0], eCoord[1]) )
+        return e;
+
+      if (matchInSameDirection(p0, p1, eCoord[eCoord.length - 1], eCoord[eCoord.length - 2]) )
+        return e;
+    }
+    return null;
+  }
+
+  /**
+   * The coordinate pairs match if they define line segments lying in the same direction.
+   * E.g. the segments are parallel and in the same quadrant
+   * (as opposed to parallel and opposite!).
+   */
+  private boolean matchInSameDirection(Coordinate p0, Coordinate p1, Coordinate ep0, Coordinate ep1)
+  {
+    if (! p0.equals(ep0))
+      return false;
+
+    if (CGAlgorithms.computeOrientation(p0, p1, ep1) == CGAlgorithms.COLLINEAR
+         && Quadrant.quadrant(p0, p1) == Quadrant.quadrant(ep0, ep1) )
+      return true;
+    return false;
+  }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Position.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Position.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Position.java	(revision 28000)
@@ -0,0 +1,52 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+/**
+ * A Position indicates the position of a Location relative to a graph component
+ * (Node, Edge, or Area).
+ * @version 1.7
+ */
+public class Position {
+
+  /** An indicator that a Location is <i>on</i> a GraphComponent */
+  public static final int ON      = 0;
+  /** An indicator that a Location is to the <i>left</i> of a GraphComponent */  
+  public static final int LEFT    = 1;
+  /** An indicator that a Location is to the <i>right</i> of a GraphComponent */  
+  public static final int RIGHT   = 2;
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Quadrant.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Quadrant.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/Quadrant.java	(revision 28000)
@@ -0,0 +1,108 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+/**
+ * @version 1.7
+ */
+import com.vividsolutions.jts.geom.Coordinate;
+
+/**
+ * Utility functions for working with quadrants, which are numbered as follows:
+ * <pre>
+ * 1 | 0
+ * --+--
+ * 2 | 3
+ * <pre>
+ *
+ * @version 1.7
+ */
+public class Quadrant 
+{
+	public static final int NE = 0;
+	public static final int NW = 1;
+	public static final int SW = 2;
+	public static final int SE = 3;
+	
+  /**
+   * Returns the quadrant of a directed line segment (specified as x and y
+   * displacements, which cannot both be 0).
+   * 
+   * @throws IllegalArgumentException if the displacements are both 0
+   */
+  public static int quadrant(double dx, double dy)
+  {
+    if (dx == 0.0 && dy == 0.0)
+      throw new IllegalArgumentException("Cannot compute the quadrant for point ( "+ dx + ", " + dy + " )" );
+    if (dx >= 0.0) {
+      if (dy >= 0.0)
+        return NE;
+      else
+        return SE;
+    }
+    else {
+    	if (dy >= 0.0)
+    		return NW;
+    	else
+    		return SW;
+    }
+  }
+
+  /**
+   * Returns the quadrant of a directed line segment from p0 to p1.
+   * 
+   * @throws IllegalArgumentException if the points are equal
+   */
+  public static int quadrant(Coordinate p0, Coordinate p1)
+  {
+    if (p1.x == p0.x && p1.y == p0.y)
+      throw new IllegalArgumentException("Cannot compute the quadrant for two identical points " + p0);
+    
+    if (p1.x >= p0.x) {
+      if (p1.y >= p0.y)
+        return NE;
+      else
+        return SE;
+    }
+    else {
+    	if (p1.y >= p0.y)
+    		return NW;
+    	else
+    		return SW;
+    }
+  }
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/TopologyLocation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/TopologyLocation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/TopologyLocation.java	(revision 28000)
@@ -0,0 +1,198 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph;
+
+
+
+import com.vividsolutions.jts.geom.Location;
+
+/**
+  * A TopologyLocation is the labelling of a
+  * GraphComponent's topological relationship to a single Geometry.
+  * <p>
+  * If the parent component is an area edge, each side and the edge itself
+  * have a topological location.  These locations are named
+  * <ul>
+  * <li> ON: on the edge
+  * <li> LEFT: left-hand side of the edge
+  * <li> RIGHT: right-hand side
+  * </ul>
+  * If the parent component is a line edge or node, there is a single
+  * topological relationship attribute, ON.
+  * <p>
+  * The possible values of a topological location are
+  * {Location.NONE, Location.EXTERIOR, Location.BOUNDARY, Location.INTERIOR}
+  * <p>
+  * The labelling is stored in an array location[j] where
+  * where j has the values ON, LEFT, RIGHT
+  * @version 1.7
+ */
+public class TopologyLocation {
+
+  int location[];
+
+  /**
+   * Constructs a TopologyLocation specifying how points on, to the left of, and to the
+   * right of some GraphComponent relate to some Geometry. Possible values for the
+   * parameters are Location.NULL, Location.EXTERIOR, Location.BOUNDARY,
+   * and Location.INTERIOR.
+   * @see Location
+   */
+  public TopologyLocation(int on, int left, int right) {
+   init(3);
+   location[Position.ON] = on;
+   location[Position.LEFT] = left;
+   location[Position.RIGHT] = right;
+  }
+
+  public TopologyLocation(int on) {
+   init(1);
+   location[Position.ON] = on;
+  }
+  public TopologyLocation(TopologyLocation gl) {
+    if (gl != null) {
+      init(gl.location.length);
+      for (int i = 0; i < location.length; i++) {
+        location[i] = gl.location[i];
+      }
+    }
+  }
+  private void init(int size)
+  {
+    location = new int[size];
+    setAllLocations(Location.NONE);
+  }
+  public int get(int posIndex)
+  {
+    if (posIndex < location.length) return location[posIndex];
+    return Location.NONE;
+  }
+  /**
+   * @return true if all locations are NULL
+   */
+  public boolean isNull()
+  {
+    for (int i = 0; i < location.length; i++) {
+      if (location[i] != Location.NONE) return false;
+    }
+    return true;
+  }
+  /**
+   * @return true if any locations are NULL
+   */
+  public boolean isAnyNull()
+  {
+    for (int i = 0; i < location.length; i++) {
+      if (location[i] == Location.NONE) return true;
+    }
+    return false;
+  }
+
+  public boolean isArea() { return location.length > 1; }
+  public boolean isLine() { return location.length == 1; }
+
+  public void flip()
+  {
+    if (location.length <= 1) return;
+    int temp = location[Position.LEFT];
+    location[Position.LEFT] = location[Position.RIGHT];
+    location[Position.RIGHT] = temp;
+  }
+
+
+  public void setAllLocations(int locValue)
+  {
+    for (int i = 0; i < location.length; i++) {
+      location[i]     = locValue;
+    }
+  }
+  public void setAllLocationsIfNull(int locValue)
+  {
+    for (int i = 0; i < location.length; i++) {
+      if (location[i] == Location.NONE) location[i]     = locValue;
+    }
+  }
+
+  public void setLocation(int locIndex, int locValue)
+  {
+      location[locIndex] = locValue;
+  }
+  public void setLocation(int locValue)
+  {
+    setLocation(Position.ON, locValue);
+  }
+  public void setLocations(int on, int left, int right) {
+      location[Position.ON] = on;
+      location[Position.LEFT] = left;
+      location[Position.RIGHT] = right;
+  }
+  public boolean allPositionsEqual(int loc)
+  {
+    for (int i = 0; i < location.length; i++) {
+      if (location[i] != loc) return false;
+    }
+    return true;
+  }
+
+  /**
+   * merge updates only the NULL attributes of this object
+   * with the attributes of another.
+   */
+  public void merge(TopologyLocation gl)
+  {
+    // if the src is an Area label & and the dest is not, increase the dest to be an Area
+    if (gl.location.length > location.length) {
+      int [] newLoc = new int[3];
+      newLoc[Position.ON] = location[Position.ON];
+      newLoc[Position.LEFT] = Location.NONE;
+      newLoc[Position.RIGHT] = Location.NONE;
+      location = newLoc;
+    }
+    for (int i = 0; i < location.length; i++) {
+      if (location[i] == Location.NONE && i < gl.location.length)
+        location[i] = gl.location[i];
+    }
+  }
+
+  public String toString()
+  {
+    StringBuffer buf = new StringBuffer();
+    if (location.length > 1) buf.append(Location.toLocationSymbol(location[Position.LEFT]));
+    buf.append(Location.toLocationSymbol(location[Position.ON]));
+    if (location.length > 1) buf.append(Location.toLocationSymbol(location[Position.RIGHT]));
+    return buf.toString();
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/EdgeSetIntersector.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/EdgeSetIntersector.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/EdgeSetIntersector.java	(revision 28000)
@@ -0,0 +1,78 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph.index;
+
+/**
+ * @version 1.7
+ */
+import java.util.List;
+
+/**
+ * An EdgeSetIntersector computes all the intersections between the
+ * edges in the set.  It adds the computed intersections to each edge
+ * they are found on.  It may be used in two scenarios:
+ * <ul>
+ * <li>determining the internal intersections between a single set of edges
+ * <li>determining the mutual intersections between two different sets of edges
+ * </ul>
+ * It uses a {@link SegmentIntersector} to compute the intersections between
+ * segments and to record statistics about what kinds of intersections were found.
+ *
+ * @version 1.7
+ */
+public abstract class EdgeSetIntersector 
+{
+  public EdgeSetIntersector() {
+  }
+
+  /**
+   * Computes all self-intersections between edges in a set of edges,
+   * allowing client to choose whether self-intersections are computed.
+   *
+   * @param edges a list of edges to test for intersections
+   * @param si the SegmentIntersector to use
+   * @param testAllSegments true if self-intersections are to be tested as well
+   */
+  abstract public void computeIntersections(List edges, SegmentIntersector si, boolean testAllSegments);
+
+  /**
+   * Computes all mutual intersections between two sets of edges.
+   */
+  abstract public void computeIntersections(List edges0, List edges1, SegmentIntersector si);
+
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/MonotoneChain.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/MonotoneChain.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/MonotoneChain.java	(revision 28000)
@@ -0,0 +1,55 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph.index;
+
+/**
+ * @version 1.7
+ */
+public class MonotoneChain {
+
+  MonotoneChainEdge mce;
+  int chainIndex;
+
+  public MonotoneChain(MonotoneChainEdge mce, int chainIndex) {
+    this.mce = mce;
+    this.chainIndex = chainIndex;
+  }
+
+  public void computeIntersections(MonotoneChain mc, SegmentIntersector si)
+  {
+    this.mce.computeIntersectsForChain(chainIndex, mc.mce, mc.chainIndex, si);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/MonotoneChainEdge.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/MonotoneChainEdge.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/MonotoneChainEdge.java	(revision 28000)
@@ -0,0 +1,140 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph.index;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geomgraph.Edge;
+
+/**
+ * MonotoneChains are a way of partitioning the segments of an edge to
+ * allow for fast searching of intersections.
+ * They have the following properties:
+ * <ol>
+ * <li>the segments within a monotone chain will never intersect each other
+ * <li>the envelope of any contiguous subset of the segments in a monotone chain
+ * is simply the envelope of the endpoints of the subset.
+ * </ol>
+ * Property 1 means that there is no need to test pairs of segments from within
+ * the same monotone chain for intersection.
+ * Property 2 allows
+ * binary search to be used to find the intersection points of two monotone chains.
+ * For many types of real-world data, these properties eliminate a large number of
+ * segment comparisons, producing substantial speed gains.
+ * @version 1.7
+ */
+public class MonotoneChainEdge {
+
+  Edge e;
+  Coordinate[] pts; // cache a reference to the coord array, for efficiency
+  // the lists of start/end indexes of the monotone chains.
+  // Includes the end point of the edge as a sentinel
+  int[] startIndex;
+  // these envelopes are created once and reused
+  Envelope env1 = new Envelope();
+  Envelope env2 = new Envelope();
+
+  public MonotoneChainEdge(Edge e) {
+    this.e = e;
+    pts = e.getCoordinates();
+    MonotoneChainIndexer mcb = new MonotoneChainIndexer();
+    startIndex = mcb.getChainStartIndices(pts);
+  }
+
+  public int[] getStartIndexes() { return startIndex; }
+
+  public double getMinX(int chainIndex)
+  {
+    double x1 = pts[startIndex[chainIndex]].x;
+    double x2 = pts[startIndex[chainIndex + 1]].x;
+    return x1 < x2 ? x1 : x2;
+  }
+  public double getMaxX(int chainIndex)
+  {
+    double x1 = pts[startIndex[chainIndex]].x;
+    double x2 = pts[startIndex[chainIndex + 1]].x;
+    return x1 > x2 ? x1 : x2;
+  }
+
+  public void computeIntersectsForChain(
+    int chainIndex0,
+    MonotoneChainEdge mce,
+    int chainIndex1,
+    SegmentIntersector si)
+  {
+    computeIntersectsForChain(startIndex[chainIndex0], startIndex[chainIndex0 + 1],
+                            mce,
+                            mce.startIndex[chainIndex1], mce.startIndex[chainIndex1 + 1],
+                            si );
+  }
+
+  private void computeIntersectsForChain(
+    int start0, int end0,
+    MonotoneChainEdge mce,
+    int start1, int end1,
+    SegmentIntersector ei)
+  {
+    Coordinate p00 = pts[start0];
+    Coordinate p01 = pts[end0];
+    Coordinate p10 = mce.pts[start1];
+    Coordinate p11 = mce.pts[end1];
+//Debug.println("computeIntersectsForChain:" + p00 + p01 + p10 + p11);
+    // terminating condition for the recursion
+    if (end0 - start0 == 1 && end1 - start1 == 1) {
+      ei.addIntersections(e, start0, mce.e, start1);
+      return;
+    }
+    // nothing to do if the envelopes of these chains don't overlap
+    env1.init(p00, p01);
+    env2.init(p10, p11);
+    if (! env1.intersects(env2)) return;
+
+    // the chains overlap, so split each in half and iterate  (binary search)
+    int mid0 = (start0 + end0) / 2;
+    int mid1 = (start1 + end1) / 2;
+
+    // Assert: mid != start or end (since we checked above for end - start <= 1)
+    // check terminating conditions before recursing
+    if (start0 < mid0) {
+      if (start1 < mid1) computeIntersectsForChain(start0, mid0, mce, start1,  mid1, ei);
+      if (mid1 < end1)   computeIntersectsForChain(start0, mid0, mce, mid1,    end1, ei);
+    }
+    if (mid0 < end0) {
+      if (start1 < mid1) computeIntersectsForChain(mid0,   end0, mce, start1,  mid1, ei);
+      if (mid1 < end1)   computeIntersectsForChain(mid0,   end0, mce, mid1,    end1, ei);
+    }
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/MonotoneChainIndexer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/MonotoneChainIndexer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/MonotoneChainIndexer.java	(revision 28000)
@@ -0,0 +1,114 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph.index;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geomgraph.Quadrant;
+/**
+ * MonotoneChains are a way of partitioning the segments of an edge to
+ * allow for fast searching of intersections.
+ * Specifically, a sequence of contiguous line segments
+ * is a monotone chain iff all the vectors defined by the oriented segments
+ * lies in the same quadrant.
+ * <p>
+ * Monotone Chains have the following useful properties:
+ * <ol>
+ * <li>the segments within a monotone chain will never intersect each other
+ * <li>the envelope of any contiguous subset of the segments in a monotone chain
+ * is simply the envelope of the endpoints of the subset.
+ * </ol>
+ * Property 1 means that there is no need to test pairs of segments from within
+ * the same monotone chain for intersection.
+ * Property 2 allows
+ * binary search to be used to find the intersection points of two monotone chains.
+ * For many types of real-world data, these properties eliminate a large number of
+ * segment comparisons, producing substantial speed gains.
+ *
+ * @version 1.7
+ */
+public class MonotoneChainIndexer {
+
+  public static int[] toIntArray(List list)
+  {
+    int[] array = new int[list.size()];
+    for (int i = 0; i < array.length; i++) {
+      array[i] = ((Integer) list.get(i)).intValue();
+    }
+    return array;
+  }
+
+  public MonotoneChainIndexer() {
+  }
+
+  public int[] getChainStartIndices(Coordinate[] pts)
+  {
+    // find the startpoint (and endpoints) of all monotone chains in this edge
+    int start = 0;
+    List startIndexList = new ArrayList();
+    startIndexList.add(new Integer(start));
+    do {
+      int last = findChainEnd(pts, start);
+      startIndexList.add(new Integer(last));
+      start = last;
+    } while (start < pts.length - 1);
+    // copy list to an array of ints, for efficiency
+    int[] startIndex = toIntArray(startIndexList);
+    return startIndex;
+  }
+
+  /**
+   * @return the index of the last point in the monotone chain
+   */
+  private int findChainEnd(Coordinate[] pts, int start)
+  {
+    // determine quadrant for chain
+    int chainQuad = Quadrant.quadrant(pts[start], pts[start + 1]);
+    int last = start + 1;
+    while (last < pts.length) {
+      // compute quadrant for next possible segment in chain
+      int quad = Quadrant.quadrant(pts[last - 1], pts[last]);
+      if (quad != chainQuad) break;
+      last++;
+    }
+    return last - 1;
+  }
+
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/SegmentIntersector.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/SegmentIntersector.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/SegmentIntersector.java	(revision 28000)
@@ -0,0 +1,215 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph.index;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import com.vividsolutions.jts.algorithm.LineIntersector;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geomgraph.Edge;
+import com.vividsolutions.jts.geomgraph.Node;
+
+
+/**
+ * Computes the intersection of line segments,
+ * and adds the intersection to the edges containing the segments.
+ * 
+ * @version 1.7
+ */
+public class SegmentIntersector 
+{
+
+  public static boolean isAdjacentSegments(int i1, int i2)
+  {
+    return Math.abs(i1 - i2) == 1;
+  }
+
+  /**
+   * These variables keep track of what types of intersections were
+   * found during ALL edges that have been intersected.
+   */
+  private boolean hasIntersection = false;
+  private boolean hasProper = false;
+  private boolean hasProperInterior = false;
+  // the proper intersection point found
+  private Coordinate properIntersectionPoint = null;
+
+  private LineIntersector li;
+  private boolean includeProper;
+  private boolean recordIsolated;
+  //private boolean intersectionFound;
+
+  // testing only
+  public int numTests = 0;
+
+  private Collection[] bdyNodes;
+/*
+  public SegmentIntersector()
+  {
+  }
+*/
+  public SegmentIntersector(LineIntersector li,  boolean includeProper, boolean recordIsolated)
+  {
+    this.li = li;
+    this.includeProper = includeProper;
+    this.recordIsolated = recordIsolated;
+  }
+
+  public void setBoundaryNodes( Collection bdyNodes0,
+                              Collection bdyNodes1)
+  {
+      bdyNodes = new Collection[2];
+      bdyNodes[0] = bdyNodes0;
+      bdyNodes[1] = bdyNodes1;
+  }
+
+  /**
+   * @return the proper intersection point, or <code>null</code> if none was found
+   */
+  public Coordinate getProperIntersectionPoint()  {    return properIntersectionPoint;  }
+
+  public boolean hasIntersection() { return hasIntersection; }
+  /**
+   * A proper intersection is an intersection which is interior to at least two
+   * line segments.  Note that a proper intersection is not necessarily
+   * in the interior of the entire Geometry, since another edge may have
+   * an endpoint equal to the intersection, which according to SFS semantics
+   * can result in the point being on the Boundary of the Geometry.
+   */
+  public boolean hasProperIntersection() { return hasProper; }
+  /**
+   * A proper interior intersection is a proper intersection which is <b>not</b>
+   * contained in the set of boundary nodes set for this SegmentIntersector.
+   */
+  public boolean hasProperInteriorIntersection() { return hasProperInterior; }
+
+
+  /**
+   * A trivial intersection is an apparent self-intersection which in fact
+   * is simply the point shared by adjacent line segments.
+   * Note that closed edges require a special check for the point shared by the beginning
+   * and end segments.
+   */
+  private boolean isTrivialIntersection(Edge e0, int segIndex0, Edge e1, int segIndex1)
+  {
+    if (e0 == e1) {
+      if (li.getIntersectionNum() == 1) {
+        if (isAdjacentSegments(segIndex0, segIndex1))
+          return true;
+        if (e0.isClosed()) {
+          int maxSegIndex = e0.getNumPoints() - 1;
+          if (    (segIndex0 == 0 && segIndex1 == maxSegIndex)
+              ||  (segIndex1 == 0 && segIndex0 == maxSegIndex) ) {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This method is called by clients of the EdgeIntersector class to test for and add
+   * intersections for two segments of the edges being intersected.
+   * Note that clients (such as MonotoneChainEdges) may choose not to intersect
+   * certain pairs of segments for efficiency reasons.
+   */
+  public void addIntersections(
+    Edge e0,  int segIndex0,
+    Edge e1,  int segIndex1
+     )
+  {
+    if (e0 == e1 && segIndex0 == segIndex1) return;
+numTests++;
+    Coordinate p00 = e0.getCoordinates()[segIndex0];
+    Coordinate p01 = e0.getCoordinates()[segIndex0 + 1];
+    Coordinate p10 = e1.getCoordinates()[segIndex1];
+    Coordinate p11 = e1.getCoordinates()[segIndex1 + 1];
+
+    li.computeIntersection(p00, p01, p10, p11);
+//if (li.hasIntersection() && li.isProper()) Debug.println(li);
+    /**
+     *  Always record any non-proper intersections.
+     *  If includeProper is true, record any proper intersections as well.
+     */
+    if (li.hasIntersection()) {
+      if (recordIsolated) {
+        e0.setIsolated(false);
+        e1.setIsolated(false);
+      }
+      //intersectionFound = true;
+      // if the segments are adjacent they have at least one trivial intersection,
+      // the shared endpoint.  Don't bother adding it if it is the
+      // only intersection.
+      if (! isTrivialIntersection(e0, segIndex0, e1, segIndex1)) {
+        hasIntersection = true;
+        if (includeProper || ! li.isProper() ) {
+//Debug.println(li);
+          e0.addIntersections(li, segIndex0, 0);
+          e1.addIntersections(li, segIndex1, 1);
+        }
+        if (li.isProper()) {
+          properIntersectionPoint = (Coordinate) li.getIntersection(0).clone();
+          hasProper = true;
+          if (! isBoundaryPoint(li, bdyNodes))
+            hasProperInterior = true;
+        }
+        //if (li.isCollinear())
+          //hasCollinear = true;
+      }
+    }
+  }
+
+  private boolean isBoundaryPoint(LineIntersector li, Collection[] bdyNodes)
+  {
+    if (bdyNodes == null) return false;
+    if (isBoundaryPoint(li, bdyNodes[0])) return true;
+    if (isBoundaryPoint(li, bdyNodes[1])) return true;
+    return false;
+  }
+
+  private boolean isBoundaryPoint(LineIntersector li, Collection bdyNodes)
+  {
+    for (Iterator i = bdyNodes.iterator(); i.hasNext(); ) {
+      Node node = (Node) i.next();
+      Coordinate pt = node.getCoordinate();
+      if (li.isIntersection(pt)) return true;
+    }
+    return false;
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/SimpleMCSweepLineIntersector.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/SimpleMCSweepLineIntersector.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/SimpleMCSweepLineIntersector.java	(revision 28000)
@@ -0,0 +1,169 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph.index;
+
+/**
+ * @version 1.7
+ */
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.geomgraph.Edge;
+
+/**
+ * Finds all intersections in one or two sets of edges,
+ * using an x-axis sweepline algorithm in conjunction with Monotone Chains.
+ * While still O(n^2) in the worst case, this algorithm
+ * drastically improves the average-case time.
+ * The use of MonotoneChains as the items in the index
+ * seems to offer an improvement in performance over a sweep-line alone.
+ *
+ * @version 1.7
+ */
+public class SimpleMCSweepLineIntersector
+  extends EdgeSetIntersector
+{
+
+  List events = new ArrayList();
+  // statistics information
+  int nOverlaps;
+
+  /**
+   * A SimpleMCSweepLineIntersector creates monotone chains from the edges
+   * and compares them using a simple sweep-line along the x-axis.
+   */
+  public SimpleMCSweepLineIntersector() {
+  }
+
+  public void computeIntersections(List edges, SegmentIntersector si, boolean testAllSegments)
+  {
+    if (testAllSegments)
+      add(edges, null);
+    else
+      add(edges);
+    computeIntersections(si);
+  }
+
+  public void computeIntersections(List edges0, List edges1, SegmentIntersector si)
+  {
+    add(edges0, edges0);
+    add(edges1, edges1);
+    computeIntersections(si);
+  }
+
+  private void add(List edges)
+  {
+    for (Iterator i = edges.iterator(); i.hasNext(); ) {
+      Edge edge = (Edge) i.next();
+      // edge is its own group
+      add(edge, edge);
+    }
+  }
+  private void add(List edges, Object edgeSet)
+  {
+    for (Iterator i = edges.iterator(); i.hasNext(); ) {
+      Edge edge = (Edge) i.next();
+      add(edge, edgeSet);
+    }
+  }
+
+  private void add(Edge edge, Object edgeSet)
+  {
+    MonotoneChainEdge mce = edge.getMonotoneChainEdge();
+    int[] startIndex = mce.getStartIndexes();
+    for (int i = 0; i < startIndex.length - 1; i++) {
+      MonotoneChain mc = new MonotoneChain(mce, i);
+      SweepLineEvent insertEvent = new SweepLineEvent(edgeSet, mce.getMinX(i), null, mc);
+      events.add(insertEvent);
+      events.add(new SweepLineEvent(edgeSet, mce.getMaxX(i), insertEvent, mc));
+    }
+  }
+
+  /**
+   * Because Delete Events have a link to their corresponding Insert event,
+   * it is possible to compute exactly the range of events which must be
+   * compared to a given Insert event object.
+   */
+  private void prepareEvents()
+  {
+    Collections.sort(events);
+    for (int i = 0; i < events.size(); i++ )
+    {
+      SweepLineEvent ev = (SweepLineEvent) events.get(i);
+      if (ev.isDelete()) {
+        ev.getInsertEvent().setDeleteEventIndex(i);
+      }
+    }
+  }
+
+  private void computeIntersections(SegmentIntersector si)
+  {
+    nOverlaps = 0;
+    prepareEvents();
+
+    for (int i = 0; i < events.size(); i++ )
+    {
+      SweepLineEvent ev = (SweepLineEvent) events.get(i);
+      if (ev.isInsert()) {
+        processOverlaps(i, ev.getDeleteEventIndex(), ev, si);
+      }
+    }
+  }
+
+  private void processOverlaps(int start, int end, SweepLineEvent ev0, SegmentIntersector si)
+  {
+    MonotoneChain mc0 = (MonotoneChain) ev0.getObject();
+    /**
+     * Since we might need to test for self-intersections,
+     * include current insert event object in list of event objects to test.
+     * Last index can be skipped, because it must be a Delete event.
+     */
+    for (int i = start; i < end; i++ ) {
+      SweepLineEvent ev1 = (SweepLineEvent) events.get(i);
+      if (ev1.isInsert()) {
+        MonotoneChain mc1 = (MonotoneChain) ev1.getObject();
+        // don't compare edges in same group
+        // null group indicates that edges should be compared
+        if (ev0.edgeSet == null || (ev0.edgeSet != ev1.edgeSet)) {
+          mc0.computeIntersections(mc1, si);
+          nOverlaps++;
+        }
+      }
+    }
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/SweepLineEvent.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/SweepLineEvent.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/SweepLineEvent.java	(revision 28000)
@@ -0,0 +1,89 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.geomgraph.index;
+
+/**
+ * @version 1.7
+ */
+public class SweepLineEvent
+  implements Comparable
+{
+  public static final int INSERT = 1;
+  public static final int DELETE = 2;
+
+  Object edgeSet;    // used for red-blue intersection detection
+  private double xValue;
+  private int eventType;
+  private SweepLineEvent insertEvent; // null if this is an INSERT event
+  private int deleteEventIndex;
+  private Object obj;
+
+  public SweepLineEvent(Object edgeSet, double x, SweepLineEvent insertEvent, Object obj)
+  {
+    this.edgeSet = edgeSet;
+    xValue = x;
+    this.insertEvent = insertEvent;
+    this.eventType = INSERT;
+    if (insertEvent != null)
+      eventType = DELETE;
+    this.obj = obj;
+  }
+
+  public boolean isInsert() { return insertEvent == null; }
+  public boolean isDelete() { return insertEvent != null; }
+  public SweepLineEvent getInsertEvent() { return insertEvent; }
+  public int getDeleteEventIndex() { return deleteEventIndex; }
+  public void setDeleteEventIndex(int deleteEventIndex) { this.deleteEventIndex = deleteEventIndex; }
+
+  public Object getObject() { return obj; }
+
+  /**
+   * ProjectionEvents are ordered first by their x-value, and then by their eventType.
+   * It is important that Insert events are sorted before Delete events, so that
+   * items whose Insert and Delete events occur at the same x-value will be
+   * correctly handled.
+   */
+  public int compareTo(Object o) {
+    SweepLineEvent pe = (SweepLineEvent) o;
+    if (xValue < pe.xValue) return  -1;
+    if (xValue > pe.xValue) return   1;
+    if (eventType < pe.eventType) return  -1;
+    if (eventType > pe.eventType) return   1;
+    return 0;
+  }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/index/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Contains classes that implement indexes for performing noding on geometry graph edges.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/geomgraph/package.html	(revision 28000)
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Contains classes that implement topology graphs.
+<P>
+The Java Topology Suite (JTS) is a Java API that implements a core set of spatial data operations using an explicit precision model and robust geometric algorithms. JTS is intended to be used in the development of applications that support the validation, cleaning, integration and querying of spatial datasets.
+<P>
+JTS attempts to implement the OpenGIS Simple Features Specification (SFS) as accurately as possible.  In some cases the SFS is unclear or omits a specification; in this case JTS attempts to choose a reasonable and consistent alternative.  Differences from and elaborations of the SFS are documented in this specification.
+
+<h2>Package Specification</h2>
+
+<ul>
+  <li>Java Topology Suite Technical Specifications
+  <li><A HREF="http://www.opengis.org/techno/specs.htm">
+      OpenGIS Simple Features Specification for SQL</A>
+</ul>
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/ArrayListVisitor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/ArrayListVisitor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/ArrayListVisitor.java	(revision 28000)
@@ -0,0 +1,23 @@
+package com.vividsolutions.jts.index;
+
+import java.util.ArrayList;
+
+/**
+ * @version 1.7
+ */
+public class ArrayListVisitor
+    implements ItemVisitor
+{
+
+  private ArrayList items = new ArrayList();
+  public ArrayListVisitor() {
+  }
+
+  public void visitItem(Object item)
+  {
+    items.add(item);
+  }
+
+  public ArrayList getItems() { return items; }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/ItemVisitor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/ItemVisitor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/ItemVisitor.java	(revision 28000)
@@ -0,0 +1,12 @@
+package com.vividsolutions.jts.index;
+
+/**
+ * A visitor for items in an index.
+ *
+ * @version 1.7
+ */
+
+public interface ItemVisitor
+{
+  void visitItem(Object item);
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/SpatialIndex.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/SpatialIndex.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/SpatialIndex.java	(revision 28000)
@@ -0,0 +1,88 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index;
+
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * The basic operations supported by classes
+ * implementing spatial index algorithms.
+ * <p>
+ * A spatial index typically provides a primary filter for range rectangle queries.
+ * A secondary filter is required to test for exact intersection.
+ * The secondary filter may consist of other kinds of tests,
+ * such as testing other spatial relationships.
+ *
+ * @version 1.7
+ */
+public interface SpatialIndex
+{
+  /**
+   * Adds a spatial item with an extent specified by the given {@link Envelope} to the index
+   */
+  void insert(Envelope itemEnv, Object item);
+
+  /**
+   * Queries the index for all items whose extents intersect the given search {@link Envelope}
+   * Note that some kinds of indexes may also return objects which do not in fact
+   * intersect the query envelope.
+   *
+   * @param searchEnv the envelope to query for
+   * @return a list of the items found by the query
+   */
+  List query(Envelope searchEnv);
+
+  /**
+   * Queries the index for all items whose extents intersect the given search {@link Envelope},
+   * and applies an {@link ItemVisitor} to them.
+   * Note that some kinds of indexes may also return objects which do not in fact
+   * intersect the query envelope.
+   *
+   * @param searchEnv the envelope to query for
+   * @param visitor a visitor object to apply to the items found
+   */
+  void query(Envelope searchEnv, ItemVisitor visitor);
+
+  /**
+   * Removes a single item from the tree.
+   *
+   * @param itemEnv the Envelope of the item to remove
+   * @param item the item to remove
+   * @return <code>true</code> if the item was found
+   */
+  boolean remove(Envelope itemEnv, Object item);
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Bintree.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Bintree.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Bintree.java	(revision 28000)
@@ -0,0 +1,165 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.bintree;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * An <code>BinTree</code> (or "Binary Interval Tree")
+ * is a 1-dimensional version of a quadtree.
+ * It indexes 1-dimensional intervals (which may
+ * be the projection of 2-D objects on an axis).
+ * It supports range searching
+ * (where the range may be a single point).
+ * This structure is dynamic - 
+ * new items can be added at any time,   
+ * and it will support deletion of items 
+ * (although this is not currently implemented).
+ * <p>
+ * This implementation does not require specifying the extent of the inserted
+ * items beforehand.  It will automatically expand to accomodate any extent
+ * of dataset.
+ * <p>
+ * The bintree structure is used to provide a primary filter
+ * for interval queries.  The query() method returns a list of
+ * all objects which <i>may</i> intersect the query interval.
+ * Note that it may return objects which do not in fact intersect.
+ * A secondary filter is required to test for exact intersection.
+ * Of course, this secondary filter may consist of other tests besides
+ * intersection, such as testing other kinds of spatial relationships.
+ * <p>
+ * This index is different to the Interval Tree of Edelsbrunner
+ * or the Segment Tree of Bentley.
+ *
+ * @version 1.7
+ */
+public class Bintree
+{
+  /**
+   * Ensure that the Interval for the inserted item has non-zero extents.
+   * Use the current minExtent to pad it, if necessary
+   */
+  public static Interval ensureExtent(Interval itemInterval, double minExtent)
+  {
+    double min = itemInterval.getMin();
+    double max = itemInterval.getMax();
+    // has a non-zero extent
+    if (min != max) return itemInterval;
+
+    // pad extent
+    if (min == max) {
+      min = min - minExtent / 2.0;
+      max = min + minExtent / 2.0;
+    }
+    return new Interval(min, max);
+  }
+
+  private Root root;
+  /**
+  *  Statistics
+  *
+  * minExtent is the minimum extent of all items
+  * inserted into the tree so far. It is used as a heuristic value
+  * to construct non-zero extents for features with zero extent.
+  * Start with a non-zero extent, in case the first feature inserted has
+  * a zero extent in both directions.  This value may be non-optimal, but
+  * only one feature will be inserted with this value.
+  **/
+  private double minExtent = 1.0;
+
+  public Bintree()
+  {
+    root = new Root();
+  }
+
+
+  public void insert(Interval itemInterval, Object item)
+  {
+    collectStats(itemInterval);
+    Interval insertInterval = ensureExtent(itemInterval, minExtent);
+//int oldSize = size();
+    root.insert(insertInterval, item);
+    /* DEBUG
+int newSize = size();
+System.out.println("BinTree: size = " + newSize + "   node size = " + nodeSize());
+if (newSize <= oldSize) {
+      System.out.println("Lost item!");
+      root.insert(insertInterval, item);
+      System.out.println("reinsertion size = " + size());
+}
+    */
+  }
+
+
+  /**
+   * Queries the tree to find all candidate items which 
+   * may overlap the query interval.
+   * If the query interval is <tt>null</tt>, all items in the tree are found.
+   * 
+   * min and max may be the same value
+   */
+  public List query(Interval interval)
+  {
+    /**
+     * the items that are matched are all items in intervals
+     * which overlap the query interval
+     */
+    List foundItems = new ArrayList();
+    query(interval, foundItems);
+    return foundItems;
+  }
+
+  /**
+   * Adds items in the tree which potentially overlap the query interval
+   * to the given collection.
+   * If the query interval is <tt>null</tt>, add all items in the tree.
+   * 
+   * @param interval a query nterval, or null
+   * @param resultItems the candidate items found
+   */
+  public void query(Interval interval, Collection foundItems)
+  {
+    root.addAllItemsFromOverlapping(interval, foundItems);
+  }
+
+  private void collectStats(Interval interval)
+  {
+    double del = interval.getWidth();
+    if (del < minExtent && del > 0.0)
+      minExtent = del;
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Interval.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Interval.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Interval.java	(revision 28000)
@@ -0,0 +1,102 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.bintree;
+
+/**
+ * Represents an (1-dimensional) closed interval on the Real number line.
+ *
+ * @version 1.7
+ */
+public class Interval {
+
+  public double min, max;
+
+  public Interval()
+  {
+    min = 0.0;
+    max = 0.0;
+  }
+
+  public Interval(double min, double max)
+  {
+    init(min, max);
+  }
+  public Interval(Interval interval)
+  {
+    init(interval.min, interval.max);
+  }
+  public void init(double min, double max)
+  {
+    this.min = min;
+    this.max = max;
+    if (min > max) {
+      this.min = max;
+      this.max = min;
+    }
+  }
+  public double getMin() { return min; }
+  public double getMax() { return max; }
+  public double getWidth() { return max - min; }
+
+  public void expandToInclude(Interval interval)
+  {
+    if (interval.max > max) max = interval.max;
+    if (interval.min < min) min = interval.min;
+  }
+  public boolean overlaps(Interval interval)
+  {
+    return overlaps(interval.min, interval.max);
+  }
+
+  public boolean overlaps(double min, double max)
+  {
+    if (this.min > max || this.max < min) return false;
+    return true;
+  }
+
+  public boolean contains(Interval interval)
+  {
+    return contains(interval.min, interval.max);
+  }
+  public boolean contains(double min, double max)
+  {
+    return (min >= this.min && max <= this.max);
+  }
+
+
+  public String toString()
+  {
+    return "[" + min + ", " + max + "]";
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Key.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Key.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Key.java	(revision 28000)
@@ -0,0 +1,95 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.bintree;
+
+
+
+import com.vividsolutions.jts.index.quadtree.DoubleBits;
+
+/**
+ * A Key is a unique identifier for a node in a tree.
+ * It contains a lower-left point and a level number. The level number
+ * is the power of two for the size of the node envelope
+ *
+ * @version 1.7
+ */
+public class Key {
+
+  public static int computeLevel(Interval interval)
+  {
+    double dx = interval.getWidth();
+    //int level = BinaryPower.exponent(dx) + 1;
+    int level = DoubleBits.exponent(dx) + 1;
+    return level;
+  }
+
+
+  // the fields which make up the key
+  private double pt = 0.0;
+  private int level = 0;
+  // auxiliary data which is derived from the key for use in computation
+  private Interval interval;
+
+  public Key(Interval interval)
+  {
+    computeKey(interval);
+  }
+
+  public int getLevel() { return level; }
+  public Interval getInterval() { return interval; }
+
+  /**
+   * return a square envelope containing the argument envelope,
+   * whose extent is a power of two and which is based at a power of 2
+   */
+  public void computeKey(Interval itemInterval)
+  {
+    level = computeLevel(itemInterval);
+    interval = new Interval();
+    computeInterval(level, itemInterval);
+    // MD - would be nice to have a non-iterative form of this algorithm
+    while (! interval.contains(itemInterval)) {
+      level += 1;
+      computeInterval(level, itemInterval);
+    }
+  }
+
+  private void computeInterval(int level, Interval itemInterval)
+  {
+    double size = DoubleBits.powerOf2(level);
+    //double size = pow2.power(level);
+    pt = Math.floor(itemInterval.getMin() / size) * size;
+    interval.init(pt, pt + size);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Node.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Node.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Node.java	(revision 28000)
@@ -0,0 +1,173 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.bintree;
+
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * A node of a {@link Bintree}.
+ *
+ * @version 1.7
+ */
+public class Node
+  extends NodeBase
+{
+  public static Node createNode(Interval itemInterval)
+  {
+    Key key = new Key(itemInterval);
+
+//System.out.println("input: " + env + "  binaryEnv: " + key.getEnvelope());
+    Node node = new Node(key.getInterval(), key.getLevel());
+    return node;
+  }
+
+  public static Node createExpanded(Node node, Interval addInterval)
+  {
+    Interval expandInt = new Interval(addInterval);
+    if (node != null) expandInt.expandToInclude(node.interval);
+
+    Node largerNode = createNode(expandInt);
+    if (node != null) largerNode.insert(node);
+    return largerNode;
+  }
+
+  private Interval interval;
+  private double centre;
+  private int level;
+
+  public Node(Interval interval, int level)
+  {
+    this.interval = interval;
+    this.level = level;
+    centre = (interval.getMin() + interval.getMax()) / 2;
+  }
+
+  public Interval getInterval() { return interval; }
+
+  protected boolean isSearchMatch(Interval itemInterval)
+  {
+//    System.out.println(itemInterval + " overlaps " + interval + " : "
+//                       + itemInterval.overlaps(interval));
+    return itemInterval.overlaps(interval);
+  }
+
+  /**
+   * Returns the subnode containing the envelope.
+   * Creates the node if
+   * it does not already exist.
+   */
+  public Node getNode(Interval searchInterval)
+  {
+    int subnodeIndex = getSubnodeIndex(searchInterval, centre);
+    // if index is -1 searchEnv is not contained in a subnode
+    if (subnodeIndex != -1) {
+      // create the node if it does not exist
+      Node node = getSubnode(subnodeIndex);
+      // recursively search the found/created node
+      return node.getNode(searchInterval);
+    }
+    else {
+      return this;
+    }
+  }
+
+  /**
+   * Returns the smallest <i>existing</i>
+   * node containing the envelope.
+   */
+  public NodeBase find(Interval searchInterval)
+  {
+    int subnodeIndex = getSubnodeIndex(searchInterval, centre);
+    if (subnodeIndex == -1)
+      return this;
+    if (subnode[subnodeIndex] != null) {
+      // query lies in subnode, so search it
+      Node node = subnode[subnodeIndex];
+      return node.find(searchInterval);
+    }
+    // no existing subnode, so return this one anyway
+    return this;
+  }
+
+  void insert(Node node)
+  {
+    Assert.isTrue(interval == null || interval.contains(node.interval));
+    int index = getSubnodeIndex(node.interval, centre);
+    if (node.level == level - 1) {
+      subnode[index] = node;
+    }
+    else {
+      // the node is not a direct child, so make a new child node to contain it
+      // and recursively insert the node
+      Node childNode = createSubnode(index);
+      childNode.insert(node);
+      subnode[index] = childNode;
+    }
+  }
+
+  /**
+   * get the subnode for the index.
+   * If it doesn't exist, create it
+   */
+  private Node getSubnode(int index)
+  {
+    if (subnode[index] == null) {
+      subnode[index] = createSubnode(index);
+    }
+    return subnode[index];
+  }
+
+  private Node createSubnode(int index)
+  {
+        // create a new subnode in the appropriate interval
+
+      double min = 0.0;
+      double max = 0.0;
+
+      switch (index) {
+      case 0:
+        min = interval.getMin();
+        max = centre;
+        break;
+      case 1:
+        min = centre;
+        max = interval.getMax();
+        break;
+      }
+      Interval subInt = new Interval(min, max);
+      Node node = new Node(subInt, level - 1);
+    return node;
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/NodeBase.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/NodeBase.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/NodeBase.java	(revision 28000)
@@ -0,0 +1,97 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.bintree;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+
+/**
+ * The base class for nodes in a {@link Bintree}.
+ *
+ * @version 1.7
+ */
+public abstract class NodeBase {
+
+  /**
+   * Returns the index of the subnode that wholely contains the given interval.
+   * If none does, returns -1.
+   */
+  public static int getSubnodeIndex(Interval interval, double centre)
+  {
+    int subnodeIndex = -1;
+    if (interval.min >= centre) subnodeIndex = 1;
+    if (interval.max <= centre) subnodeIndex = 0;
+    return subnodeIndex;
+  }
+
+  protected List items = new ArrayList();
+
+  /**
+   * subnodes are numbered as follows:
+   *
+   *  0 | 1
+   */
+  protected Node[] subnode = new Node[2];
+
+  public NodeBase() {
+  }
+
+  public void add(Object item)
+  {
+    items.add(item);
+  }
+  protected abstract boolean isSearchMatch(Interval interval);
+
+  /**
+   * Adds items in the tree which potentially overlap the query interval
+   * to the given collection.
+   * If the query interval is <tt>null</tt>, add all items in the tree.
+   * 
+   * @param interval a query nterval, or null
+   * @param resultItems the candidate items found
+   */
+  public void addAllItemsFromOverlapping(Interval interval, Collection resultItems)
+  {
+    if (interval != null && ! isSearchMatch(interval))
+      return;
+
+    // some of these may not actually overlap - this is allowed by the bintree contract
+    resultItems.addAll(items);
+
+    if (subnode[0] != null) subnode[0].addAllItemsFromOverlapping(interval, resultItems);
+    if (subnode[1] != null) subnode[1].addAllItemsFromOverlapping(interval, resultItems);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Root.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Root.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/Root.java	(revision 28000)
@@ -0,0 +1,121 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.bintree;
+
+import com.vividsolutions.jts.index.quadtree.IntervalSize;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * The root node of a single {@link Bintree}.
+ * It is centred at the origin,
+ * and does not have a defined extent.
+ *
+ * @version 1.7
+ */
+public class Root
+  extends NodeBase
+{
+
+  // the singleton root node is centred at the origin.
+  private static final double origin = 0.0;
+
+  public Root()
+  {
+  }
+
+  /**
+   * Insert an item into the tree this is the root of.
+   */
+  public void insert(Interval itemInterval, Object item)
+  {
+    int index = getSubnodeIndex(itemInterval, origin);
+    // if index is -1, itemEnv must contain the origin.
+    if (index == -1) {
+      add(item);
+      return;
+    }
+    /**
+     * the item must be contained in one interval, so insert it into the
+     * tree for that interval (which may not yet exist)
+     */
+    Node node = subnode[index];
+    /**
+     *  If the subnode doesn't exist or this item is not contained in it,
+     *  have to expand the tree upward to contain the item.
+     */
+
+    if (node == null || ! node.getInterval().contains(itemInterval)) {
+       Node largerNode = Node.createExpanded(node, itemInterval);
+       subnode[index] = largerNode;
+    }
+    /**
+     * At this point we have a subnode which exists and must contain
+     * contains the env for the item.  Insert the item into the tree.
+     */
+    insertContained(subnode[index], itemInterval, item);
+//System.out.println("depth = " + root.depth() + " size = " + root.size());
+  }
+
+  /**
+   * insert an item which is known to be contained in the tree rooted at
+   * the given Node.  Lower levels of the tree will be created
+   * if necessary to hold the item.
+   */
+  private void insertContained(Node tree, Interval itemInterval, Object item)
+  {
+    Assert.isTrue(tree.getInterval().contains(itemInterval));
+   /**
+    * Do NOT create a new node for zero-area intervals - this would lead
+    * to infinite recursion. Instead, use a heuristic of simply returning
+    * the smallest existing node containing the query
+    */
+    boolean isZeroArea = IntervalSize.isZeroWidth(itemInterval.getMin(), itemInterval.getMax());
+    NodeBase node;
+    if (isZeroArea)
+      node = tree.find(itemInterval);
+    else
+      node = tree.getNode(itemInterval);
+    node.add(item);
+  }
+
+  /**
+   * The root node matches all searches
+   */
+  protected boolean isSearchMatch(Interval interval)
+  {
+    return true;
+  }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/bintree/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Contains classes that implement a Binary Interval Tree index
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/MonotoneChain.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/MonotoneChain.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/MonotoneChain.java	(revision 28000)
@@ -0,0 +1,228 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.chain;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.LineSegment;
+
+
+/**
+ * Monotone Chains are a way of partitioning the segments of a linestring to
+ * allow for fast searching of intersections.
+ * They have the following properties:
+ * <ol>
+ * <li>the segments within a monotone chain never intersect each other
+ * <li>the envelope of any contiguous subset of the segments in a monotone chain
+ * is equal to the envelope of the endpoints of the subset.
+ * </ol>
+ * Property 1 means that there is no need to test pairs of segments from within
+ * the same monotone chain for intersection.
+ * <p>
+ * Property 2 allows
+ * an efficient binary search to be used to find the intersection points of two monotone chains.
+ * For many types of real-world data, these properties eliminate a large number of
+ * segment comparisons, producing substantial speed gains.
+ * <p>
+ * One of the goals of this implementation of MonotoneChains is to be
+ * as space and time efficient as possible. One design choice that aids this
+ * is that a MonotoneChain is based on a subarray of a list of points.
+ * This means that new arrays of points (potentially very large) do not
+ * have to be allocated.
+ * <p>
+ *
+ * MonotoneChains support the following kinds of queries:
+ * <ul>
+ * <li>Envelope select: determine all the segments in the chain which
+ * intersect a given envelope
+ * <li>Overlap: determine all the pairs of segments in two chains whose
+ * envelopes overlap
+ * </ul>
+ *
+ * This implementation of MonotoneChains uses the concept of internal iterators
+ * to return the resultsets for the above queries.
+ * This has time and space advantages, since it
+ * is not necessary to build lists of instantiated objects to represent the segments
+ * returned by the query.
+ * However, it does mean that the queries are not thread-safe.
+ *
+ * @version 1.7
+ */
+public class MonotoneChain {
+
+  private Coordinate[] pts;
+  private int start, end;
+  private Envelope env = null;
+  private Object context = null;// user-defined information
+  private int id;// useful for optimizing chain comparisons
+
+  public MonotoneChain(Coordinate[] pts, int start, int end, Object context)
+  {
+    this.pts    = pts;
+    this.start  = start;
+    this.end    = end;
+    this.context = context;
+  }
+
+  public void setId(int id) { this.id = id; }
+  public int getId() { return id; }
+
+  public Object getContext() { return context; }
+
+  public Envelope getEnvelope()
+  {
+    if (env == null) {
+      Coordinate p0 = pts[start];
+      Coordinate p1 = pts[end];
+      env = new Envelope(p0, p1);
+    }
+    return env;
+  }
+
+  public void getLineSegment(int index, LineSegment ls)
+  {
+    ls.p0 = pts[index];
+    ls.p1 = pts[index + 1];
+  }
+
+  /**
+   * Determine all the line segments in the chain whose envelopes overlap
+   * the searchEnvelope, and process them.
+   * <p>
+   * The monotone chain search algorithm attempts to optimize 
+   * performance by not calling the select action on chain segments
+   * which it can determine are not in the search envelope.
+   * However, it *may* call the select action on segments
+   * which do not intersect the search envelope.
+   * This saves on the overhead of checking envelope intersection
+   * each time, since clients may be able to do this more efficiently.
+   * 
+   * @param searchEnv the search envelope
+   * @param mcs the select action to execute on selected segments
+   */
+  public void select(Envelope searchEnv, MonotoneChainSelectAction mcs)
+  {
+    computeSelect(searchEnv, start, end, mcs);
+  }
+
+  private void computeSelect(
+    Envelope searchEnv,
+    int start0, int end0,
+    MonotoneChainSelectAction mcs )
+  {
+    Coordinate p0 = pts[start0];
+    Coordinate p1 = pts[end0];
+    mcs.tempEnv1.init(p0, p1);
+
+//Debug.println("trying:" + p0 + p1 + " [ " + start0 + ", " + end0 + " ]");
+    // terminating condition for the recursion
+    if (end0 - start0 == 1) {
+      //Debug.println("computeSelect:" + p0 + p1);
+      mcs.select(this, start0);
+      return;
+    }
+    // nothing to do if the envelopes don't overlap
+    if (! searchEnv.intersects(mcs.tempEnv1))
+      return;
+
+    // the chains overlap, so split each in half and iterate  (binary search)
+    int mid = (start0 + end0) / 2;
+
+    // Assert: mid != start or end (since we checked above for end - start <= 1)
+    // check terminating conditions before recursing
+    if (start0 < mid) {
+      computeSelect(searchEnv, start0, mid, mcs);
+    }
+    if (mid < end0) {
+      computeSelect(searchEnv, mid, end0, mcs);
+    }
+  }
+
+  /**
+   * Determine all the line segments in two chains which may overlap, and process them.
+   * <p>
+   * The monotone chain search algorithm attempts to optimize 
+   * performance by not calling the overlap action on chain segments
+   * which it can determine do not overlap.
+   * However, it *may* call the overlap action on segments
+   * which do not actually interact.
+   * This saves on the overhead of checking intersection
+   * each time, since clients may be able to do this more efficiently.
+   * 
+   * @param searchEnv the search envelope
+   * @param mco the overlap action to execute on selected segments
+   */
+  public void computeOverlaps(MonotoneChain mc, MonotoneChainOverlapAction mco)
+  {
+    computeOverlaps(start, end, mc, mc.start, mc.end, mco);
+  }
+
+  private void computeOverlaps(
+    int start0, int end0,
+    MonotoneChain mc,
+    int start1, int end1,
+    MonotoneChainOverlapAction mco)
+  {
+    Coordinate p00 = pts[start0];
+    Coordinate p01 = pts[end0];
+    Coordinate p10 = mc.pts[start1];
+    Coordinate p11 = mc.pts[end1];
+//Debug.println("computeIntersectsForChain:" + p00 + p01 + p10 + p11);
+    // terminating condition for the recursion
+    if (end0 - start0 == 1 && end1 - start1 == 1) {
+      mco.overlap(this, start0, mc, start1);
+      return;
+    }
+    // nothing to do if the envelopes of these chains don't overlap
+    mco.tempEnv1.init(p00, p01);
+    mco.tempEnv2.init(p10, p11);
+    if (! mco.tempEnv1.intersects(mco.tempEnv2)) return;
+
+    // the chains overlap, so split each in half and iterate  (binary search)
+    int mid0 = (start0 + end0) / 2;
+    int mid1 = (start1 + end1) / 2;
+
+    // Assert: mid != start or end (since we checked above for end - start <= 1)
+    // check terminating conditions before recursing
+    if (start0 < mid0) {
+      if (start1 < mid1) computeOverlaps(start0, mid0, mc, start1,  mid1, mco);
+      if (mid1 < end1)   computeOverlaps(start0, mid0, mc, mid1,    end1, mco);
+    }
+    if (mid0 < end0) {
+      if (start1 < mid1) computeOverlaps(mid0,   end0, mc, start1,  mid1, mco);
+      if (mid1 < end1)   computeOverlaps(mid0,   end0, mc, mid1,    end1, mco);
+    }
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/MonotoneChainBuilder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/MonotoneChainBuilder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/MonotoneChainBuilder.java	(revision 28000)
@@ -0,0 +1,141 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.chain;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geomgraph.Quadrant;
+
+/**
+ * Constructs {@link MonotoneChain}s
+ * for sequences of {@link Coordinate}s.
+ *
+ * @version 1.7
+ */
+public class MonotoneChainBuilder {
+
+  public static int[] toIntArray(List list)
+  {
+    int[] array = new int[list.size()];
+    for (int i = 0; i < array.length; i++) {
+      array[i] = ((Integer) list.get(i)).intValue();
+    }
+    return array;
+  }
+
+  public static List getChains(Coordinate[] pts)
+  {
+    return getChains(pts, null);
+  }
+
+  /**
+   * Return a list of the {@link MonotoneChain}s
+   * for the given list of coordinates.
+   */
+  public static List getChains(Coordinate[] pts, Object context)
+  {
+    List mcList = new ArrayList();
+    int[] startIndex = getChainStartIndices(pts);
+    for (int i = 0; i < startIndex.length - 1; i++) {
+      MonotoneChain mc = new MonotoneChain(pts, startIndex[i], startIndex[i + 1], context);
+      mcList.add(mc);
+    }
+    return mcList;
+  }
+
+  /**
+   * Return an array containing lists of start/end indexes of the monotone chains
+   * for the given list of coordinates.
+   * The last entry in the array points to the end point of the point array,
+   * for use as a sentinel.
+   */
+  public static int[] getChainStartIndices(Coordinate[] pts)
+  {
+    // find the startpoint (and endpoints) of all monotone chains in this edge
+    int start = 0;
+    List startIndexList = new ArrayList();
+    startIndexList.add(new Integer(start));
+    do {
+      int last = findChainEnd(pts, start);
+      startIndexList.add(new Integer(last));
+      start = last;
+    } while (start < pts.length - 1);
+    // copy list to an array of ints, for efficiency
+    int[] startIndex = toIntArray(startIndexList);
+    return startIndex;
+  }
+
+  /**
+   * Finds the index of the last point in a monotone chain
+   * starting at a given point.
+   * Any repeated points (0-length segments) will be included
+   * in the monotone chain returned.
+   * 
+   * @return the index of the last point in the monotone chain 
+   * starting at <code>start</code>.
+   */
+  private static int findChainEnd(Coordinate[] pts, int start)
+  {
+  	int safeStart = start;
+  	// skip any zero-length segments at the start of the sequence
+  	// (since they cannot be used to establish a quadrant)
+  	while (safeStart < pts.length - 1 && pts[safeStart].equals2D(pts[safeStart + 1])) {
+  		safeStart++;
+  	}
+  	// check if there are NO non-zero-length segments
+  	if (safeStart >= pts.length - 1) {
+  		return pts.length - 1;
+  	}
+    // determine overall quadrant for chain (which is the starting quadrant)
+    int chainQuad = Quadrant.quadrant(pts[safeStart], pts[safeStart + 1]);
+    int last = start + 1;
+    while (last < pts.length) {
+    	// skip zero-length segments, but include them in the chain
+    	if (! pts[last - 1].equals2D(pts[last])) {
+        // compute quadrant for next possible segment in chain
+    		int quad = Quadrant.quadrant(pts[last - 1], pts[last]);
+      	if (quad != chainQuad) break;
+    	}
+      last++;
+    }
+    return last - 1;
+  }
+
+
+  public MonotoneChainBuilder() {
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/MonotoneChainOverlapAction.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/MonotoneChainOverlapAction.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/MonotoneChainOverlapAction.java	(revision 28000)
@@ -0,0 +1,78 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.chain;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.LineSegment;
+
+/**
+ * The action for the internal iterator for performing
+ * overlap queries on a MonotoneChain
+ *
+ * @version 1.7
+ */
+public class MonotoneChainOverlapAction
+{
+  // these envelopes are used during the MonotoneChain search process
+  Envelope tempEnv1 = new Envelope();
+  Envelope tempEnv2 = new Envelope();
+
+  protected LineSegment overlapSeg1 = new LineSegment();
+  protected LineSegment overlapSeg2 = new LineSegment();
+
+  /**
+   * This function can be overridden if the original chains are needed
+   *
+   * @param start1 the index of the start of the overlapping segment from mc1
+   * @param start2 the index of the start of the overlapping segment from mc2
+   */
+  public void overlap(MonotoneChain mc1, int start1, MonotoneChain mc2, int start2)
+  {
+    mc1.getLineSegment(start1, overlapSeg1);
+    mc2.getLineSegment(start2, overlapSeg2);
+    overlap(overlapSeg1, overlapSeg2);
+  }
+
+  /**
+   * This is a convenience function which can be overridden to obtain the actual
+   * line segments which overlap
+   * @param seg1
+   * @param seg2
+   */
+  @SuppressWarnings("unused")
+public void overlap(LineSegment seg1, LineSegment seg2)
+  {
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/MonotoneChainSelectAction.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/MonotoneChainSelectAction.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/MonotoneChainSelectAction.java	(revision 28000)
@@ -0,0 +1,71 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.chain;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.LineSegment;
+/**
+ * The action for the internal iterator for performing
+ * envelope select queries on a MonotoneChain
+ *
+ * @version 1.7
+ */
+public class MonotoneChainSelectAction
+{
+  // these envelopes are used during the MonotoneChain search process
+  Envelope tempEnv1 = new Envelope();
+
+  LineSegment selectedSegment = new LineSegment();
+
+  /**
+   * This function can be overridden if the original chain is needed.
+   */
+  public void select(MonotoneChain mc, int start)
+  {
+    mc.getLineSegment(start, selectedSegment);
+    select(selectedSegment);
+  }
+
+  /**
+   * This is a convenience function which can be overridden to obtain the actual
+   * line segment which is selected.
+   * 
+   * @param seg
+   */
+  @SuppressWarnings("unused")
+public void select(LineSegment seg)
+  {
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/chain/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Contains classes that implement Monotone Chains
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/IntervalRTreeBranchNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/IntervalRTreeBranchNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/IntervalRTreeBranchNode.java	(revision 28000)
@@ -0,0 +1,67 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.intervalrtree;
+
+import com.vividsolutions.jts.index.ItemVisitor;
+
+public class IntervalRTreeBranchNode 
+extends IntervalRTreeNode
+{
+	private IntervalRTreeNode node1;
+	private IntervalRTreeNode node2;
+	
+	public IntervalRTreeBranchNode(IntervalRTreeNode n1, IntervalRTreeNode n2)
+	{
+		node1 = n1;
+		node2 = n2;
+		buildExtent(node1, node2);
+	}
+	
+	private void buildExtent(IntervalRTreeNode n1, IntervalRTreeNode n2)
+	{
+		min = Math.min(n1.min, n2.min);
+		max = Math.max(n1.max, n2.max);
+	}
+	
+	public void query(double queryMin, double queryMax, ItemVisitor visitor)
+	{
+		if (! intersects(queryMin, queryMax)) {
+//			System.out.println("Does NOT Overlap branch: " + this);
+			return;
+		}
+//		System.out.println("Overlaps branch: " + this);
+		if (node1 != null) node1.query(queryMin, queryMax, visitor);
+		if (node2 != null) node2.query(queryMin, queryMax, visitor);
+	}
+	
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/IntervalRTreeLeafNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/IntervalRTreeLeafNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/IntervalRTreeLeafNode.java	(revision 28000)
@@ -0,0 +1,58 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.intervalrtree;
+
+import com.vividsolutions.jts.index.ItemVisitor;
+
+public class IntervalRTreeLeafNode 
+extends IntervalRTreeNode
+{
+  private Object item;
+	
+	public IntervalRTreeLeafNode(double min, double max, Object item)
+	{
+		this.min = min;
+		this.max = max;
+		this.item = item;
+	}
+	
+	public void query(double queryMin, double queryMax, ItemVisitor visitor)
+	{
+		if (! intersects(queryMin, queryMax)) 
+      return;
+		
+		visitor.visitItem(item);
+	}
+
+	
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/IntervalRTreeNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/IntervalRTreeNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/IntervalRTreeNode.java	(revision 28000)
@@ -0,0 +1,76 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.intervalrtree;
+
+import java.util.Comparator;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.index.ItemVisitor;
+import com.vividsolutions.jts.io.WKTWriter;
+
+public abstract class IntervalRTreeNode 
+{
+	protected double min = Double.POSITIVE_INFINITY;
+	protected double max = Double.NEGATIVE_INFINITY;
+
+	
+	public abstract void query(double queryMin, double queryMax, ItemVisitor visitor);
+	
+	protected boolean intersects(double queryMin, double queryMax)
+	{
+		if (min > queryMax 
+				|| max < queryMin)
+			return false;
+		return true;
+	}
+
+	public String toString()
+	{
+		return WKTWriter.toLineString(new Coordinate(min, 0), new Coordinate(max, 0));
+	}
+  
+  public static class NodeComparator implements Comparator
+  {
+    public int compare(Object o1, Object o2)
+    {
+      IntervalRTreeNode n1 = (IntervalRTreeNode) o1;
+      IntervalRTreeNode n2 = (IntervalRTreeNode) o2;
+      double mid1 = (n1.min + n1.max) / 2;
+      double mid2 = (n2.min + n2.max) / 2;
+      if (mid1 < mid2) return -1;
+      if (mid1 > mid2) return 1;
+      return 0;
+    }
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/SortedPackedIntervalRTree.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/SortedPackedIntervalRTree.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/SortedPackedIntervalRTree.java	(revision 28000)
@@ -0,0 +1,144 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.intervalrtree;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.vividsolutions.jts.index.ItemVisitor;
+
+/**
+ * A static index on a set of 1-dimensional intervals,
+ * using an R-Tree packed based on the order of the interval midpoints.
+ * It supports range searching,
+ * where the range is an interval of the real line (which may be a single point).
+ * A common use is to index 1-dimensional intervals which 
+ * are the projection of 2-D objects onto an axis of the coordinate system.
+ * <p>
+ * This index structure is <i>static</i> 
+ * - items cannot be added or removed once the first query has been made.
+ * The advantage of this characteristic is that the index performance 
+ * can be optimized based on a fixed set of items.
+ * 
+ * @author Martin Davis
+ */
+public class SortedPackedIntervalRTree 
+{
+  private List leaves = new ArrayList();
+	private IntervalRTreeNode root = null;
+	
+	public SortedPackedIntervalRTree()
+	{
+		
+	}
+	
+  /**
+   * Adds an item to the index which is associated with the given interval
+   * 
+   * @param min the lower bound of the item interval
+   * @param max the upper bound of the item interval
+   * @param item the item to insert
+   * 
+   * @throws IllegalStateException if the index has already been queried
+   */
+	public void insert(double min, double max, Object item)
+	{
+    if (root != null)
+      throw new IllegalStateException("Index cannot be added to once it has been queried");
+    leaves.add(new IntervalRTreeLeafNode(min, max, item));
+	}
+	
+  private void init()
+  {
+    if (root != null) return;
+    root = buildTree();
+  }
+  
+	private IntervalRTreeNode buildTree()
+	{
+    // sort the leaf nodes
+    Collections.sort(leaves, new IntervalRTreeNode.NodeComparator());
+    
+    // now group nodes into blocks of two and build tree up recursively
+		List src = leaves;
+		List temp = null;
+		List dest = new ArrayList();
+		
+		while (true) {
+			buildLevel(src, dest);
+			if (dest.size() == 1)
+				return (IntervalRTreeNode) dest.get(0);
+      
+			temp = src;
+			src = dest;
+			dest = temp;
+		}
+	}
+	
+	private void buildLevel(List src, List dest) 
+  {
+		dest.clear();
+		for (int i = 0; i < src.size(); i += 2) {
+			IntervalRTreeNode n1 = (IntervalRTreeNode) src.get(i);
+			IntervalRTreeNode n2 = (i + 1 < src.size()) 
+						? (IntervalRTreeNode) src.get(i) : null;
+			if (n2 == null) {
+				dest.add(n1);
+			} else {
+				IntervalRTreeNode node = new IntervalRTreeBranchNode(
+						(IntervalRTreeNode) src.get(i),
+						(IntervalRTreeNode) src.get(i + 1));
+//        printNode(node);
+//				System.out.println(node);
+				dest.add(node);
+			}
+		}
+	}
+	  
+  /**
+   * Search for intervals in the index which intersect the given closed interval
+   * and apply the visitor to them.
+   * 
+   * @param min the lower bound of the query interval
+   * @param max the upper bound of the query interval
+   * @param visitor the visitor to pass any matched items to
+   */
+	public void query(double min, double max, ItemVisitor visitor)
+	{
+    init();
+
+		root.query(min, max, visitor);
+	}
+  
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/intervalrtree/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Contains classes to implement an R-tree index for one-dimensional intervals.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides classes for various kinds of spatial indexes.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/DoubleBits.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/DoubleBits.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/DoubleBits.java	(revision 28000)
@@ -0,0 +1,110 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.quadtree;
+
+/**
+ * DoubleBits manipulates Double numbers
+ * by using bit manipulation and bit-field extraction.
+ * For some operations (such as determining the exponent)
+ * this is more accurate than using mathematical operations
+ * (which suffer from round-off error).
+ * <p>
+ * The algorithms and constants in this class
+ * apply only to IEEE-754 double-precision floating point format.
+ *
+ * @version 1.7
+ */
+public class DoubleBits {
+
+  public static final int EXPONENT_BIAS = 1023;
+
+  public static double powerOf2(int exp)
+  {
+    if (exp > 1023 || exp < -1022)
+      throw new IllegalArgumentException("Exponent out of bounds");
+    long expBias = exp + EXPONENT_BIAS;
+    long bits = expBias << 52;
+    return Double.longBitsToDouble(bits);
+  }
+
+  public static int exponent(double d)
+  {
+    DoubleBits db = new DoubleBits(d);
+    return db.getExponent();
+  }
+
+  private double x;
+  private long xBits;
+
+  public DoubleBits(double x)
+  {
+    this.x = x;
+    xBits = Double.doubleToLongBits(x);
+  }
+
+  /**
+   * Determines the exponent for the number
+   */
+  public int biasedExponent()
+  {
+    int signExp = (int) (xBits >> 52);
+    int exp = signExp & 0x07ff;
+    return exp;
+  }
+
+  /**
+   * Determines the exponent for the number
+   */
+  public int getExponent()
+  {
+    return biasedExponent() - EXPONENT_BIAS;
+  }
+
+  /**
+   * A representation of the Double bits formatted for easy readability
+   */
+  public String toString()
+  {
+    String numStr = Long.toBinaryString(xBits);
+    // 64 zeroes!
+    String zero64 = "0000000000000000000000000000000000000000000000000000000000000000";
+    String padStr =  zero64 + numStr;
+    String bitStr = padStr.substring(padStr.length() - 64);
+    String str = bitStr.substring(0, 1) + "  "
+        + bitStr.substring(1, 12) + "(" + getExponent() + ") "
+        + bitStr.substring(12)
+        + " [ " + x + " ]";
+    return str;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/IntervalSize.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/IntervalSize.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/IntervalSize.java	(revision 28000)
@@ -0,0 +1,73 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.quadtree;
+
+/**
+ * Provides a test for whether an interval is
+ * so small it should be considered as zero for the purposes of
+ * inserting it into a binary tree.
+ * The reason this check is necessary is that round-off error can
+ * cause the algorithm used to subdivide an interval to fail, by
+ * computing a midpoint value which does not lie strictly between the
+ * endpoints.
+ *
+ * @version 1.7
+ */
+public class IntervalSize {
+
+  /**
+   * This value is chosen to be a few powers of 2 less than the
+   * number of bits available in the double representation (i.e. 53).
+   * This should allow enough extra precision for simple computations to be correct,
+   * at least for comparison purposes.
+   */
+  public static final int MIN_BINARY_EXPONENT = -50;
+
+  /**
+   * Computes whether the interval [min, max] is effectively zero width.
+   * I.e. the width of the interval is so much less than the
+   * location of the interval that the midpoint of the interval cannot be
+   * represented precisely.
+   */
+  public static boolean isZeroWidth(double min, double max)
+  {
+    double width = max - min;
+    if (width == 0.0) return true;
+
+    double maxAbs = Math.max(Math.abs(min), Math.abs(max));
+    double scaledInterval = width / maxAbs;
+    int level = DoubleBits.exponent(scaledInterval);
+    return level <= MIN_BINARY_EXPONENT;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/Key.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/Key.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/Key.java	(revision 28000)
@@ -0,0 +1,94 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.quadtree;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * A Key is a unique identifier for a node in a quadtree.
+ * It contains a lower-left point and a level number. The level number
+ * is the power of two for the size of the node envelope
+ *
+ * @version 1.7
+ */
+public class Key {
+
+  public static int computeQuadLevel(Envelope env)
+  {
+    double dx = env.getWidth();
+    double dy = env.getHeight();
+    double dMax = dx > dy ? dx : dy;
+    int level = DoubleBits.exponent(dMax) + 1;
+    return level;
+  }
+
+  // the fields which make up the key
+  private Coordinate pt = new Coordinate();
+  private int level = 0;
+  // auxiliary data which is derived from the key for use in computation
+  private Envelope env = null;
+
+  public Key(Envelope itemEnv)
+  {
+    computeKey(itemEnv);
+  }
+
+  public int getLevel() { return level; }
+  public Envelope getEnvelope() { return env; }
+
+  /**
+   * return a square envelope containing the argument envelope,
+   * whose extent is a power of two and which is based at a power of 2
+   */
+  public void computeKey(Envelope itemEnv)
+  {
+    level = computeQuadLevel(itemEnv);
+    env = new Envelope();
+    computeKey(level, itemEnv);
+    // MD - would be nice to have a non-iterative form of this algorithm
+    while (! env.contains(itemEnv)) {
+      level += 1;
+      computeKey(level, itemEnv);
+    }
+  }
+
+  private void computeKey(int level, Envelope itemEnv)
+  {
+    double quadSize = DoubleBits.powerOf2(level);
+    pt.x = Math.floor(itemEnv.getMinX() / quadSize) * quadSize;
+    pt.y = Math.floor(itemEnv.getMinY() / quadSize) * quadSize;
+    env.init(pt.x, pt.x + quadSize, pt.y, pt.y + quadSize);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/Node.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/Node.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/Node.java	(revision 28000)
@@ -0,0 +1,198 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.quadtree;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * Represents a node of a {@link Quadtree}.  Nodes contain
+ * items which have a spatial extent corresponding to the node's position
+ * in the quadtree.
+ *
+ * @version 1.7
+ */
+public class Node
+  extends NodeBase
+{
+  public static Node createNode(Envelope env)
+  {
+    Key key = new Key(env);
+    Node node = new Node(key.getEnvelope(), key.getLevel());
+    return node;
+  }
+
+  public static Node createExpanded(Node node, Envelope addEnv)
+  {
+    Envelope expandEnv = new Envelope(addEnv);
+    if (node != null) expandEnv.expandToInclude(node.env);
+
+    Node largerNode = createNode(expandEnv);
+    if (node != null) largerNode.insertNode(node);
+    return largerNode;
+  }
+
+  private Envelope env;
+  private Coordinate centre;
+  private int level;
+
+  public Node(Envelope env, int level)
+  {
+    //this.parent = parent;
+    this.env = env;
+    this.level = level;
+    centre = new Coordinate();
+    centre.x = (env.getMinX() + env.getMaxX()) / 2;
+    centre.y = (env.getMinY() + env.getMaxY()) / 2;
+  }
+
+  public Envelope getEnvelope() { return env; }
+
+  protected boolean isSearchMatch(Envelope searchEnv)
+  {
+    return env.intersects(searchEnv);
+  }
+
+  /**
+   * Returns the subquad containing the envelope.
+   * Creates the subquad if
+   * it does not already exist.
+   */
+  public Node getNode(Envelope searchEnv)
+  {
+    int subnodeIndex = getSubnodeIndex(searchEnv, centre);
+    // if subquadIndex is -1 searchEnv is not contained in a subquad
+    if (subnodeIndex != -1) {
+      // create the quad if it does not exist
+      Node node = getSubnode(subnodeIndex);
+      // recursively search the found/created quad
+      return node.getNode(searchEnv);
+    }
+    else {
+      return this;
+    }
+  }
+
+  /**
+   * Returns the smallest <i>existing</i>
+   * node containing the envelope.
+   */
+  public NodeBase find(Envelope searchEnv)
+  {
+    int subnodeIndex = getSubnodeIndex(searchEnv, centre);
+    if (subnodeIndex == -1)
+      return this;
+    if (subnode[subnodeIndex] != null) {
+      // query lies in subquad, so search it
+      Node node = subnode[subnodeIndex];
+      return node.find(searchEnv);
+    }
+    // no existing subquad, so return this one anyway
+    return this;
+  }
+
+  void insertNode(Node node)
+  {
+    Assert.isTrue(env == null || env.contains(node.env));
+//System.out.println(env);
+//System.out.println(quad.env);
+    int index = getSubnodeIndex(node.env, centre);
+//System.out.println(index);
+    if (node.level == level - 1) {
+      subnode[index] = node;
+//System.out.println("inserted");
+    }
+    else {
+      // the quad is not a direct child, so make a new child quad to contain it
+      // and recursively insert the quad
+      Node childNode = createSubnode(index);
+      childNode.insertNode(node);
+      subnode[index] = childNode;
+    }
+  }
+
+  /**
+   * get the subquad for the index.
+   * If it doesn't exist, create it
+   */
+  private Node getSubnode(int index)
+  {
+    if (subnode[index] == null) {
+      subnode[index] = createSubnode(index);
+    }
+    return subnode[index];
+  }
+
+  private Node createSubnode(int index)
+  {
+        // create a new subquad in the appropriate quadrant
+
+      double minx = 0.0;
+      double maxx = 0.0;
+      double miny = 0.0;
+      double maxy = 0.0;
+
+      switch (index) {
+      case 0:
+        minx = env.getMinX();
+        maxx = centre.x;
+        miny = env.getMinY();
+        maxy = centre.y;
+        break;
+      case 1:
+        minx = centre.x;
+        maxx = env.getMaxX();
+        miny = env.getMinY();
+        maxy = centre.y;
+        break;
+      case 2:
+        minx = env.getMinX();
+        maxx = centre.x;
+        miny = centre.y;
+        maxy = env.getMaxY();
+        break;
+      case 3:
+        minx = centre.x;
+        maxx = env.getMaxX();
+        miny = centre.y;
+        maxy = env.getMaxY();
+        break;
+      }
+      Envelope sqEnv = new Envelope(minx, maxx, miny, maxy);
+      Node node = new Node(sqEnv, level - 1);
+    return node;
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/NodeBase.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/NodeBase.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/NodeBase.java	(revision 28000)
@@ -0,0 +1,175 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.quadtree;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.index.ItemVisitor;
+
+/**
+ * The base class for nodes in a {@link Quadtree}.
+ *
+ * @version 1.7
+ */
+public abstract class NodeBase {
+
+//<<TODO:REFACTOR?>> Several classes in the various tree packages have the
+//same name and duplicate code. This suggests that there should be a generic
+//tree package containing the code that is duplicated, perhaps in abstract
+//base classes. [Jon Aquino]
+
+//<<TODO:RENAME?>> This little class hierarchy has some naming/conceptual
+//problems. A root node is conceptually a kind of node, yet a Root is not a Node.
+//NodeBase begs to be called BaseNode, but not all BaseNodes would be Nodes
+//(for example, Root). [Jon Aquino]
+
+//DEBUG private static int itemCount = 0;  // debugging
+  /**
+   * Returns the index of the subquad that wholly contains the given envelope.
+   * If none does, returns -1.
+   */
+  public static int getSubnodeIndex(Envelope env, Coordinate centre)
+  {
+    int subnodeIndex = -1;
+    if (env.getMinX() >= centre.x) {
+      if (env.getMinY() >= centre.y) subnodeIndex = 3;
+      if (env.getMaxY() <= centre.y) subnodeIndex = 1;
+    }
+    if (env.getMaxX() <= centre.x) {
+      if (env.getMinY() >= centre.y) subnodeIndex = 2;
+      if (env.getMaxY() <= centre.y) subnodeIndex = 0;
+    }
+    return subnodeIndex;
+  }
+
+  protected List items = new ArrayList();
+
+  /**
+   * subquads are numbered as follows:
+   * <pre>
+   *  2 | 3
+   *  --+--
+   *  0 | 1
+   * </pre>
+   */
+  protected Node[] subnode = new Node[4];
+
+  public NodeBase() {
+  }
+
+  public boolean hasItems() { return ! items.isEmpty(); }
+
+  public void add(Object item)
+  {
+    items.add(item);
+//DEBUG itemCount++;
+//DEBUG System.out.print(itemCount);
+  }
+
+  /**
+   * Removes a single item from this subtree.
+   *
+   * @param itemEnv the envelope containing the item
+   * @param item the item to remove
+   * @return <code>true</code> if the item was found and removed
+   */
+  public boolean remove(Envelope itemEnv, Object item)
+  {
+    // use envelope to restrict nodes scanned
+    if (! isSearchMatch(itemEnv))
+      return false;
+
+    boolean found = false;
+    for (int i = 0; i < 4; i++) {
+      if (subnode[i] != null) {
+        found = subnode[i].remove(itemEnv, item);
+        if (found) {
+          // trim subtree if empty
+          if (subnode[i].isPrunable())
+            subnode[i] = null;
+          break;
+        }
+      }
+    }
+    // if item was found lower down, don't need to search for it here
+    if (found) return found;
+    // otherwise, try and remove the item from the list of items in this node
+    found = items.remove(item);
+    return found;
+  }
+
+  public boolean isPrunable()
+  {
+    return ! (hasChildren() || hasItems());
+  }
+
+  public boolean hasChildren()
+  {
+    for (int i = 0; i < 4; i++) {
+      if (subnode[i] != null)
+        return true;
+    }
+    return false;
+  }
+
+  protected abstract boolean isSearchMatch(Envelope searchEnv);
+
+  public void visit(Envelope searchEnv, ItemVisitor visitor)
+  {
+    if (! isSearchMatch(searchEnv))
+      return;
+
+    // this node may have items as well as subnodes (since items may not
+    // be wholely contained in any single subnode
+    visitItems(visitor);
+
+    for (int i = 0; i < 4; i++) {
+      if (subnode[i] != null) {
+        subnode[i].visit(searchEnv, visitor);
+      }
+    }
+  }
+
+  private void visitItems(ItemVisitor visitor)
+  {
+    // would be nice to filter items based on search envelope, but can't until they contain an envelope
+    for (Iterator i = items.iterator(); i.hasNext(); ) {
+      visitor.visitItem(i.next());
+    }
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/Quadtree.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/Quadtree.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/Quadtree.java	(revision 28000)
@@ -0,0 +1,211 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.quadtree;
+
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.index.ArrayListVisitor;
+import com.vividsolutions.jts.index.ItemVisitor;
+import com.vividsolutions.jts.index.SpatialIndex;
+/**
+ * A Quadtree is a spatial index structure for efficient querying
+ * of 2D rectangles.  If other kinds of spatial objects
+ * need to be indexed they can be represented by their
+ * envelopes
+ * <p>
+ * The quadtree structure is used to provide a primary filter
+ * for range rectangle queries.  The query() method returns a list of
+ * all objects which <i>may</i> intersect the query rectangle.  Note that
+ * it may return objects which do not in fact intersect.
+ * A secondary filter is required to test for exact intersection.
+ * Of course, this secondary filter may consist of other tests besides
+ * intersection, such as testing other kinds of spatial relationships.
+ *
+ * <p>
+ * This implementation does not require specifying the extent of the inserted
+ * items beforehand.  It will automatically expand to accomodate any extent
+ * of dataset.
+ * <p>
+ * This data structure is also known as an <i>MX-CIF quadtree</i>
+ * following the usage of Samet and others.
+ *
+ * @version 1.7
+ */
+public class Quadtree
+    implements SpatialIndex
+{
+  /**
+   * Ensure that the envelope for the inserted item has non-zero extents.
+   * Use the current minExtent to pad the envelope, if necessary
+   */
+  public static Envelope ensureExtent(Envelope itemEnv, double minExtent)
+  {
+    //The names "ensureExtent" and "minExtent" are misleading -- sounds like
+    //this method ensures that the extents are greater than minExtent.
+    //Perhaps we should rename them to "ensurePositiveExtent" and "defaultExtent".
+    //[Jon Aquino]
+    double minx = itemEnv.getMinX();
+    double maxx = itemEnv.getMaxX();
+    double miny = itemEnv.getMinY();
+    double maxy = itemEnv.getMaxY();
+    // has a non-zero extent
+    if (minx != maxx && miny != maxy) return itemEnv;
+
+    // pad one or both extents
+    if (minx == maxx) {
+      minx = minx - minExtent / 2.0;
+      maxx = minx + minExtent / 2.0;
+    }
+    if (miny == maxy) {
+      miny = miny - minExtent / 2.0;
+      maxy = miny + minExtent / 2.0;
+    }
+    return new Envelope(minx, maxx, miny, maxy);
+  }
+
+  private Root root;
+  /**
+
+  * minExtent is the minimum envelope extent of all items
+  * inserted into the tree so far. It is used as a heuristic value
+  * to construct non-zero envelopes for features with zero X and/or Y extent.
+  * Start with a non-zero extent, in case the first feature inserted has
+  * a zero extent in both directions.  This value may be non-optimal, but
+  * only one feature will be inserted with this value.
+  **/
+  private double minExtent = 1.0;
+
+  /**
+   * Constructs a Quadtree with zero items.
+   */
+  public Quadtree()
+  {
+    root = new Root();
+  }
+
+
+  public void insert(Envelope itemEnv, Object item)
+  {
+    collectStats(itemEnv);
+    Envelope insertEnv = ensureExtent(itemEnv, minExtent);
+    root.insert(insertEnv, item);
+  }
+
+  /**
+   * Removes a single item from the tree.
+   *
+   * @param itemEnv the Envelope of the item to be removed
+   * @param item the item to remove
+   * @return <code>true</code> if the item was found (and thus removed)
+   */
+  public boolean remove(Envelope itemEnv, Object item)
+  {
+    Envelope posEnv = ensureExtent(itemEnv, minExtent);
+    return root.remove(posEnv, item);
+  }
+
+/*
+  public List OLDquery(Envelope searchEnv)
+  {
+    /**
+     * the items that are matched are the items in quads which
+     * overlap the search envelope
+     */
+    /*
+    List foundItems = new ArrayList();
+    root.addAllItemsFromOverlapping(searchEnv, foundItems);
+    return foundItems;
+  }
+*/
+
+  /**
+   * Queries the tree and returns items which may lie in the given search envelope.
+   * Precisely, the items that are returned are all items in the tree 
+   * whose envelope <b>may</b> intersect the search Envelope.
+   * Note that some items with non-intersecting envelopes may be returned as well;
+   * the client is responsible for filtering these out.
+   * In most situations there will be many items in the tree which do not
+   * intersect the search envelope and which are not returned - thus
+   * providing improved performance over a simple linear scan.    
+   * 
+   * @param searchEnv the envelope of the desired query area.
+   * @return a List of items which may intersect the search envelope
+   */
+  public List query(Envelope searchEnv)
+  {
+    /**
+     * the items that are matched are the items in quads which
+     * overlap the search envelope
+     */
+    ArrayListVisitor visitor = new ArrayListVisitor();
+    query(searchEnv, visitor);
+    return visitor.getItems();
+  }
+
+  /**
+   * Queries the tree and visits items which may lie in the given search envelope.
+   * Precisely, the items that are visited are all items in the tree 
+   * whose envelope <b>may</b> intersect the search Envelope.
+   * Note that some items with non-intersecting envelopes may be visited as well;
+   * the client is responsible for filtering these out.
+   * In most situations there will be many items in the tree which do not
+   * intersect the search envelope and which are not visited - thus
+   * providing improved performance over a simple linear scan.    
+   * 
+   * @param searchEnv the envelope of the desired query area.
+   * @param visitor a visitor object which is passed the visited items
+   */
+  public void query(Envelope searchEnv, ItemVisitor visitor)
+  {
+    /**
+     * the items that are matched are the items in quads which
+     * overlap the search envelope
+     */
+    root.visit(searchEnv, visitor);
+  }
+
+
+  private void collectStats(Envelope itemEnv)
+  {
+    double delX = itemEnv.getWidth();
+    if (delX < minExtent && delX > 0.0)
+      minExtent = delX;
+
+    double delY = itemEnv.getHeight();
+    if (delY < minExtent && delY > 0.0)
+      minExtent = delY;
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/Root.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/Root.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/Root.java	(revision 28000)
@@ -0,0 +1,120 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.quadtree;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * QuadRoot is the root of a single Quadtree.  It is centred at the origin,
+ * and does not have a defined extent.
+ *
+ * @version 1.7
+ */
+public class Root
+  extends NodeBase
+{
+
+  // the singleton root quad is centred at the origin.
+  private static final Coordinate origin = new Coordinate(0.0, 0.0);
+
+  public Root()
+  {
+  }
+
+  /**
+   * Insert an item into the quadtree this is the root of.
+   */
+  public void insert(Envelope itemEnv, Object item)
+  {
+    int index = getSubnodeIndex(itemEnv, origin);
+    // if index is -1, itemEnv must cross the X or Y axis.
+    if (index == -1) {
+      add(item);
+      return;
+    }
+    /**
+     * the item must be contained in one quadrant, so insert it into the
+     * tree for that quadrant (which may not yet exist)
+     */
+    Node node = subnode[index];
+    /**
+     *  If the subquad doesn't exist or this item is not contained in it,
+     *  have to expand the tree upward to contain the item.
+     */
+
+    if (node == null || ! node.getEnvelope().contains(itemEnv)) {
+       Node largerNode = Node.createExpanded(node, itemEnv);
+       subnode[index] = largerNode;
+    }
+    /**
+     * At this point we have a subquad which exists and must contain
+     * contains the env for the item.  Insert the item into the tree.
+     */
+    insertContained(subnode[index], itemEnv, item);
+    //System.out.println("depth = " + root.depth() + " size = " + root.size());
+    //System.out.println(" size = " + size());
+  }
+
+  /**
+   * insert an item which is known to be contained in the tree rooted at
+   * the given QuadNode root.  Lower levels of the tree will be created
+   * if necessary to hold the item.
+   */
+  private void insertContained(Node tree, Envelope itemEnv, Object item)
+  {
+    Assert.isTrue(tree.getEnvelope().contains(itemEnv));
+   /**
+    * Do NOT create a new quad for zero-area envelopes - this would lead
+    * to infinite recursion. Instead, use a heuristic of simply returning
+    * the smallest existing quad containing the query
+    */
+    boolean isZeroX = IntervalSize.isZeroWidth(itemEnv.getMinX(), itemEnv.getMaxX());
+    boolean isZeroY = IntervalSize.isZeroWidth(itemEnv.getMinY(), itemEnv.getMaxY());
+    NodeBase node;
+    if (isZeroX || isZeroY)
+      node = tree.find(itemEnv);
+    else
+      node = tree.getNode(itemEnv);
+    node.add(item);
+  }
+
+  protected boolean isSearchMatch(Envelope searchEnv)
+  {
+    return true;
+  }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/quadtree/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Contains classes that implement a Quadtree spatial index
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/AbstractNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/AbstractNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/AbstractNode.java	(revision 28000)
@@ -0,0 +1,94 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.strtree;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * A node of the STR tree. The children of this node are either more nodes
+ * (AbstractNodes) or real data (ItemBoundables). If this node contains real data
+ * (rather than nodes), then we say that this node is a "leaf node".
+ *
+ * @version 1.7
+ */
+public abstract class AbstractNode implements Boundable {
+  private ArrayList childBoundables = new ArrayList();
+  private Object bounds = null;
+
+  /**
+   * Constructs an AbstractNode at the given level in the tree
+   * @param level 0 if this node is a leaf, 1 if a parent of a leaf, and so on; the
+   * root node will have the highest level
+   */
+  public AbstractNode() {
+  }
+
+  /**
+   * Returns either child {@link AbstractNode}s, or if this is a leaf node, real data (wrapped
+   * in {@link ItemBoundable}s).
+   */
+  public List getChildBoundables() {
+    return childBoundables;
+  }
+
+  /**
+   * Returns a representation of space that encloses this Boundable,
+   * preferably not much bigger than this Boundable's boundary yet fast to
+   * test for intersection with the bounds of other Boundables. The class of
+   * object returned depends on the subclass of AbstractSTRtree.
+   *
+   * @return an Envelope (for STRtrees), an Interval (for SIRtrees), or other
+   *         object (for other subclasses of AbstractSTRtree)
+   * @see AbstractSTRtree.IntersectsOp
+   */
+  protected abstract Object computeBounds();
+
+  public Object getBounds() {
+    if (bounds == null) {
+      bounds = computeBounds();
+    }
+    return bounds;
+  }
+
+  /**
+   * Adds either an AbstractNode, or if this is a leaf node, a data object
+   * (wrapped in an ItemBoundable)
+   */
+  public void addChildBoundable(Boundable childBoundable) {
+    Assert.isTrue(bounds == null);
+    childBoundables.add(childBoundable);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/AbstractSTRtree.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/AbstractSTRtree.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/AbstractSTRtree.java	(revision 28000)
@@ -0,0 +1,349 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.strtree;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.index.ItemVisitor;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * Base class for STRtree and SIRtree. STR-packed R-trees are described in:
+ * P. Rigaux, Michel Scholl and Agnes Voisard. Spatial Databases With
+ * Application To GIS. Morgan Kaufmann, San Francisco, 2002.
+ * <p>
+ * This implementation is based on Boundables rather than just AbstractNodes,
+ * because the STR algorithm operates on both nodes and
+ * data, both of which are treated here as Boundables.
+ *
+ * @see STRtree
+ * @see SIRtree
+ *
+ * @version 1.7
+ */
+public abstract class AbstractSTRtree {
+
+  /**
+   * A test for intersection between two bounds, necessary because subclasses
+   * of AbstractSTRtree have different implementations of bounds.
+   */
+  protected static interface IntersectsOp {
+    /**
+     * For STRtrees, the bounds will be Envelopes; for SIRtrees, Intervals;
+     * for other subclasses of AbstractSTRtree, some other class.
+     * @param aBounds the bounds of one spatial object
+     * @param bBounds the bounds of another spatial object
+     * @return whether the two bounds intersect
+     */
+    boolean intersects(Object aBounds, Object bBounds);
+  }
+
+  protected AbstractNode root;
+
+  private boolean built = false;
+  private ArrayList itemBoundables = new ArrayList();
+  private int nodeCapacity;
+
+  /**
+   * Constructs an AbstractSTRtree with the specified maximum number of child
+   * nodes that a node may have
+   */
+  public AbstractSTRtree(int nodeCapacity) {
+    Assert.isTrue(nodeCapacity > 1, "Node capacity must be greater than 1");
+    this.nodeCapacity = nodeCapacity;
+  }
+
+  /**
+   * Creates parent nodes, grandparent nodes, and so forth up to the root
+   * node, for the data that has been inserted into the tree. Can only be
+   * called once, and thus can be called only after all of the data has been
+   * inserted into the tree.
+   */
+  public void build() {
+    Assert.isTrue(!built);
+    root = itemBoundables.isEmpty()
+           ?createNode(0)
+           :createHigherLevels(itemBoundables, -1);
+    built = true;
+  }
+
+  protected abstract AbstractNode createNode(int level);
+
+  /**
+   * Sorts the childBoundables then divides them into groups of size M, where
+   * M is the node capacity.
+   */
+  protected List createParentBoundables(List childBoundables, int newLevel) {
+    Assert.isTrue(!childBoundables.isEmpty());
+    ArrayList parentBoundables = new ArrayList();
+    parentBoundables.add(createNode(newLevel));
+    ArrayList sortedChildBoundables = new ArrayList(childBoundables);
+    Collections.sort(sortedChildBoundables, getComparator());
+    for (Iterator i = sortedChildBoundables.iterator(); i.hasNext(); ) {
+      Boundable childBoundable = (Boundable) i.next();
+      if (lastNode(parentBoundables).getChildBoundables().size() == getNodeCapacity()) {
+        parentBoundables.add(createNode(newLevel));
+      }
+      lastNode(parentBoundables).addChildBoundable(childBoundable);
+    }
+    return parentBoundables;
+  }
+
+  protected AbstractNode lastNode(List nodes) {
+    return (AbstractNode) nodes.get(nodes.size() - 1);
+  }
+
+  protected int compareDoubles(double a, double b) {
+    return a > b ? 1
+         : a < b ? -1
+         : 0;
+  }
+
+  /**
+   * Creates the levels higher than the given level
+   *
+   * @param boundablesOfALevel
+   *            the level to build on
+   * @param level
+   *            the level of the Boundables, or -1 if the boundables are item
+   *            boundables (that is, below level 0)
+   * @return the root, which may be a ParentNode or a LeafNode
+   */
+  private AbstractNode createHigherLevels(List boundablesOfALevel, int level) {
+    Assert.isTrue(!boundablesOfALevel.isEmpty());
+    List parentBoundables = createParentBoundables(boundablesOfALevel, level + 1);
+    if (parentBoundables.size() == 1) {
+      return (AbstractNode) parentBoundables.get(0);
+    }
+    return createHigherLevels(parentBoundables, level + 1);
+  }
+
+  /**
+   * Returns the maximum number of child nodes that a node may have
+   */
+  public int getNodeCapacity() { return nodeCapacity; }
+
+  protected int size() {
+    if (!built) { build(); }
+    if (itemBoundables.isEmpty()) {
+      return 0;
+    }
+    return size(root);
+  }
+
+  protected int size(AbstractNode node)
+  {
+    int size = 0;
+    for (Iterator i = node.getChildBoundables().iterator(); i.hasNext(); ) {
+      Boundable childBoundable = (Boundable) i.next();
+      if (childBoundable instanceof AbstractNode) {
+        size += size((AbstractNode) childBoundable);
+      }
+      else if (childBoundable instanceof ItemBoundable) {
+        size += 1;
+      }
+    }
+    return size;
+  }
+
+  protected int depth() {
+    if (!built) { build(); }
+    if (itemBoundables.isEmpty()) {
+      return 0;
+    }
+    return depth(root);
+  }
+
+  protected int depth(AbstractNode node)
+  {
+    int maxChildDepth = 0;
+    for (Iterator i = node.getChildBoundables().iterator(); i.hasNext(); ) {
+      Boundable childBoundable = (Boundable) i.next();
+      if (childBoundable instanceof AbstractNode) {
+        int childDepth = depth((AbstractNode) childBoundable);
+        if (childDepth > maxChildDepth)
+          maxChildDepth = childDepth;
+      }
+    }
+    return maxChildDepth + 1;
+  }
+
+
+  protected void insert(Object bounds, Object item) {
+    Assert.isTrue(!built, "Cannot insert items into an STR packed R-tree after it has been built.");
+    itemBoundables.add(new ItemBoundable(bounds, item));
+  }
+
+  /**
+   *  Also builds the tree, if necessary.
+   */
+  protected List query(Object searchBounds) {
+    if (!built) { build(); }
+    ArrayList matches = new ArrayList();
+    if (itemBoundables.isEmpty()) {
+      Assert.isTrue(root.getBounds() == null);
+      return matches;
+    }
+    if (getIntersectsOp().intersects(root.getBounds(), searchBounds)) {
+      query(searchBounds, root, matches);
+    }
+    return matches;
+  }
+
+  /**
+   *  Also builds the tree, if necessary.
+   */
+  protected void query(Object searchBounds, ItemVisitor visitor) {
+    if (!built) { build(); }
+    if (itemBoundables.isEmpty()) {
+      Assert.isTrue(root.getBounds() == null);
+    }
+    if (getIntersectsOp().intersects(root.getBounds(), searchBounds)) {
+      query(searchBounds, root, visitor);
+    }
+  }
+
+  /**
+   * @return a test for intersection between two bounds, necessary because subclasses
+   * of AbstractSTRtree have different implementations of bounds.
+   * @see IntersectsOp
+   */
+  protected abstract IntersectsOp getIntersectsOp();
+
+  private void query(Object searchBounds, AbstractNode node, List matches) {
+    for (Iterator i = node.getChildBoundables().iterator(); i.hasNext(); ) {
+      Boundable childBoundable = (Boundable) i.next();
+      if (!getIntersectsOp().intersects(childBoundable.getBounds(), searchBounds)) {
+        continue;
+      }
+      if (childBoundable instanceof AbstractNode) {
+        query(searchBounds, (AbstractNode) childBoundable, matches);
+      }
+      else if (childBoundable instanceof ItemBoundable) {
+        matches.add(((ItemBoundable)childBoundable).getItem());
+      }
+      else {
+        Assert.shouldNeverReachHere();
+      }
+    }
+  }
+
+  private void query(Object searchBounds, AbstractNode node, ItemVisitor visitor) {
+    for (Iterator i = node.getChildBoundables().iterator(); i.hasNext(); ) {
+      Boundable childBoundable = (Boundable) i.next();
+      if (!getIntersectsOp().intersects(childBoundable.getBounds(), searchBounds)) {
+        continue;
+      }
+      if (childBoundable instanceof AbstractNode) {
+        query(searchBounds, (AbstractNode) childBoundable, visitor);
+      }
+      else if (childBoundable instanceof ItemBoundable) {
+        visitor.visitItem(((ItemBoundable)childBoundable).getItem());
+      }
+      else {
+        Assert.shouldNeverReachHere();
+      }
+    }
+  }
+
+  /**
+   * Removes an item from the tree.
+   * (Builds the tree, if necessary.)
+   */
+  protected boolean remove(Object searchBounds, Object item) {
+    if (!built) { build(); }
+    if (itemBoundables.isEmpty()) {
+      Assert.isTrue(root.getBounds() == null);
+    }
+    if (getIntersectsOp().intersects(root.getBounds(), searchBounds)) {
+      return remove(searchBounds, root, item);
+    }
+    return false;
+  }
+
+  private boolean removeItem(AbstractNode node, Object item)
+  {
+    Boundable childToRemove = null;
+    for (Iterator i = node.getChildBoundables().iterator(); i.hasNext(); ) {
+      Boundable childBoundable = (Boundable) i.next();
+      if (childBoundable instanceof ItemBoundable) {
+        if ( ((ItemBoundable) childBoundable).getItem() == item)
+          childToRemove = childBoundable;
+      }
+    }
+    if (childToRemove != null) {
+      node.getChildBoundables().remove(childToRemove);
+      return true;
+    }
+    return false;
+  }
+
+  private boolean remove(Object searchBounds, AbstractNode node, Object item) {
+    // first try removing item from this node
+    boolean found = removeItem(node, item);
+    if (found)
+      return true;
+
+    AbstractNode childToPrune = null;
+    // next try removing item from lower nodes
+    for (Iterator i = node.getChildBoundables().iterator(); i.hasNext(); ) {
+      Boundable childBoundable = (Boundable) i.next();
+      if (!getIntersectsOp().intersects(childBoundable.getBounds(), searchBounds)) {
+        continue;
+      }
+      if (childBoundable instanceof AbstractNode) {
+        found = remove(searchBounds, (AbstractNode) childBoundable, item);
+        // if found, record child for pruning and exit
+        if (found) {
+          childToPrune = (AbstractNode) childBoundable;
+          break;
+        }
+      }
+    }
+    // prune child if possible
+    if (childToPrune != null) {
+      if (childToPrune.getChildBoundables().isEmpty()) {
+        node.getChildBoundables().remove(childToPrune);
+      }
+    }
+    return found;
+  }
+
+  protected abstract Comparator getComparator();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/Boundable.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/Boundable.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/Boundable.java	(revision 28000)
@@ -0,0 +1,52 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.strtree;
+
+/**
+ * A spatial object in an AbstractSTRtree.
+ *
+ * @version 1.7
+ */
+public interface Boundable {
+  /**
+   * Returns a representation of space that encloses this Boundable, preferably
+   * not much bigger than this Boundable's boundary yet fast to test for intersection
+   * with the bounds of other Boundables. The class of object returned depends
+   * on the subclass of AbstractSTRtree.
+   * @return an Envelope (for STRtrees), an Interval (for SIRtrees), or other object
+   * (for other subclasses of AbstractSTRtree)
+   * @see AbstractSTRtree.IntersectsOp
+   */
+  Object getBounds();
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/ItemBoundable.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/ItemBoundable.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/ItemBoundable.java	(revision 28000)
@@ -0,0 +1,56 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.strtree;
+
+/**
+ * Boundable wrapper for a non-Boundable spatial object. Used internally by
+ * AbstractSTRtree.
+ *
+ * @version 1.7
+ */
+public class ItemBoundable implements Boundable {
+  private Object bounds;
+  private Object item;
+
+  public ItemBoundable(Object bounds, Object item) {
+    this.bounds = bounds;
+    this.item = item;
+  }
+
+  public Object getBounds() {
+    return bounds;
+  }
+
+  public Object getItem() { return item; }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/STRtree.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/STRtree.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/STRtree.java	(revision 28000)
@@ -0,0 +1,250 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.index.strtree;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.index.ItemVisitor;
+import com.vividsolutions.jts.index.SpatialIndex;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ *  A query-only R-tree created using the Sort-Tile-Recursive (STR) algorithm.
+ *  For two-dimensional spatial data.
+ * <P>
+ *  The STR packed R-tree is simple to implement and maximizes space
+ *  utilization; that is, as many leaves as possible are filled to capacity.
+ *  Overlap between nodes is far less than in a basic R-tree. However, once the
+ *  tree has been built (explicitly or on the first call to #query), items may
+ *  not be added or removed.
+ * <P>
+ * Described in: P. Rigaux, Michel Scholl and Agnes Voisard.
+ * <i>Spatial Databases With Application To GIS</i>.
+ * Morgan Kaufmann, San Francisco, 2002.
+ *
+ * @version 1.7
+ */
+public class STRtree extends AbstractSTRtree implements SpatialIndex {
+
+  private Comparator xComparator =
+    new Comparator() {
+      public int compare(Object o1, Object o2) {
+        return compareDoubles(
+            centreX((Envelope)((Boundable)o1).getBounds()),
+            centreX((Envelope)((Boundable)o2).getBounds()));
+      }
+    };
+  private Comparator yComparator =
+    new Comparator() {
+      public int compare(Object o1, Object o2) {
+        return compareDoubles(
+            centreY((Envelope)((Boundable)o1).getBounds()),
+            centreY((Envelope)((Boundable)o2).getBounds()));
+      }
+    };
+
+  private double centreX(Envelope e) {
+    return avg(e.getMinX(), e.getMaxX());
+  }
+
+  private double avg(double a, double b) { return (a + b) / 2d; }
+
+  private double centreY(Envelope e) {
+    return avg(e.getMinY(), e.getMaxY());
+  }
+
+  private IntersectsOp intersectsOp = new IntersectsOp() {
+    public boolean intersects(Object aBounds, Object bBounds) {
+      return ((Envelope)aBounds).intersects((Envelope)bBounds);
+    }
+  };
+
+  /**
+   * Creates the parent level for the given child level. First, orders the items
+   * by the x-values of the midpoints, and groups them into vertical slices.
+   * For each slice, orders the items by the y-values of the midpoints, and
+   * group them into runs of size M (the node capacity). For each run, creates
+   * a new (parent) node.
+   */
+  protected List createParentBoundables(List childBoundables, int newLevel) {
+    Assert.isTrue(!childBoundables.isEmpty());
+    int minLeafCount = (int) Math.ceil((childBoundables.size() / (double) getNodeCapacity()));
+    ArrayList sortedChildBoundables = new ArrayList(childBoundables);
+    Collections.sort(sortedChildBoundables, xComparator);
+    List[] verticalSlices = verticalSlices(sortedChildBoundables,
+        (int) Math.ceil(Math.sqrt(minLeafCount)));
+    return createParentBoundablesFromVerticalSlices(verticalSlices, newLevel);
+  }
+
+  private List createParentBoundablesFromVerticalSlices(List[] verticalSlices, int newLevel) {
+    Assert.isTrue(verticalSlices.length > 0);
+    List parentBoundables = new ArrayList();
+    for (int i = 0; i < verticalSlices.length; i++) {
+      parentBoundables.addAll(
+            createParentBoundablesFromVerticalSlice(verticalSlices[i], newLevel));
+    }
+    return parentBoundables;
+  }
+
+  protected List createParentBoundablesFromVerticalSlice(List childBoundables, int newLevel) {
+    return super.createParentBoundables(childBoundables, newLevel);
+  }
+
+  /**
+   * @param childBoundables Must be sorted by the x-value of the envelope midpoints
+   */
+  protected List[] verticalSlices(List childBoundables, int sliceCount) {
+    int sliceCapacity = (int) Math.ceil(childBoundables.size() / (double) sliceCount);
+    List[] slices = new List[sliceCount];
+    Iterator i = childBoundables.iterator();
+    for (int j = 0; j < sliceCount; j++) {
+      slices[j] = new ArrayList();
+      int boundablesAddedToSlice = 0;
+      while (i.hasNext() && boundablesAddedToSlice < sliceCapacity) {
+        Boundable childBoundable = (Boundable) i.next();
+        slices[j].add(childBoundable);
+        boundablesAddedToSlice++;
+      }
+    }
+    return slices;
+  }
+
+  private static final int DEFAULT_NODE_CAPACITY = 10;
+  /**
+   * Constructs an STRtree with the default node capacity.
+   */
+  public STRtree() 
+  { 
+    this(DEFAULT_NODE_CAPACITY); 
+  }
+
+  /**
+   * Constructs an STRtree with the given maximum number of child nodes that
+   * a node may have.
+   * <p>
+   * The minimum recommended capacity setting is 4.
+   * 
+   */
+  public STRtree(int nodeCapacity) {
+    super(nodeCapacity);
+  }
+
+  protected AbstractNode createNode(int level) {
+    return new AbstractNode() {
+      protected Object computeBounds() {
+        Envelope bounds = null;
+        for (Iterator i = getChildBoundables().iterator(); i.hasNext(); ) {
+          Boundable childBoundable = (Boundable) i.next();
+          if (bounds == null) {
+            bounds = new Envelope((Envelope)childBoundable.getBounds());
+          }
+          else {
+            bounds.expandToInclude((Envelope)childBoundable.getBounds());
+          }
+        }
+        return bounds;
+      }
+    };
+  }
+
+  protected IntersectsOp getIntersectsOp() {
+    return intersectsOp;
+  }
+
+  /**
+   * Inserts an item having the given bounds into the tree.
+   */
+  public void insert(Envelope itemEnv, Object item) {
+    if (itemEnv.isNull()) { return; }
+    super.insert(itemEnv, item);
+  }
+
+  /**
+   * Returns items whose bounds intersect the given envelope.
+   */
+  public List query(Envelope searchEnv) {
+    //Yes this method does something. It specifies that the bounds is an
+    //Envelope. super.query takes an Object, not an Envelope. [Jon Aquino 10/24/2003]
+    return super.query(searchEnv);
+  }
+
+  /**
+   * Returns items whose bounds intersect the given envelope.
+   */
+  public void query(Envelope searchEnv, ItemVisitor visitor) {
+    //Yes this method does something. It specifies that the bounds is an
+    //Envelope. super.query takes an Object, not an Envelope. [Jon Aquino 10/24/2003]
+    super.query(searchEnv, visitor);
+  }
+
+  /**
+   * Removes a single item from the tree.
+   *
+   * @param itemEnv the Envelope of the item to remove
+   * @param item the item to remove
+   * @return <code>true</code> if the item was found
+   */
+  public boolean remove(Envelope itemEnv, Object item) {
+    return super.remove(itemEnv, item);
+  }
+
+  /**
+   * Returns the number of items in the tree.
+   *
+   * @return the number of items in the tree
+   */
+  public int size()
+  {
+    return super.size();
+  }
+
+  /**
+   * Returns the number of items in the tree.
+   *
+   * @return the number of items in the tree
+   */
+  public int depth()
+  {
+    return super.depth();
+  }
+
+  protected Comparator getComparator() {
+    return yComparator;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/index/strtree/package.html	(revision 28000)
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+Contains 2-D and 1-D versions of the Sort-Tile-Recursive (STR) tree, a query-only R-tree.
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/io/WKTWriter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/io/WKTWriter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/io/WKTWriter.java	(revision 28000)
@@ -0,0 +1,604 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.io;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.MultiLineString;
+import com.vividsolutions.jts.geom.MultiPoint;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geom.PrecisionModel;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * Writes the Well-Known Text representation of a {@link Geometry}.
+ * The Well-Known Text format is defined in the
+ * OGC <A HREF="http://www.opengis.org/techno/specs.htm">
+ * <i>Simple Features Specification for SQL</i></A>.
+ * See {@link WKTReader} for a formal specification of the format syntax.
+ * <p>
+ * The <code>WKTWriter</code> outputs coordinates rounded to the precision
+ * model. Only the maximum number of decimal places 
+ * necessary to represent the ordinates to the required precision will be
+ * output.
+ * <p>
+ * The SFS WKT spec does not define a special tag for {@link LinearRing}s.
+ * Under the spec, rings are output as <code>LINESTRING</code>s.
+ * In order to allow precisely specifying constructed geometries, 
+ * JTS also supports a non-standard <code>LINEARRING</code> tag which is used 
+ * to output LinearRings.
+ *
+ * @version 1.7
+ * @see WKTReader
+ */
+public class WKTWriter
+{
+
+  /**
+   * Generates the WKT for a N-point <code>LineString</code>.
+   *
+   * @param seq the sequence to outpout
+   *
+   * @return the WKT
+   */
+  public static String toLineString(CoordinateSequence seq)
+  {
+    StringBuffer buf = new StringBuffer();
+    buf.append("LINESTRING ");
+    if (seq.size() == 0)
+      buf.append(" EMPTY");
+    else {
+      buf.append("(");
+      for (int i = 0; i < seq.size(); i++) {
+        if (i > 0)
+          buf.append(", ");
+        buf.append(seq.getX(i) + " " + seq.getY(i));
+      }
+      buf.append(")");
+    }
+    return buf.toString();
+  }
+
+  /**
+   * Generates the WKT for a 2-point <code>LineString</code>.
+   *
+   * @param p0 the first coordinate
+   * @param p1 the second coordinate
+   *
+   * @return the WKT
+   */
+  public static String toLineString(Coordinate p0, Coordinate p1)
+  {
+    return "LINESTRING ( " + p0.x + " " + p0.y + ", " + p1.x + " " + p1.y + " )";
+  }
+
+  /**
+   *  Creates the <code>DecimalFormat</code> used to write <code>double</code>s
+   *  with a sufficient number of decimal places.
+   *
+   *@param  precisionModel  the <code>PrecisionModel</code> used to determine
+   *      the number of decimal places to write.
+   *@return                 a <code>DecimalFormat</code> that write <code>double</code>
+   *      s without scientific notation.
+   */
+  private static DecimalFormat createFormatter(PrecisionModel precisionModel) {
+    // the default number of decimal places is 16, which is sufficient
+    // to accomodate the maximum precision of a double.
+    int decimalPlaces = precisionModel.getMaximumSignificantDigits();
+    // specify decimal separator explicitly to avoid problems in other locales
+    DecimalFormatSymbols symbols = new DecimalFormatSymbols();
+    symbols.setDecimalSeparator('.');
+    String fmtString = "0" + (decimalPlaces > 0 ? "." : "")
+                 +  stringOfChar('#', decimalPlaces);
+    return new DecimalFormat(fmtString, symbols);
+  }
+
+  /**
+   *  Returns a <code>String</code> of repeated characters.
+   *
+   *@param  ch     the character to repeat
+   *@param  count  the number of times to repeat the character
+   *@return        a <code>String</code> of characters
+   */
+  public static String stringOfChar(char ch, int count) {
+    StringBuffer buf = new StringBuffer();
+    for (int i = 0; i < count; i++) {
+      buf.append(ch);
+    }
+    return buf.toString();
+  }
+
+  private int outputDimension = 2;
+  private DecimalFormat formatter;
+  private boolean isFormatted = false;
+  private boolean useFormatting = false;
+  private int coordsPerLine = -1;
+  private String indentTabStr = "  ";
+
+  /**
+   * Creates a new WKTWriter with default settings
+   */
+  public WKTWriter()
+  {
+  }
+
+  /**
+   *  Converts a <code>Geometry</code> to its Well-known Text representation.
+   *
+   *@param  geometry  a <code>Geometry</code> to process
+   *@return           a <Geometry Tagged Text> string (see the OpenGIS Simple
+   *      Features Specification)
+   */
+  public String write(Geometry geometry)
+  {
+    Writer sw = new StringWriter();
+    try {
+      writeFormatted(geometry, isFormatted, sw);
+    }
+    catch (IOException ex) {
+      Assert.shouldNeverReachHere();
+    }
+    return sw.toString();
+  }
+
+  /**
+   *  Converts a <code>Geometry</code> to its Well-known Text representation.
+   *
+   *@param  geometry  a <code>Geometry</code> to process
+   *@return           a <Geometry Tagged Text> string (see the OpenGIS Simple
+   *      Features Specification)
+   */
+  private void writeFormatted(Geometry geometry, boolean useFormatting, Writer writer)
+    throws IOException
+  {
+    this.useFormatting = useFormatting;
+    formatter = createFormatter(geometry.getPrecisionModel());
+    appendGeometryTaggedText(geometry, 0, writer);
+  }
+
+
+  /**
+   *  Converts a <code>Geometry</code> to &lt;Geometry Tagged Text&gt; format,
+   *  then appends it to the writer.
+   *
+   *@param  geometry  the <code>Geometry</code> to process
+   *@param  writer    the output writer to append to
+   */
+  private void appendGeometryTaggedText(Geometry geometry, int level, Writer writer)
+    throws IOException
+  {
+    indent(level, writer);
+
+    if (geometry instanceof Point) {
+      Point point = (Point) geometry;
+      appendPointTaggedText(point.getCoordinate(), writer);
+    }
+    else if (geometry instanceof LinearRing) {
+      appendLinearRingTaggedText((LinearRing) geometry, level, writer);
+    }
+    else if (geometry instanceof LineString) {
+      appendLineStringTaggedText((LineString) geometry, level, writer);
+    }
+    else if (geometry instanceof Polygon) {
+      appendPolygonTaggedText((Polygon) geometry, level, writer);
+    }
+    else if (geometry instanceof MultiPoint) {
+      appendMultiPointTaggedText((MultiPoint) geometry, level, writer);
+    }
+    else if (geometry instanceof MultiLineString) {
+      appendMultiLineStringTaggedText((MultiLineString) geometry, level, writer);
+    }
+    else if (geometry instanceof MultiPolygon) {
+      appendMultiPolygonTaggedText((MultiPolygon) geometry, level, writer);
+    }
+    else if (geometry instanceof GeometryCollection) {
+      appendGeometryCollectionTaggedText((GeometryCollection) geometry, level, writer);
+    }
+    else {
+      Assert.shouldNeverReachHere("Unsupported Geometry implementation:"
+           + geometry.getClass());
+    }
+  }
+
+  /**
+   *  Converts a <code>Coordinate</code> to &lt;Point Tagged Text&gt; format,
+   *  then appends it to the writer.
+   *
+   *@param  coordinate      the <code>Coordinate</code> to process
+   *@param  writer          the output writer to append to
+   *@param  precisionModel  the <code>PrecisionModel</code> to use to convert
+   *      from a precise coordinate to an external coordinate
+   */
+  private void appendPointTaggedText(Coordinate coordinate, Writer writer)
+    throws IOException
+  {
+    writer.write("POINT ");
+    appendPointText(coordinate, writer);
+  }
+
+  /**
+   *  Converts a <code>LineString</code> to &lt;LineString Tagged Text&gt;
+   *  format, then appends it to the writer.
+   *
+   *@param  lineString  the <code>LineString</code> to process
+   *@param  writer      the output writer to append to
+   */
+  private void appendLineStringTaggedText(LineString lineString, int level, Writer writer)
+    throws IOException
+  {
+    writer.write("LINESTRING ");
+    appendLineStringText(lineString, level, false, writer);
+  }
+
+  /**
+   *  Converts a <code>LinearRing</code> to &lt;LinearRing Tagged Text&gt;
+   *  format, then appends it to the writer.
+   *
+   *@param  linearRing  the <code>LinearRing</code> to process
+   *@param  writer      the output writer to append to
+   */
+  private void appendLinearRingTaggedText(LinearRing linearRing, int level, Writer writer)
+    throws IOException
+  {
+    writer.write("LINEARRING ");
+    appendLineStringText(linearRing, level, false, writer);
+  }
+
+  /**
+   *  Converts a <code>Polygon</code> to &lt;Polygon Tagged Text&gt; format,
+   *  then appends it to the writer.
+   *
+   *@param  polygon  the <code>Polygon</code> to process
+   *@param  writer   the output writer to append to
+   */
+  private void appendPolygonTaggedText(Polygon polygon, int level, Writer writer)
+    throws IOException
+  {
+    writer.write("POLYGON ");
+    appendPolygonText(polygon, level, false, writer);
+  }
+
+  /**
+   *  Converts a <code>MultiPoint</code> to &lt;MultiPoint Tagged Text&gt;
+   *  format, then appends it to the writer.
+   *
+   *@param  multipoint  the <code>MultiPoint</code> to process
+   *@param  writer      the output writer to append to
+   */
+  private void appendMultiPointTaggedText(MultiPoint multipoint, int level, Writer writer)
+    throws IOException
+  {
+    writer.write("MULTIPOINT ");
+    appendMultiPointText(multipoint, level, writer);
+  }
+
+  /**
+   *  Converts a <code>MultiLineString</code> to &lt;MultiLineString Tagged
+   *  Text&gt; format, then appends it to the writer.
+   *
+   *@param  multiLineString  the <code>MultiLineString</code> to process
+   *@param  writer           the output writer to append to
+   */
+  private void appendMultiLineStringTaggedText(MultiLineString multiLineString, int level,
+      Writer writer)
+    throws IOException
+  {
+    writer.write("MULTILINESTRING ");
+    appendMultiLineStringText(multiLineString, level, false, writer);
+  }
+
+  /**
+   *  Converts a <code>MultiPolygon</code> to &lt;MultiPolygon Tagged Text&gt;
+   *  format, then appends it to the writer.
+   *
+   *@param  multiPolygon  the <code>MultiPolygon</code> to process
+   *@param  writer        the output writer to append to
+   */
+  private void appendMultiPolygonTaggedText(MultiPolygon multiPolygon, int level, Writer writer)
+    throws IOException
+  {
+    writer.write("MULTIPOLYGON ");
+    appendMultiPolygonText(multiPolygon, level, writer);
+  }
+
+  /**
+   *  Converts a <code>GeometryCollection</code> to &lt;GeometryCollection
+   *  Tagged Text&gt; format, then appends it to the writer.
+   *
+   *@param  geometryCollection  the <code>GeometryCollection</code> to process
+   *@param  writer              the output writer to append to
+   */
+  private void appendGeometryCollectionTaggedText(GeometryCollection geometryCollection, int level,
+      Writer writer)
+    throws IOException
+  {
+    writer.write("GEOMETRYCOLLECTION ");
+    appendGeometryCollectionText(geometryCollection, level, writer);
+  }
+
+  /**
+   *  Converts a <code>Coordinate</code> to &lt;Point Text&gt; format, then
+   *  appends it to the writer.
+   *
+   *@param  coordinate      the <code>Coordinate</code> to process
+   *@param  writer          the output writer to append to
+   *@param  precisionModel  the <code>PrecisionModel</code> to use to convert
+   *      from a precise coordinate to an external coordinate
+   */
+  private void appendPointText(Coordinate coordinate, Writer writer)
+    throws IOException
+  {
+    if (coordinate == null) {
+      writer.write("EMPTY");
+    }
+    else {
+      writer.write("(");
+      appendCoordinate(coordinate, writer);
+      writer.write(")");
+    }
+  }
+
+  /**
+   *  Converts a <code>Coordinate</code> to <code>&lt;Point&gt;</code> format,
+   *  then appends it to the writer.
+   *
+   *@param  coordinate      the <code>Coordinate</code> to process
+   *@param  writer          the output writer to append to
+   */
+  private void appendCoordinate(Coordinate coordinate, Writer writer)
+    throws IOException
+  {
+    writer.write(writeNumber(coordinate.x) + " " + writeNumber(coordinate.y));
+    if (outputDimension >= 3 && ! Double.isNaN(coordinate.z)) {
+      writer.write(" ");
+      writer.write(writeNumber(coordinate.z));
+    }
+  }
+
+  /**
+   *  Converts a <code>double</code> to a <code>String</code>, not in scientific
+   *  notation.
+   *
+   *@param  d  the <code>double</code> to convert
+   *@return    the <code>double</code> as a <code>String</code>, not in
+   *      scientific notation
+   */
+  private String writeNumber(double d) {
+    return formatter.format(d);
+  }
+
+  /**
+   *  Converts a <code>LineString</code> to &lt;LineString Text&gt; format, then
+   *  appends it to the writer.
+   *
+   *@param  lineString  the <code>LineString</code> to process
+   *@param  writer      the output writer to append to
+   */
+  private void appendLineStringText(LineString lineString, int level, boolean doIndent, Writer writer)
+    throws IOException
+  {
+    if (lineString.isEmpty()) {
+      writer.write("EMPTY");
+    }
+    else {
+      if (doIndent) indent(level, writer);
+      writer.write("(");
+      for (int i = 0; i < lineString.getNumPoints(); i++) {
+        if (i > 0) {
+          writer.write(", ");
+          if (coordsPerLine > 0
+              && i % coordsPerLine == 0) {
+            indent(level + 1, writer);
+          }
+        }
+        appendCoordinate(lineString.getCoordinateN(i), writer);
+      }
+      writer.write(")");
+    }
+  }
+
+  /**
+   *  Converts a <code>Polygon</code> to &lt;Polygon Text&gt; format, then
+   *  appends it to the writer.
+   *
+   *@param  polygon  the <code>Polygon</code> to process
+   *@param  writer   the output writer to append to
+   */
+  private void appendPolygonText(Polygon polygon, int level, boolean indentFirst, Writer writer)
+    throws IOException
+  {
+    if (polygon.isEmpty()) {
+      writer.write("EMPTY");
+    }
+    else {
+      if (indentFirst) indent(level, writer);
+      writer.write("(");
+      appendLineStringText(polygon.getExteriorRing(), level, false, writer);
+      for (int i = 0; i < polygon.getNumInteriorRing(); i++) {
+        writer.write(", ");
+        appendLineStringText(polygon.getInteriorRingN(i), level + 1, true, writer);
+      }
+      writer.write(")");
+    }
+  }
+
+  /**
+   *  Converts a <code>MultiPoint</code> to &lt;MultiPoint Text&gt; format, then
+   *  appends it to the writer.
+   *
+   *@param  multiPoint  the <code>MultiPoint</code> to process
+   *@param  writer      the output writer to append to
+   */
+  private void appendMultiPointText(MultiPoint multiPoint, int level, Writer writer)
+    throws IOException
+  {
+    if (multiPoint.isEmpty()) {
+      writer.write("EMPTY");
+    }
+    else {
+      writer.write("(");
+      for (int i = 0; i < multiPoint.getNumGeometries(); i++) {
+        if (i > 0) {
+          writer.write(", ");
+          indentCoords(i, level + 1, writer);
+        }
+        writer.write("(");
+        appendCoordinate(((Point) multiPoint.getGeometryN(i)).getCoordinate(), writer);
+        writer.write(")");
+     }
+      writer.write(")");
+    }
+  }
+
+  /**
+   *  Converts a <code>MultiLineString</code> to &lt;MultiLineString Text&gt;
+   *  format, then appends it to the writer.
+   *
+   *@param  multiLineString  the <code>MultiLineString</code> to process
+   *@param  writer           the output writer to append to
+   */
+  private void appendMultiLineStringText(MultiLineString multiLineString, int level, boolean indentFirst,
+      Writer writer)
+    throws IOException
+  {
+    if (multiLineString.isEmpty()) {
+      writer.write("EMPTY");
+    }
+    else {
+      int level2 = level;
+      boolean doIndent = indentFirst;
+      writer.write("(");
+      for (int i = 0; i < multiLineString.getNumGeometries(); i++) {
+        if (i > 0) {
+          writer.write(", ");
+          level2 = level + 1;
+          doIndent = true;
+        }
+        appendLineStringText((LineString) multiLineString.getGeometryN(i), level2, doIndent, writer);
+      }
+      writer.write(")");
+    }
+  }
+
+  /**
+   *  Converts a <code>MultiPolygon</code> to &lt;MultiPolygon Text&gt; format,
+   *  then appends it to the writer.
+   *
+   *@param  multiPolygon  the <code>MultiPolygon</code> to process
+   *@param  writer        the output writer to append to
+   */
+  private void appendMultiPolygonText(MultiPolygon multiPolygon, int level, Writer writer)
+    throws IOException
+  {
+    if (multiPolygon.isEmpty()) {
+      writer.write("EMPTY");
+    }
+    else {
+      int level2 = level;
+      boolean doIndent = false;
+      writer.write("(");
+      for (int i = 0; i < multiPolygon.getNumGeometries(); i++) {
+        if (i > 0) {
+          writer.write(", ");
+          level2 = level + 1;
+          doIndent = true;
+        }
+        appendPolygonText((Polygon) multiPolygon.getGeometryN(i), level2, doIndent, writer);
+      }
+      writer.write(")");
+    }
+  }
+
+  /**
+   *  Converts a <code>GeometryCollection</code> to &lt;GeometryCollectionText&gt;
+   *  format, then appends it to the writer.
+   *
+   *@param  geometryCollection  the <code>GeometryCollection</code> to process
+   *@param  writer              the output writer to append to
+   */
+  private void appendGeometryCollectionText(GeometryCollection geometryCollection, int level,
+      Writer writer)
+    throws IOException
+  {
+    if (geometryCollection.isEmpty()) {
+      writer.write("EMPTY");
+    }
+    else {
+      int level2 = level;
+      writer.write("(");
+      for (int i = 0; i < geometryCollection.getNumGeometries(); i++) {
+        if (i > 0) {
+          writer.write(", ");
+          level2 = level + 1;
+        }
+        appendGeometryTaggedText(geometryCollection.getGeometryN(i), level2, writer);
+      }
+      writer.write(")");
+    }
+  }
+
+  private void indentCoords(int coordIndex,  int level, Writer writer)
+    throws IOException
+  {
+    if (coordsPerLine <= 0
+        || coordIndex % coordsPerLine != 0)
+      return;
+    indent(level, writer);
+  }
+
+  private void indent(int level, Writer writer)
+    throws IOException
+  {
+    if (! useFormatting || level <= 0)
+      return;
+    writer.write("\n");
+    for (int i = 0; i < level; i++) {
+      writer.write(indentTabStr);
+    }
+  }
+
+
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/io/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/io/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/io/package.html	(revision 28000)
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Contains the interfaces for converting JTS objects to and from other formats.
+<P>
+The Java Topology Suite (JTS) is a Java API that implements a core set of spatial data operations using an explicit precision model and robust geometric algorithms. JTS is intended to be used in the development of applications that support the validation, cleaning, integration and querying of spatial datasets.
+<P>
+JTS attempts to implement the OpenGIS Simple Features Specification (SFS) as accurately as possible.  In some cases the SFS is unclear or omits a specification; in this case JTS attempts to choose a reasonable and consistent alternative.  Differences from and elaborations of the SFS are documented in this specification.
+
+<h2>Package Specification</h2>
+
+<ul>
+  <li>Java Topology Suite Technical Specifications
+  <li><A HREF="http://www.opengis.org/techno/specs.htm">
+      OpenGIS Simple Features Specification for SQL</A>
+</ul>
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/BasicSegmentString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/BasicSegmentString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/BasicSegmentString.java	(revision 28000)
@@ -0,0 +1,80 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+import com.vividsolutions.jts.geom.Coordinate;
+
+/**
+ * Represents a list of contiguous line segments,
+ * and supports noding the segments.
+ * The line segments are represented by an array of {@link Coordinate}s.
+ * Intended to optimize the noding of contiguous segments by
+ * reducing the number of allocated objects.
+ * SegmentStrings can carry a context object, which is useful
+ * for preserving topological or parentage information.
+ * All noded substrings are initialized with the same context object.
+ *
+ * @version 1.7
+ */
+public class BasicSegmentString
+	implements SegmentString 
+{
+  private Coordinate[] pts;
+  private Object data;
+
+  /**
+   * Creates a new segment string from a list of vertices.
+   *
+   * @param pts the vertices of the segment string
+   * @param data the user-defined data of this segment string (may be null)
+   */
+  public BasicSegmentString(Coordinate[] pts, Object data)
+  {
+    this.pts = pts;
+    this.data = data;
+  }
+
+  /**
+   * Gets the user-defined data for this segment string.
+   *
+   * @return the user-defined data
+   */
+  public Object getData() { return data; }
+
+
+  public int size() { return pts.length; }
+  public Coordinate getCoordinate(int i) { return pts[i]; }
+  public Coordinate[] getCoordinates() { return pts; }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/FastNodingValidator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/FastNodingValidator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/FastNodingValidator.java	(revision 28000)
@@ -0,0 +1,134 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+import java.util.Collection;
+
+import com.vividsolutions.jts.algorithm.LineIntersector;
+import com.vividsolutions.jts.algorithm.RobustLineIntersector;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.TopologyException;
+import com.vividsolutions.jts.io.WKTWriter;
+
+/**
+ * Validates that a collection of {@link SegmentString}s is correctly noded.
+ * Indexing is used to improve performance.
+ * In the most common use case, validation stops after a single 
+ * non-noded intersection is detected.
+ * Does NOT check a-b-a collapse situations. 
+ * Also does not check for endpoint-interior vertex intersections.
+ * This should not be a problem, since the noders should be
+ * able to compute intersections between vertices correctly.
+ * <p>
+ * The client may either test the {@link #isValid} condition, 
+ * or request that a suitable {@link TopologyException} be thrown.
+ *
+ * @version 1.7
+ */
+public class FastNodingValidator 
+{
+  private LineIntersector li = new RobustLineIntersector();
+
+  private Collection segStrings;
+  private boolean findAllIntersections = false;
+  private InteriorIntersectionFinder segInt = null;
+  private boolean isValid = true;
+  
+  /**
+   * Creates a new noding validator for a given set of linework.
+   * 
+   * @param segStrings a collection of {@link SegmentString}s
+   */
+  public FastNodingValidator(Collection segStrings)
+  {
+    this.segStrings = segStrings;
+  }
+  
+  /**
+   * Returns an error message indicating the segments containing
+   * the intersection.
+   * 
+   * @return an error message documenting the intersection location
+   */
+  public String getErrorMessage()
+  {
+  	if (isValid) return "no intersections found";
+  	
+		Coordinate[] intSegs = segInt.getIntersectionSegments();
+    return "found non-noded intersection between "
+        + WKTWriter.toLineString(intSegs[0], intSegs[1])
+        + " and "
+        + WKTWriter.toLineString(intSegs[2], intSegs[3]);
+  }
+  
+  /**
+   * Checks for an intersection and throws
+   * a TopologyException if one is found.
+   *
+   * @throws TopologyException if an intersection is found
+   */
+  public void checkValid()
+  {
+  	execute();
+  	if (! isValid)
+  		throw new TopologyException(getErrorMessage(), segInt.getInteriorIntersection());
+  }
+
+  private void execute()
+  {
+  	if (segInt != null) 
+  		return;
+    checkInteriorIntersections();
+  }
+
+  private void checkInteriorIntersections()
+  {
+  	/**
+  	 * MD - It may even be reliable to simply check whether 
+  	 * end segments (of SegmentStrings) have an interior intersection,
+  	 * since noding should have split any true interior intersections already.
+  	 */
+  	isValid = true;
+  	segInt = new InteriorIntersectionFinder(li);
+    segInt.setFindAllIntersections(findAllIntersections);
+  	MCIndexNoder noder = new MCIndexNoder();
+  	noder.setSegmentIntersector(segInt);
+  	noder.computeNodes(segStrings);
+  	if (segInt.hasIntersection()) {
+  		isValid = false;
+  		return;
+  	}
+  }
+  
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/FastSegmentSetIntersectionFinder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/FastSegmentSetIntersectionFinder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/FastSegmentSetIntersectionFinder.java	(revision 28000)
@@ -0,0 +1,52 @@
+package com.vividsolutions.jts.noding;
+
+import java.util.*;
+import com.vividsolutions.jts.algorithm.*;
+
+/**
+ * Finds if two sets of {@link SegmentString}s intersect.
+ * Uses indexing for fast performance and to optimize repeated tests
+ * against a target set of lines.
+ * Short-circuited to return as soon an intersection is found.
+ *
+ * @version 1.7
+ */
+public class FastSegmentSetIntersectionFinder 
+{
+	private SegmentSetMutualIntersector segSetMutInt; 
+	// for testing purposes
+//	private SimpleSegmentSetMutualIntersector mci;  
+
+	public FastSegmentSetIntersectionFinder(Collection baseSegStrings)
+	{
+		init(baseSegStrings);
+	}
+	
+	private void init(Collection baseSegStrings)
+	{
+    segSetMutInt = new MCIndexSegmentSetMutualIntersector();
+//    segSetMutInt = new MCIndexIntersectionSegmentSetMutualIntersector();
+    
+//		mci = new SimpleSegmentSetMutualIntersector();
+		segSetMutInt.setBaseSegments(baseSegStrings);
+	}
+		
+  private static LineIntersector li = new RobustLineIntersector();
+
+	public boolean intersects(Collection segStrings)
+	{
+		SegmentIntersectionDetector intFinder = new SegmentIntersectionDetector(li);
+		segSetMutInt.setSegmentIntersector(intFinder);
+
+		segSetMutInt.process(segStrings);
+		return intFinder.hasIntersection();
+	}
+	
+	public boolean intersects(Collection segStrings, SegmentIntersectionDetector intDetector)
+	{
+		segSetMutInt.setSegmentIntersector(intDetector);
+
+		segSetMutInt.process(segStrings);
+		return intDetector.hasIntersection();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/InteriorIntersectionFinder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/InteriorIntersectionFinder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/InteriorIntersectionFinder.java	(revision 28000)
@@ -0,0 +1,179 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.*;
+import com.vividsolutions.jts.algorithm.LineIntersector;
+//import com.vividsolutions.jts.util.Debug;
+
+/**
+ * Finds an interior intersection in a set of {@link SegmentString}s,
+ * if one exists.  Only the first intersection found is reported.
+ *
+ * @version 1.7
+ */
+public class InteriorIntersectionFinder
+    implements SegmentIntersector
+{
+	private boolean findAllIntersections = false;
+	private boolean isCheckEndSegmentsOnly = false;
+  private LineIntersector li;
+  private Coordinate interiorIntersection = null;
+  private Coordinate[] intSegments = null;
+  private List intersections = new ArrayList();
+
+  /**
+   * Creates an intersection finder which finds an interior intersection
+   * if one exists
+   *
+   * @param li the LineIntersector to use
+   */
+  public InteriorIntersectionFinder(LineIntersector li)
+  {
+    this.li = li;
+    interiorIntersection = null;
+  }
+
+  public void setFindAllIntersections(boolean findAllIntersections)
+  {
+    this.findAllIntersections = findAllIntersections;
+  }
+  
+  
+  /**
+   * Tests whether an intersection was found.
+   * 
+   * @return true if an intersection was found
+   */
+  public boolean hasIntersection() 
+  { 
+  	return interiorIntersection != null; 
+  }
+  
+  /**
+   * Gets the computed location of the intersection.
+   * Due to round-off, the location may not be exact.
+   * 
+   * @return the coordinate for the intersection location
+   */
+  public Coordinate getInteriorIntersection()  
+  {    
+  	return interiorIntersection;  
+  }
+
+  /**
+   * Gets the endpoints of the intersecting segments.
+   * 
+   * @return an array of the segment endpoints (p00, p01, p10, p11)
+   */
+  public Coordinate[] getIntersectionSegments()
+  {
+  	return intSegments;
+  }
+  
+  /**
+   * This method is called by clients
+   * of the {@link SegmentIntersector} class to process
+   * intersections for two segments of the {@link SegmentString}s being intersected.
+   * Note that some clients (such as {@link MonotoneChain}s) may optimize away
+   * this call for segment pairs which they have determined do not intersect
+   * (e.g. by an disjoint envelope test).
+   */
+  public void processIntersections(
+      SegmentString e0,  int segIndex0,
+      SegmentString e1,  int segIndex1
+      )
+  {
+  	// short-circuit if intersection already found
+  	if (hasIntersection())
+  		return;
+  	
+    // don't bother intersecting a segment with itself
+    if (e0 == e1 && segIndex0 == segIndex1) return;
+
+    /**
+     * If enabled, only test end segments (on either segString).
+     * 
+     */
+    if (isCheckEndSegmentsOnly) {
+    	boolean isEndSegPresent = isEndSegment(e0, segIndex0) || isEndSegment(e1, segIndex1);
+    	if (! isEndSegPresent)
+    		return;
+    }
+    
+    Coordinate p00 = e0.getCoordinates()[segIndex0];
+    Coordinate p01 = e0.getCoordinates()[segIndex0 + 1];
+    Coordinate p10 = e1.getCoordinates()[segIndex1];
+    Coordinate p11 = e1.getCoordinates()[segIndex1 + 1];
+    
+    li.computeIntersection(p00, p01, p10, p11);
+//if (li.hasIntersection() && li.isProper()) Debug.println(li);
+
+    if (li.hasIntersection()) {
+      if (li.isInteriorIntersection()) {
+      	intSegments = new Coordinate[4];
+      	intSegments[0] = p00;
+      	intSegments[1] = p01;
+      	intSegments[2] = p10;
+      	intSegments[3] = p11;
+      	
+      	interiorIntersection = li.getIntersection(0);
+      	intersections.add(interiorIntersection);
+      }
+    }
+  }
+  
+  /**
+   * Tests whether a segment in a {@link SegmentString} is an end segment.
+   * (either the first or last).
+   * 
+   * @param segStr a segment string
+   * @param index the index of a segment in the segment string
+   * @return true if the segment is an end segment
+   */
+  private boolean isEndSegment(SegmentString segStr, int index)
+  {
+  	if (index == 0) return true;
+  	if (index >= segStr.size() - 2) return true;
+  	return false;
+  }
+  
+  public boolean isDone()
+  { 
+  	if (findAllIntersections) return false;
+  	return interiorIntersection != null;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/MCIndexNoder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/MCIndexNoder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/MCIndexNoder.java	(revision 28000)
@@ -0,0 +1,130 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+import com.vividsolutions.jts.index.*;
+import com.vividsolutions.jts.index.chain.*;
+import com.vividsolutions.jts.index.strtree.*;
+import java.util.*;
+
+/**
+ * Nodes a set of {@link SegmentString}s using a index based
+ * on {@link MonotoneChain}s and a {@link SpatialIndex}.
+ * The {@link SpatialIndex} used should be something that supports
+ * envelope (range) queries efficiently (such as a {@link Quadtree}
+ * or {@link STRtree} (which is the default index provided).
+ *
+ * @version 1.7
+ */
+public class MCIndexNoder
+    extends SinglePassNoder
+{
+  private List monoChains = new ArrayList();
+  private SpatialIndex index= new STRtree();
+  private int idCounter = 0;
+  private Collection nodedSegStrings;
+  // statistics
+
+  public MCIndexNoder()
+  {
+  }
+
+  public Collection getNodedSubstrings()
+  {
+    return  NodedSegmentString.getNodedSubstrings(nodedSegStrings);
+  }
+
+  public void computeNodes(Collection inputSegStrings)
+  {
+    this.nodedSegStrings = inputSegStrings;
+    for (Iterator i = inputSegStrings.iterator(); i.hasNext(); ) {
+      add((SegmentString) i.next());
+    }
+    intersectChains();
+//System.out.println("MCIndexNoder: # chain overlaps = " + nOverlaps);
+  }
+
+  private void intersectChains()
+  {
+    MonotoneChainOverlapAction overlapAction = new SegmentOverlapAction(segInt);
+
+    for (Iterator i = monoChains.iterator(); i.hasNext(); ) {
+      MonotoneChain queryChain = (MonotoneChain) i.next();
+      List overlapChains = index.query(queryChain.getEnvelope());
+      for (Iterator j = overlapChains.iterator(); j.hasNext(); ) {
+        MonotoneChain testChain = (MonotoneChain) j.next();
+        /**
+         * following test makes sure we only compare each pair of chains once
+         * and that we don't compare a chain to itself
+         */
+        if (testChain.getId() > queryChain.getId()) {
+          queryChain.computeOverlaps(testChain, overlapAction);
+        }
+        // short-circuit if possible
+        if (segInt.isDone())
+        	return;
+      }
+    }
+  }
+
+  private void add(SegmentString segStr)
+  {
+    List segChains = MonotoneChainBuilder.getChains(segStr.getCoordinates(), segStr);
+    for (Iterator i = segChains.iterator(); i.hasNext(); ) {
+      MonotoneChain mc = (MonotoneChain) i.next();
+      mc.setId(idCounter++);
+      index.insert(mc.getEnvelope(), mc);
+      monoChains.add(mc);
+    }
+  }
+
+  public class SegmentOverlapAction
+      extends MonotoneChainOverlapAction
+  {
+    private SegmentIntersector si = null;
+
+    public SegmentOverlapAction(SegmentIntersector si)
+    {
+      this.si = si;
+    }
+
+    public void overlap(MonotoneChain mc1, int start1, MonotoneChain mc2, int start2)
+    {
+      SegmentString ss1 = (SegmentString) mc1.getContext();
+      SegmentString ss2 = (SegmentString) mc2.getContext();
+      si.processIntersections(ss1, start1, ss2, start2);
+    }
+
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/MCIndexSegmentSetMutualIntersector.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/MCIndexSegmentSetMutualIntersector.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/MCIndexSegmentSetMutualIntersector.java	(revision 28000)
@@ -0,0 +1,142 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.index.SpatialIndex;
+import com.vividsolutions.jts.index.chain.MonotoneChain;
+import com.vividsolutions.jts.index.chain.MonotoneChainBuilder;
+import com.vividsolutions.jts.index.chain.MonotoneChainOverlapAction;
+import com.vividsolutions.jts.index.strtree.STRtree;
+
+/**
+ * Intersects two sets of {@link SegmentString}s using a index based
+ * on {@link MonotoneChain}s and a {@link SpatialIndex}.
+ *
+ * @version 1.7
+ */
+public class MCIndexSegmentSetMutualIntersector
+    extends SegmentSetMutualIntersector
+{
+  private List monoChains = new ArrayList();
+  /*
+  * The {@link SpatialIndex} used should be something that supports
+  * envelope (range) queries efficiently (such as a {@link Quadtree}
+  * or {@link STRtree}.
+  */
+  private SpatialIndex index= new STRtree();
+  private int indexCounter = 0;
+  private int processCounter = 0;
+  // statistics
+
+  public MCIndexSegmentSetMutualIntersector()
+  {
+  }
+
+  public void setBaseSegments(Collection segStrings)
+  {
+    for (Iterator i = segStrings.iterator(); i.hasNext(); ) {
+      addToIndex((SegmentString) i.next());
+    }
+  }
+  
+  private void addToIndex(SegmentString segStr)
+  {
+    List segChains = MonotoneChainBuilder.getChains(segStr.getCoordinates(), segStr);
+    for (Iterator i = segChains.iterator(); i.hasNext(); ) {
+      MonotoneChain mc = (MonotoneChain) i.next();
+      mc.setId(indexCounter++);
+      index.insert(mc.getEnvelope(), mc);
+    }
+  }
+
+  public void process(Collection segStrings)
+  {
+  	processCounter = indexCounter + 1;
+  	monoChains.clear();
+    for (Iterator i = segStrings.iterator(); i.hasNext(); ) {
+      addToMonoChains((SegmentString) i.next());
+    }
+    intersectChains();
+//    System.out.println("MCIndexBichromaticIntersector: # chain overlaps = " + nOverlaps);
+//    System.out.println("MCIndexBichromaticIntersector: # oct chain overlaps = " + nOctOverlaps);
+  }
+
+  private void intersectChains()
+  {
+    MonotoneChainOverlapAction overlapAction = new SegmentOverlapAction(segInt);
+
+    for (Iterator i = monoChains.iterator(); i.hasNext(); ) {
+      MonotoneChain queryChain = (MonotoneChain) i.next();
+      List overlapChains = index.query(queryChain.getEnvelope());
+      for (Iterator j = overlapChains.iterator(); j.hasNext(); ) {
+        MonotoneChain testChain = (MonotoneChain) j.next();
+        queryChain.computeOverlaps(testChain, overlapAction);
+        if (segInt.isDone()) return;
+      }
+    }
+  }
+
+  private void addToMonoChains(SegmentString segStr)
+  {
+    List segChains = MonotoneChainBuilder.getChains(segStr.getCoordinates(), segStr);
+    for (Iterator i = segChains.iterator(); i.hasNext(); ) {
+      MonotoneChain mc = (MonotoneChain) i.next();
+      mc.setId(processCounter++);
+      monoChains.add(mc);
+    }
+  }
+
+  public class SegmentOverlapAction
+      extends MonotoneChainOverlapAction
+  {
+    private SegmentIntersector si = null;
+
+    public SegmentOverlapAction(SegmentIntersector si)
+    {
+      this.si = si;
+    }
+
+    public void overlap(MonotoneChain mc1, int start1, MonotoneChain mc2, int start2)
+    {
+      SegmentString ss1 = (SegmentString) mc1.getContext();
+      SegmentString ss2 = (SegmentString) mc2.getContext();
+      si.processIntersections(ss1, start1, ss2, start2);
+    }
+
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/NodableSegmentString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/NodableSegmentString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/NodableSegmentString.java	(revision 28000)
@@ -0,0 +1,14 @@
+package com.vividsolutions.jts.noding;
+
+
+/**
+ * An interface for classes which support adding nodes to
+ * a segment string.
+ * 
+ * @author Martin Davis
+ */
+public interface NodableSegmentString
+	extends SegmentString
+{
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/NodedSegmentString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/NodedSegmentString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/NodedSegmentString.java	(revision 28000)
@@ -0,0 +1,139 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.impl.CoordinateArraySequence;
+import com.vividsolutions.jts.io.WKTWriter;
+
+/**
+ * Represents a list of contiguous line segments,
+ * and supports noding the segments.
+ * The line segments are represented by an array of {@link Coordinate}s.
+ * Intended to optimize the noding of contiguous segments by
+ * reducing the number of allocated objects.
+ * SegmentStrings can carry a context object, which is useful
+ * for preserving topological or parentage information.
+ * All noded substrings are initialized with the same context object.
+ *
+ * @version 1.7
+ */
+public class NodedSegmentString
+	implements NodableSegmentString
+{
+	/**
+	 * 
+	 * @param segStrings a Collection of NodedSegmentStrings
+	 * @return a Collection of NodedSegmentStrings representing the substrings
+	 */
+  public static List getNodedSubstrings(Collection segStrings)
+  {
+    List resultEdgelist = new ArrayList();
+    getNodedSubstrings(segStrings, resultEdgelist);
+    return resultEdgelist;
+  }
+
+	/**
+	 * 
+	 * @param segStrings a Collection of NodedSegmentStrings
+	 * @param resultEdgelist a List which will collect the NodedSegmentStrings representing the substrings
+	 */
+ public static void getNodedSubstrings(Collection segStrings, Collection resultEdgelist)
+  {
+    for (Iterator i = segStrings.iterator(); i.hasNext(); ) {
+      NodedSegmentString ss = (NodedSegmentString) i.next();
+      ss.getNodeList().addSplitEdges(resultEdgelist);
+    }
+  }
+
+  private SegmentNodeList nodeList = new SegmentNodeList(this);
+  private Coordinate[] pts;
+  private Object data;
+
+  /**
+   * Creates a new segment string from a list of vertices.
+   *
+   * @param pts the vertices of the segment string
+   * @param data the user-defined data of this segment string (may be null)
+   */
+  public NodedSegmentString(Coordinate[] pts, Object data)
+  {
+    this.pts = pts;
+    this.data = data;
+  }
+
+  /**
+   * Gets the user-defined data for this segment string.
+   *
+   * @return the user-defined data
+   */
+  public Object getData() { return data; }
+
+
+  public SegmentNodeList getNodeList() { return nodeList; }
+  public int size() { return pts.length; }
+  public Coordinate getCoordinate(int i) { return pts[i]; }
+  public Coordinate[] getCoordinates() { return pts; }
+
+
+  /**
+   * Gets the octant of the segment starting at vertex <code>index</code>.
+   *
+   * @param index the index of the vertex starting the segment.  Must not be
+   * the last index in the vertex list
+   * @return the octant of the segment at the vertex
+   */
+  public int getSegmentOctant(int index)
+  {
+    if (index == pts.length - 1) return -1;
+    return safeOctant(getCoordinate(index), getCoordinate(index + 1));
+//    return Octant.octant(getCoordinate(index), getCoordinate(index + 1));
+  }
+
+  private int safeOctant(Coordinate p0, Coordinate p1)
+  {
+  	if (p0.equals2D(p1)) return 0;
+  	return Octant.octant(p0, p1);
+  }
+  
+  public String toString()
+  {
+  	return WKTWriter.toLineString(new CoordinateArraySequence(pts));
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/Noder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/Noder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/Noder.java	(revision 28000)
@@ -0,0 +1,60 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+import java.util.*;
+
+/**
+ * Computes all intersections between segments in a set of {@link SegmentString}s.
+ * Intersections found are represented as {@link SegmentNode}s and added to the
+ * {@link SegmentString}s in which they occur.
+ * As a final step in the noding a new set of segment strings split
+ * at the nodes may be returned.
+ *
+ * @version 1.7
+ */
+public interface Noder
+{
+
+  /**
+   * Computes the noding for a collection of {@link SegmentString}s.
+   * Some Noders may add all these nodes to the input SegmentStrings;
+   * others may only add some or none at all.
+   *
+   * @param segStrings a collection of {@link SegmentString}s to node
+   */
+  void computeNodes(Collection segStrings);
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/Octant.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/Octant.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/Octant.java	(revision 28000)
@@ -0,0 +1,77 @@
+package com.vividsolutions.jts.noding;
+
+import com.vividsolutions.jts.geom.Coordinate;
+/**
+ * Methods for computing and working with octants of the Cartesian plane
+ * Octants are numbered as follows:
+ * <pre>
+ *  \2|1/
+ * 3 \|/ 0
+ * ---+--
+ * 4 /|\ 7
+ *  /5|6\
+ * <pre>
+ * If line segments lie along a coordinate axis, the octant is the lower of the two
+ * possible values.
+ *
+ * @version 1.7
+ */
+public class Octant {
+
+  /**
+   * Returns the octant of a directed line segment (specified as x and y
+   * displacements, which cannot both be 0).
+   */
+  public static int octant(double dx, double dy)
+  {
+    if (dx == 0.0 && dy == 0.0)
+      throw new IllegalArgumentException("Cannot compute the octant for point ( "+ dx + ", " + dy + " )" );
+
+    double adx = Math.abs(dx);
+    double ady = Math.abs(dy);
+
+    if (dx >= 0) {
+      if (dy >= 0) {
+        if (adx >= ady)
+          return 0;
+        else
+          return 1;
+      }
+      else { // dy < 0
+        if (adx >= ady)
+          return 7;
+        else
+          return 6;
+      }
+    }
+    else { // dx < 0
+      if (dy >= 0) {
+        if (adx >= ady)
+          return 3;
+        else
+          return 2;
+      }
+      else { // dy < 0
+        if (adx >= ady)
+          return 4;
+        else
+          return 5;
+      }
+    }
+  }
+
+  /**
+   * Returns the octant of a directed line segment from p0 to p1.
+   */
+  public static int octant(Coordinate p0, Coordinate p1)
+  {
+    double dx = p1.x - p0.x;
+    double dy = p1.y - p0.y;
+    if (dx == 0.0 && dy == 0.0)
+      throw new IllegalArgumentException("Cannot compute the octant for two identical points " + p0);
+    return octant(dx, dy);
+  }
+
+  private Octant() {
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/OrientedCoordinateArray.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/OrientedCoordinateArray.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/OrientedCoordinateArray.java	(revision 28000)
@@ -0,0 +1,130 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateArrays;
+
+/**
+ * Allows comparing {@link Coordinate} arrays
+ * in an orientation-independent way.
+ *
+ * @author Martin Davis
+ * @version 1.7
+ */
+public class OrientedCoordinateArray
+    implements Comparable
+{
+  private Coordinate[] pts;
+  private boolean orientation;
+
+  /**
+   * Creates a new {@link OrientedCoordinateArray}
+   * for the given {@link Coordinate} array.
+   *
+   * @param pts the coordinates to orient
+   */
+  public OrientedCoordinateArray(Coordinate[] pts)
+  {
+    this.pts = pts;
+    orientation = orientation(pts);
+  }
+
+  /**
+   * Computes the canonical orientation for a coordinate array.
+   *
+   * @param pts the array to test
+   * @return <code>true</code> if the points are oriented forwards
+   * @return <code>false</code if the points are oriented in reverse
+   */
+  private static boolean orientation(Coordinate[] pts)
+  {
+    return CoordinateArrays.increasingDirection(pts) == 1;
+  }
+
+  /**
+   * Compares two {@link OrientedCoordinateArray}s for their relative order
+   *
+   * @return -1 this one is smaller
+   * @return 0 the two objects are equal
+   * @return 1 this one is greater
+   */
+
+  public int compareTo(Object o1) {
+    OrientedCoordinateArray oca = (OrientedCoordinateArray) o1;
+    int comp = compareOriented(pts, orientation,
+                               oca.pts, oca.orientation);
+/*
+    // MD - testing only
+    int oldComp = SegmentStringDissolver.ptsComp.compare(pts, oca.pts);
+    if ((oldComp == 0 || comp == 0) && oldComp != comp) {
+      System.out.println("bidir mismatch");
+
+      boolean orient1 = orientation(pts);
+      boolean orient2 = orientation(oca.pts);
+      int comp2 = compareOriented(pts, orientation,
+                               oca.pts, oca.orientation);
+      int oldComp2 = SegmentStringDissolver.ptsComp.compare(pts, oca.pts);
+    }
+    */
+    return comp;
+  }
+
+  private static int compareOriented(Coordinate[] pts1,
+                                     boolean orientation1,
+                                     Coordinate[] pts2,
+                                     boolean orientation2)
+  {
+    int dir1 = orientation1 ? 1 : -1;
+    int dir2 = orientation2 ? 1 : -1;
+    int limit1 = orientation1 ? pts1.length : -1;
+    int limit2 = orientation2 ? pts2.length : -1;
+
+    int i1 = orientation1 ? 0 : pts1.length - 1;
+    int i2 = orientation2 ? 0 : pts2.length - 1;
+    while (true) {
+      int compPt = pts1[i1].compareTo(pts2[i2]);
+      if (compPt != 0)
+        return compPt;
+      i1 += dir1;
+      i2 += dir2;
+      boolean done1 = i1 == limit1;
+      boolean done2 = i2 == limit2;
+      if (done1 && ! done2) return -1;
+      if (! done1 && done2) return 1;
+      if (done1 && done2) return 0;
+    }
+  }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentIntersectionDetector.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentIntersectionDetector.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentIntersectionDetector.java	(revision 28000)
@@ -0,0 +1,187 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+
+import com.vividsolutions.jts.geom.*;
+import com.vividsolutions.jts.algorithm.LineIntersector;
+
+/**
+ * Detects and records an intersection between two {@link SegmentString}s,
+ * if one exists.  Only a single intersection is recorded.
+ * This strategy can be configured to search for proper intersections.
+ * In this case, the presence of <i>any</i> kind of intersection will still be recorded,
+ * but searching will continue until either a proper intersection has been found
+ * or no intersections are detected.
+ *
+ * @version 1.7
+ */
+public class SegmentIntersectionDetector
+    implements SegmentIntersector
+{
+  private LineIntersector li;
+  private boolean findProper = false;
+  private boolean findAllTypes = false;
+  
+  private boolean hasIntersection = false;
+  private boolean hasProperIntersection = false;
+  private boolean hasNonProperIntersection = false;
+  
+  private Coordinate intPt = null;
+  private Coordinate[] intSegments = null;
+
+  /**
+   * Creates an intersection finder 
+   *
+   * @param li the LineIntersector to use
+   */
+  public SegmentIntersectionDetector(LineIntersector li)
+  {
+    this.li = li;
+   }
+
+  
+  public void setFindAllIntersectionTypes(boolean findAllTypes)
+  {
+    this.findAllTypes = findAllTypes;
+  }
+  
+  /**
+   * Tests whether an intersection was found.
+   * 
+   * @return true if an intersection was found
+   */
+  public boolean hasIntersection() 
+  { 
+  	return hasIntersection; 
+  }
+  
+  /**
+   * Tests whether a proper intersection was found.
+   * 
+   * @return true if a proper intersection was found
+   */
+  public boolean hasProperIntersection() 
+  { 
+    return hasProperIntersection; 
+  }
+  
+  /**
+   * Tests whether a non-proper intersection was found.
+   * 
+   * @return true if a non-proper intersection was found
+   */
+  public boolean hasNonProperIntersection() 
+  { 
+    return hasNonProperIntersection; 
+  }
+  
+  
+  /**
+   * This method is called by clients
+   * of the {@link SegmentIntersector} class to process
+   * intersections for two segments of the {@link SegmentString}s being intersected.
+   * Note that some clients (such as {@link MonotoneChain}s) may optimize away
+   * this call for segment pairs which they have determined do not intersect
+   * (e.g. by an disjoint envelope test).
+   */
+  public void processIntersections(
+      SegmentString e0,  int segIndex0,
+      SegmentString e1,  int segIndex1
+      )
+  {  	
+    // don't bother intersecting a segment with itself
+    if (e0 == e1 && segIndex0 == segIndex1) return;
+    
+    Coordinate p00 = e0.getCoordinates()[segIndex0];
+    Coordinate p01 = e0.getCoordinates()[segIndex0 + 1];
+    Coordinate p10 = e1.getCoordinates()[segIndex1];
+    Coordinate p11 = e1.getCoordinates()[segIndex1 + 1];
+    
+    li.computeIntersection(p00, p01, p10, p11);
+//  if (li.hasIntersection() && li.isProper()) Debug.println(li);
+
+    if (li.hasIntersection()) {
+			// System.out.println(li);
+    	
+    	// record intersection info
+			hasIntersection = true;
+			
+			boolean isProper = li.isProper();
+			if (isProper)
+				hasProperIntersection = true;
+      if (! isProper)
+        hasNonProperIntersection = true;
+			
+			/**
+			 * If this is the kind of intersection we are searching for
+			 * OR no location has yet been recorded
+			 * save the location data
+			 */
+			boolean saveLocation = true;
+			if (findProper && ! isProper) saveLocation = false;
+			
+			if (intPt == null || saveLocation) {
+
+				// record intersection location (approximate)
+				intPt = li.getIntersection(0);
+
+				// record intersecting segments
+				intSegments = new Coordinate[4];
+				intSegments[0] = p00;
+				intSegments[1] = p01;
+				intSegments[2] = p10;
+				intSegments[3] = p11;
+			}
+		}
+  }
+  
+  public boolean isDone()
+  { 
+    /**
+     * If finding all types, we can stop
+     * when both possible types have been found.
+     */
+    if (findAllTypes) {
+      return hasProperIntersection && hasNonProperIntersection;
+    }
+    
+  	/**
+  	 * If searching for a proper intersection, only stop if one is found
+  	 */
+  	if (findProper) {
+  		return hasProperIntersection;
+  	}
+  	return hasIntersection;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentIntersector.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentIntersector.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentIntersector.java	(revision 28000)
@@ -0,0 +1,68 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+
+/**
+ * Processes possible intersections detected by a {@link Noder}.
+ * The {@link SegmentIntersector} is passed to a {@link Noder}.
+ * The {@link addIntersections} method is called whenever the {@link Noder}
+ * detects that two SegmentStrings <i>might</i> intersect.
+ * This class may be used either to find all intersections, or
+ * to detect the presence of an intersection.  In the latter case,
+ * Noders may choose to short-circuit their computation by calling the
+ * {@link isDone} method.
+ * This class is an example of the <i>Strategy</i> pattern.
+ *
+ * @version 1.7
+ */
+public interface SegmentIntersector
+{
+  /**
+   * This method is called by clients
+   * of the {@link SegmentIntersector} interface to process
+   * intersections for two segments of the {@link SegmentString}s being intersected.
+   */
+  void processIntersections(
+    SegmentString e0,  int segIndex0,
+    SegmentString e1,  int segIndex1
+     );
+  
+  /**
+   * Reports whether the client of this class
+   * needs to continue testing all intersections in an arrangement.
+   * 
+   * @return true if there is no need to continue testing segments
+   */
+  boolean isDone();
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentNode.java	(revision 28000)
@@ -0,0 +1,77 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+import com.vividsolutions.jts.geom.Coordinate;
+
+/**
+ * Represents an intersection point between two {@link SegmentString}s.
+ *
+ * @version 1.7
+ */
+public class SegmentNode
+    implements Comparable
+{
+  public final Coordinate coord;   // the point of intersection
+  public final int segmentIndex;   // the index of the containing line segment in the parent edge
+  private final int segmentOctant;
+  private final boolean isInterior;
+
+  public SegmentNode(NodedSegmentString segString, Coordinate coord, int segmentIndex, int segmentOctant) {
+    this.coord = new Coordinate(coord);
+    this.segmentIndex = segmentIndex;
+    this.segmentOctant = segmentOctant;
+    isInterior = ! coord.equals2D(segString.getCoordinate(segmentIndex));
+  }
+
+  public boolean isInterior() { return isInterior; }
+
+
+  /**
+   * @return -1 this SegmentNode is located before the argument location
+   * @return 0 this SegmentNode is at the argument location
+   * @return 1 this SegmentNode is located after the argument location
+   */
+  public int compareTo(Object obj)
+  {
+    SegmentNode other = (SegmentNode) obj;
+
+    if (segmentIndex < other.segmentIndex) return -1;
+    if (segmentIndex > other.segmentIndex) return 1;
+
+    if (coord.equals2D(other.coord)) return 0;
+
+    return SegmentPointComparator.compare(segmentOctant, coord, other.coord);
+    //return segment.compareNodePosition(this, other);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentNodeList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentNodeList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentNodeList.java	(revision 28000)
@@ -0,0 +1,232 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * A list of the {@link SegmentNode}s present along a noded {@link SegmentString}.
+ *
+ * @version 1.7
+ */
+public class SegmentNodeList
+{
+  private Map nodeMap = new TreeMap();
+  private NodedSegmentString edge;  // the parent edge
+
+  public SegmentNodeList(NodedSegmentString edge)
+  {
+    this.edge = edge;
+  }
+
+  /**
+   * Adds an intersection into the list, if it isn't already there.
+   * The input segmentIndex and dist are expected to be normalized.
+   *
+   * @return the SegmentIntersection found or added
+   */
+  public SegmentNode add(Coordinate intPt, int segmentIndex)
+  {
+    SegmentNode eiNew = new SegmentNode(edge, intPt, segmentIndex, edge.getSegmentOctant(segmentIndex));
+    SegmentNode ei = (SegmentNode) nodeMap.get(eiNew);
+    if (ei != null) {
+      // debugging sanity check
+      Assert.isTrue(ei.coord.equals2D(intPt), "Found equal nodes with different coordinates");
+//      if (! ei.coord.equals2D(intPt))
+//        Debug.println("Found equal nodes with different coordinates");
+
+      return ei;
+    }
+    // node does not exist, so create it
+    nodeMap.put(eiNew, eiNew);
+    return eiNew;
+  }
+
+  /**
+   * returns an iterator of SegmentNodes
+   */
+  public Iterator iterator() { return nodeMap.values().iterator(); }
+
+  /**
+   * Adds nodes for the first and last points of the edge
+   */
+  private void addEndpoints()
+  {
+    int maxSegIndex = edge.size() - 1;
+    add(edge.getCoordinate(0), 0);
+    add(edge.getCoordinate(maxSegIndex), maxSegIndex);
+  }
+
+  /**
+   * Adds nodes for any collapsed edge pairs.
+   * Collapsed edge pairs can be caused by inserted nodes, or they can be
+   * pre-existing in the edge vertex list.
+   * In order to provide the correct fully noded semantics,
+   * the vertex at the base of a collapsed pair must also be added as a node.
+   */
+  private void addCollapsedNodes()
+  {
+    List collapsedVertexIndexes = new ArrayList();
+
+    findCollapsesFromInsertedNodes(collapsedVertexIndexes);
+    findCollapsesFromExistingVertices(collapsedVertexIndexes);
+
+    // node the collapses
+    for (Iterator it = collapsedVertexIndexes.iterator(); it.hasNext(); ) {
+      int vertexIndex = ((Integer) it.next()).intValue();
+      add(edge.getCoordinate(vertexIndex), vertexIndex);
+    }
+  }
+
+  /**
+   * Adds nodes for any collapsed edge pairs
+   * which are pre-existing in the vertex list.
+   */
+  private void findCollapsesFromExistingVertices(List collapsedVertexIndexes)
+  {
+    for (int i = 0; i < edge.size() - 2; i++) {
+      Coordinate p0 = edge.getCoordinate(i);
+      Coordinate p2 = edge.getCoordinate(i + 2);
+      if (p0.equals2D(p2)) {
+        // add base of collapse as node
+        collapsedVertexIndexes.add(new Integer(i + 1));
+      }
+    }
+  }
+
+  /**
+   * Adds nodes for any collapsed edge pairs caused by inserted nodes
+   * Collapsed edge pairs occur when the same coordinate is inserted as a node
+   * both before and after an existing edge vertex.
+   * To provide the correct fully noded semantics,
+   * the vertex must be added as a node as well.
+   */
+  private void findCollapsesFromInsertedNodes(List collapsedVertexIndexes)
+  {
+    int[] collapsedVertexIndex = new int[1];
+    Iterator it = iterator();
+    // there should always be at least two entries in the list, since the endpoints are nodes
+    SegmentNode eiPrev = (SegmentNode) it.next();
+    while (it.hasNext()) {
+      SegmentNode ei = (SegmentNode) it.next();
+      boolean isCollapsed = findCollapseIndex(eiPrev, ei, collapsedVertexIndex);
+      if (isCollapsed)
+        collapsedVertexIndexes.add(new Integer(collapsedVertexIndex[0]));
+
+      eiPrev = ei;
+    }
+  }
+
+  private boolean findCollapseIndex(SegmentNode ei0, SegmentNode ei1, int[] collapsedVertexIndex)
+  {
+    // only looking for equal nodes
+    if (! ei0.coord.equals2D(ei1.coord)) return false;
+
+    int numVerticesBetween = ei1.segmentIndex - ei0.segmentIndex;
+    if (! ei1.isInterior()) {
+      numVerticesBetween--;
+    }
+
+    // if there is a single vertex between the two equal nodes, this is a collapse
+    if (numVerticesBetween == 1) {
+      collapsedVertexIndex[0] = ei0.segmentIndex + 1;
+      return true;
+    }
+    return false;
+  }
+
+
+  /**
+   * Creates new edges for all the edges that the intersections in this
+   * list split the parent edge into.
+   * Adds the edges to the provided argument list
+   * (this is so a single list can be used to accumulate all split edges
+   * for a set of {@link SegmentString}s).
+   */
+  public void addSplitEdges(Collection edgeList)
+  {
+    // ensure that the list has entries for the first and last point of the edge
+    addEndpoints();
+    addCollapsedNodes();
+
+    Iterator it = iterator();
+    // there should always be at least two entries in the list, since the endpoints are nodes
+    SegmentNode eiPrev = (SegmentNode) it.next();
+    while (it.hasNext()) {
+      SegmentNode ei = (SegmentNode) it.next();
+      SegmentString newEdge = createSplitEdge(eiPrev, ei);
+      edgeList.add(newEdge);
+      eiPrev = ei;
+    }
+    //checkSplitEdgesCorrectness(testingSplitEdges);
+  }
+
+  /**
+   * Create a new "split edge" with the section of points between
+   * (and including) the two intersections.
+   * The label for the new edge is the same as the label for the parent edge.
+   */
+  SegmentString createSplitEdge(SegmentNode ei0, SegmentNode ei1)
+  {
+//Debug.println("\ncreateSplitEdge"); Debug.print(ei0); Debug.print(ei1);
+    int npts = ei1.segmentIndex - ei0.segmentIndex + 2;
+
+    Coordinate lastSegStartPt = edge.getCoordinate(ei1.segmentIndex);
+    // if the last intersection point is not equal to the its segment start pt,
+    // add it to the points list as well.
+    // (This check is needed because the distance metric is not totally reliable!)
+    // The check for point equality is 2D only - Z values are ignored
+    boolean useIntPt1 = ei1.isInterior() || ! ei1.coord.equals2D(lastSegStartPt);
+    if (! useIntPt1) {
+      npts--;
+    }
+
+    Coordinate[] pts = new Coordinate[npts];
+    int ipt = 0;
+    pts[ipt++] = new Coordinate(ei0.coord);
+    for (int i = ei0.segmentIndex + 1; i <= ei1.segmentIndex; i++) {
+      pts[ipt++] = edge.getCoordinate(i);
+    }
+    if (useIntPt1) pts[ipt] = ei1.coord;
+
+    return new NodedSegmentString(pts, edge.getData());
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentPointComparator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentPointComparator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentPointComparator.java	(revision 28000)
@@ -0,0 +1,65 @@
+package com.vividsolutions.jts.noding;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * Implements a robust method of comparing the relative position of two
+ * points along the same segment.
+ * The coordinates are assumed to lie "near" the segment.
+ * This means that this algorithm will only return correct results
+ * if the input coordinates
+ * have the same precision and correspond to rounded values
+ * of exact coordinates lying on the segment.
+ *
+ * @version 1.7
+ */
+public class SegmentPointComparator {
+
+  /**
+   * Compares two {@link Coordinate}s for their relative position along a segment
+   * lying in the specified {@link Octant}.
+   *
+   * @return -1 node0 occurs first
+   * @return 0 the two nodes are equal
+   * @return 1 node1 occurs first
+   */
+  public static int compare(int octant, Coordinate p0, Coordinate p1)
+  {
+    // nodes can only be equal if their coordinates are equal
+    if (p0.equals2D(p1)) return 0;
+
+    int xSign = relativeSign(p0.x, p1.x);
+    int ySign = relativeSign(p0.y, p1.y);
+
+    switch (octant) {
+      case 0: return compareValue(xSign, ySign);
+      case 1: return compareValue(ySign, xSign);
+      case 2: return compareValue(ySign, -xSign);
+      case 3: return compareValue(-xSign, ySign);
+      case 4: return compareValue(-xSign, -ySign);
+      case 5: return compareValue(-ySign, -xSign);
+      case 6: return compareValue(-ySign, xSign);
+      case 7: return compareValue(xSign, -ySign);
+    }
+    Assert.shouldNeverReachHere("invalid octant value");
+    return 0;
+  }
+
+  public static int relativeSign(double x0, double x1)
+  {
+    if (x0 < x1) return -1;
+    if (x0 > x1) return 1;
+    return 0;
+  }
+
+  private static int compareValue(int compareSign0, int compareSign1)
+  {
+    if (compareSign0 < 0) return -1;
+    if (compareSign0 > 0) return 1;
+    if (compareSign1 < 0) return -1;
+    if (compareSign1 > 0) return 1;
+    return 0;
+
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentSetMutualIntersector.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentSetMutualIntersector.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentSetMutualIntersector.java	(revision 28000)
@@ -0,0 +1,76 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+import java.util.*;
+
+/**
+ * An intersector for the red-blue intersection problem.
+ * In this class of line arrangement problem,
+ * two disjoint sets of linestrings are provided.
+ * It is assumed that within
+ * each set, no two linestrings intersect except possibly at their endpoints.
+ * Implementations can take advantage of this fact to optimize processing.
+ *
+ * @author Martin Davis
+ * @version 1.10
+ */
+public abstract class SegmentSetMutualIntersector
+{
+  protected SegmentIntersector segInt;
+
+  /**
+   * Sets the {@link SegmentIntersector} to use with this intersector.
+   * The SegmentIntersector will either rocord or add intersection nodes
+   * for the input segment strings.
+   *
+   * @param segInt the segment intersector to use
+   */
+  public void setSegmentIntersector(SegmentIntersector segInt)
+  {
+    this.segInt = segInt;
+  }
+
+  /**
+   * 
+   * @param segStrings0 a collection of {@link SegmentString}s to node
+   */
+  public abstract void setBaseSegments(Collection segStrings);
+  
+  /**
+   * Computes the intersections for two collections of {@link SegmentString}s.
+   *
+  * @param segStrings1 a collection of {@link SegmentString}s to node
+   */
+  public abstract void process(Collection segStrings);
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentString.java	(revision 28000)
@@ -0,0 +1,58 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+import com.vividsolutions.jts.geom.Coordinate;
+
+/**
+ * An interface for classes which represent a sequence of contiguous line segments.
+ * SegmentStrings can carry a context object, which is useful
+ * for preserving topological or parentage information.
+ *
+ * @version 1.7
+ */
+public interface SegmentString
+{
+  /**
+   * Gets the user-defined data for this segment string.
+   *
+   * @return the user-defined data
+   */
+  public Object getData();
+
+
+  public int size();
+  public Coordinate getCoordinate(int i);
+  public Coordinate[] getCoordinates();
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentStringUtil.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentStringUtil.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SegmentStringUtil.java	(revision 28000)
@@ -0,0 +1,35 @@
+package com.vividsolutions.jts.noding;
+
+import java.util.*;
+import com.vividsolutions.jts.geom.*;
+import com.vividsolutions.jts.geom.util.LinearComponentExtracter;
+
+/**
+ * Utility methods for processing {@link SegmentString}s.
+ * 
+ * @author Martin Davis
+ *
+ */
+public class SegmentStringUtil 
+{
+  /**
+   * Extracts all linear components from a given {@link Geometry}
+   * to {@link SegmentString}s.
+   * The SegmentString data item is set to be the source Geometry.
+   * 
+   * @param geom the geometry to extract from
+   * @return a List of SegmentStrings
+   */
+  public static List extractSegmentStrings(Geometry geom)
+  {
+    List segStr = new ArrayList();
+    List lines = LinearComponentExtracter.getLines(geom);
+    for (Iterator i = lines.iterator(); i.hasNext(); ) {
+      LineString line = (LineString) i.next();
+      Coordinate[] pts = line.getCoordinates();
+      segStr.add(new NodedSegmentString(pts, geom));
+    }
+    return segStr;
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SinglePassNoder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SinglePassNoder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/SinglePassNoder.java	(revision 28000)
@@ -0,0 +1,87 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.noding;
+
+import java.util.*;
+
+/**
+ * Base class for {@link Noder}s which make a single
+ * pass to find intersections.
+ * This allows using a custom {@link SegmentIntersector}
+ * (which for instance may simply identify intersections, rather than
+ * insert them).
+ *
+ * @version 1.7
+ */
+public abstract class SinglePassNoder
+    implements Noder
+{
+
+  protected SegmentIntersector segInt;
+
+  public SinglePassNoder() {
+  }
+
+  /**
+   * Sets the SegmentIntersector to use with this noder.
+   * A SegmentIntersector will normally add intersection nodes
+   * to the input segment strings, but it may not - it may
+   * simply record the presence of intersections.
+   * However, some Noders may require that intersections be added.
+   *
+   * @param segInt
+   */
+  public void setSegmentIntersector(SegmentIntersector segInt)
+  {
+    this.segInt = segInt;
+  }
+
+  /**
+   * Computes the noding for a collection of {@link SegmentString}s.
+   * Some Noders may add all these nodes to the input SegmentStrings;
+   * others may only add some or none at all.
+   *
+   * @param segStrings a collection of {@link SegmentString}s to node
+   */
+  public abstract void computeNodes(Collection segStrings);
+
+  /**
+   * Returns a {@link Collection} of fully noded {@link SegmentString}s.
+   * The SegmentStrings have the same context as their parent.
+   *
+   * @return a Collection of SegmentStrings
+   */
+  public abstract Collection getNodedSubstrings();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/noding/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Classes to compute nodings for arrangements of line segments and line segment sequences.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/BoundaryOp.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/BoundaryOp.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/BoundaryOp.java	(revision 28000)
@@ -0,0 +1,192 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.vividsolutions.jts.algorithm.BoundaryNodeRule;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateArrays;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.MultiLineString;
+import com.vividsolutions.jts.geom.MultiPoint;
+import com.vividsolutions.jts.geom.Point;
+
+/**
+ * Computes the boundary of a {@link Geometry}.
+ * Allows specifying the {@link BoundaryNodeRule} to be used.
+ * This operation will always return a {@link Geometry} of the appropriate
+ * dimension for the boundary (even if the input geometry is empty).
+ * The boundary of zero-dimensional geometries (Points) is
+ * always the empty {@link GeometryCollection}.
+ *
+ * @author Martin Davis
+ * @version 1.7
+ */
+
+public class BoundaryOp
+{
+  private Geometry geom;
+  private GeometryFactory geomFact;
+  private BoundaryNodeRule bnRule;
+
+  public BoundaryOp(Geometry geom)
+  {
+    this(geom, BoundaryNodeRule.MOD2_BOUNDARY_RULE);
+  }
+
+  public BoundaryOp(Geometry geom, BoundaryNodeRule bnRule)
+  {
+    this.geom = geom;
+    geomFact = geom.getFactory();
+    this.bnRule = bnRule;
+  }
+
+  public Geometry getBoundary()
+  {
+    if (geom instanceof LineString) return boundaryLineString((LineString) geom);
+    if (geom instanceof MultiLineString) return boundaryMultiLineString((MultiLineString) geom);
+    return geom.getBoundary();
+  }
+
+  private MultiPoint getEmptyMultiPoint()
+  {
+    return geomFact.createMultiPoint((CoordinateSequence) null);
+  }
+
+  private Geometry boundaryMultiLineString(MultiLineString mLine)
+  {
+    if (geom.isEmpty()) {
+      return getEmptyMultiPoint();
+    }
+
+    Coordinate[] bdyPts = computeBoundaryCoordinates(mLine);
+
+    // return Point or MultiPoint
+    if (bdyPts.length == 1) {
+      return geomFact.createPoint(bdyPts[0]);
+    }
+    // this handles 0 points case as well
+    return geomFact.createMultiPoint(bdyPts);
+  }
+
+/*
+// MD - superseded
+  private Coordinate[] computeBoundaryFromGeometryGraph(MultiLineString mLine)
+  {
+    GeometryGraph g = new GeometryGraph(0, mLine, bnRule);
+    Coordinate[] bdyPts = g.getBoundaryPoints();
+    return bdyPts;
+  }
+*/
+
+  private Map endpointMap;
+
+  private Coordinate[] computeBoundaryCoordinates(MultiLineString mLine)
+  {
+    List bdyPts = new ArrayList();
+    endpointMap = new TreeMap();
+    for (int i = 0; i < mLine.getNumGeometries(); i++) {
+      LineString line = (LineString) mLine.getGeometryN(i);
+      if (line.getNumPoints() == 0)
+        continue;
+      addEndpoint(line.getCoordinateN(0));
+      addEndpoint(line.getCoordinateN(line.getNumPoints() - 1));
+    }
+
+    for (Iterator it = endpointMap.entrySet().iterator(); it.hasNext(); ) {
+      Map.Entry entry = (Map.Entry) it.next();
+      Counter counter = (Counter) entry.getValue();
+      int valence = counter.count;
+      if (bnRule.isInBoundary(valence)) {
+        bdyPts.add(entry.getKey());
+      }
+    }
+
+    return CoordinateArrays.toCoordinateArray(bdyPts);
+  }
+
+  private void addEndpoint(Coordinate pt)
+  {
+    Counter counter = (Counter) endpointMap.get(pt);
+    if (counter == null) {
+      counter = new Counter();
+      endpointMap.put(pt, counter);
+    }
+    counter.count++;
+  }
+
+  private Geometry boundaryLineString(LineString line)
+  {
+    if (geom.isEmpty()) {
+      return getEmptyMultiPoint();
+    }
+
+    if (line.isClosed()) {
+      // check whether endpoints of valence 2 are on the boundary or not
+      boolean closedEndpointOnBoundary = bnRule.isInBoundary(2);
+      if (closedEndpointOnBoundary) {
+        return line.getStartPoint();
+      }
+      else {
+        return geomFact.createMultiPoint((Coordinate[]) null);
+      }
+    }
+    return geomFact.createMultiPoint(new Point[]{
+                                     line.getStartPoint(),
+                                     line.getEndPoint()
+    });
+  }
+}
+
+/**
+ * Stores an integer count, for use as a Map entry.
+ *
+ * @author Martin Davis
+ * @version 1.7
+ */
+class Counter
+{
+  /**
+   * The value of the count
+   */
+  int count;
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/GeometryGraphOperation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/GeometryGraphOperation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/GeometryGraphOperation.java	(revision 28000)
@@ -0,0 +1,85 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation;
+
+import com.vividsolutions.jts.algorithm.BoundaryNodeRule;
+import com.vividsolutions.jts.algorithm.LineIntersector;
+import com.vividsolutions.jts.algorithm.RobustLineIntersector;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.PrecisionModel;
+import com.vividsolutions.jts.geomgraph.GeometryGraph;
+
+/**
+ * The base class for operations that require {@link GeometryGraph}s.
+ *
+ * @version 1.7
+ */
+public class GeometryGraphOperation
+{
+  protected final LineIntersector li = new RobustLineIntersector();
+  protected PrecisionModel resultPrecisionModel;
+
+  /**
+   * The operation args into an array so they can be accessed by index
+   */
+  protected GeometryGraph[] arg;  // the arg(s) of the operation
+
+  public GeometryGraphOperation(Geometry g0, Geometry g1)
+  {
+    this(g0, g1,
+         BoundaryNodeRule.OGC_SFS_BOUNDARY_RULE
+//         BoundaryNodeRule.ENDPOINT_BOUNDARY_RULE
+         );
+  }
+
+  public GeometryGraphOperation(Geometry g0, Geometry g1, BoundaryNodeRule boundaryNodeRule)
+  {
+    // use the most precise model for the result
+    if (g0.getPrecisionModel().compareTo(g1.getPrecisionModel()) >= 0)
+      setComputationPrecision(g0.getPrecisionModel());
+    else
+      setComputationPrecision(g1.getPrecisionModel());
+
+    arg = new GeometryGraph[2];
+    arg[0] = new GeometryGraph(0, g0, boundaryNodeRule);
+    arg[1] = new GeometryGraph(1, g1, boundaryNodeRule);
+  }
+
+  protected void setComputationPrecision(PrecisionModel pm)
+  {
+    resultPrecisionModel = pm;
+    li.setPrecisionModel(resultPrecisionModel);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/IsSimpleOp.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/IsSimpleOp.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/IsSimpleOp.java	(revision 28000)
@@ -0,0 +1,230 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import com.vividsolutions.jts.algorithm.BoundaryNodeRule;
+import com.vividsolutions.jts.algorithm.LineIntersector;
+import com.vividsolutions.jts.algorithm.RobustLineIntersector;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.MultiLineString;
+import com.vividsolutions.jts.geom.MultiPoint;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geomgraph.Edge;
+import com.vividsolutions.jts.geomgraph.EdgeIntersection;
+import com.vividsolutions.jts.geomgraph.GeometryGraph;
+import com.vividsolutions.jts.geomgraph.index.SegmentIntersector;
+
+/**
+ * Tests whether a <code>Geometry</code> is simple.
+ * In general, the SFS specification of simplicity
+ * follows the rule:
+ * <ul>
+ *    <li> A Geometry is simple if and only if the only self-intersections are at
+ *    boundary points.
+ * </ul>
+ * This definition relies on the definition of boundary points.
+ * The SFS uses the Mod-2 rule to determine which points are on the boundary of
+ * lineal geometries, but this class supports
+ * using other {@link BoundaryNodeRule}s as well.
+ * <p>
+ * Simplicity is defined for each {@link Geometry} subclass as follows:
+ * <ul>
+ * <li>Valid polygonal geometries are simple by definition, so
+ * <code>isSimple</code> trivially returns true.
+ * (Hint: in order to check if a polygonal geometry has self-intersections,
+ * use {@link Geometry#isValid}).
+ * <li>Linear geometries are simple iff they do not self-intersect at points
+ * other than boundary points. 
+ * (Using the Mod-2 rule, this means that closed linestrings
+ * cannot be touched at their endpoints, since these are
+ * interior points, not boundary points).
+ * <li>Zero-dimensional geometries (points) are simple iff they have no
+ * repeated points.
+ * <li>Empty <code>Geometry</code>s are always simple
+ * </ul>
+ *
+ * @see BoundaryNodeRule
+ *
+ * @version 1.7
+ */
+public class IsSimpleOp
+{
+  private Geometry geom;
+  private boolean isClosedEndpointsInInterior = true;
+
+
+  /**
+   * Creates a simplicity checker using the default SFS Mod-2 Boundary Node Rule
+   *
+   * @param geom the geometry to test
+   */
+  public IsSimpleOp(Geometry geom) {
+    this.geom = geom;
+  }
+
+  /**
+   * Tests whether the geometry is simple.
+   *
+   * @return true if the geometry is simple
+   */
+  public boolean isSimple()
+  {
+    if (geom instanceof LineString) return isSimpleLinearGeometry(geom);
+    if (geom instanceof MultiLineString) return isSimpleLinearGeometry(geom);
+    if (geom instanceof MultiPoint) return isSimpleMultiPoint((MultiPoint) geom);
+    // all other geometry types are simple by definition
+    return true;
+  }
+
+  private boolean isSimpleMultiPoint(MultiPoint mp)
+  {
+    if (mp.isEmpty()) return true;
+    Set points = new TreeSet();
+    for (int i = 0; i < mp.getNumGeometries(); i++) {
+      Point pt = (Point) mp.getGeometryN(i);
+      Coordinate p = pt.getCoordinate();
+      if (points.contains(p)) {
+        return false;
+      }
+      points.add(p);
+    }
+    return true;
+  }
+
+  private boolean isSimpleLinearGeometry(Geometry geom)
+  {
+    if (geom.isEmpty()) return true;
+    GeometryGraph graph = new GeometryGraph(0, geom);
+    LineIntersector li = new RobustLineIntersector();
+    SegmentIntersector si = graph.computeSelfNodes(li, true);
+    // if no self-intersection, must be simple
+    if (! si.hasIntersection()) return true;
+    if (si.hasProperIntersection()) {
+      return false;
+    }
+    if (hasNonEndpointIntersection(graph)) return false;
+    if (isClosedEndpointsInInterior) {
+      if (hasClosedEndpointIntersection(graph)) return false;
+    }
+    return true;
+  }
+
+  /**
+   * For all edges, check if there are any intersections which are NOT at an endpoint.
+   * The Geometry is not simple if there are intersections not at endpoints.
+   */
+  private boolean hasNonEndpointIntersection(GeometryGraph graph)
+  {
+    for (Iterator i = graph.getEdgeIterator(); i.hasNext(); ) {
+      Edge e = (Edge) i.next();
+      int maxSegmentIndex = e.getMaximumSegmentIndex();
+      for (Iterator eiIt = e.getEdgeIntersectionList().iterator(); eiIt.hasNext(); ) {
+        EdgeIntersection ei = (EdgeIntersection) eiIt.next();
+        if (! ei.isEndPoint(maxSegmentIndex)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  private static class EndpointInfo {
+    boolean isClosed;
+    int degree;
+
+    public EndpointInfo()
+    {
+      isClosed = false;
+      degree = 0;
+    }
+
+    public void addEndpoint(boolean isClosed)
+    {
+      degree++;
+      this.isClosed |= isClosed;
+    }
+  }
+
+  /**
+   * Tests that no edge intersection is the endpoint of a closed line.
+   * This ensures that closed lines are not touched at their endpoint,
+   * which is an interior point according to the Mod-2 rule
+   * To check this we compute the degree of each endpoint.
+   * The degree of endpoints of closed lines
+   * must be exactly 2.
+   */
+  private boolean hasClosedEndpointIntersection(GeometryGraph graph)
+  {
+    Map endPoints = new TreeMap();
+    for (Iterator i = graph.getEdgeIterator(); i.hasNext(); ) {
+      Edge e = (Edge) i.next();
+      boolean isClosed = e.isClosed();
+      Coordinate p0 = e.getCoordinate(0);
+      addEndpoint(endPoints, p0, isClosed);
+      Coordinate p1 = e.getCoordinate(e.getNumPoints() - 1);
+      addEndpoint(endPoints, p1, isClosed);
+    }
+
+    for (Iterator i = endPoints.values().iterator(); i.hasNext(); ) {
+      EndpointInfo eiInfo = (EndpointInfo) i.next();
+      if (eiInfo.isClosed && eiInfo.degree != 2) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Add an endpoint to the map, creating an entry for it if none exists
+   */
+  private void addEndpoint(Map endPoints, Coordinate p, boolean isClosed)
+  {
+    EndpointInfo eiInfo = (EndpointInfo) endPoints.get(p);
+    if (eiInfo == null) {
+      eiInfo = new EndpointInfo();
+      endPoints.put(p, eiInfo);
+    }
+    eiInfo.addEndpoint(isClosed);
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/distance/ConnectedElementLocationFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/distance/ConnectedElementLocationFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/distance/ConnectedElementLocationFilter.java	(revision 28000)
@@ -0,0 +1,80 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.distance;
+
+import java.util.*;
+import com.vividsolutions.jts.geom.*;
+
+/**
+ * A ConnectedElementPointFilter extracts a single point
+ * from each connected element in a Geometry
+ * (e.g. a polygon, linestring or point)
+ * and returns them in a list. The elements of the list are 
+ * {@link com.vividsolutions.jts.operation.distance.GeometryLocation}s.
+ *
+ * @version 1.7
+ */
+public class ConnectedElementLocationFilter
+  implements GeometryFilter
+{
+
+  /**
+   * Returns a list containing a point from each Polygon, LineString, and Point
+   * found inside the specified geometry. Thus, if the specified geometry is
+   * not a GeometryCollection, an empty list will be returned. The elements of the list 
+   * are {@link com.vividsolutions.jts.operation.distance.GeometryLocation}s.
+   */  
+  public static List getLocations(Geometry geom)
+  {
+    List locations = new ArrayList();
+    geom.apply(new ConnectedElementLocationFilter(locations));
+    return locations;
+  }
+
+  private List locations;
+
+  ConnectedElementLocationFilter(List locations)
+  {
+    this.locations = locations;
+  }
+
+  public void filter(Geometry geom)
+  {
+    if (geom instanceof Point
+      || geom instanceof LineString
+      || geom instanceof Polygon )
+      locations.add(new Coordinate(geom.getCoordinate()));
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/distance/DistanceOp.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/distance/DistanceOp.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/distance/DistanceOp.java	(revision 28000)
@@ -0,0 +1,330 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.distance;
+
+import java.util.*;
+import com.vividsolutions.jts.geom.*;
+import com.vividsolutions.jts.geom.util.*;
+import com.vividsolutions.jts.algorithm.*;
+
+/**
+ * Find two points on two {@link Geometry}s which lie
+ * within a given distance, or else are the nearest points
+ * on the geometries (in which case this also
+ * provides the distance between the geometries).
+ * <p>
+ * The distance computation also finds a pair of points in the input geometries
+ * which have the minimum distance between them.
+ * If a point lies in the interior of a line segment,
+ * the coordinate computed is a close
+ * approximation to the exact point.
+ * <p>
+ * The algorithms used are straightforward O(n^2)
+ * comparisons.  This worst-case performance could be improved on
+ * by using Voronoi techniques or spatial indexes.
+ *
+ * @version 1.7
+ */
+public class DistanceOp
+{
+
+
+  /**
+   * Test whether two geometries lie within a given distance of each other.
+   * @param g0 a {@link Geometry}
+   * @param g1 another {@link Geometry}
+   * @param distance the distance to test
+   * @return true if g0.distance(g1) <= distance
+   */
+  public static boolean isWithinDistance(Geometry g0, Geometry g1, double distance)
+  {
+    DistanceOp distOp = new DistanceOp(g0, g1, distance);
+    return distOp.distance() <= distance;
+  }
+
+
+  // input
+  private Geometry[] geom;
+  private double terminateDistance = 0.0;
+  // working
+  private PointLocator ptLocator = new PointLocator();
+  private Coordinate[] minDistanceLocation;
+  private double minDistance = Double.MAX_VALUE;
+
+
+  /**
+   * Constructs a DistanceOp that computes the distance and nearest points between
+   * the two specified geometries.
+   * @param g0 a Geometry
+   * @param g1 a Geometry
+   * @param terminateDistance the distance on which to terminate the search
+   */
+  public DistanceOp(Geometry g0, Geometry g1, double terminateDistance)
+  {
+    this.geom = new Geometry[2];
+    geom[0] = g0;
+    geom[1] = g1;
+    this.terminateDistance = terminateDistance;
+  }
+
+  /**
+   * Report the distance between the nearest points on the input geometries.
+   *
+   * @return the distance between the geometries
+   * @return 0 if either input geometry is empty
+   * @throws IllegalArgumentException if either input geometry is null
+   */
+  public double distance()
+  {
+  	if (geom[0] == null || geom[1] == null)
+  		throw new IllegalArgumentException("null geometries are not supported");
+  	if (geom[0].isEmpty() || geom[1].isEmpty()) 
+  		return 0.0;
+  	
+    computeMinDistance();
+    return minDistance;
+  }
+
+
+  private void updateMinDistance(Coordinate[] locGeom, boolean flip)
+  {
+    // if not set then don't update
+    if (locGeom[0] == null) return;
+
+    if (flip) {
+      minDistanceLocation[0] = locGeom[1];
+      minDistanceLocation[1] = locGeom[0];
+    }
+    else {
+      minDistanceLocation[0] = locGeom[0];
+      minDistanceLocation[1] = locGeom[1];
+    }
+  }
+
+  private void computeMinDistance()
+  {
+    // only compute once!
+    if (minDistanceLocation != null) return;
+
+    minDistanceLocation = new Coordinate[2];
+    computeContainmentDistance();
+    if (minDistance <= terminateDistance) return;
+    computeFacetDistance();
+  }
+
+  private void computeContainmentDistance()
+  {
+    Coordinate[] locPtPoly = new Coordinate[2];
+    // test if either geometry has a vertex inside the other
+    computeContainmentDistance(0, locPtPoly);
+    if (minDistance <= terminateDistance) return;
+    computeContainmentDistance(1, locPtPoly);
+  }
+  
+  private void computeContainmentDistance(int polyGeomIndex, Coordinate[] locPtPoly)
+  {
+  	int locationsIndex = 1 - polyGeomIndex;
+    List polys = PolygonExtracter.getPolygons(geom[polyGeomIndex]);
+    if (polys.size() > 0) {
+      List insideLocs = ConnectedElementLocationFilter.getLocations(geom[locationsIndex]);
+      computeContainmentDistance(insideLocs, polys, locPtPoly);
+      if (minDistance <= terminateDistance) {
+      	// this assigment is determined by the order of the args in the computeInside call above
+        minDistanceLocation[locationsIndex] = locPtPoly[0];
+        minDistanceLocation[polyGeomIndex] 	= locPtPoly[1];
+        return;
+      }
+    }	
+  }
+  
+  private void computeContainmentDistance(List locs, List polys, Coordinate[] locPtPoly)
+  {
+    for (int i = 0; i < locs.size(); i++) {
+      Coordinate loc = (Coordinate) locs.get(i);
+      for (int j = 0; j < polys.size(); j++) {
+      	computeContainmentDistance(loc, (Polygon) polys.get(j), locPtPoly);
+        if (minDistance <= terminateDistance) return;
+      }
+    }
+  }
+
+  private void computeContainmentDistance(Coordinate ptLoc,
+      Polygon poly,
+      Coordinate[] locPtPoly)
+  {
+    Coordinate pt = ptLoc;
+    // if pt is not in exterior, distance to geom is 0
+    if (Location.EXTERIOR != ptLocator.locate(pt, poly)) {
+      minDistance = 0.0;
+      locPtPoly[0] = ptLoc;
+      locPtPoly[1] = new Coordinate(pt);
+      return;
+    }
+  }
+
+  /**
+   * Computes distance between facets (lines and points)
+   * of input geometries.
+   *
+   */
+  private void computeFacetDistance()
+  {
+    Coordinate[] locGeom = new Coordinate[2];
+
+    /**
+     * Geometries are not wholely inside, so compute distance from lines and points
+     * of one to lines and points of the other
+     */
+    List lines0 = LinearComponentExtracter.getLines(geom[0]);
+    List lines1 = LinearComponentExtracter.getLines(geom[1]);
+
+    List pts0 = PointExtracter.getPoints(geom[0]);
+    List pts1 = PointExtracter.getPoints(geom[1]);
+
+    // exit whenever minDistance goes LE than terminateDistance
+    computeMinDistanceLines(lines0, lines1, locGeom);
+    updateMinDistance(locGeom, false);
+    if (minDistance <= terminateDistance) return;
+
+    locGeom[0] = null;
+    locGeom[1] = null;
+    computeMinDistanceLinesPoints(lines0, pts1, locGeom);
+    updateMinDistance(locGeom, false);
+    if (minDistance <= terminateDistance) return;
+
+    locGeom[0] = null;
+    locGeom[1] = null;
+    computeMinDistanceLinesPoints(lines1, pts0, locGeom);
+    updateMinDistance(locGeom, true);
+    if (minDistance <= terminateDistance) return;
+
+    locGeom[0] = null;
+    locGeom[1] = null;
+    computeMinDistancePoints(pts0, pts1, locGeom);
+    updateMinDistance(locGeom, false);
+  }
+
+  private void computeMinDistanceLines(List lines0, List lines1, Coordinate[] locGeom)
+  {
+    for (int i = 0; i < lines0.size(); i++) {
+      LineString line0 = (LineString) lines0.get(i);
+      for (int j = 0; j < lines1.size(); j++) {
+        LineString line1 = (LineString) lines1.get(j);
+        computeMinDistance(line0, line1, locGeom);
+        if (minDistance <= terminateDistance) return;
+      }
+    }
+  }
+
+  private void computeMinDistancePoints(List points0, List points1, Coordinate[] locGeom)
+  {
+    for (int i = 0; i < points0.size(); i++) {
+      Point pt0 = (Point) points0.get(i);
+      for (int j = 0; j < points1.size(); j++) {
+        Point pt1 = (Point) points1.get(j);
+        double dist = pt0.getCoordinate().distance(pt1.getCoordinate());
+        if (dist < minDistance) {
+          minDistance = dist;
+          locGeom[0] = new Coordinate(pt0.getCoordinate());
+          locGeom[1] = new Coordinate(pt1.getCoordinate());
+        }
+        if (minDistance <= terminateDistance) return;
+      }
+    }
+  }
+
+  private void computeMinDistanceLinesPoints(List lines, List points,
+      Coordinate[] locGeom)
+  {
+    for (int i = 0; i < lines.size(); i++) {
+      LineString line = (LineString) lines.get(i);
+      for (int j = 0; j < points.size(); j++) {
+        Point pt = (Point) points.get(j);
+        computeMinDistance(line, pt, locGeom);
+        if (minDistance <= terminateDistance) return;
+      }
+    }
+  }
+
+  private void computeMinDistance(LineString line0, LineString line1,
+                                  Coordinate[] locGeom)
+  {
+    if (line0.getEnvelopeInternal().distance(line1.getEnvelopeInternal())
+        > minDistance)
+          return;
+    Coordinate[] coord0 = line0.getCoordinates();
+    Coordinate[] coord1 = line1.getCoordinates();
+      // brute force approach!
+    for (int i = 0; i < coord0.length - 1; i++) {
+      for (int j = 0; j < coord1.length - 1; j++) {
+        double dist = CGAlgorithms.distanceLineLine(
+                                        coord0[i], coord0[i + 1],
+                                        coord1[j], coord1[j + 1] );
+        if (dist < minDistance) {
+          minDistance = dist;
+          LineSegment seg0 = new LineSegment(coord0[i], coord0[i + 1]);
+          LineSegment seg1 = new LineSegment(coord1[j], coord1[j + 1]);
+          Coordinate[] closestPt = seg0.closestPoints(seg1);
+          locGeom[0] = new Coordinate(closestPt[0]);
+          locGeom[1] = new Coordinate(closestPt[1]);
+        }
+        if (minDistance <= terminateDistance) return;
+      }
+    }
+  }
+
+  private void computeMinDistance(LineString line, Point pt,
+                                  Coordinate[] locGeom)
+  {
+    if (line.getEnvelopeInternal().distance(pt.getEnvelopeInternal())
+        > minDistance)
+          return;
+    Coordinate[] coord0 = line.getCoordinates();
+    Coordinate coord = pt.getCoordinate();
+      // brute force approach!
+    for (int i = 0; i < coord0.length - 1; i++) {
+        double dist = CGAlgorithms.distancePointLine(
+            coord, coord0[i], coord0[i + 1] );
+        if (dist < minDistance) {
+          minDistance = dist;
+          LineSegment seg = new LineSegment(coord0[i], coord0[i + 1]);
+          Coordinate segClosestPoint = seg.closestPoint(coord);
+          locGeom[0] = new Coordinate(segClosestPoint);
+          locGeom[1] = new Coordinate(coord);
+        }
+        if (minDistance <= terminateDistance) return;
+
+    }
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/distance/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/distance/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/distance/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides classes for computing the distance between geometries
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/LineBuilder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/LineBuilder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/LineBuilder.java	(revision 28000)
@@ -0,0 +1,180 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.overlay;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geomgraph.DirectedEdge;
+import com.vividsolutions.jts.geomgraph.DirectedEdgeStar;
+import com.vividsolutions.jts.geomgraph.Edge;
+import com.vividsolutions.jts.geomgraph.Label;
+import com.vividsolutions.jts.geomgraph.Node;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * Forms JTS LineStrings out of a the graph of {@link DirectedEdge}s
+ * created by an {@link OverlayOp}.
+ *
+ * @version 1.7
+ */
+public class LineBuilder {
+  private OverlayOp op;
+  private GeometryFactory geometryFactory;
+
+  private List lineEdgesList    = new ArrayList();
+  private List resultLineList   = new ArrayList();
+
+  public LineBuilder(OverlayOp op, GeometryFactory geometryFactory) {
+    this.op = op;
+    this.geometryFactory = geometryFactory;
+  }
+  /**
+   * @return a list of the LineStrings in the result of the specified overlay operation
+   */
+  public List build(int opCode)
+  {
+    findCoveredLineEdges();
+    collectLines(opCode);
+    //labelIsolatedLines(lineEdgesList);
+    buildLines();
+    return resultLineList;
+  }
+  /**
+   * Find and mark L edges which are "covered" by the result area (if any).
+   * L edges at nodes which also have A edges can be checked by checking
+   * their depth at that node.
+   * L edges at nodes which do not have A edges can be checked by doing a
+   * point-in-polygon test with the previously computed result areas.
+   */
+  private void findCoveredLineEdges()
+  {
+    // first set covered for all L edges at nodes which have A edges too
+    for (Iterator nodeit = op.getGraph().getNodes().iterator(); nodeit.hasNext(); ) {
+      Node node = (Node) nodeit.next();
+//node.print(System.out);
+      ((DirectedEdgeStar) node.getEdges()).findCoveredLineEdges();
+    }
+
+    /**
+     * For all L edges which weren't handled by the above,
+     * use a point-in-poly test to determine whether they are covered
+     */
+    for (Iterator it = op.getGraph().getEdgeEnds().iterator(); it.hasNext(); ) {
+      DirectedEdge de = (DirectedEdge) it.next();
+      Edge e = de.getEdge();
+      if (de.isLineEdge() && ! e.isCoveredSet()) {
+        boolean isCovered = op.isCoveredByA(de.getCoordinate());
+        e.setCovered(isCovered);
+      }
+    }
+  }
+
+  private void collectLines(int opCode)
+  {
+    for (Iterator it = op.getGraph().getEdgeEnds().iterator(); it.hasNext(); ) {
+      DirectedEdge de = (DirectedEdge) it.next();
+      collectLineEdge(de, opCode, lineEdgesList);
+      collectBoundaryTouchEdge(de, opCode, lineEdgesList);
+    }
+  }
+
+  /**
+   * Collect line edges which are in the result.
+   * Line edges are in the result if they are not part of
+   * an area boundary, if they are in the result of the overlay operation,
+   * and if they are not covered by a result area.
+   *
+   * @param de the directed edge to test
+   * @param opCode the overlap operation
+   * @param edges the list of included line edges
+   */
+  private void collectLineEdge(DirectedEdge de, int opCode, List edges)
+  {
+    Label label = de.getLabel();
+    Edge e = de.getEdge();
+    // include L edges which are in the result
+    if (de.isLineEdge()) {
+      if (! de.isVisited() && OverlayOp.isResultOfOp(label, opCode) && ! e.isCovered()) {
+//Debug.println("de: " + de.getLabel());
+//Debug.println("edge: " + e.getLabel());
+
+        edges.add(e);
+        de.setVisitedEdge(true);
+      }
+    }
+  }
+
+  /**
+   * Collect edges from Area inputs which should be in the result but
+   * which have not been included in a result area.
+   * This happens ONLY:
+   * <ul>
+   * <li>during an intersection when the boundaries of two
+   * areas touch in a line segment
+   * <li> OR as a result of a dimensional collapse.
+   * </ul>
+   */
+  private void collectBoundaryTouchEdge(DirectedEdge de, int opCode, List edges)
+  {
+    Label label = de.getLabel();
+    if (de.isLineEdge()) return;  // only interested in area edges
+    if (de.isVisited()) return;  // already processed
+    if (de.isInteriorAreaEdge()) return;  // added to handle dimensional collapses
+    if (de.getEdge().isInResult()) return;  // if the edge linework is already included, don't include it again
+
+    // sanity check for labelling of result edgerings
+    Assert.isTrue(! (de.isInResult() || de.getSym().isInResult()) || ! de.getEdge().isInResult());
+
+    // include the linework if it's in the result of the operation
+    if (OverlayOp.isResultOfOp(label, opCode)
+          && opCode == OverlayOp.INTERSECTION)
+    {
+      edges.add(de.getEdge());
+      de.setVisitedEdge(true);
+    }
+  }
+
+  private void buildLines()
+  {
+    for (Iterator it = lineEdgesList.iterator(); it.hasNext(); ) {
+      Edge e = (Edge) it.next();
+        LineString line = geometryFactory.createLineString(e.getCoordinates());
+        resultLineList.add(line);
+        e.setInResult(true);
+    }
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/MaximalEdgeRing.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/MaximalEdgeRing.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/MaximalEdgeRing.java	(revision 28000)
@@ -0,0 +1,109 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.overlay;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geomgraph.DirectedEdge;
+import com.vividsolutions.jts.geomgraph.DirectedEdgeStar;
+import com.vividsolutions.jts.geomgraph.EdgeRing;
+import com.vividsolutions.jts.geomgraph.Node;
+
+/**
+ * A ring of {@link DirectedEdge}s which may contain nodes of degree > 2.
+ * A <tt>MaximalEdgeRing</tt> may represent two different spatial entities:
+ * <ul>
+ * <li>a single polygon possibly containing inversions (if the ring is oriented CW)
+ * <li>a single hole possibly containing exversions (if the ring is oriented CCW)
+ * </ul>
+ * If the MaximalEdgeRing represents a polygon,
+ * the interior of the polygon is strongly connected.
+ * <p>
+ * These are the form of rings used to define polygons under some spatial data models.
+ * However, under the OGC SFS model, {@link MinimalEdgeRing}s are required.
+ * A MaximalEdgeRing can be converted to a list of MinimalEdgeRings using the
+ * {@link #buildMinimalRings() } method.
+ *
+ * @version 1.7
+ * @see com.vividsolutions.jts.operation.overlay.MinimalEdgeRing
+ */
+public class MaximalEdgeRing
+  extends EdgeRing
+{
+
+  public MaximalEdgeRing(DirectedEdge start, GeometryFactory geometryFactory) {
+    super(start, geometryFactory);
+  }
+
+  public DirectedEdge getNext(DirectedEdge de)
+  {
+    return de.getNext();
+  }
+  public void setEdgeRing(DirectedEdge de, EdgeRing er)
+  {
+    de.setEdgeRing(er);
+  }
+
+  /**
+   * For all nodes in this EdgeRing,
+   * link the DirectedEdges at the node to form minimalEdgeRings
+   */
+  public void linkDirectedEdgesForMinimalEdgeRings()
+  {
+    DirectedEdge de = startDe;
+    do {
+      Node node = de.getNode();
+      ((DirectedEdgeStar) node.getEdges()).linkMinimalDirectedEdges(this);
+      de = de.getNext();
+    } while (de != startDe);
+  }
+
+  public List buildMinimalRings()
+  {
+    List minEdgeRings = new ArrayList();
+    DirectedEdge de = startDe;
+    do {
+      if (de.getMinEdgeRing() == null) {
+        EdgeRing minEr = new MinimalEdgeRing(de, geometryFactory);
+        minEdgeRings.add(minEr);
+      }
+      de = de.getNext();
+    } while (de != startDe);
+    return minEdgeRings;
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/MinimalEdgeRing.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/MinimalEdgeRing.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/MinimalEdgeRing.java	(revision 28000)
@@ -0,0 +1,67 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.overlay;
+
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geomgraph.DirectedEdge;
+import com.vividsolutions.jts.geomgraph.Edge;
+import com.vividsolutions.jts.geomgraph.EdgeRing;
+
+/**
+ * A ring of {@link Edge}s with the property that no node
+ * has degree greater than 2.  These are the form of rings required
+ * to represent polygons under the OGC SFS spatial data model.
+ *
+ * @version 1.7
+ * @see com.vividsolutions.jts.operation.overlay.MaximalEdgeRing
+ */
+public class MinimalEdgeRing
+  extends EdgeRing
+{
+
+  public MinimalEdgeRing(DirectedEdge start, GeometryFactory geometryFactory) {
+    super(start, geometryFactory);
+  }
+
+  public DirectedEdge getNext(DirectedEdge de)
+  {
+    return de.getNextMin();
+  }
+  public void setEdgeRing(DirectedEdge de, EdgeRing er)
+  {
+    de.setMinEdgeRing(er);
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/OverlayNodeFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/OverlayNodeFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/OverlayNodeFactory.java	(revision 28000)
@@ -0,0 +1,56 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.overlay;
+
+/**
+ * @version 1.7
+ */
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geomgraph.*;
+
+/**
+ * Creates nodes for use in the {@link PlanarGraph}s constructed during
+ * overlay operations.
+ *
+ * @version 1.7
+ */
+public class OverlayNodeFactory
+  extends NodeFactory
+{
+  public Node createNode(Coordinate coord)
+  {
+    return new Node(coord, new DirectedEdgeStar());
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/OverlayOp.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/OverlayOp.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/OverlayOp.java	(revision 28000)
@@ -0,0 +1,566 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.overlay;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.algorithm.PointLocator;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geomgraph.Depth;
+import com.vividsolutions.jts.geomgraph.DirectedEdge;
+import com.vividsolutions.jts.geomgraph.DirectedEdgeStar;
+import com.vividsolutions.jts.geomgraph.Edge;
+import com.vividsolutions.jts.geomgraph.EdgeList;
+import com.vividsolutions.jts.geomgraph.EdgeNodingValidator;
+import com.vividsolutions.jts.geomgraph.Label;
+import com.vividsolutions.jts.geomgraph.Node;
+import com.vividsolutions.jts.geomgraph.PlanarGraph;
+import com.vividsolutions.jts.geomgraph.Position;
+import com.vividsolutions.jts.operation.GeometryGraphOperation;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * Computes the overlay of two {@link Geometry}s.  The overlay
+ * can be used to determine any boolean combination of the geometries.
+ *
+ * @version 1.7
+ */
+public class OverlayOp
+  extends GeometryGraphOperation
+{
+/**
+ * The spatial functions supported by this class.
+ * These operations implement various boolean combinations of the resultants of the overlay.
+ */
+  public static final int INTERSECTION  = 1;
+  public static final int UNION         = 2;
+  public static final int DIFFERENCE    = 3;
+  public static final int SYMDIFFERENCE = 4;
+
+  public static Geometry overlayOp(Geometry geom0, Geometry geom1, int opCode)
+  {
+    OverlayOp gov = new OverlayOp(geom0, geom1);
+    Geometry geomOv = gov.getResultGeometry(opCode);
+    return geomOv;
+  }
+
+  public static boolean isResultOfOp(Label label, int opCode)
+  {
+    int loc0 = label.getLocation(0);
+    int loc1 = label.getLocation(1);
+    return isResultOfOp(loc0, loc1, opCode);
+  }
+
+  /**
+   * This method will handle arguments of Location.NONE correctly
+   *
+   * @return true if the locations correspond to the opCode
+   */
+  public static boolean isResultOfOp(int loc0, int loc1, int opCode)
+  {
+    if (loc0 == Location.BOUNDARY) loc0 = Location.INTERIOR;
+    if (loc1 == Location.BOUNDARY) loc1 = Location.INTERIOR;
+    switch (opCode) {
+    case INTERSECTION:
+      return loc0 == Location.INTERIOR
+          && loc1 == Location.INTERIOR;
+    case UNION:
+      return loc0 == Location.INTERIOR
+          || loc1 == Location.INTERIOR;
+    case DIFFERENCE:
+      return loc0 == Location.INTERIOR
+          && loc1 != Location.INTERIOR;
+    case SYMDIFFERENCE:
+      return   (     loc0 == Location.INTERIOR &&  loc1 != Location.INTERIOR)
+            || (     loc0 != Location.INTERIOR &&  loc1 == Location.INTERIOR);
+    }
+    return false;
+  }
+
+  private final PointLocator ptLocator = new PointLocator();
+  private GeometryFactory geomFact;
+  private Geometry resultGeom;
+
+  private PlanarGraph graph;
+  private EdgeList edgeList     = new EdgeList();
+
+  private List resultPolyList   = new ArrayList();
+  private List resultLineList   = new ArrayList();
+  private List resultPointList  = new ArrayList();
+
+  public OverlayOp(Geometry g0, Geometry g1) {
+    super(g0, g1);
+    graph = new PlanarGraph(new OverlayNodeFactory());
+    /**
+     * Use factory of primary geometry.
+     * Note that this does NOT handle mixed-precision arguments
+     * where the second arg has greater precision than the first.
+     */
+    geomFact = g0.getFactory();
+  }
+
+  public Geometry getResultGeometry(int funcCode)
+  {
+    computeOverlay(funcCode);
+    return resultGeom;
+  }
+
+  public PlanarGraph getGraph() { return graph; }
+
+  private void computeOverlay(int opCode)
+  {
+    // copy points from input Geometries.
+    // This ensures that any Point geometries
+    // in the input are considered for inclusion in the result set
+    copyPoints(0);
+    copyPoints(1);
+
+    // node the input Geometries
+    arg[0].computeSelfNodes(li, false);
+    arg[1].computeSelfNodes(li, false);
+
+    // compute intersections between edges of the two input geometries
+    arg[0].computeEdgeIntersections(arg[1], li, true);
+
+    List baseSplitEdges = new ArrayList();
+    arg[0].computeSplitEdges(baseSplitEdges);
+    arg[1].computeSplitEdges(baseSplitEdges);
+    // add the noded edges to this result graph
+    insertUniqueEdges(baseSplitEdges);
+
+    computeLabelsFromDepths();
+    replaceCollapsedEdges();
+
+//Debug.println(edgeList);
+
+    /**
+     * Check that the noding completed correctly.
+     * 
+     * This test is slow, but necessary in order to catch robustness failure 
+     * situations.
+     * If an exception is thrown because of a noding failure, 
+     * then snapping will be performed, which will hopefully avoid the problem.
+     * In the future hopefully a faster check can be developed.  
+     * 
+     */
+    EdgeNodingValidator.checkValid(edgeList.getEdges());
+
+    graph.addEdges(edgeList.getEdges());
+    computeLabelling();
+//Debug.printWatch();
+    labelIncompleteNodes();
+//Debug.printWatch();
+//nodeMap.print(System.out);
+
+    /**
+     * The ordering of building the result Geometries is important.
+     * Areas must be built before lines, which must be built before points.
+     * This is so that lines which are covered by areas are not included
+     * explicitly, and similarly for points.
+     */
+    findResultAreaEdges(opCode);
+    cancelDuplicateResultEdges();
+
+    PolygonBuilder polyBuilder = new PolygonBuilder(geomFact);
+    polyBuilder.add(graph);
+    resultPolyList = polyBuilder.getPolygons();
+
+    LineBuilder lineBuilder = new LineBuilder(this, geomFact);
+    resultLineList = lineBuilder.build(opCode);
+
+    PointBuilder pointBuilder = new PointBuilder(this, geomFact);
+    resultPointList = pointBuilder.build(opCode);
+
+    // gather the results from all calculations into a single Geometry for the result set
+    resultGeom = computeGeometry(resultPointList, resultLineList, resultPolyList);
+  }
+
+  private void insertUniqueEdges(List edges)
+  {
+    for (Iterator i = edges.iterator(); i.hasNext(); ) {
+      Edge e = (Edge) i.next();
+      insertUniqueEdge(e);
+    }
+  }
+  /**
+   * Insert an edge from one of the noded input graphs.
+   * Checks edges that are inserted to see if an
+   * identical edge already exists.
+   * If so, the edge is not inserted, but its label is merged
+   * with the existing edge.
+   */
+  protected void insertUniqueEdge(Edge e)
+  {
+//<FIX> MD 8 Oct 03  speed up identical edge lookup
+    // fast lookup
+    Edge existingEdge = edgeList.findEqualEdge(e);
+
+    // If an identical edge already exists, simply update its label
+    if (existingEdge != null) {
+      Label existingLabel = existingEdge.getLabel();
+
+      Label labelToMerge = e.getLabel();
+      // check if new edge is in reverse direction to existing edge
+      // if so, must flip the label before merging it
+      if (! existingEdge.isPointwiseEqual(e)) {
+        labelToMerge = new Label(e.getLabel());
+        labelToMerge.flip();
+      }
+      Depth depth = existingEdge.getDepth();
+      // if this is the first duplicate found for this edge, initialize the depths
+      ///*
+      if (depth.isNull()) {
+        depth.add(existingLabel);
+      }
+      //*/
+      depth.add(labelToMerge);
+      existingLabel.merge(labelToMerge);
+//Debug.print("inserted edge: "); Debug.println(e);
+//Debug.print("existing edge: "); Debug.println(existingEdge);
+
+    }
+    else {  // no matching existing edge was found
+      // add this new edge to the list of edges in this graph
+      //e.setName(name + edges.size());
+      //e.getDepth().add(e.getLabel());
+      edgeList.add(e);
+    }
+  }
+
+  /**
+   * If either of the GeometryLocations for the existing label is
+   * exactly opposite to the one in the labelToMerge,
+   * this indicates a dimensional collapse has happened.
+   * In this case, convert the label for that Geometry to a Line label
+   */
+   /* NOT NEEDED?
+  private void checkDimensionalCollapse(Label labelToMerge, Label existingLabel)
+  {
+    if (existingLabel.isArea() && labelToMerge.isArea()) {
+      for (int i = 0; i < 2; i++) {
+        if (! labelToMerge.isNull(i)
+            &&  labelToMerge.getLocation(i, Position.LEFT)  == existingLabel.getLocation(i, Position.RIGHT)
+            &&  labelToMerge.getLocation(i, Position.RIGHT) == existingLabel.getLocation(i, Position.LEFT) )
+        {
+          existingLabel.toLine(i);
+        }
+      }
+    }
+  }
+  */
+  /**
+   * Update the labels for edges according to their depths.
+   * For each edge, the depths are first normalized.
+   * Then, if the depths for the edge are equal,
+   * this edge must have collapsed into a line edge.
+   * If the depths are not equal, update the label
+   * with the locations corresponding to the depths
+   * (i.e. a depth of 0 corresponds to a Location of EXTERIOR,
+   * a depth of 1 corresponds to INTERIOR)
+   */
+  private void computeLabelsFromDepths()
+  {
+    for (Iterator it = edgeList.iterator(); it.hasNext(); ) {
+      Edge e = (Edge) it.next();
+      Label lbl = e.getLabel();
+      Depth depth = e.getDepth();
+      /**
+       * Only check edges for which there were duplicates,
+       * since these are the only ones which might
+       * be the result of dimensional collapses.
+       */
+      if (! depth.isNull()) {
+        depth.normalize();
+        for (int i = 0; i < 2; i++) {
+          if (! lbl.isNull(i) && lbl.isArea() && ! depth.isNull(i)) {
+          /**
+           * if the depths are equal, this edge is the result of
+           * the dimensional collapse of two or more edges.
+           * It has the same location on both sides of the edge,
+           * so it has collapsed to a line.
+           */
+            if (depth.getDelta(i) == 0) {
+              lbl.toLine(i);
+            }
+            else {
+            /**
+             * This edge may be the result of a dimensional collapse,
+             * but it still has different locations on both sides.  The
+             * label of the edge must be updated to reflect the resultant
+             * side locations indicated by the depth values.
+             */
+              Assert.isTrue(! depth.isNull(i, Position.LEFT), "depth of LEFT side has not been initialized");
+              lbl.setLocation(i, Position.LEFT,   depth.getLocation(i, Position.LEFT));
+              Assert.isTrue(! depth.isNull(i, Position.RIGHT), "depth of RIGHT side has not been initialized");
+              lbl.setLocation(i, Position.RIGHT,  depth.getLocation(i, Position.RIGHT));
+            }
+          }
+        }
+      }
+    }
+  }
+  /**
+   * If edges which have undergone dimensional collapse are found,
+   * replace them with a new edge which is a L edge
+   */
+  private void replaceCollapsedEdges()
+  {
+    List newEdges = new ArrayList();
+    for (Iterator it = edgeList.iterator(); it.hasNext(); ) {
+      Edge e = (Edge) it.next();
+      if (e.isCollapsed()) {
+//Debug.print(e);
+        it.remove();
+        newEdges.add(e.getCollapsedEdge());
+      }
+    }
+    edgeList.addAll(newEdges);
+  }
+  /**
+   * Copy all nodes from an arg geometry into this graph.
+   * The node label in the arg geometry overrides any previously computed
+   * label for that argIndex.
+   * (E.g. a node may be an intersection node with
+   * a previously computed label of BOUNDARY,
+   * but in the original arg Geometry it is actually
+   * in the interior due to the Boundary Determination Rule)
+   */
+  private void copyPoints(int argIndex)
+  {
+    for (Iterator i = arg[argIndex].getNodeIterator(); i.hasNext(); ) {
+      Node graphNode = (Node) i.next();
+      Node newNode = graph.addNode(graphNode.getCoordinate());
+      newNode.setLabel(argIndex, graphNode.getLabel().getLocation(argIndex));
+    }
+  }
+
+  /**
+   * Compute initial labelling for all DirectedEdges at each node.
+   * In this step, DirectedEdges will acquire a complete labelling
+   * (i.e. one with labels for both Geometries)
+   * only if they
+   * are incident on a node which has edges for both Geometries
+   */
+  private void computeLabelling()
+  {
+    for (Iterator nodeit = graph.getNodes().iterator(); nodeit.hasNext(); ) {
+      Node node = (Node) nodeit.next();
+//if (node.getCoordinate().equals(new Coordinate(222, 100)) ) Debug.addWatch(node.getEdges());
+      node.getEdges().computeLabelling(arg);
+    }
+    mergeSymLabels();
+    updateNodeLabelling();
+  }
+  /**
+   * For nodes which have edges from only one Geometry incident on them,
+   * the previous step will have left their dirEdges with no labelling for the other
+   * Geometry.  However, the sym dirEdge may have a labelling for the other
+   * Geometry, so merge the two labels.
+   */
+  private void mergeSymLabels()
+  {
+    for (Iterator nodeit = graph.getNodes().iterator(); nodeit.hasNext(); ) {
+      Node node = (Node) nodeit.next();
+      ((DirectedEdgeStar) node.getEdges()).mergeSymLabels();
+//node.print(System.out);
+    }
+  }
+  private void updateNodeLabelling()
+  {
+    // update the labels for nodes
+    // The label for a node is updated from the edges incident on it
+    // (Note that a node may have already been labelled
+    // because it is a point in one of the input geometries)
+    for (Iterator nodeit = graph.getNodes().iterator(); nodeit.hasNext(); ) {
+      Node node = (Node) nodeit.next();
+      Label lbl = ((DirectedEdgeStar) node.getEdges()).getLabel();
+      node.getLabel().merge(lbl);
+    }
+  }
+
+  /**
+   * Incomplete nodes are nodes whose labels are incomplete.
+   * (e.g. the location for one Geometry is null).
+   * These are either isolated nodes,
+   * or nodes which have edges from only a single Geometry incident on them.
+   *
+   * Isolated nodes are found because nodes in one graph which don't intersect
+   * nodes in the other are not completely labelled by the initial process
+   * of adding nodes to the nodeList.
+   * To complete the labelling we need to check for nodes that lie in the
+   * interior of edges, and in the interior of areas.
+   * <p>
+   * When each node labelling is completed, the labelling of the incident
+   * edges is updated, to complete their labelling as well.
+   */
+  private void labelIncompleteNodes()
+  {
+    for (Iterator ni = graph.getNodes().iterator(); ni.hasNext(); ) {
+      Node n = (Node) ni.next();
+      Label label = n.getLabel();
+      if (n.isIsolated()) {
+        if (label.isNull(0))
+          labelIncompleteNode(n, 0);
+        else
+          labelIncompleteNode(n, 1);
+      }
+      // now update the labelling for the DirectedEdges incident on this node
+      ((DirectedEdgeStar) n.getEdges()).updateLabelling(label);
+//n.print(System.out);
+    }
+    /*
+    int nPoly0 = arg[0].getGeometry().getNumGeometries();
+    int nPoly1 = arg[1].getGeometry().getNumGeometries();
+    System.out.println("# isolated nodes= " + nodeCount 
+    		+ "   # poly[0] = " + nPoly0
+    		+ "   # poly[1] = " + nPoly1);
+    */
+  }
+
+  /**
+   * Label an isolated node with its relationship to the target geometry.
+   */
+  private void labelIncompleteNode(Node n, int targetIndex)
+  {
+    int loc = ptLocator.locate(n.getCoordinate(), arg[targetIndex].getGeometry());
+  	
+  	// MD - 2008-10-24 - experimental for now
+//    int loc = arg[targetIndex].locate(n.getCoordinate());
+    n.getLabel().setLocation(targetIndex, loc);
+  }
+
+  /**
+   * Find all edges whose label indicates that they are in the result area(s),
+   * according to the operation being performed.  Since we want polygon shells to be
+   * oriented CW, choose dirEdges with the interior of the result on the RHS.
+   * Mark them as being in the result.
+   * Interior Area edges are the result of dimensional collapses.
+   * They do not form part of the result area boundary.
+   */
+  private void findResultAreaEdges(int opCode)
+  {
+    for (Iterator it = graph.getEdgeEnds().iterator(); it.hasNext(); ) {
+      DirectedEdge de = (DirectedEdge) it.next();
+    // mark all dirEdges with the appropriate label
+      Label label = de.getLabel();
+      if (label.isArea()
+          && ! de.isInteriorAreaEdge()
+          && isResultOfOp(
+                label.getLocation(0, Position.RIGHT),
+                label.getLocation(1, Position.RIGHT),
+                opCode)) {
+        de.setInResult(true);
+//Debug.print("in result "); Debug.println(de);
+      }
+    }
+  }
+  /**
+   * If both a dirEdge and its sym are marked as being in the result, cancel
+   * them out.
+   */
+  private void cancelDuplicateResultEdges()
+  {
+    // remove any dirEdges whose sym is also included
+    // (they "cancel each other out")
+    for (Iterator it = graph.getEdgeEnds().iterator(); it.hasNext(); ) {
+      DirectedEdge de = (DirectedEdge) it.next();
+      DirectedEdge sym = de.getSym();
+      if (de.isInResult() && sym.isInResult()) {
+        de.setInResult(false);
+        sym.setInResult(false);
+//Debug.print("cancelled "); Debug.println(de); Debug.println(sym);
+      }
+    }
+  }
+  /**
+   * This method is used to decide if a point node should be included in the result or not.
+   *
+   * @return true if the coord point is covered by a result Line or Area geometry
+   */
+  public boolean isCoveredByLA(Coordinate coord)
+  {
+    if (isCovered(coord, resultLineList)) return true;
+    if (isCovered(coord, resultPolyList)) return true;
+    return false;
+  }
+  /**
+   * This method is used to decide if an L edge should be included in the result or not.
+   *
+   * @return true if the coord point is covered by a result Area geometry
+   */
+  public boolean isCoveredByA(Coordinate coord)
+  {
+    if (isCovered(coord, resultPolyList)) return true;
+    return false;
+  }
+  /**
+   * @return true if the coord is located in the interior or boundary of
+   * a geometry in the list.
+   */
+  private boolean isCovered(Coordinate coord, List geomList)
+  {
+    for (Iterator it = geomList.iterator(); it.hasNext(); ) {
+      Geometry geom = (Geometry) it.next();
+      int loc = ptLocator.locate(coord, geom);
+      if (loc != Location.EXTERIOR) return true;
+    }
+    return false;
+  }
+
+  private Geometry computeGeometry( List resultPointList,
+                                        List resultLineList,
+                                        List resultPolyList
+                                        )
+  {
+    List geomList = new ArrayList();
+    // element geometries of the result are always in the order P,L,A
+    geomList.addAll(resultPointList);
+    geomList.addAll(resultLineList);
+    geomList.addAll(resultPolyList);
+    
+    /*
+    if (geomList.isEmpty())
+    	return createEmptyResult(opcode);
+    */
+    
+    // build the most specific geometry possible
+    return geomFact.buildGeometry(geomList);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/PointBuilder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/PointBuilder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/PointBuilder.java	(revision 28000)
@@ -0,0 +1,131 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.overlay;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geomgraph.Label;
+import com.vividsolutions.jts.geomgraph.Node;
+
+/**
+ * Constructs {@link Point}s from the nodes of an overlay graph.
+ * @version 1.7
+ */
+public class PointBuilder {
+  private OverlayOp op;
+  private GeometryFactory geometryFactory;
+  private List resultPointList = new ArrayList();
+
+  public PointBuilder(OverlayOp op, GeometryFactory geometryFactory) {
+    this.op = op;
+    this.geometryFactory = geometryFactory;
+    // ptLocator is never used in this class
+  }
+
+  /**
+   * Computes the Point geometries which will appear in the result,
+   * given the specified overlay operation.
+   *
+   * @return a list of the Points objects in the result
+   */
+  public List build(int opCode)
+  {
+    extractNonCoveredResultNodes(opCode);
+    /**
+     * It can happen that connected result nodes are still covered by
+     * result geometries, so must perform this filter.
+     * (For instance, this can happen during topology collapse).
+     */
+    return resultPointList;
+  }
+
+  /**
+   * Determines nodes which are in the result, and creates {@link Point}s for them.
+   *
+   * This method determines nodes which are candidates for the result via their
+   * labelling and their graph topology.
+   *
+   * @param opCode the overlay operation
+   */
+  private void extractNonCoveredResultNodes(int opCode)
+  {
+    // testing only
+    //if (true) return resultNodeList;
+
+    for (Iterator nodeit = op.getGraph().getNodes().iterator(); nodeit.hasNext(); ) {
+      Node n = (Node) nodeit.next();
+
+      // filter out nodes which are known to be in the result
+      if (n.isInResult())
+        continue;
+      // if an incident edge is in the result, then the node coordinate is included already
+      if (n.isIncidentEdgeInResult())
+        continue;
+      if (n.getEdges().getDegree() == 0 || opCode == OverlayOp.INTERSECTION) {
+
+        /**
+         * For nodes on edges, only INTERSECTION can result in edge nodes being included even
+         * if none of their incident edges are included
+         */
+          Label label = n.getLabel();
+          if (OverlayOp.isResultOfOp(label, opCode)) {
+            filterCoveredNodeToPoint(n);
+          }
+      }
+    }
+    //System.out.println("connectedResultNodes collected = " + connectedResultNodes.size());
+  }
+
+  /**
+   * Converts non-covered nodes to Point objects and adds them to the result.
+   *
+   * A node is covered if it is contained in another element Geometry
+   * with higher dimension (e.g. a node point might be contained in a polygon,
+   * in which case the point can be eliminated from the result).
+   *
+   * @param n the node to test
+   */
+  private void filterCoveredNodeToPoint(Node n)
+  {
+    Coordinate coord = n.getCoordinate();
+    if (! op.isCoveredByLA(coord)) {
+      Point pt = geometryFactory.createPoint(coord);
+      resultPointList.add(pt);
+    }
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/PolygonBuilder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/PolygonBuilder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/PolygonBuilder.java	(revision 28000)
@@ -0,0 +1,286 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.overlay;
+
+import java.util.*;
+import com.vividsolutions.jts.geom.*;
+import com.vividsolutions.jts.algorithm.*;
+import com.vividsolutions.jts.geomgraph.*;
+import com.vividsolutions.jts.util.*;
+
+/**
+ * Forms {@link Polygon}s out of a graph of {@link DirectedEdge}s.
+ * The edges to use are marked as being in the result Area.
+ * <p>
+ *
+ * @version 1.7
+ */
+public class PolygonBuilder {
+
+  private GeometryFactory geometryFactory;
+  //private List dirEdgeList;
+  //private NodeMap nodes;
+  private List shellList        = new ArrayList();
+
+  public PolygonBuilder(GeometryFactory geometryFactory)
+  {
+    this.geometryFactory = geometryFactory;
+  }
+
+  /**
+   * Add a complete graph.
+   * The graph is assumed to contain one or more polygons,
+   * possibly with holes.
+   */
+  public void add(PlanarGraph graph)
+  {
+    add(graph.getEdgeEnds(), graph.getNodes());
+  }
+
+  /**
+   * Add a set of edges and nodes, which form a graph.
+   * The graph is assumed to contain one or more polygons,
+   * possibly with holes.
+   */
+  public void add(Collection dirEdges, Collection nodes)
+  {
+    PlanarGraph.linkResultDirectedEdges(nodes);
+    List maxEdgeRings = buildMaximalEdgeRings(dirEdges);
+    List freeHoleList = new ArrayList();
+    List edgeRings = buildMinimalEdgeRings(maxEdgeRings, shellList, freeHoleList);
+    sortShellsAndHoles(edgeRings, shellList, freeHoleList);
+    placeFreeHoles(shellList, freeHoleList);
+    //Assert: every hole on freeHoleList has a shell assigned to it
+  }
+
+  public List getPolygons()
+  {
+    List resultPolyList = computePolygons(shellList);
+    return resultPolyList;
+  }
+
+
+  /**
+   * for all DirectedEdges in result, form them into MaximalEdgeRings
+   */
+  private List buildMaximalEdgeRings(Collection dirEdges)
+  {
+    List maxEdgeRings     = new ArrayList();
+    for (Iterator it = dirEdges.iterator(); it.hasNext(); ) {
+      DirectedEdge de = (DirectedEdge) it.next();
+      if (de.isInResult() && de.getLabel().isArea() ) {
+        // if this edge has not yet been processed
+        if (de.getEdgeRing() == null) {
+          MaximalEdgeRing er = new MaximalEdgeRing(de, geometryFactory);
+          maxEdgeRings.add(er);
+          er.setInResult();
+//System.out.println("max node degree = " + er.getMaxDegree());
+        }
+      }
+    }
+    return maxEdgeRings;
+  }
+
+  private List buildMinimalEdgeRings(List maxEdgeRings, List shellList, List freeHoleList)
+  {
+    List edgeRings = new ArrayList();
+    for (Iterator it = maxEdgeRings.iterator(); it.hasNext(); ) {
+      MaximalEdgeRing er = (MaximalEdgeRing) it.next();
+      if (er.getMaxNodeDegree() > 2) {
+        er.linkDirectedEdgesForMinimalEdgeRings();
+        List minEdgeRings = er.buildMinimalRings();
+        // at this point we can go ahead and attempt to place holes, if this EdgeRing is a polygon
+        EdgeRing shell = findShell(minEdgeRings);
+        if (shell != null) {
+          placePolygonHoles(shell, minEdgeRings);
+          shellList.add(shell);
+        }
+        else {
+          freeHoleList.addAll(minEdgeRings);
+        }
+      }
+      else {
+        edgeRings.add(er);
+      }
+    }
+    return edgeRings;
+  }
+
+  /**
+   * This method takes a list of MinimalEdgeRings derived from a MaximalEdgeRing,
+   * and tests whether they form a Polygon.  This is the case if there is a single shell
+   * in the list.  In this case the shell is returned.
+   * The other possibility is that they are a series of connected holes, in which case
+   * no shell is returned.
+   *
+   * @return the shell EdgeRing, if there is one
+   * @return null, if all the rings are holes
+   */
+  private EdgeRing findShell(List minEdgeRings)
+  {
+    int shellCount = 0;
+    EdgeRing shell = null;
+    for (Iterator it = minEdgeRings.iterator(); it.hasNext(); ) {
+      EdgeRing er = (MinimalEdgeRing) it.next();
+      if (! er.isHole()) {
+        shell = er;
+        shellCount++;
+      }
+    }
+    Assert.isTrue(shellCount <= 1, "found two shells in MinimalEdgeRing list");
+    return shell;
+  }
+  /**
+   * This method assigns the holes for a Polygon (formed from a list of
+   * MinimalEdgeRings) to its shell.
+   * Determining the holes for a MinimalEdgeRing polygon serves two purposes:
+   * <ul>
+   * <li>it is faster than using a point-in-polygon check later on.
+   * <li>it ensures correctness, since if the PIP test was used the point
+   * chosen might lie on the shell, which might return an incorrect result from the
+   * PIP test
+   * </ul>
+   */
+  private void placePolygonHoles(EdgeRing shell, List minEdgeRings)
+  {
+    for (Iterator it = minEdgeRings.iterator(); it.hasNext(); ) {
+      MinimalEdgeRing er = (MinimalEdgeRing) it.next();
+      if (er.isHole()) {
+        er.setShell(shell);
+      }
+    }
+  }
+  /**
+   * For all rings in the input list,
+   * determine whether the ring is a shell or a hole
+   * and add it to the appropriate list.
+   * Due to the way the DirectedEdges were linked,
+   * a ring is a shell if it is oriented CW, a hole otherwise.
+   */
+  private void sortShellsAndHoles(List edgeRings, List shellList, List freeHoleList)
+  {
+    for (Iterator it = edgeRings.iterator(); it.hasNext(); ) {
+      EdgeRing er = (EdgeRing) it.next();
+//      er.setInResult();
+      if (er.isHole() ) {
+        freeHoleList.add(er);
+      }
+      else {
+        shellList.add(er);
+      }
+    }
+  }
+  /**
+   * This method determines finds a containing shell for all holes
+   * which have not yet been assigned to a shell.
+   * These "free" holes should
+   * all be <b>properly</b> contained in their parent shells, so it is safe to use the
+   * <code>findEdgeRingContaining</code> method.
+   * (This is the case because any holes which are NOT
+   * properly contained (i.e. are connected to their
+   * parent shell) would have formed part of a MaximalEdgeRing
+   * and been handled in a previous step).
+   *
+   * @throws TopologyException if a hole cannot be assigned to a shell
+   */
+  private void placeFreeHoles(List shellList, List freeHoleList)
+  {
+    for (Iterator it = freeHoleList.iterator(); it.hasNext(); ) {
+      EdgeRing hole = (EdgeRing) it.next();
+      // only place this hole if it doesn't yet have a shell
+      if (hole.getShell() == null) {
+        EdgeRing shell = findEdgeRingContaining(hole, shellList);
+        if (shell == null)
+          throw new TopologyException("unable to assign hole to a shell", hole.getCoordinate(0));
+//        Assert.isTrue(shell != null, "unable to assign hole to a shell");
+        hole.setShell(shell);
+      }
+    }
+  }
+
+  /**
+   * Find the innermost enclosing shell EdgeRing containing the argument EdgeRing, if any.
+   * The innermost enclosing ring is the <i>smallest</i> enclosing ring.
+   * The algorithm used depends on the fact that:
+   * <br>
+   *  ring A contains ring B iff envelope(ring A) contains envelope(ring B)
+   * <br>
+   * This routine is only safe to use if the chosen point of the hole
+   * is known to be properly contained in a shell
+   * (which is guaranteed to be the case if the hole does not touch its shell)
+   *
+   * @return containing EdgeRing, if there is one
+   * @return null if no containing EdgeRing is found
+   */
+  private EdgeRing findEdgeRingContaining(EdgeRing testEr, List shellList)
+  {
+    LinearRing testRing = testEr.getLinearRing();
+    Envelope testEnv = testRing.getEnvelopeInternal();
+    Coordinate testPt = testRing.getCoordinateN(0);
+
+    EdgeRing minShell = null;
+    Envelope minEnv = null;
+    for (Iterator it = shellList.iterator(); it.hasNext(); ) {
+      EdgeRing tryShell = (EdgeRing) it.next();
+      LinearRing tryRing = tryShell.getLinearRing();
+      Envelope tryEnv = tryRing.getEnvelopeInternal();
+      if (minShell != null) minEnv = minShell.getLinearRing().getEnvelopeInternal();
+      boolean isContained = false;
+      if (tryEnv.contains(testEnv)
+          && CGAlgorithms.isPointInRing(testPt, tryRing.getCoordinates()) )
+        isContained = true;
+      // check if this new containing ring is smaller than the current minimum ring
+      if (isContained) {
+        if (minShell == null
+            || minEnv.contains(tryEnv)) {
+          minShell = tryShell;
+        }
+      }
+    }
+    return minShell;
+  }
+  private List computePolygons(List shellList)
+  {
+    List resultPolyList   = new ArrayList();
+    // add Polygons for all shells
+    for (Iterator it = shellList.iterator(); it.hasNext(); ) {
+      EdgeRing er = (EdgeRing) it.next();
+      Polygon poly = er.toPolygon(geometryFactory);
+      resultPolyList.add(poly);
+    }
+    return resultPolyList;
+  }
+
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/package.html	(revision 28000)
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Contains classes that perform a topological overlay to compute boolean spatial functions.
+<P>
+The Overlay Algorithm is used in spatial analysis methods for computing set-theoretic 
+operations (boolean combinations) of input {@link Geometry}s. The algorithm for 
+computing the overlay uses the intersection operations supported by topology graphs.  
+To compute an overlay it is necessary to explicitly compute the resultant graph formed 
+by the computed intersections.
+<P>
+The algorithm to compute a set-theoretic spatial analysis method has the following steps:
+<UL>
+  <LI>Build topology graphs of the two input geometries.  For each geometry all 
+      self-intersection nodes are computed and added to the graph.
+  <LI>Compute nodes for all intersections between edges and nodes of the graphs.
+  <LI>Compute the labeling for the computed nodes by merging the labels from the input graphs. 
+  <LI>Compute new edges between the compute intersection nodes.  Label the edges appropriately.
+  <LI>Build the resultant graph from the new nodes and edges.
+  <LI>Compute the labeling for isolated components of the graph.  Add the 
+      isolated components to the resultant graph.
+  <LI>Compute the result of the boolean combination by selecting the node and edges 
+      with the appropriate labels. Polygonize areas and sew linear geometries together.
+</UL>
+
+<h2>Package Specification</h2>
+
+<ul>
+  <li>Java Topology Suite Technical Specifications
+  <li><A HREF="http://www.opengis.org/techno/specs.htm">
+      OpenGIS Simple Features Specification for SQL</A>
+</ul>
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/GeometrySnapper.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/GeometrySnapper.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/GeometrySnapper.java	(revision 28000)
@@ -0,0 +1,166 @@
+package com.vividsolutions.jts.operation.overlay.snap;
+
+import java.util.*;
+import com.vividsolutions.jts.geom.*;
+import com.vividsolutions.jts.geom.util.GeometryTransformer;
+
+/**
+ * Snaps the vertices and segments of a {@link Geometry} 
+ * to another Geometry's vertices.
+ * A snap distance tolerance is used to control where snapping is performed.
+ * Snapping one geometry to another can improve 
+ * robustness for overlay operations by eliminating
+ * nearly-coincident edges 
+ * (which cause problems during noding and intersection calculation).
+ * Too much snapping can result in invalid topology 
+ * beging created, so the number and location of snapped vertices
+ * is decided using heuristics to determine when it 
+ * is safe to snap.
+ * This can result in some potential snaps being omitted, however.
+ *
+ * @author Martin Davis
+ * @version 1.7
+ */
+public class GeometrySnapper
+{
+  private static final double SNAP_PRECISION_FACTOR = 1e-9;
+
+  /**
+   * Estimates the snap tolerance for a Geometry, taking into account its precision model.
+   * 
+   * @param g a Geometry
+   * @return the estimated snap tolerance
+   */
+  public static double computeOverlaySnapTolerance(Geometry g)
+  {
+		double snapTolerance = computeSizeBasedSnapTolerance(g);
+		
+		/**
+		 * Overlay is carried out in the precision model 
+		 * of the two inputs.  
+		 * If this precision model is of type FIXED, then the snap tolerance
+		 * must reflect the precision grid size.  
+		 * Specifically, the snap tolerance should be at least 
+		 * the distance from a corner of a precision grid cell
+		 * to the centre point of the cell.  
+		 */
+		PrecisionModel pm = g.getPrecisionModel();
+		if (pm.getType() == PrecisionModel.FIXED) {
+			double fixedSnapTol = (1 / pm.getScale()) * 2 / 1.415;
+			if (fixedSnapTol > snapTolerance)
+				snapTolerance = fixedSnapTol;
+		}
+		return snapTolerance;
+  }
+
+  public static double computeSizeBasedSnapTolerance(Geometry g)
+  {
+    Envelope env = g.getEnvelopeInternal();
+    double minDimension = Math.min(env.getHeight(), env.getWidth());
+    double snapTol = minDimension * SNAP_PRECISION_FACTOR;
+    return snapTol;
+  }
+
+  public static double computeOverlaySnapTolerance(Geometry g0, Geometry g1)
+  {
+    return Math.min(computeOverlaySnapTolerance(g0), computeOverlaySnapTolerance(g1));
+  }
+
+  /**
+   * Snaps two geometries together with a given tolerance.
+   * 
+   * @param g0 a geometry to snap
+   * @param g1 a geometry to snap
+   * @param snapTolerance the tolerance to use
+   * @return the snapped geometries
+   */
+  public static Geometry[] snap(Geometry g0, Geometry g1, double snapTolerance)
+  {
+    Geometry[] snapGeom = new Geometry[2];
+    GeometrySnapper snapper0 = new GeometrySnapper(g0);
+    snapGeom[0] = snapper0.snapTo(g1, snapTolerance);
+    
+    /**
+     * Snap the second geometry to the snapped first geometry
+     * (this strategy minimizes the number of possible different points in the result)
+     */
+    GeometrySnapper snapper1 = new GeometrySnapper(g1);
+    snapGeom[1] = snapper1.snapTo(snapGeom[0], snapTolerance);
+
+//    System.out.println(snap[0]);
+//    System.out.println(snap[1]);
+    return snapGeom;
+  }
+
+  
+  private Geometry srcGeom;
+
+  /**
+   * Creates a new snapper acting on the given geometry
+   * 
+   * @param srcGeom the geometry to snap
+   */
+  public GeometrySnapper(Geometry srcGeom)
+  {
+    this.srcGeom = srcGeom;
+  }
+
+
+  /**
+   * Snaps the vertices in the component {@link LineString}s
+   * of the source geometry
+   * to the vertices of the given snap geometry.
+   *
+   * @param snapGeom a geometry to snap the source to
+   * @return a new snapped Geometry
+   */
+  public Geometry snapTo(Geometry snapGeom, double snapTolerance)
+  {
+    Coordinate[] snapPts = extractTargetCoordinates(snapGeom);
+
+    SnapTransformer snapTrans = new SnapTransformer(snapTolerance, snapPts);
+    return snapTrans.transform(srcGeom);
+  }
+
+
+  public Coordinate[] extractTargetCoordinates(Geometry g)
+  {
+    // TODO: should do this more efficiently.  Use CoordSeq filter to get points, KDTree for uniqueness & queries
+    Set ptSet = new TreeSet();
+    Coordinate[] pts = g.getCoordinates();
+    for (int i = 0; i < pts.length; i++) {
+      ptSet.add(pts[i]);
+    }
+    return (Coordinate[]) ptSet.toArray(new Coordinate[0]);
+  }
+}
+
+class SnapTransformer
+    extends GeometryTransformer
+{
+  private double snapTolerance;
+  private Coordinate[] snapPts;
+  private boolean isSelfSnap = false;
+
+  SnapTransformer(double snapTolerance, Coordinate[] snapPts)
+  {
+    this.snapTolerance = snapTolerance;
+    this.snapPts = snapPts;
+  }
+
+  protected CoordinateSequence transformCoordinates(CoordinateSequence coords)
+  {
+    Coordinate[] srcPts = coords.toCoordinateArray();
+    Coordinate[] newPts = snapLine(srcPts, snapPts);
+    return factory.getCoordinateSequenceFactory().create(newPts);
+  }
+
+  private Coordinate[] snapLine(Coordinate[] srcPts, Coordinate[] snapPts)
+  {
+    LineStringSnapper snapper = new LineStringSnapper(srcPts, snapTolerance);
+    snapper.setAllowSnappingToSourceVertices(isSelfSnap);
+    return snapper.snapTo(snapPts);
+  }
+}
+
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/LineStringSnapper.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/LineStringSnapper.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/LineStringSnapper.java	(revision 28000)
@@ -0,0 +1,191 @@
+package com.vividsolutions.jts.operation.overlay.snap;
+
+import com.vividsolutions.jts.geom.*;
+
+/**
+ * Snaps the vertices and segments of a {@link LineString} 
+ * to a set of target snap vertices.
+ * A snap distance tolerance is used to control where snapping is performed.
+ * <p>
+ * The implementation handles empty geometry and empty snap vertex sets.
+ *
+ * @author Martin Davis
+ * @version 1.7
+ */
+public class LineStringSnapper
+{
+  private double snapTolerance = 0.0;
+
+  private Coordinate[] srcPts;
+  private LineSegment seg = new LineSegment(); // for reuse during snapping
+  private boolean allowSnappingToSourceVertices = false;
+  private boolean isClosed = false;
+
+  /**
+   * Creates a new snapper using the given points
+   * as source points to be snapped.
+   * 
+   * @param srcPts the points to snap 
+   * @param snapTolerance the snap tolerance to use
+   */
+  public LineStringSnapper(Coordinate[] srcPts, double snapTolerance)
+  {
+    this.srcPts = srcPts;
+    isClosed = isClosed(srcPts);
+    this.snapTolerance = snapTolerance;
+  }
+
+  public void setAllowSnappingToSourceVertices(boolean allowSnappingToSourceVertices)
+  {
+    this.allowSnappingToSourceVertices = allowSnappingToSourceVertices;
+  }
+  private static boolean isClosed(Coordinate[] pts)
+  {
+    if (pts.length <= 1) return false;
+    return pts[0].equals2D(pts[pts.length - 1]);
+  }
+  /**
+   * Snaps the vertices and segments of the source LineString 
+   * to the given set of snap vertices.
+   * 
+   * @param snapPts the vertices to snap to
+   * @return a list of the snapped points
+   */
+  public Coordinate[] snapTo(Coordinate[] snapPts)
+  {
+    CoordinateList coordList = new CoordinateList(srcPts);
+
+    snapVertices(coordList, snapPts);
+    snapSegments(coordList, snapPts);
+
+    Coordinate[] newPts = coordList.toCoordinateArray();
+    return newPts;
+  }
+
+  /**
+   * Snap source vertices to vertices in the target.
+   * 
+   * @param srcCoords the points to snap
+   * @param snapPts the points to snap to
+   */
+  private void snapVertices(CoordinateList srcCoords, Coordinate[] snapPts)
+  {
+    // try snapping vertices
+    // if src is a ring then don't snap final vertex
+    int end = isClosed ? srcCoords.size() - 1 : srcCoords.size();
+    for (int i = 0; i < end; i++) {
+      Coordinate srcPt = (Coordinate) srcCoords.get(i);
+      Coordinate snapVert = findSnapForVertex(srcPt, snapPts);
+      if (snapVert != null) {
+        // update src with snap pt
+        srcCoords.set(i, new Coordinate(snapVert));
+        // keep final closing point in synch (rings only)
+        if (i == 0 && isClosed)
+          srcCoords.set(srcCoords.size() - 1, new Coordinate(snapVert));
+      }
+    }
+  }
+
+  private Coordinate findSnapForVertex(Coordinate pt, Coordinate[] snapPts)
+  {
+    for (int i = 0; i < snapPts.length; i++) {
+      // if point is already equal to a src pt, don't snap
+      if (pt.equals2D(snapPts[i]))
+        return null;
+      if (pt.distance(snapPts[i]) < snapTolerance)
+        return snapPts[i];
+    }
+    return null;
+  }
+
+  /**
+   * Snap segments of the source to nearby snap vertices.
+   * Source segments are "cracked" at a snap vertex.
+   * A single input segment may be snapped several times 
+   * to different snap vertices.
+   * <p>
+   * For each distinct snap vertex, at most one source segment
+   * is snapped to.  This prevents "cracking" multiple segments 
+   * at the same point, which would likely cause 
+   * topology collapse when being used on polygonal linework.
+   * 
+   * @param srcCoords the coordinates of the source linestring to be snapped
+   * @param snapPts the target snap vertices
+   */
+  private void snapSegments(CoordinateList srcCoords, Coordinate[] snapPts)
+  {
+    // guard against empty input
+    if (snapPts.length == 0) return;
+    
+    int distinctPtCount = snapPts.length;
+
+    // check for duplicate snap pts when they are sourced from a linear ring.  
+    // TODO: Need to do this better - need to check *all* snap points for dups (using a Set?)
+    if (snapPts[0].equals2D(snapPts[snapPts.length - 1]))
+        distinctPtCount = snapPts.length - 1;
+
+    for (int i = 0; i < distinctPtCount; i++) {
+      Coordinate snapPt = snapPts[i];
+      int index = findSegmentIndexToSnap(snapPt, srcCoords);
+      /**
+       * If a segment to snap to was found, "crack" it at the snap pt.
+       * The new pt is inserted immediately into the src segment list,
+       * so that subsequent snapping will take place on the modified segments.
+       * Duplicate points are not added.
+       */
+      if (index >= 0) {
+        srcCoords.add(index + 1, new Coordinate(snapPt), false);
+      }
+    }
+  }
+
+
+  /**
+   * Finds a src segment which snaps to (is close to) the given snap point.
+   * <p>
+   * Only a single segment is selected for snapping.
+   * This prevents multiple segments snapping to the same snap vertex,
+   * which would almost certainly cause invalid geometry
+   * to be created.
+   * (The heuristic approach to snapping used here
+   * is really only appropriate when
+   * snap pts snap to a unique spot on the src geometry.)
+   * <p>
+   * Also, if the snap vertex occurs as a vertex in the src coordinate list,
+   * no snapping is performed.
+   * 
+   * @param snapPt the point to snap to
+   * @param srcCoords the source segment coordinates
+   * @return the index of the snapped segment
+   * @return -1 if no segment snaps to the snap point
+   */
+  private int findSegmentIndexToSnap(Coordinate snapPt, CoordinateList srcCoords)
+  {
+    double minDist = Double.MAX_VALUE;
+    int snapIndex = -1;
+    for (int i = 0; i < srcCoords.size() - 1; i++) {
+      seg.p0 = (Coordinate) srcCoords.get(i);
+      seg.p1 = (Coordinate) srcCoords.get(i + 1);
+
+      /**
+       * Check if the snap pt is equal to one of the segment endpoints.
+       * 
+       * If the snap pt is already in the src list, don't snap at all.
+       */
+      if (seg.p0.equals2D(snapPt) || seg.p1.equals2D(snapPt)) {
+        if (allowSnappingToSourceVertices)
+          continue;
+        else
+          return -1;
+      }
+      
+      double dist = seg.distance(snapPt);
+      if (dist < snapTolerance && dist < minDist) {
+        minDist = dist;
+        snapIndex = i;
+      }
+    }
+    return snapIndex;
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/SnapIfNeededOverlayOp.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/SnapIfNeededOverlayOp.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/SnapIfNeededOverlayOp.java	(revision 28000)
@@ -0,0 +1,71 @@
+package com.vividsolutions.jts.operation.overlay.snap;
+
+import com.vividsolutions.jts.geom.*;
+import com.vividsolutions.jts.operation.overlay.OverlayOp;
+
+
+/**
+ * Performs an overlay operation using snapping and enhanced precision
+ * to improve the robustness of the result.
+ * This class only uses snapping
+ * if an error is detected when running the standard JTS overlay code.
+ * Errors detected include thrown exceptions 
+ * (in particular, {@link TopologyException})
+ * and invalid overlay computations.
+ *     
+ * @author Martin Davis
+ * @version 1.7
+ */
+public class SnapIfNeededOverlayOp
+{
+  public static Geometry overlayOp(Geometry g0, Geometry g1, int opCode)
+  {
+  	SnapIfNeededOverlayOp op = new SnapIfNeededOverlayOp(g0, g1);
+  	return op.getResultGeometry(opCode);
+  }
+
+  
+  private Geometry[] geom = new Geometry[2];
+
+  public SnapIfNeededOverlayOp(Geometry g1, Geometry g2)
+  {
+    geom[0] = g1;
+    geom[1] = g2;
+  }
+
+  public Geometry getResultGeometry(int opCode)
+  {
+    Geometry result = null;
+    boolean isSuccess = false;
+    RuntimeException savedException = null;
+    try {
+      result = OverlayOp.overlayOp(geom[0], geom[1], opCode); 
+      boolean isValid = true;
+      // not needed if noding validation is used
+//      boolean isValid = OverlayResultValidator.isValid(geom[0], geom[1], OverlayOp.INTERSECTION, result);
+      if (isValid)
+      	isSuccess = true;
+    
+    }
+    catch (RuntimeException ex) {
+    	savedException = ex;
+    	// ignore this exception, since the operation will be rerun
+//    	System.out.println(ex.getMessage());
+//    	ex.printStackTrace();
+    	//System.out.println(ex.getMessage());
+    	//System.out.println("Geom 0: " + geom[0]);
+    	//System.out.println("Geom 1: " + geom[1]);
+    }
+    if (! isSuccess) {
+    	// this may still throw an exception
+    	// if so, throw the original exception since it has the input coordinates
+    	try {
+    		result = SnapOverlayOp.overlayOp(geom[0], geom[1], opCode);
+    	}
+    	catch (RuntimeException ex) {
+    		throw savedException;
+    	}
+    }
+    return result;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/SnapOverlayOp.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/SnapOverlayOp.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/SnapOverlayOp.java	(revision 28000)
@@ -0,0 +1,90 @@
+package com.vividsolutions.jts.operation.overlay.snap;
+
+import com.vividsolutions.jts.geom.*;
+import com.vividsolutions.jts.operation.overlay.OverlayOp;
+import com.vividsolutions.jts.precision.CommonBitsRemover;
+
+/**
+ * Performs an overlay operation using snapping and enhanced precision
+ * to improve the robustness of the result.
+ * This class <i>always</i> uses snapping.  
+ * This is less performant than the standard JTS overlay code, 
+ * and may even introduce errors which were not present in the original data.
+ * For this reason, this class should only be used 
+ * if the standard overlay code fails to produce a correct result. 
+ *  
+ * @author Martin Davis
+ * @version 1.7
+ */
+public class SnapOverlayOp
+{
+  public static Geometry overlayOp(Geometry g0, Geometry g1, int opCode)
+  {
+  	SnapOverlayOp op = new SnapOverlayOp(g0, g1);
+  	return op.getResultGeometry(opCode);
+  }
+ 
+
+  private Geometry[] geom = new Geometry[2];
+  private double snapTolerance;
+
+  public SnapOverlayOp(Geometry g1, Geometry g2)
+  {
+    geom[0] = g1;
+    geom[1] = g2;
+    computeSnapTolerance();
+  }
+  private void computeSnapTolerance() 
+  {
+		snapTolerance = GeometrySnapper.computeOverlaySnapTolerance(geom[0], geom[1]);
+
+		// System.out.println("Snap tol = " + snapTolerance);
+	}
+
+  public Geometry getResultGeometry(int opCode)
+  {
+//  	Geometry[] selfSnapGeom = new Geometry[] { selfSnap(geom[0]), selfSnap(geom[1])};
+    Geometry[] prepGeom = snap(geom);
+    Geometry result = OverlayOp.overlayOp(prepGeom[0], prepGeom[1], opCode);
+    return prepareResult(result);	
+  }
+    
+  private Geometry[] snap(Geometry[] geom)
+  {
+    Geometry[] remGeom = removeCommonBits(geom);
+  	
+  	// MD - testing only
+//  	Geometry[] remGeom = geom;
+    
+    Geometry[] snapGeom = GeometrySnapper.snap(remGeom[0], remGeom[1], snapTolerance);
+    // MD - may want to do this at some point, but it adds cycles
+//    checkValid(snapGeom[0]);
+//    checkValid(snapGeom[1]);
+
+    /*
+    System.out.println("Snapped geoms: ");
+    System.out.println(snapGeom[0]);
+    System.out.println(snapGeom[1]);
+    */
+    return snapGeom;
+  }
+
+  private Geometry prepareResult(Geometry geom)
+  {
+    cbr.addCommonBits(geom);
+    return geom;
+  }
+
+  private CommonBitsRemover cbr;
+
+  private Geometry[] removeCommonBits(Geometry[] geom)
+  {
+    cbr = new CommonBitsRemover();
+    cbr.add(geom[0]);
+    cbr.add(geom[1]);
+    Geometry remGeom[] = new Geometry[2];
+    remGeom[0] = cbr.removeCommonBits((Geometry) geom[0].clone());
+    remGeom[1] = cbr.removeCommonBits((Geometry) geom[1].clone());
+    return remGeom;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/overlay/snap/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Classes to perform snapping on geometries to prepare them for overlay operations.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides classes for implementing operations on geometries
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/predicate/RectangleContains.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/predicate/RectangleContains.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/predicate/RectangleContains.java	(revision 28000)
@@ -0,0 +1,152 @@
+package com.vividsolutions.jts.operation.predicate;
+
+import com.vividsolutions.jts.geom.*;
+
+/**
+ * Optimized implementation of the <tt>contains</tt> spatial predicate 
+ * for cases where the first {@link Geometry} is a rectangle.
+ * This class works for all input geometries, including
+ * {@link GeometryCollection}s.
+ * <p>
+ * As a further optimization,
+ * this class can be used to test 
+ * many geometries against a single
+ * rectangle in a slightly more efficient way.
+ *
+ * @version 1.7
+ */
+public class RectangleContains {
+
+  /**
+   * Tests whether a rectangle contains a given geometry.
+   * 
+   * @param rectangle a rectangular Polygon
+   * @param b a Geometry of any type
+   * @return true if the geometries intersect
+   */
+  public static boolean contains(Polygon rectangle, Geometry b)
+  {
+    RectangleContains rc = new RectangleContains(rectangle);
+    return rc.contains(b);
+  }
+
+  private Envelope rectEnv;
+
+  /**
+   * Create a new contains computer for two geometries.
+   *
+   * @param rectangle a rectangular geometry
+   */
+  public RectangleContains(Polygon rectangle) {
+    rectEnv = rectangle.getEnvelopeInternal();
+  }
+
+  public boolean contains(Geometry geom)
+  {
+    // the test geometry must be wholly contained in the rectangle envelope
+    if (! rectEnv.contains(geom.getEnvelopeInternal()))
+      return false;
+    
+    /**
+     * Check that geom is not contained entirely in the rectangle boundary.
+     * According to the somewhat odd spec of the SFS, if this
+     * is the case the geometry is NOT contained.
+     */
+    if (isContainedInBoundary(geom))
+      return false;
+    return true;
+  }
+
+  private boolean isContainedInBoundary(Geometry geom)
+  {
+    // polygons can never be wholely contained in the boundary
+    if (geom instanceof Polygon) return false;
+    if (geom instanceof Point) return isPointContainedInBoundary((Point) geom);
+    if (geom instanceof LineString) return isLineStringContainedInBoundary((LineString) geom);
+
+    for (int i = 0; i < geom.getNumGeometries(); i++) {
+      Geometry comp = geom.getGeometryN(i);
+      if (! isContainedInBoundary(comp))
+        return false;
+    }
+    return true;
+  }
+
+  private boolean isPointContainedInBoundary(Point point)
+  {
+    return isPointContainedInBoundary(point.getCoordinate());
+  }
+
+  /**
+   * Tests if a point is contained in the boundary of the target rectangle.
+   * 
+   * @param pt the point to test
+   * @return true if the point is contained in the boundary
+   */
+  private boolean isPointContainedInBoundary(Coordinate pt)
+  {
+    /**
+     * contains = false iff the point is properly contained in the rectangle.
+     * 
+     * This code assumes that the point lies in the rectangle envelope
+     */ 
+    return pt.x == rectEnv.getMinX() 
+    		|| pt.x == rectEnv.getMaxX()
+    		|| pt.y == rectEnv.getMinY()
+    		|| pt.y == rectEnv.getMaxY();
+  }
+
+  /**
+   * Tests if a linestring is completely contained in the boundary of the target rectangle.
+   * @param line the linestring to test
+   * @return true if the linestring is contained in the boundary
+   */
+  private boolean isLineStringContainedInBoundary(LineString line)
+  {
+    CoordinateSequence seq = line.getCoordinateSequence();
+    Coordinate p0 = new Coordinate();
+    Coordinate p1 = new Coordinate();
+    for (int i = 0; i < seq.size() - 1; i++) {
+      seq.getCoordinate(i, p0);
+      seq.getCoordinate(i + 1, p1);
+
+      if (! isLineSegmentContainedInBoundary(p0, p1))
+        return false;
+    }
+    return true;
+  }
+
+  /**
+   * Tests if a line segment is contained in the boundary of the target rectangle.
+   * @param p0 an endpoint of the segment
+   * @param p1 an endpoint of the segment
+   * @return true if the line segment is contained in the boundary
+   */
+  private boolean isLineSegmentContainedInBoundary(Coordinate p0, Coordinate p1)
+  {
+    if (p0.equals(p1))
+      return isPointContainedInBoundary(p0);
+
+    // we already know that the segment is contained in the rectangle envelope
+    if (p0.x == p1.x) {
+      if (p0.x == rectEnv.getMinX() ||
+          p0.x == rectEnv.getMaxX() )
+        return true;
+    }
+    else if (p0.y == p1.y) {
+      if (p0.y == rectEnv.getMinY() ||
+          p0.y == rectEnv.getMaxY() )
+        return true;
+    }
+    /**
+     * Either
+     *   both x and y values are different
+     * or
+     *   one of x and y are the same, but the other ordinate is not the same as a boundary ordinate
+     *
+     * In either case, the segment is not wholely in the boundary
+     */
+    return false;
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/predicate/RectangleIntersects.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/predicate/RectangleIntersects.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/predicate/RectangleIntersects.java	(revision 28000)
@@ -0,0 +1,269 @@
+package com.vividsolutions.jts.operation.predicate;
+
+import java.util.List;
+
+import com.vividsolutions.jts.algorithm.locate.SimplePointInAreaLocator;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geom.util.LinearComponentExtracter;
+import com.vividsolutions.jts.geom.util.ShortCircuitedGeometryVisitor;
+
+/**
+ * Optimized implementation of the <tt>intersects</tt> spatial predicate 
+ * for cases where one {@link Geometry} is a rectangle.
+ * This class works for all input geometries, including
+ * {@link GeometryCollection}s.
+ * <p>
+ * As a further optimization,
+ * this class can be used to test 
+ * many geometries against a single
+ * rectangle in a slightly more efficient way.
+ *
+ * @version 1.7
+ */
+public class RectangleIntersects 
+{
+  /**
+   * Tests whether a rectangle intersects a given geometry.
+   * 
+   * @param rectangle a rectangular Polygon
+   * @param b a Geometry of any type
+   * @return true if the geometries intersect
+   */
+  public static boolean intersects(Polygon rectangle, Geometry b)
+  {
+    RectangleIntersects rp = new RectangleIntersects(rectangle);
+    return rp.intersects(b);
+  }
+
+  private Polygon rectangle;
+  private Envelope rectEnv;
+
+  /**
+   * Create a new intersects computer for a rectangle.
+   *
+   * @param rectangle a rectangular geometry
+   */
+  public RectangleIntersects(Polygon rectangle) {
+    this.rectangle = rectangle;
+    rectEnv = rectangle.getEnvelopeInternal();
+  }
+
+  public boolean intersects(Geometry geom)
+  {
+    if (! rectEnv.intersects(geom.getEnvelopeInternal()))
+        return false;
+    // test envelope relationships
+    EnvelopeIntersectsVisitor visitor = new EnvelopeIntersectsVisitor(rectEnv);
+    visitor.applyTo(geom);
+    if (visitor.intersects())
+      return true;
+
+    // test if any rectangle corner is contained in the target
+    ContainsPointVisitor ecpVisitor = new ContainsPointVisitor(rectangle);
+    ecpVisitor.applyTo(geom);
+    if (ecpVisitor.containsPoint())
+      return true;
+
+    // test if any lines intersect
+    LineIntersectsVisitor liVisitor = new LineIntersectsVisitor(rectangle);
+    liVisitor.applyTo(geom);
+    if (liVisitor.intersects())
+      return true;
+
+    return false;
+  }
+}
+
+/**
+ * Tests whether it can be concluded
+ * that a rectangle intersects a geometry,
+ * based on the locations of the envelope(s) of the geometry.
+ *
+ * @author Martin Davis
+ * @version 1.7
+ */
+class EnvelopeIntersectsVisitor
+    extends ShortCircuitedGeometryVisitor
+{
+  private Envelope rectEnv;
+  private boolean intersects = false;
+
+  public EnvelopeIntersectsVisitor(Envelope rectEnv)
+  {
+    this.rectEnv = rectEnv;
+  }
+
+  /**
+   * Reports whether it can be concluded that an intersection occurs,
+   * or whether further testing is required.
+   *
+   * @return <code>true</code> if an intersection must occur
+   * <code>false</code> if no conclusion can be made
+   */
+  public boolean intersects() { return intersects; }
+
+  protected void visit(Geometry element)
+  {
+    Envelope elementEnv = element.getEnvelopeInternal();
+    // disjoint
+    if (! rectEnv.intersects(elementEnv)) {
+      return;
+    }
+    // fully contained - must intersect
+    if (rectEnv.contains(elementEnv)) {
+      intersects = true;
+      return;
+    }
+    /**
+     * Since the envelopes intersect and the test element is connected,
+     * if the test envelope is completely bisected by an edge of the rectangle
+     * the element and the rectangle must touch
+     * (This is basically an application of the Jordan Curve Theorem).
+     * The alternative situation is that
+     * the test envelope is "on a corner" of the rectangle envelope,
+     * i.e. is not completely bisected.
+     * In this case it is not possible to make a conclusion
+     * about the presence of an intersection.
+     */
+    if (elementEnv.getMinX() >= rectEnv.getMinX()
+        && elementEnv.getMaxX() <= rectEnv.getMaxX()) {
+      intersects = true;
+      return;
+    }
+    if (elementEnv.getMinY() >= rectEnv.getMinY()
+        && elementEnv.getMaxY() <= rectEnv.getMaxY()) {
+      intersects = true;
+      return;
+    }
+  }
+
+  protected boolean isDone() {
+    return intersects == true;
+  }
+}
+
+/**
+ * Tests whether it can be concluded
+ * that a geometry contains a corner point of a rectangle.
+ *
+ * @author Martin Davis
+ * @version 1.7
+ */
+class ContainsPointVisitor
+    extends ShortCircuitedGeometryVisitor
+{
+  private CoordinateSequence rectSeq;
+  private Envelope rectEnv;
+  private boolean containsPoint = false;
+
+  public ContainsPointVisitor(Polygon rectangle)
+  {
+    this.rectSeq = rectangle.getExteriorRing().getCoordinateSequence();
+    rectEnv = rectangle.getEnvelopeInternal();
+  }
+
+  /**
+   * Reports whether it can be concluded that a corner
+   * point of the rectangle is contained in the geometry,
+   * or whether further testing is required.
+   *
+   * @return <code>true</code> if a corner point is contained
+   * <code>false</code> if no conclusion can be made
+   */
+  public boolean containsPoint() { return containsPoint; }
+
+  protected void visit(Geometry geom)
+  {
+    // if test geometry is not polygonal this check is not needed
+    if (! (geom instanceof Polygon))
+      return;
+    
+    // skip if envelopes do not intersect
+    Envelope elementEnv = geom.getEnvelopeInternal();
+    if (! rectEnv.intersects(elementEnv))
+      return;
+    
+    // test each corner of rectangle for inclusion
+    Coordinate rectPt = new Coordinate();
+    for (int i = 0; i < 4; i++) {
+      rectSeq.getCoordinate(i, rectPt);
+      if (! elementEnv.contains(rectPt))
+        continue;
+      // check rect point in poly (rect is known not to touch polygon at this point)
+      if (SimplePointInAreaLocator.containsPointInPolygon(rectPt, (Polygon) geom)) {
+        containsPoint = true;
+        return;
+      }
+    }
+  }
+
+  protected boolean isDone() {
+    return containsPoint == true;
+  }
+}
+
+/**
+ * Tests whether any line segment of a geometry intersects a given rectangle.
+ * Optimizes the algorithm used based on the number of line segments in the
+ * test geometry.
+ *
+ * @author Martin Davis
+ * @version 1.7
+ */
+class LineIntersectsVisitor
+    extends ShortCircuitedGeometryVisitor
+{
+  private LineString rectLine;
+  private Envelope rectEnv;
+  private boolean intersects = false;
+
+  public LineIntersectsVisitor(Polygon rectangle)
+  {
+    this.rectLine = rectangle.getExteriorRing();
+    rectEnv = rectangle.getEnvelopeInternal();
+  }
+
+
+  /**
+   * Reports whether any segment intersection exists.
+   *
+   * @return <code>true</code> if a segment intersection exists
+   * <code>false</code> if no segment intersection exists
+   */
+  public boolean intersects() { return intersects; }
+
+  protected void visit(Geometry geom)
+  {
+    Envelope elementEnv = geom.getEnvelopeInternal();
+    
+    // check for envelope intersection
+    if (! rectEnv.intersects(elementEnv))
+      return;
+    
+    computeSegmentIntersection(geom);
+  }
+
+  private void computeSegmentIntersection(Geometry geom)
+  {
+    // check segment intersection
+    // get all lines from geom (e.g. if it's a multi-ring polygon)
+    List lines = LinearComponentExtracter.getLines(geom);
+    SegmentIntersectionTester si = new SegmentIntersectionTester();
+    boolean hasIntersection = si.hasIntersectionWithLineStrings(rectLine, lines);
+    if (hasIntersection) {
+      intersects = true;
+      return;
+    }
+  }
+
+  protected boolean isDone() {
+    return intersects == true;
+  }
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/predicate/SegmentIntersectionTester.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/predicate/SegmentIntersectionTester.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/predicate/SegmentIntersectionTester.java	(revision 28000)
@@ -0,0 +1,81 @@
+package com.vividsolutions.jts.operation.predicate;
+
+import java.util.*;
+import com.vividsolutions.jts.algorithm.*;
+import com.vividsolutions.jts.geom.*;
+
+/**
+ * Tests if any of the segments in a
+ * {@link LineString} intersect any segment in a set of {@link LineString}s.
+ * <p>
+ * The algorithm is optimized for use when the first input has smaller extent
+ * than the set of test lines.
+ * The code is short-circuited to return as soon an intersection is found.
+ *
+ * @version 1.7
+ */
+public class SegmentIntersectionTester 
+{
+  // for intersection testing, don't need to set precision model
+  private LineIntersector li = new RobustLineIntersector();
+
+  private boolean hasIntersection = false;
+  private Coordinate pt00 = new Coordinate();
+  private Coordinate pt01 = new Coordinate();
+  private Coordinate pt10 = new Coordinate();
+  private Coordinate pt11 = new Coordinate();
+
+  public SegmentIntersectionTester() {
+  }
+
+  public boolean hasIntersectionWithLineStrings(LineString line, List lines)
+  {
+    for (Iterator i = lines.iterator(); i.hasNext(); ) {
+      LineString testLine = (LineString) i.next();
+      //hasIntersection(line, testLine);
+      hasIntersectionWithEnvelopeFilter(line, testLine);
+      if (hasIntersection)
+        break;
+    }
+    return hasIntersection;
+  }
+
+  /**
+   * Tests the segments of a LineString against the segs in 
+   * another LineString for intersection.
+   * Uses the envelope of the query LineString
+   * to filter before testing segments directly.
+   * This is optimized for the case when the query
+   * LineString is a rectangle.
+   * 
+   * Testing shows this is somewhat faster than not checking the envelope.
+   * 
+   * @param line
+   * @param testLine
+   * @return
+   */
+  private boolean hasIntersectionWithEnvelopeFilter(LineString line, LineString testLine) {
+    CoordinateSequence seq0 = line.getCoordinateSequence();
+    CoordinateSequence seq1 = testLine.getCoordinateSequence();
+    Envelope lineEnv = line.getEnvelopeInternal();
+    
+    for (int i = 1; i < seq1.size() && ! hasIntersection; i++) {
+      seq1.getCoordinate(i - 1, pt10);
+      seq1.getCoordinate(i, pt11);
+      
+      // skip test if segment does not intersect query envelope
+      if (! lineEnv.intersects(new Envelope(pt10, pt11)))
+        continue;
+      
+      for (int j = 1; j < seq0.size() && ! hasIntersection; j++) {
+        seq0.getCoordinate(j - 1, pt00);
+        seq0.getCoordinate(j, pt01);
+
+        li.computeIntersection(pt00, pt01, pt10, pt11);
+        if (li.hasIntersection())
+          hasIntersection = true;
+      }
+    }
+    return hasIntersection;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/predicate/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/predicate/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/predicate/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Classes which implement topological predicates optimized for particular kinds of geometries.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/EdgeEndBuilder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/EdgeEndBuilder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/EdgeEndBuilder.java	(revision 28000)
@@ -0,0 +1,171 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.relate;
+
+/**
+ * An EdgeEndBuilder creates EdgeEnds for all the "split edges"
+ * created by the
+ * intersections determined for an Edge.
+ *
+ * @version 1.7
+ */
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geomgraph.Edge;
+import com.vividsolutions.jts.geomgraph.EdgeEnd;
+import com.vividsolutions.jts.geomgraph.EdgeIntersection;
+import com.vividsolutions.jts.geomgraph.EdgeIntersectionList;
+import com.vividsolutions.jts.geomgraph.Label;
+
+/**
+ * Computes the {@link EdgeEnd}s which arise from a noded {@link Edge}.
+ *
+ * @version 1.7
+ */
+public class EdgeEndBuilder {
+
+  public EdgeEndBuilder() {
+  }
+
+  public List computeEdgeEnds(Iterator edges)
+  {
+    List l = new ArrayList();
+    for (Iterator i = edges; i.hasNext(); ) {
+      Edge e = (Edge) i.next();
+      computeEdgeEnds(e, l);
+    }
+    return l;
+  }
+
+  /**
+   * Creates stub edges for all the intersections in this
+   * Edge (if any) and inserts them into the graph.
+   */
+  public void computeEdgeEnds(Edge edge, List l)
+  {
+    EdgeIntersectionList eiList = edge.getEdgeIntersectionList();
+//Debug.print(eiList);
+    // ensure that the list has entries for the first and last point of the edge
+    eiList.addEndpoints();
+
+    Iterator it = eiList.iterator();
+    EdgeIntersection eiPrev = null;
+    EdgeIntersection eiCurr = null;
+    // no intersections, so there is nothing to do
+    if (! it.hasNext()) return;
+    EdgeIntersection eiNext = (EdgeIntersection) it.next();
+    do {
+      eiPrev = eiCurr;
+      eiCurr = eiNext;
+      eiNext = null;
+      if (it.hasNext()) eiNext = (EdgeIntersection) it.next();
+
+      if (eiCurr != null) {
+        createEdgeEndForPrev(edge, l, eiCurr, eiPrev);
+        createEdgeEndForNext(edge, l, eiCurr, eiNext);
+      }
+
+    } while (eiCurr != null);
+
+  }
+
+  /**
+   * Create a EdgeStub for the edge before the intersection eiCurr.
+   * The previous intersection is provided
+   * in case it is the endpoint for the stub edge.
+   * Otherwise, the previous point from the parent edge will be the endpoint.
+   * <br>
+   * eiCurr will always be an EdgeIntersection, but eiPrev may be null.
+   */
+  void createEdgeEndForPrev(
+                      Edge edge,
+                      List l,
+                      EdgeIntersection eiCurr,
+                      EdgeIntersection eiPrev)
+  {
+
+    int iPrev = eiCurr.segmentIndex;
+    if (eiCurr.dist == 0.0) {
+      // if at the start of the edge there is no previous edge
+      if (iPrev == 0) return;
+      iPrev--;
+    }
+    Coordinate pPrev = edge.getCoordinate(iPrev);
+    // if prev intersection is past the previous vertex, use it instead
+    if (eiPrev != null && eiPrev.segmentIndex >= iPrev)
+      pPrev = eiPrev.coord;
+
+    Label label = new Label(edge.getLabel());
+    // since edgeStub is oriented opposite to it's parent edge, have to flip sides for edge label
+    label.flip();
+    EdgeEnd e = new EdgeEnd(edge, eiCurr.coord, pPrev, label);
+//e.print(System.out);  System.out.println();
+    l.add(e);
+  }
+    /**
+     * Create a StubEdge for the edge after the intersection eiCurr.
+     * The next intersection is provided
+     * in case it is the endpoint for the stub edge.
+     * Otherwise, the next point from the parent edge will be the endpoint.
+     * <br>
+     * eiCurr will always be an EdgeIntersection, but eiNext may be null.
+     */
+  void createEdgeEndForNext(
+                      Edge edge,
+                      List l,
+                      EdgeIntersection eiCurr,
+                      EdgeIntersection eiNext)
+  {
+
+    int iNext = eiCurr.segmentIndex + 1;
+    // if there is no next edge there is nothing to do
+    if (iNext >= edge.getNumPoints() && eiNext == null) return;
+
+    Coordinate pNext = edge.getCoordinate(iNext);
+
+    // if the next intersection is in the same segment as the current, use it as the endpoint
+    if (eiNext != null && eiNext.segmentIndex == eiCurr.segmentIndex)
+      pNext = eiNext.coord;
+
+    EdgeEnd e = new EdgeEnd(edge, eiCurr.coord, pNext, new Label(edge.getLabel()));
+//Debug.println(e);
+    l.add(e);
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/EdgeEndBundle.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/EdgeEndBundle.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/EdgeEndBundle.java	(revision 28000)
@@ -0,0 +1,208 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.relate;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.algorithm.BoundaryNodeRule;
+import com.vividsolutions.jts.geom.IntersectionMatrix;
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geomgraph.Edge;
+import com.vividsolutions.jts.geomgraph.EdgeEnd;
+import com.vividsolutions.jts.geomgraph.GeometryGraph;
+import com.vividsolutions.jts.geomgraph.Label;
+import com.vividsolutions.jts.geomgraph.Position;
+
+/**
+ * A collection of {@link EdgeEnd}s which obey the following invariant:
+ * They originate at the same node and have the same direction.
+ *
+ * @version 1.7
+ */
+public class EdgeEndBundle
+  extends EdgeEnd
+{
+//  private BoundaryNodeRule boundaryNodeRule;
+  private List edgeEnds = new ArrayList();
+
+  public EdgeEndBundle(EdgeEnd e)
+  {
+    super(e.getEdge(), e.getCoordinate(), e.getDirectedCoordinate(), new Label(e.getLabel()));
+    insert(e);
+    /*
+    if (boundaryNodeRule != null)
+      this.boundaryNodeRule = boundaryNodeRule;
+    else
+      boundaryNodeRule = BoundaryNodeRule.OGC_SFS_BOUNDARY_RULE;
+    */
+  }
+
+  public Label getLabel() { return label; }
+  public Iterator iterator() { return edgeEnds.iterator(); }
+  public List getEdgeEnds() { return edgeEnds; }
+
+  public void insert(EdgeEnd e)
+  {
+    // Assert: start point is the same
+    // Assert: direction is the same
+    edgeEnds.add(e);
+  }
+  /**
+   * This computes the overall edge label for the set of
+   * edges in this EdgeStubBundle.  It essentially merges
+   * the ON and side labels for each edge.  These labels must be compatible
+   */
+  public void computeLabel(BoundaryNodeRule boundaryNodeRule)
+  {
+    // create the label.  If any of the edges belong to areas,
+    // the label must be an area label
+    boolean isArea = false;
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEnd e = (EdgeEnd) it.next();
+      if (e.getLabel().isArea()) isArea = true;
+    }
+    if (isArea)
+      label = new Label(Location.NONE, Location.NONE, Location.NONE);
+    else
+      label = new Label(Location.NONE);
+
+    // compute the On label, and the side labels if present
+    for (int i = 0; i < 2; i++) {
+      computeLabelOn(i, boundaryNodeRule);
+      if (isArea)
+        computeLabelSides(i);
+    }
+  }
+
+  /**
+   * Compute the overall ON location for the list of EdgeStubs.
+   * (This is essentially equivalent to computing the self-overlay of a single Geometry)
+   * edgeStubs can be either on the boundary (eg Polygon edge)
+   * OR in the interior (e.g. segment of a LineString)
+   * of their parent Geometry.
+   * In addition, GeometryCollections use a {@link BoundaryNodeRule} to determine
+   * whether a segment is on the boundary or not.
+   * Finally, in GeometryCollections it can occur that an edge is both
+   * on the boundary and in the interior (e.g. a LineString segment lying on
+   * top of a Polygon edge.) In this case the Boundary is given precendence.
+   * <br>
+   * These observations result in the following rules for computing the ON location:
+   * <ul>
+   * <li> if there are an odd number of Bdy edges, the attribute is Bdy
+   * <li> if there are an even number >= 2 of Bdy edges, the attribute is Int
+   * <li> if there are any Int edges, the attribute is Int
+   * <li> otherwise, the attribute is NULL.
+   * </ul>
+   */
+  private void computeLabelOn(int geomIndex, BoundaryNodeRule boundaryNodeRule)
+  {
+    // compute the ON location value
+    int boundaryCount = 0;
+    boolean foundInterior = false;
+
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEnd e = (EdgeEnd) it.next();
+      int loc = e.getLabel().getLocation(geomIndex);
+      if (loc == Location.BOUNDARY) boundaryCount++;
+      if (loc == Location.INTERIOR) foundInterior = true;
+    }
+    int loc = Location.NONE;
+    if (foundInterior)  loc = Location.INTERIOR;
+    if (boundaryCount > 0) {
+      loc = GeometryGraph.determineBoundary(boundaryNodeRule, boundaryCount);
+    }
+    label.setLocation(geomIndex, loc);
+
+  }
+  /**
+   * Compute the labelling for each side
+   */
+  private void computeLabelSides(int geomIndex)
+  {
+    computeLabelSide(geomIndex, Position.LEFT);
+    computeLabelSide(geomIndex, Position.RIGHT);
+  }
+
+  /**
+   * To compute the summary label for a side, the algorithm is:
+   *   FOR all edges
+   *     IF any edge's location is INTERIOR for the side, side location = INTERIOR
+   *     ELSE IF there is at least one EXTERIOR attribute, side location = EXTERIOR
+   *     ELSE  side location = NULL
+   *  <br>
+   *  Note that it is possible for two sides to have apparently contradictory information
+   *  i.e. one edge side may indicate that it is in the interior of a geometry, while
+   *  another edge side may indicate the exterior of the same geometry.  This is
+   *  not an incompatibility - GeometryCollections may contain two Polygons that touch
+   *  along an edge.  This is the reason for Interior-primacy rule above - it
+   *  results in the summary label having the Geometry interior on <b>both</b> sides.
+   */
+  private void computeLabelSide(int geomIndex, int side)
+  {
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEnd e = (EdgeEnd) it.next();
+      if (e.getLabel().isArea()) {
+        int loc = e.getLabel().getLocation(geomIndex, side);
+        if (loc == Location.INTERIOR) {
+            label.setLocation(geomIndex, side, Location.INTERIOR);
+            return;
+        }
+        else if (loc == Location.EXTERIOR)
+              label.setLocation(geomIndex, side, Location.EXTERIOR);
+      }
+    }
+  }
+
+  /**
+   * Update the IM with the contribution for the computed label for the EdgeStubs.
+   */
+  void updateIM(IntersectionMatrix im)
+  {
+    Edge.updateIM(label, im);
+  }
+  public void print(PrintStream out)
+  {
+    out.println("EdgeEndBundle--> Label: " + label);
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEnd ee = (EdgeEnd) it.next();
+      ee.print(out);
+      out.println();
+    }
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/EdgeEndBundleStar.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/EdgeEndBundleStar.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/EdgeEndBundleStar.java	(revision 28000)
@@ -0,0 +1,90 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.relate;
+
+import java.util.Iterator;
+
+import com.vividsolutions.jts.geom.IntersectionMatrix;
+import com.vividsolutions.jts.geomgraph.EdgeEnd;
+import com.vividsolutions.jts.geomgraph.EdgeEndStar;
+
+/**
+ * An ordered list of {@link EdgeEndBundle}s around a {@link RelateNode}.
+ * They are maintained in CCW order (starting with the positive x-axis) around the node
+ * for efficient lookup and topology building.
+ *
+ * @version 1.7
+ */
+public class EdgeEndBundleStar
+  extends EdgeEndStar
+{
+  /**
+   * Creates a new empty EdgeEndBundleStar
+   */
+  public EdgeEndBundleStar() {
+  }
+
+  /**
+   * Insert a EdgeEnd in order in the list.
+   * If there is an existing EdgeStubBundle which is parallel, the EdgeEnd is
+   * added to the bundle.  Otherwise, a new EdgeEndBundle is created
+   * to contain the EdgeEnd.
+   * <br>
+   */
+  public void insert(EdgeEnd e)
+  {
+    EdgeEndBundle eb = (EdgeEndBundle) edgeMap.get(e);
+    if (eb == null) {
+      eb = new EdgeEndBundle(e);
+      insertEdgeEnd(e, eb);
+    }
+    else {
+      eb.insert(e);
+    }
+  }
+
+  /**
+   * Update the IM with the contribution for the EdgeStubs around the node.
+   */
+  void updateIM(IntersectionMatrix im)
+  {
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      EdgeEndBundle esb = (EdgeEndBundle) it.next();
+      esb.updateIM(im);
+    }
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateComputer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateComputer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateComputer.java	(revision 28000)
@@ -0,0 +1,383 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.relate;
+
+/**
+ * @version 1.7
+ */
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.algorithm.LineIntersector;
+import com.vividsolutions.jts.algorithm.PointLocator;
+import com.vividsolutions.jts.algorithm.RobustLineIntersector;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.IntersectionMatrix;
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geomgraph.Edge;
+import com.vividsolutions.jts.geomgraph.EdgeEnd;
+import com.vividsolutions.jts.geomgraph.EdgeIntersection;
+import com.vividsolutions.jts.geomgraph.GeometryGraph;
+import com.vividsolutions.jts.geomgraph.Label;
+import com.vividsolutions.jts.geomgraph.Node;
+import com.vividsolutions.jts.geomgraph.NodeMap;
+import com.vividsolutions.jts.geomgraph.index.SegmentIntersector;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * Computes the topological relationship between two Geometries.
+ * <p>
+ * RelateComputer does not need to build a complete graph structure to compute
+ * the IntersectionMatrix.  The relationship between the geometries can
+ * be computed by simply examining the labelling of edges incident on each node.
+ * <p>
+ * RelateComputer does not currently support arbitrary GeometryCollections.
+ * This is because GeometryCollections can contain overlapping Polygons.
+ * In order to correct compute relate on overlapping Polygons, they
+ * would first need to be noded and merged (if not explicitly, at least
+ * implicitly).
+ *
+ * @version 1.7
+ */
+public class RelateComputer
+{
+  private LineIntersector li = new RobustLineIntersector();
+  private PointLocator ptLocator = new PointLocator();
+  private GeometryGraph[] arg;  // the arg(s) of the operation
+  private NodeMap nodes = new NodeMap(new RelateNodeFactory());
+  // this intersection matrix will hold the results compute for the relate
+  private ArrayList isolatedEdges = new ArrayList();
+
+  // the intersection point found (if any)
+
+  public RelateComputer(GeometryGraph[] arg) {
+    this.arg = arg;
+  }
+
+  public IntersectionMatrix computeIM()
+  {
+    IntersectionMatrix im = new IntersectionMatrix();
+    // since Geometries are finite and embedded in a 2-D space, the EE element must always be 2
+    im.set(Location.EXTERIOR, Location.EXTERIOR, 2);
+
+    // if the Geometries don't overlap there is nothing to do
+    if (! arg[0].getGeometry().getEnvelopeInternal().intersects(
+            arg[1].getGeometry().getEnvelopeInternal()) ) {
+      computeDisjointIM(im);
+      return im;
+    }
+    arg[0].computeSelfNodes(li, false);
+    arg[1].computeSelfNodes(li, false);
+
+    // compute intersections between edges of the two input geometries
+    SegmentIntersector intersector = arg[0].computeEdgeIntersections(arg[1], li, false);
+//System.out.println("computeIM: # segment intersection tests: " + intersector.numTests);
+    computeIntersectionNodes(0);
+    computeIntersectionNodes(1);
+    /**
+     * Copy the labelling for the nodes in the parent Geometries.  These override
+     * any labels determined by intersections between the geometries.
+     */
+    copyNodesAndLabels(0);
+    copyNodesAndLabels(1);
+
+    // complete the labelling for any nodes which only have a label for a single geometry
+//Debug.addWatch(nodes.find(new Coordinate(110, 200)));
+//Debug.printWatch();
+    labelIsolatedNodes();
+//Debug.printWatch();
+
+    // If a proper intersection was found, we can set a lower bound on the IM.
+    computeProperIntersectionIM(intersector, im);
+
+    /**
+     * Now process improper intersections
+     * (eg where one or other of the geometries has a vertex at the intersection point)
+     * We need to compute the edge graph at all nodes to determine the IM.
+     */
+
+    // build EdgeEnds for all intersections
+    EdgeEndBuilder eeBuilder = new EdgeEndBuilder();
+    List ee0 = eeBuilder.computeEdgeEnds(arg[0].getEdgeIterator());
+    insertEdgeEnds(ee0);
+    List ee1 = eeBuilder.computeEdgeEnds(arg[1].getEdgeIterator());
+    insertEdgeEnds(ee1);
+
+//Debug.println("==== NodeList ===");
+//Debug.print(nodes);
+
+    labelNodeEdges();
+
+  /**
+   * Compute the labeling for isolated components
+   * <br>
+   * Isolated components are components that do not touch any other components in the graph.
+   * They can be identified by the fact that they will
+   * contain labels containing ONLY a single element, the one for their parent geometry.
+   * We only need to check components contained in the input graphs, since
+   * isolated components will not have been replaced by new components formed by intersections.
+   */
+//debugPrintln("Graph A isolated edges - ");
+    labelIsolatedEdges(0, 1);
+//debugPrintln("Graph B isolated edges - ");
+    labelIsolatedEdges(1, 0);
+
+    // update the IM from all components
+    updateIM(im);
+    return im;
+  }
+
+  private void insertEdgeEnds(List ee)
+  {
+    for (Iterator i = ee.iterator(); i.hasNext(); ) {
+      EdgeEnd e = (EdgeEnd) i.next();
+      nodes.add(e);
+    }
+  }
+
+  private void computeProperIntersectionIM(SegmentIntersector intersector, IntersectionMatrix im)
+  {
+    // If a proper intersection is found, we can set a lower bound on the IM.
+    int dimA = arg[0].getGeometry().getDimension();
+    int dimB = arg[1].getGeometry().getDimension();
+    boolean hasProper         = intersector.hasProperIntersection();
+    boolean hasProperInterior = intersector.hasProperInteriorIntersection();
+
+      // For Geometry's of dim 0 there can never be proper intersections.
+
+      /**
+       * If edge segments of Areas properly intersect, the areas must properly overlap.
+       */
+    if (dimA == 2 && dimB == 2) {
+      if (hasProper) im.setAtLeast("212101212");
+    }
+      /**
+       * If an Line segment properly intersects an edge segment of an Area,
+       * it follows that the Interior of the Line intersects the Boundary of the Area.
+       * If the intersection is a proper <i>interior</i> intersection, then
+       * there is an Interior-Interior intersection too.
+       * Note that it does not follow that the Interior of the Line intersects the Exterior
+       * of the Area, since there may be another Area component which contains the rest of the Line.
+       */
+    else if (dimA == 2 && dimB == 1) {
+      if (hasProper)          im.setAtLeast("FFF0FFFF2");
+      if (hasProperInterior)  im.setAtLeast("1FFFFF1FF");
+    }
+    else if (dimA == 1 && dimB == 2) {
+      if (hasProper)          im.setAtLeast("F0FFFFFF2");
+      if (hasProperInterior)  im.setAtLeast("1F1FFFFFF");
+    }
+    /* If edges of LineStrings properly intersect *in an interior point*, all
+        we can deduce is that
+        the interiors intersect.  (We can NOT deduce that the exteriors intersect,
+        since some other segments in the geometries might cover the points in the
+        neighbourhood of the intersection.)
+        It is important that the point be known to be an interior point of
+        both Geometries, since it is possible in a self-intersecting geometry to
+        have a proper intersection on one segment that is also a boundary point of another segment.
+    */
+    else if (dimA == 1 && dimB == 1) {
+      if (hasProperInterior)    im.setAtLeast("0FFFFFFFF");
+    }
+  }
+
+    /**
+     * Copy all nodes from an arg geometry into this graph.
+     * The node label in the arg geometry overrides any previously computed
+     * label for that argIndex.
+     * (E.g. a node may be an intersection node with
+     * a computed label of BOUNDARY,
+     * but in the original arg Geometry it is actually
+     * in the interior due to the Boundary Determination Rule)
+     */
+  private void copyNodesAndLabels(int argIndex)
+  {
+    for (Iterator i = arg[argIndex].getNodeIterator(); i.hasNext(); ) {
+      Node graphNode = (Node) i.next();
+      Node newNode = nodes.addNode(graphNode.getCoordinate());
+      newNode.setLabel(argIndex, graphNode.getLabel().getLocation(argIndex));
+//node.print(System.out);
+    }
+  }
+  /**
+   * Insert nodes for all intersections on the edges of a Geometry.
+   * Label the created nodes the same as the edge label if they do not already have a label.
+   * This allows nodes created by either self-intersections or
+   * mutual intersections to be labelled.
+   * Endpoint nodes will already be labelled from when they were inserted.
+   */
+  private void computeIntersectionNodes(int argIndex)
+  {
+    for (Iterator i = arg[argIndex].getEdgeIterator(); i.hasNext(); ) {
+      Edge e = (Edge) i.next();
+      int eLoc = e.getLabel().getLocation(argIndex);
+      for (Iterator eiIt = e.getEdgeIntersectionList().iterator(); eiIt.hasNext(); ) {
+        EdgeIntersection ei = (EdgeIntersection) eiIt.next();
+        RelateNode n = (RelateNode) nodes.addNode(ei.coord);
+        if (eLoc == Location.BOUNDARY)
+          n.setLabelBoundary(argIndex);
+        else {
+          if (n.getLabel().isNull(argIndex))
+            n.setLabel(argIndex, Location.INTERIOR);
+        }
+//Debug.println(n);
+      }
+    }
+  }
+
+  /**
+   * If the Geometries are disjoint, we need to enter their dimension and
+   * boundary dimension in the Ext rows in the IM
+   */
+  private void computeDisjointIM(IntersectionMatrix im)
+  {
+    Geometry ga = arg[0].getGeometry();
+    if (! ga.isEmpty()) {
+      im.set(Location.INTERIOR, Location.EXTERIOR, ga.getDimension());
+      im.set(Location.BOUNDARY, Location.EXTERIOR, ga.getBoundaryDimension());
+    }
+    Geometry gb = arg[1].getGeometry();
+    if (! gb.isEmpty()) {
+      im.set(Location.EXTERIOR, Location.INTERIOR, gb.getDimension());
+      im.set(Location.EXTERIOR, Location.BOUNDARY, gb.getBoundaryDimension());
+    }
+  }
+
+  private void labelNodeEdges()
+  {
+    for (Iterator ni = nodes.iterator(); ni.hasNext(); ) {
+      RelateNode node = (RelateNode) ni.next();
+      node.getEdges().computeLabelling(arg);
+//Debug.print(node.getEdges());
+//node.print(System.out);
+    }
+  }
+
+  /**
+   * update the IM with the sum of the IMs for each component
+   */
+  private void updateIM(IntersectionMatrix im)
+  {
+//Debug.println(im);
+    for (Iterator ei = isolatedEdges.iterator(); ei.hasNext(); ) {
+      Edge e = (Edge) ei.next();
+      e.updateIM(im);
+//Debug.println(im);
+    }
+    for (Iterator ni = nodes.iterator(); ni.hasNext(); ) {
+      RelateNode node = (RelateNode) ni.next();
+      node.updateIM(im);
+//Debug.println(im);
+      node.updateIMFromEdges(im);
+//Debug.println(im);
+//node.print(System.out);
+    }
+  }
+
+  /**
+   * Processes isolated edges by computing their labelling and adding them
+   * to the isolated edges list.
+   * Isolated edges are guaranteed not to touch the boundary of the target (since if they
+   * did, they would have caused an intersection to be computed and hence would
+   * not be isolated)
+   */
+  private void labelIsolatedEdges(int thisIndex, int targetIndex)
+  {
+    for (Iterator ei = arg[thisIndex].getEdgeIterator(); ei.hasNext(); ) {
+      Edge e = (Edge) ei.next();
+      if (e.isIsolated()) {
+        labelIsolatedEdge(e, targetIndex, arg[targetIndex].getGeometry());
+        isolatedEdges.add(e);
+      }
+    }
+  }
+  /**
+   * Label an isolated edge of a graph with its relationship to the target geometry.
+   * If the target has dim 2 or 1, the edge can either be in the interior or the exterior.
+   * If the target has dim 0, the edge must be in the exterior
+   */
+  private void labelIsolatedEdge(Edge e, int targetIndex, Geometry target)
+  {
+    // this won't work for GeometryCollections with both dim 2 and 1 geoms
+    if ( target.getDimension() > 0) {
+    // since edge is not in boundary, may not need the full generality of PointLocator?
+    // Possibly should use ptInArea locator instead?  We probably know here
+    // that the edge does not touch the bdy of the target Geometry
+      int loc = ptLocator.locate(e.getCoordinate(), target);
+      e.getLabel().setAllLocations(targetIndex, loc);
+    }
+    else {
+      e.getLabel().setAllLocations(targetIndex, Location.EXTERIOR);
+    }
+//System.out.println(e.getLabel());
+  }
+
+  /**
+   * Isolated nodes are nodes whose labels are incomplete
+   * (e.g. the location for one Geometry is null).
+   * This is the case because nodes in one graph which don't intersect
+   * nodes in the other are not completely labelled by the initial process
+   * of adding nodes to the nodeList.
+   * To complete the labelling we need to check for nodes that lie in the
+   * interior of edges, and in the interior of areas.
+   */
+  private void labelIsolatedNodes()
+  {
+    for (Iterator ni = nodes.iterator(); ni.hasNext(); ) {
+      Node n = (Node) ni.next();
+      Label label = n.getLabel();
+      // isolated nodes should always have at least one geometry in their label
+      Assert.isTrue(label.getGeometryCount() > 0, "node with empty label found");
+      if (n.isIsolated()) {
+        if (label.isNull(0))
+          labelIsolatedNode(n, 0);
+        else
+          labelIsolatedNode(n, 1);
+      }
+    }
+  }
+
+  /**
+   * Label an isolated node with its relationship to the target geometry.
+   */
+  private void labelIsolatedNode(Node n, int targetIndex)
+  {
+    int loc = ptLocator.locate(n.getCoordinate(), arg[targetIndex].getGeometry());
+    n.getLabel().setAllLocations(targetIndex, loc);
+//debugPrintln(n.getLabel());
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateNode.java	(revision 28000)
@@ -0,0 +1,80 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.relate;
+
+/**
+ * A RelateNode is a Node that maintains a list of EdgeStubs
+ * for the edges that are incident on it.
+ *
+ * @version 1.7
+ */
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.IntersectionMatrix;
+import com.vividsolutions.jts.geomgraph.EdgeEndStar;
+import com.vividsolutions.jts.geomgraph.Node;
+
+/**
+ * Represents a node in the topological graph used to compute spatial relationships.
+ *
+ * @version 1.7
+ */
+public class RelateNode
+  extends Node
+{
+
+  public RelateNode(Coordinate coord, EdgeEndStar edges)
+  {
+    super(coord, edges);
+  }
+
+  /**
+   * Update the IM with the contribution for this component.
+   * A component only contributes if it has a labelling for both parent geometries
+   */
+  protected void computeIM(IntersectionMatrix im)
+  {
+    im.setAtLeastIfValid(label.getLocation(0), label.getLocation(1), 0);
+  }
+  /**
+   * Update the IM with the contribution for the EdgeEnds incident on this node.
+   */
+  void updateIMFromEdges(IntersectionMatrix im)
+  {
+    ((EdgeEndBundleStar) edges).updateIM(im);
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateNodeFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateNodeFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateNodeFactory.java	(revision 28000)
@@ -0,0 +1,54 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.relate;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geomgraph.Node;
+import com.vividsolutions.jts.geomgraph.NodeFactory;
+import com.vividsolutions.jts.geomgraph.NodeMap;
+
+/**
+ * Used by the {@link NodeMap} in a {@link RelateNodeGraph} to create {@link RelateNode}s.
+ *
+ * @version 1.7
+ */
+public class RelateNodeFactory
+  extends NodeFactory
+{
+  public Node createNode(Coordinate coord)
+  {
+    return new RelateNode(coord, new EdgeEndBundleStar());
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateNodeGraph.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateNodeGraph.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateNodeGraph.java	(revision 28000)
@@ -0,0 +1,156 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.relate;
+
+/**
+ * @version 1.7
+ */
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geomgraph.Edge;
+import com.vividsolutions.jts.geomgraph.EdgeEnd;
+import com.vividsolutions.jts.geomgraph.EdgeIntersection;
+import com.vividsolutions.jts.geomgraph.GeometryGraph;
+import com.vividsolutions.jts.geomgraph.Node;
+import com.vividsolutions.jts.geomgraph.NodeMap;
+
+/**
+ * Implements the simple graph of Nodes and EdgeEnd which is all that is
+ * required to determine topological relationships between Geometries.
+ * Also supports building a topological graph of a single Geometry, to
+ * allow verification of valid topology.
+ * <p>
+ * It is <b>not</b> necessary to create a fully linked
+ * PlanarGraph to determine relationships, since it is sufficient
+ * to know how the Geometries interact locally around the nodes.
+ * In fact, this is not even feasible, since it is not possible to compute
+ * exact intersection points, and hence the topology around those nodes
+ * cannot be computed robustly.
+ * The only Nodes that are created are for improper intersections;
+ * that is, nodes which occur at existing vertices of the Geometries.
+ * Proper intersections (e.g. ones which occur between the interior of line segments)
+ * have their topology determined implicitly, without creating a Node object
+ * to represent them.
+ *
+ * @version 1.7
+ */
+public class RelateNodeGraph {
+
+  private NodeMap nodes = new NodeMap(new RelateNodeFactory());
+
+  public RelateNodeGraph() {
+  }
+
+  public Iterator getNodeIterator() { return nodes.iterator(); }
+
+  public void build(GeometryGraph geomGraph)
+  {
+      // compute nodes for intersections between previously noded edges
+    computeIntersectionNodes(geomGraph, 0);
+    /**
+     * Copy the labelling for the nodes in the parent Geometry.  These override
+     * any labels determined by intersections.
+     */
+    copyNodesAndLabels(geomGraph, 0);
+
+    /**
+     * Build EdgeEnds for all intersections.
+     */
+    EdgeEndBuilder eeBuilder = new EdgeEndBuilder();
+    List eeList = eeBuilder.computeEdgeEnds(geomGraph.getEdgeIterator());
+    insertEdgeEnds(eeList);
+
+//Debug.println("==== NodeList ===");
+//Debug.print(nodes);
+  }
+
+  /**
+   * Insert nodes for all intersections on the edges of a Geometry.
+   * Label the created nodes the same as the edge label if they do not already have a label.
+   * This allows nodes created by either self-intersections or
+   * mutual intersections to be labelled.
+   * Endpoint nodes will already be labelled from when they were inserted.
+   * <p>
+   * Precondition: edge intersections have been computed.
+   */
+  public void computeIntersectionNodes(GeometryGraph geomGraph, int argIndex)
+  {
+    for (Iterator edgeIt = geomGraph.getEdgeIterator(); edgeIt.hasNext(); ) {
+      Edge e = (Edge) edgeIt.next();
+      int eLoc = e.getLabel().getLocation(argIndex);
+      for (Iterator eiIt = e.getEdgeIntersectionList().iterator(); eiIt.hasNext(); ) {
+        EdgeIntersection ei = (EdgeIntersection) eiIt.next();
+        RelateNode n = (RelateNode) nodes.addNode(ei.coord);
+        if (eLoc == Location.BOUNDARY)
+          n.setLabelBoundary(argIndex);
+        else {
+          if (n.getLabel().isNull(argIndex))
+            n.setLabel(argIndex, Location.INTERIOR);
+        }
+//Debug.println(n);
+      }
+    }
+  }
+
+    /**
+     * Copy all nodes from an arg geometry into this graph.
+     * The node label in the arg geometry overrides any previously computed
+     * label for that argIndex.
+     * (E.g. a node may be an intersection node with
+     * a computed label of BOUNDARY,
+     * but in the original arg Geometry it is actually
+     * in the interior due to the Boundary Determination Rule)
+     */
+  public void copyNodesAndLabels(GeometryGraph geomGraph, int argIndex)
+  {
+    for (Iterator nodeIt = geomGraph.getNodeIterator(); nodeIt.hasNext(); ) {
+      Node graphNode = (Node) nodeIt.next();
+      Node newNode = nodes.addNode(graphNode.getCoordinate());
+      newNode.setLabel(argIndex, graphNode.getLabel().getLocation(argIndex));
+//node.print(System.out);
+    }
+  }
+
+  public void insertEdgeEnds(List ee)
+  {
+    for (Iterator i = ee.iterator(); i.hasNext(); ) {
+      EdgeEnd e = (EdgeEnd) i.next();
+      nodes.add(e);
+    }
+  }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateOp.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateOp.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/RelateOp.java	(revision 28000)
@@ -0,0 +1,103 @@
+
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.relate;
+
+/**
+ * @version 1.7
+ */
+
+import com.vividsolutions.jts.algorithm.BoundaryNodeRule;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.IntersectionMatrix;
+import com.vividsolutions.jts.operation.GeometryGraphOperation;
+
+/**
+ * Implements the SFS <tt>relate()</tt> operation on two {@link Geometry}s.
+ * This class supports specifying a custom {@link BoundaryNodeRule}
+ * to be used during the relate computation.
+ * <p>
+ * <b>Note:</b> custom Boundary Node Rules do not (currently)
+ * affect the results of other Geometry methods (such
+ * as {@link Geometry#getBoundary}.  The results of
+ * these methods may not be consistent with the relationship computed by
+ * a custom Boundary Node Rule.
+ *
+ * @version 1.7
+ */
+public class RelateOp
+  extends GeometryGraphOperation
+{
+  /**
+   * Computes the {@link IntersectionMatrix} for the spatial relationship
+   * between two {@link Geometry}s, using the default (OGC SFS) Boundary Node Rule
+   *
+   * @param a a Geometry to test
+   * @param b a Geometry to test
+   * @return the IntersectonMatrix for the spatial relationship between the geometries
+   */
+  public static IntersectionMatrix relate(Geometry a, Geometry b)
+  {
+    RelateOp relOp = new RelateOp(a, b);
+    IntersectionMatrix im = relOp.getIntersectionMatrix();
+    return im;
+  }
+
+  private RelateComputer relate;
+
+  /**
+   * Creates a new Relate operation, using the default (OGC SFS) Boundary Node Rule.
+   *
+   * @param g0 a Geometry to relate
+   * @param g1 another Geometry to relate
+   */
+  public RelateOp(Geometry g0, Geometry g1)
+  {
+    super(g0, g1);
+    relate = new RelateComputer(arg);
+  }
+
+  /**
+   * Gets the IntersectionMatrix for the spatial relationship
+   * between the input geometries.
+   *
+   * @return the IntersectonMatrix for the spatial relationship between the input geometries
+   */
+  public IntersectionMatrix getIntersectionMatrix()
+  {
+    return relate.computeIM();
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/relate/package.html	(revision 28000)
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Contains classes to implement the computation of the spatial relationships of <CODE>Geometry</CODE>s.
+<P>
+The <code>relate</code> algorithm computes the <code>IntersectionMatrix</code> describing the 
+relationship of two <code>Geometry</code>s.  The algorithm for computing <code>relate</code> 
+uses the intersection operations supported by topology graphs.  Although the <code>relate</code> 
+result depends on the resultant graph formed by the computed intersections, there is 
+no need to explicitly compute the entire graph.  
+It is sufficient to compute the local structure of the graph 
+at each intersection node. 
+<P>
+The algorithm to compute <code>relate</code> has the following steps:
+<UL>
+  <LI>Build topology graphs of the two input geometries. For each geometry 
+      all self-intersection nodes are computed and added to the graph.
+  <LI>Compute nodes for all intersections between edges and nodes of the graphs.
+  <LI>Compute the labeling for the computed nodes by merging the labels from the input graphs. 
+  <LI>Compute the labeling for isolated components of the graph (see below)
+  <LI>Compute the <code>IntersectionMatrix</code> from the labels on the nodes and edges.
+</UL>
+
+<H3>Labeling isolated components</H3>
+
+Isolated components are components (edges or nodes) of an input <code>Geometry</code> which 
+do not contain any intersections with the other input <code>Geometry</code>.  The 
+topological relationship of these components to the other input <code>Geometry</code> 
+must be computed in order to determine the complete labeling of the component.  This can 
+be done by testing whether the component lies in the interior or exterior of the other 
+<code>Geometry</code>.  If the other <code>Geometry</code> is 1-dimensional, the isolated 
+component must lie in the exterior (since otherwise it would have an intersection with an 
+edge of the <code>Geometry</code>).  If the other <code>Geometry</code> is 2-dimensional, 
+a Point-In-Polygon test can be used to determine whether the isolated component is in the 
+interior or exterior. 
+
+<h2>Package Specification</h2>
+
+<ul>
+  <li>Java Topology Suite Technical Specifications
+  <li><A HREF="http://www.opengis.org/techno/specs.htm">
+      OpenGIS Simple Features Specification for SQL</A>
+</ul>
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/ConnectedInteriorTester.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/ConnectedInteriorTester.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/ConnectedInteriorTester.java	(revision 28000)
@@ -0,0 +1,254 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.valid;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.Location;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geomgraph.DirectedEdge;
+import com.vividsolutions.jts.geomgraph.Edge;
+import com.vividsolutions.jts.geomgraph.EdgeRing;
+import com.vividsolutions.jts.geomgraph.GeometryGraph;
+import com.vividsolutions.jts.geomgraph.PlanarGraph;
+import com.vividsolutions.jts.geomgraph.Position;
+import com.vividsolutions.jts.operation.overlay.MaximalEdgeRing;
+import com.vividsolutions.jts.operation.overlay.OverlayNodeFactory;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * This class tests that the interior of an area {@link Geometry}
+ * ( {@link Polygon}  or {@link MultiPolygon} )
+ * is connected.
+ * This can happen if:
+ * <ul>
+ * <li>a shell self-intersects
+ * <li>one or more holes form a connected chain touching a shell at two different points
+ * <li>one or more holes form a ring around a subset of the interior
+ * </ul>
+ * If a disconnected situation is found the location of the problem is recorded.
+ *
+ * @version 1.7
+ */
+public class ConnectedInteriorTester {
+
+  public static Coordinate findDifferentPoint(Coordinate[] coord, Coordinate pt)
+  {
+    for (int i = 0; i < coord.length; i++) {
+      if (! coord[i].equals(pt))
+        return coord[i];
+    }
+    return null;
+  }
+
+  private GeometryFactory geometryFactory = new GeometryFactory();
+
+  private GeometryGraph geomGraph;
+  // save a coordinate for any disconnected interior found
+  // the coordinate will be somewhere on the ring surrounding the disconnected interior
+  private Coordinate disconnectedRingcoord;
+
+  public ConnectedInteriorTester(GeometryGraph geomGraph)
+  {
+    this.geomGraph = geomGraph;
+  }
+
+  public Coordinate getCoordinate() { return disconnectedRingcoord; }
+
+  public boolean isInteriorsConnected()
+  {
+    // node the edges, in case holes touch the shell
+    List splitEdges = new ArrayList();
+    geomGraph.computeSplitEdges(splitEdges);
+
+    // form the edges into rings
+    PlanarGraph graph = new PlanarGraph(new OverlayNodeFactory());
+    graph.addEdges(splitEdges);
+    setInteriorEdgesInResult(graph);
+    graph.linkResultDirectedEdges();
+    List edgeRings = buildEdgeRings(graph.getEdgeEnds());
+
+    /**
+     * Mark all the edges for the edgeRings corresponding to the shells
+     * of the input polygons.  Note only ONE ring gets marked for each shell.
+     */
+    visitShellInteriors(geomGraph.getGeometry(), graph);
+
+    /**
+     * If there are any unvisited shell edges
+     * (i.e. a ring which is not a hole and which has the interior
+     * of the parent area on the RHS)
+     * this means that one or more holes must have split the interior of the
+     * polygon into at least two pieces.  The polygon is thus invalid.
+     */
+    return ! hasUnvisitedShellEdge(edgeRings);
+  }
+
+  private void setInteriorEdgesInResult(PlanarGraph graph)
+  {
+    for (Iterator it = graph.getEdgeEnds().iterator(); it.hasNext(); ) {
+      DirectedEdge de = (DirectedEdge) it.next();
+      if (de.getLabel().getLocation(0, Position.RIGHT) == Location.INTERIOR) {
+        de.setInResult(true);
+      }
+    }
+  }
+
+  /**
+   * Form DirectedEdges in graph into Minimal EdgeRings.
+   * (Minimal Edgerings must be used, because only they are guaranteed to provide
+   * a correct isHole computation)
+   */
+  private List buildEdgeRings(Collection dirEdges)
+  {
+    List edgeRings = new ArrayList();
+    for (Iterator it = dirEdges.iterator(); it.hasNext(); ) {
+      DirectedEdge de = (DirectedEdge) it.next();
+      // if this edge has not yet been processed
+      if (de.isInResult()
+         && de.getEdgeRing() == null) {
+        MaximalEdgeRing er = new MaximalEdgeRing(de, geometryFactory);
+
+        er.linkDirectedEdgesForMinimalEdgeRings();
+        List minEdgeRings = er.buildMinimalRings();
+        edgeRings.addAll(minEdgeRings);
+      }
+    }
+    return edgeRings;
+  }
+
+  /**
+   * Mark all the edges for the edgeRings corresponding to the shells
+   * of the input polygons.
+   * Only ONE ring gets marked for each shell - if there are others which remain unmarked
+   * this indicates a disconnected interior.
+   */
+  private void visitShellInteriors(Geometry g, PlanarGraph graph)
+  {
+    if (g instanceof Polygon) {
+      Polygon p = (Polygon) g;
+      visitInteriorRing(p.getExteriorRing(), graph);
+    }
+    if (g instanceof MultiPolygon) {
+      MultiPolygon mp = (MultiPolygon) g;
+      for (int i = 0; i < mp.getNumGeometries(); i++) {
+        Polygon p = (Polygon) mp.getGeometryN(i);
+        visitInteriorRing(p.getExteriorRing(), graph);
+      }
+    }
+  }
+
+  private void visitInteriorRing(LineString ring, PlanarGraph graph)
+  {
+    Coordinate[] pts = ring.getCoordinates();
+    Coordinate pt0 = pts[0];
+    /**
+     * Find first point in coord list different to initial point.
+     * Need special check since the first point may be repeated.
+     */
+    Coordinate pt1 = findDifferentPoint(pts, pt0);
+    Edge e = graph.findEdgeInSameDirection(pt0, pt1);
+    DirectedEdge de = (DirectedEdge) graph.findEdgeEnd(e);
+    DirectedEdge intDe = null;
+    if (de.getLabel().getLocation(0, Position.RIGHT) == Location.INTERIOR) {
+      intDe = de;
+    }
+    else if (de.getSym().getLabel().getLocation(0, Position.RIGHT) == Location.INTERIOR) {
+      intDe = de.getSym();
+    }
+    Assert.isTrue(intDe != null, "unable to find dirEdge with Interior on RHS");
+
+    visitLinkedDirectedEdges(intDe);
+  }
+
+  protected void visitLinkedDirectedEdges(DirectedEdge start)
+  {
+    DirectedEdge startDe = start;
+    DirectedEdge de = start;
+    do {
+      Assert.isTrue(de != null, "found null Directed Edge");
+      de.setVisited(true);
+      de = de.getNext();
+    } while (de != startDe);
+  }
+
+  /**
+   * Check if any shell ring has an unvisited edge.
+   * A shell ring is a ring which is not a hole and which has the interior
+   * of the parent area on the RHS.
+   * (Note that there may be non-hole rings with the interior on the LHS,
+   * since the interior of holes will also be polygonized into CW rings
+   * by the linkAllDirectedEdges() step)
+   *
+   * @return true if there is an unvisited edge in a non-hole ring
+   */
+  private boolean hasUnvisitedShellEdge(List edgeRings)
+  {
+    for (int i = 0; i < edgeRings.size(); i++) {
+      EdgeRing er = (EdgeRing) edgeRings.get(i);
+      // don't check hole rings
+      if (er.isHole())
+        continue;
+      List edges = er.getEdges();
+      DirectedEdge de = (DirectedEdge) edges.get(0);
+      // don't check CW rings which are holes
+      // (MD - this check may now be irrelevant)
+      if (de.getLabel().getLocation(0, Position.RIGHT) != Location.INTERIOR) continue;
+
+      /**
+       * the edgeRing is CW ring which surrounds the INT of the area, so check all
+       * edges have been visited.  If any are unvisited, this is a disconnected part of the interior
+       */
+      for (int j = 0; j < edges.size(); j++) {
+        de = (DirectedEdge) edges.get(j);
+//Debug.print("visted? "); Debug.println(de);
+        if (! de.isVisited()) {
+//Debug.print("not visited "); Debug.println(de);
+          disconnectedRingcoord = de.getCoordinate();
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/ConsistentAreaTester.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/ConsistentAreaTester.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/ConsistentAreaTester.java	(revision 28000)
@@ -0,0 +1,167 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.valid;
+
+import java.util.Iterator;
+
+import com.vividsolutions.jts.algorithm.LineIntersector;
+import com.vividsolutions.jts.algorithm.RobustLineIntersector;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geomgraph.GeometryGraph;
+import com.vividsolutions.jts.geomgraph.index.SegmentIntersector;
+import com.vividsolutions.jts.operation.relate.EdgeEndBundle;
+import com.vividsolutions.jts.operation.relate.RelateNode;
+import com.vividsolutions.jts.operation.relate.RelateNodeGraph;
+
+/**
+ * Checks that a {@link GeometryGraph} representing an area
+ * (a {@link Polygon} or {@link MultiPolygon} )
+ * has consistent semantics for area geometries.
+ * This check is required for any reasonable polygonal model
+ * (including the OGC-SFS model, as well as models which allow ring self-intersection at single points)
+ * <p>
+ * Checks include:
+ * <ul>
+ * <li>test for rings which properly intersect
+ * (but not for ring self-intersection, or intersections at vertices)
+ * <li>test for consistent labelling at all node points
+ * (this detects vertex intersections with invalid topology,
+ * i.e. where the exterior side of an edge lies in the interior of the area)
+ * <li>test for duplicate rings
+ * </ul>
+ * If an inconsistency is found the location of the problem
+ * is recorded and is available to the caller.
+ *
+ * @version 1.7
+ */
+public class ConsistentAreaTester {
+
+  private final LineIntersector li = new RobustLineIntersector();
+  private GeometryGraph geomGraph;
+  private RelateNodeGraph nodeGraph = new RelateNodeGraph();
+
+  // the intersection point found (if any)
+  private Coordinate invalidPoint;
+
+  /**
+   * Creates a new tester for consistent areas.
+   *
+   * @param geomGraph the topology graph of the area geometry
+   */
+  public ConsistentAreaTester(GeometryGraph geomGraph)
+  {
+    this.geomGraph = geomGraph;
+  }
+
+    /**
+   * @return the intersection point, or <code>null</code> if none was found
+   */
+  public Coordinate getInvalidPoint() { return invalidPoint; }
+
+  /**
+   * Check all nodes to see if their labels are consistent with area topology.
+   *
+   * @return <code>true</code> if this area has a consistent node labelling
+   */
+  public boolean isNodeConsistentArea()
+  {
+    /**
+     * To fully check validity, it is necessary to
+     * compute ALL intersections, including self-intersections within a single edge.
+     */
+    SegmentIntersector intersector = geomGraph.computeSelfNodes(li, true);
+    if (intersector.hasProperIntersection()) {
+      invalidPoint = intersector.getProperIntersectionPoint();
+      return false;
+    }
+
+    nodeGraph.build(geomGraph);
+
+    return isNodeEdgeAreaLabelsConsistent();
+  }
+
+  /**
+   * Check all nodes to see if their labels are consistent.
+   * If any are not, return false
+   *
+   * @return <code>true</code> if the edge area labels are consistent at this node
+   */
+  private boolean isNodeEdgeAreaLabelsConsistent()
+  {
+    for (Iterator nodeIt = nodeGraph.getNodeIterator(); nodeIt.hasNext(); ) {
+      RelateNode node = (RelateNode) nodeIt.next();
+      if (! node.getEdges().isAreaLabelsConsistent(geomGraph)) {
+        invalidPoint = (Coordinate) node.getCoordinate().clone();
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Checks for two duplicate rings in an area.
+   * Duplicate rings are rings that are topologically equal
+   * (that is, which have the same sequence of points up to point order).
+   * If the area is topologically consistent (determined by calling the
+   * <code>isNodeConsistentArea</code>,
+   * duplicate rings can be found by checking for EdgeBundles which contain
+   * more than one EdgeEnd.
+   * (This is because topologically consistent areas cannot have two rings sharing
+   * the same line segment, unless the rings are equal).
+   * The start point of one of the equal rings will be placed in
+   * invalidPoint.
+   *
+   * @return true if this area Geometry is topologically consistent but has two duplicate rings
+   */
+  public boolean hasDuplicateRings()
+  {
+    for (Iterator nodeIt = nodeGraph.getNodeIterator(); nodeIt.hasNext(); ) {
+      RelateNode node = (RelateNode) nodeIt.next();
+      for (Iterator i = node.getEdges().iterator(); i.hasNext(); ) {
+        EdgeEndBundle eeb = (EdgeEndBundle) i.next();
+        if (eeb.getEdgeEnds().size() > 1) {
+          invalidPoint = eeb.getEdge().getCoordinate(0);
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/IndexedNestedRingTester.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/IndexedNestedRingTester.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/IndexedNestedRingTester.java	(revision 28000)
@@ -0,0 +1,129 @@
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.valid;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vividsolutions.jts.algorithm.CGAlgorithms;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geomgraph.GeometryGraph;
+import com.vividsolutions.jts.index.SpatialIndex;
+import com.vividsolutions.jts.index.strtree.STRtree;
+
+/**
+ * Tests whether any of a set of {@link LinearRing}s are
+ * nested inside another ring in the set, using a spatial
+ * index to speed up the comparisons.
+ *
+ * @version 1.7
+ */
+public class IndexedNestedRingTester
+{
+  private GeometryGraph graph;  // used to find non-node vertices
+  private List rings = new ArrayList();
+  private Envelope totalEnv = new Envelope();
+  private SpatialIndex index;
+  private Coordinate nestedPt;
+
+  public IndexedNestedRingTester(GeometryGraph graph)
+  {
+    this.graph = graph;
+  }
+
+  public Coordinate getNestedPoint() { return nestedPt; }
+
+  public void add(LinearRing ring)
+  {
+    rings.add(ring);
+    totalEnv.expandToInclude(ring.getEnvelopeInternal());
+  }
+
+  public boolean isNonNested()
+  {
+    buildIndex();
+
+    for (int i = 0; i < rings.size(); i++) {
+      LinearRing innerRing = (LinearRing) rings.get(i);
+      Coordinate[] innerRingPts = innerRing.getCoordinates();
+
+      List results = index.query(innerRing.getEnvelopeInternal());
+//System.out.println(results.size());
+      for (int j = 0; j < results.size(); j++) {
+        LinearRing searchRing = (LinearRing) results.get(j);
+        Coordinate[] searchRingPts = searchRing.getCoordinates();
+
+        if (innerRing == searchRing)
+          continue;
+
+        if (! innerRing.getEnvelopeInternal().intersects(searchRing.getEnvelopeInternal()))
+          continue;
+
+        Coordinate innerRingPt = IsValidOp.findPtNotNode(innerRingPts, searchRing, graph);
+        
+        /**
+         * If no non-node pts can be found, this means
+         * that the searchRing touches ALL of the innerRing vertices.
+         * This indicates an invalid polygon, since either
+         * the two holes create a disconnected interior, 
+         * or they touch in an infinite number of points 
+         * (i.e. along a line segment).
+         * Both of these cases are caught by other tests,
+         * so it is safe to simply skip this situation here.
+         */
+        if (innerRingPt == null)
+          continue;
+
+        boolean isInside = CGAlgorithms.isPointInRing(innerRingPt, searchRingPts);
+        if (isInside) {
+          nestedPt = innerRingPt;
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  private void buildIndex()
+  {
+    index = new STRtree();
+
+    for (int i = 0; i < rings.size(); i++) {
+      LinearRing ring = (LinearRing) rings.get(i);
+      Envelope env = ring.getEnvelopeInternal();
+      index.insert(env, ring);
+    }
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/IsValidOp.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/IsValidOp.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/IsValidOp.java	(revision 28000)
@@ -0,0 +1,589 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.valid;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeSet;
+
+import com.vividsolutions.jts.algorithm.CGAlgorithms;
+import com.vividsolutions.jts.algorithm.LineIntersector;
+import com.vividsolutions.jts.algorithm.MCPointInRing;
+import com.vividsolutions.jts.algorithm.PointInRing;
+import com.vividsolutions.jts.algorithm.RobustLineIntersector;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.MultiPoint;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geomgraph.Edge;
+import com.vividsolutions.jts.geomgraph.EdgeIntersection;
+import com.vividsolutions.jts.geomgraph.EdgeIntersectionList;
+import com.vividsolutions.jts.geomgraph.GeometryGraph;
+import com.vividsolutions.jts.util.Assert;
+
+/**
+ * Implements the algorithms required to compute the <code>isValid()</code> method
+ * for {@link Geometry}s.
+ * See the documentation for the various geometry types for a specification of validity.
+ *
+ * @version 1.7
+ */
+public class IsValidOp
+{
+	/**
+	 * Tests whether a {@link Geometry} is valid.
+	 * @param geom the Geometry to test
+	 * @return true if the geometry is valid
+	 */
+	public static boolean isValid(Geometry geom)
+	{
+    IsValidOp isValidOp = new IsValidOp(geom);
+    return isValidOp.isValid();
+	}
+	
+  /**
+   * Checks whether a coordinate is valid for processing.
+   * Coordinates are valid iff their x and y ordinates are in the
+   * range of the floating point representation.
+   *
+   * @param coord the coordinate to validate
+   * @return <code>true</code> if the coordinate is valid
+   */
+  public static boolean isValid(Coordinate coord)
+  {
+    if (Double.isNaN(coord.x)) return false;
+    if (Double.isInfinite(coord.x)) return false;
+    if (Double.isNaN(coord.y)) return false;
+    if (Double.isInfinite(coord.y)) return false;
+    return true;
+  }
+  /**
+   * Find a point from the list of testCoords
+   * that is NOT a node in the edge for the list of searchCoords
+   *
+   * @return the point found, or <code>null</code> if none found
+   */
+  public static Coordinate findPtNotNode(
+                          Coordinate[] testCoords,
+                          LinearRing searchRing,
+                          GeometryGraph graph)
+  {
+    // find edge corresponding to searchRing.
+    Edge searchEdge = graph.findEdge(searchRing);
+    // find a point in the testCoords which is not a node of the searchRing
+    EdgeIntersectionList eiList = searchEdge.getEdgeIntersectionList();
+    // somewhat inefficient - is there a better way? (Use a node map, for instance?)
+    for (int i = 0 ; i < testCoords.length; i++) {
+      Coordinate pt = testCoords[i];
+      if (! eiList.isIntersection(pt))
+        return pt;
+    }
+    return null;
+  }
+
+  private Geometry parentGeometry;  // the base Geometry to be validated
+  /**
+   * If the following condition is TRUE JTS will validate inverted shells and exverted holes
+   * (the ESRI SDE model)
+   */
+  private boolean isSelfTouchingRingFormingHoleValid = false;
+  private TopologyValidationError validErr;
+
+  public IsValidOp(Geometry parentGeometry)
+  {
+    this.parentGeometry = parentGeometry;
+  }
+
+
+  public boolean isValid()
+  {
+    checkValid(parentGeometry);
+    return validErr == null;
+  }
+
+
+  private void checkValid(Geometry g)
+  {
+    validErr = null;
+
+    // empty geometries are always valid!
+    if (g.isEmpty()) return;
+
+    if (g instanceof Point)                   checkValid((Point) g);
+    else if (g instanceof MultiPoint)         checkValid((MultiPoint) g);
+                        // LineString also handles LinearRings
+    else if (g instanceof LinearRing)         checkValid( (LinearRing) g);
+    else if (g instanceof LineString)         checkValid( (LineString) g);
+    else if (g instanceof Polygon)            checkValid( (Polygon) g);
+    else if (g instanceof MultiPolygon)       checkValid( (MultiPolygon) g);
+    else if (g instanceof GeometryCollection) checkValid( (GeometryCollection) g);
+    else  throw new UnsupportedOperationException(g.getClass().getName());
+  }
+
+  /**
+   * Checks validity of a Point.
+   */
+  private void checkValid(Point g)
+  {
+    checkInvalidCoordinates(g.getCoordinates());
+  }
+  /**
+   * Checks validity of a MultiPoint.
+   */
+  private void checkValid(MultiPoint g)
+  {
+    checkInvalidCoordinates(g.getCoordinates());
+  }
+
+  /**
+   * Checks validity of a LineString.  Almost anything goes for linestrings!
+   */
+  private void checkValid(LineString g)
+  {
+    checkInvalidCoordinates(g.getCoordinates());
+    if (validErr != null) return;
+    GeometryGraph graph = new GeometryGraph(0, g);
+    checkTooFewPoints(graph);
+  }
+  /**
+   * Checks validity of a LinearRing.
+   */
+  private void checkValid(LinearRing g)
+  {
+    checkInvalidCoordinates(g.getCoordinates());
+    if (validErr != null) return;
+    checkClosedRing(g);
+    if (validErr != null) return;
+
+    GeometryGraph graph = new GeometryGraph(0, g);
+    checkTooFewPoints(graph);
+    if (validErr != null) return;
+    LineIntersector li = new RobustLineIntersector();
+    graph.computeSelfNodes(li, true);
+    checkNoSelfIntersectingRings(graph);
+  }
+
+  /**
+   * Checks the validity of a polygon.
+   * Sets the validErr flag.
+   */
+  private void checkValid(Polygon g)
+  {
+    checkInvalidCoordinates(g);
+    if (validErr != null) return;
+    checkClosedRings(g);
+    if (validErr != null) return;
+
+    GeometryGraph graph = new GeometryGraph(0, g);
+
+    checkTooFewPoints(graph);
+    if (validErr != null) return;
+    checkConsistentArea(graph);
+    if (validErr != null) return;
+
+    if (! isSelfTouchingRingFormingHoleValid) {
+      checkNoSelfIntersectingRings(graph);
+      if (validErr != null) return;
+    }
+    checkHolesInShell(g, graph);
+    if (validErr != null) return;
+    //SLOWcheckHolesNotNested(g);
+    checkHolesNotNested(g, graph);
+    if (validErr != null) return;
+    checkConnectedInteriors(graph);
+  }
+
+  private void checkValid(MultiPolygon g)
+  {
+    for (int i = 0; i < g.getNumGeometries(); i++) {
+      Polygon p = (Polygon) g.getGeometryN(i);
+      checkInvalidCoordinates(p);
+      if (validErr != null) return;
+      checkClosedRings(p);
+      if (validErr != null) return;
+    }
+
+    GeometryGraph graph = new GeometryGraph(0, g);
+
+    checkTooFewPoints(graph);
+    if (validErr != null) return;
+    checkConsistentArea(graph);
+    if (validErr != null) return;
+    if (! isSelfTouchingRingFormingHoleValid) {
+      checkNoSelfIntersectingRings(graph);
+      if (validErr != null) return;
+    }
+    for (int i = 0; i < g.getNumGeometries(); i++) {
+      Polygon p = (Polygon) g.getGeometryN(i);
+      checkHolesInShell(p, graph);
+      if (validErr != null) return;
+    }
+    for (int i = 0; i < g.getNumGeometries(); i++) {
+      Polygon p = (Polygon) g.getGeometryN(i);
+      checkHolesNotNested(p, graph);
+      if (validErr != null) return;
+    }
+    checkShellsNotNested(g, graph);
+    if (validErr != null) return;
+    checkConnectedInteriors(graph);
+  }
+
+  private void checkValid(GeometryCollection gc)
+  {
+    for (int i = 0; i < gc.getNumGeometries(); i++) {
+      Geometry g = gc.getGeometryN(i);
+      checkValid(g);
+      if (validErr != null) return;
+    }
+  }
+
+  private void checkInvalidCoordinates(Coordinate[] coords)
+  {
+    for (int i = 0; i < coords.length; i++) {
+      if (! isValid(coords[i])) {
+        validErr = new TopologyValidationError(
+                          TopologyValidationError.INVALID_COORDINATE,
+                          coords[i]);
+        return;
+      }
+    }
+  }
+
+  private void checkInvalidCoordinates(Polygon poly)
+  {
+    checkInvalidCoordinates(poly.getExteriorRing().getCoordinates());
+    if (validErr != null) return;
+    for (int i = 0; i < poly.getNumInteriorRing(); i++) {
+      checkInvalidCoordinates(poly.getInteriorRingN(i).getCoordinates());
+      if (validErr != null) return;
+    }
+  }
+
+  private void checkClosedRings(Polygon poly)
+  {
+    checkClosedRing((LinearRing) poly.getExteriorRing());
+    if (validErr != null) return;
+    for (int i = 0; i < poly.getNumInteriorRing(); i++) {
+      checkClosedRing((LinearRing) poly.getInteriorRingN(i));
+      if (validErr != null) return;
+    }
+  }
+
+  private void checkClosedRing(LinearRing ring)
+  {
+    if (! ring.isClosed() ) {
+    	Coordinate pt = null;
+    	if (ring.getNumPoints() >= 1)
+    		pt = ring.getCoordinateN(0);
+      validErr = new TopologyValidationError(
+                        TopologyValidationError.RING_NOT_CLOSED,
+                        pt);
+    }
+  }
+
+  private void checkTooFewPoints(GeometryGraph graph)
+  {
+    if (graph.hasTooFewPoints()) {
+      validErr = new TopologyValidationError(
+                        TopologyValidationError.TOO_FEW_POINTS,
+                        graph.getInvalidPoint());
+      return;
+    }
+  }
+
+  /**
+   * Checks that the arrangement of edges in a polygonal geometry graph
+   * forms a consistent area.
+   *
+   * @param graph
+   *
+   * @see ConsistentAreaTester
+   */
+  private void checkConsistentArea(GeometryGraph graph)
+  {
+    ConsistentAreaTester cat = new ConsistentAreaTester(graph);
+    boolean isValidArea = cat.isNodeConsistentArea();
+    if (! isValidArea) {
+      validErr = new TopologyValidationError(
+                        TopologyValidationError.SELF_INTERSECTION,
+                        cat.getInvalidPoint());
+      return;
+    }
+    if (cat.hasDuplicateRings()) {
+      validErr = new TopologyValidationError(
+                        TopologyValidationError.DUPLICATE_RINGS,
+                        cat.getInvalidPoint());
+    }
+  }
+
+  /**
+   * Check that there is no ring which self-intersects (except of course at its endpoints).
+   * This is required by OGC topology rules (but not by other models
+   * such as ESRI SDE, which allow inverted shells and exverted holes).
+   *
+   * @param graph the topology graph of the geometry
+   */
+  private void checkNoSelfIntersectingRings(GeometryGraph graph)
+  {
+    for (Iterator i = graph.getEdgeIterator(); i.hasNext(); ) {
+      Edge e = (Edge) i.next();
+      checkNoSelfIntersectingRing(e.getEdgeIntersectionList());
+      if (validErr != null)
+        return;
+    }
+  }
+
+  /**
+   * Check that a ring does not self-intersect, except at its endpoints.
+   * Algorithm is to count the number of times each node along edge occurs.
+   * If any occur more than once, that must be a self-intersection.
+   */
+  private void checkNoSelfIntersectingRing(EdgeIntersectionList eiList)
+  {
+    Set nodeSet = new TreeSet();
+    boolean isFirst = true;
+    for (Iterator i = eiList.iterator(); i.hasNext(); ) {
+      EdgeIntersection ei = (EdgeIntersection) i.next();
+      if (isFirst) {
+        isFirst = false;
+        continue;
+      }
+      if (nodeSet.contains(ei.coord)) {
+        validErr = new TopologyValidationError(
+                          TopologyValidationError.RING_SELF_INTERSECTION,
+                          ei.coord);
+        return;
+      }
+      else {
+        nodeSet.add(ei.coord);
+      }
+    }
+  }
+
+  /**
+   * Tests that each hole is inside the polygon shell.
+   * This routine assumes that the holes have previously been tested
+   * to ensure that all vertices lie on the shell oon the same side of it
+   * (i.e that the hole rings do not cross the shell ring).
+   * In other words, this test is only correct if the ConsistentArea test is passed first.
+   * Given this, a simple point-in-polygon test of a single point in the hole can be used,
+   * provided the point is chosen such that it does not lie on the shell.
+   *
+   * @param p the polygon to be tested for hole inclusion
+   * @param graph a GeometryGraph incorporating the polygon
+   */
+  private void checkHolesInShell(Polygon p, GeometryGraph graph)
+  {
+    LinearRing shell = (LinearRing) p.getExteriorRing();
+
+    //PointInRing pir = new SimplePointInRing(shell);
+    //PointInRing pir = new SIRtreePointInRing(shell);
+    PointInRing pir = new MCPointInRing(shell);
+
+    for (int i = 0; i < p.getNumInteriorRing(); i++) {
+
+      LinearRing hole = (LinearRing) p.getInteriorRingN(i);
+      Coordinate holePt = findPtNotNode(hole.getCoordinates(), shell, graph);
+      /**
+       * If no non-node hole vertex can be found, the hole must
+       * split the polygon into disconnected interiors.
+       * This will be caught by a subsequent check.
+       */
+      if (holePt == null) return;
+
+      boolean outside = ! pir.isInside(holePt);
+      if ( outside ) {
+        validErr = new TopologyValidationError(
+                          TopologyValidationError.HOLE_OUTSIDE_SHELL,
+                          holePt);
+        return;
+      }
+    }
+  }
+
+  /**
+   * Tests that no hole is nested inside another hole.
+   * This routine assumes that the holes are disjoint.
+   * To ensure this, holes have previously been tested
+   * to ensure that:
+   * <ul>
+   * <li>they do not partially overlap
+   *      (checked by <code>checkRelateConsistency</code>)
+   * <li>they are not identical
+   *      (checked by <code>checkRelateConsistency</code>)
+   * </ul>
+   */
+  private void checkHolesNotNested(Polygon p, GeometryGraph graph)
+  {
+    IndexedNestedRingTester nestedTester = new IndexedNestedRingTester(graph);
+    //SimpleNestedRingTester nestedTester = new SimpleNestedRingTester(arg[0]);
+    //SweeplineNestedRingTester nestedTester = new SweeplineNestedRingTester(arg[0]);
+
+    for (int i = 0; i < p.getNumInteriorRing(); i++) {
+      LinearRing innerHole = (LinearRing) p.getInteriorRingN(i);
+      nestedTester.add(innerHole);
+    }
+    boolean isNonNested = nestedTester.isNonNested();
+    if ( ! isNonNested ) {
+      validErr = new TopologyValidationError(
+                            TopologyValidationError.NESTED_HOLES,
+                            nestedTester.getNestedPoint());
+    }
+  }
+
+  /**
+   * Tests that no element polygon is wholly in the interior of another element polygon.
+   * <p>
+   * Preconditions:
+   * <ul>
+   * <li>shells do not partially overlap
+   * <li>shells do not touch along an edge
+   * <li>no duplicate rings exist
+   * </ul>
+   * This routine relies on the fact that while polygon shells may touch at one or
+   * more vertices, they cannot touch at ALL vertices.
+   */
+  private void checkShellsNotNested(MultiPolygon mp, GeometryGraph graph)
+  {
+    for (int i = 0; i < mp.getNumGeometries(); i++) {
+      Polygon p = (Polygon) mp.getGeometryN(i);
+      LinearRing shell = (LinearRing) p.getExteriorRing();
+      for (int j = 0; j < mp.getNumGeometries(); j++) {
+        if (i == j) continue;
+        Polygon p2 = (Polygon) mp.getGeometryN(j);
+        checkShellNotNested(shell, p2, graph);
+        if (validErr != null) return;
+      }
+    }
+  }
+
+  /**
+   * Check if a shell is incorrectly nested within a polygon.  This is the case
+   * if the shell is inside the polygon shell, but not inside a polygon hole.
+   * (If the shell is inside a polygon hole, the nesting is valid.)
+   * <p>
+   * The algorithm used relies on the fact that the rings must be properly contained.
+   * E.g. they cannot partially overlap (this has been previously checked by
+   * <code>checkRelateConsistency</code> )
+   */
+  private void checkShellNotNested(LinearRing shell, Polygon p, GeometryGraph graph)
+  {
+    Coordinate[] shellPts = shell.getCoordinates();
+    // test if shell is inside polygon shell
+    LinearRing polyShell =  (LinearRing) p.getExteriorRing();
+    Coordinate[] polyPts = polyShell.getCoordinates();
+    Coordinate shellPt = findPtNotNode(shellPts, polyShell, graph);
+    // if no point could be found, we can assume that the shell is outside the polygon
+    if (shellPt == null)
+      return;
+    boolean insidePolyShell = CGAlgorithms.isPointInRing(shellPt, polyPts);
+    if (! insidePolyShell) return;
+
+    // if no holes, this is an error!
+    if (p.getNumInteriorRing() <= 0) {
+      validErr = new TopologyValidationError(
+                            TopologyValidationError.NESTED_SHELLS,
+                            shellPt);
+      return;
+    }
+
+    /**
+     * Check if the shell is inside one of the holes.
+     * This is the case if one of the calls to checkShellInsideHole
+     * returns a null coordinate.
+     * Otherwise, the shell is not properly contained in a hole, which is an error.
+     */
+    Coordinate badNestedPt = null;
+    for (int i = 0; i < p.getNumInteriorRing(); i++) {
+      LinearRing hole = (LinearRing) p.getInteriorRingN(i);
+      badNestedPt = checkShellInsideHole(shell, hole, graph);
+      if (badNestedPt == null)
+        return;
+    }
+    validErr = new TopologyValidationError(
+                          TopologyValidationError.NESTED_SHELLS,
+                          badNestedPt);
+  }
+
+  /**
+   * This routine checks to see if a shell is properly contained in a hole.
+   * It assumes that the edges of the shell and hole do not
+   * properly intersect.
+   *
+   * @return <code>null</code> if the shell is properly contained, or
+   *   a Coordinate which is not inside the hole if it is not
+   *
+   */
+  private Coordinate checkShellInsideHole(LinearRing shell, LinearRing hole, GeometryGraph graph)
+  {
+    Coordinate[] shellPts = shell.getCoordinates();
+    Coordinate[] holePts = hole.getCoordinates();
+    // TODO: improve performance of this - by sorting pointlists for instance?
+    Coordinate shellPt = findPtNotNode(shellPts, hole, graph);
+    // if point is on shell but not hole, check that the shell is inside the hole
+    if (shellPt != null) {
+      boolean insideHole = CGAlgorithms.isPointInRing(shellPt, holePts);
+      if (! insideHole) {
+        return shellPt;
+      }
+    }
+    Coordinate holePt = findPtNotNode(holePts, shell, graph);
+    // if point is on hole but not shell, check that the hole is outside the shell
+    if (holePt != null) {
+      boolean insideShell = CGAlgorithms.isPointInRing(holePt, shellPts);
+      if (insideShell) {
+        return holePt;
+      }
+      return null;
+    }
+    Assert.shouldNeverReachHere("points in shell and hole appear to be equal");
+    return null;
+  }
+
+  private void checkConnectedInteriors(GeometryGraph graph)
+  {
+    ConnectedInteriorTester cit = new ConnectedInteriorTester(graph);
+    if (! cit.isInteriorsConnected())
+      validErr = new TopologyValidationError(
+                        TopologyValidationError.DISCONNECTED_INTERIOR,
+                        cit.getCoordinate());
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/TopologyValidationError.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/TopologyValidationError.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/TopologyValidationError.java	(revision 28000)
@@ -0,0 +1,158 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.operation.valid;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * Contains information about the nature and location of a {@link Geometry}
+ * validation error
+ *
+ * @version 1.7
+ */
+public class TopologyValidationError {
+
+  /**
+   * Indicates that a hole of a polygon lies partially or completely in the exterior of the shell
+   */
+  public static final int HOLE_OUTSIDE_SHELL      = 2;
+
+  /**
+   * Indicates that a hole lies in the interior of another hole in the same polygon
+   */
+  public static final int NESTED_HOLES            = 3;
+
+  /**
+   * Indicates that the interior of a polygon is disjoint
+   * (often caused by set of contiguous holes splitting the polygon into two parts)
+   */
+  public static final int DISCONNECTED_INTERIOR   = 4;
+
+  /**
+   * Indicates that two rings of a polygonal geometry intersect
+   */
+  public static final int SELF_INTERSECTION       = 5;
+
+  /**
+   * Indicates that a ring self-intersects
+   */
+  public static final int RING_SELF_INTERSECTION  = 6;
+
+  /**
+   * Indicates that a polygon component of a MultiPolygon lies inside another polygonal component
+   */
+  public static final int NESTED_SHELLS           = 7;
+
+  /**
+   * Indicates that a polygonal geometry contains two rings which are identical
+   */
+  public static final int DUPLICATE_RINGS         = 8;
+
+  /**
+   * Indicates that either
+   * <ul>
+   * <li>a LineString contains a single point
+   * <li>a LinearRing contains 2 or 3 points
+   * </ul>
+   */
+  public static final int TOO_FEW_POINTS          = 9;
+
+  /**
+   * Indicates that the <code>X</code> or <code>Y</code> ordinate of
+   * a Coordinate is not a valid numeric value (e.g. {@link Double#NaN} )
+   */
+  public static final int INVALID_COORDINATE      = 10;
+
+  /**
+   * Indicates that a ring is not correctly closed
+   * (the first and the last coordinate are different)
+   */
+  public static final int RING_NOT_CLOSED      = 11;
+
+  /**
+   * Messages corresponding to error codes
+   */
+  public static final String[] errMsg = {
+    "Topology Validation Error",
+    "Repeated Point",
+    "Hole lies outside shell",
+    "Holes are nested",
+    "Interior is disconnected",
+    "Self-intersection",
+    "Ring Self-intersection",
+    "Nested shells",
+    "Duplicate Rings",
+    "Too few distinct points in geometry component",
+    "Invalid Coordinate",
+    "Ring is not closed"
+  };
+
+  private int errorType;
+  private Coordinate pt;
+
+  /**
+   * Creates a validation error with the given type and location
+   *
+   * @param errorType the type of the error
+   * @param pt the location of the error
+   */
+  public TopologyValidationError(int errorType, Coordinate pt)
+  {
+    this.errorType = errorType;
+    if (pt != null)
+      this.pt = (Coordinate) pt.clone();
+  }
+
+  /**
+   * Gets an error message describing this error.
+   * The error message does not describe the location of the error.
+   *
+   * @return the error message
+   */
+  public String getMessage() { return errMsg[errorType]; }
+
+  /**
+   * Gets a message describing the type and location of this error.
+   * @return the error message
+   */
+  public String toString()
+  {
+    String locStr = "";
+    if (pt != null)
+      locStr = " at or near point " + pt;
+    return getMessage() + locStr;
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/operation/valid/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides classes for testing the validity of geometries.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/planargraph/DirectedEdge.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/planargraph/DirectedEdge.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/planargraph/DirectedEdge.java	(revision 28000)
@@ -0,0 +1,113 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.planargraph;
+
+import com.vividsolutions.jts.algorithm.CGAlgorithms;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geomgraph.PlanarGraph;
+
+/**
+ * Represents a directed edge in a {@link PlanarGraph}. A DirectedEdge may or
+ * may not have a reference to a parent {@link Edge} (some applications of
+ * planar graphs may not require explicit Edge objects to be created). Usually
+ * a client using a <code>PlanarGraph</code> will subclass <code>DirectedEdge</code>
+ * to add its own application-specific data and methods.
+ *
+ * @version 1.7
+ */
+public class DirectedEdge
+    extends GraphComponent
+    implements Comparable
+{
+
+  protected Edge parentEdge;
+  protected Coordinate p0, p1;
+  protected int quadrant;
+
+  /**
+   * Tests whether this directed edge has been removed from its containing graph
+   *
+   * @return <code>true</code> if this directed edge is removed
+   */
+  public boolean isRemoved()
+  {
+    return parentEdge == null;
+  }
+
+  /**
+   * Returns 1 if this DirectedEdge has a greater angle with the
+   * positive x-axis than b", 0 if the DirectedEdges are collinear, and -1 otherwise.
+   * <p>
+   * Using the obvious algorithm of simply computing the angle is not robust,
+   * since the angle calculation is susceptible to roundoff. A robust algorithm
+   * is:
+   * <ul>
+   * <li>first compare the quadrants. If the quadrants are different, it it
+   * trivial to determine which vector is "greater".
+   * <li>if the vectors lie in the same quadrant, the robust
+   * {@link CGAlgorithms#computeOrientation(Coordinate, Coordinate, Coordinate)}
+   * function can be used to decide the relative orientation of the vectors.
+   * </ul>
+   */
+  public int compareTo(Object obj)
+  {
+      DirectedEdge de = (DirectedEdge) obj;
+      return compareDirection(de);
+  }
+
+  /**
+   * Returns 1 if this DirectedEdge has a greater angle with the
+   * positive x-axis than b", 0 if the DirectedEdges are collinear, and -1 otherwise.
+   * <p>
+   * Using the obvious algorithm of simply computing the angle is not robust,
+   * since the angle calculation is susceptible to roundoff. A robust algorithm
+   * is:
+   * <ul>
+   * <li>first compare the quadrants. If the quadrants are different, it it
+   * trivial to determine which vector is "greater".
+   * <li>if the vectors lie in the same quadrant, the robust
+   * {@link CGAlgorithms#computeOrientation(Coordinate, Coordinate, Coordinate)}
+   * function can be used to decide the relative orientation of the vectors.
+   * </ul>
+   */
+  public int compareDirection(DirectedEdge e)
+  {
+    // if the rays are in different quadrants, determining the ordering is trivial
+    if (quadrant > e.quadrant) return 1;
+    if (quadrant < e.quadrant) return -1;
+    // vectors are in the same quadrant - check relative orientation of direction vectors
+    // this is > e if it is CCW of e
+    return CGAlgorithms.computeOrientation(e.p0, e.p1, p1);
+  }
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/planargraph/Edge.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/planargraph/Edge.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/planargraph/Edge.java	(revision 28000)
@@ -0,0 +1,75 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.planargraph;
+
+/**
+ * Represents an undirected edge of a {@link PlanarGraph}. An undirected edge
+ * in fact simply acts as a central point of reference for two opposite
+ * {@link DirectedEdge}s.
+ * <p>
+ * Usually a client using a <code>PlanarGraph</code> will subclass <code>Edge</code>
+ * to add its own application-specific data and methods.
+ *
+ * @version 1.7
+ */
+public class Edge
+    extends GraphComponent
+{
+
+  /**
+   * The two DirectedEdges associated with this Edge.
+   * Index 0 is forward, 1 is reverse.
+   */
+  protected DirectedEdge[] dirEdge;
+
+  /**
+   * Constructs an Edge whose DirectedEdges are not yet set. Be sure to call
+   * {@link #setDirectedEdges(DirectedEdge, DirectedEdge)}
+   */
+  public Edge()
+  {
+  }
+
+
+  /**
+   * Tests whether this edge has been removed from its containing graph
+   *
+   * @return <code>true</code> if this edge is removed
+   */
+  public boolean isRemoved()
+  {
+    return dirEdge == null;
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/planargraph/GraphComponent.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/planargraph/GraphComponent.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/planargraph/GraphComponent.java	(revision 28000)
@@ -0,0 +1,69 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.planargraph;
+
+
+/**
+ * The base class for all graph component classes.
+ * Maintains flags of use in generic graph algorithms.
+ * Provides two flags:
+ * <ul>
+ * <li><b>marked</b> - typically this is used to indicate a state that persists
+ * for the course of the graph's lifetime.  For instance, it can be
+ * used to indicate that a component has been logically deleted from the graph.
+ * <li><b>visited</b> - this is used to indicate that a component has been processed
+ * or visited by an single graph algorithm.  For instance, a breadth-first traversal of the
+ * graph might use this to indicate that a node has already been traversed.
+ * The visited flag may be set and cleared many times during the lifetime of a graph.
+ *
+ * <p>
+ * Graph components support storing user context data.  This will typically be
+ * used by client algorithms which use planar graphs.
+ *
+ * @version 1.7
+ */
+public abstract class GraphComponent
+{
+
+
+  public GraphComponent() {
+  }
+
+  /**
+   * Tests whether this component has been removed from its containing graph
+   *
+   * @return <code>true</code> if this component is removed
+   */
+  public abstract boolean isRemoved();
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/planargraph/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/planargraph/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/planargraph/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Contains classes to implement a planar graph data structure.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/precision/CommonBits.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/precision/CommonBits.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/precision/CommonBits.java	(revision 28000)
@@ -0,0 +1,146 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.precision;
+
+/**
+ * Determines the maximum number of common most-significant
+ * bits in the mantissa of one or numbers.
+ * Can be used to compute the double-precision number which
+ * is represented by the common bits.
+ * If there are no common bits, the number computed is 0.0.
+ *
+ * @version 1.7
+ */
+public class CommonBits {
+
+  /**
+   * Computes the bit pattern for the sign and exponent of a
+   * double-precision number.
+   * 
+   * @param num
+   * @return the bit pattern for the sign and exponent
+   */
+  public static long signExpBits(long num)
+  {
+    return num >> 52;
+  }
+
+  /**
+ * This computes the number of common most-significant bits in the mantissas
+ * of two double-precision numbers.
+ * It does not count the hidden bit, which is always 1.
+ * It does not determine whether the numbers have the same exponent - if they do
+ * not, the value computed by this function is meaningless.
+ * 
+ * @param num1 the first number
+ * @param num2 the second number
+ * @return the number of common most-significant mantissa bits
+ */
+  public static int numCommonMostSigMantissaBits(long num1, long num2)
+  {
+    int count = 0;
+    for (int i = 52; i >= 0; i--)
+    {
+      if (getBit(num1, i) != getBit(num2, i))
+        return count;
+      count++;
+    }
+    return 52;
+  }
+
+  /**
+   * Zeroes the lower n bits of a bitstring.
+   * 
+   * @param bits the bitstring to alter
+   * @return the zeroed bitstring
+   */
+  public static long zeroLowerBits(long bits, int nBits)
+  {
+    long invMask = (1L << nBits) - 1L;
+    long mask = ~ invMask;
+    long zeroed = bits & mask;
+    return zeroed;
+  }
+
+  /**
+   * Extracts the i'th bit of a bitstring.
+   * 
+   * @param bits the bitstring to extract from
+   * @param i the bit to extract
+   * @return the value of the extracted bit
+   */
+  public static int getBit(long bits, int i)
+  {
+    long mask = (1L << i);
+    return (bits & mask) != 0 ? 1 : 0;
+  }
+
+  private boolean isFirst = true;
+  private int commonMantissaBitsCount = 53;
+  private long commonBits = 0;
+  private long commonSignExp;
+
+  public CommonBits() {
+  }
+
+  public void add(double num)
+  {
+    long numBits = Double.doubleToLongBits(num);
+    if (isFirst) {
+      commonBits = numBits;
+      commonSignExp = signExpBits(commonBits);
+      isFirst = false;
+      return;
+    }
+
+    long numSignExp = signExpBits(numBits);
+    if (numSignExp != commonSignExp) {
+      commonBits = 0;
+      return;
+    }
+
+//    System.out.println(toString(commonBits));
+//    System.out.println(toString(numBits));
+    commonMantissaBitsCount = numCommonMostSigMantissaBits(commonBits, numBits);
+    commonBits = zeroLowerBits(commonBits, 64 - (12 + commonMantissaBitsCount));
+//    System.out.println(toString(commonBits));
+  }
+
+  public double getCommon()
+  {
+    return Double.longBitsToDouble(commonBits);
+  }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/precision/CommonBitsRemover.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/precision/CommonBitsRemover.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/precision/CommonBitsRemover.java	(revision 28000)
@@ -0,0 +1,167 @@
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.precision;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateFilter;
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * Removes common most-significant mantissa bits 
+ * from one or more {@link Geometry}s.
+ * <p>
+ * The CommonBitsRemover "scavenges" precision 
+ * which is "wasted" by a large displacement of the geometry 
+ * from the origin.  
+ * For example, if a small geometry is displaced from the origin 
+ * by a large distance, 
+ * the displacement increases the significant figures in the coordinates, 
+ * but does not affect the <i>relative</i> topology of the geometry.  
+ * Thus the geometry can be translated back to the origin 
+ * without affecting its topology.
+ * In order to compute the translation without affecting 
+ * the full precision of the coordinate values, 
+ * the translation is performed at the bit level by
+ * removing the common leading mantissa bits.
+ * <p>
+ * If the geometry envelope already contains the origin, 
+ * the translation procedure cannot be applied.  
+ * In this case, the common bits value is computed as zero.
+ * <p>
+ * If the geometry crosses the Y axis but not the X axis 
+ * (and <i>mutatis mutandum</i>), 
+ * the common bits for Y are zero, 
+ * but the common bits for X are non-zero.
+ *
+ * @version 1.7
+ */
+public class CommonBitsRemover
+{
+  private Coordinate commonCoord;
+  private CommonCoordinateFilter ccFilter = new CommonCoordinateFilter();
+
+  public CommonBitsRemover()
+  {
+  }
+
+  /**
+   * Add a geometry to the set of geometries whose common bits are
+   * being computed.  After this method has executed the
+   * common coordinate reflects the common bits of all added
+   * geometries.
+   *
+   * @param geom a Geometry to test for common bits
+   */
+  public void add(Geometry geom)
+  {
+    geom.apply(ccFilter);
+    commonCoord = ccFilter.getCommonCoordinate();
+  }
+
+  /**
+   * The common bits of the Coordinates in the supplied Geometries.
+   */
+  public Coordinate getCommonCoordinate() { return commonCoord; }
+
+  /**
+   * Removes the common coordinate bits from a Geometry.
+   * The coordinates of the Geometry are changed.
+   *
+   * @param geom the Geometry from which to remove the common coordinate bits
+   * @return the shifted Geometry
+   */
+  public Geometry removeCommonBits(Geometry geom)
+  {
+    if (commonCoord.x == 0.0 && commonCoord.y == 0.0)
+      return geom;
+    Coordinate invCoord = new Coordinate(commonCoord);
+    invCoord.x = -invCoord.x;
+    invCoord.y = -invCoord.y;
+    Translater trans = new Translater(invCoord);
+    geom.apply(trans);
+    geom.geometryChanged();
+    return geom;
+  }
+
+  /**
+   * Adds the common coordinate bits back into a Geometry.
+   * The coordinates of the Geometry are changed.
+   *
+   * @param geom the Geometry to which to add the common coordinate bits
+   */
+  public void addCommonBits(Geometry geom)
+  {
+    Translater trans = new Translater(commonCoord);
+    geom.apply(trans);
+    geom.geometryChanged();
+  }
+
+  class CommonCoordinateFilter
+      implements CoordinateFilter
+  {
+    private CommonBits commonBitsX = new CommonBits();
+    private CommonBits commonBitsY = new CommonBits();
+
+    public void filter(Coordinate coord)
+    {
+      commonBitsX.add(coord.x);
+      commonBitsY.add(coord.y);
+    }
+
+    public Coordinate getCommonCoordinate()
+    {
+      return new Coordinate(
+          commonBitsX.getCommon(),
+          commonBitsY.getCommon());
+    }
+  }
+
+  class Translater
+      implements CoordinateFilter
+  {
+    Coordinate trans = null;
+
+    public Translater(Coordinate trans)
+    {
+      this.trans = trans;
+    }
+    public void filter(Coordinate coord)
+    {
+      coord.x += trans.x;
+      coord.y += trans.y;
+    }
+
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/precision/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/precision/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/precision/package.html	(revision 28000)
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+-->
+</head>
+<body bgcolor="white">
+
+Provides classes for analyzing and
+manipulating the precision of Geometries.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/util/Assert.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/util/Assert.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/util/Assert.java	(revision 28000)
@@ -0,0 +1,125 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.util;
+
+
+/**
+ *  A utility for making programming assertions.
+ *
+ *@version 1.7
+ */
+public class Assert {
+
+  /**
+   *  Throws an <code>AssertionFailedException</code> if the given assertion is
+   *  not true.
+   *
+   *@param  assertion                  a condition that is supposed to be true
+   *@throws  AssertionFailedException  if the condition is false
+   */
+  public static void isTrue(boolean assertion) {
+    isTrue(assertion, null);
+  }
+
+  /**
+   *  Throws an <code>AssertionFailedException</code> with the given message if
+   *  the given assertion is not true.
+   *
+   *@param  assertion                  a condition that is supposed to be true
+   *@param  message                    a description of the assertion
+   *@throws  AssertionFailedException  if the condition is false
+   */
+  public static void isTrue(boolean assertion, String message) {
+    if (!assertion) {
+      if (message == null) {
+        throw new AssertionFailedException();
+      }
+      else {
+        throw new AssertionFailedException(message);
+      }
+    }
+  }
+
+  /**
+   *  Throws an <code>AssertionFailedException</code> if the given objects are
+   *  not equal, according to the <code>equals</code> method.
+   *
+   *@param  expectedValue              the correct value
+   *@param  actualValue                the value being checked
+   *@throws  AssertionFailedException  if the two objects are not equal
+   */
+  public static void equals(Object expectedValue, Object actualValue) {
+    equals(expectedValue, actualValue, null);
+  }
+
+  /**
+   *  Throws an <code>AssertionFailedException</code> with the given message if
+   *  the given objects are not equal, according to the <code>equals</code>
+   *  method.
+   *
+   *@param  expectedValue              the correct value
+   *@param  actualValue                the value being checked
+   *@param  message                    a description of the assertion
+   *@throws  AssertionFailedException  if the two objects are not equal
+   */
+  public static void equals(Object expectedValue, Object actualValue, String message) {
+    if (!actualValue.equals(expectedValue)) {
+      throw new AssertionFailedException("Expected " + expectedValue + " but encountered "
+           + actualValue + (message != null ? ": " + message : ""));
+    }
+  }
+
+  /**
+   *  Always throws an <code>AssertionFailedException</code>.
+   *
+   *@throws  AssertionFailedException  thrown always
+   */
+  public static void shouldNeverReachHere() {
+    shouldNeverReachHere(null);
+  }
+
+  /**
+   *  Always throws an <code>AssertionFailedException</code> with the given
+   *  message.
+   *
+   *@param  message                    a description of the assertion
+   *@throws  AssertionFailedException  thrown always
+   */
+  public static void shouldNeverReachHere(String message) {
+    throw new AssertionFailedException("Should never reach here"
+         + (message != null ? ": " + message : ""));
+  }
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/util/AssertionFailedException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/util/AssertionFailedException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/util/AssertionFailedException.java	(revision 28000)
@@ -0,0 +1,63 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.util;
+
+/**
+ *  Thrown when the application is in an inconsistent state. Indicates a problem
+ *  with the code.
+ *
+ *@version 1.7
+ */
+public class AssertionFailedException extends RuntimeException {
+
+  /**
+   *  Creates an <code>AssertionFailedException</code>.
+   */
+  public AssertionFailedException() {
+    super();
+  }
+
+  /**
+   *  Creates a <code>AssertionFailedException</code> with the given detail
+   *  message.
+   *
+   *@param  message  a description of the assertion
+   */
+  public AssertionFailedException(String message) {
+    super(message);
+  }
+}
+
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/util/UniqueCoordinateArrayFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/util/UniqueCoordinateArrayFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/util/UniqueCoordinateArrayFilter.java	(revision 28000)
@@ -0,0 +1,72 @@
+
+
+/*
+ * The JTS Topology Suite is a collection of Java classes that
+ * implement the fundamental operations required to validate a given
+ * geo-spatial data set to a known topological specification.
+ *
+ * Copyright (C) 2001 Vivid Solutions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, contact:
+ *
+ *     Vivid Solutions
+ *     Suite #1A
+ *     2328 Government Street
+ *     Victoria BC  V8T 5G5
+ *     Canada
+ *
+ *     (250)385-6040
+ *     www.vividsolutions.com
+ */
+package com.vividsolutions.jts.util;
+
+import java.util.ArrayList;
+import java.util.TreeSet;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateFilter;
+
+/**
+ *  A {@link CoordinateFilter} that builds a set of <code>Coordinate</code>s.
+ *  The set of coordinates contains no duplicate points.
+ *
+ *@version 1.7
+ */
+public class UniqueCoordinateArrayFilter implements CoordinateFilter {
+  TreeSet treeSet = new TreeSet();
+  ArrayList list = new ArrayList();
+
+  public UniqueCoordinateArrayFilter() { }
+
+  /**
+   *  Returns the gathered <code>Coordinate</code>s.
+   *
+   *@return    the <code>Coordinate</code>s collected by this <code>CoordinateArrayFilter</code>
+   */
+  public Coordinate[] getCoordinates() {
+    Coordinate[] coordinates = new Coordinate[list.size()];
+    return (Coordinate[]) list.toArray(coordinates);
+  }
+
+  public void filter(Coordinate coord) {
+    if (!treeSet.contains(coord)) {
+      list.add(coord);
+      treeSet.add(coord);
+    }
+  }
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/util/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/util/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/com/vividsolutions/jts/util/package.html	(revision 28000)
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+Contains support classes for the Java Topology Suite.
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/Measurable.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/Measurable.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/Measurable.java	(revision 28000)
@@ -0,0 +1,76 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2007 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure;
+
+import javax.measure.quantity.Quantity;
+import javax.measure.unit.Unit;
+
+/**
+ * <p> This interface represents the measurable, countable, or comparable 
+ *     property or aspect of a thing.</p>
+ *     
+ * <p> Implementing instances are typically the result of a measurement:[code]
+ *         Measurable<Mass> weight = Measure.valueOf(180.0, POUND);
+ *     [/code]
+ *     They can also be created from custom classes:[code]
+ *     class Delay implements Measurable<Duration> {
+ *          private long nanoSeconds; // Implicit internal unit.
+ *          public double doubleValue(Unit<Velocity> unit) { ... }
+ *          public long longValue(Unit<Velocity> unit) { ... }
+ *     }
+ *     Thread.wait(new Delay(24, HOUR)); // Assuming Thread.wait(Measurable<Duration>) method.
+ *     [/code]</p>
+ *     
+ * <p> Although measurable instances are for the most part scalar quantities; 
+ *     more complex implementations (e.g. vectors, data set) are allowed as 
+ *     long as an aggregate magnitude can be determined. For example:[code]
+ *     class Velocity3D implements Measurable<Velocity> {
+ *          private double x, y, z; // Meter per seconds.
+ *          public double doubleValue(Unit<Velocity> unit) { ... } // Returns vector norm.
+ *          ... 
+ *     }
+ *     class Sensors<Q extends Quantity> extends Measure<double[], Q> {
+ *          public doubleValue(Unit<Q> unit) { ... } // Returns median value. 
+ *          ...
+ *     } [/code]</p>
+ *     
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 4.1, June 8, 2007
+ */
+public interface Measurable<Q extends Quantity> extends Comparable<Measurable<Q>> {
+    
+    /**
+     * Returns the value of this measurable stated in the specified unit as 
+     * a <code>double</code>. If the measurable has too great a magnitude to 
+     * be represented as a <code>double</code>, it will be converted to 
+     * <code>Double.NEGATIVE_INFINITY</code> or
+     * <code>Double.POSITIVE_INFINITY</code> as appropriate.
+     * 
+     * @param unit the unit in which this measurable value is stated.
+     * @return the numeric value after conversion to type <code>double</code>.
+     */
+    double doubleValue(Unit<Q> unit);
+
+    /**
+     * Returns the estimated integral value of this measurable stated in 
+     * the specified unit as a <code>long</code>. 
+     * 
+     * <p> Note: This method differs from the <code>Number.longValue()</code>
+     *           in the sense that the closest integer value is returned 
+     *           and an ArithmeticException is raised instead
+     *           of a bit truncation in case of overflow (safety critical).</p> 
+     * 
+     * @param unit the unit in which the measurable value is stated.
+     * @return the numeric value after conversion to type <code>long</code>.
+     * @throws ArithmeticException if this quantity cannot be represented 
+     *         as a <code>long</code> number in the specified unit.
+     */
+    long longValue(Unit<Q> unit) throws ArithmeticException;
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/Measure.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/Measure.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/Measure.java	(revision 28000)
@@ -0,0 +1,403 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2007 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure;
+
+import java.io.Serializable;
+
+import javax.measure.quantity.Quantity;
+import javax.measure.unit.Unit;
+
+/**
+ * <p> This class represents the result of a measurement stated in a 
+ *     known unit.</p>
+ * 
+ * <p> There is no constraint upon the measurement value itself: scalars, 
+ *     vectors, or even data sets are valid values as long as 
+ *     an aggregate magnitude can be determined (see {@link Measurable}).</p>
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 4.2, August 26, 2007
+ */
+@SuppressWarnings("serial")
+public abstract class Measure<V, Q extends Quantity> implements Measurable<Q>,
+        Serializable {
+
+    /**
+     * Default constructor.
+     */
+    protected Measure() {
+    }
+
+    /**
+     * Returns the scalar measure for the specified <code>double</code>
+     * stated in the specified unit.
+     * 
+     * @param doubleValue the measurement value.
+     * @param unit the measurement unit.
+     */
+    public static <Q extends Quantity> Measure<java.lang.Double, Q> valueOf(
+            double doubleValue, Unit<Q> unit) {
+        return new Double<Q>(doubleValue, unit);
+    }
+
+    /**
+     * Returns the scalar measure for the specified <code>double</code>
+     * stated in the specified unit.
+     * 
+     * @param longValue the measurement value.
+     * @param unit the measurement unit.
+     */
+    public static <Q extends Quantity> Measure<java.lang.Long, Q> valueOf(
+            long longValue, Unit<Q> unit) {
+        return new Long<Q>(longValue, unit);
+    }
+
+    /**
+     * Returns the scalar measure for the specified <code>float</code>
+     * stated in the specified unit.
+     * 
+     * @param floatValue the measurement value.
+     * @param unit the measurement unit.
+     */
+    public static <Q extends Quantity> Measure<java.lang.Float, Q> valueOf(
+            float floatValue, Unit<Q> unit) {
+        return new Float<Q>(floatValue, unit);
+    }
+
+    /**
+     * Returns the scalar measure for the specified <code>int</code>
+     * stated in the specified unit.
+     * 
+     * @param intValue the measurement value.
+     * @param unit the measurement unit.
+     */
+    public static <Q extends Quantity> Measure<java.lang.Integer, Q> valueOf(
+            int intValue, Unit<Q> unit) {
+        return new Integer<Q>(intValue, unit);
+    }
+
+    /**
+     * Returns the measurement value of this measure.
+     *    
+     * @return the measurement value.
+     */
+    public abstract V getValue();
+
+    /**
+     * Returns the measurement unit of this measure.
+     * 
+     * @return the measurement unit.
+     */
+    public abstract Unit<Q> getUnit();
+
+    /**
+     * Returns the measure equivalent to this measure but stated in the 
+     * specified unit. This method may result in lost of precision 
+     * (e.g. measure of integral value).
+     * 
+     * @param unit the new measurement unit.
+     * @return the measure stated in the specified unit.
+     */
+    public abstract Measure<V, Q> to(Unit<Q> unit);
+
+    /**
+     * Returns the value of this measure stated in the specified unit as 
+     * a <code>double</code>. If the measure has too great a magnitude to 
+     * be represented as a <code>double</code>, it will be converted to 
+     * <code>Double.NEGATIVE_INFINITY</code> or
+     * <code>Double.POSITIVE_INFINITY</code> as appropriate.
+     * 
+     * @param unit the unit in which this measure is stated.
+     * @return the numeric value after conversion to type <code>double</code>.
+     */
+    public abstract double doubleValue(Unit<Q> unit);
+
+    /**
+     * Returns the estimated integral value of this measure stated in 
+     * the specified unit as a <code>long</code>. 
+     * 
+     * <p> Note: This method differs from the <code>Number.longValue()</code>
+     *           in the sense that the closest integer value is returned 
+     *           and an ArithmeticException is raised instead
+     *           of a bit truncation in case of overflow (safety critical).</p> 
+     * 
+     * @param unit the unit in which the measurable value is stated.
+     * @return the numeric value after conversion to type <code>long</code>.
+     * @throws ArithmeticException if this quantity cannot be represented 
+     *         as a <code>long</code> number in the specified unit.
+     */
+    public long longValue(Unit<Q> unit) throws ArithmeticException {
+        double doubleValue = doubleValue(unit);
+        if (java.lang.Double.isNaN(doubleValue)
+                || (doubleValue < java.lang.Long.MIN_VALUE)
+                || (doubleValue > java.lang.Long.MAX_VALUE))
+            throw new ArithmeticException(doubleValue + " " + unit
+                    + " cannot be represented as long");
+        return Math.round(doubleValue);
+    }
+
+    /**
+     * Returns the value of this measure stated in the specified unit as a 
+     * <code>float</code>. If the measure has too great a magnitude to be 
+     * represented as a <code>float</code>, it will be converted to 
+     * <code>Float.NEGATIVE_INFINITY</code> or
+     * <code>Float.POSITIVE_INFINITY</code> as appropriate.
+     * 
+     * @param unit the unit in which the measure is stated.
+     * @return the numeric value after conversion to type <code>float</code>.
+     */
+    public float floatValue(Unit<Q> unit) {
+        return (float) doubleValue(unit);
+    }
+
+    /**
+     * Returns the estimated integral value of this measure stated in 
+     * the specified unit as a <code>int</code>. 
+     * 
+     * <p> Note: This method differs from the <code>Number.intValue()</code>
+     *           in the sense that the closest integer value is returned 
+     *           and an ArithmeticException is raised instead
+     *           of a bit truncation in case of overflow (safety critical).</p> 
+     * 
+     * @param unit the unit in which the measurable value is stated.
+     * @return the numeric value after conversion to type <code>int</code>.
+     * @throws ArithmeticException if this quantity cannot be represented 
+     *         as a <code>int</code> number in the specified unit.
+     */
+    public int intValue(Unit<Q> unit) {
+        long longValue = longValue(unit);
+        if ((longValue > java.lang.Integer.MAX_VALUE)
+                || (longValue < java.lang.Integer.MIN_VALUE))
+            throw new ArithmeticException("Overflow");
+        return (int) longValue;
+    }
+
+    /**
+     * Compares this measure against the specified object for 
+     * strict equality (same unit and amount).
+     * To compare measures stated using different units the  
+     * {@link #compareTo} method should be used. 
+     *
+     * @param  obj the object to compare with.
+     * @return <code>true</code> if both objects are identical (same 
+     *         unit and same amount); <code>false</code> otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Measure))
+            return false;
+        Measure that = (Measure) obj;
+        return this.getUnit().equals(that.getUnit())
+                && this.getValue().equals(that.getValue());
+    }
+
+    /**
+     * Returns the hash code for this scalar.
+     * 
+     * @return the hash code value.
+     */
+    public int hashCode() {
+        return getUnit().hashCode() + getValue().hashCode();
+    }
+
+
+    /**
+     * Compares this measure to the specified measurable quantity.
+     * This method compares the {@link Measurable#doubleValue(Unit)} of 
+     * both this measure and the specified measurable stated in the 
+     * same unit (this measure's {@link #getUnit() unit}).
+     * 
+     * @return  a negative integer, zero, or a positive integer as this measure
+     *          is less than, equal to, or greater than the specified measurable
+     *          quantity.
+      * @return <code>Double.compare(this.doubleValue(getUnit()), 
+      *         that.doubleValue(getUnit()))</code>
+     */
+    public int compareTo(Measurable<Q> that) {
+        return java.lang.Double.compare(doubleValue(getUnit()), that
+                .doubleValue(getUnit()));
+    }
+
+    /**
+     * Holds scalar implementation for <code>double</code> values.
+     */
+    private static final class Double<Q extends Quantity> extends
+            Measure<java.lang.Double, Q> {
+
+        private final double _value;
+
+        private final Unit<Q> _unit;
+
+        public Double(double value, Unit<Q> unit) {
+            _value = value;
+            _unit = unit;
+        }
+
+        @Override
+        public Unit<Q> getUnit() {
+            return _unit;
+        }
+
+        @Override
+        public java.lang.Double getValue() {
+            return _value;
+        }
+
+        @Override
+        public Measure<java.lang.Double, Q> to(Unit<Q> unit) {
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return this;
+            return new Double<Q>(doubleValue(unit), unit);
+        }
+
+        public double doubleValue(Unit<Q> unit) {
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return _value;
+            return _unit.getConverterTo(unit).convert(_value);
+        }
+
+        private static final long serialVersionUID = 1L;
+    }
+
+    /**
+     * Holds scalar implementation for <code>long</code> values.
+     */
+    private static final class Long<Q extends Quantity> extends
+            Measure<java.lang.Long, Q> {
+
+        private final long _value;
+
+        private final Unit<Q> _unit;
+
+        public Long(long value, Unit<Q> unit) {
+            _value = value;
+            _unit = unit;
+        }
+
+        @Override
+        public Unit<Q> getUnit() {
+            return _unit;
+        }
+
+        @Override
+        public java.lang.Long getValue() {
+            return _value;
+        }
+
+        @Override
+        public Measure<java.lang.Long, Q> to(Unit<Q> unit) {
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return this;
+            return new Long<Q>(longValue(unit), unit);
+        }
+
+        public double doubleValue(Unit<Q> unit) {
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return _value;
+            return _unit.getConverterTo(unit).convert(_value);
+        }
+
+        public long longValue(Unit<Q> unit) throws ArithmeticException {
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return _value; // No conversion, returns value directly.
+            return super.longValue(unit);
+        }
+
+        private static final long serialVersionUID = 1L;
+
+    }
+
+    /**
+     * Holds scalar implementation for <code>float</code> values.
+     */
+    private static final class Float<Q extends Quantity> extends
+            Measure<java.lang.Float, Q> {
+
+        private final float _value;
+
+        private final Unit<Q> _unit;
+
+        public Float(float value, Unit<Q> unit) {
+            _value = value;
+            _unit = unit;
+        }
+
+        @Override
+        public Unit<Q> getUnit() {
+            return _unit;
+        }
+
+        @Override
+        public java.lang.Float getValue() {
+            return _value;
+        }
+
+        @Override
+        public Measure<java.lang.Float, Q> to(Unit<Q> unit) {
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return this;
+            return new Float<Q>(floatValue(unit), unit);
+        }
+
+        public double doubleValue(Unit<Q> unit) {
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return _value;
+            return _unit.getConverterTo(unit).convert(_value);
+        }
+
+        private static final long serialVersionUID = 1L;
+    }
+
+    /**
+     * Holds scalar implementation for <code>long</code> values.
+     */
+    private static final class Integer<Q extends Quantity> extends
+            Measure<java.lang.Integer, Q> {
+
+        private final int _value;
+
+        private final Unit<Q> _unit;
+
+        public Integer(int value, Unit<Q> unit) {
+            _value = value;
+            _unit = unit;
+        }
+
+        @Override
+        public Unit<Q> getUnit() {
+            return _unit;
+        }
+
+        @Override
+        public java.lang.Integer getValue() {
+            return _value;
+        }
+
+        @Override
+        public Measure<java.lang.Integer, Q> to(Unit<Q> unit) {
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return this;
+            return new Integer<Q>(intValue(unit), unit);
+        }
+
+        public double doubleValue(Unit<Q> unit) {
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return _value;
+            return _unit.getConverterTo(unit).convert(_value);
+        }
+
+        public long longValue(Unit<Q> unit) throws ArithmeticException {
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return _value; // No conversion, returns value directly.
+            return super.longValue(unit);
+        }
+
+        private static final long serialVersionUID = 1L;
+
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/VectorMeasure.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/VectorMeasure.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/VectorMeasure.java	(revision 28000)
@@ -0,0 +1,248 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2007 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure;
+
+import javax.measure.converter.UnitConverter;
+import javax.measure.quantity.Quantity;
+import javax.measure.unit.Unit;
+
+/**
+ * <p> This class represents a measurement vector of two or more dimensions.
+ *     For example:[code]
+ *         VectorMeasure<Length> dimension = VectorMeasure.valueOf(12.0, 30.0, 40.0, MILLIMETER);
+ *         VectorMeasure<Velocity> v2d = VectorMeasure.valueOf(-2.2, -3.0, KNOTS);
+ *         VectorMeasure<ElectricCurrent> c2d = VectorMeasure.valueOf(-7.3, 3.5, NANOAMPERE);
+ *     [/code]
+ * </p>
+ *     
+ * <p> Subclasses may provide fixed dimensions specializations:[code]
+ *         class Velocity2D extends VectorMeasure<Velocity> {
+ *              public Velocity2D(double x, double y, Unit<Velocity> unit) {
+ *                  ...
+ *              }
+ *         }
+ *     [/code]</p>
+ *     
+ * <p> Measurement vectors may use {@link CompoundUnit compound units}:[code]
+ *     VectorMeasure<Angle> latLong = VectorMeasure.valueOf(12.345, 22.23, DEGREE_ANGLE);
+ *     Unit<Angle> HOUR_MINUTE_SECOND_ANGLE = DEGREE_ANGLE.compound(MINUTE_ANGLE).compound(SECOND_ANGLE);
+ *     System.out.println(latLong.to(HOUR_MINUTE_SECOND_ANGLE));
+ *     
+ *     > [12°19'42", 22°12'48"] [/code]</p>
+ *     
+ * <p> Instances of this class (and sub-classes) are immutable.</p>    
+ *     
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 4.3, October 3, 2007
+ */
+@SuppressWarnings("serial")
+public abstract class VectorMeasure<Q extends Quantity> extends Measure<double[], Q> {
+    
+    /**
+     * Default constructor (for sub-classes). 
+     */
+    protected VectorMeasure() {
+    }
+
+    /**
+     * Returns a 2-dimensional measurement vector.
+     * 
+     * @param x the first vector component value.
+     * @param y the second vector component value.
+     * @param unit the measurement unit.
+     */
+    public static <Q extends Quantity> VectorMeasure<Q> valueOf(
+            double x, double y, Unit<Q> unit) {
+        return new TwoDimensional<Q>(x, y, unit);
+    }
+
+    /**
+     * Returns a 3-dimensional measurement vector.
+     * 
+     * @param x the first vector component value.
+     * @param y the second vector component value.
+     * @param z the third vector component value.
+     * @param unit the measurement unit.
+     */
+    public static <Q extends Quantity> VectorMeasure<Q> valueOf(
+            double x, double y, double z, Unit<Q> unit) {
+        return new ThreeDimensional<Q>(x, y, z, unit);
+    }
+
+    /**
+     * Returns a multi-dimensional measurement vector.
+     * 
+     * @param components the vector component values.
+     * @param unit the measurement unit.
+     */
+    public static <Q extends Quantity> VectorMeasure<Q> valueOf(double[] components, 
+            Unit<Q> unit) {
+        return new MultiDimensional<Q>(components, unit);
+    }
+    
+    /**
+     * Returns the measurement vector equivalent to this one but stated in the 
+     * specified unit.
+     * 
+     * @param unit the new measurement unit.
+     * @return the vector measure stated in the specified unit.
+     */
+    public abstract VectorMeasure<Q> to(Unit<Q> unit);
+
+    /**
+     * Returns the norm of this measurement vector stated in the specified
+     * unit.
+     * 
+     * @param unit the unit in which the norm is stated.
+     * @return <code>|this|</code>
+     */
+    public abstract double doubleValue(Unit<Q> unit);
+    
+    // Holds 2-dimensional implementation.
+    private static class TwoDimensional<Q extends Quantity> extends VectorMeasure<Q> {
+        
+        private final double _x;
+        
+        private final double _y;
+        
+        private final Unit<Q> _unit;
+        
+        private TwoDimensional(double x, double y, Unit<Q> unit) {
+            _x = x;
+            _y = y;
+            _unit = unit;
+            
+        }
+        @Override
+        public double doubleValue(Unit<Q> unit) {
+            double norm = Math.sqrt(_x * _x + _y * _y); 
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return norm;
+            return _unit.getConverterTo(unit).convert(norm);            
+        }
+
+        @Override
+        public Unit<Q> getUnit() {
+            return _unit;
+        }
+
+        @Override
+        public double[] getValue() {
+            return new double[] { _x, _y };
+        }
+
+        @Override
+        public TwoDimensional<Q> to(Unit<Q> unit) {
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return this;
+            UnitConverter cvtr = _unit.getConverterTo(unit);
+            return new TwoDimensional<Q>(cvtr.convert(_x), cvtr.convert(_y), unit); 
+        } 
+
+        private static final long serialVersionUID = 1L;
+
+    }
+    
+    // Holds 3-dimensional implementation.
+    private static class ThreeDimensional<Q extends Quantity> extends VectorMeasure<Q> {
+        
+        private final double _x;
+        
+        private final double _y;
+        
+        private final double _z;
+        
+        private final Unit<Q> _unit;
+        
+        private ThreeDimensional(double x, double y, double z, Unit<Q> unit) {
+            _x = x;
+            _y = y;
+            _z = z;
+            _unit = unit;
+            
+        }
+        @Override
+        public double doubleValue(Unit<Q> unit) {
+            double norm = Math.sqrt(_x * _x + _y * _y + _z * _z); 
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return norm;
+            return _unit.getConverterTo(unit).convert(norm);            
+        }
+
+        @Override
+        public Unit<Q> getUnit() {
+            return _unit;
+        }
+
+        @Override
+        public double[] getValue() {
+            return new double[] { _x, _y, _z };
+        }
+
+        @Override
+        public ThreeDimensional<Q> to(Unit<Q> unit) {
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return this;
+            UnitConverter cvtr = _unit.getConverterTo(unit);
+            return new ThreeDimensional<Q>(cvtr.convert(_x), cvtr.convert(_y), cvtr.convert(_z), unit); 
+        } 
+
+        private static final long serialVersionUID = 1L;
+
+    }
+    // Holds multi-dimensional implementation.
+    private static class MultiDimensional<Q extends Quantity> extends VectorMeasure<Q> {
+        
+        private final double[] _components;
+        
+        private final Unit<Q> _unit;
+        
+        private MultiDimensional(double[] components, Unit<Q> unit) {
+            _components = components.clone();
+            _unit = unit;            
+        }
+        
+        @Override
+        public double doubleValue(Unit<Q> unit) {
+            double normSquare = _components[0] * _components[0];
+            for (int i=1, n=_components.length; i < n;) {
+                double d = _components[i++];
+                normSquare += d * d;
+            }
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return Math.sqrt(normSquare);
+            return _unit.getConverterTo(unit).convert(Math.sqrt(normSquare));            
+        }
+
+        @Override
+        public Unit<Q> getUnit() {
+            return _unit;
+        }
+
+        @Override
+        public double[] getValue() {
+            return _components.clone();
+        }
+
+        @Override
+        public MultiDimensional<Q> to(Unit<Q> unit) {
+            if ((unit == _unit) || (unit.equals(_unit)))
+                return this;
+            UnitConverter cvtr = _unit.getConverterTo(unit);
+            double[] newValues = new double[_components.length];
+            for (int i=0; i < _components.length; i++) {
+                newValues[i] = cvtr.convert(_components[i]);
+            }
+            return new MultiDimensional<Q>(newValues, unit); 
+        } 
+
+        private static final long serialVersionUID = 1L;
+
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/ConversionException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/ConversionException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/ConversionException.java	(revision 28000)
@@ -0,0 +1,38 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.converter;
+
+/**
+ * Signals that a problem of some sort has occurred either when creating a
+ * converter between two units or during the conversion itself.
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 3.1, April 2, 2006
+ */
+public class ConversionException extends RuntimeException {
+
+    /**
+     * Constructs a <code>ConversionException</code> with no detail message.
+     */
+    public ConversionException() {
+        super();
+    }
+
+    /**
+     * Constructs a <code>ConversionException</code> with the specified detail
+     * message.
+     *
+     * @param  message the detail message.
+     */
+    public ConversionException(String message) {
+        super(message);
+    }
+
+    private static final long serialVersionUID = 1L;
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/MultiplyConverter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/MultiplyConverter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/MultiplyConverter.java	(revision 28000)
@@ -0,0 +1,77 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.converter;
+
+/**
+ * <p> This class represents a converter multiplying numeric values by a 
+ *     constant scaling factor (approximated as a <code>double</code>). 
+ *     For exact scaling conversions {@link RationalConverter} is preferred.</p>
+ *      
+ * <p> Instances of this class are immutable.</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 3.1, April 22, 2006
+ */
+public final class MultiplyConverter extends UnitConverter {
+
+    /**
+     * Holds the scale factor.
+     */
+    private final double _factor;
+
+    /**
+     * Creates a multiply converter with the specified scale factor.
+     *
+     * @param  factor the scale factor.
+     * @throws IllegalArgumentException if offset is one (or close to one).
+     */
+    public MultiplyConverter(double factor) {
+        if ((float)factor == 1.0)
+            throw new IllegalArgumentException("Identity converter not allowed");
+        _factor = factor;
+    }
+
+    @Override
+    public UnitConverter inverse() {
+        return new MultiplyConverter(1.0 / _factor);
+    }
+
+    @Override
+    public double convert(double amount) {
+        return _factor * amount;
+    }
+
+    @Override
+    public boolean isLinear() {
+        return true;
+    }
+
+    @Override
+    public UnitConverter concatenate(UnitConverter converter) {
+        if (converter instanceof MultiplyConverter) {
+            double factor = _factor * ((MultiplyConverter) converter)._factor;
+            return valueOf(factor);
+        } else if (converter instanceof RationalConverter) {
+            double factor = _factor
+                    * ((RationalConverter) converter).getDividend()
+                    / ((RationalConverter) converter).getDivisor();
+            return valueOf(factor);
+        } else {
+            return super.concatenate(converter);
+        }
+    }
+
+    private static UnitConverter valueOf(double factor) {
+        float asFloat = (float) factor;
+        return asFloat == 1.0f ? UnitConverter.IDENTITY
+                : new MultiplyConverter(factor);
+    }
+
+    private static final long serialVersionUID = 1L;
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/RationalConverter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/RationalConverter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/RationalConverter.java	(revision 28000)
@@ -0,0 +1,127 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.converter;
+
+/**
+ * <p> This class represents a converter multiplying numeric values by an
+ *     exact scaling factor (represented as the quotient of two 
+ *     <code>long</code> numbers).</p>
+ *  
+ * <p> Instances of this class are immutable.</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 3.1, April 22, 2006
+ */
+public final class RationalConverter extends UnitConverter {
+
+    /**
+     * Holds the converter dividend.
+     */
+    private final long _dividend;
+
+    /**
+     * Holds the converter divisor (always positive).
+     */
+    private final long _divisor;
+
+    /**
+     * Creates a rational converter with the specified dividend and 
+     * divisor.
+     *
+     * @param dividend the dividend.
+     * @param divisor the positive divisor.
+     * @throws IllegalArgumentException if <code>divisor &lt; 0</code>
+     * @throws IllegalArgumentException if <code>dividend == divisor</code>
+     */
+    public RationalConverter(long dividend, long divisor) {
+        if (divisor < 0)
+            throw new IllegalArgumentException("Negative divisor");
+        if (dividend == divisor) 
+            throw new IllegalArgumentException("Identity converter not allowed");
+        _dividend = dividend;
+        _divisor = divisor;
+    }
+
+    /**
+     * Returns the dividend for this rational converter.
+     *
+     * @return this converter dividend.
+     */
+    public long getDividend() {
+        return _dividend;
+    }
+
+    /**
+     * Returns the positive divisor for this rational converter.
+     *
+     * @return this converter divisor.
+     */
+    public long getDivisor() {
+        return _divisor;
+    }
+
+    @Override
+    public UnitConverter inverse() {
+        return _dividend < 0 ? new RationalConverter(-_divisor, -_dividend)
+                : new RationalConverter(_divisor, _dividend);
+    }
+
+    @Override
+    public double convert(double amount) {
+        return amount * _dividend / _divisor;
+    }
+
+    @Override
+    public boolean isLinear() {
+        return true;
+    }
+
+    @Override
+    public UnitConverter concatenate(UnitConverter converter) {
+        if (converter instanceof RationalConverter) {
+            RationalConverter that = (RationalConverter) converter;
+            long dividendLong = this._dividend * that._dividend;
+            long divisorLong = this._divisor * that._divisor;
+            double dividendDouble = ((double)this._dividend) * that._dividend;
+            double divisorDouble = ((double)this._divisor) * that._divisor;
+            if ((dividendLong != dividendDouble) || 
+                    (divisorLong != divisorDouble)) { // Long overflows.
+                return new MultiplyConverter(dividendDouble / divisorDouble);
+            }
+            long gcd = gcd(dividendLong, divisorLong);
+            return RationalConverter.valueOf(dividendLong / gcd, divisorLong / gcd);
+        } else if (converter instanceof MultiplyConverter) {
+            return converter.concatenate(this);
+        } else {
+            return super.concatenate(converter);
+        }
+    }
+
+    private static UnitConverter valueOf(long dividend, long divisor) {
+        return (dividend == 1L) && (divisor == 1L) ? UnitConverter.IDENTITY
+                : new RationalConverter(dividend, divisor);
+    }
+
+    /**
+     * Returns the greatest common divisor (Euclid's algorithm).
+     *
+     * @param  m the first number.
+     * @param  nn the second number.
+     * @return the greatest common divisor.
+     */
+    private static long gcd(long m, long n) {
+        if (n == 0L) {
+            return m;
+        } else {
+            return gcd(n, m % n);
+        }
+    }
+
+    private static final long serialVersionUID = 1L;
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/UnitConverter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/UnitConverter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/UnitConverter.java	(revision 28000)
@@ -0,0 +1,189 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.converter;
+
+import java.io.Serializable;
+
+/**
+ * <p> This class represents a converter of numeric values.</p>
+ * 
+ * <p> It is not required for sub-classes to be immutable
+ *     (e.g. currency converter).</p>
+ *     
+ * <p> Sub-classes must ensure unicity of the {@link #IDENTITY identity} 
+ *     converter. In other words, if the result of an operation is equivalent
+ *     to the identity converter, then the unique {@link #IDENTITY} instance 
+ *     should be returned.</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 3.1, April 22, 2006
+ */
+@SuppressWarnings("serial")
+public abstract class UnitConverter implements Serializable {
+
+    /**
+     * Holds the identity converter (unique). This converter does nothing
+     * (<code>ONE.convert(x) == x</code>).
+     */
+    public static final UnitConverter IDENTITY = new Identity();
+
+    /**
+     * Default constructor.
+     */
+    protected UnitConverter() {
+    }
+
+    /**
+     * Returns the inverse of this converter. If <code>x</code> is a valid
+     * value, then <code>x == inverse().convert(convert(x))</code> to within
+     * the accuracy of computer arithmetic.
+     *
+     * @return the inverse of this converter.
+     */
+    public abstract UnitConverter inverse();
+
+    /**
+     * Converts a double value.
+     *
+     * @param  x the numeric value to convert.
+     * @return the converted numeric value.
+     * @throws ConversionException if an error occurs during conversion.
+     */
+    public abstract double convert(double x) throws ConversionException;
+
+    /**
+     * Indicates if this converter is linear. A converter is linear if
+     * <code>convert(u + v) == convert(u) + convert(v)</code> and
+     * <code>convert(r * u) == r * convert(u)</code>.
+     * For linear converters the following property always hold:[code]
+     *     y1 = c1.convert(x1);
+     *     y2 = c2.convert(x2); 
+     * then y1*y2 = c1.concatenate(c2).convert(x1*x2)[/code]
+     *
+     * @return <code>true</code> if this converter is linear;
+     *         <code>false</code> otherwise.
+     */
+    public abstract boolean isLinear();
+
+    /**
+     * Indicates whether this converter is considered the same as the  
+     * converter specified. To be considered equal this converter 
+     * concatenated with the one specified must returns the {@link #IDENTITY}.
+     *
+     * @param  cvtr the converter with which to compare.
+     * @return <code>true</code> if the specified object is a converter 
+     *         considered equals to this converter;<code>false</code> otherwise.
+     */
+    public boolean equals(Object cvtr) {
+        if (!(cvtr instanceof UnitConverter)) return false;
+        return this.concatenate(((UnitConverter)cvtr).inverse()) == IDENTITY;        
+    }
+
+    /**
+     * Returns a hash code value for this converter. Equals object have equal
+     * hash codes.
+     *
+     * @return this converter hash code value.
+     * @see    #equals
+     */
+    public int hashCode() {
+        return Float.floatToIntBits((float)convert(1.0));
+    }
+
+    /**
+     * Concatenates this converter with another converter. The resulting
+     * converter is equivalent to first converting by the specified converter,
+     * and then converting by this converter.
+     * 
+     * <p>Note: Implementations must ensure that the {@link #IDENTITY} instance
+     *          is returned if the resulting converter is an identity 
+     *          converter.</p> 
+     * 
+     * @param  converter the other converter.
+     * @return the concatenation of this converter with the other converter.
+     */
+    public UnitConverter concatenate(UnitConverter converter) {
+        return (converter == IDENTITY) ? this : new Compound(converter, this);
+    }
+
+    /**
+     * This inner class represents the identity converter (singleton).
+     */
+    private static final class Identity extends UnitConverter {
+
+        @Override
+        public UnitConverter inverse() {
+            return this;
+        }
+
+        @Override
+        public double convert(double x) {
+            return x;
+        }
+
+        @Override
+        public boolean isLinear() {
+            return true;
+        }
+
+        @Override
+        public UnitConverter concatenate(UnitConverter converter) {
+            return converter;
+        }
+
+        private static final long serialVersionUID = 1L;
+
+    }
+
+    /**
+     * This inner class represents a compound converter.
+     */
+    private static final class Compound extends UnitConverter {
+
+        /**
+         * Holds the first converter.
+         */
+        private final UnitConverter _first;
+
+        /**
+         * Holds the second converter.
+         */
+        private final UnitConverter _second;
+
+        /**
+         * Creates a compound converter resulting from the combined
+         * transformation of the specified converters.
+         *
+         * @param  first the first converter.
+         * @param  second the second converter.
+         */
+        private Compound(UnitConverter first, UnitConverter second) {
+            _first = first;
+            _second = second;
+        }
+
+        @Override
+        public UnitConverter inverse() {
+            return new Compound(_second.inverse(), _first.inverse());
+        }
+
+        @Override
+        public double convert(double x) {
+            return _second.convert(_first.convert(x));
+        }
+
+        @Override
+        public boolean isLinear() {
+            return _first.isLinear() && _second.isLinear();
+        }
+
+        private static final long serialVersionUID = 1L;
+
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/converter/package.html	(revision 28000)
@@ -0,0 +1,5 @@
+<body>
+<p> Provides support for unit conversion.</p>
+<h3>UML Diagram</h3>
+        <IMG alt="UML Diagram" src="doc-files/converter.png">
+</body>
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/package.html	(revision 28000)
@@ -0,0 +1,77 @@
+<body>
+<p> Provides strongly typed measurements to enforce compile-time
+    check of parameters consistency and avoid interface errors.</p>
+
+<p> Let's take the following example:[code]
+        class Person {
+            void setWeight(double weight);
+        }[/code]
+    Should the weight be in pound, kilogram ??<br>
+    Using measures there is no room for error:[code]
+        class Person {
+            void setWeight(Measurable<Mass> weight);
+        }[/code]
+    Not only the interface is cleaner (the weight has to be of mass type); 
+    but also there is no confusion on the measurement unit:[code]
+        double weightInKg = weight.doubleValue(KILOGRAM);
+        double weightInLb = weight.doubleValue(POUND);[/code]
+    Measurable work hand-in-hand with units (also parameterized).
+    For example, the following would result in compile-time error:[code]
+        double weightInLiter = weight.doubleValue(LITER); // Compile error, Unit<Mass> required.
+        [/code]</p>
+
+<p> Users may create their own {@link javax.measure.Measurable
+    Measurable} implementation:[code]
+
+         public class Period implements Measurable<Duration> {
+              long nanoseconds;
+              ...
+         }
+ 
+         public class Distance implements Measurable<Length> {
+              double meters;
+              ...
+         }
+                  
+         public class Velocity3D implements Measurable<Velocity> {
+              double x, y, z; // In meters.
+              ...
+         }
+                 
+
+[/code]</p>
+
+<p> Users may also combine a definite amount (scalar, vector, collection, etc.) 
+    to a unit and make it a {@link javax.measure.Measure Measure} (and  
+    a {@link javax.measure.Measurable Measurable} instance). For example:
+    [code]
+           
+         // Scalar measurement (numerical).     
+         person.setWeight(Measure.valueOf(180.0, POUND)); // Measure<Double, Mass>
+         timer.setPeriod(Measure.valueOf(20, MILLI(SECOND)); // Measure<Integer, Duration>
+         circuit.setCurrent(Measure.valueOf(Complex.valueOf(2, -3), AMPERE); // (2 - 3i) A
+         bottle.setPression(Measure.valueOf(Rational.valueOf(20, 100), ATMOSPHERE)); // (20/100) Atm
+
+         // Vector measurement.
+         abstract class MeasureVector<E, Q extends Quantity> extends Measure<E[], Q> {
+             ... // doubleValue(Unit) returns vector norm.
+         }
+         MeasureVector<Double, Velocity> v = MeasureVector.valueOf(METRE_PER_SECOND, 1.0, 2.0, 3.0);
+         plane.setVelocity(v);
+
+         // Statistical measurement.
+         class Average<Q extends Quantity> extends Measure<double[], Q>{
+             ... // doubleValue(Unit) returns average value.
+         }
+         sea.setTemperature(Average.valueOf(new double[] { 33.4, 44.55, 32.33} , CELCIUS));
+         
+         // Measurement with uncertainty (and additional operations).
+         public class Amount<Q extends Quantity> extends Measurable<Q>  {
+              public Amount(double value, double error, Unit<Q> unit) { ... }
+              public Amount<Q> plus(Amount<Q> that) {...}
+              public Amount<?> times(Amount<?> that) {...} 
+              ... // doubleValue(Unit) returns estimated value.
+         }  
+    [/code]</p>
+    
+</body>
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Angle.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Angle.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Angle.java	(revision 28000)
@@ -0,0 +1,28 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.quantity;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+/**
+ * This interface represents the figure formed by two lines diverging from a 
+ * common point. The system unit for this quantity is "rad" (radian).
+ * This quantity is dimensionless.
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 1.0, January 14, 2006
+ */
+public interface Angle extends Dimensionless {
+
+    /**
+     * Holds the SI unit (Système International d'Unités) for this quantity.
+     */
+    public final static Unit<Angle> UNIT = SI.RADIAN; // NO_UCD
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Dimensionless.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Dimensionless.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Dimensionless.java	(revision 28000)
@@ -0,0 +1,25 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.quantity;
+import javax.measure.unit.Unit;
+
+/**
+ * This interface represents a dimensionless quantity.
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 1.0, January 14, 2006
+ */
+public interface Dimensionless extends Quantity {
+
+    /**
+     * Holds the SI unit (Système International d'Unités) for this quantity.
+     */
+    public final static Unit<Dimensionless> UNIT = Unit.ONE; // NO_UCD
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Duration.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Duration.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Duration.java	(revision 28000)
@@ -0,0 +1,27 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.quantity;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+/**
+ * This interface represents a period of existence or persistence. The system
+ * unit for this quantity is "s" (second).
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 1.0, January 14, 2006
+ */
+public interface Duration extends Quantity {
+
+    /**
+     * Holds the SI unit (Système International d'Unités) for this quantity.
+     */
+    public final static Unit<Duration> UNIT = SI.SECOND; // NO_UCD
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Length.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Length.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Length.java	(revision 28000)
@@ -0,0 +1,28 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.quantity;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+/**
+ * This interface represents the extent of something along its greatest 
+ * dimension or the extent of space between two objects or places. 
+ * The system unit for this quantity is "m" (meter).
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 1.0, January 14, 2006
+ */
+public interface Length extends Quantity {
+
+    /**
+     * Holds the SI unit (Système International d'Unités) for this quantity.
+     */
+    public final static Unit<Length> UNIT = SI.METRE; // NO_UCD
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Quantity.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Quantity.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/Quantity.java	(revision 28000)
@@ -0,0 +1,31 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.quantity;
+
+/**
+ * <p> This interface represents any type of quantitative properties or 
+ *     attributes of thing. Mass, time, distance, heat, and angular separation 
+ *     are among the familiar examples of quantitative properties.</p>
+ *     
+ * <p> Distinct quantities have usually different physical dimensions; although 
+ *     it is not required nor necessary, for example {@link Torque} and 
+ *     {@link Energy} have same dimension but are of different nature 
+ *     (vector for torque, scalar for energy).</p>
+ * 
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 4.0, February 25, 2007
+ * @see <a href="http://en.wikipedia.org/wiki/Quantity">Wikipedia: Quantity</a>
+ * @see <a href="http://en.wikipedia.org/wiki/Dimensional_analysis">
+ *      Wikipedia: Dimensional Analysis</a>
+ */
+public interface Quantity  {
+    
+    // No method - Tagging interface.
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/quantity/package.html	(revision 28000)
@@ -0,0 +1,6 @@
+<body>
+<p> Provides quantitative properties or attributes of thing such as 
+    mass, time, distance, heat, and angular separation.</p>
+<p> Each quantity sub-interface holds a static <code>UNIT</code> field 
+    holding the standard unit for the quantity.</p>
+</body>
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/AlternateUnit.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/AlternateUnit.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/AlternateUnit.java	(revision 28000)
@@ -0,0 +1,117 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.unit;
+
+import javax.measure.converter.UnitConverter;
+import javax.measure.quantity.Quantity;
+
+/**
+ * <p> This class represents the units used in expressions to distinguish
+ *     between quantities of a different nature but of the same dimensions.</p>
+ *     
+ * <p> Instances of this class are created through the 
+ *     {@link Unit#alternate(String)} method.</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 4.2, August 26, 2007
+ */
+public final class AlternateUnit<Q extends Quantity> extends DerivedUnit<Q> {
+
+    /**
+     * Holds the symbol.
+     */
+    private final String _symbol;
+
+    /**
+     * Holds the parent unit (a system unit).
+     */
+    private final Unit<?> _parent;
+
+    /**
+     * Creates an alternate unit for the specified unit identified by the 
+     * specified symbol. 
+     *
+     * @param symbol the symbol for this alternate unit.
+     * @param parent the system unit from which this alternate unit is
+     *        derived.
+     * @throws UnsupportedOperationException if the source is not 
+     *         a standard unit.
+     * @throws IllegalArgumentException if the specified symbol is 
+     *         associated to a different unit.
+     */
+    AlternateUnit(String symbol, Unit<?> parent) {
+        if (!parent.isStandardUnit())
+            throw new UnsupportedOperationException(this
+                    + " is not a standard unit");
+        _symbol = symbol;
+        _parent = parent;
+        // Checks if the symbol is associated to a different unit.
+        synchronized (Unit.SYMBOL_TO_UNIT) {
+            Unit<?> unit = Unit.SYMBOL_TO_UNIT.get(symbol);
+            if (unit == null) {
+                Unit.SYMBOL_TO_UNIT.put(symbol, this);
+                return;
+            }
+            if (unit instanceof AlternateUnit) {
+                AlternateUnit<?> existingUnit = (AlternateUnit<?>) unit;
+                if (symbol.equals(existingUnit._symbol)
+                        && _parent.equals(existingUnit._parent))
+                    return; // OK, same unit.
+            }
+            throw new IllegalArgumentException("Symbol " + symbol
+                    + " is associated to a different unit");
+        }
+    }
+
+    /**
+     * Returns the parent unit from which this alternate unit is derived 
+     * (a system unit itself).
+     *
+     * @return the parent of the alternate unit.
+     */
+    @SuppressWarnings("unchecked")
+    public final Unit<? super Q> getParent() {
+        return (Unit<? super Q>) _parent;
+    }
+
+    @Override
+    public final Unit<? super Q> getStandardUnit() {
+        return this;
+    }
+
+    @Override
+    public final UnitConverter toStandardUnit() {
+        return UnitConverter.IDENTITY;
+    }
+
+    /**
+     * Indicates if this alternate unit is considered equals to the specified 
+     * object (both are alternate units with equal symbol, equal base units
+     * and equal converter to base units).
+     *
+     * @param  that the object to compare for equality.
+     * @return <code>true</code> if <code>this</code> and <code>that</code>
+     *         are considered equals; <code>false</code>otherwise. 
+     */
+    public boolean equals(Object that) {
+        if (this == that)
+            return true;
+        if (!(that instanceof AlternateUnit))
+            return false;
+        AlternateUnit<?> thatUnit = (AlternateUnit<?>) that;
+        return this._symbol.equals(thatUnit._symbol); // Symbols are unique.
+    }
+
+    // Implements abstract method.
+    public int hashCode() {
+        return _symbol.hashCode();
+    }
+
+    private static final long serialVersionUID = 1L;
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/BaseUnit.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/BaseUnit.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/BaseUnit.java	(revision 28000)
@@ -0,0 +1,112 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.unit;
+
+import javax.measure.converter.UnitConverter;
+import javax.measure.quantity.Quantity;
+
+/**
+ * <p> This class represents the building blocks on top of which all others
+ *     units are created. Base units are typically dimensionally independent.
+ *     The actual unit dimension is determinated by the current 
+ *     {@link Dimension.Model model}. For example using the {@link 
+ *     Dimension.Model#STANDARD standard} model, {@link SI#CANDELA} 
+ *     has the dimension of {@link SI#WATT watt}:[code]
+ *     // Standard model.
+ *     BaseUnit<Length> METER = new BaseUnit<Length>("m");
+ *     BaseUnit<LuminousIntensity> CANDELA = new BaseUnit<LuminousIntensity>("cd");
+ *     System.out.println(METER.getDimension());
+ *     System.out.println(CANDELA.getDimension());
+ *     
+ *     > [L]
+ *     > [L]²·[M]/[T]³
+ *     [/code]</p>
+ * <p> This class represents the "standard base units" which includes SI base 
+ *     units and possibly others user-defined base units. It does not represent 
+ *     the base units of any specific {@link SystemOfUnits} (they would have 
+ *     be base units accross all possible systems otherwise).</p> 
+ *           
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 3.1, April 22, 2006
+ * @see <a href="http://en.wikipedia.org/wiki/SI_base_unit">
+ *       Wikipedia: SI base unit</a>
+ */
+public class BaseUnit<Q extends Quantity> extends Unit<Q> {
+
+    /**
+     * Holds the symbol.
+     */
+    private final String _symbol;
+
+    /**
+     * Creates a base unit having the specified symbol. 
+     *
+     * @param symbol the symbol of this base unit.
+     * @throws IllegalArgumentException if the specified symbol is 
+     *         associated to a different unit.
+     */
+    public BaseUnit(String symbol) {
+        _symbol = symbol;
+        // Checks if the symbol is associated to a different unit.
+        synchronized (Unit.SYMBOL_TO_UNIT) {
+            Unit<?> unit = Unit.SYMBOL_TO_UNIT.get(symbol);
+            if (unit == null) {
+                Unit.SYMBOL_TO_UNIT.put(symbol, this);
+                return;
+            }
+            if (!(unit instanceof BaseUnit)) 
+               throw new IllegalArgumentException("Symbol " + symbol
+                    + " is associated to a different unit");
+        }
+    }
+
+    /**
+     * Returns the unique symbol for this base unit. 
+     *
+     * @return this base unit symbol.
+     */
+    public final String getSymbol() {
+        return _symbol;
+    }
+
+    /**
+     * Indicates if this base unit is considered equals to the specified 
+     * object (both are base units with equal symbol, standard dimension and 
+     * standard transform).
+     *
+     * @param  that the object to compare for equality.
+     * @return <code>true</code> if <code>this</code> and <code>that</code>
+     *         are considered equals; <code>false</code>otherwise. 
+     */
+    public boolean equals(Object that) {
+        if (this == that)
+            return true;
+        if (!(that instanceof BaseUnit))
+            return false;
+        BaseUnit<?> thatUnit = (BaseUnit<?>) that;
+        return this._symbol.equals(thatUnit._symbol); 
+    }
+        
+    @Override
+    public int hashCode() {
+        return _symbol.hashCode();
+    }
+
+    @Override
+    public Unit<? super Q> getStandardUnit() {
+        return this;
+    }
+
+    @Override
+    public UnitConverter toStandardUnit() {
+        return UnitConverter.IDENTITY;
+    }
+
+    private static final long serialVersionUID = 1L;
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/DerivedUnit.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/DerivedUnit.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/DerivedUnit.java	(revision 28000)
@@ -0,0 +1,28 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.unit;
+
+import javax.measure.quantity.Quantity;
+
+/**
+ * <p> This class identifies the units created by combining or transforming
+ *     other units.</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 3.1, April 22, 2006
+ */
+@SuppressWarnings("serial")
+public abstract class DerivedUnit<Q extends Quantity> extends Unit<Q> {
+
+    /**
+     * Default constructor.
+     */
+    protected DerivedUnit() {
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/Dimension.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/Dimension.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/Dimension.java	(revision 28000)
@@ -0,0 +1,213 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.unit;
+
+import java.io.Serializable;
+
+import javax.measure.converter.UnitConverter;
+import javax.measure.quantity.Dimensionless;
+
+/**
+ * <p> This class represents the dimension of an unit. Two units <code>u1</code>
+ *     and <code>u2</code> are {@link Unit#isCompatible compatible} if and
+ *     only if <code>(u1.getDimension().equals(u2.getDimension())))</code>
+ *     </p>
+ *     
+ * <p> Instances of this class are immutable.</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 3.1, April 22, 2006
+ * @see <a href="http://en.wikipedia.org/wiki/Dimensional_analysis">
+ *      Wikipedia: Dimensional Analysis</a>
+ */
+public final class Dimension implements Serializable {
+
+    /**
+     * Holds the current physical model.
+     */
+    private static Model CurrentModel = Model.STANDARD;
+
+    /**
+     * Holds dimensionless.
+     */
+    public static final Dimension NONE = new Dimension(Unit.ONE);
+
+    /**
+     * Holds length dimension (L).
+     */
+    public static final Dimension LENGTH = new Dimension('L');
+
+    /**
+     * Holds time dimension (T).
+     */
+    public static final Dimension TIME = new Dimension('T');
+
+    /**
+     * Holds the pseudo unit associated to this dimension.
+     */
+    private final Unit<?> _pseudoUnit;
+
+    /**
+     * Creates a new dimension associated to the specified symbol.
+     * 
+     * @param symbol the associated symbol.
+     */
+    public Dimension(char symbol) {
+        _pseudoUnit = new BaseUnit<Dimensionless>("[" + symbol + "]");
+    }
+
+    /**
+     * Creates a dimension having the specified pseudo-unit 
+     * (base unit or product of base unit).
+     * 
+     * @param pseudoUnit the pseudo-unit identifying this dimension.
+     */
+    private Dimension(Unit<?> pseudoUnit) {
+        _pseudoUnit = pseudoUnit;
+    }
+
+    /**
+     * Returns the product of this dimension with the one specified.
+     *
+     * @param  that the dimension multiplicand.
+     * @return <code>this * that</code>
+     */
+    public final Dimension times(Dimension that) {
+        return new Dimension(this._pseudoUnit.times(that._pseudoUnit));
+    }
+
+    /**
+     * Returns this dimension raised to an exponent.
+     *
+     * @param  n the exponent.
+     * @return the result of raising this dimension to the exponent.
+     */
+    public final Dimension pow(int n) {
+        return new Dimension(this._pseudoUnit.pow(n));
+    }
+
+    /**
+     * Returns the given root of this dimension.
+     *
+     * @param  n the root's order.
+     * @return the result of taking the given root of this dimension.
+     * @throws ArithmeticException if <code>n == 0</code>.
+     */
+    public final Dimension root(int n) {
+        return new Dimension(this._pseudoUnit.root(n));
+    }
+
+    /**
+     * Returns the representation of this dimension.
+     *
+     * @return the representation of this dimension.
+     */
+    public String toString() {
+        return _pseudoUnit.toString();
+    }
+
+    /**
+     * Indicates if the specified dimension is equals to the one specified.
+     *
+     * @param that the object to compare to.
+     * @return <code>true</code> if this dimension is equals to that dimension;
+     *         <code>false</code> otherwise.
+     */
+    public boolean equals(Object that) {
+        if (this == that)
+            return true;
+        return (that instanceof Dimension)
+                && _pseudoUnit.equals(((Dimension) that)._pseudoUnit);
+    }
+
+    /**
+     * Returns the hash code for this dimension.
+     *
+     * @return this dimension hashcode value.
+     */
+    public int hashCode() {
+        return _pseudoUnit.hashCode();
+    }
+
+    /**
+     * Returns the model used to determinate the units dimensions
+     * (default {@link Model#STANDARD STANDARD}).
+     *  
+     * @return the model used when calculating unit dimensions.
+     */
+    public static Model getModel() {
+        return Dimension.CurrentModel;
+    }
+
+    /**
+     * This interface represents the mapping between {@link BaseUnit base units}
+     * and {@link Dimension dimensions}. Custom models may allow
+     * conversions not possible using the {@link #STANDARD standard} model.
+     * For example:[code]
+     * public static void main(String[] args) {
+     *     Dimension.Model relativistic = new Dimension.Model() {
+     *         RationalConverter meterToSecond = new RationalConverter(1, 299792458); // 1/c
+     *   
+     *         public Dimension getDimension(BaseUnit unit) {
+     *             if (unit.equals(SI.METER)) return Dimension.TIME;
+     *             return Dimension.Model.STANDARD.getDimension(unit);
+     *         }
+     *
+     *         public UnitConverter getTransform(BaseUnit unit) {
+     *             if (unit.equals(SI.METER)) return meterToSecond;
+     *             return Dimension.Model.STANDARD.getTransform(unit);
+     *         }};
+     *     Dimension.setModel(relativistic);
+     * 
+     *     // Converts 1.0 GeV (energy) to kg (mass).
+     *     System.out.println(Unit.valueOf("GeV").getConverterTo(KILOGRAM).convert(1.0));
+     * }
+     *   
+     * > 1.7826617302520883E-27[/code]
+     */
+    public interface Model {
+
+        /**
+         * Holds the standard model (default).
+         */
+        public Model STANDARD = new Model() {
+
+            public Dimension getDimension(BaseUnit<?> unit) {
+                if (unit.equals(SI.METRE)) return Dimension.LENGTH;
+                if (unit.equals(SI.SECOND)) return Dimension.TIME;
+                return new Dimension(new BaseUnit<Dimensionless>("[" + unit.getSymbol() + "]"));
+            }
+            
+            public UnitConverter getTransform(BaseUnit<?> unit) {
+                return UnitConverter.IDENTITY;
+            }
+        };
+
+        /**
+         * Returns the dimension of the specified base unit (a dimension 
+         * particular to the base unit if the base unit is not recognized).
+         * 
+         * @param unit the base unit for which the dimension is returned.
+         * @return the dimension of the specified unit.
+         */
+        Dimension getDimension(BaseUnit<?> unit);
+
+        /**
+         * Returns the normalization transform of the specified base unit
+         * ({@link UnitConverter#IDENTITY IDENTITY} if the base unit is 
+         * not recognized).
+         * 
+         * @param unit the base unit for which the transform is returned.
+         * @return the normalization transform.
+         */
+        UnitConverter getTransform(BaseUnit<?> unit);
+    }
+
+    private static final long serialVersionUID = 1L;
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/NonSI.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/NonSI.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/NonSI.java	(revision 28000)
@@ -0,0 +1,115 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.unit;
+
+import static javax.measure.unit.SI.RADIAN;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.measure.quantity.Angle;
+import javax.measure.quantity.Duration;
+
+/**
+ * <p> This class contains units that are not part of the International
+ *     System of Units, that is, they are outside the SI, but are important
+ *     and widely used.</p>
+ *     
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 4.2, August 26, 2007
+ */
+public final class NonSI extends SystemOfUnits {
+
+    /**
+     * Holds collection of NonSI units.
+     */
+    private static HashSet<Unit<?>> UNITS = new HashSet<Unit<?>>();
+
+    /**
+     * Default constructor (prevents this class from being instantiated).
+     */
+    private NonSI() {
+    }
+
+    //////////////
+    // Duration //
+    //////////////
+
+    /**
+     * A unit of duration equal to <code>60 s</code>
+     * (standard name <code>min</code>).
+     */
+    public static final Unit<Duration> MINUTE = nonSI(SI.SECOND.times(60));
+
+    /**
+     * A unit of duration equal to <code>60 {@link #MINUTE}</code>
+     * (standard name <code>h</code>).
+     */
+    public static final Unit<Duration> HOUR = nonSI(MINUTE.times(60));
+
+    /**
+     * A unit of duration equal to <code>24 {@link #HOUR}</code>
+     * (standard name <code>d</code>).
+     */
+    public static final Unit<Duration> DAY = nonSI(HOUR.times(24));
+
+    ///////////
+    // Angle //
+    ///////////
+
+    /**
+     * A unit of angle equal to a full circle or <code>2<i>&pi;</i> 
+     * {@link SI#RADIAN}</code> (standard name <code>rev</code>).
+     */
+    public static final Unit<Angle> REVOLUTION = nonSI(RADIAN.times(2.0 * Math.PI));
+
+    /**
+     * A unit of angle equal to <code>1/360 {@link #REVOLUTION}</code>
+     * (standard name <code>°</code>).
+     */
+    public static final Unit<Angle> DEGREE_ANGLE = nonSI(REVOLUTION.divide(360));
+
+    /**
+     * A unit of angle equal to <code>1/60 {@link #DEGREE_ANGLE}</code>
+     * (standard name <code>′</code>).
+     */
+    public static final Unit<Angle> MINUTE_ANGLE = nonSI(DEGREE_ANGLE.divide(60));
+
+    /**
+     *  A unit of angle equal to <code>1/60 {@link #MINUTE_ANGLE}</code>
+     * (standard name <code>"</code>).
+     */
+    public static final Unit<Angle> SECOND_ANGLE = nonSI(MINUTE_ANGLE.divide(60));
+
+    /////////////////////
+    // Collection View //
+    /////////////////////
+    
+    /**
+     * Returns a read only view over the units defined in this class.
+     *
+     * @return the collection of NonSI units.
+     */
+    public Set<Unit<?>> getUnits() {
+        return Collections.unmodifiableSet(UNITS);
+    }
+
+    /**
+     * Adds a new unit to the collection.
+     *
+     * @param  unit the unit being added.
+     * @return <code>unit</code>.
+     */
+    private static <U extends Unit<?>> U nonSI(U unit) {
+        UNITS.add(unit);
+        return unit;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/ProductUnit.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/ProductUnit.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/ProductUnit.java	(revision 28000)
@@ -0,0 +1,434 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.unit;
+
+import java.io.Serializable;
+
+import javax.measure.converter.ConversionException;
+import javax.measure.converter.UnitConverter;
+import javax.measure.quantity.Quantity;
+
+/**
+ * <p> This class represents units formed by the product of rational powers of
+ *     existing units.</p>
+ *     
+ * <p> This class maintains the canonical form of this product (simplest
+ *     form after factorization). For example:
+ *     <code>METER.pow(2).divide(METER)</code> returns
+ *     <code>METER</code>.</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 3.1, April 22, 2006
+ * @see     Unit#times(Unit)
+ * @see     Unit#divide(Unit)
+ * @see     Unit#pow(int)
+ * @see     Unit#root(int)
+ */
+public final class ProductUnit<Q extends Quantity> extends DerivedUnit<Q> {
+
+    /**
+     * Holds the units composing this product unit.
+     */
+    private final Element[] _elements;
+
+    /**
+     * Holds the hashcode (optimization).
+     */
+    private int _hashCode;
+
+    /**
+     * Default constructor (used solely to create <code>ONE</code> instance).
+     */
+    ProductUnit() {
+        _elements = new Element[0];
+    }
+
+    /**
+     * Product unit constructor.
+     *
+     * @param  elements the product elements.
+     */
+    private ProductUnit(Element[] elements) {
+        _elements = elements;
+    }
+
+    /**
+     * Returns the unit defined from the product of the specifed elements.
+     *
+     * @param  leftElems left multiplicand elements.
+     * @param  rightElems right multiplicand elements.
+     * @return the corresponding unit.
+     */
+    private static Unit<? extends Quantity> getInstance(Element[] leftElems,
+            Element[] rightElems) {
+
+        // Merges left elements with right elements.
+        Element[] result = new Element[leftElems.length + rightElems.length];
+        int resultIndex = 0;
+        for (int i = 0; i < leftElems.length; i++) {
+            Unit<?> unit = leftElems[i]._unit;
+            int p1 = leftElems[i]._pow;
+            int r1 = leftElems[i]._root;
+            int p2 = 0;
+            int r2 = 1;
+            for (int j = 0; j < rightElems.length; j++) {
+                if (unit.equals(rightElems[j]._unit)) {
+                    p2 = rightElems[j]._pow;
+                    r2 = rightElems[j]._root;
+                    break; // No duplicate.
+                }
+            }
+            int pow = (p1 * r2) + (p2 * r1);
+            int root = r1 * r2;
+            if (pow != 0) {
+                int gcd = gcd(Math.abs(pow), root);
+                result[resultIndex++] = new Element(unit, pow / gcd, root / gcd);
+            }
+        }
+
+        // Appends remaining right elements not merged.
+        for (int i = 0; i < rightElems.length; i++) {
+            Unit<?> unit = rightElems[i]._unit;
+            boolean hasBeenMerged = false;
+            for (int j = 0; j < leftElems.length; j++) {
+                if (unit.equals(leftElems[j]._unit)) {
+                    hasBeenMerged = true;
+                    break;
+                }
+            }
+            if (!hasBeenMerged) {
+                result[resultIndex++] = rightElems[i];
+            }
+        }
+
+        // Returns or creates instance.
+        if (resultIndex == 0) {
+            return ONE;
+        } else if ((resultIndex == 1) && (result[0]._pow == result[0]._root)) {
+            return result[0]._unit;
+        } else {
+            Element[] elems = new Element[resultIndex];
+            for (int i = 0; i < resultIndex; i++) {
+                elems[i] = result[i];
+            }
+            return new ProductUnit<Quantity>(elems);
+        }
+    }
+
+    /**
+     * Returns the product of the specified units.
+     *
+     * @param  left the left unit operand.
+     * @param  right the right unit operand.
+     * @return <code>left * right</code>
+     */
+    static Unit<? extends Quantity> getProductInstance(Unit<?> left, Unit<?> right) {
+        Element[] leftElems;
+        if (left instanceof ProductUnit) {
+            leftElems = ((ProductUnit<?>) left)._elements;
+        } else {
+            leftElems = new Element[] { new Element(left, 1, 1) };
+        }
+        Element[] rightElems;
+        if (right instanceof ProductUnit) {
+            rightElems = ((ProductUnit<?>) right)._elements;
+        } else {
+            rightElems = new Element[] { new Element(right, 1, 1) };
+        }
+        return getInstance(leftElems, rightElems);
+    }
+
+    /**
+     * Returns the quotient of the specified units.
+     *
+     * @param  left the dividend unit operand.
+     * @param  right the divisor unit operand.
+     * @return <code>dividend / divisor</code>
+     */
+    static Unit<? extends Quantity> getQuotientInstance(Unit<?> left, Unit<?> right) {
+        Element[] leftElems;
+        if (left instanceof ProductUnit) {
+            leftElems = ((ProductUnit<?>) left)._elements;
+        } else {
+            leftElems = new Element[] { new Element(left, 1, 1) };
+        }
+        Element[] rightElems;
+        if (right instanceof ProductUnit) {
+            Element[] elems = ((ProductUnit<?>) right)._elements;
+            rightElems = new Element[elems.length];
+            for (int i = 0; i < elems.length; i++) {
+                rightElems[i] = new Element(elems[i]._unit, -elems[i]._pow,
+                        elems[i]._root);
+            }
+        } else {
+            rightElems = new Element[] { new Element(right, -1, 1) };
+        }
+        return getInstance(leftElems, rightElems);
+    }
+
+    /**
+     * Returns the product unit corresponding to the specified root of
+     * the specified unit.
+     *
+     * @param  unit the unit.
+     * @param  n the root's order (n &gt; 0).
+     * @return <code>unit^(1/nn)</code>
+     * @throws ArithmeticException if <code>n == 0</code>.
+     */
+    static Unit<? extends Quantity> getRootInstance(Unit<?> unit, int n) {
+        Element[] unitElems;
+        if (unit instanceof ProductUnit) {
+            Element[] elems = ((ProductUnit<?>) unit)._elements;
+            unitElems = new Element[elems.length];
+            for (int i = 0; i < elems.length; i++) {
+                int gcd = gcd(Math.abs(elems[i]._pow), elems[i]._root * n);
+                unitElems[i] = new Element(elems[i]._unit, elems[i]._pow / gcd,
+                        elems[i]._root * n / gcd);
+            }
+        } else {
+            unitElems = new Element[] { new Element(unit, 1, n) };
+        }
+        return getInstance(unitElems, new Element[0]);
+    }
+
+    /**
+     * Returns the number of units in this product.
+     *
+     * @return  the number of units being multiplied.
+     */
+    public int getUnitCount() {
+        return _elements.length;
+    }
+
+    /**
+     * Returns the unit at the specified position.
+     *
+     * @param  index the index of the unit to return.
+     * @return the unit at the specified position.
+     * @throws IndexOutOfBoundsException if index is out of range
+     *         <code>(index &lt; 0 || index &gt;= size())</code>.
+     */
+    public Unit<? extends Quantity> getUnit(int index) {
+        return _elements[index].getUnit();
+    }
+
+    /**
+     * Returns the power exponent of the unit at the specified position.
+     *
+     * @param  index the index of the unit to return.
+     * @return the unit power exponent at the specified position.
+     * @throws IndexOutOfBoundsException if index is out of range
+     *         <code>(index &lt; 0 || index &gt;= size())</code>.
+     */
+    public int getUnitPow(int index) {
+        return _elements[index].getPow();
+    }
+
+    /**
+     * Returns the root exponent of the unit at the specified position.
+     *
+     * @param  index the index of the unit to return.
+     * @return the unit root exponent at the specified position.
+     * @throws IndexOutOfBoundsException if index is out of range
+     *         <code>(index &lt; 0 || index &gt;= size())</code>.
+     */
+    public int getUnitRoot(int index) {
+        return _elements[index].getRoot();
+    }
+
+    /**
+     * Indicates if this product unit is considered equals to the specified 
+     * object.
+     *
+     * @param  that the object to compare for equality.
+     * @return <code>true</code> if <code>this</code> and <code>that</code>
+     *         are considered equals; <code>false</code>otherwise. 
+     */
+    public boolean equals(Object that) {
+        if (this == that)
+            return true;
+        if (that instanceof ProductUnit) {
+            // Two products are equals if they have the same elements
+            // regardless of the elements' order.
+            Element[] elems = ((ProductUnit<?>) that)._elements;
+            if (_elements.length == elems.length) {
+                for (int i = 0; i < _elements.length; i++) {
+                    boolean unitFound = false;
+                    for (int j = 0; j < elems.length; j++) {
+                        if (_elements[i]._unit.equals(elems[j]._unit)) {
+                            if ((_elements[i]._pow != elems[j]._pow)
+                                    || (_elements[i]._root != elems[j]._root)) {
+                                return false;
+                            } else {
+                                unitFound = true;
+                                break;
+                            }
+                        }
+                    }
+                    if (!unitFound) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    // Implements abstract method.
+    public int hashCode() {
+        if (_hashCode != 0)
+            return _hashCode;
+        int code = 0;
+        for (int i = 0; i < _elements.length; i++) {
+            code += _elements[i]._unit.hashCode()
+                    * (_elements[i]._pow * 3 - _elements[i]._root * 2);
+        }
+        _hashCode = code;
+        return code;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Unit<? super Q> getStandardUnit() {
+        if (hasOnlyStandardUnit())
+            return this;
+        Unit systemUnit = ONE;
+        for (int i = 0; i < _elements.length; i++) {
+            Unit unit = _elements[i]._unit.getStandardUnit();
+            unit = unit.pow(_elements[i]._pow);
+            unit = unit.root(_elements[i]._root);
+            systemUnit = systemUnit.times(unit);
+        }
+        return systemUnit;
+    }
+
+    @Override
+    public UnitConverter toStandardUnit() {
+        if (hasOnlyStandardUnit())
+            return UnitConverter.IDENTITY;
+        UnitConverter converter = UnitConverter.IDENTITY;
+        for (int i = 0; i < _elements.length; i++) {
+            UnitConverter cvtr = _elements[i]._unit.toStandardUnit();
+            if (!cvtr.isLinear())
+                throw new ConversionException(_elements[i]._unit
+                        + " is non-linear, cannot convert");
+            if (_elements[i]._root != 1)
+                throw new ConversionException(_elements[i]._unit
+                        + " holds a base unit with fractional exponent");
+            int pow = _elements[i]._pow;
+            if (pow < 0) { // Negative power.
+                pow = -pow;
+                cvtr = cvtr.inverse();
+            }
+            for (int j = 0; j < pow; j++) {
+                converter = converter.concatenate(cvtr);
+            }
+        }
+        return converter;
+    }
+
+    /**
+     * Indicates if this product unit is a standard unit.
+     *
+     * @return <code>true</code> if all elements are standard units;
+     *         <code>false</code> otherwise.
+     */
+    private boolean hasOnlyStandardUnit() {
+        for (int i = 0; i < _elements.length; i++) {
+            Unit<?> u = _elements[i]._unit;
+            if (!u.isStandardUnit())
+                return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns the greatest common divisor (Euclid's algorithm).
+     *
+     * @param  m the first number.
+     * @param  nn the second number.
+     * @return the greatest common divisor.
+     */
+    private static int gcd(int m, int n) {
+        if (n == 0) {
+            return m;
+        } else {
+            return gcd(n, m % n);
+        }
+    }
+
+    /**
+     * Inner product element represents a rational power of a single unit.
+     */
+    private final static class Element implements Serializable {
+
+        /**
+         * Holds the single unit.
+         */
+        private final Unit<?> _unit;
+
+        /**
+         * Holds the power exponent.
+         */
+        private final int _pow;
+
+        /**
+         * Holds the root exponent.
+         */
+        private final int _root;
+
+        /**
+         * Structural constructor.
+         *
+         * @param  unit the unit.
+         * @param  pow the power exponent.
+         * @param  root the root exponent.
+         */
+        private Element(Unit<?> unit, int pow, int root) {
+            _unit = unit;
+            _pow = pow;
+            _root = root;
+        }
+
+        /**
+         * Returns this element's unit.
+         *
+         * @return the single unit.
+         */
+        public Unit<?> getUnit() {
+            return _unit;
+        }
+
+        /**
+         * Returns the power exponent. The power exponent can be negative
+         * but is always different from zero.
+         *
+         * @return the power exponent of the single unit.
+         */
+        public int getPow() {
+            return _pow;
+        }
+
+        /**
+         * Returns the root exponent. The root exponent is always greater
+         * than zero.
+         *
+         * @return the root exponent of the single unit.
+         */
+        public int getRoot() {
+            return _root;
+        }
+
+        private static final long serialVersionUID = 1L;
+    }
+
+    private static final long serialVersionUID = 1L;
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/SI.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/SI.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/SI.java	(revision 28000)
@@ -0,0 +1,130 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.unit;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.measure.converter.RationalConverter;
+import javax.measure.quantity.Angle;
+import javax.measure.quantity.Duration;
+import javax.measure.quantity.Length;
+import javax.measure.quantity.Quantity;
+
+/**
+ * <p> This class contains SI (Système International d'Unités) base units,
+ *     and derived units.</p>
+ *     
+ * <p> It also defines the 20 SI prefixes used to form decimal multiples and
+ *     submultiples of SI units. For example:[code]
+ *     import static org.jscience.physics.units.SI.*; // Static import.
+ *     ...
+ *     Unit<Pressure> HECTO_PASCAL = HECTO(PASCAL);
+ *     Unit<Length> KILO_METER = KILO(METER);
+ *     [/code]</p>
+ *     
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 4.2, August 26, 2006
+ * @see <a href="http://en.wikipedia.org/wiki/SI">Wikipedia: SI</a>
+ * @see <a href="http://en.wikipedia.org/wiki/SI_prefix">Wikipedia: SI prefix</a>
+ */
+public final class SI extends SystemOfUnits {
+
+    /**
+     * Holds collection of SI units.
+     */
+    private static HashSet<Unit<?>> UNITS = new HashSet<Unit<?>>();
+
+    /**
+     * Default constructor (prevents this class from being instantiated).
+     */
+    private SI() {
+    }
+
+    ////////////////
+    // BASE UNITS //
+    ////////////////
+
+    /**
+     * The base unit for length quantities (<code>m</code>).
+     * One meter was redefined in 1983 as the distance traveled by light in
+     * a vacuum in 1/299,792,458 of a second.
+     */
+    public static final BaseUnit<Length> METRE = si(new BaseUnit<Length>("m"));
+
+    /**
+     * Equivalent to {@link #METRE} (American spelling).
+     */
+    public static final Unit<Length> METER = METRE;
+
+    /**
+     * The base unit for duration quantities (<code>s</code>).
+     * It is defined as the duration of 9,192,631,770 cycles of radiation
+     * corresponding to the transition between two hyperfine levels of
+     * the ground state of cesium (1967 Standard).
+     */
+    public static final BaseUnit<Duration> SECOND = si(new BaseUnit<Duration>(
+            "s"));
+
+    ////////////////////////////////
+    // SI DERIVED ALTERNATE UNITS //
+    ////////////////////////////////
+
+    /**
+     * The unit for plane angle quantities (<code>rad</code>).
+     * One radian is the angle between two radii of a circle such that the
+     * length of the arc between them is equal to the radius.
+     */
+    public static final AlternateUnit<Angle> RADIAN = si(new AlternateUnit<Angle>(
+            "rad", Unit.ONE));
+
+    /////////////////
+    // SI PREFIXES //
+    /////////////////
+
+    /**
+     * Returns the specified unit multiplied by the factor
+     * <code>10<sup>-3</sup></code>
+     *
+     * @param  unit any unit.
+     * @return <code>unit.multiply(1e-3)</code>.
+     */
+    public static <Q extends Quantity> Unit<Q> MILLI(Unit<Q> unit) {
+        return unit.transform(Em3);
+    }
+
+    /////////////////////
+    // Collection View //
+    /////////////////////
+
+    /**
+     * Returns a read only view over theunits defined in this class.
+     *
+     * @return the collection of SI units.
+     */
+    public Set<Unit<?>> getUnits() {
+        return Collections.unmodifiableSet(UNITS);
+    }
+
+    /**
+     * Adds a new unit to the collection.
+     *
+     * @param  unit the unit being added.
+     * @return <code>unit</code>.
+     */
+    private static <U extends Unit<?>> U si(U unit) {
+        UNITS.add(unit);
+        return unit;
+    }
+
+    // Holds prefix converters (optimization).
+
+    static final RationalConverter Em3 = new RationalConverter(1, 1000L);
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/SystemOfUnits.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/SystemOfUnits.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/SystemOfUnits.java	(revision 28000)
@@ -0,0 +1,32 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.unit;
+
+import java.util.Set;
+
+/**
+ * <p> This class represents a system of units, it groups units together 
+ *     for historical or cultural reasons. Nothing prevents a unit from 
+ *     belonging to several system of units at the same time
+ *     (for example an imperial system would have many of the units 
+ *     held by {@link NonSI}).</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 4.2, August 26, 2007
+ */
+public abstract class SystemOfUnits {
+    
+    /**
+     * Returns a read only view over the units defined in this system.
+     *
+     * @return the collection of units.
+     */
+    public abstract Set<Unit<?>> getUnits();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/TransformedUnit.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/TransformedUnit.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/TransformedUnit.java	(revision 28000)
@@ -0,0 +1,121 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.unit;
+
+import javax.measure.converter.UnitConverter;
+import javax.measure.quantity.Quantity;
+        
+/**
+ * <p> This class represents the units derived from other units using
+ *     {@link UnitConverter converters}.</p>
+ *     
+ * <p> Examples of transformed units:[code]
+ *         CELSIUS = KELVIN.add(273.15);
+ *         FOOT = METER.multiply(0.3048);
+ *         MILLISECOND = MILLI(SECOND); 
+ *     [/code]</p>
+ *     
+ * <p> Transformed units have no label. But like any other units,
+ *     they may have labels attached to them:[code]
+ *         UnitFormat.getStandardInstance().label(FOOT, "ft");
+ *     [/code]
+ *     or aliases: [code]
+ *         UnitFormat.getStandardInstance().alias(CENTI(METER)), "centimeter");
+ *         UnitFormat.getStandardInstance().alias(CENTI(METER)), "centimetre");
+ *     [/code]</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @version 3.1, April 22, 2006
+ * @see     Unit#plus(double)
+ * @see     Unit#times(double)
+ * @see     Unit#transform(UnitConverter)
+ * @see     UnitFormat
+ */
+public final class TransformedUnit<Q extends Quantity> extends DerivedUnit<Q> {
+
+    /**
+     * Holds the parent unit (not a transformed unit).
+     */
+    private final Unit<Q> _parentUnit;
+
+    /**
+     * Holds the converter to the parent unit.
+     */
+    private final UnitConverter _toParentUnit;
+
+    /**
+     * Creates a transformed unit from the specified parent unit.
+     *
+     * @param parentUnit the untransformed unit from which this unit is 
+     *        derived.
+     * @param  toParentUnit the converter to the parent units.
+     * @throws IllegalArgumentException if <code>toParentUnit == 
+     *         {@link UnitConverter#IDENTITY UnitConverter.IDENTITY}</code>
+     */
+    TransformedUnit(Unit<Q> parentUnit, UnitConverter toParentUnit) {
+        if (toParentUnit == UnitConverter.IDENTITY)
+            throw new IllegalArgumentException("Identity not allowed");
+        _parentUnit = parentUnit;
+        _toParentUnit = toParentUnit;
+    }
+        
+    /**
+     * Returns the parent unit for this unit. The parent unit is the 
+     * untransformed unit from which this unit is derived.
+     *
+     * @return the untransformed unit from which this unit is derived.
+     */
+    public Unit<Q> getParentUnit() {
+        return _parentUnit;
+    }
+        
+    /**
+     * Returns the converter to the parent unit.
+     *
+     * @return the converter to the parent unit.
+     */
+    public UnitConverter toParentUnit() {
+        return _toParentUnit;
+    }
+        
+    /**
+     * Indicates if this transformed unit is considered equals to the specified 
+     * object (both are transformed units with equal parent unit and equal
+     * converter to parent unit).
+     *
+     * @param  that the object to compare for equality.
+     * @return <code>true</code> if <code>this</code> and <code>that</code>
+     *         are considered equals; <code>false</code>otherwise. 
+     */
+    public boolean equals(Object that) {
+        if (this == that) return true;
+        if (!(that instanceof TransformedUnit)) return false;
+        TransformedUnit<?> thatUnit = (TransformedUnit<?>) that; 
+        return this._parentUnit.equals(thatUnit._parentUnit) &&
+                 this._toParentUnit.equals(thatUnit._toParentUnit);
+    }
+
+    // Implements abstract method.
+    public int hashCode() {
+        return _parentUnit.hashCode() + _toParentUnit.hashCode();
+    }
+
+    // Implements abstract method.
+    public Unit<? super Q> getStandardUnit() {
+        return _parentUnit.getStandardUnit();
+    }
+
+    // Implements abstract method.
+    public UnitConverter toStandardUnit() {
+        return _parentUnit.toStandardUnit().concatenate(_toParentUnit);
+    }
+
+    private static final long serialVersionUID = 1L;
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/Unit.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/Unit.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/Unit.java	(revision 28000)
@@ -0,0 +1,396 @@
+/*
+ * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
+ * Copyright (C) 2006 - JScience (http://jscience.org/)
+ * All rights reserved.
+ * 
+ * Permission to use, copy, modify, and distribute this software is
+ * freely granted, provided that this notice is preserved.
+ */
+package javax.measure.unit;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+import javax.measure.converter.ConversionException;
+import javax.measure.converter.MultiplyConverter;
+import javax.measure.converter.RationalConverter;
+import javax.measure.converter.UnitConverter;
+import javax.measure.quantity.Dimensionless;
+import javax.measure.quantity.Quantity;
+
+/**
+ * <p> This class represents a determinate {@link javax.measure.quantity.Quantity
+ *     quantity} (as of length, time, heat, or value) adopted as a standard
+ *     of measurement.</p>
+ *
+ * <p> It is helpful to think of instances of this class as recording the
+ *     history by which they are created. Thus, for example, the string
+ *     "g/kg" (which is a dimensionless unit) would result from invoking
+ *     the method toString() on a unit that was created by dividing a
+ *     gram unit by a kilogram unit. Yet, "kg" divided by "kg" returns
+ *     {@link #ONE} and not "kg/kg" due to automatic unit factorization.</p>
+ *
+ * <p> This class supports the multiplication of offsets units. The result is
+ *     usually a unit not convertible to its {@link #getStandardUnit standard unit}.
+ *     Such units may appear in derivative quantities. For example °C/m is an 
+ *     unit of gradient, which is common in atmospheric and oceanographic
+ *     research.</p>
+ *
+ * <p> Units raised at rational powers are also supported. For example
+ *     the cubic root of "liter" is a unit compatible with meter.</p>
+ *     
+ * <p> Instances of this class are immutable.</p>
+ *
+ * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
+ * @author  <a href="mailto:steve@unidata.ucar.edu">Steve Emmerson</a>
+ * @author  Martin Desruisseaux
+ * @version 3.2, August 28, 2006
+ * @see <a href="http://en.wikipedia.org/wiki/Units_of_measurement">
+ *       Wikipedia: Units of measurement</a>
+ */
+@SuppressWarnings("serial")
+public abstract class Unit<Q extends Quantity> implements Serializable {
+
+    /**
+     * Holds the dimensionless unit <code>ONE</code>.
+     */
+    public static final Unit<Dimensionless> ONE = new ProductUnit<Dimensionless>();
+
+    /**
+     * Holds the unique symbols collection (base unit or alternate units).
+     */
+    static final HashMap<String, Unit<?>> SYMBOL_TO_UNIT = new HashMap<String, Unit<?>>();
+
+    /**
+     * Default constructor.
+     */
+    protected Unit() {
+    }
+
+    //////////////////////////////////////////////////////
+    // Contract methods (for sub-classes to implement). //
+    //////////////////////////////////////////////////////
+
+    /**
+     * Returns the {@link BaseUnit base unit}, {@link AlternateUnit alternate
+     * unit} or product of base units and alternate units this unit is derived
+     * from. The standard unit identifies the "type" of 
+     * {@link javax.measure.quantity.Quantity quantity} for which this unit is employed.
+     * For example:[code]
+     *    boolean isAngularVelocity(Unit<?> u) {
+     *       return u.getStandardUnit().equals(RADIAN.divide(SECOND));
+     *    }
+     *    assert(REVOLUTION.divide(MINUTE).isAngularVelocity());  
+     * [/code]
+     * 
+     * <p><i> Note: Having the same system unit is not sufficient to ensure
+     *              that a converter exists between the two units
+     *              (e.g. °C/m and K/m).</i></p>
+     * @return the system unit this unit is derived from.
+     */
+    public abstract Unit<? super Q> getStandardUnit();
+
+    
+    /**
+     * Returns the converter from this unit to its system unit.
+     * 
+     * @return <code>this.getConverterTo(this.getSystemUnit())</code>
+     */
+    public abstract UnitConverter toStandardUnit();
+
+    /**
+     * Returns the hash code for this unit.
+     *
+     * @return this unit hashcode value.
+     */
+    public abstract int hashCode();
+
+    /**
+     * Indicates if the specified unit can be considered equals to 
+     * the one specified.
+     *
+     * @param that the object to compare to.
+     * @return <code>true</code> if this unit is considered equal to 
+     *         that unit; <code>false</code> otherwise.
+     */
+    public abstract boolean equals(Object that);
+
+    /**
+     * Indicates if this unit is a standard unit (base units and 
+     * alternate units are standard units). The standard unit identifies 
+     * the "type" of {@link javax.measure.quantity.Quantity quantity} for 
+     * which the unit is employed.
+     * 
+     * @return <code>getStandardUnit().equals(this)</code>
+     */
+    public boolean isStandardUnit() {
+        return getStandardUnit().equals(this);
+    }
+
+    /**
+     * Indicates if this unit is compatible with the unit specified.
+     * Units don't need to be equals to be compatible. For example:[code]
+     *     RADIAN.equals(ONE) == false
+     *     RADIAN.isCompatible(ONE) == true
+     * [/code]
+     * @param  that the other unit.
+     * @return <code>this.getDimension().equals(that.getDimension())</code>
+     * @see #getDimension()
+     */
+    public final boolean isCompatible(Unit<?> that) {
+        return (this == that)
+                || this.getStandardUnit().equals(that.getStandardUnit())
+                || this.getDimension().equals(that.getDimension());
+    }
+
+    /**
+     * Casts this unit to a parameterized unit of specified nature or 
+     * throw a <code>ClassCastException</code> if the dimension of the 
+     * specified quantity and this unit's dimension do not match.
+     * For example:[code]
+     * Unit<Length> LIGHT_YEAR = NonSI.C.times(NonSI.YEAR).asType(Length.class);
+     * [/code]
+     * 
+     * @param  type the quantity class identifying the nature of the unit.
+     * @return this unit parameterized with the specified type.
+     * @throws ClassCastException if the dimension of this unit is different 
+     *         from the specified quantity dimension.
+     * @throws UnsupportedOperationException if the specified quantity class
+     *         does not have a public static field named "UNIT" holding the 
+     *         standard unit for the quantity.
+     */
+    @SuppressWarnings("unchecked")
+    public final <T extends Quantity> Unit<T> asType(Class<T> type) throws ClassCastException {
+        Dimension dim1 = this.getDimension();
+        Unit<T> u = null;
+        try {
+            u = (Unit<T>)type.getField("UNIT").get(null);
+        } catch (Exception e) {
+            throw new Error(e);
+        }
+        Dimension dim2 = u.getDimension();
+        if (!dim1.equals(dim2))
+            throw new ClassCastException();
+        return (Unit<T>)this;
+    }
+   
+    /**
+     * Returns the dimension of this unit (depends upon the current 
+     * dimensional {@link Dimension.Model model}). 
+     *
+     * @return the dimension of this unit for the current model.
+     */
+    public final Dimension getDimension() {
+        Unit<?> systemUnit = this.getStandardUnit();
+        if (systemUnit instanceof BaseUnit)
+            return Dimension.getModel().getDimension((BaseUnit<?>) systemUnit);
+        if (systemUnit instanceof AlternateUnit)
+            return ((AlternateUnit<?>) systemUnit).getParent().getDimension();
+        // Product of units.
+        ProductUnit<?> productUnit = (ProductUnit<?>) systemUnit;
+        Dimension dimension = Dimension.NONE;
+        for (int i = 0; i < productUnit.getUnitCount(); i++) {
+            Unit<?> unit = productUnit.getUnit(i);
+            Dimension d = unit.getDimension().pow(productUnit.getUnitPow(i))
+                    .root(productUnit.getUnitRoot(i));
+            dimension = dimension.times(d);
+        }
+        return dimension;
+    }
+
+    /**
+     * Returns a converter of numeric values from this unit to another unit.
+     *
+     * @param  that the unit to which to convert the numeric values.
+     * @return the converter from this unit to <code>that</code> unit.
+     * @throws ConversionException if the conveter cannot be constructed
+     *         (e.g. <code>!this.isCompatible(that)</code>).
+     */
+    public final UnitConverter getConverterTo(Unit<?> that)
+            throws ConversionException {
+        if (this.equals(that))
+            return UnitConverter.IDENTITY;
+        Unit<?> thisSystemUnit = this.getStandardUnit();
+        Unit<?> thatSystemUnit = that.getStandardUnit();
+        if (thisSystemUnit.equals(thatSystemUnit))
+            return that.toStandardUnit().inverse().concatenate(
+                    this.toStandardUnit());
+        // Use dimensional transforms.
+        if (!thisSystemUnit.getDimension()
+                .equals(thatSystemUnit.getDimension()))
+            throw new ConversionException(this + " is not compatible with "
+                    + that);
+        // Transform between SystemUnit and BaseUnits is Identity. 
+        UnitConverter thisTransform = this.toStandardUnit().concatenate(
+                transformOf(this.getBaseUnits()));
+        UnitConverter thatTransform = that.toStandardUnit().concatenate(
+                transformOf(that.getBaseUnits()));
+        return thatTransform.inverse().concatenate(thisTransform);
+    }
+
+    private Unit<?> getBaseUnits() {
+        Unit<?> systemUnit = this.getStandardUnit();
+        if (systemUnit instanceof BaseUnit) return systemUnit;
+        if (systemUnit instanceof AlternateUnit) 
+            return ((AlternateUnit<?>)systemUnit).getParent().getBaseUnits();
+        if (systemUnit instanceof ProductUnit) {
+            ProductUnit<?> productUnit = (ProductUnit<?>)systemUnit;
+            Unit<?> baseUnits = ONE;
+            for (int i = 0; i < productUnit.getUnitCount(); i++) {
+                Unit<?> unit = productUnit.getUnit(i).getBaseUnits();
+                unit = unit.pow(productUnit.getUnitPow(i));
+                unit = unit.root(productUnit.getUnitRoot(i));
+                baseUnits = baseUnits.times(unit);
+            }
+            return baseUnits;
+        } else {
+            throw new InternalError(
+                    "System Unit cannot be an instance of " + this.getClass());            
+        }        
+    }
+    private static UnitConverter transformOf(Unit<?> baseUnits) {
+        if (baseUnits instanceof BaseUnit)
+            return Dimension.getModel().getTransform((BaseUnit<?>) baseUnits);
+        // Product of units.
+        ProductUnit<?> productUnit = (ProductUnit<?>) baseUnits;
+        UnitConverter converter = UnitConverter.IDENTITY;
+        for (int i = 0; i < productUnit.getUnitCount(); i++) {
+            Unit<?> unit = productUnit.getUnit(i);
+            UnitConverter cvtr = transformOf(unit);
+            if (!cvtr.isLinear())
+                throw new ConversionException(baseUnits
+                        + " is non-linear, cannot convert");
+            if (productUnit.getUnitRoot(i) != 1)
+                throw new ConversionException(productUnit
+                        + " holds a base unit with fractional exponent");
+            int pow = productUnit.getUnitPow(i);
+            if (pow < 0) { // Negative power.
+                pow = -pow;
+                cvtr = cvtr.inverse();
+            }
+            for (int j = 0; j < pow; j++) {
+                converter = converter.concatenate(cvtr);
+            }
+        }
+        return converter;
+    }
+
+    /**
+     * Returns the unit derived from this unit using the specified converter.
+     * The converter does not need to be linear. For example:[code]
+     * Unit<Dimensionless> DECIBEL = Unit.ONE.transform(
+     *     new LogConverter(10).inverse().concatenate(
+     *           new RationalConverter(1, 10)));[/code]
+     *
+     * @param operation the converter from the transformed unit to this unit.
+     * @return the unit after the specified transformation.
+     */
+    public final Unit<Q> transform(UnitConverter operation) {
+        if (this instanceof TransformedUnit) {
+            TransformedUnit<Q> tf = (TransformedUnit<Q>) this;
+            Unit<Q> parent = tf.getParentUnit();
+            UnitConverter toParent = tf.toParentUnit().concatenate(operation);
+            if (toParent == UnitConverter.IDENTITY)
+                return parent;
+            return new TransformedUnit<Q>(parent, toParent);
+        }
+        if (operation == UnitConverter.IDENTITY) 
+            return this;
+        return new TransformedUnit<Q>(this, operation);
+    }
+
+    /**
+     * Returns the result of multiplying this unit by an exact factor. 
+     *
+     * @param  factor the exact scale factor
+     *         (e.g. <code>KILOMETER = METER.times(1000)</code>).
+     * @return <code>this.transform(new RationalConverter(factor, 1))</code>
+     */
+    public final Unit<Q> times(long factor) {
+        return transform(new RationalConverter(factor, 1));
+    }
+
+    /**
+     * Returns the result of multiplying this unit by a an approximate factor
+     *
+     * @param  factor the approximate factor (e.g. 
+     *         <code>ELECTRON_MASS = KILOGRAM.times(9.10938188e-31)</code>).
+     * @return <code>this.transform(new MultiplyConverter(factor))</code>
+     */
+    public final Unit<Q> times(double factor) {
+        return transform(new MultiplyConverter(factor));
+    }
+
+    /**
+     * Returns the product of this unit with the one specified.
+     *
+     * @param  that the unit multiplicand.
+     * @return <code>this * that</code>
+     */
+    public final Unit<? extends Quantity> times(Unit<?> that) {
+        return ProductUnit.getProductInstance(this, that);
+    }
+
+    /**
+     * Returns the inverse of this unit.
+     *
+     * @return <code>1 / this</code>
+     */
+    public final Unit<? extends Quantity> inverse() {
+        return ProductUnit.getQuotientInstance(ONE, this);
+    }
+
+    /**
+     * Returns the result of dividing this unit by an exact divisor.
+     *
+     * @param  divisor the exact divisor.
+     *         (e.g. <code>QUART = GALLON_LIQUID_US.divide(4)</code>).
+     * @return <code>this.transform(new RationalConverter(1 , divisor))</code>
+     */
+    public final Unit<Q> divide(long divisor) {
+        return transform(new RationalConverter(1, divisor));
+    }
+
+    /**
+     * Returns the quotient of this unit with the one specified.
+     *
+     * @param  that the unit divisor.
+     * @return <code>this / that</code>
+     */
+    public final Unit<? extends Quantity> divide(Unit<?> that) {
+        return this.times(that.inverse());
+    }
+
+    /**
+     * Returns a unit equals to the given root of this unit.
+     *
+     * @param  n the root's order.
+     * @return the result of taking the given root of this unit.
+     * @throws ArithmeticException if <code>n == 0</code>.
+     */
+    public final Unit<? extends Quantity> root(int n) {
+        if (n > 0) {
+            return ProductUnit.getRootInstance(this, n);
+        } else if (n == 0) {
+            throw new ArithmeticException("Root's order of zero");
+        } else { // n < 0
+            return ONE.divide(this.root(-n));
+        }
+    }
+
+    /**
+     * Returns a unit equals to this unit raised to an exponent.
+     *
+     * @param  n the exponent.
+     * @return the result of raising this unit to the exponent.
+     */
+    public final Unit<? extends Quantity> pow(int n) {
+        if (n > 0) {
+            return this.times(this.pow(n - 1));
+        } else if (n == 0) {
+            return ONE;
+        } else { // n < 0
+            return ONE.divide(this.pow(-n));
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/measure/unit/package.html	(revision 28000)
@@ -0,0 +1,61 @@
+<body>
+<p> Provides support for programatic unit handling.</p>
+<h3> Standart/NonStandard Units</h3>
+     Standard units and prefixes are provided by the 
+     {@link javax.measure.unit.SI SI} class (Système International d'Unités) and
+     about 50 non-standard units are available through the 
+     {@link javax.measure.unit.NonSI NonSI} class.
+
+<h3>Usage examples:</h3>
+[code]    
+import javax.measure.Scalar;
+import javax.measure.Measure;
+import javax.measure.unit.*;
+import javax.measure.quantity.*;
+import static javax.measure.unit.SI.*;
+import static javax.measure.unit.NonSI.*;
+import static javax.measure.unit.Dimension.*;
+public class Main { 
+    public void main(String[] args) { 
+
+        // Conversion between units.
+        System.out.println(KILO(METRE).getConverterTo(MILE).convert(10));
+            
+        // Retrieval of the system unit (identifies the measurement type).    
+        System.out.println(REVOLUTION.divide(MINUTE).getSystemUnit());
+        
+        // Dimension checking (allows/disallows conversions)    
+        System.out.println(ELECTRON_VOLT.isCompatible(WATT.times(HOUR)));
+
+        // Retrieval of the unit dimension (depends upon the current model).
+        System.out.println(ELECTRON_VOLT.getDimension());
+    }
+}
+
+> 6.2137119223733395
+> rad/s
+> true
+> [L]²·[M]/[T]²
+[/code]
+       
+<h3>Unit Parameterization</h3>
+
+    Units are parameterized (&lt;Q extends {@link javax.measure.quantity.Quantity Quantity}>) to
+    enforce compile-time checks of units/measures consistency, for example:[code]
+
+    Unit<Duration> MINUTE = SECONDS.times(60); // Ok.
+    Unit<Duration> MINUTE = METRE.times(60); // Compile error.
+    
+    Unit<Pressure> HECTOPASCAL = HECTO(PASCAL); // Ok.
+    Unit<Pressure> HECTOPASCAL = HECTO(NEWTON); // Compile error.
+    
+    Measurable<Duration> duration = Measure.valueOf(2, MINUTE); // Ok.
+    Measurable<Duration> duration = Measure.valueOf(2, CELSIUS); // Compile error.
+    
+    long milliseconds = duration.longValue(MILLI(SECOND)); // Ok.
+    long milliseconds = duration.longValue(POUND); // Compile error.
+    [/code]</p>
+   
+<h3>UML Diagram</h3>
+        <IMG alt="UML Diagram" src="doc-files/unit.png">
+</body>
Index: /applications/editors/josm/plugins/opendata/includes/javax/vecmath/GMatrix.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/vecmath/GMatrix.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/vecmath/GMatrix.java	(revision 28000)
@@ -0,0 +1,776 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * $Revision: 127 $
+ * $Date: 2008-02-28 21:18:51 +0100 (jeu., 28 févr. 2008) $
+ * $State$
+ */
+
+package javax.vecmath;
+
+
+/**
+ * A double precision, general, dynamically-resizable,
+ * two-dimensional matrix class.  Row and column numbering begins with
+ * zero.  The representation is row major.
+ */
+
+public class GMatrix implements java.io.Serializable, Cloneable {
+
+    // Compatible with 1.1
+    static final long serialVersionUID = 2777097312029690941L;
+
+    int nRow;
+    int nCol;
+
+    // double dereference is slow 
+    double[][] values;
+
+    /**
+     * Constructs an nRow by NCol identity matrix. 
+     * Note that because row and column numbering begins with
+     * zero, nRow and nCol will be one larger than the maximum
+     * possible matrix index values.
+     * @param nRow  number of rows in this matrix.
+     * @param nCol  number of columns in this matrix.
+     */
+    public GMatrix(int nRow, int nCol)
+    {
+        values = new double[nRow][nCol];
+	this.nRow = nRow;
+	this.nCol = nCol;
+
+	int i, j;
+	for (i = 0; i < nRow; i++) {
+	    for (j = 0; j < nCol; j++) {
+		values[i][j] = 0.0;
+	    }
+	}
+
+	int l;
+	if (nRow < nCol)
+	    l = nRow;
+        else
+	    l = nCol;
+
+	for (i = 0; i < l; i++) {
+	    values[i][i] = 1.0;
+	}
+    }
+
+    /** 
+     * Constructs an nRow by nCol matrix initialized to the values 
+     * in the matrix array.  The array values are copied in one row at
+     * a time in row major fashion.  The array should be at least 
+     * nRow*nCol in length.
+     * Note that because row and column numbering begins with 
+     * zero, nRow and nCol will be one larger than the maximum
+     * possible matrix index values.
+     * @param nRow  number of rows in this matrix. 
+     * @param nCol  number of columns in this matrix. 
+     * @param matrix  a 1D array that specifies a matrix in row major fashion
+     */ 
+    public GMatrix(int nRow, int nCol, double[] matrix)
+    {
+        values = new double[nRow][nCol];
+	this.nRow = nRow;
+	this.nCol = nCol;
+
+	int i, j;
+	for (i = 0; i < nRow; i++) {
+	    for (j = 0; j < nCol; j++) {
+		values[i][j] = matrix[i*nCol+j];
+	    }
+	}
+    }
+
+    /**
+     * Sets the value of this matrix to the result of multiplying itself
+     * with matrix m1 (this = this * m1).  
+     * @param m1 the other matrix
+     */  
+    public final void mul(GMatrix m1)
+    {
+	int i, j, k;
+
+	if (nCol != m1.nRow ||  nCol != m1.nCol)
+	    throw new MismatchedSizeException
+		(VecMathI18N.getString("GMatrix0"));
+
+	double [][] tmp = new double[nRow][nCol];
+
+	for (i = 0; i < nRow; i++) {
+	    for (j = 0; j < nCol; j++) {
+		tmp[i][j] = 0.0;
+		for (k = 0; k < nCol; k++) {
+		    tmp[i][j] += values[i][k]*m1.values[k][j];	
+		}
+	    }
+	}
+       
+	values = tmp;
+    }
+
+    /**
+     * Sets the value of this matrix to the result of multiplying
+     * the two argument matrices together (this = m1 * m2).
+     * @param m1 the first matrix
+     * @param m2 the second matrix
+     */
+    public final void mul(GMatrix m1, GMatrix m2)
+    {
+	int i, j, k;
+
+	if (m1.nCol != m2.nRow || nRow != m1.nRow || nCol != m2.nCol)
+	    throw new MismatchedSizeException
+		(VecMathI18N.getString("GMatrix1"));
+
+	double[][] tmp = new double[nRow][nCol];
+
+	for (i = 0; i < m1.nRow; i++) {
+	    for (j = 0; j < m2.nCol; j++) {
+		tmp[i][j] = 0.0;
+		for (k = 0; k < m1.nCol; k++) {
+		    tmp[i][j] += m1.values[i][k]*m2.values[k][j];	
+		}
+	    }
+	}
+       
+	values = tmp;
+    }
+
+    /** 
+     * Negates the value of this matrix: this = -this.
+     */
+    public final void negate() // NO_UCD
+    {
+	int i, j;
+	for (i = 0; i < nRow; i++) {
+	    for (j = 0;j < nCol; j++) {
+		values[i][j] = -values[i][j];
+	    }
+	}
+    }
+
+    /**
+     * Sets this GMatrix to the identity matrix.
+     */
+    public final void setIdentity() // NO_UCD
+    {
+        int i, j;
+        for (i = 0; i < nRow; i++) {
+	    for (j = 0; j < nCol; j++) {
+		values[i][j] = 0.0;
+	    }
+        }
+
+        int l;
+        if (nRow < nCol)
+	    l = nRow;
+        else
+	    l = nCol;
+
+        for (i = 0; i < l; i++) {
+	    values[i][i] = 1.0;
+        }
+    }
+
+    /**
+     * Sets all the values in this matrix to zero.
+     */
+    public final void setZero()
+    {
+	int i, j;
+	for (i = 0; i < nRow; i++) {
+	    for (j = 0; j < nCol; j++) {
+		values[i][j] = 0.0; 
+	    }
+	}   
+    }
+
+   
+    /**
+     * Inverts this matrix in place.
+     */
+    public final void invert() // NO_UCD
+    {
+	invertGeneral(this);
+    }
+
+
+    /**
+     * Copies a sub-matrix derived from this matrix into the target matrix.
+     * The upper left of the sub-matrix is located at (rowSource, colSource);
+     * the lower right of the sub-matrix is located at 
+     * (lastRowSource,lastColSource).  The sub-matrix is copied into the
+     * the target matrix starting at (rowDest, colDest).
+     * @param rowSource   the top-most row of the sub-matrix 
+     * @param colSource   the left-most column of the sub-matrix 
+     * @param numRow   the number of rows in the sub-matrix
+     * @param numCol  the number of columns in the sub-matrix
+     * @param rowDest  the top-most row of the position of the copied
+     *                 sub-matrix within the target matrix
+     * @param colDest  the left-most column of the position of the copied
+     *                 sub-matrix within the target matrix
+     * @param target  the matrix into which the sub-matrix will be copied
+     */
+    public final void copySubMatrix(int rowSource, int colSource, 
+				    int numRow, int numCol, int rowDest,
+				    int colDest, GMatrix target) 
+    {
+        int i, j;
+
+	if (this != target) {
+	    for (i = 0; i < numRow; i++) {
+		for (j = 0; j < numCol; j++) {
+		    target.values[rowDest+i][colDest+j] =
+			values[rowSource+i][colSource+j];
+		}
+	    }
+	} else {
+	    double[][] tmp = new double[numRow][numCol];
+	    for (i = 0; i < numRow; i++) {
+		for (j = 0; j < numCol; j++) {
+		    tmp[i][j] = values[rowSource+i][colSource+j];
+		}
+	    }
+	    for (i = 0; i < numRow; i++) {
+		for (j = 0; j < numCol; j++) {
+		    target.values[rowDest+i][colDest+j] = tmp[i][j];
+		}
+	    }
+	}
+    }
+
+    /**
+     * Changes the size of this matrix dynamically.  If the size is increased
+     * no data values will be lost.  If the size is decreased, only those data
+     * values whose matrix positions were eliminated will be lost.
+     * @param nRow  number of desired rows in this matrix
+     * @param nCol  number of desired columns in this matrix
+     */
+    public final void setSize(int nRow, int nCol)
+    {
+	double[][] tmp = new double[nRow][nCol];
+	int i, j, maxRow, maxCol;
+
+	if (this.nRow < nRow)
+	    maxRow = this.nRow;
+	else
+	    maxRow = nRow;
+
+	if (this.nCol < nCol)
+	    maxCol = this.nCol;
+	else
+	    maxCol = nCol;
+
+	for (i = 0; i < maxRow; i++) {
+	    for (j = 0; j < maxCol; j++) {
+		tmp[i][j] = values[i][j];
+	    }
+	}
+
+	this.nRow = nRow;
+	this.nCol = nCol;
+
+	values = tmp;
+    }
+
+
+    /**
+     * Returns the number of rows in this matrix.
+     * @return  number of rows in this matrix
+     */
+    public final int getNumRow()
+    {
+        return(nRow);
+    }
+
+    /**
+     * Returns the number of colmuns in this matrix.
+     * @return  number of columns in this matrix
+     */
+    public final int getNumCol()
+    {
+	return(nCol);
+    }
+
+    /**
+     * Retrieves the value at the specified row and column of this matrix.
+     * @param row the row number to be retrieved (zero indexed)
+     * @param column the column number to be retrieved (zero indexed)
+     * @return the value at the indexed element
+     */  
+    public final double getElement(int row, int column)
+    {
+        return(values[row][column]);
+    }
+
+ 
+    /**  
+     * Modifies the value at the specified row and column of this matrix.
+     * @param row  the row number to be modified (zero indexed) 
+     * @param column  the column number to be modified (zero indexed) 
+     * @param value  the new matrix element value
+     */   
+    public final void setElement(int row, int column, double value)
+    {
+	values[row][column] = value;
+    }
+
+    /**
+     * Transposes this matrix in place.
+     */
+    public final void transpose() // NO_UCD
+    {
+        int i, j;
+
+        if (nRow != nCol) {
+	    double[][] tmp;
+	    i=nRow;
+	    nRow = nCol;
+	    nCol = i;
+	    tmp = new double[nRow][nCol];
+	    for (i = 0; i < nRow; i++) { 
+		for (j = 0; j < nCol; j++) {
+		    tmp[i][j] = values[j][i]; 
+		}  
+	    }  
+	    values = tmp;
+        } else {
+	    double swap;
+	    for (i = 0; i < nRow; i++) { 
+		for (j = 0; j < i; j++) {
+		    swap = values[i][j];
+		    values[i][j] = values[j][i];
+		    values[j][i] = swap;
+		}  
+	    }  
+	}
+    }
+
+
+    /**
+     * Returns a string that contains the values of this GMatrix.
+     * @return the String representation
+     */  
+    public String toString() 
+    {
+	StringBuffer buffer = new StringBuffer(nRow*nCol*8);
+
+	int i, j;
+
+	for (i = 0; i < nRow; i++) {
+	    for (j = 0; j < nCol; j++) {
+		buffer.append(values[i][j]).append(" ");
+	    }
+	    buffer.append("\n");
+	}
+
+	return buffer.toString();
+    }
+
+    /**
+     * Returns a hash code value based on the data values in this
+     * object.  Two different GMatrix objects with identical data
+     * values (i.e., GMatrix.equals returns true) will return the
+     * same hash number.  Two GMatrix objects with different data
+     * members may return the same hash value, although this is not
+     * likely.
+     * @return the integer hash code value
+     */
+    public int hashCode() {
+	long bits = 1L;
+
+	bits = 31L * bits + nRow;
+	bits = 31L * bits + nCol;
+
+	for (int i = 0; i < nRow; i++) {
+	    for (int j = 0; j < nCol; j++) {
+		bits = 31L * bits + VecMathUtil.doubleToLongBits(values[i][j]);
+	    }
+	}
+
+	return (int) (bits ^ (bits >> 32));
+    } 
+
+
+    /**
+     * Returns true if all of the data members of GMatrix m1 are
+     * equal to the corresponding data members in this GMatrix.
+     * @param m1  The matrix with which the comparison is made.
+     * @return  true or false
+     */  
+    public boolean equals(GMatrix m1)
+    {
+	try { 
+	    int i, j;
+
+	    if (nRow != m1.nRow || nCol != m1.nCol)
+		return false;
+
+	    for (i = 0;i < nRow; i++) {
+		for (j = 0; j < nCol; j++) {
+		    if (values[i][j] != m1.values[i][j])
+			return false;
+		}
+	    }
+	    return true;
+	}  
+	catch (NullPointerException e2) {
+	    return false;
+	}
+    }
+
+    /**
+     * Returns true if the Object o1 is of type GMatrix and all of the
+     * data members of o1 are equal to the corresponding data members in
+     * this GMatrix.
+     * @param o1  The object with which the comparison is made.
+     * @return  true or false
+     */  
+    public boolean equals(Object o1)
+    {
+        try { 
+	    GMatrix m2 = (GMatrix) o1;
+	    int i, j;
+	    if (nRow != m2.nRow || nCol != m2.nCol)
+		return false;
+
+	    for (i = 0; i < nRow; i++) {
+                for (j = 0; j < nCol; j++) {
+		    if (values[i][j] != m2.values[i][j])
+			return false;
+                }
+	    }
+	    return true;
+        }
+        catch (ClassCastException e1) {
+	    return false;
+	}
+        catch (NullPointerException e2) {
+	    return false;
+	}
+    }
+
+
+    /**
+     * General invert routine.  Inverts m1 and places the result in "this".
+     * Note that this routine handles both the "this" version and the
+     * non-"this" version.
+     *
+     * Also note that since this routine is slow anyway, we won't worry
+     * about allocating a little bit of garbage.
+     */
+    final void invertGeneral(GMatrix  m1) {
+        int size = m1.nRow*m1.nCol;
+	double temp[] = new double[size];
+	double result[] = new double[size];
+	int row_perm[] = new int[m1.nRow];
+	int[] even_row_exchange = new int[1];
+	int i, j;
+
+	// Use LU decomposition and backsubstitution code specifically
+	// for floating-point nxn matrices.
+	if (m1.nRow != m1.nCol) {
+	    // Matrix is either under or over determined 
+	    throw new MismatchedSizeException
+		(VecMathI18N.getString("GMatrix22"));
+	}
+
+	// Copy source matrix to temp 
+	for (i = 0; i < nRow; i++) {
+	    for (j = 0; j < nCol; j++) {
+		temp[i*nCol+j] = m1.values[i][j];
+	    }
+	}
+
+	// Calculate LU decomposition: Is the matrix singular? 
+	if (!luDecomposition(m1.nRow, temp, row_perm, even_row_exchange)) {
+	    // Matrix has no inverse 
+	    throw new SingularMatrixException
+		(VecMathI18N.getString("GMatrix21"));
+	}
+
+	// Perform back substitution on the identity matrix 
+        for (i = 0; i < size; i++)
+	    result[i] = 0.0;
+
+        for (i = 0; i < nCol; i++)
+	    result[i+i*nCol] = 1.0;
+
+	luBacksubstitution(m1.nRow, temp, row_perm, result);
+
+	for (i = 0; i < nRow; i++) {
+	    for (j = 0; j < nCol; j++) {
+		values[i][j] =  result[i*nCol+j];
+	    }
+        }
+    }
+
+    /**
+     * Given a nxn array "matrix0", this function replaces it with the 
+     * LU decomposition of a row-wise permutation of itself.  The input 
+     * parameters are "matrix0" and "dim".  The array "matrix0" is also 
+     * an output parameter.  The vector "row_perm[]" is an output 
+     * parameter that contains the row permutations resulting from partial 
+     * pivoting.  The output parameter "even_row_xchg" is 1 when the 
+     * number of row exchanges is even, or -1 otherwise.  Assumes data 
+     * type is always double.
+     *
+     * @return true if the matrix is nonsingular, or false otherwise.
+     */
+    //
+    // Reference: Press, Flannery, Teukolsky, Vetterling, 
+    //	      _Numerical_Recipes_in_C_, Cambridge University Press, 
+    //	      1988, pp 40-45.
+    //
+    static boolean luDecomposition(int dim, double[] matrix0,
+				   int[] row_perm, int[] even_row_xchg) {
+
+	double row_scale[] = new double[dim];
+
+	// Determine implicit scaling information by looping over rows 
+	int i, j;
+	int ptr, rs, mtx;
+	double big, temp;
+
+	ptr = 0;
+	rs = 0;
+	even_row_xchg[0] = 1;
+
+	// For each row ... 
+	i = dim;
+	while (i-- != 0) {
+	    big = 0.0;
+
+	    // For each column, find the largest element in the row 
+	    j = dim;
+	    while (j-- != 0) {
+		temp = matrix0[ptr++];
+		temp = Math.abs(temp);
+		if (temp > big) {
+		    big = temp;
+		}
+	    }
+
+	    // Is the matrix singular? 
+	    if (big == 0.0) {
+		return false;
+	    }
+	    row_scale[rs++] = 1.0 / big;
+	}
+
+	// For all columns, execute Crout's method 
+	mtx = 0;
+	for (j = 0; j < dim; j++) {
+	    int imax, k;
+	    int target, p1, p2;
+	    double sum;
+
+	    // Determine elements of upper diagonal matrix U 
+	    for (i = 0; i < j; i++) {
+		target = mtx + (dim*i) + j;
+		sum = matrix0[target];
+		k = i;
+		p1 = mtx + (dim*i);
+		p2 = mtx + j;
+		while (k-- != 0) {
+		    sum -= matrix0[p1] * matrix0[p2];
+		    p1++;
+		    p2 += dim;
+		}
+		matrix0[target] = sum;
+	    }
+
+	    // Search for largest pivot element and calculate
+	    // intermediate elements of lower diagonal matrix L.
+	    big = 0.0;
+	    imax = -1;
+	    for (i = j; i < dim; i++) {
+		target = mtx + (dim*i) + j;
+		sum = matrix0[target];
+		k = j;
+		p1 = mtx + (dim*i);
+		p2 = mtx + j;
+		while (k-- != 0) {
+		    sum -= matrix0[p1] * matrix0[p2];
+		    p1++;
+		    p2 += dim;
+		}
+		matrix0[target] = sum;
+
+		// Is this the best pivot so far? 
+		if ((temp = row_scale[i] * Math.abs(sum)) >= big) {
+		    big = temp;
+		    imax = i;
+		}
+	    }
+
+	    if (imax < 0) {
+		throw new RuntimeException(VecMathI18N.getString("GMatrix24"));
+	    }
+
+	    // Is a row exchange necessary? 
+	    if (j != imax) {
+		// Yes: exchange rows 
+		k = dim;
+		p1 = mtx + (dim*imax);
+		p2 = mtx + (dim*j);
+		while (k-- != 0) {
+		    temp = matrix0[p1];
+		    matrix0[p1++] = matrix0[p2];
+		    matrix0[p2++] = temp;
+		}
+
+		// Record change in scale factor 
+		row_scale[imax] = row_scale[j];
+		even_row_xchg[0] = -even_row_xchg[0]; // change exchange parity
+	    }
+
+	    // Record row permutation 
+	    row_perm[j] = imax;
+
+	    // Is the matrix singular 
+	    if (matrix0[(mtx + (dim*j) + j)] == 0.0) {
+		return false;
+	    }
+
+	    // Divide elements of lower diagonal matrix L by pivot 
+	    if (j != (dim-1)) {
+		temp = 1.0 / (matrix0[(mtx + (dim*j) + j)]);
+		target = mtx + (dim*(j+1)) + j;
+		i = (dim-1) - j;
+		while (i-- != 0) {
+		    matrix0[target] *= temp;
+		    target += dim;
+		}
+	    }
+
+	}
+
+	return true;
+    }
+
+    /**
+     * Solves a set of linear equations.  The input parameters "matrix1",
+     * and "row_perm" come from luDecompostion and do not change
+     * here.  The parameter "matrix2" is a set of column vectors assembled
+     * into a nxn matrix of floating-point values.  The procedure takes each
+     * column of "matrix2" in turn and treats it as the right-hand side of the
+     * matrix equation Ax = LUx = b.  The solution vector replaces the
+     * original column of the matrix.
+     *
+     * If "matrix2" is the identity matrix, the procedure replaces its contents
+     * with the inverse of the matrix from which "matrix1" was originally
+     * derived.
+     */
+    //
+    // Reference: Press, Flannery, Teukolsky, Vetterling, 
+    //	      _Numerical_Recipes_in_C_, Cambridge University Press, 
+    //	      1988, pp 44-45.
+    //
+    static void luBacksubstitution(int dim, double[] matrix1,
+				   int[] row_perm,
+				   double[] matrix2) {
+
+	int i, ii, ip, j, k;
+	int rp;
+	int cv, rv, ri;
+	double tt;
+	
+	// rp = row_perm;
+	rp = 0;
+
+	// For each column vector of matrix2 ... 
+	for (k = 0; k < dim; k++) {
+	    // cv = &(matrix2[0][k]);
+	    cv = k;
+	    ii = -1;
+
+	    // Forward substitution 
+	    for (i = 0; i < dim; i++) {
+		double sum;
+
+		ip = row_perm[rp+i];
+		sum = matrix2[cv+dim*ip];
+		matrix2[cv+dim*ip] = matrix2[cv+dim*i];
+		if (ii >= 0) {
+		    // rv = &(matrix1[i][0]);
+		    rv = i*dim;
+		    for (j = ii; j <= i-1; j++) {
+			sum -= matrix1[rv+j] * matrix2[cv+dim*j];
+		    }
+		}
+		else if (sum != 0.0) {
+		    ii = i;
+		}
+		matrix2[cv+dim*i] = sum;
+	    }
+
+	    // Backsubstitution 
+	    for (i = 0; i < dim; i++) {
+		ri = (dim-1-i);
+		rv = dim*(ri);
+		tt = 0.0;
+		for(j=1;j<=i;j++) {
+		    tt += matrix1[rv+dim-j] * matrix2[cv+dim*(dim-j)]; 	  
+		}
+		matrix2[cv+dim*ri]= (matrix2[cv+dim*ri] - tt) / matrix1[rv+ri];
+            }
+	}
+    }
+
+
+    /**
+     * Creates a new object of the same class as this object.
+     *
+     * @return a clone of this instance.
+     * @exception OutOfMemoryError if there is not enough memory.
+     * @see java.lang.Cloneable
+     * @since vecmath 1.3
+     */
+    public Object clone() {
+	GMatrix m1 = null;
+	try {
+	    m1 = (GMatrix)super.clone();
+	} catch (CloneNotSupportedException e) {
+	    // this shouldn't happen, since we are Cloneable
+	    throw new InternalError();
+	}
+
+	// Also need to clone array of values
+        m1.values = new double[nRow][nCol];
+	for (int i = 0; i < nRow; i++) {
+	   for(int j = 0; j < nCol; j++) {
+	       m1.values[i][j] = values[i][j];
+	   }
+	}
+
+	return m1;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/vecmath/Matrix3d.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/vecmath/Matrix3d.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/vecmath/Matrix3d.java	(revision 28000)
@@ -0,0 +1,721 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * $Revision: 127 $
+ * $Date: 2008-02-28 21:18:51 +0100 (jeu., 28 févr. 2008) $
+ * $State$
+ */
+
+package javax.vecmath;
+
+
+/**
+ * A double precision floating point 3 by 3 matrix.
+ * Primarily to support 3D rotations.
+ *
+ */
+public class Matrix3d implements java.io.Serializable, Cloneable {
+
+    // Compatible with 1.1
+    static final long serialVersionUID = 6837536777072402710L;
+
+    /**
+     * The first matrix element in the first row.
+     */
+    public	double	m00;
+
+    /**
+     * The second matrix element in the first row.
+     */
+    public	double	m01;
+
+    /**
+     * The third matrix element in the first row.
+     */
+    public	double	m02;
+
+    /**
+     * The first matrix element in the second row.
+     */
+    public	double	m10;
+
+    /**
+     * The second matrix element in the second row.
+     */
+    public	double	m11;
+
+    /**
+     * The third matrix element in the second row.
+     */
+    public	double	m12;
+
+    /**
+     * The first matrix element in the third row.
+     */
+    public	double	m20;
+
+    /**
+     * The second matrix element in the third row.
+     */
+    public	double	m21;
+
+    /**
+     * The third matrix element in the third row.
+     */
+    public	double	m22;
+
+    /**
+     * Constructs and initializes a Matrix3d to all zeros.
+     */
+    public Matrix3d()
+    {
+	this.m00 = 0.0;
+	this.m01 = 0.0;
+	this.m02 = 0.0;
+
+	this.m10 = 0.0;
+	this.m11 = 0.0;
+	this.m12 = 0.0;
+
+	this.m20 = 0.0;
+	this.m21 = 0.0;
+	this.m22 = 0.0;
+
+    }
+
+   /**
+     * Returns a string that contains the values of this Matrix3d.
+     * @return the String representation
+     */
+    public String toString() {
+      return
+	this.m00 + ", " + this.m01 + ", " + this.m02 + "\n" +
+	this.m10 + ", " + this.m11 + ", " + this.m12 + "\n" +
+	this.m20 + ", " + this.m21 + ", " + this.m22 + "\n";
+    }
+
+    /**
+     * Sets this Matrix3d to identity.
+     */
+    public final void setIdentity()
+    {
+	this.m00 = 1.0;
+	this.m01 = 0.0;
+	this.m02 = 0.0;
+
+	this.m10 = 0.0;
+	this.m11 = 1.0;
+	this.m12 = 0.0;
+
+	this.m20 = 0.0;
+	this.m21 = 0.0;
+	this.m22 = 1.0;
+    }
+
+
+    /**
+     * Sets the specified element of this matrix3f to the value provided.
+     * @param row the row number to be modified (zero indexed)
+     * @param column the column number to be modified (zero indexed)
+     * @param value the new value
+     */
+    public final void setElement(int row, int column, double value)
+    {
+	switch (row)
+	  {
+	  case 0:
+	    switch(column)
+	      {
+	      case 0:
+		this.m00 = value;
+		break;
+	      case 1:
+		this.m01 = value;
+		break;
+	      case 2:
+		this.m02 = value;
+		break;
+	      default:
+		throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d0"));
+	      }
+	    break;
+
+	  case 1:
+	    switch(column)
+	      {
+	      case 0:
+		this.m10 = value;
+		break;
+	      case 1:
+		this.m11 = value;
+		break;
+	      case 2:
+		this.m12 = value;
+		break;
+	      default:
+		throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d0"));
+	      }
+	    break;
+
+
+	  case 2:
+	    switch(column)
+	      {
+	      case 0:
+		this.m20 = value;
+		break;
+	      case 1:
+		this.m21 = value;
+		break;
+	      case 2:
+		this.m22 = value;
+		break;
+	      default:
+		throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d0"));
+	      }
+	    break;
+
+	  default:
+		throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d0"));
+	  }
+    }
+
+    /**
+     * Retrieves the value at the specified row and column of the specified
+     * matrix.
+     * @param row the row number to be retrieved (zero indexed)
+     * @param column the column number to be retrieved (zero indexed)
+     * @return the value at the indexed element.
+     */
+    public final double getElement(int row, int column)
+    {
+	switch (row)
+	  {
+	  case 0:
+	    switch(column)
+	      {
+	      case 0:
+		return(this.m00);
+	      case 1:
+		return(this.m01);
+	      case 2:
+		return(this.m02);
+	      default:
+		break;
+	      }
+	    break;
+	  case 1:
+	    switch(column)
+	      {
+	      case 0:
+		return(this.m10);
+	      case 1:
+		return(this.m11);
+	      case 2:
+		return(this.m12);
+	      default:
+		break;
+	      }
+	    break;
+
+	  case 2:
+	    switch(column)
+	      {
+	      case 0:
+		return(this.m20);
+	      case 1:
+		return(this.m21);
+	      case 2:
+		return(this.m22);
+	      default:
+		break;
+	      }
+	    break;
+
+	  default:
+	    break;
+	  }
+
+	throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix3d1"));
+    }
+
+    /**
+     * Sets the value of this matrix to its transpose.
+     */
+    public final void transpose() // NO_UCD
+    {
+	double temp;
+
+	temp = this.m10;
+	this.m10 = this.m01;
+	this.m01 = temp;
+
+	temp = this.m20;
+	this.m20 = this.m02;
+	this.m02 = temp;
+
+	temp = this.m21;
+	this.m21 = this.m12;
+	this.m12 = temp;
+    }
+
+    /**
+     * Inverts this matrix in place.
+     */
+    public final void invert() // NO_UCD
+    {
+         invertGeneral( this );
+    }
+
+    /**
+     * General invert routine.  Inverts m1 and places the result in "this".
+     * Note that this routine handles both the "this" version and the
+     * non-"this" version.
+     *
+     * Also note that since this routine is slow anyway, we won't worry
+     * about allocating a little bit of garbage.
+     */
+    private final void invertGeneral(Matrix3d  m1) {
+	double result[] = new double[9];
+	int row_perm[] = new int[3];
+	int i;
+	double[]    tmp = new double[9];  // scratch matrix
+
+	// Use LU decomposition and backsubstitution code specifically
+	// for floating-point 3x3 matrices.
+
+	// Copy source matrix to t1tmp
+        tmp[0] = m1.m00;
+        tmp[1] = m1.m01;
+        tmp[2] = m1.m02;
+
+        tmp[3] = m1.m10;
+        tmp[4] = m1.m11;
+        tmp[5] = m1.m12;
+
+        tmp[6] = m1.m20;
+        tmp[7] = m1.m21;
+        tmp[8] = m1.m22;
+
+
+	// Calculate LU decomposition: Is the matrix singular?
+	if (!luDecomposition(tmp, row_perm)) {
+	    // Matrix has no inverse
+	    throw new SingularMatrixException(VecMathI18N.getString("Matrix3d12"));
+	}
+
+	// Perform back substitution on the identity matrix
+        for(i=0;i<9;i++) result[i] = 0.0;
+        result[0] = 1.0; result[4] = 1.0; result[8] = 1.0;
+	luBacksubstitution(tmp, row_perm, result);
+
+        this.m00 = result[0];
+        this.m01 = result[1];
+        this.m02 = result[2];
+
+        this.m10 = result[3];
+        this.m11 = result[4];
+        this.m12 = result[5];
+
+        this.m20 = result[6];
+        this.m21 = result[7];
+        this.m22 = result[8];
+
+    }
+
+    /**
+     * Given a 3x3 array "matrix0", this function replaces it with the
+     * LU decomposition of a row-wise permutation of itself.  The input
+     * parameters are "matrix0" and "dimen".  The array "matrix0" is also
+     * an output parameter.  The vector "row_perm[3]" is an output
+     * parameter that contains the row permutations resulting from partial
+     * pivoting.  The output parameter "even_row_xchg" is 1 when the
+     * number of row exchanges is even, or -1 otherwise.  Assumes data
+     * type is always double.
+     *
+     * This function is similar to luDecomposition, except that it
+     * is tuned specifically for 3x3 matrices.
+     *
+     * @return true if the matrix is nonsingular, or false otherwise.
+     */
+    //
+    // Reference: Press, Flannery, Teukolsky, Vetterling,
+    //	      _Numerical_Recipes_in_C_, Cambridge University Press,
+    //	      1988, pp 40-45.
+    //
+    static boolean luDecomposition(double[] matrix0,
+				   int[] row_perm) {
+
+	double row_scale[] = new double[3];
+
+	// Determine implicit scaling information by looping over rows
+	{
+	    int i, j;
+	    int ptr, rs;
+	    double big, temp;
+
+	    ptr = 0;
+	    rs = 0;
+
+	    // For each row ...
+	    i = 3;
+	    while (i-- != 0) {
+		big = 0.0;
+
+		// For each column, find the largest element in the row
+		j = 3;
+		while (j-- != 0) {
+		    temp = matrix0[ptr++];
+		    temp = Math.abs(temp);
+		    if (temp > big) {
+			big = temp;
+		    }
+		}
+
+		// Is the matrix singular?
+		if (big == 0.0) {
+		    return false;
+		}
+		row_scale[rs++] = 1.0 / big;
+	    }
+	}
+
+	{
+	    int j;
+	    int mtx;
+
+	    mtx = 0;
+
+	    // For all columns, execute Crout's method
+	    for (j = 0; j < 3; j++) {
+		int i, imax, k;
+		int target, p1, p2;
+		double sum, big, temp;
+
+		// Determine elements of upper diagonal matrix U
+		for (i = 0; i < j; i++) {
+		    target = mtx + (3*i) + j;
+		    sum = matrix0[target];
+		    k = i;
+		    p1 = mtx + (3*i);
+		    p2 = mtx + j;
+		    while (k-- != 0) {
+			sum -= matrix0[p1] * matrix0[p2];
+			p1++;
+			p2 += 3;
+		    }
+		    matrix0[target] = sum;
+		}
+
+		// Search for largest pivot element and calculate
+		// intermediate elements of lower diagonal matrix L.
+		big = 0.0;
+		imax = -1;
+		for (i = j; i < 3; i++) {
+		    target = mtx + (3*i) + j;
+		    sum = matrix0[target];
+		    k = j;
+		    p1 = mtx + (3*i);
+		    p2 = mtx + j;
+		    while (k-- != 0) {
+			sum -= matrix0[p1] * matrix0[p2];
+			p1++;
+			p2 += 3;
+		    }
+		    matrix0[target] = sum;
+
+		    // Is this the best pivot so far?
+		    if ((temp = row_scale[i] * Math.abs(sum)) >= big) {
+			big = temp;
+			imax = i;
+		    }
+		}
+
+		if (imax < 0) {
+		    throw new RuntimeException(VecMathI18N.getString("Matrix3d13"));
+		}
+
+		// Is a row exchange necessary?
+		if (j != imax) {
+		    // Yes: exchange rows
+		    k = 3;
+		    p1 = mtx + (3*imax);
+		    p2 = mtx + (3*j);
+		    while (k-- != 0) {
+			temp = matrix0[p1];
+			matrix0[p1++] = matrix0[p2];
+			matrix0[p2++] = temp;
+		    }
+
+		    // Record change in scale factor
+		    row_scale[imax] = row_scale[j];
+		}
+
+		// Record row permutation
+		row_perm[j] = imax;
+
+		// Is the matrix singular
+		if (matrix0[(mtx + (3*j) + j)] == 0.0) {
+		    return false;
+		}
+
+		// Divide elements of lower diagonal matrix L by pivot
+		if (j != (3-1)) {
+		    temp = 1.0 / (matrix0[(mtx + (3*j) + j)]);
+		    target = mtx + (3*(j+1)) + j;
+		    i = 2 - j;
+		    while (i-- != 0) {
+			matrix0[target] *= temp;
+			target += 3;
+		    }
+		}
+	    }
+	}
+
+	return true;
+    }
+
+    /**
+     * Solves a set of linear equations.  The input parameters "matrix1",
+     * and "row_perm" come from luDecompostionD3x3 and do not change
+     * here.  The parameter "matrix2" is a set of column vectors assembled
+     * into a 3x3 matrix of floating-point values.  The procedure takes each
+     * column of "matrix2" in turn and treats it as the right-hand side of the
+     * matrix equation Ax = LUx = b.  The solution vector replaces the
+     * original column of the matrix.
+     *
+     * If "matrix2" is the identity matrix, the procedure replaces its contents
+     * with the inverse of the matrix from which "matrix1" was originally
+     * derived.
+     */
+    //
+    // Reference: Press, Flannery, Teukolsky, Vetterling,
+    //	      _Numerical_Recipes_in_C_, Cambridge University Press,
+    //	      1988, pp 44-45.
+    //
+    static void luBacksubstitution(double[] matrix1,
+				   int[] row_perm,
+				   double[] matrix2) {
+
+	int i, ii, ip, j, k;
+	int rp;
+	int cv, rv;
+
+	//	rp = row_perm;
+	rp = 0;
+
+	// For each column vector of matrix2 ...
+	for (k = 0; k < 3; k++) {
+	    //	    cv = &(matrix2[0][k]);
+	    cv = k;
+	    ii = -1;
+
+	    // Forward substitution
+	    for (i = 0; i < 3; i++) {
+		double sum;
+
+		ip = row_perm[rp+i];
+		sum = matrix2[cv+3*ip];
+		matrix2[cv+3*ip] = matrix2[cv+3*i];
+		if (ii >= 0) {
+		    //		    rv = &(matrix1[i][0]);
+		    rv = i*3;
+		    for (j = ii; j <= i-1; j++) {
+			sum -= matrix1[rv+j] * matrix2[cv+3*j];
+		    }
+		}
+		else if (sum != 0.0) {
+		    ii = i;
+		}
+		matrix2[cv+3*i] = sum;
+	    }
+
+	    // Backsubstitution
+	    //	    rv = &(matrix1[3][0]);
+	    rv = 2*3;
+	    matrix2[cv+3*2] /= matrix1[rv+2];
+
+	    rv -= 3;
+	    matrix2[cv+3*1] = (matrix2[cv+3*1] -
+			    matrix1[rv+2] * matrix2[cv+3*2]) / matrix1[rv+1];
+
+	    rv -= 3;
+	    matrix2[cv+4*0] = (matrix2[cv+3*0] -
+			    matrix1[rv+1] * matrix2[cv+3*1] -
+			    matrix1[rv+2] * matrix2[cv+3*2]) / matrix1[rv+0];
+
+	}
+    }
+
+   /**
+     * Sets the value of this matrix to the result of multiplying itself
+     * with matrix m1.
+     * @param m1 the other matrix
+     */
+    public final void mul(Matrix3d m1)
+    {
+            double      m00, m01, m02,
+                        m10, m11, m12,
+                        m20, m21, m22;
+
+            m00 = this.m00*m1.m00 + this.m01*m1.m10 + this.m02*m1.m20;
+            m01 = this.m00*m1.m01 + this.m01*m1.m11 + this.m02*m1.m21;
+            m02 = this.m00*m1.m02 + this.m01*m1.m12 + this.m02*m1.m22;
+
+            m10 = this.m10*m1.m00 + this.m11*m1.m10 + this.m12*m1.m20;
+            m11 = this.m10*m1.m01 + this.m11*m1.m11 + this.m12*m1.m21;
+            m12 = this.m10*m1.m02 + this.m11*m1.m12 + this.m12*m1.m22;
+
+            m20 = this.m20*m1.m00 + this.m21*m1.m10 + this.m22*m1.m20;
+            m21 = this.m20*m1.m01 + this.m21*m1.m11 + this.m22*m1.m21;
+            m22 = this.m20*m1.m02 + this.m21*m1.m12 + this.m22*m1.m22;
+
+            this.m00 = m00; this.m01 = m01; this.m02 = m02;
+            this.m10 = m10; this.m11 = m11; this.m12 = m12;
+            this.m20 = m20; this.m21 = m21; this.m22 = m22;
+    }
+
+   /**
+     * Returns true if all of the data members of Matrix3d m1 are
+     * equal to the corresponding data members in this Matrix3d.
+     * @param m1  the matrix with which the comparison is made
+     * @return  true or false
+     */
+    public boolean equals(Matrix3d m1)
+    {
+      try {
+         return(this.m00 == m1.m00 && this.m01 == m1.m01 && this.m02 == m1.m02
+            && this.m10 == m1.m10 && this.m11 == m1.m11 && this.m12 == m1.m12
+            && this.m20 == m1.m20 && this.m21 == m1.m21 && this.m22 == m1.m22);
+      }
+      catch (NullPointerException e2) { return false; }
+
+    }
+
+   /**
+     * Returns true if the Object t1 is of type Matrix3d and all of the
+     * data members of t1 are equal to the corresponding data members in
+     * this Matrix3d.
+     * @param t1  the matrix with which the comparison is made
+     * @return  true or false
+     */
+    public boolean equals(Object t1)
+    {
+        try {
+           Matrix3d m2 = (Matrix3d) t1;
+           return(this.m00 == m2.m00 && this.m01 == m2.m01 && this.m02 == m2.m02
+             && this.m10 == m2.m10 && this.m11 == m2.m11 && this.m12 == m2.m12
+             && this.m20 == m2.m20 && this.m21 == m2.m21 && this.m22 == m2.m22);
+        }
+        catch (ClassCastException   e1) { return false; }
+        catch (NullPointerException e2) { return false; }
+
+    }
+
+
+    /**
+     * Returns a hash code value based on the data values in this
+     * object.  Two different Matrix3d objects with identical data values
+     * (i.e., Matrix3d.equals returns true) will return the same hash
+     * code value.  Two objects with different data members may return the
+     * same hash value, although this is not likely.
+     * @return the integer hash code value
+     */
+    public int hashCode() {
+	long bits = 1L;
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m00);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m01);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m02);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m10);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m11);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m12);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m20);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m21);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m22);
+	return (int) (bits ^ (bits >> 32));
+    }
+
+
+  /**
+    *  Sets this matrix to all zeros.
+    */
+   public final void setZero() // NO_UCD
+   {
+        m00 = 0.0;
+        m01 = 0.0;
+        m02 = 0.0;
+
+        m10 = 0.0;
+        m11 = 0.0;
+        m12 = 0.0;
+
+        m20 = 0.0;
+        m21 = 0.0;
+        m22 = 0.0;
+
+   }
+
+   /**
+    * Negates the value of this matrix: this = -this.
+    */
+   public final void negate() // NO_UCD
+   {
+       this.m00 = -this.m00;
+       this.m01 = -this.m01;
+       this.m02 = -this.m02;
+
+       this.m10 = -this.m10;
+       this.m11 = -this.m11;
+       this.m12 = -this.m12;
+
+       this.m20 = -this.m20;
+       this.m21 = -this.m21;
+       this.m22 = -this.m22;
+
+   }
+
+    /**
+     * Creates a new object of the same class as this object.
+     *
+     * @return a clone of this instance.
+     * @exception OutOfMemoryError if there is not enough memory.
+     * @see java.lang.Cloneable
+     * @since vecmath 1.3
+     */
+    public Object clone() {
+	Matrix3d m1 = null;
+	try {
+	    m1 = (Matrix3d)super.clone();
+	} catch (CloneNotSupportedException e) {
+	    // this shouldn't happen, since we are Cloneable
+	    throw new InternalError();
+	}
+
+	// Also need to create new tmp arrays (no need to actually clone them)
+	return m1;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/vecmath/Matrix4d.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/vecmath/Matrix4d.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/vecmath/Matrix4d.java	(revision 28000)
@@ -0,0 +1,961 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * $Revision: 127 $
+ * $Date: 2008-02-28 21:18:51 +0100 (jeu., 28 févr. 2008) $
+ * $State$
+ */
+
+package javax.vecmath;
+
+import java.lang.Math;
+
+/**
+ * A double precision floating point 4 by 4 matrix.
+ * Primarily to support 3D rotations.
+ *
+ */
+public class Matrix4d implements java.io.Serializable, Cloneable {
+
+    // Compatible with 1.1
+    static final long serialVersionUID = 8223903484171633710L;
+
+    /**
+     *  The first element of the first row.
+     */
+    public	double	m00;
+
+    /**
+     *  The second element of the first row.
+     */
+    public	double	m01;
+
+    /**
+     *  The third element of the first row.
+     */
+    public	double	m02;
+
+    /**
+     *  The fourth element of the first row.
+     */
+    public	double	m03;
+
+    /**
+     *  The first element of the second row.
+     */
+    public	double	m10;
+
+    /**
+     *  The second element of the second row.
+     */
+    public	double	m11;
+
+    /**
+     *  The third element of the second row.
+     */
+    public	double	m12;
+
+    /**
+     *  The fourth element of the second row.
+     */
+    public	double	m13;
+
+    /**
+     *  The first element of the third row.
+     */
+    public	double	m20;
+
+    /**
+     *  The second element of the third row.
+     */
+    public	double	m21;
+
+    /**
+     *  The third element of the third row.
+     */
+    public	double	m22;
+
+    /**
+     *  The fourth element of the third row.
+     */
+    public	double	m23;
+
+    /**
+     *  The first element of the fourth row.
+     */
+    public	double	m30;
+
+    /**
+     *  The second element of the fourth row.
+     */
+    public	double	m31;
+
+    /**
+     *  The third element of the fourth row.
+     */
+    public	double	m32;
+
+    /**
+     *  The fourth element of the fourth row.
+     */
+    public	double	m33;
+    /*
+    double[] tmp = new double[16];
+    double[] tmp_rot = new double[9];  // scratch matrix
+    double[] tmp_scale = new double[3];  // scratch matrix
+    */
+ 
+
+    /**
+     * Constructs and initializes a Matrix4d from the specified 16 values.
+     * @param m00 the [0][0] element
+     * @param m01 the [0][1] element
+     * @param m02 the [0][2] element
+     * @param m03 the [0][3] element
+     * @param m10 the [1][0] element
+     * @param m11 the [1][1] element
+     * @param m12 the [1][2] element
+     * @param m13 the [1][3] element
+     * @param m20 the [2][0] element
+     * @param m21 the [2][1] element
+     * @param m22 the [2][2] element
+     * @param m23 the [2][3] element
+     * @param m30 the [3][0] element
+     * @param m31 the [3][1] element
+     * @param m32 the [3][2] element
+     * @param m33 the [3][3] element
+     */
+    public Matrix4d(double m00, double m01, double m02, double m03,
+		    double m10, double m11, double m12, double m13,
+		    double m20, double m21, double m22, double m23,
+		    double m30, double m31, double m32, double m33)
+    {
+	this.m00 = m00;
+	this.m01 = m01;
+	this.m02 = m02;
+	this.m03 = m03;
+
+	this.m10 = m10;
+	this.m11 = m11;
+	this.m12 = m12;
+	this.m13 = m13;
+
+	this.m20 = m20;
+	this.m21 = m21;
+	this.m22 = m22;
+	this.m23 = m23;
+
+	this.m30 = m30;
+	this.m31 = m31;
+	this.m32 = m32;
+	this.m33 = m33;
+
+    }
+
+
+
+    /**
+     * Constructs and initializes a Matrix4d to all zeros.
+     */
+    public Matrix4d()
+    {
+	this.m00 = 0.0;
+	this.m01 = 0.0;
+	this.m02 = 0.0;
+	this.m03 = 0.0;
+
+	this.m10 = 0.0;
+	this.m11 = 0.0;
+	this.m12 = 0.0;
+	this.m13 = 0.0;
+
+	this.m20 = 0.0;
+	this.m21 = 0.0;
+	this.m22 = 0.0;
+	this.m23 = 0.0;
+
+	this.m30 = 0.0;
+	this.m31 = 0.0;
+	this.m32 = 0.0;
+	this.m33 = 0.0;
+
+    }
+
+   /**
+     * Returns a string that contains the values of this Matrix4d.
+     * @return the String representation
+     */ 
+    public String toString() {
+      return
+	this.m00 + ", " + this.m01 + ", " + this.m02 + ", " + this.m03 + "\n" +
+	this.m10 + ", " + this.m11 + ", " + this.m12 + ", " + this.m13 + "\n" +
+	this.m20 + ", " + this.m21 + ", " + this.m22 + ", " + this.m23 + "\n" +
+	this.m30 + ", " + this.m31 + ", " + this.m32 + ", " + this.m33 + "\n";
+    }
+
+    /**
+     * Sets this Matrix4d to identity.
+     */
+    public final void setIdentity()
+    {
+	this.m00 = 1.0;
+	this.m01 = 0.0;
+	this.m02 = 0.0;
+	this.m03 = 0.0;
+
+	this.m10 = 0.0;
+	this.m11 = 1.0;
+	this.m12 = 0.0;
+	this.m13 = 0.0;
+
+	this.m20 = 0.0;
+	this.m21 = 0.0;
+	this.m22 = 1.0;
+	this.m23 = 0.0;
+
+	this.m30 = 0.0;
+	this.m31 = 0.0;
+	this.m32 = 0.0;
+	this.m33 = 1.0;
+    }
+
+    /**
+     * Sets the specified element of this matrix4f to the value provided.
+     * @param row the row number to be modified (zero indexed)
+     * @param column the column number to be modified (zero indexed)
+     * @param value the new value
+     */
+    public final void setElement(int row, int column, double value)
+    {
+	switch (row) 
+	  {
+	  case 0:
+	    switch(column)
+	      {
+	      case 0:
+		this.m00 = value;
+		break;
+	      case 1:
+		this.m01 = value;
+		break;
+	      case 2:
+		this.m02 = value;
+		break;
+	      case 3:
+		this.m03 = value;
+		break;
+	      default:
+		throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d0"));
+	      }
+	    break;
+
+	  case 1:
+	    switch(column) 
+	      {
+	      case 0:
+		this.m10 = value;
+		break;
+	      case 1:
+		this.m11 = value;
+		break;
+	      case 2:
+		this.m12 = value;
+		break;
+	      case 3:
+		this.m13 = value;
+		break;
+	      default:
+		throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d0"));
+	      }
+	    break;
+
+	  case 2:
+	    switch(column) 
+	      {
+	      case 0:
+		this.m20 = value;
+		break;
+	      case 1:
+		this.m21 = value;
+		break;
+	      case 2:
+		this.m22 = value;
+		break;
+	      case 3:
+		this.m23 = value;
+		break;
+	      default:
+		throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d0"));
+	      }
+	    break;
+
+	  case 3:
+	    switch(column) 
+	      {
+	      case 0:
+		this.m30 = value;
+		break;
+	      case 1:
+		this.m31 = value;
+		break;
+	      case 2:
+		this.m32 = value;
+		break;
+	      case 3:
+		this.m33 = value;
+		break;
+	      default:
+		throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d0"));
+	      }
+	    break;
+
+	  default:
+		throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d0"));
+	  }
+    }
+
+    /**
+     * Retrieves the value at the specified row and column of this matrix.
+     * @param row the row number to be retrieved (zero indexed)
+     * @param column the column number to be retrieved (zero indexed)
+     * @return the value at the indexed element
+     */
+    public final double getElement(int row, int column)
+    {
+	switch (row) 
+	  {
+	  case 0:
+	    switch(column)
+	      {
+	      case 0:
+		return(this.m00);
+	      case 1:
+		return(this.m01);
+	      case 2:
+		return(this.m02);
+	      case 3:
+		return(this.m03);
+	      default:
+		break;
+	      }
+	    break;
+	  case 1:
+	    switch(column) 
+	      {
+	      case 0:
+		return(this.m10);
+	      case 1:
+		return(this.m11);
+	      case 2:
+		return(this.m12);
+	      case 3:
+		return(this.m13);
+	      default:
+		break;
+	      }
+	    break;
+	  
+	  case 2:
+	    switch(column) 
+	      {
+	      case 0:
+		return(this.m20);
+	      case 1:
+		return(this.m21);
+	      case 2:
+		return(this.m22);
+	      case 3:
+		return(this.m23);
+	      default:
+		break;
+	      }
+	    break;
+	    
+	  case 3:
+	    switch(column) 
+	      {
+	      case 0:
+		return(this.m30);
+	      case 1:
+		return(this.m31);
+	      case 2:
+		return(this.m32);
+	      case 3:
+		return(this.m33);
+	      default:
+		break;
+	      }
+	    break;
+	    
+	  default:
+	    break;
+	  }
+	throw new ArrayIndexOutOfBoundsException(VecMathI18N.getString("Matrix4d1"));
+    }
+
+ 
+ 
+ 
+ 
+
+
+    /**
+     * Sets the value of this matrix to its transpose.
+     */
+    public final void transpose() // NO_UCD
+    {
+	double temp;
+
+	temp = this.m10;
+	this.m10 = this.m01;
+	this.m01 = temp;
+
+	temp = this.m20;
+	this.m20 = this.m02;
+	this.m02 = temp;
+
+	temp = this.m30;
+	this.m30 = this.m03;
+	this.m03 = temp;
+
+	temp = this.m21;
+	this.m21 = this.m12;
+	this.m12 = temp;
+
+	temp = this.m31;
+	this.m31 = this.m13;
+	this.m13 = temp;
+
+	temp = this.m32;
+	this.m32 = this.m23;
+	this.m23 = temp;
+    }
+
+
+  /**
+   * Inverts this matrix in place.
+   */
+  public final void invert() // NO_UCD
+  {
+     invertGeneral( this );    
+  }
+
+    /**
+     * General invert routine.  Inverts m1 and places the result in "this".
+     * Note that this routine handles both the "this" version and the
+     * non-"this" version.
+     *
+     * Also note that since this routine is slow anyway, we won't worry
+     * about allocating a little bit of garbage.
+     */
+    final void invertGeneral(Matrix4d  m1) {
+	double result[] = new double[16];
+	int row_perm[] = new int[4];
+	int i;
+
+	// Use LU decomposition and backsubstitution code specifically
+	// for floating-point 4x4 matrices.
+	double[]    tmp = new double[16];  // scratch matrix
+	// Copy source matrix to t1tmp 
+        tmp[0] = m1.m00;
+        tmp[1] = m1.m01;
+        tmp[2] = m1.m02;
+        tmp[3] = m1.m03;
+ 
+        tmp[4] = m1.m10;
+        tmp[5] = m1.m11;
+        tmp[6] = m1.m12;
+        tmp[7] = m1.m13;
+ 
+        tmp[8] = m1.m20;
+        tmp[9] = m1.m21;
+        tmp[10] = m1.m22;
+        tmp[11] = m1.m23;
+ 
+        tmp[12] = m1.m30;
+        tmp[13] = m1.m31;
+        tmp[14] = m1.m32;
+        tmp[15] = m1.m33;
+
+	// Calculate LU decomposition: Is the matrix singular? 
+	if (!luDecomposition(tmp, row_perm)) {
+	    // Matrix has no inverse 
+	    throw new SingularMatrixException(VecMathI18N.getString("Matrix4d10"));
+	}
+
+	// Perform back substitution on the identity matrix 
+        for(i=0;i<16;i++) result[i] = 0.0;
+        result[0] = 1.0; result[5] = 1.0; result[10] = 1.0; result[15] = 1.0;
+	luBacksubstitution(tmp, row_perm, result);
+
+        this.m00 = result[0];
+        this.m01 = result[1];
+        this.m02 = result[2];
+        this.m03 = result[3];
+
+        this.m10 = result[4];
+        this.m11 = result[5];
+        this.m12 = result[6];
+        this.m13 = result[7];
+ 
+        this.m20 = result[8];
+        this.m21 = result[9];
+        this.m22 = result[10];
+        this.m23 = result[11];
+ 
+        this.m30 = result[12];
+        this.m31 = result[13];
+        this.m32 = result[14];
+        this.m33 = result[15];
+
+    }
+
+    /**
+     * Given a 4x4 array "matrix0", this function replaces it with the 
+     * LU decomposition of a row-wise permutation of itself.  The input 
+     * parameters are "matrix0" and "dimen".  The array "matrix0" is also 
+     * an output parameter.  The vector "row_perm[4]" is an output 
+     * parameter that contains the row permutations resulting from partial 
+     * pivoting.  The output parameter "even_row_xchg" is 1 when the 
+     * number of row exchanges is even, or -1 otherwise.  Assumes data 
+     * type is always double.
+     *
+     * This function is similar to luDecomposition, except that it
+     * is tuned specifically for 4x4 matrices.
+     *
+     * @return true if the matrix is nonsingular, or false otherwise.
+     */
+    //
+    // Reference: Press, Flannery, Teukolsky, Vetterling, 
+    //	      _Numerical_Recipes_in_C_, Cambridge University Press, 
+    //	      1988, pp 40-45.
+    //
+    static boolean luDecomposition(double[] matrix0,
+				   int[] row_perm) {
+
+	double row_scale[] = new double[4];
+
+	// Determine implicit scaling information by looping over rows 
+	{
+	    int i, j;
+	    int ptr, rs;
+	    double big, temp;
+
+	    ptr = 0;
+	    rs = 0;
+
+	    // For each row ... 
+	    i = 4;
+	    while (i-- != 0) {
+		big = 0.0;
+
+		// For each column, find the largest element in the row 
+		j = 4;
+		while (j-- != 0) {
+		    temp = matrix0[ptr++];
+		    temp = Math.abs(temp);
+		    if (temp > big) {
+			big = temp;
+		    }
+		}
+
+		// Is the matrix singular? 
+		if (big == 0.0) {
+		    return false;
+		}
+		row_scale[rs++] = 1.0 / big;
+	    }
+	}
+
+	{
+	    int j;
+	    int mtx;
+
+	    mtx = 0;
+
+	    // For all columns, execute Crout's method 
+	    for (j = 0; j < 4; j++) {
+		int i, imax, k;
+		int target, p1, p2;
+		double sum, big, temp;
+
+		// Determine elements of upper diagonal matrix U 
+		for (i = 0; i < j; i++) {
+		    target = mtx + (4*i) + j;
+		    sum = matrix0[target];
+		    k = i;
+		    p1 = mtx + (4*i);
+		    p2 = mtx + j;
+		    while (k-- != 0) {
+			sum -= matrix0[p1] * matrix0[p2];
+			p1++;
+			p2 += 4;
+		    }
+		    matrix0[target] = sum;
+		}
+
+		// Search for largest pivot element and calculate
+		// intermediate elements of lower diagonal matrix L.
+		big = 0.0;
+		imax = -1;
+		for (i = j; i < 4; i++) {
+		    target = mtx + (4*i) + j;
+		    sum = matrix0[target];
+		    k = j;
+		    p1 = mtx + (4*i);
+		    p2 = mtx + j;
+		    while (k-- != 0) {
+			sum -= matrix0[p1] * matrix0[p2];
+			p1++;
+			p2 += 4;
+		    }
+		    matrix0[target] = sum;
+
+		    // Is this the best pivot so far? 
+		    if ((temp = row_scale[i] * Math.abs(sum)) >= big) {
+			big = temp;
+			imax = i;
+		    }
+		}
+
+		if (imax < 0) {
+		    throw new RuntimeException(VecMathI18N.getString("Matrix4d11"));
+		}
+
+		// Is a row exchange necessary? 
+		if (j != imax) {
+		    // Yes: exchange rows 
+		    k = 4;
+		    p1 = mtx + (4*imax);
+		    p2 = mtx + (4*j);
+		    while (k-- != 0) {
+			temp = matrix0[p1];
+			matrix0[p1++] = matrix0[p2];
+			matrix0[p2++] = temp;
+		    }
+
+		    // Record change in scale factor 
+		    row_scale[imax] = row_scale[j];
+		}
+
+		// Record row permutation 
+		row_perm[j] = imax;
+
+		// Is the matrix singular 
+		if (matrix0[(mtx + (4*j) + j)] == 0.0) {
+		    return false;
+		}
+
+		// Divide elements of lower diagonal matrix L by pivot 
+		if (j != (4-1)) {
+		    temp = 1.0 / (matrix0[(mtx + (4*j) + j)]);
+		    target = mtx + (4*(j+1)) + j;
+		    i = 3 - j;
+		    while (i-- != 0) {
+			matrix0[target] *= temp;
+			target += 4;
+		    }
+		}
+	    }
+	}
+
+	return true;
+    }
+
+    /**
+     * Solves a set of linear equations.  The input parameters "matrix1",
+     * and "row_perm" come from luDecompostionD4x4 and do not change
+     * here.  The parameter "matrix2" is a set of column vectors assembled
+     * into a 4x4 matrix of floating-point values.  The procedure takes each
+     * column of "matrix2" in turn and treats it as the right-hand side of the
+     * matrix equation Ax = LUx = b.  The solution vector replaces the
+     * original column of the matrix.
+     *
+     * If "matrix2" is the identity matrix, the procedure replaces its contents
+     * with the inverse of the matrix from which "matrix1" was originally
+     * derived.
+     */
+    //
+    // Reference: Press, Flannery, Teukolsky, Vetterling, 
+    //	      _Numerical_Recipes_in_C_, Cambridge University Press, 
+    //	      1988, pp 44-45.
+    //
+    static void luBacksubstitution(double[] matrix1,
+				   int[] row_perm,
+				   double[] matrix2) {
+
+	int i, ii, ip, j, k;
+	int rp;
+	int cv, rv;
+	
+	//	rp = row_perm;
+	rp = 0;
+
+	// For each column vector of matrix2 ... 
+	for (k = 0; k < 4; k++) {
+	    //	    cv = &(matrix2[0][k]);
+	    cv = k;
+	    ii = -1;
+
+	    // Forward substitution 
+	    for (i = 0; i < 4; i++) {
+		double sum;
+
+		ip = row_perm[rp+i];
+		sum = matrix2[cv+4*ip];
+		matrix2[cv+4*ip] = matrix2[cv+4*i];
+		if (ii >= 0) {
+		    //		    rv = &(matrix1[i][0]);
+		    rv = i*4;
+		    for (j = ii; j <= i-1; j++) {
+			sum -= matrix1[rv+j] * matrix2[cv+4*j];
+		    }
+		}
+		else if (sum != 0.0) {
+		    ii = i;
+		}
+		matrix2[cv+4*i] = sum;
+	    }
+
+	    // Backsubstitution 
+	    //	    rv = &(matrix1[3][0]);
+	    rv = 3*4;
+	    matrix2[cv+4*3] /= matrix1[rv+3];
+
+	    rv -= 4;
+	    matrix2[cv+4*2] = (matrix2[cv+4*2] -
+			    matrix1[rv+3] * matrix2[cv+4*3]) / matrix1[rv+2];
+
+	    rv -= 4;
+	    matrix2[cv+4*1] = (matrix2[cv+4*1] -
+			    matrix1[rv+2] * matrix2[cv+4*2] -
+			    matrix1[rv+3] * matrix2[cv+4*3]) / matrix1[rv+1];
+
+	    rv -= 4;
+	    matrix2[cv+4*0] = (matrix2[cv+4*0] -
+			    matrix1[rv+1] * matrix2[cv+4*1] -
+			    matrix1[rv+2] * matrix2[cv+4*2] -
+			    matrix1[rv+3] * matrix2[cv+4*3]) / matrix1[rv+0];
+	}
+    }
+
+
+
+    /**
+     * Sets the value of this matrix to the result of multiplying itself
+     * with matrix m1.
+     * @param m1 the other matrix
+     */
+    public final void mul(Matrix4d m1) 
+    {
+            double      m00, m01, m02, m03,
+                        m10, m11, m12, m13,
+                        m20, m21, m22, m23,
+		        m30, m31, m32, m33;  // vars for temp result matrix 
+
+        m00 = this.m00*m1.m00 + this.m01*m1.m10 + 
+              this.m02*m1.m20 + this.m03*m1.m30;
+        m01 = this.m00*m1.m01 + this.m01*m1.m11 + 
+              this.m02*m1.m21 + this.m03*m1.m31;
+        m02 = this.m00*m1.m02 + this.m01*m1.m12 + 
+              this.m02*m1.m22 + this.m03*m1.m32;
+        m03 = this.m00*m1.m03 + this.m01*m1.m13 + 
+              this.m02*m1.m23 + this.m03*m1.m33;
+
+        m10 = this.m10*m1.m00 + this.m11*m1.m10 + 
+              this.m12*m1.m20 + this.m13*m1.m30;
+        m11 = this.m10*m1.m01 + this.m11*m1.m11 + 
+              this.m12*m1.m21 + this.m13*m1.m31;
+        m12 = this.m10*m1.m02 + this.m11*m1.m12 + 
+              this.m12*m1.m22 + this.m13*m1.m32;
+        m13 = this.m10*m1.m03 + this.m11*m1.m13 + 
+              this.m12*m1.m23 + this.m13*m1.m33;
+
+        m20 = this.m20*m1.m00 + this.m21*m1.m10 + 
+              this.m22*m1.m20 + this.m23*m1.m30;
+        m21 = this.m20*m1.m01 + this.m21*m1.m11 + 
+              this.m22*m1.m21 + this.m23*m1.m31;
+        m22 = this.m20*m1.m02 + this.m21*m1.m12 + 
+              this.m22*m1.m22 + this.m23*m1.m32;
+        m23 = this.m20*m1.m03 + this.m21*m1.m13 + 
+              this.m22*m1.m23 + this.m23*m1.m33;
+
+        m30 = this.m30*m1.m00 + this.m31*m1.m10 + 
+              this.m32*m1.m20 + this.m33*m1.m30;
+        m31 = this.m30*m1.m01 + this.m31*m1.m11 + 
+              this.m32*m1.m21 + this.m33*m1.m31;
+        m32 = this.m30*m1.m02 + this.m31*m1.m12 + 
+              this.m32*m1.m22 + this.m33*m1.m32;
+        m33 = this.m30*m1.m03 + this.m31*m1.m13 + 
+              this.m32*m1.m23 + this.m33*m1.m33;
+
+        this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
+        this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
+        this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
+        this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
+    }
+
+  
+   /**
+     * Returns true if all of the data members of Matrix4d m1 are
+     * equal to the corresponding data members in this Matrix4d.
+     * @param m1  the matrix with which the comparison is made
+     * @return  true or false
+     */
+    public boolean equals(Matrix4d m1)
+    {
+      try {
+        return(this.m00 == m1.m00 && this.m01 == m1.m01 && this.m02 == m1.m02
+            && this.m03 == m1.m03 && this.m10 == m1.m10 && this.m11 == m1.m11
+            && this.m12 == m1.m12 && this.m13 == m1.m13 && this.m20 == m1.m20
+            && this.m21 == m1.m21 && this.m22 == m1.m22 && this.m23 == m1.m23
+            && this.m30 == m1.m30 && this.m31 == m1.m31 && this.m32 == m1.m32
+            && this.m33 == m1.m33);
+      }  
+      catch (NullPointerException e2) { return false; }
+
+    }
+
+   /**
+     * Returns true if the Object t1 is of type Matrix4d and all of the
+     * data members of t1 are equal to the corresponding data members in
+     * this Matrix4d.
+     * @param t1  the matrix with which the comparison is made
+     * @return  true or false
+     */  
+    public boolean equals(Object t1)
+    {
+        try {    
+           Matrix4d m2 = (Matrix4d) t1;
+           return(this.m00 == m2.m00 && this.m01 == m2.m01 && this.m02 == m2.m02
+             && this.m03 == m2.m03 && this.m10 == m2.m10 && this.m11 == m2.m11
+             && this.m12 == m2.m12 && this.m13 == m2.m13 && this.m20 == m2.m20
+             && this.m21 == m2.m21 && this.m22 == m2.m22 && this.m23 == m2.m23
+             && this.m30 == m2.m30 && this.m31 == m2.m31 && this.m32 == m2.m32
+             && this.m33 == m2.m33);
+        }
+        catch (ClassCastException   e1) { return false; } 
+        catch (NullPointerException e2) { return false; }
+    }
+
+
+    /**
+     * Returns a hash code value based on the data values in this
+     * object.  Two different Matrix4d objects with identical data values
+     * (i.e., Matrix4d.equals returns true) will return the same hash
+     * code value.  Two objects with different data members may return the
+     * same hash value, although this is not likely.
+     * @return the integer hash code value
+     */  
+    public int hashCode() {
+	long bits = 1L;
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m00);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m01);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m02);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m03);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m10);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m11);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m12);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m13);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m20);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m21);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m22);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m23);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m30);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m31);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m32);
+	bits = 31L * bits + VecMathUtil.doubleToLongBits(m33);
+	return (int) (bits ^ (bits >> 32));
+    }
+
+
+  /**
+    *  Sets this matrix to all zeros.
+    */
+   public final void setZero() // NO_UCD
+   {
+        m00 = 0.0;
+        m01 = 0.0;
+        m02 = 0.0;
+        m03 = 0.0;
+        m10 = 0.0;
+        m11 = 0.0;
+        m12 = 0.0;
+        m13 = 0.0;
+        m20 = 0.0;
+        m21 = 0.0;
+        m22 = 0.0;
+        m23 = 0.0;
+        m30 = 0.0;
+        m31 = 0.0;
+        m32 = 0.0;
+        m33 = 0.0;
+   }
+
+   /**
+     * Negates the value of this matrix: this = -this.
+     */  
+    public final void negate() // NO_UCD
+    {
+        m00 = -m00;
+        m01 = -m01;
+        m02 = -m02;
+        m03 = -m03;
+        m10 = -m10;
+        m11 = -m11;
+        m12 = -m12;
+        m13 = -m13;
+        m20 = -m20;
+        m21 = -m21;
+        m22 = -m22;
+        m23 = -m23;
+        m30 = -m30;
+        m31 = -m31;
+        m32 = -m32;
+        m33 = -m33;
+    }
+
+
+    /**
+     * Creates a new object of the same class as this object.
+     *
+     * @return a clone of this instance.
+     * @exception OutOfMemoryError if there is not enough memory.
+     * @see java.lang.Cloneable
+     * @since vecmath 1.3
+     */
+    public Object clone() {
+	Matrix4d m1 = null;
+	try {
+	    m1 = (Matrix4d)super.clone();
+	} catch (CloneNotSupportedException e) {
+	    // this shouldn't happen, since we are Cloneable
+	    throw new InternalError();
+	}
+
+	return m1;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/vecmath/MismatchedSizeException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/vecmath/MismatchedSizeException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/vecmath/MismatchedSizeException.java	(revision 28000)
@@ -0,0 +1,51 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * $Revision: 127 $
+ * $Date: 2008-02-28 21:18:51 +0100 (jeu., 28 févr. 2008) $
+ * $State$
+ */
+
+package javax.vecmath;
+
+/**
+ * Indicates that an operation cannot be completed properly because
+ * of a mismatch in the sizes of object attributes.
+ */
+@SuppressWarnings("serial")
+public class MismatchedSizeException extends RuntimeException{
+
+/**
+ * Create the exception object that outputs a message.
+ * @param str the message string to be output.
+ */
+  public MismatchedSizeException(String str){
+
+    super(str);
+  }
+
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/javax/vecmath/SingularMatrixException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/vecmath/SingularMatrixException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/vecmath/SingularMatrixException.java	(revision 28000)
@@ -0,0 +1,55 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * $Revision: 127 $
+ * $Date: 2008-02-28 21:18:51 +0100 (jeu., 28 févr. 2008) $
+ * $State$
+ */
+
+package javax.vecmath;
+
+/**
+ * Indicates that inverse of a matrix can not be computed.
+ */
+@SuppressWarnings("serial")
+public class SingularMatrixException extends RuntimeException{
+
+/**
+ * Create the exception object with default values.
+ */
+  public SingularMatrixException(){
+  }
+
+/**
+ * Create the exception object that outputs message.
+ * @param str the message string to be output.
+ */
+  public SingularMatrixException(String str){
+
+    super(str);
+  }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/vecmath/VecMathI18N.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/vecmath/VecMathI18N.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/vecmath/VecMathI18N.java	(revision 28000)
@@ -0,0 +1,50 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * $Revision: 127 $
+ * $Date: 2008-02-28 21:18:51 +0100 (jeu., 28 févr. 2008) $
+ * $State$
+ */
+
+package javax.vecmath;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+
+class VecMathI18N {
+    static String getString(String key) {
+	String s;
+	try {
+	    s = ResourceBundle.getBundle("javax.vecmath.ExceptionStrings").getString(key);
+	}
+	catch (MissingResourceException e) {
+	    System.err.println("VecMathI18N: Error looking up: " + key);
+	    s = key;
+	}
+	return s;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/javax/vecmath/VecMathUtil.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/javax/vecmath/VecMathUtil.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/javax/vecmath/VecMathUtil.java	(revision 28000)
@@ -0,0 +1,75 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright 2004-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * $Revision: 127 $
+ * $Date: 2008-02-28 21:18:51 +0100 (jeu., 28 févr. 2008) $
+ * $State$
+ */
+
+package javax.vecmath;
+
+/**
+ * Utility vecmath class used when computing the hash code for vecmath
+ * objects containing float or double values. This fixes Issue 36.
+ */
+class VecMathUtil {
+
+    /**
+     * Returns the representation of the specified floating-point
+     * value according to the IEEE 754 floating-point "double format"
+     * bit layout, after first mapping -0.0 to 0.0. This method is
+     * identical to Double.doubleToLongBits(double) except that an
+     * integer value of 0L is returned for a floating-point value of
+     * -0.0. This is done for the purpose of computing a hash code
+     * that satisfies the contract of hashCode() and equals(). The
+     * equals() method in each vecmath class does a pair-wise "=="
+     * test on each floating-point field in the class (e.g., x, y, and
+     * z for a Tuple3d). Since 0.0&nbsp;==&nbsp;-0.0 returns true, we
+     * must also return the same hash code for two objects, one of
+     * which has a field with a value of -0.0 and the other of which
+     * has a cooresponding field with a value of 0.0.
+     *
+     * @param d an input double precision floating-point number
+     * @return the integer bits representing that floating-point
+     * number, after first mapping -0.0f to 0.0f
+     */
+    static long doubleToLongBits(double d) {
+	// Check for +0 or -0
+	if (d == 0.0) {
+	    return 0L;
+	}
+	else {
+	    return Double.doubleToLongBits(d);
+	}
+    }
+
+
+    /**
+     * Do not construct an instance of this class.
+     */
+    private VecMathUtil() {
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/CollectionUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/CollectionUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/CollectionUtils.java	(revision 28000)
@@ -0,0 +1,146 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * Provides utility methods and decorators for {@link Collection} instances.
+ *
+ * @since Commons Collections 1.0
+ * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (jeu., 10 avr. 2008) $
+ * 
+ * @author Rodney Waldhoff
+ * @author Paul Jack
+ * @author Stephen Colebourne
+ * @author Steve Downey
+ * @author Herve Quiroz
+ * @author Peter KoBek
+ * @author Matthew Hawthorne
+ * @author Janek Bogucki
+ * @author Phil Steitz
+ * @author Steven Melzer
+ * @author Jon Schewe
+ * @author Neil O'Toole
+ * @author Stephen Smith
+ */
+public class CollectionUtils {
+
+
+    /**
+     * <code>CollectionUtils</code> should not normally be instantiated.
+     */
+    public CollectionUtils() {
+    }
+
+
+    /** 
+     * Transform the collection by applying a Transformer to each element.
+     * <p>
+     * If the input collection or transformer is null, there is no change made.
+     * <p>
+     * This routine is best for Lists, for which set() is used to do the 
+     * transformations "in place."  For other Collections, clear() and addAll()
+     * are used to replace elements.  
+     * <p>
+     * If the input collection controls its input, such as a Set, and the
+     * Transformer creates duplicates (or are otherwise invalid), the 
+     * collection may reduce in size due to calling this method.
+     * 
+     * @param collection  the collection to get the input from, may be null
+     * @param transformer  the transformer to perform, may be null
+     */
+    public static void transform(Collection collection, Transformer transformer) {
+        if (collection != null && transformer != null) {
+            if (collection instanceof List) {
+                List list = (List) collection;
+                for (ListIterator it = list.listIterator(); it.hasNext();) {
+                    it.set(transformer.transform(it.next()));
+                }
+            } else {
+                Collection resultCollection = collect(collection, transformer);
+                collection.clear();
+                collection.addAll(resultCollection);
+            }
+        }
+    }
+        
+    /** 
+     * Returns a new Collection consisting of the elements of inputCollection transformed
+     * by the given transformer.
+     * <p>
+     * If the input transformer is null, the result is an empty list.
+     * 
+     * @param inputCollection  the collection to get the input from, may not be null
+     * @param transformer  the transformer to use, may be null
+     * @return the transformed result (new list)
+     * @throws NullPointerException if the input collection is null
+     */
+    public static Collection collect(Collection inputCollection, Transformer transformer) {
+        ArrayList answer = new ArrayList(inputCollection.size());
+        collect(inputCollection, transformer, answer);
+        return answer;
+    }
+    
+    /** 
+     * Transforms all elements from inputCollection with the given transformer 
+     * and adds them to the outputCollection.
+     * <p>
+     * If the input collection or transformer is null, there is no change to the 
+     * output collection.
+     *
+     * @param inputCollection  the collection to get the input from, may be null
+     * @param transformer  the transformer to use, may be null
+     * @param outputCollection  the collection to output into, may not be null
+     * @return the outputCollection with the transformed input added
+     * @throws NullPointerException if the output collection is null
+     */
+    public static Collection collect(Collection inputCollection, final Transformer transformer, final Collection outputCollection) {
+        if (inputCollection != null) {
+            return collect(inputCollection.iterator(), transformer, outputCollection);
+        }
+        return outputCollection;
+    }
+
+    /** 
+     * Transforms all elements from the inputIterator with the given transformer 
+     * and adds them to the outputCollection.
+     * <p>
+     * If the input iterator or transformer is null, there is no change to the 
+     * output collection.
+     *
+     * @param inputIterator  the iterator to get the input from, may be null
+     * @param transformer  the transformer to use, may be null
+     * @param outputCollection  the collection to output into, may not be null
+     * @return the outputCollection with the transformed input added
+     * @throws NullPointerException if the output collection is null
+     */
+    public static Collection collect(Iterator inputIterator, final Transformer transformer, final Collection outputCollection) {
+        if (inputIterator != null && transformer != null) {
+            while (inputIterator.hasNext()) {
+                Object item = inputIterator.next();
+                Object value = transformer.transform(item);
+                outputCollection.add(value);
+            }
+        }
+        return outputCollection;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/Factory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/Factory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/Factory.java	(revision 28000)
@@ -0,0 +1,45 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections;
+
+/**
+ * Defines a functor interface implemented by classes that create objects.
+ * <p>
+ * A <code>Factory</code> creates an object without using an input parameter.
+ * If an input parameter is required, then {@link Transformer} is more appropriate.
+ * <p>
+ * Standard implementations of common factories are provided by
+ * {@link FactoryUtils}. These include factories that return a constant,
+ * a copy of a prototype or a new instance.
+ * 
+ * @since Commons Collections 2.1
+ * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (jeu., 10 avr. 2008) $
+ *
+ * @author Arron Bates
+ * @author Stephen Colebourne
+ */
+public interface Factory {
+
+    /**
+     * Create a new object.
+     *
+     * @return a new object
+     * @throws FunctorException (runtime) if the factory cannot create an object
+     */
+    public Object create();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/FunctorException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/FunctorException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/FunctorException.java	(revision 28000)
@@ -0,0 +1,122 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * Runtime exception thrown from functors.
+ * If required, a root cause error can be wrapped within this one.
+ * 
+ * @since Commons Collections 3.0
+ * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (jeu., 10 avr. 2008) $
+ *
+ * @author Stephen Colebourne
+ */
+@SuppressWarnings("serial")
+public class FunctorException extends RuntimeException {
+    
+    /**
+     * Does JDK support nested exceptions
+     */
+    private static final boolean JDK_SUPPORTS_NESTED;
+    
+    static {
+        boolean flag = false;
+        try {
+            Throwable.class.getDeclaredMethod("getCause", new Class[0]);
+            flag = true;
+        } catch (NoSuchMethodException ex) {
+            flag = false;
+        }
+        JDK_SUPPORTS_NESTED = flag;
+    }
+    
+    /**
+     * Root cause of the exception
+     */
+    private final Throwable rootCause;
+
+    /**
+     * Constructs a new <code>FunctorException</code> without specified
+     * detail message.
+     */
+    public FunctorException() {
+        super();
+        this.rootCause = null;
+    }
+
+    /**
+     * Constructs a new <code>FunctorException</code> with specified
+     * detail message and nested <code>Throwable</code> root cause.
+     *
+     * @param msg        the error message.
+     * @param rootCause  the exception or error that caused this exception
+     *                   to be thrown.
+     */
+    public FunctorException(String msg, Throwable rootCause) {
+        super(msg);
+        this.rootCause = rootCause;
+    }
+
+    /**
+     * Gets the cause of this throwable.
+     * 
+     * @return  the cause of this throwable, or <code>null</code>
+     */
+    public Throwable getCause() {
+        return rootCause;
+    }
+
+    /**
+     * Prints the stack trace of this exception to the standard error stream.
+     */
+    public void printStackTrace() {
+        printStackTrace(System.err);
+    }
+
+    /**
+     * Prints the stack trace of this exception to the specified stream.
+     *
+     * @param out  the <code>PrintStream</code> to use for output
+     */
+    public void printStackTrace(PrintStream out) {
+        synchronized (out) {
+            PrintWriter pw = new PrintWriter(out, false);
+            printStackTrace(pw);
+            // Flush the PrintWriter before it's GC'ed.
+            pw.flush();
+        }
+    }
+
+    /**
+     * Prints the stack trace of this exception to the specified writer.
+     *
+     * @param out  the <code>PrintWriter</code> to use for output
+     */
+    public void printStackTrace(PrintWriter out) {
+        synchronized (out) {
+            super.printStackTrace(out);
+            if (rootCause != null && JDK_SUPPORTS_NESTED == false) {
+                out.print("Caused by: ");
+                rootCause.printStackTrace(out);
+            }
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/MultiHashMap.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/MultiHashMap.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/MultiHashMap.java	(revision 28000)
@@ -0,0 +1,493 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.apache.commons.collections.iterators.EmptyIterator;
+
+/** 
+ * <code>MultiHashMap</code> is the default implementation of the 
+ * {@link org.apache.commons.collections.MultiMap MultiMap} interface.
+ * <p>
+ * A <code>MultiMap</code> is a Map with slightly different semantics.
+ * Putting a value into the map will add the value to a Collection at that key.
+ * Getting a value will return a Collection, holding all the values put to that key.
+ * <p>
+ * This implementation uses an <code>ArrayList</code> as the collection.
+ * The internal storage list is made available without cloning via the
+ * <code>get(Object)</code> and <code>entrySet()</code> methods.
+ * The implementation returns <code>null</code> when there are no values mapped to a key.
+ * <p>
+ * For example:
+ * <pre>
+ * MultiMap mhm = new MultiHashMap();
+ * mhm.put(key, "A");
+ * mhm.put(key, "B");
+ * mhm.put(key, "C");
+ * List list = (List) mhm.get(key);</pre>
+ * <p>
+ * <code>list</code> will be a list containing "A", "B", "C".
+ *
+ * @deprecated Class now available as MultiValueMap in map subpackage.
+ * This version is due to be removed in collections v4.0.
+ *
+ * @since Commons Collections 2.0
+ * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (jeu., 10 avr. 2008) $
+ * 
+ * @author Christopher Berry
+ * @author James Strachan
+ * @author Steve Downey
+ * @author Stephen Colebourne
+ * @author Julien Buret
+ * @author Serhiy Yevtushenko
+ * @author Robert Ribnitz
+ */
+public class MultiHashMap extends HashMap implements MultiMap {
+    
+    // backed values collection
+    private transient Collection values = null;
+    
+    // compatibility with commons-collection releases 2.0/2.1
+    private static final long serialVersionUID = 1943563828307035349L;
+
+    /**
+     * Constructor.
+     */
+    public MultiHashMap() {
+        super();
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param initialCapacity  the initial map capacity
+     */
+    public MultiHashMap(int initialCapacity) {
+        super(initialCapacity);
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param initialCapacity  the initial map capacity
+     * @param loadFactor  the amount 0.0-1.0 at which to resize the map
+     */
+    public MultiHashMap(int initialCapacity, float loadFactor) { // NO_UCD
+        super(initialCapacity, loadFactor);
+    }
+
+    /**
+     * Constructor that copies the input map creating an independent copy.
+     * <p>
+     * This method performs different behaviour depending on whether the map
+     * specified is a MultiMap or not. If a MultiMap is specified, each internal
+     * collection is also cloned. If the specified map only implements Map, then
+     * the values are not cloned.
+     * <p>
+     * NOTE: From Commons Collections 3.1 this method correctly copies a MultiMap
+     * to form a truly independent new map.
+     * NOTE: From Commons Collections 3.2 this method delegates to the newly
+     * added putAll(Map) override method.
+     * 
+     * @param mapToCopy  a Map to copy
+     */
+    public MultiHashMap(Map mapToCopy) {
+        // be careful of JDK 1.3 vs 1.4 differences
+        super((int) (mapToCopy.size() * 1.4f));
+        putAll(mapToCopy);
+    }
+
+    /**
+     * Read the object during deserialization.
+     */
+    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
+        // This method is needed because the 1.2/1.3 Java deserialisation called
+        // put and thus messed up that method
+        
+        // default read object
+        s.defaultReadObject();
+
+        // problem only with jvm <1.4
+        String version = "1.2";
+        try {
+            version = System.getProperty("java.version");
+        } catch (SecurityException ex) {
+            // ignore and treat as 1.2/1.3
+        }
+
+        if (version.startsWith("1.2") || version.startsWith("1.3")) {
+            for (Iterator iterator = entrySet().iterator(); iterator.hasNext();) {
+                Map.Entry entry = (Map.Entry) iterator.next();
+                // put has created a extra collection level, remove it
+                super.put(entry.getKey(), ((Collection) entry.getValue()).iterator().next());
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Gets the total size of the map by counting all the values.
+     * 
+     * @return the total size of the map counting all values
+     * @since Commons Collections 3.1
+     */
+    public int totalSize() {
+        int total = 0;
+        Collection values = super.values();
+        for (Iterator it = values.iterator(); it.hasNext();) {
+            Collection coll = (Collection) it.next();
+            total += coll.size();
+        }
+        return total;
+    }
+
+    /**
+     * Gets the collection mapped to the specified key.
+     * This method is a convenience method to typecast the result of <code>get(key)</code>.
+     * 
+     * @param key  the key to retrieve
+     * @return the collection mapped to the key, null if no mapping
+     * @since Commons Collections 3.1
+     */
+    public Collection getCollection(Object key) {
+        return (Collection) get(key);
+    }
+
+    /**
+     * Gets the size of the collection mapped to the specified key.
+     * 
+     * @param key  the key to get size for
+     * @return the size of the collection at the key, zero if key not in map
+     * @since Commons Collections 3.1
+     */
+    public int size(Object key) {
+        Collection coll = getCollection(key);
+        if (coll == null) {
+            return 0;
+        }
+        return coll.size();
+    }
+
+    /**
+     * Gets an iterator for the collection mapped to the specified key.
+     * 
+     * @param key  the key to get an iterator for
+     * @return the iterator of the collection at the key, empty iterator if key not in map
+     * @since Commons Collections 3.1
+     */
+    public Iterator iterator(Object key) {
+        Collection coll = getCollection(key);
+        if (coll == null) {
+            return EmptyIterator.INSTANCE;
+        }
+        return coll.iterator();
+    }
+
+    /**
+     * Adds the value to the collection associated with the specified key.
+     * <p>
+     * Unlike a normal <code>Map</code> the previous value is not replaced.
+     * Instead the new value is added to the collection stored against the key.
+     *
+     * @param key  the key to store against
+     * @param value  the value to add to the collection at the key
+     * @return the value added if the map changed and null if the map did not change
+     */    
+    public Object put(Object key, Object value) {
+        // NOTE:: put is called during deserialization in JDK < 1.4 !!!!!!
+        //        so we must have a readObject()
+        Collection coll = getCollection(key);
+        if (coll == null) {
+            coll = createCollection(null);
+            super.put(key, coll);
+        }
+        boolean results = coll.add(value);
+        return (results ? value : null);
+    }
+
+    /**
+     * Override superclass to ensure that MultiMap instances are
+     * correctly handled.
+     * <p>
+     * NOTE: Prior to version 3.2, putAll(map) did not work properly
+     * when passed a MultiMap.
+     * 
+     * @param map  the map to copy (either a normal or multi map)
+     */
+    public void putAll(Map map) {
+        if (map instanceof MultiMap) {
+            for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
+                Map.Entry entry = (Map.Entry) it.next();
+                Collection coll = (Collection) entry.getValue();
+                putAll(entry.getKey(), coll);
+            }
+        } else {
+            for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
+                Map.Entry entry = (Map.Entry) it.next();
+                put(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+
+    /**
+     * Adds a collection of values to the collection associated with the specified key.
+     *
+     * @param key  the key to store against
+     * @param values  the values to add to the collection at the key, null ignored
+     * @return true if this map changed
+     * @since Commons Collections 3.1
+     */    
+    public boolean putAll(Object key, Collection values) {
+        if (values == null || values.size() == 0) {
+            return false;
+        }
+        Collection coll = getCollection(key);
+        if (coll == null) {
+            coll = createCollection(values);
+            if (coll.size() == 0) {
+                return false;
+            }
+            super.put(key, coll);
+            return true;
+        } else {
+            return coll.addAll(values);
+        }
+    }
+
+    /**
+     * Checks whether the map contains the value specified.
+     * <p>
+     * This checks all collections against all keys for the value, and thus could be slow.
+     * 
+     * @param value  the value to search for
+     * @return true if the map contains the value
+     */
+    public boolean containsValue(Object value) {
+        Set pairs = super.entrySet();
+
+        if (pairs == null) {
+            return false;
+        }
+        Iterator pairsIterator = pairs.iterator();
+        while (pairsIterator.hasNext()) {
+            Map.Entry keyValuePair = (Map.Entry) pairsIterator.next();
+            Collection coll = (Collection) keyValuePair.getValue();
+            if (coll.contains(value)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks whether the collection at the specified key contains the value.
+     * 
+     * @param value  the value to search for
+     * @return true if the map contains the value
+     * @since Commons Collections 3.1
+     */
+    public boolean containsValue(Object key, Object value) {
+        Collection coll = getCollection(key);
+        if (coll == null) {
+            return false;
+        }
+        return coll.contains(value);
+    }
+
+    /**
+     * Removes a specific value from map.
+     * <p>
+     * The item is removed from the collection mapped to the specified key.
+     * Other values attached to that key are unaffected.
+     * <p>
+     * If the last value for a key is removed, <code>null</code> will be returned
+     * from a subsequant <code>get(key)</code>.
+     * 
+     * @param key  the key to remove from
+     * @param item  the value to remove
+     * @return the value removed (which was passed in), null if nothing removed
+     */
+    public Object remove(Object key, Object item) {
+        Collection valuesForKey = getCollection(key);
+        if (valuesForKey == null) {
+            return null;
+        }
+        boolean removed = valuesForKey.remove(item);
+        if (removed == false) {
+            return null;
+        }
+        // remove the list if it is now empty
+        // (saves space, and allows equals to work)
+        if (valuesForKey.isEmpty()){
+            remove(key);
+        }
+        return item;
+    }
+
+    /**
+     * Clear the map.
+     * <p>
+     * This clears each collection in the map, and so may be slow.
+     */
+    public void clear() {
+        // For gc, clear each list in the map
+        Set pairs = super.entrySet();
+        Iterator pairsIterator = pairs.iterator();
+        while (pairsIterator.hasNext()) {
+            Map.Entry keyValuePair = (Map.Entry) pairsIterator.next();
+            Collection coll = (Collection) keyValuePair.getValue();
+            coll.clear();
+        }
+        super.clear();
+    }
+
+    /**
+     * Gets a collection containing all the values in the map.
+     * <p>
+     * This returns a collection containing the combination of values from all keys.
+     *
+     * @return a collection view of the values contained in this map
+     */
+    public Collection values() {
+        Collection vs = values;
+        return (vs != null ? vs : (values = new Values()));
+    }
+
+    /**
+     * Gets the values iterator from the superclass, as used by inner class.
+     *
+     * @return iterator
+     */
+    Iterator superValuesIterator() {
+        return super.values().iterator();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Inner class to view the elements.
+     */
+    private class Values extends AbstractCollection {
+
+        public Iterator iterator() {
+            return new ValueIterator();
+        }
+
+        public int size() {
+            int compt = 0;
+            Iterator it = iterator();
+            while (it.hasNext()) {
+                it.next();
+                compt++;
+            }
+            return compt;
+        }
+
+        public void clear() {
+            MultiHashMap.this.clear();
+        }
+
+    }
+
+    /**
+     * Inner iterator to view the elements.
+     */
+    private class ValueIterator implements Iterator {
+        private Iterator backedIterator;
+        private Iterator tempIterator;
+
+        private ValueIterator() {
+            backedIterator = MultiHashMap.this.superValuesIterator();
+        }
+
+        private boolean searchNextIterator() {
+            while (tempIterator == null || tempIterator.hasNext() == false) {
+                if (backedIterator.hasNext() == false) {
+                    return false;
+                }
+                tempIterator = ((Collection) backedIterator.next()).iterator();
+            }
+            return true;
+        }
+
+        public boolean hasNext() {
+            return searchNextIterator();
+        }
+
+        public Object next() {
+            if (searchNextIterator() == false) {
+                throw new NoSuchElementException();
+            }
+            return tempIterator.next();
+        }
+
+        public void remove() {
+            if (tempIterator == null) {
+                throw new IllegalStateException();
+            }
+            tempIterator.remove();
+        }
+
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Clones the map creating an independent copy.
+     * <p>
+     * The clone will shallow clone the collections as well as the map.
+     * 
+     * @return the cloned map
+     */
+    public Object clone() {
+        MultiHashMap cloned = (MultiHashMap) super.clone();
+
+        // clone each Collection container
+        for (Iterator it = cloned.entrySet().iterator(); it.hasNext();) {
+            Map.Entry entry = (Map.Entry) it.next();
+            Collection coll = (Collection) entry.getValue();
+            Collection newColl = createCollection(coll);
+            entry.setValue(newColl);
+        }
+        return cloned;
+    }
+
+    /** 
+     * Creates a new instance of the map value Collection container.
+     * <p>
+     * This method can be overridden to use your own collection type.
+     *
+     * @param coll  the collection to copy, may be null
+     * @return the new collection
+     */
+    protected Collection createCollection(Collection coll) {
+        if (coll == null) {
+            return new ArrayList();
+        } else {
+            return new ArrayList(coll);
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/MultiMap.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/MultiMap.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/MultiMap.java	(revision 28000)
@@ -0,0 +1,160 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections;
+
+import java.util.Collection;
+import java.util.Map;
+
+/** 
+ * Defines a map that holds a collection of values against each key.
+ * <p>
+ * A <code>MultiMap</code> is a Map with slightly different semantics.
+ * Putting a value into the map will add the value to a Collection at that key.
+ * Getting a value will return a Collection, holding all the values put to that key.
+ * <p>
+ * For example:
+ * <pre>
+ * MultiMap mhm = new MultiHashMap();
+ * mhm.put(key, "A");
+ * mhm.put(key, "B");
+ * mhm.put(key, "C");
+ * Collection coll = (Collection) mhm.get(key);</pre>
+ * <p>
+ * <code>coll</code> will be a collection containing "A", "B", "C".
+ * <p>
+ * NOTE: Additional methods were added to this interface in Commons Collections 3.1.
+ * These were added solely for documentation purposes and do not change the interface
+ * as they were defined in the superinterface <code>Map</code> anyway.
+ *
+ * @since Commons Collections 2.0
+ * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (jeu., 10 avr. 2008) $
+ * 
+ * @author Christopher Berry
+ * @author James Strachan
+ * @author Stephen Colebourne
+ */
+public interface MultiMap extends Map {
+
+    /**
+     * Removes a specific value from map.
+     * <p>
+     * The item is removed from the collection mapped to the specified key.
+     * Other values attached to that key are unaffected.
+     * <p>
+     * If the last value for a key is removed, implementations typically
+     * return <code>null</code> from a subsequant <code>get(Object)</code>, however
+     * they may choose to return an empty collection.
+     * 
+     * @param key  the key to remove from
+     * @param item  the item to remove
+     * @return the value removed (which was passed in), null if nothing removed
+     * @throws UnsupportedOperationException if the map is unmodifiable
+     * @throws ClassCastException if the key or value is of an invalid type
+     * @throws NullPointerException if the key or value is null and null is invalid
+     */
+    public Object remove(Object key, Object item); // NO_UCD
+
+    //-----------------------------------------------------------------------
+    /**
+     * Gets the number of keys in this map.
+     * <p>
+     * Implementations typically return only the count of keys in the map
+     * This cannot be mandated due to backwards compatability of this interface.
+     *
+     * @return the number of key-collection mappings in this map
+     */
+    int size();
+
+    /**
+     * Gets the collection of values associated with the specified key.
+     * <p>
+     * The returned value will implement <code>Collection</code>. Implementations
+     * are free to declare that they return <code>Collection</code> subclasses
+     * such as <code>List</code> or <code>Set</code>.
+     * <p>
+     * Implementations typically return <code>null</code> if no values have
+     * been mapped to the key, however the implementation may choose to
+     * return an empty collection.
+     * <p>
+     * Implementations may choose to return a clone of the internal collection.
+     *
+     * @param key  the key to retrieve
+     * @return the <code>Collection</code> of values, implementations should
+     *  return <code>null</code> for no mapping, but may return an empty collection
+     * @throws ClassCastException if the key is of an invalid type
+     * @throws NullPointerException if the key is null and null keys are invalid
+     */
+    Object get(Object key);
+
+    /**
+     * Checks whether the map contains the value specified.
+     * <p>
+     * Implementations typically check all collections against all keys for the value.
+     * This cannot be mandated due to backwards compatability of this interface.
+     *
+     * @param value  the value to search for
+     * @return true if the map contains the value
+     * @throws ClassCastException if the value is of an invalid type
+     * @throws NullPointerException if the value is null and null value are invalid
+     */
+    boolean containsValue(Object value);
+
+    /**
+     * Adds the value to the collection associated with the specified key.
+     * <p>
+     * Unlike a normal <code>Map</code> the previous value is not replaced.
+     * Instead the new value is added to the collection stored against the key.
+     * The collection may be a <code>List</code>, <code>Set</code> or other
+     * collection dependent on implementation.
+     *
+     * @param key  the key to store against
+     * @param value  the value to add to the collection at the key
+     * @return typically the value added if the map changed and null if the map did not change
+     * @throws UnsupportedOperationException if the map is unmodifiable
+     * @throws ClassCastException if the key or value is of an invalid type
+     * @throws NullPointerException if the key or value is null and null is invalid
+     * @throws IllegalArgumentException if the key or value is invalid
+     */
+    Object put(Object key, Object value);
+
+    /**
+     * Removes all values associated with the specified key.
+     * <p>
+     * Implementations typically return <code>null</code> from a subsequant
+     * <code>get(Object)</code>, however they may choose to return an empty collection.
+     *
+     * @param key  the key to remove values from
+     * @return the <code>Collection</code> of values removed, implementations should
+     *  return <code>null</code> for no mapping found, but may return an empty collection
+     * @throws UnsupportedOperationException if the map is unmodifiable
+     * @throws ClassCastException if the key is of an invalid type
+     * @throws NullPointerException if the key is null and null keys are invalid
+     */
+    Object remove(Object key);
+
+    /**
+     * Gets a collection containing all the values in the map.
+     * <p>
+     * Inplementations typically return a collection containing the combination
+     * of values from all keys.
+     * This cannot be mandated due to backwards compatability of this interface.
+     *
+     * @return a collection view of the values contained in this map
+     */
+    Collection values();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/ResettableIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/ResettableIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/ResettableIterator.java	(revision 28000)
@@ -0,0 +1,33 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections;
+
+import java.util.Iterator;
+
+/** 
+ * Defines an iterator that can be reset back to an initial state.
+ * <p>
+ * This interface allows an iterator to be repeatedly reused.
+ *
+ * @since Commons Collections 3.0
+ * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (jeu., 10 avr. 2008) $
+ * 
+ * @author Stephen Colebourne
+ */
+public interface ResettableIterator extends Iterator {
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/Transformer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/Transformer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/Transformer.java	(revision 28000)
@@ -0,0 +1,51 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections;
+
+/**
+ * Defines a functor interface implemented by classes that transform one
+ * object into another.
+ * <p>
+ * A <code>Transformer</code> converts the input object to the output object.
+ * The input object should be left unchanged.
+ * Transformers are typically used for type conversions, or extracting data
+ * from an object.
+ * <p>
+ * Standard implementations of common transformers are provided by
+ * {@link TransformerUtils}. These include method invokation, returning a constant,
+ * cloning and returning the string value.
+ * 
+ * @since Commons Collections 1.0
+ * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (jeu., 10 avr. 2008) $
+ * 
+ * @author James Strachan
+ * @author Stephen Colebourne
+ */
+public interface Transformer {
+
+    /**
+     * Transforms the input object (leaving it unchanged) into some output object.
+     *
+     * @param input  the object to be transformed, should be left unchanged
+     * @return a transformed object
+     * @throws ClassCastException (runtime) if the input is the wrong class
+     * @throws IllegalArgumentException (runtime) if the input is invalid
+     * @throws FunctorException (runtime) if the transform cannot be completed
+     */
+    public Object transform(Object input);
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/TransformerUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/TransformerUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/TransformerUtils.java	(revision 28000)
@@ -0,0 +1,63 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections;
+
+import org.apache.commons.collections.functors.NOPTransformer;
+
+/**
+ * <code>TransformerUtils</code> provides reference implementations and 
+ * utilities for the Transformer functor interface. The supplied transformers are:
+ * <ul>
+ * <li>Invoker - returns the result of a method call on the input object
+ * <li>Clone - returns a clone of the input object
+ * <li>Constant - always returns the same object
+ * <li>Closure - performs a Closure and returns the input object
+ * <li>Predicate - returns the result of the predicate as a Boolean
+ * <li>Factory - returns a new object from a factory
+ * <li>Chained - chains two or more transformers together
+ * <li>Switch - calls one transformer based on one or more predicates
+ * <li>SwitchMap - calls one transformer looked up from a Map
+ * <li>Instantiate - the Class input object is instantiated
+ * <li>Map - returns an object from a supplied Map
+ * <li>Null - always returns null
+ * <li>NOP - returns the input object, which should be immutable
+ * <li>Exception - always throws an exception
+ * <li>StringValue - returns a <code>java.lang.String</code> representation of the input object
+ * </ul>
+ * All the supplied transformers are Serializable.
+ *
+ * @since Commons Collections 3.0
+ * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (jeu., 10 avr. 2008) $
+ * 
+ * @author Stephen Colebourne
+ * @author James Carman
+ */
+public class TransformerUtils {
+
+    /**
+     * Gets a transformer that returns the input object.
+     * The input object should be immutable to maintain the
+     * contract of Transformer (although this is not checked).
+     * 
+     * @see org.apache.commons.collections.functors.NOPTransformer
+     * 
+     * @return the transformer
+     */
+    public static Transformer nopTransformer() {
+        return NOPTransformer.INSTANCE;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/functors/NOPTransformer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/functors/NOPTransformer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/functors/NOPTransformer.java	(revision 28000)
@@ -0,0 +1,56 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections.functors;
+
+import java.io.Serializable;
+
+import org.apache.commons.collections.Transformer;
+
+/**
+ * Transformer implementation that does nothing.
+ * 
+ * @since Commons Collections 3.0
+ * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (jeu., 10 avr. 2008) $
+ *
+ * @author Stephen Colebourne
+ */
+public class NOPTransformer implements Transformer, Serializable {
+
+    /** Serial version UID */
+    private static final long serialVersionUID = 2133891748318574490L;
+
+    /** Singleton predicate instance */
+    public static final Transformer INSTANCE = new NOPTransformer();
+
+    /**
+     * Constructor
+     */
+    private NOPTransformer() {
+        super();
+    }
+
+    /**
+     * Transforms the input to result by doing nothing.
+     * 
+     * @param input  the input object to transform
+     * @return the transformed result which is the input
+     */
+    public Object transform(Object input) {
+        return input;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/functors/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/functors/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/functors/package.html	(revision 28000)
@@ -0,0 +1,27 @@
+<!-- $Id: package.html 646777 2008-04-10 12:33:15Z niallp $ -->
+ <!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+  -->
+<BODY>
+<p>
+This package contains implementations of the
+{@link org.apache.commons.collections.Closure Closure},
+{@link org.apache.commons.collections.Predicate Predicate},
+{@link org.apache.commons.collections.Transformer Transformer} and
+{@link org.apache.commons.collections.Factory Factory} interfaces.
+These provide simple callbacks for processing with collections.
+</p>
+</BODY>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/iterators/AbstractEmptyIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/iterators/AbstractEmptyIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/iterators/AbstractEmptyIterator.java	(revision 28000)
@@ -0,0 +1,95 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections.iterators;
+
+import java.util.NoSuchElementException;
+
+import org.apache.commons.collections.ResettableIterator;
+
+/** 
+ * Provides an implementation of an empty iterator.
+ *
+ * @since Commons Collections 3.1
+ * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (jeu., 10 avr. 2008) $
+ * 
+ * @author Stephen Colebourne
+ */
+abstract class AbstractEmptyIterator implements ResettableIterator {
+ 
+    /**
+     * Constructor.
+     */
+    protected AbstractEmptyIterator() {
+        super();
+    }
+
+    public boolean hasNext() {
+        return false;
+    }
+
+    public Object next() {
+        throw new NoSuchElementException("Iterator contains no elements");
+    }
+
+    public boolean hasPrevious() {
+        return false;
+    }
+
+    public Object previous() {
+        throw new NoSuchElementException("Iterator contains no elements");
+    }
+
+    public int nextIndex() {
+        return 0;
+    }
+
+    public int previousIndex() {
+        return -1;
+    }
+
+    @SuppressWarnings("unused")
+	public void add(Object obj) {
+        throw new UnsupportedOperationException("add() not supported for empty Iterator");
+    }
+
+    @SuppressWarnings("unused")
+	public void set(Object obj) {
+        throw new IllegalStateException("Iterator contains no elements");
+    }
+
+    public void remove() {
+        throw new IllegalStateException("Iterator contains no elements");
+    }
+
+    public Object getKey() {
+        throw new IllegalStateException("Iterator contains no elements");
+    }
+
+    public Object getValue() {
+        throw new IllegalStateException("Iterator contains no elements");
+    }
+
+    @SuppressWarnings("unused")
+	public Object setValue(Object value) {
+        throw new IllegalStateException("Iterator contains no elements");
+    }
+
+    public void reset() {
+        // do nothing
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/iterators/EmptyIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/iterators/EmptyIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/iterators/EmptyIterator.java	(revision 28000)
@@ -0,0 +1,55 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections.iterators;
+
+import java.util.Iterator;
+
+import org.apache.commons.collections.ResettableIterator;
+
+/** 
+ * Provides an implementation of an empty iterator.
+ * <p>
+ * This class provides an implementation of an empty iterator.
+ * This class provides for binary compatability between Commons Collections
+ * 2.1.1 and 3.1 due to issues with <code>IteratorUtils</code>.
+ *
+ * @since Commons Collections 2.1.1 and 3.1
+ * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (jeu., 10 avr. 2008) $
+ * 
+ * @author Stephen Colebourne
+ */
+public class EmptyIterator extends AbstractEmptyIterator /*implements ResettableIterator*/ {
+
+    /**
+     * Singleton instance of the iterator.
+     * @since Commons Collections 3.1
+     */
+    public static final ResettableIterator RESETTABLE_INSTANCE = new EmptyIterator();
+    /**
+     * Singleton instance of the iterator.
+     * @since Commons Collections 2.1.1 and 3.1
+     */
+    public static final Iterator INSTANCE = RESETTABLE_INSTANCE;
+
+    /**
+     * Constructor.
+     */
+    protected EmptyIterator() {
+        super();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/iterators/IteratorChain.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/iterators/IteratorChain.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/iterators/IteratorChain.java	(revision 28000)
@@ -0,0 +1,186 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections.iterators;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * An IteratorChain is an Iterator that wraps a number of Iterators.
+ * <p>
+ * This class makes multiple iterators look like one to the caller
+ * When any method from the Iterator interface is called, the IteratorChain
+ * will delegate to a single underlying Iterator. The IteratorChain will
+ * invoke the Iterators in sequence until all Iterators are exhausted.
+ * <p>
+ * Under many circumstances, linking Iterators together in this manner is
+ * more efficient (and convenient) than reading out the contents of each
+ * Iterator into a List and creating a new Iterator.
+ * <p>
+ * Calling a method that adds new Iterator<i>after a method in the Iterator
+ * interface has been called</i> will result in an UnsupportedOperationException.
+ * Subclasses should <i>take care</i> to not alter the underlying List of Iterators.
+ * <p>
+ * NOTE: As from version 3.0, the IteratorChain may contain no
+ * iterators. In this case the class will function as an empty iterator.
+ *
+ * @since Commons Collections 2.1
+ * @version $Revision: 647116 $ $Date: 2008-04-11 13:23:08 +0200 (ven., 11 avr. 2008) $
+ *
+ * @author Morgan Delagrange
+ * @author Stephen Colebourne
+ */
+public class IteratorChain implements Iterator {
+
+    /** The chain of iterators */
+    protected final List iteratorChain = new ArrayList();
+    /** The index of the current iterator */
+    protected int currentIteratorIndex = 0;
+    /** The current iterator */
+    protected Iterator currentIterator = null;
+    /**
+     * The "last used" Iterator is the Iterator upon which
+     * next() or hasNext() was most recently called
+     * used for the remove() operation only
+     */
+    protected Iterator lastUsedIterator = null;
+    /**
+     * ComparatorChain is "locked" after the first time
+     * compare(Object,Object) is called
+     */
+    protected boolean isLocked = false;
+
+    //-----------------------------------------------------------------------
+    /**
+     * Construct an IteratorChain with no Iterators.
+     * <p>
+     * You will normally use {@link #addIterator(Iterator)} to add
+     * some iterators after using this constructor.
+     */
+    public IteratorChain() {
+        super();
+    }
+    
+    //-----------------------------------------------------------------------
+    /**
+     * Add an Iterator to the end of the chain
+     *
+     * @param iterator Iterator to add
+     * @throws IllegalStateException if I've already started iterating
+     * @throws NullPointerException if the iterator is null
+     */
+    public void addIterator(Iterator iterator) {
+        checkLocked();
+        if (iterator == null) {
+            throw new NullPointerException("Iterator must not be null");
+        }
+        iteratorChain.add(iterator);
+    }
+
+    /**
+     * Checks whether the iterator chain is now locked and in use.
+     */
+    private void checkLocked() {
+        if (isLocked == true) {
+            throw new UnsupportedOperationException("IteratorChain cannot be changed after the first use of a method from the Iterator interface");
+        }
+    }
+
+    /**
+     * Lock the chain so no more iterators can be added.
+     * This must be called from all Iterator interface methods.
+     */
+    private void lockChain() {
+        if (isLocked == false) {
+            isLocked = true;
+        }
+    }
+
+    /**
+     * Updates the current iterator field to ensure that the current Iterator
+     * is not exhausted
+     */
+    protected void updateCurrentIterator() {
+        if (currentIterator == null) {
+            if (iteratorChain.isEmpty()) {
+                currentIterator = EmptyIterator.INSTANCE;
+            } else {
+                currentIterator = (Iterator) iteratorChain.get(0);
+            }
+            // set last used iterator here, in case the user calls remove
+            // before calling hasNext() or next() (although they shouldn't)
+            lastUsedIterator = currentIterator;
+        }
+
+        while (currentIterator.hasNext() == false && currentIteratorIndex < iteratorChain.size() - 1) {
+            currentIteratorIndex++;
+            currentIterator = (Iterator) iteratorChain.get(currentIteratorIndex);
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Return true if any Iterator in the IteratorChain has a remaining element.
+     *
+     * @return true if elements remain
+     */
+    public boolean hasNext() {
+        lockChain();
+        updateCurrentIterator();
+        lastUsedIterator = currentIterator;
+
+        return currentIterator.hasNext();
+    }
+
+    /**
+     * Returns the next Object of the current Iterator
+     *
+     * @return Object from the current Iterator
+     * @throws java.util.NoSuchElementException if all the Iterators are exhausted
+     */
+    public Object next() {
+        lockChain();
+        updateCurrentIterator();
+        lastUsedIterator = currentIterator;
+
+        return currentIterator.next();
+    }
+
+    /**
+     * Removes from the underlying collection the last element
+     * returned by the Iterator.  As with next() and hasNext(),
+     * this method calls remove() on the underlying Iterator.
+     * Therefore, this method may throw an
+     * UnsupportedOperationException if the underlying
+     * Iterator does not support this method.
+     *
+     * @throws UnsupportedOperationException
+     *   if the remove operator is not supported by the underlying Iterator
+     * @throws IllegalStateException
+     *   if the next method has not yet been called, or the remove method has
+     *   already been called after the last call to the next method.
+     */
+    public void remove() {
+        lockChain();
+        if (currentIterator == null) {
+            updateCurrentIterator();
+        }
+        lastUsedIterator.remove();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/iterators/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/iterators/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/iterators/package.html	(revision 28000)
@@ -0,0 +1,27 @@
+<!-- $Id: package.html 646777 2008-04-10 12:33:15Z niallp $ -->
+ <!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+  -->
+<body>
+<p>
+This package contains implementations of the
+{@link java.util.Iterator Iterator} interface.
+<p>
+You may also consider using 
+{@link org.apache.commons.collections.IteratorUtils IteratorUtils},
+which is a single class that uses static methods to construct instances
+of the classes in this package.
+</body>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/map/AbstractMapDecorator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/map/AbstractMapDecorator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/map/AbstractMapDecorator.java	(revision 28000)
@@ -0,0 +1,141 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections.map;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Provides a base decorator that enables additional functionality to be added
+ * to a Map via decoration.
+ * <p>
+ * Methods are forwarded directly to the decorated map.
+ * <p>
+ * This implementation does not perform any special processing with
+ * {@link #entrySet()}, {@link #keySet()} or {@link #values()}. Instead
+ * it simply returns the set/collection from the wrapped map. This may be
+ * undesirable, for example if you are trying to write a validating
+ * implementation it would provide a loophole around the validation.
+ * But, you might want that loophole, so this class is kept simple.
+ *
+ * @since Commons Collections 3.0
+ * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (jeu., 10 avr. 2008) $
+ * 
+ * @author Daniel Rall
+ * @author Stephen Colebourne
+ */
+public abstract class AbstractMapDecorator implements Map {
+
+    /** The map to decorate */
+    protected transient Map map;
+
+    /**
+     * Constructor only used in deserialization, do not use otherwise.
+     * @since Commons Collections 3.1
+     */
+    protected AbstractMapDecorator() {
+        super();
+    }
+
+    /**
+     * Constructor that wraps (not copies).
+     *
+     * @param map  the map to decorate, must not be null
+     * @throws IllegalArgumentException if the collection is null
+     */
+    public AbstractMapDecorator(Map map) {
+        if (map == null) {
+            throw new IllegalArgumentException("Map must not be null");
+        }
+        this.map = map;
+    }
+
+    /**
+     * Gets the map being decorated.
+     * 
+     * @return the decorated map
+     */
+    protected Map getMap() {
+        return map;
+    }
+
+    //-----------------------------------------------------------------------
+    public void clear() {
+        map.clear();
+    }
+
+    public boolean containsKey(Object key) {
+        return map.containsKey(key);
+    }
+
+    public boolean containsValue(Object value) {
+        return map.containsValue(value);
+    }
+
+    public Set entrySet() {
+        return map.entrySet();
+    }
+
+    public Object get(Object key) {
+        return map.get(key);
+    }
+
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    public Set keySet() {
+        return map.keySet();
+    }
+
+    public Object put(Object key, Object value) {
+        return map.put(key, value);
+    }
+
+    public void putAll(Map mapToCopy) {
+        map.putAll(mapToCopy);
+    }
+
+    public Object remove(Object key) {
+        return map.remove(key);
+    }
+
+    public int size() {
+        return map.size();
+    }
+
+    public Collection values() {
+        return map.values();
+    }
+   
+    public boolean equals(Object object) {
+        if (object == this) {
+            return true;
+        }
+        return map.equals(object);
+    }
+
+    public int hashCode() {
+        return map.hashCode();
+    }
+
+    public String toString() {
+        return map.toString();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/map/MultiValueMap.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/map/MultiValueMap.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/map/MultiValueMap.java	(revision 28000)
@@ -0,0 +1,440 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.commons.collections.map;
+
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections.Factory;
+import org.apache.commons.collections.FunctorException;
+import org.apache.commons.collections.MultiMap;
+import org.apache.commons.collections.iterators.EmptyIterator;
+import org.apache.commons.collections.iterators.IteratorChain;
+
+/**
+ * A MultiValueMap decorates another map, allowing it to have
+ * more than one value for a key.
+ * <p>
+ * A <code>MultiMap</code> is a Map with slightly different semantics.
+ * Putting a value into the map will add the value to a Collection at that key.
+ * Getting a value will return a Collection, holding all the values put to that key.
+ * <p>
+ * This implementation is a decorator, allowing any Map implementation
+ * to be used as the base.
+ * <p>
+ * In addition, this implementation allows the type of collection used
+ * for the values to be controlled. By default, an <code>ArrayList</code>
+ * is used, however a <code>Class</code> to instantiate may be specified,
+ * or a factory that returns a <code>Collection</code> instance.
+ * <p>
+ * <strong>Note that MultiValueMap is not synchronized and is not thread-safe.</strong>
+ * If you wish to use this map from multiple threads concurrently, you must use
+ * appropriate synchronization. This class may throw exceptions when accessed
+ * by concurrent threads without synchronization.
+ *
+ * @author James Carman
+ * @author Christopher Berry
+ * @author James Strachan
+ * @author Steve Downey
+ * @author Stephen Colebourne
+ * @author Julien Buret
+ * @author Serhiy Yevtushenko
+ * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (jeu., 10 avr. 2008) $
+ * @since Commons Collections 3.2
+ */
+public class MultiValueMap extends AbstractMapDecorator implements MultiMap {
+
+    /** The factory for creating value collections. */
+    private final Factory collectionFactory;
+    /** The cached values. */
+    private transient Collection values;
+
+    /**
+     * Creates a map which wraps the given map and
+     * maps keys to ArrayLists.
+     *
+     * @param map  the map to wrap
+     */
+    public static MultiValueMap decorate(Map map) {
+        return new MultiValueMap(map, new ReflectionFactory(ArrayList.class));
+    }
+
+    /**
+     * Creates a map which decorates the given <code>map</code> and
+     * maps keys to collections of type <code>collectionClass</code>.
+     *
+     * @param map  the map to wrap
+     * @param collectionClass  the type of the collection class
+     */
+    public static MultiValueMap decorate(Map map, Class collectionClass) {
+        return new MultiValueMap(map, new ReflectionFactory(collectionClass));
+    }
+
+    /**
+     * Creates a map which decorates the given <code>map</code> and
+     * creates the value collections using the supplied <code>collectionFactory</code>.
+     *
+     * @param map  the map to decorate
+     * @param collectionFactory  the collection factory (must return a Collection object).
+     */
+    public static MultiValueMap decorate(Map map, Factory collectionFactory) {
+        return new MultiValueMap(map, collectionFactory);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Creates a MultiValueMap based on a <code>HashMap</code> and
+     * storing the multiple values in an <code>ArrayList</code>.
+     */
+    public MultiValueMap() {
+        this(new HashMap(), new ReflectionFactory(ArrayList.class));
+    }
+
+    /**
+     * Creates a MultiValueMap which decorates the given <code>map</code> and
+     * creates the value collections using the supplied <code>collectionFactory</code>.
+     *
+     * @param map  the map to decorate
+     * @param collectionFactory  the collection factory which must return a Collection instance
+     */
+    protected MultiValueMap(Map map, Factory collectionFactory) {
+        super(map);
+        if (collectionFactory == null) {
+            throw new IllegalArgumentException("The factory must not be null");
+        }
+        this.collectionFactory = collectionFactory;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Clear the map.
+     */
+    public void clear() {
+        // If you believe that you have GC issues here, try uncommenting this code
+//        Set pairs = getMap().entrySet();
+//        Iterator pairsIterator = pairs.iterator();
+//        while (pairsIterator.hasNext()) {
+//            Map.Entry keyValuePair = (Map.Entry) pairsIterator.next();
+//            Collection coll = (Collection) keyValuePair.getValue();
+//            coll.clear();
+//        }
+        getMap().clear();
+    }
+
+    /**
+     * Removes a specific value from map.
+     * <p>
+     * The item is removed from the collection mapped to the specified key.
+     * Other values attached to that key are unaffected.
+     * <p>
+     * If the last value for a key is removed, <code>null</code> will be returned
+     * from a subsequant <code>get(key)</code>.
+     *
+     * @param key  the key to remove from
+     * @param value the value to remove
+     * @return the value removed (which was passed in), null if nothing removed
+     */
+    public Object remove(Object key, Object value) {
+        Collection valuesForKey = getCollection(key);
+        if (valuesForKey == null) {
+            return null;
+        }
+        boolean removed = valuesForKey.remove(value);
+        if (removed == false) {
+            return null;
+        }
+        if (valuesForKey.isEmpty()) {
+            remove(key);
+        }
+        return value;
+    }
+
+    /**
+     * Checks whether the map contains the value specified.
+     * <p>
+     * This checks all collections against all keys for the value, and thus could be slow.
+     *
+     * @param value  the value to search for
+     * @return true if the map contains the value
+     */
+    public boolean containsValue(Object value) {
+        Set pairs = getMap().entrySet();
+        if (pairs == null) {
+            return false;
+        }
+        Iterator pairsIterator = pairs.iterator();
+        while (pairsIterator.hasNext()) {
+            Map.Entry keyValuePair = (Map.Entry) pairsIterator.next();
+            Collection coll = (Collection) keyValuePair.getValue();
+            if (coll.contains(value)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Adds the value to the collection associated with the specified key.
+     * <p>
+     * Unlike a normal <code>Map</code> the previous value is not replaced.
+     * Instead the new value is added to the collection stored against the key.
+     *
+     * @param key  the key to store against
+     * @param value  the value to add to the collection at the key
+     * @return the value added if the map changed and null if the map did not change
+     */
+    public Object put(Object key, Object value) {
+        boolean result = false;
+        Collection coll = getCollection(key);
+        if (coll == null) {
+            coll = createCollection();
+            result = coll.add(value);
+            if (coll.size() > 0) {
+                // only add if non-zero size to maintain class state
+                getMap().put(key, coll);
+                result = false;
+            }
+        } else {
+            result = coll.add(value);
+        }
+        return (result ? value : null);
+    }
+
+    /**
+     * Override superclass to ensure that MultiMap instances are
+     * correctly handled.
+     * <p>
+     * If you call this method with a normal map, each entry is
+     * added using <code>put(Object,Object)</code>.
+     * If you call this method with a multi map, each entry is
+     * added using <code>putAll(Object,Collection)</code>.
+     *
+     * @param map  the map to copy (either a normal or multi map)
+     */
+    public void putAll(Map map) {
+        if (map instanceof MultiMap) {
+            for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
+                Map.Entry entry = (Map.Entry) it.next();
+                Collection coll = (Collection) entry.getValue();
+                putAll(entry.getKey(), coll);
+            }
+        } else {
+            for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
+                Map.Entry entry = (Map.Entry) it.next();
+                put(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+
+    /**
+     * Gets a collection containing all the values in the map.
+     * <p>
+     * This returns a collection containing the combination of values from all keys.
+     *
+     * @return a collection view of the values contained in this map
+     */
+    public Collection values() {
+        Collection vs = values;
+        return (vs != null ? vs : (values = new Values()));
+    }
+
+    /**
+     * Checks whether the collection at the specified key contains the value.
+     *
+     * @param value  the value to search for
+     * @return true if the map contains the value
+     */
+    public boolean containsValue(Object key, Object value) {
+        Collection coll = getCollection(key);
+        if (coll == null) {
+            return false;
+        }
+        return coll.contains(value);
+    }
+
+    /**
+     * Gets the collection mapped to the specified key.
+     * This method is a convenience method to typecast the result of <code>get(key)</code>.
+     *
+     * @param key  the key to retrieve
+     * @return the collection mapped to the key, null if no mapping
+     */
+    public Collection getCollection(Object key) {
+        return (Collection) getMap().get(key);
+    }
+
+    /**
+     * Gets the size of the collection mapped to the specified key.
+     *
+     * @param key  the key to get size for
+     * @return the size of the collection at the key, zero if key not in map
+     */
+    public int size(Object key) {
+        Collection coll = getCollection(key);
+        if (coll == null) {
+            return 0;
+        }
+        return coll.size();
+    }
+
+    /**
+     * Adds a collection of values to the collection associated with
+     * the specified key.
+     *
+     * @param key  the key to store against
+     * @param values  the values to add to the collection at the key, null ignored
+     * @return true if this map changed
+     */
+    public boolean putAll(Object key, Collection values) {
+        if (values == null || values.size() == 0) {
+            return false;
+        }
+        Collection coll = getCollection(key);
+        if (coll == null) {
+            coll = createCollection();
+            boolean result = coll.addAll(values);
+            if (coll.size() > 0) {
+                // only add if non-zero size to maintain class state
+                getMap().put(key, coll);
+                result = false;
+            }
+            return result;
+        } else {
+            return coll.addAll(values);
+        }
+    }
+
+    /**
+     * Gets an iterator for the collection mapped to the specified key.
+     *
+     * @param key  the key to get an iterator for
+     * @return the iterator of the collection at the key, empty iterator if key not in map
+     */
+    public Iterator iterator(Object key) {
+        if (!containsKey(key)) {
+            return EmptyIterator.INSTANCE;
+        } else {
+            return new ValuesIterator(key);
+        }
+    }
+
+    /**
+     * Gets the total size of the map by counting all the values.
+     *
+     * @return the total size of the map counting all values
+     */
+    public int totalSize() {
+        int total = 0;
+        Collection values = getMap().values();
+        for (Iterator it = values.iterator(); it.hasNext();) {
+            Collection coll = (Collection) it.next();
+            total += coll.size();
+        }
+        return total;
+    }
+
+    /**
+     * Creates a new instance of the map value Collection container
+     * using the factory.
+     * <p>
+     * This method can be overridden to perform your own processing
+     * instead of using the factory.
+     *
+     * @param size  the collection size that is about to be added
+     * @return the new collection
+     */
+    protected Collection createCollection() {
+        return (Collection) collectionFactory.create();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Inner class that provides the values view.
+     */
+    private class Values extends AbstractCollection {
+        public Iterator iterator() {
+            final IteratorChain chain = new IteratorChain();
+            for (Iterator it = keySet().iterator(); it.hasNext();) {
+                chain.addIterator(new ValuesIterator(it.next()));
+            }
+            return chain;
+        }
+
+        public int size() {
+            return totalSize();
+        }
+
+        public void clear() {
+            MultiValueMap.this.clear();
+        }
+    }
+
+    /**
+     * Inner class that provides the values iterator.
+     */
+    private class ValuesIterator implements Iterator {
+        private final Object key;
+        private final Collection values;
+        private final Iterator iterator;
+
+        public ValuesIterator(Object key) {
+            this.key = key;
+            this.values = getCollection(key);
+            this.iterator = values.iterator();
+        }
+
+        public void remove() {
+            iterator.remove();
+            if (values.isEmpty()) {
+                MultiValueMap.this.remove(key);
+            }
+        }
+
+        public boolean hasNext() {
+            return iterator.hasNext();
+        }
+
+        public Object next() {
+            return iterator.next();
+        }
+    }
+
+    /**
+     * Inner class that provides a simple reflection factory.
+     */
+    private static class ReflectionFactory implements Factory {
+        private final Class clazz;
+
+        public ReflectionFactory(Class clazz) {
+            this.clazz = clazz;
+        }
+
+        public Object create() {
+            try {
+                return clazz.newInstance();
+            } catch (Exception ex) {
+                throw new FunctorException("Cannot instantiate class: " + clazz, ex);
+            }
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/map/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/map/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/map/package.html	(revision 28000)
@@ -0,0 +1,55 @@
+<!-- $Id: package.html 646777 2008-04-10 12:33:15Z niallp $ -->
+ <!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+  -->
+<BODY>
+<p>
+This package contains implementations of the 
+{@link java.util.Map Map},
+{@link org.apache.commons.collections.IterableMap IterableMap},
+{@link org.apache.commons.collections.OrderedMap OrderedMap} and
+{@link java.util.SortedMap SortedMap} interfaces.
+A Map provides a lookup from a key to a value.
+A number of implementations also support the new MapIterator interface that enables
+simple iteration of map keys and values.
+<p>
+The following implementations are provided:
+<ul>
+<li>CaseInsensitiveMap - map that compares keys in a case insensitive way
+<li>CompositeMap - map that combines multiple maps into a single view
+<li>HashedMap - general purpose HashMap replacement supporting MapIterator
+<li>IdentityMap - map that uses == for comparison instead of equals()
+<li>Flat3Map - designed for good performance at size 3 or less
+<li>LinkedMap - a hash map that maintains insertion order, supporting OrderedMapIterator
+<li>MultiKeyMap - map that provides special methods for using more than one key to access the value
+<li>ReferenceMap - allows the garbage collector to collect keys and values using equals() for comparison
+<li>ReferenceIdentityMap - allows the garbage collector to collect keys and values using == for comparison
+<li>SingletonMap - a fully featured map to hold one key-value pair
+<li>StaticBucketMap - internally synchronized and designed for thread-contentious environments
+</ul>
+<p>
+The following decorators are provided:
+<ul>
+<li>Unmodifiable - ensures the collection cannot be altered
+<li>Predicated - ensures that only elements that are valid according to a predicate can be added
+<li>Typed - ensures that only elements that are of a specific type can be added
+<li>Transformed - transforms each element added
+<li>FixedSize - ensures that the size of the map cannot change
+<li>Lazy - creates objects in the map on demand
+<li>ListOrdered - ensures that insertion order is retained
+</ul>
+</pre>
+</BODY>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/overview.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/overview.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/overview.html	(revision 28000)
@@ -0,0 +1,113 @@
+<!-- $Id: overview.html 646777 2008-04-10 12:33:15Z niallp $ -->
+ <!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+  -->
+<body>
+  <p>
+     Commons-Collections contains implementations, enhancements and utilities
+     that complement the Java Collections Framework.
+  </p>
+  <p>
+     The Apache Jakarta Commons Collections Framework component adds a significant
+     amount of enhancements to the standard JDK collections. These enhancements
+     come in the form of new interfaces, new implementations and utility classes.
+  </p>
+  <p>
+     See also the <code>java.util</code> package for the standard Java collections.
+  </p>
+     
+  <h4>Main features</h4>
+  <p>
+     Commons-Collections defines a number of key interfaces:
+  </p>
+  <table border="1" cellspacing="0" cellpadding="3">
+  <tr bgcolor="#CCCCFF" class="TableHeadingColor">
+    <th>Interface</th><th>Description</th>
+  </tr>
+  <tr>
+    <td>
+      {@link org.apache.commons.collections.Bag}
+    </td>
+    <td valign="top">
+      A new <code>Collection</code> subinterface that stores each object together
+      with the number of occurances. Methods are provided to get the number of
+      occurances, and to add and remove a certain number of that object.
+    </td>
+  </tr>
+  <tr>
+    <td>
+      {@link org.apache.commons.collections.Buffer}
+    </td>
+    <td valign="top">
+      A new <code>Collection</code> subinterface that allows objects to be removed
+      in some well-defined order. Methods enable the next item to be peeked and removed.
+    </td>
+  </tr>
+  <tr>
+    <td>
+      {@link org.apache.commons.collections.BidiMap}
+    </td>
+    <td valign="top">
+      A new <code>Map</code> subinterface that allows lookup from key to value and
+      from value to key with equal ease.
+    </td>
+  </tr>
+  <tr>
+    <td>
+      {@link org.apache.commons.collections.OrderedMap}
+    </td>
+    <td valign="top">
+      A new <code>Map</code> subinterface that is used when a map has an order, but is
+      not sorted. Methods enable bidriectional iteration through the map.
+    </td>
+  </tr>
+  <tr>
+    <td>
+      {@link org.apache.commons.collections.MapIterator}
+    </td>
+    <td valign="top">
+      A new <code>Iterator</code> subinterface specially designed for maps. This iterator
+      avoids the need for entrySet iteration of a map, and is simpler to use.
+    </td>
+  </tr>
+  <tr>
+    <td>
+      {@link org.apache.commons.collections.ResettableIterator}
+    </td>
+    <td valign="top">
+      A new <code>Iterator</code> subinterface that allows the iteration to be reset back
+      to the start. Many iterators in this library have this functionality.
+    </td>
+  </tr>
+  <tr>
+    <td>
+      {@link org.apache.commons.collections.Closure}<br />
+      {@link org.apache.commons.collections.Predicate}<br />
+      {@link org.apache.commons.collections.Transformer}<br />
+      {@link org.apache.commons.collections.Factory}<br />
+    </td>
+    <td valign="top">
+      A group of <i>functor</i> interfaces that provide plugin behaviour to various
+      collections and utilities.
+    </td>
+  </tr>
+  </table>
+  <p>
+     In addition to the interfaces, there are many implementations.
+     Consult each subpackage for full details of these.
+  </p>
+     
+</body>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/collections/package.html	(revision 28000)
@@ -0,0 +1,30 @@
+<!-- $Id: package.html 646777 2008-04-10 12:33:15Z niallp $ -->
+ <!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+  -->
+<body>
+<p>
+This package contains the interfaces and utilities shared across all the subpackages of this component.
+</p>
+<p>
+The following collection implementations are provided in the package:
+<ul>
+<li>ArrayStack - a non synchronized Stack that follows the same API as java util Stack
+<li>ExtendedProperties - extends the Properties class to add extra functionality
+</ul>
+<p>
+
+</body>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/ArrayUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/ArrayUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/ArrayUtils.java	(revision 28000)
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.commons.lang3;
+
+
+/**
+ * <p>Operations on arrays, primitive arrays (like {@code int[]}) and
+ * primitive wrapper arrays (like {@code Integer[]}).</p>
+ *
+ * <p>This class tries to handle {@code null} input gracefully.
+ * An exception will not be thrown for a {@code null}
+ * array input. However, an Object array that contains a {@code null}
+ * element may throw an exception. Each method documents its behaviour.</p>
+ *
+ * <p>#ThreadSafe#</p>
+ * @since 2.0
+ * @version $Id: ArrayUtils.java 1154216 2011-08-05 13:57:16Z mbenson $
+ */
+public class ArrayUtils {
+
+    /**
+     * <p>ArrayUtils instances should NOT be constructed in standard programming.
+     * Instead, the class should be used as <code>ArrayUtils.clone(new int[] {2})</code>.</p>
+     *
+     * <p>This constructor is public to permit tools that require a JavaBean instance
+     * to operate.</p>
+     */
+    public ArrayUtils() {
+      super();
+    }
+
+
+    // NOTE: Cannot use {@code} to enclose text which includes {}, but <code></code> is OK
+
+
+    // ----------------------------------------------------------------------
+    /**
+     * <p>Checks if an array of Objects is empty or {@code null}.</p>
+     *
+     * @param array  the array to test
+     * @return {@code true} if the array is empty or {@code null}
+     * @since 2.1
+     */
+    public static boolean isEmpty(Object[] array) {
+        return array == null || array.length == 0;
+    }
+
+
+    /**
+     * <p>Checks if an array of primitive chars is empty or {@code null}.</p>
+     *
+     * @param array  the array to test
+     * @return {@code true} if the array is empty or {@code null}
+     * @since 2.1
+     */
+    public static boolean isEmpty(char[] array) {
+        return array == null || array.length == 0;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/CharSequenceUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/CharSequenceUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/CharSequenceUtils.java	(revision 28000)
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.commons.lang3;
+
+/**
+ * <p>Operations on {@link java.lang.CharSequence} that are
+ * {@code null} safe.</p>
+ *
+ * @see java.lang.CharSequence
+ * @since 3.0
+ * @version $Id: CharSequenceUtils.java 1199894 2011-11-09 17:53:59Z ggregory $
+ */
+public class CharSequenceUtils {
+
+    /**
+     * <p>{@code CharSequenceUtils} instances should NOT be constructed in
+     * standard programming. </p>
+     *
+     * <p>This constructor is public to permit tools that require a JavaBean
+     * instance to operate.</p>
+     */
+    public CharSequenceUtils() {
+        super();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Finds the first index in the {@code CharSequence} that matches the
+     * specified character.</p>
+     *
+     * @param cs  the {@code CharSequence} to be processed, not null
+     * @param searchChar  the char to be searched for
+     * @param start  the start index, negative starts at the string start
+     * @return the index where the search char was found, -1 if not found
+     */
+    static int indexOf(CharSequence cs, int searchChar, int start) {
+        if (cs instanceof String) {
+            return ((String) cs).indexOf(searchChar, start);
+        } else {
+            int sz = cs.length();
+            if (start < 0) {
+                start = 0;
+            }
+            for (int i = start; i < sz; i++) {
+                if (cs.charAt(i) == searchChar) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+    }
+
+    /**
+     * Used by the indexOf(CharSequence methods) as a green implementation of indexOf.
+     *
+     * @param cs the {@code CharSequence} to be processed
+     * @param searchChar the {@code CharSequence} to be searched for
+     * @param start the start index
+     * @return the index where the search sequence was found
+     */
+    static int indexOf(CharSequence cs, CharSequence searchChar, int start) {
+        return cs.toString().indexOf(searchChar.toString(), start);
+//        if (cs instanceof String && searchChar instanceof String) {
+//            // TODO: Do we assume searchChar is usually relatively small;
+//            //       If so then calling toString() on it is better than reverting to
+//            //       the green implementation in the else block
+//            return ((String) cs).indexOf((String) searchChar, start);
+//        } else {
+//            // TODO: Implement rather than convert to String
+//            return cs.toString().indexOf(searchChar.toString(), start);
+//        }
+    }
+
+    /**
+     * <p>Finds the last index in the {@code CharSequence} that matches the
+     * specified character.</p>
+     *
+     * @param cs  the {@code CharSequence} to be processed
+     * @param searchChar  the char to be searched for
+     * @param start  the start index, negative returns -1, beyond length starts at end
+     * @return the index where the search char was found, -1 if not found
+     */
+    static int lastIndexOf(CharSequence cs, int searchChar, int start) {
+        if (cs instanceof String) {
+            return ((String) cs).lastIndexOf(searchChar, start);
+        } else {
+            int sz = cs.length();
+            if (start < 0) {
+                return -1;
+            }
+            if (start >= sz) {
+                start = sz - 1;
+            }
+            for (int i = start; i >= 0; --i) {
+                if (cs.charAt(i) == searchChar) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+    }
+
+    /**
+     * Used by the lastIndexOf(CharSequence methods) as a green implementation of lastIndexOf
+     *
+     * @param cs the {@code CharSequence} to be processed
+     * @param searchChar the {@code CharSequence} to be searched for
+     * @param start the start index
+     * @return the index where the search sequence was found
+     */
+    static int lastIndexOf(CharSequence cs, CharSequence searchChar, int start) {
+        return cs.toString().lastIndexOf(searchChar.toString(), start);
+//        if (cs instanceof String && searchChar instanceof String) {
+//            // TODO: Do we assume searchChar is usually relatively small;
+//            //       If so then calling toString() on it is better than reverting to
+//            //       the green implementation in the else block
+//            return ((String) cs).lastIndexOf((String) searchChar, start);
+//        } else {
+//            // TODO: Implement rather than convert to String
+//            return cs.toString().lastIndexOf(searchChar.toString(), start);
+//        }
+    }
+
+    /**
+     * Green implementation of toCharArray.
+     *
+     * @param cs the {@code CharSequence} to be processed
+     * @return the resulting char array
+     */
+    static char[] toCharArray(CharSequence cs) {
+        if (cs instanceof String) {
+            return ((String) cs).toCharArray();
+        } else {
+            int sz = cs.length();
+            char[] array = new char[cs.length()];
+            for (int i = 0; i < sz; i++) {
+                array[i] = cs.charAt(i);
+            }
+            return array;
+        }
+    }
+
+    /**
+     * Green implementation of regionMatches.
+     *
+     * @param cs the {@code CharSequence} to be processed
+     * @param ignoreCase whether or not to be case insensitive
+     * @param thisStart the index to start on the {@code cs} CharSequence
+     * @param substring the {@code CharSequence} to be looked for
+     * @param start the index to start on the {@code substring} CharSequence
+     * @param length character length of the region
+     * @return whether the region matched
+     */
+    static boolean regionMatches(CharSequence cs, boolean ignoreCase, int thisStart,
+            CharSequence substring, int start, int length)    {
+        if (cs instanceof String && substring instanceof String) {
+            return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length);
+        } else {
+            // TODO: Implement rather than convert to String
+            return cs.toString().regionMatches(ignoreCase, thisStart, substring.toString(), start, length);
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/CharUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/CharUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/CharUtils.java	(revision 28000)
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.commons.lang3;
+
+/**
+ * <p>Operations on char primitives and Character objects.</p>
+ *
+ * <p>This class tries to handle {@code null} input gracefully.
+ * An exception will not be thrown for a {@code null} input.
+ * Each method documents its behaviour in more detail.</p>
+ * 
+ * <p>#ThreadSafe#</p>
+ * @since 2.1
+ * @version $Id: CharUtils.java 1158279 2011-08-16 14:06:45Z ggregory $
+ */
+public class CharUtils {
+    
+    private static final String[] CHAR_STRING_ARRAY = new String[128];
+    
+    /**
+     * {@code \u000a} linefeed LF ('\n').
+     * 
+     * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
+     *      for Character and String Literals</a>
+     * @since 2.2
+     */
+    public static final char LF = '\n';
+
+    /**
+     * {@code \u000d} carriage return CR ('\r').
+     * 
+     * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
+     *      for Character and String Literals</a>
+     * @since 2.2
+     */
+    public static final char CR = '\r';
+    
+
+    static {
+        for (char c = 0; c < CHAR_STRING_ARRAY.length; c++) {
+            CHAR_STRING_ARRAY[c] = String.valueOf(c);
+        }
+    }
+
+    /**
+     * <p>{@code CharUtils} instances should NOT be constructed in standard programming.
+     * Instead, the class should be used as {@code CharUtils.toString('c');}.</p>
+     *
+     * <p>This constructor is public to permit tools that require a JavaBean instance
+     * to operate.</p>
+     */
+    public CharUtils() {
+      super();
+    }
+
+
+    
+    
+    /**
+     * <p>Checks whether the character is ASCII 7 bit printable.</p>
+     *
+     * <pre>
+     *   CharUtils.isAsciiPrintable('a')  = true
+     *   CharUtils.isAsciiPrintable('A')  = true
+     *   CharUtils.isAsciiPrintable('3')  = true
+     *   CharUtils.isAsciiPrintable('-')  = true
+     *   CharUtils.isAsciiPrintable('\n') = false
+     *   CharUtils.isAsciiPrintable('&copy;') = false
+     * </pre>
+     * 
+     * @param ch  the character to check
+     * @return true if between 32 and 126 inclusive
+     */
+    public static boolean isAsciiPrintable(char ch) {
+        return ch >= 32 && ch < 127;
+    }
+    
+        
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/ObjectUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/ObjectUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/ObjectUtils.java	(revision 28000)
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.commons.lang3;
+
+
+/**
+ * <p>Operations on {@code Object}.</p>
+ *
+ * <p>This class tries to handle {@code null} input gracefully.
+ * An exception will generally not be thrown for a {@code null} input.
+ * Each method documents its behaviour in more detail.</p>
+ *
+ * <p>#ThreadSafe#</p>
+ * @since 1.0
+ * @version $Id: ObjectUtils.java 1199894 2011-11-09 17:53:59Z ggregory $
+ */
+//@Immutable
+public class ObjectUtils {
+
+    /**
+     * <p>{@code ObjectUtils} instances should NOT be constructed in
+     * standard programming. Instead, the static methods on the class should
+     * be used, such as {@code ObjectUtils.defaultIfNull("a","b");}.</p>
+     *
+     * <p>This constructor is public to permit tools that require a JavaBean
+     * instance to operate.</p>
+     */
+    public ObjectUtils() {
+        super();
+    }
+
+    // ToString
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Gets the {@code toString} of an {@code Object} returning
+     * an empty string ("") if {@code null} input.</p>
+     *
+     * <pre>
+     * ObjectUtils.toString(null)         = ""
+     * ObjectUtils.toString("")           = ""
+     * ObjectUtils.toString("bat")        = "bat"
+     * ObjectUtils.toString(Boolean.TRUE) = "true"
+     * </pre>
+     *
+     * @see StringUtils#defaultString(String)
+     * @see String#valueOf(Object)
+     * @param obj  the Object to {@code toString}, may be null
+     * @return the passed in Object's toString, or nullStr if {@code null} input
+     * @since 2.0
+     */
+    public static String toString(Object obj) {
+        return obj == null ? "" : obj.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/StringUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/StringUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/StringUtils.java	(revision 28000)
@@ -0,0 +1,5675 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.commons.lang3;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.regex.Pattern;
+
+/**
+ * <p>Operations on {@link java.lang.String} that are
+ * {@code null} safe.</p>
+ *
+ * <ul>
+ *  <li><b>IsEmpty/IsBlank</b>
+ *      - checks if a String contains text</li>
+ *  <li><b>Trim/Strip</b>
+ *      - removes leading and trailing whitespace</li>
+ *  <li><b>Equals</b>
+ *      - compares two strings null-safe</li>
+ *  <li><b>startsWith</b>
+ *      - check if a String starts with a prefix null-safe</li>
+ *  <li><b>endsWith</b>
+ *      - check if a String ends with a suffix null-safe</li>
+ *  <li><b>IndexOf/LastIndexOf/Contains</b>
+ *      - null-safe index-of checks
+ *  <li><b>IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut</b>
+ *      - index-of any of a set of Strings</li>
+ *  <li><b>ContainsOnly/ContainsNone/ContainsAny</b>
+ *      - does String contains only/none/any of these characters</li>
+ *  <li><b>Substring/Left/Right/Mid</b>
+ *      - null-safe substring extractions</li>
+ *  <li><b>SubstringBefore/SubstringAfter/SubstringBetween</b>
+ *      - substring extraction relative to other strings</li>
+ *  <li><b>Split/Join</b>
+ *      - splits a String into an array of substrings and vice versa</li>
+ *  <li><b>Remove/Delete</b>
+ *      - removes part of a String</li>
+ *  <li><b>Replace/Overlay</b>
+ *      - Searches a String and replaces one String with another</li>
+ *  <li><b>Chomp/Chop</b>
+ *      - removes the last part of a String</li>
+ *  <li><b>LeftPad/RightPad/Center/Repeat</b>
+ *      - pads a String</li>
+ *  <li><b>UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize</b>
+ *      - changes the case of a String</li>
+ *  <li><b>CountMatches</b>
+ *      - counts the number of occurrences of one String in another</li>
+ *  <li><b>IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable</b>
+ *      - checks the characters in a String</li>
+ *  <li><b>DefaultString</b>
+ *      - protects against a null input String</li>
+ *  <li><b>Reverse/ReverseDelimited</b>
+ *      - reverses a String</li>
+ *  <li><b>Abbreviate</b>
+ *      - abbreviates a string using ellipsis</li>
+ *  <li><b>Difference</b>
+ *      - compares Strings and reports on their differences</li>
+ *  <li><b>LevenshteinDistance</b>
+ *      - the number of changes needed to change one String into another</li>
+ * </ul>
+ *
+ * <p>The {@code StringUtils} class defines certain words related to
+ * String handling.</p>
+ *
+ * <ul>
+ *  <li>null - {@code null}</li>
+ *  <li>empty - a zero-length string ({@code ""})</li>
+ *  <li>space - the space character ({@code ' '}, char 32)</li>
+ *  <li>whitespace - the characters defined by {@link Character#isWhitespace(char)}</li>
+ *  <li>trim - the characters &lt;= 32 as in {@link String#trim()}</li>
+ * </ul>
+ *
+ * <p>{@code StringUtils} handles {@code null} input Strings quietly.
+ * That is to say that a {@code null} input will return {@code null}.
+ * Where a {@code boolean} or {@code int} is being returned
+ * details vary by method.</p>
+ *
+ * <p>A side effect of the {@code null} handling is that a
+ * {@code NullPointerException} should be considered a bug in
+ * {@code StringUtils}.</p>
+ *
+ * <p>Methods in this class give sample code to explain their operation.
+ * The symbol {@code *} is used to indicate any input including {@code null}.</p>
+ *
+ * <p>#ThreadSafe#</p>
+ * @see java.lang.String
+ * @since 1.0
+ * @version $Id: StringUtils.java 1199894 2011-11-09 17:53:59Z ggregory $
+ */
+//@Immutable
+public class StringUtils {
+    // Performance testing notes (JDK 1.4, Jul03, scolebourne)
+    // Whitespace:
+    // Character.isWhitespace() is faster than WHITESPACE.indexOf()
+    // where WHITESPACE is a string of all whitespace characters
+    //
+    // Character access:
+    // String.charAt(n) versus toCharArray(), then array[n]
+    // String.charAt(n) is about 15% worse for a 10K string
+    // They are about equal for a length 50 string
+    // String.charAt(n) is about 4 times better for a length 3 string
+    // String.charAt(n) is best bet overall
+    //
+    // Append:
+    // String.concat about twice as fast as StringBuffer.append
+    // (not sure who tested this)
+
+    /**
+     * The empty String {@code ""}.
+     * @since 2.0
+     */
+    public static final String EMPTY = "";
+
+    /**
+     * Represents a failed index search.
+     * @since 2.1
+     */
+    public static final int INDEX_NOT_FOUND = -1;
+
+    /**
+     * <p>The maximum size to which the padding constant(s) can expand.</p>
+     */
+    private static final int PAD_LIMIT = 8192;
+
+    /**
+     * A regex pattern for recognizing blocks of whitespace characters.
+     */
+    private static final Pattern WHITESPACE_BLOCK = Pattern.compile("\\s+");
+
+    /**
+     * <p>{@code StringUtils} instances should NOT be constructed in
+     * standard programming. Instead, the class should be used as
+     * {@code StringUtils.trim(" foo ");}.</p>
+     *
+     * <p>This constructor is public to permit tools that require a JavaBean
+     * instance to operate.</p>
+     */
+    public StringUtils() {
+        super();
+    }
+
+    // Empty checks
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Checks if a CharSequence is empty ("") or null.</p>
+     *
+     * <pre>
+     * StringUtils.isEmpty(null)      = true
+     * StringUtils.isEmpty("")        = true
+     * StringUtils.isEmpty(" ")       = false
+     * StringUtils.isEmpty("bob")     = false
+     * StringUtils.isEmpty("  bob  ") = false
+     * </pre>
+     *
+     * <p>NOTE: This method changed in Lang version 2.0.
+     * It no longer trims the CharSequence.
+     * That functionality is available in isBlank().</p>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @return {@code true} if the CharSequence is empty or null
+     * @since 3.0 Changed signature from isEmpty(String) to isEmpty(CharSequence)
+     */
+    public static boolean isEmpty(CharSequence cs) {
+        return cs == null || cs.length() == 0;
+    }
+
+    /**
+     * <p>Checks if a CharSequence is not empty ("") and not null.</p>
+     *
+     * <pre>
+     * StringUtils.isNotEmpty(null)      = false
+     * StringUtils.isNotEmpty("")        = false
+     * StringUtils.isNotEmpty(" ")       = true
+     * StringUtils.isNotEmpty("bob")     = true
+     * StringUtils.isNotEmpty("  bob  ") = true
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @return {@code true} if the CharSequence is not empty and not null
+     * @since 3.0 Changed signature from isNotEmpty(String) to isNotEmpty(CharSequence)
+     */
+    public static boolean isNotEmpty(CharSequence cs) {
+        return !StringUtils.isEmpty(cs);
+    }
+
+    /**
+     * <p>Checks if a CharSequence is whitespace, empty ("") or null.</p>
+     *
+     * <pre>
+     * StringUtils.isBlank(null)      = true
+     * StringUtils.isBlank("")        = true
+     * StringUtils.isBlank(" ")       = true
+     * StringUtils.isBlank("bob")     = false
+     * StringUtils.isBlank("  bob  ") = false
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @return {@code true} if the CharSequence is null, empty or whitespace
+     * @since 2.0
+     * @since 3.0 Changed signature from isBlank(String) to isBlank(CharSequence)
+     */
+    public static boolean isBlank(CharSequence cs) {
+        int strLen;
+        if (cs == null || (strLen = cs.length()) == 0) {
+            return true;
+        }
+        for (int i = 0; i < strLen; i++) {
+            if (Character.isWhitespace(cs.charAt(i)) == false) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * <p>Checks if a CharSequence is not empty (""), not null and not whitespace only.</p>
+     *
+     * <pre>
+     * StringUtils.isNotBlank(null)      = false
+     * StringUtils.isNotBlank("")        = false
+     * StringUtils.isNotBlank(" ")       = false
+     * StringUtils.isNotBlank("bob")     = true
+     * StringUtils.isNotBlank("  bob  ") = true
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @return {@code true} if the CharSequence is
+     *  not empty and not null and not whitespace
+     * @since 2.0
+     * @since 3.0 Changed signature from isNotBlank(String) to isNotBlank(CharSequence)
+     */
+    public static boolean isNotBlank(CharSequence cs) {
+        return !StringUtils.isBlank(cs);
+    }
+
+    // Trim
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Removes control characters (char &lt;= 32) from both
+     * ends of this String, handling {@code null} by returning
+     * {@code null}.</p>
+     *
+     * <p>The String is trimmed using {@link String#trim()}.
+     * Trim removes start and end characters &lt;= 32.
+     * To strip whitespace use {@link #strip(String)}.</p>
+     *
+     * <p>To trim your choice of characters, use the
+     * {@link #strip(String, String)} methods.</p>
+     *
+     * <pre>
+     * StringUtils.trim(null)          = null
+     * StringUtils.trim("")            = ""
+     * StringUtils.trim("     ")       = ""
+     * StringUtils.trim("abc")         = "abc"
+     * StringUtils.trim("    abc    ") = "abc"
+     * </pre>
+     *
+     * @param str  the String to be trimmed, may be null
+     * @return the trimmed string, {@code null} if null String input
+     */
+    public static String trim(String str) {
+        return str == null ? null : str.trim();
+    }
+
+    /**
+     * <p>Removes control characters (char &lt;= 32) from both
+     * ends of this String returning {@code null} if the String is
+     * empty ("") after the trim or if it is {@code null}.
+     *
+     * <p>The String is trimmed using {@link String#trim()}.
+     * Trim removes start and end characters &lt;= 32.
+     * To strip whitespace use {@link #stripToNull(String)}.</p>
+     *
+     * <pre>
+     * StringUtils.trimToNull(null)          = null
+     * StringUtils.trimToNull("")            = null
+     * StringUtils.trimToNull("     ")       = null
+     * StringUtils.trimToNull("abc")         = "abc"
+     * StringUtils.trimToNull("    abc    ") = "abc"
+     * </pre>
+     *
+     * @param str  the String to be trimmed, may be null
+     * @return the trimmed String,
+     *  {@code null} if only chars &lt;= 32, empty or null String input
+     * @since 2.0
+     */
+    public static String trimToNull(String str) {
+        String ts = trim(str);
+        return isEmpty(ts) ? null : ts;
+    }
+
+    /**
+     * <p>Removes control characters (char &lt;= 32) from both
+     * ends of this String returning an empty String ("") if the String
+     * is empty ("") after the trim or if it is {@code null}.
+     *
+     * <p>The String is trimmed using {@link String#trim()}.
+     * Trim removes start and end characters &lt;= 32.
+     * To strip whitespace use {@link #stripToEmpty(String)}.</p>
+     *
+     * <pre>
+     * StringUtils.trimToEmpty(null)          = ""
+     * StringUtils.trimToEmpty("")            = ""
+     * StringUtils.trimToEmpty("     ")       = ""
+     * StringUtils.trimToEmpty("abc")         = "abc"
+     * StringUtils.trimToEmpty("    abc    ") = "abc"
+     * </pre>
+     *
+     * @param str  the String to be trimmed, may be null
+     * @return the trimmed String, or an empty String if {@code null} input
+     * @since 2.0
+     */
+    public static String trimToEmpty(String str) {
+        return str == null ? EMPTY : str.trim();
+    }
+
+    // Stripping
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Strips whitespace from the start and end of a String.</p>
+     *
+     * <p>This is similar to {@link #trim(String)} but removes whitespace.
+     * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
+     *
+     * <p>A {@code null} input String returns {@code null}.</p>
+     *
+     * <pre>
+     * StringUtils.strip(null)     = null
+     * StringUtils.strip("")       = ""
+     * StringUtils.strip("   ")    = ""
+     * StringUtils.strip("abc")    = "abc"
+     * StringUtils.strip("  abc")  = "abc"
+     * StringUtils.strip("abc  ")  = "abc"
+     * StringUtils.strip(" abc ")  = "abc"
+     * StringUtils.strip(" ab c ") = "ab c"
+     * </pre>
+     *
+     * @param str  the String to remove whitespace from, may be null
+     * @return the stripped String, {@code null} if null String input
+     */
+    public static String strip(String str) {
+        return strip(str, null);
+    }
+
+    /**
+     * <p>Strips whitespace from the start and end of a String  returning
+     * {@code null} if the String is empty ("") after the strip.</p>
+     *
+     * <p>This is similar to {@link #trimToNull(String)} but removes whitespace.
+     * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
+     *
+     * <pre>
+     * StringUtils.stripToNull(null)     = null
+     * StringUtils.stripToNull("")       = null
+     * StringUtils.stripToNull("   ")    = null
+     * StringUtils.stripToNull("abc")    = "abc"
+     * StringUtils.stripToNull("  abc")  = "abc"
+     * StringUtils.stripToNull("abc  ")  = "abc"
+     * StringUtils.stripToNull(" abc ")  = "abc"
+     * StringUtils.stripToNull(" ab c ") = "ab c"
+     * </pre>
+     *
+     * @param str  the String to be stripped, may be null
+     * @return the stripped String,
+     *  {@code null} if whitespace, empty or null String input
+     * @since 2.0
+     */
+    public static String stripToNull(String str) {
+        if (str == null) {
+            return null;
+        }
+        str = strip(str, null);
+        return str.length() == 0 ? null : str;
+    }
+
+    /**
+     * <p>Strips whitespace from the start and end of a String  returning
+     * an empty String if {@code null} input.</p>
+     *
+     * <p>This is similar to {@link #trimToEmpty(String)} but removes whitespace.
+     * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
+     *
+     * <pre>
+     * StringUtils.stripToEmpty(null)     = ""
+     * StringUtils.stripToEmpty("")       = ""
+     * StringUtils.stripToEmpty("   ")    = ""
+     * StringUtils.stripToEmpty("abc")    = "abc"
+     * StringUtils.stripToEmpty("  abc")  = "abc"
+     * StringUtils.stripToEmpty("abc  ")  = "abc"
+     * StringUtils.stripToEmpty(" abc ")  = "abc"
+     * StringUtils.stripToEmpty(" ab c ") = "ab c"
+     * </pre>
+     *
+     * @param str  the String to be stripped, may be null
+     * @return the trimmed String, or an empty String if {@code null} input
+     * @since 2.0
+     */
+    public static String stripToEmpty(String str) {
+        return str == null ? EMPTY : strip(str, null);
+    }
+
+    /**
+     * <p>Strips any of a set of characters from the start and end of a String.
+     * This is similar to {@link String#trim()} but allows the characters
+     * to be stripped to be controlled.</p>
+     *
+     * <p>A {@code null} input String returns {@code null}.
+     * An empty string ("") input returns the empty string.</p>
+     *
+     * <p>If the stripChars String is {@code null}, whitespace is
+     * stripped as defined by {@link Character#isWhitespace(char)}.
+     * Alternatively use {@link #strip(String)}.</p>
+     *
+     * <pre>
+     * StringUtils.strip(null, *)          = null
+     * StringUtils.strip("", *)            = ""
+     * StringUtils.strip("abc", null)      = "abc"
+     * StringUtils.strip("  abc", null)    = "abc"
+     * StringUtils.strip("abc  ", null)    = "abc"
+     * StringUtils.strip(" abc ", null)    = "abc"
+     * StringUtils.strip("  abcyx", "xyz") = "  abc"
+     * </pre>
+     *
+     * @param str  the String to remove characters from, may be null
+     * @param stripChars  the characters to remove, null treated as whitespace
+     * @return the stripped String, {@code null} if null String input
+     */
+    public static String strip(String str, String stripChars) {
+        if (isEmpty(str)) {
+            return str;
+        }
+        str = stripStart(str, stripChars);
+        return stripEnd(str, stripChars);
+    }
+
+    /**
+     * <p>Strips any of a set of characters from the start of a String.</p>
+     *
+     * <p>A {@code null} input String returns {@code null}.
+     * An empty string ("") input returns the empty string.</p>
+     *
+     * <p>If the stripChars String is {@code null}, whitespace is
+     * stripped as defined by {@link Character#isWhitespace(char)}.</p>
+     *
+     * <pre>
+     * StringUtils.stripStart(null, *)          = null
+     * StringUtils.stripStart("", *)            = ""
+     * StringUtils.stripStart("abc", "")        = "abc"
+     * StringUtils.stripStart("abc", null)      = "abc"
+     * StringUtils.stripStart("  abc", null)    = "abc"
+     * StringUtils.stripStart("abc  ", null)    = "abc  "
+     * StringUtils.stripStart(" abc ", null)    = "abc "
+     * StringUtils.stripStart("yxabc  ", "xyz") = "abc  "
+     * </pre>
+     *
+     * @param str  the String to remove characters from, may be null
+     * @param stripChars  the characters to remove, null treated as whitespace
+     * @return the stripped String, {@code null} if null String input
+     */
+    public static String stripStart(String str, String stripChars) {
+        int strLen;
+        if (str == null || (strLen = str.length()) == 0) {
+            return str;
+        }
+        int start = 0;
+        if (stripChars == null) {
+            while (start != strLen && Character.isWhitespace(str.charAt(start))) {
+                start++;
+            }
+        } else if (stripChars.length() == 0) {
+            return str;
+        } else {
+            while (start != strLen && stripChars.indexOf(str.charAt(start)) != INDEX_NOT_FOUND) {
+                start++;
+            }
+        }
+        return str.substring(start);
+    }
+
+    /**
+     * <p>Strips any of a set of characters from the end of a String.</p>
+     *
+     * <p>A {@code null} input String returns {@code null}.
+     * An empty string ("") input returns the empty string.</p>
+     *
+     * <p>If the stripChars String is {@code null}, whitespace is
+     * stripped as defined by {@link Character#isWhitespace(char)}.</p>
+     *
+     * <pre>
+     * StringUtils.stripEnd(null, *)          = null
+     * StringUtils.stripEnd("", *)            = ""
+     * StringUtils.stripEnd("abc", "")        = "abc"
+     * StringUtils.stripEnd("abc", null)      = "abc"
+     * StringUtils.stripEnd("  abc", null)    = "  abc"
+     * StringUtils.stripEnd("abc  ", null)    = "abc"
+     * StringUtils.stripEnd(" abc ", null)    = " abc"
+     * StringUtils.stripEnd("  abcyx", "xyz") = "  abc"
+     * StringUtils.stripEnd("120.00", ".0")   = "12"
+     * </pre>
+     *
+     * @param str  the String to remove characters from, may be null
+     * @param stripChars  the set of characters to remove, null treated as whitespace
+     * @return the stripped String, {@code null} if null String input
+     */
+    public static String stripEnd(String str, String stripChars) {
+        int end;
+        if (str == null || (end = str.length()) == 0) {
+            return str;
+        }
+
+        if (stripChars == null) {
+            while (end != 0 && Character.isWhitespace(str.charAt(end - 1))) {
+                end--;
+            }
+        } else if (stripChars.length() == 0) {
+            return str;
+        } else {
+            while (end != 0 && stripChars.indexOf(str.charAt(end - 1)) != INDEX_NOT_FOUND) {
+                end--;
+            }
+        }
+        return str.substring(0, end);
+    }
+
+    // StripAll
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Strips whitespace from the start and end of every String in an array.
+     * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
+     *
+     * <p>A new array is returned each time, except for length zero.
+     * A {@code null} array will return {@code null}.
+     * An empty array will return itself.
+     * A {@code null} array entry will be ignored.</p>
+     *
+     * <pre>
+     * StringUtils.stripAll(null)             = null
+     * StringUtils.stripAll([])               = []
+     * StringUtils.stripAll(["abc", "  abc"]) = ["abc", "abc"]
+     * StringUtils.stripAll(["abc  ", null])  = ["abc", null]
+     * </pre>
+     *
+     * @param strs  the array to remove whitespace from, may be null
+     * @return the stripped Strings, {@code null} if null array input
+     */
+    public static String[] stripAll(String... strs) {
+        return stripAll(strs, null);
+    }
+
+    /**
+     * <p>Strips any of a set of characters from the start and end of every
+     * String in an array.</p>
+     * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
+     *
+     * <p>A new array is returned each time, except for length zero.
+     * A {@code null} array will return {@code null}.
+     * An empty array will return itself.
+     * A {@code null} array entry will be ignored.
+     * A {@code null} stripChars will strip whitespace as defined by
+     * {@link Character#isWhitespace(char)}.</p>
+     *
+     * <pre>
+     * StringUtils.stripAll(null, *)                = null
+     * StringUtils.stripAll([], *)                  = []
+     * StringUtils.stripAll(["abc", "  abc"], null) = ["abc", "abc"]
+     * StringUtils.stripAll(["abc  ", null], null)  = ["abc", null]
+     * StringUtils.stripAll(["abc  ", null], "yz")  = ["abc  ", null]
+     * StringUtils.stripAll(["yabcz", null], "yz")  = ["abc", null]
+     * </pre>
+     *
+     * @param strs  the array to remove characters from, may be null
+     * @param stripChars  the characters to remove, null treated as whitespace
+     * @return the stripped Strings, {@code null} if null array input
+     */
+    public static String[] stripAll(String[] strs, String stripChars) {
+        int strsLen;
+        if (strs == null || (strsLen = strs.length) == 0) {
+            return strs;
+        }
+        String[] newArr = new String[strsLen];
+        for (int i = 0; i < strsLen; i++) {
+            newArr[i] = strip(strs[i], stripChars);
+        }
+        return newArr;
+    }
+
+    /**
+     * <p>Removes diacritics (~= accents) from a string. The case will not be altered.</p>
+     * <p>For instance, '&agrave;' will be replaced by 'a'.</p>
+     * <p>Note that ligatures will be left as is.</p>
+     *
+     * <p>This method will use the first available implementation of:
+     * Java 6's {@link java.text.Normalizer}, Java 1.3&ndash;1.5's {@code sun.text.Normalizer}</p>
+     *
+     * <pre>
+     * StringUtils.stripAccents(null)                = null
+     * StringUtils.stripAccents("")                  = ""
+     * StringUtils.stripAccents("control")           = "control"
+     * StringUtils.stripAccents("&eacute;clair")     = "eclair"
+     * </pre>
+     *
+     * @param input String to be stripped
+     * @return input text with diacritics removed
+     *
+     * @since 3.0
+     */
+    // See also Lucene's ASCIIFoldingFilter (Lucene 2.9) that replaces accented characters by their unaccented equivalent (and uncommitted bug fix: https://issues.apache.org/jira/browse/LUCENE-1343?focusedCommentId=12858907&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_12858907).
+    public static String stripAccents(String input) {
+        if(input == null) {
+            return null;
+        }
+        try {
+            String result = null;
+            if (InitStripAccents.java6NormalizeMethod != null) {
+                result = removeAccentsJava6(input);
+            } else if (InitStripAccents.sunDecomposeMethod != null) {
+                result = removeAccentsSUN(input);
+            } else {
+                throw new UnsupportedOperationException(
+                    "The stripAccents(CharSequence) method requires at least"
+                        +" Java6, but got: "+InitStripAccents.java6Exception
+                        +"; or a Sun JVM: "+InitStripAccents.sunException);
+            }
+            // Note that none of the above methods correctly remove ligatures...
+            return result;
+        } catch(IllegalArgumentException iae) {
+            throw new RuntimeException("IllegalArgumentException occurred", iae);
+        } catch(IllegalAccessException iae) {
+            throw new RuntimeException("IllegalAccessException occurred", iae);
+        } catch(InvocationTargetException ite) {
+            throw new RuntimeException("InvocationTargetException occurred", ite);
+        } catch(SecurityException se) {
+            throw new RuntimeException("SecurityException occurred", se);
+        }
+    }
+
+    /**
+     * Use {@code java.text.Normalizer#normalize(CharSequence, Normalizer.Form)}
+     * (but be careful, this class exists in Java 1.3, with an entirely different meaning!)
+     *
+     * @param text the text to be processed
+     * @return the processed string
+     * @throws IllegalAccessException may be thrown by a reflection call
+     * @throws InvocationTargetException if a reflection call throws an exception
+     * @throws IllegalStateException if the {@code Normalizer} class is not available
+     */
+    private static String removeAccentsJava6(CharSequence text)
+        throws IllegalAccessException, InvocationTargetException {
+        /*
+        String decomposed = java.text.Normalizer.normalize(CharSequence, Normalizer.Form.NFD);
+        return java6Pattern.matcher(decomposed).replaceAll("");//$NON-NLS-1$
+        */
+        if (InitStripAccents.java6NormalizeMethod == null || InitStripAccents.java6NormalizerFormNFD == null) {
+            throw new IllegalStateException("java.text.Normalizer is not available", InitStripAccents.java6Exception);
+        }
+        String result;
+        result = (String) InitStripAccents.java6NormalizeMethod.invoke(null, new Object[] {text, InitStripAccents.java6NormalizerFormNFD});
+        result = InitStripAccents.java6Pattern.matcher(result).replaceAll("");//$NON-NLS-1$
+        return result;
+    }
+
+    /**
+     * Use {@code sun.text.Normalizer#decompose(String, boolean, int)}
+     *
+     * @param text the text to be processed
+     * @return the processed string
+     * @throws IllegalAccessException may be thrown by a reflection call
+     * @throws InvocationTargetException if a reflection call throws an exception
+     * @throws IllegalStateException if the {@code Normalizer} class is not available
+     */
+    private static String removeAccentsSUN(CharSequence text)
+        throws IllegalAccessException, InvocationTargetException {
+        /*
+        String decomposed = sun.text.Normalizer.decompose(text, false, 0);
+        return sunPattern.matcher(decomposed).replaceAll("");//$NON-NLS-1$
+        */
+        if (InitStripAccents.sunDecomposeMethod == null) {
+            throw new IllegalStateException("sun.text.Normalizer is not available", InitStripAccents.sunException);
+        }
+        String result;
+        result = (String) InitStripAccents.sunDecomposeMethod.invoke(null, new Object[] {text, Boolean.FALSE, Integer.valueOf(0)});
+        result = InitStripAccents.sunPattern.matcher(result).replaceAll("");//$NON-NLS-1$
+        return result;
+    }
+
+    // IOD container for stripAccent() initialisation
+    private static class InitStripAccents {
+        // SUN internal, Java 1.3 -> Java 5
+        private static final Throwable sunException;
+        private static final Method  sunDecomposeMethod;
+        private static final Pattern sunPattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");//$NON-NLS-1$
+        // Java 6+
+        private static final Throwable java6Exception;
+        private static final Method  java6NormalizeMethod;
+        private static final Object  java6NormalizerFormNFD;
+        private static final Pattern java6Pattern = sunPattern;
+    
+        static {
+            // Set up defaults for final static fields
+            Object _java6NormalizerFormNFD = null;
+            Method _java6NormalizeMethod = null;
+            Method _sunDecomposeMethod = null;
+            Throwable _java6Exception = null;
+            Throwable _sunException = null;
+            try {
+                // java.text.Normalizer.normalize(CharSequence, Normalizer.Form.NFD);
+                // Be careful not to get Java 1.3 java.text.Normalizer!
+                Class<?> normalizerFormClass = Thread.currentThread().getContextClassLoader()
+                    .loadClass("java.text.Normalizer$Form");//$NON-NLS-1$
+                _java6NormalizerFormNFD = normalizerFormClass.getField("NFD").get(null);//$NON-NLS-1$
+                Class<?> normalizerClass = Thread.currentThread().getContextClassLoader()
+                    .loadClass("java.text.Normalizer");//$NON-NLS-1$
+                _java6NormalizeMethod = normalizerClass.getMethod("normalize",//$NON-NLS-1$
+                        new Class[] {CharSequence.class, normalizerFormClass});//$NON-NLS-1$
+            } catch (Exception e1) {
+                // Only check for Sun method if Java 6 method is not available
+                _java6Exception = e1;
+                try {
+                    // sun.text.Normalizer.decompose(text, false, 0);
+                    Class<?> normalizerClass = Thread.currentThread().getContextClassLoader()
+                        .loadClass("sun.text.Normalizer");//$NON-NLS-1$
+                    _sunDecomposeMethod = normalizerClass.getMethod("decompose",//$NON-NLS-1$
+                            new Class[] {String.class, Boolean.TYPE, Integer.TYPE});//$NON-NLS-1$
+                } catch (Exception e2) {
+                    _sunException = e2;
+                }
+            }
+    
+            // Set up final static fields
+            java6Exception = _java6Exception;
+            java6NormalizerFormNFD = _java6NormalizerFormNFD;
+            java6NormalizeMethod = _java6NormalizeMethod;
+            sunException = _sunException;
+            sunDecomposeMethod = _sunDecomposeMethod;
+        }
+    }
+
+    // Equals
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Compares two CharSequences, returning {@code true} if they are equal.</p>
+     *
+     * <p>{@code null}s are handled without exceptions. Two {@code null}
+     * references are considered to be equal. The comparison is case sensitive.</p>
+     *
+     * <pre>
+     * StringUtils.equals(null, null)   = true
+     * StringUtils.equals(null, "abc")  = false
+     * StringUtils.equals("abc", null)  = false
+     * StringUtils.equals("abc", "abc") = true
+     * StringUtils.equals("abc", "ABC") = false
+     * </pre>
+     *
+     * @see java.lang.String#equals(Object)
+     * @param cs1  the first CharSequence, may be null
+     * @param cs2  the second CharSequence, may be null
+     * @return {@code true} if the CharSequences are equal, case sensitive, or
+     *  both {@code null}
+     * @since 3.0 Changed signature from equals(String, String) to equals(CharSequence, CharSequence)
+     */
+    public static boolean equals(CharSequence cs1, CharSequence cs2) {
+        return cs1 == null ? cs2 == null : cs1.equals(cs2);
+    }
+
+    /**
+     * <p>Compares two CharSequences, returning {@code true} if they are equal ignoring
+     * the case.</p>
+     *
+     * <p>{@code null}s are handled without exceptions. Two {@code null}
+     * references are considered equal. Comparison is case insensitive.</p>
+     *
+     * <pre>
+     * StringUtils.equalsIgnoreCase(null, null)   = true
+     * StringUtils.equalsIgnoreCase(null, "abc")  = false
+     * StringUtils.equalsIgnoreCase("abc", null)  = false
+     * StringUtils.equalsIgnoreCase("abc", "abc") = true
+     * StringUtils.equalsIgnoreCase("abc", "ABC") = true
+     * </pre>
+     *
+     * @param str1  the first CharSequence, may be null
+     * @param str2  the second CharSequence, may be null
+     * @return {@code true} if the CharSequence are equal, case insensitive, or
+     *  both {@code null}
+     * @since 3.0 Changed signature from equalsIgnoreCase(String, String) to equalsIgnoreCase(CharSequence, CharSequence)
+     */
+    public static boolean equalsIgnoreCase(CharSequence str1, CharSequence str2) {
+        if (str1 == null || str2 == null) {
+            return str1 == str2;
+        } else {
+            return CharSequenceUtils.regionMatches(str1, true, 0, str2, 0, Math.max(str1.length(), str2.length()));
+        }
+    }
+
+    // IndexOf
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Finds the first index within a CharSequence, handling {@code null}.
+     * This method uses {@link String#indexOf(int, int)} if possible.</p>
+     *
+     * <p>A {@code null} or empty ("") CharSequence will return {@code INDEX_NOT_FOUND (-1)}.</p>
+     *
+     * <pre>
+     * StringUtils.indexOf(null, *)         = -1
+     * StringUtils.indexOf("", *)           = -1
+     * StringUtils.indexOf("aabaabaa", 'a') = 0
+     * StringUtils.indexOf("aabaabaa", 'b') = 2
+     * </pre>
+     *
+     * @param seq  the CharSequence to check, may be null
+     * @param searchChar  the character to find
+     * @return the first index of the search character,
+     *  -1 if no match or {@code null} string input
+     * @since 2.0
+     * @since 3.0 Changed signature from indexOf(String, int) to indexOf(CharSequence, int)
+     */
+    public static int indexOf(CharSequence seq, int searchChar) {
+        if (isEmpty(seq)) {
+            return INDEX_NOT_FOUND;
+        }
+        return CharSequenceUtils.indexOf(seq, searchChar, 0);
+    }
+
+    /**
+     * <p>Finds the first index within a CharSequence from a start position,
+     * handling {@code null}.
+     * This method uses {@link String#indexOf(int, int)} if possible.</p>
+     *
+     * <p>A {@code null} or empty ("") CharSequence will return {@code (INDEX_NOT_FOUND) -1}.
+     * A negative start position is treated as zero.
+     * A start position greater than the string length returns {@code -1}.</p>
+     *
+     * <pre>
+     * StringUtils.indexOf(null, *, *)          = -1
+     * StringUtils.indexOf("", *, *)            = -1
+     * StringUtils.indexOf("aabaabaa", 'b', 0)  = 2
+     * StringUtils.indexOf("aabaabaa", 'b', 3)  = 5
+     * StringUtils.indexOf("aabaabaa", 'b', 9)  = -1
+     * StringUtils.indexOf("aabaabaa", 'b', -1) = 2
+     * </pre>
+     *
+     * @param seq  the CharSequence to check, may be null
+     * @param searchChar  the character to find
+     * @param startPos  the start position, negative treated as zero
+     * @return the first index of the search character,
+     *  -1 if no match or {@code null} string input
+     * @since 2.0
+     * @since 3.0 Changed signature from indexOf(String, int, int) to indexOf(CharSequence, int, int)
+     */
+    public static int indexOf(CharSequence seq, int searchChar, int startPos) {
+        if (isEmpty(seq)) {
+            return INDEX_NOT_FOUND;
+        }
+        return CharSequenceUtils.indexOf(seq, searchChar, startPos);
+    }
+
+    /**
+     * <p>Finds the first index within a CharSequence, handling {@code null}.
+     * This method uses {@link String#indexOf(String, int)} if possible.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.</p>
+     *
+     * <pre>
+     * StringUtils.indexOf(null, *)          = -1
+     * StringUtils.indexOf(*, null)          = -1
+     * StringUtils.indexOf("", "")           = 0
+     * StringUtils.indexOf("", *)            = -1 (except when * = "")
+     * StringUtils.indexOf("aabaabaa", "a")  = 0
+     * StringUtils.indexOf("aabaabaa", "b")  = 2
+     * StringUtils.indexOf("aabaabaa", "ab") = 1
+     * StringUtils.indexOf("aabaabaa", "")   = 0
+     * </pre>
+     *
+     * @param seq  the CharSequence to check, may be null
+     * @param searchSeq  the CharSequence to find, may be null
+     * @return the first index of the search CharSequence,
+     *  -1 if no match or {@code null} string input
+     * @since 2.0
+     * @since 3.0 Changed signature from indexOf(String, String) to indexOf(CharSequence, CharSequence)
+     */
+    public static int indexOf(CharSequence seq, CharSequence searchSeq) {
+        if (seq == null || searchSeq == null) {
+            return INDEX_NOT_FOUND;
+        }
+        return CharSequenceUtils.indexOf(seq, searchSeq, 0);
+    }
+
+    /**
+     * <p>Finds the first index within a CharSequence, handling {@code null}.
+     * This method uses {@link String#indexOf(String, int)} if possible.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.
+     * A negative start position is treated as zero.
+     * An empty ("") search CharSequence always matches.
+     * A start position greater than the string length only matches
+     * an empty search CharSequence.</p>
+     *
+     * <pre>
+     * StringUtils.indexOf(null, *, *)          = -1
+     * StringUtils.indexOf(*, null, *)          = -1
+     * StringUtils.indexOf("", "", 0)           = 0
+     * StringUtils.indexOf("", *, 0)            = -1 (except when * = "")
+     * StringUtils.indexOf("aabaabaa", "a", 0)  = 0
+     * StringUtils.indexOf("aabaabaa", "b", 0)  = 2
+     * StringUtils.indexOf("aabaabaa", "ab", 0) = 1
+     * StringUtils.indexOf("aabaabaa", "b", 3)  = 5
+     * StringUtils.indexOf("aabaabaa", "b", 9)  = -1
+     * StringUtils.indexOf("aabaabaa", "b", -1) = 2
+     * StringUtils.indexOf("aabaabaa", "", 2)   = 2
+     * StringUtils.indexOf("abc", "", 9)        = 3
+     * </pre>
+     *
+     * @param seq  the CharSequence to check, may be null
+     * @param searchSeq  the CharSequence to find, may be null
+     * @param startPos  the start position, negative treated as zero
+     * @return the first index of the search CharSequence,
+     *  -1 if no match or {@code null} string input
+     * @since 2.0
+     * @since 3.0 Changed signature from indexOf(String, String, int) to indexOf(CharSequence, CharSequence, int)
+     */
+    public static int indexOf(CharSequence seq, CharSequence searchSeq, int startPos) {
+        if (seq == null || searchSeq == null) {
+            return INDEX_NOT_FOUND;
+        }
+        return CharSequenceUtils.indexOf(seq, searchSeq, startPos);
+    }
+
+    /**
+     * <p>Finds the n-th index within a CharSequence, handling {@code null}.
+     * This method uses {@link String#indexOf(String)} if possible.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.</p>
+     *
+     * <pre>
+     * StringUtils.ordinalIndexOf(null, *, *)          = -1
+     * StringUtils.ordinalIndexOf(*, null, *)          = -1
+     * StringUtils.ordinalIndexOf("", "", *)           = 0
+     * StringUtils.ordinalIndexOf("aabaabaa", "a", 1)  = 0
+     * StringUtils.ordinalIndexOf("aabaabaa", "a", 2)  = 1
+     * StringUtils.ordinalIndexOf("aabaabaa", "b", 1)  = 2
+     * StringUtils.ordinalIndexOf("aabaabaa", "b", 2)  = 5
+     * StringUtils.ordinalIndexOf("aabaabaa", "ab", 1) = 1
+     * StringUtils.ordinalIndexOf("aabaabaa", "ab", 2) = 4
+     * StringUtils.ordinalIndexOf("aabaabaa", "", 1)   = 0
+     * StringUtils.ordinalIndexOf("aabaabaa", "", 2)   = 0
+     * </pre>
+     *
+     * <p>Note that 'head(CharSequence str, int n)' may be implemented as: </p>
+     *
+     * <pre>
+     *   str.substring(0, lastOrdinalIndexOf(str, "\n", n))
+     * </pre>
+     *
+     * @param str  the CharSequence to check, may be null
+     * @param searchStr  the CharSequence to find, may be null
+     * @param ordinal  the n-th {@code searchStr} to find
+     * @return the n-th index of the search CharSequence,
+     *  {@code -1} ({@code INDEX_NOT_FOUND}) if no match or {@code null} string input
+     * @since 2.1
+     * @since 3.0 Changed signature from ordinalIndexOf(String, String, int) to ordinalIndexOf(CharSequence, CharSequence, int)
+     */
+    public static int ordinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal) {
+        return ordinalIndexOf(str, searchStr, ordinal, false);
+    }
+
+    /**
+     * <p>Finds the n-th index within a String, handling {@code null}.
+     * This method uses {@link String#indexOf(String)} if possible.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.</p>
+     *
+     * @param str  the CharSequence to check, may be null
+     * @param searchStr  the CharSequence to find, may be null
+     * @param ordinal  the n-th {@code searchStr} to find
+     * @param lastIndex true if lastOrdinalIndexOf() otherwise false if ordinalIndexOf()
+     * @return the n-th index of the search CharSequence,
+     *  {@code -1} ({@code INDEX_NOT_FOUND}) if no match or {@code null} string input
+     */
+    // Shared code between ordinalIndexOf(String,String,int) and lastOrdinalIndexOf(String,String,int)
+    private static int ordinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal, boolean lastIndex) {
+        if (str == null || searchStr == null || ordinal <= 0) {
+            return INDEX_NOT_FOUND;
+        }
+        if (searchStr.length() == 0) {
+            return lastIndex ? str.length() : 0;
+        }
+        int found = 0;
+        int index = lastIndex ? str.length() : INDEX_NOT_FOUND;
+        do {
+            if (lastIndex) {
+                index = CharSequenceUtils.lastIndexOf(str, searchStr, index - 1);
+            } else {
+                index = CharSequenceUtils.indexOf(str, searchStr, index + 1);
+            }
+            if (index < 0) {
+                return index;
+            }
+            found++;
+        } while (found < ordinal);
+        return index;
+    }
+
+    /**
+     * <p>Case in-sensitive find of the first index within a CharSequence.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.
+     * A negative start position is treated as zero.
+     * An empty ("") search CharSequence always matches.
+     * A start position greater than the string length only matches
+     * an empty search CharSequence.</p>
+     *
+     * <pre>
+     * StringUtils.indexOfIgnoreCase(null, *)          = -1
+     * StringUtils.indexOfIgnoreCase(*, null)          = -1
+     * StringUtils.indexOfIgnoreCase("", "")           = 0
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "a")  = 0
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "b")  = 2
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "ab") = 1
+     * </pre>
+     *
+     * @param str  the CharSequence to check, may be null
+     * @param searchStr  the CharSequence to find, may be null
+     * @return the first index of the search CharSequence,
+     *  -1 if no match or {@code null} string input
+     * @since 2.5
+     * @since 3.0 Changed signature from indexOfIgnoreCase(String, String) to indexOfIgnoreCase(CharSequence, CharSequence)
+     */
+    public static int indexOfIgnoreCase(CharSequence str, CharSequence searchStr) {
+        return indexOfIgnoreCase(str, searchStr, 0);
+    }
+
+    /**
+     * <p>Case in-sensitive find of the first index within a CharSequence
+     * from the specified position.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.
+     * A negative start position is treated as zero.
+     * An empty ("") search CharSequence always matches.
+     * A start position greater than the string length only matches
+     * an empty search CharSequence.</p>
+     *
+     * <pre>
+     * StringUtils.indexOfIgnoreCase(null, *, *)          = -1
+     * StringUtils.indexOfIgnoreCase(*, null, *)          = -1
+     * StringUtils.indexOfIgnoreCase("", "", 0)           = 0
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
+     * StringUtils.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
+     * StringUtils.indexOfIgnoreCase("abc", "", 9)        = 3
+     * </pre>
+     *
+     * @param str  the CharSequence to check, may be null
+     * @param searchStr  the CharSequence to find, may be null
+     * @param startPos  the start position, negative treated as zero
+     * @return the first index of the search CharSequence,
+     *  -1 if no match or {@code null} string input
+     * @since 2.5
+     * @since 3.0 Changed signature from indexOfIgnoreCase(String, String, int) to indexOfIgnoreCase(CharSequence, CharSequence, int)
+     */
+    public static int indexOfIgnoreCase(CharSequence str, CharSequence searchStr, int startPos) {
+        if (str == null || searchStr == null) {
+            return INDEX_NOT_FOUND;
+        }
+        if (startPos < 0) {
+            startPos = 0;
+        }
+        int endLimit = str.length() - searchStr.length() + 1;
+        if (startPos > endLimit) {
+            return INDEX_NOT_FOUND;
+        }
+        if (searchStr.length() == 0) {
+            return startPos;
+        }
+        for (int i = startPos; i < endLimit; i++) {
+            if (CharSequenceUtils.regionMatches(str, true, i, searchStr, 0, searchStr.length())) {
+                return i;
+            }
+        }
+        return INDEX_NOT_FOUND;
+    }
+
+    // LastIndexOf
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Finds the last index within a CharSequence, handling {@code null}.
+     * This method uses {@link String#lastIndexOf(int)} if possible.</p>
+     *
+     * <p>A {@code null} or empty ("") CharSequence will return {@code -1}.</p>
+     *
+     * <pre>
+     * StringUtils.lastIndexOf(null, *)         = -1
+     * StringUtils.lastIndexOf("", *)           = -1
+     * StringUtils.lastIndexOf("aabaabaa", 'a') = 7
+     * StringUtils.lastIndexOf("aabaabaa", 'b') = 5
+     * </pre>
+     *
+     * @param seq  the CharSequence to check, may be null
+     * @param searchChar  the character to find
+     * @return the last index of the search character,
+     *  -1 if no match or {@code null} string input
+     * @since 2.0
+     * @since 3.0 Changed signature from lastIndexOf(String, int) to lastIndexOf(CharSequence, int)
+     */
+    public static int lastIndexOf(CharSequence seq, int searchChar) {
+        if (isEmpty(seq)) {
+            return INDEX_NOT_FOUND;
+        }
+        return CharSequenceUtils.lastIndexOf(seq, searchChar, seq.length());
+    }
+
+    /**
+     * <p>Finds the last index within a CharSequence from a start position,
+     * handling {@code null}.
+     * This method uses {@link String#lastIndexOf(int, int)} if possible.</p>
+     *
+     * <p>A {@code null} or empty ("") CharSequence will return {@code -1}.
+     * A negative start position returns {@code -1}.
+     * A start position greater than the string length searches the whole string.</p>
+     *
+     * <pre>
+     * StringUtils.lastIndexOf(null, *, *)          = -1
+     * StringUtils.lastIndexOf("", *,  *)           = -1
+     * StringUtils.lastIndexOf("aabaabaa", 'b', 8)  = 5
+     * StringUtils.lastIndexOf("aabaabaa", 'b', 4)  = 2
+     * StringUtils.lastIndexOf("aabaabaa", 'b', 0)  = -1
+     * StringUtils.lastIndexOf("aabaabaa", 'b', 9)  = 5
+     * StringUtils.lastIndexOf("aabaabaa", 'b', -1) = -1
+     * StringUtils.lastIndexOf("aabaabaa", 'a', 0)  = 0
+     * </pre>
+     *
+     * @param seq  the CharSequence to check, may be null
+     * @param searchChar  the character to find
+     * @param startPos  the start position
+     * @return the last index of the search character,
+     *  -1 if no match or {@code null} string input
+     * @since 2.0
+     * @since 3.0 Changed signature from lastIndexOf(String, int, int) to lastIndexOf(CharSequence, int, int)
+     */
+    public static int lastIndexOf(CharSequence seq, int searchChar, int startPos) {
+        if (isEmpty(seq)) {
+            return INDEX_NOT_FOUND;
+        }
+        return CharSequenceUtils.lastIndexOf(seq, searchChar, startPos);
+    }
+
+    /**
+     * <p>Finds the last index within a CharSequence, handling {@code null}.
+     * This method uses {@link String#lastIndexOf(String)} if possible.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.</p>
+     *
+     * <pre>
+     * StringUtils.lastIndexOf(null, *)          = -1
+     * StringUtils.lastIndexOf(*, null)          = -1
+     * StringUtils.lastIndexOf("", "")           = 0
+     * StringUtils.lastIndexOf("aabaabaa", "a")  = 7
+     * StringUtils.lastIndexOf("aabaabaa", "b")  = 5
+     * StringUtils.lastIndexOf("aabaabaa", "ab") = 4
+     * StringUtils.lastIndexOf("aabaabaa", "")   = 8
+     * </pre>
+     *
+     * @param seq  the CharSequence to check, may be null
+     * @param searchSeq  the CharSequence to find, may be null
+     * @return the last index of the search String,
+     *  -1 if no match or {@code null} string input
+     * @since 2.0
+     * @since 3.0 Changed signature from lastIndexOf(String, String) to lastIndexOf(CharSequence, CharSequence)
+     */
+    public static int lastIndexOf(CharSequence seq, CharSequence searchSeq) {
+        if (seq == null || searchSeq == null) {
+            return INDEX_NOT_FOUND;
+        }
+        return CharSequenceUtils.lastIndexOf(seq, searchSeq, seq.length());
+    }
+
+    /**
+     * <p>Finds the n-th last index within a String, handling {@code null}.
+     * This method uses {@link String#lastIndexOf(String)}.</p>
+     *
+     * <p>A {@code null} String will return {@code -1}.</p>
+     *
+     * <pre>
+     * StringUtils.lastOrdinalIndexOf(null, *, *)          = -1
+     * StringUtils.lastOrdinalIndexOf(*, null, *)          = -1
+     * StringUtils.lastOrdinalIndexOf("", "", *)           = 0
+     * StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 1)  = 7
+     * StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 2)  = 6
+     * StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 1)  = 5
+     * StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 2)  = 2
+     * StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 1) = 4
+     * StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 2) = 1
+     * StringUtils.lastOrdinalIndexOf("aabaabaa", "", 1)   = 8
+     * StringUtils.lastOrdinalIndexOf("aabaabaa", "", 2)   = 8
+     * </pre>
+     *
+     * <p>Note that 'tail(CharSequence str, int n)' may be implemented as: </p>
+     *
+     * <pre>
+     *   str.substring(lastOrdinalIndexOf(str, "\n", n) + 1)
+     * </pre>
+     *
+     * @param str  the CharSequence to check, may be null
+     * @param searchStr  the CharSequence to find, may be null
+     * @param ordinal  the n-th last {@code searchStr} to find
+     * @return the n-th last index of the search CharSequence,
+     *  {@code -1} ({@code INDEX_NOT_FOUND}) if no match or {@code null} string input
+     * @since 2.5
+     * @since 3.0 Changed signature from lastOrdinalIndexOf(String, String, int) to lastOrdinalIndexOf(CharSequence, CharSequence, int)
+     */
+    public static int lastOrdinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal) {
+        return ordinalIndexOf(str, searchStr, ordinal, true);
+    }
+
+    /**
+     * <p>Finds the first index within a CharSequence, handling {@code null}.
+     * This method uses {@link String#lastIndexOf(String, int)} if possible.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.
+     * A negative start position returns {@code -1}.
+     * An empty ("") search CharSequence always matches unless the start position is negative.
+     * A start position greater than the string length searches the whole string.</p>
+     *
+     * <pre>
+     * StringUtils.lastIndexOf(null, *, *)          = -1
+     * StringUtils.lastIndexOf(*, null, *)          = -1
+     * StringUtils.lastIndexOf("aabaabaa", "a", 8)  = 7
+     * StringUtils.lastIndexOf("aabaabaa", "b", 8)  = 5
+     * StringUtils.lastIndexOf("aabaabaa", "ab", 8) = 4
+     * StringUtils.lastIndexOf("aabaabaa", "b", 9)  = 5
+     * StringUtils.lastIndexOf("aabaabaa", "b", -1) = -1
+     * StringUtils.lastIndexOf("aabaabaa", "a", 0)  = 0
+     * StringUtils.lastIndexOf("aabaabaa", "b", 0)  = -1
+     * </pre>
+     *
+     * @param seq  the CharSequence to check, may be null
+     * @param searchSeq  the CharSequence to find, may be null
+     * @param startPos  the start position, negative treated as zero
+     * @return the first index of the search CharSequence,
+     *  -1 if no match or {@code null} string input
+     * @since 2.0
+     * @since 3.0 Changed signature from lastIndexOf(String, String, int) to lastIndexOf(CharSequence, CharSequence, int)
+     */
+    public static int lastIndexOf(CharSequence seq, CharSequence searchSeq, int startPos) {
+        if (seq == null || searchSeq == null) {
+            return INDEX_NOT_FOUND;
+        }
+        return CharSequenceUtils.lastIndexOf(seq, searchSeq, startPos);
+    }
+
+    /**
+     * <p>Case in-sensitive find of the last index within a CharSequence.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.
+     * A negative start position returns {@code -1}.
+     * An empty ("") search CharSequence always matches unless the start position is negative.
+     * A start position greater than the string length searches the whole string.</p>
+     *
+     * <pre>
+     * StringUtils.lastIndexOfIgnoreCase(null, *)          = -1
+     * StringUtils.lastIndexOfIgnoreCase(*, null)          = -1
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A")  = 7
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B")  = 5
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB") = 4
+     * </pre>
+     *
+     * @param str  the CharSequence to check, may be null
+     * @param searchStr  the CharSequence to find, may be null
+     * @return the first index of the search CharSequence,
+     *  -1 if no match or {@code null} string input
+     * @since 2.5
+     * @since 3.0 Changed signature from lastIndexOfIgnoreCase(String, String) to lastIndexOfIgnoreCase(CharSequence, CharSequence)
+     */
+    public static int lastIndexOfIgnoreCase(CharSequence str, CharSequence searchStr) {
+        if (str == null || searchStr == null) {
+            return INDEX_NOT_FOUND;
+        }
+        return lastIndexOfIgnoreCase(str, searchStr, str.length());
+    }
+
+    /**
+     * <p>Case in-sensitive find of the last index within a CharSequence
+     * from the specified position.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.
+     * A negative start position returns {@code -1}.
+     * An empty ("") search CharSequence always matches unless the start position is negative.
+     * A start position greater than the string length searches the whole string.</p>
+     *
+     * <pre>
+     * StringUtils.lastIndexOfIgnoreCase(null, *, *)          = -1
+     * StringUtils.lastIndexOfIgnoreCase(*, null, *)          = -1
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 8)  = 7
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 8)  = 5
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB", 8) = 4
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 9)  = 5
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", -1) = -1
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 0)  = 0
+     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 0)  = -1
+     * </pre>
+     *
+     * @param str  the CharSequence to check, may be null
+     * @param searchStr  the CharSequence to find, may be null
+     * @param startPos  the start position
+     * @return the first index of the search CharSequence,
+     *  -1 if no match or {@code null} input
+     * @since 2.5
+     * @since 3.0 Changed signature from lastIndexOfIgnoreCase(String, String, int) to lastIndexOfIgnoreCase(CharSequence, CharSequence, int)
+     */
+    public static int lastIndexOfIgnoreCase(CharSequence str, CharSequence searchStr, int startPos) {
+        if (str == null || searchStr == null) {
+            return INDEX_NOT_FOUND;
+        }
+        if (startPos > str.length() - searchStr.length()) {
+            startPos = str.length() - searchStr.length();
+        }
+        if (startPos < 0) {
+            return INDEX_NOT_FOUND;
+        }
+        if (searchStr.length() == 0) {
+            return startPos;
+        }
+
+        for (int i = startPos; i >= 0; i--) {
+            if (CharSequenceUtils.regionMatches(str, true, i, searchStr, 0, searchStr.length())) {
+                return i;
+            }
+        }
+        return INDEX_NOT_FOUND;
+    }
+
+    // Contains
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Checks if CharSequence contains a search character, handling {@code null}.
+     * This method uses {@link String#indexOf(int)} if possible.</p>
+     *
+     * <p>A {@code null} or empty ("") CharSequence will return {@code false}.</p>
+     *
+     * <pre>
+     * StringUtils.contains(null, *)    = false
+     * StringUtils.contains("", *)      = false
+     * StringUtils.contains("abc", 'a') = true
+     * StringUtils.contains("abc", 'z') = false
+     * </pre>
+     *
+     * @param seq  the CharSequence to check, may be null
+     * @param searchChar  the character to find
+     * @return true if the CharSequence contains the search character,
+     *  false if not or {@code null} string input
+     * @since 2.0
+     * @since 3.0 Changed signature from contains(String, int) to contains(CharSequence, int)
+     */
+    public static boolean contains(CharSequence seq, int searchChar) {
+        if (isEmpty(seq)) {
+            return false;
+        }
+        return CharSequenceUtils.indexOf(seq, searchChar, 0) >= 0;
+    }
+
+    /**
+     * <p>Checks if CharSequence contains a search CharSequence, handling {@code null}.
+     * This method uses {@link String#indexOf(String)} if possible.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code false}.</p>
+     *
+     * <pre>
+     * StringUtils.contains(null, *)     = false
+     * StringUtils.contains(*, null)     = false
+     * StringUtils.contains("", "")      = true
+     * StringUtils.contains("abc", "")   = true
+     * StringUtils.contains("abc", "a")  = true
+     * StringUtils.contains("abc", "z")  = false
+     * </pre>
+     *
+     * @param seq  the CharSequence to check, may be null
+     * @param searchSeq  the CharSequence to find, may be null
+     * @return true if the CharSequence contains the search CharSequence,
+     *  false if not or {@code null} string input
+     * @since 2.0
+     * @since 3.0 Changed signature from contains(String, String) to contains(CharSequence, CharSequence)
+     */
+    public static boolean contains(CharSequence seq, CharSequence searchSeq) {
+        if (seq == null || searchSeq == null) {
+            return false;
+        }
+        return CharSequenceUtils.indexOf(seq, searchSeq, 0) >= 0;
+    }
+
+    /**
+     * <p>Checks if CharSequence contains a search CharSequence irrespective of case,
+     * handling {@code null}. Case-insensitivity is defined as by
+     * {@link String#equalsIgnoreCase(String)}.
+     *
+     * <p>A {@code null} CharSequence will return {@code false}.</p>
+     *
+     * <pre>
+     * StringUtils.contains(null, *) = false
+     * StringUtils.contains(*, null) = false
+     * StringUtils.contains("", "") = true
+     * StringUtils.contains("abc", "") = true
+     * StringUtils.contains("abc", "a") = true
+     * StringUtils.contains("abc", "z") = false
+     * StringUtils.contains("abc", "A") = true
+     * StringUtils.contains("abc", "Z") = false
+     * </pre>
+     *
+     * @param str  the CharSequence to check, may be null
+     * @param searchStr  the CharSequence to find, may be null
+     * @return true if the CharSequence contains the search CharSequence irrespective of
+     * case or false if not or {@code null} string input
+     * @since 3.0 Changed signature from containsIgnoreCase(String, String) to containsIgnoreCase(CharSequence, CharSequence)
+     */
+    public static boolean containsIgnoreCase(CharSequence str, CharSequence searchStr) {
+        if (str == null || searchStr == null) {
+            return false;
+        }
+        int len = searchStr.length();
+        int max = str.length() - len;
+        for (int i = 0; i <= max; i++) {
+            if (CharSequenceUtils.regionMatches(str, true, i, searchStr, 0, len)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Check whether the given CharSequence contains any whitespace characters.
+     * @param seq the CharSequence to check (may be {@code null})
+     * @return {@code true} if the CharSequence is not empty and
+     * contains at least 1 whitespace character
+     * @see java.lang.Character#isWhitespace
+     * @since 3.0
+     */
+    // From org.springframework.util.StringUtils, under Apache License 2.0
+    public static boolean containsWhitespace(CharSequence seq) {
+        if (isEmpty(seq)) {
+            return false;
+        }
+        int strLen = seq.length();
+        for (int i = 0; i < strLen; i++) {
+            if (Character.isWhitespace(seq.charAt(i))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // IndexOfAny chars
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Search a CharSequence to find the first index of any
+     * character in the given set of characters.</p>
+     *
+     * <p>A {@code null} String will return {@code -1}.
+     * A {@code null} or zero length search array will return {@code -1}.</p>
+     *
+     * <pre>
+     * StringUtils.indexOfAny(null, *)                = -1
+     * StringUtils.indexOfAny("", *)                  = -1
+     * StringUtils.indexOfAny(*, null)                = -1
+     * StringUtils.indexOfAny(*, [])                  = -1
+     * StringUtils.indexOfAny("zzabyycdxx",['z','a']) = 0
+     * StringUtils.indexOfAny("zzabyycdxx",['b','y']) = 3
+     * StringUtils.indexOfAny("aba", ['z'])           = -1
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @param searchChars  the chars to search for, may be null
+     * @return the index of any of the chars, -1 if no match or null input
+     * @since 2.0
+     * @since 3.0 Changed signature from indexOfAny(String, char[]) to indexOfAny(CharSequence, char...)
+     */
+    public static int indexOfAny(CharSequence cs, char... searchChars) {
+        if (isEmpty(cs) || ArrayUtils.isEmpty(searchChars)) {
+            return INDEX_NOT_FOUND;
+        }
+        int csLen = cs.length();
+        int csLast = csLen - 1;
+        int searchLen = searchChars.length;
+        int searchLast = searchLen - 1;
+        for (int i = 0; i < csLen; i++) {
+            char ch = cs.charAt(i);
+            for (int j = 0; j < searchLen; j++) {
+                if (searchChars[j] == ch) {
+                    if (i < csLast && j < searchLast && Character.isHighSurrogate(ch)) {
+                        // ch is a supplementary character
+                        if (searchChars[j + 1] == cs.charAt(i + 1)) {
+                            return i;
+                        }
+                    } else {
+                        return i;
+                    }
+                }
+            }
+        }
+        return INDEX_NOT_FOUND;
+    }
+
+    /**
+     * <p>Search a CharSequence to find the first index of any
+     * character in the given set of characters.</p>
+     *
+     * <p>A {@code null} String will return {@code -1}.
+     * A {@code null} search string will return {@code -1}.</p>
+     *
+     * <pre>
+     * StringUtils.indexOfAny(null, *)            = -1
+     * StringUtils.indexOfAny("", *)              = -1
+     * StringUtils.indexOfAny(*, null)            = -1
+     * StringUtils.indexOfAny(*, "")              = -1
+     * StringUtils.indexOfAny("zzabyycdxx", "za") = 0
+     * StringUtils.indexOfAny("zzabyycdxx", "by") = 3
+     * StringUtils.indexOfAny("aba","z")          = -1
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @param searchChars  the chars to search for, may be null
+     * @return the index of any of the chars, -1 if no match or null input
+     * @since 2.0
+     * @since 3.0 Changed signature from indexOfAny(String, String) to indexOfAny(CharSequence, String)
+     */
+    public static int indexOfAny(CharSequence cs, String searchChars) {
+        if (isEmpty(cs) || isEmpty(searchChars)) {
+            return INDEX_NOT_FOUND;
+        }
+        return indexOfAny(cs, searchChars.toCharArray());
+    }
+
+    // ContainsAny
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Checks if the CharSequence contains any character in the given
+     * set of characters.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code false}.
+     * A {@code null} or zero length search array will return {@code false}.</p>
+     *
+     * <pre>
+     * StringUtils.containsAny(null, *)                = false
+     * StringUtils.containsAny("", *)                  = false
+     * StringUtils.containsAny(*, null)                = false
+     * StringUtils.containsAny(*, [])                  = false
+     * StringUtils.containsAny("zzabyycdxx",['z','a']) = true
+     * StringUtils.containsAny("zzabyycdxx",['b','y']) = true
+     * StringUtils.containsAny("aba", ['z'])           = false
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @param searchChars  the chars to search for, may be null
+     * @return the {@code true} if any of the chars are found,
+     * {@code false} if no match or null input
+     * @since 2.4
+     * @since 3.0 Changed signature from containsAny(String, char[]) to containsAny(CharSequence, char...)
+     */
+    public static boolean containsAny(CharSequence cs, char... searchChars) {
+        if (isEmpty(cs) || ArrayUtils.isEmpty(searchChars)) {
+            return false;
+        }
+        int csLength = cs.length();
+        int searchLength = searchChars.length;
+        int csLast = csLength - 1;
+        int searchLast = searchLength - 1;
+        for (int i = 0; i < csLength; i++) {
+            char ch = cs.charAt(i);
+            for (int j = 0; j < searchLength; j++) {
+                if (searchChars[j] == ch) {
+                    if (Character.isHighSurrogate(ch)) {
+                        if (j == searchLast) {
+                            // missing low surrogate, fine, like String.indexOf(String)
+                            return true;
+                        }
+                        if (i < csLast && searchChars[j + 1] == cs.charAt(i + 1)) {
+                            return true;
+                        }
+                    } else {
+                        // ch is in the Basic Multilingual Plane
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * <p>
+     * Checks if the CharSequence contains any character in the given set of characters.
+     * </p>
+     *
+     * <p>
+     * A {@code null} CharSequence will return {@code false}. A {@code null} search CharSequence will return
+     * {@code false}.
+     * </p>
+     *
+     * <pre>
+     * StringUtils.containsAny(null, *)            = false
+     * StringUtils.containsAny("", *)              = false
+     * StringUtils.containsAny(*, null)            = false
+     * StringUtils.containsAny(*, "")              = false
+     * StringUtils.containsAny("zzabyycdxx", "za") = true
+     * StringUtils.containsAny("zzabyycdxx", "by") = true
+     * StringUtils.containsAny("aba","z")          = false
+     * </pre>
+     *
+     * @param cs
+     *            the CharSequence to check, may be null
+     * @param searchChars
+     *            the chars to search for, may be null
+     * @return the {@code true} if any of the chars are found, {@code false} if no match or null input
+     * @since 2.4
+     * @since 3.0 Changed signature from containsAny(String, String) to containsAny(CharSequence, CharSequence)
+     */
+    public static boolean containsAny(CharSequence cs, CharSequence searchChars) {
+        if (searchChars == null) {
+            return false;
+        }
+        return containsAny(cs, CharSequenceUtils.toCharArray(searchChars));
+    }
+
+    // IndexOfAnyBut chars
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Searches a CharSequence to find the first index of any
+     * character not in the given set of characters.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.
+     * A {@code null} or zero length search array will return {@code -1}.</p>
+     *
+     * <pre>
+     * StringUtils.indexOfAnyBut(null, *)                              = -1
+     * StringUtils.indexOfAnyBut("", *)                                = -1
+     * StringUtils.indexOfAnyBut(*, null)                              = -1
+     * StringUtils.indexOfAnyBut(*, [])                                = -1
+     * StringUtils.indexOfAnyBut("zzabyycdxx", new char[] {'z', 'a'} ) = 3
+     * StringUtils.indexOfAnyBut("aba", new char[] {'z'} )             = 0
+     * StringUtils.indexOfAnyBut("aba", new char[] {'a', 'b'} )        = -1
+
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @param searchChars  the chars to search for, may be null
+     * @return the index of any of the chars, -1 if no match or null input
+     * @since 2.0
+     * @since 3.0 Changed signature from indexOfAnyBut(String, char[]) to indexOfAnyBut(CharSequence, char...)
+     */
+    public static int indexOfAnyBut(CharSequence cs, char... searchChars) {
+        if (isEmpty(cs) || ArrayUtils.isEmpty(searchChars)) {
+            return INDEX_NOT_FOUND;
+        }
+        int csLen = cs.length();
+        int csLast = csLen - 1;
+        int searchLen = searchChars.length;
+        int searchLast = searchLen - 1;
+        outer:
+        for (int i = 0; i < csLen; i++) {
+            char ch = cs.charAt(i);
+            for (int j = 0; j < searchLen; j++) {
+                if (searchChars[j] == ch) {
+                    if (i < csLast && j < searchLast && Character.isHighSurrogate(ch)) {
+                        if (searchChars[j + 1] == cs.charAt(i + 1)) {
+                            continue outer;
+                        }
+                    } else {
+                        continue outer;
+                    }
+                }
+            }
+            return i;
+        }
+        return INDEX_NOT_FOUND;
+    }
+
+    /**
+     * <p>Search a CharSequence to find the first index of any
+     * character not in the given set of characters.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.
+     * A {@code null} or empty search string will return {@code -1}.</p>
+     *
+     * <pre>
+     * StringUtils.indexOfAnyBut(null, *)            = -1
+     * StringUtils.indexOfAnyBut("", *)              = -1
+     * StringUtils.indexOfAnyBut(*, null)            = -1
+     * StringUtils.indexOfAnyBut(*, "")              = -1
+     * StringUtils.indexOfAnyBut("zzabyycdxx", "za") = 3
+     * StringUtils.indexOfAnyBut("zzabyycdxx", "")   = -1
+     * StringUtils.indexOfAnyBut("aba","ab")         = -1
+     * </pre>
+     *
+     * @param seq  the CharSequence to check, may be null
+     * @param searchChars  the chars to search for, may be null
+     * @return the index of any of the chars, -1 if no match or null input
+     * @since 2.0
+     * @since 3.0 Changed signature from indexOfAnyBut(String, String) to indexOfAnyBut(CharSequence, CharSequence)
+     */
+    public static int indexOfAnyBut(CharSequence seq, CharSequence searchChars) {
+        if (isEmpty(seq) || isEmpty(searchChars)) {
+            return INDEX_NOT_FOUND;
+        }
+        int strLen = seq.length();
+        for (int i = 0; i < strLen; i++) {
+            char ch = seq.charAt(i);
+            boolean chFound = CharSequenceUtils.indexOf(searchChars, ch, 0) >= 0;
+            if (i + 1 < strLen && Character.isHighSurrogate(ch)) {
+                char ch2 = seq.charAt(i + 1);
+                if (chFound && CharSequenceUtils.indexOf(searchChars, ch2, 0) < 0) {
+                    return i;
+                }
+            } else {
+                if (!chFound) {
+                    return i;
+                }
+            }
+        }
+        return INDEX_NOT_FOUND;
+    }
+
+    // ContainsOnly
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Checks if the CharSequence contains only certain characters.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code false}.
+     * A {@code null} valid character array will return {@code false}.
+     * An empty CharSequence (length()=0) always returns {@code true}.</p>
+     *
+     * <pre>
+     * StringUtils.containsOnly(null, *)       = false
+     * StringUtils.containsOnly(*, null)       = false
+     * StringUtils.containsOnly("", *)         = true
+     * StringUtils.containsOnly("ab", '')      = false
+     * StringUtils.containsOnly("abab", 'abc') = true
+     * StringUtils.containsOnly("ab1", 'abc')  = false
+     * StringUtils.containsOnly("abz", 'abc')  = false
+     * </pre>
+     *
+     * @param cs  the String to check, may be null
+     * @param valid  an array of valid chars, may be null
+     * @return true if it only contains valid chars and is non-null
+     * @since 3.0 Changed signature from containsOnly(String, char[]) to containsOnly(CharSequence, char...)
+     */
+    public static boolean containsOnly(CharSequence cs, char... valid) {
+        // All these pre-checks are to maintain API with an older version
+        if (valid == null || cs == null) {
+            return false;
+        }
+        if (cs.length() == 0) {
+            return true;
+        }
+        if (valid.length == 0) {
+            return false;
+        }
+        return indexOfAnyBut(cs, valid) == INDEX_NOT_FOUND;
+    }
+
+    /**
+     * <p>Checks if the CharSequence contains only certain characters.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code false}.
+     * A {@code null} valid character String will return {@code false}.
+     * An empty String (length()=0) always returns {@code true}.</p>
+     *
+     * <pre>
+     * StringUtils.containsOnly(null, *)       = false
+     * StringUtils.containsOnly(*, null)       = false
+     * StringUtils.containsOnly("", *)         = true
+     * StringUtils.containsOnly("ab", "")      = false
+     * StringUtils.containsOnly("abab", "abc") = true
+     * StringUtils.containsOnly("ab1", "abc")  = false
+     * StringUtils.containsOnly("abz", "abc")  = false
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @param validChars  a String of valid chars, may be null
+     * @return true if it only contains valid chars and is non-null
+     * @since 2.0
+     * @since 3.0 Changed signature from containsOnly(String, String) to containsOnly(CharSequence, String)
+     */
+    public static boolean containsOnly(CharSequence cs, String validChars) {
+        if (cs == null || validChars == null) {
+            return false;
+        }
+        return containsOnly(cs, validChars.toCharArray());
+    }
+
+    // ContainsNone
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Checks that the CharSequence does not contain certain characters.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code true}.
+     * A {@code null} invalid character array will return {@code true}.
+     * An empty CharSequence (length()=0) always returns true.</p>
+     *
+     * <pre>
+     * StringUtils.containsNone(null, *)       = true
+     * StringUtils.containsNone(*, null)       = true
+     * StringUtils.containsNone("", *)         = true
+     * StringUtils.containsNone("ab", '')      = true
+     * StringUtils.containsNone("abab", 'xyz') = true
+     * StringUtils.containsNone("ab1", 'xyz')  = true
+     * StringUtils.containsNone("abz", 'xyz')  = false
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @param searchChars  an array of invalid chars, may be null
+     * @return true if it contains none of the invalid chars, or is null
+     * @since 2.0
+     * @since 3.0 Changed signature from containsNone(String, char[]) to containsNone(CharSequence, char...)
+     */
+    public static boolean containsNone(CharSequence cs, char... searchChars) {
+        if (cs == null || searchChars == null) {
+            return true;
+        }
+        int csLen = cs.length();
+        int csLast = csLen - 1;
+        int searchLen = searchChars.length;
+        int searchLast = searchLen - 1;
+        for (int i = 0; i < csLen; i++) {
+            char ch = cs.charAt(i);
+            for (int j = 0; j < searchLen; j++) {
+                if (searchChars[j] == ch) {
+                    if (Character.isHighSurrogate(ch)) {
+                        if (j == searchLast) {
+                            // missing low surrogate, fine, like String.indexOf(String)
+                            return false;
+                        }
+                        if (i < csLast && searchChars[j + 1] == cs.charAt(i + 1)) {
+                            return false;
+                        }
+                    } else {
+                        // ch is in the Basic Multilingual Plane
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * <p>Checks that the CharSequence does not contain certain characters.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code true}.
+     * A {@code null} invalid character array will return {@code true}.
+     * An empty String ("") always returns true.</p>
+     *
+     * <pre>
+     * StringUtils.containsNone(null, *)       = true
+     * StringUtils.containsNone(*, null)       = true
+     * StringUtils.containsNone("", *)         = true
+     * StringUtils.containsNone("ab", "")      = true
+     * StringUtils.containsNone("abab", "xyz") = true
+     * StringUtils.containsNone("ab1", "xyz")  = true
+     * StringUtils.containsNone("abz", "xyz")  = false
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @param invalidChars  a String of invalid chars, may be null
+     * @return true if it contains none of the invalid chars, or is null
+     * @since 2.0
+     * @since 3.0 Changed signature from containsNone(String, String) to containsNone(CharSequence, String)
+     */
+    public static boolean containsNone(CharSequence cs, String invalidChars) {
+        if (cs == null || invalidChars == null) {
+            return true;
+        }
+        return containsNone(cs, invalidChars.toCharArray());
+    }
+
+    // IndexOfAny strings
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Find the first index of any of a set of potential substrings.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.
+     * A {@code null} or zero length search array will return {@code -1}.
+     * A {@code null} search array entry will be ignored, but a search
+     * array containing "" will return {@code 0} if {@code str} is not
+     * null. This method uses {@link String#indexOf(String)} if possible.</p>
+     *
+     * <pre>
+     * StringUtils.indexOfAny(null, *)                     = -1
+     * StringUtils.indexOfAny(*, null)                     = -1
+     * StringUtils.indexOfAny(*, [])                       = -1
+     * StringUtils.indexOfAny("zzabyycdxx", ["ab","cd"])   = 2
+     * StringUtils.indexOfAny("zzabyycdxx", ["cd","ab"])   = 2
+     * StringUtils.indexOfAny("zzabyycdxx", ["mn","op"])   = -1
+     * StringUtils.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1
+     * StringUtils.indexOfAny("zzabyycdxx", [""])          = 0
+     * StringUtils.indexOfAny("", [""])                    = 0
+     * StringUtils.indexOfAny("", ["a"])                   = -1
+     * </pre>
+     *
+     * @param str  the CharSequence to check, may be null
+     * @param searchStrs  the CharSequences to search for, may be null
+     * @return the first index of any of the searchStrs in str, -1 if no match
+     * @since 3.0 Changed signature from indexOfAny(String, String[]) to indexOfAny(CharSequence, CharSequence...)
+     */
+    public static int indexOfAny(CharSequence str, CharSequence... searchStrs) {
+        if (str == null || searchStrs == null) {
+            return INDEX_NOT_FOUND;
+        }
+        int sz = searchStrs.length;
+
+        // String's can't have a MAX_VALUEth index.
+        int ret = Integer.MAX_VALUE;
+
+        int tmp = 0;
+        for (int i = 0; i < sz; i++) {
+            CharSequence search = searchStrs[i];
+            if (search == null) {
+                continue;
+            }
+            tmp = CharSequenceUtils.indexOf(str, search, 0);
+            if (tmp == INDEX_NOT_FOUND) {
+                continue;
+            }
+
+            if (tmp < ret) {
+                ret = tmp;
+            }
+        }
+
+        return ret == Integer.MAX_VALUE ? INDEX_NOT_FOUND : ret;
+    }
+
+    /**
+     * <p>Find the latest index of any of a set of potential substrings.</p>
+     *
+     * <p>A {@code null} CharSequence will return {@code -1}.
+     * A {@code null} search array will return {@code -1}.
+     * A {@code null} or zero length search array entry will be ignored,
+     * but a search array containing "" will return the length of {@code str}
+     * if {@code str} is not null. This method uses {@link String#indexOf(String)} if possible</p>
+     *
+     * <pre>
+     * StringUtils.lastIndexOfAny(null, *)                   = -1
+     * StringUtils.lastIndexOfAny(*, null)                   = -1
+     * StringUtils.lastIndexOfAny(*, [])                     = -1
+     * StringUtils.lastIndexOfAny(*, [null])                 = -1
+     * StringUtils.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6
+     * StringUtils.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6
+     * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
+     * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
+     * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn",""])   = 10
+     * </pre>
+     *
+     * @param str  the CharSequence to check, may be null
+     * @param searchStrs  the CharSequences to search for, may be null
+     * @return the last index of any of the CharSequences, -1 if no match
+     * @since 3.0 Changed signature from lastIndexOfAny(String, String[]) to lastIndexOfAny(CharSequence, CharSequence)
+     */
+    public static int lastIndexOfAny(CharSequence str, CharSequence... searchStrs) {
+        if (str == null || searchStrs == null) {
+            return INDEX_NOT_FOUND;
+        }
+        int sz = searchStrs.length;
+        int ret = INDEX_NOT_FOUND;
+        int tmp = 0;
+        for (int i = 0; i < sz; i++) {
+            CharSequence search = searchStrs[i];
+            if (search == null) {
+                continue;
+            }
+            tmp = CharSequenceUtils.lastIndexOf(str, search, str.length());
+            if (tmp > ret) {
+                ret = tmp;
+            }
+        }
+        return ret;
+    }
+
+    // Substring
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Gets a substring from the specified String avoiding exceptions.</p>
+     *
+     * <p>A negative start position can be used to start {@code n}
+     * characters from the end of the String.</p>
+     *
+     * <p>A {@code null} String will return {@code null}.
+     * An empty ("") String will return "".</p>
+     *
+     * <pre>
+     * StringUtils.substring(null, *)   = null
+     * StringUtils.substring("", *)     = ""
+     * StringUtils.substring("abc", 0)  = "abc"
+     * StringUtils.substring("abc", 2)  = "c"
+     * StringUtils.substring("abc", 4)  = ""
+     * StringUtils.substring("abc", -2) = "bc"
+     * StringUtils.substring("abc", -4) = "abc"
+     * </pre>
+     *
+     * @param str  the String to get the substring from, may be null
+     * @param start  the position to start from, negative means
+     *  count back from the end of the String by this many characters
+     * @return substring from start position, {@code null} if null String input
+     */
+    public static String substring(String str, int start) {
+        if (str == null) {
+            return null;
+        }
+
+        // handle negatives, which means last n characters
+        if (start < 0) {
+            start = str.length() + start; // remember start is negative
+        }
+
+        if (start < 0) {
+            start = 0;
+        }
+        if (start > str.length()) {
+            return EMPTY;
+        }
+
+        return str.substring(start);
+    }
+
+    /**
+     * <p>Gets a substring from the specified String avoiding exceptions.</p>
+     *
+     * <p>A negative start position can be used to start/end {@code n}
+     * characters from the end of the String.</p>
+     *
+     * <p>The returned substring starts with the character in the {@code start}
+     * position and ends before the {@code end} position. All position counting is
+     * zero-based -- i.e., to start at the beginning of the string use
+     * {@code start = 0}. Negative start and end positions can be used to
+     * specify offsets relative to the end of the String.</p>
+     *
+     * <p>If {@code start} is not strictly to the left of {@code end}, ""
+     * is returned.</p>
+     *
+     * <pre>
+     * StringUtils.substring(null, *, *)    = null
+     * StringUtils.substring("", * ,  *)    = "";
+     * StringUtils.substring("abc", 0, 2)   = "ab"
+     * StringUtils.substring("abc", 2, 0)   = ""
+     * StringUtils.substring("abc", 2, 4)   = "c"
+     * StringUtils.substring("abc", 4, 6)   = ""
+     * StringUtils.substring("abc", 2, 2)   = ""
+     * StringUtils.substring("abc", -2, -1) = "b"
+     * StringUtils.substring("abc", -4, 2)  = "ab"
+     * </pre>
+     *
+     * @param str  the String to get the substring from, may be null
+     * @param start  the position to start from, negative means
+     *  count back from the end of the String by this many characters
+     * @param end  the position to end at (exclusive), negative means
+     *  count back from the end of the String by this many characters
+     * @return substring from start position to end position,
+     *  {@code null} if null String input
+     */
+    public static String substring(String str, int start, int end) {
+        if (str == null) {
+            return null;
+        }
+
+        // handle negatives
+        if (end < 0) {
+            end = str.length() + end; // remember end is negative
+        }
+        if (start < 0) {
+            start = str.length() + start; // remember start is negative
+        }
+
+        // check length next
+        if (end > str.length()) {
+            end = str.length();
+        }
+
+        // if start is greater than end, return ""
+        if (start > end) {
+            return EMPTY;
+        }
+
+        if (start < 0) {
+            start = 0;
+        }
+        if (end < 0) {
+            end = 0;
+        }
+
+        return str.substring(start, end);
+    }
+
+    // Left/Right/Mid
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Gets the leftmost {@code len} characters of a String.</p>
+     *
+     * <p>If {@code len} characters are not available, or the
+     * String is {@code null}, the String will be returned without
+     * an exception. An empty String is returned if len is negative.</p>
+     *
+     * <pre>
+     * StringUtils.left(null, *)    = null
+     * StringUtils.left(*, -ve)     = ""
+     * StringUtils.left("", *)      = ""
+     * StringUtils.left("abc", 0)   = ""
+     * StringUtils.left("abc", 2)   = "ab"
+     * StringUtils.left("abc", 4)   = "abc"
+     * </pre>
+     *
+     * @param str  the String to get the leftmost characters from, may be null
+     * @param len  the length of the required String
+     * @return the leftmost characters, {@code null} if null String input
+     */
+    public static String left(String str, int len) {
+        if (str == null) {
+            return null;
+        }
+        if (len < 0) {
+            return EMPTY;
+        }
+        if (str.length() <= len) {
+            return str;
+        }
+        return str.substring(0, len);
+    }
+
+    /**
+     * <p>Gets the rightmost {@code len} characters of a String.</p>
+     *
+     * <p>If {@code len} characters are not available, or the String
+     * is {@code null}, the String will be returned without an
+     * an exception. An empty String is returned if len is negative.</p>
+     *
+     * <pre>
+     * StringUtils.right(null, *)    = null
+     * StringUtils.right(*, -ve)     = ""
+     * StringUtils.right("", *)      = ""
+     * StringUtils.right("abc", 0)   = ""
+     * StringUtils.right("abc", 2)   = "bc"
+     * StringUtils.right("abc", 4)   = "abc"
+     * </pre>
+     *
+     * @param str  the String to get the rightmost characters from, may be null
+     * @param len  the length of the required String
+     * @return the rightmost characters, {@code null} if null String input
+     */
+    public static String right(String str, int len) {
+        if (str == null) {
+            return null;
+        }
+        if (len < 0) {
+            return EMPTY;
+        }
+        if (str.length() <= len) {
+            return str;
+        }
+        return str.substring(str.length() - len);
+    }
+
+    /**
+     * <p>Gets {@code len} characters from the middle of a String.</p>
+     *
+     * <p>If {@code len} characters are not available, the remainder
+     * of the String will be returned without an exception. If the
+     * String is {@code null}, {@code null} will be returned.
+     * An empty String is returned if len is negative or exceeds the
+     * length of {@code str}.</p>
+     *
+     * <pre>
+     * StringUtils.mid(null, *, *)    = null
+     * StringUtils.mid(*, *, -ve)     = ""
+     * StringUtils.mid("", 0, *)      = ""
+     * StringUtils.mid("abc", 0, 2)   = "ab"
+     * StringUtils.mid("abc", 0, 4)   = "abc"
+     * StringUtils.mid("abc", 2, 4)   = "c"
+     * StringUtils.mid("abc", 4, 2)   = ""
+     * StringUtils.mid("abc", -2, 2)  = "ab"
+     * </pre>
+     *
+     * @param str  the String to get the characters from, may be null
+     * @param pos  the position to start from, negative treated as zero
+     * @param len  the length of the required String
+     * @return the middle characters, {@code null} if null String input
+     */
+    public static String mid(String str, int pos, int len) {
+        if (str == null) {
+            return null;
+        }
+        if (len < 0 || pos > str.length()) {
+            return EMPTY;
+        }
+        if (pos < 0) {
+            pos = 0;
+        }
+        if (str.length() <= pos + len) {
+            return str.substring(pos);
+        }
+        return str.substring(pos, pos + len);
+    }
+
+    // SubStringAfter/SubStringBefore
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Gets the substring before the first occurrence of a separator.
+     * The separator is not returned.</p>
+     *
+     * <p>A {@code null} string input will return {@code null}.
+     * An empty ("") string input will return the empty string.
+     * A {@code null} separator will return the input string.</p>
+     *
+     * <p>If nothing is found, the string input is returned.</p>
+     *
+     * <pre>
+     * StringUtils.substringBefore(null, *)      = null
+     * StringUtils.substringBefore("", *)        = ""
+     * StringUtils.substringBefore("abc", "a")   = ""
+     * StringUtils.substringBefore("abcba", "b") = "a"
+     * StringUtils.substringBefore("abc", "c")   = "ab"
+     * StringUtils.substringBefore("abc", "d")   = "abc"
+     * StringUtils.substringBefore("abc", "")    = ""
+     * StringUtils.substringBefore("abc", null)  = "abc"
+     * </pre>
+     *
+     * @param str  the String to get a substring from, may be null
+     * @param separator  the String to search for, may be null
+     * @return the substring before the first occurrence of the separator,
+     *  {@code null} if null String input
+     * @since 2.0
+     */
+    public static String substringBefore(String str, String separator) {
+        if (isEmpty(str) || separator == null) {
+            return str;
+        }
+        if (separator.length() == 0) {
+            return EMPTY;
+        }
+        int pos = str.indexOf(separator);
+        if (pos == INDEX_NOT_FOUND) {
+            return str;
+        }
+        return str.substring(0, pos);
+    }
+
+    /**
+     * <p>Gets the substring after the first occurrence of a separator.
+     * The separator is not returned.</p>
+     *
+     * <p>A {@code null} string input will return {@code null}.
+     * An empty ("") string input will return the empty string.
+     * A {@code null} separator will return the empty string if the
+     * input string is not {@code null}.</p>
+     *
+     * <p>If nothing is found, the empty string is returned.</p>
+     *
+     * <pre>
+     * StringUtils.substringAfter(null, *)      = null
+     * StringUtils.substringAfter("", *)        = ""
+     * StringUtils.substringAfter(*, null)      = ""
+     * StringUtils.substringAfter("abc", "a")   = "bc"
+     * StringUtils.substringAfter("abcba", "b") = "cba"
+     * StringUtils.substringAfter("abc", "c")   = ""
+     * StringUtils.substringAfter("abc", "d")   = ""
+     * StringUtils.substringAfter("abc", "")    = "abc"
+     * </pre>
+     *
+     * @param str  the String to get a substring from, may be null
+     * @param separator  the String to search for, may be null
+     * @return the substring after the first occurrence of the separator,
+     *  {@code null} if null String input
+     * @since 2.0
+     */
+    public static String substringAfter(String str, String separator) {
+        if (isEmpty(str)) {
+            return str;
+        }
+        if (separator == null) {
+            return EMPTY;
+        }
+        int pos = str.indexOf(separator);
+        if (pos == INDEX_NOT_FOUND) {
+            return EMPTY;
+        }
+        return str.substring(pos + separator.length());
+    }
+
+    /**
+     * <p>Gets the substring before the last occurrence of a separator.
+     * The separator is not returned.</p>
+     *
+     * <p>A {@code null} string input will return {@code null}.
+     * An empty ("") string input will return the empty string.
+     * An empty or {@code null} separator will return the input string.</p>
+     *
+     * <p>If nothing is found, the string input is returned.</p>
+     *
+     * <pre>
+     * StringUtils.substringBeforeLast(null, *)      = null
+     * StringUtils.substringBeforeLast("", *)        = ""
+     * StringUtils.substringBeforeLast("abcba", "b") = "abc"
+     * StringUtils.substringBeforeLast("abc", "c")   = "ab"
+     * StringUtils.substringBeforeLast("a", "a")     = ""
+     * StringUtils.substringBeforeLast("a", "z")     = "a"
+     * StringUtils.substringBeforeLast("a", null)    = "a"
+     * StringUtils.substringBeforeLast("a", "")      = "a"
+     * </pre>
+     *
+     * @param str  the String to get a substring from, may be null
+     * @param separator  the String to search for, may be null
+     * @return the substring before the last occurrence of the separator,
+     *  {@code null} if null String input
+     * @since 2.0
+     */
+    public static String substringBeforeLast(String str, String separator) {
+        if (isEmpty(str) || isEmpty(separator)) {
+            return str;
+        }
+        int pos = str.lastIndexOf(separator);
+        if (pos == INDEX_NOT_FOUND) {
+            return str;
+        }
+        return str.substring(0, pos);
+    }
+
+    /**
+     * <p>Gets the substring after the last occurrence of a separator.
+     * The separator is not returned.</p>
+     *
+     * <p>A {@code null} string input will return {@code null}.
+     * An empty ("") string input will return the empty string.
+     * An empty or {@code null} separator will return the empty string if
+     * the input string is not {@code null}.</p>
+     *
+     * <p>If nothing is found, the empty string is returned.</p>
+     *
+     * <pre>
+     * StringUtils.substringAfterLast(null, *)      = null
+     * StringUtils.substringAfterLast("", *)        = ""
+     * StringUtils.substringAfterLast(*, "")        = ""
+     * StringUtils.substringAfterLast(*, null)      = ""
+     * StringUtils.substringAfterLast("abc", "a")   = "bc"
+     * StringUtils.substringAfterLast("abcba", "b") = "a"
+     * StringUtils.substringAfterLast("abc", "c")   = ""
+     * StringUtils.substringAfterLast("a", "a")     = ""
+     * StringUtils.substringAfterLast("a", "z")     = ""
+     * </pre>
+     *
+     * @param str  the String to get a substring from, may be null
+     * @param separator  the String to search for, may be null
+     * @return the substring after the last occurrence of the separator,
+     *  {@code null} if null String input
+     * @since 2.0
+     */
+    public static String substringAfterLast(String str, String separator) {
+        if (isEmpty(str)) {
+            return str;
+        }
+        if (isEmpty(separator)) {
+            return EMPTY;
+        }
+        int pos = str.lastIndexOf(separator);
+        if (pos == INDEX_NOT_FOUND || pos == str.length() - separator.length()) {
+            return EMPTY;
+        }
+        return str.substring(pos + separator.length());
+    }
+
+    // Substring between
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Gets the String that is nested in between two instances of the
+     * same String.</p>
+     *
+     * <p>A {@code null} input String returns {@code null}.
+     * A {@code null} tag returns {@code null}.</p>
+     *
+     * <pre>
+     * StringUtils.substringBetween(null, *)            = null
+     * StringUtils.substringBetween("", "")             = ""
+     * StringUtils.substringBetween("", "tag")          = null
+     * StringUtils.substringBetween("tagabctag", null)  = null
+     * StringUtils.substringBetween("tagabctag", "")    = ""
+     * StringUtils.substringBetween("tagabctag", "tag") = "abc"
+     * </pre>
+     *
+     * @param str  the String containing the substring, may be null
+     * @param tag  the String before and after the substring, may be null
+     * @return the substring, {@code null} if no match
+     * @since 2.0
+     */
+    public static String substringBetween(String str, String tag) {
+        return substringBetween(str, tag, tag);
+    }
+
+    /**
+     * <p>Gets the String that is nested in between two Strings.
+     * Only the first match is returned.</p>
+     *
+     * <p>A {@code null} input String returns {@code null}.
+     * A {@code null} open/close returns {@code null} (no match).
+     * An empty ("") open and close returns an empty string.</p>
+     *
+     * <pre>
+     * StringUtils.substringBetween("wx[b]yz", "[", "]") = "b"
+     * StringUtils.substringBetween(null, *, *)          = null
+     * StringUtils.substringBetween(*, null, *)          = null
+     * StringUtils.substringBetween(*, *, null)          = null
+     * StringUtils.substringBetween("", "", "")          = ""
+     * StringUtils.substringBetween("", "", "]")         = null
+     * StringUtils.substringBetween("", "[", "]")        = null
+     * StringUtils.substringBetween("yabcz", "", "")     = ""
+     * StringUtils.substringBetween("yabcz", "y", "z")   = "abc"
+     * StringUtils.substringBetween("yabczyabcz", "y", "z")   = "abc"
+     * </pre>
+     *
+     * @param str  the String containing the substring, may be null
+     * @param open  the String before the substring, may be null
+     * @param close  the String after the substring, may be null
+     * @return the substring, {@code null} if no match
+     * @since 2.0
+     */
+    public static String substringBetween(String str, String open, String close) {
+        if (str == null || open == null || close == null) {
+            return null;
+        }
+        int start = str.indexOf(open);
+        if (start != INDEX_NOT_FOUND) {
+            int end = str.indexOf(close, start + open.length());
+            if (end != INDEX_NOT_FOUND) {
+                return str.substring(start + open.length(), end);
+            }
+        }
+        return null;
+    }
+
+
+    // Nested extraction
+    //-----------------------------------------------------------------------
+
+
+    // Joining
+    //-----------------------------------------------------------------------
+
+    /**
+     * <p>Joins the elements of the provided array into a single String
+     * containing the provided list of elements.</p>
+     *
+     * <p>No delimiter is added before or after the list.
+     * Null objects or empty strings within the array are represented by
+     * empty strings.</p>
+     *
+     * <pre>
+     * StringUtils.join(null, *)               = null
+     * StringUtils.join([], *)                 = ""
+     * StringUtils.join([null], *)             = ""
+     * StringUtils.join(["a", "b", "c"], ';')  = "a;b;c"
+     * StringUtils.join(["a", "b", "c"], null) = "abc"
+     * StringUtils.join([null, "", "a"], ';')  = ";;a"
+     * </pre>
+     *
+     * @param array  the array of values to join together, may be null
+     * @param separator  the separator character to use
+     * @return the joined String, {@code null} if null array input
+     * @since 2.0
+     */
+    public static String join(Object[] array, char separator) {
+        if (array == null) {
+            return null;
+        }
+
+        return join(array, separator, 0, array.length);
+    }
+
+    /**
+     * <p>Joins the elements of the provided array into a single String
+     * containing the provided list of elements.</p>
+     *
+     * <p>No delimiter is added before or after the list.
+     * Null objects or empty strings within the array are represented by
+     * empty strings.</p>
+     *
+     * <pre>
+     * StringUtils.join(null, *)               = null
+     * StringUtils.join([], *)                 = ""
+     * StringUtils.join([null], *)             = ""
+     * StringUtils.join(["a", "b", "c"], ';')  = "a;b;c"
+     * StringUtils.join(["a", "b", "c"], null) = "abc"
+     * StringUtils.join([null, "", "a"], ';')  = ";;a"
+     * </pre>
+     *
+     * @param array  the array of values to join together, may be null
+     * @param separator  the separator character to use
+     * @param startIndex the first index to start joining from.  It is
+     * an error to pass in an end index past the end of the array
+     * @param endIndex the index to stop joining from (exclusive). It is
+     * an error to pass in an end index past the end of the array
+     * @return the joined String, {@code null} if null array input
+     * @since 2.0
+     */
+    public static String join(Object[] array, char separator, int startIndex, int endIndex) {
+        if (array == null) {
+            return null;
+        }
+        int noOfItems = endIndex - startIndex;
+        if (noOfItems <= 0) {
+            return EMPTY;
+        }
+        
+        StringBuilder buf = new StringBuilder(noOfItems * 16);
+
+        for (int i = startIndex; i < endIndex; i++) {
+            if (i > startIndex) {
+                buf.append(separator);
+            }
+            if (array[i] != null) {
+                buf.append(array[i]);
+            }
+        }
+        return buf.toString();
+    }
+
+    /**
+     * <p>Joins the elements of the provided array into a single String
+     * containing the provided list of elements.</p>
+     *
+     * <p>No delimiter is added before or after the list.
+     * A {@code null} separator is the same as an empty String ("").
+     * Null objects or empty strings within the array are represented by
+     * empty strings.</p>
+     *
+     * <pre>
+     * StringUtils.join(null, *)                = null
+     * StringUtils.join([], *)                  = ""
+     * StringUtils.join([null], *)              = ""
+     * StringUtils.join(["a", "b", "c"], "--")  = "a--b--c"
+     * StringUtils.join(["a", "b", "c"], null)  = "abc"
+     * StringUtils.join(["a", "b", "c"], "")    = "abc"
+     * StringUtils.join([null, "", "a"], ',')   = ",,a"
+     * </pre>
+     *
+     * @param array  the array of values to join together, may be null
+     * @param separator  the separator character to use, null treated as ""
+     * @return the joined String, {@code null} if null array input
+     */
+    public static String join(Object[] array, String separator) {
+        if (array == null) {
+            return null;
+        }
+        return join(array, separator, 0, array.length);
+    }
+
+    /**
+     * <p>Joins the elements of the provided array into a single String
+     * containing the provided list of elements.</p>
+     *
+     * <p>No delimiter is added before or after the list.
+     * A {@code null} separator is the same as an empty String ("").
+     * Null objects or empty strings within the array are represented by
+     * empty strings.</p>
+     *
+     * <pre>
+     * StringUtils.join(null, *)                = null
+     * StringUtils.join([], *)                  = ""
+     * StringUtils.join([null], *)              = ""
+     * StringUtils.join(["a", "b", "c"], "--")  = "a--b--c"
+     * StringUtils.join(["a", "b", "c"], null)  = "abc"
+     * StringUtils.join(["a", "b", "c"], "")    = "abc"
+     * StringUtils.join([null, "", "a"], ',')   = ",,a"
+     * </pre>
+     *
+     * @param array  the array of values to join together, may be null
+     * @param separator  the separator character to use, null treated as ""
+     * @param startIndex the first index to start joining from.  It is
+     * an error to pass in an end index past the end of the array
+     * @param endIndex the index to stop joining from (exclusive). It is
+     * an error to pass in an end index past the end of the array
+     * @return the joined String, {@code null} if null array input
+     */
+    public static String join(Object[] array, String separator, int startIndex, int endIndex) {
+        if (array == null) {
+            return null;
+        }
+        if (separator == null) {
+            separator = EMPTY;
+        }
+
+        // endIndex - startIndex > 0:   Len = NofStrings *(len(firstString) + len(separator))
+        //           (Assuming that all Strings are roughly equally long)
+        int noOfItems = endIndex - startIndex;
+        if (noOfItems <= 0) {
+            return EMPTY;
+        }
+
+        StringBuilder buf = new StringBuilder(noOfItems * 16);
+
+        for (int i = startIndex; i < endIndex; i++) {
+            if (i > startIndex) {
+                buf.append(separator);
+            }
+            if (array[i] != null) {
+                buf.append(array[i]);
+            }
+        }
+        return buf.toString();
+    }
+
+    /**
+     * <p>Joins the elements of the provided {@code Iterator} into
+     * a single String containing the provided elements.</p>
+     *
+     * <p>No delimiter is added before or after the list. Null objects or empty
+     * strings within the iteration are represented by empty strings.</p>
+     *
+     * <p>See the examples here: {@link #join(Object[],char)}. </p>
+     *
+     * @param iterator  the {@code Iterator} of values to join together, may be null
+     * @param separator  the separator character to use
+     * @return the joined String, {@code null} if null iterator input
+     * @since 2.0
+     */
+    public static String join(Iterator<?> iterator, char separator) {
+
+        // handle null, zero and one elements before building a buffer
+        if (iterator == null) {
+            return null;
+        }
+        if (!iterator.hasNext()) {
+            return EMPTY;
+        }
+        Object first = iterator.next();
+        if (!iterator.hasNext()) {
+            return ObjectUtils.toString(first);
+        }
+
+        // two or more elements
+        StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small
+        if (first != null) {
+            buf.append(first);
+        }
+
+        while (iterator.hasNext()) {
+            buf.append(separator);
+            Object obj = iterator.next();
+            if (obj != null) {
+                buf.append(obj);
+            }
+        }
+
+        return buf.toString();
+    }
+
+    /**
+     * <p>Joins the elements of the provided {@code Iterator} into
+     * a single String containing the provided elements.</p>
+     *
+     * <p>No delimiter is added before or after the list.
+     * A {@code null} separator is the same as an empty String ("").</p>
+     *
+     * <p>See the examples here: {@link #join(Object[],String)}. </p>
+     *
+     * @param iterator  the {@code Iterator} of values to join together, may be null
+     * @param separator  the separator character to use, null treated as ""
+     * @return the joined String, {@code null} if null iterator input
+     */
+    public static String join(Iterator<?> iterator, String separator) {
+
+        // handle null, zero and one elements before building a buffer
+        if (iterator == null) {
+            return null;
+        }
+        if (!iterator.hasNext()) {
+            return EMPTY;
+        }
+        Object first = iterator.next();
+        if (!iterator.hasNext()) {
+            return ObjectUtils.toString(first);
+        }
+
+        // two or more elements
+        StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small
+        if (first != null) {
+            buf.append(first);
+        }
+
+        while (iterator.hasNext()) {
+            if (separator != null) {
+                buf.append(separator);
+            }
+            Object obj = iterator.next();
+            if (obj != null) {
+                buf.append(obj);
+            }
+        }
+        return buf.toString();
+    }
+
+    /**
+     * <p>Joins the elements of the provided {@code Iterable} into
+     * a single String containing the provided elements.</p>
+     *
+     * <p>No delimiter is added before or after the list. Null objects or empty
+     * strings within the iteration are represented by empty strings.</p>
+     *
+     * <p>See the examples here: {@link #join(Object[],char)}. </p>
+     *
+     * @param iterable  the {@code Iterable} providing the values to join together, may be null
+     * @param separator  the separator character to use
+     * @return the joined String, {@code null} if null iterator input
+     * @since 2.3
+     */
+    public static String join(Iterable<?> iterable, char separator) {
+        if (iterable == null) {
+            return null;
+        }
+        return join(iterable.iterator(), separator);
+    }
+
+    /**
+     * <p>Joins the elements of the provided {@code Iterable} into
+     * a single String containing the provided elements.</p>
+     *
+     * <p>No delimiter is added before or after the list.
+     * A {@code null} separator is the same as an empty String ("").</p>
+     *
+     * <p>See the examples here: {@link #join(Object[],String)}. </p>
+     *
+     * @param iterable  the {@code Iterable} providing the values to join together, may be null
+     * @param separator  the separator character to use, null treated as ""
+     * @return the joined String, {@code null} if null iterator input
+     * @since 2.3
+     */
+    public static String join(Iterable<?> iterable, String separator) {
+        if (iterable == null) {
+            return null;
+        }
+        return join(iterable.iterator(), separator);
+    }
+
+    // Delete
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Deletes all whitespaces from a String as defined by
+     * {@link Character#isWhitespace(char)}.</p>
+     *
+     * <pre>
+     * StringUtils.deleteWhitespace(null)         = null
+     * StringUtils.deleteWhitespace("")           = ""
+     * StringUtils.deleteWhitespace("abc")        = "abc"
+     * StringUtils.deleteWhitespace("   ab  c  ") = "abc"
+     * </pre>
+     *
+     * @param str  the String to delete whitespace from, may be null
+     * @return the String without whitespaces, {@code null} if null String input
+     */
+    public static String deleteWhitespace(String str) {
+        if (isEmpty(str)) {
+            return str;
+        }
+        int sz = str.length();
+        char[] chs = new char[sz];
+        int count = 0;
+        for (int i = 0; i < sz; i++) {
+            if (!Character.isWhitespace(str.charAt(i))) {
+                chs[count++] = str.charAt(i);
+            }
+        }
+        if (count == sz) {
+            return str;
+        }
+        return new String(chs, 0, count);
+    }
+
+    // Remove
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Removes a substring only if it is at the beginning of a source string,
+     * otherwise returns the source string.</p>
+     *
+     * <p>A {@code null} source string will return {@code null}.
+     * An empty ("") source string will return the empty string.
+     * A {@code null} search string will return the source string.</p>
+     *
+     * <pre>
+     * StringUtils.removeStart(null, *)      = null
+     * StringUtils.removeStart("", *)        = ""
+     * StringUtils.removeStart(*, null)      = *
+     * StringUtils.removeStart("www.domain.com", "www.")   = "domain.com"
+     * StringUtils.removeStart("domain.com", "www.")       = "domain.com"
+     * StringUtils.removeStart("www.domain.com", "domain") = "www.domain.com"
+     * StringUtils.removeStart("abc", "")    = "abc"
+     * </pre>
+     *
+     * @param str  the source String to search, may be null
+     * @param remove  the String to search for and remove, may be null
+     * @return the substring with the string removed if found,
+     *  {@code null} if null String input
+     * @since 2.1
+     */
+    public static String removeStart(String str, String remove) {
+        if (isEmpty(str) || isEmpty(remove)) {
+            return str;
+        }
+        if (str.startsWith(remove)){
+            return str.substring(remove.length());
+        }
+        return str;
+    }
+
+    /**
+     * <p>Case insensitive removal of a substring if it is at the beginning of a source string,
+     * otherwise returns the source string.</p>
+     *
+     * <p>A {@code null} source string will return {@code null}.
+     * An empty ("") source string will return the empty string.
+     * A {@code null} search string will return the source string.</p>
+     *
+     * <pre>
+     * StringUtils.removeStartIgnoreCase(null, *)      = null
+     * StringUtils.removeStartIgnoreCase("", *)        = ""
+     * StringUtils.removeStartIgnoreCase(*, null)      = *
+     * StringUtils.removeStartIgnoreCase("www.domain.com", "www.")   = "domain.com"
+     * StringUtils.removeStartIgnoreCase("www.domain.com", "WWW.")   = "domain.com"
+     * StringUtils.removeStartIgnoreCase("domain.com", "www.")       = "domain.com"
+     * StringUtils.removeStartIgnoreCase("www.domain.com", "domain") = "www.domain.com"
+     * StringUtils.removeStartIgnoreCase("abc", "")    = "abc"
+     * </pre>
+     *
+     * @param str  the source String to search, may be null
+     * @param remove  the String to search for (case insensitive) and remove, may be null
+     * @return the substring with the string removed if found,
+     *  {@code null} if null String input
+     * @since 2.4
+     */
+    public static String removeStartIgnoreCase(String str, String remove) {
+        if (isEmpty(str) || isEmpty(remove)) {
+            return str;
+        }
+        if (startsWithIgnoreCase(str, remove)) {
+            return str.substring(remove.length());
+        }
+        return str;
+    }
+
+    /**
+     * <p>Removes a substring only if it is at the end of a source string,
+     * otherwise returns the source string.</p>
+     *
+     * <p>A {@code null} source string will return {@code null}.
+     * An empty ("") source string will return the empty string.
+     * A {@code null} search string will return the source string.</p>
+     *
+     * <pre>
+     * StringUtils.removeEnd(null, *)      = null
+     * StringUtils.removeEnd("", *)        = ""
+     * StringUtils.removeEnd(*, null)      = *
+     * StringUtils.removeEnd("www.domain.com", ".com.")  = "www.domain.com"
+     * StringUtils.removeEnd("www.domain.com", ".com")   = "www.domain"
+     * StringUtils.removeEnd("www.domain.com", "domain") = "www.domain.com"
+     * StringUtils.removeEnd("abc", "")    = "abc"
+     * </pre>
+     *
+     * @param str  the source String to search, may be null
+     * @param remove  the String to search for and remove, may be null
+     * @return the substring with the string removed if found,
+     *  {@code null} if null String input
+     * @since 2.1
+     */
+    public static String removeEnd(String str, String remove) {
+        if (isEmpty(str) || isEmpty(remove)) {
+            return str;
+        }
+        if (str.endsWith(remove)) {
+            return str.substring(0, str.length() - remove.length());
+        }
+        return str;
+    }
+
+    /**
+     * <p>Case insensitive removal of a substring if it is at the end of a source string,
+     * otherwise returns the source string.</p>
+     *
+     * <p>A {@code null} source string will return {@code null}.
+     * An empty ("") source string will return the empty string.
+     * A {@code null} search string will return the source string.</p>
+     *
+     * <pre>
+     * StringUtils.removeEndIgnoreCase(null, *)      = null
+     * StringUtils.removeEndIgnoreCase("", *)        = ""
+     * StringUtils.removeEndIgnoreCase(*, null)      = *
+     * StringUtils.removeEndIgnoreCase("www.domain.com", ".com.")  = "www.domain.com"
+     * StringUtils.removeEndIgnoreCase("www.domain.com", ".com")   = "www.domain"
+     * StringUtils.removeEndIgnoreCase("www.domain.com", "domain") = "www.domain.com"
+     * StringUtils.removeEndIgnoreCase("abc", "")    = "abc"
+     * StringUtils.removeEndIgnoreCase("www.domain.com", ".COM") = "www.domain")
+     * StringUtils.removeEndIgnoreCase("www.domain.COM", ".com") = "www.domain")
+     * </pre>
+     *
+     * @param str  the source String to search, may be null
+     * @param remove  the String to search for (case insensitive) and remove, may be null
+     * @return the substring with the string removed if found,
+     *  {@code null} if null String input
+     * @since 2.4
+     */
+    public static String removeEndIgnoreCase(String str, String remove) {
+        if (isEmpty(str) || isEmpty(remove)) {
+            return str;
+        }
+        if (endsWithIgnoreCase(str, remove)) {
+            return str.substring(0, str.length() - remove.length());
+        }
+        return str;
+    }
+
+    /**
+     * <p>Removes all occurrences of a substring from within the source string.</p>
+     *
+     * <p>A {@code null} source string will return {@code null}.
+     * An empty ("") source string will return the empty string.
+     * A {@code null} remove string will return the source string.
+     * An empty ("") remove string will return the source string.</p>
+     *
+     * <pre>
+     * StringUtils.remove(null, *)        = null
+     * StringUtils.remove("", *)          = ""
+     * StringUtils.remove(*, null)        = *
+     * StringUtils.remove(*, "")          = *
+     * StringUtils.remove("queued", "ue") = "qd"
+     * StringUtils.remove("queued", "zz") = "queued"
+     * </pre>
+     *
+     * @param str  the source String to search, may be null
+     * @param remove  the String to search for and remove, may be null
+     * @return the substring with the string removed if found,
+     *  {@code null} if null String input
+     * @since 2.1
+     */
+    public static String remove(String str, String remove) {
+        if (isEmpty(str) || isEmpty(remove)) {
+            return str;
+        }
+        return replace(str, remove, EMPTY, -1);
+    }
+
+    /**
+     * <p>Removes all occurrences of a character from within the source string.</p>
+     *
+     * <p>A {@code null} source string will return {@code null}.
+     * An empty ("") source string will return the empty string.</p>
+     *
+     * <pre>
+     * StringUtils.remove(null, *)       = null
+     * StringUtils.remove("", *)         = ""
+     * StringUtils.remove("queued", 'u') = "qeed"
+     * StringUtils.remove("queued", 'z') = "queued"
+     * </pre>
+     *
+     * @param str  the source String to search, may be null
+     * @param remove  the char to search for and remove, may be null
+     * @return the substring with the char removed if found,
+     *  {@code null} if null String input
+     * @since 2.1
+     */
+    public static String remove(String str, char remove) {
+        if (isEmpty(str) || str.indexOf(remove) == INDEX_NOT_FOUND) {
+            return str;
+        }
+        char[] chars = str.toCharArray();
+        int pos = 0;
+        for (int i = 0; i < chars.length; i++) {
+            if (chars[i] != remove) {
+                chars[pos++] = chars[i];
+            }
+        }
+        return new String(chars, 0, pos);
+    }
+
+    // Replacing
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Replaces a String with another String inside a larger String, once.</p>
+     *
+     * <p>A {@code null} reference passed to this method is a no-op.</p>
+     *
+     * <pre>
+     * StringUtils.replaceOnce(null, *, *)        = null
+     * StringUtils.replaceOnce("", *, *)          = ""
+     * StringUtils.replaceOnce("any", null, *)    = "any"
+     * StringUtils.replaceOnce("any", *, null)    = "any"
+     * StringUtils.replaceOnce("any", "", *)      = "any"
+     * StringUtils.replaceOnce("aba", "a", null)  = "aba"
+     * StringUtils.replaceOnce("aba", "a", "")    = "ba"
+     * StringUtils.replaceOnce("aba", "a", "z")   = "zba"
+     * </pre>
+     *
+     * @see #replace(String text, String searchString, String replacement, int max)
+     * @param text  text to search and replace in, may be null
+     * @param searchString  the String to search for, may be null
+     * @param replacement  the String to replace with, may be null
+     * @return the text with any replacements processed,
+     *  {@code null} if null String input
+     */
+    public static String replaceOnce(String text, String searchString, String replacement) {
+        return replace(text, searchString, replacement, 1);
+    }
+
+    /**
+     * <p>Replaces all occurrences of a String within another String.</p>
+     *
+     * <p>A {@code null} reference passed to this method is a no-op.</p>
+     *
+     * <pre>
+     * StringUtils.replace(null, *, *)        = null
+     * StringUtils.replace("", *, *)          = ""
+     * StringUtils.replace("any", null, *)    = "any"
+     * StringUtils.replace("any", *, null)    = "any"
+     * StringUtils.replace("any", "", *)      = "any"
+     * StringUtils.replace("aba", "a", null)  = "aba"
+     * StringUtils.replace("aba", "a", "")    = "b"
+     * StringUtils.replace("aba", "a", "z")   = "zbz"
+     * </pre>
+     *
+     * @see #replace(String text, String searchString, String replacement, int max)
+     * @param text  text to search and replace in, may be null
+     * @param searchString  the String to search for, may be null
+     * @param replacement  the String to replace it with, may be null
+     * @return the text with any replacements processed,
+     *  {@code null} if null String input
+     */
+    public static String replace(String text, String searchString, String replacement) {
+        return replace(text, searchString, replacement, -1);
+    }
+
+    /**
+     * <p>Replaces a String with another String inside a larger String,
+     * for the first {@code max} values of the search String.</p>
+     *
+     * <p>A {@code null} reference passed to this method is a no-op.</p>
+     *
+     * <pre>
+     * StringUtils.replace(null, *, *, *)         = null
+     * StringUtils.replace("", *, *, *)           = ""
+     * StringUtils.replace("any", null, *, *)     = "any"
+     * StringUtils.replace("any", *, null, *)     = "any"
+     * StringUtils.replace("any", "", *, *)       = "any"
+     * StringUtils.replace("any", *, *, 0)        = "any"
+     * StringUtils.replace("abaa", "a", null, -1) = "abaa"
+     * StringUtils.replace("abaa", "a", "", -1)   = "b"
+     * StringUtils.replace("abaa", "a", "z", 0)   = "abaa"
+     * StringUtils.replace("abaa", "a", "z", 1)   = "zbaa"
+     * StringUtils.replace("abaa", "a", "z", 2)   = "zbza"
+     * StringUtils.replace("abaa", "a", "z", -1)  = "zbzz"
+     * </pre>
+     *
+     * @param text  text to search and replace in, may be null
+     * @param searchString  the String to search for, may be null
+     * @param replacement  the String to replace it with, may be null
+     * @param max  maximum number of values to replace, or {@code -1} if no maximum
+     * @return the text with any replacements processed,
+     *  {@code null} if null String input
+     */
+    public static String replace(String text, String searchString, String replacement, int max) {
+        if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {
+            return text;
+        }
+        int start = 0;
+        int end = text.indexOf(searchString, start);
+        if (end == INDEX_NOT_FOUND) {
+            return text;
+        }
+        int replLength = searchString.length();
+        int increase = replacement.length() - replLength;
+        increase = increase < 0 ? 0 : increase;
+        increase *= max < 0 ? 16 : max > 64 ? 64 : max;
+        StringBuilder buf = new StringBuilder(text.length() + increase);
+        while (end != INDEX_NOT_FOUND) {
+            buf.append(text.substring(start, end)).append(replacement);
+            start = end + replLength;
+            if (--max == 0) {
+                break;
+            }
+            end = text.indexOf(searchString, start);
+        }
+        buf.append(text.substring(start));
+        return buf.toString();
+    }
+
+    /**
+     * <p>
+     * Replaces all occurrences of Strings within another String.
+     * </p>
+     *
+     * <p>
+     * A {@code null} reference passed to this method is a no-op, or if
+     * any "search string" or "string to replace" is null, that replace will be
+     * ignored. This will not repeat. For repeating replaces, call the
+     * overloaded method.
+     * </p>
+     *
+     * <pre>
+     *  StringUtils.replaceEach(null, *, *)        = null
+     *  StringUtils.replaceEach("", *, *)          = ""
+     *  StringUtils.replaceEach("aba", null, null) = "aba"
+     *  StringUtils.replaceEach("aba", new String[0], null) = "aba"
+     *  StringUtils.replaceEach("aba", null, new String[0]) = "aba"
+     *  StringUtils.replaceEach("aba", new String[]{"a"}, null)  = "aba"
+     *  StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""})  = "b"
+     *  StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"})  = "aba"
+     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"})  = "wcte"
+     *  (example of how it does not repeat)
+     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"})  = "dcte"
+     * </pre>
+     *
+     * @param text
+     *            text to search and replace in, no-op if null
+     * @param searchList
+     *            the Strings to search for, no-op if null
+     * @param replacementList
+     *            the Strings to replace them with, no-op if null
+     * @return the text with any replacements processed, {@code null} if
+     *         null String input
+     * @throws IllegalArgumentException
+     *             if the lengths of the arrays are not the same (null is ok,
+     *             and/or size 0)
+     * @since 2.4
+     */
+    public static String replaceEach(String text, String[] searchList, String[] replacementList) {
+        return replaceEach(text, searchList, replacementList, false, 0);
+    }
+
+    /**
+     * <p>
+     * Replaces all occurrences of Strings within another String.
+     * </p>
+     *
+     * <p>
+     * A {@code null} reference passed to this method is a no-op, or if
+     * any "search string" or "string to replace" is null, that replace will be
+     * ignored. 
+     * </p>
+     *
+     * <pre>
+     *  StringUtils.replaceEach(null, *, *, *) = null
+     *  StringUtils.replaceEach("", *, *, *) = ""
+     *  StringUtils.replaceEach("aba", null, null, *) = "aba"
+     *  StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
+     *  StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
+     *  StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
+     *  StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = "b"
+     *  StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
+     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}, *) = "wcte"
+     *  (example of how it repeats)
+     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, false) = "dcte"
+     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, true) = "tcte"
+     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, true) = IllegalStateException
+     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, false) = "dcabe"
+     * </pre>
+     *
+     * @param text
+     *            text to search and replace in, no-op if null
+     * @param searchList
+     *            the Strings to search for, no-op if null
+     * @param replacementList
+     *            the Strings to replace them with, no-op if null
+     * @return the text with any replacements processed, {@code null} if
+     *         null String input
+     * @throws IllegalStateException
+     *             if the search is repeating and there is an endless loop due
+     *             to outputs of one being inputs to another
+     * @throws IllegalArgumentException
+     *             if the lengths of the arrays are not the same (null is ok,
+     *             and/or size 0)
+     * @since 2.4
+     */
+    public static String replaceEachRepeatedly(String text, String[] searchList, String[] replacementList) {
+        // timeToLive should be 0 if not used or nothing to replace, else it's
+        // the length of the replace array
+        int timeToLive = searchList == null ? 0 : searchList.length;
+        return replaceEach(text, searchList, replacementList, true, timeToLive);
+    }
+
+    /**
+     * <p>
+     * Replaces all occurrences of Strings within another String.
+     * </p>
+     *
+     * <p>
+     * A {@code null} reference passed to this method is a no-op, or if
+     * any "search string" or "string to replace" is null, that replace will be
+     * ignored.
+     * </p>
+     *
+     * <pre>
+     *  StringUtils.replaceEach(null, *, *, *) = null
+     *  StringUtils.replaceEach("", *, *, *) = ""
+     *  StringUtils.replaceEach("aba", null, null, *) = "aba"
+     *  StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
+     *  StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
+     *  StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
+     *  StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = "b"
+     *  StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
+     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}, *) = "wcte"
+     *  (example of how it repeats)
+     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, false) = "dcte"
+     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, true) = "tcte"
+     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, *) = IllegalStateException
+     * </pre>
+     *
+     * @param text
+     *            text to search and replace in, no-op if null
+     * @param searchList
+     *            the Strings to search for, no-op if null
+     * @param replacementList
+     *            the Strings to replace them with, no-op if null
+     * @param repeat if true, then replace repeatedly
+     *       until there are no more possible replacements or timeToLive < 0
+     * @param timeToLive
+     *            if less than 0 then there is a circular reference and endless
+     *            loop
+     * @return the text with any replacements processed, {@code null} if
+     *         null String input
+     * @throws IllegalStateException
+     *             if the search is repeating and there is an endless loop due
+     *             to outputs of one being inputs to another
+     * @throws IllegalArgumentException
+     *             if the lengths of the arrays are not the same (null is ok,
+     *             and/or size 0)
+     * @since 2.4
+     */
+    private static String replaceEach(
+            String text, String[] searchList, String[] replacementList, boolean repeat, int timeToLive) {
+
+        // mchyzer Performance note: This creates very few new objects (one major goal)
+        // let me know if there are performance requests, we can create a harness to measure
+
+        if (text == null || text.length() == 0 || searchList == null ||
+                searchList.length == 0 || replacementList == null || replacementList.length == 0) {
+            return text;
+        }
+
+        // if recursing, this shouldn't be less than 0
+        if (timeToLive < 0) {
+            throw new IllegalStateException("Aborting to protect against StackOverflowError - " +
+                                            "output of one loop is the input of another");
+        }
+
+        int searchLength = searchList.length;
+        int replacementLength = replacementList.length;
+
+        // make sure lengths are ok, these need to be equal
+        if (searchLength != replacementLength) {
+            throw new IllegalArgumentException("Search and Replace array lengths don't match: "
+                + searchLength
+                + " vs "
+                + replacementLength);
+        }
+
+        // keep track of which still have matches
+        boolean[] noMoreMatchesForReplIndex = new boolean[searchLength];
+
+        // index on index that the match was found
+        int textIndex = -1;
+        int replaceIndex = -1;
+        int tempIndex = -1;
+
+        // index of replace array that will replace the search string found
+        // NOTE: logic duplicated below START
+        for (int i = 0; i < searchLength; i++) {
+            if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
+                    searchList[i].length() == 0 || replacementList[i] == null) {
+                continue;
+            }
+            tempIndex = text.indexOf(searchList[i]);
+
+            // see if we need to keep searching for this
+            if (tempIndex == -1) {
+                noMoreMatchesForReplIndex[i] = true;
+            } else {
+                if (textIndex == -1 || tempIndex < textIndex) {
+                    textIndex = tempIndex;
+                    replaceIndex = i;
+                }
+            }
+        }
+        // NOTE: logic mostly below END
+
+        // no search strings found, we are done
+        if (textIndex == -1) {
+            return text;
+        }
+
+        int start = 0;
+
+        // get a good guess on the size of the result buffer so it doesn't have to double if it goes over a bit
+        int increase = 0;
+
+        // count the replacement text elements that are larger than their corresponding text being replaced
+        for (int i = 0; i < searchList.length; i++) {
+            if (searchList[i] == null || replacementList[i] == null) {
+                continue;
+            }
+            int greater = replacementList[i].length() - searchList[i].length();
+            if (greater > 0) {
+                increase += 3 * greater; // assume 3 matches
+            }
+        }
+        // have upper-bound at 20% increase, then let Java take over
+        increase = Math.min(increase, text.length() / 5);
+
+        StringBuilder buf = new StringBuilder(text.length() + increase);
+
+        while (textIndex != -1) {
+
+            for (int i = start; i < textIndex; i++) {
+                buf.append(text.charAt(i));
+            }
+            buf.append(replacementList[replaceIndex]);
+
+            start = textIndex + searchList[replaceIndex].length();
+
+            textIndex = -1;
+            replaceIndex = -1;
+            tempIndex = -1;
+            // find the next earliest match
+            // NOTE: logic mostly duplicated above START
+            for (int i = 0; i < searchLength; i++) {
+                if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
+                        searchList[i].length() == 0 || replacementList[i] == null) {
+                    continue;
+                }
+                tempIndex = text.indexOf(searchList[i], start);
+
+                // see if we need to keep searching for this
+                if (tempIndex == -1) {
+                    noMoreMatchesForReplIndex[i] = true;
+                } else {
+                    if (textIndex == -1 || tempIndex < textIndex) {
+                        textIndex = tempIndex;
+                        replaceIndex = i;
+                    }
+                }
+            }
+            // NOTE: logic duplicated above END
+
+        }
+        int textLength = text.length();
+        for (int i = start; i < textLength; i++) {
+            buf.append(text.charAt(i));
+        }
+        String result = buf.toString();
+        if (!repeat) {
+            return result;
+        }
+
+        return replaceEach(result, searchList, replacementList, repeat, timeToLive - 1);
+    }
+
+    // Replace, character based
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Replaces all occurrences of a character in a String with another.
+     * This is a null-safe version of {@link String#replace(char, char)}.</p>
+     *
+     * <p>A {@code null} string input returns {@code null}.
+     * An empty ("") string input returns an empty string.</p>
+     *
+     * <pre>
+     * StringUtils.replaceChars(null, *, *)        = null
+     * StringUtils.replaceChars("", *, *)          = ""
+     * StringUtils.replaceChars("abcba", 'b', 'y') = "aycya"
+     * StringUtils.replaceChars("abcba", 'z', 'y') = "abcba"
+     * </pre>
+     *
+     * @param str  String to replace characters in, may be null
+     * @param searchChar  the character to search for, may be null
+     * @param replaceChar  the character to replace, may be null
+     * @return modified String, {@code null} if null string input
+     * @since 2.0
+     */
+    public static String replaceChars(String str, char searchChar, char replaceChar) {
+        if (str == null) {
+            return null;
+        }
+        return str.replace(searchChar, replaceChar);
+    }
+
+    /**
+     * <p>Replaces multiple characters in a String in one go.
+     * This method can also be used to delete characters.</p>
+     *
+     * <p>For example:<br />
+     * <code>replaceChars(&quot;hello&quot;, &quot;ho&quot;, &quot;jy&quot;) = jelly</code>.</p>
+     *
+     * <p>A {@code null} string input returns {@code null}.
+     * An empty ("") string input returns an empty string.
+     * A null or empty set of search characters returns the input string.</p>
+     *
+     * <p>The length of the search characters should normally equal the length
+     * of the replace characters.
+     * If the search characters is longer, then the extra search characters
+     * are deleted.
+     * If the search characters is shorter, then the extra replace characters
+     * are ignored.</p>
+     *
+     * <pre>
+     * StringUtils.replaceChars(null, *, *)           = null
+     * StringUtils.replaceChars("", *, *)             = ""
+     * StringUtils.replaceChars("abc", null, *)       = "abc"
+     * StringUtils.replaceChars("abc", "", *)         = "abc"
+     * StringUtils.replaceChars("abc", "b", null)     = "ac"
+     * StringUtils.replaceChars("abc", "b", "")       = "ac"
+     * StringUtils.replaceChars("abcba", "bc", "yz")  = "ayzya"
+     * StringUtils.replaceChars("abcba", "bc", "y")   = "ayya"
+     * StringUtils.replaceChars("abcba", "bc", "yzx") = "ayzya"
+     * </pre>
+     *
+     * @param str  String to replace characters in, may be null
+     * @param searchChars  a set of characters to search for, may be null
+     * @param replaceChars  a set of characters to replace, may be null
+     * @return modified String, {@code null} if null string input
+     * @since 2.0
+     */
+    public static String replaceChars(String str, String searchChars, String replaceChars) {
+        if (isEmpty(str) || isEmpty(searchChars)) {
+            return str;
+        }
+        if (replaceChars == null) {
+            replaceChars = EMPTY;
+        }
+        boolean modified = false;
+        int replaceCharsLength = replaceChars.length();
+        int strLength = str.length();
+        StringBuilder buf = new StringBuilder(strLength);
+        for (int i = 0; i < strLength; i++) {
+            char ch = str.charAt(i);
+            int index = searchChars.indexOf(ch);
+            if (index >= 0) {
+                modified = true;
+                if (index < replaceCharsLength) {
+                    buf.append(replaceChars.charAt(index));
+                }
+            } else {
+                buf.append(ch);
+            }
+        }
+        if (modified) {
+            return buf.toString();
+        }
+        return str;
+    }
+
+    // Overlay
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Overlays part of a String with another String.</p>
+     *
+     * <p>A {@code null} string input returns {@code null}.
+     * A negative index is treated as zero.
+     * An index greater than the string length is treated as the string length.
+     * The start index is always the smaller of the two indices.</p>
+     *
+     * <pre>
+     * StringUtils.overlay(null, *, *, *)            = null
+     * StringUtils.overlay("", "abc", 0, 0)          = "abc"
+     * StringUtils.overlay("abcdef", null, 2, 4)     = "abef"
+     * StringUtils.overlay("abcdef", "", 2, 4)       = "abef"
+     * StringUtils.overlay("abcdef", "", 4, 2)       = "abef"
+     * StringUtils.overlay("abcdef", "zzzz", 2, 4)   = "abzzzzef"
+     * StringUtils.overlay("abcdef", "zzzz", 4, 2)   = "abzzzzef"
+     * StringUtils.overlay("abcdef", "zzzz", -1, 4)  = "zzzzef"
+     * StringUtils.overlay("abcdef", "zzzz", 2, 8)   = "abzzzz"
+     * StringUtils.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"
+     * StringUtils.overlay("abcdef", "zzzz", 8, 10)  = "abcdefzzzz"
+     * </pre>
+     *
+     * @param str  the String to do overlaying in, may be null
+     * @param overlay  the String to overlay, may be null
+     * @param start  the position to start overlaying at
+     * @param end  the position to stop overlaying before
+     * @return overlayed String, {@code null} if null String input
+     * @since 2.0
+     */
+    public static String overlay(String str, String overlay, int start, int end) {
+        if (str == null) {
+            return null;
+        }
+        if (overlay == null) {
+            overlay = EMPTY;
+        }
+        int len = str.length();
+        if (start < 0) {
+            start = 0;
+        }
+        if (start > len) {
+            start = len;
+        }
+        if (end < 0) {
+            end = 0;
+        }
+        if (end > len) {
+            end = len;
+        }
+        if (start > end) {
+            int temp = start;
+            start = end;
+            end = temp;
+        }
+        return new StringBuilder(len + start - end + overlay.length() + 1)
+            .append(str.substring(0, start))
+            .append(overlay)
+            .append(str.substring(end))
+            .toString();
+    }
+
+    // Chomping
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Removes one newline from end of a String if it's there,
+     * otherwise leave it alone.  A newline is &quot;{@code \n}&quot;,
+     * &quot;{@code \r}&quot;, or &quot;{@code \r\n}&quot;.</p>
+     *
+     * <p>NOTE: This method changed in 2.0.
+     * It now more closely matches Perl chomp.</p>
+     *
+     * <pre>
+     * StringUtils.chomp(null)          = null
+     * StringUtils.chomp("")            = ""
+     * StringUtils.chomp("abc \r")      = "abc "
+     * StringUtils.chomp("abc\n")       = "abc"
+     * StringUtils.chomp("abc\r\n")     = "abc"
+     * StringUtils.chomp("abc\r\n\r\n") = "abc\r\n"
+     * StringUtils.chomp("abc\n\r")     = "abc\n"
+     * StringUtils.chomp("abc\n\rabc")  = "abc\n\rabc"
+     * StringUtils.chomp("\r")          = ""
+     * StringUtils.chomp("\n")          = ""
+     * StringUtils.chomp("\r\n")        = ""
+     * </pre>
+     *
+     * @param str  the String to chomp a newline from, may be null
+     * @return String without newline, {@code null} if null String input
+     */
+    public static String chomp(String str) { // NO_UCD
+        if (isEmpty(str)) {
+            return str;
+        }
+
+        if (str.length() == 1) {
+            char ch = str.charAt(0);
+            if (ch == CharUtils.CR || ch == CharUtils.LF) {
+                return EMPTY;
+            }
+            return str;
+        }
+
+        int lastIdx = str.length() - 1;
+        char last = str.charAt(lastIdx);
+
+        if (last == CharUtils.LF) {
+            if (str.charAt(lastIdx - 1) == CharUtils.CR) {
+                lastIdx--;
+            }
+        } else if (last != CharUtils.CR) {
+            lastIdx++;
+        }
+        return str.substring(0, lastIdx);
+    }
+
+    /**
+     * <p>Removes {@code separator} from the end of
+     * {@code str} if it's there, otherwise leave it alone.</p>
+     *
+     * <p>NOTE: This method changed in version 2.0.
+     * It now more closely matches Perl chomp.
+     * For the previous behavior, use {@link #substringBeforeLast(String, String)}.
+     * This method uses {@link String#endsWith(String)}.</p>
+     *
+     * <pre>
+     * StringUtils.chomp(null, *)         = null
+     * StringUtils.chomp("", *)           = ""
+     * StringUtils.chomp("foobar", "bar") = "foo"
+     * StringUtils.chomp("foobar", "baz") = "foobar"
+     * StringUtils.chomp("foo", "foo")    = ""
+     * StringUtils.chomp("foo ", "foo")   = "foo "
+     * StringUtils.chomp(" foo", "foo")   = " "
+     * StringUtils.chomp("foo", "foooo")  = "foo"
+     * StringUtils.chomp("foo", "")       = "foo"
+     * StringUtils.chomp("foo", null)     = "foo"
+     * </pre>
+     *
+     * @param str  the String to chomp from, may be null
+     * @param separator  separator String, may be null
+     * @return String without trailing separator, {@code null} if null String input
+     * @deprecated This feature will be removed in Lang 4.0, use {@link StringUtils#removeEnd(String, String)} instead
+     */
+    @Deprecated
+    public static String chomp(String str, String separator) {
+        return removeEnd(str,separator);
+    }
+
+    // Chopping
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Remove the last character from a String.</p>
+     *
+     * <p>If the String ends in {@code \r\n}, then remove both
+     * of them.</p>
+     *
+     * <pre>
+     * StringUtils.chop(null)          = null
+     * StringUtils.chop("")            = ""
+     * StringUtils.chop("abc \r")      = "abc "
+     * StringUtils.chop("abc\n")       = "abc"
+     * StringUtils.chop("abc\r\n")     = "abc"
+     * StringUtils.chop("abc")         = "ab"
+     * StringUtils.chop("abc\nabc")    = "abc\nab"
+     * StringUtils.chop("a")           = ""
+     * StringUtils.chop("\r")          = ""
+     * StringUtils.chop("\n")          = ""
+     * StringUtils.chop("\r\n")        = ""
+     * </pre>
+     *
+     * @param str  the String to chop last character from, may be null
+     * @return String without last character, {@code null} if null String input
+     */
+    public static String chop(String str) { // NO_UCD
+        if (str == null) {
+            return null;
+        }
+        int strLen = str.length();
+        if (strLen < 2) {
+            return EMPTY;
+        }
+        int lastIdx = strLen - 1;
+        String ret = str.substring(0, lastIdx);
+        char last = str.charAt(lastIdx);
+        if (last == CharUtils.LF && ret.charAt(lastIdx - 1) == CharUtils.CR) {
+            return ret.substring(0, lastIdx - 1);
+        }
+        return ret;
+    }
+
+    // Conversion
+    //-----------------------------------------------------------------------
+
+    // Padding
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Repeat a String {@code repeat} times to form a
+     * new String.</p>
+     *
+     * <pre>
+     * StringUtils.repeat(null, 2) = null
+     * StringUtils.repeat("", 0)   = ""
+     * StringUtils.repeat("", 2)   = ""
+     * StringUtils.repeat("a", 3)  = "aaa"
+     * StringUtils.repeat("ab", 2) = "abab"
+     * StringUtils.repeat("a", -2) = ""
+     * </pre>
+     *
+     * @param str  the String to repeat, may be null
+     * @param repeat  number of times to repeat str, negative treated as zero
+     * @return a new String consisting of the original String repeated,
+     *  {@code null} if null String input
+     */
+    public static String repeat(String str, int repeat) {
+        // Performance tuned for 2.0 (JDK1.4)
+
+        if (str == null) {
+            return null;
+        }
+        if (repeat <= 0) {
+            return EMPTY;
+        }
+        int inputLength = str.length();
+        if (repeat == 1 || inputLength == 0) {
+            return str;
+        }
+        if (inputLength == 1 && repeat <= PAD_LIMIT) {
+            return repeat(str.charAt(0), repeat);
+        }
+
+        int outputLength = inputLength * repeat;
+        switch (inputLength) {
+            case 1 :
+                return repeat(str.charAt(0), repeat);
+            case 2 :
+                char ch0 = str.charAt(0);
+                char ch1 = str.charAt(1);
+                char[] output2 = new char[outputLength];
+                for (int i = repeat * 2 - 2; i >= 0; i--, i--) {
+                    output2[i] = ch0;
+                    output2[i + 1] = ch1;
+                }
+                return new String(output2);
+            default :
+                StringBuilder buf = new StringBuilder(outputLength);
+                for (int i = 0; i < repeat; i++) {
+                    buf.append(str);
+                }
+                return buf.toString();
+        }
+    }
+
+    /**
+     * <p>Repeat a String {@code repeat} times to form a
+     * new String, with a String separator injected each time. </p>
+     *
+     * <pre>
+     * StringUtils.repeat(null, null, 2) = null
+     * StringUtils.repeat(null, "x", 2)  = null
+     * StringUtils.repeat("", null, 0)   = ""
+     * StringUtils.repeat("", "", 2)     = ""
+     * StringUtils.repeat("", "x", 3)    = "xxx"
+     * StringUtils.repeat("?", ", ", 3)  = "?, ?, ?"
+     * </pre>
+     *
+     * @param str        the String to repeat, may be null
+     * @param separator  the String to inject, may be null
+     * @param repeat     number of times to repeat str, negative treated as zero
+     * @return a new String consisting of the original String repeated,
+     *  {@code null} if null String input
+     * @since 2.5
+     */
+    public static String repeat(String str, String separator, int repeat) {
+        if(str == null || separator == null) {
+            return repeat(str, repeat);
+        } else {
+            // given that repeat(String, int) is quite optimized, better to rely on it than try and splice this into it
+            String result = repeat(str + separator, repeat);
+            return removeEnd(result, separator);
+        }
+    }
+
+    /**
+     * <p>Returns padding using the specified delimiter repeated
+     * to a given length.</p>
+     *
+     * <pre>
+     * StringUtils.repeat(0, 'e')  = ""
+     * StringUtils.repeat(3, 'e')  = "eee"
+     * StringUtils.repeat(-2, 'e') = ""
+     * </pre>
+     *
+     * <p>Note: this method doesn't not support padding with
+     * <a href="http://www.unicode.org/glossary/#supplementary_character">Unicode Supplementary Characters</a>
+     * as they require a pair of {@code char}s to be represented.
+     * If you are needing to support full I18N of your applications
+     * consider using {@link #repeat(String, int)} instead.
+     * </p>
+     *
+     * @param ch  character to repeat
+     * @param repeat  number of times to repeat char, negative treated as zero
+     * @return String with repeated character
+     * @see #repeat(String, int)
+     */
+    public static String repeat(char ch, int repeat) {
+        char[] buf = new char[repeat];
+        for (int i = repeat - 1; i >= 0; i--) {
+            buf[i] = ch;
+        }
+        return new String(buf);
+    }
+
+    /**
+     * <p>Right pad a String with spaces (' ').</p>
+     *
+     * <p>The String is padded to the size of {@code size}.</p>
+     *
+     * <pre>
+     * StringUtils.rightPad(null, *)   = null
+     * StringUtils.rightPad("", 3)     = "   "
+     * StringUtils.rightPad("bat", 3)  = "bat"
+     * StringUtils.rightPad("bat", 5)  = "bat  "
+     * StringUtils.rightPad("bat", 1)  = "bat"
+     * StringUtils.rightPad("bat", -1) = "bat"
+     * </pre>
+     *
+     * @param str  the String to pad out, may be null
+     * @param size  the size to pad to
+     * @return right padded String or original String if no padding is necessary,
+     *  {@code null} if null String input
+     */
+    public static String rightPad(String str, int size) {
+        return rightPad(str, size, ' ');
+    }
+
+    /**
+     * <p>Right pad a String with a specified character.</p>
+     *
+     * <p>The String is padded to the size of {@code size}.</p>
+     *
+     * <pre>
+     * StringUtils.rightPad(null, *, *)     = null
+     * StringUtils.rightPad("", 3, 'z')     = "zzz"
+     * StringUtils.rightPad("bat", 3, 'z')  = "bat"
+     * StringUtils.rightPad("bat", 5, 'z')  = "batzz"
+     * StringUtils.rightPad("bat", 1, 'z')  = "bat"
+     * StringUtils.rightPad("bat", -1, 'z') = "bat"
+     * </pre>
+     *
+     * @param str  the String to pad out, may be null
+     * @param size  the size to pad to
+     * @param padChar  the character to pad with
+     * @return right padded String or original String if no padding is necessary,
+     *  {@code null} if null String input
+     * @since 2.0
+     */
+    public static String rightPad(String str, int size, char padChar) {
+        if (str == null) {
+            return null;
+        }
+        int pads = size - str.length();
+        if (pads <= 0) {
+            return str; // returns original String when possible
+        }
+        if (pads > PAD_LIMIT) {
+            return rightPad(str, size, String.valueOf(padChar));
+        }
+        return str.concat(repeat(padChar, pads));
+    }
+
+    /**
+     * <p>Right pad a String with a specified String.</p>
+     *
+     * <p>The String is padded to the size of {@code size}.</p>
+     *
+     * <pre>
+     * StringUtils.rightPad(null, *, *)      = null
+     * StringUtils.rightPad("", 3, "z")      = "zzz"
+     * StringUtils.rightPad("bat", 3, "yz")  = "bat"
+     * StringUtils.rightPad("bat", 5, "yz")  = "batyz"
+     * StringUtils.rightPad("bat", 8, "yz")  = "batyzyzy"
+     * StringUtils.rightPad("bat", 1, "yz")  = "bat"
+     * StringUtils.rightPad("bat", -1, "yz") = "bat"
+     * StringUtils.rightPad("bat", 5, null)  = "bat  "
+     * StringUtils.rightPad("bat", 5, "")    = "bat  "
+     * </pre>
+     *
+     * @param str  the String to pad out, may be null
+     * @param size  the size to pad to
+     * @param padStr  the String to pad with, null or empty treated as single space
+     * @return right padded String or original String if no padding is necessary,
+     *  {@code null} if null String input
+     */
+    public static String rightPad(String str, int size, String padStr) {
+        if (str == null) {
+            return null;
+        }
+        if (isEmpty(padStr)) {
+            padStr = " ";
+        }
+        int padLen = padStr.length();
+        int strLen = str.length();
+        int pads = size - strLen;
+        if (pads <= 0) {
+            return str; // returns original String when possible
+        }
+        if (padLen == 1 && pads <= PAD_LIMIT) {
+            return rightPad(str, size, padStr.charAt(0));
+        }
+
+        if (pads == padLen) {
+            return str.concat(padStr);
+        } else if (pads < padLen) {
+            return str.concat(padStr.substring(0, pads));
+        } else {
+            char[] padding = new char[pads];
+            char[] padChars = padStr.toCharArray();
+            for (int i = 0; i < pads; i++) {
+                padding[i] = padChars[i % padLen];
+            }
+            return str.concat(new String(padding));
+        }
+    }
+
+    /**
+     * <p>Left pad a String with spaces (' ').</p>
+     *
+     * <p>The String is padded to the size of {@code size}.</p>
+     *
+     * <pre>
+     * StringUtils.leftPad(null, *)   = null
+     * StringUtils.leftPad("", 3)     = "   "
+     * StringUtils.leftPad("bat", 3)  = "bat"
+     * StringUtils.leftPad("bat", 5)  = "  bat"
+     * StringUtils.leftPad("bat", 1)  = "bat"
+     * StringUtils.leftPad("bat", -1) = "bat"
+     * </pre>
+     *
+     * @param str  the String to pad out, may be null
+     * @param size  the size to pad to
+     * @return left padded String or original String if no padding is necessary,
+     *  {@code null} if null String input
+     */
+    public static String leftPad(String str, int size) {
+        return leftPad(str, size, ' ');
+    }
+
+    /**
+     * <p>Left pad a String with a specified character.</p>
+     *
+     * <p>Pad to a size of {@code size}.</p>
+     *
+     * <pre>
+     * StringUtils.leftPad(null, *, *)     = null
+     * StringUtils.leftPad("", 3, 'z')     = "zzz"
+     * StringUtils.leftPad("bat", 3, 'z')  = "bat"
+     * StringUtils.leftPad("bat", 5, 'z')  = "zzbat"
+     * StringUtils.leftPad("bat", 1, 'z')  = "bat"
+     * StringUtils.leftPad("bat", -1, 'z') = "bat"
+     * </pre>
+     *
+     * @param str  the String to pad out, may be null
+     * @param size  the size to pad to
+     * @param padChar  the character to pad with
+     * @return left padded String or original String if no padding is necessary,
+     *  {@code null} if null String input
+     * @since 2.0
+     */
+    public static String leftPad(String str, int size, char padChar) {
+        if (str == null) {
+            return null;
+        }
+        int pads = size - str.length();
+        if (pads <= 0) {
+            return str; // returns original String when possible
+        }
+        if (pads > PAD_LIMIT) {
+            return leftPad(str, size, String.valueOf(padChar));
+        }
+        return repeat(padChar, pads).concat(str);
+    }
+
+    /**
+     * <p>Left pad a String with a specified String.</p>
+     *
+     * <p>Pad to a size of {@code size}.</p>
+     *
+     * <pre>
+     * StringUtils.leftPad(null, *, *)      = null
+     * StringUtils.leftPad("", 3, "z")      = "zzz"
+     * StringUtils.leftPad("bat", 3, "yz")  = "bat"
+     * StringUtils.leftPad("bat", 5, "yz")  = "yzbat"
+     * StringUtils.leftPad("bat", 8, "yz")  = "yzyzybat"
+     * StringUtils.leftPad("bat", 1, "yz")  = "bat"
+     * StringUtils.leftPad("bat", -1, "yz") = "bat"
+     * StringUtils.leftPad("bat", 5, null)  = "  bat"
+     * StringUtils.leftPad("bat", 5, "")    = "  bat"
+     * </pre>
+     *
+     * @param str  the String to pad out, may be null
+     * @param size  the size to pad to
+     * @param padStr  the String to pad with, null or empty treated as single space
+     * @return left padded String or original String if no padding is necessary,
+     *  {@code null} if null String input
+     */
+    public static String leftPad(String str, int size, String padStr) {
+        if (str == null) {
+            return null;
+        }
+        if (isEmpty(padStr)) {
+            padStr = " ";
+        }
+        int padLen = padStr.length();
+        int strLen = str.length();
+        int pads = size - strLen;
+        if (pads <= 0) {
+            return str; // returns original String when possible
+        }
+        if (padLen == 1 && pads <= PAD_LIMIT) {
+            return leftPad(str, size, padStr.charAt(0));
+        }
+
+        if (pads == padLen) {
+            return padStr.concat(str);
+        } else if (pads < padLen) {
+            return padStr.substring(0, pads).concat(str);
+        } else {
+            char[] padding = new char[pads];
+            char[] padChars = padStr.toCharArray();
+            for (int i = 0; i < pads; i++) {
+                padding[i] = padChars[i % padLen];
+            }
+            return new String(padding).concat(str);
+        }
+    }
+
+    /**
+     * Gets a CharSequence length or {@code 0} if the CharSequence is
+     * {@code null}.
+     *
+     * @param cs
+     *            a CharSequence or {@code null}
+     * @return CharSequence length or {@code 0} if the CharSequence is
+     *         {@code null}.
+     * @since 2.4
+     * @since 3.0 Changed signature from length(String) to length(CharSequence)
+     */
+    public static int length(CharSequence cs) {
+        return cs == null ? 0 : cs.length();
+    }
+
+    // Centering
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Centers a String in a larger String of size {@code size}
+     * using the space character (' ').<p>
+     *
+     * <p>If the size is less than the String length, the String is returned.
+     * A {@code null} String returns {@code null}.
+     * A negative size is treated as zero.</p>
+     *
+     * <p>Equivalent to {@code center(str, size, " ")}.</p>
+     *
+     * <pre>
+     * StringUtils.center(null, *)   = null
+     * StringUtils.center("", 4)     = "    "
+     * StringUtils.center("ab", -1)  = "ab"
+     * StringUtils.center("ab", 4)   = " ab "
+     * StringUtils.center("abcd", 2) = "abcd"
+     * StringUtils.center("a", 4)    = " a  "
+     * </pre>
+     *
+     * @param str  the String to center, may be null
+     * @param size  the int size of new String, negative treated as zero
+     * @return centered String, {@code null} if null String input
+     */
+    public static String center(String str, int size) {
+        return center(str, size, ' ');
+    }
+
+    /**
+     * <p>Centers a String in a larger String of size {@code size}.
+     * Uses a supplied character as the value to pad the String with.</p>
+     *
+     * <p>If the size is less than the String length, the String is returned.
+     * A {@code null} String returns {@code null}.
+     * A negative size is treated as zero.</p>
+     *
+     * <pre>
+     * StringUtils.center(null, *, *)     = null
+     * StringUtils.center("", 4, ' ')     = "    "
+     * StringUtils.center("ab", -1, ' ')  = "ab"
+     * StringUtils.center("ab", 4, ' ')   = " ab"
+     * StringUtils.center("abcd", 2, ' ') = "abcd"
+     * StringUtils.center("a", 4, ' ')    = " a  "
+     * StringUtils.center("a", 4, 'y')    = "yayy"
+     * </pre>
+     *
+     * @param str  the String to center, may be null
+     * @param size  the int size of new String, negative treated as zero
+     * @param padChar  the character to pad the new String with
+     * @return centered String, {@code null} if null String input
+     * @since 2.0
+     */
+    public static String center(String str, int size, char padChar) {
+        if (str == null || size <= 0) {
+            return str;
+        }
+        int strLen = str.length();
+        int pads = size - strLen;
+        if (pads <= 0) {
+            return str;
+        }
+        str = leftPad(str, strLen + pads / 2, padChar);
+        str = rightPad(str, size, padChar);
+        return str;
+    }
+
+    /**
+     * <p>Centers a String in a larger String of size {@code size}.
+     * Uses a supplied String as the value to pad the String with.</p>
+     *
+     * <p>If the size is less than the String length, the String is returned.
+     * A {@code null} String returns {@code null}.
+     * A negative size is treated as zero.</p>
+     *
+     * <pre>
+     * StringUtils.center(null, *, *)     = null
+     * StringUtils.center("", 4, " ")     = "    "
+     * StringUtils.center("ab", -1, " ")  = "ab"
+     * StringUtils.center("ab", 4, " ")   = " ab"
+     * StringUtils.center("abcd", 2, " ") = "abcd"
+     * StringUtils.center("a", 4, " ")    = " a  "
+     * StringUtils.center("a", 4, "yz")   = "yayz"
+     * StringUtils.center("abc", 7, null) = "  abc  "
+     * StringUtils.center("abc", 7, "")   = "  abc  "
+     * </pre>
+     *
+     * @param str  the String to center, may be null
+     * @param size  the int size of new String, negative treated as zero
+     * @param padStr  the String to pad the new String with, must not be null or empty
+     * @return centered String, {@code null} if null String input
+     * @throws IllegalArgumentException if padStr is {@code null} or empty
+     */
+    public static String center(String str, int size, String padStr) {
+        if (str == null || size <= 0) {
+            return str;
+        }
+        if (isEmpty(padStr)) {
+            padStr = " ";
+        }
+        int strLen = str.length();
+        int pads = size - strLen;
+        if (pads <= 0) {
+            return str;
+        }
+        str = leftPad(str, strLen + pads / 2, padStr);
+        str = rightPad(str, size, padStr);
+        return str;
+    }
+
+    // Case conversion
+    //-----------------------------------------------------------------------
+
+
+    /**
+     * <p>Capitalizes a String changing the first letter to title case as
+     * per {@link Character#toTitleCase(char)}. No other letters are changed.</p>
+     *
+     * <p>For a word based algorithm, see {@link org.apache.commons.lang3.text.WordUtils#capitalize(String)}.
+     * A {@code null} input String returns {@code null}.</p>
+     *
+     * <pre>
+     * StringUtils.capitalize(null)  = null
+     * StringUtils.capitalize("")    = ""
+     * StringUtils.capitalize("cat") = "Cat"
+     * StringUtils.capitalize("cAt") = "CAt"
+     * </pre>
+     *
+     * @param str the String to capitalize, may be null
+     * @return the capitalized String, {@code null} if null String input
+     * @see org.apache.commons.lang3.text.WordUtils#capitalize(String)
+     * @see #uncapitalize(String)
+     * @since 2.0
+     */
+    public static String capitalize(String str) { // NO_UCD
+        int strLen;
+        if (str == null || (strLen = str.length()) == 0) {
+            return str;
+        }
+        return new StringBuilder(strLen)
+            .append(Character.toTitleCase(str.charAt(0)))
+            .append(str.substring(1))
+            .toString();
+    }
+
+    /**
+     * <p>Uncapitalizes a String changing the first letter to title case as
+     * per {@link Character#toLowerCase(char)}. No other letters are changed.</p>
+     *
+     * <p>For a word based algorithm, see {@link org.apache.commons.lang3.text.WordUtils#uncapitalize(String)}.
+     * A {@code null} input String returns {@code null}.</p>
+     *
+     * <pre>
+     * StringUtils.uncapitalize(null)  = null
+     * StringUtils.uncapitalize("")    = ""
+     * StringUtils.uncapitalize("Cat") = "cat"
+     * StringUtils.uncapitalize("CAT") = "cAT"
+     * </pre>
+     *
+     * @param str the String to uncapitalize, may be null
+     * @return the uncapitalized String, {@code null} if null String input
+     * @see org.apache.commons.lang3.text.WordUtils#uncapitalize(String)
+     * @see #capitalize(String)
+     * @since 2.0
+     */
+    public static String uncapitalize(String str) {
+        int strLen;
+        if (str == null || (strLen = str.length()) == 0) {
+            return str;
+        }
+        return new StringBuilder(strLen)
+            .append(Character.toLowerCase(str.charAt(0)))
+            .append(str.substring(1))
+            .toString();
+    }
+
+    /**
+     * <p>Swaps the case of a String changing upper and title case to
+     * lower case, and lower case to upper case.</p>
+     *
+     * <ul>
+     *  <li>Upper case character converts to Lower case</li>
+     *  <li>Title case character converts to Lower case</li>
+     *  <li>Lower case character converts to Upper case</li>
+     * </ul>
+     *
+     * <p>For a word based algorithm, see {@link org.apache.commons.lang3.text.WordUtils#swapCase(String)}.
+     * A {@code null} input String returns {@code null}.</p>
+     *
+     * <pre>
+     * StringUtils.swapCase(null)                 = null
+     * StringUtils.swapCase("")                   = ""
+     * StringUtils.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
+     * </pre>
+     *
+     * <p>NOTE: This method changed in Lang version 2.0.
+     * It no longer performs a word based algorithm.
+     * If you only use ASCII, you will notice no change.
+     * That functionality is available in org.apache.commons.lang3.text.WordUtils.</p>
+     *
+     * @param str  the String to swap case, may be null
+     * @return the changed String, {@code null} if null String input
+     */
+    public static String swapCase(String str) {
+        if (StringUtils.isEmpty(str)) {
+            return str;
+        }
+
+        char[] buffer = str.toCharArray();
+
+        for (int i = 0; i < buffer.length; i++) {
+            char ch = buffer[i];
+            if (Character.isUpperCase(ch)) {
+                buffer[i] = Character.toLowerCase(ch);
+            } else if (Character.isTitleCase(ch)) {
+                buffer[i] = Character.toLowerCase(ch);
+            } else if (Character.isLowerCase(ch)) {
+                buffer[i] = Character.toUpperCase(ch);
+            }
+        }
+        return new String(buffer);
+    }
+
+    // Count matches
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Counts how many times the substring appears in the larger string.</p>
+     *
+     * <p>A {@code null} or empty ("") String input returns {@code 0}.</p>
+     *
+     * <pre>
+     * StringUtils.countMatches(null, *)       = 0
+     * StringUtils.countMatches("", *)         = 0
+     * StringUtils.countMatches("abba", null)  = 0
+     * StringUtils.countMatches("abba", "")    = 0
+     * StringUtils.countMatches("abba", "a")   = 2
+     * StringUtils.countMatches("abba", "ab")  = 1
+     * StringUtils.countMatches("abba", "xxx") = 0
+     * </pre>
+     *
+     * @param str  the CharSequence to check, may be null
+     * @param sub  the substring to count, may be null
+     * @return the number of occurrences, 0 if either CharSequence is {@code null}
+     * @since 3.0 Changed signature from countMatches(String, String) to countMatches(CharSequence, CharSequence)
+     */
+    public static int countMatches(CharSequence str, CharSequence sub) {
+        if (isEmpty(str) || isEmpty(sub)) {
+            return 0;
+        }
+        int count = 0;
+        int idx = 0;
+        while ((idx = CharSequenceUtils.indexOf(str, sub, idx)) != INDEX_NOT_FOUND) {
+            count++;
+            idx += sub.length();
+        }
+        return count;
+    }
+
+    // Character Tests
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Checks if the CharSequence contains only Unicode letters.</p>
+     *
+     * <p>{@code null} will return {@code false}.
+     * An empty CharSequence (length()=0) will return {@code false}.</p>
+     *
+     * <pre>
+     * StringUtils.isAlpha(null)   = false
+     * StringUtils.isAlpha("")     = false
+     * StringUtils.isAlpha("  ")   = false
+     * StringUtils.isAlpha("abc")  = true
+     * StringUtils.isAlpha("ab2c") = false
+     * StringUtils.isAlpha("ab-c") = false
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @return {@code true} if only contains letters, and is non-null
+     * @since 3.0 Changed signature from isAlpha(String) to isAlpha(CharSequence)
+     * @since 3.0 Changed "" to return false and not true
+     */
+    public static boolean isAlpha(CharSequence cs) {
+        if (cs == null || cs.length() == 0) {
+            return false;
+        }
+        int sz = cs.length();
+        for (int i = 0; i < sz; i++) {
+            if (Character.isLetter(cs.charAt(i)) == false) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * <p>Checks if the CharSequence contains only Unicode letters and
+     * space (' ').</p>
+     *
+     * <p>{@code null} will return {@code false}
+     * An empty CharSequence (length()=0) will return {@code true}.</p>
+     *
+     * <pre>
+     * StringUtils.isAlphaSpace(null)   = false
+     * StringUtils.isAlphaSpace("")     = true
+     * StringUtils.isAlphaSpace("  ")   = true
+     * StringUtils.isAlphaSpace("abc")  = true
+     * StringUtils.isAlphaSpace("ab c") = true
+     * StringUtils.isAlphaSpace("ab2c") = false
+     * StringUtils.isAlphaSpace("ab-c") = false
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @return {@code true} if only contains letters and space,
+     *  and is non-null
+     * @since 3.0 Changed signature from isAlphaSpace(String) to isAlphaSpace(CharSequence)
+     */
+    public static boolean isAlphaSpace(CharSequence cs) {
+        if (cs == null) {
+            return false;
+        }
+        int sz = cs.length();
+        for (int i = 0; i < sz; i++) {
+            if (Character.isLetter(cs.charAt(i)) == false && cs.charAt(i) != ' ') {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * <p>Checks if the CharSequence contains only Unicode letters or digits.</p>
+     *
+     * <p>{@code null} will return {@code false}.
+     * An empty CharSequence (length()=0) will return {@code false}.</p>
+     *
+     * <pre>
+     * StringUtils.isAlphanumeric(null)   = false
+     * StringUtils.isAlphanumeric("")     = false
+     * StringUtils.isAlphanumeric("  ")   = false
+     * StringUtils.isAlphanumeric("abc")  = true
+     * StringUtils.isAlphanumeric("ab c") = false
+     * StringUtils.isAlphanumeric("ab2c") = true
+     * StringUtils.isAlphanumeric("ab-c") = false
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @return {@code true} if only contains letters or digits,
+     *  and is non-null
+     * @since 3.0 Changed signature from isAlphanumeric(String) to isAlphanumeric(CharSequence)
+     * @since 3.0 Changed "" to return false and not true
+     */
+    public static boolean isAlphanumeric(CharSequence cs) {
+        if (cs == null || cs.length() == 0) {
+            return false;
+        }
+        int sz = cs.length();
+        for (int i = 0; i < sz; i++) {
+            if (Character.isLetterOrDigit(cs.charAt(i)) == false) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * <p>Checks if the CharSequence contains only Unicode letters, digits
+     * or space ({@code ' '}).</p>
+     *
+     * <p>{@code null} will return {@code false}.
+     * An empty CharSequence (length()=0) will return {@code true}.</p>
+     *
+     * <pre>
+     * StringUtils.isAlphanumericSpace(null)   = false
+     * StringUtils.isAlphanumericSpace("")     = true
+     * StringUtils.isAlphanumericSpace("  ")   = true
+     * StringUtils.isAlphanumericSpace("abc")  = true
+     * StringUtils.isAlphanumericSpace("ab c") = true
+     * StringUtils.isAlphanumericSpace("ab2c") = true
+     * StringUtils.isAlphanumericSpace("ab-c") = false
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @return {@code true} if only contains letters, digits or space,
+     *  and is non-null
+     * @since 3.0 Changed signature from isAlphanumericSpace(String) to isAlphanumericSpace(CharSequence)
+     */
+    public static boolean isAlphanumericSpace(CharSequence cs) {
+        if (cs == null) {
+            return false;
+        }
+        int sz = cs.length();
+        for (int i = 0; i < sz; i++) {
+            if (Character.isLetterOrDigit(cs.charAt(i)) == false && cs.charAt(i) != ' ') {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * <p>Checks if the CharSequence contains only ASCII printable characters.</p>
+     *
+     * <p>{@code null} will return {@code false}.
+     * An empty CharSequence (length()=0) will return {@code true}.</p>
+     *
+     * <pre>
+     * StringUtils.isAsciiPrintable(null)     = false
+     * StringUtils.isAsciiPrintable("")       = true
+     * StringUtils.isAsciiPrintable(" ")      = true
+     * StringUtils.isAsciiPrintable("Ceki")   = true
+     * StringUtils.isAsciiPrintable("ab2c")   = true
+     * StringUtils.isAsciiPrintable("!ab-c~") = true
+     * StringUtils.isAsciiPrintable("\u0020") = true
+     * StringUtils.isAsciiPrintable("\u0021") = true
+     * StringUtils.isAsciiPrintable("\u007e") = true
+     * StringUtils.isAsciiPrintable("\u007f") = false
+     * StringUtils.isAsciiPrintable("Ceki G\u00fclc\u00fc") = false
+     * </pre>
+     *
+     * @param cs the CharSequence to check, may be null
+     * @return {@code true} if every character is in the range
+     *  32 thru 126
+     * @since 2.1
+     * @since 3.0 Changed signature from isAsciiPrintable(String) to isAsciiPrintable(CharSequence)
+     */
+    public static boolean isAsciiPrintable(CharSequence cs) {
+        if (cs == null) {
+            return false;
+        }
+        int sz = cs.length();
+        for (int i = 0; i < sz; i++) {
+            if (CharUtils.isAsciiPrintable(cs.charAt(i)) == false) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * <p>Checks if the CharSequence contains only Unicode digits.
+     * A decimal point is not a Unicode digit and returns false.</p>
+     *
+     * <p>{@code null} will return {@code false}.
+     * An empty CharSequence (length()=0) will return {@code false}.</p>
+     *
+     * <pre>
+     * StringUtils.isNumeric(null)   = false
+     * StringUtils.isNumeric("")     = false
+     * StringUtils.isNumeric("  ")   = false
+     * StringUtils.isNumeric("123")  = true
+     * StringUtils.isNumeric("12 3") = false
+     * StringUtils.isNumeric("ab2c") = false
+     * StringUtils.isNumeric("12-3") = false
+     * StringUtils.isNumeric("12.3") = false
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @return {@code true} if only contains digits, and is non-null
+     * @since 3.0 Changed signature from isNumeric(String) to isNumeric(CharSequence)
+     * @since 3.0 Changed "" to return false and not true
+     */
+    public static boolean isNumeric(CharSequence cs) {
+        if (cs == null || cs.length() == 0) {
+            return false;
+        }
+        int sz = cs.length();
+        for (int i = 0; i < sz; i++) {
+            if (Character.isDigit(cs.charAt(i)) == false) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * <p>Checks if the CharSequence contains only Unicode digits or space
+     * ({@code ' '}).
+     * A decimal point is not a Unicode digit and returns false.</p>
+     *
+     * <p>{@code null} will return {@code false}.
+     * An empty CharSequence (length()=0) will return {@code true}.</p>
+     *
+     * <pre>
+     * StringUtils.isNumericSpace(null)   = false
+     * StringUtils.isNumericSpace("")     = true
+     * StringUtils.isNumericSpace("  ")   = true
+     * StringUtils.isNumericSpace("123")  = true
+     * StringUtils.isNumericSpace("12 3") = true
+     * StringUtils.isNumericSpace("ab2c") = false
+     * StringUtils.isNumericSpace("12-3") = false
+     * StringUtils.isNumericSpace("12.3") = false
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @return {@code true} if only contains digits or space,
+     *  and is non-null
+     * @since 3.0 Changed signature from isNumericSpace(String) to isNumericSpace(CharSequence)
+     */
+    public static boolean isNumericSpace(CharSequence cs) {
+        if (cs == null) {
+            return false;
+        }
+        int sz = cs.length();
+        for (int i = 0; i < sz; i++) {
+            if (Character.isDigit(cs.charAt(i)) == false && cs.charAt(i) != ' ') {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * <p>Checks if the CharSequence contains only whitespace.</p>
+     *
+     * <p>{@code null} will return {@code false}.
+     * An empty CharSequence (length()=0) will return {@code true}.</p>
+     *
+     * <pre>
+     * StringUtils.isWhitespace(null)   = false
+     * StringUtils.isWhitespace("")     = true
+     * StringUtils.isWhitespace("  ")   = true
+     * StringUtils.isWhitespace("abc")  = false
+     * StringUtils.isWhitespace("ab2c") = false
+     * StringUtils.isWhitespace("ab-c") = false
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @return {@code true} if only contains whitespace, and is non-null
+     * @since 2.0
+     * @since 3.0 Changed signature from isWhitespace(String) to isWhitespace(CharSequence)
+     */
+    public static boolean isWhitespace(CharSequence cs) {
+        if (cs == null) {
+            return false;
+        }
+        int sz = cs.length();
+        for (int i = 0; i < sz; i++) {
+            if (Character.isWhitespace(cs.charAt(i)) == false) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * <p>Checks if the CharSequence contains only lowercase characters.</p>
+     *
+     * <p>{@code null} will return {@code false}.
+     * An empty CharSequence (length()=0) will return {@code false}.</p>
+     *
+     * <pre>
+     * StringUtils.isAllLowerCase(null)   = false
+     * StringUtils.isAllLowerCase("")     = false
+     * StringUtils.isAllLowerCase("  ")   = false
+     * StringUtils.isAllLowerCase("abc")  = true
+     * StringUtils.isAllLowerCase("abC") = false
+     * </pre>
+     *
+     * @param cs  the CharSequence to check, may be null
+     * @return {@code true} if only contains lowercase characters, and is non-null
+     * @since 2.5
+     * @since 3.0 Changed signature from isAllLowerCase(String) to isAllLowerCase(CharSequence)
+     */
+    public static boolean isAllLowerCase(CharSequence cs) {
+        if (cs == null || isEmpty(cs)) {
+            return false;
+        }
+        int sz = cs.length();
+        for (int i = 0; i < sz; i++) {
+            if (Character.isLowerCase(cs.charAt(i)) == false) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * <p>Checks if the CharSequence contains only uppercase characters.</p>
+     *
+     * <p>{@code null} will return {@code false}.
+     * An empty String (length()=0) will return {@code false}.</p>
+     *
+     * <pre>
+     * StringUtils.isAllUpperCase(null)   = false
+     * StringUtils.isAllUpperCase("")     = false
+     * StringUtils.isAllUpperCase("  ")   = false
+     * StringUtils.isAllUpperCase("ABC")  = true
+     * StringUtils.isAllUpperCase("aBC") = false
+     * </pre>
+     *
+     * @param cs the CharSequence to check, may be null
+     * @return {@code true} if only contains uppercase characters, and is non-null
+     * @since 2.5
+     * @since 3.0 Changed signature from isAllUpperCase(String) to isAllUpperCase(CharSequence)
+     */
+    public static boolean isAllUpperCase(CharSequence cs) {
+        if (cs == null || isEmpty(cs)) {
+            return false;
+        }
+        int sz = cs.length();
+        for (int i = 0; i < sz; i++) {
+            if (Character.isUpperCase(cs.charAt(i)) == false) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    // Defaults
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Returns either the passed in String,
+     * or if the String is {@code null}, an empty String ("").</p>
+     *
+     * <pre>
+     * StringUtils.defaultString(null)  = ""
+     * StringUtils.defaultString("")    = ""
+     * StringUtils.defaultString("bat") = "bat"
+     * </pre>
+     *
+     * @see ObjectUtils#toString(Object)
+     * @see String#valueOf(Object)
+     * @param str  the String to check, may be null
+     * @return the passed in String, or the empty String if it
+     *  was {@code null}
+     */
+    public static String defaultString(String str) {
+        return str == null ? EMPTY : str;
+    }
+
+    /**
+     * <p>Returns either the passed in String, or if the String is
+     * {@code null}, the value of {@code defaultStr}.</p>
+     *
+     * <pre>
+     * StringUtils.defaultString(null, "NULL")  = "NULL"
+     * StringUtils.defaultString("", "NULL")    = ""
+     * StringUtils.defaultString("bat", "NULL") = "bat"
+     * </pre>
+     *
+     * @see ObjectUtils#toString(Object,String)
+     * @see String#valueOf(Object)
+     * @param str  the String to check, may be null
+     * @param defaultStr  the default String to return
+     *  if the input is {@code null}, may be null
+     * @return the passed in String, or the default if it was {@code null}
+     */
+    public static String defaultString(String str, String defaultStr) {
+        return str == null ? defaultStr : str;
+    }
+
+    /**
+     * <p>Returns either the passed in CharSequence, or if the CharSequence is
+     * whitespace, empty ("") or {@code null}, the value of {@code defaultStr}.</p>
+     *
+     * <pre>
+     * StringUtils.defaultIfBlank(null, "NULL")  = "NULL"
+     * StringUtils.defaultIfBlank("", "NULL")    = "NULL"
+     * StringUtils.defaultIfBlank(" ", "NULL")   = "NULL"
+     * StringUtils.defaultIfBlank("bat", "NULL") = "bat"
+     * StringUtils.defaultIfBlank("", null)      = null
+     * </pre>
+     * @param <T> the specific kind of CharSequence
+     * @param str the CharSequence to check, may be null
+     * @param defaultStr  the default CharSequence to return
+     *  if the input is whitespace, empty ("") or {@code null}, may be null
+     * @return the passed in CharSequence, or the default
+     * @see StringUtils#defaultString(String, String)
+     */
+    public static <T extends CharSequence> T defaultIfBlank(T str, T defaultStr) {
+        return StringUtils.isBlank(str) ? defaultStr : str;
+    }
+
+    /**
+     * <p>Returns either the passed in CharSequence, or if the CharSequence is
+     * empty or {@code null}, the value of {@code defaultStr}.</p>
+     *
+     * <pre>
+     * StringUtils.defaultIfEmpty(null, "NULL")  = "NULL"
+     * StringUtils.defaultIfEmpty("", "NULL")    = "NULL"
+     * StringUtils.defaultIfEmpty(" ", "NULL")   = " "
+     * StringUtils.defaultIfEmpty("bat", "NULL") = "bat"
+     * StringUtils.defaultIfEmpty("", null)      = null
+     * </pre>
+     * @param <T> the specific kind of CharSequence
+     * @param str  the CharSequence to check, may be null
+     * @param defaultStr  the default CharSequence to return
+     *  if the input is empty ("") or {@code null}, may be null
+     * @return the passed in CharSequence, or the default
+     * @see StringUtils#defaultString(String, String)
+     */
+    public static <T extends CharSequence> T defaultIfEmpty(T str, T defaultStr) {
+        return StringUtils.isEmpty(str) ? defaultStr : str;
+    }
+
+    // Reversing
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Reverses a String as per {@link StringBuilder#reverse()}.</p>
+     *
+     * <p>A {@code null} String returns {@code null}.</p>
+     *
+     * <pre>
+     * StringUtils.reverse(null)  = null
+     * StringUtils.reverse("")    = ""
+     * StringUtils.reverse("bat") = "tab"
+     * </pre>
+     *
+     * @param str  the String to reverse, may be null
+     * @return the reversed String, {@code null} if null String input
+     */
+    public static String reverse(String str) {
+        if (str == null) {
+            return null;
+        }
+        return new StringBuilder(str).reverse().toString();
+    }
+
+
+    // Abbreviating
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Abbreviates a String using ellipses. This will turn
+     * "Now is the time for all good men" into "Now is the time for..."</p>
+     *
+     * <p>Specifically:
+     * <ul>
+     *   <li>If {@code str} is less than {@code maxWidth} characters
+     *       long, return it.</li>
+     *   <li>Else abbreviate it to {@code (substring(str, 0, max-3) + "...")}.</li>
+     *   <li>If {@code maxWidth} is less than {@code 4}, throw an
+     *       {@code IllegalArgumentException}.</li>
+     *   <li>In no case will it return a String of length greater than
+     *       {@code maxWidth}.</li>
+     * </ul>
+     * </p>
+     *
+     * <pre>
+     * StringUtils.abbreviate(null, *)      = null
+     * StringUtils.abbreviate("", 4)        = ""
+     * StringUtils.abbreviate("abcdefg", 6) = "abc..."
+     * StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
+     * StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
+     * StringUtils.abbreviate("abcdefg", 4) = "a..."
+     * StringUtils.abbreviate("abcdefg", 3) = IllegalArgumentException
+     * </pre>
+     *
+     * @param str  the String to check, may be null
+     * @param maxWidth  maximum length of result String, must be at least 4
+     * @return abbreviated String, {@code null} if null String input
+     * @throws IllegalArgumentException if the width is too small
+     * @since 2.0
+     */
+    public static String abbreviate(String str, int maxWidth) {
+        return abbreviate(str, 0, maxWidth);
+    }
+
+    /**
+     * <p>Abbreviates a String using ellipses. This will turn
+     * "Now is the time for all good men" into "...is the time for..."</p>
+     *
+     * <p>Works like {@code abbreviate(String, int)}, but allows you to specify
+     * a "left edge" offset.  Note that this left edge is not necessarily going to
+     * be the leftmost character in the result, or the first character following the
+     * ellipses, but it will appear somewhere in the result.
+     *
+     * <p>In no case will it return a String of length greater than
+     * {@code maxWidth}.</p>
+     *
+     * <pre>
+     * StringUtils.abbreviate(null, *, *)                = null
+     * StringUtils.abbreviate("", 0, 4)                  = ""
+     * StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."
+     * StringUtils.abbreviate("abcdefghijklmno", 0, 10)  = "abcdefg..."
+     * StringUtils.abbreviate("abcdefghijklmno", 1, 10)  = "abcdefg..."
+     * StringUtils.abbreviate("abcdefghijklmno", 4, 10)  = "abcdefg..."
+     * StringUtils.abbreviate("abcdefghijklmno", 5, 10)  = "...fghi..."
+     * StringUtils.abbreviate("abcdefghijklmno", 6, 10)  = "...ghij..."
+     * StringUtils.abbreviate("abcdefghijklmno", 8, 10)  = "...ijklmno"
+     * StringUtils.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"
+     * StringUtils.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"
+     * StringUtils.abbreviate("abcdefghij", 0, 3)        = IllegalArgumentException
+     * StringUtils.abbreviate("abcdefghij", 5, 6)        = IllegalArgumentException
+     * </pre>
+     *
+     * @param str  the String to check, may be null
+     * @param offset  left edge of source String
+     * @param maxWidth  maximum length of result String, must be at least 4
+     * @return abbreviated String, {@code null} if null String input
+     * @throws IllegalArgumentException if the width is too small
+     * @since 2.0
+     */
+    public static String abbreviate(String str, int offset, int maxWidth) {
+        if (str == null) {
+            return null;
+        }
+        if (maxWidth < 4) {
+            throw new IllegalArgumentException("Minimum abbreviation width is 4");
+        }
+        if (str.length() <= maxWidth) {
+            return str;
+        }
+        if (offset > str.length()) {
+            offset = str.length();
+        }
+        if (str.length() - offset < maxWidth - 3) {
+            offset = str.length() - (maxWidth - 3);
+        }
+        final String abrevMarker = "...";
+        if (offset <= 4) {
+            return str.substring(0, maxWidth - 3) + abrevMarker;
+        }
+        if (maxWidth < 7) {
+            throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
+        }
+        if (offset + maxWidth - 3 < str.length()) {
+            return abrevMarker + abbreviate(str.substring(offset), maxWidth - 3);
+        }
+        return abrevMarker + str.substring(str.length() - (maxWidth - 3));
+    }
+
+    /**
+     * <p>Abbreviates a String to the length passed, replacing the middle characters with the supplied
+     * replacement String.</p>
+     *
+     * <p>This abbreviation only occurs if the following criteria is met:
+     * <ul>
+     * <li>Neither the String for abbreviation nor the replacement String are null or empty </li>
+     * <li>The length to truncate to is less than the length of the supplied String</li>
+     * <li>The length to truncate to is greater than 0</li>
+     * <li>The abbreviated String will have enough room for the length supplied replacement String
+     * and the first and last characters of the supplied String for abbreviation</li>
+     * </ul>
+     * Otherwise, the returned String will be the same as the supplied String for abbreviation.
+     * </p>
+     *
+     * <pre>
+     * StringUtils.abbreviateMiddle(null, null, 0)      = null
+     * StringUtils.abbreviateMiddle("abc", null, 0)      = "abc"
+     * StringUtils.abbreviateMiddle("abc", ".", 0)      = "abc"
+     * StringUtils.abbreviateMiddle("abc", ".", 3)      = "abc"
+     * StringUtils.abbreviateMiddle("abcdef", ".", 4)     = "ab.f"
+     * </pre>
+     *
+     * @param str  the String to abbreviate, may be null
+     * @param middle the String to replace the middle characters with, may be null
+     * @param length the length to abbreviate {@code str} to.
+     * @return the abbreviated String if the above criteria is met, or the original String supplied for abbreviation.
+     * @since 2.5
+     */
+    public static String abbreviateMiddle(String str, String middle, int length) {
+        if (isEmpty(str) || isEmpty(middle)) {
+            return str;
+        }
+
+        if (length >= str.length() || length < middle.length()+2) {
+            return str;
+        }
+
+        int targetSting = length-middle.length();
+        int startOffset = targetSting/2+targetSting%2;
+        int endOffset = str.length()-targetSting/2;
+
+        StringBuilder builder = new StringBuilder(length);
+        builder.append(str.substring(0,startOffset));
+        builder.append(middle);
+        builder.append(str.substring(endOffset));
+
+        return builder.toString();
+    }
+
+    // Difference
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Compares two Strings, and returns the portion where they differ.
+     * (More precisely, return the remainder of the second String,
+     * starting from where it's different from the first.)</p>
+     *
+     * <p>For example,
+     * {@code difference("i am a machine", "i am a robot") -> "robot"}.</p>
+     *
+     * <pre>
+     * StringUtils.difference(null, null) = null
+     * StringUtils.difference("", "") = ""
+     * StringUtils.difference("", "abc") = "abc"
+     * StringUtils.difference("abc", "") = ""
+     * StringUtils.difference("abc", "abc") = ""
+     * StringUtils.difference("ab", "abxyz") = "xyz"
+     * StringUtils.difference("abcde", "abxyz") = "xyz"
+     * StringUtils.difference("abcde", "xyz") = "xyz"
+     * </pre>
+     *
+     * @param str1  the first String, may be null
+     * @param str2  the second String, may be null
+     * @return the portion of str2 where it differs from str1; returns the
+     * empty String if they are equal
+     * @since 2.0
+     */
+    public static String difference(String str1, String str2) {
+        if (str1 == null) {
+            return str2;
+        }
+        if (str2 == null) {
+            return str1;
+        }
+        int at = indexOfDifference(str1, str2);
+        if (at == INDEX_NOT_FOUND) {
+            return EMPTY;
+        }
+        return str2.substring(at);
+    }
+
+    /**
+     * <p>Compares two CharSequences, and returns the index at which the
+     * CharSequences begin to differ.</p>
+     *
+     * <p>For example,
+     * {@code indexOfDifference("i am a machine", "i am a robot") -> 7}</p>
+     *
+     * <pre>
+     * StringUtils.indexOfDifference(null, null) = -1
+     * StringUtils.indexOfDifference("", "") = -1
+     * StringUtils.indexOfDifference("", "abc") = 0
+     * StringUtils.indexOfDifference("abc", "") = 0
+     * StringUtils.indexOfDifference("abc", "abc") = -1
+     * StringUtils.indexOfDifference("ab", "abxyz") = 2
+     * StringUtils.indexOfDifference("abcde", "abxyz") = 2
+     * StringUtils.indexOfDifference("abcde", "xyz") = 0
+     * </pre>
+     *
+     * @param cs1  the first CharSequence, may be null
+     * @param cs2  the second CharSequence, may be null
+     * @return the index where cs1 and cs2 begin to differ; -1 if they are equal
+     * @since 2.0
+     * @since 3.0 Changed signature from indexOfDifference(String, String) to
+     * indexOfDifference(CharSequence, CharSequence)
+     */
+    public static int indexOfDifference(CharSequence cs1, CharSequence cs2) {
+        if (cs1 == cs2) {
+            return INDEX_NOT_FOUND;
+        }
+        if (cs1 == null || cs2 == null) {
+            return 0;
+        }
+        int i;
+        for (i = 0; i < cs1.length() && i < cs2.length(); ++i) {
+            if (cs1.charAt(i) != cs2.charAt(i)) {
+                break;
+            }
+        }
+        if (i < cs2.length() || i < cs1.length()) {
+            return i;
+        }
+        return INDEX_NOT_FOUND;
+    }
+
+    /**
+     * <p>Compares all CharSequences in an array and returns the index at which the
+     * CharSequences begin to differ.</p>
+     *
+     * <p>For example,
+     * <code>indexOfDifference(new String[] {"i am a machine", "i am a robot"}) -> 7</code></p>
+     *
+     * <pre>
+     * StringUtils.indexOfDifference(null) = -1
+     * StringUtils.indexOfDifference(new String[] {}) = -1
+     * StringUtils.indexOfDifference(new String[] {"abc"}) = -1
+     * StringUtils.indexOfDifference(new String[] {null, null}) = -1
+     * StringUtils.indexOfDifference(new String[] {"", ""}) = -1
+     * StringUtils.indexOfDifference(new String[] {"", null}) = 0
+     * StringUtils.indexOfDifference(new String[] {"abc", null, null}) = 0
+     * StringUtils.indexOfDifference(new String[] {null, null, "abc"}) = 0
+     * StringUtils.indexOfDifference(new String[] {"", "abc"}) = 0
+     * StringUtils.indexOfDifference(new String[] {"abc", ""}) = 0
+     * StringUtils.indexOfDifference(new String[] {"abc", "abc"}) = -1
+     * StringUtils.indexOfDifference(new String[] {"abc", "a"}) = 1
+     * StringUtils.indexOfDifference(new String[] {"ab", "abxyz"}) = 2
+     * StringUtils.indexOfDifference(new String[] {"abcde", "abxyz"}) = 2
+     * StringUtils.indexOfDifference(new String[] {"abcde", "xyz"}) = 0
+     * StringUtils.indexOfDifference(new String[] {"xyz", "abcde"}) = 0
+     * StringUtils.indexOfDifference(new String[] {"i am a machine", "i am a robot"}) = 7
+     * </pre>
+     *
+     * @param css  array of CharSequences, entries may be null
+     * @return the index where the strings begin to differ; -1 if they are all equal
+     * @since 2.4
+     * @since 3.0 Changed signature from indexOfDifference(String...) to indexOfDifference(CharSequence...)
+     */
+    public static int indexOfDifference(CharSequence... css) {
+        if (css == null || css.length <= 1) {
+            return INDEX_NOT_FOUND;
+        }
+        boolean anyStringNull = false;
+        boolean allStringsNull = true;
+        int arrayLen = css.length;
+        int shortestStrLen = Integer.MAX_VALUE;
+        int longestStrLen = 0;
+
+        // find the min and max string lengths; this avoids checking to make
+        // sure we are not exceeding the length of the string each time through
+        // the bottom loop.
+        for (int i = 0; i < arrayLen; i++) {
+            if (css[i] == null) {
+                anyStringNull = true;
+                shortestStrLen = 0;
+            } else {
+                allStringsNull = false;
+                shortestStrLen = Math.min(css[i].length(), shortestStrLen);
+                longestStrLen = Math.max(css[i].length(), longestStrLen);
+            }
+        }
+
+        // handle lists containing all nulls or all empty strings
+        if (allStringsNull || longestStrLen == 0 && !anyStringNull) {
+            return INDEX_NOT_FOUND;
+        }
+
+        // handle lists containing some nulls or some empty strings
+        if (shortestStrLen == 0) {
+            return 0;
+        }
+
+        // find the position with the first difference across all strings
+        int firstDiff = -1;
+        for (int stringPos = 0; stringPos < shortestStrLen; stringPos++) {
+            char comparisonChar = css[0].charAt(stringPos);
+            for (int arrayPos = 1; arrayPos < arrayLen; arrayPos++) {
+                if (css[arrayPos].charAt(stringPos) != comparisonChar) {
+                    firstDiff = stringPos;
+                    break;
+                }
+            }
+            if (firstDiff != -1) {
+                break;
+            }
+        }
+
+        if (firstDiff == -1 && shortestStrLen != longestStrLen) {
+            // we compared all of the characters up to the length of the
+            // shortest string and didn't find a match, but the string lengths
+            // vary, so return the length of the shortest string.
+            return shortestStrLen;
+        }
+        return firstDiff;
+    }
+
+    /**
+     * <p>Compares all Strings in an array and returns the initial sequence of
+     * characters that is common to all of them.</p>
+     *
+     * <p>For example,
+     * <code>getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) -> "i am a "</code></p>
+     *
+     * <pre>
+     * StringUtils.getCommonPrefix(null) = ""
+     * StringUtils.getCommonPrefix(new String[] {}) = ""
+     * StringUtils.getCommonPrefix(new String[] {"abc"}) = "abc"
+     * StringUtils.getCommonPrefix(new String[] {null, null}) = ""
+     * StringUtils.getCommonPrefix(new String[] {"", ""}) = ""
+     * StringUtils.getCommonPrefix(new String[] {"", null}) = ""
+     * StringUtils.getCommonPrefix(new String[] {"abc", null, null}) = ""
+     * StringUtils.getCommonPrefix(new String[] {null, null, "abc"}) = ""
+     * StringUtils.getCommonPrefix(new String[] {"", "abc"}) = ""
+     * StringUtils.getCommonPrefix(new String[] {"abc", ""}) = ""
+     * StringUtils.getCommonPrefix(new String[] {"abc", "abc"}) = "abc"
+     * StringUtils.getCommonPrefix(new String[] {"abc", "a"}) = "a"
+     * StringUtils.getCommonPrefix(new String[] {"ab", "abxyz"}) = "ab"
+     * StringUtils.getCommonPrefix(new String[] {"abcde", "abxyz"}) = "ab"
+     * StringUtils.getCommonPrefix(new String[] {"abcde", "xyz"}) = ""
+     * StringUtils.getCommonPrefix(new String[] {"xyz", "abcde"}) = ""
+     * StringUtils.getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) = "i am a "
+     * </pre>
+     *
+     * @param strs  array of String objects, entries may be null
+     * @return the initial sequence of characters that are common to all Strings
+     * in the array; empty String if the array is null, the elements are all null
+     * or if there is no common prefix.
+     * @since 2.4
+     */
+    public static String getCommonPrefix(String... strs) {
+        if (strs == null || strs.length == 0) {
+            return EMPTY;
+        }
+        int smallestIndexOfDiff = indexOfDifference(strs);
+        if (smallestIndexOfDiff == INDEX_NOT_FOUND) {
+            // all strings were identical
+            if (strs[0] == null) {
+                return EMPTY;
+            }
+            return strs[0];
+        } else if (smallestIndexOfDiff == 0) {
+            // there were no common initial characters
+            return EMPTY;
+        } else {
+            // we found a common initial character sequence
+            return strs[0].substring(0, smallestIndexOfDiff);
+        }
+    }
+
+    // Misc
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Find the Levenshtein distance between two Strings.</p>
+     *
+     * <p>This is the number of changes needed to change one String into
+     * another, where each change is a single character modification (deletion,
+     * insertion or substitution).</p>
+     *
+     * <p>The previous implementation of the Levenshtein distance algorithm
+     * was from <a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a></p>
+     *
+     * <p>Chas Emerick has written an implementation in Java, which avoids an OutOfMemoryError
+     * which can occur when my Java implementation is used with very large strings.<br>
+     * This implementation of the Levenshtein distance algorithm
+     * is from <a href="http://www.merriampark.com/ldjava.htm">http://www.merriampark.com/ldjava.htm</a></p>
+     *
+     * <pre>
+     * StringUtils.getLevenshteinDistance(null, *)             = IllegalArgumentException
+     * StringUtils.getLevenshteinDistance(*, null)             = IllegalArgumentException
+     * StringUtils.getLevenshteinDistance("","")               = 0
+     * StringUtils.getLevenshteinDistance("","a")              = 1
+     * StringUtils.getLevenshteinDistance("aaapppp", "")       = 7
+     * StringUtils.getLevenshteinDistance("frog", "fog")       = 1
+     * StringUtils.getLevenshteinDistance("fly", "ant")        = 3
+     * StringUtils.getLevenshteinDistance("elephant", "hippo") = 7
+     * StringUtils.getLevenshteinDistance("hippo", "elephant") = 7
+     * StringUtils.getLevenshteinDistance("hippo", "zzzzzzzz") = 8
+     * StringUtils.getLevenshteinDistance("hello", "hallo")    = 1
+     * </pre>
+     *
+     * @param s  the first String, must not be null
+     * @param t  the second String, must not be null
+     * @return result distance
+     * @throws IllegalArgumentException if either String input {@code null}
+     * @since 3.0 Changed signature from getLevenshteinDistance(String, String) to
+     * getLevenshteinDistance(CharSequence, CharSequence)
+     */
+    public static int getLevenshteinDistance(CharSequence s, CharSequence t) {
+        if (s == null || t == null) {
+            throw new IllegalArgumentException("Strings must not be null");
+        }
+
+        /*
+           The difference between this impl. and the previous is that, rather
+           than creating and retaining a matrix of size s.length() + 1 by t.length() + 1,
+           we maintain two single-dimensional arrays of length s.length() + 1.  The first, d,
+           is the 'current working' distance array that maintains the newest distance cost
+           counts as we iterate through the characters of String s.  Each time we increment
+           the index of String t we are comparing, d is copied to p, the second int[].  Doing so
+           allows us to retain the previous cost counts as required by the algorithm (taking
+           the minimum of the cost count to the left, up one, and diagonally up and to the left
+           of the current cost count being calculated).  (Note that the arrays aren't really
+           copied anymore, just switched...this is clearly much better than cloning an array
+           or doing a System.arraycopy() each time  through the outer loop.)
+
+           Effectively, the difference between the two implementations is this one does not
+           cause an out of memory condition when calculating the LD over two very large strings.
+         */
+
+        int n = s.length(); // length of s
+        int m = t.length(); // length of t
+
+        if (n == 0) {
+            return m;
+        } else if (m == 0) {
+            return n;
+        }
+
+        if (n > m) {
+            // swap the input strings to consume less memory
+            CharSequence tmp = s;
+            s = t;
+            t = tmp;
+            n = m;
+            m = t.length();
+        }
+
+        int p[] = new int[n + 1]; //'previous' cost array, horizontally
+        int d[] = new int[n + 1]; // cost array, horizontally
+        int _d[]; //placeholder to assist in swapping p and d
+
+        // indexes into strings s and t
+        int i; // iterates through s
+        int j; // iterates through t
+
+        char t_j; // jth character of t
+
+        int cost; // cost
+
+        for (i = 0; i <= n; i++) {
+            p[i] = i;
+        }
+
+        for (j = 1; j <= m; j++) {
+            t_j = t.charAt(j - 1);
+            d[0] = j;
+
+            for (i = 1; i <= n; i++) {
+                cost = s.charAt(i - 1) == t_j ? 0 : 1;
+                // minimum of cell to the left+1, to the top+1, diagonally left and up +cost
+                d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] + cost);
+            }
+
+            // copy current distance counts to 'previous row' distance counts
+            _d = p;
+            p = d;
+            d = _d;
+        }
+
+        // our last action in the above loop was to switch d and p, so p now
+        // actually has the most recent cost counts
+        return p[n];
+    }
+
+    /**
+     * <p>Find the Levenshtein distance between two Strings if it's less than or equal to a given 
+     * threshold.</p>
+     *
+     * <p>This is the number of changes needed to change one String into
+     * another, where each change is a single character modification (deletion,
+     * insertion or substitution).</p>
+     *
+     * <p>This implementation follows from Algorithms on Strings, Trees and Sequences by Dan Gusfield
+     * and Chas Emerick's implementation of the Levenshtein distance algorithm from
+     * <a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a></p>
+     *
+     * <pre>
+     * StringUtils.getLevenshteinDistance(null, *, *)             = IllegalArgumentException
+     * StringUtils.getLevenshteinDistance(*, null, *)             = IllegalArgumentException
+     * StringUtils.getLevenshteinDistance(*, *, -1)               = IllegalArgumentException
+     * StringUtils.getLevenshteinDistance("","", 0)               = 0
+     * StringUtils.getLevenshteinDistance("aaapppp", "", 8)       = 7
+     * StringUtils.getLevenshteinDistance("aaapppp", "", 7)       = 7
+     * StringUtils.getLevenshteinDistance("aaapppp", "", 6))      = -1
+     * StringUtils.getLevenshteinDistance("elephant", "hippo", 7) = 7
+     * StringUtils.getLevenshteinDistance("elephant", "hippo", 6) = -1
+     * StringUtils.getLevenshteinDistance("hippo", "elephant", 7) = 7
+     * StringUtils.getLevenshteinDistance("hippo", "elephant", 6) = -1
+     * </pre>
+     *
+     * @param s  the first String, must not be null
+     * @param t  the second String, must not be null
+     * @param threshold the target threshold, must not be negative
+     * @return result distance, or {@code -1} if the distance would be greater than the threshold
+     * @throws IllegalArgumentException if either String input {@code null} or negative threshold
+     */
+    public static int getLevenshteinDistance(CharSequence s, CharSequence t, int threshold) {
+        if (s == null || t == null) {
+            throw new IllegalArgumentException("Strings must not be null");
+        }
+        if (threshold < 0) {
+            throw new IllegalArgumentException("Threshold must not be negative");
+        }
+
+        /*
+        This implementation only computes the distance if it's less than or equal to the
+        threshold value, returning -1 if it's greater.  The advantage is performance: unbounded
+        distance is O(nm), but a bound of k allows us to reduce it to O(km) time by only 
+        computing a diagonal stripe of width 2k + 1 of the cost table.
+        It is also possible to use this to compute the unbounded Levenshtein distance by starting
+        the threshold at 1 and doubling each time until the distance is found; this is O(dm), where
+        d is the distance.
+        
+        One subtlety comes from needing to ignore entries on the border of our stripe
+        eg.
+        p[] = |#|#|#|*
+        d[] =  *|#|#|#|
+        We must ignore the entry to the left of the leftmost member
+        We must ignore the entry above the rightmost member
+        
+        Another subtlety comes from our stripe running off the matrix if the strings aren't
+        of the same size.  Since string s is always swapped to be the shorter of the two, 
+        the stripe will always run off to the upper right instead of the lower left of the matrix.
+        
+        As a concrete example, suppose s is of length 5, t is of length 7, and our threshold is 1.
+        In this case we're going to walk a stripe of length 3.  The matrix would look like so:
+        
+           1 2 3 4 5
+        1 |#|#| | | |
+        2 |#|#|#| | |
+        3 | |#|#|#| |
+        4 | | |#|#|#|
+        5 | | | |#|#|
+        6 | | | | |#|
+        7 | | | | | |
+
+        Note how the stripe leads off the table as there is no possible way to turn a string of length 5
+        into one of length 7 in edit distance of 1.
+        
+        Additionally, this implementation decreases memory usage by using two 
+        single-dimensional arrays and swapping them back and forth instead of allocating
+        an entire n by m matrix.  This requires a few minor changes, such as immediately returning 
+        when it's detected that the stripe has run off the matrix and initially filling the arrays with
+        large values so that entries we don't compute are ignored.
+
+        See Algorithms on Strings, Trees and Sequences by Dan Gusfield for some discussion.
+         */
+
+        int n = s.length(); // length of s
+        int m = t.length(); // length of t
+
+        // if one string is empty, the edit distance is necessarily the length of the other
+        if (n == 0) {
+            return m <= threshold ? m : -1;
+        } else if (m == 0) {
+            return n <= threshold ? n : -1;
+        }
+
+        if (n > m) {
+            // swap the two strings to consume less memory
+            CharSequence tmp = s;
+            s = t;
+            t = tmp;
+            n = m;
+            m = t.length();
+        }
+
+        int p[] = new int[n + 1]; // 'previous' cost array, horizontally
+        int d[] = new int[n + 1]; // cost array, horizontally
+        int _d[]; // placeholder to assist in swapping p and d
+
+        // fill in starting table values
+        int boundary = Math.min(n, threshold) + 1;
+        for (int i = 0; i < boundary; i++) {
+            p[i] = i;
+        }
+        // these fills ensure that the value above the rightmost entry of our 
+        // stripe will be ignored in following loop iterations
+        Arrays.fill(p, boundary, p.length, Integer.MAX_VALUE);
+        Arrays.fill(d, Integer.MAX_VALUE);
+
+        // iterates through t
+        for (int j = 1; j <= m; j++) {
+            char t_j = t.charAt(j - 1); // jth character of t
+            d[0] = j;
+
+            // compute stripe indices, constrain to array size
+            int min = Math.max(1, j - threshold);
+            int max = Math.min(n, j + threshold);
+
+            // the stripe may lead off of the table if s and t are of different sizes
+            if (min > max) {
+                return -1;
+            }
+
+            // ignore entry left of leftmost
+            if (min > 1) {
+                d[min - 1] = Integer.MAX_VALUE;
+            }
+
+            // iterates through [min, max] in s
+            for (int i = min; i <= max; i++) {
+                if (s.charAt(i - 1) == t_j) {
+                    // diagonally left and up
+                    d[i] = p[i - 1];
+                } else {
+                    // 1 + minimum of cell to the left, to the top, diagonally left and up
+                    d[i] = 1 + Math.min(Math.min(d[i - 1], p[i]), p[i - 1]);
+                }
+            }
+
+            // copy current distance counts to 'previous row' distance counts
+            _d = p;
+            p = d;
+            d = _d;
+        }
+
+        // if p[n] is greater than the threshold, there's no guarantee on it being the correct
+        // distance
+        if (p[n] <= threshold) {
+            return p[n];
+        } else {
+            return -1;
+        }
+    }
+
+    // startsWith
+    //-----------------------------------------------------------------------
+
+    /**
+     * <p>Check if a CharSequence starts with a specified prefix.</p>
+     *
+     * <p>{@code null}s are handled without exceptions. Two {@code null}
+     * references are considered to be equal. The comparison is case sensitive.</p>
+     *
+     * <pre>
+     * StringUtils.startsWith(null, null)      = true
+     * StringUtils.startsWith(null, "abc")     = false
+     * StringUtils.startsWith("abcdef", null)  = false
+     * StringUtils.startsWith("abcdef", "abc") = true
+     * StringUtils.startsWith("ABCDEF", "abc") = false
+     * </pre>
+     *
+     * @see java.lang.String#startsWith(String)
+     * @param str  the CharSequence to check, may be null
+     * @param prefix the prefix to find, may be null
+     * @return {@code true} if the CharSequence starts with the prefix, case sensitive, or
+     *  both {@code null}
+     * @since 2.4
+     * @since 3.0 Changed signature from startsWith(String, String) to startsWith(CharSequence, CharSequence)
+     */
+    public static boolean startsWith(CharSequence str, CharSequence prefix) {
+        return startsWith(str, prefix, false);
+    }
+
+    /**
+     * <p>Case insensitive check if a CharSequence starts with a specified prefix.</p>
+     *
+     * <p>{@code null}s are handled without exceptions. Two {@code null}
+     * references are considered to be equal. The comparison is case insensitive.</p>
+     *
+     * <pre>
+     * StringUtils.startsWithIgnoreCase(null, null)      = true
+     * StringUtils.startsWithIgnoreCase(null, "abc")     = false
+     * StringUtils.startsWithIgnoreCase("abcdef", null)  = false
+     * StringUtils.startsWithIgnoreCase("abcdef", "abc") = true
+     * StringUtils.startsWithIgnoreCase("ABCDEF", "abc") = true
+     * </pre>
+     *
+     * @see java.lang.String#startsWith(String)
+     * @param str  the CharSequence to check, may be null
+     * @param prefix the prefix to find, may be null
+     * @return {@code true} if the CharSequence starts with the prefix, case insensitive, or
+     *  both {@code null}
+     * @since 2.4
+     * @since 3.0 Changed signature from startsWithIgnoreCase(String, String) to startsWithIgnoreCase(CharSequence, CharSequence)
+     */
+    public static boolean startsWithIgnoreCase(CharSequence str, CharSequence prefix) {
+        return startsWith(str, prefix, true);
+    }
+
+    /**
+     * <p>Check if a CharSequence starts with a specified prefix (optionally case insensitive).</p>
+     *
+     * @see java.lang.String#startsWith(String)
+     * @param str  the CharSequence to check, may be null
+     * @param prefix the prefix to find, may be null
+     * @param ignoreCase indicates whether the compare should ignore case
+     *  (case insensitive) or not.
+     * @return {@code true} if the CharSequence starts with the prefix or
+     *  both {@code null}
+     */
+    private static boolean startsWith(CharSequence str, CharSequence prefix, boolean ignoreCase) {
+        if (str == null || prefix == null) {
+            return str == null && prefix == null;
+        }
+        if (prefix.length() > str.length()) {
+            return false;
+        }
+        return CharSequenceUtils.regionMatches(str, ignoreCase, 0, prefix, 0, prefix.length());
+    }
+
+    /**
+     * <p>Check if a CharSequence starts with any of an array of specified strings.</p>
+     *
+     * <pre>
+     * StringUtils.startsWithAny(null, null)      = false
+     * StringUtils.startsWithAny(null, new String[] {"abc"})  = false
+     * StringUtils.startsWithAny("abcxyz", null)     = false
+     * StringUtils.startsWithAny("abcxyz", new String[] {""}) = false
+     * StringUtils.startsWithAny("abcxyz", new String[] {"abc"}) = true
+     * StringUtils.startsWithAny("abcxyz", new String[] {null, "xyz", "abc"}) = true
+     * </pre>
+     *
+     * @param string  the CharSequence to check, may be null
+     * @param searchStrings the CharSequences to find, may be null or empty
+     * @return {@code true} if the CharSequence starts with any of the the prefixes, case insensitive, or
+     *  both {@code null}
+     * @since 2.5
+     * @since 3.0 Changed signature from startsWithAny(String, String[]) to startsWithAny(CharSequence, CharSequence...)
+     */
+    public static boolean startsWithAny(CharSequence string, CharSequence... searchStrings) {
+        if (isEmpty(string) || ArrayUtils.isEmpty(searchStrings)) {
+            return false;
+        }
+        for (CharSequence searchString : searchStrings) {
+            if (StringUtils.startsWith(string, searchString)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // endsWith
+    //-----------------------------------------------------------------------
+
+    /**
+     * <p>Check if a CharSequence ends with a specified suffix.</p>
+     *
+     * <p>{@code null}s are handled without exceptions. Two {@code null}
+     * references are considered to be equal. The comparison is case sensitive.</p>
+     *
+     * <pre>
+     * StringUtils.endsWith(null, null)      = true
+     * StringUtils.endsWith(null, "def")     = false
+     * StringUtils.endsWith("abcdef", null)  = false
+     * StringUtils.endsWith("abcdef", "def") = true
+     * StringUtils.endsWith("ABCDEF", "def") = false
+     * StringUtils.endsWith("ABCDEF", "cde") = false
+     * </pre>
+     *
+     * @see java.lang.String#endsWith(String)
+     * @param str  the CharSequence to check, may be null
+     * @param suffix the suffix to find, may be null
+     * @return {@code true} if the CharSequence ends with the suffix, case sensitive, or
+     *  both {@code null}
+     * @since 2.4
+     * @since 3.0 Changed signature from endsWith(String, String) to endsWith(CharSequence, CharSequence)
+     */
+    public static boolean endsWith(CharSequence str, CharSequence suffix) {
+        return endsWith(str, suffix, false);
+    }
+
+    /**
+     * <p>Case insensitive check if a CharSequence ends with a specified suffix.</p>
+     *
+     * <p>{@code null}s are handled without exceptions. Two {@code null}
+     * references are considered to be equal. The comparison is case insensitive.</p>
+     *
+     * <pre>
+     * StringUtils.endsWithIgnoreCase(null, null)      = true
+     * StringUtils.endsWithIgnoreCase(null, "def")     = false
+     * StringUtils.endsWithIgnoreCase("abcdef", null)  = false
+     * StringUtils.endsWithIgnoreCase("abcdef", "def") = true
+     * StringUtils.endsWithIgnoreCase("ABCDEF", "def") = true
+     * StringUtils.endsWithIgnoreCase("ABCDEF", "cde") = false
+     * </pre>
+     *
+     * @see java.lang.String#endsWith(String)
+     * @param str  the CharSequence to check, may be null
+     * @param suffix the suffix to find, may be null
+     * @return {@code true} if the CharSequence ends with the suffix, case insensitive, or
+     *  both {@code null}
+     * @since 2.4
+     * @since 3.0 Changed signature from endsWithIgnoreCase(String, String) to endsWithIgnoreCase(CharSequence, CharSequence)
+     */
+    public static boolean endsWithIgnoreCase(CharSequence str, CharSequence suffix) {
+        return endsWith(str, suffix, true);
+    }
+
+    /**
+     * <p>Check if a CharSequence ends with a specified suffix (optionally case insensitive).</p>
+     *
+     * @see java.lang.String#endsWith(String)
+     * @param str  the CharSequence to check, may be null
+     * @param suffix the suffix to find, may be null
+     * @param ignoreCase indicates whether the compare should ignore case
+     *  (case insensitive) or not.
+     * @return {@code true} if the CharSequence starts with the prefix or
+     *  both {@code null}
+     */
+    private static boolean endsWith(CharSequence str, CharSequence suffix, boolean ignoreCase) {
+        if (str == null || suffix == null) {
+            return str == null && suffix == null;
+        }
+        if (suffix.length() > str.length()) {
+            return false;
+        }
+        int strOffset = str.length() - suffix.length();
+        return CharSequenceUtils.regionMatches(str, ignoreCase, strOffset, suffix, 0, suffix.length());
+    }
+
+    /**
+     * <p>
+     * Similar to <a
+     * href="http://www.w3.org/TR/xpath/#function-normalize-space">http://www.w3.org/TR/xpath/#function-normalize
+     * -space</a>
+     * </p>
+     * <p>
+     * The function returns the argument string with whitespace normalized by using
+     * <code>{@link #trim(String)}</code> to remove leading and trailing whitespace
+     * and then replacing sequences of whitespace characters by a single space.
+     * </p>
+     * In XML Whitespace characters are the same as those allowed by the <a
+     * href="http://www.w3.org/TR/REC-xml/#NT-S">S</a> production, which is S ::= (#x20 | #x9 | #xD | #xA)+
+     * <p>
+     * Java's regexp pattern \s defines whitespace as [ \t\n\x0B\f\r]
+     * <p>
+     * For reference:
+     * <ul>
+     * <li>\x0B = vertical tab</li>
+     * <li>\f = #xC = form feed</li>
+     * <li>#x20 = space</li>
+     * <li>#x9 = \t</li>
+     * <li>#xA = \n</li>
+     * <li>#xD = \r</li>
+     * </ul>
+     * </p>
+     * <p>
+     * The difference is that Java's whitespace includes vertical tab and form feed, which this functional will also
+     * normalize. Additionally <code>{@link #trim(String)}</code> removes control characters (char &lt;= 32) from both
+     * ends of this String.
+     * </p>
+     *
+     * @see Pattern
+     * @see #trim(String)
+     * @see <a
+     *      href="http://www.w3.org/TR/xpath/#function-normalize-space">http://www.w3.org/TR/xpath/#function-normalize-space</a>
+     * @param str the source String to normalize whitespaces from, may be null
+     * @return the modified string with whitespace normalized, {@code null} if null String input
+     *
+     * @since 3.0
+     */
+    public static String normalizeSpace(String str) {
+        if (str == null) {
+            return null;
+        }
+        return WHITESPACE_BLOCK.matcher(trim(str)).replaceAll(" ");
+    }
+
+    /**
+     * <p>Check if a CharSequence ends with any of an array of specified strings.</p>
+     *
+     * <pre>
+     * StringUtils.endsWithAny(null, null)      = false
+     * StringUtils.endsWithAny(null, new String[] {"abc"})  = false
+     * StringUtils.endsWithAny("abcxyz", null)     = false
+     * StringUtils.endsWithAny("abcxyz", new String[] {""}) = true
+     * StringUtils.endsWithAny("abcxyz", new String[] {"xyz"}) = true
+     * StringUtils.endsWithAny("abcxyz", new String[] {null, "xyz", "abc"}) = true
+     * </pre>
+     *
+     * @param string  the CharSequence to check, may be null
+     * @param searchStrings the CharSequences to find, may be null or empty
+     * @return {@code true} if the CharSequence ends with any of the the prefixes, case insensitive, or
+     *  both {@code null}
+     * @since 3.0
+     */
+    public static boolean endsWithAny(CharSequence string, CharSequence... searchStrings) {
+        if (isEmpty(string) || ArrayUtils.isEmpty(searchStrings)) {
+            return false;
+        }
+        for (CharSequence searchString : searchStrings) {
+            if (StringUtils.endsWith(string, searchString)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Converts a <code>byte[]</code> to a String using the specified character encoding.
+     * 
+     * @param bytes
+     *            the byte array to read from
+     * @param charsetName
+     *            the encoding to use, if null then use the platform default
+     * @return a new String
+     * @throws UnsupportedEncodingException
+     *             If the named charset is not supported
+     * @throws NullPointerException
+     *             if the input is null
+     * @since 3.1
+     */
+    public static String toString(byte[] bytes, String charsetName) throws UnsupportedEncodingException {
+        return charsetName == null ? new String(bytes) : new String(bytes, charsetName);
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/SystemUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/SystemUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/SystemUtils.java	(revision 28000)
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.commons.lang3;
+
+
+/**
+ * <p>
+ * Helpers for {@code java.lang.System}.
+ * </p>
+ * <p>
+ * If a system property cannot be read due to security restrictions, the corresponding field in this class will be set
+ * to {@code null} and a message will be written to {@code System.err}.
+ * </p>
+ * <p>
+ * #ThreadSafe#
+ * </p>
+ *
+ * @since 1.0
+ * @version $Id: SystemUtils.java 1199816 2011-11-09 16:11:34Z bayard $
+ */
+public class SystemUtils {
+
+    // System property constants
+    // -----------------------------------------------------------------------
+    // These MUST be declared first. Other constants depend on this.
+
+    /**
+     * <p>
+     * The {@code line.separator} System Property. Line separator (<code>&quot;\n&quot;</code> on UNIX).
+     * </p>
+     * <p>
+     * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
+     * not exist.
+     * </p>
+     * <p>
+     * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
+     * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
+     * sync with that System property.
+     * </p>
+     *
+     * @since Java 1.1
+     */
+    public static final String LINE_SEPARATOR = getSystemProperty("line.separator");
+
+
+    // -----------------------------------------------------------------------
+    /**
+     * <p>
+     * Gets a System property, defaulting to {@code null} if the property cannot be read.
+     * </p>
+     * <p>
+     * If a {@code SecurityException} is caught, the return value is {@code null} and a message is written to
+     * {@code System.err}.
+     * </p>
+     *
+     * @param property the system property name
+     * @return the system property value or {@code null} if a security problem occurs
+     */
+    private static String getSystemProperty(String property) {
+        try {
+            return System.getProperty(property);
+        } catch (SecurityException ex) {
+            // we are not allowed to look at this property
+            System.err.println("Caught a SecurityException reading the system property '" + property
+                    + "'; the SystemUtils property value will default to null.");
+            return null;
+        }
+    }
+
+
+    // -----------------------------------------------------------------------
+    /**
+     * <p>
+     * SystemUtils instances should NOT be constructed in standard programming. Instead, the class should be used as
+     * {@code SystemUtils.FILE_SEPARATOR}.
+     * </p>
+     * <p>
+     * This constructor is public to permit tools that require a JavaBean instance to operate.
+     * </p>
+     */
+    public SystemUtils() {
+        super();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/overview.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/overview.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/overview.html	(revision 28000)
@@ -0,0 +1,23 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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.
+-->
+<html>
+<body>
+<p>
+This document is the API specification for the Apache Commons Lang library.
+</p>
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/package.html	(revision 28000)
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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.
+-->
+<html>
+<body>
+Provides highly reusable static utility methods, chiefly concerned 
+with adding value to the {@link java.lang} classes.
+@since 1.0
+<p>Most of these classes are immutable and thus thread-safe. 
+However Charset is not currently guaranteed thread-safe under all circumstances.</p>
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/text/WordUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/text/WordUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/text/WordUtils.java	(revision 28000)
@@ -0,0 +1,444 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.commons.lang3.text;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.SystemUtils;
+
+/**
+ * <p>Operations on Strings that contain words.</p>
+ * 
+ * <p>This class tries to handle <code>null</code> input gracefully.
+ * An exception will not be thrown for a <code>null</code> input.
+ * Each method documents its behaviour in more detail.</p>
+ * 
+ * @since 2.0
+ * @version $Id: WordUtils.java 1199894 2011-11-09 17:53:59Z ggregory $
+ */
+public class WordUtils {
+
+    /**
+     * <p><code>WordUtils</code> instances should NOT be constructed in
+     * standard programming. Instead, the class should be used as
+     * <code>WordUtils.wrap("foo bar", 20);</code>.</p>
+     *
+     * <p>This constructor is public to permit tools that require a JavaBean
+     * instance to operate.</p>
+     */
+    public WordUtils() {
+      super();
+    }
+
+    // Wrapping
+    //--------------------------------------------------------------------------
+    /**
+     * <p>Wraps a single line of text, identifying words by <code>' '</code>.</p>
+     * 
+     * <p>New lines will be separated by the system property line separator.
+     * Very long words, such as URLs will <i>not</i> be wrapped.</p>
+     * 
+     * <p>Leading spaces on a new line are stripped.
+     * Trailing spaces are not stripped.</p>
+     *
+     * <pre>
+     * WordUtils.wrap(null, *) = null
+     * WordUtils.wrap("", *) = ""
+     * </pre>
+     *
+     * @param str  the String to be word wrapped, may be null
+     * @param wrapLength  the column to wrap the words at, less than 1 is treated as 1
+     * @return a line with newlines inserted, <code>null</code> if null input
+     */
+    public static String wrap(String str, int wrapLength) { // NO_UCD
+        return wrap(str, wrapLength, null, false);
+    }
+    
+    /**
+     * <p>Wraps a single line of text, identifying words by <code>' '</code>.</p>
+     * 
+     * <p>Leading spaces on a new line are stripped.
+     * Trailing spaces are not stripped.</p>
+     * 
+     * <pre>
+     * WordUtils.wrap(null, *, *, *) = null
+     * WordUtils.wrap("", *, *, *) = ""
+     * </pre>
+     *
+     * @param str  the String to be word wrapped, may be null
+     * @param wrapLength  the column to wrap the words at, less than 1 is treated as 1
+     * @param newLineStr  the string to insert for a new line, 
+     *  <code>null</code> uses the system property line separator
+     * @param wrapLongWords  true if long words (such as URLs) should be wrapped
+     * @return a line with newlines inserted, <code>null</code> if null input
+     */
+    public static String wrap(String str, int wrapLength, String newLineStr, boolean wrapLongWords) {
+        if (str == null) {
+            return null;
+        }
+        if (newLineStr == null) {
+            newLineStr = SystemUtils.LINE_SEPARATOR;
+        }
+        if (wrapLength < 1) {
+            wrapLength = 1;
+        }
+        int inputLineLength = str.length();
+        int offset = 0;
+        StringBuilder wrappedLine = new StringBuilder(inputLineLength + 32);
+        
+        while (inputLineLength - offset > wrapLength) {
+            if (str.charAt(offset) == ' ') {
+                offset++;
+                continue;
+            }
+            int spaceToWrapAt = str.lastIndexOf(' ', wrapLength + offset);
+
+            if (spaceToWrapAt >= offset) {
+                // normal case
+                wrappedLine.append(str.substring(offset, spaceToWrapAt));
+                wrappedLine.append(newLineStr);
+                offset = spaceToWrapAt + 1;
+                
+            } else {
+                // really long word or URL
+                if (wrapLongWords) {
+                    // wrap really long word one line at a time
+                    wrappedLine.append(str.substring(offset, wrapLength + offset));
+                    wrappedLine.append(newLineStr);
+                    offset += wrapLength;
+                } else {
+                    // do not wrap really long word, just extend beyond limit
+                    spaceToWrapAt = str.indexOf(' ', wrapLength + offset);
+                    if (spaceToWrapAt >= 0) {
+                        wrappedLine.append(str.substring(offset, spaceToWrapAt));
+                        wrappedLine.append(newLineStr);
+                        offset = spaceToWrapAt + 1;
+                    } else {
+                        wrappedLine.append(str.substring(offset));
+                        offset = inputLineLength;
+                    }
+                }
+            }
+        }
+
+        // Whatever is left in line is short enough to just pass through
+        wrappedLine.append(str.substring(offset));
+
+        return wrappedLine.toString();
+    }
+
+    // Capitalizing
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Capitalizes all the whitespace separated words in a String.
+     * Only the first letter of each word is changed. To convert the 
+     * rest of each word to lowercase at the same time, 
+     * use {@link #capitalizeFully(String)}.</p>
+     *
+     * <p>Whitespace is defined by {@link Character#isWhitespace(char)}.
+     * A <code>null</code> input String returns <code>null</code>.
+     * Capitalization uses the Unicode title case, normally equivalent to
+     * upper case.</p>
+     *
+     * <pre>
+     * WordUtils.capitalize(null)        = null
+     * WordUtils.capitalize("")          = ""
+     * WordUtils.capitalize("i am FINE") = "I Am FINE"
+     * </pre>
+     * 
+     * @param str  the String to capitalize, may be null
+     * @return capitalized String, <code>null</code> if null String input
+     * @see #uncapitalize(String)
+     * @see #capitalizeFully(String)
+     */
+    public static String capitalize(String str) { // NO_UCD
+        return capitalize(str, null);
+    }
+
+    /**
+     * <p>Capitalizes all the delimiter separated words in a String.
+     * Only the first letter of each word is changed. To convert the 
+     * rest of each word to lowercase at the same time, 
+     * use {@link #capitalizeFully(String, char[])}.</p>
+     *
+     * <p>The delimiters represent a set of characters understood to separate words.
+     * The first string character and the first non-delimiter character after a
+     * delimiter will be capitalized. </p>
+     *
+     * <p>A <code>null</code> input String returns <code>null</code>.
+     * Capitalization uses the Unicode title case, normally equivalent to
+     * upper case.</p>
+     *
+     * <pre>
+     * WordUtils.capitalize(null, *)            = null
+     * WordUtils.capitalize("", *)              = ""
+     * WordUtils.capitalize(*, new char[0])     = *
+     * WordUtils.capitalize("i am fine", null)  = "I Am Fine"
+     * WordUtils.capitalize("i aM.fine", {'.'}) = "I aM.Fine"
+     * </pre>
+     * 
+     * @param str  the String to capitalize, may be null
+     * @param delimiters  set of characters to determine capitalization, null means whitespace
+     * @return capitalized String, <code>null</code> if null String input
+     * @see #uncapitalize(String)
+     * @see #capitalizeFully(String)
+     * @since 2.1
+     */
+    public static String capitalize(String str, char... delimiters) {
+        int delimLen = delimiters == null ? -1 : delimiters.length;
+        if (StringUtils.isEmpty(str) || delimLen == 0) {
+            return str;
+        }
+        char[] buffer = str.toCharArray();
+        boolean capitalizeNext = true;
+        for (int i = 0; i < buffer.length; i++) {
+            char ch = buffer[i];
+            if (isDelimiter(ch, delimiters)) {
+                capitalizeNext = true;
+            } else if (capitalizeNext) {
+                buffer[i] = Character.toTitleCase(ch);
+                capitalizeNext = false;
+            }
+        }
+        return new String(buffer);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Converts all the whitespace separated words in a String into capitalized words, 
+     * that is each word is made up of a titlecase character and then a series of 
+     * lowercase characters.  </p>
+     *
+     * <p>Whitespace is defined by {@link Character#isWhitespace(char)}.
+     * A <code>null</code> input String returns <code>null</code>.
+     * Capitalization uses the Unicode title case, normally equivalent to
+     * upper case.</p>
+     *
+     * <pre>
+     * WordUtils.capitalizeFully(null)        = null
+     * WordUtils.capitalizeFully("")          = ""
+     * WordUtils.capitalizeFully("i am FINE") = "I Am Fine"
+     * </pre>
+     * 
+     * @param str  the String to capitalize, may be null
+     * @return capitalized String, <code>null</code> if null String input
+     */
+    public static String capitalizeFully(String str) {
+        return capitalizeFully(str, null);
+    }
+
+    /**
+     * <p>Converts all the delimiter separated words in a String into capitalized words, 
+     * that is each word is made up of a titlecase character and then a series of 
+     * lowercase characters. </p>
+     *
+     * <p>The delimiters represent a set of characters understood to separate words.
+     * The first string character and the first non-delimiter character after a
+     * delimiter will be capitalized. </p>
+     *
+     * <p>A <code>null</code> input String returns <code>null</code>.
+     * Capitalization uses the Unicode title case, normally equivalent to
+     * upper case.</p>
+     *
+     * <pre>
+     * WordUtils.capitalizeFully(null, *)            = null
+     * WordUtils.capitalizeFully("", *)              = ""
+     * WordUtils.capitalizeFully(*, null)            = *
+     * WordUtils.capitalizeFully(*, new char[0])     = *
+     * WordUtils.capitalizeFully("i aM.fine", {'.'}) = "I am.Fine"
+     * </pre>
+     * 
+     * @param str  the String to capitalize, may be null
+     * @param delimiters  set of characters to determine capitalization, null means whitespace
+     * @return capitalized String, <code>null</code> if null String input
+     * @since 2.1
+     */
+    public static String capitalizeFully(String str, char... delimiters) {
+        int delimLen = delimiters == null ? -1 : delimiters.length;
+        if (StringUtils.isEmpty(str) || delimLen == 0) {
+            return str;
+        }
+        str = str.toLowerCase();
+        return capitalize(str, delimiters);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Uncapitalizes all the whitespace separated words in a String.
+     * Only the first letter of each word is changed.</p>
+     *
+     * <p>Whitespace is defined by {@link Character#isWhitespace(char)}.
+     * A <code>null</code> input String returns <code>null</code>.</p>
+     *
+     * <pre>
+     * WordUtils.uncapitalize(null)        = null
+     * WordUtils.uncapitalize("")          = ""
+     * WordUtils.uncapitalize("I Am FINE") = "i am fINE"
+     * </pre>
+     * 
+     * @param str  the String to uncapitalize, may be null
+     * @return uncapitalized String, <code>null</code> if null String input
+     * @see #capitalize(String)
+     */
+    public static String uncapitalize(String str) { // NO_UCD
+        return uncapitalize(str, null);
+    }
+
+    /**
+     * <p>Uncapitalizes all the whitespace separated words in a String.
+     * Only the first letter of each word is changed.</p>
+     *
+     * <p>The delimiters represent a set of characters understood to separate words.
+     * The first string character and the first non-delimiter character after a
+     * delimiter will be uncapitalized. </p>
+     *
+     * <p>Whitespace is defined by {@link Character#isWhitespace(char)}.
+     * A <code>null</code> input String returns <code>null</code>.</p>
+     *
+     * <pre>
+     * WordUtils.uncapitalize(null, *)            = null
+     * WordUtils.uncapitalize("", *)              = ""
+     * WordUtils.uncapitalize(*, null)            = *
+     * WordUtils.uncapitalize(*, new char[0])     = *
+     * WordUtils.uncapitalize("I AM.FINE", {'.'}) = "i AM.fINE"
+     * </pre>
+     * 
+     * @param str  the String to uncapitalize, may be null
+     * @param delimiters  set of characters to determine uncapitalization, null means whitespace
+     * @return uncapitalized String, <code>null</code> if null String input
+     * @see #capitalize(String)
+     * @since 2.1
+     */
+    public static String uncapitalize(String str, char... delimiters) {
+        int delimLen = delimiters == null ? -1 : delimiters.length;
+        if (StringUtils.isEmpty(str) || delimLen == 0) {
+            return str;
+        }
+        char[] buffer = str.toCharArray();
+        boolean uncapitalizeNext = true;
+        for (int i = 0; i < buffer.length; i++) {
+            char ch = buffer[i];
+            if (isDelimiter(ch, delimiters)) {
+                uncapitalizeNext = true;
+            } else if (uncapitalizeNext) {
+                buffer[i] = Character.toLowerCase(ch);
+                uncapitalizeNext = false;
+            }
+        }
+        return new String(buffer);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Extracts the initial letters from each word in the String.</p>
+     * 
+     * <p>The first letter of the string and all first letters after
+     * whitespace are returned as a new string.
+     * Their case is not changed.</p>
+     *
+     * <p>Whitespace is defined by {@link Character#isWhitespace(char)}.
+     * A <code>null</code> input String returns <code>null</code>.</p>
+     *
+     * <pre>
+     * WordUtils.initials(null)             = null
+     * WordUtils.initials("")               = ""
+     * WordUtils.initials("Ben John Lee")   = "BJL"
+     * WordUtils.initials("Ben J.Lee")      = "BJ"
+     * </pre>
+     *
+     * @param str  the String to get initials from, may be null
+     * @return String of initial letters, <code>null</code> if null String input
+     * @see #initials(String,char[])
+     * @since 2.2
+     */
+    public static String initials(String str) { // NO_UCD
+        return initials(str, null);
+    }
+
+    /**
+     * <p>Extracts the initial letters from each word in the String.</p>
+     * 
+     * <p>The first letter of the string and all first letters after the
+     * defined delimiters are returned as a new string.
+     * Their case is not changed.</p>
+     *
+     * <p>If the delimiters array is null, then Whitespace is used.
+     * Whitespace is defined by {@link Character#isWhitespace(char)}.
+     * A <code>null</code> input String returns <code>null</code>.
+     * An empty delimiter array returns an empty String.</p>
+     *
+     * <pre>
+     * WordUtils.initials(null, *)                = null
+     * WordUtils.initials("", *)                  = ""
+     * WordUtils.initials("Ben John Lee", null)   = "BJL"
+     * WordUtils.initials("Ben J.Lee", null)      = "BJ"
+     * WordUtils.initials("Ben J.Lee", [' ','.']) = "BJL"
+     * WordUtils.initials(*, new char[0])         = ""
+     * </pre>
+     * 
+     * @param str  the String to get initials from, may be null
+     * @param delimiters  set of characters to determine words, null means whitespace
+     * @return String of initial letters, <code>null</code> if null String input
+     * @see #initials(String)
+     * @since 2.2
+     */
+    public static String initials(String str, char... delimiters) {
+        if (StringUtils.isEmpty(str)) {
+            return str;
+        }
+        if (delimiters != null && delimiters.length == 0) {
+            return "";
+        }
+        int strLen = str.length();
+        char[] buf = new char[strLen / 2 + 1];
+        int count = 0;
+        boolean lastWasGap = true;
+        for (int i = 0; i < strLen; i++) {
+            char ch = str.charAt(i);
+
+            if (isDelimiter(ch, delimiters)) {
+                lastWasGap = true;
+            } else if (lastWasGap) {
+                buf[count++] = ch;
+                lastWasGap = false;
+            } else {
+                continue; // ignore ch
+            }
+        }
+        return new String(buf, 0, count);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Is the character a delimiter.
+     *
+     * @param ch  the character to check
+     * @param delimiters  the delimiters
+     * @return true if it is a delimiter
+     */
+    private static boolean isDelimiter(char ch, char[] delimiters) {
+        if (delimiters == null) {
+            return Character.isWhitespace(ch);
+        }
+        for (char delimiter : delimiters) {
+            if (ch == delimiter) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/text/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/text/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/commons/lang3/text/package.html	(revision 28000)
@@ -0,0 +1,26 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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.
+-->
+<html>
+<body>
+<p>
+Provides classes for handling and manipulating text, partly as an extension to {@link java.text}.
+The classes in this package are, for the most part, intended to be instantiated.
+(ie. they are not utility classes with lots of static methods)
+</p>
+@since 2.1
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/OldFileFormatException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/OldFileFormatException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/OldFileFormatException.java	(revision 28000)
@@ -0,0 +1,28 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi;
+
+/**
+ * Base class of all the exceptions that POI throws in the event
+ * that it's given a file that's older than currently supported.
+ */
+@SuppressWarnings("serial")
+public abstract class OldFileFormatException extends IllegalArgumentException {
+	public OldFileFormatException(String s) {
+		super(s);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/POIDocument.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/POIDocument.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/POIDocument.java	(revision 28000)
@@ -0,0 +1,135 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi;
+
+import java.io.IOException;
+
+import org.apache.poi.hpsf.DocumentSummaryInformation;
+import org.apache.poi.hpsf.PropertySet;
+import org.apache.poi.hpsf.PropertySetFactory;
+import org.apache.poi.hpsf.SummaryInformation;
+import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.DocumentInputStream;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * This holds the common functionality for all POI
+ *  Document classes.
+ * Currently, this relates to Document Information Properties 
+ * 
+ * @author Nick Burch
+ */
+public abstract class POIDocument {
+	/** Holds metadata on our document */
+	private SummaryInformation sInf;
+	/** Holds further metadata on our document */
+	private DocumentSummaryInformation dsInf;
+	/**	The directory that our document lives in */
+	protected DirectoryNode directory;
+	
+	/** For our own logging use */
+	private final static POILogger logger = POILogFactory.getLogger(POIDocument.class);
+
+    /* Have the property streams been read yet? (Only done on-demand) */
+    private boolean initialized = false;
+    
+
+    protected POIDocument(DirectoryNode dir) {
+    	this.directory = dir;
+    }
+
+
+	/**
+	 * Fetch the Document Summary Information of the document
+	 */
+	public DocumentSummaryInformation getDocumentSummaryInformation() { // NO_UCD
+        if(!initialized) readProperties();
+        return dsInf;
+    }
+
+	/** 
+	 * Fetch the Summary Information of the document
+	 */
+	public SummaryInformation getSummaryInformation() { // NO_UCD
+        if(!initialized) readProperties();
+        return sInf;
+    }
+	
+
+	/**
+	 * Find, and create objects for, the standard
+	 *  Documment Information Properties (HPSF).
+	 * If a given property set is missing or corrupt,
+	 *  it will remain null;
+	 */
+	protected void readProperties() {
+		PropertySet ps;
+		
+		// DocumentSummaryInformation
+		ps = getPropertySet(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
+		if(ps != null && ps instanceof DocumentSummaryInformation) {
+			dsInf = (DocumentSummaryInformation)ps;
+		} else if(ps != null) {
+			logger.log(POILogger.WARN, "DocumentSummaryInformation property set came back with wrong class - ", ps.getClass());
+		}
+
+		// SummaryInformation
+		ps = getPropertySet(SummaryInformation.DEFAULT_STREAM_NAME);
+		if(ps instanceof SummaryInformation) {
+			sInf = (SummaryInformation)ps;
+		} else if(ps != null) {
+			logger.log(POILogger.WARN, "SummaryInformation property set came back with wrong class - ", ps.getClass());
+		}
+
+		// Mark the fact that we've now loaded up the properties
+        initialized = true;
+	}
+
+	/** 
+	 * For a given named property entry, either return it or null if
+	 *  if it wasn't found
+	 */
+	protected PropertySet getPropertySet(String setName) {
+        //directory can be null when creating new documents
+        if(directory == null) return null;
+        
+        DocumentInputStream dis;
+		try {
+			// Find the entry, and get an input stream for it
+			dis = directory.createDocumentInputStream(setName);
+		} catch(IOException ie) {
+			// Oh well, doesn't exist
+			logger.log(POILogger.WARN, "Error getting property set with name " + setName + "\n" + ie);
+			return null;
+		}
+
+		try {
+			// Create the Property Set
+			PropertySet set = PropertySetFactory.create(dis);
+			return set;
+		} catch(IOException ie) {
+			// Must be corrupt or something like that
+			logger.log(POILogger.WARN, "Error creating property set with name " + setName + "\n" + ie);
+		} catch(org.apache.poi.hpsf.HPSFException he) {
+			// Oh well, doesn't exist
+			logger.log(POILogger.WARN, "Error creating property set with name " + setName + "\n" + he);
+		}
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/ClassID.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/ClassID.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/ClassID.java	(revision 28000)
@@ -0,0 +1,218 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import org.apache.poi.util.HexDump;
+
+/**
+ *  <p>Represents a class ID (16 bytes). Unlike other little-endian
+ *  type the {@link ClassID} is not just 16 bytes stored in the wrong
+ *  order. Instead, it is a double word (4 bytes) followed by two
+ *  words (2 bytes each) followed by 8 bytes.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+public class ClassID
+{
+
+    /**
+     * <p>The bytes making out the class ID in correct order,
+     * i.e. big-endian.</p>
+     */
+    protected byte[] bytes;
+
+
+
+    /**
+     *  <p>Creates a {@link ClassID} and reads its value from a byte
+     *  array.</p>
+     *
+     * @param src The byte array to read from.
+     * @param offset The offset of the first byte to read.
+     */
+    public ClassID(final byte[] src, final int offset)
+    {
+        read(src, offset);
+    }
+
+
+    /**
+     *  <p>Creates a {@link ClassID} and initializes its value with
+     *  0x00 bytes.</p>
+     */
+    public ClassID()
+    {
+        bytes = new byte[LENGTH];
+        for (int i = 0; i < LENGTH; i++)
+            bytes[i] = 0x00;
+    }
+
+
+
+    /** <p>The number of bytes occupied by this object in the byte
+     * stream.</p> */
+    public static final int LENGTH = 16;
+
+
+
+
+    /**
+     * <p>Gets the bytes making out the class ID. They are returned in
+     * correct order, i.e. big-endian.</p>
+     *
+     * @return the bytes making out the class ID.
+     */
+    public byte[] getBytes()
+    {
+        return bytes;
+    }
+
+
+
+    /**
+     * <p>Reads the class ID's value from a byte array by turning
+     * little-endian into big-endian.</p>
+     *
+     * @param src The byte array to read from
+     *
+     * @param offset The offset within the <var>src</var> byte array
+     *
+     * @return A byte array containing the class ID.
+     */
+    public byte[] read(final byte[] src, final int offset)
+    {
+        bytes = new byte[16];
+
+        /* Read double word. */
+        bytes[0] = src[3 + offset];
+        bytes[1] = src[2 + offset];
+        bytes[2] = src[1 + offset];
+        bytes[3] = src[0 + offset];
+
+        /* Read first word. */
+        bytes[4] = src[5 + offset];
+        bytes[5] = src[4 + offset];
+
+        /* Read second word. */
+        bytes[6] = src[7 + offset];
+        bytes[7] = src[6 + offset];
+
+        /* Read 8 bytes. */
+        for (int i = 8; i < 16; i++)
+            bytes[i] = src[i + offset];
+
+        return bytes;
+    }
+
+
+
+    /**
+     * <p>Writes the class ID to a byte array in the
+     * little-endian format.</p>
+     *
+     * @param dst The byte array to write to.
+     *
+     * @param offset The offset within the <var>dst</var> byte array.
+     *
+     * @exception ArrayStoreException if there is not enough room for the class
+     * ID 16 bytes in the byte array after the <var>offset</var> position.
+     */
+    public void write(final byte[] dst, final int offset)
+    throws ArrayStoreException
+    {
+        /* Check array size: */
+        if (dst.length < 16)
+            throw new ArrayStoreException
+                ("Destination byte[] must have room for at least 16 bytes, " +
+                 "but has a length of only " + dst.length + ".");
+        /* Write double word. */
+        dst[0 + offset] = bytes[3];
+        dst[1 + offset] = bytes[2];
+        dst[2 + offset] = bytes[1];
+        dst[3 + offset] = bytes[0];
+
+        /* Write first word. */
+        dst[4 + offset] = bytes[5];
+        dst[5 + offset] = bytes[4];
+
+        /* Write second word. */
+        dst[6 + offset] = bytes[7];
+        dst[7 + offset] = bytes[6];
+
+        /* Write 8 bytes. */
+        for (int i = 8; i < 16; i++)
+            dst[i + offset] = bytes[i];
+    }
+
+
+
+    /**
+     * <p>Checks whether this <code>ClassID</code> is equal to another
+     * object.</p>
+     *
+     * @param o the object to compare this <code>PropertySet</code> with
+     * @return <code>true</code> if the objects are equal, else
+     * <code>false</code>.</p>
+     */
+    public boolean equals(final Object o)
+    {
+        if (o == null || !(o instanceof ClassID))
+            return false;
+        final ClassID cid = (ClassID) o;
+        if (bytes.length != cid.bytes.length)
+            return false;
+        for (int i = 0; i < bytes.length; i++)
+            if (bytes[i] != cid.bytes[i])
+                return false;
+        return true;
+    }
+
+
+
+    /**
+     * @see Object#hashCode()
+     */
+    public int hashCode()
+    {
+        return new String(bytes).hashCode();
+    }
+
+
+
+    /**
+     * <p>Returns a human-readable representation of the Class ID in standard 
+     * format <code>"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"</code>.</p>
+     * 
+     * @return String representation of the Class ID represented by this object.
+     */
+    public String toString()
+    {
+        StringBuffer sbClassId = new StringBuffer(38);
+        sbClassId.append('{');
+        for (int i = 0; i < 16; i++)
+        {
+            sbClassId.append(HexDump.toHex(bytes[i]));
+            if (i == 3 || i == 5 || i == 7 || i == 9)
+                sbClassId.append('-');
+        }
+        sbClassId.append('}');
+        return sbClassId.toString();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Constants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Constants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Constants.java	(revision 28000)
@@ -0,0 +1,194 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+/**
+ * <p>Defines constants of general use.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+public class Constants
+{
+    /** <p>Codepage 037, a special case</p> */
+    public static final int CP_037 = 37;
+
+    /** <p>Codepage for SJIS</p> */
+    public static final int CP_SJIS = 932;
+
+    /** <p>Codepage for GBK, aka MS936</p> */
+    public static final int CP_GBK = 936;
+
+    /** <p>Codepage for MS949</p> */
+    public static final int CP_MS949 = 949;
+
+    /** <p>Codepage for UTF-16</p> */
+    public static final int CP_UTF16 = 1200;
+
+    /** <p>Codepage for UTF-16 big-endian</p> */
+    public static final int CP_UTF16_BE = 1201;
+
+    /** <p>Codepage for Windows 1250</p> */
+    public static final int CP_WINDOWS_1250 = 1250;
+
+    /** <p>Codepage for Windows 1251</p> */
+    public static final int CP_WINDOWS_1251 = 1251;
+
+    /** <p>Codepage for Windows 1252</p> */
+    public static final int CP_WINDOWS_1252 = 1252;
+
+    /** <p>Codepage for Windows 1253</p> */
+    public static final int CP_WINDOWS_1253 = 1253;
+
+    /** <p>Codepage for Windows 1254</p> */
+    public static final int CP_WINDOWS_1254 = 1254;
+
+    /** <p>Codepage for Windows 1255</p> */
+    public static final int CP_WINDOWS_1255 = 1255;
+
+    /** <p>Codepage for Windows 1256</p> */
+    public static final int CP_WINDOWS_1256 = 1256;
+
+    /** <p>Codepage for Windows 1257</p> */
+    public static final int CP_WINDOWS_1257 = 1257;
+
+    /** <p>Codepage for Windows 1258</p> */
+    public static final int CP_WINDOWS_1258 = 1258;
+
+    /** <p>Codepage for Johab</p> */
+    public static final int CP_JOHAB = 1361;
+
+    /** <p>Codepage for Macintosh Roman (Java: MacRoman)</p> */
+    public static final int CP_MAC_ROMAN = 10000;
+
+    /** <p>Codepage for Macintosh Japan (Java: unknown - use SJIS, cp942 or
+     * cp943)</p> */
+    public static final int CP_MAC_JAPAN = 10001;
+
+    /** <p>Codepage for Macintosh Chinese Traditional (Java: unknown - use Big5,
+     * MS950, or cp937)</p> */
+    public static final int CP_MAC_CHINESE_TRADITIONAL = 10002;
+
+    /** <p>Codepage for Macintosh Korean (Java: unknown - use EUC_KR or
+     * cp949)</p> */
+    public static final int CP_MAC_KOREAN = 10003;
+
+    /** <p>Codepage for Macintosh Arabic (Java: MacArabic)</p> */
+    public static final int CP_MAC_ARABIC = 10004;
+
+    /** <p>Codepage for Macintosh Hebrew (Java: MacHebrew)</p> */
+    public static final int CP_MAC_HEBREW = 10005;
+
+    /** <p>Codepage for Macintosh Greek (Java: MacGreek)</p> */
+    public static final int CP_MAC_GREEK = 10006;
+
+    /** <p>Codepage for Macintosh Cyrillic (Java: MacCyrillic)</p> */
+    public static final int CP_MAC_CYRILLIC = 10007;
+
+    /** <p>Codepage for Macintosh Chinese Simplified (Java: unknown - use
+     * EUC_CN, ISO2022_CN_GB, MS936 or cp935)</p> */
+    public static final int CP_MAC_CHINESE_SIMPLE = 10008;
+
+    /** <p>Codepage for Macintosh Romanian (Java: MacRomania)</p> */
+    public static final int CP_MAC_ROMANIA = 10010;
+
+    /** <p>Codepage for Macintosh Ukrainian (Java: MacUkraine)</p> */
+    public static final int CP_MAC_UKRAINE = 10017;
+
+    /** <p>Codepage for Macintosh Thai (Java: MacThai)</p> */
+    public static final int CP_MAC_THAI = 10021;
+
+    /** <p>Codepage for Macintosh Central Europe (Latin-2)
+     * (Java: MacCentralEurope)</p> */
+    public static final int CP_MAC_CENTRAL_EUROPE = 10029;
+
+    /** <p>Codepage for Macintosh Iceland (Java: MacIceland)</p> */
+    public static final int CP_MAC_ICELAND = 10079;
+
+    /** <p>Codepage for Macintosh Turkish (Java: MacTurkish)</p> */
+    public static final int CP_MAC_TURKISH = 10081;
+
+    /** <p>Codepage for Macintosh Croatian (Java: MacCroatian)</p> */
+    public static final int CP_MAC_CROATIAN = 10082;
+
+    /** <p>Codepage for US-ASCII</p> */
+    public static final int CP_US_ACSII = 20127;
+
+    /** <p>Codepage for KOI8-R</p> */
+    public static final int CP_KOI8_R = 20866;
+
+    /** <p>Codepage for ISO-8859-1</p> */
+    public static final int CP_ISO_8859_1 = 28591;
+
+    /** <p>Codepage for ISO-8859-2</p> */
+    public static final int CP_ISO_8859_2 = 28592;
+
+    /** <p>Codepage for ISO-8859-3</p> */
+    public static final int CP_ISO_8859_3 = 28593;
+
+    /** <p>Codepage for ISO-8859-4</p> */
+    public static final int CP_ISO_8859_4 = 28594;
+
+    /** <p>Codepage for ISO-8859-5</p> */
+    public static final int CP_ISO_8859_5 = 28595;
+
+    /** <p>Codepage for ISO-8859-6</p> */
+    public static final int CP_ISO_8859_6 = 28596;
+
+    /** <p>Codepage for ISO-8859-7</p> */
+    public static final int CP_ISO_8859_7 = 28597;
+
+    /** <p>Codepage for ISO-8859-8</p> */
+    public static final int CP_ISO_8859_8 = 28598;
+
+    /** <p>Codepage for ISO-8859-9</p> */
+    public static final int CP_ISO_8859_9 = 28599;
+
+    /** <p>Codepage for ISO-2022-JP</p> */
+    public static final int CP_ISO_2022_JP1 = 50220;
+
+    /** <p>Another codepage for ISO-2022-JP</p> */
+    public static final int CP_ISO_2022_JP2 = 50221;
+
+    /** <p>Yet another codepage for ISO-2022-JP</p> */
+    public static final int CP_ISO_2022_JP3 = 50222;
+
+    /** <p>Codepage for ISO-2022-KR</p> */
+    public static final int CP_ISO_2022_KR = 50225;
+
+    /** <p>Codepage for EUC-JP</p> */
+    public static final int CP_EUC_JP = 51932;
+
+    /** <p>Codepage for EUC-KR</p> */
+    public static final int CP_EUC_KR = 51949;
+
+    /** <p>Codepage for GB2312</p> */
+    public static final int CP_GB2312 = 52936;
+
+    /** <p>Codepage for GB18030</p> */
+    public static final int CP_GB18030 = 54936;
+
+    /** <p>Another codepage for US-ASCII</p> */
+    public static final int CP_US_ASCII2 = 65000;
+
+    /** <p>Codepage for UTF-8</p> */
+    public static final int CP_UTF8 = 65001;
+
+    /** <p>Codepage for Unicode</p> */
+    public static final int CP_UNICODE = CP_UTF16;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/DocumentSummaryInformation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/DocumentSummaryInformation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/DocumentSummaryInformation.java	(revision 28000)
@@ -0,0 +1,64 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import org.apache.poi.hpsf.wellknown.PropertyIDMap;
+
+/**
+ * <p>Convenience class representing a DocumentSummary Information stream in a
+ * Microsoft Office document.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ * @author Drew Varner (Drew.Varner closeTo sc.edu)
+ * @author robert_flaherty@hyperion.com
+ * @see SummaryInformation
+ */
+public class DocumentSummaryInformation extends SpecialPropertySet
+{
+
+    /**
+     * <p>The document name a document summary information stream
+     * usually has in a POIFS filesystem.</p>
+     */
+    public static final String DEFAULT_STREAM_NAME =
+        "\005DocumentSummaryInformation";
+
+    public PropertyIDMap getPropertySetIDMap() {
+    	return PropertyIDMap.getDocumentSummaryInformationProperties();
+    }
+
+
+    /**
+     * <p>Creates a {@link DocumentSummaryInformation} from a given
+     * {@link PropertySet}.</p>
+     *
+     * @param ps A property set which should be created from a
+     * document summary information stream.
+     * @throws UnexpectedPropertySetTypeException if <var>ps</var>
+     * does not contain a document summary information stream.
+     */
+    public DocumentSummaryInformation(final PropertySet ps)
+        throws UnexpectedPropertySetTypeException
+    {
+        super(ps);
+        if (!isDocumentSummaryInformation())
+            throw new UnexpectedPropertySetTypeException
+                ("Not a " + getClass().getName());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/HPSFException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/HPSFException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/HPSFException.java	(revision 28000)
@@ -0,0 +1,50 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+/**
+ * <p>This exception is the superclass of all other checked exceptions thrown
+ * in this package. It supports a nested "reason" throwable, i.e. an exception
+ * that caused this one to be thrown.</p>
+ * 
+ * @author Rainer Klute <a
+ *         href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+@SuppressWarnings("serial")
+public class HPSFException extends Exception
+{
+    /**
+     * <p>Creates an {@link HPSFException}.</p>
+     */
+    public HPSFException()
+    {
+        super();
+    }
+
+
+
+    /**
+     * <p>Creates an {@link HPSFException} with a message string.</p>
+     *
+     * @param msg The message string.
+     */
+    public HPSFException(final String msg)
+    {
+        super(msg);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/HPSFRuntimeException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/HPSFRuntimeException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/HPSFRuntimeException.java	(revision 28000)
@@ -0,0 +1,135 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * <p>This exception is the superclass of all other unchecked
+ * exceptions thrown in this package. It supports a nested "reason"
+ * throwable, i.e. an exception that caused this one to be thrown.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+@SuppressWarnings("serial")
+public class HPSFRuntimeException extends RuntimeException
+{
+
+    /** <p>The underlying reason for this exception - may be
+     * <code>null</code>.</p> */
+    private Throwable reason;
+
+
+
+    /**
+     * <p>Creates a new {@link HPSFRuntimeException}.</p>
+     */
+    public HPSFRuntimeException()
+    {
+        super();
+    }
+
+
+
+    /**
+     * <p>Creates a new {@link HPSFRuntimeException} with a message
+     * string.</p>
+     *
+     * @param msg The message string.
+     */
+    public HPSFRuntimeException(final String msg)
+    {
+        super(msg);
+    }
+
+
+
+    /**
+     * <p>Creates a new {@link HPSFRuntimeException} with a
+     * reason.</p>
+     *
+     * @param reason The reason, i.e. a throwable that indirectly
+     * caused this exception.
+     */
+    public HPSFRuntimeException(final Throwable reason)
+    {
+        super();
+        this.reason = reason;
+    }
+
+
+
+
+
+    /**
+     * <p>Returns the {@link Throwable} that caused this exception to
+     * be thrown or <code>null</code> if there was no such {@link
+     * Throwable}.</p>
+     *
+     * @return The reason
+     */
+    public Throwable getReason()
+    {
+        return reason;
+    }
+
+
+
+    /**
+     * @see Throwable#printStackTrace()
+     */
+    public void printStackTrace()
+    {
+        printStackTrace(System.err);
+    }
+
+
+
+    /**
+     * @see Throwable#printStackTrace(java.io.PrintStream)
+     */
+    public void printStackTrace(final PrintStream p)
+    {
+        final Throwable reason = getReason();
+        super.printStackTrace(p);
+        if (reason != null)
+        {
+            p.println("Caused by:");
+            reason.printStackTrace(p);
+        }
+    }
+
+
+
+    /**
+     * @see Throwable#printStackTrace(java.io.PrintWriter)
+     */
+    public void printStackTrace(final PrintWriter p)
+    {
+        final Throwable reason = getReason();
+        super.printStackTrace(p);
+        if (reason != null)
+        {
+            p.println("Caused by:");
+            reason.printStackTrace(p);
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/IllegalPropertySetDataException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/IllegalPropertySetDataException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/IllegalPropertySetDataException.java	(revision 28000)
@@ -0,0 +1,67 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+/**
+ * <p>This exception is thrown when there is an illegal value set in a
+ * {@link PropertySet}. For example, a {@link Variant#VT_BOOL} must
+ * have a value of <code>-1 (true)</code> or <code>0 (false)</code>.
+ * Any other value would trigger this exception. It supports a nested
+ * "reason" throwable, i.e. an exception that caused this one to be
+ * thrown.</p>
+ *
+ * @author Drew Varner(Drew.Varner atDomain sc.edu)
+ */
+@SuppressWarnings("serial")
+public class IllegalPropertySetDataException extends HPSFRuntimeException
+{
+
+    /**
+     * <p>Constructor</p>
+     */
+    public IllegalPropertySetDataException()
+    {
+        super();
+    }
+
+
+
+    /**
+     * <p>Constructor</p>
+     * 
+     * @param msg The exception's message string
+     */
+    public IllegalPropertySetDataException(final String msg)
+    {
+        super(msg);
+    }
+
+
+
+    /**
+     * <p>Constructor</p>
+     * 
+     * @param reason This exception's underlying reason
+     */
+    public IllegalPropertySetDataException(final Throwable reason)
+    {
+        super(reason);
+    }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MarkUnsupportedException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MarkUnsupportedException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MarkUnsupportedException.java	(revision 28000)
@@ -0,0 +1,50 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+/**
+ * <p>This exception is thrown if an {@link java.io.InputStream} does
+ * not support the {@link java.io.InputStream#mark} operation.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+@SuppressWarnings("serial")
+public class MarkUnsupportedException extends HPSFException
+{
+
+    /**
+     * <p>Constructor</p>
+     */
+    public MarkUnsupportedException()
+    {
+        super();
+    }
+
+
+    /**
+     * <p>Constructor</p>
+     *
+     * @param msg The exception's message string
+     */
+    public MarkUnsupportedException(final String msg)
+    {
+        super(msg);
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MissingSectionException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MissingSectionException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MissingSectionException.java	(revision 28000)
@@ -0,0 +1,53 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+/**
+ * <p>This exception is thrown if one of the {@link PropertySet}'s
+ * convenience methods does not find a required {@link Section}.</p>
+ *
+ * <p>The constructors of this class are analogous to those of its
+ * superclass and documented there.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+@SuppressWarnings("serial")
+public class MissingSectionException extends HPSFRuntimeException
+{
+
+    /**
+     * <p>Constructor</p>
+     */
+    public MissingSectionException()
+    {
+        super();
+    }
+
+
+    /**
+     * <p>Constructor</p>
+     * 
+     * @param msg The exception's message string
+     */
+    public MissingSectionException(final String msg)
+    {
+        super(msg);
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MutableProperty.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MutableProperty.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MutableProperty.java	(revision 28000)
@@ -0,0 +1,120 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * <p>Adds writing capability to the {@link Property} class.</p>
+ *
+ * <p>Please be aware that this class' functionality will be merged into the
+ * {@link Property} class at a later time, so the API will change.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+public class MutableProperty extends Property
+{
+
+    /**
+     * <p>Creates an empty property. It must be filled using the set method to
+     * be usable.</p>
+     */
+    public MutableProperty()
+    { }
+
+
+
+    /**
+     * <p>Creates a <code>MutableProperty</code> as a copy of an existing
+     * <code>Property</code>.</p>
+     *
+     * @param p The property to copy.
+     */
+    public MutableProperty(final Property p)
+    {
+        setID(p.getID());
+        setType(p.getType());
+        setValue(p.getValue());
+    }
+
+
+    /**
+     * <p>Sets the property's ID.</p>
+     *
+     * @param id the ID
+     */
+    public void setID(final long id)
+    {
+        this.id = id;
+    }
+
+
+
+    /**
+     * <p>Sets the property's type.</p>
+     *
+     * @param type the property's type
+     */
+    public void setType(final long type)
+    {
+        this.type = type;
+    }
+
+
+
+    /**
+     * <p>Sets the property's value.</p>
+     *
+     * @param value the property's value
+     */
+    public void setValue(final Object value)
+    {
+        this.value = value;
+    }
+
+
+
+    /**
+     * <p>Writes the property to an output stream.</p>
+     *
+     * @param out The output stream to write to.
+     * @param codepage The codepage to use for writing non-wide strings
+     * @return the number of bytes written to the stream
+     *
+     * @exception IOException if an I/O error occurs
+     * @exception WritingNotSupportedException if a variant type is to be
+     * written that is not yet supported
+     */
+    public int write(final OutputStream out, final int codepage)
+        throws IOException, WritingNotSupportedException
+    {
+        int length = 0;
+        long variantType = getType();
+
+        /* Ensure that wide strings are written if the codepage is Unicode. */
+        if (codepage == Constants.CP_UNICODE && variantType == Variant.VT_LPSTR)
+            variantType = Variant.VT_LPWSTR;
+
+        length += TypeWriter.writeUIntToStream(out, variantType);
+        length += VariantSupport.write(out, variantType, getValue(), codepage);
+        return length;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MutablePropertySet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MutablePropertySet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MutablePropertySet.java	(revision 28000)
@@ -0,0 +1,303 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+import org.apache.poi.poifs.filesystem.DirectoryEntry;
+import org.apache.poi.poifs.filesystem.Entry;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianConsts;
+
+/**
+ * <p>Adds writing support to the {@link PropertySet} class.</p>
+ *
+ * <p>Please be aware that this class' functionality will be merged into the
+ * {@link PropertySet} class at a later time, so the API will change.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+public class MutablePropertySet extends PropertySet
+{
+
+    /**
+     * <p>Constructs a <code>MutablePropertySet</code> instance. Its
+     * primary task is to initialize the immutable field with their proper
+     * values. It also sets fields that might change to reasonable defaults.</p>
+     */
+    public MutablePropertySet()
+    {
+        /* Initialize the "byteOrder" field. */
+        byteOrder = LittleEndian.getUShort(BYTE_ORDER_ASSERTION);
+
+        /* Initialize the "format" field. */
+        format = LittleEndian.getUShort(FORMAT_ASSERTION);
+
+        /* Initialize "osVersion" field as if the property has been created on
+         * a Win32 platform, whether this is the case or not. */
+        osVersion = (OS_WIN32 << 16) | 0x0A04;
+
+        /* Initailize the "classID" field. */
+        classID = new ClassID();
+
+        /* Initialize the sections. Since property set must have at least
+         * one section it is added right here. */
+        sections = new LinkedList<Section>();
+        sections.add(new MutableSection());
+    }
+
+
+
+    /**
+     * <p>Constructs a <code>MutablePropertySet</code> by doing a deep copy of
+     * an existing <code>PropertySet</code>. All nested elements, i.e.
+     * <code>Section</code>s and <code>Property</code> instances, will be their
+     * mutable counterparts in the new <code>MutablePropertySet</code>.</p>
+     *
+     * @param ps The property set to copy
+     */
+    public MutablePropertySet(final PropertySet ps)
+    {
+        byteOrder = ps.getByteOrder();
+        format = ps.getFormat();
+        osVersion = ps.getOSVersion();
+        setClassID(ps.getClassID());
+        clearSections();
+        if (sections == null)
+            sections = new LinkedList<Section>();
+        for (final Iterator<Section> i = ps.getSections().iterator(); i.hasNext();)
+        {
+            addSection(new MutableSection(i.next()));
+        }
+    }
+
+
+
+    /**
+     * <p>The length of the property set stream header.</p>
+     */
+    private final int OFFSET_HEADER =
+        BYTE_ORDER_ASSERTION.length + /* Byte order    */
+        FORMAT_ASSERTION.length +     /* Format        */
+        LittleEndianConsts.INT_SIZE + /* OS version    */
+        ClassID.LENGTH +              /* Class ID      */
+        LittleEndianConsts.INT_SIZE;  /* Section count */
+
+
+
+    /**
+     * <p>Sets the "byteOrder" property.</p>
+     *
+     * @param byteOrder the byteOrder value to set
+     */
+    public void setByteOrder(final int byteOrder)
+    {
+        this.byteOrder = byteOrder;
+    }
+
+
+
+    /**
+     * <p>Sets the "format" property.</p>
+     *
+     * @param format the format value to set
+     */
+    public void setFormat(final int format)
+    {
+        this.format = format;
+    }
+
+
+
+    /**
+     * <p>Sets the "osVersion" property.</p>
+     *
+     * @param osVersion the osVersion value to set
+     */
+    public void setOSVersion(final int osVersion)
+    {
+        this.osVersion = osVersion;
+    }
+
+
+
+    /**
+     * <p>Sets the property set stream's low-level "class ID"
+     * field.</p>
+     *
+     * @param classID The property set stream's low-level "class ID" field.
+     *
+     * @see PropertySet#getClassID()
+     */
+    public void setClassID(final ClassID classID)
+    {
+        this.classID = classID;
+    }
+
+
+
+    /**
+     * <p>Removes all sections from this property set.</p>
+     */
+    public void clearSections()
+    {
+        sections = null;
+    }
+
+
+
+    /**
+     * <p>Adds a section to this property set.</p>
+     *
+     * @param section The {@link Section} to add. It will be appended
+     * after any sections that are already present in the property set
+     * and thus become the last section.
+     */
+    public void addSection(final Section section)
+    {
+        if (sections == null)
+            sections = new LinkedList<Section>();
+        sections.add(section);
+    }
+
+
+
+    /**
+     * <p>Writes the property set to an output stream.</p>
+     *
+     * @param out the output stream to write the section to
+     * @exception IOException if an error when writing to the output stream
+     * occurs
+     * @exception WritingNotSupportedException if HPSF does not yet support
+     * writing a property's variant type.
+     */
+    public void write(final OutputStream out)
+        throws WritingNotSupportedException, IOException
+    {
+        /* Write the number of sections in this property set stream. */
+        final int nrSections = sections.size();
+        //int length = 0;
+
+        /* Write the property set's header. */
+        /*length +=*/ TypeWriter.writeToStream(out, (short) getByteOrder());
+        /*length +=*/ TypeWriter.writeToStream(out, (short) getFormat());
+        /*length +=*/ TypeWriter.writeToStream(out, getOSVersion());
+        /*length +=*/ TypeWriter.writeToStream(out, getClassID());
+        /*length +=*/ TypeWriter.writeToStream(out, nrSections);
+        int offset = OFFSET_HEADER;
+
+        /* Write the section list, i.e. the references to the sections. Each
+         * entry in the section list consist of the section's class ID and the
+         * section's offset relative to the beginning of the stream. */
+        offset += nrSections * (ClassID.LENGTH + LittleEndian.INT_SIZE);
+        final int sectionsBegin = offset;
+        for (final ListIterator<Section> i = sections.listIterator(); i.hasNext();)
+        {
+            final MutableSection s = (MutableSection) i.next();
+            final ClassID formatID = s.getFormatID();
+            if (formatID == null)
+                throw new NoFormatIDException();
+            /*length +=*/ TypeWriter.writeToStream(out, s.getFormatID());
+            /*length +=*/ TypeWriter.writeUIntToStream(out, offset);
+            try
+            {
+                offset += s.getSize();
+            }
+            catch (HPSFRuntimeException ex)
+            {
+                final Throwable cause = ex.getReason();
+                if (cause instanceof UnsupportedEncodingException) {
+                    throw new IllegalPropertySetDataException(cause);
+                }
+                throw ex;
+            }
+        }
+
+        /* Write the sections themselves. */
+        offset = sectionsBegin;
+        for (final ListIterator<Section> i = sections.listIterator(); i.hasNext();)
+        {
+            final MutableSection s = (MutableSection) i.next();
+            offset += s.write(out);
+        }
+    }
+
+
+
+    /**
+     * <p>Returns the contents of this property set stream as an input stream.
+     * The latter can be used for example to write the property set into a POIFS
+     * document. The input stream represents a snapshot of the property set.
+     * If the latter is modified while the input stream is still being
+     * read, the modifications will not be reflected in the input stream but in
+     * the {@link MutablePropertySet} only.</p>
+     *
+     * @return the contents of this property set stream
+     *
+     * @throws WritingNotSupportedException if HPSF does not yet support writing
+     * of a property's variant type.
+     * @throws IOException if an I/O exception occurs.
+     */
+    public InputStream toInputStream()
+        throws IOException, WritingNotSupportedException
+    {
+        final ByteArrayOutputStream psStream = new ByteArrayOutputStream();
+        write(psStream);
+        psStream.close();
+        final byte[] streamData = psStream.toByteArray();
+        return new ByteArrayInputStream(streamData);
+    }
+
+    /**
+     * <p>Writes a property set to a document in a POI filesystem directory.</p>
+     *
+     * @param dir The directory in the POI filesystem to write the document to.
+     * @param name The document's name. If there is already a document with the
+     * same name in the directory the latter will be overwritten.
+     *
+     * @throws WritingNotSupportedException
+     * @throws IOException
+     */
+    public void write(final DirectoryEntry dir, final String name)
+    throws WritingNotSupportedException, IOException
+    {
+        /* If there is already an entry with the same name, remove it. */
+        try
+        {
+            final Entry e = dir.getEntry(name);
+            e.delete();
+        }
+        catch (FileNotFoundException ex)
+        {
+            /* Entry not found, no need to remove it. */
+        }
+        /* Create the new entry. */
+        dir.createDocument(name, toInputStream());
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MutableSection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MutableSection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/MutableSection.java	(revision 28000)
@@ -0,0 +1,533 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.apache.poi.hpsf.wellknown.PropertyIDMap;
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * <p>Adds writing capability to the {@link Section} class.</p>
+ *
+ * <p>Please be aware that this class' functionality will be merged into the
+ * {@link Section} class at a later time, so the API will change.</p>
+ */
+public class MutableSection extends Section
+{
+    /**
+     * <p>If the "dirty" flag is true, the section's size must be
+     * (re-)calculated before the section is written.</p>
+     */
+    private boolean dirty = true;
+
+
+
+    /**
+     * <p>List to assemble the properties. Unfortunately a wrong
+     * decision has been taken when specifying the "properties" field
+     * as an Property[]. It should have been a {@link java.util.List}.</p>
+     */
+    private List<Property> preprops;
+
+
+
+    /**
+     * <p>Contains the bytes making out the section. This byte array is
+     * established when the section's size is calculated and can be reused
+     * later. It is valid only if the "dirty" flag is false.</p>
+     */
+    private byte[] sectionBytes;
+
+
+
+    /**
+     * <p>Creates an empty mutable section.</p>
+     */
+    public MutableSection()
+    {
+        dirty = true;
+        formatID = null;
+        offset = -1;
+        preprops = new LinkedList<Property>();
+    }
+
+
+
+    /**
+     * <p>Constructs a <code>MutableSection</code> by doing a deep copy of an
+     * existing <code>Section</code>. All nested <code>Property</code>
+     * instances, will be their mutable counterparts in the new
+     * <code>MutableSection</code>.</p>
+     *
+     * @param s The section set to copy
+     */
+    public MutableSection(final Section s)
+    {
+        setFormatID(s.getFormatID());
+        final Property[] pa = s.getProperties();
+        final MutableProperty[] mpa = new MutableProperty[pa.length];
+        for (int i = 0; i < pa.length; i++)
+            mpa[i] = new MutableProperty(pa[i]);
+        setProperties(mpa);
+        setDictionary(s.getDictionary());
+    }
+
+
+
+    /**
+     * <p>Sets the section's format ID.</p>
+     *
+     * @param formatID The section's format ID
+     *
+     * @see #setFormatID(byte[])
+     * @see Section#getFormatID
+     */
+    public void setFormatID(final ClassID formatID)
+    {
+        this.formatID = formatID;
+    }
+
+
+
+
+    /**
+     * <p>Sets this section's properties. Any former values are overwritten.</p>
+     *
+     * @param properties This section's new properties.
+     */
+    public void setProperties(final Property[] properties)
+    {
+        this.properties = properties;
+        preprops = new LinkedList<Property>();
+        for (int i = 0; i < properties.length; i++)
+            preprops.add(properties[i]);
+        dirty = true;
+    }
+
+
+    /**
+     * <p>Sets the value and the variant type of the property with the
+     * specified ID. If a property with this ID is not yet present in
+     * the section, it will be added. An already present property with
+     * the specified ID will be overwritten. A default mapping will be
+     * used to choose the property's type.</p>
+     *
+     * @param id The property's ID.
+     * @param variantType The property's variant type.
+     * @param value The property's value.
+     *
+     * @see #setProperty(int, String)
+     * @see #getProperty
+     * @see Variant
+     */
+    public void setProperty(final int id, final long variantType,
+                            final Object value)
+    {
+        final MutableProperty p = new MutableProperty();
+        p.setID(id);
+        p.setType(variantType);
+        p.setValue(value);
+        setProperty(p);
+        dirty = true;
+    }
+
+
+
+    /**
+     * <p>Sets a property.</p>
+     *
+     * @param p The property to be set.
+     *
+     * @see #setProperty(int, long, Object)
+     * @see #getProperty
+     * @see Variant
+     */
+    public void setProperty(final Property p)
+    {
+        final long id = p.getID();
+        removeProperty(id);
+        preprops.add(p);
+        dirty = true;
+    }
+
+
+
+    /**
+     * <p>Removes a property.</p>
+     *
+     * @param id The ID of the property to be removed
+     */
+    public void removeProperty(final long id)
+    {
+        for (final Iterator<Property> i = preprops.iterator(); i.hasNext();)
+            if (i.next().getID() == id)
+            {
+                i.remove();
+                break;
+            }
+        dirty = true;
+    }
+
+
+    /**
+     * <p>Returns the section's size.</p>
+     *
+     * @return the section's size.
+     */
+    public int getSize()
+    {
+        if (dirty)
+        {
+            try
+            {
+                size = calcSize();
+                dirty = false;
+            }
+            catch (HPSFRuntimeException ex)
+            {
+                throw ex;
+            }
+            catch (Exception ex)
+            {
+                throw new HPSFRuntimeException(ex);
+            }
+        }
+        return size;
+    }
+
+
+
+    /**
+     * <p>Calculates the section's size. It is the sum of the lengths of the
+     * section's header (8), the properties list (16 times the number of
+     * properties) and the properties themselves.</p>
+     *
+     * @return the section's length in bytes.
+     * @throws WritingNotSupportedException
+     * @throws IOException
+     */
+    private int calcSize() throws WritingNotSupportedException, IOException
+    {
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+        write(out);
+        out.close();
+        /* Pad to multiple of 4 bytes so that even the Windows shell (explorer)
+         * shows custom properties. */
+        sectionBytes = Util.pad4(out.toByteArray());
+        return sectionBytes.length;
+    }
+
+
+
+    /**
+     * <p>Writes this section into an output stream.</p>
+     *
+     * <p>Internally this is done by writing into three byte array output
+     * streams: one for the properties, one for the property list and one for
+     * the section as such. The two former are appended to the latter when they
+     * have received all their data.</p>
+     *
+     * @param out The stream to write into.
+     *
+     * @return The number of bytes written, i.e. the section's size.
+     * @exception IOException if an I/O error occurs
+     * @exception WritingNotSupportedException if HPSF does not yet support
+     * writing a property's variant type.
+     */
+    public int write(final OutputStream out)
+        throws WritingNotSupportedException, IOException
+    {
+        /* Check whether we have already generated the bytes making out the
+         * section. */
+        if (!dirty && sectionBytes != null)
+        {
+            out.write(sectionBytes);
+            return sectionBytes.length;
+        }
+
+        /* The properties are written to this stream. */
+        final ByteArrayOutputStream propertyStream =
+            new ByteArrayOutputStream();
+
+        /* The property list is established here. After each property that has
+         * been written to "propertyStream", a property list entry is written to
+         * "propertyListStream". */
+        final ByteArrayOutputStream propertyListStream =
+            new ByteArrayOutputStream();
+
+        /* Maintain the current position in the list. */
+        int position = 0;
+
+        /* Increase the position variable by the size of the property list so
+         * that it points behind the property list and to the beginning of the
+         * properties themselves. */
+        position += 2 * LittleEndian.INT_SIZE +
+                    getPropertyCount() * 2 * LittleEndian.INT_SIZE;
+
+        /* Writing the section's dictionary it tricky. If there is a dictionary
+         * (property 0) the codepage property (property 1) must be set, too. */
+        int codepage = -1;
+        if (getProperty(PropertyIDMap.PID_DICTIONARY) != null)
+        {
+            final Object p1 = getProperty(PropertyIDMap.PID_CODEPAGE);
+            if (p1 != null)
+            {
+                if (!(p1 instanceof Integer))
+                    throw new IllegalPropertySetDataException
+                        ("The codepage property (ID = 1) must be an " +
+                         "Integer object.");
+            }
+            else
+                /* Warning: The codepage property is not set although a
+                 * dictionary is present. In order to cope with this problem we
+                 * add the codepage property and set it to Unicode. */
+                setProperty(PropertyIDMap.PID_CODEPAGE, Variant.VT_I2,
+                            Integer.valueOf(Constants.CP_UNICODE));
+            codepage = getCodepage();
+        }
+
+        /* Sort the property list by their property IDs: */
+        Collections.sort(preprops, new Comparator<Property>()
+            {
+                public int compare(final Property p1, final Property p2)
+                {
+                    if (p1.getID() < p2.getID())
+                        return -1;
+                    else if (p1.getID() == p2.getID())
+                        return 0;
+                    else
+                        return 1;
+                }
+            });
+
+        /* Write the properties and the property list into their respective
+         * streams: */
+        for (final ListIterator<Property> i = preprops.listIterator(); i.hasNext();)
+        {
+            final MutableProperty p = (MutableProperty) i.next();
+            final long id = p.getID();
+
+            /* Write the property list entry. */
+            TypeWriter.writeUIntToStream(propertyListStream, p.getID());
+            TypeWriter.writeUIntToStream(propertyListStream, position);
+
+            /* If the property ID is not equal 0 we write the property and all
+             * is fine. However, if it equals 0 we have to write the section's
+             * dictionary which has an implicit type only and an explicit
+             * value. */
+            if (id != 0)
+                /* Write the property and update the position to the next
+                 * property. */
+                position += p.write(propertyStream, getCodepage());
+            else
+            {
+                if (codepage == -1)
+                    throw new IllegalPropertySetDataException
+                        ("Codepage (property 1) is undefined.");
+                position += writeDictionary(propertyStream, dictionary,
+                                            codepage);
+            }
+        }
+        propertyStream.close();
+        propertyListStream.close();
+
+        /* Write the section: */
+        byte[] pb1 = propertyListStream.toByteArray();
+        byte[] pb2 = propertyStream.toByteArray();
+
+        /* Write the section's length: */
+        TypeWriter.writeToStream(out, LittleEndian.INT_SIZE * 2 +
+                                      pb1.length + pb2.length);
+
+        /* Write the section's number of properties: */
+        TypeWriter.writeToStream(out, getPropertyCount());
+
+        /* Write the property list: */
+        out.write(pb1);
+
+        /* Write the properties: */
+        out.write(pb2);
+
+        int streamLength = LittleEndian.INT_SIZE * 2 + pb1.length + pb2.length;
+        return streamLength;
+    }
+
+
+
+    /**
+     * <p>Writes the section's dictionary.</p>
+     *
+     * @param out The output stream to write to.
+     * @param dictionary The dictionary.
+     * @param codepage The codepage to be used to write the dictionary items.
+     * @return The number of bytes written
+     * @exception IOException if an I/O exception occurs.
+     */
+    private static int writeDictionary(final OutputStream out,
+                                       final Map<Long,String> dictionary, final int codepage)
+        throws IOException
+    {
+        int length = TypeWriter.writeUIntToStream(out, dictionary.size());
+        for (final Iterator<Long> i = dictionary.keySet().iterator(); i.hasNext();)
+        {
+            final Long key = i.next();
+            final String value = dictionary.get(key);
+
+            if (codepage == Constants.CP_UNICODE)
+            {
+                /* Write the dictionary item in Unicode. */
+                int sLength = value.length() + 1;
+                if (sLength % 2 == 1)
+                    sLength++;
+                length += TypeWriter.writeUIntToStream(out, key.longValue());
+                length += TypeWriter.writeUIntToStream(out, sLength);
+                final byte[] ca =
+                    value.getBytes(VariantSupport.codepageToEncoding(codepage));
+                for (int j = 2; j < ca.length; j += 2)
+                {
+                    out.write(ca[j+1]);
+                    out.write(ca[j]);
+                    length += 2;
+                }
+                sLength -= value.length();
+                while (sLength > 0)
+                {
+                    out.write(0x00);
+                    out.write(0x00);
+                    length += 2;
+                    sLength--;
+                }
+            }
+            else
+            {
+                /* Write the dictionary item in another codepage than
+                 * Unicode. */
+                length += TypeWriter.writeUIntToStream(out, key.longValue());
+                length += TypeWriter.writeUIntToStream(out, value.length() + 1);
+                final byte[] ba =
+                    value.getBytes(VariantSupport.codepageToEncoding(codepage));
+                for (int j = 0; j < ba.length; j++)
+                {
+                    out.write(ba[j]);
+                    length++;
+                }
+                out.write(0x00);
+                length++;
+            }
+        }
+        return length;
+    }
+
+
+
+    /**
+     * <p>Overwrites the super class' method to cope with a redundancy:
+     * the property count is maintained in a separate member variable, but
+     * shouldn't.</p>
+     *
+     * @return The number of properties in this section
+     */
+    public int getPropertyCount()
+    {
+        return preprops.size();
+    }
+
+
+
+    /**
+     * <p>Gets this section's properties.</p>
+     *
+     * @return this section's properties.
+     */
+    public Property[] getProperties()
+    {
+        properties = preprops.toArray(new Property[0]);
+        return properties;
+    }
+
+
+
+    /**
+     * <p>Gets a property.</p>
+     *
+     * @param id The ID of the property to get
+     * @return The property or <code>null</code> if there is no such property
+     */
+    public Object getProperty(final long id)
+    {
+        /* Calling getProperties() ensures that properties and preprops are in
+         * sync.</p> */
+        getProperties();
+        return super.getProperty(id);
+    }
+
+
+
+    /**
+     * <p>Sets the section's dictionary. All keys in the dictionary must be
+     * {@link java.lang.Long} instances, all values must be
+     * {@link java.lang.String}s. This method overwrites the properties with IDs
+     * 0 and 1 since they are reserved for the dictionary and the dictionary's
+     * codepage. Setting these properties explicitly might have surprising
+     * effects. An application should never do this but always use this
+     * method.</p>
+     *
+     * @param dictionary The dictionary
+     *
+     * @exception IllegalPropertySetDataException if the dictionary's key and
+     * value types are not correct.
+     *
+     * @see Section#getDictionary()
+     */
+    public void setDictionary(final Map<Long,String> dictionary)
+        throws IllegalPropertySetDataException
+    {
+        if (dictionary != null)
+        {
+            this.dictionary = dictionary;
+
+            /* Set the dictionary property (ID 0). Please note that the second
+             * parameter in the method call below is unused because dictionaries
+             * don't have a type. */
+            setProperty(PropertyIDMap.PID_DICTIONARY, -1, dictionary);
+
+            /* If the codepage property (ID 1) for the strings (keys and
+             * values) used in the dictionary is not yet defined, set it to
+             * Unicode. */
+            final Integer codepage =
+                (Integer) getProperty(PropertyIDMap.PID_CODEPAGE);
+            if (codepage == null)
+                setProperty(PropertyIDMap.PID_CODEPAGE, Variant.VT_I2,
+                            Integer.valueOf(Constants.CP_UNICODE));
+        }
+        else
+            /* Setting the dictionary to null means to remove property 0.
+             * However, it does not mean to remove property 1 (codepage). */
+            removeProperty(PropertyIDMap.PID_DICTIONARY);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/NoFormatIDException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/NoFormatIDException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/NoFormatIDException.java	(revision 28000)
@@ -0,0 +1,41 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+/**
+ * <p>This exception is thrown if a {@link MutablePropertySet} is to be written
+ * but does not have a formatID set (see {@link
+ * MutableSection#setFormatID(ClassID)} or
+ * {@link org.apache.poi.hpsf.MutableSection#setFormatID(byte[])}. 
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+@SuppressWarnings("serial")
+public class NoFormatIDException extends HPSFRuntimeException
+{
+
+    /**
+     * <p>Constructor</p>
+     */
+    public NoFormatIDException()
+    {
+        super();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/NoPropertySetStreamException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/NoPropertySetStreamException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/NoPropertySetStreamException.java	(revision 28000)
@@ -0,0 +1,41 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+/**
+ * <p>This exception is thrown if a format error in a property set stream is
+ * detected or when the input data do not constitute a property set stream.</p>
+ * 
+ * <p>The constructors of this class are analogous to those of its superclass
+ * and are documented there.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+@SuppressWarnings("serial")
+public class NoPropertySetStreamException extends HPSFException
+{
+
+    /**
+     * <p>Constructor</p>
+     */
+    public NoPropertySetStreamException()
+    {
+        super();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/NoSingleSectionException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/NoSingleSectionException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/NoSingleSectionException.java	(revision 28000)
@@ -0,0 +1,44 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+/**
+ * <p>This exception is thrown if one of the {@link PropertySet}'s
+ * convenience methods that require a single {@link Section} is called
+ * and the {@link PropertySet} does not contain exactly one {@link
+ * Section}.</p>
+ *
+ * <p>The constructors of this class are analogous to those of its
+ * superclass and documented there.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+@SuppressWarnings("serial")
+public class NoSingleSectionException extends HPSFRuntimeException
+{
+
+    /**
+     * <p>Constructor</p>
+     */
+    public NoSingleSectionException()
+    {
+        super();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Property.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Property.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Property.java	(revision 28000)
@@ -0,0 +1,396 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * <p>A property in a {@link Section} of a {@link PropertySet}.</p>
+ *
+ * <p>The property's <strong>ID</strong> gives the property a meaning
+ * in the context of its {@link Section}. Each {@link Section} spans
+ * its own name space of property IDs.</p>
+ *
+ * <p>The property's <strong>type</strong> determines how its
+ * <strong>value </strong> is interpreted. For example, if the type is
+ * {@link Variant#VT_LPSTR} (byte string), the value consists of a
+ * DWord telling how many bytes the string contains. The bytes follow
+ * immediately, including any null bytes that terminate the
+ * string. The type {@link Variant#VT_I4} denotes a four-byte integer
+ * value, {@link Variant#VT_FILETIME} some date and time (of a
+ * file).</p>
+ *
+ * <p>Please note that not all {@link Variant} types yet. This might change
+ * over time but largely depends on your feedback so that the POI team knows
+ * which variant types are really needed. So please feel free to submit error
+ * reports or patches for the types you need.</p>
+ *
+ * <p>Microsoft documentation: <a
+ * href="http://msdn.microsoft.com/library/en-us/stg/stg/property_set_display_name_dictionary.asp?frame=true">
+ * Property Set Display Name Dictionary</a>.
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ * @author Drew Varner (Drew.Varner InAndAround sc.edu)
+ * @see Section
+ * @see Variant
+ */
+public class Property
+{
+
+    /** <p>The property's ID.</p> */
+    protected long id;
+
+
+    /**
+     * <p>Returns the property's ID.</p>
+     *
+     * @return The ID value
+     */
+    public long getID()
+    {
+        return id;
+    }
+
+
+
+    /** <p>The property's type.</p> */
+    protected long type;
+
+
+    /**
+     * <p>Returns the property's type.</p>
+     *
+     * @return The type value
+     */
+    public long getType()
+    {
+        return type;
+    }
+
+
+
+    /** <p>The property's value.</p> */
+    protected Object value;
+
+
+    /**
+     * <p>Returns the property's value.</p>
+     *
+     * @return The property's value
+     */
+    public Object getValue()
+    {
+        return value;
+    }
+
+
+
+    /**
+     * <p>Creates a property.</p>
+     *
+     * @param id the property's ID.
+     * @param type the property's type, see {@link Variant}.
+     * @param value the property's value. Only certain types are allowed, see
+     *        {@link Variant}.
+     */
+    public Property(final long id, final long type, final Object value)
+    {
+        this.id = id;
+        this.type = type;
+        this.value = value;
+    }
+
+
+
+    /**
+     * <p>Creates a {@link Property} instance by reading its bytes
+     * from the property set stream.</p>
+     *
+     * @param id The property's ID.
+     * @param src The bytes the property set stream consists of.
+     * @param offset The property's type/value pair's offset in the
+     * section.
+     * @param length The property's type/value pair's length in bytes.
+     * @param codepage The section's and thus the property's
+     * codepage. It is needed only when reading string values.
+     * @exception UnsupportedEncodingException if the specified codepage is not
+     * supported.
+     */
+    public Property(final long id, final byte[] src, final long offset,
+                    final int length, final int codepage)
+    throws UnsupportedEncodingException
+    {
+        this.id = id;
+
+        /*
+         * ID 0 is a special case since it specifies a dictionary of
+         * property IDs and property names.
+         */
+        if (id == 0)
+        {
+            value = readDictionary(src, offset, length, codepage);
+            return;
+        }
+
+        int o = (int) offset;
+        type = LittleEndian.getUInt(src, o);
+        o += LittleEndian.INT_SIZE;
+
+        try
+        {
+            value = VariantSupport.read(src, o, length, (int) type, codepage);
+        }
+        catch (UnsupportedVariantTypeException ex)
+        {
+            VariantSupport.writeUnsupportedTypeMessage(ex);
+            value = ex.getValue();
+        }
+    }
+
+
+
+    /**
+     * <p>Creates an empty property. It must be filled using the set method to
+     * be usable.</p>
+     */
+    protected Property()
+    { }
+
+
+
+    /**
+     * <p>Reads a dictionary.</p>
+     *
+     * @param src The byte array containing the bytes making out the dictionary.
+     * @param offset At this offset within <var>src </var> the dictionary
+     *        starts.
+     * @param length The dictionary contains at most this many bytes.
+     * @param codepage The codepage of the string values.
+     * @return The dictonary
+     * @throws UnsupportedEncodingException if the dictionary's codepage is not
+     *         (yet) supported.
+     */
+    protected Map<Long, String> readDictionary(final byte[] src, final long offset,
+                                 final int length, final int codepage)
+    throws UnsupportedEncodingException
+    {
+        /* Check whether "offset" points into the "src" array". */
+        if (offset < 0 || offset > src.length)
+            throw new HPSFRuntimeException
+                ("Illegal offset " + offset + " while HPSF stream contains " +
+                 length + " bytes.");
+        int o = (int) offset;
+
+        /*
+         * Read the number of dictionary entries.
+         */
+        final long nrEntries = LittleEndian.getUInt(src, o);
+        o += LittleEndian.INT_SIZE;
+
+        final Map<Long, String> m = new HashMap<Long, String>((int) nrEntries, (float) 1.0);
+
+        try
+        {
+            for (int i = 0; i < nrEntries; i++)
+            {
+                /* The key. */
+                final Long id = Long.valueOf(LittleEndian.getUInt(src, o));
+                o += LittleEndian.INT_SIZE;
+
+                /* The value (a string). The length is the either the
+                 * number of (two-byte) characters if the character set is Unicode
+                 * or the number of bytes if the character set is not Unicode.
+                 * The length includes terminating 0x00 bytes which we have to strip
+                 * off to create a Java string. */
+                long sLength = LittleEndian.getUInt(src, o);
+                o += LittleEndian.INT_SIZE;
+
+                /* Read the string. */
+                final StringBuffer b = new StringBuffer();
+                switch (codepage)
+                {
+                    case -1:
+                    {
+                        /* Without a codepage the length is equal to the number of
+                         * bytes. */
+                        b.append(new String(src, o, (int) sLength));
+                        break;
+                    }
+                    case Constants.CP_UNICODE:
+                    {
+                        /* The length is the number of characters, i.e. the number
+                         * of bytes is twice the number of the characters. */
+                        final int nrBytes = (int) (sLength * 2);
+                        final byte[] h = new byte[nrBytes];
+                        for (int i2 = 0; i2 < nrBytes; i2 += 2)
+                        {
+                            h[i2] = src[o + i2 + 1];
+                            h[i2 + 1] = src[o + i2];
+                        }
+                        b.append(new String(h, 0, nrBytes,
+                                VariantSupport.codepageToEncoding(codepage)));
+                        break;
+                    }
+                    default:
+                    {
+                        /* For encodings other than Unicode the length is the number
+                         * of bytes. */
+                        b.append(new String(src, o, (int) sLength,
+                                 VariantSupport.codepageToEncoding(codepage)));
+                        break;
+                    }
+                }
+
+                /* Strip 0x00 characters from the end of the string: */
+                while (b.length() > 0 && b.charAt(b.length() - 1) == 0x00)
+                    b.setLength(b.length() - 1);
+                if (codepage == Constants.CP_UNICODE)
+                {
+                    if (sLength % 2 == 1)
+                        sLength++;
+                    o += (sLength + sLength);
+                }
+                else
+                    o += sLength;
+                m.put(id, b.toString());
+            }
+        }
+        catch (RuntimeException ex)
+        {
+            final POILogger l = POILogFactory.getLogger(getClass());
+            l.log(POILogger.WARN,
+                    "The property set's dictionary contains bogus data. "
+                    + "All dictionary entries starting with the one with ID "
+                    + id + " will be ignored.", ex);
+        }
+        return m;
+    }
+
+    /**
+     * <p>Compares two properties.</p> <p>Please beware that a property with
+     * ID == 0 is a special case: It does not have a type, and its value is the
+     * section's dictionary. Another special case are strings: Two properties
+     * may have the different types Variant.VT_LPSTR and Variant.VT_LPWSTR;</p>
+     *
+     * @see Object#equals(java.lang.Object)
+     */
+    public boolean equals(final Object o)
+    {
+        if (!(o instanceof Property)) {
+            return false;
+        }
+        final Property p = (Property) o;
+        final Object pValue = p.getValue();
+        final long pId = p.getID();
+        if (id != pId || (id != 0 && !typesAreEqual(type, p.getType())))
+            return false;
+        if (value == null && pValue == null)
+            return true;
+        if (value == null || pValue == null)
+            return false;
+
+        /* It's clear now that both values are non-null. */
+        final Class<?> valueClass = value.getClass();
+        final Class<?> pValueClass = pValue.getClass();
+        if (!(valueClass.isAssignableFrom(pValueClass)) &&
+            !(pValueClass.isAssignableFrom(valueClass)))
+            return false;
+
+        if (value instanceof byte[])
+            return Util.equal((byte[]) value, (byte[]) pValue);
+
+        return value.equals(pValue);
+    }
+
+
+
+    private boolean typesAreEqual(final long t1, final long t2)
+    {
+        if (t1 == t2 ||
+            (t1 == Variant.VT_LPSTR && t2 == Variant.VT_LPWSTR) ||
+            (t2 == Variant.VT_LPSTR && t1 == Variant.VT_LPWSTR)) {
+            return true;
+        }
+        return false;
+    }
+
+
+
+    /**
+     * @see Object#hashCode()
+     */
+    public int hashCode()
+    {
+        long hashCode = 0;
+        hashCode += id;
+        hashCode += type;
+        if (value != null)
+            hashCode += value.hashCode();
+        final int returnHashCode = (int) (hashCode & 0x0ffffffffL );
+        return returnHashCode;
+
+    }
+
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        final StringBuffer b = new StringBuffer();
+        b.append(getClass().getName());
+        b.append('[');
+        b.append("id: ");
+        b.append(getID());
+        b.append(", type: ");
+        b.append(getType());
+        final Object value = getValue();
+        b.append(", value: ");
+        b.append(value.toString());
+        if (value instanceof String)
+        {
+            final String s = (String) value;
+            final int l = s.length();
+            final byte[] bytes = new byte[l * 2];
+            for (int i = 0; i < l; i++)
+            {
+                final char c = s.charAt(i);
+                final byte high = (byte) ((c & 0x00ff00) >> 8);
+                final byte low  = (byte) ((c & 0x0000ff) >> 0);
+                bytes[i * 2]     = high;
+                bytes[i * 2 + 1] = low;
+            }
+            final String hex = HexDump.dump(bytes, 0L, 0);
+            b.append(" [");
+            b.append(hex);
+            b.append("]");
+        }
+        b.append(']');
+        return b.toString();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/PropertySet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/PropertySet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/PropertySet.java	(revision 28000)
@@ -0,0 +1,623 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hpsf.wellknown.SectionIDMap;
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * <p>Represents a property set in the Horrible Property Set Format
+ * (HPSF). These are usually metadata of a Microsoft Office
+ * document.</p>
+ *
+ * <p>An application that wants to access these metadata should create
+ * an instance of this class or one of its subclasses by calling the
+ * factory method {@link PropertySetFactory#create} and then retrieve
+ * the information its needs by calling appropriate methods.</p>
+ *
+ * <p>{@link PropertySetFactory#create} does its work by calling one
+ * of the constructors {@link PropertySet#PropertySet(InputStream)} or
+ * {@link PropertySet#PropertySet(byte[])}. If the constructor's
+ * argument is not in the Horrible Property Set Format, i.e. not a
+ * property set stream, or if any other error occurs, an appropriate
+ * exception is thrown.</p>
+ *
+ * <p>A {@link PropertySet} has a list of {@link Section}s, and each
+ * {@link Section} has a {@link Property} array. Use {@link
+ * #getSections} to retrieve the {@link Section}s, then call {@link
+ * Section#getProperties} for each {@link Section} to get hold of the
+ * {@link Property} arrays.</p> Since the vast majority of {@link
+ * PropertySet}s contains only a single {@link Section}, the
+ * convenience method {@link #getProperties} returns the properties of
+ * a {@link PropertySet}'s {@link Section} (throwing a {@link
+ * NoSingleSectionException} if the {@link PropertySet} contains more
+ * (or less) than exactly one {@link Section}).</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ * @author Drew Varner (Drew.Varner hanginIn sc.edu)
+ */
+public class PropertySet
+{
+
+    /**
+     * <p>The "byteOrder" field must equal this value.</p>
+     */
+    static final byte[] BYTE_ORDER_ASSERTION =
+        new byte[] {(byte) 0xFE, (byte) 0xFF};
+
+    /**
+     * <p>Specifies this {@link PropertySet}'s byte order. See the
+     * HPFS documentation for details!</p>
+     */
+    protected int byteOrder;
+
+    /**
+     * <p>Returns the property set stream's low-level "byte order"
+     * field. It is always <tt>0xFFFE</tt> .</p>
+     *
+     * @return The property set stream's low-level "byte order" field.
+     */
+    public int getByteOrder()
+    {
+        return byteOrder;
+    }
+
+
+
+    /**
+     * <p>The "format" field must equal this value.</p>
+     */
+    static final byte[] FORMAT_ASSERTION =
+        new byte[]{(byte) 0x00, (byte) 0x00};
+
+    /**
+     * <p>Specifies this {@link PropertySet}'s format. See the HPFS
+     * documentation for details!</p>
+     */
+    protected int format;
+
+    /**
+     * <p>Returns the property set stream's low-level "format"
+     * field. It is always <tt>0x0000</tt> .</p>
+     *
+     * @return The property set stream's low-level "format" field.
+     */
+    public int getFormat()
+    {
+        return format;
+    }
+
+
+ 
+    /**
+     * <p>Specifies the version of the operating system that created
+     * this {@link PropertySet}. See the HPFS documentation for
+     * details!</p>
+     */
+    protected int osVersion;
+
+    /**
+     * <p>If the OS version field holds this value the property set stream was
+     * created on a 32-bit Windows system.</p>
+     */
+    public static final int OS_WIN32     = 0x0002;
+
+    /**
+     * <p>Returns the property set stream's low-level "OS version"
+     * field.</p>
+     *
+     * @return The property set stream's low-level "OS version" field.
+     */
+    public int getOSVersion()
+    {
+        return osVersion;
+    }
+
+
+
+    /**
+     * <p>Specifies this {@link PropertySet}'s "classID" field. See
+     * the HPFS documentation for details!</p>
+     */
+    protected ClassID classID;
+
+    /**
+     * <p>Returns the property set stream's low-level "class ID"
+     * field.</p>
+     *
+     * @return The property set stream's low-level "class ID" field.
+     */
+    public ClassID getClassID()
+    {
+        return classID;
+    }
+
+
+
+    /**
+     * <p>Returns the number of {@link Section}s in the property
+     * set.</p>
+     *
+     * @return The number of {@link Section}s in the property set.
+     */
+    public int getSectionCount()
+    {
+        return sections.size();
+    }
+
+
+
+    /**
+     * <p>The sections in this {@link PropertySet}.</p>
+     */
+    protected List<Section> sections;
+
+
+    /**
+     * <p>Returns the {@link Section}s in the property set.</p>
+     *
+     * @return The {@link Section}s in the property set.
+     */
+    public List<Section> getSections()
+    {
+        return sections;
+    }
+
+
+
+    /**
+     * <p>Creates an empty (uninitialized) {@link PropertySet}.</p>
+     *
+     * <p><strong>Please note:</strong> For the time being this
+     * constructor is protected since it is used for internal purposes
+     * only, but expect it to become public once the property set's
+     * writing functionality is implemented.</p>
+     */
+    protected PropertySet()
+    { }
+
+
+
+    /**
+     * <p>Creates a {@link PropertySet} instance from an {@link
+     * InputStream} in the Horrible Property Set Format.</p>
+     *
+     * <p>The constructor reads the first few bytes from the stream
+     * and determines whether it is really a property set stream. If
+     * it is, it parses the rest of the stream. If it is not, it
+     * resets the stream to its beginning in order to let other
+     * components mess around with the data and throws an
+     * exception.</p>
+     *
+     * @param stream Holds the data making out the property set
+     * stream.
+     * @throws MarkUnsupportedException if the stream does not support
+     * the {@link InputStream#markSupported} method.
+     * @throws IOException if the {@link InputStream} cannot not be
+     * accessed as needed.
+     * @exception NoPropertySetStreamException if the input stream does not
+     * contain a property set.
+     * @exception UnsupportedEncodingException if a character encoding is not
+     * supported.
+     */
+    public PropertySet(final InputStream stream)
+        throws NoPropertySetStreamException, MarkUnsupportedException,
+               IOException, UnsupportedEncodingException
+    {
+        if (isPropertySetStream(stream))
+        {
+            final int avail = stream.available();
+            final byte[] buffer = new byte[avail];
+            stream.read(buffer, 0, buffer.length);
+            init(buffer, 0, buffer.length);
+        }
+        else
+            throw new NoPropertySetStreamException();
+    }
+
+
+
+
+    /**
+     * <p>Checks whether an {@link InputStream} is in the Horrible
+     * Property Set Format.</p>
+     *
+     * @param stream The {@link InputStream} to check. In order to
+     * perform the check, the method reads the first bytes from the
+     * stream. After reading, the stream is reset to the position it
+     * had before reading. The {@link InputStream} must support the
+     * {@link InputStream#mark} method.
+     * @return <code>true</code> if the stream is a property set
+     * stream, else <code>false</code>.
+     * @throws MarkUnsupportedException if the {@link InputStream}
+     * does not support the {@link InputStream#mark} method.
+     * @exception IOException if an I/O error occurs
+     */
+    public static boolean isPropertySetStream(final InputStream stream)
+        throws MarkUnsupportedException, IOException
+    {
+        /*
+         * Read at most this many bytes.
+         */
+        final int BUFFER_SIZE = 50;
+
+        /*
+         * Mark the current position in the stream so that we can
+         * reset to this position if the stream does not contain a
+         * property set.
+         */
+        if (!stream.markSupported())
+            throw new MarkUnsupportedException(stream.getClass().getName());
+        stream.mark(BUFFER_SIZE);
+
+        /*
+         * Read a couple of bytes from the stream.
+         */
+        final byte[] buffer = new byte[BUFFER_SIZE];
+        final int bytes =
+            stream.read(buffer, 0,
+                        Math.min(buffer.length, stream.available()));
+        final boolean isPropertySetStream =
+            isPropertySetStream(buffer, 0, bytes);
+        stream.reset();
+        return isPropertySetStream;
+    }
+
+
+
+    /**
+     * <p>Checks whether a byte array is in the Horrible Property Set
+     * Format.</p>
+     *
+     * @param src The byte array to check.
+     * @param offset The offset in the byte array.
+     * @param length The significant number of bytes in the byte
+     * array. Only this number of bytes will be checked.
+     * @return <code>true</code> if the byte array is a property set
+     * stream, <code>false</code> if not.
+     */
+    public static boolean isPropertySetStream(final byte[] src,
+                                              final int offset,
+                                              final int length)
+    {
+        /* FIXME (3): Ensure that at most "length" bytes are read. */
+
+        /*
+         * Read the header fields of the stream. They must always be
+         * there.
+         */
+        int o = offset;
+        final int byteOrder = LittleEndian.getUShort(src, o);
+        o += LittleEndian.SHORT_SIZE;
+        byte[] temp = new byte[LittleEndian.SHORT_SIZE];
+        LittleEndian.putShort(temp, (short) byteOrder);
+        if (!Util.equal(temp, BYTE_ORDER_ASSERTION))
+            return false;
+        final int format = LittleEndian.getUShort(src, o);
+        o += LittleEndian.SHORT_SIZE;
+        temp = new byte[LittleEndian.SHORT_SIZE];
+        LittleEndian.putShort(temp, (short) format);
+        if (!Util.equal(temp, FORMAT_ASSERTION))
+            return false;
+        // final long osVersion = LittleEndian.getUInt(src, offset);
+        o += LittleEndian.INT_SIZE;
+        // final ClassID classID = new ClassID(src, offset);
+        o += ClassID.LENGTH;
+        final long sectionCount = LittleEndian.getUInt(src, o);
+        o += LittleEndian.INT_SIZE;
+        if (sectionCount < 0)
+            return false;
+        return true;
+    }
+
+
+
+    /**
+     * <p>Initializes this {@link PropertySet} instance from a byte
+     * array. The method assumes that it has been checked already that
+     * the byte array indeed represents a property set stream. It does
+     * no more checks on its own.</p>
+     *
+     * @param src Byte array containing the property set stream
+     * @param offset The property set stream starts at this offset
+     * from the beginning of <var>src</var>
+     * @param length Length of the property set stream.
+     * @throws UnsupportedEncodingException if HPSF does not (yet) support the
+     * property set's character encoding.
+     */
+    private void init(final byte[] src, final int offset, final int length)
+    throws UnsupportedEncodingException
+    {
+        /* FIXME (3): Ensure that at most "length" bytes are read. */
+        
+        /*
+         * Read the stream's header fields.
+         */
+        int o = offset;
+        byteOrder = LittleEndian.getUShort(src, o);
+        o += LittleEndian.SHORT_SIZE;
+        format = LittleEndian.getUShort(src, o);
+        o += LittleEndian.SHORT_SIZE;
+        osVersion = (int) LittleEndian.getUInt(src, o);
+        o += LittleEndian.INT_SIZE;
+        classID = new ClassID(src, o);
+        o += ClassID.LENGTH;
+        final int sectionCount = LittleEndian.getInt(src, o);
+        o += LittleEndian.INT_SIZE;
+        if (sectionCount < 0)
+            throw new HPSFRuntimeException("Section count " + sectionCount +
+                                           " is negative.");
+
+        /*
+         * Read the sections, which are following the header. They
+         * start with an array of section descriptions. Each one
+         * consists of a format ID telling what the section contains
+         * and an offset telling how many bytes from the start of the
+         * stream the section begins.
+         */
+        /*
+         * Most property sets have only one section. The Document
+         * Summary Information stream has 2. Everything else is a rare
+         * exception and is no longer fostered by Microsoft.
+         */
+        sections = new ArrayList<Section>(sectionCount);
+
+        /*
+         * Loop over the section descriptor array. Each descriptor
+         * consists of a ClassID and a DWord, and we have to increment
+         * "offset" accordingly.
+         */
+        for (int i = 0; i < sectionCount; i++)
+        {
+            final Section s = new Section(src, o);
+            o += ClassID.LENGTH + LittleEndian.INT_SIZE;
+            sections.add(s);
+        }
+    }
+
+
+
+    /**
+     * <p>Checks whether this {@link PropertySet} represents a Summary
+     * Information.</p>
+     *
+     * @return <code>true</code> if this {@link PropertySet}
+     * represents a Summary Information, else <code>false</code>.
+     */
+    public boolean isSummaryInformation()
+    {
+        if (sections.size() <= 0)
+            return false;
+        return Util.equal(sections.get(0).getFormatID().getBytes(),
+                          SectionIDMap.SUMMARY_INFORMATION_ID);
+    }
+
+
+
+    /**
+     * <p>Checks whether this {@link PropertySet} is a Document
+     * Summary Information.</p>
+     *
+     * @return <code>true</code> if this {@link PropertySet}
+     * represents a Document Summary Information, else <code>false</code>.
+     */
+    public boolean isDocumentSummaryInformation()
+    {
+        if (sections.size() <= 0)
+            return false;
+        return Util.equal(sections.get(0).getFormatID().getBytes(),
+                          SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[0]);
+    }
+
+
+
+    /**
+     * <p>Convenience method returning the {@link Property} array
+     * contained in this property set. It is a shortcut for getting
+     * the {@link PropertySet}'s {@link Section}s list and then
+     * getting the {@link Property} array from the first {@link
+     * Section}.</p>
+     *
+     * @return The properties of the only {@link Section} of this
+     * {@link PropertySet}.
+     * @throws NoSingleSectionException if the {@link PropertySet} has
+     * more or less than one {@link Section}.
+     */
+    public Property[] getProperties()
+        throws NoSingleSectionException
+    {
+        return getFirstSection().getProperties();
+    }
+
+
+
+    /**
+     * <p>Convenience method returning the value of the property with
+     * the specified ID. If the property is not available,
+     * <code>null</code> is returned and a subsequent call to {@link
+     * #wasNull} will return <code>true</code> .</p>
+     *
+     * @param id The property ID
+     * @return The property value
+     * @throws NoSingleSectionException if the {@link PropertySet} has
+     * more or less than one {@link Section}.
+     */
+    protected Object getProperty(final int id) throws NoSingleSectionException
+    {
+        return getFirstSection().getProperty(id);
+    }
+
+
+
+    /**
+     * <p>Convenience method returning the value of a boolean property
+     * with the specified ID. If the property is not available,
+     * <code>false</code> is returned. A subsequent call to {@link
+     * #wasNull} will return <code>true</code> to let the caller
+     * distinguish that case from a real property value of
+     * <code>false</code>.</p>
+     *
+     * @param id The property ID
+     * @return The property value
+     * @throws NoSingleSectionException if the {@link PropertySet} has
+     * more or less than one {@link Section}.
+     */
+    protected boolean getPropertyBooleanValue(final int id)
+        throws NoSingleSectionException
+    {
+        return getFirstSection().getPropertyBooleanValue(id);
+    }
+
+
+
+    /**
+     * <p>Convenience method returning the value of the numeric
+     * property with the specified ID. If the property is not
+     * available, 0 is returned. A subsequent call to {@link #wasNull}
+     * will return <code>true</code> to let the caller distinguish
+     * that case from a real property value of 0.</p>
+     *
+     * @param id The property ID
+     * @return The propertyIntValue value
+     * @throws NoSingleSectionException if the {@link PropertySet} has
+     * more or less than one {@link Section}.
+     */
+    protected int getPropertyIntValue(final int id)
+        throws NoSingleSectionException
+    {
+        return getFirstSection().getPropertyIntValue(id);
+    }
+
+
+
+    /**
+     * <p>Checks whether the property which the last call to {@link
+     * #getPropertyIntValue} or {@link #getProperty} tried to access
+     * was available or not. This information might be important for
+     * callers of {@link #getPropertyIntValue} since the latter
+     * returns 0 if the property does not exist. Using {@link
+     * #wasNull}, the caller can distiguish this case from a
+     * property's real value of 0.</p>
+     *
+     * @return <code>true</code> if the last call to {@link
+     * #getPropertyIntValue} or {@link #getProperty} tried to access a
+     * property that was not available, else <code>false</code>.
+     * @throws NoSingleSectionException if the {@link PropertySet} has
+     * more than one {@link Section}.
+     */
+    public boolean wasNull() throws NoSingleSectionException
+    {
+        return getFirstSection().wasNull();
+    }
+
+
+
+    /**
+     * <p>Gets the {@link PropertySet}'s first section.</p>
+     *
+     * @return The {@link PropertySet}'s first section.
+     */
+    public Section getFirstSection()
+    {
+        if (getSectionCount() < 1)
+            throw new MissingSectionException("Property set does not contain any sections.");
+        return sections.get(0);
+    }
+
+    /**
+     * <p>Returns <code>true</code> if the <code>PropertySet</code> is equal
+     * to the specified parameter, else <code>false</code>.</p>
+     *
+     * @param o the object to compare this <code>PropertySet</code> with
+     * 
+     * @return <code>true</code> if the objects are equal, <code>false</code>
+     * if not
+     */
+    public boolean equals(final Object o)
+    {
+        if (o == null || !(o instanceof PropertySet))
+            return false;
+        final PropertySet ps = (PropertySet) o;
+        int byteOrder1 = ps.getByteOrder();
+        int byteOrder2 = getByteOrder();
+        ClassID classID1 = ps.getClassID();
+        ClassID classID2 = getClassID();
+        int format1 = ps.getFormat();
+        int format2 = getFormat();
+        int osVersion1 = ps.getOSVersion();
+        int osVersion2 = getOSVersion();
+        int sectionCount1 = ps.getSectionCount();
+        int sectionCount2 = getSectionCount();
+        if (byteOrder1 != byteOrder2      ||
+            !classID1.equals(classID2)    ||
+            format1 != format2            ||
+            osVersion1 != osVersion2      ||
+            sectionCount1 != sectionCount2)
+            return false;
+
+        /* Compare the sections: */
+        return Util.equals(getSections(), ps.getSections());
+    }
+
+
+
+    /**
+     * @see Object#hashCode()
+     */
+    public int hashCode()
+    {
+        throw new UnsupportedOperationException("FIXME: Not yet implemented.");
+    }
+
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        final StringBuffer b = new StringBuffer();
+        final int sectionCount = getSectionCount();
+        b.append(getClass().getName());
+        b.append('[');
+        b.append("byteOrder: ");
+        b.append(getByteOrder());
+        b.append(", classID: ");
+        b.append(getClassID());
+        b.append(", format: ");
+        b.append(getFormat());
+        b.append(", OSVersion: ");
+        b.append(getOSVersion());
+        b.append(", sectionCount: ");
+        b.append(sectionCount);
+        b.append(", sections: [\n");
+        final List<Section> sections = getSections();
+        for (int i = 0; i < sectionCount; i++)
+            b.append(sections.get(i).toString());
+        b.append(']');
+        b.append(']');
+        return b.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/PropertySetFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/PropertySetFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/PropertySetFactory.java	(revision 28000)
@@ -0,0 +1,77 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.rmi.UnexpectedException;
+
+/**
+ * <p>Factory class to create instances of {@link SummaryInformation},
+ * {@link DocumentSummaryInformation} and {@link PropertySet}.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+public class PropertySetFactory
+{
+
+    /**
+     * <p>Creates the most specific {@link PropertySet} from an {@link
+     * InputStream}. This is preferrably a {@link
+     * DocumentSummaryInformation} or a {@link SummaryInformation}. If
+     * the specified {@link InputStream} does not contain a property
+     * set stream, an exception is thrown and the {@link InputStream}
+     * is repositioned at its beginning.</p>
+     *
+     * @param stream Contains the property set stream's data.
+     * @return The created {@link PropertySet}.
+     * @throws NoPropertySetStreamException if the stream does not
+     * contain a property set.
+     * @throws MarkUnsupportedException if the stream does not support
+     * the <code>mark</code> operation.
+     * @throws IOException if some I/O problem occurs.
+     * @exception UnsupportedEncodingException if the specified codepage is not
+     * supported.
+     */
+    public static PropertySet create(final InputStream stream)
+        throws NoPropertySetStreamException, MarkUnsupportedException,
+               UnsupportedEncodingException, IOException
+    {
+        final PropertySet ps = new PropertySet(stream);
+        try
+        {
+            if (ps.isSummaryInformation())
+                return new SummaryInformation(ps);
+            else if (ps.isDocumentSummaryInformation())
+                return new DocumentSummaryInformation(ps);
+            else
+                return ps;
+        }
+        catch (UnexpectedPropertySetTypeException ex)
+        {
+            /* This exception will never be throws because we already checked
+             * explicitly for this case above. */
+            throw new UnexpectedException(ex.toString());
+        }
+    }
+
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/ReadingNotSupportedException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/ReadingNotSupportedException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/ReadingNotSupportedException.java	(revision 28000)
@@ -0,0 +1,47 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+/**
+ * <p>This exception is thrown when HPSF tries to read a (yet) unsupported
+ * variant type.</p>
+ * 
+ * @see WritingNotSupportedException
+ * @see UnsupportedVariantTypeException
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+@SuppressWarnings("serial")
+public class ReadingNotSupportedException
+    extends UnsupportedVariantTypeException
+{
+
+    /**
+     * <p>Constructor</p>
+     * 
+     * @param variantType The unsupported variant type.
+     * @param value The value.
+     */
+    public ReadingNotSupportedException(final long variantType,
+                                        final Object value)
+    {
+        super(variantType, value);
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Section.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Section.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Section.java	(revision 28000)
@@ -0,0 +1,627 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.poi.hpsf.wellknown.PropertyIDMap;
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * <p>Represents a section in a {@link PropertySet}.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ * @author Drew Varner (Drew.Varner allUpIn sc.edu)
+ */
+public class Section
+{
+
+    /**
+     * <p>Maps property IDs to section-private PID strings. These
+     * strings can be found in the property with ID 0.</p>
+     */
+    protected Map<Long,String> dictionary;
+
+    /**
+     * <p>The section's format ID, {@link #getFormatID}.</p>
+     */
+    protected ClassID formatID;
+
+
+    /**
+     * <p>Returns the format ID. The format ID is the "type" of the
+     * section. For example, if the format ID of the first {@link
+     * Section} contains the bytes specified by
+     * <code>org.apache.poi.hpsf.wellknown.SectionIDMap.SUMMARY_INFORMATION_ID</code>
+     * the section (and thus the property set) is a SummaryInformation.</p>
+     *
+     * @return The format ID
+     */
+    public ClassID getFormatID()
+    {
+        return formatID;
+    }
+
+
+
+    /**
+     * @see #getOffset
+     */
+    protected long offset;
+
+
+    /**
+     * <p>Returns the offset of the section in the stream.</p>
+     *
+     * @return The offset of the section in the stream.
+     */
+    public long getOffset()
+    {
+        return offset;
+    }
+
+
+
+    /**
+     * @see #getSize
+     */
+    protected int size;
+
+
+    /**
+     * <p>Returns the section's size in bytes.</p>
+     *
+     * @return The section's size in bytes.
+     */
+    public int getSize()
+    {
+        return size;
+    }
+
+
+
+    /**
+     * <p>Returns the number of properties in this section.</p>
+     *
+     * @return The number of properties in this section.
+     */
+    public int getPropertyCount()
+    {
+        return properties.length;
+    }
+
+
+
+    /**
+     * @see #getProperties
+     */
+    protected Property[] properties;
+
+
+    /**
+     * <p>Returns this section's properties.</p>
+     *
+     * @return This section's properties.
+     */
+    public Property[] getProperties()
+    {
+        return properties;
+    }
+
+
+
+    /**
+     * <p>Creates an empty and uninitialized {@link Section}.
+     */
+    protected Section()
+    { }
+
+
+
+    /**
+     * <p>Creates a {@link Section} instance from a byte array.</p>
+     *
+     * @param src Contains the complete property set stream.
+     * @param offset The position in the stream that points to the
+     * section's format ID.
+     *
+     * @exception UnsupportedEncodingException if the section's codepage is not
+     * supported.
+     */
+    @SuppressWarnings("unchecked")
+	public Section(final byte[] src, final int offset)
+    throws UnsupportedEncodingException
+    {
+        int o1 = offset;
+
+        /*
+         * Read the format ID.
+         */
+        formatID = new ClassID(src, o1);
+        o1 += ClassID.LENGTH;
+
+        /*
+         * Read the offset from the stream's start and positions to
+         * the section header.
+         */
+        this.offset = LittleEndian.getUInt(src, o1);
+        o1 = (int) this.offset;
+
+        /*
+         * Read the section length.
+         */
+        size = (int) LittleEndian.getUInt(src, o1);
+        o1 += LittleEndian.INT_SIZE;
+
+        /*
+         * Read the number of properties.
+         */
+        final int propertyCount = (int) LittleEndian.getUInt(src, o1);
+        o1 += LittleEndian.INT_SIZE;
+
+        /*
+         * Read the properties. The offset is positioned at the first
+         * entry of the property list. There are two problems:
+         *
+         * 1. For each property we have to find out its length. In the
+         *    property list we find each property's ID and its offset relative
+         *    to the section's beginning. Unfortunately the properties in the
+         *    property list need not to be in ascending order, so it is not
+         *    possible to calculate the length as
+         *    (offset of property(i+1) - offset of property(i)). Before we can
+         *    that we first have to sort the property list by ascending offsets.
+         *
+         * 2. We have to read the property with ID 1 before we read other
+         *    properties, at least before other properties containing strings.
+         *    The reason is that property 1 specifies the codepage. If it is
+         *    1200, all strings are in Unicode. In other words: Before we can
+         *    read any strings we have to know whether they are in Unicode or
+         *    not. Unfortunately property 1 is not guaranteed to be the first in
+         *    a section.
+         *
+         *    The algorithm below reads the properties in two passes: The first
+         *    one looks for property ID 1 and extracts the codepage number. The
+         *    seconds pass reads the other properties.
+         */
+        properties = new Property[propertyCount];
+
+        /* Pass 1: Read the property list. */
+        int pass1Offset = o1;
+        final List<PropertyListEntry> propertyList = new ArrayList<PropertyListEntry>(propertyCount);
+        PropertyListEntry ple;
+        for (int i = 0; i < properties.length; i++)
+        {
+            ple = new PropertyListEntry();
+
+            /* Read the property ID. */
+            ple.id = (int) LittleEndian.getUInt(src, pass1Offset);
+            pass1Offset += LittleEndian.INT_SIZE;
+
+            /* Offset from the section's start. */
+            ple.offset = (int) LittleEndian.getUInt(src, pass1Offset);
+            pass1Offset += LittleEndian.INT_SIZE;
+
+            /* Add the entry to the property list. */
+            propertyList.add(ple);
+        }
+
+        /* Sort the property list by ascending offsets: */
+        Collections.sort(propertyList);
+
+        /* Calculate the properties' lengths. */
+        for (int i = 0; i < propertyCount - 1; i++)
+        {
+            PropertyListEntry ple1 = propertyList.get(i);
+            PropertyListEntry ple2 = propertyList.get(i + 1);
+            ple1.length = ple2.offset - ple1.offset;
+        }
+        if (propertyCount > 0)
+        {
+            ple = propertyList.get(propertyCount - 1);
+            ple.length = size - ple.offset;
+        }
+
+        /* Look for the codepage. */
+        int codepage = -1;
+        for (final Iterator<PropertyListEntry> i = propertyList.iterator();
+             codepage == -1 && i.hasNext();)
+        {
+            ple = i.next();
+
+            /* Read the codepage if the property ID is 1. */
+            if (ple.id == PropertyIDMap.PID_CODEPAGE)
+            {
+                /* Read the property's value type. It must be
+                 * VT_I2. */
+                int o = (int) (this.offset + ple.offset);
+                final long type = LittleEndian.getUInt(src, o);
+                o += LittleEndian.INT_SIZE;
+
+                if (type != Variant.VT_I2)
+                    throw new HPSFRuntimeException
+                        ("Value type of property ID 1 is not VT_I2 but " +
+                         type + ".");
+
+                /* Read the codepage number. */
+                codepage = LittleEndian.getUShort(src, o);
+            }
+        }
+
+        /* Pass 2: Read all properties - including the codepage property,
+         * if available. */
+        int i1 = 0;
+        for (final Iterator<PropertyListEntry> i = propertyList.iterator(); i.hasNext();)
+        {
+            ple = i.next();
+            Property p = new Property(ple.id, src,
+                    this.offset + ple.offset,
+                    ple.length, codepage);
+            if (p.getID() == PropertyIDMap.PID_CODEPAGE)
+                p = new Property(p.getID(), p.getType(), Integer.valueOf(codepage));
+            properties[i1++] = p;
+        }
+
+        /*
+         * Extract the dictionary (if available).
+         */
+        dictionary = (Map<Long,String>) getProperty(0);
+    }
+
+
+
+    /**
+     * <p>Represents an entry in the property list and holds a property's ID and
+     * its offset from the section's beginning.</p>
+     */
+    class PropertyListEntry implements Comparable<PropertyListEntry>
+    {
+        int id;
+        int offset;
+        int length;
+
+        /**
+         * <p>Compares this {@link PropertyListEntry} with another one by their
+         * offsets. A {@link PropertyListEntry} is "smaller" than another one if
+         * its offset from the section's begin is smaller.</p>
+         *
+         * @see Comparable#compareTo(java.lang.Object)
+         */
+        public int compareTo(final PropertyListEntry o)
+        {
+            final int otherOffset = o.offset;
+            if (offset < otherOffset)
+                return -1;
+            else if (offset == otherOffset)
+                return 0;
+            else
+                return 1;
+        }
+
+        public String toString()
+        {
+            final StringBuffer b = new StringBuffer();
+            b.append(getClass().getName());
+            b.append("[id=");
+            b.append(id);
+            b.append(", offset=");
+            b.append(offset);
+            b.append(", length=");
+            b.append(length);
+            b.append(']');
+            return b.toString();
+        }
+    }
+
+
+
+    /**
+     * <p>Returns the value of the property with the specified ID. If
+     * the property is not available, <code>null</code> is returned
+     * and a subsequent call to {@link #wasNull} will return
+     * <code>true</code>.</p>
+     *
+     * @param id The property's ID
+     *
+     * @return The property's value
+     */
+    public Object getProperty(final long id)
+    {
+        wasNull = false;
+        for (int i = 0; i < properties.length; i++)
+            if (id == properties[i].getID())
+                return properties[i].getValue();
+        wasNull = true;
+        return null;
+    }
+
+
+
+    /**
+     * <p>Returns the value of the numeric property with the specified
+     * ID. If the property is not available, 0 is returned. A
+     * subsequent call to {@link #wasNull} will return
+     * <code>true</code> to let the caller distinguish that case from
+     * a real property value of 0.</p>
+     *
+     * @param id The property's ID
+     *
+     * @return The property's value
+     */
+    protected int getPropertyIntValue(final long id)
+    {
+        final Number i;
+        final Object o = getProperty(id);
+        if (o == null)
+            return 0;
+        if (!(o instanceof Long || o instanceof Integer))
+            throw new HPSFRuntimeException
+                ("This property is not an integer type, but " +
+                 o.getClass().getName() + ".");
+        i = (Number) o;
+        return i.intValue();
+    }
+
+
+
+    /**
+     * <p>Returns the value of the boolean property with the specified
+     * ID. If the property is not available, <code>false</code> is
+     * returned. A subsequent call to {@link #wasNull} will return
+     * <code>true</code> to let the caller distinguish that case from
+     * a real property value of <code>false</code>.</p>
+     *
+     * @param id The property's ID
+     *
+     * @return The property's value
+     */
+    protected boolean getPropertyBooleanValue(final int id)
+    {
+        final Boolean b = (Boolean) getProperty(id);
+        if (b == null) {
+            return false;
+        }
+        return b.booleanValue();
+        }
+
+
+
+    /**
+     * <p>This member is <code>true</code> if the last call to {@link
+     * #getPropertyIntValue} or {@link #getProperty} tried to access a
+     * property that was not available, else <code>false</code>.</p>
+     */
+    private boolean wasNull;
+
+
+    /**
+     * <p>Checks whether the property which the last call to {@link
+     * #getPropertyIntValue} or {@link #getProperty} tried to access
+     * was available or not. This information might be important for
+     * callers of {@link #getPropertyIntValue} since the latter
+     * returns 0 if the property does not exist. Using {@link
+     * #wasNull} the caller can distiguish this case from a property's
+     * real value of 0.</p>
+     *
+     * @return <code>true</code> if the last call to {@link
+     * #getPropertyIntValue} or {@link #getProperty} tried to access a
+     * property that was not available, else <code>false</code>.
+     */
+    public boolean wasNull()
+    {
+        return wasNull;
+    }
+
+    /**
+     * <p>Checks whether this section is equal to another object. The result is
+     * <code>false</code> if one of the the following conditions holds:</p>
+     *
+     * <ul>
+     *
+     * <li><p>The other object is not a {@link Section}.</p></li>
+     *
+     * <li><p>The format IDs of the two sections are not equal.</p></li>
+     *
+     * <li><p>The sections have a different number of properties. However,
+     * properties with ID 1 (codepage) are not counted.</p></li>
+     *
+     * <li><p>The other object is not a {@link Section}.</p></li>
+     *
+     * <li><p>The properties have different values. The order of the properties
+     * is irrelevant.</p></li>
+     *
+     * </ul>
+     *
+     * @param o The object to compare this section with
+     * @return <code>true</code> if the objects are equal, <code>false</code> if
+     * not
+     */
+    public boolean equals(final Object o)
+    {
+        if (o == null || !(o instanceof Section))
+            return false;
+        final Section s = (Section) o;
+        if (!s.getFormatID().equals(getFormatID()))
+            return false;
+
+        /* Compare all properties except 0 and 1 as they must be handled
+         * specially. */
+        Property[] pa1 = new Property[getProperties().length];
+        Property[] pa2 = new Property[s.getProperties().length];
+        System.arraycopy(getProperties(), 0, pa1, 0, pa1.length);
+        System.arraycopy(s.getProperties(), 0, pa2, 0, pa2.length);
+
+        /* Extract properties 0 and 1 and remove them from the copy of the
+         * arrays. */
+        Property p10 = null;
+        Property p20 = null;
+        for (int i = 0; i < pa1.length; i++)
+        {
+            final long id = pa1[i].getID();
+            if (id == 0)
+            {
+                p10 = pa1[i];
+                pa1 = remove(pa1, i);
+                i--;
+            }
+            if (id == 1)
+            {
+                // p11 = pa1[i];
+                pa1 = remove(pa1, i);
+                i--;
+            }
+        }
+        for (int i = 0; i < pa2.length; i++)
+        {
+            final long id = pa2[i].getID();
+            if (id == 0)
+            {
+                p20 = pa2[i];
+                pa2 = remove(pa2, i);
+                i--;
+            }
+            if (id == 1)
+            {
+                // p21 = pa2[i];
+                pa2 = remove(pa2, i);
+                i--;
+            }
+        }
+
+        /* If the number of properties (not counting property 1) is unequal the
+         * sections are unequal. */
+        if (pa1.length != pa2.length)
+            return false;
+
+        /* If the dictionaries are unequal the sections are unequal. */
+        boolean dictionaryEqual = true;
+        if (p10 != null && p20 != null)
+            dictionaryEqual = p10.getValue().equals(p20.getValue());
+        else if (p10 != null || p20 != null)
+            dictionaryEqual = false;
+        if (dictionaryEqual) {
+            return Util.equals(pa1, pa2);
+        }
+        return false;
+    }
+
+
+
+    /**
+     * <p>Removes a field from a property array. The resulting array is
+     * compactified and returned.</p>
+     *
+     * @param pa The property array.
+     * @param i The index of the field to be removed.
+     * @return the compactified array.
+     */
+    private Property[] remove(final Property[] pa, final int i)
+    {
+        final Property[] h = new Property[pa.length - 1];
+        if (i > 0)
+            System.arraycopy(pa, 0, h, 0, i);
+        System.arraycopy(pa, i + 1, h, i, h.length - i);
+        return h;
+    }
+
+
+
+    /**
+     * @see Object#hashCode()
+     */
+    public int hashCode()
+    {
+        long hashCode = 0;
+        hashCode += getFormatID().hashCode();
+        final Property[] pa = getProperties();
+        for (int i = 0; i < pa.length; i++)
+            hashCode += pa[i].hashCode();
+        final int returnHashCode = (int) (hashCode & 0x0ffffffffL);
+        return returnHashCode;
+    }
+
+
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        final StringBuffer b = new StringBuffer();
+        final Property[] pa = getProperties();
+        b.append(getClass().getName());
+        b.append('[');
+        b.append("formatID: ");
+        b.append(getFormatID());
+        b.append(", offset: ");
+        b.append(getOffset());
+        b.append(", propertyCount: ");
+        b.append(getPropertyCount());
+        b.append(", size: ");
+        b.append(getSize());
+        b.append(", properties: [\n");
+        for (int i = 0; i < pa.length; i++)
+        {
+            b.append(pa[i].toString());
+            b.append(",\n");
+        }
+        b.append(']');
+        b.append(']');
+        return b.toString();
+    }
+
+
+
+    /**
+     * <p>Gets the section's dictionary. A dictionary allows an application to
+     * use human-readable property names instead of numeric property IDs. It
+     * contains mappings from property IDs to their associated string
+     * values. The dictionary is stored as the property with ID 0. The codepage
+     * for the strings in the dictionary is defined by property with ID 1.</p>
+     *
+     * @return the dictionary or <code>null</code> if the section does not have
+     * a dictionary.
+     */
+    public Map<Long,String> getDictionary()
+    {
+        return dictionary;
+    }
+
+
+
+    /**
+     * <p>Gets the section's codepage, if any.</p>
+     *
+     * @return The section's codepage if one is defined, else -1.
+     */
+    public int getCodepage()
+    {
+        final Integer codepage =
+            (Integer) getProperty(PropertyIDMap.PID_CODEPAGE);
+        if (codepage == null)
+            return -1;
+        int cp = codepage.intValue();
+        return cp;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/SpecialPropertySet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/SpecialPropertySet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/SpecialPropertySet.java	(revision 28000)
@@ -0,0 +1,341 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+
+import org.apache.poi.hpsf.wellknown.PropertyIDMap;
+import org.apache.poi.poifs.filesystem.DirectoryEntry;
+
+/**
+ * <p>Abstract superclass for the convenience classes {@link
+ * SummaryInformation} and {@link DocumentSummaryInformation}.</p>
+ *
+ * <p>The motivation behind this class is quite nasty if you look
+ * behind the scenes, but it serves the application programmer well by
+ * providing him with the easy-to-use {@link SummaryInformation} and
+ * {@link DocumentSummaryInformation} classes. When parsing the data a
+ * property set stream consists of (possibly coming from an {@link
+ * java.io.InputStream}) we want to read and process each byte only
+ * once. Since we don't know in advance which kind of property set we
+ * have, we can expect only the most general {@link
+ * PropertySet}. Creating a special subclass should be as easy as
+ * calling the special subclass' constructor and pass the general
+ * {@link PropertySet} in. To make things easy internally, the special
+ * class just holds a reference to the general {@link PropertySet} and
+ * delegates all method calls to it.</p>
+ *
+ * <p>A cleaner implementation would have been like this: The {@link
+ * PropertySetFactory} parses the stream data into some internal
+ * object first.  Then it finds out whether the stream is a {@link
+ * SummaryInformation}, a {@link DocumentSummaryInformation} or a
+ * general {@link PropertySet}.  However, the current implementation
+ * went the other way round historically: the convenience classes came
+ * only late to my mind.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+public abstract class SpecialPropertySet extends MutablePropertySet
+{
+	/**
+	 * The id to name mapping of the properties
+	 *  in this set.
+	 */
+	public abstract PropertyIDMap getPropertySetIDMap();
+
+    /**
+     * <p>The "real" property set <code>SpecialPropertySet</code>
+     * delegates to.</p>
+     */
+    private MutablePropertySet delegate;
+
+
+
+    /**
+     * <p>Creates a <code>SpecialPropertySet</code>.
+     *
+     * @param ps The property set to be encapsulated by the
+     * <code>SpecialPropertySet</code>
+     */
+    public SpecialPropertySet(final PropertySet ps)
+    {
+        delegate = new MutablePropertySet(ps);
+    }
+
+    /**
+     * @see PropertySet#getByteOrder
+     */
+    public int getByteOrder()
+    {
+        return delegate.getByteOrder();
+    }
+
+
+
+    /**
+     * @see PropertySet#getFormat
+     */
+    public int getFormat()
+    {
+        return delegate.getFormat();
+    }
+
+
+
+    /**
+     * @see PropertySet#getOSVersion
+     */
+    public int getOSVersion()
+    {
+        return delegate.getOSVersion();
+    }
+
+
+
+    /**
+     * @see PropertySet#getClassID
+     */
+    public ClassID getClassID()
+    {
+        return delegate.getClassID();
+    }
+
+
+
+    /**
+     * @see PropertySet#getSectionCount
+     */
+    public int getSectionCount()
+    {
+        return delegate.getSectionCount();
+    }
+
+
+
+    /**
+     * @see PropertySet#getSections
+     */
+    public List<Section> getSections()
+    {
+        return delegate.getSections();
+    }
+
+
+
+    /**
+     * @see PropertySet#isSummaryInformation
+     */
+    public boolean isSummaryInformation()
+    {
+        return delegate.isSummaryInformation();
+    }
+
+
+
+    /**
+     * @see PropertySet#isDocumentSummaryInformation
+     */
+    public boolean isDocumentSummaryInformation()
+    {
+        return delegate.isDocumentSummaryInformation();
+    }
+
+
+
+    /**
+     * @see PropertySet#getSingleSection
+     */
+    public Section getFirstSection()
+    {
+        return delegate.getFirstSection();
+    }
+
+
+    /**
+     * @see org.apache.poi.hpsf.MutablePropertySet#addSection(org.apache.poi.hpsf.Section)
+     */
+    public void addSection(final Section section)
+    {
+        delegate.addSection(section);
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.MutablePropertySet#clearSections()
+     */
+    public void clearSections()
+    {
+        delegate.clearSections();
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.MutablePropertySet#setByteOrder(int)
+     */
+    public void setByteOrder(final int byteOrder)
+    {
+        delegate.setByteOrder(byteOrder);
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.MutablePropertySet#setClassID(org.apache.poi.hpsf.ClassID)
+     */
+    public void setClassID(final ClassID classID)
+    {
+        delegate.setClassID(classID);
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.MutablePropertySet#setFormat(int)
+     */
+    public void setFormat(final int format)
+    {
+        delegate.setFormat(format);
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.MutablePropertySet#setOSVersion(int)
+     */
+    public void setOSVersion(final int osVersion)
+    {
+        delegate.setOSVersion(osVersion);
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.MutablePropertySet#toInputStream()
+     */
+    public InputStream toInputStream() throws IOException, WritingNotSupportedException
+    {
+        return delegate.toInputStream();
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.MutablePropertySet#write(org.apache.poi.poifs.filesystem.DirectoryEntry, java.lang.String)
+     */
+    public void write(final DirectoryEntry dir, final String name) throws WritingNotSupportedException, IOException
+    {
+        delegate.write(dir, name);
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.MutablePropertySet#write(java.io.OutputStream)
+     */
+    public void write(final OutputStream out) throws WritingNotSupportedException, IOException
+    {
+        delegate.write(out);
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.PropertySet#equals(java.lang.Object)
+     */
+    public boolean equals(final Object o)
+    {
+        return delegate.equals(o);
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.PropertySet#getProperties()
+     */
+    public Property[] getProperties() throws NoSingleSectionException
+    {
+        return delegate.getProperties();
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.PropertySet#getProperty(int)
+     */
+    protected Object getProperty(final int id) throws NoSingleSectionException
+    {
+        return delegate.getProperty(id);
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.PropertySet#getPropertyBooleanValue(int)
+     */
+    protected boolean getPropertyBooleanValue(final int id) throws NoSingleSectionException
+    {
+        return delegate.getPropertyBooleanValue(id);
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.PropertySet#getPropertyIntValue(int)
+     */
+    protected int getPropertyIntValue(final int id) throws NoSingleSectionException
+    {
+        return delegate.getPropertyIntValue(id);
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.PropertySet#hashCode()
+     */
+    public int hashCode()
+    {
+        return delegate.hashCode();
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.PropertySet#toString()
+     */
+    public String toString()
+    {
+        return delegate.toString();
+    }
+
+
+
+    /**
+     * @see org.apache.poi.hpsf.PropertySet#wasNull()
+     */
+    public boolean wasNull() throws NoSingleSectionException
+    {
+        return delegate.wasNull();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/SummaryInformation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/SummaryInformation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/SummaryInformation.java	(revision 28000)
@@ -0,0 +1,122 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.util.Date;
+
+import org.apache.poi.hpsf.wellknown.PropertyIDMap;
+
+/**
+ * <p>Convenience class representing a Summary Information stream in a
+ * Microsoft Office document.</p>
+ *
+ * @author Rainer Klute <a
+ *         href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ * @see DocumentSummaryInformation
+ */
+public final class SummaryInformation extends SpecialPropertySet {
+
+    /**
+     * <p>The document name a summary information stream usually has in a POIFS
+     * filesystem.</p>
+     */
+    public static final String DEFAULT_STREAM_NAME = "\005SummaryInformation";
+
+    public PropertyIDMap getPropertySetIDMap() {
+    	return PropertyIDMap.getSummaryInformationProperties();
+    }
+
+
+    /**
+     * <p>Creates a {@link SummaryInformation} from a given {@link
+     * PropertySet}.</p>
+     *
+     * @param ps A property set which should be created from a summary
+     *        information stream.
+     * @throws UnexpectedPropertySetTypeException if <var>ps</var> does not
+     *         contain a summary information stream.
+     */
+    public SummaryInformation(final PropertySet ps)
+            throws UnexpectedPropertySetTypeException
+    {
+        super(ps);
+        if (!isSummaryInformation())
+            throw new UnexpectedPropertySetTypeException("Not a "
+                    + getClass().getName());
+    }
+
+    /**
+     * <p>Returns the title (or <code>null</code>).</p>
+     *
+     * @return The title or <code>null</code>
+     */
+    public String getTitle() // NO_UCD
+    {
+        return (String) getProperty(PropertyIDMap.PID_TITLE);
+    }
+
+    /**
+     * <p>Returns the author (or <code>null</code>).</p>
+     *
+     * @return The author or <code>null</code>
+     */
+    public String getAuthor() // NO_UCD
+    {
+        return (String) getProperty(PropertyIDMap.PID_AUTHOR);
+    }
+
+    /**
+     * <p>Returns the last author (or <code>null</code>).</p>
+     *
+     * @return The last author or <code>null</code>
+     */
+    public String getLastAuthor() // NO_UCD
+    {
+        return (String) getProperty(PropertyIDMap.PID_LASTAUTHOR);
+    }
+
+    /**
+     * <p>Returns the revision number (or <code>null</code>). </p>
+     *
+     * @return The revision number or <code>null</code>
+     */
+    public String getRevNumber() // NO_UCD
+    {
+        return (String) getProperty(PropertyIDMap.PID_REVNUMBER);
+    }
+
+    /**
+     * <p>Returns the creation time (or <code>null</code>).</p>
+     *
+     * @return The creation time or <code>null</code>
+     */
+    public Date getCreateDateTime() // NO_UCD
+    {
+        return (Date) getProperty(PropertyIDMap.PID_CREATE_DTM);
+    }
+
+    /**
+     * <p>Returns the last save time (or <code>null</code>).</p>
+     *
+     * @return The last save time or <code>null</code>
+     */
+    public Date getLastSaveDateTime() // NO_UCD
+    {
+        return (Date) getProperty(PropertyIDMap.PID_LASTSAVE_DTM);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/TypeWriter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/TypeWriter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/TypeWriter.java	(revision 28000)
@@ -0,0 +1,153 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * <p>Class for writing little-endian data and more.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+public class TypeWriter
+{
+
+    /**
+     * <p>Writes a two-byte value (short) to an output stream.</p>
+     *
+     * @param out The stream to write to.
+     * @param n The value to write.
+     * @return The number of bytes that have been written.
+     * @exception IOException if an I/O error occurs
+     */
+    public static int writeToStream(final OutputStream out, final short n)
+        throws IOException
+    {
+        final int length = LittleEndian.SHORT_SIZE;
+        byte[] buffer = new byte[length];
+        LittleEndian.putShort(buffer, 0, n); // FIXME: unsigned
+        out.write(buffer, 0, length);
+        return length;
+    }
+
+
+
+    /**
+     * <p>Writes a four-byte value to an output stream.</p>
+     *
+     * @param out The stream to write to.
+     * @param n The value to write.
+     * @exception IOException if an I/O error occurs
+     * @return The number of bytes written to the output stream. 
+     */
+    public static int writeToStream(final OutputStream out, final int n)
+        throws IOException
+    {
+        final int l = LittleEndian.INT_SIZE;
+        final byte[] buffer = new byte[l];
+        LittleEndian.putInt(buffer, 0, n);
+        out.write(buffer, 0, l);
+        return l;
+        
+    }
+
+
+
+    /**
+     * <p>Writes a eight-byte value to an output stream.</p>
+     *
+     * @param out The stream to write to.
+     * @param n The value to write.
+     * @exception IOException if an I/O error occurs
+     * @return The number of bytes written to the output stream. 
+     */
+    public static int writeToStream(final OutputStream out, final long n)
+        throws IOException
+    {
+        final int l = LittleEndian.LONG_SIZE;
+        final byte[] buffer = new byte[l];
+        LittleEndian.putLong(buffer, 0, n);
+        out.write(buffer, 0, l);
+        return l;
+        
+    }
+
+
+    /**
+     * <p>Writes an unsigned four-byte value to an output stream.</p>
+     *
+     * @param out The stream to write to.
+     * @param n The value to write.
+     * @return The number of bytes that have been written to the output stream.
+     * @exception IOException if an I/O error occurs
+     */
+    public static int writeUIntToStream(final OutputStream out, final long n)
+        throws IOException
+    {
+        long high = n & 0xFFFFFFFF00000000L;
+        if (high != 0 && high != 0xFFFFFFFF00000000L)
+            throw new IllegalPropertySetDataException
+                ("Value " + n + " cannot be represented by 4 bytes.");
+        return writeToStream(out, (int) n);
+    }
+
+
+
+    /**
+     * <p>Writes a 16-byte {@link ClassID} to an output stream.</p>
+     *
+     * @param out The stream to write to
+     * @param n The value to write
+     * @return The number of bytes written
+     * @exception IOException if an I/O error occurs
+     */
+    public static int writeToStream(final OutputStream out, final ClassID n)
+        throws IOException
+    {
+        byte[] b = new byte[16];
+        n.write(b, 0);
+        out.write(b, 0, b.length);
+        return b.length;
+    }
+
+
+
+
+    /**
+     * <p>Writes a double value value to an output stream.</p>
+     *
+     * @param out The stream to write to.
+     * @param n The value to write.
+     * @exception IOException if an I/O error occurs
+     * @return The number of bytes written to the output stream. 
+     */
+    public static int writeToStream(final OutputStream out, final double n)
+        throws IOException
+    {
+        final int l = LittleEndian.DOUBLE_SIZE;
+        final byte[] buffer = new byte[l];
+        LittleEndian.putDouble(buffer, 0, n);
+        out.write(buffer, 0, l);
+        return l;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/UnexpectedPropertySetTypeException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/UnexpectedPropertySetTypeException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/UnexpectedPropertySetTypeException.java	(revision 28000)
@@ -0,0 +1,56 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+/**
+ * <p>This exception is thrown if a certain type of property set is
+ * expected (e.g. a Document Summary Information) but the provided
+ * property set is not of that type.</p>
+ *
+ * <p>The constructors of this class are analogous to those of its
+ * superclass and documented there.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+@SuppressWarnings("serial")
+public class UnexpectedPropertySetTypeException extends HPSFException
+{
+
+    /**
+     * <p>Creates an {@link UnexpectedPropertySetTypeException}.</p>
+     */
+    public UnexpectedPropertySetTypeException()
+    {
+        super();
+    }
+
+
+    /**
+     * <p>Creates an {@link UnexpectedPropertySetTypeException} with a message
+     * string.</p>
+     *
+     * @param msg The message string.
+     */
+    public UnexpectedPropertySetTypeException(final String msg)
+    {
+        super(msg);
+    }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/UnsupportedVariantTypeException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/UnsupportedVariantTypeException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/UnsupportedVariantTypeException.java	(revision 28000)
@@ -0,0 +1,57 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import org.apache.poi.util.HexDump;
+
+/**
+ * <p>This exception is thrown if HPSF encounters a variant type that isn't
+ * supported yet. Although a variant type is unsupported the value can still be
+ * retrieved using the {@link VariantTypeException#getValue} method.</p>
+ * 
+ * <p>Obviously this class should disappear some day.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+@SuppressWarnings("serial")
+public abstract class UnsupportedVariantTypeException
+extends VariantTypeException
+{
+
+    /**
+     * <p>Constructor.</p>
+     * 
+     * @param variantType The unsupported variant type
+     * @param value The value who's variant type is not yet supported
+     */
+    public UnsupportedVariantTypeException(final long variantType,
+                                           final Object value)
+    {
+        super(variantType, value,
+              "HPSF does not yet support the variant type " + variantType + 
+              " (" + Variant.getVariantName(variantType) + ", " +
+              HexDump.toHex(variantType) + "). If you want support for " +
+              "this variant type in one of the next POI releases please " +
+              "submit a request for enhancement (RFE) to " +
+              "<http://issues.apache.org/bugzilla/>! Thank you!");
+    }
+
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Util.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Util.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Util.java	(revision 28000)
@@ -0,0 +1,263 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.util.Collection;
+import java.util.Date;
+
+/**
+ * <p>Provides various static utility methods.</p>
+ *
+ * @author Rainer Klute (klute@rainer-klute.de)
+ */
+public class Util
+{
+
+    /**
+     * <p>Checks whether two byte arrays <var>a</var> and <var>b</var>
+     * are equal. They are equal</p>
+     *
+     * <ul>
+     *
+     *  <li><p>if they have the same length and</p></li>
+     *
+     *  <li><p>if for each <var>i</var> with
+     *  <var>i</var>&nbsp;&gt;=&nbsp;0 and
+     *  <var>i</var>&nbsp;&lt;&nbsp;<var>a.length</var> holds
+     *  <var>a</var>[<var>i</var>]&nbsp;== <var>b</var>[<var>i</var>].</p></li>
+     *
+     * </ul>
+     *
+     * @param a The first byte array
+     * @param b The first byte array
+     * @return <code>true</code> if the byte arrays are equal, else
+     * <code>false</code>
+     */
+    public static boolean equal(final byte[] a, final byte[] b)
+    {
+        if (a.length != b.length)
+            return false;
+        for (int i = 0; i < a.length; i++)
+            if (a[i] != b[i])
+                return false;
+        return true;
+    }
+
+
+
+
+    /**
+     * <p>The difference between the Windows epoch (1601-01-01
+     * 00:00:00) and the Unix epoch (1970-01-01 00:00:00) in
+     * milliseconds: 11644473600000L. (Use your favorite spreadsheet
+     * program to verify the correctness of this value. By the way,
+     * did you notice that you can tell from the epochs which
+     * operating system is the modern one? :-))</p>
+     */
+    public static final long EPOCH_DIFF = 11644473600000L;
+
+
+    /**
+     * <p>Converts a Windows FILETIME into a {@link Date}. The Windows
+     * FILETIME structure holds a date and time associated with a
+     * file. The structure identifies a 64-bit integer specifying the
+     * number of 100-nanosecond intervals which have passed since
+     * January 1, 1601. This 64-bit value is split into the two double
+     * words stored in the structure.</p>
+     *
+     * @param high The higher double word of the FILETIME structure.
+     * @param low The lower double word of the FILETIME structure.
+     * @return The Windows FILETIME as a {@link Date}.
+     */
+    public static Date filetimeToDate(final int high, final int low)
+    {
+        final long filetime = ((long) high) << 32 | (low & 0xffffffffL);
+        return filetimeToDate(filetime);
+    }
+
+    /**
+     * <p>Converts a Windows FILETIME into a {@link Date}. The Windows
+     * FILETIME structure holds a date and time associated with a
+     * file. The structure identifies a 64-bit integer specifying the
+     * number of 100-nanosecond intervals which have passed since
+     * January 1, 1601.</p>
+     *
+     * @param filetime The filetime to convert.
+     * @return The Windows FILETIME as a {@link Date}.
+     */
+    public static Date filetimeToDate(final long filetime)
+    {
+        final long ms_since_16010101 = filetime / (1000 * 10);
+        final long ms_since_19700101 = ms_since_16010101 - EPOCH_DIFF;
+        return new Date(ms_since_19700101);
+    }
+
+
+
+    /**
+     * <p>Converts a {@link Date} into a filetime.</p>
+     *
+     * @param date The date to be converted
+     * @return The filetime
+     *
+     * @see #filetimeToDate(long)
+     * @see #filetimeToDate(int, int)
+     */
+    public static long dateToFileTime(final Date date)
+    {
+        long ms_since_19700101 = date.getTime();
+        long ms_since_16010101 = ms_since_19700101 + EPOCH_DIFF;
+        return ms_since_16010101 * (1000 * 10);
+    }
+
+
+    /**
+     * <p>Checks whether two collections are equal. Two collections
+     * C<sub>1</sub> and C<sub>2</sub> are equal, if the following conditions
+     * are true:</p>
+     *
+     * <ul>
+     *
+     * <li><p>For each c<sub>1<em>i</em></sub> (element of C<sub>1</sub>) there
+     * is a c<sub>2<em>j</em></sub> (element of C<sub>2</sub>), and
+     * c<sub>1<em>i</em></sub> equals c<sub>2<em>j</em></sub>.</p></li>
+     *
+     * <li><p>For each c<sub>2<em>i</em></sub> (element of C<sub>2</sub>) there
+     * is a c<sub>1<em>j</em></sub> (element of C<sub>1</sub>) and
+     * c<sub>2<em>i</em></sub> equals c<sub>1<em>j</em></sub>.</p></li>
+     *
+     * </ul>
+     *
+     * @param c1 the first collection
+     * @param c2 the second collection
+     * @return <code>true</code> if the collections are equal, else
+     * <code>false</code>.
+     */
+    public static boolean equals(Collection<?> c1, Collection<?> c2)
+    {
+        Object[] o1 = c1.toArray();
+        Object[] o2 = c2.toArray();
+        return internalEquals(o1, o2);
+    }
+
+
+
+    /**
+     * <p>Compares to object arrays with regarding the objects' order. For
+     * example, [1, 2, 3] and [2, 1, 3] are equal.</p>
+     *
+     * @param c1 The first object array.
+     * @param c2 The second object array.
+     * @return <code>true</code> if the object arrays are equal,
+     * <code>false</code> if they are not.
+     */
+    public static boolean equals(Object[] c1, Object[] c2)
+    {
+        final Object[] o1 = c1.clone();
+        final Object[] o2 = c2.clone();
+        return internalEquals(o1, o2);
+    }
+
+    private static boolean internalEquals(Object[] o1, Object[] o2)
+    {
+        for (int i1 = 0; i1 < o1.length; i1++)
+        {
+            final Object obj1 = o1[i1];
+            boolean matchFound = false;
+            for (int i2 = 0; !matchFound && i2 < o1.length; i2++)
+            {
+                final Object obj2 = o2[i2];
+                if (obj1.equals(obj2))
+                {
+                    matchFound = true;
+                    o2[i2] = null;
+                }
+            }
+            if (!matchFound)
+                return false;
+        }
+        return true;
+    }
+
+
+
+    /**
+     * <p>Pads a byte array with 0x00 bytes so that its length is a multiple of
+     * 4.</p>
+     *
+     * @param ba The byte array to pad.
+     * @return The padded byte array.
+     */
+    public static byte[] pad4(final byte[] ba)
+    {
+        final int PAD = 4;
+        final byte[] result;
+        int l = ba.length % PAD;
+        if (l == 0)
+            result = ba;
+        else
+        {
+            l = PAD - l;
+            result = new byte[ba.length + l];
+            System.arraycopy(ba, 0, result, 0, ba.length);
+        }
+        return result;
+    }
+
+
+
+    /**
+     * <p>Pads a character array with 0x0000 characters so that its length is a
+     * multiple of 4.</p>
+     *
+     * @param ca The character array to pad.
+     * @return The padded character array.
+     */
+    public static char[] pad4(final char[] ca)
+    {
+        final int PAD = 4;
+        final char[] result;
+        int l = ca.length % PAD;
+        if (l == 0)
+            result = ca;
+        else
+        {
+            l = PAD - l;
+            result = new char[ca.length + l];
+            System.arraycopy(ca, 0, result, 0, ca.length);
+        }
+        return result;
+    }
+
+
+
+    /**
+     * <p>Pads a string with 0x0000 characters so that its length is a
+     * multiple of 4.</p>
+     *
+     * @param s The string to pad.
+     * @return The padded string as a character array.
+     */
+    public static char[] pad4(final String s)
+    {
+        return pad4(s.toCharArray());
+    }
+
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Variant.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Variant.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/Variant.java	(revision 28000)
@@ -0,0 +1,245 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>The <em>Variant</em> types as defined by Microsoft's COM. I
+ * found this information in <a
+ * href="http://www.marin.clara.net/COM/variant_type_definitions.htm">
+ * http://www.marin.clara.net/COM/variant_type_definitions.htm</a>.</p>
+ *
+ * <p>In the variant types descriptions the following shortcuts are
+ * used: <strong> [V]</strong> - may appear in a VARIANT,
+ * <strong>[T]</strong> - may appear in a TYPEDESC,
+ * <strong>[P]</strong> - may appear in an OLE property set,
+ * <strong>[S]</strong> - may appear in a Safe Array.</p>
+ *
+ * @author Rainer Klute (klute@rainer-klute.de)
+ */
+public class Variant
+{
+
+    /**
+     * <p>[V][P] Nothing, i.e. not a single byte of data.</p>
+     */
+    public static final int VT_EMPTY = 0;
+
+    /**
+     * <p>[V][T][P][S] 2 byte signed int.</p>
+     */
+    public static final int VT_I2 = 2;
+
+    /**
+     * <p>[V][T][P][S] 4 byte signed int.</p>
+     */
+    public static final int VT_I4 = 3;
+
+    /**
+     * <p>[V][T][P][S] 8 byte real.</p>
+     */
+    public static final int VT_R8 = 5;
+
+    /**
+     * <p>[V][T][P][S] True=-1, False=0.</p>
+     */
+    public static final int VT_BOOL = 11;
+
+    /**
+     * <p>[T][P] signed 64-bit int.</p>
+     */
+    public static final int VT_I8 = 20;
+
+    /**
+     * <p>[T][P] null terminated string.</p>
+     */
+    public static final int VT_LPSTR = 30;
+
+    /**
+     * <p>[T][P] wide (Unicode) null terminated string.</p>
+     */
+    public static final int VT_LPWSTR = 31;
+
+    /**
+     * <p>[P] FILETIME. The FILETIME structure holds a date and time
+     * associated with a file. The structure identifies a 64-bit
+     * integer specifying the number of 100-nanosecond intervals which
+     * have passed since January 1, 1601. This 64-bit value is split
+     * into the two dwords stored in the structure.</p>
+     */
+    public static final int VT_FILETIME = 64;
+
+    /**
+     * <p>[P] Clipboard format. <span style="background-color:
+     * #ffff00">How long is this? How is it to be
+     * interpreted?</span></p>
+     */
+    public static final int VT_CF = 71;
+
+    /**
+     * <p>Maps the numbers denoting the variant types to their corresponding
+     * variant type names.</p>
+     */
+    private static Map<Long, Object> numberToName;
+
+    /**
+     * <p>Denotes a variant type with a length that is unknown to HPSF yet.</p>
+     */
+    public static final Integer LENGTH_UNKNOWN = Integer.valueOf(-2);
+
+    /**
+     * <p>Denotes a variant type with a variable length.</p>
+     */
+    public static final Integer LENGTH_VARIABLE = Integer.valueOf(-1);
+
+    /**
+     * <p>Denotes a variant type with a length of 0 bytes.</p>
+     */
+    public static final Integer LENGTH_0 = Integer.valueOf(0);
+
+    /**
+     * <p>Denotes a variant type with a length of 2 bytes.</p>
+     */
+    public static final Integer LENGTH_2 = Integer.valueOf(2);
+
+    /**
+     * <p>Denotes a variant type with a length of 4 bytes.</p>
+     */
+    public static final Integer LENGTH_4 = Integer.valueOf(4);
+
+    /**
+     * <p>Denotes a variant type with a length of 8 bytes.</p>
+     */
+    public static final Integer LENGTH_8 = Integer.valueOf(8);
+
+
+
+    static
+    {
+        /* Initialize the number-to-name map: */
+        Map<Long, Object> tm1 = new HashMap<Long, Object>();
+        tm1.put(Long.valueOf(0), "VT_EMPTY");
+        tm1.put(Long.valueOf(1), "VT_NULL");
+        tm1.put(Long.valueOf(2), "VT_I2");
+        tm1.put(Long.valueOf(3), "VT_I4");
+        tm1.put(Long.valueOf(4), "VT_R4");
+        tm1.put(Long.valueOf(5), "VT_R8");
+        tm1.put(Long.valueOf(6), "VT_CY");
+        tm1.put(Long.valueOf(7), "VT_DATE");
+        tm1.put(Long.valueOf(8), "VT_BSTR");
+        tm1.put(Long.valueOf(9), "VT_DISPATCH");
+        tm1.put(Long.valueOf(10), "VT_ERROR");
+        tm1.put(Long.valueOf(11), "VT_BOOL");
+        tm1.put(Long.valueOf(12), "VT_VARIANT");
+        tm1.put(Long.valueOf(13), "VT_UNKNOWN");
+        tm1.put(Long.valueOf(14), "VT_DECIMAL");
+        tm1.put(Long.valueOf(16), "VT_I1");
+        tm1.put(Long.valueOf(17), "VT_UI1");
+        tm1.put(Long.valueOf(18), "VT_UI2");
+        tm1.put(Long.valueOf(19), "VT_UI4");
+        tm1.put(Long.valueOf(20), "VT_I8");
+        tm1.put(Long.valueOf(21), "VT_UI8");
+        tm1.put(Long.valueOf(22), "VT_INT");
+        tm1.put(Long.valueOf(23), "VT_UINT");
+        tm1.put(Long.valueOf(24), "VT_VOID");
+        tm1.put(Long.valueOf(25), "VT_HRESULT");
+        tm1.put(Long.valueOf(26), "VT_PTR");
+        tm1.put(Long.valueOf(27), "VT_SAFEARRAY");
+        tm1.put(Long.valueOf(28), "VT_CARRAY");
+        tm1.put(Long.valueOf(29), "VT_USERDEFINED");
+        tm1.put(Long.valueOf(30), "VT_LPSTR");
+        tm1.put(Long.valueOf(31), "VT_LPWSTR");
+        tm1.put(Long.valueOf(64), "VT_FILETIME");
+        tm1.put(Long.valueOf(65), "VT_BLOB");
+        tm1.put(Long.valueOf(66), "VT_STREAM");
+        tm1.put(Long.valueOf(67), "VT_STORAGE");
+        tm1.put(Long.valueOf(68), "VT_STREAMED_OBJECT");
+        tm1.put(Long.valueOf(69), "VT_STORED_OBJECT");
+        tm1.put(Long.valueOf(70), "VT_BLOB_OBJECT");
+        tm1.put(Long.valueOf(71), "VT_CF");
+        tm1.put(Long.valueOf(72), "VT_CLSID");
+        Map<Long, Object> tm2 = new HashMap<Long, Object>(tm1.size(), 1.0F);
+        tm2.putAll(tm1);
+        numberToName = Collections.unmodifiableMap(tm2);
+
+        /* Initialize the number-to-length map: */
+        tm1.clear();
+        tm1.put(Long.valueOf(0), LENGTH_0);
+        tm1.put(Long.valueOf(1), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(2), LENGTH_2);
+        tm1.put(Long.valueOf(3), LENGTH_4);
+        tm1.put(Long.valueOf(4), LENGTH_4);
+        tm1.put(Long.valueOf(5), LENGTH_8);
+        tm1.put(Long.valueOf(6), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(7), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(8), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(9), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(10), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(11), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(12), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(13), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(14), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(16), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(17), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(18), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(19), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(20), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(21), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(22), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(23), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(24), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(25), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(26), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(27), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(28), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(29), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(30), LENGTH_VARIABLE);
+        tm1.put(Long.valueOf(31), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(64), LENGTH_8);
+        tm1.put(Long.valueOf(65), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(66), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(67), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(68), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(69), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(70), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(71), LENGTH_UNKNOWN);
+        tm1.put(Long.valueOf(72), LENGTH_UNKNOWN);
+        tm2 = new HashMap<Long, Object>(tm1.size(), 1.0F);
+        tm2.putAll(tm1);
+    }
+
+
+
+    /**
+     * <p>Returns the variant type name associated with a variant type
+     * number.</p>
+     *
+     * @param variantType The variant type number
+     * @return The variant type name or the string "unknown variant type"
+     */
+    public static String getVariantName(final long variantType)
+    {
+        final String name = (String) numberToName.get(Long.valueOf(variantType));
+        return name != null ? name : "unknown variant type";
+    }
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/VariantSupport.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/VariantSupport.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/VariantSupport.java	(revision 28000)
@@ -0,0 +1,555 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianConsts;
+
+/**
+ * <p>Supports reading and writing of variant data.</p>
+ *
+ * <p><strong>FIXME (3):</strong> Reading and writing should be made more
+ * uniform than it is now. The following items should be resolved:
+ *
+ * <ul>
+ *
+ * <li><p>Reading requires a length parameter that is 4 byte greater than the
+ * actual data, because the variant type field is included. </p></li>
+ *
+ * <li><p>Reading reads from a byte array while writing writes to an byte array
+ * output stream.</p></li>
+ *
+ * </ul>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+public class VariantSupport extends Variant
+{
+
+    private static boolean logUnsupportedTypes = false;
+
+
+
+    /**
+     * <p>Checks whether logging of unsupported variant types warning is turned
+     * on or off.</p>
+     *
+     * @return <code>true</code> if logging is turned on, else
+     * <code>false</code>.
+     */
+    public static boolean isLogUnsupportedTypes()
+    {
+        return logUnsupportedTypes;
+    }
+
+
+
+    /**
+     * <p>Keeps a list of the variant types an "unsupported" message has already
+     * been issued for.</p>
+     */
+    protected static List<Long> unsupportedMessage;
+
+    /**
+     * <p>Writes a warning to <code>System.err</code> that a variant type is
+     * unsupported by HPSF. Such a warning is written only once for each variant
+     * type. Log messages can be turned on or off by </p>
+     *
+     * @param ex The exception to log
+     */
+    protected static void writeUnsupportedTypeMessage
+        (final UnsupportedVariantTypeException ex)
+    {
+        if (isLogUnsupportedTypes())
+        {
+            if (unsupportedMessage == null)
+                unsupportedMessage = new LinkedList<Long>();
+            Long vt = Long.valueOf(ex.getVariantType());
+            if (!unsupportedMessage.contains(vt))
+            {
+                System.err.println(ex.getMessage());
+                unsupportedMessage.add(vt);
+            }
+        }
+    }
+
+    /**
+     * <p>Reads a variant type from a byte array.</p>
+     *
+     * @param src The byte array
+     * @param offset The offset in the byte array where the variant starts
+     * @param length The length of the variant including the variant type field
+     * @param type The variant type to read
+     * @param codepage The codepage to use for non-wide strings
+     * @return A Java object that corresponds best to the variant field. For
+     *         example, a VT_I4 is returned as a {@link Long}, a VT_LPSTR as a
+     *         {@link String}.
+     * @exception ReadingNotSupportedException if a property is to be written
+     *            who's variant type HPSF does not yet support
+     * @exception UnsupportedEncodingException if the specified codepage is not
+     *            supported.
+     * @see Variant
+     */
+    public static Object read(final byte[] src, final int offset,
+                              final int length, final long type,
+                              final int codepage)
+    throws ReadingNotSupportedException, UnsupportedEncodingException
+    {
+        Object value;
+        int o1 = offset;
+        int l1 = length - LittleEndian.INT_SIZE;
+        long lType = type;
+
+        /* Instead of trying to read 8-bit characters from a Unicode string,
+         * read 16-bit characters. */
+        if (codepage == Constants.CP_UNICODE && type == Variant.VT_LPSTR)
+            lType = Variant.VT_LPWSTR;
+
+        switch ((int) lType)
+        {
+            case Variant.VT_EMPTY:
+            {
+                value = null;
+                break;
+            }
+            case Variant.VT_I2:
+            {
+                /*
+                 * Read a short. In Java it is represented as an
+                 * Integer object.
+                 */
+                value = Integer.valueOf(LittleEndian.getShort(src, o1));
+                break;
+            }
+            case Variant.VT_I4:
+            {
+                /*
+                 * Read a word. In Java it is represented as an
+                 * Integer object.
+                 */
+                value = Integer.valueOf(LittleEndian.getInt(src, o1));
+                break;
+            }
+            case Variant.VT_I8:
+            {
+                /*
+                 * Read a double word. In Java it is represented as a
+                 * Long object.
+                 */
+                value = Long.valueOf(LittleEndian.getLong(src, o1));
+                break;
+            }
+            case Variant.VT_R8:
+            {
+                /*
+                 * Read an eight-byte double value. In Java it is represented as
+                 * a Double object.
+                 */
+                value = new Double(LittleEndian.getDouble(src, o1));
+                break;
+            }
+            case Variant.VT_FILETIME:
+            {
+                /*
+                 * Read a FILETIME object. In Java it is represented
+                 * as a Date object.
+                 */
+                final long low = LittleEndian.getUInt(src, o1);
+                o1 += LittleEndian.INT_SIZE;
+                final long high = LittleEndian.getUInt(src, o1);
+                value = Util.filetimeToDate((int) high, (int) low);
+                break;
+            }
+            case Variant.VT_LPSTR:
+            {
+                /*
+                 * Read a byte string. In Java it is represented as a
+                 * String object. The 0x00 bytes at the end must be
+                 * stripped.
+                 */
+                final int first = o1 + LittleEndian.INT_SIZE;
+                long last = first + LittleEndian.getUInt(src, o1) - 1;
+                o1 += LittleEndian.INT_SIZE;
+                while (src[(int) last] == 0 && first <= last)
+                    last--;
+                final int l = (int) (last - first + 1);
+                value = codepage != -1 ?
+                    new String(src, first, l,
+                               codepageToEncoding(codepage)) :
+                    new String(src, first, l);
+                break;
+            }
+            case Variant.VT_LPWSTR:
+            {
+                /*
+                 * Read a Unicode string. In Java it is represented as
+                 * a String object. The 0x00 bytes at the end must be
+                 * stripped.
+                 */
+                final int first = o1 + LittleEndian.INT_SIZE;
+                long last = first + LittleEndian.getUInt(src, o1) - 1;
+                long l = last - first;
+                o1 += LittleEndian.INT_SIZE;
+                StringBuffer b = new StringBuffer((int) (last - first));
+                for (int i = 0; i <= l; i++)
+                {
+                    final int i1 = o1 + (i * 2);
+                    final int i2 = i1 + 1;
+                    final int high = src[i2] << 8;
+                    final int low = src[i1] & 0x00ff;
+                    final char c = (char) (high | low);
+                    b.append(c);
+                }
+                /* Strip 0x00 characters from the end of the string: */
+                while (b.length() > 0 && b.charAt(b.length() - 1) == 0x00)
+                    b.setLength(b.length() - 1);
+                value = b.toString();
+                break;
+            }
+            case Variant.VT_CF:
+            {
+                if(l1 < 0) {
+                    /**
+                     *  YK: reading the ClipboardData packet (VT_CF) is not quite correct.
+                     *  The size of the data is determined by the first four bytes of the packet
+                     *  while the current implementation calculates it in the Section constructor.
+                     *  Test files in Bugzilla 42726 and 45583 clearly show that this approach does not always work.
+                     *  The workaround below attempts to gracefully handle such cases instead of throwing exceptions.
+                     *
+                     *  August 20, 2009
+                     */
+                    l1 = LittleEndian.getInt(src, o1); o1 += LittleEndian.INT_SIZE;
+                }
+                final byte[] v = new byte[l1];
+                System.arraycopy(src, o1, v, 0, v.length);
+                value = v;
+                break;
+            }
+            case Variant.VT_BOOL:
+            {
+                /*
+                 * The first four bytes in src, from src[offset] to
+                 * src[offset + 3] contain the DWord for VT_BOOL, so
+                 * skip it, we don't need it.
+                 */
+                // final int first = offset + LittleEndian.INT_SIZE;
+                long bool = LittleEndian.getUInt(src, o1);
+                if (bool != 0)
+                    value = Boolean.TRUE;
+                else
+                    value = Boolean.FALSE;
+                break;
+            }
+            default:
+            {
+                final byte[] v = new byte[l1];
+                for (int i = 0; i < l1; i++)
+                    v[i] = src[(o1 + i)];
+                throw new ReadingNotSupportedException(type, v);
+            }
+        }
+        return value;
+    }
+
+
+
+    /**
+     * <p>Turns a codepage number into the equivalent character encoding's
+     * name.</p>
+     *
+     * @param codepage The codepage number
+     *
+     * @return The character encoding's name. If the codepage number is 65001,
+     * the encoding name is "UTF-8". All other positive numbers are mapped to
+     * "cp" followed by the number, e.g. if the codepage number is 1252 the
+     * returned character encoding name will be "cp1252".
+     *
+     * @exception UnsupportedEncodingException if the specified codepage is
+     * less than zero.
+     */
+    public static String codepageToEncoding(final int codepage)
+    throws UnsupportedEncodingException
+    {
+        if (codepage <= 0)
+            throw new UnsupportedEncodingException
+                ("Codepage number may not be " + codepage);
+        switch (codepage)
+        {
+            case Constants.CP_UTF16:
+                return "UTF-16";
+            case Constants.CP_UTF16_BE:
+                return "UTF-16BE";
+            case Constants.CP_UTF8:
+                return "UTF-8";
+            case Constants.CP_037:
+                return "cp037";
+            case Constants.CP_GBK:
+                return "GBK";
+            case Constants.CP_MS949:
+                return "ms949";
+            case Constants.CP_WINDOWS_1250:
+                return "windows-1250";
+            case Constants.CP_WINDOWS_1251:
+                return "windows-1251";
+            case Constants.CP_WINDOWS_1252:
+                return "windows-1252";
+            case Constants.CP_WINDOWS_1253:
+                return "windows-1253";
+            case Constants.CP_WINDOWS_1254:
+                return "windows-1254";
+            case Constants.CP_WINDOWS_1255:
+                return "windows-1255";
+            case Constants.CP_WINDOWS_1256:
+                return "windows-1256";
+            case Constants.CP_WINDOWS_1257:
+                return "windows-1257";
+            case Constants.CP_WINDOWS_1258:
+                return "windows-1258";
+            case Constants.CP_JOHAB:
+                return "johab";
+            case Constants.CP_MAC_ROMAN:
+                return "MacRoman";
+            case Constants.CP_MAC_JAPAN:
+                return "SJIS";
+            case Constants.CP_MAC_CHINESE_TRADITIONAL:
+                return "Big5";
+            case Constants.CP_MAC_KOREAN:
+                return "EUC-KR";
+            case Constants.CP_MAC_ARABIC:
+                return "MacArabic";
+            case Constants.CP_MAC_HEBREW:
+                return "MacHebrew";
+            case Constants.CP_MAC_GREEK:
+                return "MacGreek";
+            case Constants.CP_MAC_CYRILLIC:
+                return "MacCyrillic";
+            case Constants.CP_MAC_CHINESE_SIMPLE:
+                return "EUC_CN";
+            case Constants.CP_MAC_ROMANIA:
+                return "MacRomania";
+            case Constants.CP_MAC_UKRAINE:
+                return "MacUkraine";
+            case Constants.CP_MAC_THAI:
+                return "MacThai";
+            case Constants.CP_MAC_CENTRAL_EUROPE:
+                return "MacCentralEurope";
+            case Constants.CP_MAC_ICELAND:
+                  return "MacIceland";
+            case Constants.CP_MAC_TURKISH:
+                return "MacTurkish";
+            case Constants.CP_MAC_CROATIAN:
+                return "MacCroatian";
+            case Constants.CP_US_ACSII:
+            case Constants.CP_US_ASCII2:
+                return "US-ASCII";
+            case Constants.CP_KOI8_R:
+                return "KOI8-R";
+            case Constants.CP_ISO_8859_1:
+                return "ISO-8859-1";
+            case Constants.CP_ISO_8859_2:
+                return "ISO-8859-2";
+            case Constants.CP_ISO_8859_3:
+                return "ISO-8859-3";
+            case Constants.CP_ISO_8859_4:
+                return "ISO-8859-4";
+            case Constants.CP_ISO_8859_5:
+                return "ISO-8859-5";
+            case Constants.CP_ISO_8859_6:
+                return "ISO-8859-6";
+            case Constants.CP_ISO_8859_7:
+                return "ISO-8859-7";
+            case Constants.CP_ISO_8859_8:
+                return "ISO-8859-8";
+            case Constants.CP_ISO_8859_9:
+                return "ISO-8859-9";
+            case Constants.CP_ISO_2022_JP1:
+            case Constants.CP_ISO_2022_JP2:
+            case Constants.CP_ISO_2022_JP3:
+                return "ISO-2022-JP";
+            case Constants.CP_ISO_2022_KR:
+                return "ISO-2022-KR";
+            case Constants.CP_EUC_JP:
+                return "EUC-JP";
+            case Constants.CP_EUC_KR:
+                return "EUC-KR";
+            case Constants.CP_GB2312:
+                return "GB2312";
+            case Constants.CP_GB18030:
+                return "GB18030";
+            case Constants.CP_SJIS:
+                return "SJIS";
+            default:
+                return "cp" + codepage;
+        }
+    }
+
+
+    /**
+     * <p>Writes a variant value to an output stream. This method ensures that
+     * always a multiple of 4 bytes is written.</p>
+     *
+     * <p>If the codepage is UTF-16, which is encouraged, strings
+     * <strong>must</strong> always be written as {@link Variant#VT_LPWSTR}
+     * strings, not as {@link Variant#VT_LPSTR} strings. This method ensure this
+     * by converting strings appropriately, if needed.</p>
+     *
+     * @param out The stream to write the value to.
+     * @param type The variant's type.
+     * @param value The variant's value.
+     * @param codepage The codepage to use to write non-wide strings
+     * @return The number of entities that have been written. In many cases an
+     * "entity" is a byte but this is not always the case.
+     * @exception IOException if an I/O exceptions occurs
+     * @exception WritingNotSupportedException if a property is to be written
+     * who's variant type HPSF does not yet support
+     */
+    public static int write(final OutputStream out, final long type,
+                            final Object value, final int codepage)
+        throws IOException, WritingNotSupportedException
+    {
+        int length = 0;
+        switch ((int) type)
+        {
+            case Variant.VT_BOOL:
+            {
+                int trueOrFalse;
+                if (((Boolean) value).booleanValue())
+                    trueOrFalse = 1;
+                else
+                    trueOrFalse = 0;
+                length = TypeWriter.writeUIntToStream(out, trueOrFalse);
+                break;
+            }
+            case Variant.VT_LPSTR:
+            {
+                final byte[] bytes =
+                    (codepage == -1 ?
+                    ((String) value).getBytes() :
+                    ((String) value).getBytes(codepageToEncoding(codepage)));
+                length = TypeWriter.writeUIntToStream(out, bytes.length + 1);
+                final byte[] b = new byte[bytes.length + 1];
+                System.arraycopy(bytes, 0, b, 0, bytes.length);
+                b[b.length - 1] = 0x00;
+                out.write(b);
+                length += b.length;
+                break;
+            }
+            case Variant.VT_LPWSTR:
+            {
+                final int nrOfChars = ((String) value).length() + 1;
+                length += TypeWriter.writeUIntToStream(out, nrOfChars);
+                char[] s = Util.pad4((String) value);
+                for (int i = 0; i < s.length; i++)
+                {
+                    final int high = ((s[i] & 0x0000ff00) >> 8);
+                    final int low = (s[i] & 0x000000ff);
+                    final byte highb = (byte) high;
+                    final byte lowb = (byte) low;
+                    out.write(lowb);
+                    out.write(highb);
+                    length += 2;
+                }
+                out.write(0x00);
+                out.write(0x00);
+                length += 2;
+                break;
+            }
+            case Variant.VT_CF:
+            {
+                final byte[] b = (byte[]) value;
+                out.write(b);
+                length = b.length;
+                break;
+            }
+            case Variant.VT_EMPTY:
+            {
+                TypeWriter.writeUIntToStream(out, Variant.VT_EMPTY);
+                length = LittleEndianConsts.INT_SIZE;
+                break;
+            }
+            case Variant.VT_I2:
+            {
+                TypeWriter.writeToStream(out, ((Integer) value).shortValue());
+                length = LittleEndianConsts.SHORT_SIZE;
+                break;
+            }
+            case Variant.VT_I4:
+            {
+                if (!(value instanceof Integer))
+                {
+                    throw new ClassCastException("Could not cast an object to "
+                            + Integer.class.toString() + ": "
+                            + value.getClass().toString() + ", "
+                            + value.toString());
+                }
+                length += TypeWriter.writeToStream(out,
+                          ((Integer) value).intValue());
+                break;
+            }
+            case Variant.VT_I8:
+            {
+                TypeWriter.writeToStream(out, ((Long) value).longValue());
+                length = LittleEndianConsts.LONG_SIZE;
+                break;
+            }
+            case Variant.VT_R8:
+            {
+                length += TypeWriter.writeToStream(out,
+                          ((Double) value).doubleValue());
+                break;
+            }
+            case Variant.VT_FILETIME:
+            {
+                long filetime = Util.dateToFileTime((Date) value);
+                int high = (int) ((filetime >> 32) & 0x00000000FFFFFFFFL);
+                int low = (int) (filetime & 0x00000000FFFFFFFFL);
+                length += TypeWriter.writeUIntToStream
+                    (out, 0x0000000FFFFFFFFL & low);
+                length += TypeWriter.writeUIntToStream
+                    (out, 0x0000000FFFFFFFFL & high);
+                break;
+            }
+            default:
+            {
+                /* The variant type is not supported yet. However, if the value
+                 * is a byte array we can write it nevertheless. */
+                if (value instanceof byte[])
+                {
+                    final byte[] b = (byte[]) value;
+                    out.write(b);
+                    length = b.length;
+                    writeUnsupportedTypeMessage
+                        (new WritingNotSupportedException(type, value));
+                }
+                else
+                    throw new WritingNotSupportedException(type, value);
+                break;
+            }
+        }
+
+        return length;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/VariantTypeException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/VariantTypeException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/VariantTypeException.java	(revision 28000)
@@ -0,0 +1,76 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+/**
+ * <p>This exception is thrown if HPSF encounters a problem with a variant type.
+ * Concrete subclasses specifiy the problem further.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+@SuppressWarnings("serial")
+public abstract class VariantTypeException extends HPSFException
+{
+
+    private Object value;
+
+    private long variantType;
+
+
+
+    /**
+     * <p>Constructor.</p>
+     *
+     * @param variantType The variant type causing the problem
+     * @param value The value who's variant type causes the problem
+     * @param msg A message text describing the problem
+     */
+    public VariantTypeException(final long variantType, final Object value,
+                                final String msg)
+    {
+        super(msg);
+        this.variantType = variantType;
+        this.value = value;
+    }
+
+
+
+    /**
+     * <p>Returns the offending variant type.</p>
+     *
+     * @return the offending variant type.
+     */
+    public long getVariantType()
+    {
+        return variantType;
+    }
+
+
+
+    /**
+     * <p>Returns the value who's variant type caused the problem.</p>
+     *
+     * @return the value who's variant type caused the problem
+     */
+    public Object getValue()
+    {
+        return value;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/WritingNotSupportedException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/WritingNotSupportedException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/WritingNotSupportedException.java	(revision 28000)
@@ -0,0 +1,47 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf;
+
+/**
+ * <p>This exception is thrown when trying to write a (yet) unsupported variant
+ * type.</p>
+ * 
+ * @see ReadingNotSupportedException
+ * @see UnsupportedVariantTypeException
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+@SuppressWarnings("serial")
+public class WritingNotSupportedException
+    extends UnsupportedVariantTypeException
+{
+
+    /**
+     * <p>Constructor</p>
+     * 
+     * @param variantType The unsupported variant type.
+     * @param value The value.
+     */
+    public WritingNotSupportedException(final long variantType,
+                                        final Object value)
+    {
+        super(variantType, value);
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/package.html	(revision 28000)
@@ -0,0 +1,164 @@
+<!doctype html public "-//W3C//DTD HTML 4.0//EN//">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+ <head>
+  <title>HPSF</title>
+ </head>
+
+ <body>
+  <div>
+   <p>Processes streams in the Horrible Property Set Format (HPSF) in POI
+    filesystems. Microsoft Office documents, i.e. POI filesystems, usually
+    contain meta data like author, title, last saving time etc. These items
+    are called <strong>properties</strong> and stored in
+    <strong>property set streams</strong> along with the document itself. These
+    streams are commonly named <tt>\005SummaryInformation</tt> and
+    <tt>\005DocumentSummaryInformation</tt>. However, a POI filesystem may
+    contain further property sets of other names or types.</p>
+
+   <p>In order to extract the properties from a POI filesystem, a property set
+    stream's contents must be parsed into a {@link
+    org.apache.poi.hpsf.PropertySet} instance.  Its subclasses {@link
+    org.apache.poi.hpsf.SummaryInformation} and {@link
+    org.apache.poi.hpsf.DocumentSummaryInformation} deal with the well-known
+    property set streams <tt>\005SummaryInformation</tt> and
+    <tt>\005DocumentSummaryInformation</tt>. (However, the streams' names are
+    irrelevant. What counts is the property set's first section's format ID -
+    see below.)</p>
+
+   <p>The factory method {@link org.apache.poi.hpsf.PropertySetFactory#create}
+    creates a {@link org.apache.poi.hpsf.PropertySet} instance. This method
+    always returns the <strong>most specific property set</strong>: If it
+    identifies the stream data as a Summary Information or as a Document
+    Summary Information it returns an instance of the corresponding class, else
+    the general {@link org.apache.poi.hpsf.PropertySet}.</p>
+
+   <p>A {@link org.apache.poi.hpsf.PropertySet} contains a list of {@link
+    org.apache.poi.hpsf.Section}s which can be retrieved  with {@link
+    org.apache.poi.hpsf.PropertySet#getSections}. Each {@link
+    org.apache.poi.hpsf.Section} contains a {@link
+    org.apache.poi.hpsf.Property} array which can be retrieved with {@link
+    org.apache.poi.hpsf.Section#getProperties}. Since the vast majority of
+    {@link org.apache.poi.hpsf.PropertySet}s contains only a single {@link
+    org.apache.poi.hpsf.Section}, the convenience method {@link
+    org.apache.poi.hpsf.PropertySet#getProperties} returns the properties of a
+    {@link org.apache.poi.hpsf.PropertySet}'s  {@link
+    org.apache.poi.hpsf.Section} (throwing a {@link
+    org.apache.poi.hpsf.NoSingleSectionException} if the {@link
+    org.apache.poi.hpsf.PropertySet} contains more (or less) than exactly one
+    {@link org.apache.poi.hpsf.Section}).</p>
+
+   <p>Each {@link org.apache.poi.hpsf.Property} has an <strong>ID</strong>, a
+    <strong>type</strong>, and a <strong>value</strong> which can be retrieved
+    with {@link org.apache.poi.hpsf.Property#getID}, {@link
+    org.apache.poi.hpsf.Property#getType}, and {@link
+    org.apache.poi.hpsf.Property#getValue}, respectively. The value's class
+    depends on the property's type. <!-- FIXME: --> The current implementation
+    does not yet support all property types and restricts the values' classes
+    to {@link java.lang.String}, {@link java.lang.Integer} and {@link
+    java.util.Date}. A value of a yet unknown type is returned as a byte array
+    containing the value's origin bytes from the property set stream.</p>
+
+   <p>To retrieve the value of a specific {@link org.apache.poi.hpsf.Property},
+    use {@link org.apache.poi.hpsf.Section#getProperty} or {@link
+    org.apache.poi.hpsf.Section#getPropertyIntValue}.</p>
+
+   <p>The {@link org.apache.poi.hpsf.SummaryInformation} and {@link
+    org.apache.poi.hpsf.DocumentSummaryInformation} classes provide convenience
+    methods for retrieving well-known properties. For example, an application
+    that wants to retrieve a document's title string just calls {@link
+    org.apache.poi.hpsf.SummaryInformation#getTitle} instead of going through
+    the hassle of first finding out what the title's property ID is and then
+    using this ID to get the property's value.</p>
+
+   <p>Writing properties can be done with the classes
+    {@link org.apache.poi.hpsf.MutablePropertySet}, {@link
+    org.apache.poi.hpsf.MutableSection}, and {@link
+    org.apache.poi.hpsf.MutableProperty}.</p>
+
+   <p>Public documentation from Microsoft can be found in the  <a 
+    href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/stg/stg/properties_and_property_sets.asp"
+    target="_blank">appropriate section of the MSDN Library</a>.</p>
+
+   <div>
+    <h2>History</h2>
+
+    <dl>
+     <dt>2003-09-11:</dt>
+
+     <dd>
+      <p>{@link org.apache.poi.hpsf.PropertySetFactory#create(InputStream)} no
+       longer throws an
+       {@link org.apache.poi.hpsf.UnexpectedPropertySetTypeException}.</p></dd>
+    </dl>
+   </div>
+
+
+   <div>
+    <h2>To Do</h2>
+
+    <p>The following is still left to be implemented. Sponsering could foster
+     these issues considerably.</p>
+
+    <ul>
+
+     <li>
+      <p>Convenience methods for setting summary information and document
+       summary information properties</p>
+     </li>
+
+     <li>
+      <p>Better codepage support</p>
+     </li>
+
+     <li>
+      <p>Support for more property (variant) types</p>
+     </li>
+
+    </ul>
+
+   </div>
+
+   <p>
+    @author Rainer Klute (klute@rainer-klute.de)
+   </p>
+  </div>
+
+ </body>
+</html>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+sgml-default-dtd-file:"HTML_4.0_Strict.ced"
+mode: html
+sgml-omittag:t
+sgml-shorttag:nil
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/wellknown/PropertyIDMap.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/wellknown/PropertyIDMap.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/wellknown/PropertyIDMap.java	(revision 28000)
@@ -0,0 +1,363 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf.wellknown;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>This is a dictionary which maps property ID values to property
+ * ID strings.</p>
+ *
+ * <p>The methods {@link #getSummaryInformationProperties} and {@link
+ * #getDocumentSummaryInformationProperties} return singleton {@link
+ * PropertyIDMap}s. An application that wants to extend these maps
+ * should treat them as unmodifiable, copy them and modifiy the
+ * copies.</p>
+ *
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
+ */
+@SuppressWarnings("serial")
+public class PropertyIDMap extends HashMap<Integer, String> {
+
+    /*
+     * The following definitions are for property IDs in the first
+     * (and only) section of the Summary Information property set.
+     */
+
+    /** <p>ID of the property that denotes the document's title</p> */
+    public static final int PID_TITLE = 2;
+
+    /** <p>ID of the property that denotes the document's subject</p> */
+    public static final int PID_SUBJECT = 3;
+
+    /** <p>ID of the property that denotes the document's author</p> */
+    public static final int PID_AUTHOR = 4;
+
+    /** <p>ID of the property that denotes the document's keywords</p> */
+    public static final int PID_KEYWORDS = 5;
+
+    /** <p>ID of the property that denotes the document's comments</p> */
+    public static final int PID_COMMENTS = 6;
+
+    /** <p>ID of the property that denotes the document's template</p> */
+    public static final int PID_TEMPLATE = 7;
+
+    /** <p>ID of the property that denotes the document's last author</p> */
+    public static final int PID_LASTAUTHOR = 8;
+
+    /** <p>ID of the property that denotes the document's revision number</p> */
+    public static final int PID_REVNUMBER = 9;
+
+    /** <p>ID of the property that denotes the document's edit time</p> */
+    public static final int PID_EDITTIME = 10;
+
+    /** <p>ID of the property that denotes the date and time the document was
+     * last printed</p> */
+    public static final int PID_LASTPRINTED = 11;
+
+    /** <p>ID of the property that denotes the date and time the document was
+     * created.</p> */
+    public static final int PID_CREATE_DTM = 12;
+
+    /** <p>ID of the property that denotes the date and time the document was
+     * saved</p> */
+    public static final int PID_LASTSAVE_DTM = 13;
+
+    /** <p>ID of the property that denotes the number of pages in the
+     * document</p> */
+    public static final int PID_PAGECOUNT = 14;
+
+    /** <p>ID of the property that denotes the number of words in the
+     * document</p> */
+    public static final int PID_WORDCOUNT = 15;
+
+    /** <p>ID of the property that denotes the number of characters in the
+     * document</p> */
+    public static final int PID_CHARCOUNT = 16;
+
+    /** <p>ID of the property that denotes the document's thumbnail</p> */
+    public static final int PID_THUMBNAIL = 17;
+
+    /** <p>ID of the property that denotes the application that created the
+     * document</p> */
+    public static final int PID_APPNAME = 18;
+
+    /** <p>ID of the property that denotes whether read/write access to the
+     * document is allowed or whether is should be opened as read-only. It can
+     * have the following values:</p>
+     *
+     * <table>
+     *  <tbody>
+     *   <tr>
+     *    <th><p>Value</p></th>
+     *    <th><p>Description</p></th>
+     *   </tr>
+     *   <tr>
+     *    <th><p>0</p></th>
+     *    <th><p>No restriction</p></th>
+     *   </tr>
+     *   <tr>
+     *    <th><p>2</p></th>
+     *    <th><p>Read-only recommended</p></th>
+     *   </tr>
+     *   <tr>
+     *    <th><p>4</p></th>
+     *    <th><p>Read-only enforced</p></th>
+     *   </tr>
+     *  </tbody>
+     * </table>
+     */
+    public static final int PID_SECURITY = 19;
+
+
+
+    /*
+     * The following definitions are for property IDs in the first
+     * section of the Document Summary Information property set.
+     */
+
+    /**
+     * <p>The entry is a dictionary.</p>
+     */
+    public static final int PID_DICTIONARY = 0;
+
+    /**
+     * <p>The entry denotes a code page.</p>
+     */
+    public static final int PID_CODEPAGE = 1;
+
+    /**
+     * <p>The entry is a string denoting the category the file belongs
+     * to, e.g. review, memo, etc. This is useful to find documents of
+     * same type.</p>
+     */
+    public static final int PID_CATEGORY = 2;
+
+    /**
+     * <p>Target format for power point presentation, e.g. 35mm,
+     * printer, video etc.</p>
+     */
+    public static final int PID_PRESFORMAT = 3;
+
+    /**
+     * <p>Number of bytes.</p>
+     */
+    public static final int PID_BYTECOUNT = 4;
+
+    /**
+     * <p>Number of lines.</p>
+     */
+    public static final int PID_LINECOUNT = 5;
+
+    /**
+     * <p>Number of paragraphs.</p>
+     */
+    public static final int PID_PARCOUNT = 6;
+
+    /**
+     * <p>Number of slides in a power point presentation.</p>
+     */
+    public static final int PID_SLIDECOUNT = 7;
+
+    /**
+     * <p>Number of slides with notes.</p>
+     */
+    public static final int PID_NOTECOUNT = 8;
+
+    /**
+     * <p>Number of hidden slides.</p>
+     */
+    public static final int PID_HIDDENCOUNT = 9;
+
+    /**
+     * <p>Number of multimedia clips, e.g. sound or video.</p>
+     */
+    public static final int PID_MMCLIPCOUNT = 10;
+
+    /**
+     * <p>This entry is set to -1 when scaling of the thumbnail is
+     * desired. Otherwise the thumbnail should be cropped.</p>
+     */
+    public static final int PID_SCALE = 11;
+
+    /**
+     * <p>This entry denotes an internally used property. It is a
+     * vector of variants consisting of pairs of a string (VT_LPSTR)
+     * and a number (VT_I4). The string is a heading name, and the
+     * number tells how many document parts are under that
+     * heading.</p>
+     */
+    public static final int PID_HEADINGPAIR = 12;
+
+    /**
+     * <p>This entry contains the names of document parts (word: names
+     * of the documents in the master document, excel: sheet names,
+     * power point: slide titles, binder: document names).</p>
+     */
+    public static final int PID_DOCPARTS = 13;
+
+    /**
+     * <p>This entry contains the name of the project manager.</p>
+     */
+    public static final int PID_MANAGER = 14;
+
+    /**
+     * <p>This entry contains the company name.</p>
+     */
+    public static final int PID_COMPANY = 15;
+
+    /**
+     * <p>If this entry is -1 the links are dirty and should be
+     * re-evaluated.</p>
+     */
+    public static final int PID_LINKSDIRTY = 16;
+
+    /**
+     * <p>Contains the summary information property ID values and
+     * associated strings. See the overall HPSF documentation for
+     * details!</p>
+     */
+    private static PropertyIDMap summaryInformationProperties;
+
+    /**
+     * <p>Contains the summary information property ID values and
+     * associated strings. See the overall HPSF documentation for
+     * details!</p>
+     */
+    private static PropertyIDMap documentSummaryInformationProperties;
+
+
+
+    /**
+     * <p>Creates a {@link PropertyIDMap}.</p>
+     *
+     * @param initialCapacity The initial capacity as defined for
+     * {@link HashMap}
+     * @param loadFactor The load factor as defined for {@link HashMap}
+     */
+    public PropertyIDMap(final int initialCapacity, final float loadFactor)
+    {
+        super(initialCapacity, loadFactor);
+    }
+
+
+
+    /**
+     * <p>Creates a {@link PropertyIDMap} backed by another map.</p>
+     *
+     * @param map The instance to be created is backed by this map.
+     */
+    public PropertyIDMap(final Map<Integer, String> map)
+    {
+        super(map);
+    }
+
+
+
+    /**
+     * <p>Puts a ID string for an ID into the {@link
+     * PropertyIDMap}.</p>
+     *
+     * @param id The ID.
+     * @param idString The ID string.
+     * @return As specified by the {@link java.util.Map} interface, this method
+     * returns the previous value associated with the specified
+     * <var>id</var>, or <code>null</code> if there was no mapping for
+     * key.
+     */
+    public Object put(final long id, final String idString)
+    {
+        return put(Long.valueOf(id), idString);
+    }
+
+
+
+
+
+
+    /**
+     * @return the Summary Information properties singleton
+     */
+    public static PropertyIDMap getSummaryInformationProperties()
+    {
+        if (summaryInformationProperties == null)
+        {
+            PropertyIDMap m = new PropertyIDMap(18, (float) 1.0);
+            m.put(PID_TITLE, "PID_TITLE");
+            m.put(PID_SUBJECT, "PID_SUBJECT");
+            m.put(PID_AUTHOR, "PID_AUTHOR");
+            m.put(PID_KEYWORDS, "PID_KEYWORDS");
+            m.put(PID_COMMENTS, "PID_COMMENTS");
+            m.put(PID_TEMPLATE, "PID_TEMPLATE");
+            m.put(PID_LASTAUTHOR, "PID_LASTAUTHOR");
+            m.put(PID_REVNUMBER, "PID_REVNUMBER");
+            m.put(PID_EDITTIME, "PID_EDITTIME");
+            m.put(PID_LASTPRINTED, "PID_LASTPRINTED");
+            m.put(PID_CREATE_DTM, "PID_CREATE_DTM");
+            m.put(PID_LASTSAVE_DTM, "PID_LASTSAVE_DTM");
+            m.put(PID_PAGECOUNT, "PID_PAGECOUNT");
+            m.put(PID_WORDCOUNT, "PID_WORDCOUNT");
+            m.put(PID_CHARCOUNT, "PID_CHARCOUNT");
+            m.put(PID_THUMBNAIL, "PID_THUMBNAIL");
+            m.put(PID_APPNAME, "PID_APPNAME");
+            m.put(PID_SECURITY, "PID_SECURITY");
+            summaryInformationProperties =
+                new PropertyIDMap(Collections.unmodifiableMap(m));
+        }
+        return summaryInformationProperties;
+    }
+
+
+
+    /**
+     * <p>Returns the Document Summary Information properties
+     * singleton.</p>
+     *
+     * @return The Document Summary Information properties singleton.
+     */
+    public static PropertyIDMap getDocumentSummaryInformationProperties()
+    {
+        if (documentSummaryInformationProperties == null)
+        {
+            PropertyIDMap m = new PropertyIDMap(17, (float) 1.0);
+            m.put(PID_DICTIONARY, "PID_DICTIONARY");
+            m.put(PID_CODEPAGE, "PID_CODEPAGE");
+            m.put(PID_CATEGORY, "PID_CATEGORY");
+            m.put(PID_PRESFORMAT, "PID_PRESFORMAT");
+            m.put(PID_BYTECOUNT, "PID_BYTECOUNT");
+            m.put(PID_LINECOUNT, "PID_LINECOUNT");
+            m.put(PID_PARCOUNT, "PID_PARCOUNT");
+            m.put(PID_SLIDECOUNT, "PID_SLIDECOUNT");
+            m.put(PID_NOTECOUNT, "PID_NOTECOUNT");
+            m.put(PID_HIDDENCOUNT, "PID_HIDDENCOUNT");
+            m.put(PID_MMCLIPCOUNT, "PID_MMCLIPCOUNT");
+            m.put(PID_SCALE, "PID_SCALE");
+            m.put(PID_HEADINGPAIR, "PID_HEADINGPAIR");
+            m.put(PID_DOCPARTS, "PID_DOCPARTS");
+            m.put(PID_MANAGER, "PID_MANAGER");
+            m.put(PID_COMPANY, "PID_COMPANY");
+            m.put(PID_LINKSDIRTY, "PID_LINKSDIRTY");
+            documentSummaryInformationProperties =
+                new PropertyIDMap(Collections.unmodifiableMap(m));
+        }
+        return documentSummaryInformationProperties;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/wellknown/SectionIDMap.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/wellknown/SectionIDMap.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/wellknown/SectionIDMap.java	(revision 28000)
@@ -0,0 +1,70 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hpsf.wellknown;
+
+
+/**
+ * <p>Maps section format IDs to {@link PropertyIDMap}s. It is
+ * initialized with two well-known section format IDs: those of the
+ * <tt>\005SummaryInformation</tt> stream and the
+ * <tt>\005DocumentSummaryInformation</tt> stream.</p>
+ *
+ * <p>If you have a section format ID you can use it as a key to query
+ * this map.  If you get a {@link PropertyIDMap} returned your section
+ * is well-known and you can query the {@link PropertyIDMap} for PID
+ * strings. If you get back <code>null</code> you are on your own.</p>
+ *
+ * <p>This {@link java.util.Map} expects the byte arrays of section format IDs
+ * as keys. A key maps to a {@link PropertyIDMap} describing the
+ * property IDs in sections with the specified section format ID.</p>
+ *
+ * @author Rainer Klute (klute@rainer-klute.de)
+ */
+public class SectionIDMap {
+
+    /**
+     * <p>The SummaryInformation's section's format ID.</p>
+     */
+    public static final byte[] SUMMARY_INFORMATION_ID = new byte[]
+    {
+        (byte) 0xF2, (byte) 0x9F, (byte) 0x85, (byte) 0xE0,
+        (byte) 0x4F, (byte) 0xF9, (byte) 0x10, (byte) 0x68,
+        (byte) 0xAB, (byte) 0x91, (byte) 0x08, (byte) 0x00,
+        (byte) 0x2B, (byte) 0x27, (byte) 0xB3, (byte) 0xD9
+    };
+
+    /**
+     * <p>The DocumentSummaryInformation's first and second sections' format
+     * ID.</p>
+     */
+    public static final byte[][] DOCUMENT_SUMMARY_INFORMATION_ID = new byte[][]
+    {
+        {
+            (byte) 0xD5, (byte) 0xCD, (byte) 0xD5, (byte) 0x02,
+            (byte) 0x2E, (byte) 0x9C, (byte) 0x10, (byte) 0x1B,
+            (byte) 0x93, (byte) 0x97, (byte) 0x08, (byte) 0x00,
+            (byte) 0x2B, (byte) 0x2C, (byte) 0xF9, (byte) 0xAE
+        },
+        {
+            (byte) 0xD5, (byte) 0xCD, (byte) 0xD5, (byte) 0x05,
+            (byte) 0x2E, (byte) 0x9C, (byte) 0x10, (byte) 0x1B,
+            (byte) 0x93, (byte) 0x97, (byte) 0x08, (byte) 0x00,
+            (byte) 0x2B, (byte) 0x2C, (byte) 0xF9, (byte) 0xAE
+        }
+    };
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/wellknown/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/wellknown/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hpsf/wellknown/package.html	(revision 28000)
@@ -0,0 +1,59 @@
+<!doctype html public "-//W3C//DTD HTML 4.0//EN//">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+ <head>
+  <title></title>
+ </head>
+
+ <body>
+  <div>
+   Specific support for DocumentSummaryInformation, SummaryInformation types.
+   <p>Support classes for "well-known" section format IDs and property IDs. The
+    streams <tt>\005DocumentSummaryInformation</tt> and
+    <tt>\005SummaryInformation</tt> (or any streams with the same section
+    format IDs as the aforementioned) are considered well-known. So are most
+    property IDs in these streams.</p>
+
+   <p>
+    @author Rainer Klute (klute@rainer-klute.de)
+   </p>
+  </div>
+
+ </body>
+</html>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+sgml-default-dtd-file:"HTML_4.0_Strict.ced"
+mode: html
+sgml-omittag:t
+sgml-shorttag:nil
+sgml-namecase-general:t
+sgml-general-insert-case:lower
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:1
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/OldExcelFormatException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/OldExcelFormatException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/OldExcelFormatException.java	(revision 28000)
@@ -0,0 +1,26 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf;
+
+import org.apache.poi.OldFileFormatException;
+
+@SuppressWarnings("serial")
+public class OldExcelFormatException extends OldFileFormatException {
+	public OldExcelFormatException(String s) {
+		super(s);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/HSSFFormulaParser.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/HSSFFormulaParser.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/HSSFFormulaParser.java	(revision 28000)
@@ -0,0 +1,46 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.model;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.formula.FormulaRenderer;
+
+/**
+ * HSSF wrapper for the {@link FormulaParser} and {@link FormulaRenderer}
+ *
+ * @author Josh Micich
+ */
+public final class HSSFFormulaParser {
+
+	private HSSFFormulaParser() {
+		// no instances of this class
+	}
+
+	/**
+	 * Static method to convert an array of {@link Ptg}s in RPN order
+	 * to a human readable string format in infix mode.
+	 * @param book  used for defined names and 3D references
+	 * @param ptgs  must not be <code>null</code>
+	 * @return a human readable String
+	 */
+	public static String toFormulaString(HSSFWorkbook book, Ptg[] ptgs) {
+		return FormulaRenderer.toFormulaString(HSSFEvaluationWorkbook.create(book), ptgs);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/InternalSheet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/InternalSheet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/InternalSheet.java	(revision 28000)
@@ -0,0 +1,618 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.hssf.record.BOFRecord;
+import org.apache.poi.hssf.record.CalcCountRecord;
+import org.apache.poi.hssf.record.CalcModeRecord;
+import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.ColumnInfoRecord;
+import org.apache.poi.hssf.record.DVALRecord;
+import org.apache.poi.hssf.record.DeltaRecord;
+import org.apache.poi.hssf.record.DimensionsRecord;
+import org.apache.poi.hssf.record.EOFRecord;
+import org.apache.poi.hssf.record.FeatHdrRecord;
+import org.apache.poi.hssf.record.FeatRecord;
+import org.apache.poi.hssf.record.GridsetRecord;
+import org.apache.poi.hssf.record.GutsRecord;
+import org.apache.poi.hssf.record.IndexRecord;
+import org.apache.poi.hssf.record.IterationRecord;
+import org.apache.poi.hssf.record.MergeCellsRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordBase;
+import org.apache.poi.hssf.record.RefModeRecord;
+import org.apache.poi.hssf.record.RowRecord;
+import org.apache.poi.hssf.record.SaveRecalcRecord;
+import org.apache.poi.hssf.record.SelectionRecord;
+import org.apache.poi.hssf.record.UncalcedRecord;
+import org.apache.poi.hssf.record.WSBoolRecord;
+import org.apache.poi.hssf.record.WindowTwoRecord;
+import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
+import org.apache.poi.hssf.record.aggregates.DataValidityTable;
+import org.apache.poi.hssf.record.aggregates.MergedCellsTable;
+import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
+import org.apache.poi.util.Internal;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * Low level model implementation of a Sheet (one workbook contains many sheets)
+ * This file contains the low level binary records starting at the sheets BOF and
+ * ending with the sheets EOF.  Use HSSFSheet for a high level representation.
+ * <P>
+ * The structures of the highlevel API use references to this to perform most of their
+ * operations.  Its probably unwise to use these low level structures directly unless you
+ * really know what you're doing.  I recommend you read the Microsoft Excel 97 Developer's
+ * Kit (Microsoft Press) and the documentation at http://sc.openoffice.org/excelfileformat.pdf
+ * before even attempting to use this.
+ * <P>
+ * @author  Andrew C. Oliver (acoliver at apache dot org)
+ * @author  Glen Stampoultzis (glens at apache.org)
+ * @author  Shawn Laubach (slaubach at apache dot org) Gridlines, Headers, Footers, PrintSetup, and Setting Default Column Styles
+ * @author Jason Height (jheight at chariot dot net dot au) Clone support. DBCell & Index Record writing support
+ * @author  Brian Sanders (kestrel at burdell dot org) Active Cell support
+ * @author  Jean-Pierre Paris (jean-pierre.paris at m4x dot org) (Just a little)
+ *
+ * @see org.apache.poi.hssf.model.InternalWorkbook
+ * @see org.apache.poi.hssf.usermodel.HSSFSheet
+ */
+@Internal
+public final class InternalSheet {
+
+    private static POILogger            log              = POILogFactory.getLogger(InternalSheet.class);
+
+    private List<RecordBase>             _records;
+    protected GridsetRecord              gridset           =     null;
+    private   GutsRecord                 _gutsRecord;
+    protected WindowTwoRecord            windowTwo         =     null;
+    protected SelectionRecord            _selection         =     null;
+    /** java object always present, but if empty no BIFF records are written */
+    private final MergedCellsTable       _mergedCellsTable;
+    /** always present in this POI object, not always written to Excel file */
+    /*package*/ColumnInfoRecordsAggregate _columnInfos;
+    /** the DimensionsRecord is always present */
+    private DimensionsRecord             _dimensions;
+    /** always present */
+    protected final RowRecordsAggregate  _rowsAggregate;
+    private   DataValidityTable          _dataValidityTable=     null;
+    private   Iterator<RowRecord>        rowRecIterator    =     null;
+
+    /**
+     * read support  (offset used as starting point for search) for low level
+     * API.  Pass in an array of Record objects, the sheet number (0 based) and
+     * a record offset (should be the location of the sheets BOF record).  A Sheet
+     * object is constructed and passed back with all of its initialization set
+     * to the passed in records and references to those records held. This function
+     * is normally called via Workbook.
+     *
+     * @param rs the stream to read records from
+     *
+     * @return Sheet object with all values set to those read from the file
+     *
+     * @see org.apache.poi.hssf.model.InternalWorkbook
+     * @see org.apache.poi.hssf.record.Record
+     */
+    public static InternalSheet createSheet(RecordStream rs) {
+        return new InternalSheet(rs);
+    }
+    private InternalSheet(RecordStream rs) {
+        _mergedCellsTable = new MergedCellsTable();
+        RowRecordsAggregate rra = null;
+
+        List<RecordBase> records = new ArrayList<RecordBase>(128);
+        _records = records; // needed here due to calls to findFirstRecordLocBySid before we're done
+        int dimsloc = -1;
+
+        if (rs.peekNextSid() != BOFRecord.sid) {
+            throw new RuntimeException("BOF record expected");
+        }
+        BOFRecord bof = (BOFRecord) rs.getNext();
+        if (bof.getType() != BOFRecord.TYPE_WORKSHEET) {
+            // TODO - fix junit tests throw new RuntimeException("Bad BOF record type");
+        }
+        records.add(bof);
+        while (rs.hasNext()) {
+            int recSid = rs.peekNextSid();
+
+            if (recSid == ColumnInfoRecord.sid) {
+                _columnInfos = new ColumnInfoRecordsAggregate(rs);
+                records.add(_columnInfos);
+                continue;
+            }
+            if ( recSid == DVALRecord.sid) {
+                _dataValidityTable = new DataValidityTable(rs);
+                records.add(_dataValidityTable);
+                continue;
+            }
+
+            if (RecordOrderer.isRowBlockRecord(recSid)) {
+                //only add the aggregate once
+                if (rra != null) {
+                    throw new RuntimeException("row/cell records found in the wrong place");
+                }
+                RowBlocksReader rbr = new RowBlocksReader(rs);
+                _mergedCellsTable.addRecords(rbr.getLooseMergedCells());
+                rra = new RowRecordsAggregate(rbr.getPlainRecordStream(), rbr.getSharedFormulaManager());
+                records.add(rra); //only add the aggregate once
+                continue;
+            }
+
+            if (recSid == MergeCellsRecord.sid) {
+                // when the MergedCellsTable is found in the right place, we expect those records to be contiguous
+                _mergedCellsTable.read(rs);
+                continue;
+            }
+
+            if (recSid == BOFRecord.sid) {
+                continue;
+            }
+
+            Record rec = rs.getNext();
+            if ( recSid == IndexRecord.sid ) {
+                // ignore INDEX record because it is only needed by Excel,
+                // and POI always re-calculates its contents
+                continue;
+            }
+
+
+            if (recSid == UncalcedRecord.sid) {
+                // don't add UncalcedRecord to the list
+                continue;
+            }
+
+            if (recSid == FeatRecord.sid ||
+            		recSid == FeatHdrRecord.sid) {
+                records.add(rec);
+                continue;
+            }
+            
+            if (recSid == EOFRecord.sid) {
+                records.add(rec);
+                break;
+            }
+
+            if (recSid == DimensionsRecord.sid)
+            {
+                // Make a columns aggregate if one hasn't ready been created.
+                if (_columnInfos == null)
+                {
+                    _columnInfos = new ColumnInfoRecordsAggregate();
+                    records.add(_columnInfos);
+                }
+
+                _dimensions    = ( DimensionsRecord ) rec;
+                dimsloc = records.size();
+            }
+            else if ( recSid == GridsetRecord.sid )
+            {
+                gridset = (GridsetRecord) rec;
+            }
+            else if ( recSid == SelectionRecord.sid )
+            {
+                _selection = (SelectionRecord) rec;
+            }
+            else if ( recSid == WindowTwoRecord.sid )
+            {
+                windowTwo = (WindowTwoRecord) rec;
+            }
+            else if ( recSid == GutsRecord.sid )
+            {
+                _gutsRecord = (GutsRecord) rec;
+            }
+
+            records.add(rec);
+        }
+        if (windowTwo == null) {
+            throw new RuntimeException("WINDOW2 was not found");
+        }
+        if (_dimensions == null) {
+            // Excel seems to always write the DIMENSION record, but tolerates when it is not present
+            // in all cases Excel (2007) adds the missing DIMENSION record
+            if (rra == null) {
+                // bug 46206 alludes to files which skip the DIMENSION record
+                // when there are no row/cell records.
+                // Not clear which application wrote these files.
+                rra = new RowRecordsAggregate();
+            } else {
+                log.log(POILogger.WARN, "DIMENSION record not found even though row/cells present");
+                // Not sure if any tools write files like this, but Excel reads them OK
+            }
+            dimsloc = findFirstRecordLocBySid(WindowTwoRecord.sid);
+            _dimensions = rra.createDimensions();
+            records.add(dimsloc, _dimensions);
+        }
+        if (rra == null) {
+            rra = new RowRecordsAggregate();
+            records.add(dimsloc + 1, rra);
+        }
+        _rowsAggregate = rra;
+        // put merged cells table in the right place (regardless of where the first MergedCellsRecord was found */
+        RecordOrderer.addNewSheetRecord(records, _mergedCellsTable);
+        if (log.check( POILogger.DEBUG ))
+            log.log(POILogger.DEBUG, "sheet createSheet (existing file) exited");
+    }
+
+    private InternalSheet() {
+        _mergedCellsTable = new MergedCellsTable();
+        List<RecordBase> records = new ArrayList<RecordBase>(32);
+
+        if (log.check( POILogger.DEBUG ))
+            log.log(POILogger.DEBUG, "Sheet createsheet from scratch called");
+
+        records.add(createBOF());
+
+        records.add(createCalcMode());
+        records.add(createCalcCount() );
+        records.add(createRefMode() );
+        records.add(createIteration() );
+        records.add(createDelta() );
+        records.add(createSaveRecalc() );
+        gridset = createGridset();
+        records.add( gridset );
+        _gutsRecord = createGuts();
+        records.add( _gutsRecord );
+        records.add( createWSBool() );
+
+        ColumnInfoRecordsAggregate columns = new ColumnInfoRecordsAggregate();
+        records.add( columns );
+        _columnInfos = columns;
+        _dimensions = createDimensions();
+        records.add(_dimensions);
+        _rowsAggregate = new RowRecordsAggregate();
+        records.add(_rowsAggregate);
+        // 'Sheet View Settings'
+        records.add(windowTwo = createWindowTwo());
+        _selection = createSelection();
+        records.add(_selection);
+
+        records.add(_mergedCellsTable); // MCT comes after 'Sheet View Settings'
+        records.add(EOFRecord.instance);
+
+        _records = records;
+        if (log.check( POILogger.DEBUG ))
+            log.log(POILogger.DEBUG, "Sheet createsheet from scratch exit");
+    }
+
+    public RowRecordsAggregate getRowsAggregate() {
+        return _rowsAggregate;
+    }
+
+    /**
+     * Adds a value record to the sheet's contained binary records
+     * (i.e. LabelSSTRecord or NumberRecord).
+     * <P>
+     * This method is "loc" sensitive.  Meaning you need to set LOC to where you
+     * want it to start searching.  If you don't know do this: setLoc(getDimsLoc).
+     * When adding several rows you can just start at the last one by leaving loc
+     * at what this sets it to.
+     *
+     * @param row the row to add the cell value to
+     * @param col the cell value record itself.
+     */
+    public void addValueRecord(int row, CellValueRecordInterface col) {
+
+        if(log.check(POILogger.DEBUG)) {
+          log.log(POILogger.DEBUG, "add value record  row" + row);
+        }
+        DimensionsRecord d = _dimensions;
+
+        if (col.getColumn() > d.getLastCol()) {
+            d.setLastCol(( short ) (col.getColumn() + 1));
+        }
+        if (col.getColumn() < d.getFirstCol()) {
+            d.setFirstCol(col.getColumn());
+        }
+        _rowsAggregate.insertCell(col);
+    }
+
+    /**
+     * replace a value record from the records array.
+     *
+     * This method is not loc sensitive, it resets loc to = dimsloc so no worries.
+     *
+     * @param newval - a record supporting the CellValueRecordInterface.  this will replace
+     *                the cell value with the same row and column.  If there isn't one, one will
+     *                be added.
+     */
+
+    public void replaceValueRecord(CellValueRecordInterface newval) {
+
+        if (log.check( POILogger.DEBUG ))
+            log.log(POILogger.DEBUG, "replaceValueRecord ");
+        //The ValueRecordsAggregate use a tree map underneath.
+        //The tree Map uses the CellValueRecordInterface as both the
+        //key and the value, if we dont do a remove, then
+        //the previous instance of the key is retained, effectively using
+        //double the memory
+        _rowsAggregate.removeCell(newval);
+        _rowsAggregate.insertCell(newval);
+    }
+
+    /**
+     * Adds a row record to the sheet
+     *
+     * <P>
+     * This method is "loc" sensitive.  Meaning you need to set LOC to where you
+     * want it to start searching.  If you don't know do this: setLoc(getDimsLoc).
+     * When adding several rows you can just start at the last one by leaving loc
+     * at what this sets it to.
+     *
+     * @param row the row record to be added
+     */
+
+    public void addRow(RowRecord row) {
+        if (log.check( POILogger.DEBUG ))
+            log.log(POILogger.DEBUG, "addRow ");
+        DimensionsRecord d = _dimensions;
+
+        if (row.getRowNumber() >= d.getLastRow()) {
+            d.setLastRow(row.getRowNumber() + 1);
+        }
+        if (row.getRowNumber() < d.getFirstRow()) {
+            d.setFirstRow(row.getRowNumber());
+        }
+
+        //If the row exists remove it, so that any cells attached to the row are removed
+        RowRecord existingRow = _rowsAggregate.getRow(row.getRowNumber());
+        if (existingRow != null) {
+            _rowsAggregate.removeRow(existingRow);
+        }
+
+        _rowsAggregate.insertRow(row);
+
+        if (log.check( POILogger.DEBUG ))
+            log.log(POILogger.DEBUG, "exit addRow");
+    }
+
+
+    /**
+     * get the NEXT value record (from LOC).  The first record that is a value record
+     * (starting at LOC) will be returned.
+     *
+     * <P>
+     * This method is "loc" sensitive.  Meaning you need to set LOC to where you
+     * want it to start searching.  If you don't know do this: setLoc(getDimsLoc).
+     * When adding several rows you can just start at the last one by leaving loc
+     * at what this sets it to.  For this method, set loc to dimsloc to start with,
+     * subsequent calls will return values in (physical) sequence or NULL when you get to the end.
+     *
+     * @return CellValueRecordInterface representing the next value record or NULL if there are no more
+     */
+    public CellValueRecordInterface[] getValueRecords() {
+        return _rowsAggregate.getValueRecords();
+    }
+
+    /**
+     * get the NEXT RowRecord (from LOC).  The first record that is a Row record
+     * (starting at LOC) will be returned.
+     * <P>
+     * This method is "loc" sensitive.  Meaning you need to set LOC to where you
+     * want it to start searching.  If you don't know do this: setLoc(getDimsLoc).
+     * When adding several rows you can just start at the last one by leaving loc
+     * at what this sets it to.  For this method, set loc to dimsloc to start with.
+     * subsequent calls will return rows in (physical) sequence or NULL when you get to the end.
+     *
+     * @return RowRecord representing the next row record or NULL if there are no more
+     */
+    public RowRecord getNextRow() {
+        if (rowRecIterator == null)
+        {
+            rowRecIterator = _rowsAggregate.getIterator();
+        }
+        if (!rowRecIterator.hasNext())
+        {
+            return null;
+        }
+        return rowRecIterator.next();
+    }
+
+
+    /**
+     * creates the BOF record
+     */
+    /* package */ static BOFRecord createBOF() {
+        BOFRecord retval = new BOFRecord();
+
+        retval.setVersion(( short ) 0x600);
+        retval.setType(( short ) 0x010);
+
+        retval.setBuild(( short ) 0x0dbb);
+        retval.setBuildYear(( short ) 1996);
+        retval.setHistoryBitMask(0xc1);
+        retval.setRequiredVersion(0x6);
+        return retval;
+    }
+
+    /**
+     * creates the CalcMode record and sets it to 1 (automatic formula caculation)
+     */
+    private static CalcModeRecord createCalcMode() {
+        CalcModeRecord retval = new CalcModeRecord();
+
+        retval.setCalcMode(( short ) 1);
+        return retval;
+    }
+
+    /**
+     * creates the CalcCount record and sets it to 100 (default number of iterations)
+     */
+    private static CalcCountRecord createCalcCount() {
+        CalcCountRecord retval = new CalcCountRecord();
+
+        retval.setIterations(( short ) 100);   // default 100 iterations
+        return retval;
+    }
+
+    /**
+     * creates the RefMode record and sets it to A1 Mode (default reference mode)
+     */
+    private static RefModeRecord createRefMode() {
+        RefModeRecord retval = new RefModeRecord();
+
+        retval.setMode(RefModeRecord.USE_A1_MODE);
+        return retval;
+    }
+
+    /**
+     * creates the Iteration record and sets it to false (don't iteratively calculate formulas)
+     */
+    private static IterationRecord createIteration() {
+        return new IterationRecord(false);
+    }
+
+    /**
+     * creates the Delta record and sets it to 0.0010 (default accuracy)
+     */
+    private static DeltaRecord createDelta() {
+        return new DeltaRecord(DeltaRecord.DEFAULT_VALUE);
+    }
+
+    /**
+     * creates the SaveRecalc record and sets it to true (recalculate before saving)
+     */
+    private static SaveRecalcRecord createSaveRecalc() {
+        SaveRecalcRecord retval = new SaveRecalcRecord();
+
+        retval.setRecalc(true);
+        return retval;
+    }
+
+    /**
+     * creates the Gridset record and sets it to true (user has mucked with the gridlines)
+     */
+    private static GridsetRecord createGridset() {
+        GridsetRecord retval = new GridsetRecord();
+
+        retval.setGridset(true);
+        return retval;
+    }
+
+    /**
+     * creates the Guts record and sets leftrow/topcol guttter and rowlevelmax/collevelmax to 0
+      */
+    private static GutsRecord createGuts() {
+        GutsRecord retval = new GutsRecord();
+
+        retval.setLeftRowGutter(( short ) 0);
+        retval.setTopColGutter(( short ) 0);
+        retval.setRowLevelMax(( short ) 0);
+        retval.setColLevelMax(( short ) 0);
+        return retval;
+    }
+
+    /**
+     * creates the WSBoolRecord and sets its values to defaults
+     */
+    private static WSBoolRecord createWSBool() {
+        WSBoolRecord retval = new WSBoolRecord();
+
+        retval.setWSBool1(( byte ) 0x4);
+        retval.setWSBool2(( byte ) 0xffffffc1);
+        return retval;
+    }
+
+    /**
+     * get the index to the ExtendedFormatRecord "associated" with
+     * the column at specified 0-based index. (In this case, an
+     * ExtendedFormatRecord index is actually associated with a
+     * ColumnInfoRecord which spans 1 or more columns)
+     * <br/>
+     * Returns the index to the default ExtendedFormatRecord (0xF)
+     * if no ColumnInfoRecord exists that includes the column
+     * index specified.
+     * @param columnIndex
+     * @return index of ExtendedFormatRecord associated with
+     * ColumnInfoRecord that includes the column index or the
+     * index of the default ExtendedFormatRecord (0xF)
+     */
+    public short getXFIndexForColAt(short columnIndex) {
+        ColumnInfoRecord ci = _columnInfos.findColumnInfo(columnIndex);
+        if (ci != null) {
+            return (short)ci.getXFIndex();
+        }
+        return 0xF;
+    }
+
+    /**
+     * creates the Dimensions Record and sets it to bogus values (you should set this yourself
+     * or let the high level API do it for you)
+     */
+    private static DimensionsRecord createDimensions() {
+        DimensionsRecord retval = new DimensionsRecord();
+
+        retval.setFirstCol(( short ) 0);
+        retval.setLastRow(1);             // one more than it is
+        retval.setFirstRow(0);
+        retval.setLastCol(( short ) 1);   // one more than it is
+        return retval;
+    }
+
+    /**
+     * creates the WindowTwo Record and sets it to:  <P>
+     * options        = 0x6b6 <P>
+     * toprow         = 0 <P>
+     * leftcol        = 0 <P>
+     * headercolor    = 0x40 <P>
+     * pagebreakzoom  = 0x0 <P>
+     * normalzoom     = 0x0 <p>
+     */
+    private static WindowTwoRecord createWindowTwo() {
+        WindowTwoRecord retval = new WindowTwoRecord();
+
+        retval.setOptions(( short ) 0x6b6);
+        retval.setTopRow(( short ) 0);
+        retval.setLeftCol(( short ) 0);
+        retval.setHeaderColor(0x40);
+        retval.setPageBreakZoom(( short ) 0);
+        retval.setNormalZoom(( short ) 0);
+        return retval;
+    }
+
+    /**
+     * Creates the Selection record and sets it to nothing selected
+    */
+    private static SelectionRecord createSelection() {
+        return new SelectionRecord(0, 0);
+    }
+
+    /**
+     * Finds the first occurrence of a record matching a particular sid and
+     * returns it's position.
+     * @param sid   the sid to search for
+     * @return  the record position of the matching record or -1 if no match
+     *          is made.
+     */
+    public int findFirstRecordLocBySid( short sid ) { // TODO - remove this method
+        int max = _records.size();
+        for (int i=0; i< max; i++) {
+            Object rb = _records.get(i);
+            if (!(rb instanceof Record)) {
+                continue;
+            }
+            Record record = (Record) rb;
+            if (record.getSid() == sid) {
+                return i;
+            }
+        }
+        return -1;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/InternalWorkbook.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/InternalWorkbook.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/InternalWorkbook.java	(revision 28000)
@@ -0,0 +1,467 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.model;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.poi.hssf.record.BoundSheetRecord;
+import org.apache.poi.hssf.record.DateWindow1904Record;
+import org.apache.poi.hssf.record.EOFRecord;
+import org.apache.poi.hssf.record.ExtSSTRecord;
+import org.apache.poi.hssf.record.ExtendedFormatRecord;
+import org.apache.poi.hssf.record.ExternSheetRecord;
+import org.apache.poi.hssf.record.FormatRecord;
+import org.apache.poi.hssf.record.HyperlinkRecord;
+import org.apache.poi.hssf.record.NameCommentRecord;
+import org.apache.poi.hssf.record.NameRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.SSTRecord;
+import org.apache.poi.hssf.record.SupBookRecord;
+import org.apache.poi.hssf.record.TabIdRecord;
+import org.apache.poi.hssf.record.WindowOneRecord;
+import org.apache.poi.hssf.record.common.UnicodeString;
+import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
+import org.apache.poi.util.Internal;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * Low level model implementation of a Workbook.  Provides creational methods
+ * for settings and objects contained in the workbook object.
+ * <P>
+ * This file contains the low level binary records starting at the workbook's BOF and
+ * ending with the workbook's EOF.  Use HSSFWorkbook for a high level representation.
+ * <P>
+ * The structures of the highlevel API use references to this to perform most of their
+ * operations.  Its probably unwise to use these low level structures directly unless you
+ * really know what you're doing.  I recommend you read the Microsoft Excel 97 Developer's
+ * Kit (Microsoft Press) and the documentation at http://sc.openoffice.org/excelfileformat.pdf
+ * before even attempting to use this.
+ *
+ *
+ * @author  Luc Girardin (luc dot girardin at macrofocus dot com)
+ * @author  Sergei Kozello (sergeikozello at mail.ru)
+ * @author  Shawn Laubach (slaubach at apache dot org) (Data Formats)
+ * @author  Andrew C. Oliver (acoliver at apache dot org)
+ * @author  Brian Sanders (bsanders at risklabs dot com) - custom palette
+ * @author  Dan Sherman (dsherman at isisph.com)
+ * @author  Glen Stampoultzis (glens at apache.org)
+ * @see org.apache.poi.hssf.usermodel.HSSFWorkbook
+ */
+@Internal
+public final class InternalWorkbook {
+
+
+    private static final POILogger log = POILogFactory.getLogger(InternalWorkbook.class);
+    private static final int DEBUG = POILogger.DEBUG;
+
+    /**
+     * this contains the Worksheet record objects
+     */
+    private final WorkbookRecordList records;
+
+    /**
+     * this contains a reference to the SSTRecord so that new stings can be added
+     * to it.
+     */
+    protected SSTRecord sst;
+
+
+    private LinkTable linkTable; // optionally occurs if there are  references in the document. (4.10.3)
+
+    /**
+     * holds the "boundsheet" records (aka bundlesheet) so that they can have their
+     * reference to their "BOF" marker
+     */
+    private final List<BoundSheetRecord> boundsheets;
+    private final List<FormatRecord> formats;
+    private final List<HyperlinkRecord> hyperlinks;
+
+    /** the number of extended format records */
+	private int numxfs;
+    /** holds the max format id */
+	private int maxformatid;
+    /** whether 1904 date windowing is being used */
+    private boolean uses1904datewindowing;
+    private WindowOneRecord windowOne;
+
+    /**
+     * Hold the {@link NameCommentRecord}s indexed by the name of the {@link NameRecord} to which they apply.
+     */
+    private final Map<String, NameCommentRecord> commentRecords;
+
+    private InternalWorkbook() {
+    	records     = new WorkbookRecordList();
+
+		boundsheets = new ArrayList<BoundSheetRecord>();
+		formats = new ArrayList<FormatRecord>();
+		hyperlinks = new ArrayList<HyperlinkRecord>();
+		numxfs = 0;
+		maxformatid = -1;
+		uses1904datewindowing = false;
+		commentRecords = new LinkedHashMap<String, NameCommentRecord>();
+    }
+
+    /**
+     * read support  for low level
+     * API.  Pass in an array of Record objects, A Workbook
+     * object is constructed and passed back with all of its initialization set
+     * to the passed in records and references to those records held. Unlike Sheet
+     * workbook does not use an offset (its assumed to be 0) since its first in a file.
+     * If you need an offset then construct a new array with a 0 offset or write your
+     * own ;-p.
+     *
+     * @param recs an array of Record objects
+     * @return Workbook object
+     */
+    public static InternalWorkbook createWorkbook(List<Record> recs) {
+        if (log.check( POILogger.DEBUG ))
+            log.log(DEBUG, "Workbook (readfile) created with reclen=",
+                    Integer.valueOf(recs.size()));
+        InternalWorkbook retval = new InternalWorkbook();
+        List<Record> records = new ArrayList<Record>(recs.size() / 3);
+        retval.records.setRecords(records);
+
+        int k;
+        for (k = 0; k < recs.size(); k++) {
+            Record rec = recs.get(k);
+
+            if (rec.getSid() == EOFRecord.sid) {
+                records.add(rec);
+                if (log.check( POILogger.DEBUG ))
+                    log.log(DEBUG, "found workbook eof record at " + k);
+                break;
+            }
+            switch (rec.getSid()) {
+
+                case BoundSheetRecord.sid :
+                    if (log.check( POILogger.DEBUG ))
+                        log.log(DEBUG, "found boundsheet record at " + k);
+                    retval.boundsheets.add((BoundSheetRecord) rec);
+                    retval.records.setBspos( k );
+                    break;
+
+                case SSTRecord.sid :
+                    if (log.check( POILogger.DEBUG ))
+                        log.log(DEBUG, "found sst record at " + k);
+                    retval.sst = ( SSTRecord ) rec;
+                    break;
+
+                case ExtendedFormatRecord.sid :
+                    if (log.check( POILogger.DEBUG ))
+                        log.log(DEBUG, "found XF record at " + k);
+                    retval.records.setXfpos( k );
+                    retval.numxfs++;
+                    break;
+
+                case TabIdRecord.sid :
+                    if (log.check( POILogger.DEBUG ))
+                        log.log(DEBUG, "found tabid record at " + k);
+                    retval.records.setTabpos( k );
+                    break;
+
+                case ExternSheetRecord.sid :
+                    throw new RuntimeException("Extern sheet is part of LinkTable");
+                case NameRecord.sid :
+                case SupBookRecord.sid :
+                    // LinkTable can start with either of these
+                    if (log.check( POILogger.DEBUG ))
+                        log.log(DEBUG, "found SupBook record at " + k);
+                    retval.linkTable = new LinkTable(recs, k, retval.records, retval.commentRecords);
+                    k+=retval.linkTable.getRecordCount() - 1;
+                    continue;
+                case FormatRecord.sid :
+                    if (log.check( POILogger.DEBUG ))
+                        log.log(DEBUG, "found format record at " + k);
+                    retval.formats.add((FormatRecord) rec);
+                    retval.maxformatid = retval.maxformatid >= ((FormatRecord)rec).getIndexCode() ? retval.maxformatid : ((FormatRecord)rec).getIndexCode();
+                    break;
+                case DateWindow1904Record.sid :
+                    if (log.check( POILogger.DEBUG ))
+                        log.log(DEBUG, "found datewindow1904 record at " + k);
+                    retval.uses1904datewindowing = ((DateWindow1904Record)rec).getWindowing() == 1;
+                    break;
+                case WindowOneRecord.sid:
+                    if (log.check( POILogger.DEBUG ))
+                        log.log(DEBUG, "found WindowOneRecord at " + k);
+                    retval.windowOne = (WindowOneRecord) rec;
+                    break;
+                case NameCommentRecord.sid:
+                    final NameCommentRecord ncr = (NameCommentRecord) rec;
+                    if (log.check( POILogger.DEBUG ))
+                        log.log(DEBUG, "found NameComment at " + k);
+                    retval.commentRecords.put(ncr.getNameText(), ncr);
+                default :
+            }
+            records.add(rec);
+        }
+        //What if we dont have any ranges and supbooks
+        //        if (retval.records.supbookpos == 0) {
+        //            retval.records.supbookpos = retval.records.bspos + 1;
+        //            retval.records.namepos    = retval.records.supbookpos + 1;
+        //        }
+
+        // Look for other interesting values that
+        //  follow the EOFRecord
+        for ( ; k < recs.size(); k++) {
+            Record rec = recs.get(k);
+            switch (rec.getSid()) {
+                case HyperlinkRecord.sid:
+                    retval.hyperlinks.add((HyperlinkRecord)rec);
+                    break;
+            }
+        }
+
+        if (retval.windowOne == null) {
+            retval.windowOne = createWindowOne();
+        }
+        if (log.check( POILogger.DEBUG ))
+            log.log(DEBUG, "exit create workbook from existing file function");
+        return retval;
+    }
+
+    public int getNumRecords() {
+        return records.size();
+    }
+
+
+    private BoundSheetRecord getBoundSheetRec(int sheetIndex) {
+        return boundsheets.get(sheetIndex);
+    }
+
+
+    /**
+     * gets the name for a given sheet.
+     *
+     * @param sheetIndex the sheet number (0 based)
+     * @return sheetname the name for the sheet
+     */
+    public String getSheetName(int sheetIndex) {
+        return getBoundSheetRec(sheetIndex).getSheetname();
+    }
+
+    /**
+     * gets the ExtendedFormatRecord at the given 0-based index
+     *
+     * @param index of the Extended format record (0-based)
+     * @return ExtendedFormatRecord at the given index
+     */
+
+    public ExtendedFormatRecord getExFormatAt(int index) {
+        int xfptr = records.getXfpos() - (numxfs - 1);
+
+        xfptr += index;
+        ExtendedFormatRecord retval =
+        ( ExtendedFormatRecord ) records.get(xfptr);
+
+        return retval;
+    }
+
+    /**
+     * Adds a string to the SST table and returns its index (if its a duplicate
+     * just returns its index and update the counts) ASSUMES compressed unicode
+     * (meaning 8bit)
+     *
+     * @param string the string to be added to the SSTRecord
+     *
+     * @return index of the string within the SSTRecord
+     */
+
+    public int addSSTString(UnicodeString string) {
+        if (log.check( POILogger.DEBUG ))
+          log.log(DEBUG, "insert to sst string='", string);
+        if (sst == null) {
+            insertSST();
+        }
+      return sst.addString(string);
+    }
+
+    /**
+     * given an index into the SST table, this function returns the corresponding String value
+     * @return String containing the SST String
+     */
+
+    public UnicodeString getSSTString(int str) {
+        if (sst == null) {
+            insertSST();
+        }
+        UnicodeString retval = sst.getString(str);
+
+        if (log.check( POILogger.DEBUG ))
+            log.log(DEBUG, "Returning SST for index=", Integer.valueOf(str),
+                " String= ", retval);
+        return retval;
+    }
+
+    /**
+     * use this function to add a Shared String Table to an existing sheet (say
+     * generated by a different java api) without an sst....
+     * @see #createExtendedSST()
+     * @see org.apache.poi.hssf.record.SSTRecord
+     */
+
+    public void insertSST() {
+        if (log.check( POILogger.DEBUG ))
+            log.log(DEBUG, "creating new SST via insertSST!");
+        sst = new SSTRecord();
+        records.add(records.size() - 1, createExtendedSST());
+        records.add(records.size() - 2, sst);
+    }
+
+    /**
+     * Serializes all records int the worksheet section into a big byte array. Use
+     * this to write the Workbook out.
+     *
+     * @return byte array containing the HSSF-only portions of the POIFS file.
+     */
+     // GJS: Not used so why keep it.
+//    public byte [] serialize() {
+//        log.log(DEBUG, "Serializing Workbook!");
+//        byte[] retval    = null;
+//
+////         ArrayList bytes     = new ArrayList(records.size());
+//        int    arraysize = getSize();
+//        int    pos       = 0;
+//
+//        retval = new byte[ arraysize ];
+//        for (int k = 0; k < records.size(); k++) {
+//
+//            Record record = records.get(k);
+////             Let's skip RECALCID records, as they are only use for optimization
+//        if(record.getSid() != RecalcIdRecord.sid || ((RecalcIdRecord)record).isNeeded()) {
+//                pos += record.serialize(pos, retval);   // rec.length;
+//        }
+//        }
+//        log.log(DEBUG, "Exiting serialize workbook");
+//        return retval;
+//    }
+
+    /**
+     * creates the WindowOne record with the following magic values: <P>
+     * horizontal hold - 0x168 <P>
+     * vertical hold   - 0x10e <P>
+     * width           - 0x3a5c <P>
+     * height          - 0x23be <P>
+     * options         - 0x38 <P>
+     * selected tab    - 0 <P>
+     * displayed tab   - 0 <P>
+     * num selected tab- 0 <P>
+     * tab width ratio - 0x258 <P>
+     */
+    private static WindowOneRecord createWindowOne() {
+        WindowOneRecord retval = new WindowOneRecord();
+
+        retval.setHorizontalHold(( short ) 0x168);
+        retval.setVerticalHold(( short ) 0x10e);
+        retval.setWidth(( short ) 0x3a5c);
+        retval.setHeight(( short ) 0x23be);
+        retval.setOptions(( short ) 0x38);
+        retval.setActiveSheetIndex( 0x0);
+        retval.setFirstVisibleTab(0x0);
+        retval.setNumSelectedTabs(( short ) 1);
+        retval.setTabWidthRatio(( short ) 0x258);
+        return retval;
+    }
+
+    /**
+     * Creates the ExtendedSST record with numstrings per bucket set to 0x8.  HSSF
+     * doesn't yet know what to do with this thing, but we create it with nothing in
+     * it hardly just to make Excel happy and our sheets look like Excel's
+     */
+    private static ExtSSTRecord createExtendedSST() {
+        ExtSSTRecord retval = new ExtSSTRecord();
+        retval.setNumStringsPerBucket(( short ) 0x8);
+        return retval;
+    }
+
+    /** finds the sheet name by his extern sheet index
+     * @param externSheetIndex extern sheet index
+     * @return sheet name.
+     */
+    public String findSheetNameFromExternSheet(int externSheetIndex){
+
+        int indexToSheet = linkTable.getIndexToInternalSheet(externSheetIndex);
+        if (indexToSheet < 0) {
+            // TODO - what does '-1' mean here?
+            //error check, bail out gracefully!
+            return "";
+        }
+        if (indexToSheet >= boundsheets.size()) {
+            // Not sure if this can ever happen (See bug 45798)
+            return ""; // Seems to be what excel would do in this case
+        }
+        return getSheetName(indexToSheet);
+    }
+    public ExternalSheet getExternalSheet(int externSheetIndex) {
+        String[] extNames = linkTable.getExternalBookAndSheetName(externSheetIndex);
+        if (extNames == null) {
+            return null;
+        }
+        return new ExternalSheet(extNames[0], extNames[1]);
+    }
+
+    /** gets the total number of names
+     * @return number of names
+     */
+    public int getNumNames(){
+        if(linkTable == null) {
+            return 0;
+        }
+        return linkTable.getNumNames();
+    }
+
+    /** gets the name record
+     * @param index name index
+     * @return name record
+     */
+    public NameRecord getNameRecord(int index){
+        return linkTable.getNameRecord(index);
+    }
+
+
+
+    /**
+     * Returns the list of FormatRecords in the workbook.
+     * @return ArrayList of FormatRecords in the notebook
+     */
+    public List<FormatRecord> getFormats() {
+      return formats;
+    }
+
+    /**
+    * Whether date windowing is based on 1/2/1904 or 1/1/1900.
+    * Some versions of Excel (Mac) can save workbooks using 1904 date windowing.
+    *
+    * @return true if using 1904 date windowing
+    */
+    public boolean isUsing1904DateWindowing() {
+        return uses1904datewindowing;
+    }
+
+    /**
+     * @param refIndex Index to REF entry in EXTERNSHEET record in the Link Table
+     * @param definedNameIndex zero-based to DEFINEDNAME or EXTERNALNAME record
+     * @return the string representation of the defined or external name
+     */
+    public String resolveNameXText(int refIndex, int definedNameIndex) {
+        return linkTable.resolveNameXText(refIndex, definedNameIndex);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/LinkTable.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/LinkTable.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/LinkTable.java	(revision 28000)
@@ -0,0 +1,242 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.poi.hssf.record.CRNCountRecord;
+import org.apache.poi.hssf.record.CRNRecord;
+import org.apache.poi.hssf.record.ExternSheetRecord;
+import org.apache.poi.hssf.record.ExternalNameRecord;
+import org.apache.poi.hssf.record.NameCommentRecord;
+import org.apache.poi.hssf.record.NameRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.SupBookRecord;
+import org.apache.poi.hssf.record.formula.Area3DPtg;
+import org.apache.poi.hssf.record.formula.Ref3DPtg;
+
+/**
+ * Link Table (OOO pdf reference: 4.10.3 ) <p/>
+ *
+ * The main data of all types of references is stored in the Link Table inside the Workbook Globals
+ * Substream (4.2.5). The Link Table itself is optional and occurs only, if  there are any
+ * references in the document.
+ *  <p/>
+ *
+ *  In BIFF8 the Link Table consists of
+ *  <ul>
+ *  <li>zero or more EXTERNALBOOK Blocks<p/>
+ *  	each consisting of
+ *  	<ul>
+ *  	<li>exactly one EXTERNALBOOK (0x01AE) record</li>
+ *  	<li>zero or more EXTERNALNAME (0x0023) records</li>
+ *  	<li>zero or more CRN Blocks<p/>
+ *			each consisting of
+ *  		<ul>
+ *  		<li>exactly one XCT (0x0059)record</li>
+ *  		<li>zero or more CRN (0x005A) records (documentation says one or more)</li>
+ *  		</ul>
+ *  	</li>
+ *  	</ul>
+ *  </li>
+ *  <li>zero or one EXTERNSHEET (0x0017) record</li>
+ *  <li>zero or more DEFINEDNAME (0x0018) records</li>
+ *  </ul>
+ *
+ *
+ * @author Josh Micich
+ */
+final class LinkTable {
+
+
+	// TODO make this class into a record aggregate
+
+	private static final class CRNBlock {
+
+		private final CRNCountRecord _countRecord;
+
+		public CRNBlock(RecordStream rs) {
+			_countRecord = (CRNCountRecord) rs.getNext();
+			int nCRNs = _countRecord.getNumberOfCRNs();
+			CRNRecord[] crns = new CRNRecord[nCRNs];
+			for (int i = 0; i < crns.length; i++) {
+				crns[i] = (CRNRecord) rs.getNext();
+			}
+		}
+	}
+
+	private static final class ExternalBookBlock {
+		private final SupBookRecord _externalBookRecord;
+		private final ExternalNameRecord[] _externalNameRecords;
+		private final CRNBlock[] _crnBlocks;
+
+		public ExternalBookBlock(RecordStream rs) {
+			_externalBookRecord = (SupBookRecord) rs.getNext();
+			List<Object> temp = new ArrayList<Object>();
+			while(rs.peekNextClass() == ExternalNameRecord.class) {
+			   temp.add(rs.getNext());
+			}
+			_externalNameRecords = new ExternalNameRecord[temp.size()];
+			temp.toArray(_externalNameRecords);
+
+			temp.clear();
+
+			while(rs.peekNextClass() == CRNCountRecord.class) {
+				temp.add(new CRNBlock(rs));
+			}
+			_crnBlocks = new CRNBlock[temp.size()];
+			temp.toArray(_crnBlocks);
+		}
+
+		public SupBookRecord getExternalBookRecord() {
+			return _externalBookRecord;
+		}
+
+		public String getNameText(int definedNameIndex) {
+			return _externalNameRecords[definedNameIndex].getText();
+		}
+
+	}
+
+	private final ExternalBookBlock[] _externalBookBlocks;
+	private final ExternSheetRecord _externSheetRecord;
+	private final List<NameRecord> _definedNames;
+	private final int _recordCount;
+	private final WorkbookRecordList _workbookRecordList; // TODO - would be nice to remove this
+
+	public LinkTable(List<Record> inputList, int startIndex, WorkbookRecordList workbookRecordList, Map<String, NameCommentRecord> commentRecords) {
+
+		_workbookRecordList = workbookRecordList;
+		RecordStream rs = new RecordStream(inputList, startIndex);
+
+		List<ExternalBookBlock> temp = new ArrayList<ExternalBookBlock>();
+		while(rs.peekNextClass() == SupBookRecord.class) {
+		   temp.add(new ExternalBookBlock(rs));
+		}
+
+		_externalBookBlocks = new ExternalBookBlock[temp.size()];
+		temp.toArray(_externalBookBlocks);
+		temp.clear();
+
+		if (_externalBookBlocks.length > 0) {
+			// If any ExternalBookBlock present, there is always 1 of ExternSheetRecord
+			if (rs.peekNextClass() != ExternSheetRecord.class) {
+				// not quite - if written by google docs
+				_externSheetRecord = null;
+			} else {
+				_externSheetRecord = readExtSheetRecord(rs);
+			}
+		} else {
+			_externSheetRecord = null;
+		}
+
+		_definedNames = new ArrayList<NameRecord>();
+		// collect zero or more DEFINEDNAMEs id=0x18,
+		//  with their comments if present
+		while(true) {
+		  Class<? extends Record> nextClass = rs.peekNextClass();
+		  if (nextClass == NameRecord.class) {
+		    NameRecord nr = (NameRecord)rs.getNext();
+		    _definedNames.add(nr);
+		  }
+		  else if (nextClass == NameCommentRecord.class) {
+		    NameCommentRecord ncr = (NameCommentRecord)rs.getNext();
+		    commentRecords.put(ncr.getNameText(), ncr);
+		  }
+		  else {
+		    break;
+		  }
+		}
+
+		_recordCount = rs.getCountRead();
+		_workbookRecordList.getRecords().addAll(inputList.subList(startIndex, startIndex + _recordCount));
+	}
+
+	private static ExternSheetRecord readExtSheetRecord(RecordStream rs) {
+		List<ExternSheetRecord> temp = new ArrayList<ExternSheetRecord>(2);
+		while(rs.peekNextClass() == ExternSheetRecord.class) {
+			temp.add((ExternSheetRecord) rs.getNext());
+		}
+
+		int nItems = temp.size();
+		if (nItems < 1) {
+			throw new RuntimeException("Expected an EXTERNSHEET record but got ("
+					+ rs.peekNextClass().getName() + ")");
+		}
+		if (nItems == 1) {
+			// this is the normal case. There should be just one ExternSheetRecord
+			return temp.get(0);
+		}
+		// Some apps generate multiple ExternSheetRecords (see bug 45698).
+		// It seems like the best thing to do might be to combine these into one
+		ExternSheetRecord[] esrs = new ExternSheetRecord[nItems];
+		temp.toArray(esrs);
+		return ExternSheetRecord.combine(esrs);
+	}
+
+	/**
+	 * TODO - would not be required if calling code used RecordStream or similar
+	 */
+	public int getRecordCount() {
+		return _recordCount;
+	}
+
+	public int getNumNames() {
+		return _definedNames.size();
+	}
+
+	public NameRecord getNameRecord(int index) {
+		return _definedNames.get(index);
+	}
+
+	public String[] getExternalBookAndSheetName(int extRefIndex) {
+		int ebIx = _externSheetRecord.getExtbookIndexFromRefIndex(extRefIndex);
+		SupBookRecord ebr = _externalBookBlocks[ebIx].getExternalBookRecord();
+		if (!ebr.isExternalReferences()) {
+			return null;
+		}
+		// Sheet name only applies if not a global reference
+		int shIx = _externSheetRecord.getFirstSheetIndexFromRefIndex(extRefIndex);
+		String usSheetName = null;
+		if(shIx >= 0) {
+		   usSheetName = ebr.getSheetNames()[shIx];
+		}
+		return new String[] {
+				ebr.getURL(),
+				usSheetName,
+		};
+	}
+
+
+	/**
+	 * @param extRefIndex as from a {@link Ref3DPtg} or {@link Area3DPtg}
+	 * @return -1 if the reference is to an external book
+	 */
+	public int getIndexToInternalSheet(int extRefIndex) {
+		return _externSheetRecord.getFirstSheetIndexFromRefIndex(extRefIndex);
+	}
+
+	
+	public String resolveNameXText(int refIndex, int definedNameIndex) {
+		int extBookIndex = _externSheetRecord.getExtbookIndexFromRefIndex(refIndex);
+		return _externalBookBlocks[extBookIndex].getNameText(definedNameIndex);
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/RecordOrderer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/RecordOrderer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/RecordOrderer.java	(revision 28000)
@@ -0,0 +1,302 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.model;
+
+import java.util.List;
+
+import org.apache.poi.hssf.record.ArrayRecord;
+import org.apache.poi.hssf.record.BOFRecord;
+import org.apache.poi.hssf.record.BlankRecord;
+import org.apache.poi.hssf.record.BoolErrRecord;
+import org.apache.poi.hssf.record.CalcCountRecord;
+import org.apache.poi.hssf.record.CalcModeRecord;
+import org.apache.poi.hssf.record.DVALRecord;
+import org.apache.poi.hssf.record.DateWindow1904Record;
+import org.apache.poi.hssf.record.DeltaRecord;
+import org.apache.poi.hssf.record.DimensionsRecord;
+import org.apache.poi.hssf.record.EOFRecord;
+import org.apache.poi.hssf.record.FeatRecord;
+import org.apache.poi.hssf.record.FormulaRecord;
+import org.apache.poi.hssf.record.GridsetRecord;
+import org.apache.poi.hssf.record.GutsRecord;
+import org.apache.poi.hssf.record.HyperlinkRecord;
+import org.apache.poi.hssf.record.IndexRecord;
+import org.apache.poi.hssf.record.IterationRecord;
+import org.apache.poi.hssf.record.LabelRecord;
+import org.apache.poi.hssf.record.LabelSSTRecord;
+import org.apache.poi.hssf.record.NumberRecord;
+import org.apache.poi.hssf.record.ObjRecord;
+import org.apache.poi.hssf.record.PaneRecord;
+import org.apache.poi.hssf.record.PrecisionRecord;
+import org.apache.poi.hssf.record.RKRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordBase;
+import org.apache.poi.hssf.record.RefModeRecord;
+import org.apache.poi.hssf.record.RowRecord;
+import org.apache.poi.hssf.record.SCLRecord;
+import org.apache.poi.hssf.record.SaveRecalcRecord;
+import org.apache.poi.hssf.record.SelectionRecord;
+import org.apache.poi.hssf.record.SharedFormulaRecord;
+import org.apache.poi.hssf.record.TableRecord;
+import org.apache.poi.hssf.record.TextObjectRecord;
+import org.apache.poi.hssf.record.UncalcedRecord;
+import org.apache.poi.hssf.record.UnknownRecord;
+import org.apache.poi.hssf.record.WindowOneRecord;
+import org.apache.poi.hssf.record.WindowTwoRecord;
+import org.apache.poi.hssf.record.aggregates.DataValidityTable;
+import org.apache.poi.hssf.record.aggregates.MergedCellsTable;
+import org.apache.poi.hssf.record.aggregates.PageSettingsBlock;
+
+/**
+ * Finds correct insert positions for records in workbook streams<p/>
+ *
+ * See OOO excelfileformat.pdf sec. 4.2.5 'Record Order in a BIFF8 Workbook Stream'
+ *
+ * @author Josh Micich
+ */
+final class RecordOrderer {
+
+	// TODO - simplify logic using a generalised record ordering
+
+	private RecordOrderer() {
+		// no instances of this class
+	}
+	/**
+	 * Adds the specified new record in the correct place in sheet records list
+	 */
+	public static void addNewSheetRecord(List<RecordBase> sheetRecords, RecordBase newRecord) {
+		int index = findSheetInsertPos(sheetRecords, newRecord.getClass());
+		sheetRecords.add(index, newRecord);
+	}
+
+	private static int findSheetInsertPos(List<RecordBase> records, Class<? extends RecordBase> recClass) {
+		if (recClass == DataValidityTable.class) {
+			return findDataValidationTableInsertPos(records);
+		}
+		if (recClass == MergedCellsTable.class) {
+			return findInsertPosForNewMergedRecordTable(records);
+		}
+		if (recClass == GutsRecord.class) {
+			return getGutsRecordInsertPos(records);
+		}
+		throw new RuntimeException("Unexpected record class (" + recClass.getName() + ")");
+	}
+
+	private static int findInsertPosForNewMergedRecordTable(List<RecordBase> records) {
+		for (int i = records.size() - 2; i >= 0; i--) { // -2 to skip EOF record
+			Object rb = records.get(i);
+			if (!(rb instanceof Record)) {
+				// DataValidityTable, ConditionalFormattingTable,
+				// even PageSettingsBlock (which doesn't normally appear after 'View Settings')
+				continue;
+			}
+			Record rec = (Record) rb;
+			switch (rec.getSid()) {
+				// 'View Settings' (4 records)
+				case WindowTwoRecord.sid:
+				case SCLRecord.sid:
+				case PaneRecord.sid:
+				case SelectionRecord.sid:
+
+				case UnknownRecord.STANDARDWIDTH_0099:
+					return i + 1;
+			}
+		}
+		throw new RuntimeException("Did not find Window2 record");
+	}
+
+
+	/**
+	 * Finds the index where the sheet validations header record should be inserted
+	 * @param records the records for this sheet
+	 *
+	 * + WINDOW2
+	 * o SCL
+	 * o PANE
+	 * oo SELECTION
+	 * o STANDARDWIDTH
+	 * oo MERGEDCELLS
+	 * o LABELRANGES
+	 * o PHONETICPR
+	 * o Conditional Formatting Table
+	 * o Hyperlink Table
+	 * o Data Validity Table
+	 * o SHEETLAYOUT
+	 * o SHEETPROTECTION
+	 * o RANGEPROTECTION
+	 * + EOF
+	 */
+	private static int findDataValidationTableInsertPos(List<RecordBase> records) {
+		int i = records.size() - 1;
+		if (!(records.get(i) instanceof EOFRecord)) {
+			throw new IllegalStateException("Last sheet record should be EOFRecord");
+		}
+		while (i > 0) {
+			i--;
+			RecordBase rb = records.get(i);
+			if (isDVTPriorRecord(rb)) {
+				Record nextRec = (Record) records.get(i + 1);
+				if (!isDVTSubsequentRecord(nextRec.getSid())) {
+					throw new IllegalStateException("Unexpected (" + nextRec.getClass().getName()
+							+ ") found after (" + rb.getClass().getName() + ")");
+				}
+				return i+1;
+			}
+			Record rec = (Record) rb;
+			if (!isDVTSubsequentRecord(rec.getSid())) {
+				throw new IllegalStateException("Unexpected (" + rec.getClass().getName()
+						+ ") while looking for DV Table insert pos");
+			}
+		}
+		return 0;
+	}
+
+
+	private static boolean isDVTPriorRecord(RecordBase rb) {
+		if (rb instanceof MergedCellsTable) {
+			return true;
+		}
+		short sid = ((Record)rb).getSid();
+		switch(sid) {
+			case WindowTwoRecord.sid:
+			case UnknownRecord.SCL_00A0:
+			case PaneRecord.sid:
+			case SelectionRecord.sid:
+			case UnknownRecord.STANDARDWIDTH_0099:
+			// MergedCellsTable
+			case UnknownRecord.LABELRANGES_015F:
+			case UnknownRecord.PHONETICPR_00EF:
+			// ConditionalFormattingTable
+			case HyperlinkRecord.sid:
+			case UnknownRecord.QUICKTIP_0800:
+            // name of a VBA module    
+            case UnknownRecord.CODENAME_1BA:
+				return true;
+		}
+		return false;
+	}
+
+	private static boolean isDVTSubsequentRecord(short sid) {
+		switch(sid) {
+			case UnknownRecord.SHEETEXT_0862:
+			case UnknownRecord.SHEETPROTECTION_0867:
+			case FeatRecord.sid:
+			case EOFRecord.sid:
+				return true;
+		}
+		return false;
+	}
+	/**
+	 * DIMENSIONS record is always present
+	 */
+	private static int getDimensionsIndex(List<RecordBase> records) {
+		int nRecs = records.size();
+		for(int i=0; i<nRecs; i++) {
+			if(records.get(i) instanceof DimensionsRecord) {
+				return i;
+			}
+		}
+		// worksheet stream is seriously broken
+		throw new RuntimeException("DimensionsRecord not found");
+	}
+
+	private static int getGutsRecordInsertPos(List<RecordBase> records) {
+		int dimensionsIndex = getDimensionsIndex(records);
+		int i = dimensionsIndex-1;
+		while (i > 0) {
+			i--;
+			RecordBase rb = records.get(i);
+			if (isGutsPriorRecord(rb)) {
+				return i+1;
+			}
+		}
+		throw new RuntimeException("Did not find insert point for GUTS");
+	}
+
+	private static boolean isGutsPriorRecord(RecordBase rb) {
+		if (rb instanceof Record) {
+			Record record = (Record) rb;
+			switch (record.getSid()) {
+				case BOFRecord.sid:
+				case IndexRecord.sid:
+				// calc settings block
+					case UncalcedRecord.sid:
+					case CalcCountRecord.sid:
+					case CalcModeRecord.sid:
+					case PrecisionRecord.sid:
+					case RefModeRecord.sid:
+					case DeltaRecord.sid:
+					case IterationRecord.sid:
+					case DateWindow1904Record.sid:
+					case SaveRecalcRecord.sid:
+				// end calc settings
+				case GridsetRecord.sid:
+					return true;
+				// DefaultRowHeightRecord.sid is next
+			}
+		}
+		return false;
+	}
+	/**
+	 * @return <code>true</code> if the specified record ID terminates a sequence of Row block records
+	 * It is assumed that at least one row or cell value record has been found prior to the current
+	 * record
+	 */
+	public static boolean isEndOfRowBlock(int sid) {
+		switch(sid) {
+			case ObjRecord.sid:
+			case TextObjectRecord.sid:
+
+			case WindowOneRecord.sid:
+				// should really be part of workbook stream, but some apps seem to put this before WINDOW2
+			case WindowTwoRecord.sid:
+				return true;
+
+			case DVALRecord.sid:
+				return true;
+			case EOFRecord.sid:
+				// WINDOW2 should always be present, so shouldn't have got this far
+				throw new RuntimeException("Found EOFRecord before WindowTwoRecord was encountered");
+		}
+		return PageSettingsBlock.isComponentRecord(sid);
+	}
+
+	/**
+	 * @return <code>true</code> if the specified record id normally appears in the row blocks section
+	 * of the sheet records
+	 */
+	public static boolean isRowBlockRecord(int sid) {
+		switch (sid) {
+			case RowRecord.sid:
+
+			case BlankRecord.sid:
+			case BoolErrRecord.sid:
+			case FormulaRecord.sid:
+			case LabelRecord.sid:
+			case LabelSSTRecord.sid:
+			case NumberRecord.sid:
+			case RKRecord.sid:
+
+			case ArrayRecord.sid:
+			case SharedFormulaRecord.sid:
+			case TableRecord.sid:
+				return true;
+		}
+		return false;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/RecordStream.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/RecordStream.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/RecordStream.java	(revision 28000)
@@ -0,0 +1,84 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.model;
+
+import java.util.List;
+
+import org.apache.poi.hssf.record.Record;
+/**
+ * Simplifies iteration over a sequence of <tt>Record</tt> objects.
+ *
+ * @author Josh Micich
+ */
+public final class RecordStream {
+
+	private final List<Record> _list;
+	private int _nextIndex;
+	private int _countRead;
+	private final int _endIx;
+
+	/**
+	 * Creates a RecordStream bounded by startIndex and endIndex
+	 */
+	public RecordStream(List<Record> inputList, int startIndex, int endIx) {
+		_list = inputList;
+		_nextIndex = startIndex;
+		_endIx = endIx;
+		_countRead = 0;
+	}
+
+	public RecordStream(List<Record> records, int startIx) {
+		this(records, startIx, records.size());
+	}
+
+	public boolean hasNext() {
+		return _nextIndex < _endIx;
+	}
+
+	public Record getNext() {
+		if(!hasNext()) {
+			throw new RuntimeException("Attempt to read past end of record stream");
+		}
+		_countRead ++;
+		return _list.get(_nextIndex++);
+	}
+
+	/**
+	 * @return the {@link Class} of the next Record. <code>null</code> if this stream is exhausted.
+	 */
+	public Class<? extends Record> peekNextClass() {
+		if(!hasNext()) {
+			return null;
+		}
+		return _list.get(_nextIndex).getClass();
+	}
+
+	/**
+	 * @return -1 if at end of records
+	 */
+	public int peekNextSid() {
+		if(!hasNext()) {
+			return -1;
+		}
+		return _list.get(_nextIndex).getSid();
+	}
+
+	public int getCountRead() {
+		return _countRead;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/RowBlocksReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/RowBlocksReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/RowBlocksReader.java	(revision 28000)
@@ -0,0 +1,119 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hssf.record.ArrayRecord;
+import org.apache.poi.hssf.record.FormulaRecord;
+import org.apache.poi.hssf.record.MergeCellsRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.SharedFormulaRecord;
+import org.apache.poi.hssf.record.TableRecord;
+import org.apache.poi.hssf.record.aggregates.MergedCellsTable;
+import org.apache.poi.hssf.record.aggregates.SharedValueManager;
+import org.apache.poi.ss.util.CellReference;
+
+/**
+ * Segregates the 'Row Blocks' section of a single sheet into plain row/cell records and
+ * shared formula records.
+ *
+ * @author Josh Micich
+ */
+public final class RowBlocksReader {
+
+	private final List<Record> _plainRecords;
+	private final SharedValueManager _sfm;
+	private final MergeCellsRecord[] _mergedCellsRecords;
+
+	/**
+	 * Also collects any loose MergeCellRecords and puts them in the supplied
+	 * mergedCellsTable
+	 */
+	public RowBlocksReader(RecordStream rs) {
+		List<Record> plainRecords = new ArrayList<Record>();
+		List<Record> shFrmRecords = new ArrayList<Record>();
+		List<CellReference> firstCellRefs = new ArrayList<CellReference>();
+		List<Record> arrayRecords = new ArrayList<Record>();
+		List<Record> tableRecords = new ArrayList<Record>();
+		List<Record> mergeCellRecords = new ArrayList<Record>();
+
+		Record prevRec = null;
+		while(!RecordOrderer.isEndOfRowBlock(rs.peekNextSid())) {
+			// End of row/cell records for the current sheet
+			// Note - It is important that this code does not inadvertently add any sheet
+			// records from a subsequent sheet.  For example, if SharedFormulaRecords
+			// are taken from the wrong sheet, this could cause bug 44449.
+			if (!rs.hasNext()) {
+				throw new RuntimeException("Failed to find end of row/cell records");
+
+			}
+			Record rec = rs.getNext();
+			List<Record> dest;
+			switch (rec.getSid()) {
+				case MergeCellsRecord.sid:    dest = mergeCellRecords; break;
+				case SharedFormulaRecord.sid: dest = shFrmRecords;
+					if (!(prevRec instanceof FormulaRecord)) {
+						throw new RuntimeException("Shared formula record should follow a FormulaRecord");
+					}
+					FormulaRecord fr = (FormulaRecord)prevRec;
+					firstCellRefs.add(new CellReference(fr.getRow(), fr.getColumn()));
+					break;
+				case ArrayRecord.sid:         dest = arrayRecords;     break;
+				case TableRecord.sid:         dest = tableRecords;     break;
+				default:                      dest = plainRecords;
+			}
+			dest.add(rec);
+			prevRec = rec;
+		}
+		SharedFormulaRecord[] sharedFormulaRecs = new SharedFormulaRecord[shFrmRecords.size()];
+		CellReference[] firstCells = new CellReference[firstCellRefs.size()];
+		ArrayRecord[] arrayRecs = new ArrayRecord[arrayRecords.size()];
+		TableRecord[] tableRecs = new TableRecord[tableRecords.size()];
+		shFrmRecords.toArray(sharedFormulaRecs);
+		firstCellRefs.toArray(firstCells);
+		arrayRecords.toArray(arrayRecs);
+		tableRecords.toArray(tableRecs);
+
+		_plainRecords = plainRecords;
+		_sfm = SharedValueManager.create(sharedFormulaRecs, firstCells, arrayRecs, tableRecs);
+		_mergedCellsRecords = new MergeCellsRecord[mergeCellRecords.size()];
+		mergeCellRecords.toArray(_mergedCellsRecords);
+	}
+
+	/**
+	 * Some unconventional apps place {@link MergeCellsRecord}s within the row block.  They
+	 * actually should be in the {@link MergedCellsTable} which is much later (see bug 45699).
+	 * @return any loose  <tt>MergeCellsRecord</tt>s found
+	 */
+	public MergeCellsRecord[] getLooseMergedCells() {
+		return _mergedCellsRecords;
+	}
+
+	public SharedValueManager getSharedFormulaManager() {
+		return _sfm;
+	}
+	/**
+	 * @return a {@link RecordStream} containing all the non-{@link SharedFormulaRecord}
+	 * non-{@link ArrayRecord} and non-{@link TableRecord} Records.
+	 */
+	public RecordStream getPlainRecordStream() {
+		return new RecordStream(_plainRecords, 0);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/WorkbookRecordList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/WorkbookRecordList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/WorkbookRecordList.java	(revision 28000)
@@ -0,0 +1,159 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.hssf.record.Record;
+
+public final class WorkbookRecordList implements Iterable<Record> {
+    private List<Record> records = new ArrayList<Record>();
+
+	private int  protpos	 = 0;   // holds the position of the protect record.
+	private int  bspos	   = 0;   // holds the position of the last bound sheet.
+	private int  tabpos	  = 0;   // holds the position of the tabid record
+	private int  xfpos	   = 0;   // hold the position of the last extended font record
+	private int  namepos	 = 0;   // holds the position of last name record
+	private int  supbookpos  = 0;   // holds the position of sup book
+	private int  externsheetPos = 0;// holds the position of the extern sheet
+	private int  palettepos  = -1;   // hold the position of the palette, if applicable
+
+
+	public void setRecords(List<Record> records) {
+		this.records = records;
+	}
+
+	public int size() {
+		return records.size();
+	}
+
+	public Record get(int i) {
+		return records.get(i);
+	}
+
+	public void add(int pos, Record r) {
+		records.add(pos, r);
+		if (getProtpos() >= pos) setProtpos( protpos + 1 );
+		if (getBspos() >= pos) setBspos( bspos + 1 );
+		if (getTabpos() >= pos) setTabpos( tabpos + 1 );
+		if (getXfpos() >= pos) setXfpos( xfpos + 1 );
+		if (getNamepos() >= pos) setNamepos(namepos+1);
+		if (getSupbookpos() >= pos) setSupbookpos(supbookpos+1);
+		if ((getPalettepos() != -1) && (getPalettepos() >= pos)) setPalettepos( palettepos + 1 );
+		if (getExternsheetPos() >= pos) setExternsheetPos(getExternsheetPos() + 1);
+	}
+
+	public List<Record> getRecords() {
+		return records;
+	}
+
+	public Iterator<Record> iterator() {
+		return records.iterator();
+	}
+
+	public int getProtpos() {
+		return protpos;
+	}
+
+	public void setProtpos(int protpos) {
+		this.protpos = protpos;
+	}
+
+	public int getBspos() {
+		return bspos;
+	}
+
+	public void setBspos(int bspos) {
+		this.bspos = bspos;
+	}
+
+	public int getTabpos() {
+		return tabpos;
+	}
+
+	public void setTabpos(int tabpos) {
+		this.tabpos = tabpos;
+	}
+
+	public int getXfpos() {
+		return xfpos;
+	}
+
+	public void setXfpos(int xfpos) {
+		this.xfpos = xfpos;
+	}
+
+	public int getPalettepos() {
+		return palettepos;
+	}
+
+	public void setPalettepos(int palettepos) {
+		this.palettepos = palettepos;
+	}
+
+	
+	/**
+	 * Returns the namepos.
+	 * @return int
+	 */
+	public int getNamepos() {
+		return namepos;
+	}
+
+	/**
+	 * Returns the supbookpos.
+	 * @return int
+	 */
+	public int getSupbookpos() {
+		return supbookpos;
+	}
+
+	/**
+	 * Sets the namepos.
+	 * @param namepos The namepos to set
+	 */
+	public void setNamepos(int namepos) {
+		this.namepos = namepos;
+	}
+
+	/**
+	 * Sets the supbookpos.
+	 * @param supbookpos The supbookpos to set
+	 */
+	public void setSupbookpos(int supbookpos) {
+		this.supbookpos = supbookpos;
+	}
+
+	/**
+	 * Returns the externsheetPos.
+	 * @return int
+	 */
+	public int getExternsheetPos() {
+		return externsheetPos;
+	}
+
+	/**
+	 * Sets the externsheetPos.
+	 * @param externsheetPos The externsheetPos to set
+	 */
+	public void setExternsheetPos(int externsheetPos) {
+		this.externsheetPos = externsheetPos;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/model/package.html	(revision 28000)
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Provides low level API structures for reading, writing, modifying XLS files.
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+@see org.apache.poi.hssf.usermodel
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/package.html	(revision 28000)
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Horrible SpreadSheet Format API's for reading/writting Excel files using pure Java.
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ArrayRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ArrayRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ArrayRecord.java	(revision 28000)
@@ -0,0 +1,81 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.ss.formula.Formula;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * ARRAY (0x0221)<p/>
+ *
+ * Treated in a similar way to SharedFormulaRecord
+ *
+ * @author Josh Micich
+ */
+public final class ArrayRecord extends SharedValueRecordBase {
+
+	public final static short sid = 0x0221;
+
+	private int _options;
+	private int _field3notUsed;
+	private Formula _formula;
+
+	public ArrayRecord(RecordInputStream in) { // NO_UCD
+		super(in);
+		_options = in.readUShort();
+		_field3notUsed = in.readInt();
+		int formulaTokenLen = in.readUShort();
+		int totalFormulaLen = in.available();
+		_formula = Formula.read(formulaTokenLen, in, totalFormulaLen);
+	}
+
+	public Ptg[] getFormulaTokens() {
+		return _formula.getTokens();
+	}
+
+	protected int getExtraDataSize() {
+		return 2 + 4 + _formula.getEncodedSize();
+	}
+	protected void serializeExtraData(LittleEndianOutput out) {
+		out.writeShort(_options);
+		out.writeInt(_field3notUsed);
+		_formula.serialize(out);
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append(getClass().getName()).append(" [ARRAY]\n");
+		sb.append(" range=").append(getRange().toString()).append("\n");
+		sb.append(" options=").append(HexDump.shortToHex(_options)).append("\n");
+		sb.append(" notUsed=").append(HexDump.intToHex(_field3notUsed)).append("\n");
+		sb.append(" formula:").append("\n");
+		Ptg[] ptgs = _formula.getTokens();
+		for (int i = 0; i < ptgs.length; i++) {
+			Ptg ptg = ptgs[i];
+			sb.append(ptg.toString()).append(ptg.getRVAType()).append("\n");
+		}
+		sb.append("]");
+		return sb.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BOFRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BOFRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BOFRecord.java	(revision 28000)
@@ -0,0 +1,252 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: Beginning Of File (0x0809)<P>
+ * Description: Somewhat of a misnomer, its used for the beginning of a set of
+ *              records that have a particular purpose or subject.
+ *              Used in sheets and workbooks.<P>
+ * REFERENCE:  PG 289 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class BOFRecord extends StandardRecord {
+    /**
+     * for BIFF8 files the BOF is 0x809.  For earlier versions it was 0x09 or 0x(biffversion)09
+     */
+    public final static short sid = 0x809;
+
+    public final static int TYPE_WORKBOOK       = 0x05;
+    public final static int TYPE_VB_MODULE      = 0x06;
+    public final static int TYPE_WORKSHEET      = 0x10;
+    public final static int TYPE_CHART          = 0x20;
+    public final static int TYPE_EXCEL_4_MACRO  = 0x40;
+    public final static int TYPE_WORKSPACE_FILE = 0x100;
+
+    private int field_1_version;
+    private int field_2_type;
+    private int field_3_build;
+    private int field_4_year;
+    private int field_5_history;
+    private int field_6_rversion;
+
+    /**
+     * Constructs an empty BOFRecord with no fields set.
+     */
+    public BOFRecord() {
+    }
+    
+    public BOFRecord(RecordInputStream in) { // NO_UCD
+        field_1_version  = in.readShort();
+        field_2_type     = in.readShort();
+
+        // Some external tools don't generate all of
+        //  the remaining fields
+        if (in.remaining() >= 2) {
+            field_3_build = in.readShort();
+        }
+        if (in.remaining() >= 2) {
+            field_4_year = in.readShort();
+        }
+        if (in.remaining() >= 4) {
+            field_5_history  = in.readInt();
+        }
+        if (in.remaining() >= 4) {
+            field_6_rversion = in.readInt();
+        }
+    }
+
+    /**
+     * Version number - for BIFF8 should be 0x06
+     * @see #VERSION
+     * @param version version to be set
+     */
+    public void setVersion(int version) {
+        field_1_version = version;
+    }
+
+    /**
+     * type of object this marks
+     * @see #TYPE_WORKBOOK
+     * @see #TYPE_VB_MODULE
+     * @see #TYPE_WORKSHEET
+     * @see #TYPE_CHART
+     * @see #TYPE_EXCEL_4_MACRO
+     * @see #TYPE_WORKSPACE_FILE
+     * @param type type to be set
+     */
+    public void setType(int type) {
+        field_2_type = type;
+    }
+
+    /**
+     * build that wrote this file
+     * @see #BUILD
+     * @param build build number to set
+     */
+    public void setBuild(int build) {
+        field_3_build = build;
+    }
+
+    /**
+     * Year of the build that wrote this file
+     * @see #BUILD_YEAR
+     * @param year build year to set
+     */
+    public void setBuildYear(int year) {
+        field_4_year = year;
+    }
+
+    /**
+     * set the history bit mask (not very useful)
+     * @see #HISTORY_MASK
+     * @param bitmask bitmask to set for the history
+     */
+    public void setHistoryBitMask(int bitmask) {
+        field_5_history = bitmask;
+    }
+
+    /**
+     * set the minimum version required to read this file
+     *
+     * @see #VERSION
+     * @param version version to set
+     */
+    public void setRequiredVersion(int version) {
+        field_6_rversion = version;
+    }
+
+    /**
+     * Version number - for BIFF8 should be 0x06
+     * @see #VERSION
+     * @return version number of the generator of this file
+     */
+    public int getVersion() {
+        return field_1_version;
+    }
+
+    /**
+     * type of object this marks
+     * @see #TYPE_WORKBOOK
+     * @see #TYPE_VB_MODULE
+     * @see #TYPE_WORKSHEET
+     * @see #TYPE_CHART
+     * @see #TYPE_EXCEL_4_MACRO
+     * @see #TYPE_WORKSPACE_FILE
+     * @return type of object
+     */
+    public int getType() {
+        return field_2_type;
+    }
+
+    /**
+     * get the build that wrote this file
+     * @see #BUILD
+     * @return short build number of the generator of this file
+     */
+    public int getBuild() {
+        return field_3_build;
+    }
+
+    /**
+     * Year of the build that wrote this file
+     * @see #BUILD_YEAR
+     * @return short build year of the generator of this file
+     */
+    public int getBuildYear() {
+        return field_4_year;
+    }
+
+    /**
+     * get the history bit mask (not very useful)
+     * @see #HISTORY_MASK
+     * @return int bitmask showing the history of the file (who cares!)
+     */
+    public int getHistoryBitMask() {
+        return field_5_history;
+    }
+
+    /**
+     * get the minimum version required to read this file
+     *
+     * @see #VERSION
+     * @return int least version that can read the file
+     */
+    public int getRequiredVersion() {
+        return field_6_rversion;
+    }
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[BOF RECORD]\n");
+        buffer.append("    .version  = ").append(HexDump.shortToHex(getVersion())).append("\n");
+        buffer.append("    .type     = ").append(HexDump.shortToHex(getType()));
+        buffer.append(" (").append(getTypeName()).append(")").append("\n");
+        buffer.append("    .build    = ").append(HexDump.shortToHex(getBuild())).append("\n");
+        buffer.append("    .buildyear= ").append(getBuildYear()).append("\n");
+        buffer.append("    .history  = ").append(HexDump.intToHex(getHistoryBitMask())).append("\n");
+        buffer.append("    .reqver   = ").append(HexDump.intToHex(getRequiredVersion())).append("\n");
+        buffer.append("[/BOF RECORD]\n");
+        return buffer.toString();
+    }
+
+    private String getTypeName() {
+        switch(field_2_type) {
+            case TYPE_CHART: return "chart";
+            case TYPE_EXCEL_4_MACRO: return "excel 4 macro";
+            case TYPE_VB_MODULE: return "vb module";
+            case TYPE_WORKBOOK: return "workbook";
+            case TYPE_WORKSHEET: return "worksheet";
+            case TYPE_WORKSPACE_FILE: return "workspace file";
+        }
+        return "#error unknown type#";
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(getVersion());
+        out.writeShort(getType());
+        out.writeShort(getBuild());
+        out.writeShort(getBuildYear());
+        out.writeInt(getHistoryBitMask());
+        out.writeInt(getRequiredVersion());
+    }
+
+    protected int getDataSize() {
+        return 16;
+    }
+
+    public short getSid(){
+        return sid;
+    }
+
+    public Object clone() {
+      BOFRecord rec = new BOFRecord();
+      rec.field_1_version = field_1_version;
+      rec.field_2_type = field_2_type;
+      rec.field_3_build = field_3_build;
+      rec.field_4_year = field_4_year;
+      rec.field_5_history = field_5_history;
+      rec.field_6_rversion = field_6_rversion;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BiffHeaderInput.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BiffHeaderInput.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BiffHeaderInput.java	(revision 28000)
@@ -0,0 +1,32 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+public interface BiffHeaderInput {
+
+	/**
+	 * Read an unsigned short from the stream without decrypting
+	 */
+	int readRecordSID();
+	/**
+	 * Read an unsigned short from the stream without decrypting
+	 */
+	int readDataSize();
+
+	int available();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BlankRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BlankRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BlankRecord.java	(revision 28000)
@@ -0,0 +1,147 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Blank cell record (0x0201) <P>
+ * Description:  Represents a column in a row with no value but with styling.<P>
+ * REFERENCE:  PG 287 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @version 2.0-pre
+ */
+public final class BlankRecord extends StandardRecord implements CellValueRecordInterface {
+    public final static short sid = 0x0201;
+    private int             field_1_row;
+    private short             field_2_col;
+    private short             field_3_xf;
+
+    /** Creates a new instance of BlankRecord */
+    public BlankRecord()
+    {
+    }
+
+    public BlankRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_row = in.readUShort();
+        field_2_col = in.readShort();
+        field_3_xf  = in.readShort();
+    }
+
+    /**
+     * set the row this cell occurs on
+     * @param row the row this cell occurs within
+     */
+    public void setRow(int row)
+    {
+        field_1_row = row;
+    }
+
+    /**
+     * get the row this cell occurs on
+     *
+     * @return the row
+     */
+    public int getRow()
+    {
+        return field_1_row;
+    }
+
+    /**
+     * get the column this cell defines within the row
+     *
+     * @return the column
+     */
+    public short getColumn()
+    {
+        return field_2_col;
+    }
+
+    /**
+     * set the index of the extended format record to style this cell with
+     *
+     * @param xf - the 0-based index of the extended format
+     * @see org.apache.poi.hssf.record.ExtendedFormatRecord
+     */
+    public void setXFIndex(short xf)
+    {
+        field_3_xf = xf;
+    }
+
+    /**
+     * get the index of the extended format record to style this cell with
+     *
+     * @return extended format index
+     */
+    public short getXFIndex()
+    {
+        return field_3_xf;
+    }
+
+    /**
+     * set the column this cell defines within the row
+     *
+     * @param col the column this cell defines
+     */
+
+    public void setColumn(short col)
+    {
+        field_2_col = col;
+    }
+
+    /**
+     * return the non static version of the id for this record.
+     */
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public String toString()
+    {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("[BLANK]\n");
+        sb.append("    row= ").append(HexDump.shortToHex(getRow())).append("\n");
+        sb.append("    col= ").append(HexDump.shortToHex(getColumn())).append("\n");
+        sb.append("    xf = ").append(HexDump.shortToHex(getXFIndex())).append("\n");
+        sb.append("[/BLANK]\n");
+        return sb.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(getRow());
+        out.writeShort(getColumn());
+        out.writeShort(getXFIndex());
+    }
+
+    protected int getDataSize() {
+        return 6;
+    }
+
+    public Object clone() {
+      BlankRecord rec = new BlankRecord();
+      rec.field_1_row = field_1_row;
+      rec.field_2_col = field_2_col;
+      rec.field_3_xf = field_3_xf;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BoolErrRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BoolErrRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BoolErrRecord.java	(revision 28000)
@@ -0,0 +1,170 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.ss.usermodel.ErrorConstants;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Creates new BoolErrRecord. (0x0205) <P>
+ * REFERENCE:  PG ??? Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Michael P. Harhen
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class BoolErrRecord extends CellRecord {
+	public final static short sid = 0x0205;
+	private int _value;
+	/**
+	 * If <code>true</code>, this record represents an error cell value, otherwise this record represents a boolean cell value
+	 */
+	private boolean _isError;
+
+	/** Creates new BoolErrRecord */
+	public BoolErrRecord() {
+		// fields uninitialised
+	}
+
+	/**
+	 * @param in the RecordInputstream to read the record from
+	 */
+	public BoolErrRecord(RecordInputStream in) { // NO_UCD
+		super(in);
+		switch (in.remaining()) {
+			case 2:
+				_value = in.readByte();
+				break;
+			case 3:
+				_value = in.readUShort();
+				break;
+			default:
+				throw new RecordFormatException("Unexpected size ("
+						+ in.remaining() + ") for BOOLERR record.");
+		}
+		int flag = in.readUByte();
+		switch (flag) {
+			case 0:
+				_isError = false;
+				break;
+			case 1:
+				_isError = true;
+				break;
+			default:
+				throw new RecordFormatException("Unexpected isError flag ("
+						+ flag + ") for BOOLERR record.");
+		}
+	}
+
+	/**
+	 * set the boolean value for the cell
+	 *
+	 * @param value   representing the boolean value
+	 */
+	public void setValue(boolean value) {
+		_value = value ? 1 : 0;
+		_isError = false;
+	}
+
+	/**
+	 * set the error value for the cell
+	 *
+	 * @param value     error representing the error value
+	 *                  this value can only be 0,7,15,23,29,36 or 42
+	 *                  see bugzilla bug 16560 for an explanation
+	 */
+	public void setValue(byte value) {
+		switch(value) {
+			case ErrorConstants.ERROR_NULL:
+			case ErrorConstants.ERROR_DIV_0:
+			case ErrorConstants.ERROR_VALUE:
+			case ErrorConstants.ERROR_REF:
+			case ErrorConstants.ERROR_NAME:
+			case ErrorConstants.ERROR_NUM:
+			case ErrorConstants.ERROR_NA:
+				_value = value;
+				_isError = true;
+				return;
+		}
+		throw new IllegalArgumentException("Error Value can only be 0,7,15,23,29,36 or 42. It cannot be "+value);
+	}
+
+	/**
+	 * get the value for the cell
+	 *
+	 * @return boolean representing the boolean value
+	 */
+	public boolean getBooleanValue() {
+		return _value != 0;
+	}
+
+	/**
+	 * get the error value for the cell
+	 *
+	 * @return byte representing the error value
+	 */
+	public byte getErrorValue() {
+		return (byte)_value;
+	}
+
+	/**
+	 * Indicates whether the call holds a boolean value
+	 *
+	 * @return boolean true if the cell holds a boolean value
+	 */
+	public boolean isBoolean() {
+		return !_isError;
+	}
+
+	@Override
+	protected String getRecordName() {
+		return "BOOLERR";
+	}
+	@Override
+	protected void appendValueText(StringBuilder sb) {
+		if (isBoolean()) {
+			sb.append("  .boolVal = ");
+			sb.append(getBooleanValue());
+		} else {
+			sb.append("  .errCode = ");
+			sb.append(ErrorConstants.getText(getErrorValue()));
+			sb.append(" (").append(HexDump.byteToHex(getErrorValue())).append(")");
+		}
+	}
+	@Override
+	protected void serializeValue(LittleEndianOutput out) {
+		out.writeByte(_value);
+		out.writeByte(_isError ? 1 : 0);
+	}
+
+	@Override
+	protected int getValueDataSize() {
+		return 2;
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	public Object clone() {
+	  BoolErrRecord rec = new BoolErrRecord();
+	  copyBaseFields(rec);
+	  rec._value = _value;
+	  rec._isError = _isError;
+	  return rec;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BoundSheetRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BoundSheetRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/BoundSheetRecord.java	(revision 28000)
@@ -0,0 +1,116 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * Title:        Bound Sheet Record (aka BundleSheet) (0x0085)<P>
+ * Description:  Defines a sheet within a workbook.  Basically stores the sheet name
+ *               and tells where the Beginning of file record is within the HSSF
+ *               file. <P>
+ * REFERENCE:  PG 291 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Sergei Kozello (sergeikozello at mail.ru)
+ */
+public final class BoundSheetRecord extends StandardRecord {
+	public final static short sid = 0x0085;
+
+	private int field_1_position_of_BOF;
+	private int field_2_option_flags;
+	private int field_4_isMultibyteUnicode;
+	private String field_5_sheetname;
+
+	/**
+	 * UTF8: sid + len + bof + flags + len(str) + unicode + str 2 + 2 + 4 + 2 +
+	 * 1 + 1 + len(str)
+	 *
+	 * UNICODE: sid + len + bof + flags + len(str) + unicode + str 2 + 2 + 4 + 2 +
+	 * 1 + 1 + 2 * len(str)
+	 */
+	public BoundSheetRecord(RecordInputStream in) { // NO_UCD
+		field_1_position_of_BOF = in.readInt();
+		field_2_option_flags = in.readUShort();
+		int field_3_sheetname_length = in.readUByte();
+		field_4_isMultibyteUnicode = in.readByte();
+
+		if (isMultibyte()) {
+			field_5_sheetname = in.readUnicodeLEString(field_3_sheetname_length);
+		} else {
+			field_5_sheetname = in.readCompressedUnicode(field_3_sheetname_length);
+		}
+	}
+
+	/**
+	 * get the offset in bytes of the Beginning of File Marker within the HSSF Stream part of the POIFS file
+	 *
+	 * @return offset in bytes
+	 */
+	public int getPositionOfBof() {
+		return field_1_position_of_BOF;
+	}
+
+	private boolean isMultibyte() {
+		return (field_4_isMultibyteUnicode & 0x01) != 0;
+	}
+
+	/**
+	 * get the sheetname for this sheet.  (this appears in the tabs at the bottom)
+	 * @return sheetname the name of the sheet
+	 */
+	public String getSheetname() {
+		return field_5_sheetname;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+
+		buffer.append("[BOUNDSHEET]\n");
+		buffer.append("    .bof        = ").append(HexDump.intToHex(getPositionOfBof())).append("\n");
+		buffer.append("    .options    = ").append(HexDump.shortToHex(field_2_option_flags)).append("\n");
+		buffer.append("    .unicodeflag= ").append(HexDump.byteToHex(field_4_isMultibyteUnicode)).append("\n");
+		buffer.append("    .sheetname  = ").append(field_5_sheetname).append("\n");
+		buffer.append("[/BOUNDSHEET]\n");
+		return buffer.toString();
+	}
+
+	protected int getDataSize() {
+		return 8 + field_5_sheetname.length() * (isMultibyte() ? 2 : 1);
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		out.writeInt(getPositionOfBof());
+		out.writeShort(field_2_option_flags);
+
+		String name = field_5_sheetname;
+		out.writeByte(name.length());
+		out.writeByte(field_4_isMultibyteUnicode);
+
+		if (isMultibyte()) {
+			StringUtil.putUnicodeLE(name, out);
+		} else {
+			StringUtil.putCompressedUnicode(name, out);
+		}
+	}
+
+	public short getSid() {
+		return sid;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CRNCountRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CRNCountRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CRNCountRecord.java	(revision 28000)
@@ -0,0 +1,80 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+/**
+ * XCT - CRN Count <P>
+ *
+ * REFERENCE:  5.114<P>
+ *
+ * @author Josh Micich
+ */
+public final class CRNCountRecord extends StandardRecord {
+	public final static short sid = 0x59;
+
+	private static final short DATA_SIZE = 4;
+
+
+	private int	 field_1_number_crn_records;
+	private int	 field_2_sheet_table_index;
+
+	public CRNCountRecord() {
+		throw new RuntimeException("incomplete code");
+	}
+
+	public int getNumberOfCRNs() {
+		return field_1_number_crn_records;
+	}
+
+
+	public CRNCountRecord(RecordInputStream in) { // NO_UCD
+		field_1_number_crn_records = in.readShort();
+		if(field_1_number_crn_records < 0) {
+			// TODO - seems like the sign bit of this field might be used for some other purpose
+			// see example file for test case "TestBugs.test19599()"
+			field_1_number_crn_records = (short)-field_1_number_crn_records;
+		}
+		field_2_sheet_table_index = in.readShort();
+	 }
+
+
+	public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getClass().getName()).append(" [XCT");
+        sb.append(" nCRNs=").append(field_1_number_crn_records);
+        sb.append(" sheetIx=").append(field_2_sheet_table_index);
+        sb.append("]");
+        return sb.toString();
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		out.writeShort((short)field_1_number_crn_records);
+		out.writeShort((short)field_2_sheet_table_index);
+	}
+	protected int getDataSize() {
+		return DATA_SIZE;
+	}
+
+	/**
+	 * return the non static version of the id for this record.
+	 */
+	public short getSid() {
+		return sid;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CRNRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CRNRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CRNRecord.java	(revision 28000)
@@ -0,0 +1,77 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.constant.ConstantValueParser;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:       CRN(0x005A) <p/>
+ * Description: This record stores the contents of an external cell or cell range <p/>
+ * REFERENCE:   OOO 5.23<p/>
+ *
+ * @author josh micich
+ */
+public final class CRNRecord extends StandardRecord {
+	public final static short sid = 0x005A;
+
+	private int	 field_1_last_column_index;
+	private int	 field_2_first_column_index;
+	private int	 field_3_row_index;
+	private Object[] field_4_constant_values;
+
+	public CRNRecord() {
+		throw new RuntimeException("incomplete code");
+	}
+
+	public CRNRecord(RecordInputStream in) { // NO_UCD
+		field_1_last_column_index = in.readUByte();
+		field_2_first_column_index = in.readUByte();
+		field_3_row_index = in.readShort();
+		int nValues = field_1_last_column_index - field_2_first_column_index + 1;
+		field_4_constant_values = ConstantValueParser.parse(in, nValues);
+	}
+
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append(getClass().getName()).append(" [CRN");
+		sb.append(" rowIx=").append(field_3_row_index);
+		sb.append(" firstColIx=").append(field_2_first_column_index);
+		sb.append(" lastColIx=").append(field_1_last_column_index);
+		sb.append("]");
+		return sb.toString();
+	}
+	protected int getDataSize() {
+		return 4 + ConstantValueParser.getEncodedSize(field_4_constant_values);
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		out.writeByte(field_1_last_column_index);
+		out.writeByte(field_2_first_column_index);
+		out.writeShort(field_3_row_index);
+		ConstantValueParser.encode(out, field_4_constant_values);
+	}
+
+	/**
+	 * return the non static version of the id for this record.
+	 */
+	public short getSid() {
+		return sid;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CalcCountRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CalcCountRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CalcCountRecord.java	(revision 28000)
@@ -0,0 +1,102 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Calc Count Record
+ * Description:  Specifies the maximum times the gui should perform a formula
+ *               recalculation.  For instance: in the case a formula includes
+ *               cells that are themselves a result of a formula and a value
+ *               changes.  This is essentially a failsafe against an infinate
+ *               loop in the event the formulas are not independant. <P>
+ * REFERENCE:  PG 292 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @version 2.0-pre
+ * @see org.apache.poi.hssf.record.CalcModeRecord
+ */
+
+public final class CalcCountRecord
+    extends StandardRecord
+{
+    public final static short sid = 0xC;
+    private short             field_1_iterations;
+
+    public CalcCountRecord()
+    {
+    }
+
+    public CalcCountRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_iterations = in.readShort();
+    }
+
+    /**
+     * set the number of iterations to perform
+     * @param iterations to perform
+     */
+
+    public void setIterations(short iterations)
+    {
+        field_1_iterations = iterations;
+    }
+
+    /**
+     * get the number of iterations to perform
+     * @return iterations
+     */
+
+    public short getIterations()
+    {
+        return field_1_iterations;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[CALCCOUNT]\n");
+        buffer.append("    .iterations     = ")
+            .append(Integer.toHexString(getIterations())).append("\n");
+        buffer.append("[/CALCCOUNT]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(getIterations());
+    }
+
+    protected int getDataSize() {
+        return 2;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public Object clone() {
+      CalcCountRecord rec = new CalcCountRecord();
+      rec.field_1_iterations = field_1_iterations;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CalcModeRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CalcModeRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CalcModeRecord.java	(revision 28000)
@@ -0,0 +1,111 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Calc Mode Record<P>
+ * Description:  Tells the gui whether to calculate formulas
+ *               automatically, manually or automatically
+ *               except for tables.<P>
+ * REFERENCE:  PG 292 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @version 2.0-pre
+ * @see org.apache.poi.hssf.record.CalcCountRecord
+ */
+
+public final class CalcModeRecord
+    extends StandardRecord
+{
+    public final static short sid                     = 0xD;
+
+    private short             field_1_calcmode;
+
+    public CalcModeRecord()
+    {
+    }
+
+    public CalcModeRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_calcmode = in.readShort();
+    }
+
+    /**
+     * set the calc mode flag for formulas
+     *
+     * @see #MANUAL
+     * @see #AUTOMATIC
+     * @see #AUTOMATIC_EXCEPT_TABLES
+     *
+     * @param calcmode one of the three flags above
+     */
+
+    public void setCalcMode(short calcmode)
+    {
+        field_1_calcmode = calcmode;
+    }
+
+    /**
+     * get the calc mode flag for formulas
+     *
+     * @see #MANUAL
+     * @see #AUTOMATIC
+     * @see #AUTOMATIC_EXCEPT_TABLES
+     *
+     * @return calcmode one of the three flags above
+     */
+
+    public short getCalcMode()
+    {
+        return field_1_calcmode;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[CALCMODE]\n");
+        buffer.append("    .calcmode       = ")
+            .append(Integer.toHexString(getCalcMode())).append("\n");
+        buffer.append("[/CALCMODE]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(getCalcMode());
+    }
+
+    protected int getDataSize() {
+        return 2;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public Object clone() {
+      CalcModeRecord rec = new CalcModeRecord();
+      rec.field_1_calcmode = field_1_calcmode;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CellRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CellRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CellRecord.java	(revision 28000)
@@ -0,0 +1,132 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Base class for all cell value records (implementors of {@link CellValueRecordInterface}).
+ * Subclasses are expected to manage the cell data values (of various types).
+ *
+ * @author Josh Micich
+ */
+public abstract class CellRecord extends StandardRecord implements CellValueRecordInterface {
+	private int _rowIndex;
+	private int _columnIndex;
+	private int _formatIndex;
+
+	protected CellRecord() {
+		// fields uninitialised
+	}
+
+	protected CellRecord(RecordInputStream in) {
+		_rowIndex = in.readUShort();
+		_columnIndex = in.readUShort();
+		_formatIndex = in.readUShort();
+	}
+
+	public final void setRow(int row) {
+		_rowIndex = row;
+	}
+
+	public final void setColumn(short col) {
+		_columnIndex = col;
+	}
+
+	/**
+	 * set the index to the ExtendedFormat
+	 *
+	 * @see org.apache.poi.hssf.record.ExtendedFormatRecord
+	 * @param xf index to the XF record
+	 */
+	public final void setXFIndex(short xf) {
+		_formatIndex = xf;
+	}
+
+	public final int getRow() {
+		return _rowIndex;
+	}
+
+	public final short getColumn() {
+		return (short) _columnIndex;
+	}
+
+	/**
+	 * get the index to the ExtendedFormat
+	 *
+	 * @see org.apache.poi.hssf.record.ExtendedFormatRecord
+	 * @return index to the XF record
+	 */
+	public final short getXFIndex() {
+		return (short) _formatIndex;
+	}
+
+	public final String toString() {
+		StringBuilder sb = new StringBuilder();
+		String recordName = getRecordName();
+
+		sb.append("[").append(recordName).append("]\n");
+		sb.append("    .row    = ").append(HexDump.shortToHex(getRow())).append("\n");
+		sb.append("    .col    = ").append(HexDump.shortToHex(getColumn())).append("\n");
+		sb.append("    .xfindex= ").append(HexDump.shortToHex(getXFIndex())).append("\n");
+		appendValueText(sb);
+		sb.append("\n");
+		sb.append("[/").append(recordName).append("]\n");
+		return sb.toString();
+	}
+
+	/**
+	 * Append specific debug info (used by {@link #toString()} for the value
+	 * contained in this record. Trailing new-line should not be appended
+	 * (superclass does that).
+	 */
+	protected abstract void appendValueText(StringBuilder sb);
+
+	/**
+	 * Gets the debug info BIFF record type name (used by {@link #toString()}.
+	 */
+	protected abstract String getRecordName();
+
+	/**
+	 * writes out the value data for this cell record
+	 */
+	protected abstract void serializeValue(LittleEndianOutput out);
+
+	/**
+	 * @return the size (in bytes) of the value data for this cell record
+	 */
+	protected abstract int getValueDataSize();
+
+	public final void serialize(LittleEndianOutput out) {
+		out.writeShort(getRow());
+		out.writeShort(getColumn());
+		out.writeShort(getXFIndex());
+		serializeValue(out);
+	}
+
+	protected final int getDataSize() {
+		return 6 + getValueDataSize();
+	}
+
+	protected final void copyBaseFields(CellRecord rec) {
+		rec._rowIndex = _rowIndex;
+		rec._columnIndex = _columnIndex;
+		rec._formatIndex = _formatIndex;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CellValueRecordInterface.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CellValueRecordInterface.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CellValueRecordInterface.java	(revision 28000)
@@ -0,0 +1,56 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+/**
+ * The cell value record interface is implemented by all classes of type Record that
+ * contain cell values.  It allows the containing sheet to move through them and compare
+ * them.
+ *
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ *
+ * @see org.apache.poi.hssf.record.Record
+ * @see org.apache.poi.hssf.record.RecordFactory
+ */
+public interface CellValueRecordInterface {
+
+    /**
+     * @return the row this cell occurs on
+     */
+    int getRow();
+
+    /**
+     * @return the column this cell defines within the row
+     */
+    short getColumn();
+
+    /**
+     * @param row the row this cell occurs within
+     */
+    void setRow(int row);
+
+    /**
+     * @param col the column this cell defines
+     */
+    void setColumn(short col);
+
+    void setXFIndex(short xf);
+
+    short getXFIndex();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ColumnInfoRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ColumnInfoRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ColumnInfoRecord.java	(revision 28000)
@@ -0,0 +1,208 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: COLINFO Record (0x007D)<p/>
+ * Description:  Defines with width and formatting for a range of columns<p/>
+ * REFERENCE:  PG 293 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ */
+public final class ColumnInfoRecord extends StandardRecord {
+    public static final short sid = 0x007D;
+
+    private int _firstCol;
+    private int _lastCol;
+    private int _colWidth;
+    private int _xfIndex;
+    private int _options;
+    private static final BitField hidden    = BitFieldFactory.getInstance(0x01);
+    private static final BitField outlevel  = BitFieldFactory.getInstance(0x0700);
+    private static final BitField collapsed = BitFieldFactory.getInstance(0x1000);
+    // Excel seems write values 2, 10, and 260, even though spec says "must be zero"
+    private int field_6_reserved;
+
+    /**
+     * Creates a column info record with default width and format
+     */
+    public ColumnInfoRecord() {
+        setColumnWidth(2275);
+        _options = 2;
+        _xfIndex = 0x0f;
+        field_6_reserved = 2; // seems to be the most common value
+    }
+
+    public ColumnInfoRecord(RecordInputStream in) { // NO_UCD
+        _firstCol = in.readUShort();
+        _lastCol  = in.readUShort();
+        _colWidth = in.readUShort();
+        _xfIndex  = in.readUShort();
+        _options   = in.readUShort();
+        switch(in.remaining()) {
+            case 2: // usual case
+                field_6_reserved  = in.readUShort();
+                break;
+            case 1:
+                // often COLINFO gets encoded 1 byte short
+                // shouldn't matter because this field is unused
+                field_6_reserved  = in.readByte();
+                break;
+            case 0:
+                // According to bugzilla 48332,
+                // "SoftArtisans OfficeWriter for Excel" totally skips field 6
+                // Excel seems to be OK with this, and assumes zero.
+                field_6_reserved  = 0;
+                break;
+            default:
+                throw new RuntimeException("Unusual record size remaining=(" + in.remaining() + ")");
+        }
+    }
+
+    /**
+     * set the columns' width in 1/256 of a character width
+     * @param cw - column width
+     */
+    public void setColumnWidth(int cw) {
+        _colWidth = cw;
+    }
+
+    /**
+     * get the first column this record defines formatting info for
+     * @return the first column index (0-based)
+     */
+    public int getFirstColumn() {
+        return _firstCol;
+    }
+
+    /**
+     * get the last column this record defines formatting info for
+     * @return the last column index (0-based)
+     */
+    public int getLastColumn() {
+        return _lastCol;
+    }
+
+    /**
+     * @return column width in units of 1/256 of a character width
+     */
+    public int getColumnWidth() {
+        return _colWidth;
+    }
+
+    /**
+     * get the columns' default format info
+     * @return the extended format index
+     * @see org.apache.poi.hssf.record.ExtendedFormatRecord
+     */
+    public int getXFIndex() {
+        return _xfIndex;
+    }
+
+    /**
+     * @return whether the cells are hidden.
+     */
+    public boolean getHidden() {
+        return hidden.isSet(_options);
+    }
+
+    /**
+     * @return outline level for the cells
+     */
+    public int getOutlineLevel() {
+        return outlevel.getValue(_options);
+    }
+
+    /**
+     * @return whether the cells are collapsed
+     */
+    public boolean getCollapsed() {
+        return collapsed.isSet(_options);
+    }
+
+    public boolean containsColumn(int columnIndex) {
+        return _firstCol <= columnIndex && columnIndex <= _lastCol;
+    }
+    public boolean isAdjacentBefore(ColumnInfoRecord other) { // NO_UCD
+        return _lastCol == other._firstCol - 1;
+    }
+
+    /**
+     * @return <code>true</code> if the format, options and column width match
+     */
+    public boolean formatMatches(ColumnInfoRecord other) { // NO_UCD
+        if (_xfIndex != other._xfIndex) {
+            return false;
+        }
+        if (_options != other._options) {
+            return false;
+        }
+        if (_colWidth != other._colWidth) {
+            return false;
+        }
+        return true;
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(getFirstColumn());
+        out.writeShort(getLastColumn());
+        out.writeShort(getColumnWidth());
+        out.writeShort(getXFIndex());
+        out.writeShort(_options);
+        out.writeShort(field_6_reserved);
+    }
+
+    protected int getDataSize() {
+        return 12;
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("[COLINFO]\n");
+        sb.append("  colfirst = ").append(getFirstColumn()).append("\n");
+        sb.append("  collast  = ").append(getLastColumn()).append("\n");
+        sb.append("  colwidth = ").append(getColumnWidth()).append("\n");
+        sb.append("  xfindex  = ").append(getXFIndex()).append("\n");
+        sb.append("  options  = ").append(HexDump.shortToHex(_options)).append("\n");
+        sb.append("    hidden   = ").append(getHidden()).append("\n");
+        sb.append("    olevel   = ").append(getOutlineLevel()).append("\n");
+        sb.append("    collapsed= ").append(getCollapsed()).append("\n");
+        sb.append("[/COLINFO]\n");
+        return sb.toString();
+    }
+
+    public Object clone() {
+        ColumnInfoRecord rec = new ColumnInfoRecord();
+        rec._firstCol = _firstCol;
+        rec._lastCol = _lastCol;
+        rec._colWidth = _colWidth;
+        rec._xfIndex = _xfIndex;
+        rec._options = _options;
+        rec.field_6_reserved = field_6_reserved;
+        return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CommonObjectDataSubRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CommonObjectDataSubRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/CommonObjectDataSubRecord.java	(revision 28000)
@@ -0,0 +1,253 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * The common object data record is used to store all common preferences for an excel object.<p/>
+ * 
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class CommonObjectDataSubRecord extends SubRecord {
+    public final static short sid = 0x0015;
+
+    private static final BitField locked    = BitFieldFactory.getInstance(0x0001);
+    private static final BitField printable = BitFieldFactory.getInstance(0x0010);
+    private static final BitField autofill  = BitFieldFactory.getInstance(0x2000);
+    private static final BitField autoline  = BitFieldFactory.getInstance(0x4000);
+
+    private  short      field_1_objectType;
+    private  int        field_2_objectId;
+    private  short      field_3_option;
+    private  int        field_4_reserved1;
+    private  int        field_5_reserved2;
+    private  int        field_6_reserved3;
+
+
+    public CommonObjectDataSubRecord()
+    {
+
+    }
+
+    public CommonObjectDataSubRecord(LittleEndianInput in, int size) {
+        if (size != 18) {
+            throw new RecordFormatException("Expected size 18 but got (" + size + ")");
+        }
+        field_1_objectType             = in.readShort();
+        field_2_objectId               = in.readUShort();
+        field_3_option                 = in.readShort();
+        field_4_reserved1              = in.readInt();
+        field_5_reserved2              = in.readInt();
+        field_6_reserved3              = in.readInt();
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[ftCmo]\n");
+        buffer.append("    .objectType           = ")
+            .append("0x").append(HexDump.toHex(  getObjectType ()))
+            .append(" (").append( getObjectType() ).append(" )");
+        buffer.append(System.getProperty("line.separator")); 
+        buffer.append("    .objectId             = ")
+            .append("0x").append(HexDump.toHex(  getObjectId ()))
+            .append(" (").append( getObjectId() ).append(" )");
+        buffer.append(System.getProperty("line.separator")); 
+        buffer.append("    .option               = ")
+            .append("0x").append(HexDump.toHex(  getOption ()))
+            .append(" (").append( getOption() ).append(" )");
+        buffer.append(System.getProperty("line.separator")); 
+        buffer.append("         .locked                   = ").append(isLocked()).append('\n'); 
+        buffer.append("         .printable                = ").append(isPrintable()).append('\n'); 
+        buffer.append("         .autofill                 = ").append(isAutofill()).append('\n'); 
+        buffer.append("         .autoline                 = ").append(isAutoline()).append('\n'); 
+        buffer.append("    .reserved1            = ")
+            .append("0x").append(HexDump.toHex(  getReserved1 ()))
+            .append(" (").append( getReserved1() ).append(" )");
+        buffer.append(System.getProperty("line.separator")); 
+        buffer.append("    .reserved2            = ")
+            .append("0x").append(HexDump.toHex(  getReserved2 ()))
+            .append(" (").append( getReserved2() ).append(" )");
+        buffer.append(System.getProperty("line.separator")); 
+        buffer.append("    .reserved3            = ")
+            .append("0x").append(HexDump.toHex(  getReserved3 ()))
+            .append(" (").append( getReserved3() ).append(" )");
+        buffer.append(System.getProperty("line.separator")); 
+
+        buffer.append("[/ftCmo]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+
+        out.writeShort(sid);
+        out.writeShort(getDataSize());
+
+        out.writeShort(field_1_objectType);
+        out.writeShort(field_2_objectId);
+        out.writeShort(field_3_option);
+        out.writeInt(field_4_reserved1);
+        out.writeInt(field_5_reserved2);
+        out.writeInt(field_6_reserved3);
+    }
+
+	protected int getDataSize() {
+        return 2 + 2 + 2 + 4 + 4 + 4;
+    }
+
+    public short getSid() // NO_UCD
+    {
+        return sid;
+    }
+
+    public Object clone() {
+        CommonObjectDataSubRecord rec = new CommonObjectDataSubRecord();
+    
+        rec.field_1_objectType = field_1_objectType;
+        rec.field_2_objectId = field_2_objectId;
+        rec.field_3_option = field_3_option;
+        rec.field_4_reserved1 = field_4_reserved1;
+        rec.field_5_reserved2 = field_5_reserved2;
+        rec.field_6_reserved3 = field_6_reserved3;
+        return rec;
+    }
+
+
+    /**
+     * Get the object type field for the CommonObjectData record.
+     *
+     * @return  One of 
+     *        OBJECT_TYPE_GROUP
+     *        OBJECT_TYPE_LINE
+     *        OBJECT_TYPE_RECTANGLE
+     *        OBJECT_TYPE_OVAL
+     *        OBJECT_TYPE_ARC
+     *        OBJECT_TYPE_CHART
+     *        OBJECT_TYPE_TEXT
+     *        OBJECT_TYPE_BUTTON
+     *        OBJECT_TYPE_PICTURE
+     *        OBJECT_TYPE_POLYGON
+     *        OBJECT_TYPE_RESERVED1
+     *        OBJECT_TYPE_CHECKBOX
+     *        OBJECT_TYPE_OPTION_BUTTON
+     *        OBJECT_TYPE_EDIT_BOX
+     *        OBJECT_TYPE_LABEL
+     *        OBJECT_TYPE_DIALOG_BOX
+     *        OBJECT_TYPE_SPINNER
+     *        OBJECT_TYPE_SCROLL_BAR
+     *        OBJECT_TYPE_LIST_BOX
+     *        OBJECT_TYPE_GROUP_BOX
+     *        OBJECT_TYPE_COMBO_BOX
+     *        OBJECT_TYPE_RESERVED2
+     *        OBJECT_TYPE_RESERVED3
+     *        OBJECT_TYPE_RESERVED4
+     *        OBJECT_TYPE_RESERVED5
+     *        OBJECT_TYPE_COMMENT
+     *        OBJECT_TYPE_RESERVED6
+     *        OBJECT_TYPE_RESERVED7
+     *        OBJECT_TYPE_RESERVED8
+     *        OBJECT_TYPE_RESERVED9
+     *        OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING
+     */
+    public short getObjectType()
+    {
+        return field_1_objectType;
+    }
+
+    /**
+     * Get the object id field for the CommonObjectData record.
+     */
+    public int getObjectId()
+    {
+        return field_2_objectId;
+    }
+
+    /**
+     * Get the option field for the CommonObjectData record.
+     */
+    public short getOption()
+    {
+        return field_3_option;
+    }
+
+    /**
+     * Get the reserved1 field for the CommonObjectData record.
+     */
+    public int getReserved1()
+    {
+        return field_4_reserved1;
+    }
+
+    /**
+     * Get the reserved2 field for the CommonObjectData record.
+     */
+    public int getReserved2()
+    {
+        return field_5_reserved2;
+    }
+
+    /**
+     * Get the reserved3 field for the CommonObjectData record.
+     */
+    public int getReserved3()
+    {
+        return field_6_reserved3;
+    }
+
+    /**
+     * true if object is locked when sheet has been protected
+     * @return  the locked field value.
+     */
+    public boolean isLocked()
+    {
+        return locked.isSet(field_3_option);
+    }
+
+    /**
+     * object appears when printed
+     * @return  the printable field value.
+     */
+    public boolean isPrintable()
+    {
+        return printable.isSet(field_3_option);
+    }
+
+    /**
+     * whether object uses an automatic fill style
+     * @return  the autofill field value.
+     */
+    public boolean isAutofill()
+    {
+        return autofill.isSet(field_3_option);
+    }
+
+    /**
+     * whether object uses an automatic line style
+     * @return  the autoline field value.
+     */
+    public boolean isAutoline()
+    {
+        return autoline.isSet(field_3_option);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ContinueRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ContinueRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ContinueRecord.java	(revision 28000)
@@ -0,0 +1,67 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Continue Record(0x003C) - Helper class used primarily for SST Records <P>
+ * Description:  handles overflow for prior record in the input
+ *               stream; content is tailored to that prior record<P>
+ * @author Marc Johnson (mjohnson at apache dot org)
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Csaba Nagy (ncsaba at yahoo dot com)
+ */
+public final class ContinueRecord extends StandardRecord {
+    public final static short sid = 0x003C;
+    private byte[] _data;
+
+    public ContinueRecord(byte[] data) {
+        _data = data;
+    }
+
+    protected int getDataSize() {
+        return _data.length;
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.write(_data);
+    }
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[CONTINUE RECORD]\n");
+        buffer.append("    .data = ").append(HexDump.toHex(_data)).append("\n");
+        buffer.append("[/CONTINUE RECORD]\n");
+        return buffer.toString();
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    public ContinueRecord(RecordInputStream in) { // NO_UCD
+        _data = in.readRemainder();
+    }
+
+    public Object clone() {
+        return new ContinueRecord(_data);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DBCellRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DBCellRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DBCellRecord.java	(revision 28000)
@@ -0,0 +1,113 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        DBCell Record (0x00D7)<p/>
+ * Description:  Used by Excel and other MS apps to quickly find rows in the sheets.<P>
+ * REFERENCE:  PG 299/440 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height
+ */
+public final class DBCellRecord extends StandardRecord {
+    public final static short sid = 0x00D7;
+    public final static int BLOCK_SIZE = 32;
+    
+    public static final class Builder {
+        private short[] _cellOffsets;
+        private int _nCellOffsets;
+        public Builder() {
+        	_cellOffsets = new short[4];
+		}
+
+        public void addCellOffset(int cellRefOffset) {
+            if (_cellOffsets.length <= _nCellOffsets) {
+                short[] temp = new short[_nCellOffsets * 2];
+                System.arraycopy(_cellOffsets, 0, temp, 0, _nCellOffsets);
+                _cellOffsets = temp;
+            }
+            _cellOffsets[_nCellOffsets] = (short) cellRefOffset;
+            _nCellOffsets++;
+        }
+
+        public DBCellRecord build(int rowOffset) {
+            short[] cellOffsets = new short[_nCellOffsets];
+            System.arraycopy(_cellOffsets, 0, cellOffsets, 0, _nCellOffsets);
+            return new DBCellRecord(rowOffset, cellOffsets);
+        }
+    }
+    /**
+     * offset from the start of this DBCellRecord to the start of the first cell in
+     * the next DBCell block.
+     */
+    private final int     field_1_row_offset;
+    private final short[] field_2_cell_offsets;
+
+    DBCellRecord(int rowOffset, short[]cellOffsets) {
+        field_1_row_offset = rowOffset;
+        field_2_cell_offsets = cellOffsets;
+    }
+
+    public DBCellRecord(RecordInputStream in) { // NO_UCD
+        field_1_row_offset   = in.readUShort();
+        int size = in.remaining();        
+        field_2_cell_offsets = new short[ size / 2 ];
+
+        for (int i=0;i<field_2_cell_offsets.length;i++)
+        {
+            field_2_cell_offsets[ i ] = in.readShort();
+        }
+    }
+
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[DBCELL]\n");
+        buffer.append("    .rowoffset = ").append(HexDump.intToHex(field_1_row_offset)).append("\n");
+        for (int k = 0; k < field_2_cell_offsets.length; k++) {
+            buffer.append("    .cell_").append(k).append(" = ")
+                .append(HexDump.shortToHex(field_2_cell_offsets[ k ])).append("\n");
+        }
+        buffer.append("[/DBCELL]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeInt(field_1_row_offset);
+        for (int k = 0; k < field_2_cell_offsets.length; k++) {
+            out.writeShort(field_2_cell_offsets[ k ]);
+        }
+    }
+    protected int getDataSize() {
+        return 4 + field_2_cell_offsets.length * 2;
+    }
+    
+
+    public short getSid() {
+        return sid;
+    }
+
+    public Object clone() {
+        // safe because immutable
+        return this;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DVALRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DVALRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DVALRecord.java	(revision 28000)
@@ -0,0 +1,134 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        DATAVALIDATIONS Record (0x01B2)<p/>
+ * Description:  used in data validation ;
+ *               This record is the list header of all data validation records (0x01BE) in the current sheet.
+ * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
+ */
+public final class DVALRecord extends StandardRecord {
+	public final static short sid = 0x01B2;
+
+	/** Options of the DVAL */
+	private short field_1_options;
+	/** Horizontal position of the dialog */
+	private int field_2_horiz_pos;
+	/** Vertical position of the dialog */
+	private int field_3_vert_pos;
+
+	/** Object ID of the drop down arrow object for list boxes ;
+	 * in our case this will be always FFFF , until
+	 * MSODrawingGroup and MSODrawing records are implemented */
+	private int  field_cbo_id;
+
+	/** Number of following DV Records */
+	private int  field_5_dv_no;
+
+    public DVALRecord() {
+        field_cbo_id = 0xFFFFFFFF;
+        field_5_dv_no = 0x00000000;
+    }
+
+	public DVALRecord(RecordInputStream in) { // NO_UCD
+		field_1_options = in.readShort();
+		field_2_horiz_pos = in.readInt();
+		field_3_vert_pos = in.readInt();
+        field_cbo_id    = in.readInt(); 
+        field_5_dv_no   = in.readInt();
+	}
+
+    /**
+	 * @return the field_1_options
+	 */
+	public short getOptions() {
+		return field_1_options;
+	}
+
+	/**
+	 * @return the Horizontal position of the dialog
+	 */
+	public int getHorizontalPos() {
+		return field_2_horiz_pos;
+	}
+
+	/**
+	 * @return the the Vertical position of the dialog
+	 */
+	public int getVerticalPos() {
+		return field_3_vert_pos;
+	}
+
+	/**
+     * get Object ID of the drop down arrow object for list boxes
+     */
+    public int getObjectID() {
+        return field_cbo_id;
+    }
+
+    /**
+     * Get number of following DV records
+     */
+    public int getDVRecNo() {
+        return field_5_dv_no;
+    }
+
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+
+		buffer.append("[DVAL]\n");
+		buffer.append("    .options      = ").append(getOptions()).append('\n');
+		buffer.append("    .horizPos     = ").append(getHorizontalPos()).append('\n');
+		buffer.append("    .vertPos      = ").append(getVerticalPos()).append('\n');
+		buffer.append("    .comboObjectID   = ").append(Integer.toHexString(getObjectID())).append("\n");
+		buffer.append("    .DVRecordsNumber = ").append(Integer.toHexString(getDVRecNo())).append("\n");
+		buffer.append("[/DVAL]\n");
+		return buffer.toString();
+	}
+
+    public void serialize(LittleEndianOutput out) {
+ 		
+		out.writeShort(getOptions());
+		out.writeInt(getHorizontalPos());
+		out.writeInt(getVerticalPos());
+		out.writeInt(getObjectID());
+		out.writeInt(getDVRecNo());
+    }
+
+    protected int getDataSize() {
+        return 18;
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    public Object clone() {
+      DVALRecord rec = new DVALRecord();
+      rec.field_1_options = field_1_options;
+      rec.field_2_horiz_pos = field_2_horiz_pos;
+      rec.field_3_vert_pos = field_3_vert_pos;
+      rec.field_cbo_id = field_cbo_id;
+      rec.field_5_dv_no = field_5_dv_no;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DVRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DVRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DVRecord.java	(revision 28000)
@@ -0,0 +1,197 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.common.UnicodeString;
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.ss.formula.Formula;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * Title:        DATAVALIDATION Record (0x01BE)<p/>
+ * Description:  This record stores data validation settings and a list of cell ranges
+ *               which contain these settings. The data validation settings of a sheet
+ *               are stored in a sequential list of DV records. This list is followed by
+ *               DVAL record(s)
+ * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
+ * @author Josh Micich
+ */
+public final class DVRecord extends StandardRecord {
+	public final static short sid = 0x01BE;
+	
+	/** Option flags */
+	private int _option_flags;
+	/** Title of the prompt box */
+	private UnicodeString _promptTitle;
+	/** Title of the error box */
+	private UnicodeString _errorTitle;
+	/** Text of the prompt box */
+	private UnicodeString _promptText;
+	/** Text of the error box */
+	private UnicodeString _errorText;
+	/** Not used - Excel seems to always write 0x3FE0 */
+	private short _not_used_1 = 0x3FE0;
+	/** Formula data for first condition (RPN token array without size field) */
+	private Formula _formula1;
+	/** Not used - Excel seems to always write 0x0000 */
+	private short _not_used_2 = 0x0000;
+	/** Formula data for second condition (RPN token array without size field) */
+	private Formula _formula2;
+	/** Cell range address list with all affected ranges */
+	private CellRangeAddressList _regions;
+
+	/**
+	 * Option flags field
+	 * 
+	 * @see HSSFDataValidation utility class
+	 */
+
+	public DVRecord(RecordInputStream in) { // NO_UCD
+
+		_option_flags = in.readInt();
+
+		_promptTitle = readUnicodeString(in);
+		_errorTitle = readUnicodeString(in);
+		_promptText = readUnicodeString(in);
+		_errorText = readUnicodeString(in);
+
+		int field_size_first_formula = in.readUShort();
+		_not_used_1 = in.readShort();
+
+		// "You may not use unions, intersections or array constants in Data Validation criteria"
+
+		// read first formula data condition
+		_formula1 = Formula.read(field_size_first_formula, in);
+
+		int field_size_sec_formula = in.readUShort();
+		_not_used_2 = in.readShort();
+
+		// read sec formula data condition
+		_formula2 = Formula.read(field_size_sec_formula, in);
+
+		// read cell range address list with all affected ranges
+		_regions = new CellRangeAddressList(in);
+	}
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append("[DV]\n");
+		sb.append(" options=").append(Integer.toHexString(_option_flags));
+		sb.append(" title-prompt=").append(formatTextTitle(_promptTitle));
+		sb.append(" title-error=").append(formatTextTitle(_errorTitle));
+		sb.append(" text-prompt=").append(formatTextTitle(_promptText));
+		sb.append(" text-error=").append(formatTextTitle(_errorText));
+		sb.append("\n");
+		appendFormula(sb, "Formula 1:",  _formula1);
+		appendFormula(sb, "Formula 2:",  _formula2);
+		sb.append("Regions: ");
+		int nRegions = _regions.countRanges();
+		for(int i=0; i<nRegions; i++) {
+			if (i>0) {
+				sb.append(", ");
+			}
+			CellRangeAddress addr = _regions.getCellRangeAddress(i);
+			sb.append('(').append(addr.getFirstRow()).append(',').append(addr.getLastRow());
+			sb.append(',').append(addr.getFirstColumn()).append(',').append(addr.getLastColumn()).append(')');
+		}
+		sb.append("\n");
+		sb.append("[/DV]");
+
+		return sb.toString();
+	}
+
+	private static String formatTextTitle(UnicodeString us) {
+		String str = us.getString();
+		if (str.length() == 1 && str.charAt(0) == '\0') {
+			return "'\\0'";
+		}
+		return str;
+	}
+
+	private static void appendFormula(StringBuffer sb, String label, Formula f) {
+		sb.append(label);
+		
+		if (f == null) {
+			sb.append("<empty>\n");
+			return;
+		}
+		Ptg[] ptgs = f.getTokens();
+		sb.append('\n');
+		for (int i = 0; i < ptgs.length; i++) {
+			sb.append('\t').append(ptgs[i].toString()).append('\n');
+		}
+	}
+
+	public void serialize(LittleEndianOutput out) {
+
+		out.writeInt(_option_flags);
+		
+		serializeUnicodeString(_promptTitle, out);
+		serializeUnicodeString(_errorTitle, out);
+		serializeUnicodeString(_promptText, out);
+		serializeUnicodeString(_errorText, out);
+		out.writeShort(_formula1.getEncodedTokenSize());
+		out.writeShort(_not_used_1);
+		_formula1.serializeTokens(out);
+		
+		out.writeShort(_formula2.getEncodedTokenSize());
+		out.writeShort(_not_used_2);
+		_formula2.serializeTokens(out);
+		
+		_regions.serialize(out);
+	}
+
+	private static UnicodeString readUnicodeString(RecordInputStream in) {
+		return new UnicodeString(in);
+	}
+
+	private static void serializeUnicodeString(UnicodeString us, LittleEndianOutput out) {
+		StringUtil.writeUnicodeString(out, us.getString());
+	}
+	private static int getUnicodeStringSize(UnicodeString us) {
+		String str = us.getString();
+		return 3 + str.length() * (StringUtil.hasMultibyte(str) ? 2 : 1);
+	}
+
+	protected int getDataSize() {
+		int size = 4+2+2+2+2;//options_field+first_formula_size+first_unused+sec_formula_size+sec+unused;
+		size += getUnicodeStringSize(_promptTitle);
+		size += getUnicodeStringSize(_errorTitle);
+		size += getUnicodeStringSize(_promptText);
+		size += getUnicodeStringSize(_errorText);
+		size += _formula1.getEncodedTokenSize();
+		size += _formula2.getEncodedTokenSize();
+		size += _regions.getSize();
+		return size;
+	}
+
+	public short getSid() {
+		return sid;
+	}
+	
+	/**
+	 * Clones the object. Uses serialisation, as the
+	 *  contents are somewhat complex
+	 */
+	public Object clone() {
+		return cloneViaReserialise();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DateWindow1904Record.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DateWindow1904Record.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DateWindow1904Record.java	(revision 28000)
@@ -0,0 +1,81 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Date Window 1904 Flag record <P>
+ * Description:  Flag specifying whether 1904 date windowing is used.
+ *               (tick toc tick toc...BOOM!) <P>
+ * REFERENCE:  PG 280 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @version 2.0-pre
+ */
+
+public final class DateWindow1904Record
+    extends StandardRecord
+{
+    public final static short sid = 0x22;
+    private short             field_1_window;
+
+    public DateWindow1904Record()
+    {
+    }
+
+    public DateWindow1904Record(RecordInputStream in) // NO_UCD
+    {
+        field_1_window = in.readShort();
+    }
+
+    /**
+     * gets whether or not to use 1904 date windowing (which means you'll be screwed in 2004)
+     * @return window flag - 0/1 (false,true)
+     */
+
+    public short getWindowing()
+    {
+        return field_1_window;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[1904]\n");
+        buffer.append("    .is1904          = ")
+            .append(Integer.toHexString(getWindowing())).append("\n");
+        buffer.append("[/1904]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(getWindowing());
+    }
+
+    protected int getDataSize() {
+        return 2;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DeltaRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DeltaRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DeltaRecord.java	(revision 28000)
@@ -0,0 +1,78 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Delta Record (0x0010)<p/>
+ * Description:  controls the accuracy of the calculations<p/>
+ * REFERENCE:  PG 303 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class DeltaRecord extends StandardRecord {
+    public final static short sid = 0x0010;
+    public final static double DEFAULT_VALUE = 0.0010;   // should be .001
+
+    // a double is an IEEE 8-byte float...damn IEEE and their goofy standards an
+    // ambiguous numeric identifiers
+    private double field_1_max_change;
+
+    public DeltaRecord(double maxChange) {
+        field_1_max_change = maxChange;
+    }
+
+    public DeltaRecord(RecordInputStream in) { // NO_UCD
+        field_1_max_change = in.readDouble();
+    }
+
+    /**
+     * get the maximum change
+     * @return maxChange - maximum rounding error
+     */
+    public double getMaxChange() {
+        return field_1_max_change;
+    }
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[DELTA]\n");
+        buffer.append("    .maxchange = ").append(getMaxChange()).append("\n");
+        buffer.append("[/DELTA]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeDouble(getMaxChange());
+    }
+
+    protected int getDataSize() {
+        return 8;
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    public Object clone() {
+        // immutable
+        return this;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DimensionsRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DimensionsRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/DimensionsRecord.java	(revision 28000)
@@ -0,0 +1,182 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Dimensions Record<P>
+ * Description:  provides the minumum and maximum bounds
+ *               of a sheet.<P>
+ * REFERENCE:  PG 303 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @version 2.0-pre
+ */
+
+public final class DimensionsRecord
+    extends StandardRecord
+{
+    public final static short sid = 0x200;
+    private int               field_1_first_row;
+    private int               field_2_last_row;   // plus 1
+    private short             field_3_first_col;
+    private short             field_4_last_col;
+    private short             field_5_zero;       // must be 0 (reserved)
+
+    public DimensionsRecord()
+    {
+    }
+
+    public DimensionsRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_first_row = in.readInt();
+        field_2_last_row  = in.readInt();
+        field_3_first_col = in.readShort();
+        field_4_last_col  = in.readShort();
+        field_5_zero      = in.readShort();
+    }
+
+    /**
+     * set the first row number for the sheet
+     * @param row - first row on the sheet
+     */
+
+    public void setFirstRow(int row)
+    {
+        field_1_first_row = row;
+    }
+
+    /**
+     * set the last row number for the sheet
+     * @param row - last row on the sheet
+     */
+
+    public void setLastRow(int row)
+    {
+        field_2_last_row = row;
+    }
+
+    /**
+     * set the first column number for the sheet
+     * @param col  first column on the sheet
+     */
+
+    public void setFirstCol(short col)
+    {
+        field_3_first_col = col;
+    }
+
+    /**
+     * set the last col number for the sheet
+     * @param col  last column on the sheet
+     */
+
+    public void setLastCol(short col)
+    {
+        field_4_last_col = col;
+    }
+
+    /**
+     * get the first row number for the sheet
+     * @return row - first row on the sheet
+     */
+
+    public int getFirstRow()
+    {
+        return field_1_first_row;
+    }
+
+    /**
+     * get the last row number for the sheet
+     * @return row - last row on the sheet
+     */
+
+    public int getLastRow()
+    {
+        return field_2_last_row;
+    }
+
+    /**
+     * get the first column number for the sheet
+     * @return column - first column on the sheet
+     */
+
+    public short getFirstCol()
+    {
+        return field_3_first_col;
+    }
+
+    /**
+     * get the last col number for the sheet
+     * @return column - last column on the sheet
+     */
+
+    public short getLastCol()
+    {
+        return field_4_last_col;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[DIMENSIONS]\n");
+        buffer.append("    .firstrow       = ")
+            .append(Integer.toHexString(getFirstRow())).append("\n");
+        buffer.append("    .lastrow        = ")
+            .append(Integer.toHexString(getLastRow())).append("\n");
+        buffer.append("    .firstcol       = ")
+            .append(Integer.toHexString(getFirstCol())).append("\n");
+        buffer.append("    .lastcol        = ")
+            .append(Integer.toHexString(getLastCol())).append("\n");
+        buffer.append("    .zero           = ")
+            .append(Integer.toHexString(field_5_zero)).append("\n");
+        buffer.append("[/DIMENSIONS]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeInt(getFirstRow());
+        out.writeInt(getLastRow());
+        out.writeShort(getFirstCol());
+        out.writeShort(getLastCol());
+        out.writeShort(( short ) 0);
+    }
+
+    protected int getDataSize() {
+        return 14;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public Object clone() {
+      DimensionsRecord rec = new DimensionsRecord();
+      rec.field_1_first_row = field_1_first_row;
+      rec.field_2_last_row = field_2_last_row;
+      rec.field_3_first_col = field_3_first_col;
+      rec.field_4_last_col = field_4_last_col;
+      rec.field_5_zero = field_5_zero;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/EOFRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/EOFRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/EOFRecord.java	(revision 28000)
@@ -0,0 +1,73 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * End Of File record.
+ * <P>
+ * Description:  Marks the end of records belonging to a particular object in the
+ *               HSSF File<P>
+ * REFERENCE:  PG 307 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @version 2.0-pre
+ */
+public final class EOFRecord extends StandardRecord {
+    public final static short sid = 0x0A;
+	public static final int ENCODED_SIZE = 4;
+
+	public static final EOFRecord instance = new EOFRecord();
+	
+    private EOFRecord() {
+    	// no data fields
+    }
+
+    /**
+     * @param in unused (since this record has no data)
+     */
+    public EOFRecord(RecordInputStream in) // NO_UCD
+    {
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[EOF]\n");
+        buffer.append("[/EOF]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+    }
+
+    protected int getDataSize() {
+        return ENCODED_SIZE - 4;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public Object clone() {
+      return instance;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java	(revision 28000)
@@ -0,0 +1,316 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import java.io.ByteArrayInputStream;
+
+import org.apache.poi.hssf.record.formula.Area3DPtg;
+import org.apache.poi.hssf.record.formula.AreaPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.Ref3DPtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianInputStream;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * ftPictFmla (0x0009)<br/>
+ * A sub-record within the OBJ record which stores a reference to an object
+ * stored in a separate entry within the OLE2 compound file.
+ *
+ * @author Daniel Noll
+ */
+public final class EmbeddedObjectRefSubRecord extends SubRecord {
+	public static final short sid = 0x0009;
+
+	private static final byte[] EMPTY_BYTE_ARRAY = { };
+
+	private int field_1_unknown_int;
+	/** either an area or a cell ref */
+	private Ptg field_2_refPtg;
+	/** for when the 'formula' doesn't parse properly */
+	private byte[] field_2_unknownFormulaData;
+	/** note- this byte is not present in the encoding if the string length is zero */
+	private boolean field_3_unicode_flag;  // Flags whether the string is Unicode.
+	private String  field_4_ole_classname; // Classname of the embedded OLE document (e.g. Word.Document.8)
+	/** Formulas often have a single non-zero trailing byte.
+	 * This is in a similar position to he pre-streamId padding
+	 * It is unknown if the value is important (it seems to mirror a value a few bytes earlier)
+	 *  */
+	private Byte  field_4_unknownByte;
+	private Integer field_5_stream_id;	 // ID of the OLE stream containing the actual data.
+	private byte[] field_6_unknown;
+
+
+	// currently for testing only - needs review
+	EmbeddedObjectRefSubRecord() {
+		field_2_unknownFormulaData = new byte[] { 0x02, 0x6C, 0x6A, 0x16, 0x01, }; // just some sample data.  These values vary a lot
+		field_6_unknown = EMPTY_BYTE_ARRAY;
+		field_4_ole_classname = null;
+	}
+
+	public short getSid() { // NO_UCD
+		return sid;
+	}
+
+	public EmbeddedObjectRefSubRecord(LittleEndianInput in, int size) {
+
+		// Much guess-work going on here due to lack of any documentation.
+		// See similar source code in OOO:
+		// http://svn.services.openoffice.org/ooo/trunk/sc/source/filter/excel/xiescher.cxx
+		// 1223 void XclImpOleObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nRecSize )
+
+		int streamIdOffset = in.readShort(); // OOO calls this 'nFmlaLen'
+		int remaining = size - LittleEndian.SHORT_SIZE;
+
+		int dataLenAfterFormula = remaining - streamIdOffset;
+		int formulaSize = in.readUShort();
+		remaining -= LittleEndian.SHORT_SIZE;
+		field_1_unknown_int = in.readInt();
+		remaining -= LittleEndian.INT_SIZE;
+		byte[] formulaRawBytes = readRawData(in, formulaSize);
+		remaining -= formulaSize;
+		field_2_refPtg = readRefPtg(formulaRawBytes);
+		if (field_2_refPtg == null) {
+			// common case
+			// field_2_n16 seems to be 5 here
+			// The formula almost looks like tTbl but the row/column values seem like garbage.
+			field_2_unknownFormulaData = formulaRawBytes;
+		} else {
+			field_2_unknownFormulaData = null;
+		}
+
+		int stringByteCount;
+		if (remaining >= dataLenAfterFormula + 3) {
+			int tag = in.readByte();
+			stringByteCount = LittleEndian.BYTE_SIZE;
+			if (tag != 0x03) {
+				throw new RecordFormatException("Expected byte 0x03 here");
+			}
+			int nChars = in.readUShort();
+			stringByteCount += LittleEndian.SHORT_SIZE;
+			if (nChars > 0) {
+				 // OOO: the 4th way Xcl stores a unicode string: not even a Grbit byte present if length 0
+				field_3_unicode_flag = ( in.readByte() & 0x01 ) != 0;
+				stringByteCount += LittleEndian.BYTE_SIZE;
+				if (field_3_unicode_flag) {
+					field_4_ole_classname = StringUtil.readUnicodeLE(in, nChars);
+					stringByteCount += nChars * 2;
+				} else {
+					field_4_ole_classname = StringUtil.readCompressedUnicode(in, nChars);
+					stringByteCount += nChars;
+				}
+			} else {
+				field_4_ole_classname = "";
+			}
+		} else {
+			field_4_ole_classname = null;
+			stringByteCount = 0;
+		}
+		remaining -= stringByteCount;
+		// Pad to next 2-byte boundary
+		if (((stringByteCount + formulaSize) % 2) != 0) {
+			int b = in.readByte();
+			remaining -= LittleEndian.BYTE_SIZE;
+			if (field_2_refPtg != null && field_4_ole_classname == null) {
+				field_4_unknownByte = Byte.valueOf((byte)b);
+			}
+		}
+		int nUnexpectedPadding = remaining - dataLenAfterFormula;
+
+		if (nUnexpectedPadding > 0) {
+			System.err.println("Discarding " + nUnexpectedPadding + " unexpected padding bytes ");
+			readRawData(in, nUnexpectedPadding);
+			remaining-=nUnexpectedPadding;
+		}
+
+		// Fetch the stream ID
+		if (dataLenAfterFormula >= 4) {
+			field_5_stream_id = Integer.valueOf(in.readInt());
+			remaining -= LittleEndian.INT_SIZE;
+		} else {
+			field_5_stream_id = null;
+		}
+		field_6_unknown = readRawData(in, remaining);
+	}
+
+	private static Ptg readRefPtg(byte[] formulaRawBytes) {
+		LittleEndianInput in = new LittleEndianInputStream(new ByteArrayInputStream(formulaRawBytes));
+		byte ptgSid = in.readByte();
+		switch(ptgSid) {
+			case AreaPtg.sid:   return new AreaPtg(in);
+			case Area3DPtg.sid: return new Area3DPtg(in);
+			case RefPtg.sid:	return new RefPtg(in);
+			case Ref3DPtg.sid:  return new Ref3DPtg(in);
+		}
+		return null;
+	}
+
+	private static byte[] readRawData(LittleEndianInput in, int size) {
+		if (size < 0) {
+			throw new IllegalArgumentException("Negative size (" + size + ")");
+		}
+		if (size == 0) {
+			return EMPTY_BYTE_ARRAY;
+		}
+		byte[] result = new byte[size];
+		in.readFully(result);
+		return result;
+	}
+
+	private int getStreamIDOffset(int formulaSize) {
+		int result = 2 + 4; // formulaSize + f2unknown_int
+		result += formulaSize;
+
+		int stringLen;
+		if (field_4_ole_classname == null) {
+			// don't write 0x03, stringLen, flag, text
+			stringLen = 0;
+		} else {
+			result += 1 + 2;  // 0x03, stringLen
+			stringLen = field_4_ole_classname.length();
+			if (stringLen > 0) {
+				result += 1; // flag
+				if (field_3_unicode_flag) {
+					result += stringLen * 2;
+				} else {
+					result += stringLen;
+				}
+			}
+		}
+		// pad to next 2 byte boundary
+		if ((result % 2) != 0) {
+			result ++;
+		}
+		return result;
+	}
+
+	private int getDataSize(int idOffset) {
+
+		int result = 2 + idOffset; // 2 for idOffset short field itself
+		if (field_5_stream_id != null) {
+			result += 4;
+		}
+		return result +  field_6_unknown.length;
+	}
+	protected int getDataSize() {
+		int formulaSize = field_2_refPtg == null ? field_2_unknownFormulaData.length : field_2_refPtg.getSize();
+		int idOffset = getStreamIDOffset(formulaSize);
+		return getDataSize(idOffset);
+	}
+
+	public void serialize(LittleEndianOutput out) {
+
+		int formulaSize = field_2_refPtg == null ? field_2_unknownFormulaData.length : field_2_refPtg.getSize();
+		int idOffset = getStreamIDOffset(formulaSize);
+		int dataSize = getDataSize(idOffset);
+
+
+		out.writeShort(sid);
+		out.writeShort(dataSize);
+
+		out.writeShort(idOffset);
+		out.writeShort(formulaSize);
+		out.writeInt(field_1_unknown_int);
+
+		int pos = 12;
+
+		if (field_2_refPtg == null) {
+			out.write(field_2_unknownFormulaData);
+		} else {
+			field_2_refPtg.write(out);
+		}
+		pos += formulaSize;
+
+		int stringLen;
+		if (field_4_ole_classname == null) {
+			// don't write 0x03, stringLen, flag, text
+			stringLen = 0;
+		} else {
+			out.writeByte(0x03);
+			pos+=1;
+			stringLen = field_4_ole_classname.length();
+			out.writeShort(stringLen);
+			pos+=2;
+			if (stringLen > 0) {
+				out.writeByte(field_3_unicode_flag ? 0x01 : 0x00);
+				pos+=1;
+
+				if (field_3_unicode_flag) {
+					StringUtil.putUnicodeLE(field_4_ole_classname, out);
+					pos += stringLen * 2;
+				} else {
+					StringUtil.putCompressedUnicode(field_4_ole_classname, out);
+					pos += stringLen;
+				}
+			}
+		}
+
+		// pad to next 2-byte boundary (requires 0 or 1 bytes)
+		switch(idOffset - (pos - 6)) { // 6 for 3 shorts: sid, dataSize, idOffset
+			case 1:
+				out.writeByte(field_4_unknownByte == null ? 0x00 : field_4_unknownByte.intValue());
+				pos ++;
+			case 0:
+				break;
+			default:
+				throw new IllegalStateException("Bad padding calculation (" + idOffset + ", " + pos + ")");
+		}
+
+		if (field_5_stream_id != null) {
+			out.writeInt(field_5_stream_id.intValue());
+			pos += 4;
+		}
+		out.write(field_6_unknown);
+	}
+
+
+
+	public Object clone() {
+		return this; // TODO proper clone
+	}
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append("[ftPictFmla]\n");
+		sb.append("    .f2unknown     = ").append(HexDump.intToHex(field_1_unknown_int)).append("\n");
+		if (field_2_refPtg == null) {
+			sb.append("    .f3unknown     = ").append(HexDump.toHex(field_2_unknownFormulaData)).append("\n");
+		} else {
+			sb.append("    .formula       = ").append(field_2_refPtg.toString()).append("\n");
+		}
+		if (field_4_ole_classname != null) {
+			sb.append("    .unicodeFlag   = ").append(field_3_unicode_flag).append("\n");
+			sb.append("    .oleClassname  = ").append(field_4_ole_classname).append("\n");
+		}
+		if (field_4_unknownByte != null) {
+			sb.append("    .f4unknown   = ").append(HexDump.byteToHex(field_4_unknownByte.intValue())).append("\n");
+		}
+		if (field_5_stream_id != null) {
+			sb.append("    .streamId      = ").append(HexDump.intToHex(field_5_stream_id.intValue())).append("\n");
+		}
+		if (field_6_unknown.length > 0) {
+			sb.append("    .f7unknown     = ").append(HexDump.toHex(field_6_unknown)).append("\n");
+		}
+		sb.append("[/ftPictFmla]");
+		return sb.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/EndSubRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/EndSubRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/EndSubRecord.java	(revision 28000)
@@ -0,0 +1,83 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * ftEnd (0x0000)<p/>
+ * 
+ * The end data record is used to denote the end of the subrecords.<p/>
+ * 
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class EndSubRecord extends SubRecord {
+    public final static short sid = 0x0000; // Note - zero sid is somewhat unusual (compared to plain Records)
+    private static final int ENCODED_SIZE = 0;
+
+    public EndSubRecord()
+    {
+
+    }
+
+    /**
+     * @param in unused (since this record has no data)
+     * @param size 
+     */
+    public EndSubRecord(LittleEndianInput in, int size) {
+        if ((size & 0xFF) != ENCODED_SIZE) { // mask out random crap in upper byte
+            throw new RecordFormatException("Unexpected size (" + size + ")");
+        }
+    }
+
+    @Override
+    public boolean isTerminating(){
+        return true;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[ftEnd]\n");
+
+        buffer.append("[/ftEnd]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(sid);
+        out.writeShort(ENCODED_SIZE);
+    }
+
+	protected int getDataSize() {
+        return ENCODED_SIZE;
+    }
+
+    public short getSid() // NO_UCD
+    {
+        return sid;
+    }
+
+    public Object clone() {
+        EndSubRecord rec = new EndSubRecord();
+    
+        return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ExtSSTRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ExtSSTRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ExtSSTRecord.java	(revision 28000)
@@ -0,0 +1,143 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Extended Static String Table (0x00FF)<p/>
+ * Description: This record is used for a quick lookup into the SST record. This
+ *              record breaks the SST table into a set of buckets. The offsets
+ *              to these buckets within the SST record are kept as well as the
+ *              position relative to the start of the SST record.
+ * REFERENCE:  PG 313 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at apache dot org)
+ */
+public final class ExtSSTRecord extends StandardRecord {
+    public final static short sid = 0x00FF;
+    public static final int DEFAULT_BUCKET_SIZE = 8;
+    //Can't seem to find this documented but from the biffviewer it is clear that
+    //Excel only records the indexes for the first 128 buckets.
+    public static final int MAX_BUCKETS = 128;
+    
+    
+    private static final class InfoSubRecord {
+    	public static final int ENCODED_SIZE = 8;
+        private int field_1_stream_pos;          // stream pointer to the SST record
+        private int field_2_bucket_sst_offset;   // don't really understand this yet.
+        /** unused - supposed to be zero */
+        private short field_3_zero;
+
+
+        public InfoSubRecord(RecordInputStream in)
+        {
+            field_1_stream_pos        = in.readInt();
+            field_2_bucket_sst_offset = in.readShort();
+            field_3_zero              = in.readShort();
+        }
+
+        public int getStreamPos() {
+            return field_1_stream_pos;
+        }
+
+        public int getBucketSSTOffset() {
+            return field_2_bucket_sst_offset;
+        }
+
+        public void serialize(LittleEndianOutput out) {
+            out.writeInt(field_1_stream_pos);
+            out.writeShort(field_2_bucket_sst_offset);
+            out.writeShort(field_3_zero);
+        }
+    }
+    
+    
+    private short _stringsPerBucket;
+    private InfoSubRecord[] _sstInfos;
+
+
+    public ExtSSTRecord() {
+    	_stringsPerBucket = DEFAULT_BUCKET_SIZE;
+        _sstInfos = new InfoSubRecord[0];
+    }
+
+    public ExtSSTRecord(RecordInputStream in) { // NO_UCD
+        _stringsPerBucket = in.readShort();
+        int nInfos = in.remaining() / InfoSubRecord.ENCODED_SIZE;
+        _sstInfos = new InfoSubRecord[nInfos];
+        for (int i = 0; i < _sstInfos.length; i++) {
+            _sstInfos[i] = new InfoSubRecord(in);
+        }
+    }
+
+    public void setNumStringsPerBucket(short numStrings) {
+        _stringsPerBucket = numStrings;
+    }
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[EXTSST]\n");
+        buffer.append("    .dsst           = ")
+            .append(Integer.toHexString(_stringsPerBucket))
+            .append("\n");
+        buffer.append("    .numInfoRecords = ").append(_sstInfos.length)
+            .append("\n");
+        for (int k = 0; k < _sstInfos.length; k++)
+        {
+            buffer.append("    .inforecord     = ").append(k).append("\n");
+            buffer.append("    .streampos      = ")
+                .append(Integer
+                .toHexString(_sstInfos[k].getStreamPos())).append("\n");
+            buffer.append("    .sstoffset      = ")
+                .append(Integer
+                .toHexString(_sstInfos[k].getBucketSSTOffset()))
+                    .append("\n");
+        }
+        buffer.append("[/EXTSST]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(_stringsPerBucket);
+        for (int k = 0; k < _sstInfos.length; k++) {
+            _sstInfos[k].serialize(out);
+        }
+    }
+    protected int getDataSize() {
+    	return 2 + InfoSubRecord.ENCODED_SIZE*_sstInfos.length;
+    }
+
+    public static final int getNumberOfInfoRecsForStrings(int numStrings) {
+      int infoRecs = (numStrings / DEFAULT_BUCKET_SIZE);
+      if ((numStrings % DEFAULT_BUCKET_SIZE) != 0)
+        infoRecs ++;
+      //Excel seems to max out after 128 info records.
+      //This isn't really documented anywhere...
+      if (infoRecs > MAX_BUCKETS)
+        infoRecs = MAX_BUCKETS;
+      return infoRecs;
+    }
+
+
+    public short getSid() {
+        return sid;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ExtendedFormatRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ExtendedFormatRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ExtendedFormatRecord.java	(revision 28000)
@@ -0,0 +1,1036 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Extended Format Record
+ * Description:  Probably one of the more complex records.  There are two breeds:
+ *               Style and Cell.
+ *<P>
+ *               It should be noted that fields in the extended format record are
+ *               somewhat arbitrary.  Almost all of the fields are bit-level, but
+ *               we name them as best as possible by functional group.  In some
+ *               places this is better than others.
+ *<P>
+ *
+ * REFERENCE:  PG 426 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @version 2.0-pre
+ */
+
+public final class ExtendedFormatRecord
+    extends StandardRecord
+{
+    public final static short     sid                 = 0xE0;
+
+    // xf type
+    public final static short     XF_STYLE            = 1;
+    public final static short     XF_CELL             = 0;
+
+    // fields in BOTH style and Cell XF records
+    private short                 field_1_font_index;             // not bit-mapped
+    private short                 field_2_format_index;           // not bit-mapped
+
+    // field_3_cell_options bit map
+    static final private BitField _locked       = BitFieldFactory.getInstance(0x0001);
+    static final private BitField _hidden       = BitFieldFactory.getInstance(0x0002);
+    static final private BitField _xf_type      = BitFieldFactory.getInstance(0x0004);
+    static final private BitField _parent_index = BitFieldFactory.getInstance(0xFFF0);
+    private short                 field_3_cell_options;
+
+    // field_4_alignment_options bit map
+    static final private BitField _alignment          = BitFieldFactory.getInstance(0x0007);
+    static final private BitField _wrap_text          = BitFieldFactory.getInstance(0x0008);
+    static final private BitField _vertical_alignment = BitFieldFactory.getInstance(0x0070);
+    static final private BitField _justify_last       = BitFieldFactory.getInstance(0x0080);
+    static final private BitField _rotation           = BitFieldFactory.getInstance(0xFF00);
+    private short                 field_4_alignment_options;
+
+    // field_5_indention_options
+    static final private BitField _indent                         =
+        BitFieldFactory.getInstance(0x000F);
+    static final private BitField _shrink_to_fit                  =
+        BitFieldFactory.getInstance(0x0010);
+    static final private BitField _merge_cells                    =
+        BitFieldFactory.getInstance(0x0020);
+    static final private BitField _reading_order                  =
+        BitFieldFactory.getInstance(0x00C0);
+
+    // apparently bits 8 and 9 are unused
+    static final private BitField _indent_not_parent_format       =
+        BitFieldFactory.getInstance(0x0400);
+    static final private BitField _indent_not_parent_font         =
+        BitFieldFactory.getInstance(0x0800);
+    static final private BitField _indent_not_parent_alignment    =
+        BitFieldFactory.getInstance(0x1000);
+    static final private BitField _indent_not_parent_border       =
+        BitFieldFactory.getInstance(0x2000);
+    static final private BitField _indent_not_parent_pattern      =
+        BitFieldFactory.getInstance(0x4000);
+    static final private BitField _indent_not_parent_cell_options =
+        BitFieldFactory.getInstance(0x8000);
+    private short                 field_5_indention_options;
+
+    // field_6_border_options bit map
+    static final private BitField _border_left   = BitFieldFactory.getInstance(0x000F);
+    static final private BitField _border_right  = BitFieldFactory.getInstance(0x00F0);
+    static final private BitField _border_top    = BitFieldFactory.getInstance(0x0F00);
+    static final private BitField _border_bottom = BitFieldFactory.getInstance(0xF000);
+    private short                 field_6_border_options;
+
+    // all three of the following attributes are palette options
+    // field_7_palette_options bit map
+    static final private BitField _left_border_palette_idx  =
+        BitFieldFactory.getInstance(0x007F);
+    static final private BitField _right_border_palette_idx =
+        BitFieldFactory.getInstance(0x3F80);
+    static final private BitField _diag                     =
+        BitFieldFactory.getInstance(0xC000);
+    private short                 field_7_palette_options;
+
+    // field_8_adtl_palette_options bit map
+    static final private BitField _top_border_palette_idx    =
+        BitFieldFactory.getInstance(0x0000007F);
+    static final private BitField _bottom_border_palette_idx =
+        BitFieldFactory.getInstance(0x00003F80);
+    static final private BitField _adtl_diag                 =
+        BitFieldFactory.getInstance(0x001fc000);
+    static final private BitField _adtl_diag_line_style      =
+        BitFieldFactory.getInstance(0x01e00000);
+
+    // apparently bit 25 is unused
+    static final private BitField _adtl_fill_pattern         =
+        BitFieldFactory.getInstance(0xfc000000);
+    private int                   field_8_adtl_palette_options;   // additional to avoid 2
+
+    // field_9_fill_palette_options bit map
+    static final private BitField _fill_foreground = BitFieldFactory.getInstance(0x007F);
+    static final private BitField _fill_background = BitFieldFactory.getInstance(0x3f80);
+
+    // apparently bits 15 and 14 are unused
+    private short                 field_9_fill_palette_options;
+
+    /**
+     * Constructor ExtendedFormatRecord
+     *
+     *
+     */
+
+    public ExtendedFormatRecord()
+    {
+    }
+
+    public ExtendedFormatRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_font_index           = in.readShort();
+        field_2_format_index         = in.readShort();
+        field_3_cell_options         = in.readShort();
+        field_4_alignment_options    = in.readShort();
+        field_5_indention_options    = in.readShort();
+        field_6_border_options       = in.readShort();
+        field_7_palette_options      = in.readShort();
+        field_8_adtl_palette_options = in.readInt();
+        field_9_fill_palette_options = in.readShort();
+    }
+
+
+    /**
+     * get the index to the FONT record (which font to use 0 based)
+     *
+     *
+     * @return index to the font
+     * @see org.apache.poi.hssf.record.FontRecord
+     */
+
+    public short getFontIndex()
+    {
+        return field_1_font_index;
+    }
+
+    /**
+     *  get the index to the Format record (which FORMAT to use 0-based)
+     *
+     *
+     * @return index to the format record
+     * @see org.apache.poi.hssf.record.FormatRecord
+     */
+
+    public short getFormatIndex()
+    {
+        return field_2_format_index;
+    }
+
+    /**
+     * gets the options bitmask - you can also use corresponding option bit getters
+     * (see other methods that reference this one)
+     *
+     *
+     * @return options bitmask
+     *
+     */
+
+    public short getCellOptions()
+    {
+        return field_3_cell_options;
+    }
+
+    // These are the bit fields in cell options
+
+    /**
+     * get whether the cell is locked or not
+     *
+     *
+     * @return locked - if the cell is locked
+     * @see #getCellOptions()
+     */
+
+    public boolean isLocked()
+    {
+        return _locked.isSet(field_3_cell_options);
+    }
+
+    /**
+     * get whether the cell is hidden or not
+     *
+     *
+     * @return hidden - if the cell is hidden
+     * @see #getCellOptions()
+     */
+
+    public boolean isHidden()
+    {
+        return _hidden.isSet(field_3_cell_options);
+    }
+
+    /**
+     * get whether the cell is a cell or style XFRecord
+     *
+     *
+     * @return type - cell or style (0/1)
+     * @see #XF_STYLE
+     * @see #XF_CELL
+     * @see #getCellOptions()
+     */
+
+    public short getXFType()
+    {
+        return _xf_type.getShortValue(field_3_cell_options);
+    }
+
+
+    /**
+     * for cell XF types this is the parent style (usually 0/normal).  For
+     * style this should be NULL.
+     *
+     * @return index of parent XF
+     * @see #NULL
+     * @see #getCellOptions()
+     */
+
+    public short getParentIndex()
+    {
+        return _parent_index.getShortValue(field_3_cell_options);
+    }
+
+    // end bitfields in cell options
+
+    /**
+     * get the alignment options bitmask.  See corresponding bitgetter methods
+     * that reference this one.
+     *
+     *
+     * @return options     - the bitmask
+     */
+
+    public short getAlignmentOptions()
+    {
+        return field_4_alignment_options;
+    }
+
+    // bitfields in alignment options
+
+    /**
+     * get the horizontal alignment of the cell.
+     *
+     *
+     * @return align - how to align the cell (see constants)
+     * @see #GENERAL
+     * @see #LEFT
+     * @see #CENTER
+     * @see #RIGHT
+     * @see #FILL
+     * @see #JUSTIFY
+     * @see #CENTER_SELECTION
+     * @see #getAlignmentOptions()
+     */
+
+    public short getAlignment()
+    {
+        return _alignment.getShortValue(field_4_alignment_options);
+    }
+
+    /**
+     * get whether to wrap the text in the cell
+     *
+     *
+     * @return wrapped - whether or not to wrap the cell text
+     * @see #getAlignmentOptions()
+     */
+
+    public boolean getWrapText()
+    {
+        return _wrap_text.isSet(field_4_alignment_options);
+    }
+
+    /**
+     * get the vertical alignment of text in the cell
+     *
+     *
+     * @return where to align the text
+     * @see #VERTICAL_TOP
+     * @see #VERTICAL_CENTER
+     * @see #VERTICAL_BOTTOM
+     * @see #VERTICAL_JUSTIFY
+     *
+     * @see #getAlignmentOptions()
+     */
+
+    public short getVerticalAlignment()
+    {
+        return _vertical_alignment.getShortValue(field_4_alignment_options);
+    }
+
+    /**
+     * Dunno.  Docs just say this is for far east versions..  (I'm guessing it
+     * justifies for right-to-left read languages)
+     *
+     *
+     * @return justify
+     * @see #getAlignmentOptions()
+     */
+
+    public short getJustifyLast()
+    {   // for far east languages supported only for format always 0 for US
+        return _justify_last.getShortValue(field_4_alignment_options);
+    }
+
+    /**
+     * get the degree of rotation.  (I've not actually seen this used anywhere)
+     *
+     *
+     * @return rotation - the degree of rotation
+     * @see #getAlignmentOptions()
+     */
+
+    public short getRotation()
+    {
+        return _rotation.getShortValue(field_4_alignment_options);
+    }
+
+    // end alignment options bitfields
+
+    /**
+     * get the indent options bitmask  (see corresponding bit getters that reference
+     * this field)
+     *
+     *
+     * @return options bitmask
+     *
+     */
+
+    public short getIndentionOptions()
+    {
+        return field_5_indention_options;
+    }
+
+    // bitfields for indention options
+
+    /**
+     * get indention (not sure of the units, think its spaces)
+     *
+     * @return indent - how far to indent the cell
+     * @see #getIndentionOptions()
+     */
+
+    public short getIndent()
+    {
+        return _indent.getShortValue(field_5_indention_options);
+    }
+
+    /**
+     * get whether to shrink the text to fit
+     *
+     *
+     * @return shrink - shrink to fit or not
+     * @see #getIndentionOptions()
+     */
+
+    public boolean getShrinkToFit()
+    {
+        return _shrink_to_fit.isSet(field_5_indention_options);
+    }
+
+    /**
+     * get whether to merge cells
+     *
+     *
+     * @return merge - merge cells or not
+     * @see #getIndentionOptions()
+     */
+
+    public boolean getMergeCells()
+    {
+        return _merge_cells.isSet(field_5_indention_options);
+    }
+
+    /**
+     * get the reading order for far east versions (0 - Context, 1 - Left to right,
+     * 2 - right to left) - We could use some help with support for the far east.
+     *
+     * @return order - the reading order (0,1,2)
+     * @see #getIndentionOptions()
+     */
+
+    public short getReadingOrder()
+    {   // only for far east  always 0 in US
+        return _reading_order.getShortValue(field_5_indention_options);
+    }
+
+    /**
+     * get whether or not to use the format in this XF instead of the parent XF.
+     *
+     *
+     * @return parent - true if this XF has a different format value than its parent,
+     *                 false otherwise.
+     * @see #getIndentionOptions()
+     */
+
+    public boolean isIndentNotParentFormat()
+    {
+        return _indent_not_parent_format.isSet(field_5_indention_options);
+    }
+
+    /**
+     * get whether or not to use the font in this XF instead of the parent XF.
+     *
+     *
+     * @return font   - true if this XF has a different font value than its parent,
+     *                 false otherwise.
+     * @see #getIndentionOptions()
+     */
+
+    public boolean isIndentNotParentFont()
+    {
+        return _indent_not_parent_font.isSet(field_5_indention_options);
+    }
+
+    /**
+     * get whether or not to use the alignment in this XF instead of the parent XF.
+     *
+     *
+     * @return alignment true if this XF has a different alignment value than its parent,
+     *                  false otherwise.
+     * @see #getIndentionOptions()
+     */
+
+    public boolean isIndentNotParentAlignment()
+    {
+        return _indent_not_parent_alignment.isSet(field_5_indention_options);
+    }
+
+    /**
+     * get whether or not to use the border in this XF instead of the parent XF.
+     *
+     *
+     * @return border - true if this XF has a different border value than its parent,
+     *                 false otherwise.
+     * @see #getIndentionOptions()
+     */
+
+    public boolean isIndentNotParentBorder()
+    {
+        return _indent_not_parent_border.isSet(field_5_indention_options);
+    }
+
+    /**
+     * get whether or not to use the pattern in this XF instead of the parent XF.
+     * (foregrount/background)
+     *
+     * @return pattern- true if this XF has a different pattern value than its parent,
+     *                 false otherwise.
+     * @see #getIndentionOptions()
+     */
+
+    public boolean isIndentNotParentPattern()
+    {
+        return _indent_not_parent_pattern.isSet(field_5_indention_options);
+    }
+
+    /**
+     * get whether or not to use the locking/hidden in this XF instead of the parent XF.
+     *
+     *
+     * @return options- true if this XF has a different locking or hidden value than its parent,
+     *                 false otherwise.
+     * @see #getIndentionOptions()
+     */
+
+    public boolean isIndentNotParentCellOptions()
+    {
+        return _indent_not_parent_cell_options
+            .isSet(field_5_indention_options);
+    }
+
+    // end of bitfields for indention options
+    // border options
+
+    /**
+     * get the border options bitmask (see the corresponding bit getter methods
+     * that reference back to this one)
+     *
+     * @return options - the bit mask to set
+     *
+     */
+
+    public short getBorderOptions()
+    {
+        return field_6_border_options;
+    }
+
+    // bitfields for border options
+
+    /**
+     * get the borderline style for the left border
+     *
+     *
+     * @return border - type of border for the left side of the cell
+     * @see     #NONE
+     * @see     #THIN
+     * @see     #MEDIUM
+     * @see     #DASHED
+     * @see     #DOTTED
+     * @see     #THICK
+     * @see     #DOUBLE
+     * @see     #HAIR
+     * @see     #MEDIUM_DASHED
+     * @see     #DASH_DOT
+     * @see     #MEDIUM_DASH_DOT
+     * @see     #DASH_DOT_DOT
+     * @see     #MEDIUM_DASH_DOT_DOT
+     * @see     #SLANTED_DASH_DOT
+     * @see #getBorderOptions()
+     */
+
+    public short getBorderLeft()
+    {
+        return _border_left.getShortValue(field_6_border_options);
+    }
+
+    /**
+     * get the borderline style for the right border
+     *
+     *
+     * @return  border - type of border for the right side of the cell
+     * @see     #NONE
+     * @see     #THIN
+     * @see     #MEDIUM
+     * @see     #DASHED
+     * @see     #DOTTED
+     * @see     #THICK
+     * @see     #DOUBLE
+     * @see     #HAIR
+     * @see     #MEDIUM_DASHED
+     * @see     #DASH_DOT
+     * @see     #MEDIUM_DASH_DOT
+     * @see     #DASH_DOT_DOT
+     * @see     #MEDIUM_DASH_DOT_DOT
+     * @see     #SLANTED_DASH_DOT
+     * @see #getBorderOptions()
+     */
+
+    public short getBorderRight()
+    {
+        return _border_right.getShortValue(field_6_border_options);
+    }
+
+    /**
+     * get the borderline style for the top border
+     *
+     *
+     * @return border - type of border for the top of the cell
+     * @see     #NONE
+     * @see     #THIN
+     * @see     #MEDIUM
+     * @see     #DASHED
+     * @see     #DOTTED
+     * @see     #THICK
+     * @see     #DOUBLE
+     * @see     #HAIR
+     * @see     #MEDIUM_DASHED
+     * @see     #DASH_DOT
+     * @see     #MEDIUM_DASH_DOT
+     * @see     #DASH_DOT_DOT
+     * @see     #MEDIUM_DASH_DOT_DOT
+     * @see     #SLANTED_DASH_DOT
+     * @see #getBorderOptions()
+     */
+
+    public short getBorderTop()
+    {
+        return _border_top.getShortValue(field_6_border_options);
+    }
+
+    /**
+     * get the borderline style for the bottom border
+     *
+     *
+     * @return border - type of border for the bottom of the cell
+     * @see     #NONE
+     * @see     #THIN
+     * @see     #MEDIUM
+     * @see     #DASHED
+     * @see     #DOTTED
+     * @see     #THICK
+     * @see     #DOUBLE
+     * @see     #HAIR
+     * @see     #MEDIUM_DASHED
+     * @see     #DASH_DOT
+     * @see     #MEDIUM_DASH_DOT
+     * @see     #DASH_DOT_DOT
+     * @see     #MEDIUM_DASH_DOT_DOT
+     * @see     #SLANTED_DASH_DOT
+     * @see #getBorderOptions()
+     */
+
+    public short getBorderBottom()
+    {
+        return _border_bottom.getShortValue(field_6_border_options);
+    }
+
+    // record types -- palette options
+
+    /**
+     * get the palette options bitmask (see the individual bit getter methods that
+     * reference this one)
+     *
+     *
+     * @return options - the bitmask
+     *
+     */
+
+    public short getPaletteOptions()
+    {
+        return field_7_palette_options;
+    }
+
+    // bitfields for palette options
+
+    /**
+     * get the palette index for the left border color
+     *
+     *
+     * @return border - palette index
+     * @see #getPaletteOptions()
+     */
+
+    public short getLeftBorderPaletteIdx()
+    {
+        return _left_border_palette_idx
+            .getShortValue(field_7_palette_options);
+    }
+
+    /**
+     * get the palette index for the right border color
+     *
+     *
+     * @return border - palette index
+     * @see #getPaletteOptions()
+     */
+
+    public short getRightBorderPaletteIdx()
+    {
+        return _right_border_palette_idx
+            .getShortValue(field_7_palette_options);
+    }
+
+    // i've no idea.. possible values are 1 for down, 2 for up and 3 for both...0 for none..
+    // maybe a diagnal line?
+
+    /**
+     * Not sure what this is for (maybe fill lines?) 1 = down, 2 = up, 3 = both, 0 for none..
+     *
+     *
+     * @return diag - whatever it is that this is.
+     * @see #getPaletteOptions()
+     */
+
+    public short getDiag()
+    {
+        return _diag.getShortValue(field_7_palette_options);
+    }
+
+    // end of style palette options
+    // additional palette options
+
+    /**
+     * get the additional palette options bitmask (see individual bit getter methods
+     * that reference this method)
+     *
+     *
+     * @return options - bitmask to set
+     *
+     */
+
+    public int getAdtlPaletteOptions()
+    {
+        return field_8_adtl_palette_options;
+    }
+
+    // bitfields for additional palette options
+
+    /**
+     * get the palette index for the top border
+     *
+     *
+     * @return border - palette index
+     * @see #getAdtlPaletteOptions()
+     */
+
+    public short getTopBorderPaletteIdx()
+    {
+        return ( short ) _top_border_palette_idx
+            .getValue(field_8_adtl_palette_options);
+    }
+
+    /**
+     * get the palette index for the bottom border
+     *
+     *
+     * @return border - palette index
+     * @see #getAdtlPaletteOptions()
+     */
+
+    public short getBottomBorderPaletteIdx()
+    {
+        return ( short ) _bottom_border_palette_idx
+            .getValue(field_8_adtl_palette_options);
+    }
+
+    /**
+     * get for diagonal borders?  No idea (its a palette color for the other function
+     * we didn't know what was?)
+     *
+     *
+     * @return diag - the palette index?
+     * @see #getAdtlPaletteOptions()
+     */
+
+    public short getAdtlDiag()
+    {
+        return ( short ) _adtl_diag.getValue(field_8_adtl_palette_options);
+    }
+
+    /**
+     * get the diagonal border line style?  Who the heck ever heard of a diagonal border?
+     *
+     *
+     * @return diag - the line style
+     * @see     #NONE
+     * @see     #THIN
+     * @see     #MEDIUM
+     * @see     #DASHED
+     * @see     #DOTTED
+     * @see     #THICK
+     * @see     #DOUBLE
+     * @see     #HAIR
+     * @see     #MEDIUM_DASHED
+     * @see     #DASH_DOT
+     * @see     #MEDIUM_DASH_DOT
+     * @see     #DASH_DOT_DOT
+     * @see     #MEDIUM_DASH_DOT_DOT
+     * @see     #SLANTED_DASH_DOT
+     * @see #getAdtlPaletteOptions()
+     */
+
+    public short getAdtlDiagLineStyle()
+    {
+        return ( short ) _adtl_diag_line_style
+            .getValue(field_8_adtl_palette_options);
+    }
+
+    /**
+     * get the additional fill pattern
+     *
+     * @see #NO_FILL
+     * @see #SOLID_FILL
+     * @see #FINE_DOTS
+     * @see #ALT_BARS
+     * @see #SPARSE_DOTS
+     * @see #THICK_HORZ_BANDS
+     * @see #THICK_VERT_BANDS
+     * @see #THICK_BACKWARD_DIAG
+     * @see #THICK_FORWARD_DIAG
+     * @see #BIG_SPOTS
+     * @see #BRICKS
+     * @see #THIN_HORZ_BANDS
+     * @see #THIN_VERT_BANDS
+     * @see #THIN_BACKWARD_DIAG
+     * @see #THIN_FORWARD_DIAG
+     * @see #SQUARES
+     * @see #DIAMONDS
+     *
+     * @return fill - fill pattern??
+     * @see #getAdtlPaletteOptions()
+     */
+
+    public short getAdtlFillPattern()
+    {
+        return ( short ) _adtl_fill_pattern
+            .getValue(field_8_adtl_palette_options);
+    }
+
+    // end bitfields for additional palette options
+    // fill palette options
+
+    /**
+     * get the fill palette options bitmask (see indivdual bit getters that
+     * reference this method)
+     *
+     * @return options
+     *
+     */
+
+    public short getFillPaletteOptions()
+    {
+        return field_9_fill_palette_options;
+    }
+
+    // bitfields for fill palette options
+
+    /**
+     * get the foreground palette color index
+     *
+     *
+     * @return color - palette index
+     * @see #getFillPaletteOptions()
+     */
+
+    public short getFillForeground()
+    {
+        return _fill_foreground.getShortValue(field_9_fill_palette_options);
+    }
+
+    /**
+     * get the background palette color index
+     *
+     * @return color palette index
+     * @see #getFillPaletteOptions()
+     */
+
+    public short getFillBackground()
+    {
+        return _fill_background.getShortValue(field_9_fill_palette_options);
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[EXTENDEDFORMAT]\n");
+        if (getXFType() == XF_STYLE)
+        {
+            buffer.append(" STYLE_RECORD_TYPE\n");
+        }
+        else if (getXFType() == XF_CELL)
+        {
+            buffer.append(" CELL_RECORD_TYPE\n");
+        }
+        buffer.append("    .fontindex       = ")
+            .append(Integer.toHexString(getFontIndex())).append("\n");
+        buffer.append("    .formatindex     = ")
+            .append(Integer.toHexString(getFormatIndex())).append("\n");
+        buffer.append("    .celloptions     = ")
+            .append(Integer.toHexString(getCellOptions())).append("\n");
+        buffer.append("          .islocked  = ").append(isLocked())
+            .append("\n");
+        buffer.append("          .ishidden  = ").append(isHidden())
+            .append("\n");
+        buffer.append("          .recordtype= ")
+            .append(Integer.toHexString(getXFType())).append("\n");
+        buffer.append("          .parentidx = ")
+            .append(Integer.toHexString(getParentIndex())).append("\n");
+        buffer.append("    .alignmentoptions= ")
+            .append(Integer.toHexString(getAlignmentOptions())).append("\n");
+        buffer.append("          .alignment = ").append(getAlignment())
+            .append("\n");
+        buffer.append("          .wraptext  = ").append(getWrapText())
+            .append("\n");
+        buffer.append("          .valignment= ")
+            .append(Integer.toHexString(getVerticalAlignment())).append("\n");
+        buffer.append("          .justlast  = ")
+            .append(Integer.toHexString(getJustifyLast())).append("\n");
+        buffer.append("          .rotation  = ")
+            .append(Integer.toHexString(getRotation())).append("\n");
+        buffer.append("    .indentionoptions= ")
+            .append(Integer.toHexString(getIndentionOptions())).append("\n");
+        buffer.append("          .indent    = ")
+            .append(Integer.toHexString(getIndent())).append("\n");
+        buffer.append("          .shrinktoft= ").append(getShrinkToFit())
+            .append("\n");
+        buffer.append("          .mergecells= ").append(getMergeCells())
+            .append("\n");
+        buffer.append("          .readngordr= ")
+            .append(Integer.toHexString(getReadingOrder())).append("\n");
+        buffer.append("          .formatflag= ")
+            .append(isIndentNotParentFormat()).append("\n");
+        buffer.append("          .fontflag  = ")
+            .append(isIndentNotParentFont()).append("\n");
+        buffer.append("          .prntalgnmt= ")
+            .append(isIndentNotParentAlignment()).append("\n");
+        buffer.append("          .borderflag= ")
+            .append(isIndentNotParentBorder()).append("\n");
+        buffer.append("          .paternflag= ")
+            .append(isIndentNotParentPattern()).append("\n");
+        buffer.append("          .celloption= ")
+            .append(isIndentNotParentCellOptions()).append("\n");
+        buffer.append("    .borderoptns     = ")
+            .append(Integer.toHexString(getBorderOptions())).append("\n");
+        buffer.append("          .lftln     = ")
+            .append(Integer.toHexString(getBorderLeft())).append("\n");
+        buffer.append("          .rgtln     = ")
+            .append(Integer.toHexString(getBorderRight())).append("\n");
+        buffer.append("          .topln     = ")
+            .append(Integer.toHexString(getBorderTop())).append("\n");
+        buffer.append("          .btmln     = ")
+            .append(Integer.toHexString(getBorderBottom())).append("\n");
+        buffer.append("    .paleteoptns     = ")
+            .append(Integer.toHexString(getPaletteOptions())).append("\n");
+        buffer.append("          .leftborder= ")
+            .append(Integer.toHexString(getLeftBorderPaletteIdx()))
+            .append("\n");
+        buffer.append("          .rghtborder= ")
+            .append(Integer.toHexString(getRightBorderPaletteIdx()))
+            .append("\n");
+        buffer.append("          .diag      = ")
+            .append(Integer.toHexString(getDiag())).append("\n");
+        buffer.append("    .paleteoptn2     = ")
+            .append(Integer.toHexString(getAdtlPaletteOptions()))
+            .append("\n");
+        buffer.append("          .topborder = ")
+            .append(Integer.toHexString(getTopBorderPaletteIdx()))
+            .append("\n");
+        buffer.append("          .botmborder= ")
+            .append(Integer.toHexString(getBottomBorderPaletteIdx()))
+            .append("\n");
+        buffer.append("          .adtldiag  = ")
+            .append(Integer.toHexString(getAdtlDiag())).append("\n");
+        buffer.append("          .diaglnstyl= ")
+            .append(Integer.toHexString(getAdtlDiagLineStyle())).append("\n");
+        buffer.append("          .fillpattrn= ")
+            .append(Integer.toHexString(getAdtlFillPattern())).append("\n");
+        buffer.append("    .fillpaloptn     = ")
+            .append(Integer.toHexString(getFillPaletteOptions()))
+            .append("\n");
+        buffer.append("          .foreground= ")
+            .append(Integer.toHexString(getFillForeground())).append("\n");
+        buffer.append("          .background= ")
+            .append(Integer.toHexString(getFillBackground())).append("\n");
+        buffer.append("[/EXTENDEDFORMAT]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(getFontIndex());
+        out.writeShort(getFormatIndex());
+        out.writeShort(getCellOptions());
+        out.writeShort(getAlignmentOptions());
+        out.writeShort(getIndentionOptions());
+        out.writeShort(getBorderOptions());
+        out.writeShort(getPaletteOptions());
+        out.writeInt(getAdtlPaletteOptions());
+        out.writeShort(getFillPaletteOptions());
+    }
+
+    protected int getDataSize() {
+        return 20;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+    
+
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + field_1_font_index;
+		result = prime * result + field_2_format_index;
+		result = prime * result + field_3_cell_options;
+		result = prime * result + field_4_alignment_options;
+		result = prime * result + field_5_indention_options;
+		result = prime * result + field_6_border_options;
+		result = prime * result + field_7_palette_options;
+		result = prime * result + field_8_adtl_palette_options;
+		result = prime * result + field_9_fill_palette_options;
+		return result;
+	}
+
+	/**
+	 * Will consider two different records with the same
+	 *  contents as equals, as the various indexes
+	 *  that matter are embedded in the records
+	 */
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (obj instanceof ExtendedFormatRecord) {
+			final ExtendedFormatRecord other = (ExtendedFormatRecord) obj;
+			if (field_1_font_index != other.field_1_font_index)
+				return false;
+			if (field_2_format_index != other.field_2_format_index)
+				return false;
+			if (field_3_cell_options != other.field_3_cell_options)
+				return false;
+			if (field_4_alignment_options != other.field_4_alignment_options)
+				return false;
+			if (field_5_indention_options != other.field_5_indention_options)
+				return false;
+			if (field_6_border_options != other.field_6_border_options)
+				return false;
+			if (field_7_palette_options != other.field_7_palette_options)
+				return false;
+			if (field_8_adtl_palette_options != other.field_8_adtl_palette_options)
+				return false;
+			if (field_9_fill_palette_options != other.field_9_fill_palette_options)
+				return false;
+			return true;
+		}
+		return false;
+	}
+    
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ExternSheetRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ExternSheetRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ExternSheetRecord.java	(revision 28000)
@@ -0,0 +1,174 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * EXTERNSHEET (0x0017)<br/>
+ * A List of Indexes to  EXTERNALBOOK (supplemental book) Records <p/>
+ * 
+ * @author Libin Roman (Vista Portal LDT. Developer)
+ */
+public class ExternSheetRecord extends StandardRecord {
+	public final static short sid = 0x0017;
+	private List<RefSubRecord> _list;
+	
+	private static final class RefSubRecord {
+		public static final int ENCODED_SIZE = 6;
+
+		/** index to External Book Block (which starts with a EXTERNALBOOK record) */
+		private int _extBookIndex;
+		private int _firstSheetIndex; // may be -1 (0xFFFF)
+		private int _lastSheetIndex;  // may be -1 (0xFFFF)
+		
+		
+		/** a Constructor for making new sub record
+		 */
+		public RefSubRecord(int extBookIndex, int firstSheetIndex, int lastSheetIndex) {
+			_extBookIndex = extBookIndex;
+			_firstSheetIndex = firstSheetIndex;
+			_lastSheetIndex = lastSheetIndex;
+		}
+		
+		/**
+		 * @param in the RecordInputstream to read the record from
+		 */
+		public RefSubRecord(RecordInputStream in) {
+			this(in.readShort(), in.readShort(), in.readShort());
+		}
+		public int getExtBookIndex(){
+			return _extBookIndex;
+		}
+		public int getFirstSheetIndex(){
+			return _firstSheetIndex;
+		}
+		
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append("extBook=").append(_extBookIndex);
+			buffer.append(" firstSheet=").append(_firstSheetIndex);
+			buffer.append(" lastSheet=").append(_lastSheetIndex);
+			return buffer.toString();
+		}
+		
+		public void serialize(LittleEndianOutput out) {
+			out.writeShort(_extBookIndex);
+			out.writeShort(_firstSheetIndex);
+			out.writeShort(_lastSheetIndex);
+		}
+	}	
+	
+	
+	
+	public ExternSheetRecord() {
+		_list = new ArrayList<RefSubRecord>();
+	}
+
+	public ExternSheetRecord(RecordInputStream in) { // NO_UCD
+		_list = new ArrayList<RefSubRecord>();
+		
+		int nItems  = in.readShort();
+		
+		for (int i = 0 ; i < nItems ; ++i) {
+			RefSubRecord rec = new RefSubRecord(in);
+			_list.add(rec);
+		}
+	}
+
+	
+	/** 
+	 * adds REF struct (ExternSheetSubRecord)
+	 * @param rec REF struct
+	 */
+	public void addREFRecord(RefSubRecord rec) {
+		_list.add(rec);
+	}
+	
+	/** returns the number of REF Records, which is in model
+	 * @return number of REF records
+	 */
+	public int getNumOfREFRecords() {
+		return _list.size();
+	}
+	
+	
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		int nItems = _list.size();
+		sb.append("[EXTERNSHEET]\n");
+		sb.append("   numOfRefs     = ").append(nItems).append("\n");
+		for (int i=0; i < nItems; i++) {
+			sb.append("refrec         #").append(i).append(": ");
+			sb.append(getRef(i).toString());
+			sb.append('\n');
+		}
+		sb.append("[/EXTERNSHEET]\n");
+		
+		
+		return sb.toString();
+	}
+	
+	protected int getDataSize() {
+		return 2 + _list.size() * RefSubRecord.ENCODED_SIZE;
+	}
+	
+	public void serialize(LittleEndianOutput out) {
+		int nItems = _list.size();
+
+		out.writeShort(nItems);
+		
+		for (int i = 0; i < nItems; i++) {
+			getRef(i).serialize(out);
+		}
+	}
+
+	private RefSubRecord getRef(int i) {
+		return _list.get(i);
+	}
+	
+	/**
+	 * return the non static version of the id for this record.
+	 */
+	public short getSid() {
+		return sid;
+	}
+
+	public int getExtbookIndexFromRefIndex(int refIndex) {
+		return getRef(refIndex).getExtBookIndex();
+	}
+
+	public int getFirstSheetIndexFromRefIndex(int extRefIndex) {
+		return getRef(extRefIndex).getFirstSheetIndex();
+	}
+
+	public static ExternSheetRecord combine(ExternSheetRecord[] esrs) {
+		ExternSheetRecord result = new ExternSheetRecord();
+		for (int i = 0; i < esrs.length; i++) {
+			ExternSheetRecord esr = esrs[i];
+			int nRefs = esr.getNumOfREFRecords();
+			for (int j=0; j<nRefs; j++) {
+				result.addREFRecord(esr.getRef(j));
+			}
+		}
+		return result;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ExternalNameRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ExternalNameRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ExternalNameRecord.java	(revision 28000)
@@ -0,0 +1,167 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.constant.ConstantValueParser;
+import org.apache.poi.ss.formula.Formula;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * EXTERNALNAME (0x0023)<p/>
+ *
+ * @author Josh Micich
+ */
+public final class ExternalNameRecord extends StandardRecord {
+
+	public final static short sid = 0x0023; // as per BIFF8. (some old versions used 0x223)
+
+	private static final int OPT_AUTOMATIC_LINK        = 0x0002; // m$ doc calls this fWantAdvise
+	private static final int OPT_STD_DOCUMENT_NAME     = 0x0008; //fOle
+	private static final int OPT_OLE_LINK              = 0x0010; //fOleLink
+//	private static final int OPT_CLIP_FORMAT_MASK      = 0x7FE0;
+
+
+	private short  field_1_option_flag;
+	private short  field_2_ixals;
+	private short  field_3_not_used;
+	private String field_4_name;
+	private Formula  field_5_name_definition;
+
+	/**
+	 * 'rgoper' / 'Last received results of the DDE link'
+	 * (seems to be only applicable to DDE links)<br/>
+	 * Logically this is a 2-D array, which has been flattened into 1-D array here.
+	 */
+	private Object[] _ddeValues;
+	/**
+	 * (logical) number of columns in the {@link #_ddeValues} array
+	 */
+	private int _nColumns;
+	/**
+	 * (logical) number of rows in the {@link #_ddeValues} array
+	 */
+	private int _nRows;
+
+
+	/**
+	 * For OLE and DDE, links can be either 'automatic' or 'manual'
+	 */
+	public boolean isAutomaticLink() {
+		return (field_1_option_flag & OPT_AUTOMATIC_LINK) != 0;
+	}
+
+	/**
+	 * DDE links only. If <code>true</code>, this denotes the 'StdDocumentName'
+	 */
+	public boolean isStdDocumentNameIdentifier() {
+		return (field_1_option_flag & OPT_STD_DOCUMENT_NAME) != 0;
+	}
+	public boolean isOLELink() {
+		return (field_1_option_flag & OPT_OLE_LINK) != 0;
+	}
+
+	/**
+	 * @return the standard String representation of this name
+	 */
+	public String getText() {
+		return field_4_name;
+	}
+	
+
+	protected int getDataSize(){
+		int result = 2 + 4;  // short and int
+        result += StringUtil.getEncodedSize(field_4_name) - 1; //size is byte, not short 
+
+        if(!isOLELink() && !isStdDocumentNameIdentifier()){
+            if(isAutomaticLink()){
+                result += 3; // byte, short
+                result += ConstantValueParser.getEncodedSize(_ddeValues);
+            } else {
+                result += field_5_name_definition.getEncodedSize();
+            }
+        }
+		return result;
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		out.writeShort(field_1_option_flag);
+		out.writeShort(field_2_ixals);
+		out.writeShort(field_3_not_used);
+
+		out.writeByte(field_4_name.length());
+		StringUtil.writeUnicodeStringFlagAndData(out, field_4_name);
+
+        if(!isOLELink() && !isStdDocumentNameIdentifier()){
+            if(isAutomaticLink()){
+                out.writeByte(_nColumns-1);
+                out.writeShort(_nRows-1);
+                ConstantValueParser.encode(out, _ddeValues);
+            } else {
+                field_5_name_definition.serialize(out);
+            }
+        }
+	}
+
+
+	public ExternalNameRecord(RecordInputStream in) { // NO_UCD
+		field_1_option_flag = in.readShort();
+		field_2_ixals       = in.readShort();
+      field_3_not_used    = in.readShort();
+
+        int numChars = in.readUByte();
+        field_4_name = StringUtil.readUnicodeString(in, numChars);
+
+        // the record body can take different forms.
+        // The form is dictated by the values of 3-th and 4-th bits in field_1_option_flag
+        if(!isOLELink() && !isStdDocumentNameIdentifier()){
+            // another switch: the fWantAdvise bit specifies whether the body describes
+            // an external defined name or a DDE data item
+            if(isAutomaticLink()){
+                //body specifies DDE data item
+                int nColumns = in.readUByte() + 1;
+                int nRows = in.readShort() + 1;
+
+                int totalCount = nRows * nColumns;
+                _ddeValues = ConstantValueParser.parse(in, totalCount);
+                _nColumns = nColumns;
+                _nRows = nRows;
+            } else {
+                //body specifies an external defined name
+                int formulaLen = in.readUShort();
+                field_5_name_definition = Formula.read(formulaLen, in);
+            }
+        }
+    }
+
+	public short getSid() {
+		return sid;
+	}
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append("[EXTERNALNAME]\n");
+		sb.append("    .ix      = ").append(field_2_ixals).append("\n");
+		sb.append("    .name    = ").append(field_4_name).append("\n");
+		if(field_5_name_definition != null) {
+		sb.append("    .formula = ").append(field_5_name_definition).append("\n");
+		}
+		sb.append("[/EXTERNALNAME]\n");
+		return sb.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FeatHdrRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FeatHdrRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FeatHdrRecord.java	(revision 28000)
@@ -0,0 +1,105 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.common.FtrHeader;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: FeatHdr (Feature Header) Record
+ * <P>
+ * This record specifies common information for Shared Features, and 
+ *  specifies the beginning of a collection of records to define them. 
+ * The collection of data (Globals Substream ABNF, macro sheet substream 
+ *  ABNF or worksheet substream ABNF) specifies Shared Feature data.
+ */
+public final class FeatHdrRecord extends StandardRecord  {
+	/**
+	 * Specifies that formula errors should be ignored 
+	 */
+	public static final int SHAREDFEATURES_ISFFEC2       = 0x03;
+	/**
+	 * Specifies the smart tag type. Recognises certain
+	 * types of entries (proper names, dates/times etc) and
+	 * flags them for action 
+	 */
+	public static final int SHAREDFEATURES_ISFFACTOID    = 0x04;
+
+	
+	public final static short sid = 0x0867;
+
+	private FtrHeader futureHeader;
+	private int isf_sharedFeatureType; // See SHAREDFEATURES_
+	private byte reserved; // Should always be one
+	/** 
+	 * 0x00000000 = rgbHdrData not present
+	 * 0xffffffff = rgbHdrData present
+	 */
+	private long cbHdrData;
+	/** We need a BOFRecord to make sense of this... */
+	private byte[] rgbHdrData;
+
+	public FeatHdrRecord() {
+		futureHeader = new FtrHeader();
+		futureHeader.setRecordType(sid);
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	public FeatHdrRecord(RecordInputStream in) { // NO_UCD
+		futureHeader = new FtrHeader(in);
+		
+		isf_sharedFeatureType = in.readShort();
+		reserved = in.readByte();
+		cbHdrData = in.readInt();
+		// Don't process this just yet, need the BOFRecord
+		rgbHdrData = in.readRemainder();
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("[FEATURE HEADER]\n");
+		
+		// TODO ...
+		
+		buffer.append("[/FEATURE HEADER]\n");
+		return buffer.toString();
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		futureHeader.serialize(out);
+		
+		out.writeShort(isf_sharedFeatureType);
+		out.writeByte(reserved);
+		out.writeInt((int)cbHdrData);
+		out.write(rgbHdrData);
+	}
+
+	protected int getDataSize() {
+		return 12 + 2+1+4+rgbHdrData.length;
+	}
+    
+    //HACK: do a "cheat" clone, see Record.java for more information
+    public Object clone() {
+        return cloneViaReserialise();
+    }
+
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FeatRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FeatRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FeatRecord.java	(revision 28000)
@@ -0,0 +1,134 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.common.FeatFormulaErr2;
+import org.apache.poi.hssf.record.common.FeatSmartTag;
+import org.apache.poi.hssf.record.common.FtrHeader;
+import org.apache.poi.hssf.record.common.SharedFeature;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: Feat (Feature) Record
+ * <P>
+ * This record specifies Shared Features data. It is normally paired
+ *  up with a {@link FeatHdrRecord}.
+ */
+public final class FeatRecord extends StandardRecord  {
+	public final static short sid = 0x0868;
+	
+	private FtrHeader futureHeader;
+	
+	/**
+	 * See SHAREDFEATURES_* on {@link FeatHdrRecord}
+	 */
+	private int isf_sharedFeatureType; 
+	private byte reserved1; // Should always be zero
+	private long reserved2; // Should always be zero
+	/** Only matters if type is ISFFEC2 */
+	private long cbFeatData;
+	private int reserved3; // Should always be zero
+	private CellRangeAddress[] cellRefs;
+
+	/**
+	 * Contents depends on isf_sharedFeatureType :
+	 *  ISFPROTECTION -> FeatProtection 
+	 *  ISFFEC2       -> FeatFormulaErr2
+	 *  ISFFACTOID    -> FeatSmartTag
+	 */
+	private SharedFeature sharedFeature; 
+	
+	public FeatRecord() {
+		futureHeader = new FtrHeader();
+		futureHeader.setRecordType(sid);
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	public FeatRecord(RecordInputStream in) { // NO_UCD
+		futureHeader = new FtrHeader(in);
+		
+		isf_sharedFeatureType = in.readShort();
+		reserved1 = in.readByte();
+		reserved2 = in.readInt();
+		int cref = in.readUShort();
+		cbFeatData = in.readInt();
+		reserved3 = in.readShort();
+
+		cellRefs = new CellRangeAddress[cref];
+		for(int i=0; i<cellRefs.length; i++) {
+			cellRefs[i] = new CellRangeAddress(in);
+		}
+		
+		switch(isf_sharedFeatureType) {
+		case FeatHdrRecord.SHAREDFEATURES_ISFFEC2:
+			sharedFeature = new FeatFormulaErr2(in);
+			break;
+		case FeatHdrRecord.SHAREDFEATURES_ISFFACTOID:
+			sharedFeature = new FeatSmartTag(in);
+			break;
+		default:
+			System.err.println("Unknown Shared Feature " + isf_sharedFeatureType + " found!");
+		}
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("[SHARED FEATURE]\n");
+		
+		// TODO ...
+		
+		buffer.append("[/SHARED FEATURE]\n");
+		return buffer.toString();
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		futureHeader.serialize(out);
+		
+		out.writeShort(isf_sharedFeatureType);
+		out.writeByte(reserved1);
+		out.writeInt((int)reserved2);
+		out.writeShort(cellRefs.length);
+		out.writeInt((int)cbFeatData);
+		out.writeShort(reserved3);
+		
+		for(int i=0; i<cellRefs.length; i++) {
+			cellRefs[i].serialize(out);
+		}
+		
+		sharedFeature.serialize(out);
+	}
+
+	protected int getDataSize() {
+		return 12 + 2+1+4+2+4+2+
+			(cellRefs.length * CellRangeAddress.ENCODED_SIZE)
+			+sharedFeature.getDataSize();
+	}
+
+
+    
+    //HACK: do a "cheat" clone, see Record.java for more information
+    public Object clone() {
+        return cloneViaReserialise();
+    }
+
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FilePassRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FilePassRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FilePassRecord.java	(revision 28000)
@@ -0,0 +1,122 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: File Pass Record (0x002F) <p/>
+ *
+ * Description: Indicates that the record after this record are encrypted.
+ *
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class FilePassRecord extends StandardRecord {
+	public final static short sid = 0x002F;
+	private int _encryptionType;
+	private int _encryptionInfo;
+	private int _minorVersionNo;
+	private byte[] _docId;
+	private byte[] _saltData;
+	private byte[] _saltHash;
+	
+	private static final int ENCRYPTION_XOR = 0;
+	private static final int ENCRYPTION_OTHER = 1;
+
+	private static final int ENCRYPTION_OTHER_RC4 = 1;
+	private static final int ENCRYPTION_OTHER_CAPI_2 = 2;
+	private static final int ENCRYPTION_OTHER_CAPI_3 = 3;
+
+
+	public FilePassRecord(RecordInputStream in) { // NO_UCD
+		_encryptionType = in.readUShort();
+
+		switch (_encryptionType) {
+			case ENCRYPTION_XOR:
+				throw new RecordFormatException("HSSF does not currently support XOR obfuscation");
+			case ENCRYPTION_OTHER:
+				// handled below
+				break;
+			default:
+				throw new RecordFormatException("Unknown encryption type " + _encryptionType);
+		}
+		_encryptionInfo = in.readUShort();
+		switch (_encryptionInfo) {
+			case ENCRYPTION_OTHER_RC4:
+				// handled below
+				break;
+			case ENCRYPTION_OTHER_CAPI_2:
+			case ENCRYPTION_OTHER_CAPI_3:
+				throw new RecordFormatException(
+						"HSSF does not currently support CryptoAPI encryption");
+			default:
+				throw new RecordFormatException("Unknown encryption info " + _encryptionInfo);
+		}
+		_minorVersionNo = in.readUShort();
+		if (_minorVersionNo!=1) {
+			throw new RecordFormatException("Unexpected VersionInfo number for RC4Header " + _minorVersionNo);
+		}
+		_docId = read(in, 16);
+		_saltData = read(in, 16);
+		_saltHash = read(in, 16);
+	}
+	
+	private static byte[] read(RecordInputStream in, int size) {
+		byte[] result = new byte[size];
+		in.readFully(result);
+		return result;
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		out.writeShort(_encryptionType);
+		out.writeShort(_encryptionInfo);
+		out.writeShort(_minorVersionNo);
+		out.write(_docId);
+		out.write(_saltData);
+		out.write(_saltHash);
+	}
+
+	protected int getDataSize() {
+		return 54;
+	}
+
+
+	public short getSid() {
+		return sid;
+	}
+
+	public Object clone() {
+		// currently immutable
+		return this;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+
+		buffer.append("[FILEPASS]\n");
+		buffer.append("    .type = ").append(HexDump.shortToHex(_encryptionType)).append("\n");
+		buffer.append("    .info = ").append(HexDump.shortToHex(_encryptionInfo)).append("\n");
+		buffer.append("    .ver  = ").append(HexDump.shortToHex(_minorVersionNo)).append("\n");
+		buffer.append("    .docId= ").append(HexDump.toHex(_docId)).append("\n");
+		buffer.append("    .salt = ").append(HexDump.toHex(_saltData)).append("\n");
+		buffer.append("    .hash = ").append(HexDump.toHex(_saltHash)).append("\n");
+		buffer.append("[/FILEPASS]\n");
+		return buffer.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FormatRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FormatRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FormatRecord.java	(revision 28000)
@@ -0,0 +1,106 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * Title:        Format Record (0x041E) <p/>
+ * Description:  describes a number format -- those goofy strings like $(#,###)<p/>
+ *
+ * REFERENCE:  PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Shawn M. Laubach (slaubach at apache dot org)
+ */
+public final class FormatRecord extends StandardRecord {
+    public final static short sid = 0x041E;
+
+    private final int field_1_index_code;
+    private final boolean field_3_hasMultibyte;
+    private final String field_4_formatstring;
+
+    public FormatRecord(RecordInputStream in) { // NO_UCD
+        field_1_index_code = in.readShort();
+        int field_3_unicode_len = in.readUShort();
+        field_3_hasMultibyte = (in.readByte() & 0x01) != 0;
+
+        if (field_3_hasMultibyte) {
+            field_4_formatstring = in.readUnicodeLEString(field_3_unicode_len);
+        } else {
+            field_4_formatstring = in.readCompressedUnicode(field_3_unicode_len);
+        }
+    }
+
+    /**
+     * get the format index code (for built in formats)
+     *
+     * @return the format index code
+     * @see org.apache.poi.hssf.model.InternalWorkbook
+     */
+    public int getIndexCode() {
+        return field_1_index_code;
+    }
+
+    /**
+     * get the format string
+     *
+     * @return the format string
+     */
+    public String getFormatString() {
+        return field_4_formatstring;
+    }
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[FORMAT]\n");
+        buffer.append("    .indexcode       = ").append(HexDump.shortToHex(getIndexCode())).append("\n");
+        buffer.append("    .isUnicode       = ").append(field_3_hasMultibyte ).append("\n");
+        buffer.append("    .formatstring    = ").append(getFormatString()).append("\n");
+        buffer.append("[/FORMAT]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        String formatString = getFormatString();
+        out.writeShort(getIndexCode());
+        out.writeShort(formatString.length());
+        out.writeByte(field_3_hasMultibyte ? 0x01 : 0x00);
+
+      if ( field_3_hasMultibyte ) {
+          StringUtil.putUnicodeLE( formatString, out);
+      }  else {
+          StringUtil.putCompressedUnicode( formatString, out);
+      }
+    }
+    protected int getDataSize() {
+        return 5 // 2 shorts + 1 byte
+            + getFormatString().length() * (field_3_hasMultibyte ? 2 : 1);
+    }
+
+    public short getSid() {
+        return sid;
+    }
+    @Override
+    public Object clone() {
+        // immutable
+        return this;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FormulaRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FormulaRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FormulaRecord.java	(revision 28000)
@@ -0,0 +1,336 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.ss.formula.Formula;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Formula Record (0x0006).
+ * REFERENCE:  PG 317/444 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class FormulaRecord extends CellRecord {
+
+	public static final short sid = 0x0006;   // docs say 406...because of a bug Microsoft support site article #Q184647)
+	private static int FIXED_SIZE = 14; // double + short + int
+
+	private static final BitField alwaysCalc = BitFieldFactory.getInstance(0x0001);
+	private static final BitField calcOnLoad = BitFieldFactory.getInstance(0x0002);
+	private static final BitField sharedFormula = BitFieldFactory.getInstance(0x0008);
+
+	/**
+	 * Manages the cached formula result values of other types besides numeric.
+	 * Excel encodes the same 8 bytes that would be field_4_value with various NaN
+	 * values that are decoded/encoded by this class. 
+	 */
+	private static final class SpecialCachedValue {
+		/** deliberately chosen by Excel in order to encode other values within Double NaNs */
+		private static final long BIT_MARKER = 0xFFFF000000000000L;
+		private static final int VARIABLE_DATA_LENGTH = 6;
+		private static final int DATA_INDEX = 2;
+
+		public static final int STRING = 0;
+		public static final int BOOLEAN = 1;
+		public static final int ERROR_CODE = 2;
+		public static final int EMPTY = 3;
+
+		private final byte[] _variableData;
+
+		private SpecialCachedValue(byte[] data) {
+			_variableData = data;
+		}
+		public int getTypeCode() {
+			return _variableData[0];
+		}
+
+		/**
+		 * @return <code>null</code> if the double value encoded by <tt>valueLongBits</tt> 
+		 * is a normal (non NaN) double value.
+		 */
+		public static SpecialCachedValue create(long valueLongBits) {
+			if ((BIT_MARKER & valueLongBits) != BIT_MARKER) {
+				return null;
+			}
+
+			byte[] result = new byte[VARIABLE_DATA_LENGTH];
+			long x = valueLongBits;
+			for (int i=0; i<VARIABLE_DATA_LENGTH; i++) {
+				result[i] = (byte) x;
+				x >>= 8;
+			}
+			switch (result[0]) {
+				case STRING:
+				case BOOLEAN:
+				case ERROR_CODE:
+				case EMPTY:
+					break;
+				default:
+					throw new RecordFormatException("Bad special value code (" + result[0] + ")");
+			}
+			return new SpecialCachedValue(result);
+		}
+		public void serialize(LittleEndianOutput out) {
+			out.write(_variableData);
+			out.writeShort(0xFFFF);
+		}
+		public String formatDebugString() {
+			return formatValue() + ' ' + HexDump.toHex(_variableData);
+		}
+		private String formatValue() {
+			int typeCode = getTypeCode();
+			switch (typeCode) {
+				case STRING:	 return "<string>";
+				case BOOLEAN:	return getDataValue() == 0 ? "FALSE" : "TRUE";
+				case ERROR_CODE: return ErrorEval.getText(getDataValue());
+				case EMPTY:	  return "<empty>";
+			}
+			return "#error(type=" + typeCode + ")#";
+		}
+		private int getDataValue() {
+			return _variableData[DATA_INDEX];
+		}
+		public String toString() {
+			StringBuffer sb = new StringBuffer(64);
+			sb.append(getClass().getName());
+			sb.append('[').append(formatValue()).append(']');
+			return sb.toString();
+		}
+		public int getValueType() {
+			int typeCode = getTypeCode();
+			switch (typeCode) {
+				case STRING:	 return HSSFCell.CELL_TYPE_STRING;
+				case BOOLEAN:	return HSSFCell.CELL_TYPE_BOOLEAN;
+				case ERROR_CODE: return HSSFCell.CELL_TYPE_ERROR;
+				case EMPTY:	  return HSSFCell.CELL_TYPE_STRING; // is this correct?
+			}
+			throw new IllegalStateException("Unexpected type id (" + typeCode + ")");
+		}
+		public boolean getBooleanValue() {
+			if (getTypeCode() != BOOLEAN) {
+				throw new IllegalStateException("Not a boolean cached value - " + formatValue());
+			}
+			return getDataValue() != 0;
+		}
+		public int getErrorValue() {
+			if (getTypeCode() != ERROR_CODE) {
+				throw new IllegalStateException("Not an error cached value - " + formatValue());
+			}
+			return getDataValue();
+		}
+	}
+
+	private double field_4_value;
+	private short  field_5_options;
+	/**
+	 * Unused field.  As it turns out this field is often not zero..
+	 * According to Microsoft Excel Developer's Kit Page 318:
+	 * when writing the chn field (offset 20), it's supposed to be 0 but ignored on read
+	 */
+	private int field_6_zero;
+	private Formula field_8_parsed_expr;
+
+	/**
+	 * Since the NaN support seems sketchy (different constants) we'll store and spit it out directly
+	 */
+	private SpecialCachedValue specialCachedValue;
+
+	/** Creates new FormulaRecord */
+
+	public FormulaRecord() {
+		field_8_parsed_expr = Formula.create(Ptg.EMPTY_PTG_ARRAY);
+	}
+
+	public FormulaRecord(RecordInputStream ris) { // NO_UCD
+		super(ris);
+		LittleEndianInput in = ris;
+		long valueLongBits  = in.readLong();
+		field_5_options = in.readShort();
+		specialCachedValue = SpecialCachedValue.create(valueLongBits);
+		if (specialCachedValue == null) {
+			field_4_value = Double.longBitsToDouble(valueLongBits);
+		}
+
+		field_6_zero = in.readInt();
+
+		int field_7_expression_len = in.readShort(); // this length does not include any extra array data
+		int nBytesAvailable = in.available();
+		field_8_parsed_expr = Formula.read(field_7_expression_len, in, nBytesAvailable);
+	}
+
+	/**
+	 * set the calculated value of the formula
+	 *
+	 * @param value  calculated value
+	 */
+	public void setValue(double value) {
+		field_4_value = value;
+		specialCachedValue = null;
+	}
+
+	/**
+	 * @return <code>true</code> if this {@link FormulaRecord} is followed by a
+	 *  {@link StringRecord} representing the cached text result of the formula
+	 *  evaluation.
+	 */
+	public boolean hasCachedResultString() {
+		if (specialCachedValue == null) {
+			return false;
+		}
+		return specialCachedValue.getTypeCode() == SpecialCachedValue.STRING;
+	}
+
+	public int getCachedResultType() {
+		if (specialCachedValue == null) {
+			return HSSFCell.CELL_TYPE_NUMERIC;
+		}
+		return specialCachedValue.getValueType();
+	}
+
+	public boolean getCachedBooleanValue() {
+		return specialCachedValue.getBooleanValue();
+	}
+	public int getCachedErrorValue() {
+		return specialCachedValue.getErrorValue();
+	}
+
+
+	/**
+	 * get the calculated value of the formula
+	 *
+	 * @return calculated value
+	 */
+	public double getValue() {
+		return field_4_value;
+	}
+
+	/**
+	 * get the option flags
+	 *
+	 * @return bitmask
+	 */
+	public short getOptions() {
+		return field_5_options;
+	}
+
+	public boolean isSharedFormula() {
+		return sharedFormula.isSet(field_5_options);
+	}
+	public void setSharedFormula(boolean flag) {
+		field_5_options =
+			sharedFormula.setShortBoolean(field_5_options, flag);
+	}
+
+	public boolean isAlwaysCalc() {
+		return alwaysCalc.isSet(field_5_options);
+	}
+
+
+	public boolean isCalcOnLoad() {
+		return calcOnLoad.isSet(field_5_options);
+	}
+
+
+	/**
+	 * @return the formula tokens. never <code>null</code>
+	 */
+	public Ptg[] getParsedExpression() {
+		return field_8_parsed_expr.getTokens();
+	}
+
+	public Formula getFormula() {
+		return field_8_parsed_expr;
+	}
+
+	public void setParsedExpression(Ptg[] ptgs) {
+		field_8_parsed_expr = Formula.create(ptgs);
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	@Override
+	protected int getValueDataSize() {
+		return FIXED_SIZE + field_8_parsed_expr.getEncodedSize();
+	}
+	@Override
+	protected void serializeValue(LittleEndianOutput out) {
+
+		if (specialCachedValue == null) {
+			out.writeDouble(field_4_value);
+		} else {
+			specialCachedValue.serialize(out);
+		}
+
+		out.writeShort(getOptions());
+
+		out.writeInt(field_6_zero); // may as well write original data back so as to minimise differences from original
+		field_8_parsed_expr.serialize(out);
+	}
+	
+	@Override
+	protected String getRecordName() {
+		return "FORMULA";
+	}
+	
+	@Override
+	protected void appendValueText(StringBuilder sb) {
+		sb.append("  .value	 = ");
+		if (specialCachedValue == null) {
+			sb.append(field_4_value).append("\n");
+		} else {
+			sb.append(specialCachedValue.formatDebugString()).append("\n");
+		}
+		sb.append("  .options   = ").append(HexDump.shortToHex(getOptions())).append("\n");
+		sb.append("    .alwaysCalc= ").append(isAlwaysCalc()).append("\n");
+		sb.append("    .calcOnLoad= ").append(isCalcOnLoad()).append("\n");
+		sb.append("    .shared    = ").append(isSharedFormula()).append("\n");
+		sb.append("  .zero      = ").append(HexDump.intToHex(field_6_zero));
+
+		Ptg[] ptgs = field_8_parsed_expr.getTokens();
+		for (int k = 0; k < ptgs.length; k++ ) {
+			if (k>0) {
+				sb.append("\n");
+			}
+			sb.append("    Ptg[").append(k).append("]=");
+			Ptg ptg = ptgs[k];
+			sb.append(ptg.toString()).append(ptg.getRVAType());
+		}
+	}
+
+	public Object clone() {
+		FormulaRecord rec = new FormulaRecord();
+		copyBaseFields(rec);
+		rec.field_4_value = field_4_value;
+		rec.field_5_options = field_5_options;
+		rec.field_6_zero = field_6_zero;
+		rec.field_8_parsed_expr = field_8_parsed_expr;
+		rec.specialCachedValue = specialCachedValue;
+		return rec;
+	}
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FtCblsSubRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FtCblsSubRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/FtCblsSubRecord.java	(revision 28000)
@@ -0,0 +1,101 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+
+/**
+ * This structure appears as part of an Obj record that represents a checkbox or radio button.
+ *
+ * @author Yegor Kozlov
+ */
+public final class FtCblsSubRecord extends SubRecord {
+    public final static short sid = 0x0C;
+    private static final int ENCODED_SIZE = 20;
+
+    private byte[] reserved;
+
+    /**
+     * Construct a new <code>FtCblsSubRecord</code> and
+     * fill its data with the default values
+     */
+    public FtCblsSubRecord()
+    {
+        reserved = new byte[ENCODED_SIZE];
+    }
+
+    public FtCblsSubRecord(LittleEndianInput in, int size) {
+        if (size != ENCODED_SIZE) {
+            throw new RecordFormatException("Unexpected size (" + size + ")");
+        }
+        //just grab the raw data
+        byte[] buf = new byte[size];
+        in.readFully(buf);
+        reserved = buf;
+    }
+
+    /**
+     * Convert this record to string.
+     * Used by BiffViewer and other utilities.
+     */
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[FtCbls ]").append("\n");
+        buffer.append("  size     = ").append(getDataSize()).append("\n");
+        buffer.append("  reserved = ").append(HexDump.toHex(reserved)).append("\n");
+        buffer.append("[/FtCbls ]").append("\n");
+        return buffer.toString();
+    }
+
+    /**
+     * Serialize the record data into the supplied array of bytes
+     *
+     * @param out the stream to serialize into
+     */
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(sid);
+        out.writeShort(reserved.length);
+        out.write(reserved);
+    }
+
+	protected int getDataSize() {
+        return reserved.length;
+    }
+
+    /**
+     * @return id of this record.
+     */
+    public short getSid() // NO_UCD
+    {
+        return sid;
+    }
+
+    public Object clone() {
+        FtCblsSubRecord rec = new FtCblsSubRecord();
+        byte[] recdata = new byte[reserved.length];
+        System.arraycopy(reserved, 0, recdata, 0, recdata.length);
+        rec.reserved = recdata;
+        return rec;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/GridsetRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/GridsetRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/GridsetRecord.java	(revision 28000)
@@ -0,0 +1,110 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Gridset Record.<P>
+ * Description:  flag denoting whether the user specified that gridlines are used when
+ *               printing.<P>
+ * REFERENCE:  PG 320 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ *
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author  Glen Stampoultzis (glens at apache.org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ *
+ * @version 2.0-pre
+ */
+
+public final class GridsetRecord
+    extends StandardRecord
+{
+    public final static short sid = 0x82;
+    public short              field_1_gridset_flag;
+
+    public GridsetRecord()
+    {
+    }
+
+    public GridsetRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_gridset_flag = in.readShort();
+    }
+
+    /**
+     * set whether gridlines are visible when printing
+     *
+     * @param gridset - <b>true</b> if no gridlines are print, <b>false</b> if gridlines are not print.
+     */
+
+    public void setGridset(boolean gridset)
+    {
+        if (gridset == true)
+        {
+            field_1_gridset_flag = 1;
+        }
+        else
+        {
+            field_1_gridset_flag = 0;
+        }
+    }
+
+    /**
+     * get whether the gridlines are shown during printing.
+     *
+     * @return gridset - true if gridlines are NOT printed, false if they are.
+     */
+
+    public boolean getGridset()
+    {
+        return (field_1_gridset_flag == 1);
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[GRIDSET]\n");
+        buffer.append("    .gridset        = ").append(getGridset())
+            .append("\n");
+        buffer.append("[/GRIDSET]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(field_1_gridset_flag);
+    }
+
+    protected int getDataSize() {
+        return 2;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public Object clone() {
+      GridsetRecord rec = new GridsetRecord();
+      rec.field_1_gridset_flag = field_1_gridset_flag;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/GroupMarkerSubRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/GroupMarkerSubRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/GroupMarkerSubRecord.java	(revision 28000)
@@ -0,0 +1,80 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * ftGmo (0x0006)<p/>
+ * The group marker record is used as a position holder for groups.
+
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class GroupMarkerSubRecord extends SubRecord {
+    public final static short sid = 0x0006;
+
+    private static final byte[] EMPTY_BYTE_ARRAY = { };
+
+    private byte[] reserved;    // would really love to know what goes in here.
+
+    public GroupMarkerSubRecord() {
+        reserved = EMPTY_BYTE_ARRAY;
+    }
+
+    public GroupMarkerSubRecord(LittleEndianInput in, int size) {
+        byte[] buf = new byte[size];
+        in.readFully(buf);
+        reserved = buf;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        String nl = System.getProperty("line.separator");
+        buffer.append("[ftGmo]" + nl);
+        buffer.append("  reserved = ").append(HexDump.toHex(reserved)).append(nl);
+        buffer.append("[/ftGmo]" + nl);
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(sid);
+        out.writeShort(reserved.length);
+        out.write(reserved);
+    }
+
+	protected int getDataSize() {
+        return reserved.length;
+    }
+
+    public short getSid() // NO_UCD
+    {
+        return sid;
+    }
+
+    public Object clone() {
+        GroupMarkerSubRecord rec = new GroupMarkerSubRecord();
+        rec.reserved = new byte[reserved.length];
+        for ( int i = 0; i < reserved.length; i++ )
+            rec.reserved[i] = reserved[i];
+        return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/GutsRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/GutsRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/GutsRecord.java	(revision 28000)
@@ -0,0 +1,183 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Guts Record <P>
+ * Description:  Row/column gutter sizes <P>
+ * REFERENCE:  PG 320 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @version 2.0-pre
+ */
+
+public final class GutsRecord
+    extends StandardRecord
+{
+    public final static short sid = 0x80;
+    private short             field_1_left_row_gutter;   // size of the row gutter to the left of the rows
+    private short             field_2_top_col_gutter;    // size of the column gutter above the columns
+    private short             field_3_row_level_max;     // maximum outline level for row gutters
+    private short             field_4_col_level_max;     // maximum outline level for column gutters
+
+    public GutsRecord()
+    {
+    }
+
+    public GutsRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_left_row_gutter = in.readShort();
+        field_2_top_col_gutter  = in.readShort();
+        field_3_row_level_max   = in.readShort();
+        field_4_col_level_max   = in.readShort();
+    }
+
+    /**
+     * set the size of the gutter that appears at the left of the rows
+     *
+     * @param gut  gutter size in screen units
+     */
+
+    public void setLeftRowGutter(short gut)
+    {
+        field_1_left_row_gutter = gut;
+    }
+
+    /**
+     * set the size of the gutter that appears at the above the columns
+     *
+     * @param gut  gutter size in screen units
+     */
+
+    public void setTopColGutter(short gut)
+    {
+        field_2_top_col_gutter = gut;
+    }
+
+    /**
+     * set the maximum outline level for the row gutter.
+     *
+     * @param max  maximum outline level
+     */
+
+    public void setRowLevelMax(short max)
+    {
+        field_3_row_level_max = max;
+    }
+
+    /**
+     * set the maximum outline level for the col gutter.
+     *
+     * @param max  maximum outline level
+     */
+
+    public void setColLevelMax(short max)
+    {
+        field_4_col_level_max = max;
+    }
+
+    /**
+     * get the size of the gutter that appears at the left of the rows
+     *
+     * @return gutter size in screen units
+     */
+
+    public short getLeftRowGutter()
+    {
+        return field_1_left_row_gutter;
+    }
+
+    /**
+     * get the size of the gutter that appears at the above the columns
+     *
+     * @return gutter size in screen units
+     */
+
+    public short getTopColGutter()
+    {
+        return field_2_top_col_gutter;
+    }
+
+    /**
+     * get the maximum outline level for the row gutter.
+     *
+     * @return maximum outline level
+     */
+
+    public short getRowLevelMax()
+    {
+        return field_3_row_level_max;
+    }
+
+    /**
+     * get the maximum outline level for the col gutter.
+     *
+     * @return maximum outline level
+     */
+
+    public short getColLevelMax()
+    {
+        return field_4_col_level_max;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[GUTS]\n");
+        buffer.append("    .leftgutter     = ")
+            .append(Integer.toHexString(getLeftRowGutter())).append("\n");
+        buffer.append("    .topgutter      = ")
+            .append(Integer.toHexString(getTopColGutter())).append("\n");
+        buffer.append("    .rowlevelmax    = ")
+            .append(Integer.toHexString(getRowLevelMax())).append("\n");
+        buffer.append("    .collevelmax    = ")
+            .append(Integer.toHexString(getColLevelMax())).append("\n");
+        buffer.append("[/GUTS]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(getLeftRowGutter());
+        out.writeShort(getTopColGutter());
+        out.writeShort(getRowLevelMax());
+        out.writeShort(getColLevelMax());
+    }
+
+    protected int getDataSize() {
+        return 8;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public Object clone() {
+      GutsRecord rec = new GutsRecord();
+      rec.field_1_left_row_gutter = field_1_left_row_gutter;
+      rec.field_2_top_col_gutter = field_2_top_col_gutter;
+      rec.field_3_row_level_max = field_3_row_level_max;
+      rec.field_4_col_level_max = field_4_col_level_max;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java	(revision 28000)
@@ -0,0 +1,60 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import java.util.Iterator;
+
+/**
+ * HorizontalPageBreak (0x001B) record that stores page breaks at rows <p/>
+ * 
+ * @see PageBreakRecord
+ * @author Danny Mui (dmui at apache dot org)
+ */
+public final class HorizontalPageBreakRecord extends PageBreakRecord {
+
+	public static final short sid = 0x001B;
+
+	/**
+	 * Creates an empty horizontal page break record
+	 */
+	public HorizontalPageBreakRecord() {
+		//
+	}
+
+	/**
+	 * @param in
+	 *            the RecordInputstream to read the record from
+	 */
+	public HorizontalPageBreakRecord(RecordInputStream in) { // NO_UCD
+		super(in);
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	public Object clone() {
+		PageBreakRecord result = new HorizontalPageBreakRecord();
+		Iterator<Break> iterator = getBreaksIterator();
+		while (iterator.hasNext()) {
+			Break original = iterator.next();
+			result.addBreak(original.main, original.subFrom, original.subTo);
+		}
+		return result;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/HyperlinkRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/HyperlinkRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/HyperlinkRecord.java	(revision 28000)
@@ -0,0 +1,543 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.HexRead;
+import org.apache.poi.util.LittleEndianByteArrayInputStream;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * The <code>HyperlinkRecord</code> (0x01B8) wraps an HLINK-record
+ *  from the Excel-97 format.
+ * Supports only external links for now (eg http://)
+ *
+ * @author      Mark Hissink Muller <a href="mailto:mark@hissinkmuller.nl >mark&064;hissinkmuller.nl</a>
+ * @author      Yegor Kozlov (yegor at apache dot org)
+ */
+public final class HyperlinkRecord extends StandardRecord {
+    public final static short sid = 0x01B8;
+
+    static final class GUID {
+		/*
+		 * this class is currently only used here, but could be moved to a
+		 * common package if needed
+		 */
+		private static final int TEXT_FORMAT_LENGTH = 36;
+
+		public static final int ENCODED_SIZE = 16;
+
+		/** 4 bytes - little endian */
+		private final int _d1;
+		/** 2 bytes - little endian */
+		private final int _d2;
+		/** 2 bytes - little endian */
+		private final int _d3;
+		/**
+		 * 8 bytes - serialized as big endian,  stored with inverted endianness here
+		 */
+		private final long _d4;
+
+		public GUID(LittleEndianInput in) {
+			this(in.readInt(), in.readUShort(), in.readUShort(), in.readLong());
+		}
+
+		public GUID(int d1, int d2, int d3, long d4) {
+			_d1 = d1;
+			_d2 = d2;
+			_d3 = d3;
+			_d4 = d4;
+		}
+
+		public void serialize(LittleEndianOutput out) {
+			out.writeInt(_d1);
+			out.writeShort(_d2);
+			out.writeShort(_d3);
+			out.writeLong(_d4);
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			GUID other = (GUID) obj;
+            if (obj == null || !(obj instanceof GUID))
+                return false;
+			return _d1 == other._d1 && _d2 == other._d2
+			    && _d3 == other._d3 && _d4 == other._d4;
+		}
+
+		public long getD4() {
+			//
+			ByteArrayOutputStream baos = new ByteArrayOutputStream(8);
+			try {
+				new DataOutputStream(baos).writeLong(_d4);
+			} catch (IOException e) {
+				throw new RuntimeException(e);
+			}
+			byte[] buf = baos.toByteArray();
+			return new LittleEndianByteArrayInputStream(buf).readLong();
+		}
+
+		public String formatAsString() {
+
+			StringBuilder sb = new StringBuilder(36);
+
+			int PREFIX_LEN = "0x".length();
+			sb.append(HexDump.intToHex(_d1), PREFIX_LEN, 8);
+			sb.append("-");
+			sb.append(HexDump.shortToHex(_d2), PREFIX_LEN, 4);
+			sb.append("-");
+			sb.append(HexDump.shortToHex(_d3), PREFIX_LEN, 4);
+			sb.append("-");
+			char[] d4Chars = HexDump.longToHex(getD4());
+			sb.append(d4Chars, PREFIX_LEN, 4);
+			sb.append("-");
+			sb.append(d4Chars, PREFIX_LEN + 4, 12);
+			return sb.toString();
+		}
+
+		@Override
+		public String toString() {
+			StringBuilder sb = new StringBuilder(64);
+			sb.append(getClass().getName()).append(" [");
+			sb.append(formatAsString());
+			sb.append("]");
+			return sb.toString();
+		}
+
+		/**
+		 * Read a GUID in standard text form e.g.<br/>
+		 * 13579BDF-0246-8ACE-0123-456789ABCDEF 
+		 * <br/> -&gt; <br/>
+		 *  0x13579BDF, 0x0246, 0x8ACE 0x0123456789ABCDEF
+		 */
+		public static GUID parse(String rep) {
+			char[] cc = rep.toCharArray();
+			if (cc.length != TEXT_FORMAT_LENGTH) {
+				throw new RecordFormatException("supplied text is the wrong length for a GUID");
+			}
+			int d0 = (parseShort(cc, 0) << 16) + (parseShort(cc, 4) << 0);
+			int d1 = parseShort(cc, 9);
+			int d2 = parseShort(cc, 14);
+			for (int i = 23; i > 19; i--) {
+				cc[i] = cc[i - 1];
+			}
+			long d3 = parseLELong(cc, 20);
+
+			return new GUID(d0, d1, d2, d3);
+		}
+
+		private static long parseLELong(char[] cc, int startIndex) {
+			long acc = 0;
+			for (int i = startIndex + 14; i >= startIndex; i -= 2) {
+				acc <<= 4;
+				acc += parseHexChar(cc[i + 0]);
+				acc <<= 4;
+				acc += parseHexChar(cc[i + 1]);
+			}
+			return acc;
+		}
+
+		private static int parseShort(char[] cc, int startIndex) {
+			int acc = 0;
+			for (int i = 0; i < 4; i++) {
+				acc <<= 4;
+				acc += parseHexChar(cc[startIndex + i]);
+			}
+			return acc;
+		}
+
+		private static int parseHexChar(char c) {
+			if (c >= '0' && c <= '9') {
+				return c - '0';
+			}
+			if (c >= 'A' && c <= 'F') {
+				return c - 'A' + 10;
+			}
+			if (c >= 'a' && c <= 'f') {
+				return c - 'a' + 10;
+			}
+			throw new RecordFormatException("Bad hex char '" + c + "'");
+		}
+	}
+
+    /**
+     * Link flags
+     */
+     static final int  HLINK_URL    = 0x01;  // File link or URL.
+     static final int  HLINK_LABEL  = 0x14;  // Has label/description.
+    /** Place in worksheet. If set, the {@link #_textMark} field will be present */
+     static final int  HLINK_PLACE  = 0x08;
+    private static final int  HLINK_TARGET_FRAME  = 0x80;  // has 'target frame'
+    private static final int  HLINK_UNC_PATH  = 0x100;  // has UNC path
+
+     final static GUID STD_MONIKER = GUID.parse("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B");
+     final static GUID URL_MONIKER = GUID.parse("79EAC9E0-BAF9-11CE-8C82-00AA004BA90B");
+     final static GUID FILE_MONIKER = GUID.parse("00000303-0000-0000-C000-000000000046");
+    /** expected Tail of a URL link */
+    private final static byte[] URL_TAIL  = HexRead.readFromString("79 58 81 F4  3B 1D 7F 48   AF 2C 82 5D  C4 85 27 63   00 00 00 00  A5 AB 00 00"); 
+    /** expected Tail of a file link */
+    private final static byte[] FILE_TAIL = HexRead.readFromString("FF FF AD DE  00 00 00 00   00 00 00 00  00 00 00 00   00 00 00 00  00 00 00 00");
+
+    private static final int TAIL_SIZE = FILE_TAIL.length;
+
+    /** cell range of this hyperlink */
+    private CellRangeAddress _range;
+
+    /** 16-byte GUID */
+    private GUID _guid;
+    /** Some sort of options for file links. */
+    private int _fileOpts;
+    /** Link options. Can include any of HLINK_* flags. */
+    private int _linkOpts;
+    /** Test label */
+    private String _label;
+
+    private String _targetFrame;
+    /** Moniker. Makes sense only for URL and file links */
+    private GUID _moniker;
+    /** in 8:3 DOS format No Unicode string header,
+     * always 8-bit characters, zero-terminated */
+    private String _shortFilename;
+    /** Link */
+    private String _address;
+    /**
+     * Text describing a place in document.  In Excel UI, this is appended to the
+     * address, (after a '#' delimiter).<br/>
+     * This field is optional.  If present, the {@link #HLINK_PLACE} must be set.
+     */
+    private String _textMark;
+    
+    private byte[] _uninterpretedTail;
+
+    /**
+     * Create a new hyperlink
+     */
+    public HyperlinkRecord()
+    {
+
+    }
+
+
+
+    private static String cleanString(String s) {
+        if (s == null) {
+            return null;
+        }
+        int idx = s.indexOf('\u0000');
+        if (idx < 0) {
+            return s;
+        }
+        return s.substring(0, idx);
+    }
+
+
+    /**
+     * Return text label for this hyperlink
+     *
+     * @return  text to display
+     */
+    public String getLabel() {
+        return cleanString(_label);
+    }
+
+    public String getTargetFrame() {
+        return cleanString(_targetFrame);
+    }
+
+    /**
+     * Hyperlink address. Depending on the hyperlink type it can be URL, e-mail, path to a file, etc.
+     *
+     * @return  the address of this hyperlink
+     */
+    public String getAddress() {
+        if ((_linkOpts & HLINK_URL) != 0 && FILE_MONIKER.equals(_moniker))
+            return cleanString(_address != null ? _address : _shortFilename);
+        else if((_linkOpts & HLINK_PLACE) != 0)
+            return cleanString(_textMark);
+        else
+            return cleanString(_address);
+    }
+
+
+    public String getTextMark() {
+        return cleanString(_textMark);
+    }
+
+
+    public HyperlinkRecord(RecordInputStream in) { // NO_UCD
+        _range = new CellRangeAddress(in);
+
+        _guid = new GUID(in);
+
+        /**
+         * streamVersion (4 bytes): An unsigned integer that specifies the version number
+         * of the serialization implementation used to save this structure. This value MUST equal 2.
+         */
+        int streamVersion = in.readInt();
+        if (streamVersion != 0x00000002) {
+            throw new RecordFormatException("Stream Version must be 0x2 but found " + streamVersion);
+        }
+        _linkOpts = in.readInt();
+
+        if ((_linkOpts & HLINK_LABEL) != 0){
+            int label_len = in.readInt();
+            _label = in.readUnicodeLEString(label_len);
+        }
+
+        if ((_linkOpts & HLINK_TARGET_FRAME) != 0){
+            int len = in.readInt();
+            _targetFrame = in.readUnicodeLEString(len);
+        }
+
+        if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) != 0) {
+            _moniker = null;
+            int nChars = in.readInt();
+            _address = in.readUnicodeLEString(nChars);
+        }
+
+        if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) {
+            _moniker = new GUID(in);
+
+            if(URL_MONIKER.equals(_moniker)){
+                int length = in.readInt();
+                /**
+                 * The value of <code>length<code> be either the byte size of the url field
+                 * (including the terminating NULL character) or the byte size of the url field plus 24.
+                 * If the value of this field is set to the byte size of the url field,
+                 * then the tail bytes fields are not present.
+                 */
+                int remaining = in.remaining();
+                if (length == remaining) {
+                    int nChars = length/2;
+                    _address = in.readUnicodeLEString(nChars);
+                } else {
+                    int nChars = (length - TAIL_SIZE)/2;
+                    _address = in.readUnicodeLEString(nChars);
+                    /**
+                     * TODO: make sense of the remaining bytes
+                     * According to the spec they consist of:
+                     * 1. 16-byte  GUID: This field MUST equal
+                     *    {0xF4815879, 0x1D3B, 0x487F, 0xAF, 0x2C, 0x82, 0x5D, 0xC4, 0x85, 0x27, 0x63}
+                     * 2. Serial version, this field MUST equal 0 if present.
+                     * 3. URI Flags
+                     */
+                    _uninterpretedTail = readTail(URL_TAIL, in);
+                }
+            } else if (FILE_MONIKER.equals(_moniker)) {
+                _fileOpts = in.readShort();
+
+                int len = in.readInt();
+                _shortFilename = StringUtil.readCompressedUnicode(in, len);
+                _uninterpretedTail = readTail(FILE_TAIL, in);
+                int size = in.readInt();
+                if (size > 0) {
+                    int charDataSize = in.readInt();
+
+                    //From the spec: An optional unsigned integer that MUST be 3 if present
+                    int optFlags = in.readUShort();
+                    if (optFlags != 0x0003) {
+                        throw new RecordFormatException("Expected 0x3 but found " + optFlags);
+                    }
+                    _address = StringUtil.readUnicodeLE(in, charDataSize/2);
+                } else {
+                    _address = null;
+                }
+            } else if (STD_MONIKER.equals(_moniker)) {
+                _fileOpts = in.readShort();
+
+                int len = in.readInt();
+
+                byte[] path_bytes = new byte[len];
+                in.readFully(path_bytes);
+
+                _address = new String(path_bytes);
+            }
+        }
+
+        if((_linkOpts & HLINK_PLACE) != 0) {
+
+            int len = in.readInt();
+            _textMark = in.readUnicodeLEString(len);
+        }
+
+        if (in.remaining() > 0) {
+            System.out.println(HexDump.toHex(in.readRemainder()));
+        }
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        _range.serialize(out);
+
+        _guid.serialize(out);
+        out.writeInt(0x00000002); // TODO const
+        out.writeInt(_linkOpts);
+
+        if ((_linkOpts & HLINK_LABEL) != 0){
+            out.writeInt(_label.length());
+            StringUtil.putUnicodeLE(_label, out);
+        }
+        if ((_linkOpts & HLINK_TARGET_FRAME) != 0){
+            out.writeInt(_targetFrame.length());
+            StringUtil.putUnicodeLE(_targetFrame, out);
+        }
+
+        if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) != 0) {
+            out.writeInt(_address.length());
+            StringUtil.putUnicodeLE(_address, out);
+        }
+
+        if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) {
+            _moniker.serialize(out);
+            if(URL_MONIKER.equals(_moniker)){
+                if (_uninterpretedTail == null) {
+                    out.writeInt(_address.length()*2);
+                    StringUtil.putUnicodeLE(_address, out);
+                } else {
+                    out.writeInt(_address.length()*2 + TAIL_SIZE);
+                    StringUtil.putUnicodeLE(_address, out);
+                    writeTail(_uninterpretedTail, out);
+                }
+            } else if (FILE_MONIKER.equals(_moniker)){
+                out.writeShort(_fileOpts);
+                out.writeInt(_shortFilename.length());
+                StringUtil.putCompressedUnicode(_shortFilename, out);
+                writeTail(_uninterpretedTail, out);
+                if (_address == null) {
+                    out.writeInt(0);
+                } else {
+                    int addrLen = _address.length() * 2;
+                    out.writeInt(addrLen + 6);
+                    out.writeInt(addrLen);
+                    out.writeShort(0x0003); // TODO const
+                    StringUtil.putUnicodeLE(_address, out);
+                }
+            }
+        }
+        if((_linkOpts & HLINK_PLACE) != 0){
+               out.writeInt(_textMark.length());
+            StringUtil.putUnicodeLE(_textMark, out);
+        }
+    }
+
+    protected int getDataSize() {
+        int size = 0;
+        size += 2 + 2 + 2 + 2;  //rwFirst, rwLast, colFirst, colLast
+        size += GUID.ENCODED_SIZE;
+        size += 4;  //label_opts
+        size += 4;  //link_opts
+        if ((_linkOpts & HLINK_LABEL) != 0){
+            size += 4;  //link length
+            size += _label.length()*2;
+        }
+        if ((_linkOpts & HLINK_TARGET_FRAME) != 0){
+            size += 4;  // int nChars
+            size += _targetFrame.length()*2;
+        }
+        if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) != 0) {
+            size += 4;  // int nChars
+            size += _address.length()*2;
+        }
+        if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) {
+            size += GUID.ENCODED_SIZE;
+            if(URL_MONIKER.equals(_moniker)){
+                size += 4;  //address length
+                size += _address.length()*2;
+                if (_uninterpretedTail != null) {
+                	size += TAIL_SIZE;
+                }
+            } else if (FILE_MONIKER.equals(_moniker)){
+                size += 2;  //file_opts
+                size += 4;  //address length
+                size += _shortFilename.length();
+                size += TAIL_SIZE;
+                size += 4;
+                if (_address != null) {
+                    size += 6;
+                    size += _address.length() * 2;
+                }
+
+            }
+        }
+        if((_linkOpts & HLINK_PLACE) != 0){
+            size += 4;  //address length
+            size += _textMark.length()*2;
+        }
+        return size;
+    }
+
+    private static byte[] readTail(byte[] expectedTail, LittleEndianInput in) {
+    	byte[] result = new byte[TAIL_SIZE];
+    	in.readFully(result);
+        return result;
+    }
+
+    private static void writeTail(byte[] tail, LittleEndianOutput out) {
+        out.write(tail);
+    }
+
+    public short getSid() {
+        return HyperlinkRecord.sid;
+    }
+
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[HYPERLINK RECORD]\n");
+        buffer.append("    .range   = ").append(_range.formatAsString()).append("\n");
+        buffer.append("    .guid    = ").append(_guid.formatAsString()).append("\n");
+        buffer.append("    .linkOpts= ").append(HexDump.intToHex(_linkOpts)).append("\n");
+        buffer.append("    .label   = ").append(getLabel()).append("\n");
+        if ((_linkOpts & HLINK_TARGET_FRAME) != 0) {
+            buffer.append("    .targetFrame= ").append(getTargetFrame()).append("\n");
+        }
+        if((_linkOpts & HLINK_URL) != 0 && _moniker != null) {
+            buffer.append("    .moniker   = ").append(_moniker.formatAsString()).append("\n");
+        }
+        if ((_linkOpts & HLINK_PLACE) != 0) {
+            buffer.append("    .textMark= ").append(getTextMark()).append("\n");
+        }
+        buffer.append("    .address   = ").append(getAddress()).append("\n");
+        buffer.append("[/HYPERLINK RECORD]\n");
+        return buffer.toString();
+    }
+
+
+    public Object clone() {
+        HyperlinkRecord rec = new HyperlinkRecord();
+        rec._range = _range.copy();
+        rec._guid = _guid;
+        rec._linkOpts = _linkOpts;
+        rec._fileOpts = _fileOpts;
+        rec._label = _label;
+        rec._address = _address;
+        rec._moniker = _moniker;
+        rec._shortFilename = _shortFilename;
+        rec._targetFrame = _targetFrame;
+        rec._textMark = _textMark;
+        rec._uninterpretedTail = _uninterpretedTail;
+        return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/IndexRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/IndexRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/IndexRecord.java	(revision 28000)
@@ -0,0 +1,133 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.IntList;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Index Record (0x020B)<p/>
+ * Description:  Occurs right after BOF, tells you where the DBCELL records are for a sheet
+ *               Important for locating cells<p/>
+ * NOT USED IN THIS RELEASE
+ * REFERENCE:  PG 323 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public class IndexRecord extends StandardRecord {
+    public final static short sid = 0x020B;
+    private int                field_2_first_row;       // first row on the sheet
+    private int                field_3_last_row_add1;   // last row
+    private int                field_4_zero;            // supposed to be zero
+    private IntList            field_5_dbcells;         // array of offsets to DBCELL records
+
+    public IndexRecord()
+    {
+    }
+
+    public IndexRecord(RecordInputStream in) // NO_UCD
+    {
+        int field_1_zero          = in.readInt();
+        if (field_1_zero != 0) {
+        	throw new RecordFormatException("Expected zero for field 1 but got " + field_1_zero);
+        }
+        field_2_first_row     = in.readInt();
+        field_3_last_row_add1 = in.readInt();
+        field_4_zero      = in.readInt();
+        
+        int nCells = in.remaining() / 4;
+        field_5_dbcells = new IntList(nCells);
+        for(int i=0; i<nCells; i++) {
+            field_5_dbcells.add(in.readInt());
+        }
+    }
+
+
+
+    public int getFirstRow()
+    {
+        return field_2_first_row;
+    }
+
+    public int getLastRowAdd1()
+    {
+        return field_3_last_row_add1;
+    }
+
+    public int getNumDbcells()
+    {
+        if (field_5_dbcells == null)
+        {
+            return 0;
+        }
+        return field_5_dbcells.size();
+    }
+
+    public int getDbcellAt(int cellnum)
+    {
+        return field_5_dbcells.get(cellnum);
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[INDEX]\n");
+        buffer.append("    .firstrow       = ")
+            .append(Integer.toHexString(getFirstRow())).append("\n");
+        buffer.append("    .lastrowadd1    = ")
+            .append(Integer.toHexString(getLastRowAdd1())).append("\n");
+        for (int k = 0; k < getNumDbcells(); k++) {
+            buffer.append("    .dbcell_").append(k).append(" = ")
+                .append(Integer.toHexString(getDbcellAt(k))).append("\n");
+        }
+        buffer.append("[/INDEX]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+
+        out.writeInt(0);
+        out.writeInt(getFirstRow());
+        out.writeInt(getLastRowAdd1());
+        out.writeInt(field_4_zero);
+        for (int k = 0; k < getNumDbcells(); k++) {
+        	out.writeInt(getDbcellAt(k));
+        }
+    }
+
+    protected int getDataSize() {
+        return 16 // 4 ints
+        	+ getNumDbcells() * 4;
+    }
+    
+
+    public short getSid() {
+        return sid;
+    }
+
+    public Object clone() {
+      IndexRecord rec = new IndexRecord();
+      rec.field_2_first_row = field_2_first_row;
+      rec.field_3_last_row_add1 = field_3_last_row_add1;
+      rec.field_4_zero = field_4_zero;
+      rec.field_5_dbcells = new IntList();
+      rec.field_5_dbcells.addAll(field_5_dbcells);
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/IterationRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/IterationRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/IterationRecord.java	(revision 28000)
@@ -0,0 +1,84 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Iteration Record (0x0011) <p/>
+ * Description:  Tells whether to iterate over forumla calculations or not
+ *               (if a formula is dependant upon another formula's result)
+ *               (odd feature for something that can only have 32 elements in
+ *                a formula!)<P>
+ * REFERENCE:  PG 325 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class IterationRecord extends StandardRecord {
+    public final static short sid = 0x0011;
+
+    private static final BitField iterationOn = BitFieldFactory.getInstance(0x0001);
+
+    private int _flags;
+
+    public IterationRecord(boolean iterateOn) {
+        _flags = iterationOn.setBoolean(0, iterateOn);
+    }
+
+    public IterationRecord(RecordInputStream in) // NO_UCD
+    {
+        _flags = in.readShort();
+    }
+
+    /**
+     * get whether or not to iterate for calculations
+     *
+     * @return whether iterative calculations are turned off or on
+     */
+    public boolean getIteration() {
+        return iterationOn.isSet(_flags);
+    }
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[ITERATION]\n");
+        buffer.append("    .flags      = ").append(HexDump.shortToHex(_flags)).append("\n");
+        buffer.append("[/ITERATION]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(_flags);
+    }
+
+    protected int getDataSize() {
+        return 2;
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    public Object clone() {
+        return new IterationRecord(getIteration());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/LabelRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/LabelRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/LabelRecord.java	(revision 28000)
@@ -0,0 +1,165 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+
+/**
+ * Label Record (0x0204) - read only support for strings stored directly in the cell..  Don't
+ * use this (except to read), use LabelSST instead <P>
+ * REFERENCE:  PG 325 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @version 2.0-pre
+ * @see org.apache.poi.hssf.record.LabelSSTRecord
+ */
+public final class LabelRecord extends Record implements CellValueRecordInterface {
+    public final static short sid = 0x0204;
+
+    private int               field_1_row;
+    private short             field_2_column;
+    private short             field_3_xf_index;
+    private short             field_4_string_len;
+    private byte              field_5_unicode_flag;
+    private String            field_6_value;
+
+    /** Creates new LabelRecord */
+    public LabelRecord()
+    {
+    }
+
+    /**
+     * @param in the RecordInputstream to read the record from
+     */
+    public LabelRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_row          = in.readUShort();
+        field_2_column       = in.readShort();
+        field_3_xf_index     = in.readShort();
+        field_4_string_len   = in.readShort();
+        field_5_unicode_flag = in.readByte();
+        if (field_4_string_len > 0) {
+            if (isUnCompressedUnicode()) {
+                field_6_value = in.readUnicodeLEString(field_4_string_len);
+            } else {
+                field_6_value = in.readCompressedUnicode(field_4_string_len);
+            }
+        } else {
+            field_6_value = "";
+        }
+    }
+
+/*
+ * READ ONLY ACCESS... THIS IS FOR COMPATIBILITY ONLY...USE LABELSST! public
+ */
+    public int getRow()
+    {
+        return field_1_row;
+    }
+
+    public short getColumn()
+    {
+        return field_2_column;
+    }
+
+    public short getXFIndex()
+    {
+        return field_3_xf_index;
+    }
+
+    /**
+     * is this uncompressed unicode (16bit)?  Or just 8-bit compressed?
+     * @return isUnicode - True for 16bit- false for 8bit
+     */
+    public boolean isUnCompressedUnicode()
+    {
+        return (field_5_unicode_flag == 1);
+    }
+
+    /**
+     * get the value
+     *
+     * @return the text string
+     * @see #getStringLength()
+     */
+    public String getValue()
+    {
+        return field_6_value;
+    }
+
+    /**
+     * THROWS A RUNTIME EXCEPTION..  USE LABELSSTRecords.  YOU HAVE NO REASON to use LABELRecord!!
+     */
+    public int serialize(int offset, byte [] data) {
+        throw new RecordFormatException("Label Records are supported READ ONLY...convert to LabelSST");
+    }
+    public int getRecordSize() {
+        throw new RecordFormatException("Label Records are supported READ ONLY...convert to LabelSST");
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public String toString()
+    {
+        StringBuffer sb = new StringBuffer();
+		sb.append("[LABEL]\n");
+		sb.append("    .row       = ").append(HexDump.shortToHex(getRow())).append("\n");
+		sb.append("    .column    = ").append(HexDump.shortToHex(getColumn())).append("\n");
+		sb.append("    .xfindex   = ").append(HexDump.shortToHex(getXFIndex())).append("\n");
+		sb.append("    .string_len= ").append(HexDump.shortToHex(field_4_string_len)).append("\n");
+		sb.append("    .unicode_flag= ").append(HexDump.byteToHex(field_5_unicode_flag)).append("\n");
+		sb.append("    .value       = ").append(getValue()).append("\n");
+		sb.append("[/LABEL]\n");
+        return sb.toString();
+    }
+
+    /**
+	 * NO-OP!
+	 */
+    public void setColumn(short col)
+    {
+    }
+
+    /**
+     * NO-OP!
+     */
+    public void setRow(int row)
+    {
+    }
+
+    /**
+     * no op!
+     */
+    public void setXFIndex(short xf)
+    {
+    }
+
+    public Object clone() {
+      LabelRecord rec = new LabelRecord();
+      rec.field_1_row = field_1_row;
+      rec.field_2_column = field_2_column;
+      rec.field_3_xf_index = field_3_xf_index;
+      rec.field_4_string_len = field_4_string_len;
+      rec.field_5_unicode_flag = field_5_unicode_flag;
+      rec.field_6_value = field_6_value;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/LabelSSTRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/LabelSSTRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/LabelSSTRecord.java	(revision 28000)
@@ -0,0 +1,95 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Label SST Record<P>
+ * Description:  Refers to a string in the shared string table and is a column
+ *               value.  <P>
+ * REFERENCE:  PG 325 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class LabelSSTRecord extends CellRecord {
+    public final static short sid = 0xfd;
+    private int field_4_sst_index;
+
+    public LabelSSTRecord() {
+    	// fields uninitialised
+    }
+
+    public LabelSSTRecord(RecordInputStream in) { // NO_UCD
+        super(in);
+        field_4_sst_index = in.readInt();
+    }
+
+    /**
+     * set the index to the string in the SSTRecord
+     *
+     * @param index - of string in the SST Table
+     * @see org.apache.poi.hssf.record.SSTRecord
+     */
+    public void setSSTIndex(int index) {
+        field_4_sst_index = index;
+    }
+
+
+    /**
+     * get the index to the string in the SSTRecord
+     *
+     * @return index of string in the SST Table
+     * @see org.apache.poi.hssf.record.SSTRecord
+     */
+    public int getSSTIndex() {
+        return field_4_sst_index;
+    }
+    
+    @Override
+    protected String getRecordName() {
+    	return "LABELSST";
+    }
+
+    @Override
+    protected void appendValueText(StringBuilder sb) {
+		sb.append("  .sstIndex = ");
+    	sb.append(HexDump.shortToHex(getXFIndex()));
+    }
+    @Override
+    protected void serializeValue(LittleEndianOutput out) {
+        out.writeInt(getSSTIndex());
+    }
+
+    @Override
+    protected int getValueDataSize() {
+        return 4;
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    public Object clone() {
+      LabelSSTRecord rec = new LabelSSTRecord();
+      copyBaseFields(rec);
+      rec.field_4_sst_index = field_4_sst_index;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/LbsDataSubRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/LbsDataSubRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/LbsDataSubRecord.java	(revision 28000)
@@ -0,0 +1,338 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * This structure specifies the properties of a list or drop-down list embedded object in a sheet.
+ */
+public class LbsDataSubRecord extends SubRecord {
+
+    public static final int sid = 0x0013;
+
+    /**
+     * From [MS-XLS].pdf 2.5.147 FtLbsData:
+     *
+     * An unsigned integer that indirectly specifies whether
+     * some of the data in this structure appear in a subsequent Continue record.
+     * If _cbFContinued is 0x00, all of the fields in this structure except sid and _cbFContinued
+     *  MUST NOT exist. If this entire structure is contained within the same record,
+     * then _cbFContinued MUST be greater than or equal to the size, in bytes,
+     * of this structure, not including the four bytes for the ft and _cbFContinued fields
+     */
+    private int _cbFContinued;
+
+    /**
+     * a formula that specifies the range of cell values that are the items in this list.
+     */
+    private int _unknownPreFormulaInt;
+    private Ptg _linkPtg;
+    private Byte _unknownPostFormulaByte;
+
+    /**
+     * An unsigned integer that specifies the number of items in the list.
+     */
+    private int _cLines;
+
+    /**
+     * An unsigned integer that specifies the one-based index of the first selected item in this list.
+     * A value of 0x00 specifies there is no currently selected item.
+     */
+    private int _iSel;
+
+    /**
+     *  flags that tell what data follows
+     */
+    private int _flags;
+
+    /**
+     * An ObjId that specifies the edit box associated with this list.
+     * A value of 0x00 specifies that there is no edit box associated with this list.
+     */
+    private int _idEdit;
+
+    /**
+     * An optional LbsDropData that specifies properties for this dropdown control.
+     * This field MUST exist if and only if the containing Obj?s cmo.ot is equal to 0x14.
+     */
+    private LbsDropData _dropData;
+
+    /**
+     * An optional array of strings where each string specifies an item in the list.
+     * The number of elements in this array, if it exists, MUST be {@link #_cLines}
+     */
+    private String[] _rgLines;
+
+    /**
+     * An optional array of booleans that specifies
+     * which items in the list are part of a multiple selection
+     */
+    private boolean[] _bsels;
+
+    /**
+     * @param in the stream to read data from
+     * @param cbFContinued the seconf short in the record header
+     * @param cmoOt the containing Obj's {@link CommonObjectDataSubRecord#field_1_objectType}
+     */
+    public LbsDataSubRecord(LittleEndianInput in, int cbFContinued, int cmoOt) {
+        _cbFContinued = cbFContinued;
+
+        int encodedTokenLen = in.readUShort();
+        if (encodedTokenLen > 0) {
+            int formulaSize = in.readUShort();
+            _unknownPreFormulaInt = in.readInt();
+
+            Ptg[] ptgs = Ptg.readTokens(formulaSize, in);
+            if (ptgs.length != 1) {
+                throw new RecordFormatException("Read " + ptgs.length
+                        + " tokens but expected exactly 1");
+            }
+            _linkPtg = ptgs[0];
+            switch (encodedTokenLen - formulaSize - 6) {
+                case 1:
+                    _unknownPostFormulaByte = in.readByte();
+                    break;
+                case 0:
+                    _unknownPostFormulaByte = null;
+                    break;
+                default:
+                    throw new RecordFormatException("Unexpected leftover bytes");
+            }
+        }
+
+        _cLines = in.readUShort();
+        _iSel = in.readUShort();
+        _flags = in.readUShort();
+        _idEdit = in.readUShort();
+
+        // From [MS-XLS].pdf 2.5.147 FtLbsData:
+        // This field MUST exist if and only if the containing Obj?s cmo.ot is equal to 0x14.
+        if(cmoOt == 0x14) {
+            _dropData = new LbsDropData(in);
+        }
+
+        // From [MS-XLS].pdf 2.5.147 FtLbsData:
+        // This array MUST exist if and only if the fValidPlex flag (0x2) is set
+        if((_flags & 0x2) != 0) {
+            _rgLines = new String[_cLines];
+            for(int i=0; i < _cLines; i++) {
+                _rgLines[i] = StringUtil.readUnicodeString(in);
+            }
+        }
+
+        // bits 5-6 in the _flags specify the type
+        // of selection behavior this list control is expected to support
+
+        // From [MS-XLS].pdf 2.5.147 FtLbsData:
+        // This array MUST exist if and only if the wListType field is not equal to 0.
+        if(((_flags >> 4) & 0x2) != 0) {
+            _bsels = new boolean[_cLines];
+            for(int i=0; i < _cLines; i++) {
+                _bsels[i] = in.readByte() == 1;
+            }
+        }
+
+    }
+
+    LbsDataSubRecord(){
+
+    }
+
+    /**
+     * @return true as LbsDataSubRecord is always the last sub-record
+     */
+    @Override
+    public boolean isTerminating(){
+        return true;
+    }
+
+    @Override
+    protected int getDataSize() {
+        int result = 2; // 2 initial shorts
+
+        // optional link formula
+        if (_linkPtg != null) {
+            result += 2; // encoded Ptg size
+            result += 4; // unknown int
+            result += _linkPtg.getSize();
+            if (_unknownPostFormulaByte != null) {
+                result += 1;
+            }
+        }
+
+        result += 4 * 2; // 4 shorts
+        if(_dropData != null) {
+            result += _dropData.getDataSize();
+        }
+        if(_rgLines != null) {
+            for(String str : _rgLines){
+                result += StringUtil.getEncodedSize(str);
+            }
+        }
+        if(_bsels != null) {
+            result += _bsels.length;
+        }
+        return result;
+    }
+
+    @Override
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(sid);
+        out.writeShort(_cbFContinued);
+
+        if (_linkPtg == null) {
+            out.writeShort(0);
+        } else {
+            int formulaSize = _linkPtg.getSize();
+            int linkSize = formulaSize + 6;
+            if (_unknownPostFormulaByte != null) {
+                linkSize++;
+            }
+            out.writeShort(linkSize);
+            out.writeShort(formulaSize);
+            out.writeInt(_unknownPreFormulaInt);
+            _linkPtg.write(out);
+            if (_unknownPostFormulaByte != null) {
+                out.writeByte(_unknownPostFormulaByte.intValue());
+            }
+        }
+
+        out.writeShort(_cLines);
+        out.writeShort(_iSel);
+        out.writeShort(_flags);
+        out.writeShort(_idEdit);
+
+        if(_dropData != null) {
+            _dropData.serialize(out);
+        }
+
+        if(_rgLines != null) {
+            for(String str : _rgLines){
+                StringUtil.writeUnicodeString(out, str);
+            }
+        }
+
+        if(_bsels != null) {
+            for(boolean val : _bsels){
+                out.writeByte(val ? 1 : 0);
+            }
+        }
+    }
+
+    @Override
+    public Object clone() {
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer(256);
+
+        sb.append("[ftLbsData]\n");
+        sb.append("    .unknownShort1 =").append(HexDump.shortToHex(_cbFContinued)).append("\n");
+        sb.append("    .formula        = ").append('\n');
+        if(_linkPtg != null) sb.append(_linkPtg.toString()).append(_linkPtg.getRVAType()).append('\n');
+        sb.append("    .nEntryCount   =").append(HexDump.shortToHex(_cLines)).append("\n");
+        sb.append("    .selEntryIx    =").append(HexDump.shortToHex(_iSel)).append("\n");
+        sb.append("    .style         =").append(HexDump.shortToHex(_flags)).append("\n");
+        sb.append("    .unknownShort10=").append(HexDump.shortToHex(_idEdit)).append("\n");
+        if(_dropData != null) sb.append('\n').append(_dropData.toString());
+        sb.append("[/ftLbsData]\n");
+        return sb.toString();
+    }
+
+    /**
+     * This structure specifies properties of the dropdown list control
+     */
+    public static class LbsDropData {
+
+        /**
+         *  An unsigned integer that specifies the style of this dropdown. 
+         */
+        private int _wStyle;
+
+        /**
+         * An unsigned integer that specifies the number of lines to be displayed in the dropdown.
+         */
+        private int _cLine;
+
+        /**
+         * An unsigned integer that specifies the smallest width in pixels allowed for the dropdown window
+         */
+        private int _dxMin;
+
+        /**
+         * a string that specifies the current string value in the dropdown
+         */
+        private String _str;
+
+        /**
+         * Optional, undefined and MUST be ignored.
+         * This field MUST exist if and only if the size of str in bytes is an odd number
+         */
+        private Byte _unused;
+
+        public LbsDropData(){
+            _str = "";
+            _unused = 0;
+        }
+
+        public LbsDropData(LittleEndianInput in){
+            _wStyle = in.readUShort();
+            _cLine = in.readUShort();
+            _dxMin = in.readUShort();
+            _str = StringUtil.readUnicodeString(in);
+            if(StringUtil.getEncodedSize(_str) % 2 != 0){
+                _unused = in.readByte();
+            }
+        }
+
+        public void serialize(LittleEndianOutput out) {
+            out.writeShort(_wStyle);
+            out.writeShort(_cLine);
+            out.writeShort(_dxMin);
+            StringUtil.writeUnicodeString(out, _str);
+            if(_unused != null) out.writeByte(_unused);
+        }
+
+        public int getDataSize() {
+            int size = 6;
+            size += StringUtil.getEncodedSize(_str);
+            size += _unused;
+            return size;
+        }
+
+        @Override
+        public String toString(){
+            StringBuffer sb = new StringBuffer();
+            sb.append("[LbsDropData]\n");
+            sb.append("  ._wStyle:  ").append(_wStyle).append('\n');
+            sb.append("  ._cLine:  ").append(_cLine).append('\n');
+            sb.append("  ._dxMin:  ").append(_dxMin).append('\n');
+            sb.append("  ._str:  ").append(_str).append('\n');
+            if(_unused != null) sb.append("  ._unused:  ").append(_unused).append('\n');
+            sb.append("[/LbsDropData]\n");
+
+            return sb.toString();
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/MergeCellsRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/MergeCellsRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/MergeCellsRecord.java	(revision 28000)
@@ -0,0 +1,113 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: Merged Cells Record (0x00E5)
+ * <br/>
+ * Description:  Optional record defining a square area of cells to "merged" into one cell. <br>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ */
+public final class MergeCellsRecord extends StandardRecord {
+    public final static short sid = 0x00E5;
+    /** sometimes the regions array is shared with other MergedCellsRecords */ 
+    private CellRangeAddress[] _regions;
+    private final int _startIndex;
+    private final int _numberOfRegions;
+
+    public MergeCellsRecord(CellRangeAddress[] regions, int startIndex, int numberOfRegions) {
+		_regions = regions;
+		_startIndex = startIndex;
+		_numberOfRegions = numberOfRegions;
+    }
+    /**
+     * Constructs a MergedCellsRecord and sets its fields appropriately
+     * @param in the RecordInputstream to read the record from
+     */
+    public MergeCellsRecord(RecordInputStream in) { // NO_UCD
+     	int nRegions = in.readUShort();
+    	CellRangeAddress[] cras = new CellRangeAddress[nRegions];
+    	for (int i = 0; i < nRegions; i++) {
+			cras[i] = new CellRangeAddress(in);
+		}
+    	_numberOfRegions = nRegions;
+    	_startIndex = 0;
+    	_regions = cras;
+    }
+    /**
+     * get the number of merged areas.  If this drops down to 0 you should just go
+     * ahead and delete the record.
+     * @return number of areas
+     */
+    public short getNumAreas() {
+        return (short)_numberOfRegions;
+    }
+
+    /**
+     * @return MergedRegion at the given index representing the area that is Merged (r1,c1 - r2,c2)
+     */
+    public CellRangeAddress getAreaAt(int index) {
+        return _regions[_startIndex + index];
+    }
+
+    protected int getDataSize() {
+		return CellRangeAddressList.getEncodedSize(_numberOfRegions);
+	}
+
+    public short getSid() {
+        return sid;
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        int nItems = _numberOfRegions;
+        out.writeShort(nItems);
+        for (int i = 0; i < _numberOfRegions; i++) {
+			_regions[_startIndex + i].serialize(out);
+		}
+    }
+
+    public String toString() {
+        StringBuffer retval = new StringBuffer();
+
+        retval.append("[MERGEDCELLS]").append("\n");
+        retval.append("     .numregions =").append(getNumAreas()).append("\n");
+        for (int k = 0; k < _numberOfRegions; k++) {
+            CellRangeAddress r = _regions[_startIndex + k];
+
+            retval.append("     .rowfrom =").append(r.getFirstRow()).append("\n");
+            retval.append("     .rowto   =").append(r.getLastRow()).append("\n");
+            retval.append("     .colfrom =").append(r.getFirstColumn()).append("\n");
+            retval.append("     .colto   =").append(r.getLastColumn()).append("\n");
+        }
+        retval.append("[MERGEDCELLS]").append("\n");
+        return retval.toString();
+    }
+
+    public Object clone() {
+    	int nRegions = _numberOfRegions;
+    	CellRangeAddress[] clonedRegions = new CellRangeAddress[nRegions];
+		for (int i = 0; i < clonedRegions.length; i++) {
+			clonedRegions[i] = _regions[_startIndex + i].copy();
+		}
+        return new MergeCellsRecord(clonedRegions, 0, nRegions);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/MulBlankRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/MulBlankRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/MulBlankRecord.java	(revision 28000)
@@ -0,0 +1,135 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Multiple Blank cell record(0x00BE) <P/>
+ * Description:  Represents a  set of columns in a row with no value but with styling.
+ * <p/>
+ * REFERENCE:  PG 329 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P/>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @see BlankRecord
+ */
+public final class MulBlankRecord extends StandardRecord {
+	public final static short sid = 0x00BE;
+
+	private final int _row;
+	private final int _firstCol;
+	private final short[] _xfs;
+	private final int _lastCol;
+
+	public MulBlankRecord(int row, int firstCol, short[] xfs) {
+		_row = row;
+		_firstCol = firstCol;
+		_xfs = xfs;
+		_lastCol = firstCol + xfs.length - 1;
+	}
+
+	/**
+	 * @return the row number of the cells this represents
+	 */
+	public int getRow() {
+		return _row;
+	}
+
+	/**
+	 * @return starting column (first cell this holds in the row). Zero based
+	 */
+	public int getFirstColumn() {
+		return _firstCol;
+	}
+	
+	/**
+	 * get the number of columns this contains (last-first +1)
+	 * @return number of columns (last - first +1)
+	 */
+	public int getNumColumns() {
+		return _lastCol - _firstCol + 1;
+	}
+
+	/**
+	 * returns the xf index for column (coffset = column - field_2_first_col)
+	 * @param coffset  the column (coffset = column - field_2_first_col)
+	 * @return the XF index for the column
+	 */
+	public short getXFAt(int coffset) {
+		return _xfs[coffset];
+	}
+
+	/**
+	 * @param in the RecordInputstream to read the record from
+	 */
+	public MulBlankRecord(RecordInputStream in) { // NO_UCD
+		_row	   = in.readUShort();
+		_firstCol = in.readShort();
+		_xfs	   = parseXFs(in);
+		_lastCol  = in.readShort();
+	}
+
+	private static short [] parseXFs(RecordInputStream in) {
+		short[] retval = new short[(in.remaining() - 2) / 2];
+
+		for (int idx = 0; idx < retval.length;idx++) {
+		  retval[idx] = in.readShort();
+		}
+		return retval;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+
+		buffer.append("[MULBLANK]\n");
+		buffer.append("row  = ").append(Integer.toHexString(getRow())).append("\n");
+		buffer.append("firstcol  = ").append(Integer.toHexString(getFirstColumn())).append("\n");
+		buffer.append(" lastcol  = ").append(Integer.toHexString(_lastCol)).append("\n");
+		for (int k = 0; k < getNumColumns(); k++) {
+			buffer.append("xf").append(k).append("		= ").append(
+					Integer.toHexString(getXFAt(k))).append("\n");
+		}
+		buffer.append("[/MULBLANK]\n");
+		return buffer.toString();
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		out.writeShort(_row);
+		out.writeShort(_firstCol);
+		int nItems = _xfs.length;
+		for (int i = 0; i < nItems; i++) {
+			out.writeShort(_xfs[i]);
+		}
+		out.writeShort(_lastCol);
+	}
+
+	protected int getDataSize() {
+		// 3 short fields + array of shorts
+		return 6 + _xfs.length * 2;
+	}
+
+	@Override
+	public Object clone() {
+		// immutable - so OK to return this
+		return this;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/MulRKRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/MulRKRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/MulRKRecord.java	(revision 28000)
@@ -0,0 +1,143 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.util.RKUtil;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * MULRK (0x00BD) <p/>
+ * 
+ * Used to store multiple RK numbers on a row.  1 MulRk = Multiple Cell values.
+ * HSSF just converts this into multiple NUMBER records.  READ-ONLY SUPPORT!<P>
+ * REFERENCE:  PG 330 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @version 2.0-pre
+ */
+public final class MulRKRecord extends StandardRecord {
+	public final static short sid = 0x00BD;
+
+	private int	 field_1_row;
+	private short   field_2_first_col;
+	private RkRec[] field_3_rks;
+	private short   field_4_last_col;
+
+	public int getRow() {
+		return field_1_row;
+	}
+
+	/**
+	 * starting column (first cell this holds in the row)
+	 * @return first column number
+	 */
+	public short getFirstColumn() {
+		return field_2_first_col;
+	}
+
+	/**
+	 * ending column (last cell this holds in the row)
+	 * @return first column number
+	 */
+	public short getLastColumn() {
+		return field_4_last_col;
+	}
+
+	/**
+	 * get the number of columns this contains (last-first +1)
+	 * @return number of columns (last - first +1)
+	 */
+	public int getNumColumns() {
+		return field_4_last_col - field_2_first_col + 1;
+	}
+
+	/**
+	 * returns the xf index for column (coffset = column - field_2_first_col)
+	 * @return the XF index for the column
+	 */
+	public short getXFAt(int coffset) {
+		return field_3_rks[coffset].xf;
+	}
+
+	/**
+	 * returns the rk number for column (coffset = column - field_2_first_col)
+	 * @return the value (decoded into a double)
+	 */
+	public double getRKNumberAt(int coffset) {
+		return RKUtil.decodeNumber(field_3_rks[coffset].rk);
+	}
+
+	/**
+	 * @param in the RecordInputstream to read the record from
+	 */
+	public MulRKRecord(RecordInputStream in) { // NO_UCD
+		field_1_row = in.readUShort();
+		field_2_first_col = in.readShort();
+		field_3_rks = RkRec.parseRKs(in);
+		field_4_last_col = in.readShort();
+	}
+
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+
+		buffer.append("[MULRK]\n");
+		buffer.append("	.row	 = ").append(HexDump.shortToHex(getRow())).append("\n");
+		buffer.append("	.firstcol= ").append(HexDump.shortToHex(getFirstColumn())).append("\n");
+		buffer.append("	.lastcol = ").append(HexDump.shortToHex(getLastColumn())).append("\n");
+
+		for (int k = 0; k < getNumColumns(); k++) {
+			buffer.append("	xf[").append(k).append("] = ").append(HexDump.shortToHex(getXFAt(k))).append("\n");
+			buffer.append("	rk[").append(k).append("] = ").append(getRKNumberAt(k)).append("\n");
+		}
+		buffer.append("[/MULRK]\n");
+		return buffer.toString();
+	}
+
+	public short getSid()
+	{
+		return sid;
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		throw new RecordFormatException( "Sorry, you can't serialize MulRK in this release");
+	}
+	protected int getDataSize() {
+		throw new RecordFormatException( "Sorry, you can't serialize MulRK in this release");
+	}
+
+	private static final class RkRec {
+		public static final int ENCODED_SIZE = 6;
+		public final short xf;
+		public final int   rk;
+
+		private RkRec(RecordInputStream in) {
+			xf = in.readShort();
+			rk = in.readInt();
+		}
+
+		public static RkRec[] parseRKs(RecordInputStream in) {
+			int nItems = (in.remaining()-2) / ENCODED_SIZE;
+			RkRec[] retval = new RkRec[nItems];
+			for (int i=0; i<nItems; i++) {
+				retval[i] = new RkRec(in);
+			}
+			return retval;
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/NameCommentRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/NameCommentRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/NameCommentRecord.java	(revision 28000)
@@ -0,0 +1,128 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * Title: NAMECMT Record (0x0894)
+ * <p/>
+ * Description: Defines a comment associated with a specified name.
+ * <P>
+ * REFERENCE:
+ * <P>
+ *
+ * @author Andrew Shirley (aks at corefiling.co.uk)
+ */
+public final class NameCommentRecord extends StandardRecord {
+  public final static short sid = 0x0894;
+
+  private final short field_1_record_type;
+  private final short field_2_frt_cell_ref_flag;
+  private final long field_3_reserved;
+  //private short             field_4_name_length;
+  //private short             field_5_comment_length;
+  private String field_6_name_text;
+  private String field_7_comment_text;
+
+  public NameCommentRecord(final String name, final String comment) { // NO_UCD
+    field_1_record_type = 0;
+    field_2_frt_cell_ref_flag = 0;
+    field_3_reserved = 0;
+    field_6_name_text = name;
+    field_7_comment_text = comment;
+  }
+
+  @Override
+  public void serialize(final LittleEndianOutput out) {
+    final int field_4_name_length = field_6_name_text.length();
+    final int field_5_comment_length = field_7_comment_text.length();
+
+    out.writeShort(field_1_record_type);
+    out.writeShort(field_2_frt_cell_ref_flag);
+    out.writeLong(field_3_reserved);
+    out.writeShort(field_4_name_length);
+    out.writeShort(field_5_comment_length);
+
+    out.writeByte(0);
+    out.write(field_6_name_text.getBytes());
+    out.writeByte(0);
+    out.write(field_7_comment_text.getBytes());
+  }
+
+  @Override
+  protected int getDataSize() {
+    return 18 // 4 shorts + 1 long + 2 spurious 'nul's
+         + field_6_name_text.length()
+         + field_7_comment_text.length();
+  }
+
+  /**
+   * @param ris the RecordInputstream to read the record from
+   */
+  public NameCommentRecord(final RecordInputStream ris) { // NO_UCD
+    final LittleEndianInput in = ris;
+    field_1_record_type = in.readShort();
+    field_2_frt_cell_ref_flag = in.readShort();
+    field_3_reserved = in.readLong();
+    final int field_4_name_length = in.readShort();
+    final int field_5_comment_length = in.readShort();
+
+    in.readByte(); //spurious NUL
+    field_6_name_text = StringUtil.readCompressedUnicode(in, field_4_name_length);
+    in.readByte(); //spurious NUL
+    field_7_comment_text = StringUtil.readCompressedUnicode(in, field_5_comment_length);
+  }
+
+  /**
+   * return the non static version of the id for this record.
+   */
+  @Override
+  public short getSid() {
+    return sid;
+  }
+
+  @Override
+  public String toString() {
+    final StringBuffer sb = new StringBuffer();
+
+    sb.append("[NAMECMT]\n");
+    sb.append("    .record type            = ").append(HexDump.shortToHex(field_1_record_type)).append("\n");
+    sb.append("    .frt cell ref flag      = ").append(HexDump.byteToHex(field_2_frt_cell_ref_flag)).append("\n");
+    sb.append("    .reserved               = ").append(field_3_reserved).append("\n");
+    sb.append("    .name length            = ").append(field_6_name_text.length()).append("\n");
+    sb.append("    .comment length         = ").append(field_7_comment_text.length()).append("\n");
+    sb.append("    .name                   = ").append(field_6_name_text).append("\n");
+    sb.append("    .comment                = ").append(field_7_comment_text).append("\n");
+    sb.append("[/NAMECMT]\n");
+
+    return sb.toString();
+  }
+
+  /**
+   * @return the name of the NameRecord to which this comment applies.
+   */
+  public String getNameText() {
+    return field_6_name_text;
+  }
+  
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/NameRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/NameRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/NameRecord.java	(revision 28000)
@@ -0,0 +1,410 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.ss.formula.Formula;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * Title:        DEFINEDNAME Record (0x0018) <p/>
+ * Description:  Defines a named range within a workbook. <P>
+ * REFERENCE:  <P>
+ * @author Libin Roman (Vista Portal LDT. Developer)
+ * @author  Sergei Kozello (sergeikozello at mail.ru)
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @author Petr Udalau - added method setFunction(boolean)
+ */
+public final class NameRecord extends StandardRecord {
+    public final static short sid = 0x0018;
+	/**Included for completeness sake, not implemented */
+	public final static byte  BUILTIN_CONSOLIDATE_AREA      = 1;
+	/**Included for completeness sake, not implemented */
+	public final static byte  BUILTIN_AUTO_OPEN             = 2;
+	/**Included for completeness sake, not implemented */
+	public final static byte  BUILTIN_AUTO_CLOSE            = 3;
+	/**Included for completeness sake, not implemented */
+	public final static byte  BUILTIN_DATABASE              = 4;
+	/**Included for completeness sake, not implemented */
+	public final static byte  BUILTIN_CRITERIA              = 5;
+
+	public final static byte  BUILTIN_PRINT_AREA            = 6;
+	public final static byte  BUILTIN_PRINT_TITLE           = 7;
+
+	/**Included for completeness sake, not implemented */
+	public final static byte  BUILTIN_RECORDER              = 8;
+	/**Included for completeness sake, not implemented */
+	public final static byte  BUILTIN_DATA_FORM             = 9;
+	/**Included for completeness sake, not implemented */
+	public final static byte  BUILTIN_AUTO_ACTIVATE         = 10;
+	/**Included for completeness sake, not implemented */
+	public final static byte  BUILTIN_AUTO_DEACTIVATE       = 11;
+	/**Included for completeness sake, not implemented */
+	public final static byte  BUILTIN_SHEET_TITLE           = 12;
+
+	public final static byte  BUILTIN_FILTER_DB             = 13;
+
+	private static final class Option {
+		public static final int OPT_BUILTIN =       0x0020;
+	}
+
+	private short             field_1_option_flag;
+	private byte              field_2_keyboard_shortcut;
+	/** One-based extern index of sheet (resolved via LinkTable). Zero if this is a global name  */
+	private short             field_5_externSheetIndex_plus1;
+	/** the one based sheet number.  */
+	private int               field_6_sheetNumber;
+	private boolean           field_11_nameIsMultibyte;
+	private byte              field_12_built_in_code;
+	private String            field_12_name_text;
+	private Formula           field_13_name_definition;
+	private String            field_14_custom_menu_text;
+	private String            field_15_description_text;
+	private String            field_16_help_topic_text;
+	private String            field_17_status_bar_text;
+
+
+	/** Creates new NameRecord */
+	public NameRecord() {
+		field_13_name_definition = Formula.create(Ptg.EMPTY_PTG_ARRAY);
+
+		field_12_name_text = "";
+		field_14_custom_menu_text = "";
+		field_15_description_text = "";
+		field_16_help_topic_text = "";
+		field_17_status_bar_text = "";
+	}
+
+	/**
+	 * Constructor to create a built-in named region
+	 * @param builtin Built-in byte representation for the name record, use the public constants
+	 */
+	public NameRecord(byte builtin, int sheetNumber) // NO_UCD
+	{
+		this();
+		field_12_built_in_code = builtin;
+		setOptionFlag((short)(field_1_option_flag | Option.OPT_BUILTIN));
+		field_6_sheetNumber = sheetNumber; //the extern sheets are set through references
+	}
+
+	/** sets the option flag for the named range
+	 * @param flag option flag
+	 */
+	public void setOptionFlag(short flag){
+		field_1_option_flag = flag;
+	}
+
+	/** gets the option flag
+	 * @return option flag
+	 */
+	public short getOptionFlag(){
+		return field_1_option_flag;
+	}
+
+	/** returns the keyboard shortcut
+	 * @return keyboard shortcut
+	 */
+	public byte getKeyboardShortcut(){
+		return field_2_keyboard_shortcut ;
+	}
+
+	/**
+	 * gets the name length, in characters
+	 * @return name length
+	 */
+	private int getNameTextLength(){
+		if (isBuiltInName()) {
+			return 1;
+		}
+		return field_12_name_text.length();
+	}
+
+	/**Convenience Function to determine if the name is a built-in name
+	 */
+	public boolean isBuiltInName()
+	{
+		return ((field_1_option_flag & Option.OPT_BUILTIN) != 0);
+	}
+
+
+	/** gets the name
+	 * @return name
+	 */
+	public String getNameText(){
+
+		return isBuiltInName() ? translateBuiltInName(getBuiltInName()) : field_12_name_text;
+	}
+
+	/** Gets the Built In Name
+	 * @return the built in Name
+	 */
+	public byte getBuiltInName()
+	{
+		return field_12_built_in_code;
+	}
+
+	/** get the custom menu text
+	 * @return custom menu text
+	 */
+	public String getCustomMenuText(){
+		return field_14_custom_menu_text;
+	}
+
+	/** gets the description text
+	 * @return description text
+	 */
+	public String getDescriptionText(){
+		return field_15_description_text;
+	}
+
+	/** get the help topic text
+	 * @return gelp topic text
+	 */
+	public String getHelpTopicText(){
+		return field_16_help_topic_text;
+	}
+
+	/** gets the status bar text
+	 * @return status bar text
+	 */
+	public String getStatusBarText(){
+		return field_17_status_bar_text;
+	}
+
+
+	public void serialize(LittleEndianOutput out) {
+
+		int field_7_length_custom_menu = field_14_custom_menu_text.length();
+		int field_8_length_description_text = field_15_description_text.length();
+		int field_9_length_help_topic_text = field_16_help_topic_text.length();
+		int field_10_length_status_bar_text = field_17_status_bar_text.length();
+
+		// size defined below
+		out.writeShort(getOptionFlag());
+		out.writeByte(getKeyboardShortcut());
+		out.writeByte(getNameTextLength());
+		// Note - formula size is not immediately before encoded formula, and does not include any array constant data
+		out.writeShort(field_13_name_definition.getEncodedTokenSize());
+		out.writeShort(field_5_externSheetIndex_plus1);
+		out.writeShort(field_6_sheetNumber);
+		out.writeByte(field_7_length_custom_menu);
+		out.writeByte(field_8_length_description_text);
+		out.writeByte(field_9_length_help_topic_text);
+		out.writeByte(field_10_length_status_bar_text);
+		out.writeByte(field_11_nameIsMultibyte ? 1 : 0);
+
+		if (isBuiltInName()) {
+			//can send the builtin name directly in
+			out.writeByte(field_12_built_in_code);
+		} else {
+			String nameText = field_12_name_text;
+			if (field_11_nameIsMultibyte) {
+				StringUtil.putUnicodeLE(nameText, out);
+			} else {
+				StringUtil.putCompressedUnicode(nameText, out);
+			}
+		}
+		field_13_name_definition.serializeTokens(out);
+		field_13_name_definition.serializeArrayConstantData(out);
+
+		StringUtil.putCompressedUnicode( getCustomMenuText(), out);
+		StringUtil.putCompressedUnicode( getDescriptionText(), out);
+		StringUtil.putCompressedUnicode( getHelpTopicText(), out);
+		StringUtil.putCompressedUnicode( getStatusBarText(), out);
+	}
+	private int getNameRawSize() {
+		if (isBuiltInName()) {
+			return 1;
+		}
+		int nChars = field_12_name_text.length();
+		if(field_11_nameIsMultibyte) {
+			return 2 * nChars;
+		}
+		return nChars;
+	}
+
+	protected int getDataSize() {
+		return 13 // 3 shorts + 7 bytes
+			+ getNameRawSize()
+			+ field_14_custom_menu_text.length()
+			+ field_15_description_text.length()
+			+ field_16_help_topic_text.length()
+			+ field_17_status_bar_text.length()
+			+ field_13_name_definition.getEncodedSize();
+	}
+
+
+	/**
+	 * called by the constructor, should set class level fields.  Should throw
+	 * runtime exception for bad/icomplete data.
+	 *
+	 * @param ris the RecordInputstream to read the record from
+	 */
+	public NameRecord(RecordInputStream ris) { // NO_UCD
+		LittleEndianInput in = ris;
+		field_1_option_flag                 = in.readShort();
+		field_2_keyboard_shortcut           = in.readByte();
+		int field_3_length_name_text        = in.readUByte();
+		int field_4_length_name_definition  = in.readShort();
+		field_5_externSheetIndex_plus1      = in.readShort();
+		field_6_sheetNumber                 = in.readUShort();
+		int f7_customMenuLen      = in.readUByte();
+		int f8_descriptionTextLen = in.readUByte();
+		int f9_helpTopicTextLen  = in.readUByte();
+		int f10_statusBarTextLen = in.readUByte();
+
+		//store the name in byte form if it's a built-in name
+		field_11_nameIsMultibyte = (in.readByte() != 0);
+		if (isBuiltInName()) {
+			field_12_built_in_code = in.readByte();
+		} else {
+			if (field_11_nameIsMultibyte) {
+				field_12_name_text = StringUtil.readUnicodeLE(in, field_3_length_name_text);
+			} else {
+				field_12_name_text = StringUtil.readCompressedUnicode(in, field_3_length_name_text);
+			}
+		}
+
+		int nBytesAvailable = in.available() - (f7_customMenuLen
+				+ f8_descriptionTextLen + f9_helpTopicTextLen + f10_statusBarTextLen);
+		field_13_name_definition = Formula.read(field_4_length_name_definition, in, nBytesAvailable);
+
+		//Who says that this can only ever be compressed unicode???
+		field_14_custom_menu_text = StringUtil.readCompressedUnicode(in, f7_customMenuLen);
+		field_15_description_text = StringUtil.readCompressedUnicode(in, f8_descriptionTextLen);
+		field_16_help_topic_text  = StringUtil.readCompressedUnicode(in, f9_helpTopicTextLen);
+		field_17_status_bar_text  = StringUtil.readCompressedUnicode(in, f10_statusBarTextLen);
+	}
+
+	/**
+	 * return the non static version of the id for this record.
+	 */
+	public short getSid() {
+		return sid;
+	}
+	/*
+	  20 00
+	  00
+	  01
+	  1A 00 // sz = 0x1A = 26
+	  00 00
+	  01 00
+	  00
+	  00
+	  00
+	  00
+	  00 // unicode flag
+	  07 // name
+
+	  29 17 00 3B 00 00 00 00 FF FF 00 00 02 00 3B 00 //{ 26
+	  00 07 00 07 00 00 00 FF 00 10                   //  }
+
+
+
+	  20 00
+	  00
+	  01
+	  0B 00 // sz = 0xB = 11
+	  00 00
+	  01 00
+	  00
+	  00
+	  00
+	  00
+	  00 // unicode flag
+	  07 // name
+
+	  3B 00 00 07 00 07 00 00 00 FF 00   // { 11 }
+  */
+	/*
+	  18, 00,
+	  1B, 00,
+
+	  20, 00,
+	  00,
+	  01,
+	  0B, 00,
+	  00,
+	  00,
+	  00,
+	  00,
+	  00,
+	  07,
+	  3B 00 00 07 00 07 00 00 00 FF 00 ]
+	 */
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+
+		sb.append("[NAME]\n");
+		sb.append("    .option flags           = ").append(HexDump.shortToHex(field_1_option_flag)).append("\n");
+		sb.append("    .keyboard shortcut      = ").append(HexDump.byteToHex(field_2_keyboard_shortcut)).append("\n");
+		sb.append("    .length of the name     = ").append(getNameTextLength()).append("\n");
+		sb.append("    .extSheetIx(1-based, 0=Global)= ").append( field_5_externSheetIndex_plus1 ).append("\n");
+		sb.append("    .sheetTabIx             = ").append(field_6_sheetNumber ).append("\n");
+		sb.append("    .Menu text length       = ").append(field_14_custom_menu_text.length()).append("\n");
+		sb.append("    .Description text length= ").append(field_15_description_text.length()).append("\n");
+		sb.append("    .Help topic text length = ").append(field_16_help_topic_text.length()).append("\n");
+		sb.append("    .Status bar text length = ").append(field_17_status_bar_text.length()).append("\n");
+		sb.append("    .NameIsMultibyte        = ").append(field_11_nameIsMultibyte).append("\n");
+		sb.append("    .Name (Unicode text)    = ").append( getNameText() ).append("\n");
+		Ptg[] ptgs = field_13_name_definition.getTokens();
+		sb.append("    .Formula (nTokens=").append(ptgs.length).append("):") .append("\n");
+		for (int i = 0; i < ptgs.length; i++) {
+			Ptg ptg = ptgs[i];
+			sb.append("       " + ptg.toString()).append(ptg.getRVAType()).append("\n");
+		}
+
+		sb.append("    .Menu text       = ").append(field_14_custom_menu_text).append("\n");
+		sb.append("    .Description text= ").append(field_15_description_text).append("\n");
+		sb.append("    .Help topic text = ").append(field_16_help_topic_text).append("\n");
+		sb.append("    .Status bar text = ").append(field_17_status_bar_text).append("\n");
+		sb.append("[/NAME]\n");
+
+		return sb.toString();
+	}
+
+	/**Creates a human readable name for built in types
+	 * @return Unknown if the built-in name cannot be translated
+	 */
+	private static String translateBuiltInName(byte name)
+	{
+		switch (name)
+		{
+			case NameRecord.BUILTIN_AUTO_ACTIVATE :     return "Auto_Activate";
+			case NameRecord.BUILTIN_AUTO_CLOSE :        return "Auto_Close";
+			case NameRecord.BUILTIN_AUTO_DEACTIVATE :   return "Auto_Deactivate";
+			case NameRecord.BUILTIN_AUTO_OPEN :         return "Auto_Open";
+			case NameRecord.BUILTIN_CONSOLIDATE_AREA :  return "Consolidate_Area";
+			case NameRecord.BUILTIN_CRITERIA :          return "Criteria";
+			case NameRecord.BUILTIN_DATABASE :          return "Database";
+			case NameRecord.BUILTIN_DATA_FORM :         return "Data_Form";
+			case NameRecord.BUILTIN_PRINT_AREA :        return "Print_Area";
+			case NameRecord.BUILTIN_PRINT_TITLE :       return "Print_Titles";
+			case NameRecord.BUILTIN_RECORDER :          return "Recorder";
+			case NameRecord.BUILTIN_SHEET_TITLE :       return "Sheet_Title";
+			case NameRecord.BUILTIN_FILTER_DB  :        return "_FilterDatabase";
+
+		}
+
+		return "Unknown";
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/NoteStructureSubRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/NoteStructureSubRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/NoteStructureSubRecord.java	(revision 28000)
@@ -0,0 +1,111 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * ftNts (0x000D)<p/>
+ * Represents a NoteStructure sub record.
+ *
+ * <p>
+ * The docs say nothing about it. The length of this record is always 26 bytes.
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+public final class NoteStructureSubRecord extends SubRecord {
+    public final static short sid = 0x0D;
+    private static final int ENCODED_SIZE = 22;
+
+    private byte[] reserved;
+
+    /**
+     * Construct a new <code>NoteStructureSubRecord</code> and
+     * fill its data with the default values
+     */
+    public NoteStructureSubRecord()
+    {
+        //all we know is that the the length of <code>NoteStructureSubRecord</code> is always 22 bytes
+        reserved = new byte[ENCODED_SIZE];
+    }
+
+    /**
+     * Read the record data from the supplied <code>RecordInputStream</code>
+     */
+    public NoteStructureSubRecord(LittleEndianInput in, int size) {
+        if (size != ENCODED_SIZE) {
+            throw new RecordFormatException("Unexpected size (" + size + ")");
+        }
+        //just grab the raw data
+        byte[] buf = new byte[size];
+        in.readFully(buf);
+        reserved = buf;
+    }
+
+    /**
+     * Convert this record to string.
+     * Used by BiffViewer and other utilities.
+     */
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[ftNts ]").append("\n");
+        buffer.append("  size     = ").append(getDataSize()).append("\n");
+        buffer.append("  reserved = ").append(HexDump.toHex(reserved)).append("\n");
+        buffer.append("[/ftNts ]").append("\n");
+        return buffer.toString();
+    }
+
+    /**
+     * Serialize the record data into the supplied array of bytes
+     *
+     * @param out the stream to serialize into
+     */
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(sid);
+        out.writeShort(reserved.length);
+        out.write(reserved);
+    }
+
+	protected int getDataSize() {
+        return reserved.length;
+    }
+
+    /**
+     * @return id of this record.
+     */
+    public short getSid() // NO_UCD
+    {
+        return sid;
+    }
+
+    public Object clone() {
+        NoteStructureSubRecord rec = new NoteStructureSubRecord();
+        byte[] recdata = new byte[reserved.length];
+        System.arraycopy(reserved, 0, recdata, 0, recdata.length);
+        rec.reserved = recdata;
+        return rec;
+    }
+
+}
+
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/NumberRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/NumberRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/NumberRecord.java	(revision 28000)
@@ -0,0 +1,94 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.ss.util.NumberToTextConverter;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * NUMBER (0x0203) Contains a numeric cell value. <P>
+ * REFERENCE:  PG 334 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class NumberRecord extends CellRecord {
+    public static final short sid = 0x0203;
+    private double field_4_value;
+
+    /** Creates new NumberRecord */
+    public NumberRecord() {
+    	// fields uninitialised
+    }
+
+    /**
+     * @param in the RecordInputstream to read the record from
+     */
+    public NumberRecord(RecordInputStream in) { // NO_UCD
+        super(in);
+        field_4_value = in.readDouble();
+    }
+
+    /**
+     * set the value for the cell
+     *
+     * @param value  double representing the value
+     */
+    public void setValue(double value){
+        field_4_value = value;
+    }
+
+    /**
+     * get the value for the cell
+     *
+     * @return double representing the value
+     */
+    public double getValue(){
+        return field_4_value;
+    }
+
+    @Override
+    protected String getRecordName() {
+    	return "NUMBER";
+    }
+
+    @Override
+    protected void appendValueText(StringBuilder sb) {
+    	sb.append("  .value= ").append(NumberToTextConverter.toText(field_4_value));
+    }
+
+    @Override
+    protected void serializeValue(LittleEndianOutput out) {
+        out.writeDouble(getValue());
+    }
+
+    @Override
+    protected int getValueDataSize() {
+    	return 8;
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    public Object clone() {
+      NumberRecord rec = new NumberRecord();
+      copyBaseFields(rec);
+      rec.field_4_value = field_4_value;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ObjRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ObjRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/ObjRecord.java	(revision 28000)
@@ -0,0 +1,215 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianByteArrayOutputStream;
+import org.apache.poi.util.LittleEndianInputStream;
+
+/**
+ * OBJRECORD (0x005D)<p/>
+ * 
+ * The obj record is used to hold various graphic objects and controls.
+ *
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class ObjRecord extends Record {
+	public final static short sid = 0x005D;
+
+	private static final int NORMAL_PAD_ALIGNMENT = 2;
+	private static int MAX_PAD_ALIGNMENT = 4;
+	
+	private List<SubRecord> subrecords;
+	/** used when POI has no idea what is going on */
+	private final byte[] _uninterpretedData;
+	/**
+	 * Excel seems to tolerate padding to quad or double byte length
+	 */
+	private boolean _isPaddedToQuadByteMultiple;
+
+	//00000000 15 00 12 00 01 00 01 00 11 60 00 00 00 00 00 0D .........`......
+	//00000010 26 01 00 00 00 00 00 00 00 00                   &.........
+
+
+	public ObjRecord() {
+		subrecords = new ArrayList<SubRecord>(2);
+		// TODO - ensure 2 sub-records (ftCmo 15h, and ftEnd 00h) are always created
+		_uninterpretedData = null;
+	}
+
+	public ObjRecord(RecordInputStream in) { // NO_UCD
+		// TODO - problems with OBJ sub-records stream
+		// MS spec says first sub-record is always CommonObjectDataSubRecord,
+		// and last is
+		// always EndSubRecord. OOO spec does not mention ObjRecord(0x005D).
+		// Existing POI test data seems to violate that rule. Some test data
+		// seems to contain
+		// garbage, and a crash is only averted by stopping at what looks like
+		// the 'EndSubRecord'
+
+		// Check if this can be continued, if so then the
+		// following wont work properly
+		byte[] subRecordData = in.readRemainder();
+		if (LittleEndian.getUShort(subRecordData, 0) != CommonObjectDataSubRecord.sid) {
+			// seems to occur in just one junit on "OddStyleRecord.xls" (file created by CrystalReports)
+			// Excel tolerates the funny ObjRecord, and replaces it with a corrected version
+			// The exact logic/reasoning is not yet understood
+			_uninterpretedData = subRecordData;
+			subrecords = null;
+			return;
+		}
+
+        //YK: files produced by OO violate the condition below
+        /*
+        if (subRecordData.length % 2 != 0) {
+			String msg = "Unexpected length of subRecordData : " + HexDump.toHex(subRecordData);
+			throw new RecordFormatException(msg);
+		}
+        */
+
+		subrecords = new ArrayList<SubRecord>();
+		ByteArrayInputStream bais = new ByteArrayInputStream(subRecordData);
+		LittleEndianInputStream subRecStream = new LittleEndianInputStream(bais);
+		CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord)SubRecord.createSubRecord(subRecStream, 0);
+        subrecords.add(cmo);
+        while (true) {
+			SubRecord subRecord = SubRecord.createSubRecord(subRecStream, cmo.getObjectType());
+			subrecords.add(subRecord);
+			if (subRecord.isTerminating()) {
+				break;
+			}
+		}
+		int nRemainingBytes = bais.available();
+		if (nRemainingBytes > 0) {
+			// At present (Oct-2008), most unit test samples have (subRecordData.length % 2 == 0)
+			_isPaddedToQuadByteMultiple = subRecordData.length % MAX_PAD_ALIGNMENT == 0;
+			if (nRemainingBytes >= (_isPaddedToQuadByteMultiple ? MAX_PAD_ALIGNMENT : NORMAL_PAD_ALIGNMENT)) {
+				if (!canPaddingBeDiscarded(subRecordData, nRemainingBytes)) {
+					String msg = "Leftover " + nRemainingBytes 
+						+ " bytes in subrecord data " + HexDump.toHex(subRecordData);
+					throw new RecordFormatException(msg);
+				}
+				_isPaddedToQuadByteMultiple = false;
+			}
+
+        } else {
+			_isPaddedToQuadByteMultiple = false;
+		}
+		_uninterpretedData = null;
+	}
+
+	/**
+	 * Some XLS files have ObjRecords with nearly 8Kb of excessive padding. These were probably
+	 * written by a version of POI (around 3.1) which incorrectly interpreted the second short of
+	 * the ftLbs subrecord (0x1FEE) as a length, and read that many bytes as padding (other bugs
+	 * helped allow this to occur).
+	 * 
+	 * Excel reads files with this excessive padding OK, truncating the over-sized ObjRecord back
+	 * to the its proper size.  POI does the same.
+	 */
+	private static boolean canPaddingBeDiscarded(byte[] data, int nRemainingBytes) {
+        // make sure none of the padding looks important
+		for(int i=data.length-nRemainingBytes; i<data.length; i++) {
+			if (data[i] != 0x00) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+
+		sb.append("[OBJ]\n");
+		for (int i = 0; i < subrecords.size(); i++) {
+			SubRecord record = subrecords.get(i);
+			sb.append("SUBRECORD: ").append(record.toString());
+		}
+		sb.append("[/OBJ]\n");
+		return sb.toString();
+	}
+	
+	public int getRecordSize() {
+		if (_uninterpretedData != null) {
+			return _uninterpretedData.length + 4;
+		}
+		int size = 0;
+		for (int i=subrecords.size()-1; i>=0; i--) {
+			SubRecord record = subrecords.get(i);
+			size += record.getDataSize()+4;
+		}
+		if (_isPaddedToQuadByteMultiple) {
+			while (size % MAX_PAD_ALIGNMENT != 0) {
+				size++;
+			}
+		} else {
+			while (size % NORMAL_PAD_ALIGNMENT != 0) {
+				size++;
+			}
+		}
+		return size + 4;
+	}
+
+	public int serialize(int offset, byte[] data) {
+		int recSize = getRecordSize();
+		int dataSize = recSize - 4;
+		LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(data, offset, recSize);
+
+		out.writeShort(sid);
+		out.writeShort(dataSize);
+
+		if (_uninterpretedData == null) {
+
+			for (int i = 0; i < subrecords.size(); i++) {
+				SubRecord record = subrecords.get(i);
+				record.serialize(out);
+			}
+			int expectedEndIx = offset+dataSize;
+			// padding
+			while (out.getWriteIndex() < expectedEndIx) {
+				out.writeByte(0);
+			}
+		} else {
+			out.write(_uninterpretedData);
+		}
+		return recSize;
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	public boolean addSubRecord(SubRecord o) {
+		return subrecords.add(o);
+	}
+
+	public Object clone() {
+		ObjRecord rec = new ObjRecord();
+
+		for (int i = 0; i < subrecords.size(); i++) {
+			SubRecord record = subrecords.get(i);
+			rec.addSubRecord((SubRecord) record.clone());
+		}
+		return rec;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/PageBreakRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/PageBreakRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/PageBreakRecord.java	(revision 28000)
@@ -0,0 +1,171 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * <p>Record that contains the functionality page breaks (horizontal and vertical)</p>
+ *
+ * <p>The other two classes just specifically set the SIDS for record creation.</p>
+ *
+ * <p>REFERENCE:  Microsoft Excel SDK page 322 and 420</p>
+ *
+ * @see HorizontalPageBreakRecord
+ * @see VerticalPageBreakRecord
+ * @author Danny Mui (dmui at apache dot org)
+ */
+public abstract class PageBreakRecord extends StandardRecord {
+    private List<Break> _breaks;
+    private Map<Integer, Break> _breakMap;
+
+    /**
+     * Since both records store 2byte integers (short), no point in
+     * differentiating it in the records.
+     * <p>
+     * The subs (rows or columns, don't seem to be able to set but excel sets
+     * them automatically)
+     */
+    public static final class Break {
+
+        public static final int ENCODED_SIZE = 6;
+        public int main;
+        public int subFrom;
+        public int subTo;
+
+        public Break(int main, int subFrom, int subTo)
+        {
+            this.main = main;
+            this.subFrom = subFrom;
+            this.subTo = subTo;
+        }
+
+        public Break(RecordInputStream in) {
+            main = in.readUShort() - 1;
+            subFrom = in.readUShort();
+            subTo = in.readUShort();
+        }
+
+        public void serialize(LittleEndianOutput out) {
+            out.writeShort(main + 1);
+            out.writeShort(subFrom);
+            out.writeShort(subTo);
+        }
+    }
+
+    protected PageBreakRecord() {
+        _breaks = new ArrayList<Break>();
+        _breakMap = new HashMap<Integer, Break>();
+    }
+
+    public PageBreakRecord(RecordInputStream in)
+    {
+        int nBreaks = in.readShort();
+        _breaks = new ArrayList<Break>(nBreaks + 2);
+        _breakMap = new HashMap<Integer, Break>();
+
+        for(int k = 0; k < nBreaks; k++) {
+            Break br = new Break(in);
+            _breaks.add(br);
+            _breakMap.put(Integer.valueOf(br.main), br);
+        }
+
+    }
+
+    protected int getDataSize() {
+        return 2 + _breaks.size() * Break.ENCODED_SIZE;
+    }
+
+    public final void serialize(LittleEndianOutput out) {
+        int nBreaks = _breaks.size();
+        out.writeShort(nBreaks);
+        for (int i=0; i<nBreaks; i++) {
+            _breaks.get(i).serialize(out);
+        }
+    }
+
+    public int getNumBreaks() {
+        return _breaks.size();
+    }
+
+    public final Iterator<Break> getBreaksIterator() {
+        return _breaks.iterator();
+    }
+
+    public String toString() {
+        StringBuffer retval = new StringBuffer();
+
+        String label;
+        String mainLabel;
+        String subLabel;
+
+        if (getSid() == HorizontalPageBreakRecord.sid) {
+           label = "HORIZONTALPAGEBREAK";
+           mainLabel = "row";
+           subLabel = "col";
+        } else {
+           label = "VERTICALPAGEBREAK";
+           mainLabel = "column";
+           subLabel = "row";
+        }
+
+        retval.append("["+label+"]").append("\n");
+        retval.append("     .sid        =").append(getSid()).append("\n");
+        retval.append("     .numbreaks =").append(getNumBreaks()).append("\n");
+        Iterator<Break> iterator = getBreaksIterator();
+        for(int k = 0; k < getNumBreaks(); k++)
+        {
+            Break region = iterator.next();
+
+            retval.append("     .").append(mainLabel).append(" (zero-based) =").append(region.main).append("\n");
+            retval.append("     .").append(subLabel).append("From    =").append(region.subFrom).append("\n");
+            retval.append("     .").append(subLabel).append("To      =").append(region.subTo).append("\n");
+        }
+
+        retval.append("["+label+"]").append("\n");
+        return retval.toString();
+    }
+
+   /**
+    * Adds the page break at the specified parameters
+    * @param main Depending on sid, will determine row or column to put page break (zero-based)
+    * @param subFrom No user-interface to set (defaults to minimum, 0)
+    * @param subTo No user-interface to set
+    */
+    public void addBreak(int main, int subFrom, int subTo) {
+
+        Integer key = Integer.valueOf(main);
+        Break region = _breakMap.get(key);
+        if(region == null) {
+            region = new Break(main, subFrom, subTo);
+            _breakMap.put(key, region);
+            _breaks.add(region);
+        } else {
+            region.main = main;
+            region.subFrom = subFrom;
+            region.subTo = subTo;
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/PaneRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/PaneRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/PaneRecord.java	(revision 28000)
@@ -0,0 +1,161 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Describes the frozen and unfozen panes.<p/>
+ * 
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class PaneRecord extends StandardRecord {
+    public final static short      sid                             = 0x41;
+    private  short      field_1_x;
+    private  short      field_2_y;
+    private  short      field_3_topRow;
+    private  short      field_4_leftColumn;
+    private  short      field_5_activePane;
+
+    public PaneRecord()
+    {
+
+    }
+
+    public PaneRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_x                      = in.readShort();
+        field_2_y                      = in.readShort();
+        field_3_topRow                 = in.readShort();
+        field_4_leftColumn             = in.readShort();
+        field_5_activePane             = in.readShort();
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[PANE]\n");
+        buffer.append("    .x                    = ")
+            .append("0x").append(HexDump.toHex(  getX ()))
+            .append(" (").append( getX() ).append(" )");
+        buffer.append(System.getProperty("line.separator")); 
+        buffer.append("    .y                    = ")
+            .append("0x").append(HexDump.toHex(  getY ()))
+            .append(" (").append( getY() ).append(" )");
+        buffer.append(System.getProperty("line.separator")); 
+        buffer.append("    .topRow               = ")
+            .append("0x").append(HexDump.toHex(  getTopRow ()))
+            .append(" (").append( getTopRow() ).append(" )");
+        buffer.append(System.getProperty("line.separator")); 
+        buffer.append("    .leftColumn           = ")
+            .append("0x").append(HexDump.toHex(  getLeftColumn ()))
+            .append(" (").append( getLeftColumn() ).append(" )");
+        buffer.append(System.getProperty("line.separator")); 
+        buffer.append("    .activePane           = ")
+            .append("0x").append(HexDump.toHex(  getActivePane ()))
+            .append(" (").append( getActivePane() ).append(" )");
+        buffer.append(System.getProperty("line.separator")); 
+
+        buffer.append("[/PANE]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(field_1_x);
+        out.writeShort(field_2_y);
+        out.writeShort(field_3_topRow);
+        out.writeShort(field_4_leftColumn);
+        out.writeShort(field_5_activePane);
+    }
+
+    protected int getDataSize() {
+        return 2 + 2 + 2 + 2 + 2;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public Object clone() {
+        PaneRecord rec = new PaneRecord();
+    
+        rec.field_1_x = field_1_x;
+        rec.field_2_y = field_2_y;
+        rec.field_3_topRow = field_3_topRow;
+        rec.field_4_leftColumn = field_4_leftColumn;
+        rec.field_5_activePane = field_5_activePane;
+        return rec;
+    }
+
+
+
+
+    /**
+     * Get the x field for the Pane record.
+     */
+    public short getX()
+    {
+        return field_1_x;
+    }
+
+
+    /**
+     * Get the y field for the Pane record.
+     */
+    public short getY()
+    {
+        return field_2_y;
+    }
+
+    /**
+     * Get the top row field for the Pane record.
+     */
+    public short getTopRow()
+    {
+        return field_3_topRow;
+    }
+
+
+    /**
+     * Get the left column field for the Pane record.
+     */
+    public short getLeftColumn()
+    {
+        return field_4_leftColumn;
+    }
+
+
+    /**
+     * Get the active pane field for the Pane record.
+     *
+     * @return  One of 
+     *        ACTIVE_PANE_LOWER_RIGHT
+     *        ACTIVE_PANE_UPPER_RIGHT
+     *        ACTIVE_PANE_LOWER_LEFT
+     *        ACTIVE_PANE_UPPER_LEFT
+     */
+    public short getActivePane()
+    {
+        return field_5_activePane;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/PrecisionRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/PrecisionRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/PrecisionRecord.java	(revision 28000)
@@ -0,0 +1,83 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Precision Record<P>
+ * Description:  defines whether to store with full precision or what's displayed by the gui
+ *               (meaning have really screwed up and skewed figures or only think you do!)<P>
+ * REFERENCE:  PG 372 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @version 2.0-pre
+ */
+
+public final class PrecisionRecord
+    extends StandardRecord
+{
+    public final static short sid = 0xE;
+    public short              field_1_precision;
+
+    public PrecisionRecord()
+    {
+    }
+
+    public PrecisionRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_precision = in.readShort();
+    }
+
+
+    /**
+     * get whether to use full precision or just skew all you figures all to hell.
+     *
+     * @return fullprecision - or not
+     */
+
+    public boolean getFullPrecision()
+    {
+        return (field_1_precision == 1);
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[PRECISION]\n");
+        buffer.append("    .precision       = ").append(getFullPrecision())
+            .append("\n");
+        buffer.append("[/PRECISION]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(field_1_precision);
+    }
+
+    protected int getDataSize() {
+        return 2;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RKRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RKRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RKRecord.java	(revision 28000)
@@ -0,0 +1,103 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.util.RKUtil;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        RK Record (0x027E)<p/>
+ * Description:  An internal 32 bit number with the two most significant bits
+ *               storing the type.  This is part of a bizarre scheme to save disk
+ *               space and memory (gee look at all the other whole records that
+ *               are in the file just "cause"..,far better to waste processor
+ *               cycles on this then leave on of those "valuable" records out).<p/>
+ * We support this in READ-ONLY mode.  HSSF converts these to NUMBER records<p/>
+ *
+ *
+ *
+ * REFERENCE:  PG 376 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @see org.apache.poi.hssf.record.NumberRecord
+ */
+public final class RKRecord extends CellRecord {
+    public final static short sid                      = 0x027E;
+    private int field_4_rk_number;
+
+    private RKRecord() {
+    	// fields uninitialised
+    }
+
+    public RKRecord(RecordInputStream in) { // NO_UCD
+        super(in);
+        field_4_rk_number = in.readInt();
+    }
+
+    /**
+     * Extract the value of the number
+     * <P>
+     * The mechanism for determining the value is dependent on the two
+     * low order bits of the raw number. If bit 1 is set, the number
+     * is an integer and can be cast directly as a double, otherwise,
+     * it's apparently the exponent and mantissa of a double (and the
+     * remaining low-order bits of the double's mantissa are 0's).
+     * <P>
+     * If bit 0 is set, the result of the conversion to a double is
+     * divided by 100; otherwise, the value is left alone.
+     * <P>
+     * [insert picture of Screwy Squirrel in full Napoleonic regalia]
+     *
+     * @return the value as a proper double (hey, it <B>could</B>
+     *         happen)
+     */
+    public double getRKNumber() {
+        return RKUtil.decodeNumber(field_4_rk_number);
+    }
+
+    @Override
+    protected String getRecordName() {
+    	return "RK";
+    }
+
+    @Override
+    protected void appendValueText(StringBuilder sb) {
+    	sb.append("  .value= ").append(getRKNumber());
+    }
+
+    @Override
+    protected void serializeValue(LittleEndianOutput out) {
+    	out.writeInt(field_4_rk_number);
+    }
+
+    @Override
+    protected int getValueDataSize() {
+    	return 4;
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    public Object clone() {
+      RKRecord rec = new RKRecord();
+      copyBaseFields(rec);
+      rec.field_4_rk_number = field_4_rk_number;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/Record.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/Record.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/Record.java	(revision 28000)
@@ -0,0 +1,88 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import java.io.ByteArrayInputStream;
+
+/**
+ * Title: Record
+ * Description: All HSSF Records inherit from this class.
+ * @author Andrew C. Oliver
+ * @author Marc Johnson (mjohnson at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public abstract class Record extends RecordBase {
+
+	protected Record() {
+		// no fields to initialise
+	}
+
+	/**
+	 * called by the class that is responsible for writing this sucker.
+	 * Subclasses should implement this so that their data is passed back in a
+	 * byte array.
+	 *
+	 * @return byte array containing instance data
+	 */
+	public final byte[] serialize() {
+		byte[] retval = new byte[ getRecordSize() ];
+
+		serialize(0, retval);
+		return retval;
+	}
+
+	/**
+	 * get a string representation of the record (for biffview/debugging)
+	 */
+	public String toString() {
+		return super.toString();
+	}
+
+	/**
+	 * return the non static version of the id for this record.
+	 */
+
+	public abstract short getSid();
+
+	public Object clone() {
+		throw new RuntimeException("The class "+getClass().getName()+" needs to define a clone method");
+	}
+
+	/**
+	 * Clone the current record, via a call to serialize
+	 *  it, and another to create a new record from the
+	 *  bytes.
+	 * May only be used for classes which don't have
+	 *  internal counts / ids in them. For those which
+	 *  do, a full model-aware cloning is needed, which
+	 *  allocates new ids / counts as needed.
+	 */
+	public Record cloneViaReserialise() {
+		// Do it via a re-serialization
+		// It's a cheat, but it works...
+		byte[] b = serialize();
+		RecordInputStream rinp = new RecordInputStream(new ByteArrayInputStream(b));
+		rinp.nextRecord();
+
+		Record[] r = RecordFactory.createRecord(rinp);
+		if(r.length != 1) {
+			throw new IllegalStateException("Re-serialised a record to clone it, but got " + r.length + " records back!");
+		}
+		return r[0];
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordBase.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordBase.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordBase.java	(revision 28000)
@@ -0,0 +1,42 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+/**
+ * Common base class of {@link Record} and {@link org.apache.poi.hssf.record.aggregates.RecordAggregate}
+ * 
+ * @author Josh Micich
+ */
+public abstract class RecordBase {
+	/**
+	 * called by the class that is responsible for writing this sucker.
+	 * Subclasses should implement this so that their data is passed back in a
+	 * byte array.
+	 * 
+	 * @param offset to begin writing at
+	 * @param data byte array containing instance data
+	 * @return number of bytes written
+	 */
+	public abstract int serialize(int offset, byte[] data);
+
+	/**
+	 * gives the current serialized size of the record. Should include the sid
+	 * and reclength (4 bytes).
+	 */
+	public abstract int getRecordSize();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordFactory.java	(revision 28000)
@@ -0,0 +1,319 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Title:  Record Factory<P>
+ * Description:  Takes a stream and outputs an array of Record objects.<P>
+ *
+ * @see org.apache.poi.hssf.eventmodel.EventRecordFactory
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Marc Johnson (mjohnson at apache dot org)
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @author Csaba Nagy (ncsaba at yahoo dot com)
+ */
+public final class RecordFactory {
+	private static final int NUM_RECORDS = 512;
+
+	private interface I_RecordCreator {
+		Record create(RecordInputStream in);
+
+		Class<? extends Record> getRecordClass();
+	}
+	private static final class ReflectionConstructorRecordCreator implements I_RecordCreator {
+
+		private final Constructor<? extends Record> _c;
+		public ReflectionConstructorRecordCreator(Constructor<? extends Record> c) {
+			_c = c;
+		}
+		public Record create(RecordInputStream in) {
+			Object[] args = { in, };
+			try {
+				return _c.newInstance(args);
+			} catch (IllegalArgumentException e) {
+				throw new RuntimeException(e);
+			} catch (InstantiationException e) {
+				throw new RuntimeException(e);
+			} catch (IllegalAccessException e) {
+				throw new RuntimeException(e);
+			} catch (InvocationTargetException e) {
+				throw new RecordFormatException("Unable to construct record instance" , e.getTargetException());
+			}
+		}
+		public Class<? extends Record> getRecordClass() {
+			return _c.getDeclaringClass();
+		}
+	}
+	/**
+	 * A "create" method is used instead of the usual constructor if the created record might
+	 * be of a different class to the declaring class.
+	 */
+	private static final class ReflectionMethodRecordCreator implements I_RecordCreator {
+
+		private final Method _m;
+		public ReflectionMethodRecordCreator(Method m) {
+			_m = m;
+		}
+		public Record create(RecordInputStream in) {
+			Object[] args = { in, };
+			try {
+				return (Record) _m.invoke(null, args);
+			} catch (IllegalArgumentException e) {
+				throw new RuntimeException(e);
+			} catch (IllegalAccessException e) {
+				throw new RuntimeException(e);
+			} catch (InvocationTargetException e) {
+				throw new RecordFormatException("Unable to construct record instance" , e.getTargetException());
+			}
+		}
+		@SuppressWarnings("unchecked")
+		public Class<? extends Record> getRecordClass() {
+			return (Class<? extends Record>) _m.getDeclaringClass();
+		}
+	}
+
+
+	private static final Class<?>[] CONSTRUCTOR_ARGS = { RecordInputStream.class, };
+
+	/**
+	 * contains the classes for all the records we want to parse.<br/>
+	 * Note - this most but not *every* subclass of Record.
+	 */
+	@SuppressWarnings("unchecked")
+	private static final Class<? extends Record>[] recordClasses = new Class[] {
+		ArrayRecord.class,
+		BlankRecord.class,
+		BOFRecord.class,
+		BoolErrRecord.class,
+		BoundSheetRecord.class,
+		CalcCountRecord.class,
+		CalcModeRecord.class,
+		ColumnInfoRecord.class,
+		ContinueRecord.class,
+		CRNCountRecord.class,
+		CRNRecord.class,
+		DateWindow1904Record.class,
+		DBCellRecord.class,
+		DeltaRecord.class,
+		DimensionsRecord.class,
+		DVALRecord.class,
+		DVRecord.class,
+		EOFRecord.class,
+		ExtendedFormatRecord.class,
+		ExternalNameRecord.class,
+		ExternSheetRecord.class,
+		ExtSSTRecord.class,
+		FeatRecord.class,
+		FeatHdrRecord.class,
+		FilePassRecord.class,
+		FormatRecord.class,
+		FormulaRecord.class,
+		GridsetRecord.class,
+		GutsRecord.class,
+		HorizontalPageBreakRecord.class,
+		HyperlinkRecord.class,
+		IndexRecord.class,
+		IterationRecord.class,
+		LabelRecord.class,
+		LabelSSTRecord.class,
+		MergeCellsRecord.class,
+		MulBlankRecord.class,
+		MulRKRecord.class,
+		NameRecord.class,
+		NameCommentRecord.class,
+		NumberRecord.class,
+		ObjRecord.class,
+		PaneRecord.class,
+		PrecisionRecord.class,
+		RefModeRecord.class,
+		RKRecord.class,
+		RowRecord.class,
+		SaveRecalcRecord.class,
+		SelectionRecord.class,
+		SharedFormulaRecord.class,
+		SSTRecord.class,
+		StringRecord.class,
+		SupBookRecord.class,
+		TabIdRecord.class,
+		TableRecord.class,
+		TextObjectRecord.class,
+		UncalcedRecord.class,
+		VerticalPageBreakRecord.class,
+		WindowOneRecord.class,
+		WindowTwoRecord.class,
+		WSBoolRecord.class
+	};
+
+	/**
+	 * cache of the recordsToMap();
+	 */
+	private static final Map<Integer, I_RecordCreator> _recordCreatorsById  = recordsToMap(recordClasses);
+
+	/**
+	 * create a record, if there are MUL records than multiple records
+	 * are returned digested into the non-mul form.
+	 */
+	public static Record [] createRecord(RecordInputStream in) {
+
+		Record record = createSingleRecord(in);
+		if (record instanceof DBCellRecord) {
+			// Not needed by POI.  Regenerated from scratch by POI when spreadsheet is written
+			return new Record[] { null, };
+		}
+		if (record instanceof RKRecord) {
+			return new Record[] { convertToNumberRecord((RKRecord) record), };
+		}
+		if (record instanceof MulRKRecord) {
+			return convertRKRecords((MulRKRecord)record);
+		}
+		return new Record[] { record, };
+	}
+
+	public static Record createSingleRecord(RecordInputStream in) {
+		I_RecordCreator constructor = _recordCreatorsById.get(Integer.valueOf(in.getSid()));
+
+		if (constructor == null) {
+			return new UnknownRecord(in);
+		}
+
+		return constructor.create(in);
+	}
+
+	/**
+	 * RK record is a slightly smaller alternative to NumberRecord
+	 * POI likes NumberRecord better
+	 */
+	public static NumberRecord convertToNumberRecord(RKRecord rk) {
+		NumberRecord num = new NumberRecord();
+
+		num.setColumn(rk.getColumn());
+		num.setRow(rk.getRow());
+		num.setXFIndex(rk.getXFIndex());
+		num.setValue(rk.getRKNumber());
+		return num;
+	}
+
+	/**
+	 * Converts a {@link MulRKRecord} into an equivalent array of {@link NumberRecord}s
+	 */
+	public static NumberRecord[] convertRKRecords(MulRKRecord mrk) {
+		NumberRecord[] mulRecs = new NumberRecord[mrk.getNumColumns()];
+		for (int k = 0; k < mrk.getNumColumns(); k++) {
+			NumberRecord nr = new NumberRecord();
+
+			nr.setColumn((short) (k + mrk.getFirstColumn()));
+			nr.setRow(mrk.getRow());
+			nr.setXFIndex(mrk.getXFAt(k));
+			nr.setValue(mrk.getRKNumberAt(k));
+			mulRecs[k] = nr;
+		}
+		return mulRecs;
+	}
+
+
+	/**
+	 * gets the record constructors and sticks them in the map by SID
+	 * @return map of SIDs to short,short,byte[] constructors for Record classes
+	 * most of org.apache.poi.hssf.record.*
+	 */
+	private static Map<Integer, I_RecordCreator> recordsToMap(Class<? extends Record> [] records) {
+		Map<Integer, I_RecordCreator> result = new HashMap<Integer, I_RecordCreator>();
+		Set<Class<?>> uniqueRecClasses = new HashSet<Class<?>>(records.length * 3 / 2);
+
+		for (int i = 0; i < records.length; i++) {
+
+			Class<? extends Record> recClass = records[ i ];
+			if(!Record.class.isAssignableFrom(recClass)) {
+				throw new RuntimeException("Invalid record sub-class (" + recClass.getName() + ")");
+			}
+			if(Modifier.isAbstract(recClass.getModifiers())) {
+				throw new RuntimeException("Invalid record class (" + recClass.getName() + ") - must not be abstract");
+			}
+			if(!uniqueRecClasses.add(recClass)) {
+				throw new RuntimeException("duplicate record class (" + recClass.getName() + ")");
+			}
+
+			int sid;
+			try {
+				sid = recClass.getField("sid").getShort(null);
+			} catch (Exception illegalArgumentException) {
+				throw new RecordFormatException(
+					"Unable to determine record types");
+			}
+			Integer key = Integer.valueOf(sid);
+			if (result.containsKey(key)) {
+				Class<?> prevClass = result.get(key).getRecordClass();
+				throw new RuntimeException("duplicate record sid 0x" + Integer.toHexString(sid).toUpperCase()
+						+ " for classes (" + recClass.getName() + ") and (" + prevClass.getName() + ")");
+			}
+			result.put(key, getRecordCreator(recClass));
+		}
+//		result.put(Integer.valueOf(0x0406), result.get(Integer.valueOf(0x06)));
+		return result;
+	}
+
+	private static I_RecordCreator getRecordCreator(Class<? extends Record> recClass) {
+		try {
+			Constructor<? extends Record> constructor;
+			constructor = recClass.getConstructor(CONSTRUCTOR_ARGS);
+			return new ReflectionConstructorRecordCreator(constructor);
+		} catch (NoSuchMethodException e) {
+			// fall through and look for other construction methods
+		}
+		try {
+			Method m = recClass.getDeclaredMethod("create", CONSTRUCTOR_ARGS);
+			return new ReflectionMethodRecordCreator(m);
+		} catch (NoSuchMethodException e) {
+			throw new RuntimeException("Failed to find constructor or create method for (" + recClass.getName() + ").");
+		}
+	}
+	/**
+	 * Create an array of records from an input stream
+	 *
+	 * @param in the InputStream from which the records will be obtained
+	 *
+	 * @return an array of Records created from the InputStream
+	 *
+	 * @exception RecordFormatException on error processing the InputStream
+	 */
+	public static List<Record> createRecords(InputStream in) throws RecordFormatException {
+
+		List<Record> records = new ArrayList<Record>(NUM_RECORDS);
+
+		RecordFactoryInputStream recStream = new RecordFactoryInputStream(in, true);
+
+		Record record;
+		while ((record = recStream.nextRecord())!=null) {
+			records.add(record);
+		}
+
+		return records;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordFactoryInputStream.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordFactoryInputStream.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordFactoryInputStream.java	(revision 28000)
@@ -0,0 +1,284 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A stream based way to get at complete records, with
+ * as low a memory footprint as possible.
+ * This handles reading from a RecordInputStream, turning
+ * the data into full records, processing continue records
+ * etc.
+ * Most users should use {@link HSSFEventFactory} /
+ * {@link HSSFListener} and have new records pushed to
+ * them, but this does allow for a "pull" style of coding.
+ */
+public final class RecordFactoryInputStream {
+
+	/**
+	 * Keeps track of the sizes of the initial records up to and including {@link FilePassRecord}
+	 * Needed for protected files because each byte is encrypted with respect to its absolute
+	 * position from the start of the stream.
+	 */
+	private static final class StreamEncryptionInfo {
+		private final Record _lastRecord;
+		private final boolean _hasBOFRecord;
+
+		public StreamEncryptionInfo(RecordInputStream rs, List<Record> outputRecs) {
+			Record rec;
+			rs.nextRecord();
+			rec = RecordFactory.createSingleRecord(rs);
+			outputRecs.add(rec);
+			if (rec instanceof BOFRecord) {
+				_hasBOFRecord = true;
+				if (rs.hasNextRecord()) {
+					rs.nextRecord();
+					rec = RecordFactory.createSingleRecord(rs);
+					outputRecs.add(rec);
+					if (rec instanceof FilePassRecord) {
+						outputRecs.remove(outputRecs.size()-1);
+						// TODO - add fpr not added to outputRecs
+						rec = outputRecs.get(0);
+					} else {
+						// workbook not encrypted (typical case)
+						if (rec instanceof EOFRecord) {
+							// A workbook stream is never empty, so crash instead
+							// of trying to keep track of nesting level
+							throw new IllegalStateException("Nothing between BOF and EOF");
+						}
+					}
+				}
+			} else {
+				// Invalid in a normal workbook stream.
+				// However, some test cases work on sub-sections of
+				// the workbook stream that do not begin with BOF
+				_hasBOFRecord = false;
+			}
+			_lastRecord = rec;
+		}
+
+		/**
+		 * @return last record scanned while looking for encryption info.
+		 * This will typically be the first or second record read. Possibly <code>null</code>
+		 * if stream was empty
+		 */
+		public Record getLastRecord() {
+			return _lastRecord;
+		}
+
+		/**
+		 * <code>false</code> in some test cases
+		 */
+		public boolean hasBOFRecord() {
+			return _hasBOFRecord;
+		}
+	}
+
+
+	private final RecordInputStream _recStream;
+	private final boolean _shouldIncludeContinueRecords;
+
+	/**
+	 * Temporarily stores a group of {@link Record}s, for future return by {@link #nextRecord()}.
+	 * This is used at the start of the workbook stream, and also when the most recently read
+	 * underlying record is a {@link MulRKRecord}
+	 */
+	private Record[] _unreadRecordBuffer;
+
+	/**
+	 * used to help iterating over the unread records
+	 */
+	private int _unreadRecordIndex = -1;
+
+	/**
+	 * The most recent record that we gave to the user
+	 */
+	private Record _lastRecord = null;
+
+	private int _bofDepth;
+
+	private boolean _lastRecordWasEOFLevelZero;
+
+
+	/**
+	 * @param shouldIncludeContinueRecords caller can pass <code>false</code> if loose
+	 * {@link ContinueRecord}s should be skipped (this is sometimes useful in event based
+	 * processing).
+	 */
+	public RecordFactoryInputStream(InputStream in, boolean shouldIncludeContinueRecords) {
+		RecordInputStream rs = new RecordInputStream(in);
+		List<Record> records = new ArrayList<Record>();
+		StreamEncryptionInfo sei = new StreamEncryptionInfo(rs, records);
+
+		if (!records.isEmpty()) {
+			_unreadRecordBuffer = new Record[records.size()];
+			records.toArray(_unreadRecordBuffer);
+			_unreadRecordIndex =0;
+		}
+		_recStream = rs;
+		_shouldIncludeContinueRecords = shouldIncludeContinueRecords;
+		_lastRecord = sei.getLastRecord();
+
+		/*
+		* How to recognise end of stream?
+		* In the best case, the underlying input stream (in) ends just after the last EOF record
+		* Usually however, the stream is padded with an arbitrary byte count.  Excel and most apps
+		* reliably use zeros for padding and if this were always the case, this code could just
+		* skip all the (zero sized) records with sid==0.  However, bug 46987 shows a file with
+		* non-zero padding that is read OK by Excel (Excel also fixes the padding).
+		*
+		* So to properly detect the workbook end of stream, this code has to identify the last
+		* EOF record.  This is not so easy because the worbook bof+eof pair do not bracket the
+		* whole stream.  The worksheets follow the workbook, but it is not easy to tell how many
+		* sheet sub-streams should be present.  Hence we are looking for an EOF record that is not
+		* immediately followed by a BOF record.  One extra complication is that bof+eof sub-
+		* streams can be nested within worksheet streams and it's not clear in these cases what
+		* record might follow any EOF record.  So we also need to keep track of the bof/eof
+		* nesting level.
+		*/
+		_bofDepth = sei.hasBOFRecord() ? 1 : 0;
+		_lastRecordWasEOFLevelZero = false;
+	}
+
+	/**
+	 * Returns the next (complete) record from the
+	 * stream, or null if there are no more.
+	 */
+	public Record nextRecord() {
+		Record r;
+		r = getNextUnreadRecord();
+		if (r != null) {
+			// found an unread record
+			return r;
+		}
+		while (true) {
+			if (!_recStream.hasNextRecord()) {
+				// recStream is exhausted;
+				return null;
+			}
+
+			if (_lastRecordWasEOFLevelZero) {
+				// Potential place for ending the workbook stream
+				// Check that the next record is not BOFRecord(0x0809)
+				// Normally the input stream contains only zero padding after the last EOFRecord,
+				// but bug 46987 and 48068 suggests that the padding may be garbage.
+				// This code relies on the padding bytes not starting with BOFRecord.sid
+				if (_recStream.getNextSid() != BOFRecord.sid) {
+					return null;
+				}
+				// else - another sheet substream starting here
+			}
+
+            // step underlying RecordInputStream to the next record
+            _recStream.nextRecord();
+
+			r = readNextRecord();
+			if (r == null) {
+				// some record types may get skipped (e.g. DBCellRecord and ContinueRecord)
+				continue;
+			}
+			return r;
+		}
+	}
+
+	/**
+	 * @return the next {@link Record} from the multiple record group as expanded from
+	 * a recently read {@link MulRKRecord}. <code>null</code> if not present.
+	 */
+	private Record getNextUnreadRecord() {
+		if (_unreadRecordBuffer != null) {
+			int ix = _unreadRecordIndex;
+			if (ix < _unreadRecordBuffer.length) {
+				Record result = _unreadRecordBuffer[ix];
+				_unreadRecordIndex = ix + 1;
+				return result;
+			}
+			_unreadRecordIndex = -1;
+			_unreadRecordBuffer = null;
+		}
+		return null;
+	}
+
+	/**
+	 * @return the next available record, or <code>null</code> if
+	 * this pass didn't return a record that's
+	 * suitable for returning (eg was a continue record).
+	 */
+	private Record readNextRecord() {
+
+		Record record = RecordFactory.createSingleRecord(_recStream);
+		_lastRecordWasEOFLevelZero = false;
+
+		if (record instanceof BOFRecord) {
+			_bofDepth++;
+			return record;
+		}
+
+		if (record instanceof EOFRecord) {
+			_bofDepth--;
+			if (_bofDepth < 1) {
+				_lastRecordWasEOFLevelZero = true;
+			}
+
+			return record;
+		}
+
+		if (record instanceof DBCellRecord) {
+			// Not needed by POI.  Regenerated from scratch by POI when spreadsheet is written
+			return null;
+		}
+
+		if (record instanceof RKRecord) {
+			return RecordFactory.convertToNumberRecord((RKRecord) record);
+		}
+
+		if (record instanceof MulRKRecord) {
+			Record[] records = RecordFactory.convertRKRecords((MulRKRecord) record);
+
+			_unreadRecordBuffer = records;
+			_unreadRecordIndex = 1;
+			return records[0];
+		}
+
+		if (record.getSid() == ContinueRecord.sid) {
+			if (_lastRecord instanceof ObjRecord || _lastRecord instanceof TextObjectRecord) {
+				//we must remember the position of the continue record.
+				//in the serialization procedure the original structure of records must be preserved
+				if (_shouldIncludeContinueRecords) {
+					return record;
+				}
+				return null;
+			}
+			if (_lastRecord instanceof UnknownRecord) {
+				//Gracefully handle records that we don't know about,
+				//that happen to be continued
+				return record;
+			}
+			if (_lastRecord instanceof EOFRecord) {
+				// This is really odd, but excel still sometimes
+				//  outputs a file like this all the same
+				return record;
+			}
+			throw new RecordFormatException("Unhandled Continue Record followining " + _lastRecord.getClass());
+		}
+		_lastRecord = record;
+		return record;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordFormatException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordFormatException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordFormatException.java	(revision 28000)
@@ -0,0 +1,40 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+/**
+ * Title:     Record Format Exception
+ * Description: Used by records to indicate invalid format/data.<P>
+ */
+
+@SuppressWarnings("serial")
+public class RecordFormatException
+    extends org.apache.poi.util.RecordFormatException
+{
+    public RecordFormatException(String exception)
+    {
+        super(exception);
+    }
+    
+    public RecordFormatException(String exception, Throwable thr) {
+      super(exception, thr);
+    }
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordInputStream.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordInputStream.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RecordInputStream.java	(revision 28000)
@@ -0,0 +1,407 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import java.io.InputStream;
+
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianInputStream;
+
+/**
+ * Title:  Record Input Stream<P>
+ * Description:  Wraps a stream and provides helper methods for the construction of records.<P>
+ *
+ * @author Jason Height (jheight @ apache dot org)
+ */
+public final class RecordInputStream implements LittleEndianInput {
+	/** Maximum size of a single record (minus the 4 byte header) without a continue*/
+	public final static short MAX_RECORD_DATA_SIZE = 8224;
+	private static final int INVALID_SID_VALUE = -1;
+	/**
+	 * When {@link #_currentDataLength} has this value, it means that the previous BIFF record is
+	 * finished, the next sid has been properly read, but the data size field has not been read yet.
+	 */
+	private static final int DATA_LEN_NEEDS_TO_BE_READ = -1;
+	private static final byte[] EMPTY_BYTE_ARRAY = { };
+
+	/**
+	 * For use in {@link BiffViewer} which may construct {@link Record}s that don't completely
+	 * read all available data.  This exception should never be thrown otherwise.
+	 */
+	@SuppressWarnings("serial")
+	public static final class LeftoverDataException extends RuntimeException {
+		public LeftoverDataException(int sid, int remainingByteCount) {
+			super("Initialisation of record 0x" + Integer.toHexString(sid).toUpperCase()
+					+ " left " + remainingByteCount + " bytes remaining still to be read.");
+		}
+	}
+
+	/** Header {@link LittleEndianInput} facet of the wrapped {@link InputStream} */
+	private final BiffHeaderInput _bhi;
+	/** Data {@link LittleEndianInput} facet of the wrapped {@link InputStream} */
+	private final LittleEndianInput _dataInput;
+	/** the record identifier of the BIFF record currently being read */
+	private int _currentSid;
+	/**
+	 * Length of the data section of the current BIFF record (always 4 less than the total record size).
+	 * When uninitialised, this field is set to {@link #DATA_LEN_NEEDS_TO_BE_READ}.
+	 */
+	private int _currentDataLength;
+	/**
+	 * The BIFF record identifier for the next record is read when just as the current record
+	 * is finished.
+	 * This field is only really valid during the time that ({@link #_currentDataLength} ==
+	 * {@link #DATA_LEN_NEEDS_TO_BE_READ}).  At most other times its value is not really the
+	 * 'sid of the next record'.  Wwhile mid-record, this field coincidentally holds the sid
+	 * of the current record.
+	 */
+	private int _nextSid;
+	/**
+	 * index within the data section of the current BIFF record
+	 */
+	private int _currentDataOffset;
+
+	private static final class SimpleHeaderInput implements BiffHeaderInput {
+
+		private final LittleEndianInput _lei;
+
+		public SimpleHeaderInput(InputStream in) {
+			_lei = getLEI(in);
+		}
+		public int available() {
+			return _lei.available();
+		}
+		public int readDataSize() {
+			return _lei.readUShort();
+		}
+		public int readRecordSID() {
+			return _lei.readUShort();
+		}
+	}
+
+	public RecordInputStream(InputStream in) throws RecordFormatException {
+		this (in, 0);
+	}
+
+	public RecordInputStream(InputStream in, int initialOffset) throws RecordFormatException {
+		_dataInput = getLEI(in);
+		_bhi = new SimpleHeaderInput(in);
+		_nextSid = readNextSid();
+	}
+
+	static LittleEndianInput getLEI(InputStream is) {
+		if (is instanceof LittleEndianInput) {
+			// accessing directly is an optimisation
+			return (LittleEndianInput) is;
+		}
+		// less optimal, but should work OK just the same. Often occurs in junit tests.
+		return new LittleEndianInputStream(is);
+	}
+
+	/**
+	 * @return the number of bytes available in the current BIFF record
+	 * @see #remaining()
+	 */
+	public int available() {
+		return remaining();
+	}
+
+	public int read(byte[] b, int off, int len) {
+		int limit = Math.min(len, remaining());
+		if (limit == 0) {
+			return 0;
+		}
+		readFully(b, off,limit);
+		return limit;
+	}
+
+	public short getSid() {
+		return (short) _currentSid;
+	}
+
+	/**
+	 * Note - this method is expected to be called only when completed reading the current BIFF
+	 * record.
+	 * @throws LeftoverDataException if this method is called before reaching the end of the
+	 * current record.
+	 */
+	public boolean hasNextRecord() throws LeftoverDataException {
+		if (_currentDataLength != -1 && _currentDataLength != _currentDataOffset) {
+			throw new LeftoverDataException(_currentSid, remaining());
+		}
+		if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ) {
+			_nextSid = readNextSid();
+		}
+		return _nextSid != INVALID_SID_VALUE;
+	}
+
+	/**
+	 * @return the sid of the next record or {@link #INVALID_SID_VALUE} if at end of stream
+	 */
+	private int readNextSid() {
+		int nAvailable  = _bhi.available();
+		if (nAvailable < EOFRecord.ENCODED_SIZE) {
+			if (nAvailable > 0) {
+				// some scrap left over?
+				// ex45582-22397.xls has one extra byte after the last record
+				// Excel reads that file OK
+			}
+			return INVALID_SID_VALUE;
+		}
+		int result = _bhi.readRecordSID();
+		if (result == INVALID_SID_VALUE) {
+			throw new RecordFormatException("Found invalid sid (" + result + ")");
+		}
+		_currentDataLength = DATA_LEN_NEEDS_TO_BE_READ;
+		return result;
+	}
+
+	/** Moves to the next record in the stream.
+	 *
+	 * <i>Note: The auto continue flag is reset to true</i>
+	 */
+	public void nextRecord() throws RecordFormatException {
+		if (_nextSid == INVALID_SID_VALUE) {
+			throw new IllegalStateException("EOF - next record not available");
+		}
+		if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ) {
+			throw new IllegalStateException("Cannot call nextRecord() without checking hasNextRecord() first");
+		}
+		_currentSid = _nextSid;
+		_currentDataOffset = 0;
+		_currentDataLength = _bhi.readDataSize();
+		if (_currentDataLength > MAX_RECORD_DATA_SIZE) {
+			throw new RecordFormatException("The content of an excel record cannot exceed "
+					+ MAX_RECORD_DATA_SIZE + " bytes");
+		}
+	}
+
+	private void checkRecordPosition(int requiredByteCount) {
+
+		int nAvailable = remaining();
+		if (nAvailable >= requiredByteCount) {
+			// all OK
+			return;
+		}
+		if (nAvailable == 0 && isContinueNext()) {
+			nextRecord();
+			return;
+		}
+		throw new RecordFormatException("Not enough data (" + nAvailable
+				+ ") to read requested (" + requiredByteCount +") bytes");
+	}
+
+	/**
+	 * Reads an 8 bit, signed value
+	 */
+	public byte readByte() {
+		checkRecordPosition(LittleEndian.BYTE_SIZE);
+		_currentDataOffset += LittleEndian.BYTE_SIZE;
+		return _dataInput.readByte();
+	}
+
+	/**
+	 * Reads a 16 bit, signed value
+	 */
+	public short readShort() {
+		checkRecordPosition(LittleEndian.SHORT_SIZE);
+		_currentDataOffset += LittleEndian.SHORT_SIZE;
+		return _dataInput.readShort();
+	}
+
+	/**
+	 * Reads a 32 bit, signed value 
+	 */
+	public int readInt() {
+		checkRecordPosition(LittleEndian.INT_SIZE);
+		_currentDataOffset += LittleEndian.INT_SIZE;
+		return _dataInput.readInt();
+	}
+
+	/**
+	 * Reads a 64 bit, signed value
+	 */
+	public long readLong() {
+		checkRecordPosition(LittleEndian.LONG_SIZE);
+		_currentDataOffset += LittleEndian.LONG_SIZE;
+		return _dataInput.readLong();
+	}
+
+	/**
+	 * Reads an 8 bit, unsigned value
+	 */
+	public int readUByte() {
+		return readByte() & 0x00FF;
+	}
+
+	/**
+	 * Reads a 16 bit, unsigned value.
+	 */
+	public int readUShort() {
+		checkRecordPosition(LittleEndian.SHORT_SIZE);
+		_currentDataOffset += LittleEndian.SHORT_SIZE;
+		return _dataInput.readUShort();
+	}
+
+	public double readDouble() {
+		long valueLongBits = readLong();
+		double result = Double.longBitsToDouble(valueLongBits);
+		if (Double.isNaN(result)) {
+			throw new RuntimeException("Did not expect to read NaN"); // (Because Excel typically doesn't write NaN
+		}
+		return result;
+	}
+	public void readFully(byte[] buf) {
+		readFully(buf, 0, buf.length);
+	}
+
+	public void readFully(byte[] buf, int off, int len) {
+		checkRecordPosition(len);
+		_dataInput.readFully(buf, off, len);
+		_currentDataOffset+=len;
+	}
+
+	public String readString() {
+		int requestedLength = readUShort();
+		byte compressFlag = readByte();
+		return readStringCommon(requestedLength, compressFlag == 0);
+	}
+	/**
+	 *  given a byte array of 16-bit unicode characters, compress to 8-bit and
+	 *  return a string
+	 *
+	 * { 0x16, 0x00 } -0x16
+	 *
+	 * @param requestedLength the length of the final string
+	 * @return                                     the converted string
+	 * @exception  IllegalArgumentException        if len is too large (i.e.,
+	 *      there is not enough data in string to create a String of that
+	 *      length)
+	 */
+	public String readUnicodeLEString(int requestedLength) {
+		return readStringCommon(requestedLength, false);
+	}
+
+	public String readCompressedUnicode(int requestedLength) {
+		return readStringCommon(requestedLength, true);
+	}
+
+	private String readStringCommon(int requestedLength, boolean pIsCompressedEncoding) {
+		// Sanity check to detect garbage string lengths
+		if (requestedLength < 0 || requestedLength > 0x100000) { // 16 million chars?
+			throw new IllegalArgumentException("Bad requested string length (" + requestedLength + ")");
+		}
+		char[] buf = new char[requestedLength];
+		boolean isCompressedEncoding = pIsCompressedEncoding;
+		int curLen = 0;
+		while(true) {
+			int availableChars =isCompressedEncoding ?  remaining() : remaining() / LittleEndian.SHORT_SIZE;
+			if (requestedLength - curLen <= availableChars) {
+				// enough space in current record, so just read it out
+				while(curLen < requestedLength) {
+					char ch;
+					if (isCompressedEncoding) {
+						ch = (char)readUByte();
+					} else {
+						ch = (char)readShort();
+					}
+					buf[curLen] = ch;
+					curLen++;
+				}
+				return new String(buf);
+			}
+			// else string has been spilled into next continue record
+			// so read what's left of the current record
+			while(availableChars > 0) {
+				char ch;
+				if (isCompressedEncoding) {
+					ch = (char)readUByte();
+				} else {
+					ch = (char)readShort();
+				}
+				buf[curLen] = ch;
+				curLen++;
+				availableChars--;
+			}
+			if (!isContinueNext()) {
+				throw new RecordFormatException("Expected to find a ContinueRecord in order to read remaining "
+						+ (requestedLength-curLen) + " of " + requestedLength + " chars");
+			}
+			if(remaining() != 0) {
+				throw new RecordFormatException("Odd number of bytes(" + remaining() + ") left behind");
+			}
+			nextRecord();
+			// note - the compressed flag may change on the fly
+			byte compressFlag = readByte();
+			isCompressedEncoding = (compressFlag == 0);
+		}
+	}
+
+	/** Returns the remaining bytes for the current record.
+	 *
+	  * @return The remaining bytes of the current record.
+	  */
+	public byte[] readRemainder() {
+		int size = remaining();
+		if (size ==0) {
+			return EMPTY_BYTE_ARRAY;
+		}
+		byte[] result = new byte[size];
+		readFully(result);
+		return result;
+	}
+
+	/** The remaining number of bytes in the <i>current</i> record.
+	 *
+	 * @return The number of bytes remaining in the current record
+	 */
+	public int remaining() {
+		if (_currentDataLength == DATA_LEN_NEEDS_TO_BE_READ) {
+			// already read sid of next record. so current one is finished
+			return 0;
+		}
+		return _currentDataLength - _currentDataOffset;
+	}
+
+	/**
+	 *
+	 * @return <code>true</code> when a {@link ContinueRecord} is next.
+	 */
+	private boolean isContinueNext() {
+		if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ && _currentDataOffset != _currentDataLength) {
+			throw new IllegalStateException("Should never be called before end of current record");
+		}
+		if (!hasNextRecord()) {
+			return false;
+		}
+		// At what point are records continued?
+		//  - Often from within the char data of long strings (caller is within readStringCommon()).
+		//  - From UnicodeString construction (many different points - call via checkRecordPosition)
+		//  - During TextObjectRecord construction (just before the text, perhaps within the text,
+		//    and before the formatting run data)
+		return _nextSid == ContinueRecord.sid;
+	}
+
+    /**
+     @return sid of next record. Can be called after hasNextRecord()
+     */
+    public int getNextSid() {
+        return _nextSid;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RefModeRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RefModeRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RefModeRecord.java	(revision 28000)
@@ -0,0 +1,103 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        RefMode Record<P>
+ * Description:  Describes which reference mode to use<P>
+ * REFERENCE:  PG 376 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @version 2.0-pre
+ */
+
+public final class RefModeRecord
+    extends StandardRecord
+{
+    public final static short sid           = 0xf;
+    public final static short USE_A1_MODE   = 1;
+    private short             field_1_mode;
+
+    public RefModeRecord()
+    {
+    }
+
+    public RefModeRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_mode = in.readShort();
+    }
+
+    /**
+     * set the reference mode to use (HSSF uses/assumes A1)
+     * @param mode the mode to use
+     * @see #USE_A1_MODE
+     * @see #USE_R1C1_MODE
+     *
+     */
+
+    public void setMode(short mode)
+    {
+        field_1_mode = mode;
+    }
+
+    /**
+     * get the reference mode to use (HSSF uses/assumes A1)
+     * @return mode to use
+     * @see #USE_A1_MODE
+     * @see #USE_R1C1_MODE
+     */
+
+    public short getMode()
+    {
+        return field_1_mode;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[REFMODE]\n");
+        buffer.append("    .mode           = ")
+            .append(Integer.toHexString(getMode())).append("\n");
+        buffer.append("[/REFMODE]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(getMode());
+    }
+
+    protected int getDataSize() {
+        return 2;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public Object clone() {
+      RefModeRecord rec = new RefModeRecord();
+      rec.field_1_mode = field_1_mode;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RowRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RowRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/RowRecord.java	(revision 28000)
@@ -0,0 +1,275 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Row Record (0x0208)<P/>
+ * Description:  stores the row information for the sheet. <P/>
+ * REFERENCE:  PG 379 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @version 2.0-pre
+ */
+public final class RowRecord extends StandardRecord {
+    public final static short sid = 0x0208;
+
+    public static final int ENCODED_SIZE = 20;
+    
+    private static final int OPTION_BITS_ALWAYS_SET = 0x0100;
+
+    private int field_1_row_number;
+    private int field_2_first_col;
+    private int field_3_last_col; // plus 1
+    private short field_4_height;
+    private short field_5_optimize; // hint field for gui, can/should be set to zero
+
+    // for generated sheets.
+    private short field_6_reserved;
+    /** 16 bit options flags */
+    private int field_7_option_flags;
+    private static final BitField          outlineLevel  = BitFieldFactory.getInstance(0x07);
+
+    // bit 3 reserved
+    private static final BitField          colapsed      = BitFieldFactory.getInstance(0x10);
+    private static final BitField          zeroHeight    = BitFieldFactory.getInstance(0x20);
+    private static final BitField          badFontHeight = BitFieldFactory.getInstance(0x40);
+    private static final BitField          formatted     = BitFieldFactory.getInstance(0x80);
+    private short field_8_xf_index;   // only if isFormatted
+
+    public RowRecord(int rowNumber) {
+        field_1_row_number = rowNumber;
+        field_4_height = (short)0xFF;
+        field_5_optimize = ( short ) 0;
+        field_6_reserved = ( short ) 0;
+        field_7_option_flags = OPTION_BITS_ALWAYS_SET; // seems necessary for outlining
+
+        field_8_xf_index = ( short ) 0xf;
+        setEmpty();
+    }
+
+    public RowRecord(RecordInputStream in) { // NO_UCD
+        field_1_row_number   = in.readUShort();
+        field_2_first_col    = in.readShort();
+        field_3_last_col     = in.readShort();
+        field_4_height       = in.readShort();
+        field_5_optimize     = in.readShort();
+        field_6_reserved     = in.readShort();
+        field_7_option_flags = in.readShort();
+        field_8_xf_index     = in.readShort();
+    }
+
+    /**
+     * Updates the firstCol and lastCol fields to the reserved value (-1) 
+     * to signify that this row is empty
+     */
+    public void setEmpty() {
+        field_2_first_col = 0;
+        field_3_last_col = 0;
+    }
+    public boolean isEmpty() {
+        return (field_2_first_col | field_3_last_col) == 0;
+    }
+    
+    /**
+     * set the logical row number for this row (0 based index)
+     * @param row - the row number
+     */
+    public void setRowNumber(int row) {
+        field_1_row_number = row;
+    }
+
+    /**
+     * set the logical col number for the first cell this row (0 based index)
+     * @param col - the col number
+     */
+    public void setFirstCol(int col) {
+        field_2_first_col = col;
+    }
+
+    /**
+     * @param col - one past the zero-based index to the last cell in this row
+     */
+    public void setLastCol(int col) {
+        field_3_last_col = col;
+    }
+
+    /**
+     * get the logical row number for this row (0 based index)
+     * @return row - the row number
+     */
+    public int getRowNumber() {
+        return field_1_row_number;
+    }
+
+    /**
+     * get the logical col number for the first cell this row (0 based index)
+     * @return col - the col number
+     */
+    public int getFirstCol() {
+        return field_2_first_col;
+    }
+
+    /**
+     * get the logical col number for the last cell this row (0 based index), plus one 
+     * @return col - the last col index + 1
+     */
+    public int getLastCol() {
+        return field_3_last_col;
+    }
+
+    /**
+     * get the height of the row
+     * @return height of the row
+     */
+    public short getHeight() {
+        return field_4_height;
+    }
+
+    /**
+     * get whether to optimize or not (set to 0)
+     * @return optimize (set to 0)
+     */
+    public short getOptimize() {
+        return field_5_optimize;
+    }
+
+    /**
+     * gets the option bitmask.  (use the individual bit setters that refer to this
+     * method)
+     * @return options - the bitmask
+     */
+    public short getOptionFlags() {
+        return (short)field_7_option_flags;
+    }
+
+    // option bitfields
+
+    /**
+     * get the outline level of this row
+     * @return ol - the outline level
+     * @see #getOptionFlags()
+     */
+    public short getOutlineLevel() {
+        return (short)outlineLevel.getValue(field_7_option_flags);
+    }
+
+    /**
+     * get whether or not to colapse this row
+     * @return c - colapse or not
+     * @see #getOptionFlags()
+     */
+    public boolean getColapsed() {
+        return (colapsed.isSet(field_7_option_flags));
+    }
+
+    /**
+     * get whether or not to display this row with 0 height
+     * @return - z height is zero or not.
+     * @see #getOptionFlags()
+     */
+    public boolean getZeroHeight() {
+        return zeroHeight.isSet(field_7_option_flags);
+    }
+
+    /**
+     * get whether the font and row height are not compatible
+     * @return - f -true if they aren't compatible (damn not logic)
+     * @see #getOptionFlags()
+     */
+    public boolean getBadFontHeight() {
+        return badFontHeight.isSet(field_7_option_flags);
+    }
+
+    /**
+     * get whether the row has been formatted (even if its got all blank cells)
+     * @return formatted or not
+     * @see #getOptionFlags()
+     */
+    public boolean getFormatted() {
+        return formatted.isSet(field_7_option_flags);
+    }
+
+    // end bitfields
+
+    /**
+     * if the row is formatted then this is the index to the extended format record
+     * @see org.apache.poi.hssf.record.ExtendedFormatRecord
+     * @return index to the XF record or bogus value (undefined) if isn't formatted
+     */
+    public short getXFIndex() {
+        return field_8_xf_index;
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("[ROW]\n");
+        sb.append("    .rownumber      = ").append(Integer.toHexString(getRowNumber()))
+                .append("\n");
+        sb.append("    .firstcol       = ").append(HexDump.shortToHex(getFirstCol())).append("\n");
+        sb.append("    .lastcol        = ").append(HexDump.shortToHex(getLastCol())).append("\n");
+        sb.append("    .height         = ").append(HexDump.shortToHex(getHeight())).append("\n");
+        sb.append("    .optimize       = ").append(HexDump.shortToHex(getOptimize())).append("\n");
+        sb.append("    .reserved       = ").append(HexDump.shortToHex(field_6_reserved)).append("\n");
+        sb.append("    .optionflags    = ").append(HexDump.shortToHex(getOptionFlags())).append("\n");
+        sb.append("        .outlinelvl = ").append(Integer.toHexString(getOutlineLevel())).append("\n");
+        sb.append("        .colapsed   = ").append(getColapsed()).append("\n");
+        sb.append("        .zeroheight = ").append(getZeroHeight()).append("\n");
+        sb.append("        .badfontheig= ").append(getBadFontHeight()).append("\n");
+        sb.append("        .formatted  = ").append(getFormatted()).append("\n");
+        sb.append("    .xfindex        = ").append(Integer.toHexString(getXFIndex())).append("\n");
+        sb.append("[/ROW]\n");
+        return sb.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(getRowNumber());
+        out.writeShort(getFirstCol() == -1 ? (short)0 : getFirstCol());
+        out.writeShort(getLastCol() == -1 ? (short)0 : getLastCol());
+        out.writeShort(getHeight());
+        out.writeShort(getOptimize());
+        out.writeShort(field_6_reserved);
+        out.writeShort(getOptionFlags());
+        out.writeShort(getXFIndex());
+    }
+
+    protected int getDataSize() {
+        return ENCODED_SIZE - 4;
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    public Object clone() {
+      RowRecord rec = new RowRecord(field_1_row_number);
+      rec.field_2_first_col = field_2_first_col;
+      rec.field_3_last_col = field_3_last_col;
+      rec.field_4_height = field_4_height;
+      rec.field_5_optimize = field_5_optimize;
+      rec.field_6_reserved = field_6_reserved;
+      rec.field_7_option_flags = field_7_option_flags;
+      rec.field_8_xf_index = field_8_xf_index;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SCLRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SCLRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SCLRecord.java	(revision 28000)
@@ -0,0 +1,106 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Specifies the window's zoom magnification.  <p/>
+ * If this record isn't present then the windows zoom is 100%. see p384 Excel Dev Kit
+ * 
+ * @author Andrew C. Oliver (acoliver at apache.org)
+ */
+public final class SCLRecord extends StandardRecord {
+    public final static short      sid                             = 0x00A0;
+    private  short      field_1_numerator;
+    private  short      field_2_denominator;
+
+
+    public SCLRecord()
+    {
+
+    }
+
+    public SCLRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_numerator              = in.readShort();
+        field_2_denominator            = in.readShort();
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[SCL]\n");
+        buffer.append("    .numerator            = ")
+            .append("0x").append(HexDump.toHex(  getNumerator ()))
+            .append(" (").append( getNumerator() ).append(" )");
+        buffer.append(System.getProperty("line.separator")); 
+        buffer.append("    .denominator          = ")
+            .append("0x").append(HexDump.toHex(  getDenominator ()))
+            .append(" (").append( getDenominator() ).append(" )");
+        buffer.append(System.getProperty("line.separator")); 
+
+        buffer.append("[/SCL]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(field_1_numerator);
+        out.writeShort(field_2_denominator);
+    }
+
+    protected int getDataSize() {
+        return 2 + 2;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public Object clone() {
+        SCLRecord rec = new SCLRecord();
+    
+        rec.field_1_numerator = field_1_numerator;
+        rec.field_2_denominator = field_2_denominator;
+        return rec;
+    }
+
+
+
+
+    /**
+     * Get the numerator field for the SCL record.
+     */
+    public short getNumerator()
+    {
+        return field_1_numerator;
+    }
+
+
+    /**
+     * Get the denominator field for the SCL record.
+     */
+    public short getDenominator()
+    {
+        return field_2_denominator;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SSTDeserializer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SSTDeserializer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SSTDeserializer.java	(revision 28000)
@@ -0,0 +1,65 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.common.UnicodeString;
+import org.apache.poi.util.IntMapper;
+
+/**
+ * Handles the task of deserializing a SST string.  The two main entry points are
+ *
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @author Jason Height (jheight at apache.org)
+ */
+class SSTDeserializer
+{
+	
+    private IntMapper<UnicodeString> strings;
+
+    public SSTDeserializer( IntMapper<UnicodeString> strings )
+    {
+        this.strings = strings;
+    }
+
+    /**
+     * This is the starting point where strings are constructed.  Note that
+     * strings may span across multiple continuations. Read the SST record
+     * carefully before beginning to hack.
+     */
+    public void manufactureStrings( int stringCount, RecordInputStream in )
+    {
+      for (int i=0;i<stringCount;i++) {
+         // Extract exactly the count of strings from the SST record.
+         UnicodeString str;
+         if(in.available() == 0 && ! in.hasNextRecord()) {
+            System.err.println("Ran out of data before creating all the strings! String at index " + i + "");
+            str = new UnicodeString("");
+         } else {
+            str = new UnicodeString(in);
+         }
+         addToStringTable( strings, str );
+      }
+    }
+
+    static public void addToStringTable( IntMapper<UnicodeString> strings, UnicodeString string )
+    {
+      strings.add(string);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SSTRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SSTRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SSTRecord.java	(revision 28000)
@@ -0,0 +1,241 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.common.UnicodeString;
+import org.apache.poi.hssf.record.cont.ContinuableRecord;
+import org.apache.poi.hssf.record.cont.ContinuableRecordOutput;
+import org.apache.poi.util.IntMapper;
+
+/**
+ * Title:        Static String Table Record (0x00FC)<p/>
+ *
+ * Description:  This holds all the strings for LabelSSTRecords.
+ * <P>
+ * REFERENCE:    PG 389 Microsoft Excel 97 Developer's Kit (ISBN:
+ *               1-57231-498-2)
+ * <P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Marc Johnson (mjohnson at apache dot org)
+ * @author Glen Stampoultzis (glens at apache.org)
+ *
+ * @see org.apache.poi.hssf.record.LabelSSTRecord
+ * @see org.apache.poi.hssf.record.ContinueRecord
+ */
+public final class SSTRecord extends ContinuableRecord {
+    public static final short sid = 0x00FC;
+
+    private static final UnicodeString EMPTY_STRING = new UnicodeString("");
+
+    /** union of strings in the SST and EXTSST */
+    private int field_1_num_strings;
+
+    /** according to docs ONLY SST */
+    private int field_2_num_unique_strings;
+    private IntMapper<UnicodeString> field_3_strings;
+    
+    private SSTDeserializer deserializer;
+
+    public SSTRecord()
+    {
+        field_1_num_strings = 0;
+        field_2_num_unique_strings = 0;
+        field_3_strings = new IntMapper<UnicodeString>();
+    }
+
+    /**
+     * Add a string.
+     *
+     * @param string string to be added
+     *
+     * @return the index of that string in the table
+     */
+    public int addString(UnicodeString string)
+    {
+        field_1_num_strings++;
+        UnicodeString ucs = ( string == null ) ? EMPTY_STRING
+                : string;
+        int rval;
+        int index = field_3_strings.getIndex(ucs);
+
+        if ( index != -1 ) {
+            rval = index;
+        } else {
+            // This is a new string -- we didn't see it among the
+            // strings we've already collected
+            rval = field_3_strings.size();
+            field_2_num_unique_strings++;
+            SSTDeserializer.addToStringTable( field_3_strings, ucs );
+        }
+        return rval;
+    }
+
+    /**
+     * @return number of strings
+     */
+    public int getNumStrings()
+    {
+        return field_1_num_strings;
+    }
+
+    /**
+     * @return number of unique strings
+     */
+    public int getNumUniqueStrings()
+    {
+        return field_2_num_unique_strings;
+    }
+
+
+    /**
+     * Get a particular string by its index
+     *
+     * @param id index into the array of strings
+     *
+     * @return the desired string
+     */
+    public UnicodeString getString(int id )
+    {
+        return field_3_strings.get( id );
+    }
+
+
+    /**
+     * Return a debugging string representation
+     *
+     * @return string representation
+     */
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append( "[SST]\n" );
+        buffer.append( "    .numstrings     = " )
+                .append( Integer.toHexString( getNumStrings() ) ).append( "\n" );
+        buffer.append( "    .uniquestrings  = " )
+                .append( Integer.toHexString( getNumUniqueStrings() ) ).append( "\n" );
+        for ( int k = 0; k < field_3_strings.size(); k++ )
+        {
+          UnicodeString s = field_3_strings.get( k );
+            buffer.append( "    .string_" + k + "      = " )
+                    .append( s.getDebugInfo() ).append( "\n" );
+        }
+        buffer.append( "[/SST]\n" );
+        return buffer.toString();
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    /**
+     * Fill the fields from the data
+     * <P>
+     * The data consists of sets of string data. This string data is
+     * arranged as follows:
+     * <P>
+     * <CODE><pre>
+     * short  string_length;   // length of string data
+     * byte   string_flag;     // flag specifying special string
+     *                         // handling
+     * short  run_count;       // optional count of formatting runs
+     * int    extend_length;   // optional extension length
+     * char[] string_data;     // string data, can be byte[] or
+     *                         // short[] (length of array is
+     *                         // string_length)
+     * int[]  formatting_runs; // optional formatting runs (length of
+     *                         // array is run_count)
+     * byte[] extension;       // optional extension (length of array
+     *                         // is extend_length)
+     * </pre></CODE>
+     * <P>
+     * The string_flag is bit mapped as follows:
+     * <P>
+     * <TABLE>
+     *   <TR>
+     *      <TH>Bit number</TH>
+     *      <TH>Meaning if 0</TH>
+     *      <TH>Meaning if 1</TH>
+     *   <TR>
+     *   <TR>
+     *      <TD>0</TD>
+     *      <TD>string_data is byte[]</TD>
+     *      <TD>string_data is short[]</TH>
+     *   <TR>
+     *   <TR>
+     *      <TD>1</TD>
+     *      <TD>Should always be 0</TD>
+     *      <TD>string_flag is defective</TH>
+     *   <TR>
+     *   <TR>
+     *      <TD>2</TD>
+     *      <TD>extension is not included</TD>
+     *      <TD>extension is included</TH>
+     *   <TR>
+     *   <TR>
+     *      <TD>3</TD>
+     *      <TD>formatting run data is not included</TD>
+     *      <TD>formatting run data is included</TH>
+     *   <TR>
+     *   <TR>
+     *      <TD>4</TD>
+     *      <TD>Should always be 0</TD>
+     *      <TD>string_flag is defective</TH>
+     *   <TR>
+     *   <TR>
+     *      <TD>5</TD>
+     *      <TD>Should always be 0</TD>
+     *      <TD>string_flag is defective</TH>
+     *   <TR>
+     *   <TR>
+     *      <TD>6</TD>
+     *      <TD>Should always be 0</TD>
+     *      <TD>string_flag is defective</TH>
+     *   <TR>
+     *   <TR>
+     *      <TD>7</TD>
+     *      <TD>Should always be 0</TD>
+     *      <TD>string_flag is defective</TH>
+     *   <TR>
+     * </TABLE>
+     * <P>
+     * We can handle eating the overhead associated with bits 2 or 3
+     * (or both) being set, but we have no idea what to do with the
+     * associated data. The UnicodeString class can handle the byte[]
+     * vs short[] nature of the actual string data
+     *
+     * @param in the RecordInputstream to read the record from
+     */
+    public SSTRecord(RecordInputStream in) { // NO_UCD
+        // this method is ALWAYS called after construction -- using
+        // the nontrivial constructor, of course -- so this is where
+        // we initialize our fields
+        field_1_num_strings = in.readInt();
+        field_2_num_unique_strings = in.readInt();
+        field_3_strings = new IntMapper<UnicodeString>();
+        deserializer = new SSTDeserializer(field_3_strings);
+        deserializer.manufactureStrings( field_2_num_unique_strings, in );
+    }
+    
+    protected void serialize(ContinuableRecordOutput out) {
+        SSTSerializer serializer = new SSTSerializer(field_3_strings, getNumStrings(), getNumUniqueStrings() );
+        serializer.serialize(out);
+    }
+
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SSTSerializer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SSTSerializer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SSTSerializer.java	(revision 28000)
@@ -0,0 +1,85 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.common.UnicodeString;
+import org.apache.poi.hssf.record.cont.ContinuableRecordOutput;
+import org.apache.poi.util.IntMapper;
+
+/**
+ * This class handles serialization of SST records.  It utilizes the record processor
+ * class write individual records. This has been refactored from the SSTRecord class.
+ *
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+final class SSTSerializer {
+
+	private final int _numStrings;
+	private final int _numUniqueStrings;
+
+    private final IntMapper<UnicodeString> strings;
+
+    /** Offsets from the beginning of the SST record (even across continuations) */
+    private final int[] bucketAbsoluteOffsets;
+    /** Offsets relative the start of the current SST or continue record */
+    private final int[] bucketRelativeOffsets;
+
+    public SSTSerializer( IntMapper<UnicodeString> strings, int numStrings, int numUniqueStrings )
+    {
+        this.strings = strings;
+		_numStrings = numStrings;
+		_numUniqueStrings = numUniqueStrings;
+
+        int infoRecs = ExtSSTRecord.getNumberOfInfoRecsForStrings(strings.size());
+        this.bucketAbsoluteOffsets = new int[infoRecs];
+        this.bucketRelativeOffsets = new int[infoRecs];
+    }
+
+    public void serialize(ContinuableRecordOutput out) {
+        out.writeInt(_numStrings);
+        out.writeInt(_numUniqueStrings);
+
+        for ( int k = 0; k < strings.size(); k++ )
+        {
+            if (k % ExtSSTRecord.DEFAULT_BUCKET_SIZE == 0)
+            {
+              int rOff = out.getTotalSize();
+              int index = k/ExtSSTRecord.DEFAULT_BUCKET_SIZE;
+              if (index < ExtSSTRecord.MAX_BUCKETS) {
+                 //Excel only indexes the first 128 buckets.
+                 bucketAbsoluteOffsets[index] = rOff;
+                 bucketRelativeOffsets[index] = rOff;
+              }
+          }
+          UnicodeString s = getUnicodeString(k);
+          s.serialize(out);
+        }
+    }
+
+
+    private UnicodeString getUnicodeString( int index )
+    {
+        return getUnicodeString(strings, index);
+    }
+
+    private static UnicodeString getUnicodeString( IntMapper<UnicodeString> strings, int index )
+    {
+        return ( strings.get( index ) );
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SaveRecalcRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SaveRecalcRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SaveRecalcRecord.java	(revision 28000)
@@ -0,0 +1,98 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Save Recalc Record <P>
+ * Description:  defines whether to recalculate before saving (set to true)<P>
+ * REFERENCE:  PG 381 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @version 2.0-pre
+ */
+
+public final class SaveRecalcRecord
+    extends StandardRecord
+{
+    public final static short sid = 0x5f;
+    private short             field_1_recalc;
+
+    public SaveRecalcRecord()
+    {
+    }
+
+    public SaveRecalcRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_recalc = in.readShort();
+    }
+
+    /**
+     * set whether to recalculate formulas/etc before saving or not
+     * @param recalc - whether to recalculate or not
+     */
+
+    public void setRecalc(boolean recalc)
+    {
+        field_1_recalc = ( short ) ((recalc == true) ? 1
+                                                     : 0);
+    }
+
+    /**
+     * get whether to recalculate formulas/etc before saving or not
+     * @return recalc - whether to recalculate or not
+     */
+
+    public boolean getRecalc()
+    {
+        return (field_1_recalc == 1);
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[SAVERECALC]\n");
+        buffer.append("    .recalc         = ").append(getRecalc())
+            .append("\n");
+        buffer.append("[/SAVERECALC]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(field_1_recalc);
+    }
+
+    protected int getDataSize() {
+        return 2;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public Object clone() {
+      SaveRecalcRecord rec = new SaveRecalcRecord();
+      rec.field_1_recalc = field_1_recalc;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SelectionRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SelectionRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SelectionRecord.java	(revision 28000)
@@ -0,0 +1,139 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.util.CellRangeAddress8Bit;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Selection Record (0x001D)<P>
+ * Description:  shows the user's selection on the sheet
+ *               for write set num refs to 0<P>
+ *
+ * REFERENCE:  PG 291 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class SelectionRecord extends StandardRecord {
+    public final static short sid = 0x001D;
+    private byte        field_1_pane;
+    private int         field_2_row_active_cell;
+    private int         field_3_col_active_cell;
+    private int         field_4_active_cell_ref_index;
+    private CellRangeAddress8Bit[] field_6_refs;
+
+    /**
+     * Creates a default selection record (cell A1, in pane ID 3)
+     */
+    public SelectionRecord(int activeCellRow, int activeCellCol) {
+        field_1_pane = 3; // pane id 3 is always present.  see OOO sec 5.75 'PANE'
+        field_2_row_active_cell = activeCellRow;
+        field_3_col_active_cell = activeCellCol;
+        field_4_active_cell_ref_index = 0;
+        field_6_refs = new CellRangeAddress8Bit[] {
+            new CellRangeAddress8Bit(activeCellRow, activeCellRow, activeCellCol, activeCellCol),
+        };
+    }
+
+    public SelectionRecord(RecordInputStream in) { // NO_UCD
+        field_1_pane            = in.readByte();
+        field_2_row_active_cell = in.readUShort();
+        field_3_col_active_cell = in.readShort();
+        field_4_active_cell_ref_index = in.readShort();
+        int field_5_num_refs    = in.readUShort();
+
+        field_6_refs = new CellRangeAddress8Bit[field_5_num_refs];
+        for (int i = 0; i < field_6_refs.length; i++) {
+            field_6_refs[i] = new CellRangeAddress8Bit(in);
+        }
+    }
+
+
+    /**
+     * @return the pane ID which window pane this is for
+     */
+    public byte getPane() {
+        return field_1_pane;
+    }
+
+    /**
+     * get the active cell's row
+     * @return row number of active cell
+     */
+    public int getActiveCellRow() {
+        return field_2_row_active_cell;
+    }
+
+    /**
+     * get the active cell's col
+     * @return col number of active cell
+     */
+    public int getActiveCellCol() {
+        return field_3_col_active_cell;
+    }
+
+    /**
+     * get the active cell's reference number
+     * @return ref number of active cell
+     */
+    public int getActiveCellRef() {
+        return field_4_active_cell_ref_index;
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("[SELECTION]\n");
+        sb.append("    .pane            = ").append(HexDump.byteToHex(getPane())).append("\n");
+        sb.append("    .activecellrow   = ").append(HexDump.shortToHex(getActiveCellRow())).append("\n");
+        sb.append("    .activecellcol   = ").append(HexDump.shortToHex(getActiveCellCol())).append("\n");
+        sb.append("    .activecellref   = ").append(HexDump.shortToHex(getActiveCellRef())).append("\n");
+        sb.append("    .numrefs         = ").append(HexDump.shortToHex(field_6_refs.length)).append("\n");
+        sb.append("[/SELECTION]\n");
+        return sb.toString();
+    }
+    protected int getDataSize() {
+        return 9 // 1 byte + 4 shorts
+            + CellRangeAddress8Bit.getEncodedSize(field_6_refs.length);
+    }
+    public void serialize(LittleEndianOutput out) {
+        out.writeByte(getPane());
+        out.writeShort(getActiveCellRow());
+        out.writeShort(getActiveCellCol());
+        out.writeShort(getActiveCellRef());
+        int nRefs = field_6_refs.length;
+        out.writeShort(nRefs);
+        for (int i = 0; i < field_6_refs.length; i++) {
+            field_6_refs[i].serialize(out);
+        }
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    public Object clone() {
+        SelectionRecord rec = new SelectionRecord(field_2_row_active_cell, field_3_col_active_cell);
+        rec.field_1_pane = field_1_pane;
+        rec.field_4_active_cell_ref_index = field_4_active_cell_ref_index;
+        rec.field_6_refs = field_6_refs;
+        return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SharedFormulaRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SharedFormulaRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SharedFormulaRecord.java	(revision 28000)
@@ -0,0 +1,186 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.formula.AreaPtg;
+import org.apache.poi.hssf.record.formula.AreaPtgBase;
+import org.apache.poi.hssf.record.formula.OperandPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.RefPtg;
+import org.apache.poi.hssf.record.formula.RefPtgBase;
+import org.apache.poi.hssf.util.CellRangeAddress8Bit;
+import org.apache.poi.ss.formula.Formula;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        SHAREDFMLA (0x04BC) SharedFormulaRecord
+ * Description:  Primarily used as an excel optimization so that multiple similar formulas
+ *               are not written out too many times.  We should recognize this record and
+ *               serialize as is since this is used when reading templates.
+ * <p>
+ * Note: the documentation says that the SID is BC where biffviewer reports 4BC.  The hex dump shows
+ * that the two byte sid representation to be 'BC 04' that is consistent with the other high byte
+ * record types.
+ * @author Danny Mui at apache dot org
+ */
+public final class SharedFormulaRecord extends SharedValueRecordBase {
+    public final static short   sid = 0x04BC;
+
+    private int field_5_reserved;
+    private Formula field_7_parsed_expr;
+
+    // for testing only
+    public SharedFormulaRecord() {
+        this(new CellRangeAddress8Bit(0,0,0,0));
+    }
+    private SharedFormulaRecord(CellRangeAddress8Bit range) {
+        super(range);
+        field_7_parsed_expr = Formula.create(Ptg.EMPTY_PTG_ARRAY);
+    }
+
+    /**
+     * @param in the RecordInputstream to read the record from
+     */
+    public SharedFormulaRecord(RecordInputStream in) { // NO_UCD
+        super(in);
+        field_5_reserved        = in.readShort();
+        int field_6_expression_len = in.readShort();
+        int nAvailableBytes = in.available();
+        field_7_parsed_expr = Formula.read(field_6_expression_len, in, nAvailableBytes);
+    }
+
+    protected void serializeExtraData(LittleEndianOutput out) {
+        out.writeShort(field_5_reserved);
+        field_7_parsed_expr.serialize(out);
+    }
+
+    protected int getExtraDataSize() {
+        return 2 + field_7_parsed_expr.getEncodedSize();
+    }
+
+    /**
+     * print a sort of string representation ([SHARED FORMULA RECORD] id = x [/SHARED FORMULA RECORD])
+     */
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[SHARED FORMULA (").append(HexDump.intToHex(sid)).append("]\n");
+        buffer.append("    .range      = ").append(getRange().toString()).append("\n");
+        buffer.append("    .reserved    = ").append(HexDump.shortToHex(field_5_reserved)).append("\n");
+
+        Ptg[] ptgs = field_7_parsed_expr.getTokens();
+        for (int k = 0; k < ptgs.length; k++ ) {
+           buffer.append("Formula[").append(k).append("]");
+           Ptg ptg = ptgs[k];
+           buffer.append(ptg.toString()).append(ptg.getRVAType()).append("\n");
+        }
+
+        buffer.append("[/SHARED FORMULA]\n");
+        return buffer.toString();
+    }
+
+    public short getSid() {
+        return sid;
+    }
+
+    /**
+     * Creates a non shared formula from the shared formula counterpart<br/>
+     *
+     * Perhaps this functionality could be implemented in terms of the raw
+     * byte array inside {@link Formula}.
+     */
+    public static Ptg[] convertSharedFormulas(Ptg[] ptgs, int formulaRow, int formulaColumn) {
+
+        Ptg[] newPtgStack = new Ptg[ptgs.length];
+
+        for (int k = 0; k < ptgs.length; k++) {
+            Ptg ptg = ptgs[k];
+            byte originalOperandClass = -1;
+            if (!ptg.isBaseToken()) {
+                originalOperandClass = ptg.getPtgClass();
+            }
+            if (ptg instanceof RefPtgBase) {
+                RefPtgBase refNPtg = (RefPtgBase)ptg;
+                ptg = new RefPtg(fixupRelativeRow(formulaRow,refNPtg.getRow(),refNPtg.isRowRelative()),
+                                     fixupRelativeColumn(formulaColumn,refNPtg.getColumn(),refNPtg.isColRelative()),
+                                     refNPtg.isRowRelative(),
+                                     refNPtg.isColRelative());
+                ptg.setClass(originalOperandClass);
+            } else if (ptg instanceof AreaPtgBase) {
+                AreaPtgBase areaNPtg = (AreaPtgBase)ptg;
+                ptg = new AreaPtg(fixupRelativeRow(formulaRow,areaNPtg.getFirstRow(),areaNPtg.isFirstRowRelative()),
+                                fixupRelativeRow(formulaRow,areaNPtg.getLastRow(),areaNPtg.isLastRowRelative()),
+                                fixupRelativeColumn(formulaColumn,areaNPtg.getFirstColumn(),areaNPtg.isFirstColRelative()),
+                                fixupRelativeColumn(formulaColumn,areaNPtg.getLastColumn(),areaNPtg.isLastColRelative()),
+                                areaNPtg.isFirstRowRelative(),
+                                areaNPtg.isLastRowRelative(),
+                                areaNPtg.isFirstColRelative(),
+                                areaNPtg.isLastColRelative());
+                ptg.setClass(originalOperandClass);
+            } else if (ptg instanceof OperandPtg) {
+                // Any subclass of OperandPtg is mutable, so it's safest to not share these instances.
+                ptg = ((OperandPtg) ptg).copy();
+            } else {
+            	// all other Ptgs are immutable and can be shared
+            }
+            newPtgStack[k] = ptg;
+        }
+        return newPtgStack;
+    }
+
+    /**
+     * @return the equivalent {@link Ptg} array that the formula would have, were it not shared.
+     */
+    public Ptg[] getFormulaTokens(FormulaRecord formula) {
+        int formulaRow = formula.getRow();
+        int formulaColumn = formula.getColumn();
+        //Sanity checks
+        if (!isInRange(formulaRow, formulaColumn)) {
+            throw new RuntimeException("Shared Formula Conversion: Coding Error");
+        }
+
+        return convertSharedFormulas(field_7_parsed_expr.getTokens(), formulaRow, formulaColumn);
+    }
+
+    private static int fixupRelativeColumn(int currentcolumn, int column, boolean relative) {
+        if(relative) {
+            // mask out upper bits to produce 'wrapping' at column 256 ("IV")
+            return (column + currentcolumn) & 0x00FF;
+        }
+        return column;
+    }
+
+    private static int fixupRelativeRow(int currentrow, int row, boolean relative) {
+        if(relative) {
+            // mask out upper bits to produce 'wrapping' at row 65536
+            return (row+currentrow) & 0x00FFFF;
+        }
+        return row;
+    }
+
+    public Object clone() {
+        SharedFormulaRecord result = new SharedFormulaRecord(getRange());
+        result.field_5_reserved = field_5_reserved;
+        result.field_7_parsed_expr = field_7_parsed_expr.copy();
+        return result;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SharedValueRecordBase.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SharedValueRecordBase.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SharedValueRecordBase.java	(revision 28000)
@@ -0,0 +1,107 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.util.CellRangeAddress8Bit;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Common base class for {@link SharedFormulaRecord}, {@link ArrayRecord} and
+ * {@link TableRecord} which are have similarities.
+ *
+ * @author Josh Micich
+ */
+public abstract class SharedValueRecordBase extends StandardRecord {
+
+	private CellRangeAddress8Bit _range;
+
+	protected SharedValueRecordBase(CellRangeAddress8Bit range) {
+		if (range == null) {
+			throw new IllegalArgumentException("range must be supplied.");
+		}
+		_range = range;
+	}
+
+	protected SharedValueRecordBase() {
+		this(new CellRangeAddress8Bit(0, 0, 0, 0));
+	}
+
+	/**
+	 * reads only the range (1 {@link CellRangeAddress8Bit}) from the stream
+	 */
+	public SharedValueRecordBase(LittleEndianInput in) {
+		_range = new CellRangeAddress8Bit(in);
+	}
+
+	/**
+	 * @return the range of cells that this record is shared across.  Never <code>null</code>.
+	 */
+	public final CellRangeAddress8Bit getRange() {
+		return _range;
+	}
+
+	public final int getFirstRow() {
+		return _range.getFirstRow();
+	}
+
+	public final int getLastRow() {
+		return _range.getLastRow();
+	}
+
+	public final int getFirstColumn() {
+		return (short) _range.getFirstColumn();
+	}
+
+	public final int getLastColumn() {
+		return (short) _range.getLastColumn();
+	}
+
+	protected int getDataSize() {
+		return CellRangeAddress8Bit.ENCODED_SIZE + getExtraDataSize();
+	}
+
+	protected abstract int getExtraDataSize();
+
+	protected abstract void serializeExtraData(LittleEndianOutput out);
+
+	public void serialize(LittleEndianOutput out) {
+		_range.serialize(out);
+		serializeExtraData(out);
+	}
+
+	/**
+	 * @return <code>true</code> if (rowIx, colIx) is within the range ({@link #getRange()})
+	 * of this shared value object.
+	 */
+	public final boolean isInRange(int rowIx, int colIx) {
+		CellRangeAddress8Bit r = _range;
+		return r.getFirstRow() <= rowIx
+			&& r.getLastRow() >= rowIx
+			&& r.getFirstColumn() <= colIx
+			&& r.getLastColumn() >= colIx;
+	}
+	/**
+	 * @return <code>true</code> if (rowIx, colIx) describes the first cell in this shared value
+	 * object's range ({@link #getRange()})
+	 */
+	public final boolean isFirstCell(int rowIx, int colIx) {
+		CellRangeAddress8Bit r = getRange();
+		return r.getFirstRow() == rowIx && r.getFirstColumn() == colIx;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/StandardRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/StandardRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/StandardRecord.java	(revision 28000)
@@ -0,0 +1,57 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianByteArrayOutputStream;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Subclasses of this class (the majority of BIFF records) are non-continuable.  This allows for
+ * some simplification of serialization logic
+ *
+ * @author Josh Micich
+ */
+public abstract class StandardRecord extends Record {
+	protected abstract int getDataSize();
+	public final int getRecordSize() {
+		return 4 + getDataSize();
+	}
+	@Override
+	public final int serialize(int offset, byte[] data) {
+		int dataSize = getDataSize();
+		int recSize = 4 + dataSize;
+		LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(data, offset, recSize);
+		out.writeShort(getSid());
+		out.writeShort(dataSize);
+		serialize(out);
+		if (out.getWriteIndex() - offset != recSize) {
+			throw new IllegalStateException("Error in serialization of (" + getClass().getName() + "): "
+					+ "Incorrect number of bytes written - expected "
+					+ recSize + " but got " + (out.getWriteIndex() - offset));
+		}
+		return recSize;
+	}
+
+	/**
+	 * Write the data content of this BIFF record.  The 'ushort sid' and 'ushort size' header fields
+	 * have already been written by the superclass.<br/>
+	 *
+	 * The subclass must write the exact number of bytes as reported by {@link org.apache.poi.hssf.record.Record#getRecordSize()}}
+	 */
+	protected abstract void serialize(LittleEndianOutput out);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/StringRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/StringRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/StringRecord.java	(revision 28000)
@@ -0,0 +1,93 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.cont.ContinuableRecord;
+import org.apache.poi.hssf.record.cont.ContinuableRecordOutput;
+
+/**
+ * STRING (0x0207)<p/>
+ * 
+ * Stores the cached result of a text formula
+ *
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class StringRecord extends ContinuableRecord {
+
+	public final static short sid = 0x0207;
+
+	private boolean _is16bitUnicode;
+	private String _text;
+
+
+    public StringRecord()
+    {
+    }
+
+    /**
+     * @param in the RecordInputstream to read the record from
+     */
+    public StringRecord( RecordInputStream in) { // NO_UCD
+        int field_1_string_length           = in.readUShort();
+        _is16bitUnicode            = in.readByte() != 0x00;
+        
+        if (_is16bitUnicode){
+            _text = in.readUnicodeLEString(field_1_string_length);
+        } else {
+            _text = in.readCompressedUnicode(field_1_string_length);
+        }
+    }
+
+
+    protected void serialize(ContinuableRecordOutput out) {
+        out.writeShort(_text.length());
+        out.writeStringData(_text);
+    }
+
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    /**
+     * @return The string represented by this record.
+     */
+    public String getString()
+    {
+        return _text;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[STRING]\n");
+        buffer.append("    .string            = ")
+            .append(_text).append("\n");
+        buffer.append("[/STRING]\n");
+        return buffer.toString();
+    }
+    
+    public Object clone() {
+        StringRecord rec = new StringRecord();
+        rec._is16bitUnicode= _is16bitUnicode;
+        rec._text = _text;
+        return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SubRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SubRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SubRecord.java	(revision 28000)
@@ -0,0 +1,118 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Subrecords are part of the OBJ class.
+ */
+public abstract class SubRecord {
+	protected SubRecord() {
+		// no fields to initialise
+	}
+
+    /**
+     * read a sub-record from the supplied stream
+     *
+     * @param in    the stream to read from
+     * @param cmoOt the objectType field of the containing CommonObjectDataSubRecord,
+     *   we need it to propagate to next sub-records as it defines what data follows
+     * @return the created sub-record
+     */
+    public static SubRecord createSubRecord(LittleEndianInput in, int cmoOt) {
+		int sid = in.readUShort();
+		int secondUShort = in.readUShort(); // Often (but not always) the datasize for the sub-record
+
+		switch (sid) {
+			case CommonObjectDataSubRecord.sid:
+				return new CommonObjectDataSubRecord(in, secondUShort);
+			case EmbeddedObjectRefSubRecord.sid:
+				return new EmbeddedObjectRefSubRecord(in, secondUShort);
+			case GroupMarkerSubRecord.sid:
+				return new GroupMarkerSubRecord(in, secondUShort);
+			case EndSubRecord.sid:
+				return new EndSubRecord(in, secondUShort);
+			case NoteStructureSubRecord.sid:
+				return new NoteStructureSubRecord(in, secondUShort);
+			case LbsDataSubRecord.sid:
+				return new LbsDataSubRecord(in, secondUShort, cmoOt);
+            case FtCblsSubRecord.sid:
+                return new FtCblsSubRecord(in, secondUShort);
+		}
+		return new UnknownSubRecord(in, sid, secondUShort);
+	}
+
+	/**
+	 * @return the size of the data for this record (which is always 4 bytes less than the total
+	 * record size).  Note however, that ushort encoded after the record sid is usually but not
+	 * always the data size.
+	 */
+	protected abstract int getDataSize();
+
+
+	public abstract void serialize(LittleEndianOutput out);
+	public abstract Object clone();
+
+    /**
+     * Wether this record terminates the sub-record stream.
+     * There are two cases when this method must be overridden and return <code>true</code>
+     *  - EndSubRecord (sid = 0x00)
+     *  - LbsDataSubRecord (sid = 0x12)
+     *
+     * @return whether this record is the last in the sub-record stream
+     */
+    public boolean isTerminating(){
+        return false;
+    }
+    
+    private static final class UnknownSubRecord extends SubRecord {
+
+		private final int _sid;
+		private final byte[] _data;
+
+		public UnknownSubRecord(LittleEndianInput in, int sid, int size) {
+			_sid = sid;
+	    	byte[] buf = new byte[size];
+	    	in.readFully(buf);
+	        _data = buf;
+		}
+		protected int getDataSize() {
+			return _data.length;
+		}
+		public void serialize(LittleEndianOutput out) {
+			out.writeShort(_sid);
+			out.writeShort(_data.length);
+			out.write(_data);
+		}
+		public Object clone() {
+			return this;
+		}
+		public String toString() {
+			StringBuffer sb = new StringBuffer(64);
+			sb.append(getClass().getName()).append(" [");
+			sb.append("sid=").append(HexDump.shortToHex(_sid));
+			sb.append(" size=").append(_data.length);
+			sb.append(" : ").append(HexDump.toHex(_data));
+			sb.append("]\n");
+			return sb.toString();
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SupBookRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SupBookRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/SupBookRecord.java	(revision 28000)
@@ -0,0 +1,179 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * Title:        Sup Book - EXTERNALBOOK (0x01AE) <p/>
+ * Description:  A External Workbook Description (Supplemental Book)
+ *               Its only a dummy record for making new ExternSheet Record <P>
+ * REFERENCE:  5.38<P>
+ * @author Libin Roman (Vista Portal LDT. Developer)
+ * @author Andrew C. Oliver (acoliver@apache.org)
+ *
+ */
+public final class SupBookRecord extends StandardRecord {
+
+    public final static short sid = 0x01AE;
+
+    private static final short SMALL_RECORD_SIZE = 4;
+    private static final short TAG_INTERNAL_REFERENCES = 0x0401;
+    private static final short TAG_ADD_IN_FUNCTIONS = 0x3A01;
+
+    private short field_1_number_of_sheets;
+    private String field_2_encoded_url;
+    private String[] field_3_sheet_names;
+    private boolean _isAddInFunctions;
+
+    public boolean isExternalReferences() {
+        return field_3_sheet_names != null;
+    }
+
+    /**
+     * called by the constructor, should set class level fields.  Should throw
+     * runtime exception for bad/incomplete data.
+     *
+     * @param in the stream to read from
+     */
+    public SupBookRecord(RecordInputStream in) { // NO_UCD
+        int recLen = in.remaining();
+
+        field_1_number_of_sheets = in.readShort();
+
+        if(recLen > SMALL_RECORD_SIZE) {
+            // 5.38.1 External References
+            _isAddInFunctions = false;
+
+            field_2_encoded_url = in.readString();
+            String[] sheetNames = new String[field_1_number_of_sheets];
+            for (int i = 0; i < sheetNames.length; i++) {
+                sheetNames[i] = in.readString();
+            }
+            field_3_sheet_names = sheetNames;
+            return;
+        }
+        // else not 'External References'
+        field_2_encoded_url = null;
+        field_3_sheet_names = null;
+
+        short nextShort = in.readShort();
+        if(nextShort == TAG_INTERNAL_REFERENCES) {
+            // 5.38.2 'Internal References'
+            _isAddInFunctions = false;
+        } else if(nextShort == TAG_ADD_IN_FUNCTIONS) {
+            // 5.38.3 'Add-In Functions'
+            _isAddInFunctions = true;
+            if(field_1_number_of_sheets != 1) {
+                throw new RuntimeException("Expected 0x0001 for number of sheets field in 'Add-In Functions' but got ("
+                     + field_1_number_of_sheets + ")");
+            }
+        } else {
+            throw new RuntimeException("invalid EXTERNALBOOK code ("
+                     + Integer.toHexString(nextShort) + ")");
+        }
+     }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getClass().getName()).append(" [SUPBOOK ");
+
+        if(isExternalReferences()) {
+            sb.append("External References");
+            sb.append(" nSheets=").append(field_1_number_of_sheets);
+            sb.append(" url=").append(field_2_encoded_url);
+        } else if(_isAddInFunctions) {
+            sb.append("Add-In Functions");
+        } else {
+            sb.append("Internal References ");
+            sb.append(" nSheets= ").append(field_1_number_of_sheets);
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+    protected int getDataSize() {
+        if(!isExternalReferences()) {
+            return SMALL_RECORD_SIZE;
+        }
+        int sum = 2; // u16 number of sheets
+
+        sum += StringUtil.getEncodedSize(field_2_encoded_url);
+
+        for(int i=0; i<field_3_sheet_names.length; i++) {
+            sum += StringUtil.getEncodedSize(field_3_sheet_names[i]);
+        }
+        return sum;
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(field_1_number_of_sheets);
+
+        if(isExternalReferences()) {
+            StringUtil.writeUnicodeString(out, field_2_encoded_url);
+
+            for(int i=0; i<field_3_sheet_names.length; i++) {
+                StringUtil.writeUnicodeString(out, field_3_sheet_names[i]);
+            }
+        } else {
+            int field2val = _isAddInFunctions ? TAG_ADD_IN_FUNCTIONS : TAG_INTERNAL_REFERENCES;
+
+            out.writeShort(field2val);
+        }
+    }
+
+    public short getNumberOfSheets(){ // NO_UCD
+        return field_1_number_of_sheets;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+    public String getURL() {
+        String encodedUrl = field_2_encoded_url;
+        switch(encodedUrl.charAt(0)) {
+            case 0: // Reference to an empty workbook name
+                return encodedUrl.substring(1); // will this just be empty string?
+            case 1: // encoded file name
+                return decodeFileName(encodedUrl);
+            case 2: // Self-referential external reference
+                return encodedUrl.substring(1);
+
+        }
+        return encodedUrl;
+    }
+    private static String decodeFileName(String encodedUrl) {
+        return encodedUrl.substring(1);
+        // TODO the following special characters may appear in the rest of the string, and need to get interpreted
+        /* see "MICROSOFT OFFICE EXCEL 97-2007  BINARY FILE FORMAT SPECIFICATION"
+        chVolume  1
+        chSameVolume  2
+        chDownDir  3
+        chUpDir  4
+        chLongVolume  5
+        chStartupDir  6
+        chAltStartupDir 7
+        chLibDir  8
+
+        */
+    }
+    public String[] getSheetNames() {
+        return field_3_sheet_names.clone();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/TabIdRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/TabIdRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/TabIdRecord.java	(revision 28000)
@@ -0,0 +1,76 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: Sheet Tab Index Array Record (0x013D)<p/>
+ * Description:  Contains an array of sheet id's.  Sheets always keep their ID
+ *               regardless of what their name is.<p/>
+ * REFERENCE:  PG 412 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ *
+ */
+public final class TabIdRecord extends StandardRecord {
+    public final static short sid = 0x013D;
+    private static final short[] EMPTY_SHORT_ARRAY = { };
+
+    public short[] _tabids;
+
+    public TabIdRecord() {
+        _tabids = EMPTY_SHORT_ARRAY;
+    }
+
+    public TabIdRecord(RecordInputStream in) { // NO_UCD
+        int nTabs = in.remaining() / 2;
+        _tabids = new short[nTabs];
+        for (int i = 0; i < _tabids.length; i++) {
+            _tabids[i] = in.readShort();
+        }
+    }
+
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[TABID]\n");
+        buffer.append("    .elements        = ").append(_tabids.length).append("\n");
+        for (int i = 0; i < _tabids.length; i++) {
+            buffer.append("    .element_").append(i).append(" = ").append(_tabids[i]).append("\n");
+        }
+        buffer.append("[/TABID]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        short[] tabids = _tabids;
+
+        for (int i = 0; i < tabids.length; i++) {
+            out.writeShort(tabids[i]);
+        }
+    }
+
+    protected int getDataSize() {
+        return _tabids.length * 2;
+    }
+
+    public short getSid() {
+        return sid;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/TableRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/TableRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/TableRecord.java	(revision 28000)
@@ -0,0 +1,100 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.formula.TblPtg;
+import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+/**
+ * DATATABLE (0x0236)<p/>
+ *
+ * TableRecord - The record specifies a data table.
+ * This record is preceded by a single Formula record that
+ *  defines the first cell in the data table, which should
+ *  only contain a single Ptg, {@link TblPtg}.
+ *
+ * See p536 of the June 08 binary docs
+ */
+public final class TableRecord extends SharedValueRecordBase {
+	public static final short sid = 0x0236;
+
+	private static final BitField alwaysCalc      = BitFieldFactory.getInstance(0x0001);
+
+	private int field_5_flags;
+	private int field_6_res;
+	private int field_7_rowInputRow;
+	private int field_8_colInputRow;
+	private int field_9_rowInputCol;
+	private int field_10_colInputCol;
+
+	public TableRecord(RecordInputStream in) { // NO_UCD
+		super(in);
+		field_5_flags        = in.readByte();
+		field_6_res          = in.readByte();
+		field_7_rowInputRow  = in.readShort();
+		field_8_colInputRow  = in.readShort();
+		field_9_rowInputCol  = in.readShort();
+		field_10_colInputCol = in.readShort();
+	}
+
+	public boolean isAlwaysCalc() {
+		return alwaysCalc.isSet(field_5_flags);
+	}
+
+	public short getSid() {
+		return sid;
+	}
+	protected int getExtraDataSize() {
+		return 
+		2 // 2 byte fields
+		+ 8; // 4 short fields
+	}
+	protected void serializeExtraData(LittleEndianOutput out) {
+		out.writeByte(field_5_flags);
+		out.writeByte(field_6_res);
+		out.writeShort(field_7_rowInputRow);
+		out.writeShort(field_8_colInputRow);
+		out.writeShort(field_9_rowInputCol);
+		out.writeShort(field_10_colInputCol);
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("[TABLE]\n");
+		buffer.append("    .range    = ").append(getRange().toString()).append("\n");
+		buffer.append("    .flags    = ") .append(HexDump.byteToHex(field_5_flags)).append("\n");
+		buffer.append("    .alwaysClc= ").append(isAlwaysCalc()).append("\n");
+		buffer.append("    .reserved = ").append(HexDump.intToHex(field_6_res)).append("\n");
+		CellReference crRowInput = cr(field_7_rowInputRow, field_8_colInputRow);
+		CellReference crColInput = cr(field_9_rowInputCol, field_10_colInputCol);
+		buffer.append("    .rowInput = ").append(crRowInput.formatAsString()).append("\n");
+		buffer.append("    .colInput = ").append(crColInput.formatAsString()).append("\n");
+		buffer.append("[/TABLE]\n");
+		return buffer.toString();
+	}
+
+	private static CellReference cr(int rowIx, int colIxAndFlags) {
+		int colIx = colIxAndFlags & 0x00FF;
+		boolean isRowAbs = (colIxAndFlags & 0x8000) == 0;
+		boolean isColAbs = (colIxAndFlags & 0x4000) == 0;
+		return new CellReference(rowIx, colIx, isRowAbs, isColAbs);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/TextObjectRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/TextObjectRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/TextObjectRecord.java	(revision 28000)
@@ -0,0 +1,287 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.cont.ContinuableRecord;
+import org.apache.poi.hssf.record.cont.ContinuableRecordOutput;
+import org.apache.poi.hssf.record.formula.OperandPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.usermodel.HSSFRichTextString;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.HexDump;
+
+/**
+ * The TXO record (0x01B6) is used to define the properties of a text box. It is
+ * followed by two or more continue records unless there is no actual text. The
+ * first continue records contain the text data and the last continue record
+ * contains the formatting runs.<p/>
+ *
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class TextObjectRecord extends ContinuableRecord {
+	public final static short sid = 0x01B6;
+
+	private static final int FORMAT_RUN_ENCODED_SIZE = 8; // 2 shorts and 4 bytes reserved
+
+	private static final BitField HorizontalTextAlignment = BitFieldFactory.getInstance(0x000E);
+	private static final BitField VerticalTextAlignment = BitFieldFactory.getInstance(0x0070);
+	private static final BitField textLocked = BitFieldFactory.getInstance(0x0200);
+
+	private int field_1_options;
+	private int field_2_textOrientation;
+	private int field_3_reserved4;
+	private int field_4_reserved5;
+	private int field_5_reserved6;
+	private int field_8_reserved7;
+
+	private HSSFRichTextString _text;
+
+	/*
+	 * Note - the next three fields are very similar to those on
+	 * EmbededObjectRefSubRecord(ftPictFmla 0x0009)
+	 *
+	 * some observed values for the 4 bytes preceding the formula: C0 5E 86 03
+	 * C0 11 AC 02 80 F1 8A 03 D4 F0 8A 03
+	 */
+	private int _unknownPreFormulaInt;
+	/** expect tRef, tRef3D, tArea, tArea3D or tName */
+	private OperandPtg _linkRefPtg;
+	/**
+	 * Not clear if needed .  Excel seems to be OK if this byte is not present.
+	 * Value is often the same as the earlier firstColumn byte. */
+	private Byte _unknownPostFormulaByte;
+
+	public TextObjectRecord() {
+		//
+	}
+
+	public TextObjectRecord(RecordInputStream in) { // NO_UCD
+		field_1_options = in.readUShort();
+		field_2_textOrientation = in.readUShort();
+		field_3_reserved4 = in.readUShort();
+		field_4_reserved5 = in.readUShort();
+		field_5_reserved6 = in.readUShort();
+		int field_6_textLength = in.readUShort();
+		int field_7_formattingDataLength = in.readUShort();
+		field_8_reserved7 = in.readInt();
+
+		if (in.remaining() > 0) {
+			// Text Objects can have simple reference formulas
+			// (This bit not mentioned in the MS document)
+			if (in.remaining() < 11) {
+				throw new RecordFormatException("Not enough remaining data for a link formula");
+			}
+			int formulaSize = in.readUShort();
+			_unknownPreFormulaInt = in.readInt();
+			Ptg[] ptgs = Ptg.readTokens(formulaSize, in);
+			if (ptgs.length != 1) {
+				throw new RecordFormatException("Read " + ptgs.length
+						+ " tokens but expected exactly 1");
+			}
+			_linkRefPtg = (OperandPtg) ptgs[0];
+			if (in.remaining() > 0) {
+				_unknownPostFormulaByte = Byte.valueOf(in.readByte());
+			} else {
+				_unknownPostFormulaByte = null;
+			}
+		} else {
+			_linkRefPtg = null;
+		}
+		if (in.remaining() > 0) {
+			throw new RecordFormatException("Unused " + in.remaining() + " bytes at end of record");
+		}
+
+		String text;
+		if (field_6_textLength > 0) {
+			text = readRawString(in, field_6_textLength);
+		} else {
+			text = "";
+		}
+		_text = new HSSFRichTextString(text);
+
+		if (field_7_formattingDataLength > 0) {
+			processFontRuns(in, _text, field_7_formattingDataLength);
+		}
+	}
+
+	private static String readRawString(RecordInputStream in, int textLength) {
+		byte compressByte = in.readByte();
+		boolean isCompressed = (compressByte & 0x01) == 0;
+		if (isCompressed) {
+			return in.readCompressedUnicode(textLength);
+		}
+		return in.readUnicodeLEString(textLength);
+	}
+
+	private static void processFontRuns(RecordInputStream in, HSSFRichTextString str,
+			int formattingRunDataLength) {
+		if (formattingRunDataLength % FORMAT_RUN_ENCODED_SIZE != 0) {
+			throw new RecordFormatException("Bad format run data length " + formattingRunDataLength
+					+ ")");
+		}
+		int nRuns = formattingRunDataLength / FORMAT_RUN_ENCODED_SIZE;
+		for (int i = 0; i < nRuns; i++) {
+			short index = in.readShort();
+			short iFont = in.readShort();
+			in.readInt(); // skip reserved.
+			str.applyFont(index, str.length(), iFont);
+		}
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	private void serializeTXORecord(ContinuableRecordOutput out) {
+
+		out.writeShort(field_1_options);
+		out.writeShort(field_2_textOrientation);
+		out.writeShort(field_3_reserved4);
+		out.writeShort(field_4_reserved5);
+		out.writeShort(field_5_reserved6);
+		out.writeShort(_text.length());
+		out.writeShort(getFormattingDataLength());
+		out.writeInt(field_8_reserved7);
+
+		if (_linkRefPtg != null) {
+			int formulaSize = _linkRefPtg.getSize();
+			out.writeShort(formulaSize);
+			out.writeInt(_unknownPreFormulaInt);
+			_linkRefPtg.write(out);
+			if (_unknownPostFormulaByte != null) {
+				out.writeByte(_unknownPostFormulaByte.byteValue());
+			}
+		}
+	}
+
+	private void serializeTrailingRecords(ContinuableRecordOutput out) {
+		out.writeContinue();
+		out.writeStringData(_text.getString());
+		out.writeContinue();
+		writeFormatData(out, _text);
+	}
+
+	protected void serialize(ContinuableRecordOutput out) {
+
+		serializeTXORecord(out);
+		if (_text.getString().length() > 0) {
+			serializeTrailingRecords(out);
+		}
+	}
+
+	private int getFormattingDataLength() {
+		if (_text.length() < 1) {
+			// important - no formatting data if text is empty
+			return 0;
+		}
+		return (_text.numFormattingRuns() + 1) * FORMAT_RUN_ENCODED_SIZE;
+	}
+
+	private static void writeFormatData(ContinuableRecordOutput out , HSSFRichTextString str) {
+		int nRuns = str.numFormattingRuns();
+		for (int i = 0; i < nRuns; i++) {
+			out.writeShort(str.getIndexOfFormattingRun(i));
+			int fontIndex = str.getFontOfFormattingRun(i);
+			out.writeShort(fontIndex == HSSFRichTextString.NO_FONT ? 0 : fontIndex);
+			out.writeInt(0); // skip reserved
+		}
+		out.writeShort(str.length());
+		out.writeShort(0);
+		out.writeInt(0); // skip reserved
+	}
+
+	/**
+	 * @return the Horizontal text alignment field value.
+	 */
+	public int getHorizontalTextAlignment() {
+		return HorizontalTextAlignment.getValue(field_1_options);
+	}
+
+
+	/**
+	 * @return the Vertical text alignment field value.
+	 */
+	public int getVerticalTextAlignment() {
+		return VerticalTextAlignment.getValue(field_1_options);
+	}
+
+	/**
+	 * @return the text locked field value.
+	 */
+	public boolean isTextLocked() {
+		return textLocked.isSet(field_1_options);
+	}
+
+	/**
+	 * Get the text orientation field for the TextObjectBase record.
+	 *
+	 * @return One of TEXT_ORIENTATION_NONE TEXT_ORIENTATION_TOP_TO_BOTTOM
+	 *         TEXT_ORIENTATION_ROT_RIGHT TEXT_ORIENTATION_ROT_LEFT
+	 */
+	public int getTextOrientation() {
+		return field_2_textOrientation;
+	}
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+
+		sb.append("[TXO]\n");
+		sb.append("    .options        = ").append(HexDump.shortToHex(field_1_options)).append("\n");
+		sb.append("         .isHorizontal = ").append(getHorizontalTextAlignment()).append('\n');
+		sb.append("         .isVertical   = ").append(getVerticalTextAlignment()).append('\n');
+		sb.append("         .textLocked   = ").append(isTextLocked()).append('\n');
+		sb.append("    .textOrientation= ").append(HexDump.shortToHex(getTextOrientation())).append("\n");
+		sb.append("    .reserved4      = ").append(HexDump.shortToHex(field_3_reserved4)).append("\n");
+		sb.append("    .reserved5      = ").append(HexDump.shortToHex(field_4_reserved5)).append("\n");
+		sb.append("    .reserved6      = ").append(HexDump.shortToHex(field_5_reserved6)).append("\n");
+		sb.append("    .textLength     = ").append(HexDump.shortToHex(_text.length())).append("\n");
+		sb.append("    .reserved7      = ").append(HexDump.intToHex(field_8_reserved7)).append("\n");
+
+		sb.append("    .string = ").append(_text).append('\n');
+
+		for (int i = 0; i < _text.numFormattingRuns(); i++) {
+			sb.append("    .textrun = ").append(_text.getFontOfFormattingRun(i)).append('\n');
+
+		}
+		sb.append("[/TXO]\n");
+		return sb.toString();
+	}
+
+	public Object clone() {
+
+		TextObjectRecord rec = new TextObjectRecord();
+		rec._text = _text;
+
+		rec.field_1_options = field_1_options;
+		rec.field_2_textOrientation = field_2_textOrientation;
+		rec.field_3_reserved4 = field_3_reserved4;
+		rec.field_4_reserved5 = field_4_reserved5;
+		rec.field_5_reserved6 = field_5_reserved6;
+		rec.field_8_reserved7 = field_8_reserved7;
+
+		rec._text = _text; // clone needed?
+
+		if (_linkRefPtg != null) {
+			rec._unknownPreFormulaInt = _unknownPreFormulaInt;
+			rec._linkRefPtg = _linkRefPtg.copy();
+			rec._unknownPostFormulaByte = _unknownPostFormulaByte;
+		}
+		return rec;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/UncalcedRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/UncalcedRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/UncalcedRecord.java	(revision 28000)
@@ -0,0 +1,58 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: Uncalced Record
+ * <P>
+ * If this record occurs in the Worksheet Substream, it indicates that the formulas have not 
+ * been recalculated before the document was saved.
+ * 
+ * @author Olivier Leprince
+ */
+public final class UncalcedRecord extends StandardRecord  {
+	public final static short sid = 0x005E;
+
+	public UncalcedRecord() {
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	public UncalcedRecord(RecordInputStream in) { // NO_UCD
+		in.readShort(); // unused
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("[UNCALCED]\n");
+		buffer.append("[/UNCALCED]\n");
+		return buffer.toString();
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		out.writeShort(0);
+	}
+
+	protected int getDataSize() {
+		return 2;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/UnknownRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/UnknownRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/UnknownRecord.java	(revision 28000)
@@ -0,0 +1,269 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.aggregates.PageSettingsBlock;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Unknown Record (for debugging)<p/>
+ * Description:  Unknown record just tells you the sid so you can figure out
+ *               what records you are missing.  Also helps us read/modify sheets we
+ *               don't know all the records to.  (HSSF leaves these alone!) <p/>
+ * Company:      SuperLink Software, Inc.<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class UnknownRecord extends StandardRecord {
+
+	/*
+	 * Some Record IDs used by POI as 'milestones' in the record stream
+	 */
+	/**
+	 * seems to be part of the {@link PageSettingsBlock}. Not interpreted by POI.
+	 * The name 'PRINTSIZE' was taken from OOO source.<br/>
+	 * The few POI test samples with this record have data { 0x03, 0x00 }.
+	 */
+	public static final int PRINTSIZE_0033       = 0x0033;
+	/**
+	 * Environment-Specific Print Record
+	 */
+	public static final int PLS_004D             = 0x004D;
+	public static final int SHEETPR_0081         = 0x0081;
+	public static final int SORT_0090            = 0x0090;
+	public static final int STANDARDWIDTH_0099   = 0x0099;
+	public static final int SCL_00A0             = 0x00A0;
+	public static final int BITMAP_00E9          = 0x00E9;
+	public static final int PHONETICPR_00EF      = 0x00EF;
+	public static final int LABELRANGES_015F     = 0x015F;
+	public static final int QUICKTIP_0800        = 0x0800;
+	public static final int SHEETEXT_0862        = 0x0862; // OOO calls this SHEETLAYOUT
+	public static final int SHEETPROTECTION_0867 = 0x0867;
+	public static final int HEADER_FOOTER_089C   = 0x089C;
+    public static final int CODENAME_1BA         = 0x01BA;
+
+	private int _sid;
+	private byte[] _rawData;
+
+	/**
+	 * construct an unknown record.  No fields are interpreted and the record will
+	 * be serialized in its original form more or less
+	 * @param in the RecordInputstream to read the record from
+	 */
+	public UnknownRecord(RecordInputStream in) {
+		_sid = in.getSid();
+		_rawData = in.readRemainder();
+	}
+
+	/**
+	 * spit the record out AS IS. no interpretation or identification
+	 */
+	public void serialize(LittleEndianOutput out) {
+		out.write(_rawData);
+	}
+
+	protected int getDataSize() {
+		return _rawData.length;
+	}
+
+	/**
+	 * print a sort of string representation ([UNKNOWN RECORD] id = x [/UNKNOWN RECORD])
+	 */
+	public String toString() {
+		String biffName = getBiffName(_sid);
+		if (biffName == null) {
+			biffName = "UNKNOWNRECORD";
+		}
+		StringBuffer sb = new StringBuffer();
+
+		sb.append("[").append(biffName).append("] (0x");
+		sb.append(Integer.toHexString(_sid).toUpperCase() + ")\n");
+		if (_rawData.length > 0) {
+			sb.append("  rawData=").append(HexDump.toHex(_rawData)).append("\n");
+		}
+		sb.append("[/").append(biffName).append("]\n");
+		return sb.toString();
+	}
+
+	public short getSid() {
+		return (short) _sid;
+	}
+
+	/**
+	 * These BIFF record types are known but still uninterpreted by POI
+	 *
+	 * @return the documented name of this BIFF record type, <code>null</code> if unknown to POI
+	 */
+	public static String getBiffName(int sid) {
+		// Note to POI developers:
+		// Make sure you delete the corresponding entry from
+		// this method any time a new Record subclass is created.
+		switch (sid) {
+			case PRINTSIZE_0033: return "PRINTSIZE";
+			case PLS_004D: return "PLS";
+			case 0x0050: return "DCON"; // Data Consolidation Information
+			case 0x007F: return "IMDATA";
+			case SHEETPR_0081: return "SHEETPR";
+			case SORT_0090: return "SORT"; // Sorting Options
+			case 0x0094: return "LHRECORD"; // .WK? File Conversion Information
+			case STANDARDWIDTH_0099: return "STANDARDWIDTH"; //Standard Column Width
+			case SCL_00A0: return "SCL"; // Window Zoom Magnification
+			case 0x00AE: return "SCENMAN"; // Scenario Output Data
+
+			case 0x00B2: return "SXVI";        // (pivot table) View Item
+			case 0x00B4: return "SXIVD";       // (pivot table) Row/Column Field IDs
+			case 0x00B5: return "SXLI";        // (pivot table) Line Item Array
+
+			case 0x00D3: return "OBPROJ";
+			case 0x00DC: return "PARAMQRY";
+			case 0x00DE: return "OLESIZE";
+			case BITMAP_00E9: return "BITMAP";
+			case PHONETICPR_00EF: return "PHONETICPR";
+			case 0x00F1: return "SXEX";        // PivotTable View Extended Information
+
+			case LABELRANGES_015F: return "LABELRANGES";
+			case 0x01BA: return "CODENAME";
+			case 0x01A9: return "USERBVIEW";
+			case 0x01AD: return "QSI";
+
+			case 0x01C0: return "EXCEL9FILE";
+
+			case 0x0802: return "QSISXTAG";   // Pivot Table and Query Table Extensions
+			case 0x0803: return "DBQUERYEXT";
+			case 0x0805: return "TXTQUERY";
+			case 0x0810: return "SXVIEWEX9";  // Pivot Table Extensions
+
+			case 0x0812: return "CONTINUEFRT";
+			case QUICKTIP_0800: return "QUICKTIP";
+			case SHEETEXT_0862: return "SHEETEXT";
+			case 0x0863: return "BOOKEXT";
+			case 0x0864: return "SXADDL";    // Pivot Table Additional Info
+			case SHEETPROTECTION_0867: return "SHEETPROTECTION";
+			case 0x086B: return "DATALABEXTCONTENTS";
+			case 0x086C: return "CELLWATCH";
+			case 0x0874: return "DROPDOWNOBJIDS";
+			case 0x0876: return "DCONN";
+			case 0x087B: return "CFEX";
+			case 0x087C: return "XFCRC";
+			case 0x087D: return "XFEXT";
+			case 0x087F: return "CONTINUEFRT12";
+			case 0x088B: return "PLV";
+			case 0x088C: return "COMPAT12";
+			case 0x088D: return "DXF";
+			case 0x0892: return "STYLEEXT";
+			case 0x0896: return "THEME";
+			case 0x0897: return "GUIDTYPELIB";
+			case 0x089A: return "MTRSETTINGS";
+			case 0x089B: return "COMPRESSPICTURES";
+			case HEADER_FOOTER_089C: return "HEADERFOOTER";
+			case 0x08A1: return "SHAPEPROPSSTREAM";
+			case 0x08A3: return "FORCEFULLCALCULATION";
+			case 0x08A4: return "SHAPEPROPSSTREAM";
+			case 0x08A5: return "TEXTPROPSSTREAM";
+			case 0x08A6: return "RICHTEXTSTREAM";
+
+			case 0x08C8: return "PLV{Mac Excel}";
+
+
+		}
+		if (isObservedButUnknown(sid)) {
+			return "UNKNOWN-" + Integer.toHexString(sid).toUpperCase();
+		}
+
+		return null;
+	}
+
+	/**
+	 * @return <code>true</code> if the unknown record id has been observed in POI unit tests
+	 */
+	private static boolean isObservedButUnknown(int sid) {
+		switch (sid) {
+			case 0x0033:
+				// contains 2 bytes of data: 0x0001 or 0x0003
+			case 0x0034:
+				// Seems to be written by MSAccess
+				// contains text "[Microsoft JET Created Table]0021010"
+				// appears after last cell value record and before WINDOW2
+			case 0x01BD:
+			case 0x01C2:
+				// Written by Excel 2007
+				// rawData is multiple of 12 bytes long
+				// appears after last cell value record and before WINDOW2 or drawing records
+			case 0x089D:
+			case 0x089E:
+			case 0x08A7:
+
+			case 0x1001:
+			case 0x1006:
+			case 0x1007:
+			case 0x1009:
+			case 0x100A:
+			case 0x100B:
+			case 0x100C:
+			case 0x1014:
+			case 0x1017:
+			case 0x1018:
+			case 0x1019:
+			case 0x101A:
+			case 0x101B:
+			case 0x101D:
+			case 0x101E:
+			case 0x101F:
+			case 0x1020:
+			case 0x1021:
+			case 0x1022:
+			case 0x1024:
+			case 0x1025:
+			case 0x1026:
+			case 0x1027:
+			case 0x1032:
+			case 0x1033:
+			case 0x1034:
+			case 0x1035:
+			case 0x103A:
+			case 0x1041:
+			case 0x1043:
+			case 0x1044:
+			case 0x1045:
+			case 0x1046:
+			case 0x104A:
+			case 0x104B:
+			case 0x104E:
+			case 0x104F:
+			case 0x1051:
+			case 0x105C:
+			case 0x105D:
+			case 0x105F:
+			case 0x1060:
+			case 0x1062:
+			case 0x1063:
+			case 0x1064:
+			case 0x1065:
+			case 0x1066:
+				return true;
+		}
+		return false;
+	}
+
+	public Object clone() {
+		// immutable - OK to return this
+		return this;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/VerticalPageBreakRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/VerticalPageBreakRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/VerticalPageBreakRecord.java	(revision 28000)
@@ -0,0 +1,59 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import java.util.Iterator;
+
+/**
+ * VerticalPageBreak (0x001A) record that stores page breaks at columns<p/>
+ * 
+ * @see PageBreakRecord
+ * @author Danny Mui (dmui at apache dot org)
+ */
+public final class VerticalPageBreakRecord extends PageBreakRecord {
+
+	public static final short sid = 0x001A;
+
+	/**
+	 * Creates an empty vertical page break record
+	 */
+	public VerticalPageBreakRecord() {
+
+	}
+
+	/**
+	 * @param in the RecordInputstream to read the record from
+	 */
+	public VerticalPageBreakRecord(RecordInputStream in) { // NO_UCD
+		super(in);
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	public Object clone() {
+		PageBreakRecord result = new VerticalPageBreakRecord();
+		Iterator<Break> iterator = getBreaksIterator();
+		while (iterator.hasNext()) {
+			Break original = iterator.next();
+			result.addBreak(original.main, original.subFrom, original.subTo);
+		}
+		return result;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/WSBoolRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/WSBoolRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/WSBoolRecord.java	(revision 28000)
@@ -0,0 +1,257 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        WSBOOL (0x0081) (called SHEETPR in OOO doc)<p/>
+ * Description:  stores workbook settings  (aka its a big "everything we didn't
+ *               put somewhere else")<P>
+ * REFERENCE:  PG 425 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Glen Stampoultzis (gstamp@iprimus.com.au)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class WSBoolRecord extends StandardRecord {
+    public final static short     sid = 0x0081;
+    private byte                  field_1_wsbool;         // crappy names are because this is really one big short field (2byte)
+    private byte                  field_2_wsbool;         // but the docs inconsistently use it as 2 separate bytes
+
+    // I decided to be consistent in this way.
+    private static final BitField autobreaks    = BitFieldFactory.getInstance(0x01); // are automatic page breaks visible
+
+    // bits 1 to 3 unused
+    private static final BitField dialog        = BitFieldFactory.getInstance(0x10); // is sheet dialog sheet
+    private static final BitField rowsumsbelow  = BitFieldFactory.getInstance(0x40); // whether summary rows will appear below detail in outlines
+    private static final BitField rowsumsright  = BitFieldFactory.getInstance(0x80); // whether summary rows will appear right of the detail in outlines
+    private static final BitField fittopage     = BitFieldFactory.getInstance(0x01); // whether to fit stuff to the page
+
+    // bit 2 reserved
+    private static final BitField displayguts   = BitFieldFactory.getInstance(0x06); // whether to display outline symbols (in the gutters)
+
+    // bits 4-5 reserved
+    private static final BitField alternateexpression = BitFieldFactory.getInstance(0x40); // whether to use alternate expression eval
+    private static final BitField alternateformula    = BitFieldFactory.getInstance(0x80); // whether to use alternate formula entry
+
+    public WSBoolRecord()
+    {
+    }
+
+    public WSBoolRecord(RecordInputStream in) // NO_UCD
+    {
+       byte data[] = in.readRemainder();
+        field_1_wsbool =
+            data[ 1 ];   // backwards because theoretically this is one short field
+        field_2_wsbool =
+            data[ 0 ];   // but it was easier to implement it this way to avoid confusion
+    }                             // because the dev kit shows the masks for it as 2 byte fields
+
+    // why?  Why ask why?  But don't drink bud dry as its a really
+    // crappy beer, try the czech "Budvar" beer (which is the real
+    // budweiser though its ironically good...its sold in the USs
+    // as czechvar  --- odd that they had the name first but can't
+    // use it)...
+
+    /**
+     * set first byte (see bit setters)
+     */
+
+    public void setWSBool1(byte bool1)
+    {
+        field_1_wsbool = bool1;
+    }
+
+    // bool1 bitfields
+
+
+
+    // end bitfields
+
+    /**
+     * set the second byte (see bit setters)
+     */
+
+    public void setWSBool2(byte bool2)
+    {
+        field_2_wsbool = bool2;
+    }
+
+    // bool2 bitfields
+
+
+    // end bitfields
+
+    /**
+     * get first byte (see bit getters)
+     */
+
+    public byte getWSBool1()
+    {
+        return field_1_wsbool;
+    }
+
+    // bool1 bitfields
+
+    /**
+     * show automatic page breaks or not
+     * @return whether to show auto page breaks
+     */
+
+    public boolean getAutobreaks()
+    {
+        return autobreaks.isSet(field_1_wsbool);
+    }
+
+    /**
+     * get whether sheet is a dialog sheet or not
+     * @return isDialog or not
+     */
+
+    public boolean getDialog()
+    {
+        return dialog.isSet(field_1_wsbool);
+    }
+
+    /**
+     * get if row summaries appear below detail in the outline
+     * @return below or not
+     */
+
+    public boolean getRowSumsBelow()
+    {
+        return rowsumsbelow.isSet(field_1_wsbool);
+    }
+
+    /**
+     * get if col summaries appear right of the detail in the outline
+     * @return right or not
+     */
+
+    public boolean getRowSumsRight()
+    {
+        return rowsumsright.isSet(field_1_wsbool);
+    }
+
+    // end bitfields
+
+    /**
+     * get the second byte (see bit getters)
+     */
+
+    public byte getWSBool2()
+    {
+        return field_2_wsbool;
+    }
+
+    // bool2 bitfields
+
+    /**
+     * fit to page option is on
+     * @return fit or not
+     */
+
+    public boolean getFitToPage()
+    {
+        return fittopage.isSet(field_2_wsbool);
+    }
+
+    /**
+     * get whether to display the guts or not
+     *
+     * @return guts or no guts (or glory)
+     */
+
+    public boolean getDisplayGuts()
+    {
+        return displayguts.isSet(field_2_wsbool);
+    }
+
+    /**
+     * whether alternate expression evaluation is on
+     * @return alternative expression evaluation or not
+     */
+
+    public boolean getAlternateExpression()
+    {
+        return alternateexpression.isSet(field_2_wsbool);
+    }
+
+    /**
+     * whether alternative formula entry is on
+     * @return alternative formulas or not
+     */
+
+    public boolean getAlternateFormula()
+    {
+        return alternateformula.isSet(field_2_wsbool);
+    }
+
+    // end bitfields
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[WSBOOL]\n");
+        buffer.append("    .wsbool1        = ")
+            .append(Integer.toHexString(getWSBool1())).append("\n");
+        buffer.append("        .autobreaks = ").append(getAutobreaks())
+            .append("\n");
+        buffer.append("        .dialog     = ").append(getDialog())
+            .append("\n");
+        buffer.append("        .rowsumsbelw= ").append(getRowSumsBelow())
+            .append("\n");
+        buffer.append("        .rowsumsrigt= ").append(getRowSumsRight())
+            .append("\n");
+        buffer.append("    .wsbool2        = ")
+            .append(Integer.toHexString(getWSBool2())).append("\n");
+        buffer.append("        .fittopage  = ").append(getFitToPage())
+            .append("\n");
+        buffer.append("        .displayguts= ").append(getDisplayGuts())
+            .append("\n");
+        buffer.append("        .alternateex= ")
+            .append(getAlternateExpression()).append("\n");
+        buffer.append("        .alternatefo= ").append(getAlternateFormula())
+            .append("\n");
+        buffer.append("[/WSBOOL]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeByte(getWSBool2());
+        out.writeByte(getWSBool1());
+    }
+
+    protected int getDataSize() {
+        return 2;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public Object clone() {
+      WSBoolRecord rec = new WSBoolRecord();
+      rec.field_1_wsbool = field_1_wsbool;
+      rec.field_2_wsbool = field_2_wsbool;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/WindowOneRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/WindowOneRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/WindowOneRecord.java	(revision 28000)
@@ -0,0 +1,367 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Window1 Record<P>
+ * Description:  Stores the attributes of the workbook window.  This is basically
+ *               so the gui knows how big to make the window holding the spreadsheet
+ *               document.<P>
+ * REFERENCE:  PG 421 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @version 2.0-pre
+ */
+public final class WindowOneRecord extends StandardRecord {
+    public final static short     sid = 0x3d;
+
+    // our variable names stolen from old TV sets.
+    private short                 field_1_h_hold;                  // horizontal position
+    private short                 field_2_v_hold;                  // vertical position
+    private short                 field_3_width;
+    private short                 field_4_height;
+    private short                 field_5_options;
+    static final private BitField hidden   =
+        BitFieldFactory.getInstance(0x01);                                        // is this window is hidden
+    static final private BitField iconic   =
+        BitFieldFactory.getInstance(0x02);                                        // is this window is an icon
+    static final private BitField hscroll  =
+        BitFieldFactory.getInstance(0x08);                                        // display horizontal scrollbar
+    static final private BitField vscroll  =
+        BitFieldFactory.getInstance(0x10);                                        // display vertical scrollbar
+    static final private BitField tabs     =
+        BitFieldFactory.getInstance(0x20);                                        // display tabs at the bottom
+
+    // all the rest are "reserved"
+    private int                   field_6_active_sheet;
+    private int                   field_7_first_visible_tab;
+    private short                 field_8_num_selected_tabs;
+    private short                 field_9_tab_width_ratio;
+
+    public WindowOneRecord()
+    {
+    }
+
+    public WindowOneRecord(RecordInputStream in) // NO_UCD
+    {
+        field_1_h_hold            = in.readShort();
+        field_2_v_hold            = in.readShort();
+        field_3_width             = in.readShort();
+        field_4_height            = in.readShort();
+        field_5_options           = in.readShort();
+        field_6_active_sheet      = in.readShort();
+        field_7_first_visible_tab     = in.readShort();
+        field_8_num_selected_tabs = in.readShort();
+        field_9_tab_width_ratio   = in.readShort();
+    }
+
+    /**
+     * set the horizontal position of the window (in 1/20ths of a point)
+     * @param h - horizontal location
+     */
+
+    public void setHorizontalHold(short h)
+    {
+        field_1_h_hold = h;
+    }
+
+    /**
+     * set the vertical position of the window (in 1/20ths of a point)
+     * @param v - vertical location
+     */
+
+    public void setVerticalHold(short v)
+    {
+        field_2_v_hold = v;
+    }
+
+    /**
+     * set the width of the window
+     * @param w  width
+     */
+
+    public void setWidth(short w)
+    {
+        field_3_width = w;
+    }
+
+    /**
+     * set teh height of the window
+     * @param h  height
+     */
+
+    public void setHeight(short h)
+    {
+        field_4_height = h;
+    }
+
+    /**
+     * set the options bitmask (see bit setters)
+     *
+     * @param o - the bitmask
+     */
+
+    public void setOptions(short o)
+    {
+        field_5_options = o;
+    }
+
+    // bitfields for options
+
+
+
+    // end bitfields
+
+    public void setActiveSheetIndex(int index) {
+    	field_6_active_sheet = index;
+	}
+
+
+    /**
+     * Sets the first visible sheet in the worksheet tab-bar.  This method does <b>not</b>
+     *  hide, select or focus sheets.  It just sets the scroll position in the tab-bar.
+     * @param t the sheet index of the tab that will become the first in the tab-bar
+     */
+    public void setFirstVisibleTab(int t) {
+        field_7_first_visible_tab = t;
+    }
+
+
+    /**
+     * set the number of selected tabs
+     * @param n  number of tabs
+     */
+
+    public void setNumSelectedTabs(short n)
+    {
+        field_8_num_selected_tabs = n;
+    }
+
+    /**
+     * ratio of the width of the tabs to the horizontal scrollbar
+     * @param r  ratio
+     */
+
+    public void setTabWidthRatio(short r)
+    {
+        field_9_tab_width_ratio = r;
+    }
+
+    /**
+     * get the horizontal position of the window (in 1/20ths of a point)
+     * @return h - horizontal location
+     */
+
+    public short getHorizontalHold()
+    {
+        return field_1_h_hold;
+    }
+
+    /**
+     * get the vertical position of the window (in 1/20ths of a point)
+     * @return v - vertical location
+     */
+
+    public short getVerticalHold()
+    {
+        return field_2_v_hold;
+    }
+
+    /**
+     * get the width of the window
+     * @return width
+     */
+
+    public short getWidth()
+    {
+        return field_3_width;
+    }
+
+    /**
+     * get the height of the window
+     * @return height
+     */
+
+    public short getHeight()
+    {
+        return field_4_height;
+    }
+
+    /**
+     * get the options bitmask (see bit setters)
+     *
+     * @return o - the bitmask
+     */
+
+    public short getOptions()
+    {
+        return field_5_options;
+    }
+
+    // bitfields for options
+
+    /**
+     * get whether the window is hidden or not
+     * @return ishidden or not
+     */
+
+    public boolean getHidden()
+    {
+        return hidden.isSet(field_5_options);
+    }
+
+    /**
+     * get whether the window has been iconized or not
+     * @return iconize  or not
+     */
+
+    public boolean getIconic()
+    {
+        return iconic.isSet(field_5_options);
+    }
+
+    /**
+     * get whether to display the horizontal scrollbar or not
+     * @return display or not
+     */
+
+    public boolean getDisplayHorizontalScrollbar()
+    {
+        return hscroll.isSet(field_5_options);
+    }
+
+    /**
+     * get whether to display the vertical scrollbar or not
+     * @return display or not
+     */
+
+    public boolean getDisplayVerticalScrollbar()
+    {
+        return vscroll.isSet(field_5_options);
+    }
+
+    /**
+     * get whether to display the tabs or not
+     * @return display or not
+     */
+
+    public boolean getDisplayTabs()
+    {
+        return tabs.isSet(field_5_options);
+    }
+
+    // end options bitfields
+
+    
+    /**
+     * @return the index of the currently displayed sheet 
+     */
+    public int getActiveSheetIndex() {
+    	return field_6_active_sheet;
+    }
+
+
+    /**
+     * @return the first visible sheet in the worksheet tab-bar. 
+     * I.E. the scroll position of the tab-bar.
+     */
+    public int getFirstVisibleTab() {
+        return field_7_first_visible_tab;
+    }
+
+    /**
+     * get the number of selected tabs
+     * @return number of tabs
+     */
+
+    public short getNumSelectedTabs()
+    {
+        return field_8_num_selected_tabs;
+    }
+
+    /**
+     * ratio of the width of the tabs to the horizontal scrollbar
+     * @return ratio
+     */
+
+    public short getTabWidthRatio()
+    {
+        return field_9_tab_width_ratio;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[WINDOW1]\n");
+        buffer.append("    .h_hold          = ")
+            .append(Integer.toHexString(getHorizontalHold())).append("\n");
+        buffer.append("    .v_hold          = ")
+            .append(Integer.toHexString(getVerticalHold())).append("\n");
+        buffer.append("    .width           = ")
+            .append(Integer.toHexString(getWidth())).append("\n");
+        buffer.append("    .height          = ")
+            .append(Integer.toHexString(getHeight())).append("\n");
+        buffer.append("    .options         = ")
+            .append(Integer.toHexString(getOptions())).append("\n");
+        buffer.append("        .hidden      = ").append(getHidden())
+            .append("\n");
+        buffer.append("        .iconic      = ").append(getIconic())
+            .append("\n");
+        buffer.append("        .hscroll     = ")
+            .append(getDisplayHorizontalScrollbar()).append("\n");
+        buffer.append("        .vscroll     = ")
+            .append(getDisplayVerticalScrollbar()).append("\n");
+        buffer.append("        .tabs        = ").append(getDisplayTabs())
+            .append("\n");
+        buffer.append("    .activeSheet     = ")
+            .append(Integer.toHexString(getActiveSheetIndex())).append("\n");
+        buffer.append("    .firstVisibleTab    = ")
+            .append(Integer.toHexString(getFirstVisibleTab())).append("\n");
+        buffer.append("    .numselectedtabs = ")
+            .append(Integer.toHexString(getNumSelectedTabs())).append("\n");
+        buffer.append("    .tabwidthratio   = ")
+            .append(Integer.toHexString(getTabWidthRatio())).append("\n");
+        buffer.append("[/WINDOW1]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(getHorizontalHold());
+        out.writeShort(getVerticalHold());
+        out.writeShort(getWidth());
+        out.writeShort(getHeight());
+        out.writeShort(getOptions());
+        out.writeShort(getActiveSheetIndex());
+        out.writeShort(getFirstVisibleTab());
+        out.writeShort(getNumSelectedTabs());
+        out.writeShort(getTabWidthRatio());
+    }
+
+    protected int getDataSize() {
+        return 18;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/WindowTwoRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/WindowTwoRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/WindowTwoRecord.java	(revision 28000)
@@ -0,0 +1,418 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record;
+
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Window Two Record<P>
+ * Description:  sheet window settings<P>
+ * REFERENCE:  PG 422 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @version 2.0-pre
+ */
+public final class WindowTwoRecord extends StandardRecord {
+    public final static short sid = 0x023E;
+
+    // bitfields
+    private static final BitField displayFormulas         = BitFieldFactory.getInstance(0x01);
+    private static final BitField displayGridlines        = BitFieldFactory.getInstance(0x02);
+    private static final BitField displayRowColHeadings   = BitFieldFactory.getInstance(0x04);
+    private static final BitField freezePanes             = BitFieldFactory.getInstance(0x08);
+    private static final BitField displayZeros            = BitFieldFactory.getInstance(0x10);
+    /**  if false use color in field 4 if true use default foreground for headers */
+    private static final BitField defaultHeader           = BitFieldFactory.getInstance(0x20);   
+    private static final BitField arabic                  = BitFieldFactory.getInstance(0x040);
+    private static final BitField displayGuts             = BitFieldFactory.getInstance(0x080);
+    private static final BitField freezePanesNoSplit      = BitFieldFactory.getInstance(0x100);
+    private static final BitField selected                = BitFieldFactory.getInstance(0x200);
+    private static final BitField active                  = BitFieldFactory.getInstance(0x400);
+    private static final BitField savedInPageBreakPreview = BitFieldFactory.getInstance(0x800);
+    // 4-7 reserved
+    // end bitfields
+
+    private short             field_1_options;
+    private short             field_2_top_row;
+    private short             field_3_left_col;
+    private int               field_4_header_color;
+    private short             field_5_page_break_zoom;
+    private short             field_6_normal_zoom;
+    private int               field_7_reserved;
+
+    public WindowTwoRecord()
+    {
+    }
+
+    public WindowTwoRecord(RecordInputStream in) // NO_UCD
+    {
+      int size = in.remaining();
+        field_1_options      = in.readShort();
+        field_2_top_row      = in.readShort();
+        field_3_left_col     = in.readShort();
+        field_4_header_color = in.readInt();
+        if (size > 10)
+        {
+            field_5_page_break_zoom = in.readShort();
+            field_6_normal_zoom     = in.readShort();
+        }
+        if (size > 14)
+        {   // there is a special case of this record that has only 14 bytes...undocumented!
+            field_7_reserved = in.readInt();
+        }
+    }
+
+    /**
+     * set the options bitmask or just use the bit setters.
+     * @param options
+     */
+
+    public void setOptions(short options)
+    {
+        field_1_options = options;
+    }
+
+    // option bitfields
+
+    // end of bitfields.
+
+    /**
+     * set the top row visible in the window
+     * @param topRow  top row visible
+     */
+
+    public void setTopRow(short topRow)
+    {
+        field_2_top_row = topRow;
+    }
+
+    /**
+     * set the leftmost column displayed in the window
+     * @param leftCol  leftmost column
+     */
+
+    public void setLeftCol(short leftCol)
+    {
+        field_3_left_col = leftCol;
+    }
+
+    /**
+     * set the palette index for the header color
+     * @param color
+     */
+
+    public void setHeaderColor(int color)
+    {
+        field_4_header_color = color;
+    }
+
+    /**
+     * zoom magification in page break view
+     * @param zoom
+     */
+
+    public void setPageBreakZoom(short zoom)
+    {
+        field_5_page_break_zoom = zoom;
+    }
+
+    /**
+     * set the zoom magnification in normal view
+     * @param zoom
+     */
+
+    public void setNormalZoom(short zoom)
+    {
+        field_6_normal_zoom = zoom;
+    }
+
+
+    /**
+     * get the options bitmask or just use the bit setters.
+     * @return options
+     */
+
+    public short getOptions()
+    {
+        return field_1_options;
+    }
+
+    // option bitfields
+
+    /**
+     * get whether the window should display formulas
+     * @return formulas or not
+     */
+
+    public boolean getDisplayFormulas()
+    {
+        return displayFormulas.isSet(field_1_options);
+    }
+
+    /**
+     * get whether the window should display gridlines
+     * @return gridlines or not
+     */
+
+    public boolean getDisplayGridlines()
+    {
+        return displayGridlines.isSet(field_1_options);
+    }
+
+    /**
+     * get whether the window should display row and column headings
+     * @return headings or not
+     */
+
+    public boolean getDisplayRowColHeadings()
+    {
+        return displayRowColHeadings.isSet(field_1_options);
+    }
+
+    /**
+     * get whether the window should freeze panes
+     * @return freeze panes or not
+     */
+
+    public boolean getFreezePanes()
+    {
+        return freezePanes.isSet(field_1_options);
+    }
+
+    /**
+     * get whether the window should display zero values
+     * @return zeros or not
+     */
+
+    public boolean getDisplayZeros()
+    {
+        return displayZeros.isSet(field_1_options);
+    }
+
+    /**
+     * get whether the window should display a default header
+     * @return header or not
+     */
+
+    public boolean getDefaultHeader()
+    {
+        return defaultHeader.isSet(field_1_options);
+    }
+
+    /**
+     * is this arabic?
+     * @return arabic or not
+     */
+
+    public boolean getArabic()
+    {
+        return arabic.isSet(field_1_options);
+    }
+
+    /**
+     * get whether the outline symbols are displaed
+     * @return symbols or not
+     */
+
+    public boolean getDisplayGuts()
+    {
+        return displayGuts.isSet(field_1_options);
+    }
+
+    /**
+     * freeze unsplit panes or not
+     * @return freeze or not
+     */
+
+    public boolean getFreezePanesNoSplit()
+    {
+        return freezePanesNoSplit.isSet(field_1_options);
+    }
+
+    /**
+     * sheet tab is selected
+     * @return selected or not
+     */
+
+    public boolean getSelected()
+    {
+        return selected.isSet(field_1_options);
+    }
+
+    /**
+     * is the sheet currently displayed in the window
+     * @return displayed or not
+     */
+
+    public boolean isActive() {
+        return active.isSet(field_1_options);
+    }
+
+
+    /**
+     * was the sheet saved in page break view
+     * @return pagebreaksaved or not
+     */
+
+    public boolean getSavedInPageBreakPreview()
+    {
+        return savedInPageBreakPreview.isSet(field_1_options);
+    }
+
+    // end of bitfields.
+
+    /**
+     * get the top row visible in the window
+     * @return toprow
+     */
+
+    public short getTopRow()
+    {
+        return field_2_top_row;
+    }
+
+    /**
+     * get the leftmost column displayed in the window
+     * @return leftmost
+     */
+
+    public short getLeftCol()
+    {
+        return field_3_left_col;
+    }
+
+    /**
+     * get the palette index for the header color
+     * @return color
+     */
+
+    public int getHeaderColor()
+    {
+        return field_4_header_color;
+    }
+
+    /**
+     * zoom magification in page break view
+     * @return zoom
+     */
+
+    public short getPageBreakZoom()
+    {
+        return field_5_page_break_zoom;
+    }
+
+    /**
+     * get the zoom magnification in normal view
+     * @return zoom
+     */
+
+    public short getNormalZoom()
+    {
+        return field_6_normal_zoom;
+    }
+
+    /**
+     * get the reserved bits - why would you do this?
+     * @return reserved stuff -probably garbage
+     */
+
+    public int getReserved()
+    {
+        return field_7_reserved;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[WINDOW2]\n");
+        buffer.append("    .options        = ")
+            .append(Integer.toHexString(getOptions())).append("\n");
+        buffer.append("       .dispformulas= ").append(getDisplayFormulas())
+            .append("\n");
+        buffer.append("       .dispgridlins= ").append(getDisplayGridlines())
+            .append("\n");
+        buffer.append("       .disprcheadin= ")
+            .append(getDisplayRowColHeadings()).append("\n");
+        buffer.append("       .freezepanes = ").append(getFreezePanes())
+            .append("\n");
+        buffer.append("       .displayzeros= ").append(getDisplayZeros())
+            .append("\n");
+        buffer.append("       .defaultheadr= ").append(getDefaultHeader())
+            .append("\n");
+        buffer.append("       .arabic      = ").append(getArabic())
+            .append("\n");
+        buffer.append("       .displayguts = ").append(getDisplayGuts())
+            .append("\n");
+        buffer.append("       .frzpnsnosplt= ")
+            .append(getFreezePanesNoSplit()).append("\n");
+        buffer.append("       .selected    = ").append(getSelected())
+            .append("\n");
+        buffer.append("       .active       = ").append(isActive())
+            .append("\n");
+        buffer.append("       .svdinpgbrkpv= ")
+            .append(getSavedInPageBreakPreview()).append("\n");
+        buffer.append("    .toprow         = ")
+            .append(Integer.toHexString(getTopRow())).append("\n");
+        buffer.append("    .leftcol        = ")
+            .append(Integer.toHexString(getLeftCol())).append("\n");
+        buffer.append("    .headercolor    = ")
+            .append(Integer.toHexString(getHeaderColor())).append("\n");
+        buffer.append("    .pagebreakzoom  = ")
+            .append(Integer.toHexString(getPageBreakZoom())).append("\n");
+        buffer.append("    .normalzoom     = ")
+            .append(Integer.toHexString(getNormalZoom())).append("\n");
+        buffer.append("    .reserved       = ")
+            .append(Integer.toHexString(getReserved())).append("\n");
+        buffer.append("[/WINDOW2]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(getOptions());
+        out.writeShort(getTopRow());
+        out.writeShort(getLeftCol());
+        out.writeInt(getHeaderColor());
+        out.writeShort(getPageBreakZoom());
+        out.writeShort(getNormalZoom());
+        out.writeInt(getReserved());
+    }
+
+    protected int getDataSize() {
+        return 18;
+    }
+
+    public short getSid()
+    {
+        return sid;
+    }
+
+    public Object clone() {
+      WindowTwoRecord rec = new WindowTwoRecord();
+      rec.field_1_options = field_1_options;
+      rec.field_2_top_row = field_2_top_row;
+      rec.field_3_left_col = field_3_left_col;
+      rec.field_4_header_color = field_4_header_color;
+      rec.field_5_page_break_zoom = field_5_page_break_zoom;
+      rec.field_6_normal_zoom = field_6_normal_zoom;
+      rec.field_7_reserved = field_7_reserved;
+      return rec;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java	(revision 28000)
@@ -0,0 +1,128 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.aggregates;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.poi.hssf.model.RecordStream;
+import org.apache.poi.hssf.record.ColumnInfoRecord;
+
+/**
+ * @author Glen Stampoultzis
+ */
+public final class ColumnInfoRecordsAggregate extends RecordAggregate {
+	/**
+	 * List of {@link ColumnInfoRecord}s assumed to be in order
+	 */
+	private final List<ColumnInfoRecord> records;
+
+
+	private static final class CIRComparator implements Comparator<ColumnInfoRecord> {
+		public static final Comparator<ColumnInfoRecord> instance = new CIRComparator();
+		private CIRComparator() {
+			// enforce singleton
+		}
+		public int compare(ColumnInfoRecord a, ColumnInfoRecord b) {
+			return compareColInfos(a, b);
+		}
+		public static int compareColInfos(ColumnInfoRecord a, ColumnInfoRecord b) {
+			return a.getFirstColumn()-b.getFirstColumn();
+		}
+	}
+
+	/**
+	 * Creates an empty aggregate
+	 */
+	public ColumnInfoRecordsAggregate() {
+		records = new ArrayList<ColumnInfoRecord>();
+	}
+	public ColumnInfoRecordsAggregate(RecordStream rs) {
+		this();
+
+		boolean isInOrder = true;
+		ColumnInfoRecord cirPrev = null;
+		while(rs.peekNextClass() == ColumnInfoRecord.class) {
+			ColumnInfoRecord cir = (ColumnInfoRecord) rs.getNext();
+			records.add(cir);
+			if (cirPrev != null && CIRComparator.compareColInfos(cirPrev, cir) > 0) {
+				isInOrder = false;
+			}
+			cirPrev = cir;
+		}
+		if (records.size() < 1) {
+			throw new RuntimeException("No column info records found");
+		}
+		if (!isInOrder) {
+			Collections.sort(records, CIRComparator.instance);
+		}
+	}
+
+	/**
+	 * Performs a deep clone of the record
+	 */
+	public Object clone() {
+		ColumnInfoRecordsAggregate rec = new ColumnInfoRecordsAggregate();
+		for (int k = 0; k < records.size(); k++) {
+			ColumnInfoRecord ci = records.get(k);
+			rec.records.add((ColumnInfoRecord) ci.clone());
+		}
+		return rec;
+	}
+
+	public void visitContainedRecords(RecordVisitor rv) {
+		int nItems = records.size();
+		if (nItems < 1) {
+			return;
+		}
+		ColumnInfoRecord cirPrev = null;
+		for(int i=0; i<nItems; i++) {
+			ColumnInfoRecord cir = records.get(i);
+			rv.visitRecord(cir);
+			if (cirPrev != null && CIRComparator.compareColInfos(cirPrev, cir) > 0) {
+				// Excel probably wouldn't mind, but there is much logic in this class
+				// that assumes the column info records are kept in order
+				throw new RuntimeException("Column info records are out of order");
+			}
+			cirPrev = cir;
+		}
+	}
+
+	private ColumnInfoRecord getColInfo(int idx) {
+		return records.get( idx );
+	}
+
+	/**
+	 * Finds the <tt>ColumnInfoRecord</tt> which contains the specified columnIndex
+	 * @param columnIndex index of the column (not the index of the ColumnInfoRecord)
+	 * @return <code>null</code> if no column info found for the specified column
+	 */
+	public ColumnInfoRecord findColumnInfo(int columnIndex) {
+		int nInfos = records.size();
+		for(int i=0; i< nInfos; i++) {
+			ColumnInfoRecord ci = getColInfo(i);
+			if (ci.containsColumn(columnIndex)) {
+				return ci;
+			}
+		}
+		return null;
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/DataValidityTable.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/DataValidityTable.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/DataValidityTable.java	(revision 28000)
@@ -0,0 +1,66 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.aggregates;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hssf.model.RecordStream;
+import org.apache.poi.hssf.record.DVALRecord;
+import org.apache.poi.hssf.record.DVRecord;
+import org.apache.poi.hssf.record.Record;
+
+/**
+ * Manages the DVALRecord and DVRecords for a single sheet<br/>
+ * See OOO excelfileformat.pdf section 4.14
+ * @author Josh Micich
+ */
+public final class DataValidityTable extends RecordAggregate {
+
+	private final DVALRecord _headerRec;
+	/**
+	 * The list of data validations for the current sheet.
+	 * Note - this may be empty (contrary to OOO documentation)
+	 */
+	private final List<Record> _validationList;
+
+	public DataValidityTable(RecordStream rs) {
+		_headerRec = (DVALRecord) rs.getNext();
+		List<Record> temp = new ArrayList<Record>();
+		while (rs.peekNextClass() == DVRecord.class) {
+			temp.add(rs.getNext());
+		}
+		_validationList = temp;
+	}
+
+	public DataValidityTable() {
+		_headerRec = new DVALRecord();
+		_validationList = new ArrayList<Record>();
+	}
+
+	public void visitContainedRecords(RecordVisitor rv) {
+		if (_validationList.isEmpty()) {
+			return;
+		}
+		rv.visitRecord(_headerRec);
+		for (int i = 0; i < _validationList.size(); i++) {
+			rv.visitRecord(_validationList.get(i));
+		}
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java	(revision 28000)
@@ -0,0 +1,222 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.aggregates;
+
+import org.apache.poi.hssf.record.ArrayRecord;
+import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.FormulaRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordFormatException;
+import org.apache.poi.hssf.record.SharedFormulaRecord;
+import org.apache.poi.hssf.record.StringRecord;
+import org.apache.poi.hssf.record.formula.ExpPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.util.CellRangeAddress8Bit;
+import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+/**
+ * The formula record aggregate is used to join together the formula record and it's
+ * (optional) string record and (optional) Shared Formula Record (template reads, excel optimization).
+ *
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @author Vladimirs Abramovs(Vladimirs.Abramovs at exigenservices.com) - Array Formula support
+ */
+public final class FormulaRecordAggregate extends RecordAggregate implements CellValueRecordInterface {
+
+	private final FormulaRecord _formulaRecord;
+	private SharedValueManager _sharedValueManager;
+	/** caches the calculated result of the formula */
+	private StringRecord _stringRecord;
+	private SharedFormulaRecord _sharedFormulaRecord;
+
+	/**
+	 * @param stringRec may be <code>null</code> if this formula does not have a cached text
+	 * value.
+	 * @param svm the {@link SharedValueManager} for the current sheet
+	 */
+	public FormulaRecordAggregate(FormulaRecord formulaRec, StringRecord stringRec, SharedValueManager svm) {
+		if (svm == null) {
+			throw new IllegalArgumentException("sfm must not be null");
+		}
+		if (formulaRec.hasCachedResultString()) {
+			if (stringRec == null) {
+				throw new RecordFormatException("Formula record flag is set but String record was not found");
+			}
+			_stringRecord = stringRec;
+		} else {
+			// Usually stringRec is null here (in agreement with what the formula rec says).
+			// In the case where an extra StringRecord is erroneously present, Excel (2007)
+			// ignores it (see bug 46213).
+			_stringRecord = null;
+		}
+
+		_formulaRecord = formulaRec;
+		_sharedValueManager = svm;
+		if (formulaRec.isSharedFormula()) {
+			CellReference firstCell = formulaRec.getFormula().getExpReference();
+			if (firstCell == null) {
+				handleMissingSharedFormulaRecord(formulaRec);
+			} else {
+				_sharedFormulaRecord = svm.linkSharedFormulaRecord(firstCell, this);
+			}
+		}
+	}
+	/**
+	 * Sometimes the shared formula flag "seems" to be erroneously set (because the corresponding
+	 * {@link SharedFormulaRecord} does not exist). Normally this would leave no way of determining
+	 * the {@link Ptg} tokens for the formula.  However as it turns out in these
+	 * cases, Excel encodes the unshared {@link Ptg} tokens in the right place (inside the {@link
+	 * FormulaRecord}).  So the the only thing that needs to be done is to ignore the erroneous
+	 * shared formula flag.<br/>
+	 *
+	 * This method may also be used for setting breakpoints to help diagnose issues regarding the
+	 * abnormally-set 'shared formula' flags.
+	 * (see TestValueRecordsAggregate.testSpuriousSharedFormulaFlag()).<p/>
+	 */
+	private static void handleMissingSharedFormulaRecord(FormulaRecord formula) {
+		// make sure 'unshared' formula is actually available
+		Ptg firstToken = formula.getParsedExpression()[0];
+		if (firstToken instanceof ExpPtg) {
+			throw new RecordFormatException(
+					"SharedFormulaRecord not found for FormulaRecord with (isSharedFormula=true)");
+		}
+		// could log an info message here since this is a fairly unusual occurrence.
+		formula.setSharedFormula(false); // no point leaving the flag erroneously set
+	}
+
+	public FormulaRecord getFormulaRecord() {
+		return _formulaRecord;
+	}
+
+	public short getXFIndex() {
+		return _formulaRecord.getXFIndex();
+	}
+
+	public void setXFIndex(short xf) {
+		_formulaRecord.setXFIndex(xf);
+	}
+
+	public void setColumn(short col) {
+		_formulaRecord.setColumn(col);
+	}
+
+	public void setRow(int row) {
+		_formulaRecord.setRow(row);
+	}
+
+	public short getColumn() {
+		return _formulaRecord.getColumn();
+	}
+
+	public int getRow() {
+		return _formulaRecord.getRow();
+	}
+
+	public String toString() {
+		return _formulaRecord.toString();
+	}
+
+	public void visitContainedRecords(RecordVisitor rv) {
+		 rv.visitRecord(_formulaRecord);
+		 Record sharedFormulaRecord = _sharedValueManager.getRecordForFirstCell(this);
+		 if (sharedFormulaRecord != null) {
+			 rv.visitRecord(sharedFormulaRecord);
+		 }
+		 if (_formulaRecord.hasCachedResultString() && _stringRecord != null) {
+			 rv.visitRecord(_stringRecord);
+		 }
+	}
+
+	public String getStringValue() {
+		if(_stringRecord==null) {
+			return null;
+		}
+		return _stringRecord.getString();
+	}
+
+	public Ptg[] getFormulaTokens() {
+		if (_sharedFormulaRecord != null) {
+			return _sharedFormulaRecord.getFormulaTokens(_formulaRecord);
+		}
+		CellReference expRef = _formulaRecord.getFormula().getExpReference();
+		if (expRef != null) {
+			ArrayRecord arec = _sharedValueManager.getArrayRecord(expRef.getRow(), expRef.getCol());
+			return arec.getFormulaTokens();
+		}
+		return _formulaRecord.getParsedExpression();
+	}
+
+
+	public void unlinkSharedFormula() {
+		SharedFormulaRecord sfr = _sharedFormulaRecord;
+		if (sfr == null) {
+			throw new IllegalStateException("Formula not linked to shared formula");
+		}
+		Ptg[] ptgs = sfr.getFormulaTokens(_formulaRecord);
+		_formulaRecord.setParsedExpression(ptgs);
+		//Now its not shared!
+		_formulaRecord.setSharedFormula(false);
+		_sharedFormulaRecord = null;
+	}
+	/**
+	 * Should be called by any code which is either deleting this formula cell, or changing
+	 * its type.  This method gives the aggregate a chance to unlink any shared formula
+	 * that may be involved with this cell formula.
+	 */
+	public void notifyFormulaChanging() {
+		if (_sharedFormulaRecord != null) {
+			_sharedValueManager.unlink(_sharedFormulaRecord);
+		}
+	}
+	public boolean isPartOfArrayFormula() {
+		if (_sharedFormulaRecord != null) {
+			return false;
+		}
+        CellReference expRef = _formulaRecord.getFormula().getExpReference();
+        ArrayRecord arec = expRef == null ? null : _sharedValueManager.getArrayRecord(expRef.getRow(), expRef.getCol());
+		return arec != null;
+	}
+
+	public CellRangeAddress getArrayFormulaRange() {
+		if (_sharedFormulaRecord != null) {
+			throw new IllegalStateException("not an array formula cell.");
+		}
+		CellReference expRef = _formulaRecord.getFormula().getExpReference();
+		if (expRef == null) {
+			throw new IllegalStateException("not an array formula cell.");
+		}
+		ArrayRecord arec = _sharedValueManager.getArrayRecord(expRef.getRow(), expRef.getCol());
+		if (arec == null) {
+			throw new IllegalStateException("ArrayRecord was not found for the locator " + expRef.formatAsString());
+		}
+		CellRangeAddress8Bit a = arec.getRange();
+		return new CellRangeAddress(a.getFirstRow(), a.getLastRow(), a.getFirstColumn(),a.getLastColumn());
+	}
+
+	/**
+	 * Removes an array formula
+	 * @return the range of the array formula containing the specified cell. Never <code>null</code>
+	 */
+	public CellRangeAddress removeArrayFormula(int rowIndex, int columnIndex) {
+		CellRangeAddress8Bit a = _sharedValueManager.removeArrayFormula(rowIndex, columnIndex);
+        // at this point FormulaRecordAggregate#isPartOfArrayFormula() should return false
+        _formulaRecord.setParsedExpression(null);
+        return new CellRangeAddress(a.getFirstRow(), a.getLastRow(), a.getFirstColumn(), a.getLastColumn());
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/MergedCellsTable.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/MergedCellsTable.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/MergedCellsTable.java	(revision 28000)
@@ -0,0 +1,110 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.aggregates;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hssf.model.RecordStream;
+import org.apache.poi.hssf.record.MergeCellsRecord;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+
+/**
+ * 
+ * @author Josh Micich
+ */
+public final class MergedCellsTable extends RecordAggregate {
+	private static int MAX_MERGED_REGIONS = 1027; // enforced by the 8224 byte limit
+
+	private final List<CellRangeAddress> _mergedRegions;
+
+	/**
+	 * Creates an empty aggregate
+	 */
+	public MergedCellsTable() {
+		_mergedRegions = new ArrayList<CellRangeAddress>();
+	}
+
+	/**
+	 * reads zero or more consecutive {@link MergeCellsRecord}s
+	 * @param rs
+	 */
+	public void read(RecordStream rs) {
+		List<CellRangeAddress> temp = _mergedRegions;
+		while (rs.peekNextClass() == MergeCellsRecord.class) {
+			MergeCellsRecord mcr = (MergeCellsRecord) rs.getNext();
+			int nRegions = mcr.getNumAreas();
+			for (int i = 0; i < nRegions; i++) {
+				CellRangeAddress cra = mcr.getAreaAt(i);
+				temp.add(cra);
+			}
+		}
+	}
+
+	public int getRecordSize() {
+		// a bit cheaper than the default impl
+		int nRegions = _mergedRegions.size();
+		if (nRegions < 1) {
+			// no need to write a single empty MergeCellsRecord
+			return 0;
+		}
+		int nMergedCellsRecords = nRegions / MAX_MERGED_REGIONS;
+		int nLeftoverMergedRegions = nRegions % MAX_MERGED_REGIONS;
+
+		int result = nMergedCellsRecords
+				* (4 + CellRangeAddressList.getEncodedSize(MAX_MERGED_REGIONS)) + 4
+				+ CellRangeAddressList.getEncodedSize(nLeftoverMergedRegions);
+		return result;
+	}
+
+	public void visitContainedRecords(RecordVisitor rv) {
+		int nRegions = _mergedRegions.size();
+		if (nRegions < 1) {
+			// no need to write a single empty MergeCellsRecord
+			return;
+		}
+
+		int nFullMergedCellsRecords = nRegions / MAX_MERGED_REGIONS;
+		int nLeftoverMergedRegions = nRegions % MAX_MERGED_REGIONS;
+		CellRangeAddress[] cras = new CellRangeAddress[nRegions];
+		_mergedRegions.toArray(cras);
+
+		for (int i = 0; i < nFullMergedCellsRecords; i++) {
+			int startIx = i * MAX_MERGED_REGIONS;
+			rv.visitRecord(new MergeCellsRecord(cras, startIx, MAX_MERGED_REGIONS));
+		}
+		if (nLeftoverMergedRegions > 0) {
+			int startIx = nFullMergedCellsRecords * MAX_MERGED_REGIONS;
+			rv.visitRecord(new MergeCellsRecord(cras, startIx, nLeftoverMergedRegions));
+		}
+	}
+	public void addRecords(MergeCellsRecord[] mcrs) {
+		for (int i = 0; i < mcrs.length; i++) {
+			addMergeCellsRecord(mcrs[i]);
+		}
+	}
+
+	private void addMergeCellsRecord(MergeCellsRecord mcr) {
+		int nRegions = mcr.getNumAreas();
+		for (int i = 0; i < nRegions; i++) {
+			CellRangeAddress cra = mcr.getAreaAt(i);
+			_mergedRegions.add(cra);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java	(revision 28000)
@@ -0,0 +1,49 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.aggregates;
+
+import org.apache.poi.hssf.record.HorizontalPageBreakRecord;
+import org.apache.poi.hssf.record.UnknownRecord;
+import org.apache.poi.hssf.record.VerticalPageBreakRecord;
+
+/**
+ * Groups the page settings records for a worksheet.<p/>
+ *
+ * See OOO excelfileformat.pdf sec 4.4 'Page Settings Block'
+ *
+ * @author Josh Micich
+ */
+public final class PageSettingsBlock {
+
+	/**
+	 * @return <code>true</code> if the specified Record sid is one belonging to the
+	 * 'Page Settings Block'.
+	 */
+	public static boolean isComponentRecord(int sid) {
+		switch (sid) {
+			case HorizontalPageBreakRecord.sid:
+			case VerticalPageBreakRecord.sid:
+			case UnknownRecord.PLS_004D:
+			case UnknownRecord.BITMAP_00E9:
+			case UnknownRecord.PRINTSIZE_0033:
+				return true;
+		}
+		return false;
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/RecordAggregate.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/RecordAggregate.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/RecordAggregate.java	(revision 28000)
@@ -0,0 +1,115 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.aggregates;
+
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordBase;
+
+/**
+ * <tt>RecordAggregate</tt>s are groups of of BIFF <tt>Record</tt>s that are typically stored
+ * together and/or updated together.  Workbook / Sheet records are typically stored in a sequential
+ * list, which does not provide much structure to coordinate updates.
+ *
+ * @author Josh Micich
+ */
+public abstract class RecordAggregate extends RecordBase {
+
+	/**
+	 * Visit each of the atomic BIFF records contained in this {@link RecordAggregate} in the order
+	 * that they should be written to file.  Implementors may or may not return the actual
+	 * {@link Record}s being used to manage POI's internal implementation.  Callers should not
+	 * assume either way, and therefore only attempt to modify those {@link Record}s after cloning
+	 */
+	public abstract void visitContainedRecords(RecordVisitor rv);
+
+	public final int serialize(int offset, byte[] data) {
+		SerializingRecordVisitor srv = new SerializingRecordVisitor(data, offset);
+		visitContainedRecords(srv);
+		return srv.countBytesWritten();
+	}
+	public int getRecordSize() {
+		RecordSizingVisitor rsv = new RecordSizingVisitor();
+		visitContainedRecords(rsv);
+		return rsv.getTotalSize();
+	}
+
+	public interface RecordVisitor {
+		/**
+		 * Implementors may call non-mutating methods on Record r.
+		 * @param r must not be <code>null</code>
+		 */
+		void visitRecord(Record r);
+	}
+
+	private static final class SerializingRecordVisitor implements RecordVisitor {
+
+		private final byte[] _data;
+		private final int _startOffset;
+		private int _countBytesWritten;
+
+		public SerializingRecordVisitor(byte[] data, int startOffset) {
+			_data = data;
+			_startOffset = startOffset;
+			_countBytesWritten = 0;
+		}
+		public int countBytesWritten() {
+			return _countBytesWritten;
+		}
+		public void visitRecord(Record r) {
+			int currentOffset = _startOffset + _countBytesWritten;
+			_countBytesWritten += r.serialize(currentOffset, _data);
+		}
+	}
+	private static final class RecordSizingVisitor implements RecordVisitor {
+
+		private int _totalSize;
+
+		public RecordSizingVisitor() {
+			_totalSize = 0;
+		}
+		public int getTotalSize() {
+			return _totalSize;
+		}
+		public void visitRecord(Record r) {
+			_totalSize += r.getRecordSize();
+		}
+	}
+	/**
+	 * A wrapper for {@link RecordVisitor} which accumulates the sizes of all
+	 * records visited.
+	 */
+	public static final class PositionTrackingVisitor implements RecordVisitor {
+		private final RecordVisitor _rv;
+		private int _position;
+
+		public PositionTrackingVisitor(RecordVisitor rv, int initialPosition) {
+			_rv = rv;
+			_position = initialPosition;
+		}
+		public void visitRecord(Record r) {
+			_position += r.getRecordSize();
+			_rv.visitRecord(r);
+		}
+		public void setPosition(int position) {
+			_position = position;
+		}
+		public int getPosition() {
+			return _position;
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java	(revision 28000)
@@ -0,0 +1,292 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.aggregates;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.poi.hssf.model.RecordStream;
+import org.apache.poi.hssf.record.ArrayRecord;
+import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.ContinueRecord;
+import org.apache.poi.hssf.record.DBCellRecord;
+import org.apache.poi.hssf.record.DimensionsRecord;
+import org.apache.poi.hssf.record.FormulaRecord;
+import org.apache.poi.hssf.record.MergeCellsRecord;
+import org.apache.poi.hssf.record.MulBlankRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RowRecord;
+import org.apache.poi.hssf.record.SharedFormulaRecord;
+import org.apache.poi.hssf.record.TableRecord;
+import org.apache.poi.hssf.record.UnknownRecord;
+import org.apache.poi.ss.SpreadsheetVersion;
+
+/**
+ *
+ * @author  andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class RowRecordsAggregate extends RecordAggregate {
+	private int _firstrow = -1;
+	private int _lastrow  = -1;
+	private final Map<Integer, RowRecord> _rowRecords;
+	private final ValueRecordsAggregate _valuesAgg;
+	private final List<Record> _unknownRecords;
+	private final SharedValueManager _sharedValueManager;
+
+	/** Creates a new instance of ValueRecordsAggregate */
+	public RowRecordsAggregate() {
+		this(SharedValueManager.createEmpty());
+	}
+	private RowRecordsAggregate(SharedValueManager svm) {
+		if (svm == null) {
+			throw new IllegalArgumentException("SharedValueManager must be provided.");
+		}
+		_rowRecords = new TreeMap<Integer, RowRecord>();
+		_valuesAgg = new ValueRecordsAggregate();
+		_unknownRecords = new ArrayList<Record>();
+		_sharedValueManager = svm;
+	}
+
+	/**
+	 * @param rs record stream with all {@link SharedFormulaRecord}
+	 * {@link ArrayRecord}, {@link TableRecord} {@link MergeCellsRecord} Records removed
+	 * @param svm an initialised {@link SharedValueManager} (from the shared formula, array
+	 * and table records of the current sheet).  Never <code>null</code>.
+	 */
+	public RowRecordsAggregate(RecordStream rs, SharedValueManager svm) {
+		this(svm);
+		while(rs.hasNext()) {
+			Record rec = rs.getNext();
+			switch (rec.getSid()) {
+				case RowRecord.sid:
+					insertRow((RowRecord) rec);
+					continue;
+				case DBCellRecord.sid:
+					// end of 'Row Block'.  Should only occur after cell records
+					// ignore DBCELL records because POI generates them upon re-serialization
+					continue;
+			}
+			if (rec instanceof UnknownRecord) {
+				// might need to keep track of where exactly these belong
+				addUnknownRecord(rec);
+				while (rs.peekNextSid() == ContinueRecord.sid) {
+					addUnknownRecord(rs.getNext());
+				}
+				continue;
+			}
+			if (rec instanceof MulBlankRecord) {
+				_valuesAgg.addMultipleBlanks((MulBlankRecord) rec);
+				continue;
+			}
+			if (!(rec instanceof CellValueRecordInterface)) {
+				throw new RuntimeException("Unexpected record type (" + rec.getClass().getName() + ")");
+			}
+			_valuesAgg.construct((CellValueRecordInterface)rec, rs, svm);
+		}
+	}
+	/**
+	 * Handles UnknownRecords which appear within the row/cell records
+	 */
+	private void addUnknownRecord(Record rec) {
+		// ony a few distinct record IDs are encountered by the existing POI test cases:
+		// 0x1065 // many
+		// 0x01C2 // several
+		// 0x0034 // few
+		// No documentation could be found for these
+
+		// keep the unknown records for re-serialization
+		_unknownRecords.add(rec);
+	}
+	public void insertRow(RowRecord row) {
+		// Integer integer = Integer.valueOf(row.getRowNumber());
+		_rowRecords.put(Integer.valueOf(row.getRowNumber()), row);
+		if ((row.getRowNumber() < _firstrow) || (_firstrow == -1)) {
+			_firstrow = row.getRowNumber();
+		}
+		if ((row.getRowNumber() > _lastrow) || (_lastrow == -1)) {
+			_lastrow = row.getRowNumber();
+		}
+	}
+
+	public void removeRow(RowRecord row) {
+		int rowIndex = row.getRowNumber();
+		_valuesAgg.removeAllCellsValuesForRow(rowIndex);
+		Integer key = Integer.valueOf(rowIndex);
+		RowRecord rr = _rowRecords.remove(key);
+		if (rr == null) {
+			throw new RuntimeException("Invalid row index (" + key.intValue() + ")");
+		}
+		if (row != rr) {
+			_rowRecords.put(key, rr);
+			throw new RuntimeException("Attempt to remove row that does not belong to this sheet");
+		}
+	}
+
+	public RowRecord getRow(int rowIndex) {
+        int maxrow = SpreadsheetVersion.EXCEL97.getLastRowIndex();
+        if (rowIndex < 0 || rowIndex > maxrow) {
+			throw new IllegalArgumentException("The row number must be between 0 and " + maxrow);
+		}
+		return _rowRecords.get(Integer.valueOf(rowIndex));
+	}
+
+	/** Returns the number of row blocks.
+	 * <p/>The row blocks are goupings of rows that contain the DBCell record
+	 * after them
+	 */
+	public int getRowBlockCount() {
+	  int size = _rowRecords.size()/DBCellRecord.BLOCK_SIZE;
+	  if ((_rowRecords.size() % DBCellRecord.BLOCK_SIZE) != 0)
+		  size++;
+	  return size;
+	}
+
+	/** Returns the physical row number of the first row in a block*/
+	private int getStartRowNumberForBlock(int block) {
+	  //Given that we basically iterate through the rows in order,
+	  // TODO - For a performance improvement, it would be better to return an instance of
+	  //an iterator and use that instance throughout, rather than recreating one and
+	  //having to move it to the right position.
+	  int startIndex = block * DBCellRecord.BLOCK_SIZE;
+	  Iterator<RowRecord> rowIter = _rowRecords.values().iterator();
+	  RowRecord row = null;
+	  //Position the iterator at the start of the block
+	  for (int i=0; i<=startIndex;i++) {
+		row = rowIter.next();
+	  }
+	  if (row == null) {
+		  throw new RuntimeException("Did not find start row for block " + block);
+	  }
+
+	  return row.getRowNumber();
+	}
+
+	/** Returns the physical row number of the end row in a block*/
+	private int getEndRowNumberForBlock(int block) {
+	  int endIndex = ((block + 1)*DBCellRecord.BLOCK_SIZE)-1;
+	  if (endIndex >= _rowRecords.size())
+		endIndex = _rowRecords.size()-1;
+
+	  Iterator<RowRecord> rowIter = _rowRecords.values().iterator();
+	  RowRecord row = null;
+	  for (int i=0; i<=endIndex;i++) {
+		row = rowIter.next();
+	  }
+	  if (row == null) {
+		  throw new RuntimeException("Did not find start row for block " + block);
+	  }
+	  return row.getRowNumber();
+	}
+
+	private int visitRowRecordsForBlock(int blockIndex, RecordVisitor rv) {
+		final int startIndex = blockIndex*DBCellRecord.BLOCK_SIZE;
+		final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE;
+
+		Iterator<RowRecord> rowIterator = _rowRecords.values().iterator();
+
+		//Given that we basically iterate through the rows in order,
+		//For a performance improvement, it would be better to return an instance of
+		//an iterator and use that instance throughout, rather than recreating one and
+		//having to move it to the right position.
+		int i=0;
+		for (;i<startIndex;i++)
+		  rowIterator.next();
+		int result = 0;
+		while(rowIterator.hasNext() && (i++ < endIndex)) {
+		  Record rec = rowIterator.next();
+		  result += rec.getRecordSize();
+		  rv.visitRecord(rec);
+		}
+		return result;
+	}
+
+	public void visitContainedRecords(RecordVisitor rv) {
+
+		PositionTrackingVisitor stv = new PositionTrackingVisitor(rv, 0);
+		//DBCells are serialized before row records.
+		final int blockCount = getRowBlockCount();
+		for (int blockIndex = 0; blockIndex < blockCount; blockIndex++) {
+			// Serialize a block of rows.
+			// Hold onto the position of the first row in the block
+			int pos=0;
+			// Hold onto the size of this block that was serialized
+			final int rowBlockSize = visitRowRecordsForBlock(blockIndex, rv);
+			pos += rowBlockSize;
+			// Serialize a block of cells for those rows
+			final int startRowNumber = getStartRowNumberForBlock(blockIndex);
+			final int endRowNumber = getEndRowNumberForBlock(blockIndex);
+			DBCellRecord.Builder dbcrBuilder = new DBCellRecord.Builder();
+			// Note: Cell references start from the second row...
+			int cellRefOffset = (rowBlockSize - RowRecord.ENCODED_SIZE);
+			for (int row = startRowNumber; row <= endRowNumber; row++) {
+				if (_valuesAgg.rowHasCells(row)) {
+					stv.setPosition(0);
+					_valuesAgg.visitCellsForRow(row, stv);
+					int rowCellSize = stv.getPosition();
+					pos += rowCellSize;
+					// Add the offset to the first cell for the row into the
+					// DBCellRecord.
+					dbcrBuilder.addCellOffset(cellRefOffset);
+					cellRefOffset = rowCellSize;
+				}
+			}
+			// Calculate Offset from the start of a DBCellRecord to the first Row
+			rv.visitRecord(dbcrBuilder.build(pos));
+		}
+		for (int i=0; i< _unknownRecords.size(); i++) {
+			// Potentially breaking the file here since we don't know exactly where to write these records
+			rv.visitRecord(_unknownRecords.get(i));
+		}
+	}
+
+	public Iterator<RowRecord> getIterator() {
+		return _rowRecords.values().iterator();
+	}
+
+	public CellValueRecordInterface[] getValueRecords() {
+		return _valuesAgg.getValueRecords();
+	}
+
+	public void insertCell(CellValueRecordInterface cvRec) {
+		_valuesAgg.insertCell(cvRec);
+	}
+	public void removeCell(CellValueRecordInterface cvRec) {
+		if (cvRec instanceof FormulaRecordAggregate) {
+			((FormulaRecordAggregate)cvRec).notifyFormulaChanging();
+		}
+		_valuesAgg.removeCell(cvRec);
+	}
+	public FormulaRecordAggregate createFormula(int row, int col) {
+		FormulaRecord fr = new FormulaRecord();
+		fr.setRow(row);
+		fr.setColumn((short) col);
+		return new FormulaRecordAggregate(fr, null, _sharedValueManager);
+	}
+	public DimensionsRecord createDimensions() {
+		DimensionsRecord result = new DimensionsRecord();
+		result.setFirstRow(_firstrow);
+		result.setLastRow(_lastrow);
+		result.setFirstCol((short) _valuesAgg.getFirstCellNum());
+		result.setLastCol((short) _valuesAgg.getLastCellNum());
+		return result;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/SharedValueManager.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/SharedValueManager.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/SharedValueManager.java	(revision 28000)
@@ -0,0 +1,320 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.aggregates;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.poi.hssf.record.ArrayRecord;
+import org.apache.poi.hssf.record.FormulaRecord;
+import org.apache.poi.hssf.record.SharedFormulaRecord;
+import org.apache.poi.hssf.record.SharedValueRecordBase;
+import org.apache.poi.hssf.record.TableRecord;
+import org.apache.poi.hssf.record.formula.ExpPtg;
+import org.apache.poi.hssf.util.CellRangeAddress8Bit;
+import org.apache.poi.ss.util.CellReference;
+
+/**
+ * Manages various auxiliary records while constructing a
+ * {@link RowRecordsAggregate}:
+ * <ul>
+ * <li>{@link SharedFormulaRecord}s</li>
+ * <li>{@link ArrayRecord}s</li>
+ * <li>{@link TableRecord}s</li>
+ * </ul>
+ *
+ * @author Josh Micich
+ * @author Vladimirs Abramovs(Vladimirs.Abramovs at exigenservices.com) - handling of ArrayRecords
+ */
+public final class SharedValueManager {
+
+	private static final class SharedFormulaGroup {
+		private final SharedFormulaRecord _sfr;
+		private final FormulaRecordAggregate[] _frAggs;
+		private int _numberOfFormulas;
+		/**
+		 * Coordinates of the first cell having a formula that uses this shared formula.
+		 * This is often <i>but not always</i> the top left cell in the range covered by
+		 * {@link #_sfr}
+		 */
+		private final CellReference _firstCell;
+
+		public SharedFormulaGroup(SharedFormulaRecord sfr, CellReference firstCell) {
+			if (!sfr.isInRange(firstCell.getRow(), firstCell.getCol())) {
+				throw new IllegalArgumentException("First formula cell " + firstCell.formatAsString()
+						+ " is not shared formula range " + sfr.getRange().toString() + ".");
+			}
+			_sfr = sfr;
+			_firstCell = firstCell;
+			int width = sfr.getLastColumn() - sfr.getFirstColumn() + 1;
+			int height = sfr.getLastRow() - sfr.getFirstRow() + 1;
+			_frAggs = new FormulaRecordAggregate[width * height];
+			_numberOfFormulas = 0;
+		}
+
+		public void add(FormulaRecordAggregate agg) {
+			if (_numberOfFormulas == 0) {
+				if (_firstCell.getRow() != agg.getRow() || _firstCell.getCol() != agg.getColumn()) {
+					throw new IllegalStateException("shared formula coding error");
+				}
+			}
+			if (_numberOfFormulas >= _frAggs.length) {
+				throw new RuntimeException("Too many formula records for shared formula group");
+			}
+			_frAggs[_numberOfFormulas++] = agg;
+		}
+
+		public void unlinkSharedFormulas() {
+			for (int i = 0; i < _numberOfFormulas; i++) {
+				_frAggs[i].unlinkSharedFormula();
+			}
+		}
+
+		public SharedFormulaRecord getSFR() {
+			return _sfr;
+		}
+
+		public final String toString() {
+			StringBuffer sb = new StringBuffer(64);
+			sb.append(getClass().getName()).append(" [");
+			sb.append(_sfr.getRange().toString());
+			sb.append("]");
+			return sb.toString();
+		}
+
+		/**
+		 * Note - the 'first cell' of a shared formula group is not always the top-left cell
+		 * of the enclosing range.
+		 * @return <code>true</code> if the specified coordinates correspond to the 'first cell'
+		 * of this shared formula group.
+		 */
+		public boolean isFirstCell(int row, int column) {
+			return _firstCell.getRow() == row && _firstCell.getCol() == column;
+		}
+	}
+
+	/**
+	 * @return a new empty {@link SharedValueManager}.
+	 */
+	public static SharedValueManager createEmpty() {
+		// Note - must create distinct instances because they are assumed to be mutable.
+		return new SharedValueManager(
+			new SharedFormulaRecord[0], new CellReference[0], new ArrayRecord[0], new TableRecord[0]);
+	}
+	private final List<ArrayRecord> _arrayRecords;
+	private final TableRecord[] _tableRecords;
+	private final Map<SharedFormulaRecord, SharedFormulaGroup> _groupsBySharedFormulaRecord;
+	/** cached for optimization purposes */
+	private SharedFormulaGroup[] _groups;
+
+	private SharedValueManager(SharedFormulaRecord[] sharedFormulaRecords,
+			CellReference[] firstCells, ArrayRecord[] arrayRecords, TableRecord[] tableRecords) {
+		int nShF = sharedFormulaRecords.length;
+		if (nShF != firstCells.length) {
+			throw new IllegalArgumentException("array sizes don't match: " + nShF + "!=" + firstCells.length + ".");
+		}
+		_arrayRecords = toList(arrayRecords);
+		_tableRecords = tableRecords;
+		Map<SharedFormulaRecord, SharedFormulaGroup> m = new HashMap<SharedFormulaRecord, SharedFormulaGroup>(nShF * 3 / 2);
+		for (int i = 0; i < nShF; i++) {
+			SharedFormulaRecord sfr = sharedFormulaRecords[i];
+			m.put(sfr, new SharedFormulaGroup(sfr, firstCells[i]));
+		}
+		_groupsBySharedFormulaRecord = m;
+	}
+
+	/**
+	 * @return a modifiable list, independent of the supplied array
+	 */
+	private static <Z> List<Z> toList(Z[] zz) {
+		List<Z> result = new ArrayList<Z>(zz.length);
+		for (int i = 0; i < zz.length; i++) {
+			result.add(zz[i]);
+		}
+		return result;
+	}
+
+	/**
+	 */
+	public static SharedValueManager create(SharedFormulaRecord[] sharedFormulaRecords,
+			CellReference[] firstCells, ArrayRecord[] arrayRecords, TableRecord[] tableRecords) {
+		if (sharedFormulaRecords.length + firstCells.length + arrayRecords.length + tableRecords.length < 1) {
+			return createEmpty();
+		}
+		return new SharedValueManager(sharedFormulaRecords, firstCells, arrayRecords, tableRecords);
+	}
+
+
+	/**
+	 * @param firstCell as extracted from the {@link ExpPtg} from the cell's formula.
+	 * @return never <code>null</code>
+	 */
+	public SharedFormulaRecord linkSharedFormulaRecord(CellReference firstCell, FormulaRecordAggregate agg) {
+
+		SharedFormulaGroup result = findFormulaGroup(getGroups(), firstCell);
+		result.add(agg);
+		return result.getSFR();
+	}
+
+	private static SharedFormulaGroup findFormulaGroup(SharedFormulaGroup[] groups, CellReference firstCell) {
+		int row = firstCell.getRow();
+		int column = firstCell.getCol();
+		// Traverse the list of shared formulas and try to find the correct one for us
+
+		// perhaps this could be optimised to some kind of binary search
+		for (int i = 0; i < groups.length; i++) {
+			SharedFormulaGroup svg = groups[i];
+			if (svg.isFirstCell(row, column)) {
+				return svg;
+			}
+		}
+		// TODO - fix file "15228.xls" so it opens in Excel after rewriting with POI
+		throw new RuntimeException("Failed to find a matching shared formula record");
+	}
+
+	private SharedFormulaGroup[] getGroups() {
+		if (_groups == null) {
+			SharedFormulaGroup[] groups = new SharedFormulaGroup[_groupsBySharedFormulaRecord.size()];
+			_groupsBySharedFormulaRecord.values().toArray(groups);
+			Arrays.sort(groups, SVGComparator); // make search behaviour more deterministic
+			_groups = groups;
+		}
+		return _groups;
+	}
+
+	private static final Comparator<SharedFormulaGroup> SVGComparator = new Comparator<SharedFormulaGroup>() {
+
+		public int compare(SharedFormulaGroup a, SharedFormulaGroup b) {
+			CellRangeAddress8Bit rangeA = a.getSFR().getRange();
+			CellRangeAddress8Bit rangeB = b.getSFR().getRange();
+
+			int cmp;
+			cmp = rangeA.getFirstRow() - rangeB.getFirstRow();
+			if (cmp != 0) {
+				return cmp;
+			}
+			cmp = rangeA.getFirstColumn() - rangeB.getFirstColumn();
+			if (cmp != 0) {
+				return cmp;
+			}
+			return 0;
+		}
+	};
+
+	/**
+	 * Gets the {@link SharedValueRecordBase} record if it should be encoded immediately after the
+	 * formula record contained in the specified {@link FormulaRecordAggregate} agg.  Note - the
+	 * shared value record always appears after the first formula record in the group.  For arrays
+	 * and tables the first formula is always the in the top left cell.  However, since shared
+	 * formula groups can be sparse and/or overlap, the first formula may not actually be in the
+	 * top left cell.
+	 *
+	 * @return the SHRFMLA, TABLE or ARRAY record for the formula cell, if it is the first cell of
+	 * a table or array region. <code>null</code> if the formula cell is not shared/array/table,
+	 * or if the specified formula is not the the first in the group.
+	 */
+	public SharedValueRecordBase getRecordForFirstCell(FormulaRecordAggregate agg) {
+		CellReference firstCell = agg.getFormulaRecord().getFormula().getExpReference();
+		// perhaps this could be optimised by consulting the (somewhat unreliable) isShared flag
+		// and/or distinguishing between tExp and tTbl.
+		if (firstCell == null) {
+			// not a shared/array/table formula
+			return null;
+		}
+
+
+		int row = firstCell.getRow();
+		int column = firstCell.getCol();
+		if (agg.getRow() != row || agg.getColumn() != column) {
+			// not the first formula cell in the group
+			return null;
+		}
+		SharedFormulaGroup[] groups = getGroups();
+		for (int i = 0; i < groups.length; i++) {
+			// note - logic for finding correct shared formula group is slightly
+			// more complicated since the first cell
+			SharedFormulaGroup sfg = groups[i];
+			if (sfg.isFirstCell(row, column)) {
+				return sfg.getSFR();
+			}
+		}
+
+		// Since arrays and tables cannot be sparse (all cells in range participate)
+		// The first cell will be the top left in the range.  So we can match the
+		// ARRAY/TABLE record directly.
+
+		for (TableRecord tr : _tableRecords) {
+			if (tr.isFirstCell(row, column)) {
+				return tr;
+			}
+		}
+		for (ArrayRecord ar : _arrayRecords) {
+			if (ar.isFirstCell(row, column)) {
+				return ar;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Converts all {@link FormulaRecord}s handled by <tt>sharedFormulaRecord</tt>
+	 * to plain unshared formulas
+	 */
+	public void unlink(SharedFormulaRecord sharedFormulaRecord) {
+		SharedFormulaGroup svg = _groupsBySharedFormulaRecord.remove(sharedFormulaRecord);
+		if (svg == null) {
+			throw new IllegalStateException("Failed to find formulas for shared formula");
+		}
+		_groups = null; // be sure to reset cached value
+		svg.unlinkSharedFormulas();
+	}
+
+
+	/**
+	 * Removes the {@link ArrayRecord} for the cell group containing the specified cell.
+	 * The caller should clear (set blank) all cells in the returned range.
+	 * @return the range of the array formula which was just removed. Never <code>null</code>.
+	 */
+	public CellRangeAddress8Bit removeArrayFormula(int rowIndex, int columnIndex) {
+		for (ArrayRecord ar : _arrayRecords) {
+			if (ar.isInRange(rowIndex, columnIndex)) {
+				_arrayRecords.remove(ar);
+				return ar.getRange();
+			}
+		}
+		String ref = new CellReference(rowIndex, columnIndex, false, false).formatAsString();
+		throw new IllegalArgumentException("Specified cell " + ref
+				+ " is not part of an array formula.");
+	}
+
+	/**
+	 * @return the shared ArrayRecord identified by (firstRow, firstColumn). never <code>null</code>.
+	 */
+	public ArrayRecord getArrayRecord(int firstRow, int firstColumn) {
+		for(ArrayRecord ar : _arrayRecords) {
+			if(ar.isFirstCell(firstRow, firstColumn)) {
+				return ar;
+			}
+		}
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java	(revision 28000)
@@ -0,0 +1,266 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.aggregates;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hssf.model.RecordStream;
+import org.apache.poi.hssf.record.BlankRecord;
+import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.FormulaRecord;
+import org.apache.poi.hssf.record.MulBlankRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordBase;
+import org.apache.poi.hssf.record.StringRecord;
+import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor;
+
+/**
+ *
+ * Aggregate value records together.  Things are easier to handle that way.
+ *
+ * @author  andy
+ * @author  Glen Stampoultzis (glens at apache.org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class ValueRecordsAggregate {
+	private static final int MAX_ROW_INDEX = 0XFFFF;
+	private static final int INDEX_NOT_SET = -1;
+	private int firstcell = INDEX_NOT_SET;
+	private int lastcell  = INDEX_NOT_SET;
+	private CellValueRecordInterface[][] records;
+
+	/** Creates a new instance of ValueRecordsAggregate */
+
+	public ValueRecordsAggregate() {
+		this(INDEX_NOT_SET, INDEX_NOT_SET, new CellValueRecordInterface[30][]); // We start with 30 Rows.
+	}
+	private ValueRecordsAggregate(int firstCellIx, int lastCellIx, CellValueRecordInterface[][] pRecords) {
+		firstcell = firstCellIx;
+		lastcell = lastCellIx;
+		records = pRecords;
+	}
+
+	public void insertCell(CellValueRecordInterface cell) {
+		short column = cell.getColumn();
+		int row = cell.getRow();
+		if (row >= records.length) {
+			CellValueRecordInterface[][] oldRecords = records;
+			int newSize = oldRecords.length * 2;
+			if (newSize < row + 1)
+				newSize = row + 1;
+			records = new CellValueRecordInterface[newSize][];
+			System.arraycopy(oldRecords, 0, records, 0, oldRecords.length);
+		}
+		CellValueRecordInterface[] rowCells = records[row];
+		if (rowCells == null) {
+			int newSize = column + 1;
+			if (newSize < 10)
+				newSize = 10;
+			rowCells = new CellValueRecordInterface[newSize];
+			records[row] = rowCells;
+		}
+		if (column >= rowCells.length) {
+			CellValueRecordInterface[] oldRowCells = rowCells;
+			int newSize = oldRowCells.length * 2;
+			if (newSize < column + 1)
+				newSize = column + 1;
+			// if(newSize>257) newSize=257; // activate?
+			rowCells = new CellValueRecordInterface[newSize];
+			System.arraycopy(oldRowCells, 0, rowCells, 0, oldRowCells.length);
+			records[row] = rowCells;
+		}
+		rowCells[column] = cell;
+
+		if (column < firstcell || firstcell == INDEX_NOT_SET) {
+			firstcell = column;
+		}
+		if (column > lastcell || lastcell == INDEX_NOT_SET) {
+			lastcell = column;
+		}
+	}
+
+	public void removeCell(CellValueRecordInterface cell) {
+		if (cell == null) {
+			throw new IllegalArgumentException("cell must not be null");
+		}
+		int row = cell.getRow();
+		if (row >= records.length) {
+			throw new RuntimeException("cell row is out of range");
+		}
+		CellValueRecordInterface[] rowCells = records[row];
+		if (rowCells == null) {
+			throw new RuntimeException("cell row is already empty");
+		}
+		short column = cell.getColumn();
+		if (column >= rowCells.length) {
+			throw new RuntimeException("cell column is out of range");
+		}
+		rowCells[column] = null;
+	}
+
+	public void removeAllCellsValuesForRow(int rowIndex) {
+		if (rowIndex < 0 || rowIndex > MAX_ROW_INDEX) {
+			throw new IllegalArgumentException("Specified rowIndex " + rowIndex
+					+ " is outside the allowable range (0.." +MAX_ROW_INDEX + ")");
+		}
+		if (rowIndex >= records.length) {
+			// this can happen when the client code has created a row,
+			// and then removes/replaces it before adding any cells. (see bug 46312)
+			return;
+		}
+
+		records[rowIndex] = null;
+	}
+
+	public int getFirstCellNum() {
+		return firstcell;
+	}
+
+	public int getLastCellNum() {
+		return lastcell;
+	}
+
+	public void addMultipleBlanks(MulBlankRecord mbr) {
+		for (int j = 0; j < mbr.getNumColumns(); j++) {
+			BlankRecord br = new BlankRecord();
+
+			br.setColumn(( short ) (j + mbr.getFirstColumn()));
+			br.setRow(mbr.getRow());
+			br.setXFIndex(mbr.getXFAt(j));
+			insertCell(br);
+		}
+	}
+
+	/**
+	 * Processes a single cell value record
+	 * @param sfh used to resolve any shared-formulas/arrays/tables for the current sheet
+	 */
+	public void construct(CellValueRecordInterface rec, RecordStream rs, SharedValueManager sfh) {
+		if (rec instanceof FormulaRecord) {
+			FormulaRecord formulaRec = (FormulaRecord)rec;
+			// read optional cached text value
+			StringRecord cachedText;
+			Class<? extends Record> nextClass = rs.peekNextClass();
+			if (nextClass == StringRecord.class) {
+				cachedText = (StringRecord) rs.getNext();
+			} else {
+				cachedText = null;
+			}
+			insertCell(new FormulaRecordAggregate(formulaRec, cachedText, sfh));
+		} else {
+			insertCell(rec);
+		}
+	}
+
+
+	/** Returns true if the row has cells attached to it */
+	public boolean rowHasCells(int row) {
+		if (row >= records.length) {
+			return false;
+		}
+		CellValueRecordInterface[] rowCells=records[row];
+		if(rowCells==null) return false;
+		for(int col=0;col<rowCells.length;col++) {
+			if(rowCells[col]!=null) return true;
+		}
+		return false;
+	}
+
+
+	public void visitCellsForRow(int rowIndex, RecordVisitor rv) {
+
+		CellValueRecordInterface[] rowCells = records[rowIndex];
+		if(rowCells == null) {
+			throw new IllegalArgumentException("Row [" + rowIndex + "] is empty");
+		}
+
+
+		for (int i = 0; i < rowCells.length; i++) {
+			RecordBase cvr = (RecordBase) rowCells[i];
+			if(cvr == null) {
+				continue;
+			}
+			int nBlank = countBlanks(rowCells, i);
+			if (nBlank > 1) {
+				rv.visitRecord(createMBR(rowCells, i, nBlank));
+				i+=nBlank-1;
+			} else if (cvr instanceof RecordAggregate) {
+				RecordAggregate agg = (RecordAggregate) cvr;
+				agg.visitContainedRecords(rv);
+			} else {
+				rv.visitRecord((Record) cvr);
+			}
+		}
+	}
+
+	/**
+	 * @return the number of <em>consecutive</em> {@link BlankRecord}s in the specified row
+	 * starting from startIx.
+	 */
+	private static int countBlanks(CellValueRecordInterface[] rowCellValues, int startIx) {
+		int i = startIx;
+		while(i < rowCellValues.length) {
+			CellValueRecordInterface cvr = rowCellValues[i];
+			if (!(cvr instanceof BlankRecord)) {
+				break;
+			}
+			i++;
+		}
+		return i - startIx;
+	}
+
+	private MulBlankRecord createMBR(CellValueRecordInterface[] cellValues, int startIx, int nBlank) {
+
+		short[] xfs = new short[nBlank];
+		for (int i = 0; i < xfs.length; i++) {
+			xfs[i] = ((BlankRecord)cellValues[startIx + i]).getXFIndex();
+		}
+		int rowIx = cellValues[startIx].getRow();
+		return new MulBlankRecord(rowIx, startIx, xfs);
+	}
+
+	/**
+	 * Gets all the cell records contained in this aggregate. 
+	 * Note {@link BlankRecord}s appear separate (not in {@link MulBlankRecord}s).
+	 */
+	public CellValueRecordInterface[] getValueRecords() {
+		List<CellValueRecordInterface> temp = new ArrayList<CellValueRecordInterface>();
+
+		for (int rowIx = 0; rowIx < records.length; rowIx++) {
+			CellValueRecordInterface[] rowCells = records[rowIx];
+			if (rowCells == null) {
+				continue;
+			}
+			for (int colIx = 0; colIx < rowCells.length; colIx++) {
+				CellValueRecordInterface cell = rowCells[colIx];
+				if (cell != null) {
+					temp.add(cell);
+				}
+			}
+		}
+
+		CellValueRecordInterface[] result = new CellValueRecordInterface[temp.size()];
+		temp.toArray(result);
+		return result;
+	}
+
+	public Object clone() {
+		throw new RuntimeException("clone() should not be called.  ValueRecordsAggregate should be copied via Sheet.cloneSheet()");
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/aggregates/package.html	(revision 28000)
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+record aggregates are not real "records" but collections of records that act as a single record.
+This is an optimization basically.
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+@see org.apache.poi.hssf.record
+@see org.apache.poi.hssf.eventmodel
+@see org.apache.poi.hssf.record.RecordFactory
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/FeatFormulaErr2.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/FeatFormulaErr2.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/FeatFormulaErr2.java	(revision 28000)
@@ -0,0 +1,71 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.common;
+
+import org.apache.poi.hssf.record.FeatRecord;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: FeatFormulaErr2 (Formula Evaluation Shared Feature) common record part
+ * <P>
+ * This record part specifies Formula Evaluation & Error Ignoring data 
+ *  for a sheet, stored as part of a Shared Feature. It can be found in 
+ *  records such as {@link FeatRecord}.
+ * For the full meanings of the flags, see pages 669 and 670
+ *  of the Excel binary file format documentation.
+ */
+public final class FeatFormulaErr2 implements SharedFeature {
+
+	/**
+	 * What errors we should ignore
+	 */
+	private int errorCheck;
+	
+	
+	public FeatFormulaErr2() {}
+
+	public FeatFormulaErr2(RecordInputStream in) {
+		errorCheck = in.readInt();
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(" [FEATURE FORMULA ERRORS]\n");
+		buffer.append("  checkCalculationErrors    = "); 
+		buffer.append("  checkEmptyCellRef         = "); 
+		buffer.append("  checkNumbersAsText        = "); 
+		buffer.append("  checkInconsistentRanges   = "); 
+		buffer.append("  checkInconsistentFormulas = "); 
+		buffer.append("  checkDateTimeFormats      = "); 
+		buffer.append("  checkUnprotectedFormulas  = "); 
+		buffer.append("  performDataValidation     = "); 
+		buffer.append(" [/FEATURE FORMULA ERRORS]\n");
+		return buffer.toString();
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		out.writeInt(errorCheck);
+	}
+
+	public int getDataSize() {
+		return 4;
+	}
+	
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/FeatSmartTag.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/FeatSmartTag.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/FeatSmartTag.java	(revision 28000)
@@ -0,0 +1,60 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.common;
+
+import org.apache.poi.hssf.record.FeatRecord;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: FeatSmartTag (Smart Tag Shared Feature) common record part
+ * <P>
+ * This record part specifies Smart Tag data for a sheet, stored as part
+ *  of a Shared Feature. It can be found in records such as  {@link FeatRecord}.
+ * It is made up of a hash, and a set of Factoid Data that makes up
+ *  the smart tags.
+ * For more details, see page 669 of the Excel binary file
+ *  format documentation.
+ */
+public final class FeatSmartTag implements SharedFeature {
+	// TODO - process
+	private byte[] data;
+	
+	public FeatSmartTag() {
+		data = new byte[0];
+	}
+
+	public FeatSmartTag(RecordInputStream in) {
+		data = in.readRemainder();
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(" [FEATURE SMART TAGS]\n");
+		buffer.append(" [/FEATURE SMART TAGS]\n");
+		return buffer.toString();
+	}
+
+	public int getDataSize() {
+		return data.length;
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		out.write(data);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/FtrHeader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/FtrHeader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/FtrHeader.java	(revision 28000)
@@ -0,0 +1,69 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.common;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: FtrHeader (Future Record Header) common record part
+ * <P>
+ * This record part specifies a header for a Ftr (Future)
+ *  style record, which includes extra attributes above and
+ *  beyond those of a traditional record. 
+ */
+public final class FtrHeader {
+	/** This MUST match the type on the containing record */
+	private short recordType;
+	/** This is a FrtFlags */
+	private short grbitFrt;
+	/** MUST be 8 bytes and all zero */
+	private byte[] reserved;
+
+	public FtrHeader() {
+		reserved = new byte[8];
+	}
+
+	public FtrHeader(RecordInputStream in) {
+		recordType = in.readShort();
+		grbitFrt   = in.readShort();
+		
+		reserved = new byte[8];
+		in.read(reserved, 0, 8);
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(" [FUTURE HEADER]\n");
+		buffer.append("   Type " + recordType);
+		buffer.append("   Flags " + grbitFrt);
+		buffer.append(" [/FUTURE HEADER]\n");
+		return buffer.toString();
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		out.writeShort(recordType);
+		out.writeShort(grbitFrt);
+		out.write(reserved);
+	}
+
+	public void setRecordType(short recordType) {
+		this.recordType = recordType;
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/SharedFeature.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/SharedFeature.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/SharedFeature.java	(revision 28000)
@@ -0,0 +1,29 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.common;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Common Interface for all Shared Features
+ */
+public interface SharedFeature {
+	public String toString();
+	public void serialize(LittleEndianOutput out);
+	public int getDataSize();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/UnicodeString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/UnicodeString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/common/UnicodeString.java	(revision 28000)
@@ -0,0 +1,722 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.common;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.record.cont.ContinuableRecordOutput;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * Title: Unicode String<p/>
+ * Description:  Unicode String - just standard fields that are in several records.
+ *               It is considered more desirable then repeating it in all of them.<p/>
+ *               This is often called a XLUnicodeRichExtendedString in MS documentation.<p/>
+ * REFERENCE:  PG 264 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
+ * REFERENCE:  PG 951 Excel Binary File Format (.xls) Structure Specification v20091214 
+ */
+public class UnicodeString implements Comparable<UnicodeString> { // TODO - make this final when the compatibility version is removed
+    private short             field_1_charCount;
+    private byte              field_2_optionflags;
+    private String            field_3_string;
+    private List<FormatRun>   field_4_format_runs;
+    private ExtRst            field_5_ext_rst;
+    private static final BitField   highByte  = BitFieldFactory.getInstance(0x1);
+    // 0x2 is reserved
+    private static final BitField   extBit    = BitFieldFactory.getInstance(0x4);
+    private static final BitField   richText  = BitFieldFactory.getInstance(0x8);
+
+    public static class FormatRun implements Comparable<FormatRun> {
+        final short _character;
+        short _fontIndex;
+
+        public FormatRun(short character, short fontIndex) {
+            this._character = character;
+            this._fontIndex = fontIndex;
+        }
+
+        public FormatRun(LittleEndianInput in) {
+            this(in.readShort(), in.readShort());
+        }
+
+        public short getCharacterPos() {
+            return _character;
+        }
+
+        public short getFontIndex() {
+            return _fontIndex;
+        }
+
+        public boolean equals(Object o) {
+            if (!(o instanceof FormatRun)) {
+                return false;
+            }
+            FormatRun other = ( FormatRun ) o;
+
+            return _character == other._character && _fontIndex == other._fontIndex;
+        }
+
+        public int compareTo(FormatRun r) {
+            if (_character == r._character && _fontIndex == r._fontIndex) {
+                return 0;
+            }
+            if (_character == r._character) {
+                return _fontIndex - r._fontIndex;
+            }
+            return _character - r._character;
+        }
+
+        public String toString() {
+            return "character="+_character+",fontIndex="+_fontIndex;
+        }
+
+        public void serialize(LittleEndianOutput out) {
+            out.writeShort(_character);
+            out.writeShort(_fontIndex);
+        }
+    }
+    
+    // See page 681
+    public static class ExtRst implements Comparable<ExtRst> {
+       private short reserved;
+       
+       // This is a Phs (see page 881)
+       private short formattingFontIndex;
+       private short formattingOptions;
+       
+       // This is a RPHSSub (see page 894)
+       private int numberOfRuns;
+       private String phoneticText;
+       
+       // This is an array of PhRuns (see page 881)
+       private PhRun[] phRuns;
+       // Sometimes there's some cruft at the end
+       private byte[] extraData;
+
+       private void populateEmpty() {
+          reserved = 1;
+          phoneticText = "";
+          phRuns = new PhRun[0];
+          extraData = new byte[0];
+       }
+       
+       protected ExtRst() {
+          populateEmpty();
+       }
+       protected ExtRst(LittleEndianInput in, int expectedLength) {
+          reserved = in.readShort();
+          
+          // Old style detection (Reserved = 0xFF)
+          if(reserved == -1) {
+             populateEmpty();
+             return;
+          }
+          
+          // Spot corrupt records
+          if(reserved != 1) {
+             System.err.println("Warning - ExtRst was has wrong magic marker, expecting 1 but found " + reserved + " - ignoring");
+             // Grab all the remaining data, and ignore it
+             for(int i=0; i<expectedLength-2; i++) {
+                in.readByte();
+             }
+             // And make us be empty
+             populateEmpty();
+             return;
+          }
+          
+          // Carry on reading in as normal
+          short stringDataSize = in.readShort();
+          
+          formattingFontIndex = in.readShort();
+          formattingOptions   = in.readShort();
+          
+          // RPHSSub
+          numberOfRuns = in.readUShort();
+          short length1 = in.readShort();
+          // No really. Someone clearly forgot to read
+          //  the docs on their datastructure...
+          short length2 = in.readShort();
+          // And sometimes they write out garbage :(
+          if(length1 == 0 && length2 > 0) {
+             length2 = 0;
+          }
+          if(length1 != length2) {
+             throw new IllegalStateException(
+                   "The two length fields of the Phonetic Text don't agree! " +
+                   length1 + " vs " + length2
+             );
+          }
+          phoneticText = StringUtil.readUnicodeLE(in, length1);
+          
+          int runData = stringDataSize - 4 - 6 - (2*phoneticText.length());
+          int numRuns = (runData / 6);
+          phRuns = new PhRun[numRuns];
+          for(int i=0; i<phRuns.length; i++) {
+             phRuns[i] = new PhRun(in);
+          }
+
+          int extraDataLength = runData - (numRuns*6);
+          if(extraDataLength < 0) {
+             System.err.println("Warning - ExtRst overran by " + (0-extraDataLength) + " bytes");
+             extraDataLength = 0;
+          }
+          extraData = new byte[extraDataLength];
+          for(int i=0; i<extraData.length; i++) {
+             extraData[i] = in.readByte();
+          }
+       }
+       /**
+        * Returns our size, excluding our 
+        *  4 byte header
+        */
+       protected int getDataSize() {
+          return 4 + 6 + (2*phoneticText.length()) + 
+             (6*phRuns.length) + extraData.length;
+       }
+       protected void serialize(ContinuableRecordOutput out) {
+          int dataSize = getDataSize();
+          
+          out.writeContinueIfRequired(8);
+          out.writeShort(reserved);
+          out.writeShort(dataSize);
+          out.writeShort(formattingFontIndex);
+          out.writeShort(formattingOptions);
+          
+          out.writeContinueIfRequired(6);
+          out.writeShort(numberOfRuns);
+          out.writeShort(phoneticText.length());
+          out.writeShort(phoneticText.length());
+          
+          out.writeContinueIfRequired(phoneticText.length()*2);
+          StringUtil.putUnicodeLE(phoneticText, out);
+          
+          for(int i=0; i<phRuns.length; i++) {
+             phRuns[i].serialize(out);
+          }
+          
+          out.write(extraData);
+       }
+
+       public boolean equals(Object obj) {
+          if(! (obj instanceof ExtRst)) {
+             return false;
+          }
+          ExtRst other = (ExtRst)obj;
+          return (compareTo(other) == 0);
+       }
+       public int compareTo(ExtRst o) {
+          int result;
+          
+          result = reserved - o.reserved;
+          if(result != 0) return result;
+          result = formattingFontIndex - o.formattingFontIndex;
+          if(result != 0) return result;
+          result = formattingOptions - o.formattingOptions;
+          if(result != 0) return result;
+          result = numberOfRuns - o.numberOfRuns;
+          if(result != 0) return result;
+          
+          result = phoneticText.compareTo(o.phoneticText);
+          if(result != 0) return result;
+          
+          result = phRuns.length - o.phRuns.length;
+          if(result != 0) return result;
+          for(int i=0; i<phRuns.length; i++) {
+             result = phRuns[i].phoneticTextFirstCharacterOffset - o.phRuns[i].phoneticTextFirstCharacterOffset;
+             if(result != 0) return result;
+             result = phRuns[i].realTextFirstCharacterOffset - o.phRuns[i].realTextFirstCharacterOffset;
+             if(result != 0) return result;
+             result = phRuns[i].realTextFirstCharacterOffset - o.phRuns[i].realTextLength;
+             if(result != 0) return result;
+          }
+          
+          result = extraData.length - o.extraData.length;
+          if(result != 0) return result;
+          
+          // If we get here, it's the same
+          return 0;
+       }
+       
+       protected ExtRst clone() {
+          ExtRst ext = new ExtRst();
+          ext.reserved = reserved;
+          ext.formattingFontIndex = formattingFontIndex;
+          ext.formattingOptions = formattingOptions;
+          ext.numberOfRuns = numberOfRuns;
+          ext.phoneticText = new String(phoneticText);
+          ext.phRuns = new PhRun[phRuns.length];
+          for(int i=0; i<ext.phRuns.length; i++) {
+             ext.phRuns[i] = new PhRun(
+                   phRuns[i].phoneticTextFirstCharacterOffset,
+                   phRuns[i].realTextFirstCharacterOffset,
+                   phRuns[i].realTextLength
+             );
+          }
+          return ext;
+       }
+       
+    }
+    public static class PhRun {
+       private int phoneticTextFirstCharacterOffset;
+       private int realTextFirstCharacterOffset;
+       private int realTextLength;
+       
+       public PhRun(int phoneticTextFirstCharacterOffset,
+            int realTextFirstCharacterOffset, int realTextLength) {
+         this.phoneticTextFirstCharacterOffset = phoneticTextFirstCharacterOffset;
+         this.realTextFirstCharacterOffset = realTextFirstCharacterOffset;
+         this.realTextLength = realTextLength;
+      }
+      private PhRun(LittleEndianInput in) {
+          phoneticTextFirstCharacterOffset = in.readUShort();
+          realTextFirstCharacterOffset = in.readUShort();
+          realTextLength = in.readUShort();
+       }
+       private void serialize(ContinuableRecordOutput out) {
+          out.writeContinueIfRequired(6);
+          out.writeShort(phoneticTextFirstCharacterOffset);
+          out.writeShort(realTextFirstCharacterOffset);
+          out.writeShort(realTextLength);
+       }
+    }
+
+    private UnicodeString() {
+     //Used for clone method.
+    }
+
+    public UnicodeString(String str)
+    {
+      setString(str);
+    }
+
+
+
+    public int hashCode()
+    {
+        int stringHash = 0;
+        if (field_3_string != null)
+            stringHash = field_3_string.hashCode();
+        return field_1_charCount + stringHash;
+    }
+
+    /**
+     * Our handling of equals is inconsistent with compareTo.  The trouble is because we don't truely understand
+     * rich text fields yet it's difficult to make a sound comparison.
+     *
+     * @param o     The object to compare.
+     * @return      true if the object is actually equal.
+     */
+    public boolean equals(Object o)
+    {
+        if (!(o instanceof UnicodeString)) {
+            return false;
+        }
+        UnicodeString other = (UnicodeString) o;
+
+        //OK lets do this in stages to return a quickly, first check the actual string
+        boolean eq = ((field_1_charCount == other.field_1_charCount)
+                && (field_2_optionflags == other.field_2_optionflags)
+                && field_3_string.equals(other.field_3_string));
+        if (!eq) return false;
+
+        //OK string appears to be equal but now lets compare formatting runs
+        if ((field_4_format_runs == null) && (other.field_4_format_runs == null))
+          //Strings are equal, and there are not formatting runs.
+          return true;
+        if (((field_4_format_runs == null) && (other.field_4_format_runs != null)) ||
+             (field_4_format_runs != null) && (other.field_4_format_runs == null))
+           //Strings are equal, but one or the other has formatting runs
+           return false;
+
+        //Strings are equal, so now compare formatting runs.
+        int size = field_4_format_runs.size();
+        if (size != other.field_4_format_runs.size())
+          return false;
+
+        for (int i=0;i<size;i++) {
+          FormatRun run1 = field_4_format_runs.get(i);
+          FormatRun run2 = other.field_4_format_runs.get(i);
+
+          if (!run1.equals(run2))
+            return false;
+        }
+
+        // Well the format runs are equal as well!, better check the ExtRst data
+        if(field_5_ext_rst == null && other.field_5_ext_rst == null) {
+           // Good
+        } else if(field_5_ext_rst != null && other.field_5_ext_rst != null) {
+           int extCmp = field_5_ext_rst.compareTo(other.field_5_ext_rst);
+           if(extCmp == 0) {
+              // Good
+           } else {
+              return false;
+           }
+        } else {
+           return false;
+        }
+
+        //Phew!! After all of that we have finally worked out that the strings
+        //are identical.
+        return true;
+    }
+
+    /**
+     * construct a unicode string record and fill its fields, ID is ignored
+     * @param in the RecordInputstream to read the record from
+     */
+    public UnicodeString(RecordInputStream in) {
+        field_1_charCount   = in.readShort();
+        field_2_optionflags = in.readByte();
+
+        int runCount = 0;
+        int extensionLength = 0;
+        //Read the number of rich runs if rich text.
+        if ( isRichText() )
+        {
+            runCount = in.readShort();
+        }
+        //Read the size of extended data if present.
+        if ( isExtendedText() )
+        {
+            extensionLength = in.readInt();
+        }
+
+        boolean isCompressed = ((field_2_optionflags & 1) == 0);
+        if (isCompressed) {
+            field_3_string = in.readCompressedUnicode(getCharCount());
+        } else {
+            field_3_string = in.readUnicodeLEString(getCharCount());
+        }
+
+
+        if (isRichText() && (runCount > 0)) {
+          field_4_format_runs = new ArrayList<FormatRun>(runCount);
+          for (int i=0;i<runCount;i++) {
+            field_4_format_runs.add(new FormatRun(in));
+          }
+        }
+
+        if (isExtendedText() && (extensionLength > 0)) {
+          field_5_ext_rst = new ExtRst(in, extensionLength);
+          if(field_5_ext_rst.getDataSize()+4 != extensionLength) {
+             System.err.println("ExtRst was supposed to be " + extensionLength + " bytes long, but seems to actually be " + (field_5_ext_rst.getDataSize()+4));
+          }
+        }
+    }
+
+
+
+    /**
+     * get the number of characters in the string,
+     *  as an un-wrapped int
+     *
+     * @return number of characters
+     */
+    public int getCharCount() {
+    	if(field_1_charCount < 0) {
+    		return field_1_charCount + 65536;
+    	}
+        return field_1_charCount;
+    }
+
+
+    /**
+     * set the number of characters in the string
+     * @param cc - number of characters
+     */
+
+    public void setCharCount(short cc)
+    {
+        field_1_charCount = cc;
+    }
+
+    /**
+     * get the option flags which among other things return if this is a 16-bit or
+     * 8 bit string
+     *
+     * @return optionflags bitmask
+     *
+     */
+
+    public byte getOptionFlags()
+    {
+        return field_2_optionflags;
+    }
+
+    /**
+     * @return the actual string this contains as a java String object
+     */
+    public String getString()
+    {
+        return field_3_string;
+    }
+
+    /**
+     * set the actual string this contains
+     * @param string  the text
+     */
+
+    public void setString(String string)
+    {
+        field_3_string = string;
+        setCharCount((short)field_3_string.length());
+        // scan for characters greater than 255 ... if any are
+        // present, we have to use 16-bit encoding. Otherwise, we
+        // can use 8-bit encoding
+        boolean useUTF16 = false;
+        int strlen = string.length();
+
+        for ( int j = 0; j < strlen; j++ )
+        {
+            if ( string.charAt( j ) > 255 )
+        {
+                useUTF16 = true;
+                break;
+            }
+        }
+        if (useUTF16)
+          //Set the uncompressed bit
+          field_2_optionflags = highByte.setByte(field_2_optionflags);
+        else field_2_optionflags = highByte.clearByte(field_2_optionflags);
+    }
+
+    public int getFormatRunCount() {
+      if (field_4_format_runs == null)
+        return 0;
+      return field_4_format_runs.size();
+    }
+
+    public FormatRun getFormatRun(int index) {
+      if (field_4_format_runs == null) {
+		return null;
+	}
+      if (index < 0 || index >= field_4_format_runs.size()) {
+		return null;
+	}
+      return field_4_format_runs.get(index);
+    }
+
+    private int findFormatRunAt(int characterPos) {
+      int size = field_4_format_runs.size();
+      for (int i=0;i<size;i++) {
+        FormatRun r = field_4_format_runs.get(i);
+        if (r._character == characterPos)
+          return i;
+        else if (r._character > characterPos)
+          return -1;
+      }
+      return -1;
+    }
+
+    /** Adds a font run to the formatted string.
+     *
+     *  If a font run exists at the current charcter location, then it is
+     *  replaced with the font run to be added.
+     */
+    public void addFormatRun(FormatRun r) {
+      if (field_4_format_runs == null) {
+		field_4_format_runs = new ArrayList<FormatRun>();
+	}
+
+      int index = findFormatRunAt(r._character);
+      if (index != -1)
+         field_4_format_runs.remove(index);
+
+      field_4_format_runs.add(r);
+      //Need to sort the font runs to ensure that the font runs appear in
+      //character order
+      Collections.sort(field_4_format_runs);
+
+      //Make sure that we now say that we are a rich string
+      field_2_optionflags = richText.setByte(field_2_optionflags);
+    }
+
+    public Iterator<FormatRun> formatIterator() {
+      if (field_4_format_runs != null) {
+        return field_4_format_runs.iterator();
+      }
+      return null;
+    }
+
+
+
+    /**
+     * unlike the real records we return the same as "getString()" rather than debug info
+     * @see #getDebugInfo()
+     * @return String value of the record
+     */
+
+    public String toString()
+    {
+        return getString();
+    }
+
+    /**
+     * return a character representation of the fields of this record
+     *
+     *
+     * @return String of output for biffviewer etc.
+     *
+     */
+    public String getDebugInfo()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[UNICODESTRING]\n");
+        buffer.append("    .charcount       = ")
+            .append(Integer.toHexString(getCharCount())).append("\n");
+        buffer.append("    .optionflags     = ")
+            .append(Integer.toHexString(getOptionFlags())).append("\n");
+        buffer.append("    .string          = ").append(getString()).append("\n");
+        if (field_4_format_runs != null) {
+          for (int i = 0; i < field_4_format_runs.size();i++) {
+            FormatRun r = field_4_format_runs.get(i);
+            buffer.append("      .format_run"+i+"          = ").append(r.toString()).append("\n");
+          }
+        }
+        if (field_5_ext_rst != null) {
+          buffer.append("    .field_5_ext_rst          = ").append("\n");
+          buffer.append( field_5_ext_rst.toString() ).append("\n");
+        }
+        buffer.append("[/UNICODESTRING]\n");
+        return buffer.toString();
+    }
+
+    /**
+     * Serialises out the String. There are special rules
+     *  about where we can and can't split onto
+     *  Continue records.
+     */
+    public void serialize(ContinuableRecordOutput out) {
+        int numberOfRichTextRuns = 0;
+        int extendedDataSize = 0;
+        if (isRichText() && field_4_format_runs != null) {
+            numberOfRichTextRuns = field_4_format_runs.size();
+        }
+        if (isExtendedText() && field_5_ext_rst != null) {
+            extendedDataSize = 4 + field_5_ext_rst.getDataSize();
+        }
+       
+        // Serialise the bulk of the String
+        // The writeString handles tricky continue stuff for us
+        out.writeString(field_3_string, numberOfRichTextRuns, extendedDataSize);
+
+        if (numberOfRichTextRuns > 0) {
+
+          //This will ensure that a run does not split a continue
+          for (int i=0;i<numberOfRichTextRuns;i++) {
+              if (out.getAvailableSpace() < 4) {
+                  out.writeContinue();
+              }
+              FormatRun r = field_4_format_runs.get(i);
+              r.serialize(out);
+          }
+        }
+
+        if (extendedDataSize > 0) {
+           field_5_ext_rst.serialize(out);
+        }
+    }
+
+    public int compareTo(UnicodeString str) {
+
+        int result = getString().compareTo(str.getString());
+
+        //As per the equals method lets do this in stages
+        if (result != 0)
+          return result;
+
+        //OK string appears to be equal but now lets compare formatting runs
+        if ((field_4_format_runs == null) && (str.field_4_format_runs == null))
+          //Strings are equal, and there are no formatting runs.
+          return 0;
+
+        if ((field_4_format_runs == null) && (str.field_4_format_runs != null))
+          //Strings are equal, but one or the other has formatting runs
+          return 1;
+        if ((field_4_format_runs != null) && (str.field_4_format_runs == null))
+          //Strings are equal, but one or the other has formatting runs
+          return -1;
+
+        //Strings are equal, so now compare formatting runs.
+        int size = field_4_format_runs.size();
+        if (size != str.field_4_format_runs.size())
+          return size - str.field_4_format_runs.size();
+
+        for (int i=0;i<size;i++) {
+          FormatRun run1 = field_4_format_runs.get(i);
+          FormatRun run2 = str.field_4_format_runs.get(i);
+
+          result = run1.compareTo(run2);
+          if (result != 0)
+            return result;
+        }
+
+        //Well the format runs are equal as well!, better check the ExtRst data
+        if ((field_5_ext_rst == null) && (str.field_5_ext_rst == null))
+          return 0;
+        if ((field_5_ext_rst == null) && (str.field_5_ext_rst != null))
+         return 1;
+        if ((field_5_ext_rst != null) && (str.field_5_ext_rst == null))
+          return -1;
+
+        result = field_5_ext_rst.compareTo(str.field_5_ext_rst); 
+        if (result != 0)
+           return result;
+
+        //Phew!! After all of that we have finally worked out that the strings
+        //are identical.
+        return 0;
+    }
+
+    private boolean isRichText()
+    {
+      return richText.isSet(getOptionFlags());
+    }
+
+    private boolean isExtendedText()
+        {
+        return extBit.isSet(getOptionFlags());
+    }
+
+    public Object clone() {
+        UnicodeString str = new UnicodeString();
+        str.field_1_charCount = field_1_charCount;
+        str.field_2_optionflags = field_2_optionflags;
+        str.field_3_string = field_3_string;
+        if (field_4_format_runs != null) {
+          str.field_4_format_runs = new ArrayList<FormatRun>();
+          for (FormatRun r : field_4_format_runs) {
+            str.field_4_format_runs.add(new FormatRun(r._character, r._fontIndex));
+          }
+        }
+        if (field_5_ext_rst != null) {
+           str.field_5_ext_rst = field_5_ext_rst.clone();
+        }
+
+        return str;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/constant/ConstantValueParser.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/constant/ConstantValueParser.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/constant/ConstantValueParser.java	(revision 28000)
@@ -0,0 +1,157 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.constant;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * To support Constant Values (2.5.7) as required by the CRN record.
+ * This class is also used for two dimensional arrays which are encoded by 
+ * EXTERNALNAME (5.39) records and Array tokens.<p/>
+ * 
+ * @author Josh Micich
+ */
+public final class ConstantValueParser {
+	// note - these (non-combinable) enum values are sparse.
+	private static final int TYPE_EMPTY = 0;
+	private static final int TYPE_NUMBER = 1;
+	private static final int TYPE_STRING = 2;
+	private static final int TYPE_BOOLEAN = 4; 
+	private static final int TYPE_ERROR_CODE = 16; // TODO - update OOO document to include this value
+	
+	private static final int TRUE_ENCODING = 1; 
+	private static final int FALSE_ENCODING = 0;
+	
+	// TODO - is this the best way to represent 'EMPTY'?
+	private static final Object EMPTY_REPRESENTATION = null;
+
+	private ConstantValueParser() {
+		// no instances of this class
+	}
+
+	public static Object[] parse(LittleEndianInput in, int nValues) {
+		Object[] result = new Object[nValues];
+		for (int i = 0; i < result.length; i++) {
+			result[i] = readAConstantValue(in);
+		}
+		return result;
+	}
+
+	private static Object readAConstantValue(LittleEndianInput in) {
+		byte grbit = in.readByte();
+		switch(grbit) {
+			case TYPE_EMPTY:
+				in.readLong(); // 8 byte 'not used' field
+				return EMPTY_REPRESENTATION; 
+			case TYPE_NUMBER:
+				return new Double(in.readDouble());
+			case TYPE_STRING:
+				return StringUtil.readUnicodeString(in);
+			case TYPE_BOOLEAN:
+				return readBoolean(in);
+			case TYPE_ERROR_CODE:
+				int errCode = in.readUShort();
+				// next 6 bytes are unused
+				in.readUShort();
+				in.readInt();
+				return ErrorConstant.valueOf(errCode);
+		}
+		throw new RuntimeException("Unknown grbit value (" + grbit + ")");
+	}
+
+	private static Object readBoolean(LittleEndianInput in) {
+		byte val = (byte)in.readLong(); // 7 bytes 'not used'
+		switch(val) {
+			case FALSE_ENCODING:
+				return Boolean.FALSE;
+			case TRUE_ENCODING:
+				return Boolean.TRUE;
+		}
+		// Don't tolerate unusual boolean encoded values (unless it becomes evident that they occur)
+		throw new RuntimeException("unexpected boolean encoding (" + val + ")");
+	}
+
+	public static int getEncodedSize(Object[] values) {
+		// start with one byte 'type' code for each value
+		int result = values.length * 1;
+		for (int i = 0; i < values.length; i++) {
+			result += getEncodedSize(values[i]);
+		}
+		return result;
+	}
+
+	/**
+	 * @return encoded size without the 'type' code byte
+	 */
+	private static int getEncodedSize(Object object) {
+		if(object == EMPTY_REPRESENTATION) {
+			return 8;
+		}
+		Class<?> cls = object.getClass();
+		
+		if(cls == Boolean.class || cls == Double.class || cls == ErrorConstant.class) {
+			return 8;
+		}
+		String strVal = (String)object;
+		return StringUtil.getEncodedSize(strVal);
+	}
+
+	public static void encode(LittleEndianOutput out, Object[] values) {
+		for (int i = 0; i < values.length; i++) {
+			encodeSingleValue(out, values[i]);
+		}
+	}
+
+	private static void encodeSingleValue(LittleEndianOutput out, Object value) {
+		if (value == EMPTY_REPRESENTATION) {
+			out.writeByte(TYPE_EMPTY);
+			out.writeLong(0L);
+			return;
+		}
+		if (value instanceof Boolean) {
+			Boolean bVal = ((Boolean)value);
+			out.writeByte(TYPE_BOOLEAN);
+			long longVal = bVal.booleanValue() ? 1L : 0L;
+			out.writeLong(longVal);
+			return;
+		}
+		if (value instanceof Double) {
+			Double dVal = (Double) value;
+			out.writeByte(TYPE_NUMBER);
+			out.writeDouble(dVal.doubleValue());
+			return;
+		}
+		if (value instanceof String) {
+			String val = (String) value;
+			out.writeByte(TYPE_STRING);
+			StringUtil.writeUnicodeString(out, val);
+			return;
+		}
+		if (value instanceof ErrorConstant) {
+			ErrorConstant ecVal = (ErrorConstant) value;
+			out.writeByte(TYPE_ERROR_CODE);
+			long longVal = ecVal.getErrorCode();
+			out.writeLong(longVal);
+			return;
+		}
+
+		throw new IllegalStateException("Unexpected value type (" + value.getClass().getName() + "'");
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/constant/ErrorConstant.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/constant/ErrorConstant.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/constant/ErrorConstant.java	(revision 28000)
@@ -0,0 +1,75 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.constant;
+
+import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+/**
+ * Represents a constant error code value as encoded in a constant values array. <p/>
+ * 
+ * This class is a type-safe wrapper for a 16-bit int value performing a similar job to 
+ * <tt>ErrorEval</tt>.
+ * 
+ * @author Josh Micich
+ */
+public class ErrorConstant {
+
+	private static final ErrorConstant NULL = new ErrorConstant(HSSFErrorConstants.ERROR_NULL);
+	private static final ErrorConstant DIV_0 = new ErrorConstant(HSSFErrorConstants.ERROR_DIV_0);
+	private static final ErrorConstant VALUE = new ErrorConstant(HSSFErrorConstants.ERROR_VALUE);
+	private static final ErrorConstant REF = new ErrorConstant(HSSFErrorConstants.ERROR_REF);
+	private static final ErrorConstant NAME = new ErrorConstant(HSSFErrorConstants.ERROR_NAME);
+	private static final ErrorConstant NUM = new ErrorConstant(HSSFErrorConstants.ERROR_NUM);
+	private static final ErrorConstant NA = new ErrorConstant(HSSFErrorConstants.ERROR_NA);
+
+	private final int _errorCode;
+
+	private ErrorConstant(int errorCode) {
+		_errorCode = errorCode;
+	}
+	
+	public int getErrorCode() {
+		return _errorCode;
+	}
+	public String getText() {
+		if(HSSFErrorConstants.isValidCode(_errorCode)) {
+			return HSSFErrorConstants.getText(_errorCode);
+		}
+		return "unknown error code (" + _errorCode + ")";
+	}
+
+	public static ErrorConstant valueOf(int errorCode) {
+		switch (errorCode) {
+			case HSSFErrorConstants.ERROR_NULL:  return NULL;
+			case HSSFErrorConstants.ERROR_DIV_0: return DIV_0;
+			case HSSFErrorConstants.ERROR_VALUE: return VALUE;
+			case HSSFErrorConstants.ERROR_REF:   return REF;
+			case HSSFErrorConstants.ERROR_NAME:  return NAME;
+			case HSSFErrorConstants.ERROR_NUM:   return NUM;
+			case HSSFErrorConstants.ERROR_NA:	return NA;
+		}
+		System.err.println("Warning - unexpected error code (" + errorCode + ")");
+		return new ErrorConstant(errorCode);
+	}
+	public String toString() {
+		StringBuffer sb = new StringBuffer(64);
+		sb.append(getClass().getName()).append(" [");
+		sb.append(getText());
+		sb.append("]");
+		return sb.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/cont/ContinuableRecord.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/cont/ContinuableRecord.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/cont/ContinuableRecord.java	(revision 28000)
@@ -0,0 +1,69 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.cont;
+
+import org.apache.poi.hssf.record.ContinueRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.util.LittleEndianByteArrayOutputStream;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Common superclass of all records that can produce {@link ContinueRecord}s while being serialized.
+ *
+ * @author Josh Micich
+ */
+public abstract class ContinuableRecord extends Record {
+
+	protected ContinuableRecord() {
+		// no fields to initialise
+	}
+	/**
+	 * Serializes this record's content to the supplied data output.<br/>
+	 * The standard BIFF header (ushort sid, ushort size) has been handled by the superclass, so
+	 * only BIFF data should be written by this method.  Simple data types can be written with the
+	 * standard {@link LittleEndianOutput} methods.  Methods from {@link ContinuableRecordOutput}
+	 * can be used to serialize strings (with {@link ContinueRecord}s being written as required).
+	 * If necessary, implementors can explicitly start {@link ContinueRecord}s (regardless of the
+	 * amount of remaining space).
+	 *
+	 * @param out a data output stream
+	 */
+	protected abstract void serialize(ContinuableRecordOutput out);
+
+
+	/**
+	 * @return the total length of the encoded record(s)
+	 * (Note - if any {@link ContinueRecord} is required, this result includes the
+	 * size of those too)
+	 */
+	public final int getRecordSize() {
+		ContinuableRecordOutput out = ContinuableRecordOutput.createForCountingOnly();
+		serialize(out);
+		out.terminate();
+		return out.getTotalSize();
+	}
+
+	public final int serialize(int offset, byte[] data) {
+
+		LittleEndianOutput leo = new LittleEndianByteArrayOutputStream(data, offset);
+		ContinuableRecordOutput out = new ContinuableRecordOutput(leo, getSid());
+		serialize(out);
+		out.terminate();
+		return out.getTotalSize();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java	(revision 28000)
@@ -0,0 +1,262 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.cont;
+
+import org.apache.poi.hssf.record.ContinueRecord;
+import org.apache.poi.util.DelayableLittleEndianOutput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * An augmented {@link LittleEndianOutput} used for serialization of {@link ContinuableRecord}s.
+ * This class keeps track of how much remaining space is available in the current BIFF record and
+ * can start new {@link ContinueRecord}s as required.
+ *
+ * @author Josh Micich
+ */
+public final class ContinuableRecordOutput implements LittleEndianOutput {
+
+	private final LittleEndianOutput _out;
+	private UnknownLengthRecordOutput _ulrOutput;
+	private int _totalPreviousRecordsSize;
+
+	public ContinuableRecordOutput(LittleEndianOutput out, int sid) {
+		_ulrOutput = new UnknownLengthRecordOutput(out, sid);
+		_out = out;
+		_totalPreviousRecordsSize = 0;
+	}
+
+	public static ContinuableRecordOutput createForCountingOnly() {
+		return new ContinuableRecordOutput(NOPOutput, -777); // fake sid
+	}
+
+	/**
+	 * @return total number of bytes written so far (including all BIFF headers)
+	 */
+	public int getTotalSize() {
+		return _totalPreviousRecordsSize + _ulrOutput.getTotalSize();
+	}
+	/**
+	 * Terminates the last record (also updates its 'ushort size' field)
+	 */
+	void terminate() {
+		_ulrOutput.terminate();
+	}
+	/**
+	 * @return number of remaining bytes of space in current record
+	 */
+	public int getAvailableSpace() {
+		return _ulrOutput.getAvailableSpace();
+	}
+
+	/**
+	 * Terminates the current record and starts a new {@link ContinueRecord} (regardless
+	 * of how much space is still available in the current record).
+	 */
+	public void writeContinue() {
+		_ulrOutput.terminate();
+		_totalPreviousRecordsSize += _ulrOutput.getTotalSize();
+		_ulrOutput = new UnknownLengthRecordOutput(_out, ContinueRecord.sid);
+	}
+	/**
+	 * Will terminate the current record and start a new {@link ContinueRecord}
+	 *  if there isn't space for the requested number of bytes
+	 * @param requiredContinuousSize The number of bytes that need to be written
+	 */
+	public void writeContinueIfRequired(int requiredContinuousSize) {
+		if (_ulrOutput.getAvailableSpace() < requiredContinuousSize) {
+			writeContinue();
+		}
+	}
+
+	/**
+	 * Writes the 'optionFlags' byte and encoded character data of a unicode string.  This includes:
+	 * <ul>
+	 * <li>byte optionFlags</li>
+	 * <li>encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)</li>
+	 * </ul>
+	 *
+	 * Notes:
+	 * <ul>
+	 * <li>The value of the 'is16bitEncoded' flag is determined by the actual character data
+	 * of <tt>text</tt></li>
+	 * <li>The string options flag is never separated (by a {@link ContinueRecord}) from the
+	 * first chunk of character data it refers to.</li>
+	 * <li>The 'ushort length' field is assumed to have been explicitly written earlier.  Hence,
+	 * there may be an intervening {@link ContinueRecord}</li>
+	 * </ul>
+	 */
+	public void writeStringData(String text) {
+		boolean is16bitEncoded = StringUtil.hasMultibyte(text);
+		// calculate total size of the header and first encoded char
+		int keepTogetherSize = 1 + 1; // ushort len, at least one character byte
+		int optionFlags = 0x00;
+		if (is16bitEncoded) {
+			optionFlags |= 0x01;
+			keepTogetherSize += 1; // one extra byte for first char
+		}
+		writeContinueIfRequired(keepTogetherSize);
+		writeByte(optionFlags);
+		writeCharacterData(text, is16bitEncoded);
+	}
+	/**
+	 * Writes a unicode string complete with header and character data.  This includes:
+	 * <ul>
+	 * <li>ushort length</li>
+	 * <li>byte optionFlags</li>
+	 * <li>ushort numberOfRichTextRuns (optional)</li>
+	 * <li>ushort extendedDataSize (optional)</li>
+	 * <li>encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)</li>
+	 * </ul>
+	 *
+	 * The following bits of the 'optionFlags' byte will be set as appropriate:
+	 * <table border='1'>
+	 * <tr><th>Mask</th><th>Description</th></tr>
+	 * <tr><td>0x01</td><td>is16bitEncoded</td></tr>
+	 * <tr><td>0x04</td><td>hasExtendedData</td></tr>
+	 * <tr><td>0x08</td><td>isRichText</td></tr>
+	 * </table>
+	 * Notes:
+	 * <ul>
+	 * <li>The value of the 'is16bitEncoded' flag is determined by the actual character data
+	 * of <tt>text</tt></li>
+	 * <li>The string header fields are never separated (by a {@link ContinueRecord}) from the
+	 * first chunk of character data (i.e. the first character is always encoded in the same
+	 * record as the string header).</li>
+	 * </ul>
+	 */
+	public void writeString(String text, int numberOfRichTextRuns, int extendedDataSize) {
+		boolean is16bitEncoded = StringUtil.hasMultibyte(text);
+		// calculate total size of the header and first encoded char
+		int keepTogetherSize = 2 + 1 + 1; // ushort len, byte optionFlags, at least one character byte
+		int optionFlags = 0x00;
+		if (is16bitEncoded) {
+			optionFlags |= 0x01;
+			keepTogetherSize += 1; // one extra byte for first char
+		}
+		if (numberOfRichTextRuns > 0) {
+			optionFlags |= 0x08;
+			keepTogetherSize += 2;
+		}
+		if (extendedDataSize > 0) {
+			optionFlags |= 0x04;
+			keepTogetherSize += 4;
+		}
+		writeContinueIfRequired(keepTogetherSize);
+		writeShort(text.length());
+		writeByte(optionFlags);
+		if (numberOfRichTextRuns > 0) {
+			writeShort(numberOfRichTextRuns);
+		}
+		if (extendedDataSize > 0) {
+			writeInt(extendedDataSize);
+		}
+		writeCharacterData(text, is16bitEncoded);
+	}
+
+
+	private void writeCharacterData(String text, boolean is16bitEncoded) {
+		int nChars = text.length();
+		int i=0;
+		if (is16bitEncoded) {
+			while(true) {
+				int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 2);
+				for ( ; nWritableChars > 0; nWritableChars--) {
+					_ulrOutput.writeShort(text.charAt(i++));
+				}
+				if (i >= nChars) {
+					break;
+				}
+				writeContinue();
+				writeByte(0x01);
+			}
+		} else {
+			while(true) {
+				int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 1);
+				for ( ; nWritableChars > 0; nWritableChars--) {
+					_ulrOutput.writeByte(text.charAt(i++));
+				}
+				if (i >= nChars) {
+					break;
+				}
+				writeContinue();
+				writeByte(0x00);
+			}
+		}
+	}
+
+	public void write(byte[] b) {
+		writeContinueIfRequired(b.length);
+		_ulrOutput.write(b);
+	}
+	public void write(byte[] b, int offset, int len) {
+		writeContinueIfRequired(len);
+		_ulrOutput.write(b, offset, len);
+	}
+	public void writeByte(int v) {
+		writeContinueIfRequired(1);
+		_ulrOutput.writeByte(v);
+	}
+	public void writeDouble(double v) {
+		writeContinueIfRequired(8);
+		_ulrOutput.writeDouble(v);
+	}
+	public void writeInt(int v) {
+		writeContinueIfRequired(4);
+		_ulrOutput.writeInt(v);
+	}
+	public void writeLong(long v) {
+		writeContinueIfRequired(8);
+		_ulrOutput.writeLong(v);
+	}
+	public void writeShort(int v) {
+		writeContinueIfRequired(2);
+		_ulrOutput.writeShort(v);
+	}
+
+	/**
+	 * Allows optimised usage of {@link ContinuableRecordOutput} for sizing purposes only.
+	 */
+	private static final LittleEndianOutput NOPOutput = new DelayableLittleEndianOutput() {
+
+		public LittleEndianOutput createDelayedOutput(int size) {
+			return this;
+		}
+		public void write(byte[] b) {
+			// does nothing
+		}
+		public void write(byte[] b, int offset, int len) {
+			// does nothing
+		}
+		public void writeByte(int v) {
+			// does nothing
+		}
+		public void writeDouble(double v) {
+			// does nothing
+		}
+		public void writeInt(int v) {
+			// does nothing
+		}
+		public void writeLong(long v) {
+			// does nothing
+		}
+		public void writeShort(int v) {
+			// does nothing
+		}
+	};
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java	(revision 28000)
@@ -0,0 +1,114 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.cont;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.DelayableLittleEndianOutput;
+import org.apache.poi.util.LittleEndianByteArrayOutputStream;
+import org.apache.poi.util.LittleEndianOutput;
+/**
+ * Allows the writing of BIFF records when the 'ushort size' header field is not known in advance.
+ * When the client is finished writing data, it calls {@link #terminate()}, at which point this
+ * class updates the 'ushort size' with its final value.
+ *
+ * @author Josh Micich
+ */
+final class UnknownLengthRecordOutput implements LittleEndianOutput {
+	private static final int MAX_DATA_SIZE = RecordInputStream.MAX_RECORD_DATA_SIZE;
+
+	private final LittleEndianOutput _originalOut;
+	/** for writing the 'ushort size'  field once its value is known */
+	private final LittleEndianOutput _dataSizeOutput;
+	private final byte[] _byteBuffer;
+	private LittleEndianOutput _out;
+	private int _size;
+
+	public UnknownLengthRecordOutput(LittleEndianOutput out, int sid) {
+		_originalOut = out;
+		out.writeShort(sid);
+		if (out instanceof DelayableLittleEndianOutput) {
+			// optimisation
+			DelayableLittleEndianOutput dleo = (DelayableLittleEndianOutput) out;
+			_dataSizeOutput = dleo.createDelayedOutput(2);
+			_byteBuffer = null;
+			_out = out;
+		} else {
+			// otherwise temporarily write all subsequent data to a buffer
+			_dataSizeOutput = out;
+			_byteBuffer = new byte[RecordInputStream.MAX_RECORD_DATA_SIZE];
+			_out = new LittleEndianByteArrayOutputStream(_byteBuffer, 0);
+		}
+	}
+	/**
+	 * includes 4 byte header
+	 */
+	public int getTotalSize() {
+		return 4 + _size;
+	}
+	public int getAvailableSpace() {
+		if (_out == null) {
+			throw new IllegalStateException("Record already terminated");
+		}
+		return MAX_DATA_SIZE - _size;
+	}
+	/**
+	 * Finishes writing the current record and updates 'ushort size' field.<br/>
+	 * After this method is called, only {@link #getTotalSize()} may be called.
+	 */
+	public void terminate() {
+		if (_out == null) {
+			throw new IllegalStateException("Record already terminated");
+		}
+		_dataSizeOutput.writeShort(_size);
+		if (_byteBuffer != null) {
+			_originalOut.write(_byteBuffer, 0, _size);
+			_out = null;
+			return;
+		}
+		_out = null;
+	}
+
+	public void write(byte[] b) {
+		_out.write(b);
+		_size += b.length;
+	}
+	public void write(byte[] b, int offset, int len) {
+		_out.write(b, offset, len);
+		_size += len;
+	}
+	public void writeByte(int v) {
+		_out.writeByte(v);
+		_size += 1;
+	}
+	public void writeDouble(double v) {
+		_out.writeDouble(v);
+		_size += 8;
+	}
+	public void writeInt(int v) {
+		_out.writeInt(v);
+		_size += 4;
+	}
+	public void writeLong(long v) {
+		_out.writeLong(v);
+		_size += 8;
+	}
+	public void writeShort(int v) {
+		_out.writeShort(v);
+		_size += 2;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java	(revision 28000)
@@ -0,0 +1,124 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
+import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
+
+
+/**
+ * This class provides the base functionality for Excel sheet functions
+ * There are two kinds of function Ptgs - tFunc and tFuncVar
+ * Therefore, this class will have ONLY two subclasses
+ * @author  Avik Sengupta
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ */
+public abstract class AbstractFunctionPtg extends OperationPtg {
+
+    /** All external functions have function index 255 */
+    private static final short FUNCTION_INDEX_EXTERNAL = 255;
+
+    private final byte returnClass;
+
+    private final byte _numberOfArgs;
+    private final short _functionIndex;
+
+    protected AbstractFunctionPtg(int functionIndex, int pReturnClass, byte[] paramTypes, int nParams) {
+        _numberOfArgs = (byte) nParams;
+        _functionIndex = (short) functionIndex;
+        returnClass = (byte) pReturnClass;
+    }
+    public final boolean isBaseToken() {
+        return false;
+    }
+
+    public final String toString() {
+        StringBuilder sb = new StringBuilder(64);
+        sb.append(getClass().getName()).append(" [");
+        sb.append(lookupName(_functionIndex));
+        sb.append(" nArgs=").append(_numberOfArgs);
+        sb.append("]");
+        return sb.toString();
+    }
+
+    public final short getFunctionIndex() {
+        return _functionIndex;
+    }
+    public final int getNumberOfOperands() {
+        return _numberOfArgs;
+    }
+
+    public final String getName() {
+        return lookupName(_functionIndex);
+    }
+    /**
+     * external functions get some special processing
+     * @return <code>true</code> if this is an external function
+     */
+    public final boolean isExternalFunction() {
+        return _functionIndex == FUNCTION_INDEX_EXTERNAL;
+    }
+
+    public final String toFormulaString() {
+        return getName();
+    }
+
+    public String toFormulaString(String[] operands) {
+        StringBuilder buf = new StringBuilder();
+
+        if(isExternalFunction()) {
+            buf.append(operands[0]); // first operand is actually the function name
+            appendArgs(buf, 1, operands);
+        } else {
+            buf.append(getName());
+            appendArgs(buf, 0, operands);
+        }
+        return buf.toString();
+    }
+
+    private static void appendArgs(StringBuilder buf, int firstArgIx, String[] operands) {
+        buf.append('(');
+        for (int i=firstArgIx;i<operands.length;i++) {
+            if (i>firstArgIx) {
+                buf.append(',');
+            }
+            buf.append(operands[i]);
+        }
+        buf.append(")");
+    }
+
+    public abstract int getSize();
+
+
+    protected final String lookupName(short index) {
+        if(index == FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL) {
+            return "#external#";
+        }
+        FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(index);
+        if(fm == null) {
+            throw new RuntimeException("bad function index (" + index + ")");
+        }
+        return fm.getName();
+    }
+
+
+    public byte getDefaultOperandClass() {
+        return returnClass;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AddPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AddPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AddPtg.java	(revision 28000)
@@ -0,0 +1,54 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ * Addition operator PTG the "+" binomial operator.  If you need more 
+ * explanation than that then well...We really can't help you here.
+ * @author  Andrew C. Oliver (acoliver@apache.org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class AddPtg extends ValueOperatorPtg {
+    public final static byte sid  = 0x03;
+    
+    private final static String ADD = "+";
+
+    public static final ValueOperatorPtg instance = new AddPtg();
+
+    private AddPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    public int getNumberOfOperands() {
+        return 2;
+    }
+       
+   /** implementation of method from OperationsPtg*/  
+    public String toFormulaString(String[] operands) {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append(operands[ 0 ]);
+        buffer.append(ADD);
+        buffer.append(operands[ 1 ]);
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Area2DPtgBase.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Area2DPtgBase.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Area2DPtgBase.java	(revision 28000)
@@ -0,0 +1,60 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Common superclass of 2-D area refs
+ */
+public abstract class Area2DPtgBase extends AreaPtgBase {
+	private final static int SIZE = 9;
+
+	protected Area2DPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+		super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
+	}
+
+	protected Area2DPtgBase(LittleEndianInput in)  {
+		readCoordinates(in);
+	}
+
+	protected abstract byte getSid();
+
+	public final void write(LittleEndianOutput out) {
+		out.writeByte(getSid() + getPtgClass());
+		writeCoordinates(out);
+	}
+
+	public final int getSize() {
+		return SIZE;
+	}
+
+	public final String toFormulaString() {
+		return formatReferenceAsString();
+	}
+
+	public final String toString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append(getClass().getName());
+		sb.append(" [");
+		sb.append(formatReferenceAsString());
+		sb.append("]");
+		return sb.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Area3DPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Area3DPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Area3DPtg.java	(revision 28000)
@@ -0,0 +1,81 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.ss.formula.ExternSheetReferenceToken;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Area 3D Ptg - 3D reference (Sheet + Area)<P>
+ * Description:  Defined a area in Extern Sheet. <P>
+ * REFERENCE:  <P>
+ * @author Libin Roman (Vista Portal LDT. Developer)
+ * @author avik
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class Area3DPtg extends AreaPtgBase implements WorkbookDependentFormula, ExternSheetReferenceToken {
+	public final static byte sid = 0x3b;
+	private final static int SIZE = 11; // 10 + 1 for Ptg
+
+	private int field_1_index_extern_sheet;
+
+
+	public Area3DPtg(LittleEndianInput in)  {
+		field_1_index_extern_sheet = in.readShort();
+		readCoordinates(in);
+	}
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append(getClass().getName());
+		sb.append(" [");
+		sb.append("sheetIx=").append(getExternSheetIndex());
+		sb.append(" ! ");
+		sb.append(formatReferenceAsString());
+		sb.append("]");
+		return sb.toString();
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+		out.writeShort(field_1_index_extern_sheet);
+		writeCoordinates(out);
+	}
+
+	public int getSize() {
+		return SIZE;
+	}
+
+	public int getExternSheetIndex() {
+		return field_1_index_extern_sheet;
+	}
+
+	/**
+	 * @return text representation of this area reference that can be used in text
+	 *  formulas. The sheet name will get properly delimited if required.
+	 */
+	public String toFormulaString(FormulaRenderingWorkbook book) {
+		return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, formatReferenceAsString());
+	}
+	public String toFormulaString() {
+		throw new RuntimeException("3D references need a workbook to determine formula text");
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaErrPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaErrPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaErrPtg.java	(revision 28000)
@@ -0,0 +1,63 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * AreaErr - handles deleted cell area references.
+ *
+ * @author Daniel Noll (daniel at nuix dot com dot au)
+ */
+public final class AreaErrPtg extends OperandPtg {
+	public final static byte sid = 0x2B;
+	private final int unused1;
+	private final int unused2;
+
+	public AreaErrPtg() {
+		unused1 = 0;
+		unused2 = 0;
+	}
+
+	public AreaErrPtg(LittleEndianInput in)  {
+		// 8 bytes unused:
+		unused1 = in.readInt();
+		unused2 = in.readInt();
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+		out.writeInt(unused1);
+		out.writeInt(unused2);
+	}
+
+	public String toFormulaString() {
+		return HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF);
+	}
+
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_REF;
+	}
+
+	public int getSize() {
+		return 9;
+	}
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaI.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaI.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaI.java	(revision 28000)
@@ -0,0 +1,43 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ * Common interface for AreaPtg and Area3DPtg, and their child classes.
+ */
+public interface AreaI {
+	/**
+	 * @return the first row in the area
+	 */
+	public int getFirstRow();
+
+	/**
+	 * @return last row in the range (x2 in x1,y1-x2,y2)
+	 */
+	public int getLastRow();
+
+	/**
+	 * @return the first column number in the area.
+	 */
+	public int getFirstColumn();
+
+	/**
+	 * @return lastcolumn in the area
+	 */
+	public int getLastColumn();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaNPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaNPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaNPtg.java	(revision 28000)
@@ -0,0 +1,36 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianInput;
+
+/**
+ * Specifies a rectangular area of cells A1:A4 for instance.
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class AreaNPtg extends Area2DPtgBase {
+	public final static short sid = 0x2D;
+
+	public AreaNPtg(LittleEndianInput in)  {
+		super(in);
+	}
+
+	protected byte getSid() {
+		return sid;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaPtg.java	(revision 28000)
@@ -0,0 +1,38 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianInput;
+
+/**
+ * Specifies a rectangular area of cells A1:A4 for instance.
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class AreaPtg extends Area2DPtgBase {
+	public final static short sid  = 0x25;
+
+	public AreaPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+		super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
+	}
+	public AreaPtg(LittleEndianInput in)  {
+		super(in);
+	}
+	protected byte getSid() {
+		return sid;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaPtgBase.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaPtgBase.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AreaPtgBase.java	(revision 28000)
@@ -0,0 +1,226 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Specifies a rectangular area of cells A1:A4 for instance.
+ * @author  andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public abstract class AreaPtgBase extends OperandPtg implements AreaI {
+
+	/** zero based, unsigned 16 bit */
+	private int             field_1_first_row;
+	/** zero based, unsigned 16 bit */
+	private int             field_2_last_row;
+	/** zero based, unsigned 8 bit */
+	private int             field_3_first_column;
+	/** zero based, unsigned 8 bit */
+	private int             field_4_last_column;
+
+	private final static BitField   rowRelative = BitFieldFactory.getInstance(0x8000);
+	private final static BitField   colRelative = BitFieldFactory.getInstance(0x4000);
+	private final static BitField   columnMask      = BitFieldFactory.getInstance(0x3FFF);
+
+	protected AreaPtgBase() {
+		// do nothing
+	}
+
+	protected AreaPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn,
+			boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+
+		if (lastRow > firstRow) {
+			setFirstRow(firstRow);
+			setLastRow(lastRow);
+			setFirstRowRelative(firstRowRelative);
+			setLastRowRelative(lastRowRelative);
+		} else {
+			setFirstRow(lastRow);
+			setLastRow(firstRow);
+			setFirstRowRelative(lastRowRelative);
+			setLastRowRelative(firstRowRelative);
+		}
+
+		if (lastColumn > firstColumn) {
+			setFirstColumn(firstColumn);
+			setLastColumn(lastColumn);
+			setFirstColRelative(firstColRelative);
+			setLastColRelative(lastColRelative);
+		} else {
+			setFirstColumn(lastColumn);
+			setLastColumn(firstColumn);
+			setFirstColRelative(lastColRelative);
+			setLastColRelative(firstColRelative);
+		}
+	}
+
+	protected final void readCoordinates(LittleEndianInput in)  {
+		field_1_first_row = in.readUShort();
+		field_2_last_row = in.readUShort();
+		field_3_first_column = in.readUShort();
+		field_4_last_column = in.readUShort();
+	}
+	protected final void writeCoordinates(LittleEndianOutput out) {
+		out.writeShort(field_1_first_row);
+		out.writeShort(field_2_last_row);
+		out.writeShort(field_3_first_column);
+		out.writeShort(field_4_last_column);
+	}
+
+	/**
+	 * @return the first row in the area
+	 */
+	public final int getFirstRow() {
+		return field_1_first_row;
+	}
+
+	/**
+	 * sets the first row
+	 * @param rowIx number (0-based)
+	 */
+	public final void setFirstRow(int rowIx) {
+		field_1_first_row = rowIx;
+	}
+
+	/**
+	 * @return last row in the range (x2 in x1,y1-x2,y2)
+	 */
+	public final int getLastRow() {
+		return field_2_last_row;
+	}
+
+	/**
+	 * @param rowIx last row number in the area
+	 */
+	public final void setLastRow(int rowIx) {
+		field_2_last_row = rowIx;
+	}
+
+	/**
+	 * @return the first column number in the area.
+	 */
+	public final int getFirstColumn() {
+		return columnMask.getValue(field_3_first_column);
+	}
+
+	/**
+	 * @return whether or not the first row is a relative reference or not.
+	 */
+	public final boolean isFirstRowRelative() {
+		return rowRelative.isSet(field_3_first_column);
+	}
+
+	/**
+	 * sets the first row to relative or not
+	 * @param rel is relative or not.
+	 */
+	public final void setFirstRowRelative(boolean rel) {
+		field_3_first_column=rowRelative.setBoolean(field_3_first_column,rel);
+	}
+
+	/**
+	 * @return isrelative first column to relative or not
+	 */
+	public final boolean isFirstColRelative() {
+		return colRelative.isSet(field_3_first_column);
+	}
+
+	/**
+	 * set whether the first column is relative
+	 */
+	public final void setFirstColRelative(boolean rel) {
+		field_3_first_column=colRelative.setBoolean(field_3_first_column,rel);
+	}
+
+	/**
+	 * set the first column in the area
+	 */
+	public final void setFirstColumn(int colIx) {
+		field_3_first_column=columnMask.setValue(field_3_first_column, colIx);
+	}
+
+
+	/**
+	 * @return lastcolumn in the area
+	 */
+	public final int getLastColumn() {
+		return columnMask.getValue(field_4_last_column);
+	}
+
+	/**
+	 * @return last row relative or not
+	 */
+	public final boolean isLastRowRelative() {
+		return rowRelative.isSet(field_4_last_column);
+	}
+
+	/**
+	 * set whether the last row is relative or not
+	 * @param rel <code>true</code> if the last row relative, else
+	 * <code>false</code>
+	 */
+	public final void setLastRowRelative(boolean rel) {
+		field_4_last_column=rowRelative.setBoolean(field_4_last_column,rel);
+	}
+
+	/**
+	 * @return lastcol relative or not
+	 */
+	public final boolean isLastColRelative() {
+		return colRelative.isSet(field_4_last_column);
+	}
+
+	/**
+	 * set whether the last column should be relative or not
+	 */
+	public final void setLastColRelative(boolean rel) {
+		field_4_last_column=colRelative.setBoolean(field_4_last_column,rel);
+	}
+
+	/**
+	 * set the last column in the area
+	 */
+	public final void setLastColumn(int colIx) {
+		field_4_last_column=columnMask.setValue(field_4_last_column, colIx);
+	}
+
+	protected final String formatReferenceAsString() {
+		CellReference topLeft = new CellReference(getFirstRow(),getFirstColumn(),!isFirstRowRelative(),!isFirstColRelative());
+		CellReference botRight = new CellReference(getLastRow(),getLastColumn(),!isLastRowRelative(),!isLastColRelative());
+
+		if(AreaReference.isWholeColumnReference(topLeft, botRight)) {
+			return (new AreaReference(topLeft, botRight)).formatAsString();
+		}
+		return topLeft.formatAsString() + ":" + botRight.formatAsString();
+	}
+
+	public String toFormulaString() {
+		return formatReferenceAsString();
+	}
+
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_REF;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ArrayPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ArrayPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ArrayPtg.java	(revision 28000)
@@ -0,0 +1,229 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.hssf.record.constant.ConstantValueParser;
+import org.apache.poi.hssf.record.constant.ErrorConstant;
+import org.apache.poi.ss.util.NumberToTextConverter;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * ArrayPtg - handles arrays
+ *
+ * The ArrayPtg is a little weird, the size of the Ptg when parsing initially only
+ * includes the Ptg sid and the reserved bytes. The next Ptg in the expression then follows.
+ * It is only after the "size" of all the Ptgs is met, that the ArrayPtg data is actually
+ * held after this. So Ptg.createParsedExpression keeps track of the number of
+ * ArrayPtg elements and need to parse the data upto the FORMULA record size.
+ *
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class ArrayPtg extends Ptg {
+	public static final byte sid  = 0x20;
+
+	private static final int RESERVED_FIELD_LEN = 7;
+	/**
+	 * The size of the plain tArray token written within the standard formula tokens
+	 * (not including the data which comes after all formula tokens)
+	 */
+	public static final int PLAIN_TOKEN_SIZE = 1+RESERVED_FIELD_LEN;
+
+	// 7 bytes of data (stored as an int, short and byte here)
+	private final int _reserved0Int;
+	private final int _reserved1Short;
+	private final int _reserved2Byte;
+
+	// data from these fields comes after the Ptg data of all tokens in current formula
+	private final int  _nColumns;
+	private final int _nRows;
+	private final Object[] _arrayValues;
+
+	ArrayPtg(int reserved0, int reserved1, int reserved2, int nColumns, int nRows, Object[] arrayValues) {
+		_reserved0Int = reserved0;
+		_reserved1Short = reserved1;
+		_reserved2Byte = reserved2;
+		_nColumns = nColumns;
+		_nRows = nRows;
+		_arrayValues = arrayValues;
+	}
+
+	public boolean isBaseToken() {
+		return false;
+	}
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer("[ArrayPtg]\n");
+
+		sb.append("nRows = ").append(getRowCount()).append("\n");
+		sb.append("nCols = ").append(getColumnCount()).append("\n");
+		if (_arrayValues == null) {
+			sb.append("  #values#uninitialised#\n");
+		} else {
+			sb.append("  ").append(toFormulaString());
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Note - (2D) array elements are stored row by row
+	 * @return the index into the internal 1D array for the specified column and row
+	 */
+	/* package */ int getValueIndex(int colIx, int rowIx) {
+		if(colIx < 0 || colIx >= _nColumns) {
+			throw new IllegalArgumentException("Specified colIx (" + colIx
+					+ ") is outside the allowed range (0.." + (_nColumns-1) + ")");
+		}
+		if(rowIx < 0 || rowIx >= _nRows) {
+			throw new IllegalArgumentException("Specified rowIx (" + rowIx
+					+ ") is outside the allowed range (0.." + (_nRows-1) + ")");
+		}
+		return rowIx * _nColumns + colIx;
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+		out.writeInt(_reserved0Int);
+		out.writeShort(_reserved1Short);
+		out.writeByte(_reserved2Byte);
+	}
+
+	public int writeTokenValueBytes(LittleEndianOutput out) {
+
+		out.writeByte(_nColumns-1);
+		out.writeShort(_nRows-1);
+		ConstantValueParser.encode(out, _arrayValues);
+		return 3 + ConstantValueParser.getEncodedSize(_arrayValues);
+	}
+
+	public int getRowCount() {
+		return _nRows;
+	}
+
+	public int getColumnCount() {
+		return _nColumns;
+	}
+
+	/** This size includes the size of the array Ptg plus the Array Ptg Token value size*/
+	public int getSize() {
+		return PLAIN_TOKEN_SIZE
+			// data written after the all tokens:
+			+ 1 + 2 // column, row
+			+ ConstantValueParser.getEncodedSize(_arrayValues);
+	}
+
+	public String toFormulaString() {
+		StringBuffer b = new StringBuffer();
+		b.append("{");
+	  	for (int y=0;y<getRowCount();y++) {
+			if (y > 0) {
+				b.append(";");
+			}
+			for (int x=0;x<getColumnCount();x++) {
+			  	if (x > 0) {
+					b.append(",");
+				}
+		  		Object o = _arrayValues[getValueIndex(x, y)];
+		  		b.append(getConstantText(o));
+		  	}
+		  }
+		b.append("}");
+		return b.toString();
+	}
+
+	private static String getConstantText(Object o) {
+
+		if (o == null) {
+			throw new RuntimeException("Array item cannot be null");
+		}
+		if (o instanceof String) {
+			return "\"" + (String)o + "\"";
+		}
+		if (o instanceof Double) {
+			return NumberToTextConverter.toText(((Double)o).doubleValue());
+		}
+		if (o instanceof Boolean) {
+			return ((Boolean)o).booleanValue() ? "TRUE" : "FALSE";
+		}
+		if (o instanceof ErrorConstant) {
+			return ((ErrorConstant)o).getText();
+		}
+		throw new IllegalArgumentException("Unexpected constant class (" + o.getClass().getName() + ")");
+	}
+
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_ARRAY;
+	}
+
+	/**
+	 * Represents the initial plain tArray token (without the constant data that trails the whole
+	 * formula).  Objects of this class are only temporary and cannot be used as {@link Ptg}s.
+	 * These temporary objects get converted to {@link ArrayPtg} by the
+	 * {@link #finishReading(LittleEndianInput)} method.
+	 */
+	static final class Initial extends Ptg {
+		private final int _reserved0;
+		private final int _reserved1;
+		private final int _reserved2;
+
+		public Initial(LittleEndianInput in) {
+			_reserved0 = in.readInt();
+			_reserved1 = in.readUShort();
+			_reserved2 = in.readUByte();
+		}
+		private static RuntimeException invalid() {
+			throw new IllegalStateException("This object is a partially initialised tArray, and cannot be used as a Ptg");
+		}
+		public byte getDefaultOperandClass() {
+			throw invalid();
+		}
+		public int getSize() {
+			return PLAIN_TOKEN_SIZE;
+		}
+		public boolean isBaseToken() {
+			return false;
+		}
+		public String toFormulaString() {
+			throw invalid();
+		}
+		public void write(LittleEndianOutput out) {
+			throw invalid();
+		}
+		/**
+		 * Read in the actual token (array) values. This occurs
+		 * AFTER the last Ptg in the expression.
+		 * See page 304-305 of Excel97-2007BinaryFileFormat(xls)Specification.pdf
+		 */
+		public ArrayPtg finishReading(LittleEndianInput in) {
+			int nColumns = in.readUByte();
+			short nRows = in.readShort();
+			//The token_1_columns and token_2_rows do not follow the documentation.
+			//The number of physical rows and columns is actually +1 of these values.
+			//Which is not explicitly documented.
+			nColumns++;
+			nRows++;
+
+			int totalCount = nRows * nColumns;
+			Object[] arrayValues = ConstantValueParser.parse(in, totalCount);
+
+			ArrayPtg result = new ArrayPtg(_reserved0, _reserved1, _reserved2, nColumns, nRows, arrayValues);
+			result.setClass(getPtgClass());
+			return result;
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AttrPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AttrPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/AttrPtg.java	(revision 28000)
@@ -0,0 +1,189 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * "Special Attributes"
+ * This seems to be a Misc Stuff and Junk record.  One function it serves is
+ * in SUM functions (i.e. SUM(A1:A3) causes an area PTG then an ATTR with the SUM option set)
+ * @author  andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class AttrPtg extends ControlPtg {
+    public final static byte sid  = 0x19;
+    private final static int  SIZE = 4;
+    private final byte _options;
+    private final short _data;
+
+    /** only used for tAttrChoose: table of offsets to starts of args */
+    private final int[] _jumpTable;
+    /** only used for tAttrChoose: offset to the tFuncVar for CHOOSE() */
+    private final int   _chooseFuncOffset;
+
+    // flags 'volatile' and 'space', can be combined.
+    // OOO spec says other combinations are theoretically possible but not likely to occur.
+    private static final BitField semiVolatile = BitFieldFactory.getInstance(0x01);
+    private static final BitField optiIf       = BitFieldFactory.getInstance(0x02);
+    private static final BitField optiChoose   = BitFieldFactory.getInstance(0x04);
+    private static final BitField optiSkip     = BitFieldFactory.getInstance(0x08);
+    private static final BitField optiSum      = BitFieldFactory.getInstance(0x10);
+    private static final BitField baxcel       = BitFieldFactory.getInstance(0x20); // 'assignment-style formula in a macro sheet'
+    private static final BitField space        = BitFieldFactory.getInstance(0x40);
+
+
+    public AttrPtg(LittleEndianInput in) {
+        _options = in.readByte();
+        _data    = in.readShort();
+        if (isOptimizedChoose()) {
+            int nCases = _data;
+            int[] jumpTable = new int[nCases];
+            for (int i = 0; i < jumpTable.length; i++) {
+                jumpTable[i] = in.readUShort();
+            }
+            _jumpTable = jumpTable;
+            _chooseFuncOffset = in.readUShort();
+        } else {
+            _jumpTable = null;
+            _chooseFuncOffset = -1;
+        }
+
+    }
+
+    public boolean isSemiVolatile() {
+        return semiVolatile.isSet(_options);
+    }
+
+    public boolean isOptimizedIf() {
+        return optiIf.isSet(_options);
+    }
+
+    public boolean isOptimizedChoose() {
+        return optiChoose.isSet(_options);
+    }
+
+    public boolean isSum() {
+        return optiSum.isSet(_options);
+    }
+    public boolean isSkip() {
+        return optiSkip.isSet(_options);
+    }
+
+    // lets hope no one uses this anymore
+    private boolean isBaxcel() {
+        return baxcel.isSet(_options);
+    }
+
+    public boolean isSpace() {
+        return space.isSet(_options);
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer(64);
+        sb.append(getClass().getName()).append(" [");
+
+        if(isSemiVolatile()) {
+            sb.append("volatile ");
+        }
+        if(isSpace()) {
+            sb.append("space count=").append((_data >> 8) & 0x00FF);
+            sb.append(" type=").append(_data & 0x00FF).append(" ");
+        }
+        // the rest seem to be mutually exclusive
+        if(isOptimizedIf()) {
+            sb.append("if dist=").append(_data);
+        } else if(isOptimizedChoose()) {
+            sb.append("choose nCases=").append(_data);
+        } else if(isSkip()) {
+            sb.append("skip dist=").append(_data);
+        } else if(isSum()) {
+            sb.append("sum ");
+        } else if(isBaxcel()) {
+            sb.append("assign ");
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    public void write(LittleEndianOutput out) {
+        out.writeByte(sid + getPtgClass());
+        out.writeByte(_options);
+        out.writeShort(_data);
+        int[] jt = _jumpTable;
+        if (jt != null) {
+            for (int i = 0; i < jt.length; i++) {
+                out.writeShort(jt[i]);
+            }
+            out.writeShort(_chooseFuncOffset);
+        }
+    }
+
+    public int getSize() {
+        if (_jumpTable != null) {
+            return SIZE + (_jumpTable.length + 1) * LittleEndian.SHORT_SIZE;
+        }
+        return SIZE;
+    }
+
+    public String toFormulaString(String[] operands) {
+        if(space.isSet(_options)) {
+            return operands[ 0 ];
+        } else if (optiIf.isSet(_options)) {
+            return toFormulaString() + "(" + operands[0] + ")";
+        } else if (optiSkip.isSet(_options)) {
+            return toFormulaString() + operands[0];   //goto isn't a real formula element should not show up
+        } else {
+            return toFormulaString() + "(" + operands[0] + ")";
+        }
+    }
+
+
+    public int getNumberOfOperands() {
+        return 1;
+    }
+
+   public String toFormulaString() {
+      if(semiVolatile.isSet(_options)) {
+        return "ATTR(semiVolatile)";
+      }
+      if(optiIf.isSet(_options)) {
+        return "IF";
+      }
+      if( optiChoose.isSet(_options)) {
+        return "CHOOSE";
+      }
+      if(optiSkip.isSet(_options)) {
+        return "";
+      }
+      if(optiSum.isSet(_options)) {
+        return "SUM";
+      }
+      if(baxcel.isSet(_options)) {
+        return "ATTR(baxcel)";
+      }
+      if(space.isSet(_options)) {
+        return "";
+      }
+      return "UNKNOWN ATTRIBUTE";
+     }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/BoolPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/BoolPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/BoolPtg.java	(revision 28000)
@@ -0,0 +1,62 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Boolean (boolean) Stores a (java) boolean value in a formula.
+ *
+ * @author Paul Krause (pkrause at soundbite dot com)
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class BoolPtg extends ScalarConstantPtg {
+	public static final int SIZE = 2;
+	public static final byte sid = 0x1D;
+
+	private static final BoolPtg FALSE = new BoolPtg(false);
+	private static final BoolPtg TRUE = new BoolPtg(true);
+
+	private final boolean _value;
+
+	private BoolPtg(boolean b) {
+		_value = b;
+	}
+
+	public static BoolPtg valueOf(boolean b) {
+		return b ? TRUE : FALSE;
+	}
+	public static BoolPtg read(LittleEndianInput in)  {
+		return valueOf(in.readByte() == 1);
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+		out.writeByte(_value ? 1 : 0);
+	}
+
+	public int getSize() {
+		return SIZE;
+	}
+
+	public String toFormulaString() {
+		return _value ? "TRUE" : "FALSE";
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ConcatPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ConcatPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ConcatPtg.java	(revision 28000)
@@ -0,0 +1,52 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ *
+ * @author  andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class ConcatPtg extends ValueOperatorPtg {
+    public final static byte sid  = 0x08;
+    
+    private final static String CONCAT = "&";
+    
+    public static final ValueOperatorPtg instance = new ConcatPtg();
+
+    private ConcatPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    public int getNumberOfOperands() {
+        return 2;
+    }
+       
+    public String toFormulaString(String[] operands) {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append(operands[ 0 ]);
+        buffer.append(CONCAT);
+        buffer.append(operands[ 1 ]);
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ControlPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ControlPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ControlPtg.java	(revision 28000)
@@ -0,0 +1,38 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ * Common superclass for 
+ * tExp
+ * tTbl
+ * tParen
+ * tNlr
+ * tAttr
+ * tSheet
+ * tEndSheet
+ */
+public abstract class ControlPtg extends Ptg {
+
+	public boolean isBaseToken() {
+		return true;
+	}
+	public final byte getDefaultOperandClass() {
+		throw new IllegalStateException("Control tokens are not classified");
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java	(revision 28000)
@@ -0,0 +1,63 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Deleted Area 3D Ptg - 3D referecnce (Sheet + Area)<P>
+ * Description:  Defined a area in Extern Sheet. <P>
+ * REFERENCE:  <P>
+ * @author Patrick Luby
+ * @version 1.0-pre
+ */
+public final class DeletedArea3DPtg extends OperandPtg implements WorkbookDependentFormula {
+	public final static byte sid = 0x3d;
+	private final int field_1_index_extern_sheet;
+	private final int unused1;
+	private final int unused2;
+	
+	public DeletedArea3DPtg(LittleEndianInput in)  {
+		field_1_index_extern_sheet = in.readUShort();
+		unused1 = in.readInt();
+		unused2 = in.readInt();
+	}
+	public String toFormulaString(FormulaRenderingWorkbook book) {
+		return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, 
+				HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF));
+	}
+	public String toFormulaString() {
+		throw new RuntimeException("3D references need a workbook to determine formula text");
+	}
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_REF;
+	}
+	public int getSize() {
+		return 11;
+	}
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+		out.writeShort(field_1_index_extern_sheet);
+		out.writeInt(unused1);
+		out.writeInt(unused2);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java	(revision 28000)
@@ -0,0 +1,63 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+
+import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Deleted Reference 3D Ptg <P>
+ * Description:  Defined a cell in extern sheet. <P>
+ * REFERENCE:  <P>
+ * @author Patrick Luby
+ * @version 1.0-pre
+ */
+public final class DeletedRef3DPtg extends OperandPtg implements WorkbookDependentFormula {
+	public final static byte sid  = 0x3c;
+	private final int field_1_index_extern_sheet;
+	private final int unused1;
+
+	/** Creates new DeletedRef3DPtg */
+	public DeletedRef3DPtg(LittleEndianInput in)  {
+		field_1_index_extern_sheet = in.readUShort();
+		unused1 = in.readInt();
+	}
+
+	public String toFormulaString(FormulaRenderingWorkbook book) {
+		return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, 
+				HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF));
+	}
+	public String toFormulaString() {
+		throw new RuntimeException("3D references need a workbook to determine formula text");
+	}
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_REF;
+	}
+	public int getSize() {
+		return 7;
+	}
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+		out.writeShort(field_1_index_extern_sheet);
+		out.writeInt(unused1);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/DividePtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/DividePtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/DividePtg.java	(revision 28000)
@@ -0,0 +1,50 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ * This PTG implements the standard binomial divide "/"
+ * @author  Andrew C. Oliver acoliver at apache dot org
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class DividePtg extends ValueOperatorPtg {
+    public final static byte sid  = 0x06;
+
+    public static final ValueOperatorPtg instance = new DividePtg();
+
+    private DividePtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    public int getNumberOfOperands() {
+        return 2;
+    }
+
+     public String toFormulaString(String[] operands) {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append(operands[ 0 ]);
+        buffer.append("/");
+        buffer.append(operands[ 1 ]);
+        return buffer.toString();
+    }      
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/EqualPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/EqualPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/EqualPtg.java	(revision 28000)
@@ -0,0 +1,50 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ *
+ * @author  andy
+ */
+public final class EqualPtg extends ValueOperatorPtg {
+    public final static byte sid  = 0x0b;
+
+    public static final ValueOperatorPtg instance = new EqualPtg();
+
+    private EqualPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    public int getNumberOfOperands() {
+        return 2;
+    }
+ 
+    public String toFormulaString(String[] operands) {
+         StringBuffer buffer = new StringBuffer();
+
+        
+        buffer.append(operands[ 0 ]);
+        buffer.append("=");
+        buffer.append(operands[ 1 ]);
+        return buffer.toString();
+    }       
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ErrPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ErrPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ErrPtg.java	(revision 28000)
@@ -0,0 +1,88 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author Daniel Noll (daniel at nuix dot com dot au)
+ */
+public final class ErrPtg extends ScalarConstantPtg {
+
+    /** <b>#NULL!</b>  - Intersection of two cell ranges is empty */
+    public static final ErrPtg NULL_INTERSECTION = new ErrPtg(HSSFErrorConstants.ERROR_NULL);
+    /** <b>#DIV/0!</b> - Division by zero */
+    public static final ErrPtg DIV_ZERO = new ErrPtg(HSSFErrorConstants.ERROR_DIV_0);
+    /** <b>#VALUE!</b> - Wrong type of operand */
+    public static final ErrPtg VALUE_INVALID = new ErrPtg(HSSFErrorConstants.ERROR_VALUE);
+    /** <b>#REF!</b> - Illegal or deleted cell reference */
+    public static final ErrPtg REF_INVALID = new ErrPtg(HSSFErrorConstants.ERROR_REF);
+    /** <b>#NAME?</b> - Wrong function or range name */
+    public static final ErrPtg NAME_INVALID = new ErrPtg(HSSFErrorConstants.ERROR_NAME);
+    /** <b>#NUM!</b> - Value range overflow */
+    public static final ErrPtg NUM_ERROR = new ErrPtg(HSSFErrorConstants.ERROR_NUM);
+    /** <b>#N/A</b> - Argument or function not available */
+    public static final ErrPtg N_A = new ErrPtg(HSSFErrorConstants.ERROR_NA);
+
+
+    public static final short sid  = 0x1c;
+    private static final int  SIZE = 2;
+    private final int field_1_error_code;
+
+    /** Creates new ErrPtg */
+
+    private ErrPtg(int errorCode) {
+        if(!HSSFErrorConstants.isValidCode(errorCode)) {
+            throw new IllegalArgumentException("Invalid error code (" + errorCode + ")");
+        }
+        field_1_error_code = errorCode;
+    }
+
+    public static ErrPtg read(LittleEndianInput in)  {
+        return valueOf(in.readByte());
+    }
+
+    public void write(LittleEndianOutput out) {
+        out.writeByte(sid + getPtgClass());
+        out.writeByte(field_1_error_code);
+    }
+
+    public String toFormulaString() {
+        return HSSFErrorConstants.getText(field_1_error_code);
+    }
+
+    public int getSize() {
+        return SIZE;
+    }
+
+
+    public static ErrPtg valueOf(int code) {
+        switch(code) {
+            case HSSFErrorConstants.ERROR_DIV_0: return DIV_ZERO;
+            case HSSFErrorConstants.ERROR_NA: return N_A;
+            case HSSFErrorConstants.ERROR_NAME: return NAME_INVALID;
+            case HSSFErrorConstants.ERROR_NULL: return NULL_INTERSECTION;
+            case HSSFErrorConstants.ERROR_NUM: return NUM_ERROR;
+            case HSSFErrorConstants.ERROR_REF: return REF_INVALID;
+            case HSSFErrorConstants.ERROR_VALUE: return VALUE_INVALID;
+        }
+        throw new RuntimeException("Unexpected error code (" + code + ")");
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ExpPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ExpPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ExpPtg.java	(revision 28000)
@@ -0,0 +1,69 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.hssf.record.RecordFormatException;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ *
+ * @author  andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @author dmui (save existing implementation)
+ */
+public final class ExpPtg extends ControlPtg {
+    private final static int  SIZE = 5;
+    public final static short sid  = 0x1;
+    private final int field_1_first_row;
+    private final int field_2_first_col;
+
+    public ExpPtg(LittleEndianInput in) {
+      field_1_first_row = in.readShort();
+      field_2_first_col = in.readShort();
+    }
+
+    public void write(LittleEndianOutput out) {
+        out.writeByte(sid + getPtgClass());
+        out.writeShort(field_1_first_row);
+        out.writeShort(field_2_first_col);
+    }
+
+    public int getSize() {
+        return SIZE;
+    }
+
+    public int getRow() {
+      return field_1_first_row;
+    }
+
+    public int getColumn() {
+      return field_2_first_col;
+    }
+
+    public String toFormulaString() {
+        throw new RecordFormatException("Coding Error: Expected ExpPtg to be converted from Shared to Non-Shared Formula by ValueRecordsAggregate, but it wasn't");
+    }
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer("[Array Formula or Shared Formula]\n");
+        buffer.append("row = ").append(getRow()).append("\n");
+        buffer.append("col = ").append(getColumn()).append("\n");
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ExternSheetNameResolver.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ExternSheetNameResolver.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ExternSheetNameResolver.java	(revision 28000)
@@ -0,0 +1,54 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+
+/**
+ * @author Josh Micich
+ */
+final class ExternSheetNameResolver {
+
+	private ExternSheetNameResolver() {
+		// no instances of this class
+	}
+
+	public static String prependSheetName(FormulaRenderingWorkbook book, int field_1_index_extern_sheet, String cellRefText) {
+		ExternalSheet externalSheet = book.getExternalSheet(field_1_index_extern_sheet);
+		StringBuffer sb;
+		if (externalSheet != null) {
+			String wbName = externalSheet.getWorkbookName();
+			String sheetName = externalSheet.getSheetName();
+			sb = new StringBuffer(wbName.length() + sheetName.length() + cellRefText.length() + 4);
+			SheetNameFormatter.appendFormat(sb, wbName, sheetName);
+		} else {
+			String sheetName = book.getSheetNameByExternSheet(field_1_index_extern_sheet);
+			sb = new StringBuffer(sheetName.length() + cellRefText.length() + 4);
+			if (sheetName.length() < 1) {
+				// What excel does if sheet has been deleted
+				sb.append("#REF"); // note - '!' added just once below
+			} else {
+				SheetNameFormatter.appendFormat(sb, sheetName);
+			}
+		}
+   		sb.append('!');
+		sb.append(cellRefText);
+		return sb.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/FuncPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/FuncPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/FuncPtg.java	(revision 28000)
@@ -0,0 +1,60 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
+import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author aviks
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @author Danny Mui (dmui at apache dot org) (Leftover handling)
+ */
+public final class FuncPtg extends AbstractFunctionPtg {
+
+    public final static byte sid  = 0x21;
+    public final static int  SIZE = 3;
+
+    public static FuncPtg create(LittleEndianInput in) {
+        return create(in.readUShort());
+    }
+
+    private FuncPtg(int funcIndex, FunctionMetadata fm) {
+        super(funcIndex, fm.getReturnClassCode(), fm.getParameterClassCodes(), fm.getMinParams());  // minParams same as max since these are not var-arg funcs
+    }
+
+    public static FuncPtg create(int functionIndex) {
+        FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(functionIndex);
+        if(fm == null) {
+            throw new RuntimeException("Invalid built-in function index (" + functionIndex + ")");
+        }
+        return new FuncPtg(functionIndex, fm);
+    }
+
+
+    public void write(LittleEndianOutput out) {
+        out.writeByte(sid + getPtgClass());
+        out.writeShort(getFunctionIndex());
+    }
+
+    public int getSize() {
+        return SIZE;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/FuncVarPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/FuncVarPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/FuncVarPtg.java	(revision 28000)
@@ -0,0 +1,61 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
+import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class FuncVarPtg extends AbstractFunctionPtg{
+
+    public final static byte sid  = 0x22;
+    private final static int  SIZE = 4;
+
+    private FuncVarPtg(int functionIndex, int returnClass, byte[] paramClasses, int numArgs) {
+        super(functionIndex, returnClass, paramClasses, numArgs);
+    }
+
+    /**Creates new function pointer from a byte array
+     * usually called while reading an excel file.
+     */
+    public static FuncVarPtg create(LittleEndianInput in)  {
+        return create(in.readByte(), in.readShort());
+    }
+
+    private static FuncVarPtg create(int numArgs, int functionIndex) {
+        FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(functionIndex);
+        if(fm == null) {
+            // Happens only as a result of a call to FormulaParser.parse(), with a non-built-in function name
+            return new FuncVarPtg(functionIndex, Ptg.CLASS_VALUE, new byte[] {Ptg.CLASS_VALUE}, numArgs);
+        }
+        return new FuncVarPtg(functionIndex, fm.getReturnClassCode(), fm.getParameterClassCodes(), numArgs);
+    }
+
+    public void write(LittleEndianOutput out) {
+        out.writeByte(sid + getPtgClass());
+        out.writeByte(getNumberOfOperands());
+        out.writeShort(getFunctionIndex());
+    }
+
+    public int getSize() {
+        return SIZE;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/GreaterEqualPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/GreaterEqualPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/GreaterEqualPtg.java	(revision 28000)
@@ -0,0 +1,53 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+
+/**
+ * PTG class to implement greater or equal to
+ *
+ * @author  fred at stsci dot edu
+ */
+public final class GreaterEqualPtg extends ValueOperatorPtg {
+    public final static byte sid  = 0x0c;
+
+    public static final ValueOperatorPtg instance = new GreaterEqualPtg();
+
+    private GreaterEqualPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    public int getNumberOfOperands() {
+        return 2;
+    }
+
+    public String toFormulaString(String[] operands) {
+         StringBuffer buffer = new StringBuffer();
+
+        buffer.append(operands[ 0 ]);
+
+        buffer.append(">=");
+        buffer.append(operands[ 1 ]);
+
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/GreaterThanPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/GreaterThanPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/GreaterThanPtg.java	(revision 28000)
@@ -0,0 +1,61 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+
+/**
+ * Greater than operator PTG ">"
+ * @author  Cameron Riley (criley at ekmail.com)
+ */
+public final class GreaterThanPtg extends ValueOperatorPtg {
+    public final static byte sid  = 0x0D;    
+    private final static String GREATERTHAN = ">";
+
+    public static final ValueOperatorPtg instance = new GreaterThanPtg();
+
+    private GreaterThanPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    /**
+     * Get the number of operands for the Less than operator
+     * @return int the number of operands
+     */
+    public int getNumberOfOperands() {
+        return 2;
+    }
+    
+    /** 
+     * Implementation of method from OperationsPtg
+     * @param operands a String array of operands
+     * @return String the Formula as a String
+     */  
+    public String toFormulaString(String[] operands) 
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append(operands[ 0 ]);
+        buffer.append(GREATERTHAN);
+        buffer.append(operands[ 1 ]);
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/IntPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/IntPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/IntPtg.java	(revision 28000)
@@ -0,0 +1,76 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Integer (unsigned short integer) Stores an unsigned short value (java int) in
+ * a formula
+ * 
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class IntPtg extends ScalarConstantPtg {
+	// 16 bit unsigned integer
+	private static final int MIN_VALUE = 0x0000;
+	private static final int MAX_VALUE = 0xFFFF;
+
+	/**
+	 * Excel represents integers 0..65535 with the tInt token.
+	 * 
+	 * @return <code>true</code> if the specified value is within the range of values 
+	 * <tt>IntPtg</tt> can represent.
+	 */
+	public static boolean isInRange(int i) {
+		return i >= MIN_VALUE && i <= MAX_VALUE;
+	}
+
+	public final static int SIZE = 3;
+	public final static byte sid = 0x1e;
+	private final int field_1_value;
+
+	public IntPtg(LittleEndianInput in)  {
+		this(in.readUShort());
+	}
+
+	public IntPtg(int value) {
+		if (!isInRange(value)) {
+			throw new IllegalArgumentException("value is out of range: " + value);
+		}
+		field_1_value = value;
+	}
+
+	public int getValue() {
+		return field_1_value;
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+		out.writeShort(getValue());
+	}
+
+	public int getSize() {
+		return SIZE;
+	}
+
+	public String toFormulaString() {
+		return String.valueOf(getValue());
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/IntersectionPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/IntersectionPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/IntersectionPtg.java	(revision 28000)
@@ -0,0 +1,62 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author Daniel Noll (daniel at nuix dot com dot au)
+ */
+public final class IntersectionPtg extends OperationPtg {
+	public final static byte sid = 0x0f;
+
+	public static final OperationPtg instance = new IntersectionPtg();
+
+	private IntersectionPtg() {
+		// enforce singleton
+	}
+
+	public final boolean isBaseToken() {
+		return true;
+	}
+
+	public int getSize() {
+		return 1;
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+	}
+
+	public String toFormulaString() {
+		return " ";
+	}
+
+	public String toFormulaString(String[] operands) {
+		StringBuffer buffer = new StringBuffer();
+
+		buffer.append(operands[0]);
+		buffer.append(" ");
+		buffer.append(operands[1]);
+		return buffer.toString();
+	}
+
+	public int getNumberOfOperands() {
+		return 2;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/LessEqualPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/LessEqualPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/LessEqualPtg.java	(revision 28000)
@@ -0,0 +1,53 @@
+        
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+
+
+
+/**
+ * Ptg class to implement less than or equal
+ *
+ * @author fred at stsci dot edu
+ */
+public final class LessEqualPtg extends ValueOperatorPtg {
+    public final static byte sid = 0x0a;
+
+    public static final ValueOperatorPtg instance = new LessEqualPtg();
+
+    private LessEqualPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    public int getNumberOfOperands() {
+        return 2;
+    }
+
+    public String toFormulaString(String[] operands) {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append( operands[0] );
+        buffer.append("<=");
+        buffer.append( operands[1] );
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/LessThanPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/LessThanPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/LessThanPtg.java	(revision 28000)
@@ -0,0 +1,64 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ * Less than operator PTG "<". The SID is taken from the 
+ * Openoffice.orgs Documentation of the Excel File Format,
+ * Table 3.5.7
+ * @author Cameron Riley (criley at ekmail.com)
+ */
+public final class LessThanPtg extends ValueOperatorPtg {
+    /** the sid for the less than operator as hex */
+    public final static byte sid  = 0x09;    
+
+    /** identifier for LESS THAN char */
+    private final static String LESSTHAN = "<";
+
+    public static final ValueOperatorPtg instance = new LessThanPtg();
+
+    private LessThanPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    /**
+     * Get the number of operands for the Less than operator
+     * @return int the number of operands
+     */
+    public int getNumberOfOperands() {
+        return 2;
+    }
+    
+     /** 
+     * Implementation of method from OperationsPtg
+     * @param operands a String array of operands
+     * @return String the Formula as a String
+     */  
+    public String toFormulaString(String[] operands) 
+    {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(operands[ 0 ]);
+        buffer.append(LESSTHAN);
+        buffer.append(operands[ 1 ]);
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MemAreaPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MemAreaPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MemAreaPtg.java	(revision 28000)
@@ -0,0 +1,66 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author Daniel Noll (daniel at nuix dot com dot au)
+ */
+public final class MemAreaPtg extends OperandPtg {
+	public final static short sid = 0x26;
+	private final static int SIZE = 7;
+	private final int field_1_reserved;
+	private final int field_2_subex_len;
+
+	/** Creates new MemAreaPtg */
+
+	public MemAreaPtg(LittleEndianInput in)  {
+		field_1_reserved = in.readInt();
+		field_2_subex_len = in.readShort();
+	}
+
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+		out.writeInt(field_1_reserved);
+		out.writeShort(field_2_subex_len);
+	}
+
+	public int getSize() {
+		return SIZE;
+	}
+
+	public String toFormulaString() {
+		return ""; // TODO: Not sure how to format this. -- DN
+	}
+
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_VALUE;
+	}
+
+	@Override
+	public final String toString() {
+		StringBuffer sb = new StringBuffer(64);
+		sb.append(getClass().getName()).append(" [len=");
+		sb.append(field_2_subex_len);
+		sb.append("]");
+		return sb.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MemErrPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MemErrPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MemErrPtg.java	(revision 28000)
@@ -0,0 +1,57 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * 
+ * @author andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @author Daniel Noll (daniel at nuix dot com dot au)
+ */
+public final class MemErrPtg extends OperandPtg {
+	public final static short sid = 0x27;
+	private final static int SIZE = 7;
+	private int field_1_reserved;
+	private short field_2_subex_len;
+
+	public MemErrPtg(LittleEndianInput in)  {
+		field_1_reserved = in.readInt();
+		field_2_subex_len = in.readShort();
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+		out.writeInt(field_1_reserved);
+		out.writeShort(field_2_subex_len);
+	}
+
+	public int getSize() {
+		return SIZE;
+	}
+
+	public String toFormulaString() {
+		return "ERR#";
+	}
+
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_VALUE;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MemFuncPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MemFuncPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MemFuncPtg.java	(revision 28000)
@@ -0,0 +1,68 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class MemFuncPtg extends OperandPtg {
+
+	public final static byte sid = 0x29;
+	private final int field_1_len_ref_subexpression;
+
+	/**
+	 * Creates new function pointer from a byte array usually called while
+	 * reading an excel file.
+	 */
+	public MemFuncPtg(LittleEndianInput in)  {
+		this(in.readUShort());
+	}
+
+	public MemFuncPtg(int subExprLen) {
+		field_1_len_ref_subexpression = subExprLen;
+	}
+
+	public int getSize() {
+		return 3;
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+		out.writeShort(field_1_len_ref_subexpression);
+	}
+
+	public String toFormulaString() {
+		return "";
+	}
+
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_REF;
+	}
+
+	@Override
+	public final String toString() {
+		StringBuffer sb = new StringBuffer(64);
+		sb.append(getClass().getName()).append(" [len=");
+		sb.append(field_1_len_ref_subexpression);
+		sb.append("]");
+		return sb.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MissingArgPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MissingArgPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MissingArgPtg.java	(revision 28000)
@@ -0,0 +1,51 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Missing Function Arguments
+ * 
+ * Avik Sengupta &lt;avik at apache.org&gt;
+ * 
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class MissingArgPtg extends ScalarConstantPtg {
+
+	private final static int SIZE = 1;
+	public final static byte sid = 0x16;
+
+	public static final Ptg instance = new MissingArgPtg();
+
+	private MissingArgPtg() {
+		// enforce singleton
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+	}
+
+	public int getSize() {
+		return SIZE;
+	}
+
+	public String toFormulaString() {
+		return " ";
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MultiplyPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MultiplyPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/MultiplyPtg.java	(revision 28000)
@@ -0,0 +1,50 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ * Implements the standard mathmatical multiplication - *
+ * @author  Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class MultiplyPtg extends ValueOperatorPtg {
+    public final static byte sid  = 0x05;
+
+    public static final ValueOperatorPtg instance = new MultiplyPtg();
+
+    private MultiplyPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    public int getNumberOfOperands() {
+        return 2;
+    }
+    
+    public String toFormulaString(String[] operands) {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append(operands[ 0 ]);
+        buffer.append("*");
+        buffer.append(operands[ 1 ]);
+        return buffer.toString();
+    }                  
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/NamePtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/NamePtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/NamePtg.java	(revision 28000)
@@ -0,0 +1,73 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * 
+ * @author andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class NamePtg extends OperandPtg implements WorkbookDependentFormula {
+	public final static short sid = 0x23;
+	private final static int SIZE = 5;
+	/** one-based index to defined name record */
+	private int field_1_label_index;
+	private short field_2_zero; // reserved must be 0
+
+
+	/** Creates new NamePtg */
+
+	public NamePtg(LittleEndianInput in)  {
+		field_1_label_index = in.readShort();
+		field_2_zero = in.readShort();
+	}
+
+	/**
+	 * @return zero based index to a defined name record in the LinkTable
+	 */
+	public int getIndex() {
+		return field_1_label_index - 1; // convert to zero based
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+		out.writeShort(field_1_label_index);
+		out.writeShort(field_2_zero);
+	}
+
+	public int getSize() {
+		return SIZE;
+	}
+
+	public String toFormulaString(FormulaRenderingWorkbook book) {
+		return book.getNameText(this);
+	}
+
+	public String toFormulaString() {
+		throw new RuntimeException("3D references need a workbook to determine formula text");
+	}
+
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_REF;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/NameXPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/NameXPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/NameXPtg.java	(revision 28000)
@@ -0,0 +1,85 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * 
+ * @author aviks
+ */
+public final class NameXPtg extends OperandPtg implements WorkbookDependentFormula {
+	public final static short sid = 0x39;
+	private final static int SIZE = 7;
+
+	/** index to REF entry in externsheet record */
+	private final int _sheetRefIndex;
+	/** index to defined name or externname table(1 based) */
+	private final int _nameNumber;
+	/** reserved must be 0 */
+	private final int _reserved;
+
+	private NameXPtg(int sheetRefIndex, int nameNumber, int reserved) {
+		_sheetRefIndex = sheetRefIndex;
+		_nameNumber = nameNumber;
+		_reserved = reserved;
+	}
+
+	public NameXPtg(LittleEndianInput in)  {
+		this(in.readUShort(), in.readUShort(), in.readUShort());
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+		out.writeShort(_sheetRefIndex);
+		out.writeShort(_nameNumber);
+		out.writeShort(_reserved);
+	}
+
+	public int getSize() {
+		return SIZE;
+	}
+
+	public String toFormulaString(FormulaRenderingWorkbook book) {
+		// -1 to convert definedNameIndex from 1-based to zero-based
+		return book.resolveNameXText(this);
+	}
+	public String toFormulaString() {
+		throw new RuntimeException("3D references need a workbook to determine formula text");
+	}
+	
+	public String toString(){
+	   String retValue = "NameXPtg:[sheetRefIndex:" + _sheetRefIndex + 
+	      " , nameNumber:" + _nameNumber + "]" ;
+	   return retValue;
+	}
+	
+	public byte getDefaultOperandClass() {
+		return Ptg.CLASS_VALUE;
+	}
+
+	public int getSheetRefIndex() {
+		return _sheetRefIndex;
+	}
+	public int getNameIndex() {
+		return _nameNumber - 1;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/NotEqualPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/NotEqualPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/NotEqualPtg.java	(revision 28000)
@@ -0,0 +1,52 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ * Ptg class to implement not equal
+ *
+ * @author fred at stsci dot edu
+ */
+public final class NotEqualPtg extends ValueOperatorPtg {
+    public final static byte sid = 0x0e;
+
+    public static final ValueOperatorPtg instance = new NotEqualPtg();
+
+    private NotEqualPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    public int getNumberOfOperands() {
+        return 2;
+    }
+
+    public String toFormulaString(String[] operands) {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append( operands[0] );
+
+        buffer.append("<>");
+        buffer.append( operands[1] );
+
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/NumberPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/NumberPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/NumberPtg.java	(revision 28000)
@@ -0,0 +1,60 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.ss.util.NumberToTextConverter;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Number Stores a floating point value in a formula value stored in a 8 byte
+ * field using IEEE notation
+ * 
+ * @author Avik Sengupta
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class NumberPtg extends ScalarConstantPtg {
+	public final static int SIZE = 9;
+	public final static byte sid = 0x1f;
+	private final double field_1_value;
+
+	public NumberPtg(LittleEndianInput in)  {
+		this(in.readDouble());
+	}
+
+	public NumberPtg(double value) {
+		field_1_value = value;
+	}
+
+	public double getValue() {
+		return field_1_value;
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+		out.writeDouble(getValue());
+	}
+
+	public int getSize() {
+		return SIZE;
+	}
+
+	public String toFormulaString() {
+		return NumberToTextConverter.toText(field_1_value);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/OperandPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/OperandPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/OperandPtg.java	(revision 28000)
@@ -0,0 +1,38 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ * @author Josh Micich
+ */
+public abstract class OperandPtg extends Ptg implements Cloneable {
+
+	/**
+	 * All Operand {@link Ptg}s are classified ('relative', 'value', 'array')
+	 */
+	public final boolean isBaseToken() {
+		return false;
+	}
+	public final OperandPtg copy() {
+		try {
+			return (OperandPtg) clone();
+		} catch (CloneNotSupportedException e) {
+			throw new RuntimeException(e);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/OperationPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/OperationPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/OperationPtg.java	(revision 28000)
@@ -0,0 +1,41 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ * defines a Ptg that is an operation instead of an operand
+ * @author  andy
+ */
+public abstract class OperationPtg extends Ptg {
+    /**
+     *  returns a string representation of the operations
+     *  the length of the input array should equal the number returned by 
+     *  @see #getNumberOfOperands
+     *  
+     */
+    public abstract String toFormulaString(String[] operands);
+    
+    /**
+     * The number of operands expected by the operations
+     */
+    public abstract int getNumberOfOperands();
+    
+    public byte getDefaultOperandClass() {
+        return Ptg.CLASS_VALUE;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ParenthesisPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ParenthesisPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ParenthesisPtg.java	(revision 28000)
@@ -0,0 +1,55 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * While formula tokens are stored in RPN order and thus do not need parenthesis
+ * for precedence reasons, Parenthesis tokens ARE written to ensure that user
+ * entered parenthesis are displayed as-is on reading back
+ * 
+ * Avik Sengupta &lt;lists@aviksengupta.com&gt; Andrew C. Oliver (acoliver at
+ * apache dot org)
+ * 
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class ParenthesisPtg extends ControlPtg {
+
+	private final static int SIZE = 1;
+	public final static byte sid = 0x15;
+
+	public static final ControlPtg instance = new ParenthesisPtg();
+
+	private ParenthesisPtg() {
+		// enforce singleton
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(sid + getPtgClass());
+	}
+
+	public int getSize() {
+		return SIZE;
+	}
+
+	public String toFormulaString() {
+		return "()";
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/PercentPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/PercentPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/PercentPtg.java	(revision 28000)
@@ -0,0 +1,51 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ * Percent PTG.
+ *
+ * @author Daniel Noll (daniel at nuix.com.au)
+ */
+public final class PercentPtg extends ValueOperatorPtg {
+    public final static byte sid  = 0x14;
+    
+    private final static String PERCENT = "%";
+
+    public static final ValueOperatorPtg instance = new PercentPtg();
+
+    private PercentPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    public int getNumberOfOperands() {
+        return 1;
+    }
+       
+    public String toFormulaString(String[] operands) {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append(operands[ 0 ]);
+        buffer.append(PERCENT);
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/PowerPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/PowerPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/PowerPtg.java	(revision 28000)
@@ -0,0 +1,51 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ *
+ * @author  andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class PowerPtg extends ValueOperatorPtg {
+    public final static byte sid  = 0x07;
+
+    public static final ValueOperatorPtg instance = new PowerPtg();
+
+    private PowerPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    public int getNumberOfOperands() {
+        return 2; // TODO - 2 seems wrong (Jun 2008).  Maybe this method is not relevant
+    }
+ 
+    public String toFormulaString(String[] operands) {
+         StringBuffer buffer = new StringBuffer();
+
+        
+        buffer.append(operands[ 0 ]);
+        buffer.append("^");
+        buffer.append(operands[ 1 ]);
+        return buffer.toString();
+    }       
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Ptg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Ptg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Ptg.java	(revision 28000)
@@ -0,0 +1,295 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.util.LittleEndianByteArrayOutputStream;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * <tt>Ptg</tt> represents a syntactic token in a formula.  'PTG' is an acronym for
+ * '<b>p</b>arse <b>t</b>hin<b>g</b>'.  Originally, the name referred to the single
+ * byte identifier at the start of the token, but in POI, <tt>Ptg</tt> encapsulates
+ * the whole formula token (initial byte + value data).
+ * <p/>
+ *
+ * <tt>Ptg</tt>s are logically arranged in a tree representing the structure of the
+ * parsed formula.  However, in BIFF files <tt>Ptg</tt>s are written/read in
+ * <em>Reverse-Polish Notation</em> order. The RPN ordering also simplifies formula
+ * evaluation logic, so POI mostly accesses <tt>Ptg</tt>s in the same way.
+ *
+ * @author  andy
+ * @author avik
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public abstract class Ptg {
+	public static final Ptg[] EMPTY_PTG_ARRAY = { };
+
+
+	/**
+	 * Reads <tt>size</tt> bytes of the input stream, to create an array of <tt>Ptg</tt>s.
+	 * Extra data (beyond <tt>size</tt>) may be read if and <tt>ArrayPtg</tt>s are present.
+	 */
+	public static Ptg[] readTokens(int size, LittleEndianInput in) {
+		List<Ptg> temp = new ArrayList<Ptg>(4 + size / 2);
+		int pos = 0;
+		boolean hasArrayPtgs = false;
+		while (pos < size) {
+			Ptg ptg = Ptg.createPtg(in);
+			if (ptg instanceof ArrayPtg.Initial) {
+				hasArrayPtgs = true;
+			}
+			pos += ptg.getSize();
+			temp.add(ptg);
+		}
+		if(pos != size) {
+			throw new RuntimeException("Ptg array size mismatch");
+		}
+		if (hasArrayPtgs) {
+			Ptg[] result = toPtgArray(temp);
+			for (int i=0;i<result.length;i++) {
+				if (result[i] instanceof ArrayPtg.Initial) {
+					result[i] = ((ArrayPtg.Initial) result[i]).finishReading(in);
+				}
+			}
+			return result;
+		}
+		return toPtgArray(temp);
+	}
+
+	public static Ptg createPtg(LittleEndianInput in) {
+		byte id = in.readByte();
+
+		if (id < 0x20) {
+			return createBasePtg(id, in);
+		}
+
+		Ptg  retval = createClassifiedPtg(id, in);
+
+		if (id >= 0x60) {
+			retval.setClass(CLASS_ARRAY);
+		} else if (id >= 0x40) {
+			retval.setClass(CLASS_VALUE);
+		} else {
+			retval.setClass(CLASS_REF);
+		}
+		return retval;
+	}
+
+	private static Ptg createClassifiedPtg(byte id, LittleEndianInput in) {
+
+		int baseId = id & 0x1F | 0x20;
+
+		switch (baseId) {
+			case ArrayPtg.sid:    return new ArrayPtg.Initial(in);//0x20, 0x40, 0x60
+			case FuncPtg.sid:     return FuncPtg.create(in);  // 0x21, 0x41, 0x61
+			case FuncVarPtg.sid:  return FuncVarPtg.create(in);//0x22, 0x42, 0x62
+			case NamePtg.sid:     return new NamePtg(in);     // 0x23, 0x43, 0x63
+			case RefPtg.sid:      return new RefPtg(in);      // 0x24, 0x44, 0x64
+			case AreaPtg.sid:     return new AreaPtg(in);     // 0x25, 0x45, 0x65
+			case MemAreaPtg.sid:  return new MemAreaPtg(in);  // 0x26, 0x46, 0x66
+			case MemErrPtg.sid:   return new MemErrPtg(in);   // 0x27, 0x47, 0x67
+			case MemFuncPtg.sid:  return new MemFuncPtg(in);  // 0x29, 0x49, 0x69
+			case RefErrorPtg.sid: return new RefErrorPtg(in); // 0x2a, 0x4a, 0x6a
+			case AreaErrPtg.sid:  return new AreaErrPtg(in);  // 0x2b, 0x4b, 0x6b
+			case RefNPtg.sid:     return new RefNPtg(in);     // 0x2c, 0x4c, 0x6c
+			case AreaNPtg.sid:    return new AreaNPtg(in);    // 0x2d, 0x4d, 0x6d
+
+			case NameXPtg.sid:    return new NameXPtg(in);    // 0x39, 0x49, 0x79
+			case Ref3DPtg.sid:    return new Ref3DPtg(in);    // 0x3a, 0x5a, 0x7a
+			case Area3DPtg.sid:   return new Area3DPtg(in);   // 0x3b, 0x5b, 0x7b
+			case DeletedRef3DPtg.sid:  return new DeletedRef3DPtg(in);   // 0x3c, 0x5c, 0x7c
+			case DeletedArea3DPtg.sid: return  new DeletedArea3DPtg(in); // 0x3d, 0x5d, 0x7d
+		}
+		throw new UnsupportedOperationException(" Unknown Ptg in Formula: 0x"+
+					Integer.toHexString(id) + " (" + ( int ) id + ")");
+	}
+
+	private static Ptg createBasePtg(byte id, LittleEndianInput in) {
+		switch(id) {
+			case 0x00:                return new UnknownPtg(id); // TODO - not a real Ptg
+			case ExpPtg.sid:          return new ExpPtg(in);          // 0x01
+			case TblPtg.sid:          return new TblPtg(in);          // 0x02
+			case AddPtg.sid:          return AddPtg.instance;         // 0x03
+			case SubtractPtg.sid:     return SubtractPtg.instance;    // 0x04
+			case MultiplyPtg.sid:     return MultiplyPtg.instance;    // 0x05
+			case DividePtg.sid:       return DividePtg.instance;      // 0x06
+			case PowerPtg.sid:        return PowerPtg.instance;       // 0x07
+			case ConcatPtg.sid:       return ConcatPtg.instance;      // 0x08
+			case LessThanPtg.sid:     return LessThanPtg.instance;    // 0x09
+			case LessEqualPtg.sid:    return LessEqualPtg.instance;   // 0x0a
+			case EqualPtg.sid:        return EqualPtg.instance;       // 0x0b
+			case GreaterEqualPtg.sid: return GreaterEqualPtg.instance;// 0x0c
+			case GreaterThanPtg.sid:  return GreaterThanPtg.instance; // 0x0d
+			case NotEqualPtg.sid:     return NotEqualPtg.instance;    // 0x0e
+			case IntersectionPtg.sid: return IntersectionPtg.instance;// 0x0f
+			case UnionPtg.sid:        return UnionPtg.instance;       // 0x10
+			case RangePtg.sid:        return RangePtg.instance;       // 0x11
+			case UnaryPlusPtg.sid:    return UnaryPlusPtg.instance;   // 0x12
+			case UnaryMinusPtg.sid:   return UnaryMinusPtg.instance;  // 0x13
+			case PercentPtg.sid:      return PercentPtg.instance;     // 0x14
+			case ParenthesisPtg.sid:  return ParenthesisPtg.instance; // 0x15
+			case MissingArgPtg.sid:   return MissingArgPtg.instance;  // 0x16
+
+			case StringPtg.sid:       return new StringPtg(in);       // 0x17
+			case AttrPtg.sid:         return new AttrPtg(in);         // 0x19
+			case ErrPtg.sid:          return ErrPtg.read(in);         // 0x1c
+			case BoolPtg.sid:         return BoolPtg.read(in);        // 0x1d
+			case IntPtg.sid:          return new IntPtg(in);          // 0x1e
+			case NumberPtg.sid:       return new NumberPtg(in);       // 0x1f
+		}
+		throw new RuntimeException("Unexpected base token id (" + id + ")");
+	}
+
+	private static Ptg[] toPtgArray(List<Ptg> l) {
+		if (l.isEmpty()) {
+			return EMPTY_PTG_ARRAY;
+		}
+		Ptg[] result = new Ptg[l.size()];
+		l.toArray(result);
+		return result;
+	}
+	/**
+	 * This method will return the same result as {@link #getEncodedSizeWithoutArrayData(Ptg[])}
+	 * if there are no array tokens present.
+	 * @return the full size taken to encode the specified <tt>Ptg</tt>s
+	 */
+	public static int getEncodedSize(Ptg[] ptgs) {
+		int result = 0;
+		for (int i = 0; i < ptgs.length; i++) {
+			result += ptgs[i].getSize();
+		}
+		return result;
+	}
+	/**
+	 * Used to calculate value that should be encoded at the start of the encoded Ptg token array;
+	 * @return the size of the encoded Ptg tokens not including any trailing array data.
+	 */
+	public static int getEncodedSizeWithoutArrayData(Ptg[] ptgs) {
+		int result = 0;
+		for (int i = 0; i < ptgs.length; i++) {
+			Ptg ptg = ptgs[i];
+			if (ptg instanceof ArrayPtg) {
+				result += ArrayPtg.PLAIN_TOKEN_SIZE;
+			} else {
+				result += ptg.getSize();
+			}
+		}
+		return result;
+	}
+	/**
+	 * Writes the ptgs to the data buffer, starting at the specified offset.
+	 *
+	 * <br/>
+	 * The 2 byte encode length field is <b>not</b> written by this method.
+	 * @return number of bytes written
+	 */
+	public static int serializePtgs(Ptg[] ptgs, byte[] array, int offset) {
+		int nTokens = ptgs.length;
+
+		LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(array, offset);
+
+		List<Ptg> arrayPtgs = null;
+
+		for (int k = 0; k < nTokens; k++) {
+			Ptg ptg = ptgs[k];
+
+			ptg.write(out);
+			if (ptg instanceof ArrayPtg) {
+				if (arrayPtgs == null) {
+					arrayPtgs = new ArrayList<Ptg>(5);
+				}
+				arrayPtgs.add(ptg);
+			}
+		}
+		if (arrayPtgs != null) {
+			for (int i=0;i<arrayPtgs.size();i++) {
+				ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
+				p.writeTokenValueBytes(out);
+			}
+		}
+		return out.getWriteIndex() - offset;
+	}
+
+	/**
+	 * @return the encoded length of this Ptg, including the initial Ptg type identifier byte.
+	 */
+	public abstract int getSize();
+
+	public abstract void write(LittleEndianOutput out);
+
+	/**
+	 * return a string representation of this token alone
+	 */
+	public abstract String toFormulaString();
+
+	/** Overridden toString method to ensure object hash is not printed.
+	 * This helps get rid of gratuitous diffs when comparing two dumps
+	 * Subclasses may output more relevant information by overriding this method
+	 **/
+	public String toString(){
+		return this.getClass().toString();
+	}
+
+	public static final byte CLASS_REF = 0x00;
+	public static final byte CLASS_VALUE = 0x20;
+	public static final byte CLASS_ARRAY = 0x40;
+
+	private byte ptgClass = CLASS_REF; //base ptg
+
+	public final void setClass(byte thePtgClass) {
+		if (isBaseToken()) {
+			throw new RuntimeException("setClass should not be called on a base token");
+		}
+		ptgClass = thePtgClass;
+	}
+
+	/**
+	 *  @return the 'operand class' (REF/VALUE/ARRAY) for this Ptg
+	 */
+	public final byte getPtgClass() {
+		return ptgClass;
+	}
+
+	/**
+	 * Debug / diagnostic method to get this token's 'operand class' type.
+	 * @return 'R' for 'reference', 'V' for 'value', 'A' for 'array' and '.' for base tokens
+	 */
+	public final char getRVAType() {
+		if (isBaseToken()) {
+			return '.';
+		}
+		switch (ptgClass) {
+			case Ptg.CLASS_REF:   return 'R';
+			case Ptg.CLASS_VALUE: return 'V';
+			case Ptg.CLASS_ARRAY: return 'A';
+		}
+		throw new RuntimeException("Unknown operand class (" + ptgClass + ")");
+	}
+
+	public abstract byte getDefaultOperandClass();
+
+	/**
+	 * @return <code>false</code> if this token is classified as 'reference', 'value', or 'array'
+	 */
+	public abstract boolean isBaseToken();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RangePtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RangePtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RangePtg.java	(revision 28000)
@@ -0,0 +1,71 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+
+/**
+ * @author Daniel Noll (daniel at nuix dot com dot au)
+ */
+public final class RangePtg  extends OperationPtg {
+    public final static int  SIZE = 1;
+    public final static byte sid  = 0x11;
+
+    public static final OperationPtg instance = new RangePtg();
+
+    private RangePtg() {
+    	// enforce singleton
+    }
+
+    public final boolean isBaseToken() {
+        return true;
+    }
+
+    public int getSize()
+    {
+        return SIZE;
+    }
+
+    public void write(LittleEndianOutput out) {
+        out.writeByte(sid + getPtgClass());
+    }
+
+    public String toFormulaString()
+    {
+        return ":";
+    }
+
+
+    /** implementation of method from OperationsPtg*/
+    public String toFormulaString(String[] operands)
+    {
+         StringBuffer buffer = new StringBuffer();
+
+         buffer.append(operands[ 0 ]);
+         buffer.append(":");
+         buffer.append(operands[ 1 ]);
+         return buffer.toString();
+     }
+
+    public int getNumberOfOperands()
+    {
+        return 2;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Ref2DPtgBase.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Ref2DPtgBase.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Ref2DPtgBase.java	(revision 28000)
@@ -0,0 +1,65 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author Josh Micich
+ */
+abstract class Ref2DPtgBase extends RefPtgBase {
+	private final static int SIZE = 5;
+
+
+	protected Ref2DPtgBase(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
+		setRow(row);
+		setColumn(column);
+		setRowRelative(isRowRelative);
+		setColRelative(isColumnRelative);
+	}
+
+	protected Ref2DPtgBase(LittleEndianInput in)  {
+		readCoordinates(in);
+	}
+
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(getSid() + getPtgClass());
+		writeCoordinates(out);
+	}
+
+	public final String toFormulaString() {
+		return formatReferenceAsString();
+	}
+
+	protected abstract byte getSid();
+
+	public final int getSize() {
+		return SIZE;
+	}
+
+	public final String toString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append(getClass().getName());
+		sb.append(" [");
+		sb.append(formatReferenceAsString());
+		sb.append("]");
+		return sb.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Ref3DPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Ref3DPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/Ref3DPtg.java	(revision 28000)
@@ -0,0 +1,81 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.ss.formula.ExternSheetReferenceToken;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title:        Reference 3D Ptg <P>
+ * Description:  Defined a cell in extern sheet. <P>
+ * REFERENCE:  <P>
+ * @author Libin Roman (Vista Portal LDT. Developer)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class Ref3DPtg extends RefPtgBase implements WorkbookDependentFormula, ExternSheetReferenceToken {
+    public final static byte sid  = 0x3a;
+
+    private final static int  SIZE = 7; // 6 + 1 for Ptg
+    private int             field_1_index_extern_sheet;
+
+
+    public Ref3DPtg(LittleEndianInput in)  {
+        field_1_index_extern_sheet = in.readShort();
+        readCoordinates(in);
+    }
+
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getClass().getName());
+        sb.append(" [");
+        sb.append("sheetIx=").append(getExternSheetIndex());
+        sb.append(" ! ");
+        sb.append(formatReferenceAsString());
+        sb.append("]");
+        return sb.toString();
+    }
+
+    public void write(LittleEndianOutput out) {
+        out.writeByte(sid + getPtgClass());
+        out.writeShort(getExternSheetIndex());
+        writeCoordinates(out);
+    }
+
+    public int getSize() {
+        return SIZE;
+    }
+
+    public int getExternSheetIndex() {
+        return field_1_index_extern_sheet;
+    }
+
+    /**
+     * @return text representation of this cell reference that can be used in text
+     * formulas. The sheet name will get properly delimited if required.
+     */
+    public String toFormulaString(FormulaRenderingWorkbook book) {
+        return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, formatReferenceAsString());
+    }
+    public String toFormulaString() {
+        throw new RuntimeException("3D references need a workbook to determine formula text");
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RefErrorPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RefErrorPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RefErrorPtg.java	(revision 28000)
@@ -0,0 +1,62 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * RefError - handles deleted cell reference
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class RefErrorPtg extends OperandPtg {
+
+    private final static int SIZE = 5;
+    public final static byte sid  = 0x2A;
+    private int              field_1_reserved;
+
+    public RefErrorPtg() {
+        field_1_reserved = 0;
+    }
+    public RefErrorPtg(LittleEndianInput in)  {
+        field_1_reserved = in.readInt();
+    }
+
+    public String toString() {
+        return getClass().getName();
+    }
+
+    public void write(LittleEndianOutput out) {
+        out.writeByte(sid + getPtgClass());
+        out.writeInt(field_1_reserved);
+    }
+
+    public int getSize()
+    {
+        return SIZE;
+    }
+
+    public String toFormulaString() {
+        return HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF);
+    }
+    
+    public byte getDefaultOperandClass() {
+        return Ptg.CLASS_REF;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RefNPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RefNPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RefNPtg.java	(revision 28000)
@@ -0,0 +1,36 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianInput;
+
+/**
+ * RefNPtg
+ * @author Jason Height (jheight at apache dot com)
+ */
+public final class RefNPtg extends Ref2DPtgBase {
+	public final static byte sid = 0x2C;
+
+	public RefNPtg(LittleEndianInput in)  {
+		super(in);
+	}
+
+	protected byte getSid() {
+		return sid;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RefPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RefPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RefPtg.java	(revision 28000)
@@ -0,0 +1,41 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianInput;
+
+/**
+ * ReferencePtg - handles references (such as A1, A2, IA4)
+ * @author  Andrew C. Oliver (acoliver@apache.org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class RefPtg extends Ref2DPtgBase {
+	public final static byte sid = 0x24;
+
+	public RefPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
+		super(row, column, isRowRelative, isColumnRelative);
+	}
+
+	public RefPtg(LittleEndianInput in)  {
+		super(in);
+	}
+
+	protected byte getSid() {
+		return sid;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RefPtgBase.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RefPtgBase.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/RefPtgBase.java	(revision 28000)
@@ -0,0 +1,103 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * ReferencePtgBase - handles references (such as A1, A2, IA4)
+ *
+ * @author Andrew C. Oliver (acoliver@apache.org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public abstract class RefPtgBase extends OperandPtg {
+
+	/** The row index - zero based unsigned 16 bit value */
+	private int field_1_row;
+	/**
+	 * Field 2 - lower 8 bits is the zero based unsigned byte column index - bit
+	 * 16 - isRowRelative - bit 15 - isColumnRelative
+	 */
+	private int field_2_col;
+	private static final BitField rowRelative = BitFieldFactory.getInstance(0x8000);
+	private static final BitField colRelative = BitFieldFactory.getInstance(0x4000);
+	private static final BitField column = BitFieldFactory.getInstance(0x00FF);
+
+	protected RefPtgBase() {
+		// Required for clone methods
+	}
+
+	protected final void readCoordinates(LittleEndianInput in) {
+		field_1_row = in.readUShort();
+		field_2_col = in.readUShort();
+	}
+
+	protected final void writeCoordinates(LittleEndianOutput out) {
+		out.writeShort(field_1_row);
+		out.writeShort(field_2_col);
+	}
+
+	public final void setRow(int rowIndex) {
+		field_1_row = rowIndex;
+	}
+
+	/**
+	 * @return the row number as an int
+	 */
+	public final int getRow() {
+		return field_1_row;
+	}
+
+	public final boolean isRowRelative() {
+		return rowRelative.isSet(field_2_col);
+	}
+
+	public final void setRowRelative(boolean rel) {
+		field_2_col = rowRelative.setBoolean(field_2_col, rel);
+	}
+
+	public final boolean isColRelative() {
+		return colRelative.isSet(field_2_col);
+	}
+
+	public final void setColRelative(boolean rel) {
+		field_2_col = colRelative.setBoolean(field_2_col, rel);
+	}
+
+	public final void setColumn(int col) {
+		field_2_col = column.setValue(field_2_col, col);
+	}
+
+	public final int getColumn() {
+		return column.getValue(field_2_col);
+	}
+
+	protected final String formatReferenceAsString() {
+		// Only make cell references as needed. Memory is an issue
+		CellReference cr = new CellReference(getRow(), getColumn(), !isRowRelative(), !isColRelative());
+		return cr.formatAsString();
+	}
+
+	public final byte getDefaultOperandClass() {
+		return Ptg.CLASS_REF;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java	(revision 28000)
@@ -0,0 +1,42 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+
+/**
+ * Common superclass of all {@link Ptg}s that represent simple constant values.
+ *
+ * @author Josh Micich
+ */
+public abstract class ScalarConstantPtg extends Ptg {
+	public final boolean isBaseToken() {
+		return true;
+	}
+
+	public final byte getDefaultOperandClass() {
+		return Ptg.CLASS_VALUE;
+	}
+
+	public final String toString() {
+		StringBuffer sb = new StringBuffer(64);
+		sb.append(getClass().getName()).append(" [");
+		sb.append(toFormulaString());
+		sb.append("]");
+		return sb.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/SheetNameFormatter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/SheetNameFormatter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/SheetNameFormatter.java	(revision 28000)
@@ -0,0 +1,213 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.ss.SpreadsheetVersion;
+
+/**
+ * Formats sheet names for use in formula expressions.
+ * 
+ * @author Josh Micich
+ */
+public final class SheetNameFormatter {
+	
+	private static final char DELIMITER = '\'';
+	
+	/**
+	 * Matches a single cell ref with no absolute ('$') markers
+	 */
+	private static final Pattern CELL_REF_PATTERN = Pattern.compile("([A-Za-z]+)([0-9]+)");
+
+	private SheetNameFormatter() {
+		// no instances of this class
+	}
+	
+	
+	/**
+	 * Convenience method for ({@link #format(String)}) when a StringBuffer is already available.
+	 * 
+	 * @param out - sheet name will be appended here possibly with delimiting quotes 
+	 */
+	public static void appendFormat(StringBuffer out, String rawSheetName) {
+		boolean needsQuotes = needsDelimiting(rawSheetName);
+		if(needsQuotes) {
+			out.append(DELIMITER);
+			appendAndEscape(out, rawSheetName);
+			out.append(DELIMITER);
+		} else {
+			out.append(rawSheetName);
+		}
+	}
+	public static void appendFormat(StringBuffer out, String workbookName, String rawSheetName) {
+		boolean needsQuotes = needsDelimiting(workbookName) || needsDelimiting(rawSheetName);
+		if(needsQuotes) {
+			out.append(DELIMITER);
+			out.append('[');
+			appendAndEscape(out, workbookName.replace('[', '(').replace(']', ')'));
+			out.append(']');
+			appendAndEscape(out, rawSheetName);
+			out.append(DELIMITER);
+		} else {
+			out.append('[');
+			out.append(workbookName);
+			out.append(']');
+			out.append(rawSheetName);
+		}
+	}
+
+	private static void appendAndEscape(StringBuffer sb, String rawSheetName) {
+		int len = rawSheetName.length();
+		for(int i=0; i<len; i++) {
+			char ch = rawSheetName.charAt(i);
+			if(ch == DELIMITER) {
+				// single quotes (') are encoded as ('')
+				sb.append(DELIMITER);
+			}
+			sb.append(ch);
+		}
+	}
+
+	private static boolean needsDelimiting(String rawSheetName) {
+		int len = rawSheetName.length();
+		if(len < 1) {
+			throw new RuntimeException("Zero length string is an invalid sheet name");
+		}
+		if(Character.isDigit(rawSheetName.charAt(0))) {
+			// sheet name with digit in the first position always requires delimiting
+			return true;
+		}
+		for(int i=0; i<len; i++) {
+			char ch = rawSheetName.charAt(i);
+			if(isSpecialChar(ch)) {
+				return true;
+			}
+		}
+		if(Character.isLetter(rawSheetName.charAt(0))
+				&& Character.isDigit(rawSheetName.charAt(len-1))) {
+			// note - values like "A$1:$C$20" don't get this far 
+			if(nameLooksLikePlainCellReference(rawSheetName)) {
+				return true;
+			}
+		}
+		if (nameLooksLikeBooleanLiteral(rawSheetName)) {
+			return true;
+		}
+		// Error constant literals all contain '#' and other special characters
+		// so they don't get this far
+		return false;
+	}
+	
+	private static boolean nameLooksLikeBooleanLiteral(String rawSheetName) {
+		switch(rawSheetName.charAt(0)) {
+			case 'T': case 't':
+				return "TRUE".equalsIgnoreCase(rawSheetName);
+			case 'F': case 'f':
+				return "FALSE".equalsIgnoreCase(rawSheetName);
+		}
+		return false;
+	}
+	/**
+	 * @return <code>true</code> if the presence of the specified character in a sheet name would 
+	 * require the sheet name to be delimited in formulas.  This includes every non-alphanumeric 
+	 * character besides underscore '_' and dot '.'.
+	 */
+	/* package */ static boolean isSpecialChar(char ch) {
+		// note - Character.isJavaIdentifierPart() would allow dollars '$'
+		if(Character.isLetterOrDigit(ch)) {
+			return false;
+		}
+		switch(ch) {
+			case '.': // dot is OK
+			case '_': // underscore is OK
+				return false;
+			case '\n':
+			case '\r':
+			case '\t':
+				throw new RuntimeException("Illegal character (0x" 
+						+ Integer.toHexString(ch) + ") found in sheet name");
+		}
+		return true;
+	}
+	
+
+	/**
+	 * Used to decide whether sheet names like 'AB123' need delimiting due to the fact that they 
+	 * look like cell references.
+	 * <p/>
+	 * This code is currently being used for translating formulas represented with <code>Ptg</code>
+	 * tokens into human readable text form.  In formula expressions, a sheet name always has a 
+	 * trailing '!' so there is little chance for ambiguity.  It doesn't matter too much what this 
+	 * method returns but it is worth noting the likely consumers of these formula text strings:
+	 * <ol>
+	 * <li>POI's own formula parser</li>
+	 * <li>Visual reading by human</li>
+	 * <li>VBA automation entry into Excel cell contents e.g.  ActiveCell.Formula = "=c64!A1"</li>
+	 * <li>Manual entry into Excel cell contents</li>
+	 * <li>Some third party formula parser</li>
+	 * </ol>
+	 * 
+	 * At the time of writing, POI's formula parser tolerates cell-like sheet names in formulas
+	 * with or without delimiters.  The same goes for Excel(2007), both manual and automated entry.  
+	 * <p/>
+	 * For better or worse this implementation attempts to replicate Excel's formula renderer.
+	 * Excel uses range checking on the apparent 'row' and 'column' components.  Note however that
+	 * the maximum sheet size varies across versions.
+	 * @see org.apache.poi.hssf.util.CellReference
+	 */
+	/* package */ static boolean cellReferenceIsWithinRange(String lettersPrefix, String numbersSuffix) {
+		return CellReference.cellReferenceIsWithinRange(lettersPrefix, numbersSuffix, SpreadsheetVersion.EXCEL97);
+	}
+
+	/**
+	 * Note - this method assumes the specified rawSheetName has only letters and digits.  It 
+	 * cannot be used to match absolute or range references (using the dollar or colon char).
+	 * <p/>
+	 * Some notable cases:
+	 *    <blockquote><table border="0" cellpadding="1" cellspacing="0" 
+	 *                 summary="Notable cases.">
+	 *      <tr><th>Input&nbsp;</th><th>Result&nbsp;</th><th>Comments</th></tr>
+	 *      <tr><td>"A1"&nbsp;&nbsp;</td><td>true</td><td>&nbsp;</td></tr>
+	 *      <tr><td>"a111"&nbsp;&nbsp;</td><td>true</td><td>&nbsp;</td></tr>
+	 *      <tr><td>"AA"&nbsp;&nbsp;</td><td>false</td><td>&nbsp;</td></tr>
+	 *      <tr><td>"aa1"&nbsp;&nbsp;</td><td>true</td><td>&nbsp;</td></tr>
+	 *      <tr><td>"A1A"&nbsp;&nbsp;</td><td>false</td><td>&nbsp;</td></tr>
+	 *      <tr><td>"A1A1"&nbsp;&nbsp;</td><td>false</td><td>&nbsp;</td></tr>
+	 *      <tr><td>"A$1:$C$20"&nbsp;&nbsp;</td><td>false</td><td>Not a plain cell reference</td></tr>
+	 *      <tr><td>"SALES20080101"&nbsp;&nbsp;</td><td>true</td>
+	 *      		<td>Still needs delimiting even though well out of range</td></tr>
+	 *    </table></blockquote>
+	 *  
+	 * @return <code>true</code> if there is any possible ambiguity that the specified rawSheetName
+	 * could be interpreted as a valid cell name.
+	 */
+	/* package */ static boolean nameLooksLikePlainCellReference(String rawSheetName) {
+		Matcher matcher = CELL_REF_PATTERN.matcher(rawSheetName);
+		if(!matcher.matches()) {
+			return false;
+		}
+		
+		// rawSheetName == "Sheet1" gets this far.
+		String lettersPrefix = matcher.group(1);
+		String numbersSuffix = matcher.group(2);
+		return cellReferenceIsWithinRange(lettersPrefix, numbersSuffix);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/StringPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/StringPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/StringPtg.java	(revision 28000)
@@ -0,0 +1,87 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * String Stores a String value in a formula value stored in the format
+ * &lt;length 2 bytes&gt;char[]
+ * 
+ * @author Werner Froidevaux
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @author Bernard Chesnoy
+ */
+public final class StringPtg extends ScalarConstantPtg {
+     public final static byte sid = 0x17;
+    /** the character (") used in formulas to delimit string literals */
+    private static final char FORMULA_DELIMITER = '"';
+
+    private final boolean _is16bitUnicode;
+    /**
+     * NOTE: OO doc says 16bit length, but BiffViewer says 8 Book says something
+     * totally different, so don't look there!
+     */
+    private final String field_3_string;
+
+    /** Create a StringPtg from a stream */
+    public StringPtg(LittleEndianInput in)  {
+    	int nChars = in.readUByte(); // Note - nChars is 8-bit
+    	_is16bitUnicode = (in.readByte() & 0x01) != 0;
+    	if (_is16bitUnicode) {
+    		field_3_string = StringUtil.readUnicodeLE(in, nChars);
+    	} else {
+    		field_3_string = StringUtil.readCompressedUnicode(in, nChars);
+    	}
+    }
+
+    public void write(LittleEndianOutput out) {
+        out.writeByte(sid + getPtgClass());
+        out.writeByte(field_3_string.length()); // Note - nChars is 8-bit
+        out.writeByte(_is16bitUnicode ? 0x01 : 0x00);
+        if (_is16bitUnicode) {
+        	StringUtil.putUnicodeLE(field_3_string, out);
+        } else {
+        	StringUtil.putCompressedUnicode(field_3_string, out);
+        }
+    }
+
+    public int getSize() {
+    	return 3 +  field_3_string.length() * (_is16bitUnicode ? 2 : 1);
+    }
+
+    public String toFormulaString() {
+        String value = field_3_string;
+        int len = value.length();
+        StringBuffer sb = new StringBuffer(len + 4);
+        sb.append(FORMULA_DELIMITER);
+
+        for (int i = 0; i < len; i++) {
+            char c = value.charAt(i);
+            if (c == FORMULA_DELIMITER) {
+                sb.append(FORMULA_DELIMITER);
+            }
+            sb.append(c);
+        }
+
+        sb.append(FORMULA_DELIMITER);
+        return sb.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/SubtractPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/SubtractPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/SubtractPtg.java	(revision 28000)
@@ -0,0 +1,50 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ *
+ * @author  andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class SubtractPtg extends ValueOperatorPtg {
+    public final static byte sid  = 0x04;
+
+    public static final ValueOperatorPtg instance = new SubtractPtg();
+
+    private SubtractPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    public int getNumberOfOperands() {
+        return 2;
+    }
+       
+    public String toFormulaString(String[] operands) {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append(operands[ 0 ]);
+        buffer.append("-");
+        buffer.append(operands[ 1 ]);
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/TblPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/TblPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/TblPtg.java	(revision 28000)
@@ -0,0 +1,81 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.hssf.record.RecordFormatException;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * This ptg indicates a data table.
+ * It only occurs in a FORMULA record, never in an
+ *  ARRAY or NAME record.  When ptgTbl occurs in a
+ *  formula, it is the only token in the formula.
+ *
+ * This indicates that the cell containing the
+ *  formula is an interior cell in a data table;
+ *  the table description is found in a TABLE
+ *  record. Rows and columns which contain input
+ *  values to be substituted in the table do
+ *  not contain ptgTbl.
+ * See page 811 of the june 08 binary docs.
+ */
+public final class TblPtg extends ControlPtg {
+    private final static int  SIZE = 5;
+    public final static short sid  = 0x02;
+    /** The row number of the upper left corner */
+    private final int field_1_first_row;
+    /** The column number of the upper left corner */
+    private final int field_2_first_col;
+
+    public TblPtg(LittleEndianInput in)  {
+      field_1_first_row = in.readUShort();
+      field_2_first_col = in.readUShort();
+    }
+
+    public void write(LittleEndianOutput out) {
+        out.writeByte(sid + getPtgClass());
+        out.writeShort(field_1_first_row);
+        out.writeShort(field_2_first_col);
+    }
+
+    public int getSize() {
+        return SIZE;
+    }
+
+    public int getRow() {
+      return field_1_first_row;
+    }
+
+    public int getColumn() {
+      return field_2_first_col;
+    }
+
+    public String toFormulaString()
+    {
+        // table(....)[][]
+        throw new RecordFormatException("Table and Arrays are not yet supported");
+    }
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer("[Data Table - Parent cell is an interior cell in a data table]\n");
+        buffer.append("top left row = ").append(getRow()).append("\n");
+        buffer.append("top left col = ").append(getColumn()).append("\n");
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/UnaryMinusPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/UnaryMinusPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/UnaryMinusPtg.java	(revision 28000)
@@ -0,0 +1,51 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ * Unary Plus operator
+ * does not have any effect on the operand
+ * @author Avik Sengupta
+ */
+public final class UnaryMinusPtg extends ValueOperatorPtg {
+    public final static byte sid  = 0x13;
+    
+    private final static String MINUS = "-";
+
+    public static final ValueOperatorPtg instance = new UnaryMinusPtg();
+
+    private UnaryMinusPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    public int getNumberOfOperands() {
+        return 1;
+    }
+    
+   /** implementation of method from OperationsPtg*/  
+    public String toFormulaString(String[] operands) {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(MINUS);
+        buffer.append(operands[ 0]);
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/UnaryPlusPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/UnaryPlusPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/UnaryPlusPtg.java	(revision 28000)
@@ -0,0 +1,51 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+/**
+ * Unary Plus operator
+ * does not have any effect on the operand
+ * @author Avik Sengupta
+ */
+public final class UnaryPlusPtg extends ValueOperatorPtg {
+    public final static byte sid  = 0x12;
+    
+    private final static String ADD = "+";
+
+    public static final ValueOperatorPtg instance = new UnaryPlusPtg();
+
+    private UnaryPlusPtg() {
+    	// enforce singleton
+    }
+    
+    protected byte getSid() {
+    	return sid;
+    }
+
+    public int getNumberOfOperands() {
+        return 1;
+    }
+    
+   /** implementation of method from OperationsPtg*/  
+    public String toFormulaString(String[] operands) {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(ADD);
+        buffer.append(operands[ 0]);
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/UnionPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/UnionPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/UnionPtg.java	(revision 28000)
@@ -0,0 +1,70 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+
+/**
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class UnionPtg extends OperationPtg {
+    public final static byte sid  = 0x10;
+
+    public static final OperationPtg instance = new UnionPtg();
+
+    private UnionPtg() {
+    	// enforce singleton
+    }
+
+    public final boolean isBaseToken() {
+        return true;
+    }
+
+    public int getSize()
+    {
+        return 1;
+    }
+
+    public void write(LittleEndianOutput out) {
+        out.writeByte(sid + getPtgClass());
+    }
+
+    public String toFormulaString()
+    {
+        return ",";
+    }
+
+
+    /** implementation of method from OperationsPtg*/
+    public String toFormulaString(String[] operands)
+    {
+         StringBuffer buffer = new StringBuffer();
+
+         buffer.append(operands[ 0 ]);
+         buffer.append(",");
+         buffer.append(operands[ 1 ]);
+         return buffer.toString();
+     }
+
+    public int getNumberOfOperands()
+    {
+        return 2;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/UnknownPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/UnknownPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/UnknownPtg.java	(revision 28000)
@@ -0,0 +1,50 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public class UnknownPtg extends Ptg {
+    private short size = 1;
+    private final int _sid;
+
+    public UnknownPtg(int sid) {
+        _sid = sid;
+    }
+
+    public boolean isBaseToken() {
+        return true;
+    }
+    public void write(LittleEndianOutput out) {
+        out.writeByte(_sid);
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public String toFormulaString() {
+        return "UNKNOWN";
+    }
+    public byte getDefaultOperandClass() {
+        return Ptg.CLASS_VALUE;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ValueOperatorPtg.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ValueOperatorPtg.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/ValueOperatorPtg.java	(revision 28000)
@@ -0,0 +1,56 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Common superclass of all value operators. Subclasses include all unary and
+ * binary operators except for the reference operators (IntersectionPtg,
+ * RangePtg, UnionPtg)
+ * 
+ * @author Josh Micich
+ */
+public abstract class ValueOperatorPtg extends OperationPtg {
+
+	/**
+	 * All Operator <tt>Ptg</tt>s are base tokens (i.e. are not RVA classified)
+	 */
+	public final boolean isBaseToken() {
+		return true;
+	}
+
+	public final byte getDefaultOperandClass() {
+		return Ptg.CLASS_VALUE;
+	}
+
+	public void write(LittleEndianOutput out) {
+		out.writeByte(getSid());
+	}
+
+	protected abstract byte getSid();
+
+	public final int getSize() {
+		return 1;
+	}
+
+	public final String toFormulaString() {
+		// TODO - prune this method out of the hierarchy
+		throw new RuntimeException("toFormulaString(String[] operands) should be used for subclasses of OperationPtgs");
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/eval/ErrorEval.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/eval/ErrorEval.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/eval/ErrorEval.java	(revision 28000)
@@ -0,0 +1,67 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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.apache.poi.hssf.record.formula.eval;
+
+import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
+
+/**
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
+ *
+ */
+public final class ErrorEval {
+
+
+    // POI internal error codes
+    private static final int CIRCULAR_REF_ERROR_CODE = 0xFFFFFFC4;
+    private static final int FUNCTION_NOT_IMPLEMENTED_CODE = 0xFFFFFFE2;
+
+    /**
+     * Converts error codes to text.  Handles non-standard error codes OK.  
+     * For debug/test purposes (and for formatting error messages).
+     * @return the String representation of the specified Excel error code.
+     */
+    public static String getText(int errorCode) {
+        if(HSSFErrorConstants.isValidCode(errorCode)) {
+            return HSSFErrorConstants.getText(errorCode);
+        }
+        // It is desirable to make these (arbitrary) strings look clearly different from any other
+        // value expression that might appear in a formula.  In addition these error strings should
+        // look unlike the standard Excel errors.  Hence tilde ('~') was used.
+        switch(errorCode) {
+            case CIRCULAR_REF_ERROR_CODE: return "~CIRCULAR~REF~";
+            case FUNCTION_NOT_IMPLEMENTED_CODE: return "~FUNCTION~NOT~IMPLEMENTED~";
+        }
+        return "~non~std~err(" + errorCode + ")~";
+    }
+
+    private int _errorCode;
+    /**
+     * @param errorCode an 8-bit value
+     */
+    private ErrorEval(int errorCode) {
+        _errorCode = errorCode;
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer(64);
+        sb.append(getClass().getName()).append(" [");
+        sb.append(getText(_errorCode));
+        sb.append("]");
+        return sb.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/function/FunctionDataBuilder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/function/FunctionDataBuilder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/function/FunctionDataBuilder.java	(revision 28000)
@@ -0,0 +1,91 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula.function;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Temporarily collects <tt>FunctionMetadata</tt> instances for creation of a
+ * <tt>FunctionMetadataRegistry</tt>.
+ *
+ * @author Josh Micich
+ */
+final class FunctionDataBuilder {
+	private int _maxFunctionIndex;
+	private final Map<String, FunctionMetadata> _functionDataByName;
+	private final Map<Integer, FunctionMetadata> _functionDataByIndex;
+	/** stores indexes of all functions with footnotes (i.e. whose definitions might change) */
+	private final Set<Integer> _mutatingFunctionIndexes;
+
+	public FunctionDataBuilder(int sizeEstimate) {
+		_maxFunctionIndex = -1;
+		_functionDataByName = new HashMap<String, FunctionMetadata>(sizeEstimate * 3 / 2);
+		_functionDataByIndex = new HashMap<Integer, FunctionMetadata>(sizeEstimate * 3 / 2);
+		_mutatingFunctionIndexes = new HashSet<Integer>();
+	}
+
+	public void add(int functionIndex, String functionName, int minParams, int maxParams,
+			byte returnClassCode, byte[] parameterClassCodes, boolean hasFootnote) {
+		FunctionMetadata fm = new FunctionMetadata(functionIndex, functionName, minParams, maxParams,
+				returnClassCode, parameterClassCodes);
+
+		Integer indexKey = Integer.valueOf(functionIndex);
+
+
+		if(functionIndex > _maxFunctionIndex) {
+			_maxFunctionIndex = functionIndex;
+		}
+		// allow function definitions to change only if both previous and the new items have footnotes
+		FunctionMetadata prevFM;
+		prevFM = _functionDataByName.get(functionName);
+		if(prevFM != null) {
+			if(!hasFootnote || !_mutatingFunctionIndexes.contains(indexKey)) {
+				throw new RuntimeException("Multiple entries for function name '" + functionName + "'");
+			}
+			_functionDataByIndex.remove(Integer.valueOf(prevFM.getIndex()));
+		}
+		prevFM = _functionDataByIndex.get(indexKey);
+		if(prevFM != null) {
+			if(!hasFootnote || !_mutatingFunctionIndexes.contains(indexKey)) {
+				throw new RuntimeException("Multiple entries for function index (" + functionIndex + ")");
+			}
+			_functionDataByName.remove(prevFM.getName());
+		}
+		if(hasFootnote) {
+			_mutatingFunctionIndexes.add(indexKey);
+		}
+		_functionDataByIndex.put(indexKey, fm);
+		_functionDataByName.put(functionName, fm);
+	}
+
+	public FunctionMetadataRegistry build() {
+
+		FunctionMetadata[] jumbledArray =  new FunctionMetadata[_functionDataByName.size()];
+		_functionDataByName.values().toArray(jumbledArray);
+		FunctionMetadata[] fdIndexArray = new FunctionMetadata[_maxFunctionIndex+1];
+		for (int i = 0; i < jumbledArray.length; i++) {
+			FunctionMetadata fd = jumbledArray[i];
+			fdIndexArray[fd.getIndex()] = fd;
+		}
+
+		return new FunctionMetadataRegistry(fdIndexArray, _functionDataByName);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/function/FunctionMetadata.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/function/FunctionMetadata.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/function/FunctionMetadata.java	(revision 28000)
@@ -0,0 +1,64 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula.function;
+
+
+/**
+ * Holds information about Excel built-in functions.
+ *
+ * @author Josh Micich
+ */
+public final class FunctionMetadata {
+
+	private final int _index;
+	private final String _name;
+	private final int _minParams;
+	private final byte _returnClassCode;
+	private final byte[] _parameterClassCodes;
+
+	/* package */ FunctionMetadata(int index, String name, int minParams, int maxParams,
+			byte returnClassCode, byte[] parameterClassCodes) {
+		_index = index;
+		_name = name;
+		_minParams = minParams;
+		_returnClassCode = returnClassCode;
+		_parameterClassCodes = parameterClassCodes;
+	}
+	public int getIndex() {
+		return _index;
+	}
+	public String getName() {
+		return _name;
+	}
+	public int getMinParams() {
+		return _minParams;
+	}
+	public byte getReturnClassCode() {
+		return _returnClassCode;
+	}
+	public byte[] getParameterClassCodes() {
+		return _parameterClassCodes.clone();
+	}
+	public String toString() {
+		StringBuffer sb = new StringBuffer(64);
+		sb.append(getClass().getName()).append(" [");
+		sb.append(_index).append(" ").append(_name);
+		sb.append("]");
+		return sb.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/function/FunctionMetadataReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/function/FunctionMetadataReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/function/FunctionMetadataReader.java	(revision 28000)
@@ -0,0 +1,195 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula.function;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+
+/**
+ * Converts the text meta-data file into a <tt>FunctionMetadataRegistry</tt>
+ * 
+ * @author Josh Micich
+ */
+final class FunctionMetadataReader {
+
+	private static final String METADATA_FILE_NAME = "functionMetadata.txt";
+	
+	/** plain ASCII text metadata file uses three dots for ellipsis */
+	private static final String ELLIPSIS = "...";
+
+	private static final Pattern TAB_DELIM_PATTERN = Pattern.compile("\t");
+	private static final Pattern SPACE_DELIM_PATTERN = Pattern.compile(" ");
+	private static final byte[] EMPTY_BYTE_ARRAY = { };
+
+	private static final String[] DIGIT_ENDING_FUNCTION_NAMES = {
+		// Digits at the end of a function might be due to a left-over footnote marker.
+		// except in these cases
+		"LOG10", "ATAN2", "DAYS360", "SUMXMY2", "SUMX2MY2", "SUMX2PY2",
+	};
+	private static final Set<String> DIGIT_ENDING_FUNCTION_NAMES_SET = new HashSet<String>(Arrays.asList(DIGIT_ENDING_FUNCTION_NAMES));
+
+	public static FunctionMetadataRegistry createRegistry() {
+		InputStream is = FunctionMetadataReader.class.getResourceAsStream(METADATA_FILE_NAME);
+		if (is == null) {
+			throw new RuntimeException("resource '" + METADATA_FILE_NAME + "' not found");
+		}
+
+		BufferedReader br;
+		try {
+			br = new BufferedReader(new InputStreamReader(is,"UTF-8"));
+		} catch(UnsupportedEncodingException e) {
+			throw new RuntimeException(e);
+		}
+		FunctionDataBuilder fdb = new FunctionDataBuilder(400);
+
+		try {
+			while (true) {
+				String line = br.readLine();
+				if (line == null) {
+					break;
+				}
+				if (line.length() < 1 || line.charAt(0) == '#') {
+					continue;
+				}
+				String trimLine = line.trim();
+				if (trimLine.length() < 1) {
+					continue;
+				}
+				processLine(fdb, line);
+			}
+			br.close();
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+
+		return fdb.build();
+	}
+
+	private static void processLine(FunctionDataBuilder fdb, String line) {
+
+		String[] parts = TAB_DELIM_PATTERN.split(line, -2);
+		if(parts.length != 8) {
+			throw new RuntimeException("Bad line format '" + line + "' - expected 8 data fields");
+		}
+		int functionIndex = parseInt(parts[0]);
+		String functionName = parts[1];
+		int minParams = parseInt(parts[2]);
+		int maxParams = parseInt(parts[3]);
+		byte returnClassCode = parseReturnTypeCode(parts[4]);
+		byte[] parameterClassCodes = parseOperandTypeCodes(parts[5]);
+		// 6 isVolatile
+		boolean hasNote = parts[7].length() > 0;
+
+		validateFunctionName(functionName);
+		// TODO - make POI use isVolatile
+		fdb.add(functionIndex, functionName, minParams, maxParams, 
+				returnClassCode, parameterClassCodes, hasNote);
+	}
+	
+
+	private static byte parseReturnTypeCode(String code) {
+		if(code.length() == 0) {
+			return Ptg.CLASS_REF; // happens for GETPIVOTDATA
+		}
+		return parseOperandTypeCode(code);
+	}
+
+	private static byte[] parseOperandTypeCodes(String codes) {
+		if(codes.length() < 1) {
+			return EMPTY_BYTE_ARRAY; // happens for GETPIVOTDATA
+		}
+		if(isDash(codes)) {
+			// '-' means empty:
+			return EMPTY_BYTE_ARRAY;
+		}
+		String[] array = SPACE_DELIM_PATTERN.split(codes);
+		int nItems = array.length;
+		if(ELLIPSIS.equals(array[nItems-1])) {
+			// final ellipsis is optional, and ignored
+			// (all unspecified params are assumed to be the same as the last)
+			nItems --;
+		}
+		byte[] result = new byte[nItems];
+		for (int i = 0; i < nItems; i++) {
+			result[i] = parseOperandTypeCode(array[i]);
+		}
+		return result;
+	}
+
+	private static boolean isDash(String codes) {
+		if(codes.length() == 1) {
+			switch (codes.charAt(0)) {
+				case '-':
+					return true;
+			}
+		}
+		return false;
+	}
+
+	private static byte parseOperandTypeCode(String code) {
+		if(code.length() != 1) {
+			throw new RuntimeException("Bad operand type code format '" + code  + "' expected single char");
+		}
+		switch(code.charAt(0)) {
+			case 'V': return Ptg.CLASS_VALUE;
+			case 'R': return Ptg.CLASS_REF;
+			case 'A': return Ptg.CLASS_ARRAY;
+		}
+		throw new IllegalArgumentException("Unexpected operand type code '" + code + "' (" + (int)code.charAt(0) + ")");
+	}
+
+	/**
+	 * Makes sure that footnote digits from the original OOO document have not been accidentally 
+	 * left behind
+	 */
+	private static void validateFunctionName(String functionName) {
+		int len = functionName.length();
+		int ix = len - 1;
+		if (!Character.isDigit(functionName.charAt(ix))) {
+			return;
+		}
+		while(ix >= 0) {
+			if (!Character.isDigit(functionName.charAt(ix))) {
+				break;
+			}
+			ix--;
+		}
+		if(DIGIT_ENDING_FUNCTION_NAMES_SET.contains(functionName)) {
+			return;
+		}
+		throw new RuntimeException("Invalid function name '" + functionName 
+				+ "' (is footnote number incorrectly appended)");
+	}
+
+	private static int parseInt(String valStr) {
+		try {
+			return Integer.parseInt(valStr);
+		} catch (NumberFormatException e) {
+			throw new RuntimeException("Value '" + valStr + "' could not be parsed as an integer");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/function/FunctionMetadataRegistry.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/function/FunctionMetadataRegistry.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/function/FunctionMetadataRegistry.java	(revision 28000)
@@ -0,0 +1,52 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.record.formula.function;
+
+import java.util.Map;
+/**
+ * Allows clients to get {@link FunctionMetadata} instances for any built-in function of Excel.
+ *
+ * @author Josh Micich
+ */
+public final class FunctionMetadataRegistry {
+
+	public static final short FUNCTION_INDEX_EXTERNAL = 255;
+
+	private static FunctionMetadataRegistry _instance;
+
+	private final FunctionMetadata[] _functionDataByIndex;
+
+	private static FunctionMetadataRegistry getInstance() {
+		if (_instance == null) {
+			_instance = FunctionMetadataReader.createRegistry();
+		}
+		return _instance;
+	}
+
+	/* package */ FunctionMetadataRegistry(FunctionMetadata[] functionDataByIndex, Map<String, FunctionMetadata> functionDataByName) {
+		_functionDataByIndex = functionDataByIndex;
+	}
+
+	public static FunctionMetadata getFunctionByIndex(int index) {
+		return getInstance().getFunctionByIndexInternal(index);
+	}
+
+	private FunctionMetadata getFunctionByIndexInternal(int index) {
+		return _functionDataByIndex[index];
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/formula/package.html	(revision 28000)
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+formula package contains binary PTG structures used in Formulas 
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+@see org.apache.poi.hssf.record
+@see org.apache.poi.hssf.record.FormulaRecord
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/record/package.html	(revision 28000)
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Record package contains class representations for XLS binary strutures.  Its very
+low level.
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+@see org.apache.poi.hssf.eventmodel
+@see org.apache.poi.hssf.record.RecordFactory
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFCell.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFCell.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFCell.java	(revision 28000)
@@ -0,0 +1,718 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.usermodel;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.poi.hssf.model.HSSFFormulaParser;
+import org.apache.poi.hssf.record.BlankRecord;
+import org.apache.poi.hssf.record.BoolErrRecord;
+import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.ExtendedFormatRecord;
+import org.apache.poi.hssf.record.FormulaRecord;
+import org.apache.poi.hssf.record.LabelSSTRecord;
+import org.apache.poi.hssf.record.NumberRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
+import org.apache.poi.hssf.record.common.UnicodeString;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.ss.SpreadsheetVersion;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.DateUtil;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.ss.util.NumberToTextConverter;
+
+/**
+ * High level representation of a cell in a row of a spreadsheet.
+ * Cells can be numeric, formula-based or string-based (text).  The cell type
+ * specifies this.  String cells cannot conatin numbers and numeric cells cannot
+ * contain strings (at least according to our model).  Client apps should do the
+ * conversions themselves.  Formula cells have the formula string, as well as
+ * the formula result, which can be numeric or string.
+ * <p>
+ * Cells should have their number (0 based) before being added to a row.  Only
+ * cells that have values should be added.
+ * <p>
+ *
+ * @author  Andrew C. Oliver (acoliver at apache dot org)
+ * @author  Dan Sherman (dsherman at isisph.com)
+ * @author  Brian Sanders (kestrel at burdell dot org) Active Cell support
+ * @author  Yegor Kozlov cell comments support
+ */
+public class HSSFCell implements Cell {
+
+    private static final String FILE_FORMAT_NAME  = "BIFF8";
+    /**
+     * The maximum  number of columns in BIFF8
+     */
+    public static final int LAST_COLUMN_NUMBER  = SpreadsheetVersion.EXCEL97.getLastColumnIndex(); // 2^8 - 1
+    private static final String LAST_COLUMN_NAME  = SpreadsheetVersion.EXCEL97.getLastColumnName();
+
+    private final HSSFWorkbook       _book;
+    private final HSSFSheet          _sheet;
+    private int                      _cellType;
+    private HSSFRichTextString       _stringValue;
+    private CellValueRecordInterface _record;
+
+    /**
+     * Returns the HSSFSheet this cell belongs to
+     *
+     * @return the HSSFSheet that owns this cell
+     */
+    public HSSFSheet getSheet() {
+        return _sheet;
+    }
+
+    /**
+     * Returns the HSSFRow this cell belongs to
+     *
+     * @return the HSSFRow that owns this cell
+     */
+    public HSSFRow getRow() {
+        int rowIndex = getRowIndex();
+        return _sheet.getRow(rowIndex);
+    }
+
+    /**
+     * Creates new Cell - Should only be called by HSSFRow.  This creates a cell
+     * from scratch.
+     *
+     * @param book - Workbook record of the workbook containing this cell
+     * @param sheet - Sheet record of the sheet containing this cell
+     * @param row   - the row of this cell
+     * @param col   - the column for this cell
+     * @param type  - CELL_TYPE_NUMERIC, CELL_TYPE_STRING, CELL_TYPE_FORMULA, CELL_TYPE_BLANK,
+     *                CELL_TYPE_BOOLEAN, CELL_TYPE_ERROR
+     *                Type of cell
+     * @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short,int)
+     */
+    protected HSSFCell(HSSFWorkbook book, HSSFSheet sheet, int row, short col,
+                       int type)
+    {
+        checkBounds(col);
+        _cellType     = -1; // Force 'setCellType' to create a first Record
+        _stringValue  = null;
+        _book    = book;
+        _sheet   = sheet;
+
+        short xfindex = sheet.getSheet().getXFIndexForColAt(col);
+        setCellType(type,false,row,col,xfindex);
+    }
+
+    /**
+     * Creates an HSSFCell from a CellValueRecordInterface.  HSSFSheet uses this when
+     * reading in cells from an existing sheet.
+     *
+     * @param book - Workbook record of the workbook containing this cell
+     * @param sheet - Sheet record of the sheet containing this cell
+     * @param cval - the Cell Value Record we wish to represent
+     */
+    protected HSSFCell(HSSFWorkbook book, HSSFSheet sheet, CellValueRecordInterface cval) {
+        _record      = cval;
+        _cellType    = determineType(cval);
+        _stringValue = null;
+        _book   = book;
+        _sheet  = sheet;
+        switch (_cellType)
+        {
+            case CELL_TYPE_STRING :
+                _stringValue = new HSSFRichTextString(book.getWorkbook(), (LabelSSTRecord ) cval);
+                break;
+
+            case CELL_TYPE_BLANK :
+                break;
+
+            case CELL_TYPE_FORMULA :
+                _stringValue=new HSSFRichTextString(((FormulaRecordAggregate) cval).getStringValue());
+                break;
+        }
+        ExtendedFormatRecord xf = book.getWorkbook().getExFormatAt(cval.getXFIndex());
+
+        setCellStyle(new HSSFCellStyle(cval.getXFIndex(), xf, book));
+    }
+
+
+    /**
+     * used internally -- given a cell value record, figure out its type
+     */
+    private static int determineType(CellValueRecordInterface cval) {
+        if (cval instanceof FormulaRecordAggregate) {
+            return HSSFCell.CELL_TYPE_FORMULA;
+        }
+        // all others are plain BIFF records
+        Record record = ( Record ) cval;
+        switch (record.getSid()) {
+
+            case NumberRecord.sid :   return HSSFCell.CELL_TYPE_NUMERIC;
+            case BlankRecord.sid :    return HSSFCell.CELL_TYPE_BLANK;
+            case LabelSSTRecord.sid : return HSSFCell.CELL_TYPE_STRING;
+            case BoolErrRecord.sid :
+                BoolErrRecord boolErrRecord = ( BoolErrRecord ) record;
+
+                return boolErrRecord.isBoolean()
+                         ? HSSFCell.CELL_TYPE_BOOLEAN
+                         : HSSFCell.CELL_TYPE_ERROR;
+        }
+        throw new RuntimeException("Bad cell value rec (" + cval.getClass().getName() + ")");
+    }
+
+
+    /**
+     * @return the (zero based) index of the row containing this cell
+     */
+    public int getRowIndex() {
+        return _record.getRow();
+    }
+
+    public int getColumnIndex() {
+        return _record.getColumn() & 0xFFFF;
+    }
+
+    /**
+     * set the cells type (numeric, formula or string)
+     * @see #CELL_TYPE_NUMERIC
+     * @see #CELL_TYPE_STRING
+     * @see #CELL_TYPE_FORMULA
+     * @see #CELL_TYPE_BLANK
+     * @see #CELL_TYPE_BOOLEAN
+     * @see #CELL_TYPE_ERROR
+     */
+    public void setCellType(int cellType) {
+        notifyFormulaChanging();
+        if(isPartOfArrayFormulaGroup()){
+            notifyArrayFormulaChanging();
+        }
+        int row=_record.getRow();
+        short col=_record.getColumn();
+        short styleIndex=_record.getXFIndex();
+        setCellType(cellType, true, row, col, styleIndex);
+    }
+
+    /**
+     * sets the cell type. The setValue flag indicates whether to bother about
+     *  trying to preserve the current value in the new record if one is created.
+     *  <p>
+     *  The @see #setCellValue method will call this method with false in setValue
+     *  since it will overwrite the cell value later
+     *
+     */
+
+    private void setCellType(int cellType, boolean setValue, int row,short col, short styleIndex)
+    {
+
+        if (cellType > CELL_TYPE_ERROR)
+        {
+            throw new RuntimeException("I have no idea what type that is!");
+        }
+        switch (cellType)
+        {
+
+            case CELL_TYPE_FORMULA :
+                FormulaRecordAggregate frec;
+
+                if (cellType != _cellType) {
+                    frec = _sheet.getSheet().getRowsAggregate().createFormula(row, col);
+                } else {
+                    frec = (FormulaRecordAggregate) _record;
+                    frec.setRow(row);
+                    frec.setColumn(col);
+                }
+                if (setValue)
+                {
+                    frec.getFormulaRecord().setValue(getNumericCellValue());
+                }
+                frec.setXFIndex(styleIndex);
+                _record = frec;
+                break;
+
+            case CELL_TYPE_NUMERIC :
+                NumberRecord nrec = null;
+
+                if (cellType != _cellType)
+                {
+                    nrec = new NumberRecord();
+                }
+                else
+                {
+                    nrec = ( NumberRecord ) _record;
+                }
+                nrec.setColumn(col);
+                if (setValue)
+                {
+                    nrec.setValue(getNumericCellValue());
+                }
+                nrec.setXFIndex(styleIndex);
+                nrec.setRow(row);
+                _record = nrec;
+                break;
+
+            case CELL_TYPE_STRING :
+                LabelSSTRecord lrec;
+
+                if (cellType == _cellType) {
+                    lrec = (LabelSSTRecord) _record;
+                } else {
+                    lrec = new LabelSSTRecord();
+                    lrec.setColumn(col);
+                    lrec.setRow(row);
+                    lrec.setXFIndex(styleIndex);
+                }
+                if (setValue) {
+                    String str = convertCellValueToString();
+                    int sstIndex = _book.getWorkbook().addSSTString(new UnicodeString(str));
+                    lrec.setSSTIndex(sstIndex);
+                    UnicodeString us = _book.getWorkbook().getSSTString(sstIndex);
+                    _stringValue = new HSSFRichTextString();
+                    _stringValue.setUnicodeString(us);
+                }
+                _record = lrec;
+                break;
+
+            case CELL_TYPE_BLANK :
+                BlankRecord brec = null;
+
+                if (cellType != _cellType)
+                {
+                    brec = new BlankRecord();
+                }
+                else
+                {
+                    brec = ( BlankRecord ) _record;
+                }
+                brec.setColumn(col);
+
+                // During construction the cellStyle may be null for a Blank cell.
+                brec.setXFIndex(styleIndex);
+                brec.setRow(row);
+                _record = brec;
+                break;
+
+            case CELL_TYPE_BOOLEAN :
+                BoolErrRecord boolRec = null;
+
+                if (cellType != _cellType)
+                {
+                    boolRec = new BoolErrRecord();
+                }
+                else
+                {
+                    boolRec = ( BoolErrRecord ) _record;
+                }
+                boolRec.setColumn(col);
+                if (setValue)
+                {
+                    boolRec.setValue(convertCellValueToBoolean());
+                }
+                boolRec.setXFIndex(styleIndex);
+                boolRec.setRow(row);
+                _record = boolRec;
+                break;
+
+            case CELL_TYPE_ERROR :
+                BoolErrRecord errRec = null;
+
+                if (cellType != _cellType)
+                {
+                    errRec = new BoolErrRecord();
+                }
+                else
+                {
+                    errRec = ( BoolErrRecord ) _record;
+                }
+                errRec.setColumn(col);
+                if (setValue)
+                {
+                    errRec.setValue((byte)HSSFErrorConstants.ERROR_VALUE);
+                }
+                errRec.setXFIndex(styleIndex);
+                errRec.setRow(row);
+                _record = errRec;
+                break;
+        }
+        if (cellType != _cellType &&
+            _cellType!=-1 )  // Special Value to indicate an uninitialized Cell
+        {
+            _sheet.getSheet().replaceValueRecord(_record);
+        }
+        _cellType = cellType;
+    }
+
+    /**
+     * get the cells type (numeric, formula or string)
+     * @see #CELL_TYPE_STRING
+     * @see #CELL_TYPE_NUMERIC
+     * @see #CELL_TYPE_FORMULA
+     * @see #CELL_TYPE_BOOLEAN
+     * @see #CELL_TYPE_ERROR
+     */
+
+    public int getCellType()
+    {
+        return _cellType;
+    }
+
+
+    /**
+     * Should be called any time that a formula could potentially be deleted.
+     * Does nothing if this cell currently does not hold a formula
+     */
+    private void notifyFormulaChanging() {
+        if (_record instanceof FormulaRecordAggregate) {
+            ((FormulaRecordAggregate)_record).notifyFormulaChanging();
+        }
+    }
+
+    public String getCellFormula() {
+        if (!(_record instanceof FormulaRecordAggregate)) {
+            throw typeMismatch(CELL_TYPE_FORMULA, _cellType, true);
+        }
+        return HSSFFormulaParser.toFormulaString(_book, ((FormulaRecordAggregate)_record).getFormulaTokens());
+    }
+
+    /**
+     * Used to help format error messages
+     */
+    private static String getCellTypeName(int cellTypeCode) {
+        switch (cellTypeCode) {
+            case CELL_TYPE_BLANK:   return "blank";
+            case CELL_TYPE_STRING:  return "text";
+            case CELL_TYPE_BOOLEAN: return "boolean";
+            case CELL_TYPE_ERROR:   return "error";
+            case CELL_TYPE_NUMERIC: return "numeric";
+            case CELL_TYPE_FORMULA: return "formula";
+        }
+        return "#unknown cell type (" + cellTypeCode + ")#";
+    }
+
+    private static RuntimeException typeMismatch(int expectedTypeCode, int actualTypeCode, boolean isFormulaCell) {
+        String msg = "Cannot get a "
+            + getCellTypeName(expectedTypeCode) + " value from a "
+            + getCellTypeName(actualTypeCode) + " " + (isFormulaCell ? "formula " : "") + "cell";
+        return new IllegalStateException(msg);
+    }
+    private static void checkFormulaCachedValueType(int expectedTypeCode, FormulaRecord fr) {
+        int cachedValueType = fr.getCachedResultType();
+        if (cachedValueType != expectedTypeCode) {
+            throw typeMismatch(expectedTypeCode, cachedValueType, true);
+        }
+    }
+
+    /**
+     * Get the value of the cell as a number.
+     * For strings we throw an exception.
+     * For blank cells we return a 0.
+     * See {@link HSSFDataFormatter} for turning this
+     *  number into a string similar to that which
+     *  Excel would render this number as.
+     */
+    public double getNumericCellValue() {
+
+        switch(_cellType) {
+            case CELL_TYPE_BLANK:
+                return 0.0;
+            case CELL_TYPE_NUMERIC:
+                return ((NumberRecord)_record).getValue();
+            default:
+                throw typeMismatch(CELL_TYPE_NUMERIC, _cellType, false);
+            case CELL_TYPE_FORMULA:
+                break;
+        }
+        FormulaRecord fr = ((FormulaRecordAggregate)_record).getFormulaRecord();
+        checkFormulaCachedValueType(CELL_TYPE_NUMERIC, fr);
+        return fr.getValue();
+    }
+
+    /**
+     * Get the value of the cell as a date.
+     * For strings we throw an exception.
+     * For blank cells we return a null.
+     * See {@link HSSFDataFormatter} for formatting
+     *  this date into a string similar to how excel does.
+     */
+    public Date getDateCellValue() {
+
+        if (_cellType == CELL_TYPE_BLANK) {
+            return null;
+        }
+        double value = getNumericCellValue();
+        if (_book.getWorkbook().isUsing1904DateWindowing()) {
+            return DateUtil.getJavaDate(value, true);
+        }
+        return DateUtil.getJavaDate(value, false);
+    }
+
+    /**
+     * get the value of the cell as a string - for numeric cells we throw an exception.
+     * For blank cells we return an empty string.
+     * For formulaCells that are not string Formulas, we throw an exception
+     */
+    public String getStringCellValue()
+    {
+      HSSFRichTextString str = getRichStringCellValue();
+      return str.getString();
+    }
+
+    /**
+     * get the value of the cell as a string - for numeric cells we throw an exception.
+     * For blank cells we return an empty string.
+     * For formulaCells that are not string Formulas, we throw an exception
+     */
+    public HSSFRichTextString getRichStringCellValue() {
+
+        switch(_cellType) {
+            case CELL_TYPE_BLANK:
+                return new HSSFRichTextString("");
+            case CELL_TYPE_STRING:
+                return _stringValue;
+            default:
+                throw typeMismatch(CELL_TYPE_STRING, _cellType, false);
+            case CELL_TYPE_FORMULA:
+                break;
+        }
+        FormulaRecordAggregate fra = ((FormulaRecordAggregate)_record);
+        checkFormulaCachedValueType(CELL_TYPE_STRING, fra.getFormulaRecord());
+        String strVal = fra.getStringValue();
+        return new HSSFRichTextString(strVal == null ? "" : strVal);
+    }
+
+
+
+    /**
+     * Chooses a new boolean value for the cell when its type is changing.<p/>
+     *
+     * Usually the caller is calling setCellType() with the intention of calling
+     * setCellValue(boolean) straight afterwards.  This method only exists to give
+     * the cell a somewhat reasonable value until the setCellValue() call (if at all).
+     * TODO - perhaps a method like setCellTypeAndValue(int, Object) should be introduced to avoid this
+     */
+    private boolean convertCellValueToBoolean() {
+
+        switch (_cellType) {
+            case CELL_TYPE_BOOLEAN:
+                return (( BoolErrRecord ) _record).getBooleanValue();
+            case CELL_TYPE_STRING:
+                int sstIndex = ((LabelSSTRecord)_record).getSSTIndex();
+                String text = _book.getWorkbook().getSSTString(sstIndex).getString();
+                return Boolean.valueOf(text).booleanValue();
+            case CELL_TYPE_NUMERIC:
+                return ((NumberRecord)_record).getValue() != 0;
+
+            case CELL_TYPE_FORMULA:
+                // use cached formula result if it's the right type:
+                FormulaRecord fr = ((FormulaRecordAggregate)_record).getFormulaRecord();
+                checkFormulaCachedValueType(CELL_TYPE_BOOLEAN, fr);
+                return fr.getCachedBooleanValue();
+            // Other cases convert to false
+            // These choices are not well justified.
+            case CELL_TYPE_ERROR:
+            case CELL_TYPE_BLANK:
+                return false;
+        }
+        throw new RuntimeException("Unexpected cell type (" + _cellType + ")");
+    }
+    private String convertCellValueToString() {
+
+        switch (_cellType) {
+            case CELL_TYPE_BLANK:
+                return "";
+            case CELL_TYPE_BOOLEAN:
+                return ((BoolErrRecord) _record).getBooleanValue() ? "TRUE" : "FALSE";
+            case CELL_TYPE_STRING:
+                int sstIndex = ((LabelSSTRecord)_record).getSSTIndex();
+                return _book.getWorkbook().getSSTString(sstIndex).getString();
+            case CELL_TYPE_NUMERIC:
+                return NumberToTextConverter.toText(((NumberRecord)_record).getValue());
+            case CELL_TYPE_ERROR:
+                   return HSSFErrorConstants.getText(((BoolErrRecord) _record).getErrorValue());
+            case CELL_TYPE_FORMULA:
+                // should really evaluate, but HSSFCell can't call HSSFFormulaEvaluator
+                // just use cached formula result instead
+                break;
+            default:
+                throw new IllegalStateException("Unexpected cell type (" + _cellType + ")");
+        }
+        FormulaRecordAggregate fra = ((FormulaRecordAggregate)_record);
+        FormulaRecord fr = fra.getFormulaRecord();
+        switch (fr.getCachedResultType()) {
+            case CELL_TYPE_BOOLEAN:
+                return fr.getCachedBooleanValue() ? "TRUE" : "FALSE";
+            case CELL_TYPE_STRING:
+                return fra.getStringValue();
+            case CELL_TYPE_NUMERIC:
+                return NumberToTextConverter.toText(fr.getValue());
+            case CELL_TYPE_ERROR:
+                   return HSSFErrorConstants.getText(fr.getCachedErrorValue());
+        }
+        throw new IllegalStateException("Unexpected formula result type (" + _cellType + ")");
+    }
+
+    /**
+     * get the value of the cell as a boolean.  For strings, numbers, and errors, we throw an exception.
+     * For blank cells we return a false.
+     */
+    public boolean getBooleanCellValue() {
+
+        switch(_cellType) {
+            case CELL_TYPE_BLANK:
+                return false;
+            case CELL_TYPE_BOOLEAN:
+                return (( BoolErrRecord ) _record).getBooleanValue();
+            default:
+                throw typeMismatch(CELL_TYPE_BOOLEAN, _cellType, false);
+            case CELL_TYPE_FORMULA:
+                break;
+        }
+        FormulaRecord fr = ((FormulaRecordAggregate)_record).getFormulaRecord();
+        checkFormulaCachedValueType(CELL_TYPE_BOOLEAN, fr);
+        return fr.getCachedBooleanValue();
+    }
+
+    public void setCellStyle(HSSFCellStyle style) {
+        // Verify it really does belong to our workbook
+        style.verifyBelongsToWorkbook(_book);
+
+        // Change our cell record to use this style
+        _record.setXFIndex(style.getIndex());
+    }
+
+    /**
+     * get the style for the cell.  This is a reference to a cell style contained in the workbook
+     * object.
+     * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short)
+     */
+    public HSSFCellStyle getCellStyle()
+    {
+      short styleIndex=_record.getXFIndex();
+      ExtendedFormatRecord xf = _book.getWorkbook().getExFormatAt(styleIndex);
+      return new HSSFCellStyle(styleIndex, xf, _book);
+    }
+
+    /**
+     * Should only be used by HSSFSheet and friends.  Returns the low level CellValueRecordInterface record
+     *
+     * @return CellValueRecordInterface representing the cell via the low level api.
+     */
+
+    protected CellValueRecordInterface getCellValueRecord()
+    {
+        return _record;
+    }
+
+    /**
+     * @throws RuntimeException if the bounds are exceeded.
+     */
+    private static void checkBounds(int cellIndex) {
+        if (cellIndex < 0 || cellIndex > LAST_COLUMN_NUMBER) {
+            throw new IllegalArgumentException("Invalid column index (" + cellIndex
+                    + ").  Allowable column range for " + FILE_FORMAT_NAME + " is (0.."
+                    + LAST_COLUMN_NUMBER + ") or ('A'..'" + LAST_COLUMN_NAME + "')");
+        }
+    }
+
+
+    /**
+     * Returns a string representation of the cell
+     *
+     * This method returns a simple representation,
+     * anthing more complex should be in user code, with
+     * knowledge of the semantics of the sheet being processed.
+     *
+     * Formula cells return the formula string,
+     * rather than the formula result.
+     * Dates are displayed in dd-MMM-yyyy format
+     * Errors are displayed as #ERR&lt;errIdx&gt;
+     */
+    public String toString() {
+        switch (getCellType()) {
+            case CELL_TYPE_BLANK:
+                return "";
+            case CELL_TYPE_BOOLEAN:
+                return getBooleanCellValue()?"TRUE":"FALSE";
+            case CELL_TYPE_ERROR:
+                return ErrorEval.getText((( BoolErrRecord ) _record).getErrorValue());
+            case CELL_TYPE_FORMULA:
+                return getCellFormula();
+            case CELL_TYPE_NUMERIC:
+                //TODO apply the dataformat for this cell
+                if (DateUtil.isCellDateFormatted(this)) {
+                    DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
+                    return sdf.format(getDateCellValue());
+                }
+				return  String.valueOf(getNumericCellValue());
+            case CELL_TYPE_STRING:
+                return getStringCellValue();
+            default:
+                return "Unknown Cell Type: " + getCellType();
+        }
+    }
+
+    public CellRangeAddress getArrayFormulaRange() {
+        if (_cellType != CELL_TYPE_FORMULA) {
+            String ref = new CellReference(this).formatAsString();
+            throw new IllegalStateException("Cell " + ref
+                    + " is not part of an array formula.");
+        }
+        return ((FormulaRecordAggregate)_record).getArrayFormulaRange();
+    }
+
+    public boolean isPartOfArrayFormulaGroup() {
+        if (_cellType != CELL_TYPE_FORMULA) {
+            return false;
+        }
+        return ((FormulaRecordAggregate)_record).isPartOfArrayFormula();
+    }
+
+    /**
+     * The purpose of this method is to validate the cell state prior to modification
+     *
+     * @see #notifyArrayFormulaChanging()
+     */
+    void notifyArrayFormulaChanging(String msg){
+        CellRangeAddress cra = getArrayFormulaRange();
+        if(cra.getNumberOfCells() > 1) {
+            throw new IllegalStateException(msg);
+        }
+        //un-register the single-cell array formula from the parent XSSFSheet
+        getRow().getSheet().removeArrayFormula(this);
+    }
+
+    /**
+     * Called when this cell is modified.
+     * <p>
+     * The purpose of this method is to validate the cell state prior to modification.
+     * </p>
+     *
+     * @see #setCellType(int)
+     * @see #setCellFormula(String)
+     * @see HSSFRow#removeCell(org.apache.poi.ss.usermodel.Cell)
+     * @see org.apache.poi.hssf.usermodel.HSSFSheet#removeRow(org.apache.poi.ss.usermodel.Row)
+     * @see org.apache.poi.hssf.usermodel.HSSFSheet#shiftRows(int, int, int)
+     * @see org.apache.poi.hssf.usermodel.HSSFSheet#addMergedRegion(org.apache.poi.ss.util.CellRangeAddress)
+     * @throws IllegalStateException if modification is not allowed
+     */
+    void notifyArrayFormulaChanging(){
+        CellReference ref = new CellReference(this);
+        String msg = "Cell "+ref.formatAsString()+" is part of a multi-cell array formula. " +
+                "You cannot change part of an array.";
+        notifyArrayFormulaChanging(msg);
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFCellStyle.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFCellStyle.java	(revision 28000)
@@ -0,0 +1,133 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.usermodel;
+
+import org.apache.poi.hssf.model.InternalWorkbook;
+import org.apache.poi.hssf.record.ExtendedFormatRecord;
+import org.apache.poi.ss.usermodel.CellStyle;
+
+/**
+ * High level representation of the style of a cell in a sheet of a workbook.
+ *
+ * @author  Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createCellStyle()
+ * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(short)
+ * @see org.apache.poi.hssf.usermodel.HSSFCell#setCellStyle(HSSFCellStyle)
+ */
+public final class HSSFCellStyle implements CellStyle {
+    private ExtendedFormatRecord _format                     = null;
+    private short                _index                      = 0;
+    private InternalWorkbook             _workbook                   = null;
+
+
+    /** Creates new HSSFCellStyle why would you want to do this?? */
+    protected HSSFCellStyle(short index, ExtendedFormatRecord rec, HSSFWorkbook workbook)
+    {
+    	this(index, rec, workbook.getWorkbook());
+    }
+    protected HSSFCellStyle(short index, ExtendedFormatRecord rec, InternalWorkbook workbook)
+    {
+        _workbook = workbook;
+        _index = index;
+        _format     = rec;
+    }
+
+    /**
+     * get the index within the HSSFWorkbook (sequence within the collection of ExtnededFormat objects)
+     * @return unique index number of the underlying record this style represents (probably you don't care
+     *  unless you're comparing which one is which)
+     */
+    public short getIndex()
+    {
+        return _index;
+    }
+
+    /**
+     * get the index of the format
+     * @see org.apache.poi.hssf.usermodel.HSSFDataFormat
+     */
+
+    public short getDataFormat()
+    {
+        return _format.getFormatIndex();
+    }
+
+    /**
+     * Get the contents of the format string, by looking up
+     *  the DataFormat against the bound workbook
+     * @see org.apache.poi.hssf.usermodel.HSSFDataFormat
+     * @return the format string or "General" if not found
+     */
+    public String getDataFormatString() {
+        return getDataFormatString(_workbook);
+    }
+
+    /**
+     * Get the contents of the format string, by looking up
+     *  the DataFormat against the supplied low level workbook
+     * @see org.apache.poi.hssf.usermodel.HSSFDataFormat
+     */
+    public String getDataFormatString(org.apache.poi.hssf.model.InternalWorkbook workbook) {
+    	HSSFDataFormat format = new HSSFDataFormat( workbook );
+
+        return format.getFormat(getDataFormat());
+    }
+
+    /**
+     * Verifies that this style belongs to the supplied Workbook.
+     * Will throw an exception if it belongs to a different one.
+     * This is normally called when trying to assign a style to a
+     *  cell, to ensure the cell and the style are from the same
+     *  workbook (if they're not, it won't work)
+     * @throws IllegalArgumentException if there's a workbook mis-match
+     */
+    public void verifyBelongsToWorkbook(HSSFWorkbook wb) {
+		if(wb.getWorkbook() != _workbook) {
+			throw new IllegalArgumentException("This Style does not belong to the supplied Workbook. Are you trying to assign a style from one workbook to the cell of a differnt workbook?");
+		}
+	}
+
+
+
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((_format == null) ? 0 : _format.hashCode());
+		result = prime * result + _index;
+		return result;
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj) return true;
+		if (obj == null) return false;
+		if (obj instanceof HSSFCellStyle) {
+			final HSSFCellStyle other = (HSSFCellStyle) obj;
+			if (_format == null) {
+				if (other._format != null)
+					return false;
+			} else if (!_format.equals(other._format))
+				return false;
+			if (_index != other._index)
+				return false;
+			return true;
+		}
+		return false;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFDataFormat.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFDataFormat.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFDataFormat.java	(revision 28000)
@@ -0,0 +1,91 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+==================================================================== */
+
+
+/*
+ * HSSFDataFormat.java
+ *
+ * Created on December 18, 2001, 12:42 PM
+ */
+package org.apache.poi.hssf.usermodel;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.poi.hssf.model.InternalWorkbook;
+import org.apache.poi.hssf.record.FormatRecord;
+import org.apache.poi.ss.usermodel.BuiltinFormats;
+import org.apache.poi.ss.usermodel.DataFormat;
+
+/**
+ * Identifies both built-in and user defined formats within a workbook.<p/>
+ * See {@link BuiltinFormats} for a list of supported built-in formats.<p/>
+ *
+ * <b>International Formats</b><br/>
+ * Since version 2003 Excel has supported international formats.  These are denoted
+ * with a prefix "[$-xxx]" (where xxx is a 1-7 digit hexadecimal number).
+ * See the Microsoft article
+ * <a href="http://office.microsoft.com/assistance/hfws.aspx?AssetID=HA010346351033&CTT=6&Origin=EC010272491033">
+ *   Creating international number formats
+ * </a> for more details on these codes.
+ *
+ * @author  Andrew C. Oliver (acoliver at apache dot org)
+ * @author  Shawn M. Laubach (slaubach at apache dot org)
+ */
+public final class HSSFDataFormat implements DataFormat {
+	private static final String[] _builtinFormats = BuiltinFormats.getAll();
+
+	private final Vector<String> _formats = new Vector<String>();
+	private boolean _movedBuiltins = false;  // Flag to see if need to
+	// check the built in list
+	// or if the regular list
+	// has all entries.
+
+	/**
+	 * Constructs a new data formatter.  It takes a workbook to have
+	 * access to the workbooks format records.
+	 * @param workbook the workbook the formats are tied to.
+	 */
+	HSSFDataFormat(InternalWorkbook workbook) {
+		Iterator<FormatRecord> i = workbook.getFormats().iterator();
+		while (i.hasNext()) {
+			FormatRecord r = i.next();
+			if (_formats.size() < r.getIndexCode() + 1) {
+				_formats.setSize(r.getIndexCode() + 1);
+			}
+			_formats.set(r.getIndexCode(), r.getFormatString());
+		}
+	}
+
+
+
+	/**
+	 * get the format string that matches the given format index
+	 * @param index of a format
+	 * @return string represented at index of format or null if there is not a  format at that index
+	 */
+	public String getFormat(short index) {
+		if (_movedBuiltins) {
+			return _formats.get(index);
+		}
+		if (_builtinFormats.length > index && _builtinFormats[index] != null) {
+			return _builtinFormats[index];
+		}
+		return _formats.get(index);
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFErrorConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFErrorConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFErrorConstants.java	(revision 28000)
@@ -0,0 +1,27 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.usermodel;
+import org.apache.poi.ss.usermodel.ErrorConstants;
+
+/**
+ * Contains raw Excel error codes (as defined in OOO's excelfileformat.pdf (2.5.6)
+ * 
+ * @author  Michael Harhen
+ */
+public final class HSSFErrorConstants extends ErrorConstants {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java	(revision 28000)
@@ -0,0 +1,60 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.usermodel;
+
+import org.apache.poi.hssf.model.InternalWorkbook;
+import org.apache.poi.hssf.record.formula.NamePtg;
+import org.apache.poi.hssf.record.formula.NameXPtg;
+import org.apache.poi.ss.formula.EvaluationWorkbook;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+
+/**
+ * Internal POI use only
+ *
+ * @author Josh Micich
+ */
+public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, EvaluationWorkbook {
+
+	private final InternalWorkbook _iBook;
+
+	public static HSSFEvaluationWorkbook create(HSSFWorkbook book) {
+		if (book == null) {
+			return null;
+		}
+		return new HSSFEvaluationWorkbook(book);
+	}
+
+	private HSSFEvaluationWorkbook(HSSFWorkbook book) {
+		_iBook = book.getWorkbook();
+	}
+
+	public ExternalSheet getExternalSheet(int externSheetIndex) {
+		return _iBook.getExternalSheet(externSheetIndex);
+	}
+	
+	public String resolveNameXText(NameXPtg n) {
+		return _iBook.resolveNameXText(n.getSheetRefIndex(), n.getNameIndex());
+	}
+
+	public String getSheetNameByExternSheet(int externSheetIndex) {
+		return _iBook.findSheetNameFromExternSheet(externSheetIndex);
+	}
+	public String getNameText(NamePtg namePtg) {
+		return _iBook.getNameRecord(namePtg.getIndex()).getNameText();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFName.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFName.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFName.java	(revision 28000)
@@ -0,0 +1,51 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.usermodel;
+
+import org.apache.poi.hssf.record.NameRecord;
+
+/**
+ * High Level Representation of a 'defined name' which could be a 'built-in' name,
+ * 'named range' or name of a user defined function.
+ *
+ * @author Libin Roman (Vista Portal LDT. Developer)
+ */
+public final class HSSFName {
+    private NameRecord _definedNameRec;
+
+    /** 
+     * Creates new HSSFName   - called by HSSFWorkbook to create a name from
+     * scratch.
+     *
+     * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createName()
+     * @param name the Name Record
+     * @param book workbook object associated with the sheet.
+     */
+    /* package */ HSSFName(final HSSFWorkbook book, final NameRecord name) {
+        _definedNameRec = name;
+    }
+
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer(64);
+        sb.append(getClass().getName()).append(" [");
+        sb.append(_definedNameRec.getNameText());
+        sb.append("]");
+        return sb.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFRichTextString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFRichTextString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFRichTextString.java	(revision 28000)
@@ -0,0 +1,276 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.usermodel;
+
+import java.util.Iterator;
+
+import org.apache.poi.hssf.model.InternalWorkbook;
+import org.apache.poi.hssf.record.LabelSSTRecord;
+import org.apache.poi.hssf.record.common.UnicodeString;
+import org.apache.poi.hssf.record.common.UnicodeString.FormatRun;
+import org.apache.poi.ss.usermodel.RichTextString;
+/**
+ * Rich text unicode string.  These strings can have fonts applied to
+ * arbitary parts of the string.
+ *
+ * <p>
+ * Note, that in certain cases creating too many HSSFRichTextString cells may cause Excel 2003 and lower to crash
+ * when changing the color of the cells and then saving the Excel file. Compare two snippets that produce equivalent output:
+ *
+ * <p><blockquote><pre>
+ *  HSSFCell hssfCell = row.createCell(idx);
+ *  //rich text consists of two runs
+ *  HSSFRichTextString richString = new HSSFRichTextString( "Hello, World!" );
+ *  richString.applyFont( 0, 6, font1 );
+ *  richString.applyFont( 6, 13, font2 );
+ *  hssfCell.setCellValue( richString );
+ * </pre></blockquote>
+ *
+ * and
+ *
+ * <p><blockquote><pre>
+ *  //create a cell style and assign the first font to it
+ *  HSSFCellStyle style = workbook.createCellStyle();
+ *  style.setFont(font1);
+ *
+ *  HSSFCell hssfCell = row.createCell(idx);
+ *  hssfCell.setCellStyle(style);
+ *
+ *  //rich text consists of one run overriding the cell style
+ *  HSSFRichTextString richString = new HSSFRichTextString( "Hello, World!" );
+ *  richString.applyFont( 6, 13, font2 );
+ *  hssfCell.setCellValue( richString );
+ * </pre></blockquote><p>
+ *
+ * Excel always uses the latter approach: for a reach text containing N runs Excel saves the font of the first run in the cell's
+ * style and subsequent N-1 runs override this font.
+ *
+ * <p> For more information regarding this behavior please consult Bugzilla 47543:
+ *
+ * <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=47543">
+ * https://issues.apache.org/bugzilla/show_bug.cgi?id=47543</a>
+ * <p>
+ *
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @author Jason Height (jheight at apache.org)
+ */
+public final class HSSFRichTextString implements Comparable<HSSFRichTextString>, RichTextString {
+    /** Place holder for indicating that NO_FONT has been applied here */
+    public static final short NO_FONT = 0;
+
+    private UnicodeString _string;
+    private InternalWorkbook _book;
+    private LabelSSTRecord _record;
+
+    public HSSFRichTextString()
+    {
+        this("");
+    }
+
+    public HSSFRichTextString(String string) {
+        if (string == null) {
+            _string = new UnicodeString("");
+        } else {
+            _string = new UnicodeString(string);
+        }
+    }
+
+    HSSFRichTextString(InternalWorkbook book, LabelSSTRecord record) {
+      setWorkbookReferences(book, record);
+
+      _string = book.getSSTString(record.getSSTIndex());
+    }
+
+    /** This must be called to setup the internal work book references whenever
+     * a RichTextString is added to a cell
+     */
+    void setWorkbookReferences(InternalWorkbook book, LabelSSTRecord record) {
+      _book = book;
+      _record = record;
+    }
+
+    /** Called whenever the unicode string is modified. When it is modified
+     *  we need to create a new SST index, so that other LabelSSTRecords will not
+     *  be affected by changes that we make to this string.
+     */
+    private UnicodeString cloneStringIfRequired() {
+      if (_book == null)
+        return _string;
+      UnicodeString s = (UnicodeString)_string.clone();
+      return s;
+    }
+
+    private void addToSSTIfRequired() {
+      if (_book != null) {
+        int index = _book.addSSTString(_string);
+        _record.setSSTIndex(index);
+        //The act of adding the string to the SST record may have meant that
+        //an existing string was returned for the index, so update our local version
+        _string = _book.getSSTString(index);
+      }
+    }
+
+
+    /**
+     * Applies a font to the specified characters of a string.
+     *
+     * @param startIndex    The start index to apply the font to (inclusive)
+     * @param endIndex      The end index to apply the font to (exclusive)
+     * @param fontIndex     The font to use.
+     */
+    public void applyFont(int startIndex, int endIndex, short fontIndex)
+    {
+        if (startIndex > endIndex)
+            throw new IllegalArgumentException("Start index must be less than end index.");
+        if (startIndex < 0 || endIndex > length())
+            throw new IllegalArgumentException("Start and end index not in range.");
+        if (startIndex == endIndex)
+            return;
+
+        //Need to check what the font is currently, so we can reapply it after
+        //the range is completed
+        short currentFont = NO_FONT;
+        if (endIndex != length()) {
+          currentFont = this.getFontAtIndex(endIndex);
+        }
+
+        //Need to clear the current formatting between the startIndex and endIndex
+        _string = cloneStringIfRequired();
+        Iterator<FormatRun> formatting = _string.formatIterator();
+        if (formatting != null) {
+          while (formatting.hasNext()) {
+            FormatRun r = formatting.next();
+            if ((r.getCharacterPos() >= startIndex) && (r.getCharacterPos() < endIndex))
+              formatting.remove();
+          }
+        }
+
+
+        _string.addFormatRun(new UnicodeString.FormatRun((short)startIndex, fontIndex));
+        if (endIndex != length())
+          _string.addFormatRun(new UnicodeString.FormatRun((short)endIndex, currentFont));
+
+        addToSSTIfRequired();
+    }
+
+
+    /**
+     * Returns the plain string representation.
+     */
+    public String getString()
+    {
+        return _string.getString();
+    }
+
+
+    /** Used internally by the HSSFCell to set the internal string value*/
+    void setUnicodeString(UnicodeString str) {
+      this._string = str;
+    }
+
+
+    /**
+     * @return  the number of characters in the text.
+     */
+    public int length() {
+        return _string.getCharCount();
+    }
+
+    /**
+     * Returns the font in use at a particular index.
+     *
+     * @param index         The index.
+     * @return              The font that's currently being applied at that
+     *                      index or null if no font is being applied or the
+     *                      index is out of range.
+     */
+    public short getFontAtIndex( int index )
+    {
+      int size = _string.getFormatRunCount();
+      UnicodeString.FormatRun currentRun = null;
+      for (int i=0;i<size;i++) {
+        UnicodeString.FormatRun r = _string.getFormatRun(i);
+        if (r.getCharacterPos() > index) {
+            break;
+        }
+        currentRun = r;
+      }
+      if (currentRun == null) {
+          return NO_FONT;
+      }
+      return currentRun.getFontIndex();
+    }
+
+    /**
+     * @return  The number of formatting runs used. There will always be at
+     *          least one of font NO_FONT.
+     *
+     * @see #NO_FONT
+     */
+    public int numFormattingRuns()
+    {
+        return _string.getFormatRunCount();
+    }
+
+    /**
+     * The index within the string to which the specified formatting run applies.
+     * @param index     the index of the formatting run
+     * @return  the index within the string.
+     */
+    public int getIndexOfFormattingRun(int index)
+    {
+        UnicodeString.FormatRun r = _string.getFormatRun(index);
+        return r.getCharacterPos();
+    }
+
+    /**
+     * Gets the font used in a particular formatting run.
+     *
+     * @param index     the index of the formatting run
+     * @return  the font number used.
+     */
+    public short getFontOfFormattingRun(int index)
+    {
+      UnicodeString.FormatRun r = _string.getFormatRun(index);
+      return r.getFontIndex();
+    }
+
+    /**
+     * Compares one rich text string to another.
+     */
+    public int compareTo(HSSFRichTextString r) {
+       return _string.compareTo(r._string);
+    }
+
+    public boolean equals(Object o) {
+      if (o instanceof HSSFRichTextString) {
+        return _string.equals(((HSSFRichTextString)o)._string);
+      }
+      return false;
+
+    }
+
+    /**
+     * @return  the plain text representation of this string.
+     */
+    public String toString()
+    {
+        return _string.toString();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFRow.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFRow.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFRow.java	(revision 28000)
@@ -0,0 +1,376 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.usermodel;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.RowRecord;
+import org.apache.poi.ss.SpreadsheetVersion;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+
+/**
+ * High level representation of a row of a spreadsheet.
+ *
+ * Only rows that have cells should be added to a Sheet.
+ *
+ * @author  Andrew C. Oliver (acoliver at apache dot org)
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class HSSFRow implements Row {
+
+    // used for collections
+    public final static int INITIAL_CAPACITY = 5;
+
+    private int rowNum;
+    private HSSFCell[] cells=new HSSFCell[INITIAL_CAPACITY];
+
+    /**
+     * reference to low level representation
+     */
+    private RowRecord row;
+
+    /**
+     * reference to containing low level Workbook
+     */
+    private HSSFWorkbook book;
+
+    /**
+     * reference to containing Sheet
+     */
+    private HSSFSheet sheet;
+
+    /**
+     * Creates new HSSFRow from scratch. Only HSSFSheet should do this.
+     *
+     * @param book low-level Workbook object containing the sheet that contains this row
+     * @param sheet low-level Sheet object that contains this Row
+     * @param rowNum the row number of this row (0 based)
+     * @see org.apache.poi.hssf.usermodel.HSSFSheet#createRow(int)
+     */
+    HSSFRow(HSSFWorkbook book, HSSFSheet sheet, int rowNum) {
+        this(book, sheet, new RowRecord(rowNum));
+    }
+
+    /**
+     * Creates an HSSFRow from a low level RowRecord object.  Only HSSFSheet should do
+     * this.  HSSFSheet uses this when an existing file is read in.
+     *
+     * @param book low-level Workbook object containing the sheet that contains this row
+     * @param sheet low-level Sheet object that contains this Row
+     * @param record the low level api object this row should represent
+     * @see org.apache.poi.hssf.usermodel.HSSFSheet#createRow(int)
+     */
+    HSSFRow(HSSFWorkbook book, HSSFSheet sheet, RowRecord record) {
+        this.book = book;
+        this.sheet = sheet;
+        row = record;
+        setRowNum(record.getRowNumber());
+        // Don't trust colIx boundaries as read by other apps
+        // set the RowRecord empty for the moment
+        record.setEmpty();
+        // subsequent calls to createCellFromRecord() will update the colIx boundaries properly
+    }
+
+    /**
+     * Use this to create new cells within the row and return it.
+     * <p>
+     * The cell that is returned is a CELL_TYPE_BLANK. The type can be changed
+     * either through calling <code>setCellValue</code> or <code>setCellType</code>.
+     *
+     * @param column - the column number this cell represents
+     *
+     * @return HSSFCell a high level representation of the created cell.
+     * @throws IllegalArgumentException if columnIndex < 0 or greater than 255,
+     *   the maximum number of columns supported by the Excel binary format (.xls)
+     */
+    public HSSFCell createCell(int column)
+    {
+        return this.createCell(column,HSSFCell.CELL_TYPE_BLANK);
+    }
+
+    /**
+     * Use this to create new cells within the row and return it.
+     * <p>
+     * The cell that is returned is a CELL_TYPE_BLANK. The type can be changed
+     * either through calling setCellValue or setCellType.
+     *
+     * @param columnIndex - the column number this cell represents
+     *
+     * @return HSSFCell a high level representation of the created cell.
+     * @throws IllegalArgumentException if columnIndex < 0 or greater than 255,
+     *   the maximum number of columns supported by the Excel binary format (.xls)
+     */
+    public HSSFCell createCell(int columnIndex, int type)
+    {
+        short shortCellNum = (short)columnIndex;
+        if(columnIndex > 0x7FFF) {
+            shortCellNum = (short)(0xffff - columnIndex);
+        }
+
+        HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), shortCellNum, type);
+        addCell(cell);
+        sheet.getSheet().addValueRecord(getRowNum(), cell.getCellValueRecord());
+        return cell;
+    }
+
+    /**
+     * create a high level HSSFCell object from an existing low level record.  Should
+     * only be called from HSSFSheet or HSSFRow itself.
+     * @param cell low level cell to create the high level representation from
+     * @return HSSFCell representing the low level record passed in
+     */
+    HSSFCell createCellFromRecord(CellValueRecordInterface cell) {
+        HSSFCell hcell = new HSSFCell(book, sheet, cell);
+
+        addCell(hcell);
+        int colIx = cell.getColumn();
+        if (row.isEmpty()) {
+            row.setFirstCol(colIx);
+            row.setLastCol(colIx + 1);
+        } else {
+            if (colIx < row.getFirstCol()) {
+                row.setFirstCol(colIx);
+            } else if (colIx > row.getLastCol()) {
+                row.setLastCol(colIx + 1);
+            } else {
+                // added cell is within first and last cells
+            }
+        }
+        // TODO - RowRecord column boundaries need to be updated for cell comments too
+        return hcell;
+    }
+
+    /**
+     * set the row number of this row.
+     * @param rowIndex  the row number (0-based)
+     * @throws IndexOutOfBoundsException if the row number is not within the range 0-65535.
+     */
+    public void setRowNum(int rowIndex) {
+        int maxrow = SpreadsheetVersion.EXCEL97.getLastRowIndex();
+        if ((rowIndex < 0) || (rowIndex > maxrow)) {
+          throw new IllegalArgumentException("Invalid row number (" + rowIndex
+                  + ") outside allowable range (0.." + maxrow + ")");
+        }
+        rowNum = rowIndex;
+        if (row != null) {
+            row.setRowNumber(rowIndex);   // used only for KEY comparison (HSSFRow)
+        }
+    }
+
+    /**
+     * get row number this row represents
+     * @return the row number (0 based)
+     */
+    public int getRowNum()
+    {
+        return rowNum;
+    }
+
+    /**
+     * Returns the HSSFSheet this row belongs to
+     *
+     * @return the HSSFSheet that owns this row
+     */
+    public HSSFSheet getSheet()
+    {
+        return sheet;
+    }
+
+
+    /**
+     * used internally to add a cell.
+     */
+    private void addCell(HSSFCell cell) {
+
+        int column=cell.getColumnIndex();
+        // re-allocate cells array as required.
+        if(column>=cells.length) {
+            HSSFCell[] oldCells=cells;
+            int newSize=oldCells.length*2;
+            if(newSize<column+1) {
+                newSize=column+1;
+            }
+            cells=new HSSFCell[newSize];
+            System.arraycopy(oldCells,0,cells,0,oldCells.length);
+        }
+        cells[column]=cell;
+
+        // fix up firstCol and lastCol indexes
+        if (row.isEmpty() || column < row.getFirstCol()) {
+            row.setFirstCol((short)column);
+        }
+
+        if (row.isEmpty() || column >= row.getLastCol()) {
+            row.setLastCol((short) (column+1)); // +1 -> for one past the last index
+        }
+    }
+
+    /**
+     * Get the hssfcell representing a given column (logical cell)
+     *  0-based. If you ask for a cell that is not defined, then
+     *  you get a null.
+     * This is the basic call, with no policies applied
+     *
+     * @param cellIndex  0 based column number
+     * @return HSSFCell representing that column or null if undefined.
+     */
+    private HSSFCell retrieveCell(int cellIndex) {
+        if(cellIndex<0||cellIndex>=cells.length) {
+            return null;
+        }
+        return cells[cellIndex];
+    }
+
+
+    /**
+     * Get the hssfcell representing a given column (logical cell)
+     *  0-based.  If you ask for a cell that is not defined then
+     *  you get a null, unless you have set a different
+     *  {@link org.apache.poi.ss.usermodel.Row.MissingCellPolicy} on the base workbook.
+     *
+     * @param cellnum  0 based column number
+     * @return HSSFCell representing that column or null if undefined.
+     */
+    public HSSFCell getCell(int cellnum) {
+        return getCell(cellnum, book.getMissingCellPolicy());
+    }
+
+    /**
+     * Get the hssfcell representing a given column (logical cell)
+     *  0-based.  If you ask for a cell that is not defined, then
+     *  your supplied policy says what to do
+     *
+     * @param cellnum  0 based column number
+     * @param policy Policy on blank / missing cells
+     * @return representing that column or null if undefined + policy allows.
+     */
+    public HSSFCell getCell(int cellnum, MissingCellPolicy policy) {
+        HSSFCell cell = retrieveCell(cellnum);
+        if(policy == RETURN_NULL_AND_BLANK) {
+            return cell;
+        }
+        if(policy == RETURN_BLANK_AS_NULL) {
+            if(cell == null) return cell;
+            if(cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) {
+                return null;
+            }
+            return cell;
+        }
+        if(policy == CREATE_NULL_AS_BLANK) {
+            if(cell == null) {
+                return createCell(cellnum, HSSFCell.CELL_TYPE_BLANK);
+            }
+            return cell;
+        }
+        throw new IllegalArgumentException("Illegal policy " + policy + " (" + policy.id + ")");
+    }
+
+    /**
+     * get the lowlevel RowRecord represented by this object - should only be called
+     * by other parts of the high level API
+     *
+     * @return RowRecord this row represents
+     */
+
+    protected RowRecord getRowRecord()
+    {
+        return row;
+    }
+
+    /**
+     * @return cell iterator of the physically defined cells.
+     * Note that the 4th element might well not be cell 4, as the iterator
+     *  will not return un-defined (null) cells.
+     * Call getCellNum() on the returned cells to know which cell they are.
+     * As this only ever works on physically defined cells,
+     *  the {@link org.apache.poi.ss.usermodel.Row.MissingCellPolicy} has no effect.
+     */
+    public Iterator<Cell> cellIterator()
+    {
+      return new CellIterator();
+    }
+    /**
+     * Alias for {@link #cellIterator} to allow
+     *  foreach loops
+     */
+    public Iterator<Cell> iterator() {
+       return cellIterator();
+    }
+
+    /**
+     * An iterator over the (physical) cells in the row.
+     */
+    private class CellIterator implements Iterator<Cell> {
+      int thisId=-1;
+      int nextId=-1;
+
+      public CellIterator()
+      {
+        findNext();
+      }
+
+      public boolean hasNext() {
+        return nextId<cells.length;
+      }
+
+      public Cell next() {
+          if (!hasNext())
+              throw new NoSuchElementException("At last element");
+        HSSFCell cell=cells[nextId];
+        thisId=nextId;
+        findNext();
+        return cell;
+      }
+
+      public void remove() {
+          if (thisId == -1)
+              throw new IllegalStateException("remove() called before next()");
+        cells[thisId]=null;
+      }
+
+      private void findNext()
+      {
+        int i=nextId+1;
+        for(;i<cells.length;i++)
+        {
+          if(cells[i]!=null) break;
+        }
+        nextId=i;
+      }
+
+    }
+
+
+    public boolean equals(Object obj)
+    {
+        if (!(obj instanceof HSSFRow))
+        {
+            return false;
+        }
+        HSSFRow loc = (HSSFRow) obj;
+
+        if (this.getRowNum() == loc.getRowNum())
+        {
+            return true;
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFSheet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFSheet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFSheet.java	(revision 28000)
@@ -0,0 +1,304 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.usermodel;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeMap;
+
+import org.apache.poi.hssf.model.InternalSheet;
+import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RowRecord;
+import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellRange;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.ss.util.SSCellRange;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * High level representation of a worksheet.
+ * @author  Andrew C. Oliver (acoliver at apache dot org)
+ * @author  Glen Stampoultzis (glens at apache.org)
+ * @author  Libin Roman (romal at vistaportal.com)
+ * @author  Shawn Laubach (slaubach at apache dot org) (Just a little)
+ * @author  Jean-Pierre Paris (jean-pierre.paris at m4x dot org) (Just a little, too)
+ * @author  Yegor Kozlov (yegor at apache.org) (Autosizing columns)
+ * @author  Josh Micich
+ * @author  Petr Udalau(Petr.Udalau at exigenservices.com) - set/remove array formulas
+ */
+public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
+    private static final POILogger log = POILogFactory.getLogger(HSSFSheet.class);
+    private static final int DEBUG = POILogger.DEBUG;
+
+    /**
+     * reference to the low level {@link InternalSheet} object
+     */
+    private final InternalSheet _sheet;
+    /** stores rows by zero-based row number */
+    private final TreeMap<Integer, HSSFRow> _rows;
+    protected final HSSFWorkbook _workbook;
+    private int _firstrow;
+    private int _lastrow;
+
+
+    /**
+     * Creates an HSSFSheet representing the given Sheet object.  Should only be
+     * called by HSSFWorkbook when reading in an exisiting file.
+     *
+     * @param workbook - The HSSF Workbook object associated with the sheet.
+     * @param sheet - lowlevel Sheet object this sheet will represent
+     * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createSheet()
+     */
+    protected HSSFSheet(HSSFWorkbook workbook, InternalSheet sheet) {
+        this._sheet = sheet;
+        _rows = new TreeMap<Integer, HSSFRow>();
+        this._workbook = workbook;
+        setPropertiesFromSheet(sheet);
+    }
+
+    /**
+     * used internally to set the properties given a Sheet object
+     */
+    private void setPropertiesFromSheet(InternalSheet sheet) {
+
+        RowRecord row = sheet.getNextRow();
+        boolean rowRecordsAlreadyPresent = row!=null;
+
+        while (row != null) {
+            createRowFromRecord(row);
+
+            row = sheet.getNextRow();
+        }
+
+        CellValueRecordInterface[] cvals = sheet.getValueRecords();
+        long timestart = System.currentTimeMillis();
+
+        if (log.check( POILogger.DEBUG ))
+            log.log(DEBUG, "Time at start of cell creating in HSSF sheet = ",
+                Long.valueOf(timestart));
+        HSSFRow lastrow = null;
+
+        // Add every cell to its row
+        for (int i = 0; i < cvals.length; i++) {
+            CellValueRecordInterface cval = cvals[i];
+
+            long cellstart = System.currentTimeMillis();
+            HSSFRow hrow = lastrow;
+
+            if (hrow == null || hrow.getRowNum() != cval.getRow()) {
+                hrow = getRow( cval.getRow() );
+                lastrow = hrow;
+                if (hrow == null) {
+                    // Some tools (like Perl module Spreadsheet::WriteExcel - bug 41187) skip the RowRecords
+                    // Excel, OpenOffice.org and GoogleDocs are all OK with this, so POI should be too.
+                    if (rowRecordsAlreadyPresent) {
+                        // if at least one row record is present, all should be present.
+                        throw new RuntimeException("Unexpected missing row when some rows already present");
+                    }
+                    // create the row record on the fly now.
+                    RowRecord rowRec = new RowRecord(cval.getRow());
+                    sheet.addRow(rowRec);
+                    hrow = createRowFromRecord(rowRec);
+                }
+            }
+            if (log.check( POILogger.DEBUG ))
+                log.log( DEBUG, "record id = " + Integer.toHexString( ( (Record) cval ).getSid() ) );
+            hrow.createCellFromRecord( cval );
+            if (log.check( POILogger.DEBUG ))
+                log.log( DEBUG, "record took ",
+                    Long.valueOf( System.currentTimeMillis() - cellstart ) );
+
+        }
+        if (log.check( POILogger.DEBUG ))
+            log.log(DEBUG, "total sheet cell creation took ",
+                Long.valueOf(System.currentTimeMillis() - timestart));
+    }
+
+    /**
+     * Create a new row within the sheet and return the high level representation
+     *
+     * @param rownum  row number
+     * @return High level HSSFRow object representing a row in the sheet
+     * @see org.apache.poi.hssf.usermodel.HSSFRow
+     * @see #removeRow(org.apache.poi.ss.usermodel.Row)
+     */
+    public HSSFRow createRow(int rownum)
+    {
+        HSSFRow row = new HSSFRow(_workbook, this, rownum);
+
+        addRow(row, true);
+        return row;
+    }
+
+    /**
+     * Used internally to create a high level Row object from a low level row object.
+     * USed when reading an existing file
+     * @param row  low level record to represent as a high level Row and add to sheet
+     * @return HSSFRow high level representation
+     */
+
+    private HSSFRow createRowFromRecord(RowRecord row)
+    {
+        HSSFRow hrow = new HSSFRow(_workbook, this, row);
+
+        addRow(hrow, false);
+        return hrow;
+    }
+
+
+    /**
+     * add a row to the sheet
+     *
+     * @param addLow whether to add the row to the low level model - false if its already there
+     */
+
+    private void addRow(HSSFRow row, boolean addLow)
+    {
+        _rows.put(Integer.valueOf(row.getRowNum()), row);
+        if (addLow)
+        {
+            _sheet.addRow(row.getRowRecord());
+        }
+        boolean firstRow = _rows.size() == 1;
+        if (row.getRowNum() > getLastRowNum() || firstRow)
+        {
+            _lastrow = row.getRowNum();
+        }
+        if (row.getRowNum() < getFirstRowNum() || firstRow)
+        {
+            _firstrow = row.getRowNum();
+        }
+    }
+
+    /**
+     * Returns the logical row (not physical) 0-based.  If you ask for a row that is not
+     * defined you get a null.  This is to say row 4 represents the fifth row on a sheet.
+     * @param rowIndex  row to get
+     * @return HSSFRow representing the row number or null if its not defined on the sheet
+     */
+    public HSSFRow getRow(int rowIndex) {
+        return _rows.get(Integer.valueOf(rowIndex));
+    }
+
+    /**
+     * Gets the first row on the sheet
+     * @return the number of the first logical row on the sheet, zero based
+     */
+    public int getFirstRowNum() {
+        return _firstrow;
+    }
+
+    /**
+     * Gets the number last row on the sheet.
+     * Owing to idiosyncrasies in the excel file
+     *  format, if the result of calling this method
+     *  is zero, you can't tell if that means there
+     *  are zero rows on the sheet, or one at
+     *  position zero. For that case, additionally
+     *  call {@link #getPhysicalNumberOfRows()} to
+     *  tell if there is a row at position zero
+     *  or not.
+     * @return the number of the last row contained in this sheet, zero based.
+     */
+    public int getLastRowNum() {
+        return _lastrow;
+    }
+
+    /**
+     * @return an iterator of the PHYSICAL rows.  Meaning the 3rd element may not
+     * be the third row if say for instance the second row is undefined.
+     * Call getRowNum() on each row if you care which one it is.
+     */
+    public Iterator<Row> rowIterator() {
+        @SuppressWarnings("unchecked") // can this clumsy generic syntax be improved?
+        Iterator<Row> result = (Iterator<Row>)(Iterator<? extends Row>)_rows.values().iterator();
+        return result;
+    }
+    /**
+     * Alias for {@link #rowIterator()} to allow
+     *  foreach loops
+     */
+    public Iterator<Row> iterator() {
+        return rowIterator();
+    }
+
+
+    /**
+     * used internally in the API to get the low level Sheet record represented by this
+     * Object.
+     * @return Sheet - low level representation of this HSSFSheet.
+     */
+    InternalSheet getSheet() {
+        return _sheet;
+    }
+
+    /**
+     * Also creates cells if they don't exist
+     */
+    private CellRange<HSSFCell> getCellRange(CellRangeAddress range) {
+        int firstRow = range.getFirstRow();
+        int firstColumn = range.getFirstColumn();
+        int lastRow = range.getLastRow();
+        int lastColumn = range.getLastColumn();
+        int height = lastRow - firstRow + 1;
+        int width = lastColumn - firstColumn + 1;
+        List<HSSFCell> temp = new ArrayList<HSSFCell>(height*width);
+        for (int rowIn = firstRow; rowIn <= lastRow; rowIn++) {
+            for (int colIn = firstColumn; colIn <= lastColumn; colIn++) {
+                HSSFRow row = getRow(rowIn);
+                if (row == null) {
+                    row = createRow(rowIn);
+                }
+                HSSFCell cell = row.getCell(colIn);
+                if (cell == null) {
+                    cell = row.createCell(colIn);
+                }
+                temp.add(cell);
+            }
+        }
+        return SSCellRange.create(firstRow, firstColumn, height, width, temp, HSSFCell.class);
+    }
+
+    public CellRange<HSSFCell> removeArrayFormula(Cell cell) {
+        if (cell.getSheet() != this) {
+            throw new IllegalArgumentException("Specified cell does not belong to this sheet.");
+        }
+        CellValueRecordInterface rec = ((HSSFCell) cell).getCellValueRecord();
+        if (!(rec instanceof FormulaRecordAggregate)) {
+            String ref = new CellReference(cell).formatAsString();
+            throw new IllegalArgumentException("Cell " + ref + " is not part of an array formula.");
+        }
+        FormulaRecordAggregate fra = (FormulaRecordAggregate) rec;
+        CellRangeAddress range = fra.removeArrayFormula(cell.getRowIndex(), cell.getColumnIndex());
+
+        CellRange<HSSFCell> result = getCellRange(range);
+        // clear all cells in the range
+        for (Cell c : result) {
+            c.setCellType(Cell.CELL_TYPE_BLANK);
+        }
+        return result;
+    }
+    
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFWorkbook.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/HSSFWorkbook.java	(revision 28000)
@@ -0,0 +1,342 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.usermodel;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.POIDocument;
+import org.apache.poi.hssf.OldExcelFormatException;
+import org.apache.poi.hssf.model.InternalSheet;
+import org.apache.poi.hssf.model.InternalWorkbook;
+import org.apache.poi.hssf.model.RecordStream;
+import org.apache.poi.hssf.record.LabelRecord;
+import org.apache.poi.hssf.record.LabelSSTRecord;
+import org.apache.poi.hssf.record.NameRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordFactory;
+import org.apache.poi.hssf.record.common.UnicodeString;
+import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+
+/**
+ * High level representation of a workbook.  This is the first object most users
+ * will construct whether they are reading or writing a workbook.  It is also the
+ * top level object for creating new sheets/etc.
+ *
+ * @see org.apache.poi.hssf.model.InternalWorkbook
+ * @see org.apache.poi.hssf.usermodel.HSSFSheet
+ * @author  Andrew C. Oliver (acoliver at apache dot org)
+ * @author  Glen Stampoultzis (glens at apache.org)
+ * @author  Shawn Laubach (slaubach at apache dot org)
+ */
+public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.usermodel.Workbook {
+
+    /**
+     * used for compile-time performance/memory optimization.  This determines the
+     * initial capacity for the sheet collection.  Its currently set to 3.
+     * Changing it in this release will decrease performance
+     * since you're never allowed to have more or less than three sheets!
+     */
+
+    public final static int INITIAL_CAPACITY = 3;
+
+    /**
+     * this is the reference to the low level Workbook object
+     */
+
+    private InternalWorkbook workbook;
+
+    /**
+     * this holds the HSSFSheet objects attached to this workbook
+     */
+
+    protected List<HSSFSheet> _sheets;
+
+    /**
+     * this holds the HSSFName objects attached to this workbook
+     */
+
+    private ArrayList<HSSFName> names;
+
+    /**
+     * The policy to apply in the event of missing or
+     *  blank cells when fetching from a row.
+     * See {@link MissingCellPolicy}
+     */
+    private MissingCellPolicy missingCellPolicy = HSSFRow.RETURN_NULL_AND_BLANK;
+
+    private static POILogger log = POILogFactory.getLogger(HSSFWorkbook.class);
+
+	private HSSFWorkbook(InternalWorkbook book) {
+		super(null);
+		workbook = book;
+		_sheets = new ArrayList<HSSFSheet>(INITIAL_CAPACITY);
+		names = new ArrayList<HSSFName>(INITIAL_CAPACITY);
+	}
+
+    public HSSFWorkbook(POIFSFileSystem fs) throws IOException {
+        this(fs,true);
+    }
+
+    /**
+     * given a POI POIFSFileSystem object, read in its Workbook and populate the high and
+     * low level models.  If you're reading in a workbook...start here.
+     *
+     * @param fs the POI filesystem that contains the Workbook stream.
+     * @param preserveNodes whether to preseve other nodes, such as
+     *        macros.  This takes more memory, so only say yes if you
+     *        need to. If set, will store all of the POIFSFileSystem
+     *        in memory
+     * @see org.apache.poi.poifs.filesystem.POIFSFileSystem
+     * @exception IOException if the stream cannot be read
+     */
+    public HSSFWorkbook(POIFSFileSystem fs, boolean preserveNodes)
+            throws IOException
+    {
+        this(fs.getRoot(), fs, preserveNodes);
+    }
+
+    /**
+     * Normally, the Workbook will be in a POIFS Stream
+     * called "Workbook". However, some weird XLS generators use "WORKBOOK"
+     */
+    private static final String[] WORKBOOK_DIR_ENTRY_NAMES = {
+        "Workbook", // as per BIFF8 spec
+        "WORKBOOK",
+    };
+
+
+    private static String getWorkbookDirEntryName(DirectoryNode directory) {
+
+        String[] potentialNames = WORKBOOK_DIR_ENTRY_NAMES;
+        for (int i = 0; i < potentialNames.length; i++) {
+            String wbName = potentialNames[i];
+            try {
+                directory.getEntry(wbName);
+                return wbName;
+            } catch (FileNotFoundException e) {
+                // continue - to try other options
+            }
+        }
+
+        // check for previous version of file format
+        try {
+            directory.getEntry("Book");
+            throw new OldExcelFormatException("The supplied spreadsheet seems to be Excel 5.0/7.0 (BIFF5) format. "
+                    + "POI only supports BIFF8 format (from Excel versions 97/2000/XP/2003)");
+        } catch (FileNotFoundException e) {
+            // fall through
+        }
+
+        throw new IllegalArgumentException("The supplied POIFSFileSystem does not contain a BIFF8 'Workbook' entry. "
+            + "Is it really an excel file?");
+    }
+
+    /**
+     * given a POI POIFSFileSystem object, and a specific directory
+     *  within it, read in its Workbook and populate the high and
+     *  low level models.  If you're reading in a workbook...start here.
+     *
+     * @param directory the POI filesystem directory to process from
+     * @param fs the POI filesystem that contains the Workbook stream.
+     * @param preserveNodes whether to preseve other nodes, such as
+     *        macros.  This takes more memory, so only say yes if you
+     *        need to. If set, will store all of the POIFSFileSystem
+     *        in memory
+     * @see org.apache.poi.poifs.filesystem.POIFSFileSystem
+     * @exception IOException if the stream cannot be read
+     */
+    public HSSFWorkbook(DirectoryNode directory, POIFSFileSystem fs, boolean preserveNodes)
+            throws IOException
+    {
+        super(directory);
+        String workbookName = getWorkbookDirEntryName(directory);
+
+        // If we're not preserving nodes, don't track the
+        //  POIFS any more
+        if(! preserveNodes) {
+           this.directory = null;
+        }
+
+        _sheets = new ArrayList<HSSFSheet>(INITIAL_CAPACITY);
+        names  = new ArrayList<HSSFName>(INITIAL_CAPACITY);
+
+        // Grab the data from the workbook stream, however
+        //  it happens to be spelled.
+        InputStream stream = directory.createDocumentInputStream(workbookName);
+
+        List<Record> records = RecordFactory.createRecords(stream);
+
+        workbook = InternalWorkbook.createWorkbook(records);
+        setPropertiesFromWorkbook(workbook);
+        int recOffset = workbook.getNumRecords();
+
+        // convert all LabelRecord records to LabelSSTRecord
+        convertLabelRecords(records, recOffset);
+        RecordStream rs = new RecordStream(records, recOffset);
+        while (rs.hasNext()) {
+            InternalSheet sheet = InternalSheet.createSheet(rs);
+            _sheets.add(new HSSFSheet(this, sheet));
+        }
+
+        for (int i = 0 ; i < workbook.getNumNames() ; ++i){
+            NameRecord nameRecord = workbook.getNameRecord(i);
+            HSSFName name = new HSSFName(this, nameRecord);
+            names.add(name);
+        }
+    }
+
+
+    /**
+     * used internally to set the workbook properties.
+     */
+
+    private void setPropertiesFromWorkbook(InternalWorkbook book)
+    {
+        this.workbook = book;
+
+        // none currently
+    }
+
+    /**
+      * This is basically a kludge to deal with the now obsolete Label records.  If
+      * you have to read in a sheet that contains Label records, be aware that the rest
+      * of the API doesn't deal with them, the low level structure only provides read-only
+      * semi-immutable structures (the sets are there for interface conformance with NO
+      * impelmentation).  In short, you need to call this function passing it a reference
+      * to the Workbook object.  All labels will be converted to LabelSST records and their
+      * contained strings will be written to the Shared String tabel (SSTRecord) within
+      * the Workbook.
+      *
+      * @param records a collection of sheet's records.
+      * @param offset the offset to search at 
+      * @see org.apache.poi.hssf.record.LabelRecord
+      * @see org.apache.poi.hssf.record.LabelSSTRecord
+      * @see org.apache.poi.hssf.record.SSTRecord
+      */
+
+     private void convertLabelRecords(List<Record> records, int offset)
+     {
+         if (log.check( POILogger.DEBUG ))
+             log.log(POILogger.DEBUG, "convertLabelRecords called");
+         for (int k = offset; k < records.size(); k++)
+         {
+             Record rec = records.get(k);
+
+             if (rec.getSid() == LabelRecord.sid)
+             {
+                 LabelRecord oldrec = ( LabelRecord ) rec;
+
+                 records.remove(k);
+                 LabelSSTRecord newrec   = new LabelSSTRecord();
+                 int            stringid =
+                     workbook.addSSTString(new UnicodeString(oldrec.getValue()));
+
+                 newrec.setRow(oldrec.getRow());
+                 newrec.setColumn(oldrec.getColumn());
+                 newrec.setXFIndex(oldrec.getXFIndex());
+                 newrec.setSSTIndex(stringid);
+                       records.add(k, newrec);
+             }
+         }
+         if (log.check( POILogger.DEBUG ))
+             log.log(POILogger.DEBUG, "convertLabelRecords exit");
+     }
+
+    /**
+     * Retrieves the current policy on what to do when
+     *  getting missing or blank cells from a row.
+     * The default is to return blank and null cells.
+     *  {@link MissingCellPolicy}
+     */
+    public MissingCellPolicy getMissingCellPolicy() {
+        return missingCellPolicy;
+    }
+
+    private void validateSheetIndex(int index) {
+        int lastSheetIx = _sheets.size() - 1;
+        if (index < 0 || index > lastSheetIx) {
+            throw new IllegalArgumentException("Sheet index ("
+                    + index +") is out of range (0.." +    lastSheetIx + ")");
+        }
+    }
+
+
+
+    /**
+     * get the number of spreadsheets in the workbook (this will be three after serialization)
+     * @return number of sheets
+     */
+
+    public int getNumberOfSheets() // NO_UCD
+    {
+        return _sheets.size();
+    }
+
+    /**
+     * Get the HSSFSheet object at the given index.
+     * @param index of the sheet number (0-based physical & logical)
+     * @return HSSFSheet at the provided index
+     */
+
+    public HSSFSheet getSheetAt(int index)
+    {
+        validateSheetIndex(index);
+        return _sheets.get(index);
+    }
+
+    /**
+     * Get sheet with the given name (case insensitive match)
+     * @param name of the sheet
+     * @return HSSFSheet with the name provided or <code>null</code> if it does not exist
+     */
+
+    public HSSFSheet getSheet(String name) // NO_UCD
+    {
+        HSSFSheet retval = null;
+
+        for (int k = 0; k < _sheets.size(); k++)
+        {
+            String sheetname = workbook.getSheetName(k);
+
+            if (sheetname.equalsIgnoreCase(name))
+            {
+                retval = _sheets.get(k);
+            }
+        }
+        return retval;
+    }
+
+    /**
+     * get the number of styles the workbook contains
+     * @return count of cell styles
+     */
+
+
+    InternalWorkbook getWorkbook() {
+        return workbook;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/usermodel/package.html	(revision 28000)
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+usermodel package maps HSSF low level strutures to familiar workbook/sheet model
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/util/CellRangeAddress8Bit.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/util/CellRangeAddress8Bit.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/util/CellRangeAddress8Bit.java	(revision 28000)
@@ -0,0 +1,63 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.util;
+
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressBase;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>
+ *
+ * Like {@link CellRangeAddress} except column fields are 8-bit.
+ *
+ * @author Josh Micich
+ */
+public final class CellRangeAddress8Bit extends CellRangeAddressBase {
+
+	public static final int ENCODED_SIZE = 6;
+
+	public CellRangeAddress8Bit(int firstRow, int lastRow, int firstCol, int lastCol) {
+		super(firstRow, lastRow, firstCol, lastCol);
+	}
+
+	public CellRangeAddress8Bit(LittleEndianInput in) {
+		super(readUShortAndCheck(in), in.readUShort(), in.readUByte(), in.readUByte());
+	}
+	
+	private static int readUShortAndCheck(LittleEndianInput in) {
+		if (in.available() < ENCODED_SIZE) {
+			// Ran out of data
+			throw new RuntimeException("Ran out of data reading CellRangeAddress");
+		}
+		return in.readUShort();
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		out.writeShort(getFirstRow());
+		out.writeShort(getLastRow());
+		out.writeByte(getFirstColumn());
+		out.writeByte(getLastColumn());
+	}
+
+
+	public static int getEncodedSize(int numberOfItems) {
+		return numberOfItems * ENCODED_SIZE;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/util/CellReference.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/util/CellReference.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/util/CellReference.java	(revision 28000)
@@ -0,0 +1,36 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.util;
+
+/**
+ * Common conversion functions between Excel style A1, C27 style
+ *  cell references, and POI usermodel style row=0, column=0
+ *  style references.
+ * @author  Avik Sengupta
+ * @author  Dennis Doubleday (patch to seperateRowColumns())
+ */
+public final class CellReference extends org.apache.poi.ss.util.CellReference {
+   
+    public CellReference(int pRow, int pCol) {
+    	super(pRow, pCol, true, true);
+    }
+    
+    public CellReference(int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) {
+        super(null, pRow, pCol, pAbsRow, pAbsCol);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/util/RKUtil.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/util/RKUtil.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/util/RKUtil.java	(revision 28000)
@@ -0,0 +1,72 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.hssf.util;
+
+/**
+ * Utility class for helping convert RK numbers.
+ *
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @author Rolf-J\u00f6rgen Moll
+ *
+ * @see org.apache.poi.hssf.record.MulRKRecord
+ * @see org.apache.poi.hssf.record.RKRecord
+ */
+public final class RKUtil {
+    private RKUtil() {
+        // no instances of this class
+    }
+
+    /**
+     * Do the dirty work of decoding; made a private static method to
+     * facilitate testing the algorithm
+     */
+    public static double decodeNumber(int number) {
+        long raw_number = number;
+
+        // mask off the two low-order bits, 'cause they're not part of
+        // the number
+        raw_number = raw_number >> 2;
+        double rvalue = 0;
+
+        if ((number & 0x02) == 0x02)
+        {
+            // ok, it's just a plain ol' int; we can handle this
+            // trivially by casting
+            rvalue = raw_number;
+        }
+        else
+        {
+
+            // also trivial, but not as obvious ... left shift the
+            // bits high and use that clever static method in Double
+            // to convert the resulting bit image to a double
+            rvalue = Double.longBitsToDouble(raw_number << 34);
+        }
+        if ((number & 0x01) == 0x01)
+        {
+
+            // low-order bit says divide by 100, and so we do. Why?
+            // 'cause that's what the algorithm says. Can't fight city
+            // hall, especially if it's the city of Redmond
+            rvalue /= 100;
+        }
+
+        return rvalue;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/util/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/util/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/hssf/util/package.html	(revision 28000)
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+util package contains tools needed for writing HSSF files that are not necesarily "real" 
+HSSF concepts.
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/common/POIFSBigBlockSize.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/common/POIFSBigBlockSize.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/common/POIFSBigBlockSize.java	(revision 28000)
@@ -0,0 +1,60 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.common;
+
+import org.apache.poi.util.LittleEndianConsts;
+
+/**
+ * <p>A class describing attributes of the Big Block Size</p>
+ */
+public final class POIFSBigBlockSize
+{
+   private int bigBlockSize;
+   private short headerValue;
+   
+   protected POIFSBigBlockSize(int bigBlockSize, short headerValue) {
+      this.bigBlockSize = bigBlockSize;
+      this.headerValue = headerValue;
+   }
+   
+   public int getBigBlockSize() {
+      return bigBlockSize;
+   }
+   
+   /**
+    * Returns the value that gets written into the 
+    *  header.
+    * Is the power of two that corresponds to the
+    *  size of the block, eg 512 => 9
+    */
+   public short getHeaderValue() {
+      return headerValue;
+   }
+      
+   public int getBATEntriesPerBlock() {
+      return bigBlockSize / LittleEndianConsts.INT_SIZE;
+   }
+   public int getXBATEntriesPerBlock() {
+      return getBATEntriesPerBlock() - 1;
+   }
+   public int getNextXBATChainOffset() {
+      return getXBATEntriesPerBlock() * LittleEndianConsts.INT_SIZE;
+   }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/common/POIFSConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/common/POIFSConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/common/POIFSConstants.java	(revision 28000)
@@ -0,0 +1,46 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.common;
+
+/**
+ * <p>A repository for constants shared by POI classes.</p>
+ */
+public interface POIFSConstants
+{
+    /** Most files use 512 bytes as their big block size */
+    public static final int SMALLER_BIG_BLOCK_SIZE = 0x0200;
+    public static final POIFSBigBlockSize SMALLER_BIG_BLOCK_SIZE_DETAILS = 
+       new POIFSBigBlockSize(SMALLER_BIG_BLOCK_SIZE, (short)9);
+    /** Some use 4096 bytes */
+    public static final int LARGER_BIG_BLOCK_SIZE = 0x1000;
+    public static final POIFSBigBlockSize LARGER_BIG_BLOCK_SIZE_DETAILS = 
+       new POIFSBigBlockSize(LARGER_BIG_BLOCK_SIZE, (short)12);
+    
+    public static final int PROPERTY_SIZE  = 0x0080;
+    
+    /** Indicates the sector is the end of a chain (0xFFFFFFFE) */
+    public static final int END_OF_CHAIN   = -2;
+    /** Indicates the sector is not used (0xFFFFFFFF) */
+    public static final int UNUSED_BLOCK   = -1;
+    
+    /** The first 4 bytes of an OOXML file, used in detection */
+    public static final byte[] OOXML_FILE_HEADER = 
+    	new byte[] { 0x50, 0x4b, 0x03, 0x04 };
+}   // end public interface POIFSConstants;
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/common/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/common/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/common/package.html	(revision 28000)
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+common package contains constants and other classes shared across all POIFS subpackages
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DirectoryEntry.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DirectoryEntry.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DirectoryEntry.java	(revision 28000)
@@ -0,0 +1,113 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.filesystem;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+
+import org.apache.poi.hpsf.ClassID;
+
+/**
+ * This interface defines methods specific to Directory objects
+ * managed by a Filesystem instance.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+public interface DirectoryEntry
+    extends Entry, Iterable<Entry>
+{
+
+    /**
+     * get an iterator of the Entry instances contained directly in
+     * this instance (in other words, children only; no grandchildren
+     * etc.)
+     *
+     * @return iterator; never null, but hasNext() may return false
+     *         immediately (i.e., this DirectoryEntry is empty). All
+     *         objects retrieved by next() are guaranteed to be
+     *         implementations of Entry.
+     */
+
+    public Iterator<Entry> getEntries();
+
+    /**
+     * is this DirectoryEntry empty?
+     *
+     * @return true if this instance contains no Entry instances
+     */
+
+    public boolean isEmpty();
+
+    /**
+     * get a specified Entry by name
+     *
+     * @param name the name of the Entry to obtain.
+     *
+     * @return the specified Entry, if it is directly contained in
+     *         this DirectoryEntry
+     *
+     * @exception FileNotFoundException if no Entry with the specified
+     *            name exists in this DirectoryEntry
+     */
+
+    public Entry getEntry(final String name)
+        throws FileNotFoundException;
+
+    /**
+     * create a new DocumentEntry
+     *
+     * @param name the name of the new DocumentEntry
+     * @param stream the InputStream from which to create the new
+     *               DocumentEntry
+     *
+     * @return the new DocumentEntry
+     *
+     * @exception IOException
+     */
+
+    public DocumentEntry createDocument(final String name,
+                                        final InputStream stream)
+        throws IOException;
+
+    /**
+     * create a new DirectoryEntry
+     *
+     * @param name the name of the new DirectoryEntry
+     *
+     * @return the new DirectoryEntry
+     *
+     * @exception IOException
+     */
+
+    public DirectoryEntry createDirectory(final String name)
+        throws IOException;
+
+    /**
+     * Sets the storage clsid for the directory entry
+     *
+     * @param clsidStorage storage Class ID
+     */
+    public void setStorageClsid(ClassID clsidStorage);
+
+}   // end public interface DirectoryEntry
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DirectoryNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DirectoryNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DirectoryNode.java	(revision 28000)
@@ -0,0 +1,335 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.filesystem;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.poi.hpsf.ClassID;
+import org.apache.poi.poifs.property.DirectoryProperty;
+import org.apache.poi.poifs.property.DocumentProperty;
+import org.apache.poi.poifs.property.Property;
+
+/**
+ * Simple implementation of DirectoryEntry
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+public class DirectoryNode
+    extends EntryNode
+    implements DirectoryEntry
+{
+
+    // Map of Entry instances, keyed by their names
+    private Map<String,Entry> _byname;
+    // Our list of entries, kept sorted to preserve order
+    private ArrayList<Entry> _entries;
+
+    // the POIFSFileSystem we belong to
+    private POIFSFileSystem   _filesystem;
+
+    // the path described by this document
+    private POIFSDocumentPath _path;
+
+    /**
+     * create a DirectoryNode. This method is not public by design; it
+     * is intended strictly for the internal use of this package
+     *
+     * @param property the DirectoryProperty for this DirectoryEntry
+     * @param filesystem the POIFSFileSystem we belong to
+     * @param parent the parent of this entry
+     */
+
+    DirectoryNode(final DirectoryProperty property,
+                  final POIFSFileSystem filesystem,
+                  final DirectoryNode parent)
+    {
+        super(property, parent);
+        if (parent == null)
+        {
+            _path = new POIFSDocumentPath();
+        }
+        else
+        {
+            _path = new POIFSDocumentPath(parent._path, new String[]
+            {
+                property.getName()
+            });
+        }
+        _filesystem = filesystem;
+        _byname     = new HashMap<String, Entry>();
+        _entries    = new ArrayList<Entry>();
+        Iterator<Property> iter = property.getChildren();
+
+        while (iter.hasNext())
+        {
+            Property child     = iter.next();
+            Entry    childNode = null;
+
+            if (child.isDirectory())
+            {
+                childNode = new DirectoryNode(( DirectoryProperty ) child,
+                                              _filesystem, this);
+            }
+            else
+            {
+                childNode = new DocumentNode(( DocumentProperty ) child,
+                                             this);
+            }
+            _entries.add(childNode);
+            _byname.put(childNode.getName(), childNode);
+        }
+    }
+
+    /**
+     * open a document in the directory's entry's list of entries
+     *
+     * @param documentName the name of the document to be opened
+     *
+     * @return a newly opened DocumentInputStream
+     *
+     * @exception IOException if the document does not exist or the
+     *            name is that of a DirectoryEntry
+     */
+
+    public DocumentInputStream createDocumentInputStream(
+            final String documentName)
+        throws IOException
+    {
+        Entry document = getEntry(documentName);
+
+        if (!document.isDocumentEntry())
+        {
+            throw new IOException("Entry '" + documentName
+                                  + "' is not a DocumentEntry");
+        }
+        return new DocumentInputStream(( DocumentEntry ) document);
+    }
+
+    /**
+     * create a new DocumentEntry
+     *
+     * @param document the new document
+     *
+     * @return the new DocumentEntry
+     *
+     * @exception IOException
+     */
+
+    DocumentEntry createDocument(final POIFSDocument document)
+        throws IOException
+    {
+        DocumentProperty property = document.getDocumentProperty();
+        DocumentNode     rval     = new DocumentNode(property, this);
+
+        (( DirectoryProperty ) getProperty()).addChild(property);
+        _filesystem.addDocument(document);
+        _entries.add(rval);
+        _byname.put(property.getName(), rval);
+        return rval;
+    }
+
+
+    /**
+     * Delete an entry
+     *
+     * @param entry the EntryNode to be deleted
+     *
+     * @return true if the entry was deleted, else false
+     */
+
+    boolean deleteEntry(final EntryNode entry)
+    {
+        boolean rval =
+            (( DirectoryProperty ) getProperty())
+                .deleteChild(entry.getProperty());
+
+        if (rval)
+        {
+            _entries.remove(entry);
+        	_byname.remove(entry.getName());
+            _filesystem.remove(entry);
+        }
+        return rval;
+    }
+
+    /* ********** START implementation of DirectoryEntry ********** */
+
+    /**
+     * get an iterator of the Entry instances contained directly in
+     * this instance (in other words, children only; no grandchildren
+     * etc.)
+     *
+     * @return iterator; never null, but hasNext() may return false
+     *         immediately (i.e., this DirectoryEntry is empty). All
+     *         objects retrieved by next() are guaranteed to be
+     *         implementations of Entry.
+     */
+
+    public Iterator<Entry> getEntries()
+    {
+        return _entries.iterator();
+    }
+
+    /**
+     * is this DirectoryEntry empty?
+     *
+     * @return true if this instance contains no Entry instances
+     */
+
+    public boolean isEmpty()
+    {
+        return _entries.isEmpty();
+    }
+
+    /**
+     * get a specified Entry by name
+     *
+     * @param name the name of the Entry to obtain.
+     *
+     * @return the specified Entry, if it is directly contained in
+     *         this DirectoryEntry
+     *
+     * @exception FileNotFoundException if no Entry with the specified
+     *            name exists in this DirectoryEntry
+     */
+
+    public Entry getEntry(final String name)
+        throws FileNotFoundException
+    {
+        Entry rval = null;
+
+        if (name != null)
+        {
+            rval = _byname.get(name);
+        }
+        if (rval == null)
+        {
+
+            // either a null name was given, or there is no such name
+            throw new FileNotFoundException("no such entry: \"" + name
+                                            + "\"");
+        }
+        return rval;
+    }
+
+    /**
+     * create a new DocumentEntry
+     *
+     * @param name the name of the new DocumentEntry
+     * @param stream the InputStream from which to create the new
+     *               DocumentEntry
+     *
+     * @return the new DocumentEntry
+     *
+     * @exception IOException
+     */
+
+    public DocumentEntry createDocument(final String name,
+                                        final InputStream stream)
+        throws IOException
+    {
+        return createDocument(new POIFSDocument(name, stream));
+    }
+
+
+    /**
+     * create a new DirectoryEntry
+     *
+     * @param name the name of the new DirectoryEntry
+     *
+     * @return the new DirectoryEntry
+     *
+     * @exception IOException
+     */
+
+    public DirectoryEntry createDirectory(final String name)
+        throws IOException
+    {
+        DirectoryProperty property = new DirectoryProperty(name);
+        DirectoryNode     rval     = new DirectoryNode(property, _filesystem,
+                                         this);
+
+        (( DirectoryProperty ) getProperty()).addChild(property);
+        _filesystem.addDirectory(property);
+        _entries.add(rval);
+        _byname.put(name, rval);
+        return rval;
+    }
+
+    /**
+     * Sets the storage clsid for the directory entry
+     *
+     * @param clsidStorage storage Class ID
+     */
+    public void setStorageClsid(ClassID clsidStorage)
+    {
+        getProperty().setStorageClsid(clsidStorage);
+    }
+
+    /* **********  END  implementation of DirectoryEntry ********** */
+    /* ********** START implementation of Entry ********** */
+
+    /**
+     * is this a DirectoryEntry?
+     *
+     * @return true if the Entry is a DirectoryEntry, else false
+     */
+
+    public boolean isDirectoryEntry()
+    {
+        return true;
+    }
+
+    /* **********  END  implementation of Entry ********** */
+    /* ********** START extension of Entry ********** */
+
+    /**
+     * extensions use this method to verify internal rules regarding
+     * deletion of the underlying store.
+     *
+     * @return true if it's ok to delete the underlying store, else
+     *         false
+     */
+
+    protected boolean isDeleteOK()
+    {
+
+        // if this directory is empty, we can delete it
+        return isEmpty();
+    }
+
+    /* **********  END  extension of Entry ********** */
+
+    /**
+     * Returns an Iterator over all the entries
+     */
+    public Iterator<Entry> iterator() {
+        return getEntries(); 
+    }
+
+}   // end public class DirectoryNode
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DocumentEntry.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DocumentEntry.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DocumentEntry.java	(revision 28000)
@@ -0,0 +1,41 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.filesystem;
+
+/**
+ * This interface defines methods specific to Document objects
+ * managed by a Filesystem instance.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+public interface DocumentEntry
+    extends Entry
+{
+
+    /**
+     * get the zize of the document, in bytes
+     *
+     * @return size in bytes
+     */
+
+    public int getSize();
+}   // end public interface DocumentEntry
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DocumentInputStream.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DocumentInputStream.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DocumentInputStream.java	(revision 28000)
@@ -0,0 +1,313 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.filesystem;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.poi.poifs.storage.DataInputBlock;
+import org.apache.poi.util.LittleEndianInput;
+
+/**
+ * This class provides methods to read a DocumentEntry managed by a
+ * {@link POIFSFileSystem} instance.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+public final class DocumentInputStream extends InputStream implements LittleEndianInput {
+	/** returned by read operations if we're at end of document */
+	private static final int EOF = -1;
+
+	private static final int SIZE_SHORT = 2;
+	private static final int SIZE_INT = 4;
+	private static final int SIZE_LONG = 8;
+
+	/** current offset into the Document */
+	private int _current_offset;
+
+	/** current marked offset into the Document (used by mark and reset) */
+	private int _marked_offset;
+
+	/** the Document's size */
+	private int _document_size;
+
+	/** have we been closed? */
+	private boolean _closed;
+
+	/** the actual Document */
+	private POIFSDocument _document;
+
+	/** the data block containing the current stream pointer */
+	private DataInputBlock _currentBlock;
+
+	/**
+	 * Create an InputStream from the specified DocumentEntry
+	 * 
+	 * @param document the DocumentEntry to be read
+	 * 
+	 * @exception IOException if the DocumentEntry cannot be opened (like, maybe it has
+	 *                been deleted?)
+	 */
+	public DocumentInputStream(DocumentEntry document) throws IOException {
+		if (!(document instanceof DocumentNode)) {
+			throw new IOException("Cannot open internal document storage");
+		}
+		_current_offset = 0;
+		_marked_offset = 0;
+		_document_size = document.getSize();
+		_closed = false;
+		_document = ((DocumentNode) document).getDocument();
+		_currentBlock = getDataInputBlock(0);
+	}
+
+	public int available() {
+		if (_closed) {
+			throw new IllegalStateException("cannot perform requested operation on a closed stream");
+		}
+		return _document_size - _current_offset;
+	}
+
+	public void close() {
+		_closed = true;
+	}
+
+	public void mark(int ignoredReadlimit) {
+		_marked_offset = _current_offset;
+	}
+
+	/**
+	 * Tests if this input stream supports the mark and reset methods.
+	 * 
+	 * @return <code>true</code> always
+	 */
+	public boolean markSupported() {
+		return true;
+	}
+
+	private DataInputBlock getDataInputBlock(int offset) {
+		return _document.getDataInputBlock(offset);
+	}
+
+	public int read() throws IOException {
+		dieIfClosed();
+		if (atEOD()) {
+			return EOF;
+		}
+		int result = _currentBlock.readUByte();
+		_current_offset++;
+		if (_currentBlock.available() < 1) {
+			_currentBlock = getDataInputBlock(_current_offset);
+		}
+		return result;
+	}
+
+	public int read(byte[] b) throws IOException {
+		return read(b, 0, b.length);
+	}
+
+	public int read(byte[] b, int off, int len) throws IOException {
+		dieIfClosed();
+		if (b == null) {
+			throw new IllegalArgumentException("buffer must not be null");
+		}
+		if (off < 0 || len < 0 || b.length < off + len) {
+			throw new IndexOutOfBoundsException("can't read past buffer boundaries");
+		}
+		if (len == 0) {
+			return 0;
+		}
+		if (atEOD()) {
+			return EOF;
+		}
+		int limit = Math.min(available(), len);
+		readFully(b, off, limit);
+		return limit;
+	}
+
+	/**
+	 * Repositions this stream to the position at the time the mark() method was
+	 * last called on this input stream. If mark() has not been called this
+	 * method repositions the stream to its beginning.
+	 */
+	public void reset() {
+		_current_offset = _marked_offset;
+		_currentBlock = getDataInputBlock(_current_offset);
+	}
+
+	public long skip(long n) throws IOException {
+		dieIfClosed();
+		if (n < 0) {
+			return 0;
+		}
+		int new_offset = _current_offset + (int) n;
+
+		if (new_offset < _current_offset) {
+
+			// wrap around in converting a VERY large long to an int
+			new_offset = _document_size;
+		} else if (new_offset > _document_size) {
+			new_offset = _document_size;
+		}
+		long rval = new_offset - _current_offset;
+
+		_current_offset = new_offset;
+		_currentBlock = getDataInputBlock(_current_offset);
+		return rval;
+	}
+
+	private void dieIfClosed() throws IOException {
+		if (_closed) {
+			throw new IOException("cannot perform requested operation on a closed stream");
+		}
+	}
+
+	private boolean atEOD() {
+		return _current_offset == _document_size;
+	}
+
+	private void checkAvaliable(int requestedSize) {
+		if (_closed) {
+			throw new IllegalStateException("cannot perform requested operation on a closed stream");
+		}
+		if (requestedSize > _document_size - _current_offset) {
+			throw new RuntimeException("Buffer underrun - requested " + requestedSize
+					+ " bytes but " + (_document_size - _current_offset) + " was available");
+		}
+	}
+
+	public byte readByte() {
+		return (byte) readUByte();
+	}
+
+	public double readDouble() {
+		return Double.longBitsToDouble(readLong());
+	}
+
+	public void readFully(byte[] buf) {
+		readFully(buf, 0, buf.length);
+	}
+
+	public short readShort() {
+		return (short) readUShort();
+	}
+
+	public void readFully(byte[] buf, int off, int len) {
+		checkAvaliable(len);
+		int blockAvailable = _currentBlock.available();
+		if (blockAvailable > len) {
+			_currentBlock.readFully(buf, off, len);
+			_current_offset += len;
+			return;
+		}
+		// else read big amount in chunks
+		int remaining = len;
+		int writePos = off;
+		while (remaining > 0) {
+			boolean blockIsExpiring = remaining >= blockAvailable;
+			int reqSize;
+			if (blockIsExpiring) {
+				reqSize = blockAvailable;
+			} else {
+				reqSize = remaining;
+			}
+			_currentBlock.readFully(buf, writePos, reqSize);
+			remaining -= reqSize;
+			writePos += reqSize;
+			_current_offset += reqSize;
+			if (blockIsExpiring) {
+				if (_current_offset == _document_size) {
+					if (remaining > 0) {
+						throw new IllegalStateException(
+								"reached end of document stream unexpectedly");
+					}
+					_currentBlock = null;
+					break;
+				}
+				_currentBlock = getDataInputBlock(_current_offset);
+				blockAvailable = _currentBlock.available();
+			}
+		}
+	}
+
+	public long readLong() {
+		checkAvaliable(SIZE_LONG);
+		int blockAvailable = _currentBlock.available();
+		long result;
+		if (blockAvailable > SIZE_LONG) {
+			result = _currentBlock.readLongLE();
+		} else {
+			DataInputBlock nextBlock = getDataInputBlock(_current_offset + blockAvailable);
+			if (blockAvailable == SIZE_LONG) {
+				result = _currentBlock.readLongLE();
+			} else {
+				result = nextBlock.readLongLE(_currentBlock, blockAvailable);
+			}
+			_currentBlock = nextBlock;
+		}
+		_current_offset += SIZE_LONG;
+		return result;
+	}
+
+	public int readInt() {
+		checkAvaliable(SIZE_INT);
+		int blockAvailable = _currentBlock.available();
+		int result;
+		if (blockAvailable > SIZE_INT) {
+			result = _currentBlock.readIntLE();
+		} else {
+			DataInputBlock nextBlock = getDataInputBlock(_current_offset + blockAvailable);
+			if (blockAvailable == SIZE_INT) {
+				result = _currentBlock.readIntLE();
+			} else {
+				result = nextBlock.readIntLE(_currentBlock, blockAvailable);
+			}
+			_currentBlock = nextBlock;
+		}
+		_current_offset += SIZE_INT;
+		return result;
+	}
+
+	public int readUShort() {
+		checkAvaliable(SIZE_SHORT);
+		int blockAvailable = _currentBlock.available();
+		int result;
+		if (blockAvailable > SIZE_SHORT) {
+			result = _currentBlock.readUShortLE();
+		} else {
+			DataInputBlock nextBlock = getDataInputBlock(_current_offset + blockAvailable);
+			if (blockAvailable == SIZE_SHORT) {
+				result = _currentBlock.readUShortLE();
+			} else {
+				result = nextBlock.readUShortLE(_currentBlock);
+			}
+			_currentBlock = nextBlock;
+		}
+		_current_offset += SIZE_SHORT;
+		return result;
+	}
+
+	public int readUByte() {
+		checkAvaliable(1);
+		int result = _currentBlock.readUByte();
+		_current_offset++;
+		if (_currentBlock.available() < 1) {
+			_currentBlock = getDataInputBlock(_current_offset);
+		}
+		return result;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DocumentNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DocumentNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/DocumentNode.java	(revision 28000)
@@ -0,0 +1,108 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.filesystem;
+
+import org.apache.poi.poifs.property.DocumentProperty;
+
+/**
+ * Simple implementation of DocumentEntry
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+public class DocumentNode
+    extends EntryNode
+    implements DocumentEntry
+{
+
+    // underlying POIFSDocument instance
+    private POIFSDocument _document;
+
+    /**
+     * create a DocumentNode. This method is not public by design; it
+     * is intended strictly for the internal use of this package
+     *
+     * @param property the DocumentProperty for this DocumentEntry
+     * @param parent the parent of this entry
+     */
+
+    DocumentNode(final DocumentProperty property, final DirectoryNode parent)
+    {
+        super(property, parent);
+        _document = property.getDocument();
+    }
+
+    /**
+     * get the POIFSDocument
+     *
+     * @return the internal POIFSDocument
+     */
+
+    POIFSDocument getDocument()
+    {
+        return _document;
+    }
+
+    /* ********** START implementation of DocumentEntry ********** */
+
+    /**
+     * get the zize of the document, in bytes
+     *
+     * @return size in bytes
+     */
+
+    public int getSize()
+    {
+        return getProperty().getSize();
+    }
+
+    /* **********  END  implementation of DocumentEntry ********** */
+    /* ********** START implementation of Entry ********** */
+
+    /**
+     * is this a DocumentEntry?
+     *
+     * @return true if the Entry is a DocumentEntry, else false
+     */
+
+    public boolean isDocumentEntry()
+    {
+        return true;
+    }
+
+    /* **********  END  implementation of Entry ********** */
+    /* ********** START extension of Entry ********** */
+
+    /**
+     * extensions use this method to verify internal rules regarding
+     * deletion of the underlying store.
+     *
+     * @return true if it's ok to delete the underlying store, else
+     *         false
+     */
+
+    protected boolean isDeleteOK()
+    {
+        return true;
+    }
+
+    /* **********  END  extension of Entry ********** */
+}   // end public class DocumentNode
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/Entry.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/Entry.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/Entry.java	(revision 28000)
@@ -0,0 +1,67 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.filesystem;
+
+/**
+ * This interface provides access to an object managed by a Filesystem
+ * instance. Entry objects are further divided into DocumentEntry and
+ * DirectoryEntry instances.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+public interface Entry
+{
+
+    /**
+     * get the name of the Entry
+     *
+     * @return name
+     */
+
+    public String getName();
+
+
+    /**
+     * is this a DocumentEntry?
+     *
+     * @return true if the Entry is a DocumentEntry, else false
+     */
+
+    public boolean isDocumentEntry();
+
+
+    /**
+     * Delete this Entry. This operation should succeed, but there are
+     * special circumstances when it will not:
+     *
+     * If this Entry is the root of the Entry tree, it cannot be
+     * deleted, as there is no way to create another one.
+     *
+     * If this Entry is a directory, it cannot be deleted unless it is
+     * empty.
+     *
+     * @return true if the Entry was successfully deleted, else false
+     */
+
+    public boolean delete();
+
+}   // end public interface Entry
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/EntryNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/EntryNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/EntryNode.java	(revision 28000)
@@ -0,0 +1,155 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.filesystem;
+
+import org.apache.poi.poifs.property.Property;
+
+/**
+ * Abstract implementation of Entry
+ *
+ * Extending classes should override isDocument() or isDirectory(), as
+ * appropriate
+ *
+ * Extending classes must override isDeleteOK()
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+public abstract class EntryNode
+    implements Entry
+{
+
+    // the DocumentProperty backing this object
+    private Property      _property;
+
+    // this object's parent Entry
+    private DirectoryNode _parent;
+
+    /**
+     * create a DocumentNode. This method is not public by design; it
+     * is intended strictly for the internal use of extending classes
+     *
+     * @param property the Property for this Entry
+     * @param parent the parent of this entry
+     */
+
+    protected EntryNode(final Property property, final DirectoryNode parent)
+    {
+        _property = property;
+        _parent   = parent;
+    }
+
+    /**
+     * grant access to the property
+     *
+     * @return the property backing this entry
+     */
+
+    protected Property getProperty()
+    {
+        return _property;
+    }
+
+    /**
+     * is this the root of the tree?
+     *
+     * @return true if so, else false
+     */
+
+    protected boolean isRoot()
+    {
+
+        // only the root Entry has no parent ...
+        return (_parent == null);
+    }
+
+    /**
+     * extensions use this method to verify internal rules regarding
+     * deletion of the underlying store.
+     *
+     * @return true if it's ok to delete the underlying store, else
+     *         false
+     */
+
+    protected abstract boolean isDeleteOK();
+
+    /* ********** START implementation of Entry ********** */
+
+    /**
+     * get the name of the Entry
+     *
+     * @return name
+     */
+
+    public String getName()
+    {
+        return _property.getName();
+    }
+
+    /**
+     * is this a DirectoryEntry?
+     *
+     * @return true if the Entry is a DirectoryEntry, else false
+     */
+
+    public boolean isDirectoryEntry()
+    {
+        return false;
+    }
+
+    /**
+     * is this a DocumentEntry?
+     *
+     * @return true if the Entry is a DocumentEntry, else false
+     */
+
+    public boolean isDocumentEntry()
+    {
+        return false;
+    }
+
+    /**
+     * Delete this Entry. This operation should succeed, but there are
+     * special circumstances when it will not:
+     *
+     * If this Entry is the root of the Entry tree, it cannot be
+     * deleted, as there is no way to create another one.
+     *
+     * If this Entry is a directory, it cannot be deleted unless it is
+     * empty.
+     *
+     * @return true if the Entry was successfully deleted, else false
+     */
+
+    public boolean delete()
+    {
+        boolean rval = false;
+
+        if ((!isRoot()) && isDeleteOK())
+        {
+            rval = _parent.deleteEntry(this);
+        }
+        return rval;
+    }
+
+
+    /* **********  END  implementation of Entry ********** */
+}   // end public class EntryNode
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/OfficeXmlFileException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/OfficeXmlFileException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/OfficeXmlFileException.java	(revision 28000)
@@ -0,0 +1,37 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.filesystem;
+
+/**
+ * This exception is thrown when we try to open a file that's actually
+ *  an Office 2007+ XML file, rather than an OLE2 file (which is what
+ *  POI works with)
+ *
+ * @author Nick Burch
+ */
+
+@SuppressWarnings("serial")
+public class OfficeXmlFileException extends IllegalArgumentException
+{
+	public OfficeXmlFileException(String s) {
+		super(s);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/POIFSDocument.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/POIFSDocument.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/POIFSDocument.java	(revision 28000)
@@ -0,0 +1,223 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.filesystem;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.poifs.property.DocumentProperty;
+import org.apache.poi.poifs.property.Property;
+import org.apache.poi.poifs.storage.DataInputBlock;
+import org.apache.poi.poifs.storage.DocumentBlock;
+import org.apache.poi.poifs.storage.ListManagedBlock;
+import org.apache.poi.poifs.storage.RawDataBlock;
+import org.apache.poi.poifs.storage.SmallDocumentBlock;
+
+/**
+ * This class manages a document in the POIFS filesystem.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+public final class POIFSDocument {
+	private static final DocumentBlock[] EMPTY_BIG_BLOCK_ARRAY = { };
+	private static final SmallDocumentBlock[] EMPTY_SMALL_BLOCK_ARRAY = { };
+	private DocumentProperty _property;
+	private int _size;
+	
+	// one of these stores will be valid
+	private SmallBlockStore  _small_store;
+	private BigBlockStore	_big_store;
+	
+
+	// TODO - awkward typing going on here
+	private static DocumentBlock[] convertRawBlocksToBigBlocks(ListManagedBlock[] blocks) throws IOException {
+		DocumentBlock[] result = new DocumentBlock[blocks.length];
+		for (int i = 0; i < result.length; i++) {
+			result[i] = new DocumentBlock((RawDataBlock)blocks[i]);
+		}
+		return result;
+	}
+	private static SmallDocumentBlock[] convertRawBlocksToSmallBlocks(ListManagedBlock[] blocks) {
+		if (blocks instanceof SmallDocumentBlock[]) {
+			return (SmallDocumentBlock[]) blocks;
+		}
+		SmallDocumentBlock[] result = new SmallDocumentBlock[blocks.length];
+		System.arraycopy(blocks, 0, result, 0, blocks.length);
+		return result;
+	}
+
+
+	/**
+	 * Constructor from small blocks
+	 *
+	 * @param name the name of the POIFSDocument
+	 * @param blocks the small blocks making up the POIFSDocument
+	 * @param length the actual length of the POIFSDocument
+	 */
+	public POIFSDocument(String name, POIFSBigBlockSize bigBlockSize, ListManagedBlock[] blocks, int length) throws IOException {
+		_size = length;
+		_property = new DocumentProperty(name, _size);
+		_property.setDocument(this);
+		if (Property.isSmall(_size)) {
+			_big_store = new BigBlockStore(bigBlockSize,EMPTY_BIG_BLOCK_ARRAY);
+			_small_store = new SmallBlockStore(bigBlockSize,convertRawBlocksToSmallBlocks(blocks));
+		} else {
+			_big_store = new BigBlockStore(bigBlockSize,convertRawBlocksToBigBlocks(blocks));
+			_small_store = new SmallBlockStore(bigBlockSize,EMPTY_SMALL_BLOCK_ARRAY);
+		}
+	}
+	public POIFSDocument(String name, ListManagedBlock[] blocks, int length) throws IOException {
+	   this(name, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, blocks, length);
+	}
+
+	/**
+	 * Constructor
+	 *
+	 * @param name the name of the POIFSDocument
+	 * @param stream the InputStream we read data from
+	 */
+	public POIFSDocument(String name, POIFSBigBlockSize bigBlockSize, InputStream stream) throws IOException {
+		List<DocumentBlock> blocks = new ArrayList<DocumentBlock>();
+
+		_size = 0;
+		while (true) {
+			DocumentBlock block = new DocumentBlock(stream, bigBlockSize);
+			int blockSize = block.size();
+
+			if (blockSize > 0) {
+				blocks.add(block);
+				_size += blockSize;
+			}
+			if (block.partiallyRead()) {
+				break;
+			}
+		}
+		DocumentBlock[] bigBlocks = blocks.toArray(new DocumentBlock[blocks.size()]);
+
+		_big_store = new BigBlockStore(bigBlockSize,bigBlocks);
+		_property = new DocumentProperty(name, _size);
+		_property.setDocument(this);
+		if (_property.shouldUseSmallBlocks()) {
+			_small_store = new SmallBlockStore(bigBlockSize,SmallDocumentBlock.convert(bigBlockSize,bigBlocks, _size));
+			_big_store = new BigBlockStore(bigBlockSize,new DocumentBlock[0]);
+		} else {
+			_small_store = new SmallBlockStore(bigBlockSize,EMPTY_SMALL_BLOCK_ARRAY);
+		}
+	}
+	public POIFSDocument(String name, InputStream stream) throws IOException {
+	   this(name, POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS, stream);
+	}
+
+	/**
+	 * @return size of the document
+	 */
+	public int getSize() { // NO_UCD
+		return _size;
+	}
+
+
+	/**
+	 * @return <code>null</code> if <tt>offset</tt> points to the end of the document stream
+	 */
+	DataInputBlock getDataInputBlock(int offset) {
+		if (offset >= _size) {
+			if (offset > _size) {
+				throw new RuntimeException("Request for Offset " + offset + " doc size is " + _size);
+			}
+			return null;
+		}
+		if (_property.shouldUseSmallBlocks()) {
+			return SmallDocumentBlock.getDataInputBlock(_small_store.getBlocks(), offset);
+		}
+		return DocumentBlock.getDataInputBlock(_big_store.getBlocks(), offset);
+	}
+
+	/**
+	 * @return the instance's DocumentProperty
+	 */
+
+	DocumentProperty getDocumentProperty() {
+		return _property;
+	}
+
+	/* ********** START implementation of BlockWritable ********** */
+
+	/* **********  END  implementation of BlockWritable ********** */
+
+
+	/* **********  END  implementation of BATManaged ********** */
+	private static final class SmallBlockStore {
+		private SmallDocumentBlock[] _smallBlocks;
+		private final int _size;
+		private final POIFSBigBlockSize _bigBlockSize;
+
+		/**
+		 * Constructor
+		 *
+		 * @param blocks blocks to construct the store from
+		 */
+		SmallBlockStore(POIFSBigBlockSize bigBlockSize, SmallDocumentBlock[] blocks) {
+		   _bigBlockSize = bigBlockSize;
+			_smallBlocks = blocks.clone();
+			this._size = -1;
+		}
+
+		/**
+		 * @return <code>true</code> if this store is a valid source of data
+		 */
+		boolean isValid() {
+			return _smallBlocks.length > 0;
+		}
+
+		/**
+		 * @return the SmallDocumentBlocks
+		 */
+		SmallDocumentBlock[] getBlocks() {
+			if (isValid()) {
+				ByteArrayOutputStream stream = new ByteArrayOutputStream(_size);
+				_smallBlocks = SmallDocumentBlock.convert(_bigBlockSize, stream.toByteArray(), _size);
+			}
+			return _smallBlocks;
+		}
+	} // end private class SmallBlockStore
+
+	private static final class BigBlockStore {
+		private DocumentBlock[] bigBlocks;
+
+		/**
+		 * Constructor
+		 *
+		 * @param blocks the blocks making up the store
+		 */
+		BigBlockStore(POIFSBigBlockSize bigBlockSize, DocumentBlock[] blocks) {
+			bigBlocks = blocks.clone();
+		}
+
+		/**
+		 * @return the DocumentBlocks
+		 */
+		DocumentBlock[] getBlocks() {
+			return bigBlocks;
+		}
+	} // end private class BigBlockStore
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java	(revision 28000)
@@ -0,0 +1,206 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.filesystem;
+
+import java.io.File;
+
+/**
+ * Class POIFSDocumentPath
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ * @version %I%, %G%
+ */
+
+public class POIFSDocumentPath
+{
+    private String[] components;
+    private int      hashcode = 0;
+
+    /**
+     * simple constructor for the path of a document that is in the
+     * root of the POIFSFileSystem. The constructor that takes an
+     * array of Strings can also be used to create such a
+     * POIFSDocumentPath by passing it a null or empty String array
+     */
+
+    public POIFSDocumentPath()
+    {
+        this.components = new String[ 0 ];
+    }
+
+    /**
+     * constructor that adds additional subdirectories to an existing
+     * path
+     *
+     * @param path the existing path
+     * @param components the additional subdirectory names to be added
+     *
+     * @exception IllegalArgumentException if any of the Strings in
+     *                                     components is null or zero
+     *                                     length
+     */
+
+    public POIFSDocumentPath(final POIFSDocumentPath path,
+                             final String [] components)
+        throws IllegalArgumentException
+    {
+        if (components == null)
+        {
+            this.components = new String[ path.components.length ];
+        }
+        else
+        {
+            this.components =
+                new String[ path.components.length + components.length ];
+        }
+        for (int j = 0; j < path.components.length; j++)
+        {
+            this.components[ j ] = path.components[ j ];
+        }
+        if (components != null)
+        {
+            for (int j = 0; j < components.length; j++)
+            {
+                if ((components[ j ] == null)
+                        || (components[ j ].length() == 0))
+                {
+                    throw new IllegalArgumentException(
+                        "components cannot contain null or empty strings");
+                }
+                this.components[ j + path.components.length ] =
+                    components[ j ];
+            }
+        }
+    }
+
+    /**
+     * equality. Two POIFSDocumentPath instances are equal if they
+     * have the same number of component Strings, and if each
+     * component String is equal to its coresponding component String
+     *
+     * @param o the object we're checking equality for
+     *
+     * @return true if the object is equal to this object
+     */
+
+    public boolean equals(final Object o)
+    {
+        boolean rval = false;
+
+        if ((o != null) && (o.getClass() == this.getClass()))
+        {
+            if (this == o)
+            {
+                rval = true;
+            }
+            else
+            {
+                POIFSDocumentPath path = ( POIFSDocumentPath ) o;
+
+                if (path.components.length == this.components.length)
+                {
+                    rval = true;
+                    for (int j = 0; j < this.components.length; j++)
+                    {
+                        if (!path.components[ j ]
+                                .equals(this.components[ j ]))
+                        {
+                            rval = false;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return rval;
+    }
+
+    /**
+     * calculate and return the hashcode
+     *
+     * @return hashcode
+     */
+
+    public int hashCode()
+    {
+        if (hashcode == 0)
+        {
+            for (int j = 0; j < components.length; j++)
+            {
+                hashcode += components[ j ].hashCode();
+            }
+        }
+        return hashcode;
+    }
+
+    /**
+     * @return the number of components
+     */
+
+    public int length()
+    {
+        return components.length;
+    }
+
+    /**
+     * get the specified component
+     *
+     * @param n which component (0 ... length() - 1)
+     *
+     * @return the nth component;
+     *
+     * @exception ArrayIndexOutOfBoundsException if n < 0 or n >=
+     *                                           length()
+     */
+
+    public String getComponent(int n)
+        throws ArrayIndexOutOfBoundsException
+    {
+        return components[ n ];
+    }
+
+
+    /**
+     * <p>Returns a string representation of the path. Components are
+     * separated by the platform-specific file separator.</p>
+     *
+     * @return string representation
+     *
+     * @since 2002-01-24
+     */
+
+    public String toString()
+    {
+        final StringBuffer b = new StringBuffer();
+        final int          l = length();
+
+        b.append(File.separatorChar);
+        for (int i = 0; i < l; i++)
+        {
+            b.append(getComponent(i));
+            if (i < l - 1)
+            {
+                b.append(File.separatorChar);
+            }
+        }
+        return b.toString();
+    }
+}   // end public class POIFSDocumentPath
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/POIFSFileSystem.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/POIFSFileSystem.java	(revision 28000)
@@ -0,0 +1,287 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.filesystem;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.poifs.property.DirectoryProperty;
+import org.apache.poi.poifs.property.Property;
+import org.apache.poi.poifs.property.PropertyTable;
+import org.apache.poi.poifs.storage.BlockAllocationTableReader;
+import org.apache.poi.poifs.storage.BlockList;
+import org.apache.poi.poifs.storage.HeaderBlockReader;
+import org.apache.poi.poifs.storage.RawDataBlockList;
+import org.apache.poi.poifs.storage.SmallBlockTableReader;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * This is the main class of the POIFS system; it manages the entire
+ * life cycle of the filesystem.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+public class POIFSFileSystem
+{
+	private static final POILogger _logger =
+		POILogFactory.getLogger(POIFSFileSystem.class);
+
+    private PropertyTable _property_table;
+    private List<POIFSDocument> _documents;
+    private DirectoryNode _root;
+
+    /**
+     * What big block size the file uses. Most files
+     *  use 512 bytes, but a few use 4096
+     */
+    private POIFSBigBlockSize bigBlockSize = 
+       POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS;
+
+    /**
+     * Constructor, intended for writing
+     */
+    public POIFSFileSystem()
+    {
+        _property_table = new PropertyTable();
+        _documents      = new ArrayList<POIFSDocument>();
+        _root           = null;
+    }
+
+    /**
+     * Create a POIFSFileSystem from an <tt>InputStream</tt>.  Normally the stream is read until
+     * EOF.  The stream is always closed.<p/>
+     *
+     * Some streams are usable after reaching EOF (typically those that return <code>true</code>
+     * for <tt>markSupported()</tt>).  In the unlikely case that the caller has such a stream
+     * <i>and</i> needs to use it after this constructor completes, a work around is to wrap the
+     * stream in order to trap the <tt>close()</tt> call.  A convenience method (
+     * <tt>createNonClosingInputStream()</tt>) has been provided for this purpose:
+     * <pre>
+     * InputStream wrappedStream = POIFSFileSystem.createNonClosingInputStream(is);
+     * HSSFWorkbook wb = new HSSFWorkbook(wrappedStream);
+     * is.reset();
+     * doSomethingElse(is);
+     * </pre>
+     * Note also the special case of <tt>ByteArrayInputStream</tt> for which the <tt>close()</tt>
+     * method does nothing.
+     * <pre>
+     * ByteArrayInputStream bais = ...
+     * HSSFWorkbook wb = new HSSFWorkbook(bais); // calls bais.close() !
+     * bais.reset(); // no problem
+     * doSomethingElse(bais);
+     * </pre>
+     *
+     * @param stream the InputStream from which to read the data
+     *
+     * @exception IOException on errors reading, or on invalid data
+     */
+
+    public POIFSFileSystem(InputStream stream)
+        throws IOException
+    {
+        this();
+        boolean success = false;
+
+        HeaderBlockReader header_block_reader;
+        RawDataBlockList data_blocks;
+        try {
+            // read the header block from the stream
+            header_block_reader = new HeaderBlockReader(stream);
+            bigBlockSize = header_block_reader.getBigBlockSize();
+
+            // read the rest of the stream into blocks
+            data_blocks = new RawDataBlockList(stream, bigBlockSize);
+            success = true;
+        } finally {
+            closeInputStream(stream, success);
+        }
+
+
+        // set up the block allocation table (necessary for the
+        // data_blocks to be manageable
+        new BlockAllocationTableReader(header_block_reader.getBigBlockSize(),
+                                       header_block_reader.getBATCount(),
+                                       header_block_reader.getBATArray(),
+                                       header_block_reader.getXBATCount(),
+                                       header_block_reader.getXBATIndex(),
+                                       data_blocks);
+
+        // get property table from the document
+        PropertyTable properties =
+            new PropertyTable(
+                              header_block_reader.getPropertyStart(),
+                              data_blocks);
+
+        // init documents
+        processProperties(
+        		SmallBlockTableReader.getSmallDocumentBlocks(
+        		      bigBlockSize, data_blocks, properties.getRoot(),
+        				header_block_reader.getSBATStart()
+        		),
+        		data_blocks,
+        		properties.getRoot().getChildren(),
+        		null,
+        		header_block_reader.getPropertyStart()
+        );
+
+        // For whatever reason CLSID of root is always 0.
+        getRoot().setStorageClsid(properties.getRoot().getStorageClsid());
+    }
+    /**
+     * @param stream the stream to be closed
+     * @param success <code>false</code> if an exception is currently being thrown in the calling method
+     */
+    private void closeInputStream(InputStream stream, boolean success) {
+
+        if(stream.markSupported() && !(stream instanceof ByteArrayInputStream)) {
+            String msg = "POIFS is closing the supplied input stream of type ("
+                    + stream.getClass().getName() + ") which supports mark/reset.  "
+                    + "This will be a problem for the caller if the stream will still be used.  "
+                    + "If that is the case the caller should wrap the input stream to avoid this close logic.  "
+                    + "This warning is only temporary and will not be present in future versions of POI.";
+            _logger.log(POILogger.WARN, msg);
+        }
+        try {
+            stream.close();
+        } catch (IOException e) {
+            if(success) {
+                throw new RuntimeException(e);
+            }
+            // else not success? Try block did not complete normally
+            // just print stack trace and leave original ex to be thrown
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * get the root entry
+     *
+     * @return the root entry
+     */
+
+    public DirectoryNode getRoot()
+    {
+        if (_root == null)
+        {
+            _root = new DirectoryNode(_property_table.getRoot(), this, null);
+        }
+        return _root;
+    }
+
+
+    /**
+     * add a new POIFSDocument
+     *
+     * @param document the POIFSDocument being added
+     */
+
+    void addDocument(final POIFSDocument document)
+    {
+        _documents.add(document);
+        _property_table.addProperty(document.getDocumentProperty());
+    }
+
+    /**
+     * add a new DirectoryProperty
+     *
+     * @param directory the DirectoryProperty being added
+     */
+
+    void addDirectory(final DirectoryProperty directory)
+    {
+        _property_table.addProperty(directory);
+    }
+
+    /**
+     * remove an entry
+     *
+     * @param entry to be removed
+     */
+
+    void remove(EntryNode entry)
+    {
+        _property_table.removeProperty(entry.getProperty());
+        if (entry.isDocumentEntry())
+        {
+            _documents.remove((( DocumentNode ) entry).getDocument());
+        }
+    }
+
+    private void processProperties(final BlockList small_blocks,
+                                   final BlockList big_blocks,
+                                   final Iterator<Property> properties,
+                                   final DirectoryNode dir,
+                                   final int headerPropertiesStartAt)
+        throws IOException
+    {
+        while (properties.hasNext())
+        {
+            Property      property = properties.next();
+            String        name     = property.getName();
+            DirectoryNode parent   = (dir == null)
+                                     ? (( DirectoryNode ) getRoot())
+                                     : dir;
+
+            if (property.isDirectory())
+            {
+                DirectoryNode new_dir =
+                    ( DirectoryNode ) parent.createDirectory(name);
+
+                new_dir.setStorageClsid( property.getStorageClsid() );
+
+                processProperties(
+                    small_blocks, big_blocks,
+                    (( DirectoryProperty ) property).getChildren(),
+                    new_dir, headerPropertiesStartAt);
+            }
+            else
+            {
+                int           startBlock = property.getStartBlock();
+                int           size       = property.getSize();
+                POIFSDocument document   = null;
+
+                if (property.shouldUseSmallBlocks())
+                {
+                    document =
+                        new POIFSDocument(name,
+                                          small_blocks.fetchBlocks(startBlock, headerPropertiesStartAt),
+                                          size);
+                }
+                else
+                {
+                    document =
+                        new POIFSDocument(name,
+                                          big_blocks.fetchBlocks(startBlock, headerPropertiesStartAt),
+                                          size);
+                }
+                parent.createDocument(document);
+            }
+        }
+    }
+}   // end public class POIFSFileSystem
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/filesystem/package.html	(revision 28000)
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+filesystem package maps OLE 2 Compound document files to a more familiar filesystem interface.
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+@see org.apache.poi.poifs.eventfilesystem
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/package.html	(revision 28000)
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Poor Obfuscation Implementation FileSystem APIs implement the OLE 2 Compound Document format in
+pure Java.  All POI subprojects are based upon this API.
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+@see org.apache.poi.hssf
+@see org.apache.poi.hpsf
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/Child.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/Child.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/Child.java	(revision 28000)
@@ -0,0 +1,51 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.property;
+
+/**
+ * This interface defines methods for finding and setting sibling
+ * Property instances
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+public interface Child
+{
+
+
+    /**
+     * Set the next Child
+     *
+     * @param child the new 'next' child; may be null, which has the
+     *              effect of saying there is no 'next' child
+     */
+
+    public void setNextChild(final Child child);
+
+    /**
+     * Set the previous Child
+     *
+     * @param child the new 'previous' child; may be null, which has
+     *              the effect of saying there is no 'previous' child
+     */
+
+    public void setPreviousChild(final Child child);
+}   // end public interface Child
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/DirectoryProperty.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/DirectoryProperty.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/DirectoryProperty.java	(revision 28000)
@@ -0,0 +1,246 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.property;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Directory property
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+public class DirectoryProperty extends Property implements Parent { // TODO - fix instantiable superclass
+
+    /** List of Property instances */
+    private List<Property> _children;
+
+    /** set of children's names */
+    private Set<String>  _children_names;
+
+    /**
+     * Default constructor
+     *
+     * @param name the name of the directory
+     */
+    public DirectoryProperty(String name)
+    {
+        super();
+        _children       = new ArrayList<Property>();
+        _children_names = new HashSet<String>();
+        setName(name);
+        setSize(0);
+        setPropertyType(PropertyConstants.DIRECTORY_TYPE);
+        setStartBlock(0);
+        setNodeColor(_NODE_BLACK);   // simplification
+    }
+
+    /**
+     * reader constructor
+     *
+     * @param index index number
+     * @param array byte data
+     * @param offset offset into byte data
+     */
+    protected DirectoryProperty(final int index, final byte [] array,
+                                final int offset)
+    {
+        super(index, array, offset);
+        _children       = new ArrayList<Property>();
+        _children_names = new HashSet<String>();
+    }
+
+
+    /**
+     * Delete a Property
+     *
+     * @param property the Property being deleted
+     *
+     * @return true if the Property could be deleted, else false
+     */
+    public boolean deleteChild(Property property)
+    {
+        boolean result = _children.remove(property);
+
+        if (result)
+        {
+            _children_names.remove(property.getName());
+        }
+        return result;
+    }
+
+    public static class PropertyComparator implements Comparator<Property> {
+
+        /**
+         * Object equality, implemented as object identity
+         *
+         * @param o Object we're being compared to
+         *
+         * @return true if identical, else false
+         */
+        public boolean equals(Object o)
+        {
+            return this == o;
+        }
+
+        /**
+         * compare method. Assumes both parameters are non-null
+         * instances of Property. One property is less than another if
+         * its name is shorter than the other property's name. If the
+         * names are the same length, the property whose name comes
+         * before the other property's name, alphabetically, is less
+         * than the other property.
+         *
+         * @param o1 first object to compare, better be a Property
+         * @param o2 second object to compare, better be a Property
+         *
+         * @return negative value if o1 <  o2,
+         *         zero           if o1 == o2,
+         *         positive value if o1 >  o2.
+         */
+        public int compare(Property o1, Property o2)
+        {
+            String VBA_PROJECT = "_VBA_PROJECT";
+            String name1  = o1.getName();
+            String name2  = o2.getName();
+            int  result = name1.length() - name2.length();
+
+            if (result == 0)
+            {
+              // _VBA_PROJECT, it seems, will always come last
+              if (name1.compareTo(VBA_PROJECT) == 0)
+                result = 1;
+              else if (name2.compareTo(VBA_PROJECT) == 0)
+                result = -1;
+              else
+              {
+                if (name1.startsWith("__") && name2.startsWith("__"))
+                {
+                  // Betweeen __SRP_0 and __SRP_1 just sort as normal
+                  result = name1.compareToIgnoreCase(name2);
+                }
+                else if (name1.startsWith("__"))
+                {
+                  // If only name1 is __XXX then this will be placed after name2
+                  result = 1;
+                }
+                else if (name2.startsWith("__"))
+                {
+                  // If only name2 is __XXX then this will be placed after name1
+                  result = -1;
+                }
+                else
+                  // result = name1.compareTo(name2);
+                  // The default case is to sort names ignoring case
+                  result = name1.compareToIgnoreCase(name2);
+              }
+            }
+            return result;
+        }
+    }
+
+    /**
+     * @return true if a directory type Property
+     */
+    public boolean isDirectory()
+    {
+        return true;
+    }
+
+    /**
+     * Perform whatever activities need to be performed prior to
+     * writing
+     */
+    protected void preWrite()
+    {
+        if (_children.size() > 0)
+        {
+            Property[] children = _children.toArray(new Property[ 0 ]);
+
+            Arrays.sort(children, new PropertyComparator());
+            int midpoint = children.length / 2;
+
+            setChildProperty(children[ midpoint ].getIndex());
+            children[ 0 ].setPreviousChild(null);
+            children[ 0 ].setNextChild(null);
+            for (int j = 1; j < midpoint; j++)
+            {
+                children[ j ].setPreviousChild(children[ j - 1 ]);
+                children[ j ].setNextChild(null);
+            }
+            if (midpoint != 0)
+            {
+                children[ midpoint ]
+                    .setPreviousChild(children[ midpoint - 1 ]);
+            }
+            if (midpoint != (children.length - 1))
+            {
+                children[ midpoint ].setNextChild(children[ midpoint + 1 ]);
+                for (int j = midpoint + 1; j < children.length - 1; j++)
+                {
+                    children[ j ].setPreviousChild(null);
+                    children[ j ].setNextChild(children[ j + 1 ]);
+                }
+                children[ children.length - 1 ].setPreviousChild(null);
+                children[ children.length - 1 ].setNextChild(null);
+            }
+            else
+            {
+                children[ midpoint ].setNextChild(null);
+            }
+        }
+    }
+
+    /**
+     * Get an iterator over the children of this Parent; all elements
+     * are instances of Property.
+     *
+     * @return Iterator of children; may refer to an empty collection
+     */
+    public Iterator<Property> getChildren()
+    {
+        return _children.iterator();
+    }
+
+    /**
+     * Add a new child to the collection of children
+     *
+     * @param property the new child to be added; must not be null
+     *
+     * @exception IOException if we already have a child with the same
+     *                        name
+     */
+    public void addChild(final Property property)
+        throws IOException
+    {
+        String name = property.getName();
+
+        if (_children_names.contains(name))
+        {
+            throw new IOException("Duplicate name \"" + name + "\"");
+        }
+        _children_names.add(name);
+        _children.add(property);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/DocumentProperty.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/DocumentProperty.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/DocumentProperty.java	(revision 28000)
@@ -0,0 +1,126 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.property;
+
+import org.apache.poi.poifs.filesystem.POIFSDocument;
+
+/**
+ * Trivial extension of Property for POIFSDocuments
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+public class DocumentProperty
+    extends Property
+{
+
+    // the POIFSDocument this property is associated with
+    private POIFSDocument _document;
+
+    /**
+     * Constructor
+     *
+     * @param name POIFSDocument name
+     * @param size POIFSDocument size
+     */
+
+    public DocumentProperty(final String name, final int size)
+    {
+        super();
+        _document = null;
+        setName(name);
+        setSize(size);
+        setNodeColor(_NODE_BLACK);   // simplification
+        setPropertyType(PropertyConstants.DOCUMENT_TYPE);
+    }
+
+    /**
+     * reader constructor
+     *
+     * @param index index number
+     * @param array byte data
+     * @param offset offset into byte data
+     */
+
+    protected DocumentProperty(final int index, final byte [] array,
+                               final int offset)
+    {
+        super(index, array, offset);
+        _document = null;
+    }
+
+    /**
+     * set the POIFSDocument
+     *
+     * @param doc the associated POIFSDocument
+     */
+
+    public void setDocument(POIFSDocument doc)
+    {
+        _document = doc;
+    }
+
+    /**
+     * get the POIFSDocument
+     *
+     * @return the associated document
+     */
+
+    public POIFSDocument getDocument()
+    {
+        return _document;
+    }
+
+    /* ********** START extension of Property ********** */
+
+    /**
+     * give method more visibility
+     *
+     * @return true if this property should use small blocks
+     */
+
+    public boolean shouldUseSmallBlocks()
+    {
+        return super.shouldUseSmallBlocks();
+    }
+
+    /**
+     * @return true if a directory type Property
+     */
+
+    public boolean isDirectory()
+    {
+        return false;
+    }
+
+    /**
+     * Perform whatever activities need to be performed prior to
+     * writing
+     */
+
+    protected void preWrite()
+    {
+
+        // do nothing
+    }
+
+    /* **********  END  extension of Property ********** */
+}   // end public class DocumentProperty
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/Parent.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/Parent.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/Parent.java	(revision 28000)
@@ -0,0 +1,60 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.property;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+/**
+ * Behavior for parent (directory) properties
+ *
+ * @author Marc Johnson27591@hotmail.com
+ */
+
+public interface Parent
+    extends Child
+{
+
+    /**
+     * Get an iterator over the children of this Parent; all elements
+     * are instances of Property.
+     *
+     * @return Iterator of children; may refer to an empty collection
+     */
+
+    public Iterator<Property> getChildren();
+
+    /**
+     * Add a new child to the collection of children
+     *
+     * @param property the new child to be added; must not be null
+     *
+     * @exception IOException if the Parent already has a child with
+     *                        the same name
+     */
+
+    public void addChild(final Property property)
+        throws IOException;
+
+
+    /** *** end methods from interface Child *** */
+
+}   // end public interface Parent
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/Property.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/Property.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/Property.java	(revision 28000)
@@ -0,0 +1,389 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.property;
+
+import java.util.Arrays;
+
+import org.apache.poi.hpsf.ClassID;
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.util.ByteField;
+import org.apache.poi.util.IntegerField;
+import org.apache.poi.util.LittleEndianConsts;
+import org.apache.poi.util.ShortField;
+
+/**
+ * This abstract base class is the ancestor of all classes
+ * implementing POIFS Property behavior.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+public abstract class Property implements Child {
+    static final private byte   _default_fill             = ( byte ) 0x00;
+    static final private int    _name_size_offset         = 0x40;
+    static final private int    _max_name_length          =
+        (_name_size_offset / LittleEndianConsts.SHORT_SIZE) - 1;
+    static final protected int  _NO_INDEX                 = -1;
+
+    // useful offsets
+    static final private int    _node_color_offset        = 0x43;
+    static final private int    _previous_property_offset = 0x44;
+    static final private int    _next_property_offset     = 0x48;
+    static final private int    _child_property_offset    = 0x4C;
+    static final private int    _storage_clsid_offset     = 0x50;
+    static final private int    _start_block_offset       = 0x74;
+    static final private int    _size_offset              = 0x78;
+
+    // node colors
+    static final protected byte _NODE_BLACK               = 1;
+
+    // documents must be at least this size to be stored in big blocks
+    static final private int    _big_block_minimum_bytes  = 4096;
+    private String              _name;
+    private ShortField          _name_size;
+    private ByteField           _property_type;
+    private ByteField           _node_color;
+    private IntegerField        _previous_property;
+    private IntegerField        _next_property;
+    private IntegerField        _child_property;
+    private ClassID             _storage_clsid;
+    private IntegerField        _start_block;
+    private IntegerField        _size;
+    private byte[]              _raw_data;
+    private int                 _index;
+
+    protected Property()
+    {
+        _raw_data = new byte[ POIFSConstants.PROPERTY_SIZE ];
+        Arrays.fill(_raw_data, _default_fill);
+        _name_size         = new ShortField(_name_size_offset);
+        _property_type     =
+            new ByteField(PropertyConstants.PROPERTY_TYPE_OFFSET);
+        _node_color        = new ByteField(_node_color_offset);
+        _previous_property = new IntegerField(_previous_property_offset,
+                                              _NO_INDEX, _raw_data);
+        _next_property     = new IntegerField(_next_property_offset,
+                                              _NO_INDEX, _raw_data);
+        _child_property    = new IntegerField(_child_property_offset,
+                                              _NO_INDEX, _raw_data);
+        _storage_clsid     = new ClassID(_raw_data,_storage_clsid_offset);
+        _start_block       = new IntegerField(_start_block_offset);
+        _size              = new IntegerField(_size_offset, 0, _raw_data);
+        _index             = _NO_INDEX;
+        setName("");
+        setNextChild(null);
+        setPreviousChild(null);
+    }
+
+    /**
+     * Constructor from byte data
+     *
+     * @param index index number
+     * @param array byte data
+     * @param offset offset into byte data
+     */
+    protected Property(int index, byte [] array, int offset)
+    {
+        _raw_data = new byte[ POIFSConstants.PROPERTY_SIZE ];
+        System.arraycopy(array, offset, _raw_data, 0,
+                         POIFSConstants.PROPERTY_SIZE);
+        _name_size         = new ShortField(_name_size_offset, _raw_data);
+        _property_type     =
+            new ByteField(PropertyConstants.PROPERTY_TYPE_OFFSET, _raw_data);
+        _node_color        = new ByteField(_node_color_offset, _raw_data);
+        _previous_property = new IntegerField(_previous_property_offset,
+                                              _raw_data);
+        _next_property     = new IntegerField(_next_property_offset,
+                                              _raw_data);
+        _child_property    = new IntegerField(_child_property_offset,
+                                              _raw_data);
+        _storage_clsid     = new ClassID(_raw_data,_storage_clsid_offset);
+        _start_block       = new IntegerField(_start_block_offset, _raw_data);
+        _size              = new IntegerField(_size_offset, _raw_data);
+        _index             = index;
+        int name_length = (_name_size.get() / LittleEndianConsts.SHORT_SIZE)
+                          - 1;
+
+        if (name_length < 1)
+        {
+            _name = "";
+        }
+        else
+        {
+            char[] char_array  = new char[ name_length ];
+            int    name_offset = 0;
+
+            for (int j = 0; j < name_length; j++)
+            {
+                char_array[ j ] = ( char ) new ShortField(name_offset,
+                                                          _raw_data).get();
+                name_offset     += LittleEndianConsts.SHORT_SIZE;
+            }
+            _name = new String(char_array, 0, name_length);
+        }
+    }
+
+    /**
+     * Set the start block for the document referred to by this
+     * Property.
+     *
+     * @param startBlock the start block index
+     */
+    public void setStartBlock(int startBlock)
+    {
+        _start_block.set(startBlock, _raw_data);
+    }
+
+    /**
+     * @return the start block
+     */
+    public int getStartBlock()
+    {
+        return _start_block.get();
+    }
+
+    /**
+     * find out the document size
+     *
+     * @return size in bytes
+     */
+    public int getSize()
+    {
+        return _size.get();
+    }
+
+    /**
+     * Based on the currently defined size, should this property use
+     * small blocks?
+     *
+     * @return true if the size is less than _big_block_minimum_bytes
+     */
+    public boolean shouldUseSmallBlocks()
+    {
+        return Property.isSmall(_size.get());
+    }
+
+    /**
+     * does the length indicate a small document?
+     *
+     * @param length length in bytes
+     *
+     * @return true if the length is less than
+     *         _big_block_minimum_bytes
+     */
+    public static boolean isSmall(int length)
+    {
+        return length < _big_block_minimum_bytes;
+    }
+
+    /**
+     * Get the name of this property
+     *
+     * @return property name as String
+     */
+    public String getName()
+    {
+        return _name;
+    }
+
+    /**
+     * @return true if a directory type Property
+     */
+    abstract public boolean isDirectory();
+
+    /**
+     * Sets the storage clsid, which is the Class ID of a COM object which
+     *   reads and writes this stream
+     * @return storage Class ID for this property stream
+     */
+    public ClassID getStorageClsid()
+    {
+        return _storage_clsid;
+    }
+
+    /**
+     * Set the name; silently truncates the name if it's too long.
+     *
+     * @param name the new name
+     */
+    protected void setName(String name)
+    {
+        char[] char_array = name.toCharArray();
+        int    limit      = Math.min(char_array.length, _max_name_length);
+
+        _name = new String(char_array, 0, limit);
+        short offset = 0;
+        int   j      = 0;
+
+        for (; j < limit; j++)
+        {
+            new ShortField(offset, ( short ) char_array[ j ], _raw_data);
+            offset += LittleEndianConsts.SHORT_SIZE;
+        }
+        for (; j < _max_name_length + 1; j++)
+        {
+            new ShortField(offset, ( short ) 0, _raw_data);
+            offset += LittleEndianConsts.SHORT_SIZE;
+        }
+
+        // double the count, and include the null at the end
+        _name_size
+            .set(( short ) ((limit + 1)
+                            * LittleEndianConsts.SHORT_SIZE), _raw_data);
+    }
+
+    /**
+     * Sets the storage class ID for this property stream. This is the Class ID
+     *   of the COM object which can read and write this property stream
+     * @param clsidStorage Storage Class ID
+     */
+    public void setStorageClsid( ClassID clsidStorage)
+    {
+        _storage_clsid = clsidStorage;
+        if( clsidStorage == null) {
+            Arrays.fill( _raw_data, _storage_clsid_offset, _storage_clsid_offset + ClassID.LENGTH, (byte) 0);
+        } else {
+            clsidStorage.write( _raw_data, _storage_clsid_offset);
+        }
+    }
+    /**
+     * Set the property type. Makes no attempt to validate the value.
+     *
+     * @param propertyType the property type (root, file, directory)
+     */
+    protected void setPropertyType(byte propertyType)
+    {
+        _property_type.set(propertyType, _raw_data);
+    }
+
+    /**
+     * Set the node color.
+     *
+     * @param nodeColor the node color (red or black)
+     */
+    protected void setNodeColor(byte nodeColor)
+    {
+        _node_color.set(nodeColor, _raw_data);
+    }
+
+    /**
+     * Set the child property.
+     *
+     * @param child the child property's index in the Property Table
+     */
+    protected void setChildProperty(int child)
+    {
+        _child_property.set(child, _raw_data);
+    }
+
+    /**
+     * Get the child property (its index in the Property Table)
+     *
+     * @return child property index
+     */
+    protected int getChildIndex()
+    {
+        return _child_property.get();
+    }
+
+    /**
+     * Set the size of the document associated with this Property
+     *
+     * @param size the size of the document, in bytes
+     */
+    protected void setSize(int size)
+    {
+        _size.set(size, _raw_data);
+    }
+
+    /**
+     * get the index for this Property
+     *
+     * @return the index of this Property within its Property Table
+     */
+    protected int getIndex()
+    {
+        return _index;
+    }
+
+    /**
+     * Perform whatever activities need to be performed prior to
+     * writing
+     */
+    abstract protected void preWrite();
+
+    /**
+     * get the next sibling
+     *
+     * @return index of next sibling
+     */
+    int getNextChildIndex()
+    {
+        return _next_property.get();
+    }
+
+    /**
+     * get the previous sibling
+     *
+     * @return index of previous sibling
+     */
+    int getPreviousChildIndex()
+    {
+        return _previous_property.get();
+    }
+
+    /**
+     * determine whether the specified index is valid
+     *
+     * @param index value to be checked
+     *
+     * @return true if the index is valid
+     */
+    static boolean isValidIndex(int index)
+    {
+        return index != _NO_INDEX;
+    }
+
+    /**
+     * Set the next Child
+     *
+     * @param child the new 'next' child; may be null, which has the
+     *              effect of saying there is no 'next' child
+     */
+    public void setNextChild(Child child)
+    {
+        _next_property.set((child == null) ? _NO_INDEX
+                                           : (( Property ) child)
+                                               .getIndex(), _raw_data);
+    }
+
+    /**
+     * Set the previous Child
+     *
+     * @param child the new 'previous' child; may be null, which has
+     *              the effect of saying there is no 'previous' child
+     */
+    public void setPreviousChild(Child child)
+    {
+        _previous_property.set((child == null) ? _NO_INDEX
+                                               : (( Property ) child)
+                                                   .getIndex(), _raw_data);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/PropertyConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/PropertyConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/PropertyConstants.java	(revision 28000)
@@ -0,0 +1,35 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.property;
+
+/**
+ * Interface PropertyConstants
+ */
+
+public interface PropertyConstants
+{
+    public static final int  PROPERTY_TYPE_OFFSET = 0x42;
+
+    // the property types
+    public static final byte DIRECTORY_TYPE       = 1;
+    public static final byte DOCUMENT_TYPE        = 2;
+    public static final byte ROOT_TYPE            = 5;
+}   // end public interface PropertyConstants
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/PropertyFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/PropertyFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/PropertyFactory.java	(revision 28000)
@@ -0,0 +1,103 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.property;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.poifs.storage.ListManagedBlock;
+
+/**
+ * Factory for turning an array of RawDataBlock instances containing
+ * Proprty data into an array of proper Property objects.
+ *
+ * The array produced may be sparse, in that any portion of data that
+ * should correspond to a Property, but which does not map to a proper
+ * Property (i.e., a DirectoryProperty, DocumentProperty, or
+ * RootProperty) will get mapped to a null Property in the array.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+class PropertyFactory
+{
+
+    // no need for an accessible constructor
+    private PropertyFactory()
+    {
+    }
+
+    /**
+     * Convert raw data blocks to an array of Property's
+     *
+     * @param blocks to be converted
+     *
+     * @return the converted List of Property objects. May contain
+     *         nulls, but will not be null
+     *
+     * @exception IOException if any of the blocks are empty
+     */
+
+    static List<Property> convertToProperties(ListManagedBlock [] blocks)
+        throws IOException
+    {
+        List<Property> properties = new ArrayList<Property>();
+
+        for (int j = 0; j < blocks.length; j++)
+        {
+            byte[] data           = blocks[ j ].getData();
+            int    property_count = data.length
+                                    / POIFSConstants.PROPERTY_SIZE;
+            int    offset         = 0;
+
+            for (int k = 0; k < property_count; k++)
+            {
+                switch (data[ offset + PropertyConstants.PROPERTY_TYPE_OFFSET ])
+                {
+
+                    case PropertyConstants.DIRECTORY_TYPE :
+                        properties
+                            .add(new DirectoryProperty(properties.size(),
+                                                       data, offset));
+                        break;
+
+                    case PropertyConstants.DOCUMENT_TYPE :
+                        properties.add(new DocumentProperty(properties.size(),
+                                                            data, offset));
+                        break;
+
+                    case PropertyConstants.ROOT_TYPE :
+                        properties.add(new RootProperty(properties.size(),
+                                                        data, offset));
+                        break;
+
+                    default :
+                        properties.add(null);
+                        break;
+                }
+                offset += POIFSConstants.PROPERTY_SIZE;
+            }
+        }
+        return properties;
+    }
+}   // end package scope class PropertyFactory
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/PropertyTable.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/PropertyTable.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/PropertyTable.java	(revision 28000)
@@ -0,0 +1,158 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.property;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.poi.poifs.storage.BlockWritable;
+import org.apache.poi.poifs.storage.RawDataBlockList;
+
+/**
+ * This class embodies the Property Table for the filesystem; this is
+ * basically the dsirectory for all of the documents in the
+ * filesystem.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+public final class PropertyTable implements BlockWritable {
+    private List<Property>    _properties;
+    private BlockWritable[]   _blocks;
+
+    public PropertyTable()
+    {
+        _properties  = new ArrayList<Property>();
+        addProperty(new RootProperty());
+        _blocks = null;
+    }
+
+    /**
+     * reading constructor (used when we've read in a file and we want
+     * to extract the property table from it). Populates the
+     * properties thoroughly
+     *
+     * @param startBlock the first block of the property table
+     * @param blockList the list of blocks
+     *
+     * @exception IOException if anything goes wrong (which should be
+     *            a result of the input being NFG)
+     */
+    public PropertyTable(
+                         final int startBlock,
+                         final RawDataBlockList blockList)
+        throws IOException
+    {
+        _blocks      = null;
+        _properties  =
+            PropertyFactory
+                .convertToProperties(blockList.fetchBlocks(startBlock, -1));
+        populatePropertyTree(( DirectoryProperty ) _properties.get(0));
+    }
+
+    /**
+     * Add a property to the list of properties we manage
+     *
+     * @param property the new Property to manage
+     */
+    public void addProperty(Property property)
+    {
+        _properties.add(property);
+    }
+
+    /**
+     * Remove a property from the list of properties we manage
+     *
+     * @param property the Property to be removed
+     */
+    public void removeProperty(final Property property)
+    {
+        _properties.remove(property);
+    }
+
+    /**
+     * Get the root property
+     *
+     * @return the root property
+     */
+    public RootProperty getRoot()
+    {
+
+        // it's always the first element in the List
+        return ( RootProperty ) _properties.get(0);
+    }
+
+    private void populatePropertyTree(DirectoryProperty root)
+        throws IOException
+    {
+        int index = root.getChildIndex();
+
+        if (!Property.isValidIndex(index))
+        {
+
+            // property has no children
+            return;
+        }
+        Stack<Property> children = new Stack<Property>();
+
+        children.push(_properties.get(index));
+        while (!children.empty())
+        {
+            Property property = children.pop();
+
+            root.addChild(property);
+            if (property.isDirectory())
+            {
+                populatePropertyTree(( DirectoryProperty ) property);
+            }
+            index = property.getPreviousChildIndex();
+            if (Property.isValidIndex(index))
+            {
+                children.push(_properties.get(index));
+            }
+            index = property.getNextChildIndex();
+            if (Property.isValidIndex(index))
+            {
+                children.push(_properties.get(index));
+            }
+        }
+    }
+
+    /**
+     * Write the storage to an OutputStream
+     *
+     * @param stream the OutputStream to which the stored data should
+     *               be written
+     *
+     * @exception IOException on problems writing to the specified
+     *            stream
+     */
+    public void writeBlocks(final OutputStream stream)
+        throws IOException
+    {
+        if (_blocks != null)
+        {
+            for (int j = 0; j < _blocks.length; j++)
+            {
+                _blocks[ j ].writeBlocks(stream);
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/RootProperty.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/RootProperty.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/RootProperty.java	(revision 28000)
@@ -0,0 +1,62 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.property;
+
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.poifs.storage.SmallDocumentBlock;
+
+/**
+ * Root property
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+public final class RootProperty extends DirectoryProperty {
+
+    RootProperty()
+    {
+        super("Root Entry");
+
+        // overrides
+        setNodeColor(_NODE_BLACK);
+        setPropertyType(PropertyConstants.ROOT_TYPE);
+        setStartBlock(POIFSConstants.END_OF_CHAIN);
+    }
+
+    /**
+     * reader constructor
+     *
+     * @param index index number
+     * @param array byte data
+     * @param offset offset into byte data
+     */
+    protected RootProperty(final int index, final byte [] array,
+                           final int offset)
+    {
+        super(index, array, offset);
+    }
+
+    /**
+     * set size
+     *
+     * @param size size in terms of small blocks
+     */
+    public void setSize(int size)
+    {
+        super.setSize(SmallDocumentBlock.calcSize(size));
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/property/package.html	(revision 28000)
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+property package contains high and low level Property structures for POIFS.
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+@see org.apache.poi.poifs.filesystem
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BigBlock.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BigBlock.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BigBlock.java	(revision 28000)
@@ -0,0 +1,103 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+/**
+ * Abstract base class of all POIFS block storage classes. All
+ * extensions of BigBlock should write 512 bytes of data when
+ * requested to write their data.
+ *
+ * This class has package scope, as there is no reason at this time to
+ * make the class public.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
+import org.apache.poi.poifs.common.POIFSConstants;
+
+abstract class BigBlock
+    implements BlockWritable
+{
+    /** 
+     * Either 512 bytes ({@link POIFSConstants#SMALLER_BIG_BLOCK_SIZE}) 
+     *  or 4096 bytes ({@link POIFSConstants#LARGER_BIG_BLOCK_SIZE})
+     */
+    protected POIFSBigBlockSize bigBlockSize;
+    
+    protected BigBlock(POIFSBigBlockSize bigBlockSize) {
+       this.bigBlockSize = bigBlockSize;
+    }
+
+    /**
+     * Default implementation of write for extending classes that
+     * contain their data in a simple array of bytes.
+     *
+     * @param stream the OutputStream to which the data should be
+     *               written.
+     * @param data the byte array of to be written.
+     *
+     * @exception IOException on problems writing to the specified
+     *            stream.
+     */
+
+    protected void doWriteData(final OutputStream stream, final byte [] data)
+        throws IOException
+    {
+        stream.write(data);
+    }
+
+    /**
+     * Write the block's data to an OutputStream
+     *
+     * @param stream the OutputStream to which the stored data should
+     *               be written
+     *
+     * @exception IOException on problems writing to the specified
+     *            stream
+     */
+
+    abstract void writeData(final OutputStream stream)
+        throws IOException;
+
+    /* ********** START implementation of BlockWritable ********** */
+
+    /**
+     * Write the storage to an OutputStream
+     *
+     * @param stream the OutputStream to which the stored data should
+     *               be written
+     *
+     * @exception IOException on problems writing to the specified
+     *            stream
+     */
+
+    public void writeBlocks(final OutputStream stream)
+        throws IOException
+    {
+        writeData(stream);
+    }
+
+    /* **********  END  implementation of BlockWritable ********** */
+}   // end abstract class BigBlock
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BlockAllocationTableReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BlockAllocationTableReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BlockAllocationTableReader.java	(revision 28000)
@@ -0,0 +1,275 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.util.IntList;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianConsts;
+
+/**
+ * This class manages and creates the Block Allocation Table, which is
+ * basically a set of linked lists of block indices.
+ * <P>
+ * Each block of the filesystem has an index. The first block, the
+ * header, is skipped; the first block after the header is index 0,
+ * the next is index 1, and so on.
+ * <P>
+ * A block's index is also its index into the Block Allocation
+ * Table. The entry that it finds in the Block Allocation Table is the
+ * index of the next block in the linked list of blocks making up a
+ * file, or it is set to -2: end of list.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+public final class BlockAllocationTableReader {
+    
+    /**
+     * Maximum number size (in blocks) of the allocation table as supported by
+     * POI.<br/>
+     *
+     * This constant has been chosen to help POI identify corrupted data in the
+     * header block (rather than crash immediately with {@link OutOfMemoryError}
+     * ). It's not clear if the compound document format actually specifies any
+     * upper limits. For files with 512 byte blocks, having an allocation table
+     * of 65,335 blocks would correspond to a total file size of 4GB. Needless
+     * to say, POI probably cannot handle files anywhere near that size.
+     */
+    private static final int MAX_BLOCK_COUNT = 65535;
+    private final IntList _entries;
+    private POIFSBigBlockSize bigBlockSize;
+
+    /**
+     * create a BlockAllocationTableReader for an existing filesystem. Side
+     * effect: when this method finishes, the BAT blocks will have
+     * been removed from the raw block list, and any blocks labeled as
+     * 'unused' in the block allocation table will also have been
+     * removed from the raw block list.
+     *
+     * @param block_count the number of BAT blocks making up the block
+     *                    allocation table
+     * @param block_array the array of BAT block indices from the
+     *                    filesystem's header
+     * @param xbat_count the number of XBAT blocks
+     * @param xbat_index the index of the first XBAT block
+     * @param raw_block_list the list of RawDataBlocks
+     *
+     * @exception IOException if, in trying to create the table, we
+     *            encounter logic errors
+     */
+    public BlockAllocationTableReader(POIFSBigBlockSize bigBlockSize, int block_count, int [] block_array,
+            int xbat_count, int xbat_index, BlockList raw_block_list) throws IOException {
+        this(bigBlockSize);
+        
+        if (block_count <= 0) {
+            throw new IOException(
+                "Illegal block count; minimum count is 1, got " + block_count
+                + " instead");
+        }
+
+        if (block_count > MAX_BLOCK_COUNT) {
+            throw new IOException("Block count " + block_count 
+                    + " is too high. POI maximum is " + MAX_BLOCK_COUNT + ".");
+        }
+
+        // We want to get the whole of the FAT table
+        // To do this:
+        //  * Work through raw_block_list, which points to the 
+        //     first (up to) 109 BAT blocks
+        //  * Jump to the XBAT offset, and read in XBATs which
+        //     point to more BAT blocks
+        int          limit    = Math.min(block_count, block_array.length);
+        int          block_index;
+        
+        // This will hold all of the BAT blocks in order
+        RawDataBlock blocks[] = new RawDataBlock[ block_count ];
+
+        // Process the first (up to) 109 BAT blocks
+        for (block_index = 0; block_index < limit; block_index++)
+        {
+            // Check that the sector number of the BAT block is a valid one
+            int nextOffset = block_array[ block_index ];
+            if(nextOffset > raw_block_list.blockCount()) {
+               throw new IOException("Your file contains " + raw_block_list.blockCount() + 
+                     " sectors, but the initial DIFAT array at index " + block_index +
+                     " referenced block # " + nextOffset + ". This isn't allowed and " +
+                     " your file is corrupt");
+            }
+            // Record the sector number of this BAT block 
+            blocks[ block_index ] =
+                ( RawDataBlock ) raw_block_list.remove(nextOffset);
+        }
+        
+        // Process additional BAT blocks via the XBATs
+        if (block_index < block_count)
+        {
+
+            // must have extended blocks
+            if (xbat_index < 0)
+            {
+                throw new IOException(
+                    "BAT count exceeds limit, yet XBAT index indicates no valid entries");
+            }
+            int chain_index           = xbat_index;
+            int max_entries_per_block = bigBlockSize.getXBATEntriesPerBlock(); 
+            int chain_index_offset    = bigBlockSize.getNextXBATChainOffset(); 
+
+            // Each XBAT block contains either:
+            //  (maximum number of sector indexes) + index of next XBAT
+            //  some sector indexes + FREE sectors to max # + EndOfChain
+            for (int j = 0; j < xbat_count; j++)
+            {
+                limit = Math.min(block_count - block_index,
+                                 max_entries_per_block);
+                byte[] data   = raw_block_list.remove(chain_index).getData();
+                int    offset = 0;
+
+                for (int k = 0; k < limit; k++)
+                {
+                    blocks[ block_index++ ] =
+                        ( RawDataBlock ) raw_block_list
+                            .remove(LittleEndian.getInt(data, offset));
+                    offset                  += LittleEndianConsts.INT_SIZE;
+                }
+                chain_index = LittleEndian.getInt(data, chain_index_offset);
+                if (chain_index == POIFSConstants.END_OF_CHAIN)
+                {
+                    break;
+                }
+            }
+        }
+        if (block_index != block_count)
+        {
+            throw new IOException("Could not find all blocks");
+        }
+
+        // Now that we have all of the raw data blocks which make
+        //  up the FAT, go through and create the indices
+        setEntries(blocks, raw_block_list);
+    }
+
+    /**
+     * create a BlockAllocationTableReader from an array of raw data blocks
+     *
+     * @param blocks the raw data
+     * @param raw_block_list the list holding the managed blocks
+     *
+     * @exception IOException
+     */
+    BlockAllocationTableReader(POIFSBigBlockSize bigBlockSize, ListManagedBlock[] blocks, BlockList raw_block_list)
+            throws IOException {
+        this(bigBlockSize);
+        setEntries(blocks, raw_block_list);
+    }
+
+    BlockAllocationTableReader(POIFSBigBlockSize bigBlockSize) {
+        this.bigBlockSize = bigBlockSize;
+        _entries = new IntList();
+    }
+
+    /**
+     * walk the entries from a specified point and return the
+     * associated blocks. The associated blocks are removed from the
+     * block list
+     *
+     * @param startBlock the first block in the chain
+     * @param blockList the raw data block list
+     *
+     * @return array of ListManagedBlocks, in their correct order
+     *
+     * @exception IOException if there is a problem acquiring the blocks
+     */
+    ListManagedBlock[] fetchBlocks(int startBlock, int headerPropertiesStartBlock,
+            BlockList blockList) throws IOException {
+        List<ListManagedBlock> blocks = new ArrayList<ListManagedBlock>();
+        int  currentBlock = startBlock;
+        boolean firstPass = true;
+        ListManagedBlock dataBlock = null;
+
+        // Process the chain from the start to the end
+        // Normally we have header, data, end
+        // Sometimes we have data, header, end
+        // For those cases, stop at the header, not the end
+        while (currentBlock != POIFSConstants.END_OF_CHAIN) {
+            try {
+                // Grab the data at the current block offset
+                dataBlock = blockList.remove(currentBlock);
+                blocks.add(dataBlock);
+                // Now figure out which block we go to next
+                currentBlock = _entries.get(currentBlock);
+                firstPass = false;
+            } catch(IOException e) {
+                if(currentBlock == headerPropertiesStartBlock) {
+                    // Special case where things are in the wrong order
+                    System.err.println("Warning, header block comes after data blocks in POIFS block listing");
+                    currentBlock = POIFSConstants.END_OF_CHAIN;
+                } else if(currentBlock == 0 && firstPass) {
+                    // Special case where the termination isn't done right
+                    //  on an empty set
+                    System.err.println("Warning, incorrectly terminated empty data blocks in POIFS block listing (should end at -2, ended at 0)");
+                    currentBlock = POIFSConstants.END_OF_CHAIN;
+                } else {
+                    // Ripple up
+                    throw e;
+                }
+            }
+        }
+
+        return blocks.toArray(new ListManagedBlock[blocks.size()]);
+    }
+
+    // methods for debugging reader
+
+    /**
+     * Convert an array of blocks into a set of integer indices
+     *
+     * @param blocks the array of blocks containing the indices
+     * @param raw_blocks the list of blocks being managed. Unused
+     *                   blocks will be eliminated from the list
+     */
+    private void setEntries(ListManagedBlock[] blocks, BlockList raw_blocks) throws IOException {
+        int limit = bigBlockSize.getBATEntriesPerBlock(); 
+
+        for (int block_index = 0; block_index < blocks.length; block_index++)
+        {
+            byte[] data   = blocks[ block_index ].getData();
+            int    offset = 0;
+
+            for (int k = 0; k < limit; k++)
+            {
+                int entry = LittleEndian.getInt(data, offset);
+
+                if (entry == POIFSConstants.UNUSED_BLOCK)
+                {
+                    raw_blocks.zap(_entries.size());
+                }
+                _entries.add(entry);
+                offset += LittleEndianConsts.INT_SIZE;
+            }
+
+            // discard block
+            blocks[ block_index ] = null;
+        }
+        raw_blocks.setBAT(this);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BlockList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BlockList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BlockList.java	(revision 28000)
@@ -0,0 +1,85 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+import java.io.IOException;
+
+/**
+ * Interface for lists of blocks that are mapped by block allocation
+ * tables
+ *
+ * @author Marc Johnson (mjohnson at apache dot org
+ */
+
+public interface BlockList
+{
+
+    /**
+     * remove the specified block from the list
+     *
+     * @param index the index of the specified block; if the index is
+     *              out of range, that's ok
+     */
+
+    public void zap(final int index);
+
+    /**
+     * remove and return the specified block from the list
+     *
+     * @param index the index of the specified block
+     *
+     * @return the specified block
+     *
+     * @exception IOException if the index is out of range or has
+     *            already been removed
+     */
+
+    public ListManagedBlock remove(final int index)
+        throws IOException;
+
+    /**
+     * get the blocks making up a particular stream in the list. The
+     * blocks are removed from the list.
+     *
+     * @param startBlock the index of the first block in the stream
+     * @param headerPropertiesStartBlock the index of the first header block in the stream
+     *
+     * @return the stream as an array of correctly ordered blocks
+     *
+     * @exception IOException if blocks are missing
+     */
+
+    public ListManagedBlock [] fetchBlocks(final int startBlock, final int headerPropertiesStartBlock)
+        throws IOException;
+
+    /**
+     * set the associated BlockAllocationTable
+     *
+     * @param bat the associated BlockAllocationTable
+     *
+     * @exception IOException
+     */
+
+    public void setBAT(final BlockAllocationTableReader bat)
+        throws IOException;
+    
+    public int blockCount();
+}   // end public interface BlockList
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BlockListImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BlockListImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BlockListImpl.java	(revision 28000)
@@ -0,0 +1,142 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+import java.io.IOException;
+
+/**
+ * A simple implementation of BlockList
+ *
+ * @author Marc Johnson (mjohnson at apache dot org
+ */
+abstract class BlockListImpl implements BlockList {
+    private ListManagedBlock[]         _blocks;
+    private BlockAllocationTableReader _bat;
+
+    protected BlockListImpl()
+    {
+        _blocks = new ListManagedBlock[ 0 ];
+        _bat    = null;
+    }
+
+    /**
+     * provide blocks to manage
+     *
+     * @param blocks blocks to be managed
+     */
+    protected void setBlocks(final ListManagedBlock [] blocks)
+    {
+        _blocks = blocks;
+    }
+
+    /**
+     * remove the specified block from the list
+     *
+     * @param index the index of the specified block; if the index is
+     *              out of range, that's ok
+     */
+    public void zap(final int index)
+    {
+        if ((index >= 0) && (index < _blocks.length))
+        {
+            _blocks[ index ] = null;
+        }
+    }
+
+
+    /**
+     * remove and return the specified block from the list
+     *
+     * @param index the index of the specified block
+     *
+     * @return the specified block
+     *
+     * @exception IOException if the index is out of range or has
+     *            already been removed
+     */
+    public ListManagedBlock remove(final int index)
+        throws IOException
+    {
+        ListManagedBlock result = null;
+
+        try
+        {
+            result = _blocks[ index ];
+            if (result == null)
+            {
+                throw new IOException(
+                		"block[ " + index + " ] already removed - " +
+                		"does your POIFS have circular or duplicate block references?"
+                );
+            }
+            _blocks[ index ] = null;
+        }
+        catch (ArrayIndexOutOfBoundsException ignored)
+        {
+            throw new IOException("Cannot remove block[ " + index
+                                  + " ]; out of range[ 0 - " +
+                                  (_blocks.length-1) + " ]");
+        }
+        return result;
+    }
+
+    /**
+     * get the blocks making up a particular stream in the list. The
+     * blocks are removed from the list.
+     *
+     * @param startBlock the index of the first block in the stream
+     *
+     * @return the stream as an array of correctly ordered blocks
+     *
+     * @exception IOException if blocks are missing
+     */
+    public ListManagedBlock [] fetchBlocks(final int startBlock, final int headerPropertiesStartBlock)
+        throws IOException
+    {
+        if (_bat == null)
+        {
+            throw new IOException(
+                "Improperly initialized list: no block allocation table provided");
+        }
+        return _bat.fetchBlocks(startBlock, headerPropertiesStartBlock, this);
+    }
+
+    /**
+     * set the associated BlockAllocationTable
+     *
+     * @param bat the associated BlockAllocationTable
+     */
+    public void setBAT(final BlockAllocationTableReader bat)
+        throws IOException
+    {
+        if (_bat != null)
+        {
+            throw new IOException(
+                "Attempt to replace existing BlockAllocationTable");
+        }
+        _bat = bat;
+    }
+    
+    /**
+     * Returns the count of the number of blocks
+     */
+    public int blockCount() {
+       return _blocks.length;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BlockWritable.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BlockWritable.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/BlockWritable.java	(revision 28000)
@@ -0,0 +1,47 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * An interface for persisting block storage of POIFS components.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+public interface BlockWritable
+{
+
+    /**
+     * Write the storage to an OutputStream
+     *
+     * @param stream the OutputStream to which the stored data should
+     *               be written
+     *
+     * @exception IOException on problems writing to the specified
+     *            stream
+     */
+
+    public void writeBlocks(final OutputStream stream)
+        throws IOException;
+}   // end public interface BlockWritable
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/DataInputBlock.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/DataInputBlock.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/DataInputBlock.java	(revision 28000)
@@ -0,0 +1,186 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+/**
+ * Wraps a <tt>byte</tt> array and provides simple data input access.
+ * Internally, this class maintains a buffer read index, so that for the most part, primitive
+ * data can be read in a data-input-stream-like manner.<p/>
+ *
+ * Note - the calling class should call the {@link #available()} method to detect end-of-buffer
+ * and move to the next data block when the current is exhausted.
+ * For optimisation reasons, no error handling is performed in this class.  Thus, mistakes in
+ * calling code ran may raise ugly exceptions here, like {@link ArrayIndexOutOfBoundsException},
+ * etc .<p/>
+ *
+ * The multi-byte primitive input methods ({@link #readUShortLE()}, {@link #readIntLE()} and
+ * {@link #readLongLE()}) have corresponding 'spanning read' methods which (when required) perform
+ * a read across the block boundary.  These spanning read methods take the previous
+ * {@link DataInputBlock} as a parameter.
+ * Reads of larger amounts of data (into <tt>byte</tt> array buffers) must be managed by the caller
+ * since these could conceivably involve more than two blocks.
+ *
+ * @author Josh Micich
+ */
+public final class DataInputBlock {
+
+	/**
+	 * Possibly any size (usually 512K or 64K).  Assumed to be at least 8 bytes for all blocks
+	 * before the end of the stream.  The last block in the stream can be any size except zero. 
+	 */
+	private final byte[] _buf;
+	private int _readIndex;
+	private int _maxIndex;
+
+	DataInputBlock(byte[] data, int startOffset) {
+		_buf = data;
+		_readIndex = startOffset;
+		_maxIndex = _buf.length;
+	}
+	public int available() {
+		return _maxIndex-_readIndex;
+	}
+
+	public int readUByte() {
+		return _buf[_readIndex++] & 0xFF;
+	}
+
+	/**
+	 * Reads a <tt>short</tt> which was encoded in <em>little endian</em> format.
+	 */
+	public int readUShortLE() {
+		int i = _readIndex;
+		
+		int b0 = _buf[i++] & 0xFF;
+		int b1 = _buf[i++] & 0xFF;
+		_readIndex = i;
+		return (b1 << 8) + (b0 << 0);
+	}
+
+	/**
+	 * Reads a <tt>short</tt> which spans the end of <tt>prevBlock</tt> and the start of this block.
+	 */
+	public int readUShortLE(DataInputBlock prevBlock) {
+		// simple case - will always be one byte in each block
+		int i = prevBlock._buf.length-1;
+		
+		int b0 = prevBlock._buf[i++] & 0xFF;
+		int b1 = _buf[_readIndex++] & 0xFF;
+		return (b1 << 8) + (b0 << 0);
+	}
+
+	/**
+	 * Reads an <tt>int</tt> which was encoded in <em>little endian</em> format.
+	 */
+	public int readIntLE() {
+		int i = _readIndex;
+		
+		int b0 = _buf[i++] & 0xFF;
+		int b1 = _buf[i++] & 0xFF;
+		int b2 = _buf[i++] & 0xFF;
+		int b3 = _buf[i++] & 0xFF;
+		_readIndex = i;
+		return (b3 << 24) + (b2 << 16) + (b1 << 8) + (b0 << 0);
+	}
+
+	/**
+	 * Reads an <tt>int</tt> which spans the end of <tt>prevBlock</tt> and the start of this block.
+	 */
+	public int readIntLE(DataInputBlock prevBlock, int prevBlockAvailable) {
+		byte[] buf = new byte[4];
+		
+		readSpanning(prevBlock, prevBlockAvailable, buf);
+		int b0 = buf[0] & 0xFF;
+		int b1 = buf[1] & 0xFF;
+		int b2 = buf[2] & 0xFF;
+		int b3 = buf[3] & 0xFF;
+		return (b3 << 24) + (b2 << 16) + (b1 << 8) + (b0 << 0);
+	}
+
+	/**
+	 * Reads a <tt>long</tt> which was encoded in <em>little endian</em> format.
+	 */
+	public long readLongLE() {
+		int i = _readIndex;
+		
+		int b0 = _buf[i++] & 0xFF;
+		int b1 = _buf[i++] & 0xFF;
+		int b2 = _buf[i++] & 0xFF;
+		int b3 = _buf[i++] & 0xFF;
+		int b4 = _buf[i++] & 0xFF;
+		int b5 = _buf[i++] & 0xFF;
+		int b6 = _buf[i++] & 0xFF;
+		int b7 = _buf[i++] & 0xFF;
+		_readIndex = i;
+		return (((long)b7 << 56) +
+				((long)b6 << 48) +
+				((long)b5 << 40) +
+				((long)b4 << 32) +
+				((long)b3 << 24) +
+				(b2 << 16) +
+				(b1 <<  8) +
+				(b0 <<  0));
+	}
+
+	/**
+	 * Reads a <tt>long</tt> which spans the end of <tt>prevBlock</tt> and the start of this block.
+	 */
+	public long readLongLE(DataInputBlock prevBlock, int prevBlockAvailable) {
+		byte[] buf = new byte[8];
+		
+		readSpanning(prevBlock, prevBlockAvailable, buf);
+		
+		int b0 = buf[0] & 0xFF;
+		int b1 = buf[1] & 0xFF;
+		int b2 = buf[2] & 0xFF;
+		int b3 = buf[3] & 0xFF;
+		int b4 = buf[4] & 0xFF;
+		int b5 = buf[5] & 0xFF;
+		int b6 = buf[6] & 0xFF;
+		int b7 = buf[7] & 0xFF;
+		return (((long)b7 << 56) +
+				((long)b6 << 48) +
+				((long)b5 << 40) +
+				((long)b4 << 32) +
+				((long)b3 << 24) +
+				(b2 << 16) +
+				(b1 <<  8) +
+				(b0 <<  0));
+	}
+
+	/**
+	 * Reads a small amount of data from across the boundary between two blocks.  
+	 * The {@link #_readIndex} of this (the second) block is updated accordingly.
+	 * Note- this method (and other code) assumes that the second {@link DataInputBlock}
+	 * always is big enough to complete the read without being exhausted.
+	 */
+	private void readSpanning(DataInputBlock prevBlock, int prevBlockAvailable, byte[] buf) {
+		System.arraycopy(prevBlock._buf, prevBlock._readIndex, buf, 0, prevBlockAvailable);
+		int secondReadLen = buf.length-prevBlockAvailable;
+		System.arraycopy(_buf, 0, buf, prevBlockAvailable, secondReadLen);
+		_readIndex = secondReadLen;
+	}
+
+	/**
+	 * Reads <tt>len</tt> bytes from this block into the supplied buffer.
+	 */
+	public void readFully(byte[] buf, int off, int len) {
+		System.arraycopy(_buf, _readIndex, buf, off, len);
+		_readIndex += len;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/DocumentBlock.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/DocumentBlock.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/DocumentBlock.java	(revision 28000)
@@ -0,0 +1,148 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.util.IOUtils;
+
+/**
+ * A block of document data.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+public final class DocumentBlock extends BigBlock {
+    private static final byte _default_value = ( byte ) 0xFF;
+    private byte[]            _data;
+    private int               _bytes_read;
+
+    /**
+     * create a document block from a raw data block
+     *
+     * @param block the raw data block
+     *
+     * @exception IOException
+     */
+
+    public DocumentBlock(final RawDataBlock block)
+        throws IOException
+    {
+        super(
+              block.getBigBlockSize() == POIFSConstants.SMALLER_BIG_BLOCK_SIZE ?
+                    POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS :
+                    POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS
+        );
+        _data       = block.getData();
+        _bytes_read = _data.length;
+    }
+
+    /**
+     * Create a single instance initialized with data.
+     *
+     * @param stream the InputStream delivering the data.
+     *
+     * @exception IOException
+     */
+
+    public DocumentBlock(final InputStream stream, POIFSBigBlockSize bigBlockSize)
+        throws IOException
+    {
+        this(bigBlockSize);
+        int count = IOUtils.readFully(stream, _data);
+
+        _bytes_read = (count == -1) ? 0
+                                    : count;
+    }
+
+    /**
+     * Create a single instance initialized with default values
+     */
+
+    private DocumentBlock(POIFSBigBlockSize bigBlockSize)
+    {
+        super(bigBlockSize);
+        _data = new byte[ bigBlockSize.getBigBlockSize() ];
+        Arrays.fill(_data, _default_value);
+    }
+
+    /**
+     * Get the number of bytes read for this block
+     *
+     * @return bytes read into the block
+     */
+
+    public int size()
+    {
+        return _bytes_read;
+    }
+
+    /**
+     * Was this a partially read block?
+     *
+     * @return true if the block was only partially filled with data
+     */
+
+    public boolean partiallyRead()
+    {
+        return _bytes_read != bigBlockSize.getBigBlockSize();
+    }
+
+
+    public static DataInputBlock getDataInputBlock(DocumentBlock[] blocks, int offset) {
+        if(blocks == null || blocks.length == 0) {
+           return null;
+        }
+        
+        // Key things about the size of the block
+        POIFSBigBlockSize bigBlockSize = blocks[0].bigBlockSize;
+        int BLOCK_SHIFT = bigBlockSize.getHeaderValue();
+        int BLOCK_SIZE = bigBlockSize.getBigBlockSize();
+        int BLOCK_MASK = BLOCK_SIZE - 1;
+
+        // Now do the offset lookup
+        int firstBlockIndex = offset >> BLOCK_SHIFT;
+        int firstBlockOffset= offset & BLOCK_MASK;
+        return new DataInputBlock(blocks[firstBlockIndex]._data, firstBlockOffset);
+    }
+
+    /* ********** START extension of BigBlock ********** */
+
+    /**
+     * Write the block's data to an OutputStream
+     *
+     * @param stream the OutputStream to which the stored data should
+     *               be written
+     *
+     * @exception IOException on problems writing to the specified
+     *            stream
+     */
+
+    void writeData(final OutputStream stream)
+        throws IOException
+    {
+        doWriteData(stream, _data);
+    }
+
+    /* **********  END  extension of BigBlock ********** */
+}   // end public class DocumentBlock
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/HeaderBlockConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/HeaderBlockConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/HeaderBlockConstants.java	(revision 28000)
@@ -0,0 +1,49 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.util.LittleEndianConsts;
+
+/**
+ * Constants used in reading/writing the Header block
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+public interface HeaderBlockConstants
+{
+    public static final long _signature               = 0xE11AB1A1E011CFD0L;
+    public static final int  _bat_array_offset        = 0x4c;
+    public static final int  _max_bats_in_header      =
+        (POIFSConstants.SMALLER_BIG_BLOCK_SIZE - _bat_array_offset)
+        / LittleEndianConsts.INT_SIZE; // If 4k blocks, rest is blank
+
+    // Note - in Microsoft terms:
+    //  BAT ~= FAT
+    //  SBAT ~= MiniFAT
+    //  XBAT ~= DIFat
+    
+    // useful offsets
+    public static final int  _signature_offset        = 0;
+    public static final int  _bat_count_offset        = 0x2C;
+    public static final int  _property_start_offset   = 0x30;
+    public static final int  _sbat_start_offset       = 0x3C;
+    public static final int  _xbat_start_offset       = 0x44;
+    public static final int  _xbat_count_offset       = 0x48;
+}   // end public interface HeaderBlockConstants
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/HeaderBlockReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/HeaderBlockReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/HeaderBlockReader.java	(revision 28000)
@@ -0,0 +1,235 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+import static org.apache.poi.poifs.storage.HeaderBlockConstants._bat_array_offset;
+import static org.apache.poi.poifs.storage.HeaderBlockConstants._bat_count_offset;
+import static org.apache.poi.poifs.storage.HeaderBlockConstants._max_bats_in_header;
+import static org.apache.poi.poifs.storage.HeaderBlockConstants._property_start_offset;
+import static org.apache.poi.poifs.storage.HeaderBlockConstants._sbat_start_offset;
+import static org.apache.poi.poifs.storage.HeaderBlockConstants._signature;
+import static org.apache.poi.poifs.storage.HeaderBlockConstants._signature_offset;
+import static org.apache.poi.poifs.storage.HeaderBlockConstants._xbat_count_offset;
+import static org.apache.poi.poifs.storage.HeaderBlockConstants._xbat_start_offset;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianConsts;
+
+/**
+ * The block containing the archive header
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+public final class HeaderBlockReader {
+	/**
+	 * What big block size the file uses. Most files
+	 *  use 512 bytes, but a few use 4096
+	 */
+	private final POIFSBigBlockSize bigBlockSize;
+
+	/** 
+	 * number of big block allocation table blocks (int).
+	 * (Number of FAT Sectors in Microsoft parlance) 
+	 */
+	private final int _bat_count;
+
+	/** 
+	 * Start of the property set block (int index of the property set
+	 * chain's first big block).
+	 */
+	private final int _property_start;
+
+	/** 
+	 * start of the small block allocation table (int index of small
+	 * block allocation table's first big block)
+	 */
+	private final int _sbat_start;
+
+
+	/** 
+	 * Big block index for extension to the big block allocation table
+	 */
+	private final int _xbat_start;
+	/**
+	 * Number of big block allocation table blocks (int)
+	 * (Number of DIFAT Sectors in Microsoft parlance)
+	 */
+	private final int _xbat_count;
+	private final byte[] _data;
+
+	/**
+	 * create a new HeaderBlockReader from an InputStream
+	 *
+	 * @param stream the source InputStream
+	 *
+	 * @exception IOException on errors or bad data
+	 */
+	public HeaderBlockReader(InputStream stream) throws IOException {
+		// At this point, we don't know how big our
+		//  block sizes are
+		// So, read the first 32 bytes to check, then
+		//  read the rest of the block
+		byte[] blockStart = new byte[32];
+		int bsCount = IOUtils.readFully(stream, blockStart);
+		if(bsCount != 32) {
+			throw alertShortRead(bsCount, 32);
+		}
+
+		// verify signature
+		long signature = LittleEndian.getLong(blockStart, _signature_offset);
+
+		if (signature != _signature) {
+			// Is it one of the usual suspects?
+			byte[] OOXML_FILE_HEADER = POIFSConstants.OOXML_FILE_HEADER;
+			if(blockStart[0] == OOXML_FILE_HEADER[0] &&
+				blockStart[1] == OOXML_FILE_HEADER[1] &&
+				blockStart[2] == OOXML_FILE_HEADER[2] &&
+				blockStart[3] == OOXML_FILE_HEADER[3]) {
+				throw new OfficeXmlFileException("The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)");
+			}
+			if ((signature & 0xFF8FFFFFFFFFFFFFL) == 0x0010000200040009L) {
+				// BIFF2 raw stream starts with BOF (sid=0x0009, size=0x0004, data=0x00t0)
+				throw new IllegalArgumentException("The supplied data appears to be in BIFF2 format.  "
+						+ "POI only supports BIFF8 format");
+			}
+
+			// Give a generic error
+			throw new IOException("Invalid header signature; read "
+				                  + longToHex(signature) + ", expected "
+				                  + longToHex(_signature));
+		}
+
+
+		// Figure out our block size
+		switch (blockStart[30]) {
+			case 12:
+				bigBlockSize = POIFSConstants.LARGER_BIG_BLOCK_SIZE_DETAILS; break;
+			case  9:
+				bigBlockSize = POIFSConstants.SMALLER_BIG_BLOCK_SIZE_DETAILS; break;
+			default:
+				throw new IOException("Unsupported blocksize  (2^"
+						+ blockStart[30] + "). Expected 2^9 or 2^12.");
+		}
+		_data = new byte[ bigBlockSize.getBigBlockSize() ];
+		System.arraycopy(blockStart, 0, _data, 0, blockStart.length);
+
+		// Now we can read the rest of our header
+		int byte_count = IOUtils.readFully(stream, _data, blockStart.length, _data.length - blockStart.length);
+		if (byte_count+bsCount != bigBlockSize.getBigBlockSize()) {
+			throw alertShortRead(byte_count, bigBlockSize.getBigBlockSize());
+		}
+
+		_bat_count      = getInt(_bat_count_offset, _data);
+		_property_start = getInt(_property_start_offset, _data);
+		_sbat_start     = getInt(_sbat_start_offset, _data);
+		_xbat_start     = getInt(_xbat_start_offset, _data);
+		_xbat_count     = getInt(_xbat_count_offset, _data);
+	}
+
+	private static int getInt(int offset, byte[] data) {
+		return LittleEndian.getInt(data, offset);
+	}
+
+	private static String longToHex(long value) {
+		return new String(HexDump.longToHex(value));
+	}
+
+	private static IOException alertShortRead(int pRead, int expectedReadSize) {
+		int read;
+		if (pRead < 0) {
+			//Can't have -1 bytes read in the error message!
+			read = 0;
+		} else {
+			read = pRead;
+		}
+		String type = " byte" + (read == 1 ? (""): ("s"));
+
+		return new IOException("Unable to read entire header; "
+				+ read + type + " read; expected "
+				+ expectedReadSize + " bytes");
+	}
+
+	/**
+	 * get start of Property Table
+	 *
+	 * @return the index of the first block of the Property Table
+	 */
+	public int getPropertyStart() {
+		return _property_start;
+	}
+
+	/**
+	 * @return start of small block (MiniFAT) allocation table
+	 */
+	public int getSBATStart() {
+		return _sbat_start;
+	}
+
+	/**
+	 * @return number of BAT blocks
+	 */
+	public int getBATCount() {
+		return _bat_count;
+	}
+
+	/**
+	 * Returns the offsets to the first (up to) 109
+	 *  BAT sectors.
+	 * Any additional BAT sectors 
+	 * @return BAT offset array
+	 */
+	public int[] getBATArray() {
+		int[] result = new int[ _max_bats_in_header ];
+		int   offset = _bat_array_offset;
+
+		for (int j = 0; j < _max_bats_in_header; j++) {
+			result[ j ] = LittleEndian.getInt(_data, offset);
+			offset      += LittleEndianConsts.INT_SIZE;
+		}
+		return result;
+	}
+
+	/**
+	 * @return XBAT (DIFAT) count
+	 */
+	public int getXBATCount() {
+		return _xbat_count;
+	}
+
+	/**
+	 * @return XBAT (DIFAT) index
+	 */
+	public int getXBATIndex() {
+		return _xbat_start;
+	}
+
+	/**
+	 * @return The Big Block size, normally 512 bytes, sometimes 4096 bytes
+	 */
+	public POIFSBigBlockSize getBigBlockSize() {
+		return bigBlockSize;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/ListManagedBlock.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/ListManagedBlock.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/ListManagedBlock.java	(revision 28000)
@@ -0,0 +1,45 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+import java.io.IOException;
+
+/**
+ * An interface for blocks managed by a list that works with a
+ * BlockAllocationTable to keep block sequences straight
+ *
+ * @author Marc Johnson (mjohnson at apache dot org
+ */
+
+public interface ListManagedBlock
+{
+
+    /**
+     * Get the data from the block
+     *
+     * @return the block's data as a byte array
+     *
+     * @exception IOException if there is no data
+     */
+
+    public byte [] getData()
+        throws IOException;
+}   // end public interface ListManagedBlock
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/RawDataBlock.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/RawDataBlock.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/RawDataBlock.java	(revision 28000)
@@ -0,0 +1,135 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * A big block created from an InputStream, holding the raw data
+ *
+ * @author Marc Johnson (mjohnson at apache dot org
+ */
+
+public class RawDataBlock
+    implements ListManagedBlock
+{
+    private byte[]  _data;
+    private boolean _eof;
+    private boolean _hasData;
+    private static POILogger log = POILogFactory.getLogger(RawDataBlock.class);
+
+    /**
+     * Constructor RawDataBlock
+     *
+     * @param stream the InputStream from which the data will be read
+     * @param blockSize the size of the POIFS blocks, normally 512 bytes
+     * {@link org.apache.poi.poifs.common.POIFSConstants#SMALLER_BIG_BLOCK_SIZE}
+     *
+     * @exception IOException on I/O errors, and if an insufficient
+     *            amount of data is read (the InputStream must
+     *            be an exact multiple of the block size)
+     */
+    public RawDataBlock(final InputStream stream, int blockSize)
+    		throws IOException {
+        _data = new byte[ blockSize ];
+        int count = IOUtils.readFully(stream, _data);
+        _hasData = (count > 0);
+
+        if (count == -1) {
+            _eof = true;
+        }
+        else if (count != blockSize) {
+        	// IOUtils.readFully will always read the
+        	//  requested number of bytes, unless it hits
+        	//  an EOF
+            _eof = true;
+            String type = " byte" + ((count == 1) ? ("")
+                                                  : ("s"));
+
+            log.log(POILogger.ERROR,
+            		"Unable to read entire block; " + count
+                     + type + " read before EOF; expected "
+                     + blockSize + " bytes. Your document "
+                     + "was either written by software that "
+                     + "ignores the spec, or has been truncated!"
+            );
+        }
+        else {
+            _eof = false;
+        }
+    }
+
+    /**
+     * When we read the data, did we hit end of file?
+     *
+     * @return true if the EoF was hit during this block, or
+     *  false if not. If you have a dodgy short last block, then
+     *  it's possible to both have data, and also hit EoF...
+     */
+    public boolean eof() {
+        return _eof;
+    }
+    /**
+     * Did we actually find any data to read? It's possible,
+     *  in the event of a short last block, to both have hit
+     *  the EoF, but also to have data
+     */
+    public boolean hasData() {
+    	return _hasData;
+    }
+    
+    public String toString() {
+       return "RawDataBlock of size " + _data.length; 
+    }
+
+    /* ********** START implementation of ListManagedBlock ********** */
+
+    /**
+     * Get the data from the block
+     *
+     * @return the block's data as a byte array
+     *
+     * @exception IOException if there is no data
+     */
+    public byte [] getData()
+        throws IOException
+    {
+        if (! hasData())
+        {
+            throw new IOException("Cannot return empty data");
+        }
+        return _data;
+    }
+    
+    /**
+     * What's the big block size?
+     */
+    public int getBigBlockSize() {
+       return _data.length;
+    }
+
+    /* **********  END  implementation of ListManagedBlock ********** */
+}   // end public class RawDataBlock
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/RawDataBlockList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/RawDataBlockList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/RawDataBlockList.java	(revision 28000)
@@ -0,0 +1,71 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
+
+/**
+ * A list of RawDataBlocks instances, and methods to manage the list
+ *
+ * @author Marc Johnson (mjohnson at apache dot org
+ */
+
+public class RawDataBlockList
+    extends BlockListImpl
+{
+
+    /**
+     * Constructor RawDataBlockList
+     *
+     * @param stream the InputStream from which the data will be read
+     * @param bigBlockSize The big block size, either 512 bytes or 4096 bytes
+     *
+     * @exception IOException on I/O errors, and if an incomplete
+     *            block is read
+     */
+
+    public RawDataBlockList(final InputStream stream, POIFSBigBlockSize bigBlockSize)
+        throws IOException
+    {
+        List<RawDataBlock> blocks = new ArrayList<RawDataBlock>();
+
+        while (true)
+        {
+            RawDataBlock block = new RawDataBlock(stream, bigBlockSize.getBigBlockSize());
+            
+            // If there was data, add the block to the list
+            if(block.hasData()) {
+            	blocks.add(block);
+            }
+
+            // If the stream is now at the End Of File, we're done
+            if (block.eof()) {
+                break;
+            }
+        }
+        setBlocks( blocks.toArray(new RawDataBlock[ blocks.size() ]) );
+    }
+}   // end public class RawDataBlockList
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/SmallBlockTableReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/SmallBlockTableReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/SmallBlockTableReader.java	(revision 28000)
@@ -0,0 +1,66 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+import java.io.IOException;
+
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
+import org.apache.poi.poifs.property.RootProperty;
+
+/**
+ * This class implements reading the small document block list from an
+ * existing file
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+public final class SmallBlockTableReader {
+
+    /**
+     * fetch the small document block list from an existing file
+     *
+     * @param blockList the raw data from which the small block table
+     *                  will be extracted
+     * @param root the root property (which contains the start block
+     *             and small block table size)
+     * @param sbatStart the start block of the SBAT
+     *
+     * @return the small document block list
+     *
+     * @exception IOException
+     */
+    public static BlockList getSmallDocumentBlocks(
+            final POIFSBigBlockSize bigBlockSize,
+            final RawDataBlockList blockList, final RootProperty root,
+            final int sbatStart)
+        throws IOException
+    {
+       // Fetch the blocks which hold the Small Blocks stream
+       ListManagedBlock [] smallBlockBlocks = 
+          blockList.fetchBlocks(root.getStartBlock(), -1);
+        
+       // Turn that into a list
+       BlockList list =new SmallDocumentBlockList(
+             SmallDocumentBlock.extract(bigBlockSize, smallBlockBlocks));
+
+       // Process
+        new BlockAllocationTableReader(bigBlockSize,
+                                       blockList.fetchBlocks(sbatStart, -1),
+                                       list);
+        return list;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/SmallDocumentBlock.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/SmallDocumentBlock.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/SmallDocumentBlock.java	(revision 28000)
@@ -0,0 +1,211 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.poi.poifs.common.POIFSBigBlockSize;
+
+/**
+ * Storage for documents that are too small to use regular
+ * DocumentBlocks for their data
+ *
+ * @author  Marc Johnson (mjohnson at apache dot org)
+ */
+public final class SmallDocumentBlock implements BlockWritable, ListManagedBlock {
+    private static final int BLOCK_SHIFT = 6;
+
+    private byte[]            _data;
+    private static final byte _default_fill         = ( byte ) 0xff;
+    private static final int  _block_size           = 1 << BLOCK_SHIFT;
+    private static final int BLOCK_MASK = _block_size-1;
+
+    //private final int  _blocks_per_big_block;
+
+    private SmallDocumentBlock(final POIFSBigBlockSize bigBlockSize, final byte [] data, final int index)
+    {
+        this(bigBlockSize);
+        System.arraycopy(data, index * _block_size, _data, 0, _block_size);
+    }
+
+    private SmallDocumentBlock(final POIFSBigBlockSize bigBlockSize)
+    {
+        _data = new byte[ _block_size ];
+    }
+    
+    private static int getBlocksPerBigBlock(final POIFSBigBlockSize bigBlockSize)
+    {
+       return bigBlockSize.getBigBlockSize() / _block_size;
+    }
+
+    /**
+     * convert a single long array into an array of SmallDocumentBlock
+     * instances
+     *
+     * @param array the byte array to be converted
+     * @param size the intended size of the array (which may be smaller)
+     *
+     * @return an array of SmallDocumentBlock instances, filled from
+     *         the array
+     */
+    public static SmallDocumentBlock [] convert(POIFSBigBlockSize bigBlockSize,
+                                                byte [] array,
+                                                int size)
+    {
+        SmallDocumentBlock[] rval   =
+            new SmallDocumentBlock[ (size + _block_size - 1) / _block_size ];
+        int                  offset = 0;
+
+        for (int k = 0; k < rval.length; k++)
+        {
+            rval[ k ] = new SmallDocumentBlock(bigBlockSize);
+            if (offset < array.length)
+            {
+                int length = Math.min(_block_size, array.length - offset);
+
+                System.arraycopy(array, offset, rval[ k ]._data, 0, length);
+                if (length != _block_size)
+                {
+                    Arrays.fill(rval[ k ]._data, length, _block_size,
+                                _default_fill);
+                }
+            }
+            else
+            {
+                Arrays.fill(rval[ k ]._data, _default_fill);
+            }
+            offset += _block_size;
+        }
+        return rval;
+    }
+
+    /**
+     * Factory for creating SmallDocumentBlocks from DocumentBlocks
+     *
+     * @param store the original DocumentBlocks
+     * @param size the total document size
+     *
+     * @return an array of new SmallDocumentBlocks instances
+     *
+     * @exception IOException on errors reading from the DocumentBlocks
+     * @exception ArrayIndexOutOfBoundsException if, somehow, the store
+     *            contains less data than size indicates
+     */
+    public static SmallDocumentBlock [] convert(POIFSBigBlockSize bigBlockSize,
+                                                BlockWritable [] store,
+                                                int size)
+        throws IOException, ArrayIndexOutOfBoundsException
+    {
+        ByteArrayOutputStream stream = new ByteArrayOutputStream();
+
+        for (int j = 0; j < store.length; j++)
+        {
+            store[ j ].writeBlocks(stream);
+        }
+        byte[]               data = stream.toByteArray();
+        SmallDocumentBlock[] rval =
+            new SmallDocumentBlock[ convertToBlockCount(size) ];
+
+        for (int index = 0; index < rval.length; index++)
+        {
+            rval[ index ] = new SmallDocumentBlock(bigBlockSize, data, index);
+        }
+        return rval;
+    }
+
+    /**
+     * create a list of SmallDocumentBlock's from raw data
+     *
+     * @param blocks the raw data containing the SmallDocumentBlock
+     *               data
+     *
+     * @return a List of SmallDocumentBlock's extracted from the input
+     */
+    public static List<SmallDocumentBlock> extract(POIFSBigBlockSize bigBlockSize, ListManagedBlock [] blocks)
+        throws IOException
+    {
+        int _blocks_per_big_block = getBlocksPerBigBlock(bigBlockSize);
+        
+        List<SmallDocumentBlock> sdbs = new ArrayList<SmallDocumentBlock>();
+
+        for (int j = 0; j < blocks.length; j++)
+        {
+            byte[] data = blocks[ j ].getData();
+
+            for (int k = 0; k < _blocks_per_big_block; k++)
+            {
+                sdbs.add(new SmallDocumentBlock(bigBlockSize, data, k));
+            }
+        }
+        return sdbs;
+    }
+
+    public static DataInputBlock getDataInputBlock(SmallDocumentBlock[] blocks, int offset) {
+        int firstBlockIndex = offset >> BLOCK_SHIFT;
+        int firstBlockOffset= offset & BLOCK_MASK;
+        return new DataInputBlock(blocks[firstBlockIndex]._data, firstBlockOffset);
+    }
+
+    /**
+     * Calculate the storage size of a set of SmallDocumentBlocks
+     *
+     * @param size number of SmallDocumentBlocks
+     *
+     * @return total size
+     */
+    public static int calcSize(int size)
+    {
+        return size * _block_size;
+    }
+
+    private static int convertToBlockCount(int size)
+    {
+        return (size + _block_size - 1) / _block_size;
+    }
+
+    /**
+     * Write the storage to an OutputStream
+     *
+     * @param stream the OutputStream to which the stored data should
+     *               be written
+     *
+     * @exception IOException on problems writing to the specified
+     *            stream
+     */
+    public void writeBlocks(OutputStream stream)
+        throws IOException
+    {
+        stream.write(_data);
+    }
+
+    /**
+     * Get the data from the block
+     *
+     * @return the block's data as a byte array
+     *
+     * @exception IOException if there is no data
+     */
+    public byte [] getData() {
+        return _data;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/SmallDocumentBlockList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/SmallDocumentBlockList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/SmallDocumentBlockList.java	(revision 28000)
@@ -0,0 +1,46 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.poifs.storage;
+
+import java.util.List;
+
+/**
+ * A list of SmallDocumentBlocks instances, and methods to manage the list
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ */
+
+public class SmallDocumentBlockList
+    extends BlockListImpl
+{
+
+    /**
+     * Constructor SmallDocumentBlockList
+     *
+     * @param blocks a list of SmallDocumentBlock instances
+     */
+
+    public SmallDocumentBlockList(final List<SmallDocumentBlock> blocks)
+    {
+        setBlocks(blocks
+            .toArray(new SmallDocumentBlock[ blocks.size() ]));
+    }
+}   // end public class SmallDocumentBlockList
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/poifs/storage/package.html	(revision 28000)
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+storage package contains low level binary structures for POIFS's implementation of the OLE 2
+Compound Document Format.
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/SpreadsheetVersion.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/SpreadsheetVersion.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/SpreadsheetVersion.java	(revision 28000)
@@ -0,0 +1,81 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss;
+
+import org.apache.poi.ss.util.CellReference;
+
+/**
+ * This enum allows spreadsheets from multiple Excel versions to be handled by the common code.
+ * Properties of this enum correspond to attributes of the <i>spreadsheet</i> that are easily
+ * discernable to the user.  It is not intended to deal with low-level issues like file formats.
+ * <p/>
+ *
+ * @author Josh Micich
+ * @author Yegor Kozlov
+ */
+public enum SpreadsheetVersion {
+	/**
+	 * Excel97 format aka BIFF8
+	 * <ul>
+	 * <li>The total number of available columns is 256 (2^8)</li>
+	 * <li>The total number of available rows is 64k (2^16)</li>
+	 * <li>The maximum number of arguments to a function is 30</li>
+	 * <li>Number of conditional format conditions on a cell is 3</li>
+     * <li>Length of text cell contents is 32767</li>
+	 * </ul>
+	 */
+	EXCEL97(0x10000, 0x0100, 30, 3, 32767);
+
+	private final int _maxRows;
+	private final int _maxColumns;
+
+	private SpreadsheetVersion(int maxRows, int maxColumns, int maxFunctionArgs, int maxCondFormats, int maxText) {
+		_maxRows = maxRows;
+		_maxColumns = maxColumns;
+    }
+
+	/**
+	 * @return the maximum number of usable rows in each spreadsheet
+	 */
+	public int getMaxRows() {
+		return _maxRows;
+	}
+
+	/**
+	 * @return the last (maximum) valid row index, equals to <code> getMaxRows() - 1 </code>
+	 */
+	public int getLastRowIndex() {
+		return _maxRows - 1;
+	}
+
+	/**
+	 * @return the last (maximum) valid column index, equals to <code> getMaxColumns() - 1 </code>
+	 */
+	public int getLastColumnIndex() {
+		return _maxColumns - 1;
+	}
+
+	/**
+	 *
+	 * @return the last valid column index in a ALPHA-26 representation
+	 *  (<code>IV</code> or <code>XFD</code>).
+	 */
+	public String getLastColumnName() {
+		return CellReference.convertNumToColString(getLastColumnIndex());
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellDateFormatter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellDateFormatter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellDateFormatter.java	(revision 28000)
@@ -0,0 +1,213 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.format;
+
+import java.text.AttributedCharacterIterator;
+import java.text.CharacterIterator;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Formatter;
+import java.util.regex.Matcher;
+
+/**
+ * Formats a date value.
+ *
+ * @author Ken Arnold, Industrious Media LLC
+ */
+public class CellDateFormatter extends CellFormatter {
+    private boolean amPmUpper;
+    private boolean showM;
+    private boolean showAmPm;
+    private final DateFormat dateFmt;
+    private String sFmt;
+
+    private static final long EXCEL_EPOCH_TIME;
+    private static final Date EXCEL_EPOCH_DATE;
+
+    private static final CellFormatter SIMPLE_DATE = new CellDateFormatter(
+            "mm/d/y");
+
+    static {
+        Calendar c = Calendar.getInstance();
+        c.set(1904, 0, 1, 0, 0, 0);
+        EXCEL_EPOCH_DATE = c.getTime();
+        EXCEL_EPOCH_TIME = c.getTimeInMillis();
+    }
+
+    private class DatePartHandler implements CellFormatPart.PartHandler {
+        private int mStart = -1;
+        private int mLen;
+        private int hStart = -1;
+        private int hLen;
+
+        public String handlePart(Matcher m, String part, CellFormatType type,
+                StringBuffer desc) {
+
+            int pos = desc.length();
+            char firstCh = part.charAt(0);
+            switch (firstCh) {
+            case 's':
+            case 'S':
+                if (mStart >= 0) {
+                    for (int i = 0; i < mLen; i++)
+                        desc.setCharAt(mStart + i, 'm');
+                    mStart = -1;
+                }
+                return part.toLowerCase();
+
+            case 'h':
+            case 'H':
+                mStart = -1;
+                hStart = pos;
+                hLen = part.length();
+                return part.toLowerCase();
+
+            case 'd':
+            case 'D':
+                mStart = -1;
+                if (part.length() <= 2)
+                    return part.toLowerCase();
+                else
+                    return part.toLowerCase().replace('d', 'E');
+
+            case 'm':
+            case 'M':
+                mStart = pos;
+                mLen = part.length();
+                return part.toUpperCase();
+
+            case 'y':
+            case 'Y':
+                mStart = -1;
+                if (part.length() == 3)
+                    part = "yyyy";
+                return part.toLowerCase();
+
+            case '0':
+                mStart = -1;
+                int sLen = part.length();
+                sFmt = "%0" + (sLen + 2) + "." + sLen + "f";
+                return part.replace('0', 'S');
+
+            case 'a':
+            case 'A':
+            case 'p':
+            case 'P':
+                if (part.length() > 1) {
+                    // am/pm marker
+                    mStart = -1;
+                    showAmPm = true;
+                    showM = Character.toLowerCase(part.charAt(1)) == 'm';
+                    // For some reason "am/pm" becomes AM or PM, but "a/p" becomes a or p
+                    amPmUpper = showM || Character.isUpperCase(part.charAt(0));
+
+                    return "a";
+                }
+                //noinspection fallthrough
+
+            default:
+                return null;
+            }
+        }
+
+        public void finish(StringBuffer toAppendTo) {
+            if (hStart >= 0 && !showAmPm) {
+                for (int i = 0; i < hLen; i++) {
+                    toAppendTo.setCharAt(hStart + i, 'H');
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates a new date formatter with the given specification.
+     *
+     * @param format The format.
+     */
+    public CellDateFormatter(String format) {
+        super(format);
+        DatePartHandler partHandler = new DatePartHandler();
+        StringBuffer descBuf = CellFormatPart.parseFormat(format,
+                CellFormatType.DATE, partHandler);
+        partHandler.finish(descBuf);
+        dateFmt = new SimpleDateFormat(descBuf.toString());
+    }
+
+    /** {@inheritDoc} */
+    public void formatValue(StringBuffer toAppendTo, Object value) {
+        if (value == null)
+            value = 0.0;
+        if (value instanceof Number) {
+            Number num = (Number) value;
+            double v = num.doubleValue();
+            if (v == 0.0)
+                value = EXCEL_EPOCH_DATE;
+            else
+                value = new Date((long) (EXCEL_EPOCH_TIME + v));
+        }
+
+        AttributedCharacterIterator it = dateFmt.formatToCharacterIterator(
+                value);
+        boolean doneAm = false;
+        boolean doneMillis = false;
+
+        it.first();
+        for (char ch = it.first();
+             ch != CharacterIterator.DONE;
+             ch = it.next()) {
+            if (it.getAttribute(DateFormat.Field.MILLISECOND) != null) {
+                if (!doneMillis) {
+                    Date dateObj = (Date) value;
+                    int pos = toAppendTo.length();
+                    Formatter formatter = new Formatter(toAppendTo);
+                    long msecs = dateObj.getTime() % 1000;
+                    formatter.format(LOCALE, sFmt, msecs / 1000.0);
+                    toAppendTo.delete(pos, pos + 2);
+                    doneMillis = true;
+                }
+            } else if (it.getAttribute(DateFormat.Field.AM_PM) != null) {
+                if (!doneAm) {
+                    if (showAmPm) {
+                        if (amPmUpper) {
+                            toAppendTo.append(Character.toUpperCase(ch));
+                            if (showM)
+                                toAppendTo.append('M');
+                        } else {
+                            toAppendTo.append(Character.toLowerCase(ch));
+                            if (showM)
+                                toAppendTo.append('m');
+                        }
+                    }
+                    doneAm = true;
+                }
+            } else {
+                toAppendTo.append(ch);
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * For a date, this is <tt>"mm/d/y"</tt>.
+     */
+    public void simpleValue(StringBuffer toAppendTo, Object value) {
+        SIMPLE_DATE.formatValue(toAppendTo, value);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellElapsedFormatter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellElapsedFormatter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellElapsedFormatter.java	(revision 28000)
@@ -0,0 +1,215 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.format;
+
+import java.util.ArrayList;
+import java.util.Formatter;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This class implements printing out an elapsed time format.
+ *
+ * @author Ken Arnold, Industrious Media LLC
+ */
+public class CellElapsedFormatter extends CellFormatter {
+    private final List<TimeSpec> specs;
+    private TimeSpec topmost;
+    private final String printfFmt;
+
+    private static final Pattern PERCENTS = Pattern.compile("%");
+
+    private static final double HOUR__FACTOR = 1.0 / 24.0;
+    private static final double MIN__FACTOR = HOUR__FACTOR / 60.0;
+    private static final double SEC__FACTOR = MIN__FACTOR / 60.0;
+
+    private static class TimeSpec {
+        final char type;
+        final int pos;
+        final int len;
+        final double factor;
+        double modBy;
+
+        public TimeSpec(char type, int pos, int len, double factor) {
+            this.type = type;
+            this.pos = pos;
+            this.len = len;
+            this.factor = factor;
+            modBy = 0;
+        }
+
+        public long valueFor(double elapsed) {
+            double val;
+            if (modBy == 0)
+                val = elapsed / factor;
+            else
+                val = elapsed / factor % modBy;
+            if (type == '0')
+                return Math.round(val);
+            else
+                return (long) val;
+        }
+    }
+
+    private class ElapsedPartHandler implements CellFormatPart.PartHandler {
+        // This is the one class that's directly using printf, so it can't use
+        // the default handling for quoted strings and special characters.  The
+        // only special character for this is '%', so we have to handle all the
+        // quoting in this method ourselves.
+
+        public String handlePart(Matcher m, String part, CellFormatType type,
+                StringBuffer desc) {
+
+            int pos = desc.length();
+            char firstCh = part.charAt(0);
+            switch (firstCh) {
+            case '[':
+                if (part.length() < 3)
+                    break;
+                if (topmost != null)
+                    throw new IllegalArgumentException(
+                            "Duplicate '[' times in format");
+                part = part.toLowerCase();
+                int specLen = part.length() - 2;
+                topmost = assignSpec(part.charAt(1), pos, specLen);
+                return part.substring(1, 1 + specLen);
+
+            case 'h':
+            case 'm':
+            case 's':
+            case '0':
+                part = part.toLowerCase();
+                assignSpec(part.charAt(0), pos, part.length());
+                return part;
+
+            case '\n':
+                return "%n";
+
+            case '\"':
+                part = part.substring(1, part.length() - 1);
+                break;
+
+            case '\\':
+                part = part.substring(1);
+                break;
+
+            case '*':
+                if (part.length() > 1)
+                    part = CellFormatPart.expandChar(part);
+                break;
+
+            // An escape we can let it handle because it can't have a '%'
+            case '_':
+                return null;
+            }
+            // Replace ever "%" with a "%%" so we can use printf
+            return PERCENTS.matcher(part).replaceAll("%%");
+        }
+    }
+
+    /**
+     * Creates a elapsed time formatter.
+     *
+     * @param pattern The pattern to parse.
+     */
+    public CellElapsedFormatter(String pattern) {
+        super(pattern);
+
+        specs = new ArrayList<TimeSpec>();
+
+        StringBuffer desc = CellFormatPart.parseFormat(pattern,
+                CellFormatType.ELAPSED, new ElapsedPartHandler());
+
+        ListIterator<TimeSpec> it = specs.listIterator(specs.size());
+        while (it.hasPrevious()) {
+            TimeSpec spec = it.previous();
+            desc.replace(spec.pos, spec.pos + spec.len, "%0" + spec.len + "d");
+            if (spec.type != topmost.type) {
+                spec.modBy = modFor(spec.type, spec.len);
+            }
+        }
+
+        printfFmt = desc.toString();
+    }
+
+    private TimeSpec assignSpec(char type, int pos, int len) {
+        TimeSpec spec = new TimeSpec(type, pos, len, factorFor(type, len));
+        specs.add(spec);
+        return spec;
+    }
+
+    private static double factorFor(char type, int len) {
+        switch (type) {
+        case 'h':
+            return HOUR__FACTOR;
+        case 'm':
+            return MIN__FACTOR;
+        case 's':
+            return SEC__FACTOR;
+        case '0':
+            return SEC__FACTOR / Math.pow(10, len);
+        default:
+            throw new IllegalArgumentException(
+                    "Uknown elapsed time spec: " + type);
+        }
+    }
+
+    private static double modFor(char type, int len) {
+        switch (type) {
+        case 'h':
+            return 24;
+        case 'm':
+            return 60;
+        case 's':
+            return 60;
+        case '0':
+            return Math.pow(10, len);
+        default:
+            throw new IllegalArgumentException(
+                    "Uknown elapsed time spec: " + type);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void formatValue(StringBuffer toAppendTo, Object value) {
+        double elapsed = ((Number) value).doubleValue();
+
+        if (elapsed < 0) {
+            toAppendTo.append('-');
+            elapsed = -elapsed;
+        }
+
+        Object[] parts = new Long[specs.size()];
+        for (int i = 0; i < specs.size(); i++) {
+            parts[i] = specs.get(i).valueFor(elapsed);
+        }
+
+        Formatter formatter = new Formatter(toAppendTo);
+        formatter.format(printfFmt, parts);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * For a date, this is <tt>"mm/d/y"</tt>.
+     */
+    public void simpleValue(StringBuffer toAppendTo, Object value) {
+        formatValue(toAppendTo, value);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellFormatPart.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellFormatPart.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellFormatPart.java	(revision 28000)
@@ -0,0 +1,205 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.format;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Objects of this class represent a single part of a cell format expression.
+ * Each cell can have up to four of these for positive, zero, negative, and text
+ * values.
+ * <p/>
+ * Each format part can contain a color, a condition, and will always contain a
+ * format specification.  For example <tt>"[Red][>=10]#"</tt> has a color
+ * (<tt>[Red]</tt>), a condition (<tt>>=10</tt>) and a format specification
+ * (<tt>#</tt>).
+ * <p/>
+ * This class also contains patterns for matching the subparts of format
+ * specification.  These are used internally, but are made public in case other
+ * code has use for them.
+ *
+ * @author Ken Arnold, Industrious Media LLC
+ */
+public class CellFormatPart {
+
+    /** Pattern for the format specification part of a cell format part. */
+    public static final Pattern SPECIFICATION_PAT;
+
+    static {
+
+        // A number specification
+        // Note: careful that in something like ##, that the trailing comma is not caught up in the integer part
+
+        // A part of a specification
+        String part = "\\\\.                 # Quoted single character\n" +
+                "|\"([^\\\\\"]|\\\\.)*\"         # Quoted string of characters (handles escaped quotes like \\\") \n" +
+                "|_.                             # Space as wide as a given character\n" +
+                "|\\*.                           # Repeating fill character\n" +
+                "|@                              # Text: cell text\n" +
+                "|([0?\\#](?:[0?\\#,]*))         # Number: digit + other digits and commas\n" +
+                "|e[-+]                          # Number: Scientific: Exponent\n" +
+                "|m{1,5}                         # Date: month or minute spec\n" +
+                "|d{1,4}                         # Date: day/date spec\n" +
+                "|y{2,4}                         # Date: year spec\n" +
+                "|h{1,2}                         # Date: hour spec\n" +
+                "|s{1,2}                         # Date: second spec\n" +
+                "|am?/pm?                        # Date: am/pm spec\n" +
+                "|\\[h{1,2}\\]                   # Elapsed time: hour spec\n" +
+                "|\\[m{1,2}\\]                   # Elapsed time: minute spec\n" +
+                "|\\[s{1,2}\\]                   # Elapsed time: second spec\n" +
+                "|[^;]                           # A character\n" + "";
+
+        int flags = Pattern.COMMENTS | Pattern.CASE_INSENSITIVE;
+        SPECIFICATION_PAT = Pattern.compile(part, flags);
+    }
+
+    interface PartHandler {
+        String handlePart(Matcher m, String part, CellFormatType type,
+                StringBuffer desc);
+    }
+
+    /**
+     * Returns a version of the original string that has any special characters
+     * quoted (or escaped) as appropriate for the cell format type.  The format
+     * type object is queried to see what is special.
+     *
+     * @param repl The original string.
+     * @param type The format type representation object.
+     *
+     * @return A version of the string with any special characters replaced.
+     *
+     * @see CellFormatType#isSpecial(char)
+     */
+    static String quoteSpecial(String repl, CellFormatType type) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < repl.length(); i++) {
+            char ch = repl.charAt(i);
+            if (ch == '\'' && type.isSpecial('\'')) {
+                sb.append('\u0000');
+                continue;
+            }
+
+            boolean special = type.isSpecial(ch);
+            if (special)
+                sb.append("'");
+            sb.append(ch);
+            if (special)
+                sb.append("'");
+        }
+        return sb.toString();
+    }
+
+
+
+    public static StringBuffer parseFormat(String fdesc, CellFormatType type,
+            PartHandler partHandler) {
+
+        // Quoting is very awkward.  In the Java classes, quoting is done
+        // between ' chars, with '' meaning a single ' char. The problem is that
+        // in Excel, it is legal to have two adjacent escaped strings.  For
+        // example, consider the Excel format "\a\b#".  The naive (and easy)
+        // translation into Java DecimalFormat is "'a''b'#".  For the number 17,
+        // in Excel you would get "ab17", but in Java it would be "a'b17" -- the
+        // '' is in the middle of the quoted string in Java.  So the trick we
+        // use is this: When we encounter a ' char in the Excel format, we
+        // output a \u0000 char into the string.  Now we know that any '' in the
+        // output is the result of two adjacent escaped strings.  So after the
+        // main loop, we have to do two passes: One to eliminate any ''
+        // sequences, to make "'a''b'" become "'ab'", and another to replace any
+        // \u0000 with '' to mean a quote char.  Oy.
+        //
+        // For formats that don't use "'" we don't do any of this
+        Matcher m = SPECIFICATION_PAT.matcher(fdesc);
+        StringBuffer fmt = new StringBuffer();
+        while (m.find()) {
+            String part = group(m, 0);
+            if (part.length() > 0) {
+                String repl = partHandler.handlePart(m, part, type, fmt);
+                if (repl == null) {
+                    switch (part.charAt(0)) {
+                    case '\"':
+                        repl = quoteSpecial(part.substring(1,
+                                part.length() - 1), type);
+                        break;
+                    case '\\':
+                        repl = quoteSpecial(part.substring(1), type);
+                        break;
+                    case '_':
+                        repl = " ";
+                        break;
+                    case '*': //!! We don't do this for real, we just put in 3 of them
+                        repl = expandChar(part);
+                        break;
+                    default:
+                        repl = part;
+                        break;
+                    }
+                }
+                m.appendReplacement(fmt, Matcher.quoteReplacement(repl));
+            }
+        }
+        m.appendTail(fmt);
+
+        if (type.isSpecial('\'')) {
+            // Now the next pass for quoted characters: Remove '' chars, making "'a''b'" into "'ab'"
+            int pos = 0;
+            while ((pos = fmt.indexOf("''", pos)) >= 0) {
+                fmt.delete(pos, pos + 2);
+            }
+
+            // Now the final pass for quoted chars: Replace any \u0000 with ''
+            pos = 0;
+            while ((pos = fmt.indexOf("\u0000", pos)) >= 0) {
+                fmt.replace(pos, pos + 1, "''");
+            }
+        }
+
+        return fmt;
+    }
+
+    /**
+     * Expands a character. This is only partly done, because we don't have the
+     * correct info.  In Excel, this would be expanded to fill the rest of the
+     * cell, but we don't know, in general, what the "rest of the cell" is.
+     *
+     * @param part The character to be repeated is the second character in this
+     *             string.
+     *
+     * @return The character repeated three times.
+     */
+    static String expandChar(String part) {
+        String repl;
+        char ch = part.charAt(1);
+        repl = "" + ch + ch + ch;
+        return repl;
+    }
+
+    /**
+     * Returns the string from the group, or <tt>""</tt> if the group is
+     * <tt>null</tt>.
+     *
+     * @param m The matcher.
+     * @param g The group number.
+     *
+     * @return The group or <tt>""</tt>.
+     */
+    public static String group(Matcher m, int g) {
+        String str = m.group(g);
+        return (str == null ? "" : str);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellFormatType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellFormatType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellFormatType.java	(revision 28000)
@@ -0,0 +1,82 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.format;
+
+/**
+ * The different kinds of formats that the formatter understands.
+ *
+ * @author Ken Arnold, Industrious Media LLC
+ */
+public enum CellFormatType {
+
+    /** A numeric format. */
+    NUMBER {
+        boolean isSpecial(char ch) {
+            return false;
+        }
+        CellFormatter formatter(String pattern) {
+            return new CellNumberFormatter(pattern);
+        }
+    },
+    /** A date format. */
+    DATE {
+        boolean isSpecial(char ch) {
+            return ch == '\'' || (ch <= '\u007f' && Character.isLetter(ch));
+        }
+        CellFormatter formatter(String pattern) {
+            return new CellDateFormatter(pattern);
+        }
+    },
+    /** An elapsed time format. */
+    ELAPSED {
+        boolean isSpecial(char ch) {
+            return false;
+        }
+        CellFormatter formatter(String pattern) {
+            return new CellElapsedFormatter(pattern);
+        }
+    },
+    /** A text format. */
+    TEXT {
+        boolean isSpecial(char ch) {
+            return false;
+        }
+        CellFormatter formatter(String pattern) {
+            return new CellTextFormatter(pattern);
+        }
+    };
+
+    /**
+     * Returns <tt>true</tt> if the format is special and needs to be quoted.
+     *
+     * @param ch The character to test.
+     *
+     * @return <tt>true</tt> if the format is special and needs to be quoted.
+     */
+    abstract boolean isSpecial(char ch);
+
+    /**
+     * Returns a new formatter of the appropriate type, for the given pattern.
+     * The pattern must be appropriate for the type.
+     *
+     * @param pattern The pattern to use.
+     *
+     * @return A new formatter of the appropriate type, for the given pattern.
+     */
+    abstract CellFormatter formatter(String pattern);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellFormatter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellFormatter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellFormatter.java	(revision 28000)
@@ -0,0 +1,61 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.format;
+
+import java.util.Locale;
+
+/**
+ * This is the abstract supertype for the various cell formatters.
+ *
+ * @author Ken Arnold, Industrious Media LLC
+ */
+public abstract class CellFormatter {
+    /** The original specified format. */
+    protected final String format;
+
+    /**
+     * This is the locale used to get a consistent format result from which to
+     * work.
+     */
+    public static final Locale LOCALE = Locale.US;
+
+    /**
+     * Creates a new formatter object, storing the format in {@link #format}.
+     *
+     * @param format The format.
+     */
+    public CellFormatter(String format) {
+        this.format = format;
+    }
+
+    /**
+     * Format a value according the format string.
+     *
+     * @param toAppendTo The buffer to append to.
+     * @param value      The value to format.
+     */
+    public abstract void formatValue(StringBuffer toAppendTo, Object value);
+
+    /**
+     * Format a value according to the type, in the most basic way.
+     *
+     * @param toAppendTo The buffer to append to.
+     * @param value      The value to format.
+     */
+    public abstract void simpleValue(StringBuffer toAppendTo, Object value);
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellNumberFormatter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellNumberFormatter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellNumberFormatter.java	(revision 28000)
@@ -0,0 +1,1085 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.format;
+
+import java.text.DecimalFormat;
+import java.text.FieldPosition;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.Formatter;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+
+import org.apache.poi.ss.format.CellFormatPart.PartHandler;
+
+/**
+ * This class implements printing out a value using a number format.
+ *
+ * @author Ken Arnold, Industrious Media LLC
+ */
+public class CellNumberFormatter extends CellFormatter {
+    private final String desc;
+    private String printfFmt;
+    private double scale;
+    private Special decimalPoint;
+    private Special slash;
+    private Special exponent;
+    private Special numerator;
+    private Special afterInteger;
+    private Special afterFractional;
+    private boolean integerCommas;
+    private final List<Special> specials;
+    private List<Special> integerSpecials;
+    private List<Special> fractionalSpecials;
+    private List<Special> numeratorSpecials;
+    private List<Special> denominatorSpecials;
+    private List<Special> exponentSpecials;
+    private List<Special> exponentDigitSpecials;
+    private int maxDenominator;
+    private String numeratorFmt;
+    private String denominatorFmt;
+    private boolean improperFraction;
+    private DecimalFormat decimalFmt;
+
+    static final CellFormatter SIMPLE_NUMBER = new CellFormatter("General") {
+        public void formatValue(StringBuffer toAppendTo, Object value) {
+            if (value == null)
+                return;
+            if (value instanceof Number) {
+                Number num = (Number) value;
+                if (num.doubleValue() % 1.0 == 0)
+                    SIMPLE_INT.formatValue(toAppendTo, value);
+                else
+                    SIMPLE_FLOAT.formatValue(toAppendTo, value);
+            } else {
+                CellTextFormatter.SIMPLE_TEXT.formatValue(toAppendTo, value);
+            }
+        }
+
+        public void simpleValue(StringBuffer toAppendTo, Object value) {
+            formatValue(toAppendTo, value);
+        }
+    };
+
+    private static final CellFormatter SIMPLE_INT = new CellNumberFormatter(
+            "#");
+    private static final CellFormatter SIMPLE_FLOAT = new CellNumberFormatter(
+            "#.#");
+
+    /**
+     * This class is used to mark where the special characters in the format
+     * are, as opposed to the other characters that are simply printed.
+     */
+    static class Special {
+        final char ch;
+        int pos;
+
+        Special(char ch, int pos) {
+            this.ch = ch;
+            this.pos = pos;
+        }
+
+        @Override
+        public String toString() {
+            return "'" + ch + "' @ " + pos;
+        }
+    }
+
+    /**
+     * This class represents a single modification to a result string.  The way
+     * this works is complicated, but so is numeric formatting.  In general, for
+     * most formats, we use a DecimalFormat object that will put the string out
+     * in a known format, usually with all possible leading and trailing zeros.
+     * We then walk through the result and the orginal format, and note any
+     * modifications that need to be made.  Finally, we go through and apply
+     * them all, dealing with overlapping modifications.
+     */
+    static class StringMod implements Comparable<StringMod> {
+        final Special special;
+        final int op;
+        CharSequence toAdd;
+        Special end;
+        boolean startInclusive;
+        boolean endInclusive;
+
+        public static final int BEFORE = 1;
+        public static final int AFTER = 2;
+        public static final int REPLACE = 3;
+
+        private StringMod(Special special, CharSequence toAdd, int op) {
+            this.special = special;
+            this.toAdd = toAdd;
+            this.op = op;
+        }
+
+        public StringMod(Special start, boolean startInclusive, Special end,
+                boolean endInclusive, char toAdd) {
+            this(start, startInclusive, end, endInclusive);
+            this.toAdd = toAdd + "";
+        }
+
+        public StringMod(Special start, boolean startInclusive, Special end,
+                boolean endInclusive) {
+            special = start;
+            this.startInclusive = startInclusive;
+            this.end = end;
+            this.endInclusive = endInclusive;
+            op = REPLACE;
+            toAdd = "";
+        }
+
+        public int compareTo(StringMod that) {
+            int diff = special.pos - that.special.pos;
+            if (diff != 0)
+                return diff;
+            else
+                return op - that.op;
+        }
+
+        @Override
+        public boolean equals(Object that) {
+            try {
+                return compareTo((StringMod) that) == 0;
+            } catch (RuntimeException ignored) {
+                // NullPointerException or CastException
+                return false;
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return special.hashCode() + op;
+        }
+    }
+
+    private class NumPartHandler implements PartHandler {
+        private char insertSignForExponent;
+
+        public String handlePart(Matcher m, String part, CellFormatType type,
+                StringBuffer desc) {
+            int pos = desc.length();
+            char firstCh = part.charAt(0);
+            switch (firstCh) {
+            case 'e':
+            case 'E':
+                // See comment in writeScientific -- exponent handling is complex.
+                // (1) When parsing the format, remove the sign from after the 'e' and
+                // put it before the first digit of the exponent.
+                if (exponent == null && specials.size() > 0) {
+                    specials.add(exponent = new Special('.', pos));
+                    insertSignForExponent = part.charAt(1);
+                    return part.substring(0, 1);
+                }
+                break;
+
+            case '0':
+            case '?':
+            case '#':
+                if (insertSignForExponent != '\0') {
+                    specials.add(new Special(insertSignForExponent, pos));
+                    desc.append(insertSignForExponent);
+                    insertSignForExponent = '\0';
+                    pos++;
+                }
+                for (int i = 0; i < part.length(); i++) {
+                    char ch = part.charAt(i);
+                    specials.add(new Special(ch, pos + i));
+                }
+                break;
+
+            case '.':
+                if (decimalPoint == null && specials.size() > 0)
+                    specials.add(decimalPoint = new Special('.', pos));
+                break;
+
+            case '/':
+                //!! This assumes there is a numerator and a denominator, but these are actually optional
+                if (slash == null && specials.size() > 0) {
+                    numerator = previousNumber();
+                    // If the first number in the whole format is the numerator, the
+                    // entire number should be printed as an improper fraction
+                    if (numerator == firstDigit(specials))
+                        improperFraction = true;
+                    specials.add(slash = new Special('.', pos));
+                }
+                break;
+
+            case '%':
+                // don't need to remember because we don't need to do anything with these
+                scale *= 100;
+                break;
+
+            default:
+                return null;
+            }
+            return part;
+        }
+    }
+
+    /**
+     * Creates a new cell number formatter.
+     *
+     * @param format The format to parse.
+     */
+    public CellNumberFormatter(String format) {
+        super(format);
+
+        scale = 1;
+
+        specials = new LinkedList<Special>();
+
+        NumPartHandler partHandler = new NumPartHandler();
+        StringBuffer descBuf = CellFormatPart.parseFormat(format,
+                CellFormatType.NUMBER, partHandler);
+
+        // These are inconsistent settings, so ditch 'em
+        if ((decimalPoint != null || exponent != null) && slash != null) {
+            slash = null;
+            numerator = null;
+        }
+
+        interpretCommas(descBuf);
+
+        int precision;
+        int fractionPartWidth = 0;
+        if (decimalPoint == null) {
+            precision = 0;
+        } else {
+            precision = interpretPrecision();
+            fractionPartWidth = 1 + precision;
+            if (precision == 0) {
+                // This means the format has a ".", but that output should have no decimals after it.
+                // We just stop treating it specially
+                specials.remove(decimalPoint);
+                decimalPoint = null;
+            }
+        }
+
+        if (precision == 0)
+            fractionalSpecials = Collections.emptyList();
+        else
+            fractionalSpecials = specials.subList(specials.indexOf(
+                    decimalPoint) + 1, fractionalEnd());
+        if (exponent == null)
+            exponentSpecials = Collections.emptyList();
+        else {
+            int exponentPos = specials.indexOf(exponent);
+            exponentSpecials = specialsFor(exponentPos, 2);
+            exponentDigitSpecials = specialsFor(exponentPos + 2);
+        }
+
+        if (slash == null) {
+            numeratorSpecials = Collections.emptyList();
+            denominatorSpecials = Collections.emptyList();
+        } else {
+            if (numerator == null)
+                numeratorSpecials = Collections.emptyList();
+            else
+                numeratorSpecials = specialsFor(specials.indexOf(numerator));
+
+            denominatorSpecials = specialsFor(specials.indexOf(slash) + 1);
+            if (denominatorSpecials.isEmpty()) {
+                // no denominator follows the slash, drop the fraction idea
+                numeratorSpecials = Collections.emptyList();
+            } else {
+                maxDenominator = maxValue(denominatorSpecials);
+                numeratorFmt = singleNumberFormat(numeratorSpecials);
+                denominatorFmt = singleNumberFormat(denominatorSpecials);
+            }
+        }
+
+        integerSpecials = specials.subList(0, integerEnd());
+
+        if (exponent == null) {
+            StringBuffer fmtBuf = new StringBuffer("%");
+
+            int integerPartWidth = calculateIntegerPartWidth();
+            int totalWidth = integerPartWidth + fractionPartWidth;
+
+            fmtBuf.append('0').append(totalWidth).append('.').append(precision);
+
+            fmtBuf.append("f");
+            printfFmt = fmtBuf.toString();
+        } else {
+            StringBuffer fmtBuf = new StringBuffer();
+            boolean first = true;
+            List<Special> specialList = integerSpecials;
+            if (integerSpecials.size() == 1) {
+                // If we don't do this, we get ".6e5" instead of "6e4"
+                fmtBuf.append("0");
+                first = false;
+            } else
+                for (Special s : specialList) {
+                    if (isDigitFmt(s)) {
+                        fmtBuf.append(first ? '#' : '0');
+                        first = false;
+                    }
+                }
+            if (fractionalSpecials.size() > 0) {
+                fmtBuf.append('.');
+                for (Special s : fractionalSpecials) {
+                    if (isDigitFmt(s)) {
+                        if (!first)
+                            fmtBuf.append('0');
+                        first = false;
+                    }
+                }
+            }
+            fmtBuf.append('E');
+            placeZeros(fmtBuf, exponentSpecials.subList(2,
+                    exponentSpecials.size()));
+            decimalFmt = new DecimalFormat(fmtBuf.toString());
+        }
+
+        if (exponent != null)
+            scale =
+                    1;  // in "e" formats,% and trailing commas have no scaling effect
+
+        desc = descBuf.toString();
+    }
+
+    private static void placeZeros(StringBuffer sb, List<Special> specials) {
+        for (Special s : specials) {
+            if (isDigitFmt(s))
+                sb.append('0');
+        }
+    }
+
+    private static Special firstDigit(List<Special> specials) {
+        for (Special s : specials) {
+            if (isDigitFmt(s))
+                return s;
+        }
+        return null;
+    }
+
+    static StringMod insertMod(Special special, CharSequence toAdd, int where) {
+        return new StringMod(special, toAdd, where);
+    }
+
+    static StringMod deleteMod(Special start, boolean startInclusive,
+            Special end, boolean endInclusive) {
+
+        return new StringMod(start, startInclusive, end, endInclusive);
+    }
+
+    static StringMod replaceMod(Special start, boolean startInclusive,
+            Special end, boolean endInclusive, char withChar) {
+
+        return new StringMod(start, startInclusive, end, endInclusive,
+                withChar);
+    }
+
+    private static String singleNumberFormat(List<Special> numSpecials) {
+        return "%0" + numSpecials.size() + "d";
+    }
+
+    private static int maxValue(List<Special> s) {
+        return (int) Math.round(Math.pow(10, s.size()) - 1);
+    }
+
+    private List<Special> specialsFor(int pos, int takeFirst) {
+        if (pos >= specials.size())
+            return Collections.emptyList();
+        ListIterator<Special> it = specials.listIterator(pos + takeFirst);
+        Special last = it.next();
+        int end = pos + takeFirst;
+        while (it.hasNext()) {
+            Special s = it.next();
+            if (!isDigitFmt(s) || s.pos - last.pos > 1)
+                break;
+            end++;
+            last = s;
+        }
+        return specials.subList(pos, end + 1);
+    }
+
+    private List<Special> specialsFor(int pos) {
+        return specialsFor(pos, 0);
+    }
+
+    private static boolean isDigitFmt(Special s) {
+        return s.ch == '0' || s.ch == '?' || s.ch == '#';
+    }
+
+    private Special previousNumber() {
+        ListIterator<Special> it = specials.listIterator(specials.size());
+        while (it.hasPrevious()) {
+            Special s = it.previous();
+            if (isDigitFmt(s)) {
+                Special numStart = s;
+                Special last = s;
+                while (it.hasPrevious()) {
+                    s = it.previous();
+                    if (last.pos - s.pos > 1) // it has to be continuous digits
+                        break;
+                    if (isDigitFmt(s))
+                        numStart = s;
+                    else
+                        break;
+                    last = s;
+                }
+                return numStart;
+            }
+        }
+        return null;
+    }
+
+    private int calculateIntegerPartWidth() {
+        ListIterator<Special> it = specials.listIterator();
+        int digitCount = 0;
+        while (it.hasNext()) {
+            Special s = it.next();
+            //!! Handle fractions: The previous set of digits before that is the numerator, so we should stop short of that
+            if (s == afterInteger)
+                break;
+            else if (isDigitFmt(s))
+                digitCount++;
+        }
+        return digitCount;
+    }
+
+    private int interpretPrecision() {
+        if (decimalPoint == null) {
+            return -1;
+        } else {
+            int precision = 0;
+            ListIterator<Special> it = specials.listIterator(specials.indexOf(
+                    decimalPoint));
+            if (it.hasNext())
+                it.next();  // skip over the decimal point itself
+            while (it.hasNext()) {
+                Special s = it.next();
+                if (isDigitFmt(s))
+                    precision++;
+                else
+                    break;
+            }
+            return precision;
+        }
+    }
+
+    private void interpretCommas(StringBuffer sb) {
+        // In the integer part, commas at the end are scaling commas; other commas mean to show thousand-grouping commas
+        ListIterator<Special> it = specials.listIterator(integerEnd());
+
+        boolean stillScaling = true;
+        integerCommas = false;
+        while (it.hasPrevious()) {
+            Special s = it.previous();
+            if (s.ch != ',') {
+                stillScaling = false;
+            } else {
+                if (stillScaling) {
+                    scale /= 1000;
+                } else {
+                    integerCommas = true;
+                }
+            }
+        }
+
+        if (decimalPoint != null) {
+            it = specials.listIterator(fractionalEnd());
+            while (it.hasPrevious()) {
+                Special s = it.previous();
+                if (s.ch != ',') {
+                    break;
+                } else {
+                    scale /= 1000;
+                }
+            }
+        }
+
+        // Now strip them out -- we only need their interpretation, not their presence
+        it = specials.listIterator();
+        int removed = 0;
+        while (it.hasNext()) {
+            Special s = it.next();
+            s.pos -= removed;
+            if (s.ch == ',') {
+                removed++;
+                it.remove();
+                sb.deleteCharAt(s.pos);
+            }
+        }
+    }
+
+    private int integerEnd() {
+        if (decimalPoint != null)
+            afterInteger = decimalPoint;
+        else if (exponent != null)
+            afterInteger = exponent;
+        else if (numerator != null)
+            afterInteger = numerator;
+        else
+            afterInteger = null;
+        return afterInteger == null ? specials.size() : specials.indexOf(
+                afterInteger);
+    }
+
+    private int fractionalEnd() {
+        int end;
+        if (exponent != null)
+            afterFractional = exponent;
+        else if (numerator != null)
+            afterInteger = numerator;
+        else
+            afterFractional = null;
+        end = afterFractional == null ? specials.size() : specials.indexOf(
+                afterFractional);
+        return end;
+    }
+
+    /** {@inheritDoc} */
+    public void formatValue(StringBuffer toAppendTo, Object valueObject) {
+        double value = ((Number) valueObject).doubleValue();
+        value *= scale;
+
+        // the '-' sign goes at the front, always, so we pick it out
+        boolean negative = value < 0;
+        if (negative)
+            value = -value;
+
+        // Split out the fractional part if we need to print a fraction
+        double fractional = 0;
+        if (slash != null) {
+            if (improperFraction) {
+                fractional = value;
+                value = 0;
+            } else {
+                fractional = value % 1.0;
+                //noinspection SillyAssignment
+                value = (long) value;
+            }
+        }
+
+        Set<StringMod> mods = new TreeSet<StringMod>();
+        StringBuffer output = new StringBuffer(desc);
+
+        if (exponent != null) {
+            writeScientific(value, output, mods);
+        } else if (improperFraction) {
+            writeFraction(value, null, fractional, output, mods);
+        } else {
+            StringBuffer result = new StringBuffer();
+            Formatter f = new Formatter(result);
+            f.format(LOCALE, printfFmt, value);
+
+            if (numerator == null) {
+                writeFractional(result, output);
+                writeInteger(result, output, integerSpecials, mods,
+                        integerCommas);
+            } else {
+                writeFraction(value, result, fractional, output, mods);
+            }
+        }
+
+        // Now strip out any remaining '#'s and add any pending text ...
+        ListIterator<Special> it = specials.listIterator();
+        Iterator<StringMod> changes = mods.iterator();
+        StringMod nextChange = (changes.hasNext() ? changes.next() : null);
+        int adjust = 0;
+        BitSet deletedChars = new BitSet(); // records chars already deleted
+        while (it.hasNext()) {
+            Special s = it.next();
+            int adjustedPos = s.pos + adjust;
+            if (!deletedChars.get(s.pos) && output.charAt(adjustedPos) == '#') {
+                output.deleteCharAt(adjustedPos);
+                adjust--;
+                deletedChars.set(s.pos);
+            }
+            while (nextChange != null && s == nextChange.special) {
+                int lenBefore = output.length();
+                int modPos = s.pos + adjust;
+                int posTweak = 0;
+                switch (nextChange.op) {
+                case StringMod.AFTER:
+                    // ignore adding a comma after a deleted char (which was a '#')
+                    if (nextChange.toAdd.equals(",") && deletedChars.get(s.pos))
+                        break;
+                    posTweak = 1;
+                    //noinspection fallthrough
+                case StringMod.BEFORE:
+                    output.insert(modPos + posTweak, nextChange.toAdd);
+                    break;
+
+                case StringMod.REPLACE:
+                    int delPos =
+                            s.pos; // delete starting pos in original coordinates
+                    if (!nextChange.startInclusive) {
+                        delPos++;
+                        modPos++;
+                    }
+
+                    // Skip over anything already deleted
+                    while (deletedChars.get(delPos)) {
+                        delPos++;
+                        modPos++;
+                    }
+
+                    int delEndPos =
+                            nextChange.end.pos; // delete end point in original
+                    if (nextChange.endInclusive)
+                        delEndPos++;
+
+                    int modEndPos =
+                            delEndPos + adjust; // delete end point in current
+
+                    if (modPos < modEndPos) {
+                        if (nextChange.toAdd == "")
+                            output.delete(modPos, modEndPos);
+                        else {
+                            char fillCh = nextChange.toAdd.charAt(0);
+                            for (int i = modPos; i < modEndPos; i++)
+                                output.setCharAt(i, fillCh);
+                        }
+                        deletedChars.set(delPos, delEndPos);
+                    }
+                    break;
+
+                default:
+                    throw new IllegalStateException(
+                            "Unknown op: " + nextChange.op);
+                }
+                adjust += output.length() - lenBefore;
+
+                if (changes.hasNext())
+                    nextChange = changes.next();
+                else
+                    nextChange = null;
+            }
+        }
+
+        // Finally, add it to the string
+        if (negative)
+            toAppendTo.append('-');
+        toAppendTo.append(output);
+    }
+
+    private void writeScientific(double value, StringBuffer output,
+            Set<StringMod> mods) {
+
+        StringBuffer result = new StringBuffer();
+        FieldPosition fractionPos = new FieldPosition(
+                DecimalFormat.FRACTION_FIELD);
+        decimalFmt.format(value, result, fractionPos);
+        writeInteger(result, output, integerSpecials, mods, integerCommas);
+        writeFractional(result, output);
+
+        /*
+        * Exponent sign handling is complex.
+        *
+        * In DecimalFormat, you never put the sign in the format, and the sign only
+        * comes out of the format if it is negative.
+        *
+        * In Excel, you always say whether to always show the sign ("e+") or only
+        * show negative signs ("e-").
+        *
+        * Also in Excel, where you put the sign in the format is NOT where it comes
+        * out in the result.  In the format, the sign goes with the "e"; in the
+        * output it goes with the exponent value.  That is, if you say "#e-|#" you
+        * get "1e|-5", not "1e-|5". This makes sense I suppose, but it complicates
+        * things.
+        *
+        * Finally, everything else in this formatting code assumes that the base of
+        * the result is the original format, and that starting from that situation,
+        * the indexes of the original special characters can be used to place the new
+        * characters.  As just described, this is not true for the exponent's sign.
+        * <p/>
+        * So here is how we handle it:
+        *
+        * (1) When parsing the format, remove the sign from after the 'e' and put it
+        * before the first digit of the exponent (where it will be shown).
+        *
+        * (2) Determine the result's sign.
+        *
+        * (3) If it's missing, put the sign into the output to keep the result
+        * lined up with the output. (In the result, "after the 'e'" and "before the
+        * first digit" are the same because the result has no extra chars to be in
+        * the way.)
+        *
+        * (4) In the output, remove the sign if it should not be shown ("e-" was used
+        * and the sign is negative) or set it to the correct value.
+        */
+
+        // (2) Determine the result's sign.
+        int ePos = fractionPos.getEndIndex();
+        int signPos = ePos + 1;
+        char expSignRes = result.charAt(signPos);
+        if (expSignRes != '-') {
+            // not a sign, so it's a digit, and therefore a positive exponent
+            expSignRes = '+';
+            // (3) If it's missing, put the sign into the output to keep the result
+            // lined up with the output.
+            result.insert(signPos, '+');
+        }
+
+        // Now the result lines up like it is supposed to with the specials' indexes
+        ListIterator<Special> it = exponentSpecials.listIterator(1);
+        Special expSign = it.next();
+        char expSignFmt = expSign.ch;
+
+        // (4) In the output, remove the sign if it should not be shown or set it to
+        // the correct value.
+        if (expSignRes == '-' || expSignFmt == '+')
+            mods.add(replaceMod(expSign, true, expSign, true, expSignRes));
+        else
+            mods.add(deleteMod(expSign, true, expSign, true));
+
+        StringBuffer exponentNum = new StringBuffer(result.substring(
+                signPos + 1));
+        writeInteger(exponentNum, output, exponentDigitSpecials, mods, false);
+    }
+
+    private void writeFraction(double value, StringBuffer result,
+            double fractional, StringBuffer output, Set<StringMod> mods) {
+
+        // Figure out if we are to suppress either the integer or fractional part.
+        // With # the suppressed part is removed; with ? it is replaced with spaces.
+        if (!improperFraction) {
+            // If fractional part is zero, and numerator doesn't have '0', write out
+            // only the integer part and strip the rest.
+            if (fractional == 0 && !hasChar('0', numeratorSpecials)) {
+                writeInteger(result, output, integerSpecials, mods, false);
+
+                Special start = integerSpecials.get(integerSpecials.size() - 1);
+                Special end = denominatorSpecials.get(
+                        denominatorSpecials.size() - 1);
+                if (hasChar('?', integerSpecials, numeratorSpecials,
+                        denominatorSpecials)) {
+                    //if any format has '?', then replace the fraction with spaces
+                    mods.add(replaceMod(start, false, end, true, ' '));
+                } else {
+                    // otherwise, remove the fraction
+                    mods.add(deleteMod(start, false, end, true));
+                }
+
+                // That's all, just return
+                return;
+            } else {
+                // New we check to see if we should remove the integer part
+                boolean allZero = (value == 0 && fractional == 0);
+                boolean willShowFraction = fractional != 0 || hasChar('0',
+                        numeratorSpecials);
+                boolean removeBecauseZero = allZero && (hasOnly('#',
+                        integerSpecials) || !hasChar('0', numeratorSpecials));
+                boolean removeBecauseFraction =
+                        !allZero && value == 0 && willShowFraction && !hasChar(
+                                '0', integerSpecials);
+                if (removeBecauseZero || removeBecauseFraction) {
+                    Special start = integerSpecials.get(
+                            integerSpecials.size() - 1);
+                    if (hasChar('?', integerSpecials, numeratorSpecials)) {
+                        mods.add(replaceMod(start, true, numerator, false,
+                                ' '));
+                    } else {
+                        mods.add(deleteMod(start, true, numerator, false));
+                    }
+                } else {
+                    // Not removing the integer part -- print it out
+                    writeInteger(result, output, integerSpecials, mods, false);
+                }
+            }
+        }
+
+        // Calculate and print the actual fraction (improper or otherwise)
+        try {
+            int n;
+            int d;
+            // the "fractional % 1" captures integer values in improper fractions
+            if (fractional == 0 || (improperFraction && fractional % 1 == 0)) {
+                // 0 as a fraction is reported by excel as 0/1
+                n = (int) Math.round(fractional);
+                d = 1;
+            } else {
+                Fraction frac = new Fraction(fractional, maxDenominator);
+                n = frac.getNumerator();
+                d = frac.getDenominator();
+            }
+            if (improperFraction)
+                n += Math.round(value * d);
+            writeSingleInteger(numeratorFmt, n, output, numeratorSpecials,
+                    mods);
+            writeSingleInteger(denominatorFmt, d, output, denominatorSpecials,
+                    mods);
+        } catch (RuntimeException ignored) {
+            ignored.printStackTrace();
+        }
+    }
+
+    private static boolean hasChar(char ch, List<Special>... numSpecials) {
+        for (List<Special> specials : numSpecials) {
+            for (Special s : specials) {
+                if (s.ch == ch) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static boolean hasOnly(char ch, List<Special>... numSpecials) {
+        for (List<Special> specials : numSpecials) {
+            for (Special s : specials) {
+                if (s.ch != ch) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    private void writeSingleInteger(String fmt, int num, StringBuffer output,
+            List<Special> numSpecials, Set<StringMod> mods) {
+
+        StringBuffer sb = new StringBuffer();
+        Formatter formatter = new Formatter(sb);
+        formatter.format(LOCALE, fmt, num);
+        writeInteger(sb, output, numSpecials, mods, false);
+    }
+
+    private void writeInteger(StringBuffer result, StringBuffer output,
+            List<Special> numSpecials, Set<StringMod> mods,
+            boolean showCommas) {
+
+        int pos = result.indexOf(".") - 1;
+        if (pos < 0) {
+            if (exponent != null && numSpecials == integerSpecials)
+                pos = result.indexOf("E") - 1;
+            else
+                pos = result.length() - 1;
+        }
+
+        int strip;
+        for (strip = 0; strip < pos; strip++) {
+            char resultCh = result.charAt(strip);
+            if (resultCh != '0' && resultCh != ',')
+                break;
+        }
+
+        ListIterator<Special> it = numSpecials.listIterator(numSpecials.size());
+        boolean followWithComma = false;
+        Special lastOutputIntegerDigit = null;
+        int digit = 0;
+        while (it.hasPrevious()) {
+            char resultCh;
+            if (pos >= 0)
+                resultCh = result.charAt(pos);
+            else {
+                // If result is shorter than field, pretend there are leading zeros
+                resultCh = '0';
+            }
+            Special s = it.previous();
+            followWithComma = showCommas && digit > 0 && digit % 3 == 0;
+            boolean zeroStrip = false;
+            if (resultCh != '0' || s.ch == '0' || s.ch == '?' || pos >= strip) {
+                zeroStrip = s.ch == '?' && pos < strip;
+                output.setCharAt(s.pos, (zeroStrip ? ' ' : resultCh));
+                lastOutputIntegerDigit = s;
+            }
+            if (followWithComma) {
+                mods.add(insertMod(s, zeroStrip ? " " : ",", StringMod.AFTER));
+                followWithComma = false;
+            }
+            digit++;
+            --pos;
+        }
+        StringBuffer extraLeadingDigits = new StringBuffer();
+        if (pos >= 0) {
+            // We ran out of places to put digits before we ran out of digits; put this aside so we can add it later
+            ++pos;  // pos was decremented at the end of the loop above when the iterator was at its end
+            extraLeadingDigits = new StringBuffer(result.substring(0, pos));
+            if (showCommas) {
+                while (pos > 0) {
+                    if (digit > 0 && digit % 3 == 0)
+                        extraLeadingDigits.insert(pos, ',');
+                    digit++;
+                    --pos;
+                }
+            }
+            mods.add(insertMod(lastOutputIntegerDigit, extraLeadingDigits,
+                    StringMod.BEFORE));
+        }
+    }
+
+    private void writeFractional(StringBuffer result, StringBuffer output) {
+        int digit;
+        int strip;
+        ListIterator<Special> it;
+        if (fractionalSpecials.size() > 0) {
+            digit = result.indexOf(".") + 1;
+            if (exponent != null)
+                strip = result.indexOf("e") - 1;
+            else
+                strip = result.length() - 1;
+            while (strip > digit && result.charAt(strip) == '0')
+                strip--;
+            it = fractionalSpecials.listIterator();
+            while (it.hasNext()) {
+                Special s = it.next();
+                char resultCh = result.charAt(digit);
+                if (resultCh != '0' || s.ch == '0' || digit < strip)
+                    output.setCharAt(s.pos, resultCh);
+                else if (s.ch == '?') {
+                    // This is when we're in trailing zeros, and the format is '?'.  We still strip out remaining '#'s later
+                    output.setCharAt(s.pos, ' ');
+                }
+                digit++;
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * For a number, this is <tt>"#"</tt> for integer values, and <tt>"#.#"</tt>
+     * for floating-point values.
+     */
+    public void simpleValue(StringBuffer toAppendTo, Object value) {
+        SIMPLE_NUMBER.formatValue(toAppendTo, value);
+    }
+
+    /**
+     *  Based on org.apache.commons.math.fraction.Fraction from Apache Commons-Math.
+     *  YK: The only reason of having this inner class is to avoid dependency on the Commons-Math jar.
+     */
+    private static class Fraction {
+        /** The denominator. */
+        private final int denominator;
+
+        /** The numerator. */
+        private final int numerator;
+
+        /**
+         * Create a fraction given the double value and either the maximum error
+         * allowed or the maximum number of denominator digits.
+         *
+         * @param value the double value to convert to a fraction.
+         * @param epsilon maximum error allowed.  The resulting fraction is within
+         *        <code>epsilon</code> of <code>value</code>, in absolute terms.
+         * @param maxDenominator maximum denominator value allowed.
+         * @param maxIterations maximum number of convergents
+         * @throws RuntimeException if the continued fraction failed to
+         *         converge.
+         */
+        private Fraction(double value, double epsilon, int maxDenominator, int maxIterations)
+        {
+            long overflow = Integer.MAX_VALUE;
+            double r0 = value;
+            long a0 = (long)Math.floor(r0);
+            if (a0 > overflow) {
+                throw new IllegalArgumentException("Overflow trying to convert "+value+" to fraction ("+a0+"/"+1l+")");
+            }
+
+            // check for (almost) integer arguments, which should not go
+            // to iterations.
+            if (Math.abs(a0 - value) < epsilon) {
+                this.numerator = (int) a0;
+                this.denominator = 1;
+                return;
+            }
+
+            long p0 = 1;
+            long q0 = 0;
+            long p1 = a0;
+            long q1 = 1;
+
+            long p2;
+            long q2;
+
+            int n = 0;
+            boolean stop = false;
+            do {
+                ++n;
+                double r1 = 1.0 / (r0 - a0);
+                long a1 = (long)Math.floor(r1);
+                p2 = (a1 * p1) + p0;
+                q2 = (a1 * q1) + q0;
+                if ((p2 > overflow) || (q2 > overflow)) {
+                    throw new RuntimeException("Overflow trying to convert "+value+" to fraction ("+p2+"/"+q2+")");
+                }
+
+                double convergent = (double)p2 / (double)q2;
+                if (n < maxIterations && Math.abs(convergent - value) > epsilon && q2 < maxDenominator) {
+                    p0 = p1;
+                    p1 = p2;
+                    q0 = q1;
+                    q1 = q2;
+                    a0 = a1;
+                    r0 = r1;
+                } else {
+                    stop = true;
+                }
+            } while (!stop);
+
+            if (n >= maxIterations) {
+                throw new RuntimeException("Unable to convert "+value+" to fraction after "+maxIterations+" iterations");
+            }
+
+            if (q2 < maxDenominator) {
+                this.numerator = (int) p2;
+                this.denominator = (int) q2;
+            } else {
+                this.numerator = (int) p1;
+                this.denominator = (int) q1;
+            }
+
+        }
+
+        /**
+         * Create a fraction given the double value and maximum denominator.
+         * <p>
+         * References:
+         * <ul>
+         * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
+         * Continued Fraction</a> equations (11) and (22)-(26)</li>
+         * </ul>
+         * </p>
+         * @param value the double value to convert to a fraction.
+         * @param maxDenominator The maximum allowed value for denominator
+         * @throws RuntimeException if the continued fraction failed to
+         *         converge
+         */
+        public Fraction(double value, int maxDenominator)
+        {
+           this(value, 0, maxDenominator, 100);
+        }
+
+        /**
+         * Access the denominator.
+         * @return the denominator.
+         */
+        public int getDenominator() {
+            return denominator;
+        }
+
+        /**
+         * Access the numerator.
+         * @return the numerator.
+         */
+        public int getNumerator() {
+            return numerator;
+        }
+
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellTextFormatter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellTextFormatter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/CellTextFormatter.java	(revision 28000)
@@ -0,0 +1,79 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.format;
+
+import java.util.regex.Matcher;
+
+import org.apache.poi.ss.format.CellFormatPart.PartHandler;
+
+/**
+ * This class implements printing out text.
+ *
+ * @author Ken Arnold, Industrious Media LLC
+ */
+public class CellTextFormatter extends CellFormatter {
+    private final int[] textPos;
+    private final String desc;
+
+    static final CellFormatter SIMPLE_TEXT = new CellTextFormatter("@");
+
+    public CellTextFormatter(String format) {
+        super(format);
+
+        final int[] numPlaces = new int[1];
+
+        desc = CellFormatPart.parseFormat(format, CellFormatType.TEXT,
+                new PartHandler() {
+                    public String handlePart(Matcher m, String part,
+                            CellFormatType type, StringBuffer desc) {
+                        if (part.equals("@")) {
+                            numPlaces[0]++;
+                            return "\u0000";
+                        }
+                        return null;
+                    }
+                }).toString();
+
+        // Remember the "@" positions in last-to-first order (to make insertion easier)
+        textPos = new int[numPlaces[0]];
+        int pos = desc.length() - 1;
+        for (int i = 0; i < textPos.length; i++) {
+            textPos[i] = desc.lastIndexOf("\u0000", pos);
+            pos = textPos[i] - 1;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void formatValue(StringBuffer toAppendTo, Object obj) {
+        int start = toAppendTo.length();
+        String text = obj.toString();
+        toAppendTo.append(desc);
+        for (int i = 0; i < textPos.length; i++) {
+            int pos = start + textPos[i];
+            toAppendTo.replace(pos, pos + 1, text);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * For text, this is just printing the text.
+     */
+    public void simpleValue(StringBuffer toAppendTo, Object value) {
+        SIMPLE_TEXT.formatValue(toAppendTo, value);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/format/package.html	(revision 28000)
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body>
+This package contains classes that implement cell formatting
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/EvaluationWorkbook.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/EvaluationWorkbook.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/EvaluationWorkbook.java	(revision 28000)
@@ -0,0 +1,46 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.formula;
+
+
+/**
+ * Abstracts a workbook for the purpose of formula evaluation.<br/>
+ *
+ * For POI internal use only
+ *
+ * @author Josh Micich
+ */
+public interface EvaluationWorkbook {
+
+
+	class ExternalSheet {
+		private final String _workbookName;
+		private final String _sheetName;
+
+		public ExternalSheet(String workbookName, String sheetName) {
+			_workbookName = workbookName;
+			_sheetName = sheetName;
+		}
+		public String getWorkbookName() {
+			return _workbookName;
+		}
+		public String getSheetName() {
+			return _sheetName;
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/ExternSheetReferenceToken.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/ExternSheetReferenceToken.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/ExternSheetReferenceToken.java	(revision 28000)
@@ -0,0 +1,30 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.formula;
+
+/**
+ * Should be implemented by any {@link org.apache.poi.hssf.record.formula.Ptg} subclass that needs has an extern sheet index <br/>
+ *
+ * For POI internal use only
+ *
+ * @author Josh Micich
+ */
+public interface ExternSheetReferenceToken {
+	int getExternSheetIndex();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/Formula.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/Formula.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/Formula.java	(revision 28000)
@@ -0,0 +1,168 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.formula;
+
+import org.apache.poi.hssf.record.ArrayRecord;
+import org.apache.poi.hssf.record.SharedFormulaRecord;
+import org.apache.poi.hssf.record.TableRecord;
+import org.apache.poi.hssf.record.formula.ExpPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.TblPtg;
+import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianByteArrayInputStream;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Encapsulates an encoded formula token array.
+ *
+ * @author Josh Micich
+ */
+public class Formula {
+
+	private static final Formula EMPTY = new Formula(new byte[0], 0);
+
+	/** immutable */
+	private final byte[] _byteEncoding;
+	private final int _encodedTokenLen;
+
+	private Formula(byte[] byteEncoding, int encodedTokenLen) {
+		_byteEncoding = byteEncoding;
+		_encodedTokenLen = encodedTokenLen;
+	}
+
+	/**
+	 * Convenience method for {@link #read(int, LittleEndianInput, int)}
+	 */
+	public static Formula read(int encodedTokenLen, LittleEndianInput in) {
+		return read(encodedTokenLen, in, encodedTokenLen);
+	}
+	/**
+	 * When there are no array constants present, <tt>encodedTokenLen</tt>==<tt>totalEncodedLen</tt>
+	 * @param encodedTokenLen number of bytes in the stream taken by the plain formula tokens
+	 * @param totalEncodedLen the total number of bytes in the formula (includes trailing encoding
+	 * for array constants, but does not include 2 bytes for initial <tt>ushort encodedTokenLen</tt> field.
+	 * @return A new formula object as read from the stream.  Possibly empty, never <code>null</code>.
+	 */
+	public static Formula read(int encodedTokenLen, LittleEndianInput in, int totalEncodedLen) {
+		byte[] byteEncoding = new byte[totalEncodedLen];
+		in.readFully(byteEncoding);
+		return new Formula(byteEncoding, encodedTokenLen);
+	}
+
+	public Ptg[] getTokens() {
+		LittleEndianInput in = new LittleEndianByteArrayInputStream(_byteEncoding);
+		return Ptg.readTokens(_encodedTokenLen, in);
+	}
+	/**
+	 * Writes  The formula encoding is includes:
+	 * <ul>
+	 * <li>ushort tokenDataLen</li>
+	 * <li>tokenData</li>
+	 * <li>arrayConstantData (if present)</li>
+	 * </ul>
+	 */
+	public void serialize(LittleEndianOutput out) {
+		out.writeShort(_encodedTokenLen);
+		out.write(_byteEncoding);
+	}
+
+	public void serializeTokens(LittleEndianOutput out) {
+		out.write(_byteEncoding, 0, _encodedTokenLen);
+	}
+	public void serializeArrayConstantData(LittleEndianOutput out) {
+		int len = _byteEncoding.length-_encodedTokenLen;
+		out.write(_byteEncoding, _encodedTokenLen, len);
+	}
+
+
+	/**
+	 * @return total formula encoding length.  The formula encoding includes:
+	 * <ul>
+	 * <li>ushort tokenDataLen</li>
+	 * <li>tokenData</li>
+	 * <li>arrayConstantData (optional)</li>
+	 * </ul>
+	 * Note - this value is different to <tt>tokenDataLength</tt>
+	 */
+	public int getEncodedSize() {
+		return 2 + _byteEncoding.length;
+	}
+	/**
+	 * This method is often used when the formula length does not appear immediately before
+	 * the encoded token data.
+	 *
+	 * @return the encoded length of the plain formula tokens.  This does <em>not</em> include
+	 * the leading ushort field, nor any trailing array constant data.
+	 */
+	public int getEncodedTokenSize() {
+		return _encodedTokenLen;
+	}
+
+	/**
+	 * Creates a {@link Formula} object from a supplied {@link Ptg} array.
+	 * Handles <code>null</code>s OK.
+	 * @param ptgs may be <code>null</code>
+	 * @return Never <code>null</code> (Possibly empty if the supplied <tt>ptgs</tt> is <code>null</code>)
+	 */
+	public static Formula create(Ptg[] ptgs) {
+		if (ptgs == null || ptgs.length < 1) {
+			return EMPTY;
+		}
+		int totalSize = Ptg.getEncodedSize(ptgs);
+		byte[] encodedData = new byte[totalSize];
+		Ptg.serializePtgs(ptgs, encodedData, 0);
+		int encodedTokenLen = Ptg.getEncodedSizeWithoutArrayData(ptgs);
+		return new Formula(encodedData, encodedTokenLen);
+	}
+
+	public Formula copy() {
+		// OK to return this because immutable
+		return this;
+	}
+
+	/**
+	 * Gets the locator for the corresponding {@link SharedFormulaRecord}, {@link ArrayRecord} or
+	 * {@link TableRecord} if this formula belongs to such a grouping.  The {@link CellReference}
+	 * returned by this method will  match the top left corner of the range of that grouping.
+	 * The return value is usually not the same as the location of the cell containing this formula.
+	 *
+	 * @return the firstRow & firstColumn of an array formula or shared formula that this formula
+	 * belongs to.  <code>null</code> if this formula is not part of an array or shared formula.
+	 */
+	public CellReference getExpReference() {
+		byte[] data = _byteEncoding;
+		if (data.length != 5) {
+			// tExp and tTbl are always 5 bytes long, and the only ptg in the formula
+			return null;
+		}
+		switch (data[0]) {
+			case ExpPtg.sid:
+				break;
+			case TblPtg.sid:
+				break;
+			default:
+				return null;
+		}
+		int firstRow = LittleEndian.getUShort(data, 1);
+		int firstColumn = LittleEndian.getUShort(data, 3);
+		return new CellReference(firstRow, firstColumn);
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/FormulaRenderer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/FormulaRenderer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/FormulaRenderer.java	(revision 28000)
@@ -0,0 +1,131 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.formula;
+
+import java.util.Stack;
+
+import org.apache.poi.hssf.record.formula.AttrPtg;
+import org.apache.poi.hssf.record.formula.MemAreaPtg;
+import org.apache.poi.hssf.record.formula.MemErrPtg;
+import org.apache.poi.hssf.record.formula.MemFuncPtg;
+import org.apache.poi.hssf.record.formula.OperationPtg;
+import org.apache.poi.hssf.record.formula.ParenthesisPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+
+/**
+ * Common logic for rendering formulas.<br/>
+ *
+ * For POI internal use only
+ *
+ * @author Josh Micich
+ */
+public class FormulaRenderer {
+
+    /**
+     * Static method to convert an array of {@link Ptg}s in RPN order
+     * to a human readable string format in infix mode.
+     * @param book  used for defined names and 3D references
+     * @param ptgs  must not be <code>null</code>
+     * @return a human readable String
+     */
+    public static String toFormulaString(FormulaRenderingWorkbook book, Ptg[] ptgs) {
+        if (ptgs == null || ptgs.length == 0) {
+            throw new IllegalArgumentException("ptgs must not be null");
+        }
+        Stack<String> stack = new Stack<String>();
+
+        for (int i=0 ; i < ptgs.length; i++) {
+            Ptg ptg = ptgs[i];
+            // TODO - what about MemNoMemPtg?
+            if(ptg instanceof MemAreaPtg || ptg instanceof MemFuncPtg || ptg instanceof MemErrPtg) {
+                // marks the start of a list of area expressions which will be naturally combined
+                // by their trailing operators (e.g. UnionPtg)
+                // TODO - put comment and throw exception in toFormulaString() of these classes
+                continue;
+            }
+            if (ptg instanceof ParenthesisPtg) {
+                String contents = stack.pop();
+                stack.push ("(" + contents + ")");
+                continue;
+            }
+            if (ptg instanceof AttrPtg) {
+                AttrPtg attrPtg = ((AttrPtg) ptg);
+                if (attrPtg.isOptimizedIf() || attrPtg.isOptimizedChoose() || attrPtg.isSkip()) {
+                    continue;
+                }
+                if (attrPtg.isSpace()) {
+                    // POI currently doesn't render spaces in formulas
+                    continue;
+                    // but if it ever did, care must be taken:
+                    // tAttrSpace comes *before* the operand it applies to, which may be consistent
+                    // with how the formula text appears but is against the RPN ordering assumed here
+                }
+                if (attrPtg.isSemiVolatile()) {
+                    // similar to tAttrSpace - RPN is violated
+                    continue;
+                }
+                if (attrPtg.isSum()) {
+                    String[] operands = getOperands(stack, attrPtg.getNumberOfOperands());
+                    stack.push(attrPtg.toFormulaString(operands));
+                    continue;
+                }
+                throw new RuntimeException("Unexpected tAttr: " + attrPtg.toString());
+            }
+
+            if (ptg instanceof WorkbookDependentFormula) {
+                WorkbookDependentFormula optg = (WorkbookDependentFormula) ptg;
+                stack.push(optg.toFormulaString(book));
+                continue;
+            }
+            if (! (ptg instanceof OperationPtg)) {
+                stack.push(ptg.toFormulaString());
+                continue;
+            }
+
+            OperationPtg o = (OperationPtg) ptg;
+            String[] operands = getOperands(stack, o.getNumberOfOperands());
+            stack.push(o.toFormulaString(operands));
+        }
+        if(stack.isEmpty()) {
+            // inspection of the code above reveals that every stack.pop() is followed by a
+            // stack.push(). So this is either an internal error or impossible.
+            throw new IllegalStateException("Stack underflow");
+        }
+        String result = stack.pop();
+        if(!stack.isEmpty()) {
+            // Might be caused by some tokens like AttrPtg and Mem*Ptg, which really shouldn't
+            // put anything on the stack
+            throw new IllegalStateException("too much stuff left on the stack");
+        }
+        return result;
+    }
+
+    private static String[] getOperands(Stack<String> stack, int nOperands) {
+        String[] operands = new String[nOperands];
+
+        for (int j = nOperands-1; j >= 0; j--) { // reverse iteration because args were pushed in-order
+            if(stack.isEmpty()) {
+               String msg = "Too few arguments supplied to operation. Expected (" + nOperands
+                    + ") operands but got (" + (nOperands - j - 1) + ")";
+                throw new IllegalStateException(msg);
+            }
+            operands[j] = stack.pop();
+        }
+        return operands;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java	(revision 28000)
@@ -0,0 +1,40 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.formula;
+
+import org.apache.poi.hssf.record.formula.NamePtg;
+import org.apache.poi.hssf.record.formula.NameXPtg;
+import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
+
+/**
+ * Abstracts a workbook for the purpose of converting formula to text.<br/>
+ *
+ * For POI internal use only
+ *
+ * @author Josh Micich
+ */
+public interface FormulaRenderingWorkbook {
+
+	/**
+	 * @return <code>null</code> if externSheetIndex refers to a sheet inside the current workbook
+	 */
+	ExternalSheet getExternalSheet(int externSheetIndex);
+	String getSheetNameByExternSheet(int externSheetIndex);
+	String resolveNameXText(NameXPtg nameXPtg);
+	String getNameText(NamePtg namePtg);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/WorkbookDependentFormula.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/WorkbookDependentFormula.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/WorkbookDependentFormula.java	(revision 28000)
@@ -0,0 +1,30 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.formula;
+
+/**
+ * Should be implemented by any {@link org.apache.poi.hssf.record.formula.Ptg} subclass that needs a workbook to render its formula.
+ * <br/>
+ *
+ * For POI internal use only
+ *
+ * @author Josh Micich
+ */
+public interface WorkbookDependentFormula {
+	String toFormulaString(FormulaRenderingWorkbook book);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/formula/package.html	(revision 28000)
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+This package contains common internal POI code for manipulating formulas.
+Client applications should not refer to these classes directly.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/BuiltinFormats.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/BuiltinFormats.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/BuiltinFormats.java	(revision 28000)
@@ -0,0 +1,140 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.usermodel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility to identify built-in formats.  The following is a list of the formats as
+ * returned by this class.<p/>
+ *<p/>
+ *       0, "General"<br/>
+ *       1, "0"<br/>
+ *       2, "0.00"<br/>
+ *       3, "#,##0"<br/>
+ *       4, "#,##0.00"<br/>
+ *       5, "$#,##0_);($#,##0)"<br/>
+ *       6, "$#,##0_);[Red]($#,##0)"<br/>
+ *       7, "$#,##0.00);($#,##0.00)"<br/>
+ *       8, "$#,##0.00_);[Red]($#,##0.00)"<br/>
+ *       9, "0%"<br/>
+ *       0xa, "0.00%"<br/>
+ *       0xb, "0.00E+00"<br/>
+ *       0xc, "# ?/?"<br/>
+ *       0xd, "# ??/??"<br/>
+ *       0xe, "m/d/yy"<br/>
+ *       0xf, "d-mmm-yy"<br/>
+ *       0x10, "d-mmm"<br/>
+ *       0x11, "mmm-yy"<br/>
+ *       0x12, "h:mm AM/PM"<br/>
+ *       0x13, "h:mm:ss AM/PM"<br/>
+ *       0x14, "h:mm"<br/>
+ *       0x15, "h:mm:ss"<br/>
+ *       0x16, "m/d/yy h:mm"<br/>
+ *<p/>
+ *       // 0x17 - 0x24 reserved for international and undocumented
+ *       0x25, "#,##0_);(#,##0)"<br/>
+ *       0x26, "#,##0_);[Red](#,##0)"<br/>
+ *       0x27, "#,##0.00_);(#,##0.00)"<br/>
+ *       0x28, "#,##0.00_);[Red](#,##0.00)"<br/>
+ *       0x29, "_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)"<br/>
+ *       0x2a, "_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)"<br/>
+ *       0x2b, "_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)"<br/>
+ *       0x2c, "_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)"<br/>
+ *       0x2d, "mm:ss"<br/>
+ *       0x2e, "[h]:mm:ss"<br/>
+ *       0x2f, "mm:ss.0"<br/>
+ *       0x30, "##0.0E+0"<br/>
+ *       0x31, "@" - This is text format.<br/>
+ *       0x31  "text" - Alias for "@"<br/>
+ * <p/>
+ *
+ * @author Yegor Kozlov
+ *
+ * Modified 6/17/09 by Stanislav Shor - positive formats don't need starting '('
+ *
+ */
+public final class BuiltinFormats {
+
+	private final static String[] _formats;
+
+	static {
+		List<String> m = new ArrayList<String>();
+		putFormat(m, 0, "General");
+		putFormat(m, 1, "0");
+		putFormat(m, 2, "0.00");
+		putFormat(m, 3, "#,##0");
+		putFormat(m, 4, "#,##0.00");
+		putFormat(m, 5, "$#,##0_);($#,##0)");
+		putFormat(m, 6, "$#,##0_);[Red]($#,##0)");
+		putFormat(m, 7, "$#,##0.00_);($#,##0.00)");
+		putFormat(m, 8, "$#,##0.00_);[Red]($#,##0.00)");
+		putFormat(m, 9, "0%");
+		putFormat(m, 0xa, "0.00%");
+		putFormat(m, 0xb, "0.00E+00");
+		putFormat(m, 0xc, "# ?/?");
+		putFormat(m, 0xd, "# ??/??");
+		putFormat(m, 0xe, "m/d/yy");
+		putFormat(m, 0xf, "d-mmm-yy");
+		putFormat(m, 0x10, "d-mmm");
+		putFormat(m, 0x11, "mmm-yy");
+		putFormat(m, 0x12, "h:mm AM/PM");
+		putFormat(m, 0x13, "h:mm:ss AM/PM");
+		putFormat(m, 0x14, "h:mm");
+		putFormat(m, 0x15, "h:mm:ss");
+		putFormat(m, 0x16, "m/d/yy h:mm");
+
+		// 0x17 - 0x24 reserved for international and undocumented
+		for (int i=0x17; i<=0x24; i++) {
+			// TODO - one junit relies on these values which seems incorrect
+			putFormat(m, i, "reserved-0x" + Integer.toHexString(i));
+		}
+
+		putFormat(m, 0x25, "#,##0_);(#,##0)");
+		putFormat(m, 0x26, "#,##0_);[Red](#,##0)");
+		putFormat(m, 0x27, "#,##0.00_);(#,##0.00)");
+		putFormat(m, 0x28, "#,##0.00_);[Red](#,##0.00)");
+		putFormat(m, 0x29, "_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)");
+		putFormat(m, 0x2a, "_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)");
+		putFormat(m, 0x2b, "_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)");
+		putFormat(m, 0x2c, "_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)");
+		putFormat(m, 0x2d, "mm:ss");
+		putFormat(m, 0x2e, "[h]:mm:ss");
+		putFormat(m, 0x2f, "mm:ss.0");
+		putFormat(m, 0x30, "##0.0E+0");
+		putFormat(m, 0x31, "@");
+		String[] ss = new String[m.size()];
+		m.toArray(ss);
+		_formats = ss;
+	}
+	private static void putFormat(List<String> m, int index, String value) {
+		if (m.size() != index) {
+			throw new IllegalStateException("index " + index  + " is wrong");
+		}
+		m.add(value);
+	}
+
+
+	/**
+	 * @return array of built-in data formats
+	 */
+	public static String[] getAll() {
+		return _formats.clone();
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/Cell.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/Cell.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/Cell.java	(revision 28000)
@@ -0,0 +1,219 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.usermodel;
+
+import java.util.Date;
+
+import org.apache.poi.ss.util.CellRangeAddress;
+
+/**
+ * High level representation of a cell in a row of a spreadsheet.
+ * <p>
+ * Cells can be numeric, formula-based or string-based (text).  The cell type
+ * specifies this.  String cells cannot conatin numbers and numeric cells cannot
+ * contain strings (at least according to our model).  Client apps should do the
+ * conversions themselves.  Formula cells have the formula string, as well as
+ * the formula result, which can be numeric or string.
+ * </p>
+ * <p>
+ * Cells should have their number (0 based) before being added to a row.
+ * </p>
+ */
+public interface Cell {
+
+    /**
+     * Numeric Cell type (0)
+     * @see #setCellType(int)
+     * @see #getCellType()
+     */
+    public final static int CELL_TYPE_NUMERIC = 0;
+
+    /**
+     * String Cell type (1)
+     * @see #setCellType(int)
+     * @see #getCellType()
+     */
+    public final static int CELL_TYPE_STRING = 1;
+
+    /**
+     * Formula Cell type (2)
+     * @see #setCellType(int)
+     * @see #getCellType()
+     */
+    public final static int CELL_TYPE_FORMULA = 2;
+
+    /**
+     * Blank Cell type (3)
+     * @see #setCellType(int)
+     * @see #getCellType()
+     */
+    public final static int CELL_TYPE_BLANK = 3;
+
+    /**
+     * Boolean Cell type (4)
+     * @see #setCellType(int)
+     * @see #getCellType()
+     */
+    public final static int CELL_TYPE_BOOLEAN = 4;
+
+    /**
+     * Error Cell type (5)
+     * @see #setCellType(int)
+     * @see #getCellType()
+     */
+    public final static int CELL_TYPE_ERROR = 5;
+
+    /**
+     * Returns column index of this cell
+     *
+     * @return zero-based column index of a column in a sheet.
+     */
+    int getColumnIndex();
+
+    /**
+     * Returns row index of a row in the sheet that contains this cell
+     *
+     * @return zero-based row index of a row in the sheet that contains this cell
+     */
+    int getRowIndex();
+
+    /**
+     * Returns the sheet this cell belongs to
+     *
+     * @return the sheet this cell belongs to
+     */
+    Sheet getSheet();
+
+    /**
+     * Returns the Row this cell belongs to
+     *
+     * @return the Row that owns this cell
+     */
+     Row getRow();
+
+    /**
+     * Set the cells type (numeric, formula or string)
+     *
+     * @throws IllegalArgumentException if the specified cell type is invalid
+     * @see #CELL_TYPE_NUMERIC
+     * @see #CELL_TYPE_STRING
+     * @see #CELL_TYPE_FORMULA
+     * @see #CELL_TYPE_BLANK
+     * @see #CELL_TYPE_BOOLEAN
+     * @see #CELL_TYPE_ERROR
+     */
+    void setCellType(int cellType);
+
+    /**
+     * Return the cell type.
+     *
+     * @return the cell type
+     * @see Cell#CELL_TYPE_BLANK
+     * @see Cell#CELL_TYPE_NUMERIC
+     * @see Cell#CELL_TYPE_STRING
+     * @see Cell#CELL_TYPE_FORMULA
+     * @see Cell#CELL_TYPE_BOOLEAN
+     * @see Cell#CELL_TYPE_ERROR
+     */
+    int getCellType();
+
+    /**
+     * Return a formula for the cell, for example, <code>SUM(C4:E4)</code>
+     *
+     * @return a formula for the cell
+     * @throws IllegalStateException if the cell type returned by {@link #getCellType()} is not CELL_TYPE_FORMULA
+     */
+    String getCellFormula();
+
+    /**
+     * Get the value of the cell as a number.
+     * <p>
+     * For strings we throw an exception. For blank cells we return a 0.
+     * For formulas or error cells we return the precalculated value;
+     * </p>
+     * @return the value of the cell as a number
+     * @throws IllegalStateException if the cell type returned by {@link #getCellType()} is CELL_TYPE_STRING
+     * @exception NumberFormatException if the cell value isn't a parsable <code>double</code>.
+     * @see DataFormatter for turning this number into a string similar to that which Excel would render this number as.
+     */
+    double getNumericCellValue();
+
+    /**
+     * Get the value of the cell as a date.
+     * <p>
+     * For strings we throw an exception. For blank cells we return a null.
+     * </p>
+     * @return the value of the cell as a date
+     * @throws IllegalStateException if the cell type returned by {@link #getCellType()} is CELL_TYPE_STRING
+     * @exception NumberFormatException if the cell value isn't a parsable <code>double</code>.
+     * @see DataFormatter for formatting  this date into a string similar to how excel does.
+     */
+    Date getDateCellValue();
+
+    /**
+     * Get the value of the cell as a XSSFRichTextString
+     * <p>
+     * For numeric cells we throw an exception. For blank cells we return an empty string.
+     * For formula cells we return the pre-calculated value if a string, otherwise an exception.
+     * </p>
+     * @return the value of the cell as a XSSFRichTextString
+     */
+    RichTextString getRichStringCellValue();
+
+    /**
+     * Get the value of the cell as a string
+     * <p>
+     * For numeric cells we throw an exception. For blank cells we return an empty string.
+     * For formulaCells that are not string Formulas, we throw an exception.
+     * </p>
+     * @return the value of the cell as a string
+     */
+    String getStringCellValue();
+
+    /**
+     * Get the value of the cell as a boolean.
+     * <p>
+     * For strings, numbers, and errors, we throw an exception. For blank cells we return a false.
+     * </p>
+     * @return the value of the cell as a boolean
+     * @throws IllegalStateException if the cell type returned by {@link #getCellType()}
+     *   is not CELL_TYPE_BOOLEAN, CELL_TYPE_BLANK or CELL_TYPE_FORMULA
+     */
+    boolean getBooleanCellValue();
+
+    /**
+     * Return the cell's style.
+     *
+     * @return the cell's style. Always not-null. Default cell style has zero index and can be obtained as
+     * <code>workbook.getCellStyleAt(0)</code>
+     * @see Workbook#getCellStyleAt(short)
+     */
+    CellStyle getCellStyle();
+
+    /**
+     * Only valid for array formula cells
+     *
+     * @return range of the array formula group that the cell belongs to.
+     */
+    CellRangeAddress getArrayFormulaRange();
+
+    /**
+     * @return <code>true</code> if this cell is part of group of cells having a common array formula.
+     */
+    boolean isPartOfArrayFormulaGroup();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/CellRange.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/CellRange.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/CellRange.java	(revision 28000)
@@ -0,0 +1,35 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.usermodel;
+
+import java.util.Iterator;
+
+
+/**
+ * Represents a rectangular region of a {@link Sheet}
+ *
+ * @author Josh Micich
+ */
+public interface CellRange<C extends Cell> extends Iterable<C> {
+
+	/**
+	 * @return an {@link Iterator} over all cells in this range.  Iteration starts
+	 * with all cells in the first row followed by all cells in the next row, etc.
+	 */
+	Iterator<C> iterator();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/CellStyle.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/CellStyle.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/CellStyle.java	(revision 28000)
@@ -0,0 +1,41 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.usermodel;
+
+public interface CellStyle {
+
+    /**
+     * get the index within the Workbook (sequence within the collection of ExtnededFormat objects)
+     * @return unique index number of the underlying record this style represents (probably you don't care
+     *  unless you're comparing which one is which)
+     */
+
+    short getIndex();
+
+    /**
+     * get the index of the format
+     * @see DataFormat
+     */
+    short getDataFormat();
+
+    /**
+     * Get the format string
+     */
+    public String getDataFormatString();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/DataFormat.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/DataFormat.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/DataFormat.java	(revision 28000)
@@ -0,0 +1,29 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.usermodel;
+
+public interface DataFormat {
+   
+
+    /**
+     * get the format string that matches the given format index
+     * @param index of a format
+     * @return string represented at index of format or null if there is not a  format at that index
+     */
+    String getFormat(short index);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/DateUtil.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/DateUtil.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/DateUtil.java	(revision 28000)
@@ -0,0 +1,231 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.usermodel;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.regex.Pattern;
+
+/**
+ * Contains methods for dealing with Excel dates.
+ *
+ * @author  Michael Harhen
+ * @author  Glen Stampoultzis (glens at apache.org)
+ * @author  Dan Sherman (dsherman at isisph.com)
+ * @author  Hack Kampbjorn (hak at 2mba.dk)
+ * @author  Alex Jacoby (ajacoby at gmail.com)
+ * @author  Pavel Krupets (pkrupets at palmtreebusiness dot com)
+ */
+public class DateUtil {
+    protected DateUtil() {
+        // no instances of this class
+    }
+    private static final int SECONDS_PER_MINUTE = 60;
+    private static final int MINUTES_PER_HOUR = 60;
+    private static final int HOURS_PER_DAY = 24;
+    private static final int SECONDS_PER_DAY = (HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
+
+    private static final long   DAY_MILLISECONDS = SECONDS_PER_DAY * 1000L;
+
+    /**
+     * The following patterns are used in {@link #isADateFormat(int, String)}
+     */
+    private static final Pattern date_ptrn1 = Pattern.compile("^\\[\\$\\-.*?\\]");
+    private static final Pattern date_ptrn2 = Pattern.compile("^\\[[a-zA-Z]+\\]");
+    private static final Pattern date_ptrn3 = Pattern.compile("^[yYmMdDhHsS\\-/,. :\"\\\\]+0?[ampAMP/]*$");
+
+    /**
+     *  Given an Excel date with either 1900 or 1904 date windowing,
+     *  converts it to a java.util.Date.
+     *
+     *  NOTE: If the default <code>TimeZone</code> in Java uses Daylight
+     *  Saving Time then the conversion back to an Excel date may not give
+     *  the same value, that is the comparison
+     *  <CODE>excelDate == getExcelDate(getJavaDate(excelDate,false))</CODE>
+     *  is not always true. For example if default timezone is
+     *  <code>Europe/Copenhagen</code>, on 2004-03-28 the minute after
+     *  01:59 CET is 03:00 CEST, if the excel date represents a time between
+     *  02:00 and 03:00 then it is converted to past 03:00 summer time
+     *
+     *  @param date  The Excel date.
+     *  @param use1904windowing  true if date uses 1904 windowing,
+     *   or false if using 1900 date windowing.
+     *  @return Java representation of the date, or null if date is not a valid Excel date
+     *  @see java.util.TimeZone
+     */
+    public static Date getJavaDate(double date, boolean use1904windowing) {
+        if (!isValidExcelDate(date)) {
+            return null;
+        }
+        int wholeDays = (int)Math.floor(date);
+        int millisecondsInDay = (int)((date - wholeDays) * DAY_MILLISECONDS + 0.5);
+        Calendar calendar = new GregorianCalendar(); // using default time-zone
+        setCalendar(calendar, wholeDays, millisecondsInDay, use1904windowing);
+        return calendar.getTime();
+    }
+    public static void setCalendar(Calendar calendar, int wholeDays,
+            int millisecondsInDay, boolean use1904windowing) {
+        int startYear = 1900;
+        int dayAdjust = -1; // Excel thinks 2/29/1900 is a valid date, which it isn't
+        if (use1904windowing) {
+            startYear = 1904;
+            dayAdjust = 1; // 1904 date windowing uses 1/2/1904 as the first day
+        }
+        else if (wholeDays < 61) {
+            // Date is prior to 3/1/1900, so adjust because Excel thinks 2/29/1900 exists
+            // If Excel date == 2/29/1900, will become 3/1/1900 in Java representation
+            dayAdjust = 0;
+        }
+        calendar.set(startYear,0, wholeDays + dayAdjust, 0, 0, 0);
+        calendar.set(GregorianCalendar.MILLISECOND, millisecondsInDay);
+    }
+
+
+    /**
+     * Given a format ID and its format String, will check to see if the
+     *  format represents a date format or not.
+     * Firstly, it will check to see if the format ID corresponds to an
+     *  internal excel date format (eg most US date formats)
+     * If not, it will check to see if the format string only contains
+     *  date formatting characters (ymd-/), which covers most
+     *  non US date formats.
+     *
+     * @param formatIndex The index of the format, eg from ExtendedFormatRecord.getFormatIndex
+     * @param formatString The format string, eg from FormatRecord.getFormatString
+     * @see #isInternalDateFormat(int)
+     */
+    public static boolean isADateFormat(int formatIndex, String formatString) {
+        // First up, is this an internal date format?
+        if(isInternalDateFormat(formatIndex)) {
+            return true;
+        }
+
+        // If we didn't get a real string, it can't be
+        if(formatString == null || formatString.length() == 0) {
+            return false;
+        }
+
+        String fs = formatString;
+        StringBuilder sb = new StringBuilder(fs.length());
+        for (int i = 0; i < fs.length(); i++) {
+            char c = fs.charAt(i);
+            if (i < fs.length() - 1) {
+                char nc = fs.charAt(i + 1);
+                if (c == '\\') {
+                    switch (nc) {
+                        case '-':
+                        case ',':
+                        case '.':
+                        case ' ':
+                        case '\\':
+                            // skip current '\' and continue to the next char
+                            continue;
+                    }
+                } else if (c == ';' && nc == '@') {
+                    i++;
+                    // skip ";@" duplets
+                    continue;
+                }
+            }
+            sb.append(c);
+        }
+        fs = sb.toString();
+        
+        // If it starts with [$-...], then could be a date, but
+        //  who knows what that starting bit is all about
+        fs = date_ptrn1.matcher(fs).replaceAll("");
+        // If it starts with something like [Black] or [Yellow],
+        //  then it could be a date
+        fs = date_ptrn2.matcher(fs).replaceAll("");
+        // You're allowed something like dd/mm/yy;[red]dd/mm/yy
+        //  which would place dates before 1900/1904 in red
+        // For now, only consider the first one
+        if(fs.indexOf(';') > 0 && fs.indexOf(';') < fs.length()-1) {
+           fs = fs.substring(0, fs.indexOf(';'));
+        }
+
+        // Otherwise, check it's only made up, in any case, of:
+        //  y m d h s - \ / , . :
+        // optionally followed by AM/PM
+        return date_ptrn3.matcher(fs).matches();
+    }
+
+    /**
+     * Given a format ID this will check whether the format represents
+     *  an internal excel date format or not.
+     * @see #isADateFormat(int, java.lang.String)
+     */
+    public static boolean isInternalDateFormat(int format) {
+            switch(format) {
+                // Internal Date Formats as described on page 427 in
+                // Microsoft Excel Dev's Kit...
+                case 0x0e:
+                case 0x0f:
+                case 0x10:
+                case 0x11:
+                case 0x12:
+                case 0x13:
+                case 0x14:
+                case 0x15:
+                case 0x16:
+                case 0x2d:
+                case 0x2e:
+                case 0x2f:
+                    return true;
+            }
+       return false;
+    }
+
+    /**
+     *  Check if a cell contains a date
+     *  Since dates are stored internally in Excel as double values
+     *  we infer it is a date if it is formatted as such.
+     *  @see #isADateFormat(int, String)
+     *  @see #isInternalDateFormat(int)
+     */
+    public static boolean isCellDateFormatted(Cell cell) {
+        if (cell == null) return false;
+        boolean bDate = false;
+
+        double d = cell.getNumericCellValue();
+        if ( DateUtil.isValidExcelDate(d) ) {
+            CellStyle style = cell.getCellStyle();
+            if(style==null) return false;
+            int i = style.getDataFormat();
+            String f = style.getDataFormatString();
+            bDate = isADateFormat(i, f);
+        }
+        return bDate;
+    }
+    
+
+
+    /**
+     * Given a double, checks if it is a valid Excel date.
+     *
+     * @return true if valid
+     * @param  value the double value
+     */
+
+    public static boolean isValidExcelDate(double value)
+    {
+        return (value > -Double.MIN_VALUE);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/ErrorConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/ErrorConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/ErrorConstants.java	(revision 28000)
@@ -0,0 +1,82 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.usermodel;
+
+/**
+ * Contains raw Excel error codes (as defined in OOO's excelfileformat.pdf (2.5.6)
+ * 
+ * @author  Michael Harhen
+ */
+public class ErrorConstants {
+    protected ErrorConstants() {
+        // no instances of this class
+    }
+    
+    /** <b>#NULL!</b>  - Intersection of two cell ranges is empty */
+    public static final int ERROR_NULL = 0x00;
+    /** <b>#DIV/0!</b> - Division by zero */
+    public static final int ERROR_DIV_0 = 0x07;
+    /** <b>#VALUE!</b> - Wrong type of operand */
+    public static final int ERROR_VALUE = 0x0F; 
+    /** <b>#REF!</b> - Illegal or deleted cell reference */
+    public static final int ERROR_REF = 0x17;  
+    /** <b>#NAME?</b> - Wrong function or range name */
+    public static final int ERROR_NAME = 0x1D; 
+    /** <b>#NUM!</b> - Value range overflow */
+    public static final int ERROR_NUM = 0x24; 
+    /** <b>#N/A</b> - Argument or function not available */
+    public static final int ERROR_NA = 0x2A;
+    
+    
+    /**
+     * @return Standard Excel error literal for the specified error code. 
+     * @throws IllegalArgumentException if the specified error code is not one of the 7 
+     * standard error codes
+     */
+    public static final String getText(int errorCode) {
+        switch(errorCode) {
+            case ERROR_NULL:  return "#NULL!";
+            case ERROR_DIV_0: return "#DIV/0!";
+            case ERROR_VALUE: return "#VALUE!";
+            case ERROR_REF:   return "#REF!";
+            case ERROR_NAME:  return "#NAME?";
+            case ERROR_NUM:   return "#NUM!";
+            case ERROR_NA:    return "#N/A";
+        }
+        throw new IllegalArgumentException("Bad error code (" + errorCode + ")");
+    }
+    
+    /**
+     * @return <code>true</code> if the specified error code is a standard Excel error code. 
+     */
+    public static final boolean isValidCode(int errorCode) {
+        // This method exists because it would be bad to force clients to catch 
+        // IllegalArgumentException if there were potential for passing an invalid error code.  
+        switch(errorCode) {
+            case ERROR_NULL:
+            case ERROR_DIV_0:
+            case ERROR_VALUE:
+            case ERROR_REF:
+            case ERROR_NAME:
+            case ERROR_NUM:
+            case ERROR_NA:
+                return true;
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/RichTextString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/RichTextString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/RichTextString.java	(revision 28000)
@@ -0,0 +1,63 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.usermodel;
+
+/**
+ * Rich text unicode string.  These strings can have fonts 
+ *  applied to arbitary parts of the string.
+ *  
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @author Jason Height (jheight at apache.org)
+ */
+public interface RichTextString {
+    
+    /**
+     * Applies a font to the specified characters of a string.
+     *
+     * @param startIndex    The start index to apply the font to (inclusive)
+     * @param endIndex      The end index to apply the font to (exclusive)
+     * @param fontIndex     The font to use.
+     */
+    void applyFont(int startIndex, int endIndex, short fontIndex);
+
+
+
+    /**
+     * Returns the plain string representation.
+     */
+    String getString();
+
+    /**
+     * @return  the number of characters in the font.
+     */
+    int length();
+
+    /**
+     * @return  The number of formatting runs used.
+     *
+     */
+    int numFormattingRuns();
+
+    /**
+     * The index within the string to which the specified formatting run applies.
+     * @param index     the index of the formatting run
+     * @return  the index within the string.
+     */
+    int getIndexOfFormattingRun(int index);
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/Row.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/Row.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/Row.java	(revision 28000)
@@ -0,0 +1,119 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.usermodel;
+
+import java.util.Iterator;
+
+/**
+ * High level representation of a row of a spreadsheet.
+ */
+public interface Row extends Iterable<Cell> {
+
+    /**
+     * Use this to create new cells within the row and return it.
+     * <p>
+     * The cell that is returned is a {@link Cell#CELL_TYPE_BLANK}. The type can be changed
+     * either through calling <code>setCellValue</code> or <code>setCellType</code>.
+     *
+     * @param column - the column number this cell represents
+     * @return Cell a high level representation of the created cell.
+     * @throws IllegalArgumentException if columnIndex < 0 or greater than the maximum number of supported columns
+     * (255 for *.xls, 1048576 for *.xlsx)
+     */
+    Cell createCell(int column);
+
+    /**
+     * Use this to create new cells within the row and return it.
+     * <p>
+     * The cell that is returned is a {@link Cell#CELL_TYPE_BLANK}. The type can be changed
+     * either through calling setCellValue or setCellType.
+     *
+     * @param column - the column number this cell represents
+     * @return Cell a high level representation of the created cell.
+     * @throws IllegalArgumentException if columnIndex < 0 or greate than a maximum number of supported columns
+     * (255 for *.xls, 1048576 for *.xlsx)
+     */
+    Cell createCell(int column, int type);
+
+    /**
+     * Set the row number of this row.
+     *
+     * @param rowNum  the row number (0-based)
+     * @throws IllegalArgumentException if rowNum < 0
+     */
+    void setRowNum(int rowNum);
+
+    /**
+     * Get row number this row represents
+     *
+     * @return the row number (0 based)
+     */
+    int getRowNum();
+
+    /**
+     * Get the cell representing a given column (logical cell) 0-based.  If you
+     * ask for a cell that is not defined....you get a null.
+     *
+     * @param cellnum  0 based column number
+     * @return Cell representing that column or null if undefined.
+     * @see #getCell(int, org.apache.poi.ss.usermodel.Row.MissingCellPolicy)
+     */
+    Cell getCell(int cellnum);
+    
+    /**
+     * Returns the cell at the given (0 based) index, with the specified {@link org.apache.poi.ss.usermodel.Row.MissingCellPolicy}
+     *
+     * @return the cell at the given (0 based) index
+     * @throws IllegalArgumentException if cellnum < 0 or the specified MissingCellPolicy is invalid
+     * @see Row#RETURN_NULL_AND_BLANK
+     * @see Row#RETURN_BLANK_AS_NULL
+     * @see Row#CREATE_NULL_AS_BLANK
+     */
+    Cell getCell(int cellnum, MissingCellPolicy policy);
+
+    /**
+     * @return Cell iterator of the physically defined cells.  Note element 4 may
+     * actually be row cell depending on how many are defined!
+     */
+    Iterator<Cell> cellIterator();
+
+    /**
+     * Returns the Sheet this row belongs to
+     *
+     * @return the Sheet that owns this row
+     */
+    Sheet getSheet();
+
+    /**
+     * Used to specify the different possible policies
+     *  if for the case of null and blank cells
+     */
+    public static final class MissingCellPolicy {
+    	private static int NEXT_ID = 1;
+    	public final int id;
+    	private MissingCellPolicy() {
+    		this.id = NEXT_ID++;
+    	}
+    }
+    /** Missing cells are returned as null, Blank cells are returned as normal */
+    public static final MissingCellPolicy RETURN_NULL_AND_BLANK = new MissingCellPolicy();
+    /** Missing cells are returned as null, as are blank cells */
+    public static final MissingCellPolicy RETURN_BLANK_AS_NULL = new MissingCellPolicy();
+    /** A new, blank cell is created for missing cells. Blank cells are returned as normal */
+    public static final MissingCellPolicy CREATE_NULL_AS_BLANK = new MissingCellPolicy();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/Sheet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/Sheet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/Sheet.java	(revision 28000)
@@ -0,0 +1,84 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.usermodel;
+
+import java.util.Iterator;
+
+/**
+ * High level representation of a Excel worksheet.
+ *
+ * <p>
+ * Sheets are the central structures within a workbook, and are where a user does most of his spreadsheet work.
+ * The most common type of sheet is the worksheet, which is represented as a grid of cells. Worksheet cells can
+ * contain text, numbers, dates, and formulas. Cells can also be formatted.
+ * </p>
+ */
+public interface Sheet extends Iterable<Row> {
+
+    /**
+     * Create a new row within the sheet and return the high level representation
+     *
+     * @param rownum  row number
+     * @return high level Row object representing a row in the sheet
+     * @see #removeRow(Row)
+     */
+    Row createRow(int rownum);
+
+    /**
+     * Returns the logical row (not physical) 0-based.  If you ask for a row that is not
+     * defined you get a null.  This is to say row 4 represents the fifth row on a sheet.
+     *
+     * @param rownum  row to get (0-based)
+     * @return Row representing the rownumber or null if its not defined on the sheet
+     */
+    Row getRow(int rownum);
+
+
+    /**
+     * Gets the first row on the sheet
+     *
+     * @return the number of the first logical row on the sheet (0-based)
+     */
+    int getFirstRowNum();
+
+    /**
+     * Gets the last row on the sheet
+     *
+     * @return last row contained n this sheet (0-based)
+     */
+    int getLastRowNum();
+
+    /**
+     *  Returns an iterator of the physical rows
+     *
+     * @return an iterator of the PHYSICAL rows.  Meaning the 3rd element may not
+     * be the third row if say for instance the second row is undefined.
+     */
+    Iterator<Row> rowIterator();
+
+
+    /**
+     * Remove a Array Formula from this sheet.  All cells contained in the Array Formula range are removed as well
+     *
+     * @param cell   any cell within Array Formula range
+     * @return the {@link CellRange} of cells affected by this change
+     */
+    CellRange<? extends Cell> removeArrayFormula(Cell cell);
+    
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/Workbook.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/Workbook.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/usermodel/Workbook.java	(revision 28000)
@@ -0,0 +1,51 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.usermodel;
+
+import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
+
+/**
+ * High level representation of a Excel workbook.  This is the first object most users
+ * will construct whether they are reading or writing a workbook.  It is also the
+ * top level object for creating new sheets/etc.
+ */
+public interface Workbook {
+
+
+    /**
+     * Get the Sheet object at the given index.
+     *
+     * @param index of the sheet number (0-based physical & logical)
+     * @return Sheet at the provided index
+     */
+    Sheet getSheetAt(int index);
+
+
+
+	/**
+	 * Retrieves the current policy on what to do when
+	 *  getting missing or blank cells from a row.
+     * <p>
+	 * The default is to return blank and null cells.
+	 *  {@link MissingCellPolicy}
+     * </p>
+	 */
+	MissingCellPolicy getMissingCellPolicy();
+
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/AreaReference.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/AreaReference.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/AreaReference.java	(revision 28000)
@@ -0,0 +1,137 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.util;
+
+import org.apache.poi.ss.SpreadsheetVersion;
+
+public class AreaReference {
+
+    /** The character (:) that separates the two cell references in a multi-cell area reference */
+    private static final char CELL_DELIMITER = ':';
+    
+    private final CellReference _firstCell;
+    private final CellReference _lastCell;
+    private final boolean _isSingleCell;
+    
+    /**
+     * Creates an area ref from a pair of Cell References.
+     */
+    public AreaReference(CellReference topLeft, CellReference botRight) {
+        boolean swapRows = topLeft.getRow() > botRight.getRow();
+        boolean swapCols = topLeft.getCol() > botRight.getCol();
+        if (swapRows || swapCols) {
+            int firstRow; 
+            int lastRow; 
+            int firstColumn; 
+            int lastColumn;
+            boolean firstRowAbs; 
+            boolean lastRowAbs; 
+            boolean firstColAbs;
+            boolean lastColAbs;   
+            if (swapRows) {
+                firstRow = botRight.getRow();
+                firstRowAbs = botRight.isRowAbsolute();
+                lastRow = topLeft.getRow();
+                lastRowAbs = topLeft.isRowAbsolute();
+            } else {
+                firstRow = topLeft.getRow();
+                firstRowAbs = topLeft.isRowAbsolute();
+                lastRow = botRight.getRow();
+                lastRowAbs = botRight.isRowAbsolute();
+            }
+            if (swapCols) {
+                firstColumn = botRight.getCol();
+                firstColAbs = botRight.isColAbsolute();
+                lastColumn = topLeft.getCol();
+                lastColAbs = topLeft.isColAbsolute();
+            } else {
+                firstColumn = topLeft.getCol();
+                firstColAbs = topLeft.isColAbsolute();
+                lastColumn = botRight.getCol();
+                lastColAbs = botRight.isColAbsolute();
+            }
+            _firstCell = new CellReference(firstRow, firstColumn, firstRowAbs, firstColAbs);
+            _lastCell = new CellReference(lastRow, lastColumn, lastRowAbs, lastColAbs);
+        } else {
+            _firstCell = topLeft;
+            _lastCell = botRight;
+        }
+        _isSingleCell = false;
+    }
+
+
+    /**
+     * Is the reference for a whole-column reference,
+     *  such as C:C or D:G ?
+     */
+    public static boolean isWholeColumnReference(CellReference topLeft, CellReference botRight) {
+        // These are represented as something like
+        //   C$1:C$65535 or D$1:F$0
+        // i.e. absolute from 1st row to 0th one
+        if(topLeft.getRow() == 0 && topLeft.isRowAbsolute() &&
+            botRight.getRow() == SpreadsheetVersion.EXCEL97.getLastRowIndex() && botRight.isRowAbsolute()) {
+            return true;
+        }
+        return false;
+    }
+    public boolean isWholeColumnReference() {
+        return isWholeColumnReference(_firstCell, _lastCell);
+    }
+    
+    /**
+     *  Example return values:
+     *    <table border="0" cellpadding="1" cellspacing="0" summary="Example return values">
+     *      <tr><th align='left'>Result</th><th align='left'>Comment</th></tr>
+     *      <tr><td>A1:A1</td><td>Single cell area reference without sheet</td></tr>
+     *      <tr><td>A1:$C$1</td><td>Multi-cell area reference without sheet</td></tr>
+     *      <tr><td>Sheet1!A$1:B4</td><td>Standard sheet name</td></tr>
+     *      <tr><td>'O''Brien''s Sales'!B5:C6'&nbsp;</td><td>Sheet name with special characters</td></tr>
+     *    </table>
+     * @return the text representation of this area reference as it would appear in a formula.
+     */
+    public String formatAsString() {
+        // Special handling for whole-column references
+        if(isWholeColumnReference()) {
+            return
+                CellReference.convertNumToColString(_firstCell.getCol())
+                + ":" +
+                CellReference.convertNumToColString(_lastCell.getCol());
+        }
+        
+        StringBuffer sb = new StringBuffer(32);
+        sb.append(_firstCell.formatAsString());
+        if(!_isSingleCell) {
+            sb.append(CELL_DELIMITER);
+            if(_lastCell.getSheetName() == null) {
+                sb.append(_lastCell.formatAsString());
+            } else {
+                // don't want to include the sheet name twice
+                _lastCell.appendCellReference(sb);
+            }
+        }
+        return sb.toString();
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer(64);
+        sb.append(getClass().getName()).append(" [");
+        sb.append(formatAsString());
+        sb.append("]");
+        return sb.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/CellRangeAddress.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/CellRangeAddress.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/CellRangeAddress.java	(revision 28000)
@@ -0,0 +1,87 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.util;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.record.SelectionRecord;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>
+ * 
+ * <p>In the Microsoft documentation, this is also known as a 
+ *  Ref8U - see page 831 of version 1.0 of the documentation.
+ *
+ * Note - {@link SelectionRecord} uses the BIFF5 version of this structure
+ * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
+ */
+public class CellRangeAddress extends CellRangeAddressBase {
+	/*
+	 * TODO - replace  org.apache.poi.hssf.util.Region
+	 */
+	public static final int ENCODED_SIZE = 8;
+
+	public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) {
+		super(firstRow, lastRow, firstCol, lastCol);
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		out.writeShort(getFirstRow());
+		out.writeShort(getLastRow());
+		out.writeShort(getFirstColumn());
+		out.writeShort(getLastColumn());
+	}
+
+	public CellRangeAddress(RecordInputStream in) {
+		super(readUShortAndCheck(in), in.readUShort(), in.readUShort(), in.readUShort());
+	}
+
+	private static int readUShortAndCheck(RecordInputStream in) {
+		if (in.remaining() < ENCODED_SIZE) {
+			// Ran out of data
+			throw new RuntimeException("Ran out of data reading CellRangeAddress");
+		}
+		return in.readUShort();
+	}
+
+	public CellRangeAddress copy() {
+		return new CellRangeAddress(getFirstRow(), getLastRow(), getFirstColumn(), getLastColumn());
+	}
+
+	public static int getEncodedSize(int numberOfItems) {
+		return numberOfItems * ENCODED_SIZE;
+	}
+
+    /**
+     * @return the text format of this range.  Single cell ranges are formatted
+     *         like single cell references (e.g. 'A1' instead of 'A1:A1').
+     */
+    public String formatAsString() {
+        StringBuffer sb = new StringBuffer();
+        CellReference cellRefFrom = new CellReference(getFirstRow(), getFirstColumn());
+        CellReference cellRefTo = new CellReference(getLastRow(), getLastColumn());
+        sb.append(cellRefFrom.formatAsString());
+        //for a single-cell reference return A1 instead of A1:A1
+        if(!cellRefFrom.equals(cellRefTo)){
+            sb.append(':');
+            sb.append(cellRefTo.formatAsString());
+        }
+        return sb.toString();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/CellRangeAddressBase.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/CellRangeAddressBase.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/CellRangeAddressBase.java	(revision 28000)
@@ -0,0 +1,83 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.util;
+
+
+
+/**
+ * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>
+ *
+ * Common subclass of 8-bit and 16-bit versions
+ *
+ * @author Josh Micich
+ */
+public abstract class CellRangeAddressBase {
+
+	private int _firstRow;
+	private int _firstCol;
+	private int _lastRow;
+	private int _lastCol;
+
+	protected CellRangeAddressBase(int firstRow, int lastRow, int firstCol, int lastCol) {
+		_firstRow = firstRow;
+		_lastRow = lastRow;
+		_firstCol = firstCol;
+		_lastCol = lastCol;
+	}
+
+	/**
+	 * @return column number for the upper left hand corner
+	 */
+	public final int getFirstColumn() {
+		return _firstCol;
+	}
+
+	/**
+	 * @return row number for the upper left hand corner
+	 */
+	public final int getFirstRow() {
+		return _firstRow;
+	}
+
+	/**
+	 * @return column number for the lower right hand corner
+	 */
+	public final int getLastColumn() {
+		return _lastCol;
+	}
+
+	/**
+	 * @return row number for the lower right hand corner
+	 */
+	public final int getLastRow() {
+		return _lastRow;
+	}
+
+	/**
+	 * @return the size of the range (number of cells in the area).
+	 */
+	public int getNumberOfCells() {
+		return (_lastRow - _firstRow + 1) * (_lastCol - _firstCol + 1);
+	}
+
+	public final String toString() {
+		CellReference crA = new CellReference(_firstRow, _firstCol);
+		CellReference crB = new CellReference(_lastRow, _lastCol);
+		return getClass().getName() + " [" + crA.formatAsString() + ":" + crB.formatAsString() +"]";
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/CellRangeAddressList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/CellRangeAddressList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/CellRangeAddressList.java	(revision 28000)
@@ -0,0 +1,99 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Implementation of the cell range address lists,like is described
+ * in OpenOffice.org's Excel Documentation: excelfileformat.pdf sec 2.5.14 -
+ * 'Cell Range Address List'
+ * 
+ * In BIFF8 there is a common way to store absolute cell range address lists in
+ * several records (not formulas). A cell range address list consists of a field
+ * with the number of ranges and the list of the range addresses. Each cell
+ * range address (called an ADDR structure) contains 4 16-bit-values.
+ * </p>
+ * 
+ * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
+ */
+public class CellRangeAddressList {
+
+	/**
+	 * List of <tt>CellRangeAddress</tt>es. Each structure represents a cell range
+	 */
+	protected final List<CellRangeAddress> _list;
+
+	public CellRangeAddressList() {
+		_list = new ArrayList<CellRangeAddress>();
+	}
+	/**
+	 * @param in the RecordInputstream to read the record from
+	 */
+	public CellRangeAddressList(RecordInputStream in) {
+		this();
+		int nItems = in.readUShort();
+
+		for (int k = 0; k < nItems; k++) {
+			_list.add(new CellRangeAddress(in));
+		}
+	}
+	/**
+	 * Get the number of following ADDR structures. The number of this
+	 * structures is automatically set when reading an Excel file and/or
+	 * increased when you manually add a new ADDR structure . This is the reason
+	 * there isn't a set method for this field .
+	 * 
+	 * @return number of ADDR structures
+	 */
+	public int countRanges() {
+		return _list.size();
+	}
+
+	/**
+	 * @return <tt>CellRangeAddress</tt> at the given index
+	 */
+	public CellRangeAddress getCellRangeAddress(int index) {
+		return _list.get(index);
+	}
+
+	public int getSize() {
+		return getEncodedSize(_list.size());
+	}
+	/**
+	 * @return the total size of for the specified number of ranges,
+	 *  including the initial 2 byte range count
+	 */
+	public static int getEncodedSize(int numberOfRanges) {
+		return 2 + CellRangeAddress.getEncodedSize(numberOfRanges);
+	}
+
+	public void serialize(LittleEndianOutput out) {
+		int nItems = _list.size();
+		out.writeShort(nItems);
+		for (int k = 0; k < nItems; k++) {
+			CellRangeAddress region = _list.get(k);
+			region.serialize(out);
+		}
+	}
+	
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/CellReference.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/CellReference.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/CellReference.java	(revision 28000)
@@ -0,0 +1,254 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.util;
+
+import org.apache.poi.hssf.record.formula.SheetNameFormatter;
+import org.apache.poi.ss.SpreadsheetVersion;
+import org.apache.poi.ss.usermodel.Cell;
+
+/**
+ *
+ * @author  Avik Sengupta
+ * @author  Dennis Doubleday (patch to seperateRowColumns())
+ */
+public class CellReference {
+
+	/** The character ($) that signifies a row or column value is absolute instead of relative */
+	private static final char ABSOLUTE_REFERENCE_MARKER = '$';
+	/** The character (!) that separates sheet names from cell references */
+	private static final char SHEET_NAME_DELIMITER = '!';
+
+	//private static final String BIFF8_LAST_COLUMN = SpreadsheetVersion.EXCEL97.getLastColumnName();
+	//private static final int BIFF8_LAST_COLUMN_TEXT_LEN = BIFF8_LAST_COLUMN.length();
+	//private static final String BIFF8_LAST_ROW = String.valueOf(SpreadsheetVersion.EXCEL97.getMaxRows());
+	//private static final int BIFF8_LAST_ROW_TEXT_LEN = BIFF8_LAST_ROW.length();
+
+	private final int _rowIndex;
+	private final int _colIndex;
+	private final String _sheetName;
+	private final boolean _isRowAbs;
+	private final boolean _isColAbs;
+
+
+	public CellReference(int pRow, int pCol) {
+		this(pRow, pCol, false, false);
+	}
+	public CellReference(int pRow, short pCol) {
+		this(pRow, pCol & 0xFFFF, false, false);
+	}
+
+	public CellReference(Cell cell) {
+		this(cell.getRowIndex(), cell.getColumnIndex(), false, false);
+	}
+
+	public CellReference(int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) {
+		this(null, pRow, pCol, pAbsRow, pAbsCol);
+	}
+	public CellReference(String pSheetName, int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) {
+		// TODO - "-1" is a special value being temporarily used for whole row and whole column area references.
+		// so these checks are currently N.Q.R.
+		if(pRow < -1) {
+			throw new IllegalArgumentException("row index may not be negative");
+		}
+		if(pCol < -1) {
+			throw new IllegalArgumentException("column index may not be negative");
+		}
+		_sheetName = pSheetName;
+		_rowIndex=pRow;
+		_colIndex=pCol;
+		_isRowAbs = pAbsRow;
+		_isColAbs=pAbsCol;
+	}
+
+	public int getRow(){return _rowIndex;}
+	public short getCol(){return (short) _colIndex;}
+	public boolean isRowAbsolute(){return _isRowAbs;}
+	public boolean isColAbsolute(){return _isColAbs;}
+	/**
+	  * @return possibly <code>null</code> if this is a 2D reference.  Special characters are not
+	  * escaped or delimited
+	  */
+	public String getSheetName(){
+		return _sheetName;
+	}
+
+	/**
+	 * Used to decide whether a name of the form "[A-Z]*[0-9]*" that appears in a formula can be
+	 * interpreted as a cell reference.  Names of that form can be also used for sheets and/or
+	 * named ranges, and in those circumstances, the question of whether the potential cell
+	 * reference is valid (in range) becomes important.
+	 * <p/>
+	 * Note - that the maximum sheet size varies across Excel versions:
+	 * <p/>
+	 * <blockquote><table border="0" cellpadding="1" cellspacing="0"
+	 *                 summary="Notable cases.">
+	 *   <tr><th>Version&nbsp;&nbsp;</th><th>File Format&nbsp;&nbsp;</th>
+	 *   	<th>Last Column&nbsp;&nbsp;</th><th>Last Row</th></tr>
+	 *   <tr><td>97-2003</td><td>BIFF8</td><td>"IV" (2^8)</td><td>65536 (2^14)</td></tr>
+	 *   <tr><td>2007</td><td>BIFF12</td><td>"XFD" (2^14)</td><td>1048576 (2^20)</td></tr>
+	 * </table></blockquote>
+	 * POI currently targets BIFF8 (Excel 97-2003), so the following behaviour can be observed for
+	 * this method:
+	 * <blockquote><table border="0" cellpadding="1" cellspacing="0"
+	 *                 summary="Notable cases.">
+	 *   <tr><th>Input&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</th>
+	 *       <th>Result&nbsp;</th></tr>
+	 *   <tr><td>"A", "1"</td><td>true</td></tr>
+	 *   <tr><td>"a", "111"</td><td>true</td></tr>
+	 *   <tr><td>"A", "65536"</td><td>true</td></tr>
+	 *   <tr><td>"A", "65537"</td><td>false</td></tr>
+	 *   <tr><td>"iv", "1"</td><td>true</td></tr>
+	 *   <tr><td>"IW", "1"</td><td>false</td></tr>
+	 *   <tr><td>"AAA", "1"</td><td>false</td></tr>
+	 *   <tr><td>"a", "111"</td><td>true</td></tr>
+	 *   <tr><td>"Sheet", "1"</td><td>false</td></tr>
+	 * </table></blockquote>
+	 *
+	 * @param colStr a string of only letter characters
+	 * @param rowStr a string of only digit characters
+	 * @return <code>true</code> if the row and col parameters are within range of a BIFF8 spreadsheet.
+	 */
+	public static boolean cellReferenceIsWithinRange(String colStr, String rowStr, SpreadsheetVersion ssVersion) {
+		if (!isColumnWithnRange(colStr, ssVersion)) {
+			return false;
+		}
+		return isRowWithnRange(rowStr, ssVersion);
+	}
+
+	public static boolean isColumnWithnRange(String colStr, SpreadsheetVersion ssVersion) {
+		String lastCol = ssVersion.getLastColumnName();
+		int lastColLength = lastCol.length();
+
+		int numberOfLetters = colStr.length();
+		if(numberOfLetters > lastColLength) {
+			// "Sheet1" case etc
+			return false; // that was easy
+		}
+		if(numberOfLetters == lastColLength) {
+			if(colStr.toUpperCase().compareTo(lastCol) > 0) {
+				return false;
+			}
+		} else {
+			// apparent column name has less chars than max
+			// no need to check range
+		}
+		return true;
+	}
+
+	public static boolean isRowWithnRange(String rowStr, SpreadsheetVersion ssVersion) {
+		int rowNum = Integer.parseInt(rowStr);
+
+		if (rowNum < 0) {
+			throw new IllegalStateException("Invalid rowStr '" + rowStr + "'.");
+		}
+		if (rowNum == 0) {
+			// execution gets here because caller does first pass of discriminating
+			// potential cell references using a simplistic regex pattern.
+			return false;
+		}
+		return rowNum <= ssVersion.getMaxRows();
+	}
+
+	/**
+	 * Takes in a 0-based base-10 column and returns a ALPHA-26
+	 *  representation.
+	 * eg column #3 -> D
+	 */
+	public static String convertNumToColString(int col) {
+		// Excel counts column A as the 1st column, we
+		//  treat it as the 0th one
+		int excelColNum = col + 1;
+
+		String colRef = "";
+		int colRemain = excelColNum;
+
+		while(colRemain > 0) {
+			int thisPart = colRemain % 26;
+			if(thisPart == 0) { thisPart = 26; }
+			colRemain = (colRemain - thisPart) / 26;
+
+			// The letter A is at 65
+			char colChar = (char)(thisPart+64);
+			colRef = colChar + colRef;
+		}
+
+		return colRef;
+	}
+
+	/**
+	 *  Example return values:
+	 *	<table border="0" cellpadding="1" cellspacing="0" summary="Example return values">
+	 *	  <tr><th align='left'>Result</th><th align='left'>Comment</th></tr>
+	 *	  <tr><td>A1</td><td>Cell reference without sheet</td></tr>
+	 *	  <tr><td>Sheet1!A1</td><td>Standard sheet name</td></tr>
+	 *	  <tr><td>'O''Brien''s Sales'!A1'&nbsp;</td><td>Sheet name with special characters</td></tr>
+	 *	</table>
+	 * @return the text representation of this cell reference as it would appear in a formula.
+	 */
+	public String formatAsString() {
+		StringBuffer sb = new StringBuffer(32);
+		if(_sheetName != null) {
+			SheetNameFormatter.appendFormat(sb, _sheetName);
+			sb.append(SHEET_NAME_DELIMITER);
+		}
+		appendCellReference(sb);
+		return sb.toString();
+	}
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer(64);
+		sb.append(getClass().getName()).append(" [");
+		sb.append(formatAsString());
+		sb.append("]");
+		return sb.toString();
+	}
+
+	/**
+	 * Appends cell reference with '$' markers for absolute values as required.
+	 * Sheet name is not included.
+	 */
+	/* package */ void appendCellReference(StringBuffer sb) {
+		if(_isColAbs) {
+			sb.append(ABSOLUTE_REFERENCE_MARKER);
+		}
+		sb.append( convertNumToColString(_colIndex));
+		if(_isRowAbs) {
+			sb.append(ABSOLUTE_REFERENCE_MARKER);
+		}
+		sb.append(_rowIndex+1);
+	}
+
+	/**
+	 * Checks whether this cell reference is equal to another object.
+	 * <p>
+	 *  Two cells references are assumed to be equal if their string representations
+	 *  ({@link #formatAsString()}  are equal.
+	 * </p>
+	 */
+	@Override
+	public boolean equals(Object o){
+		if(!(o instanceof CellReference)) {
+			return false;
+		}
+		CellReference cr = (CellReference) o;
+		return _rowIndex == cr._rowIndex
+			&& _colIndex == cr._colIndex
+			&& _isRowAbs == cr._isColAbs
+			&& _isColAbs == cr._isColAbs;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/ExpandedDouble.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/ExpandedDouble.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/ExpandedDouble.java	(revision 28000)
@@ -0,0 +1,82 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.util;
+
+import static org.apache.poi.ss.util.IEEEDouble.FRAC_ASSUMED_HIGH_BIT;
+import static org.apache.poi.ss.util.IEEEDouble.FRAC_MASK;
+
+import java.math.BigInteger;
+
+/**
+ * Represents a 64 bit IEEE double quantity expressed with both decimal and binary exponents
+ * Does not handle negative numbers or zero
+ * <p/>
+ * The value of a {@link ExpandedDouble} is given by<br/>
+ * <tt> a &times; 2<sup>b</sup></tt>
+ * <br/>
+ * where:<br/>
+ *
+ * <tt>a</tt> = <i>significand</i><br/>
+ * <tt>b</tt> = <i>binaryExponent</i> - bitLength(significand) + 1<br/>
+ *
+ * @author Josh Micich
+ */
+final class ExpandedDouble {
+	private static final BigInteger BI_FRAC_MASK = BigInteger.valueOf(FRAC_MASK);
+	private static final BigInteger BI_IMPLIED_FRAC_MSB = BigInteger.valueOf(FRAC_ASSUMED_HIGH_BIT);
+
+	private static BigInteger getFrac(long rawBits) {
+		return BigInteger.valueOf(rawBits).and(BI_FRAC_MASK).or(BI_IMPLIED_FRAC_MSB).shiftLeft(11);
+	}
+
+	/**
+	 * Always 64 bits long (MSB, bit-63 is '1')
+	 */
+	private final BigInteger _significand;
+	private final int _binaryExponent;
+
+	public ExpandedDouble(long rawBits) {
+		int biasedExp = (int) (rawBits >> 52);
+		if (biasedExp == 0) {
+			// sub-normal numbers
+			BigInteger frac = BigInteger.valueOf(rawBits).and(BI_FRAC_MASK);
+			int expAdj = 64 - frac.bitLength();
+			_significand = frac.shiftLeft(expAdj);
+			_binaryExponent = (biasedExp & 0x07FF) - 1023 - expAdj;
+		} else {
+			BigInteger frac = getFrac(rawBits);
+			_significand = frac;
+			_binaryExponent = (biasedExp & 0x07FF) - 1023;
+		}
+	}
+
+	/**
+	 * Convert to an equivalent {@link NormalisedDecimal} representation having 15 decimal digits of precision in the
+	 * non-fractional bits of the significand.
+	 */
+	public NormalisedDecimal normaliseBaseTen() {
+		return NormalisedDecimal.create(_significand, _binaryExponent);
+	}
+
+	/**
+	 * @return the number of non-fractional bits after the MSB of the significand
+	 */
+	public int getBinaryExponent() {
+		return _binaryExponent;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/IEEEDouble.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/IEEEDouble.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/IEEEDouble.java	(revision 28000)
@@ -0,0 +1,30 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.util;
+
+
+/**
+ * For working with the internals of IEEE 754-2008 'binary64' (double precision) floating point numbers
+ *
+ * @author Josh Micich
+ */
+final class IEEEDouble {
+	private static final int  EXPONENT_SHIFT = 52;
+	public static final long FRAC_MASK = 0x000FFFFFFFFFFFFFL;
+	public static final long FRAC_ASSUMED_HIGH_BIT = ( 1L<<EXPONENT_SHIFT );
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/MutableFPNumber.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/MutableFPNumber.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/MutableFPNumber.java	(revision 28000)
@@ -0,0 +1,194 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.util;
+
+import java.math.BigInteger;
+
+final class MutableFPNumber {
+
+
+	// TODO - what about values between (10<sup>14</sup>-0.5) and (10<sup>14</sup>-0.05) ?
+	/**
+	 * The minimum value in 'Base-10 normalised form'.<br/>
+	 * When {@link #_binaryExponent} == 46 this is the the minimum {@link #_frac} value
+	 *  (10<sup>14</sup>-0.05) * 2^17
+	 *  <br/>
+	 *  Values between (10<sup>14</sup>-0.05) and 10<sup>14</sup> will be represented as '1'
+	 *  followed by 14 zeros.
+	 *  Values less than (10<sup>14</sup>-0.05) will get shifted by one more power of 10
+	 *
+	 *  This frac value rounds to '1' followed by fourteen zeros with an incremented decimal exponent
+	 */
+	private static final BigInteger BI_MIN_BASE = new BigInteger("0B5E620F47FFFE666", 16);
+	/**
+	 * For 'Base-10 normalised form'<br/>
+	 * The maximum {@link #_frac} value when {@link #_binaryExponent} == 49
+	 * (10^15-0.5) * 2^14
+	 */
+	private static final BigInteger BI_MAX_BASE = new BigInteger("0E35FA9319FFFE000", 16);
+
+	/**
+	 * Width of a long
+	 */
+	private static final int C_64 = 64;
+
+	/**
+	 * Minimum precision after discarding whole 32-bit words from the significand
+	 */
+	private static final int MIN_PRECISION = 72;
+	private BigInteger _significand;
+	private int _binaryExponent;
+	public MutableFPNumber(BigInteger frac, int binaryExponent) {
+		_significand = frac;
+		_binaryExponent = binaryExponent;
+	}
+
+	public void normalise64bit() {
+		int oldBitLen = _significand.bitLength();
+		int sc = oldBitLen - C_64;
+		if (sc == 0) {
+			return;
+		}
+		if (sc < 0) {
+			throw new IllegalStateException("Not enough precision");
+		}
+		_binaryExponent += sc;
+		if (sc > 32) {
+			int highShift = (sc-1) & 0xFFFFE0;
+			_significand = _significand.shiftRight(highShift);
+			sc -= highShift;
+			oldBitLen -= highShift;
+		}
+		if (sc < 1) {
+			throw new IllegalStateException();
+		}
+		_significand = Rounder.round(_significand, sc);
+		if (_significand.bitLength() > oldBitLen) {
+			sc++;
+			_binaryExponent++;
+		}
+		_significand = _significand.shiftRight(sc);
+	}
+	public int get64BitNormalisedExponent() {
+		return _binaryExponent + _significand.bitLength() - C_64;
+
+	}
+
+	public boolean isBelowMaxRep() {
+		int sc = _significand.bitLength() - C_64;
+		return _significand.compareTo(BI_MAX_BASE.shiftLeft(sc)) < 0;
+	}
+	public boolean isAboveMinRep() {
+		int sc = _significand.bitLength() - C_64;
+		return _significand.compareTo(BI_MIN_BASE.shiftLeft(sc)) > 0;
+	}
+	public NormalisedDecimal createNormalisedDecimal(int pow10) {
+		// missingUnderBits is (0..3)
+		int missingUnderBits = _binaryExponent-39;
+		int fracPart = (_significand.intValue() << missingUnderBits) & 0xFFFF80;
+		long wholePart = _significand.shiftRight(C_64-_binaryExponent-1).longValue();
+		return new NormalisedDecimal(wholePart, fracPart, pow10);
+	}
+	public void multiplyByPowerOfTen(int pow10) {
+		TenPower tp = TenPower.getInstance(Math.abs(pow10));
+		if (pow10 < 0) {
+			mulShift(tp._divisor, tp._divisorShift);
+		} else {
+			mulShift(tp._multiplicand, tp._multiplierShift);
+		}
+	}
+	private void mulShift(BigInteger multiplicand, int multiplierShift) {
+		_significand = _significand.multiply(multiplicand);
+		_binaryExponent += multiplierShift;
+		// check for too much precision
+		int sc = (_significand.bitLength() - MIN_PRECISION) & 0xFFFFFFE0;
+		// mask makes multiples of 32 which optimises BigInteger.shiftRight
+		if (sc > 0) {
+			// no need to round because we have at least 8 bits of extra precision
+			_significand = _significand.shiftRight(sc);
+			_binaryExponent += sc;
+		}
+	}
+
+	private static final class Rounder {
+		private static final BigInteger[] HALF_BITS;
+
+		static {
+			BigInteger[] bis = new BigInteger[33];
+			long acc=1;
+			for (int i = 1; i < bis.length; i++) {
+				bis[i] = BigInteger.valueOf(acc);
+				acc <<=1;
+			}
+			HALF_BITS = bis;
+		}
+		/**
+		 * @param nBits number of bits to shift right
+		 */
+		public static BigInteger round(BigInteger bi, int nBits) {
+			if (nBits < 1) {
+				return bi;
+			}
+			return bi.add(HALF_BITS[nBits]);
+		}
+	}
+
+	/**
+	 * Holds values for quick multiplication and division by 10
+	 */
+	private static final class TenPower {
+		private static final BigInteger FIVE = new BigInteger("5");
+		private static final TenPower[] _cache = new TenPower[350];
+
+		public final BigInteger _multiplicand;
+		public final BigInteger _divisor;
+		public final int _divisorShift;
+		public final int _multiplierShift;
+
+		private TenPower(int index) {
+			BigInteger fivePowIndex = FIVE.pow(index);
+
+			int bitsDueToFiveFactors = fivePowIndex.bitLength();
+			int px = 80 + bitsDueToFiveFactors;
+			BigInteger fx = BigInteger.ONE.shiftLeft(px).divide(fivePowIndex);
+			int adj = fx.bitLength() - 80;
+			_divisor = fx.shiftRight(adj);
+			bitsDueToFiveFactors -= adj;
+
+			_divisorShift = -(bitsDueToFiveFactors+index+80);
+			int sc = fivePowIndex.bitLength() - 68;
+			if (sc > 0) {
+				_multiplierShift = index + sc;
+				_multiplicand = fivePowIndex.shiftRight(sc);
+			} else {
+				_multiplierShift = index;
+				_multiplicand = fivePowIndex;
+			}
+		}
+
+		static TenPower getInstance(int index) {
+			TenPower result = _cache[index];
+			if (result == null) {
+				result = new TenPower(index);
+				_cache[index] = result;
+			}
+			return result;
+		}
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/NormalisedDecimal.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/NormalisedDecimal.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/NormalisedDecimal.java	(revision 28000)
@@ -0,0 +1,219 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.util;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * Represents a transformation of a 64 bit IEEE double quantity having a decimal exponent and a
+ * fixed point (15 decimal digit) significand.  Some quirks of Excel's calculation behaviour are
+ * simpler to reproduce with numeric quantities in this format.  This class is currently used to
+ * help:
+ * <ol>
+ * <li>Comparison operations</li>
+ * <li>Conversions to text</li>
+ * </ol>
+ *
+ * <p/>
+ * This class does not handle negative numbers or zero.
+ * <p/>
+ * The value of a {@link NormalisedDecimal} is given by<br/>
+ * <tt> significand &times; 10<sup>decimalExponent</sup></tt>
+ * <br/>
+ * where:<br/>
+ *
+ * <tt>significand</tt> = wholePart + fractionalPart / 2<sup>24</sup><br/>
+ *
+ * @author Josh Micich
+ */
+final class NormalisedDecimal {
+	/**
+	 * Number of powers of ten contained in the significand
+	 */
+	private static final int EXPONENT_OFFSET = 14;
+
+	private static final BigDecimal BD_2_POW_24 = new BigDecimal(BigInteger.ONE.shiftLeft(24));
+
+	/**
+	 * log<sub>10</sub>(2)&times;2<sup>20</sup>
+	 */
+	private static final int LOG_BASE_10_OF_2_TIMES_2_POW_20 = 315653; // 315652.8287
+
+	/**
+	 * 2<sup>19</sup>
+	 */
+	private static final int C_2_POW_19 = 1 << 19;
+
+
+	/**
+	 * the value of {@link #_fractionalPart} that represents 0.5
+	 */
+	private static final int FRAC_HALF = 0x800000;
+
+	/**
+	 * 10<sup>15</sup>
+	 */
+	private static final long MAX_REP_WHOLE_PART = 0x38D7EA4C68000L;
+
+
+
+	public static NormalisedDecimal create(BigInteger frac, int binaryExponent) {
+		// estimate pow2&pow10 first, perform optional mulShift, then normalize
+		int pow10;
+		if (binaryExponent > 49 || binaryExponent < 46) {
+
+			// working with ints (left shifted 20) instead of doubles
+			// x = 14.5 - binaryExponent * log10(2);
+			int x = (29 << 19) - binaryExponent * LOG_BASE_10_OF_2_TIMES_2_POW_20;
+			x += C_2_POW_19; // round
+			pow10 = -(x >> 20);
+		} else {
+			pow10 = 0;
+		}
+		MutableFPNumber cc = new MutableFPNumber(frac, binaryExponent);
+		if (pow10 != 0) {
+			cc.multiplyByPowerOfTen(-pow10);
+		}
+
+		switch (cc.get64BitNormalisedExponent()) {
+			case 46:
+				if (cc.isAboveMinRep()) {
+					break;
+				}
+			case 44:
+			case 45:
+				cc.multiplyByPowerOfTen(1);
+				pow10--;
+				break;
+			case 47:
+			case 48:
+				break;
+			case 49:
+				if (cc.isBelowMaxRep()) {
+					break;
+				}
+			case 50:
+				cc.multiplyByPowerOfTen(-1);
+				pow10++;
+				break;
+
+			default:
+				throw new IllegalStateException("Bad binary exp " + cc.get64BitNormalisedExponent() + ".");
+		}
+		cc.normalise64bit();
+
+		return cc.createNormalisedDecimal(pow10);
+	}
+
+	/**
+	 * Rounds at the digit with value 10<sup>decimalExponent</sup>
+	 */
+	public NormalisedDecimal roundUnits() {
+		long wholePart = _wholePart;
+		if (_fractionalPart >= FRAC_HALF) {
+			wholePart++;
+		}
+
+		int de = _relativeDecimalExponent;
+
+		if (wholePart < MAX_REP_WHOLE_PART) {
+			return new NormalisedDecimal(wholePart, 0, de);
+		}
+		return new NormalisedDecimal(wholePart/10, 0, de+1);
+	}
+
+	/**
+	 * The decimal exponent increased by one less than the digit count of {@link #_wholePart}
+	 */
+	private final int _relativeDecimalExponent;
+	/**
+	 * The whole part of the significand (typically 15 digits).
+	 *
+	 * 47-50 bits long (MSB may be anywhere from bit 46 to 49)
+	 * LSB is units bit.
+	 */
+	private final long _wholePart;
+	/**
+	 * The fractional part of the significand.
+	 * 24 bits (only top 14-17 bits significant): a value between 0x000000 and 0xFFFF80
+	 */
+	private final int _fractionalPart;
+
+
+	NormalisedDecimal(long wholePart, int fracPart, int decimalExponent) {
+		_wholePart = wholePart;
+		_fractionalPart = fracPart;
+		_relativeDecimalExponent = decimalExponent;
+	}
+
+
+
+
+	public String getSignificantDecimalDigits() {
+		return Long.toString(_wholePart);
+	}
+	/**
+	 * Rounds the first whole digit position (considers only units digit, not frational part).
+	 * Caller should check total digit count of result to see whether the rounding operation caused
+	 * a carry out of the most significant digit
+	 */
+	public String getSignificantDecimalDigitsLastDigitRounded() {
+		long wp = _wholePart + 5; // rounds last digit
+		StringBuilder sb = new StringBuilder(24);
+		sb.append(wp);
+		sb.setCharAt(sb.length()-1, '0');
+		return sb.toString();
+	}
+
+	/**
+	 * @return the number of powers of 10 which have been extracted from the significand and binary exponent.
+	 */
+	public int getDecimalExponent() {
+		return _relativeDecimalExponent+EXPONENT_OFFSET;
+	}
+
+	public BigDecimal getFractionalPart() {
+		return new BigDecimal(_fractionalPart).divide(BD_2_POW_24);
+	}
+
+	private String getFractionalDigits() {
+		if (_fractionalPart == 0) {
+			return "0";
+		}
+		return getFractionalPart().toString().substring(2);
+	}
+
+	@Override
+	public String toString() {
+
+		StringBuilder sb = new StringBuilder();
+		sb.append(getClass().getName());
+		sb.append(" [");
+		String ws = String.valueOf(_wholePart);
+		sb.append(ws.charAt(0));
+		sb.append('.');
+		sb.append(ws.substring(1));
+		sb.append(' ');
+		sb.append(getFractionalDigits());
+		sb.append("E");
+		sb.append(getDecimalExponent());
+		sb.append("]");
+		return sb.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/NumberToTextConverter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/NumberToTextConverter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/NumberToTextConverter.java	(revision 28000)
@@ -0,0 +1,259 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.util;
+
+
+/**
+ * Excel converts numbers to text with different rules to those of java, so
+ *  <code>Double.toString(value)</tt> won't do.
+ * <ul>
+ * <li>No more than 15 significant figures are output (java does 18).</li>
+ * <li>The sign char for the exponent is included even if positive</li>
+ * <li>Special values (<tt>NaN</tt> and <tt>Infinity</tt>) get rendered like the ordinary
+ * number that the bit pattern represents.</li>
+ * <li>Denormalised values (between &plusmn;2<sup>-1074</sup> and &plusmn;2<sup>-1022</sup>
+ *  are displayed as "0"</sup>
+ * </ul>
+ * IEEE 64-bit Double Rendering Comparison
+ *
+ * <table border="1" cellpadding="2" cellspacing="0" summary="IEEE 64-bit Double Rendering Comparison">
+ * <tr><th>Raw bits</th><th>Java</th><th>Excel</th></tr>
+ *
+ * <tr><td>0x0000000000000000L</td><td>0.0</td><td>0</td></tr>
+ * <tr><td>0x3FF0000000000000L</td><td>1.0</td><td>1</td></tr>
+ * <tr><td>0x3FF00068DB8BAC71L</td><td>1.0001</td><td>1.0001</td></tr>
+ * <tr><td>0x4087A00000000000L</td><td>756.0</td><td>756</td></tr>
+ * <tr><td>0x401E3D70A3D70A3DL</td><td>7.56</td><td>7.56</td></tr>
+ * <tr><td>0x405EDD3C07FB4C99L</td><td>123.45678901234568</td><td>123.456789012346</td></tr>
+ * <tr><td>0x4132D687E3DF2180L</td><td>1234567.8901234567</td><td>1234567.89012346</td></tr>
+ * <tr><td>0x3EE9E409302678BAL</td><td>1.2345678901234568E-5</td><td>1.23456789012346E-05</td></tr>
+ * <tr><td>0x3F202E85BE180B74L</td><td>1.2345678901234567E-4</td><td>0.000123456789012346</td></tr>
+ * <tr><td>0x3F543A272D9E0E51L</td><td>0.0012345678901234567</td><td>0.00123456789012346</td></tr>
+ * <tr><td>0x3F8948B0F90591E6L</td><td>0.012345678901234568</td><td>0.0123456789012346</td></tr>
+ * <tr><td>0x3EE9E409301B5A02L</td><td>1.23456789E-5</td><td>0.0000123456789</td></tr>
+ * <tr><td>0x3E6E7D05BDABDE50L</td><td>5.6789012345E-8</td><td>0.000000056789012345</td></tr>
+ * <tr><td>0x3E6E7D05BDAD407EL</td><td>5.67890123456E-8</td><td>5.67890123456E-08</td></tr>
+ * <tr><td>0x3E6E7D06029F18BEL</td><td>5.678902E-8</td><td>0.00000005678902</td></tr>
+ * <tr><td>0x2BCB5733CB32AE6EL</td><td>9.999999999999123E-98</td><td>9.99999999999912E-98</td></tr>
+ * <tr><td>0x2B617F7D4ED8C59EL</td><td>1.0000000000001235E-99</td><td>1.0000000000001E-99</td></tr>
+ * <tr><td>0x0036319916D67853L</td><td>1.2345678901234578E-307</td><td>1.2345678901235E-307</td></tr>
+ * <tr><td>0x359DEE7A4AD4B81FL</td><td>2.0E-50</td><td>2E-50</td></tr>
+ * <tr><td>0x41678C29DCD6E9E0L</td><td>1.2345678901234567E7</td><td>12345678.9012346</td></tr>
+ * <tr><td>0x42A674E79C5FE523L</td><td>1.2345678901234568E13</td><td>12345678901234.6</td></tr>
+ * <tr><td>0x42DC12218377DE6BL</td><td>1.2345678901234567E14</td><td>123456789012346</td></tr>
+ * <tr><td>0x43118B54F22AEB03L</td><td>1.2345678901234568E15</td><td>1234567890123460</td></tr>
+ * <tr><td>0x43E56A95319D63E1L</td><td>1.2345678901234567E19</td><td>12345678901234600000</td></tr>
+ * <tr><td>0x441AC53A7E04BCDAL</td><td>1.2345678901234568E20</td><td>1.23456789012346E+20</td></tr>
+ * <tr><td>0xC3E56A95319D63E1L</td><td>-1.2345678901234567E19</td><td>-12345678901234600000</td></tr>
+ * <tr><td>0xC41AC53A7E04BCDAL</td><td>-1.2345678901234568E20</td><td>-1.23456789012346E+20</td></tr>
+ * <tr><td>0x54820FE0BA17F46DL</td><td>1.2345678901234577E99</td><td>1.2345678901235E+99</td></tr>
+ * <tr><td>0x54B693D8E89DF188L</td><td>1.2345678901234576E100</td><td>1.2345678901235E+100</td></tr>
+ * <tr><td>0x4A611B0EC57E649AL</td><td>2.0E50</td><td>2E+50</td></tr>
+ * <tr><td>0x7FEFFFFFFFFFFFFFL</td><td>1.7976931348623157E308</td><td>1.7976931348623E+308</td></tr>
+ * <tr><td>0x0010000000000000L</td><td>2.2250738585072014E-308</td><td>2.2250738585072E-308</td></tr>
+ * <tr><td>0x000FFFFFFFFFFFFFL</td><td>2.225073858507201E-308</td><td>0</td></tr>
+ * <tr><td>0x0000000000000001L</td><td>4.9E-324</td><td>0</td></tr>
+ * <tr><td>0x7FF0000000000000L</td><td>Infinity</td><td>1.7976931348623E+308</td></tr>
+ * <tr><td>0xFFF0000000000000L</td><td>-Infinity</td><td>1.7976931348623E+308</td></tr>
+ * <tr><td>0x441AC7A08EAD02F2L</td><td>1.234999999999999E20</td><td>1.235E+20</td></tr>
+ * <tr><td>0x40FE26BFFFFFFFF9L</td><td>123499.9999999999</td><td>123500</td></tr>
+ * <tr><td>0x3E4A857BFB2F2809L</td><td>1.234999999999999E-8</td><td>0.00000001235</td></tr>
+ * <tr><td>0x3BCD291DEF868C89L</td><td>1.234999999999999E-20</td><td>1.235E-20</td></tr>
+ * <tr><td>0x444B1AE4D6E2EF4FL</td><td>9.999999999999999E20</td><td>1E+21</td></tr>
+ * <tr><td>0x412E847FFFFFFFFFL</td><td>999999.9999999999</td><td>1000000</td></tr>
+ * <tr><td>0x3E45798EE2308C39L</td><td>9.999999999999999E-9</td><td>0.00000001</td></tr>
+ * <tr><td>0x3C32725DD1D243ABL</td><td>9.999999999999999E-19</td><td>0.000000000000000001</td></tr>
+ * <tr><td>0x3BFD83C94FB6D2ABL</td><td>9.999999999999999E-20</td><td>1E-19</td></tr>
+ * <tr><td>0xC44B1AE4D6E2EF4FL</td><td>-9.999999999999999E20</td><td>-1E+21</td></tr>
+ * <tr><td>0xC12E847FFFFFFFFFL</td><td>-999999.9999999999</td><td>-1000000</td></tr>
+ * <tr><td>0xBE45798EE2308C39L</td><td>-9.999999999999999E-9</td><td>-0.00000001</td></tr>
+ * <tr><td>0xBC32725DD1D243ABL</td><td>-9.999999999999999E-19</td><td>-0.000000000000000001</td></tr>
+ * <tr><td>0xBBFD83C94FB6D2ABL</td><td>-9.999999999999999E-20</td><td>-1E-19</td></tr>
+ * <tr><td>0xFFFF0420003C0000L</td><td>NaN</td><td>3.484840871308E+308</td></tr>
+ * <tr><td>0x7FF8000000000000L</td><td>NaN</td><td>2.6965397022935E+308</td></tr>
+ * <tr><td>0x7FFF0420003C0000L</td><td>NaN</td><td>3.484840871308E+308</td></tr>
+ * <tr><td>0xFFF8000000000000L</td><td>NaN</td><td>2.6965397022935E+308</td></tr>
+ * <tr><td>0xFFFF0AAAAAAAAAAAL</td><td>NaN</td><td>3.4877119413344E+308</td></tr>
+ * <tr><td>0x7FF80AAAAAAAAAAAL</td><td>NaN</td><td>2.7012211948322E+308</td></tr>
+ * <tr><td>0xFFFFFFFFFFFFFFFFL</td><td>NaN</td><td>3.5953862697246E+308</td></tr>
+ * <tr><td>0x7FFFFFFFFFFFFFFFL</td><td>NaN</td><td>3.5953862697246E+308</td></tr>
+ * <tr><td>0xFFF7FFFFFFFFFFFFL</td><td>NaN</td><td>2.6965397022935E+308</td></tr>
+ * </table>
+ *
+ * <b>Note</b>:
+ * Excel has inconsistent rules for the following numeric operations:
+ * <ul>
+ * <li>Conversion to string (as handled here)</li>
+ * <li>Rendering numerical quantities in the cell grid.</li>
+ * <li>Conversion from text</li>
+ * <li>General arithmetic</li>
+ * </ul>
+ * Excel's text to number conversion is not a true <i>inverse</i> of this operation.  The
+ * allowable ranges are different.  Some numbers that don't correctly convert to text actually
+ * <b>do</b> get handled properly when used in arithmetic evaluations.
+ *
+ * @author Josh Micich
+ */
+public final class NumberToTextConverter {
+
+	private static final long EXCEL_NAN_BITS = 0xFFFF0420003C0000L;
+	private static final int MAX_TEXT_LEN = 20;
+
+	private NumberToTextConverter() {
+		// no instances of this class
+	}
+
+	/**
+	 * Converts the supplied <tt>value</tt> to the text representation that Excel would give if
+	 * the value were to appear in an unformatted cell, or as a literal number in a formula.<br/>
+	 * Note - the results from this method differ slightly from those of <tt>Double.toString()</tt>
+	 * In some special cases Excel behaves quite differently.  This function attempts to reproduce
+	 * those results.
+	 */
+	public static String toText(double value) {
+		return rawDoubleBitsToText(Double.doubleToLongBits(value));
+	}
+	/* package */ static String rawDoubleBitsToText(long pRawBits) {
+
+		long rawBits = pRawBits;
+		boolean isNegative = rawBits < 0; // sign bit is in the same place for long and double
+		if (isNegative) {
+			rawBits &= 0x7FFFFFFFFFFFFFFFL;
+		}
+		if (rawBits == 0) {
+			return isNegative ? "-0" : "0";
+		}
+		ExpandedDouble ed = new ExpandedDouble(rawBits);
+		if (ed.getBinaryExponent() < -1022) {
+			// value is 'denormalised' which means it is less than 2^-1022
+			// excel displays all these numbers as zero, even though calculations work OK
+			return isNegative ? "-0" : "0";
+		}
+		if (ed.getBinaryExponent() == 1024) {
+			// Special number NaN /Infinity
+			// Normally one would not create HybridDecimal objects from these values
+			// except in these cases Excel really tries to render them as if they were normal numbers
+			if(rawBits == EXCEL_NAN_BITS) {
+				return "3.484840871308E+308";
+			}
+			// This is where excel really gets it wrong
+			// Special numbers like Infinity and NaN are interpreted according to
+			// the standard rules below.
+			isNegative = false; // except that the sign bit is ignored
+		}
+		NormalisedDecimal nd = ed.normaliseBaseTen();
+		StringBuilder sb = new StringBuilder(MAX_TEXT_LEN+1);
+		if (isNegative) {
+			sb.append('-');
+		}
+		convertToText(sb, nd);
+		return sb.toString();
+	}
+	private static void convertToText(StringBuilder sb, NormalisedDecimal pnd) {
+		NormalisedDecimal rnd = pnd.roundUnits();
+		int decExponent = rnd.getDecimalExponent();
+		String decimalDigits;
+		if (Math.abs(decExponent)>98) {
+			decimalDigits = rnd.getSignificantDecimalDigitsLastDigitRounded();
+			if (decimalDigits.length() == 16) {
+				// rounding caused carry
+				decExponent++;
+			}
+		} else {
+			decimalDigits = rnd.getSignificantDecimalDigits();
+		}
+		int countSigDigits = countSignifantDigits(decimalDigits);
+		if (decExponent < 0) {
+			formatLessThanOne(sb, decimalDigits, decExponent, countSigDigits);
+		} else {
+			formatGreaterThanOne(sb, decimalDigits, decExponent, countSigDigits);
+		}
+	}
+
+	private static void formatLessThanOne(StringBuilder sb, String decimalDigits, int decExponent,
+			int countSigDigits) {
+		int nLeadingZeros = -decExponent - 1;
+		int normalLength = 2 + nLeadingZeros + countSigDigits; // 2 == "0.".length()
+
+		if (needsScientificNotation(normalLength)) {
+			sb.append(decimalDigits.charAt(0));
+			if (countSigDigits > 1) {
+    			sb.append('.');
+    			sb.append(decimalDigits.subSequence(1, countSigDigits));
+			}
+			sb.append("E-");
+			appendExp(sb, -decExponent);
+			return;
+		}
+		sb.append("0.");
+		for (int i=nLeadingZeros; i>0; i--) {
+			sb.append('0');
+		}
+		sb.append(decimalDigits.subSequence(0, countSigDigits));
+	}
+
+	private static void formatGreaterThanOne(StringBuilder sb, String decimalDigits, int decExponent, int countSigDigits) {
+
+		if (decExponent > 19) {
+			// scientific notation
+			sb.append(decimalDigits.charAt(0));
+			if (countSigDigits>1) {
+				sb.append('.');
+				sb.append(decimalDigits.subSequence(1, countSigDigits));
+			}
+			sb.append("E+");
+			appendExp(sb, decExponent);
+			return;
+		}
+		int nFractionalDigits = countSigDigits - decExponent-1;
+		if (nFractionalDigits > 0) {
+			sb.append(decimalDigits.subSequence(0, decExponent+1));
+			sb.append('.');
+			sb.append(decimalDigits.subSequence(decExponent+1, countSigDigits));
+			return;
+		}
+		sb.append(decimalDigits.subSequence(0, countSigDigits));
+		for (int i=-nFractionalDigits; i>0; i--) {
+			sb.append('0');
+		}
+	}
+
+	private static boolean needsScientificNotation(int nDigits) {
+		return nDigits > MAX_TEXT_LEN;
+	}
+
+	private static int countSignifantDigits(String sb) {
+		int result=sb.length()-1;
+		while(sb.charAt(result) == '0') {
+			result--;
+			if(result < 0) {
+				throw new RuntimeException("No non-zero digits found");
+			}
+		}
+		return result + 1;
+	}
+
+	private static void appendExp(StringBuilder sb, int val) {
+		if(val < 10) {
+			sb.append('0');
+			sb.append((char)('0' + val));
+			return;
+		}
+		sb.append(val);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/SSCellRange.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/SSCellRange.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/ss/util/SSCellRange.java	(revision 28000)
@@ -0,0 +1,81 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.ss.util;
+
+import java.lang.reflect.Array;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellRange;
+import org.apache.poi.util.Internal;
+
+/**
+ * For POI internal use only
+ *
+ * @author Josh Micich
+ */
+@Internal
+public final class SSCellRange<K extends Cell> implements CellRange<K> {
+
+	private final K[] _flattenedArray;
+
+	private SSCellRange(int firstRow, int firstColumn, int height, int width, K[] flattenedArray) {
+		_flattenedArray = flattenedArray;
+	}
+
+	public static <B extends Cell> SSCellRange<B> create(int firstRow, int firstColumn, int height, int width, List<B> flattenedList, Class<B> cellClass) {
+		int nItems = flattenedList.size();
+		if (height * width != nItems) {
+			throw new IllegalArgumentException("Array size mismatch.");
+		}
+
+		@SuppressWarnings("unchecked")
+		B[] flattenedArray = (B[]) Array.newInstance(cellClass, nItems);
+		flattenedList.toArray(flattenedArray);
+		return new SSCellRange<B>(firstRow, firstColumn, height, width, flattenedArray);
+	}
+
+	public Iterator<K> iterator() {
+		return new ArrayIterator<K>(_flattenedArray);
+	}
+	private static final class ArrayIterator<D> implements Iterator<D> {
+
+		private final D[] _array;
+		private int _index;
+
+		public ArrayIterator(D[] array) {
+			_array = array;
+			_index = 0;
+		}
+		public boolean hasNext() {
+			return _index < _array.length;
+		}
+		public D next() {
+			if (_index >= _array.length) {
+				throw new NoSuchElementException(String.valueOf(_index));
+			}
+			return _array[_index++];
+		}
+
+		public void remove() {
+			throw new UnsupportedOperationException("Cannot remove cells from this CellRange.");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/BitField.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/BitField.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/BitField.java	(revision 28000)
@@ -0,0 +1,265 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+/**
+ * Manage operations dealing with bit-mapped fields.
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ */
+
+public class BitField
+{
+    private final int _mask;
+    private final int _shift_count;
+
+    /**
+     * Create a BitField instance
+     *
+     * @param mask the mask specifying which bits apply to this
+     *             BitField. Bits that are set in this mask are the
+     *             bits that this BitField operates on
+     */
+
+    public BitField(final int mask)
+    {
+        _mask = mask;
+        int count       = 0;
+        int bit_pattern = mask;
+
+        if (bit_pattern != 0)
+        {
+            while ((bit_pattern & 1) == 0)
+            {
+                count++;
+                bit_pattern >>= 1;
+            }
+        }
+        _shift_count = count;
+    }
+
+    /**
+     * Obtain the value for the specified BitField, appropriately
+     * shifted right. Many users of a BitField will want to treat the
+     * specified bits as an int value, and will not want to be aware
+     * that the value is stored as a BitField (and so shifted left so
+     * many bits)
+     *
+     * @param holder the int data containing the bits we're interested
+     *               in
+     *
+     * @return the selected bits, shifted right appropriately
+     */
+
+    public int getValue(final int holder)
+    {
+        return getRawValue(holder) >> _shift_count;
+    }
+
+    /**
+     * Obtain the value for the specified BitField, appropriately
+     * shifted right, as a short. Many users of a BitField will want
+     * to treat the specified bits as an int value, and will not want
+     * to be aware that the value is stored as a BitField (and so
+     * shifted left so many bits)
+     *
+     * @param holder the short data containing the bits we're
+     *               interested in
+     *
+     * @return the selected bits, shifted right appropriately
+     */
+
+    public short getShortValue(final short holder)
+    {
+        return ( short ) getValue(holder);
+    }
+
+    /**
+     * Obtain the value for the specified BitField, unshifted
+     *
+     * @param holder the int data containing the bits we're interested
+     *               in
+     *
+     * @return the selected bits
+     */
+
+    public int getRawValue(final int holder)
+    {
+        return (holder & _mask);
+    }
+
+    /**
+     * Is the field set or not? This is most commonly used for a
+     * single-bit field, which is often used to represent a boolean
+     * value; the results of using it for a multi-bit field is to
+     * determine whether *any* of its bits are set
+     *
+     * @param holder the int data containing the bits we're interested
+     *               in
+     *
+     * @return true if any of the bits are set, else false
+     */
+
+    public boolean isSet(final int holder)
+    {
+        return (holder & _mask) != 0;
+    }
+
+
+    /**
+     * Replace the bits with new values.
+     *
+     * @param holder the int data containint the bits we're interested
+     *               in
+     * @param value the new value for the specified bits
+     *
+     * @return the value of holder with the bits from the value
+     *         parameter replacing the old bits
+     */
+
+    public int setValue(final int holder, final int value)
+    {
+        return (holder & ~_mask) | ((value << _shift_count) & _mask);
+    }
+
+    /**
+     * Clear the bits.
+     *
+     * @param holder the int data containing the bits we're interested
+     *               in
+     *
+     * @return the value of holder with the specified bits cleared
+     *         (set to 0)
+     */
+
+    public int clear(final int holder)
+    {
+        return holder & ~_mask;
+    }
+
+    /**
+     * Clear the bits.
+     *
+     * @param holder the short data containing the bits we're
+     *               interested in
+     *
+     * @return the value of holder with the specified bits cleared
+     *         (set to 0)
+     */
+
+    public short clearShort(final short holder)
+    {
+        return ( short ) clear(holder);
+    }
+
+    /**
+     * Clear the bits.
+     *
+     * @param holder the byte data containing the bits we're
+     *               interested in
+     *
+     * @return the value of holder with the specified bits cleared
+     *         (set to 0)
+     */
+
+    public byte clearByte(final byte holder)
+    {
+        return ( byte ) clear(holder);
+    }
+
+    /**
+     * Set the bits.
+     *
+     * @param holder the int data containing the bits we're interested
+     *               in
+     *
+     * @return the value of holder with the specified bits set to 1
+     */
+
+    public int set(final int holder)
+    {
+        return holder | _mask;
+    }
+
+    /**
+     * Set the bits.
+     *
+     * @param holder the short data containing the bits we're
+     *               interested in
+     *
+     * @return the value of holder with the specified bits set to 1
+     */
+
+    public short setShort(final short holder)
+    {
+        return ( short ) set(holder);
+    }
+
+    /**
+     * Set the bits.
+     *
+     * @param holder the byte data containing the bits we're
+     *               interested in
+     *
+     * @return the value of holder with the specified bits set to 1
+     */
+
+    public byte setByte(final byte holder)
+    {
+        return ( byte ) set(holder);
+    }
+
+    /**
+     * Set a boolean BitField
+     *
+     * @param holder the int data containing the bits we're interested
+     *               in
+     * @param flag indicating whether to set or clear the bits
+     *
+     * @return the value of holder with the specified bits set or
+     *         cleared
+     */
+
+    public int setBoolean(final int holder, final boolean flag)
+    {
+        return flag ? set(holder)
+                    : clear(holder);
+    }
+
+    /**
+     * Set a boolean BitField
+     *
+     * @param holder the short data containing the bits we're
+     *               interested in
+     * @param flag indicating whether to set or clear the bits
+     *
+     * @return the value of holder with the specified bits set or
+     *         cleared
+     */
+
+    public short setShortBoolean(final short holder, final boolean flag)
+    {
+        return flag ? setShort(holder)
+                    : clearShort(holder);
+    }
+
+}   // end public class BitField
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/BitFieldFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/BitFieldFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/BitFieldFactory.java	(revision 28000)
@@ -0,0 +1,41 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Returns immutable Btfield instances.
+ *
+ * @author Jason Height (jheight at apache dot org)
+ */
+
+public class BitFieldFactory {
+    private static Map<Integer, BitField> instances = new HashMap<Integer, BitField>();
+
+    public static BitField getInstance(int mask) {
+      BitField f = instances.get(Integer.valueOf(mask));
+      if (f == null) {
+        f = new BitField(mask);
+        instances.put(Integer.valueOf(mask), f);
+      }
+      return f;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/ByteField.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/ByteField.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/ByteField.java	(revision 28000)
@@ -0,0 +1,169 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+
+
+/**
+ * representation of a byte (8-bit) field at a fixed location within a
+ * byte array
+ *
+ * @author Marc Johnson (mjohnson at apache dot org
+ */
+
+public class ByteField
+    implements FixedField
+{
+    private static final byte _default_value = 0;
+    private byte              _value;
+    private final int         _offset;
+
+    /**
+     * construct the ByteField with its offset into its containing
+     * byte array and a default value of 0
+     *
+     * @param offset of the field within its byte array
+     *
+     * @exception ArrayIndexOutOfBoundsException if offset is negative
+     */
+
+    public ByteField(final int offset)
+        throws ArrayIndexOutOfBoundsException
+    {
+        this(offset, _default_value);
+    }
+
+    /**
+     * construct the ByteField with its offset into its containing
+     * byte array and initialize its value
+     *
+     * @param offset of the field within its byte array
+     * @param value the initial value
+     *
+     * @exception ArrayIndexOutOfBoundsException if offset is negative
+     */
+
+    public ByteField(final int offset, final byte value)
+        throws ArrayIndexOutOfBoundsException
+    {
+        if (offset < 0)
+        {
+            throw new ArrayIndexOutOfBoundsException(
+                "offset cannot be negative");
+        }
+        _offset = offset;
+        set(value);
+    }
+
+    /**
+     * Construct the ByteField with its offset into its containing
+     * byte array and initialize its value from its byte array
+     *
+     * @param offset of the field within its byte array
+     * @param data the byte array to read the value from
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is not
+     *            within the range of 0..(data.length - 1)
+     */
+
+    public ByteField(final int offset, final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        this(offset);
+        readFromBytes(data);
+    }
+
+    /**
+     * set the ByteField's current value
+     *
+     * @param value to be set
+     */
+
+    public void set(final byte value)
+    {
+        _value = value;
+    }
+
+    /**
+     * set the ByteField's current value and write it to a byte array
+     *
+     * @param value to be set
+     * @param data the byte array to write the value to
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is out
+     *            of the byte array's range
+     */
+
+    public void set(final byte value, final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        set(value);
+        writeToBytes(data);
+    }
+
+    /* ********** START implementation of FixedField ********** */
+
+    /**
+     * set the value from its offset into an array of bytes
+     *
+     * @param data the byte array from which the value is to be read
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is out
+     *            of range of the bte array
+     */
+
+    public void readFromBytes(final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        _value = data[ _offset ];
+    }
+
+
+    /**
+     * write the value out to an array of bytes at the appropriate
+     * offset
+     *
+     * @param data the array of bytes to which the value is to be
+     *             written
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is out
+     *            of the byte array's range
+     */
+
+    public void writeToBytes(final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        data[ _offset ] = _value;
+    }
+
+    /**
+     * return the value as a String
+     *
+     * @return the value as a String
+     */
+
+    public String toString()
+    {
+        return String.valueOf(_value);
+    }
+
+    /* **********  END  implementation of FixedField ********** */
+}   // end public class ByteField
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/DelayableLittleEndianOutput.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/DelayableLittleEndianOutput.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/DelayableLittleEndianOutput.java	(revision 28000)
@@ -0,0 +1,34 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+/**
+ * Implementors of this interface allow client code to 'delay' writing to a certain section of a
+ * data output stream.<br/>
+ * A typical application is for writing BIFF records when the size is not known until well after
+ * the header has been written.  The client code can call {@link #createDelayedOutput(int)}
+ * to reserve two bytes of the output for the 'ushort size' header field.  The delayed output can
+ * be written at any stage.
+ *
+ * @author Josh Micich
+ */
+public interface DelayableLittleEndianOutput extends LittleEndianOutput {
+	/**
+	 * Creates an output stream intended for outputting a sequence of <tt>size</tt> bytes.
+	 */
+	LittleEndianOutput createDelayedOutput(int size);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/FixedField.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/FixedField.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/FixedField.java	(revision 28000)
@@ -0,0 +1,67 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+
+/**
+ * behavior of a field at a fixed location within a byte array
+ *
+ * @author Marc Johnson (mjohnson at apache dot org
+ */
+
+public interface FixedField
+{
+
+    /**
+     * set the value from its offset into an array of bytes
+     *
+     * @param data the byte array from which the value is to be read
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is out
+     *            of the array's valid index range
+     */
+
+    public void readFromBytes(byte [] data)
+        throws ArrayIndexOutOfBoundsException;
+
+
+    /**
+     * write the value out to an array of bytes at the appropriate
+     * offset
+     *
+     * @param data the array of bytes to which the value is to be
+     *             written
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is out
+     *            of the array's valid index range
+     */
+
+    public void writeToBytes(byte [] data)
+        throws ArrayIndexOutOfBoundsException;
+
+    /**
+     * return the value as a String
+     *
+     * @return the value as a String
+     */
+
+    public String toString();
+}   // end public interface FixedField
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/HexDump.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/HexDump.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/HexDump.java	(revision 28000)
@@ -0,0 +1,245 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+
+/**
+ * dump data in hexadecimal format; derived from a HexDump utility I
+ * wrote in June 2001.
+ *
+ * @author Marc Johnson
+ * @author Glen Stampoultzis  (glens at apache.org)
+ */
+public class HexDump {
+    public static final String EOL = System.getProperty("line.separator");
+    private static final char _hexcodes[] = "0123456789ABCDEF".toCharArray();
+    private static final int _shifts[]   =
+    {
+        60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4, 0
+    };
+
+    private HexDump() {
+        // all static methods, so no need for a public constructor
+    }
+
+    /**
+     * dump an array of bytes to a String
+     *
+     * @param data the byte array to be dumped
+     * @param offset its offset, whatever that might mean
+     * @param index initial index into the byte array
+     *
+     * @exception ArrayIndexOutOfBoundsException if the index is
+     *            outside the data array's bounds
+     * @return output string
+     */
+
+    public static String dump(final byte [] data, final long offset,
+                            final int index) {
+        StringBuffer buffer;
+        if ((index < 0) || (index >= data.length))
+        {
+            throw new ArrayIndexOutOfBoundsException(
+                "illegal index: " + index + " into array of length "
+                + data.length);
+        }
+        long         display_offset = offset + index;
+        buffer         = new StringBuffer(74);
+
+        for (int j = index; j < data.length; j += 16)
+        {
+            int chars_read = data.length - j;
+
+            if (chars_read > 16)
+            {
+                chars_read = 16;
+            }
+            buffer.append(dump(display_offset)).append(' ');
+            for (int k = 0; k < 16; k++)
+            {
+                if (k < chars_read)
+                {
+                    buffer.append(dump(data[ k + j ]));
+                }
+                else
+                {
+                    buffer.append("  ");
+                }
+                buffer.append(' ');
+            }
+            for (int k = 0; k < chars_read; k++)
+            {
+                if ((data[ k + j ] >= ' ') && (data[ k + j ] < 127))
+                {
+                    buffer.append(( char ) data[ k + j ]);
+                }
+                else
+                {
+                    buffer.append('.');
+                }
+            }
+            buffer.append(EOL);
+            display_offset += chars_read;
+        }
+        return buffer.toString();
+    }
+
+
+    private static String dump(final long value)
+    {
+        StringBuffer buf = new StringBuffer();
+        buf.setLength(0);
+        for (int j = 0; j < 8; j++)
+        {
+            buf.append( _hexcodes[ (( int ) (value >> _shifts[ j + _shifts.length - 8 ])) & 15 ]);
+        }
+        return buf.toString();
+    }
+
+    private static String dump(final byte value)
+    {
+        StringBuffer buf = new StringBuffer();
+        buf.setLength(0);
+        for (int j = 0; j < 2; j++)
+        {
+            buf.append(_hexcodes[ (value >> _shifts[ j + 6 ]) & 15 ]);
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Converts the parameter to a hex value.
+     *
+     * @param value     The value to convert
+     * @return          A String representing the array of bytes
+     */
+    public static String toHex(final byte[] value)
+    {
+        StringBuffer retVal = new StringBuffer();
+        retVal.append('[');
+        for(int x = 0; x < value.length; x++)
+        {
+            if (x>0) {
+                retVal.append(", ");
+            }
+            retVal.append(toHex(value[x]));
+        }
+        retVal.append(']');
+        return retVal.toString();
+    }
+
+    /**
+     * Converts the parameter to a hex value.
+     *
+     * @param value     The value to convert
+     * @return          The result right padded with 0
+     */
+    public static String toHex(final short value)
+    {
+        return toHex(value, 4);
+    }
+
+    /**
+     * Converts the parameter to a hex value.
+     *
+     * @param value     The value to convert
+     * @return          The result right padded with 0
+     */
+    public static String toHex(final byte value)
+    {
+        return toHex(value, 2);
+    }
+
+    /**
+     * Converts the parameter to a hex value.
+     *
+     * @param value     The value to convert
+     * @return          The result right padded with 0
+     */
+    public static String toHex(final int value)
+    {
+        return toHex(value, 8);
+    }
+
+    /**
+     * Converts the parameter to a hex value.
+     *
+     * @param value     The value to convert
+     * @return          The result right padded with 0
+     */
+    public static String toHex(final long value)
+    {
+        return toHex(value, 16);
+    }
+
+
+    private static String toHex(final long value, final int digits)
+    {
+        StringBuffer result = new StringBuffer(digits);
+        for (int j = 0; j < digits; j++)
+        {
+            result.append( _hexcodes[ (int) ((value >> _shifts[ j + (16 - digits) ]) & 15)]);
+        }
+        return result.toString();
+    }
+
+    /**
+     * @return char array of uppercase hex chars, zero padded and prefixed with '0x'
+     */
+    private static char[] toHexChars(long pValue, int nBytes) {
+        int charPos = 2 + nBytes*2;
+        // The return type is char array because most callers will probably append the value to a
+        // StringBuffer, or write it to a Stream / Writer so there is no need to create a String;
+        char[] result = new char[charPos];
+
+        long value = pValue;
+        do {
+            result[--charPos] = _hexcodes[(int) (value & 0x0F)];
+            value >>>= 4;
+        } while (charPos > 1);
+
+        // Prefix added to avoid ambiguity
+        result[0] = '0';
+        result[1] = 'x';
+        return result;
+    }
+    /**
+     * @return char array of 4 (zero padded) uppercase hex chars and prefixed with '0x'
+     */
+    public static char[] longToHex(long value) {
+        return toHexChars(value, 8);
+    }
+    /**
+     * @return char array of 4 (zero padded) uppercase hex chars and prefixed with '0x'
+     */
+    public static char[] intToHex(int value) {
+        return toHexChars(value, 4);
+    }
+    /**
+     * @return char array of 2 (zero padded) uppercase hex chars and prefixed with '0x'
+     */
+    public static char[] shortToHex(int value) {
+        return toHexChars(value, 2);
+    }
+    /**
+     * @return char array of 1 (zero padded) uppercase hex chars and prefixed with '0x'
+     */
+    public static char[] byteToHex(int value) {
+        return toHexChars(value, 1);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/HexRead.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/HexRead.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/HexRead.java	(revision 28000)
@@ -0,0 +1,119 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utilities to read hex from files.
+ * TODO - move to test packages
+ *
+ * @author Marc Johnson
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public class HexRead
+{
+    static public byte[] readData( InputStream stream, int eofChar )
+            throws IOException
+    {
+        int characterCount = 0;
+        byte b = (byte) 0;
+        List<Byte> bytes = new ArrayList<Byte>();
+        boolean done = false;
+        while ( !done )
+        {
+            int count = stream.read();
+            char baseChar = 'a';
+            if ( count == eofChar ) break;
+            switch ( count )
+            {
+                case '#':
+                    readToEOL( stream );
+                    break;
+                case '0': case '1': case '2': case '3': case '4': case '5':
+                case '6': case '7': case '8': case '9':
+                    b <<= 4;
+                    b += (byte) ( count - '0' );
+                    characterCount++;
+                    if ( characterCount == 2 )
+                    {
+                        bytes.add( Byte.valueOf( b ) );
+                        characterCount = 0;
+                        b = (byte) 0;
+                    }
+                    break;
+                case 'A':
+                case 'B':
+                case 'C':
+                case 'D':
+                case 'E':
+                case 'F':
+                    baseChar = 'A';
+                case 'a':
+                case 'b':
+                case 'c':
+                case 'd':
+                case 'e':
+                case 'f':
+                    b <<= 4;
+                    b += (byte) ( count + 10 - baseChar );
+                    characterCount++;
+                    if ( characterCount == 2 )
+                    {
+                        bytes.add( Byte.valueOf( b ) );
+                        characterCount = 0;
+                        b = (byte) 0;
+                    }
+                    break;
+                case -1:
+                    done = true;
+                    break;
+                default :
+                    break;
+            }
+        }
+        Byte[] polished = bytes.toArray( new Byte[0] );
+        byte[] rval = new byte[polished.length];
+        for ( int j = 0; j < polished.length; j++ )
+        {
+            rval[j] = polished[j].byteValue();
+        }
+        return rval;
+    }
+
+    static public byte[] readFromString(String data) {
+        try {
+            return readData(new ByteArrayInputStream( data.getBytes() ), -1);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static private void readToEOL( InputStream stream ) throws IOException
+    {
+        int c = stream.read();
+        while ( c != -1 && c != '\n' && c != '\r' )
+        {
+            c = stream.read();
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/IOUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/IOUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/IOUtils.java	(revision 28000)
@@ -0,0 +1,59 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public final class IOUtils {
+	private IOUtils() {
+		// no instances of this class
+	}
+
+
+	/**
+	 * Helper method, just calls <tt>readFully(in, b, 0, b.length)</tt>
+	 */
+	public static int readFully(InputStream in, byte[] b) throws IOException {
+		return readFully(in, b, 0, b.length);
+	}
+
+	/**
+	 * Same as the normal <tt>in.read(b, off, len)</tt>, but tries to ensure
+	 * that the entire len number of bytes is read.
+	 * <p>
+	 * If the end of file is reached before any bytes are read, returns -1. If
+	 * the end of the file is reached after some bytes are read, returns the
+	 * number of bytes read. If the end of the file isn't reached before len
+	 * bytes have been read, will return len bytes.
+	 */
+	public static int readFully(InputStream in, byte[] b, int off, int len) throws IOException {
+		int total = 0;
+		while (true) {
+			int got = in.read(b, off + total, len - total);
+			if (got < 0) {
+				return (total == 0) ? -1 : total;
+			}
+			total += got;
+			if (total == len) {
+				return total;
+			}
+		}
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/IntList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/IntList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/IntList.java	(revision 28000)
@@ -0,0 +1,259 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+/**
+ * A List of int's; as full an implementation of the java.util.List
+ * interface as possible, with an eye toward minimal creation of
+ * objects
+ *
+ * the mimicry of List is as follows:
+ * <ul>
+ * <li> if possible, operations designated 'optional' in the List
+ *      interface are attempted
+ * <li> wherever the List interface refers to an Object, substitute
+ *      int
+ * <li> wherever the List interface refers to a Collection or List,
+ *      substitute IntList
+ * </ul>
+ *
+ * the mimicry is not perfect, however:
+ * <ul>
+ * <li> operations involving Iterators or ListIterators are not
+ *      supported
+ * <li> remove(Object) becomes removeValue to distinguish it from
+ *      remove(int index)
+ * <li> subList is not supported
+ * </ul>
+ *
+ * @author Marc Johnson
+ */
+public class IntList
+{
+    private int[]            _array;
+    private int              _limit;
+    private int              fillval = 0;
+    private static final int _default_size = 128;
+
+    /**
+     * create an IntList of default size
+     */
+
+    public IntList()
+    {
+        this(_default_size);
+    }
+
+    public IntList(final int initialCapacity)
+    {
+        this(initialCapacity,0);
+    }
+
+
+    /**
+     * create an IntList with a predefined initial size
+     *
+     * @param initialCapacity the size for the internal array
+     */
+
+    public IntList(final int initialCapacity, int fillvalue)
+    {
+        _array = new int[ initialCapacity ];
+        if (fillval != 0) {
+            fillval = fillvalue;
+            fillArray(fillval, _array, 0);
+        }
+        _limit = 0;
+    }
+
+    private void fillArray(int val, int[] array, int index) {
+      for (int k = index; k < array.length; k++) {
+        array[k] = val;
+      }
+    }
+
+
+    /**
+     * Appends the specified element to the end of this list
+     *
+     * @param value element to be appended to this list.
+     *
+     * @return true (as per the general contract of the Collection.add
+     *         method).
+     */
+
+    public boolean add(final int value)
+    {
+        if (_limit == _array.length)
+        {
+            growArray(_limit * 2);
+        }
+        _array[ _limit++ ] = value;
+        return true;
+    }
+
+    /**
+     * Appends all of the elements in the specified collection to the
+     * end of this list, in the order that they are returned by the
+     * specified collection's iterator.  The behavior of this
+     * operation is unspecified if the specified collection is
+     * modified while the operation is in progress.  (Note that this
+     * will occur if the specified collection is this list, and it's
+     * nonempty.)
+     *
+     * @param c collection whose elements are to be added to this
+     *          list.
+     *
+     * @return true if this list changed as a result of the call.
+     */
+
+    public boolean addAll(final IntList c)
+    {
+        if (c._limit != 0)
+        {
+            if ((_limit + c._limit) > _array.length)
+            {
+                growArray(_limit + c._limit);
+            }
+            System.arraycopy(c._array, 0, _array, _limit, c._limit);
+            _limit += c._limit;
+        }
+        return true;
+    }
+
+
+
+    /**
+     * Compares the specified object with this list for equality.
+     * Returns true if and only if the specified object is also a
+     * list, both lists have the same size, and all corresponding
+     * pairs of elements in the two lists are equal.  (Two elements e1
+     * and e2 are equal if e1 == e2.)  In other words, two lists are
+     * defined to be equal if they contain the same elements in the
+     * same order.  This definition ensures that the equals method
+     * works properly across different implementations of the List
+     * interface.
+     *
+     * @param o the object to be compared for equality with this list.
+     *
+     * @return true if the specified object is equal to this list.
+     */
+
+    public boolean equals(final Object o)
+    {
+        boolean rval = this == o;
+
+        if (!rval && (o != null) && (o.getClass() == this.getClass()))
+        {
+            IntList other = ( IntList ) o;
+
+            if (other._limit == _limit)
+            {
+
+                // assume match
+                rval = true;
+                for (int j = 0; rval && (j < _limit); j++)
+                {
+                    rval = _array[ j ] == other._array[ j ];
+                }
+            }
+        }
+        return rval;
+    }
+
+    /**
+     * Returns the element at the specified position in this list.
+     *
+     * @param index index of element to return.
+     *
+     * @return the element at the specified position in this list.
+     *
+     * @exception IndexOutOfBoundsException if the index is out of
+     *            range (index < 0 || index >= size()).
+     */
+
+    public int get(final int index)
+    {
+        if (index >= _limit)
+        {
+            throw new IndexOutOfBoundsException();
+        }
+        return _array[ index ];
+    }
+
+    /**
+     * Returns the hash code value for this list.  The hash code of a
+     * list is defined to be the result of the following calculation:
+     *
+     * <code>
+     * hashCode = 1;
+     * Iterator i = list.iterator();
+     * while (i.hasNext()) {
+     *      Object obj = i.next();
+     *      hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
+     * }
+     * </code>
+     *
+     * This ensures that list1.equals(list2) implies that
+     * list1.hashCode()==list2.hashCode() for any two lists, list1 and
+     * list2, as required by the general contract of Object.hashCode.
+     *
+     * @return the hash code value for this list.
+     */
+
+    public int hashCode()
+    {
+        int hash = 0;
+
+        for (int j = 0; j < _limit; j++)
+        {
+            hash = (31 * hash) + _array[ j ];
+        }
+        return hash;
+    }
+
+    /**
+     * Returns the number of elements in this list. If this list
+     * contains more than Integer.MAX_VALUE elements, returns
+     * Integer.MAX_VALUE.
+     *
+     * @return the number of elements in this IntList
+     */
+
+    public int size()
+    {
+        return _limit;
+    }
+
+
+
+    private void growArray(final int new_size)
+    {
+        int   size      = (new_size == _array.length) ? new_size + 1
+                                                      : new_size;
+        int[] new_array = new int[ size ];
+
+        if (fillval != 0) {
+          fillArray(fillval, new_array, _array.length);
+        }
+
+        System.arraycopy(_array, 0, new_array, 0, _limit);
+        _array = new_array;
+    }
+}   // end public class IntList
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/IntMapper.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/IntMapper.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/IntMapper.java	(revision 28000)
@@ -0,0 +1,94 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A List of objects that are indexed AND keyed by an int; also allows for getting
+ * the index of a value in the list
+ *
+ * <p>I am happy is someone wants to re-implement this without using the
+ * internal list and hashmap. If so could you please make sure that
+ * you can add elements half way into the list and have the value-key mappings
+ * update</p>
+ *
+ *
+ * @author Jason Height
+ */
+
+public class IntMapper<T>
+{
+  private List<T> elements;
+  private Map<T,Integer> valueKeyMap;
+
+  private static final int _default_size = 10;
+
+    /**
+     * create an IntMapper of default size
+     */
+
+    public IntMapper()
+    {
+        this(_default_size);
+    }
+
+    public IntMapper(final int initialCapacity)
+    {
+        elements = new ArrayList<T>(initialCapacity);
+        valueKeyMap = new HashMap<T,Integer>(initialCapacity);
+    }
+
+    /**
+     * Appends the specified element to the end of this list
+     *
+     * @param value element to be appended to this list.
+     *
+     * @return true (as per the general contract of the Collection.add
+     *         method).
+     */
+    public boolean add(final T value)
+    {
+      int index = elements.size();
+      elements.add(value);
+      valueKeyMap.put(value, index);
+      return true;
+    }
+
+    public int size() {
+      return elements.size();
+    }
+
+    public T get(int index) {
+      return elements.get(index);
+    }
+
+    public int getIndex(T o) {
+      Integer i = valueKeyMap.get(o);
+      if (i == null)
+        return -1;
+      return i.intValue();
+    }
+
+}   // end public class IntMapper
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/IntegerField.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/IntegerField.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/IntegerField.java	(revision 28000)
@@ -0,0 +1,173 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+
+/**
+ * representation of an integer (32-bit) field at a fixed location
+ * within a byte array
+ *
+ * @author Marc Johnson (mjohnson at apache dot org
+ */
+
+public class IntegerField
+    implements FixedField
+{
+    private int       _value;
+    private final int _offset;
+
+    /**
+     * construct the IntegerField with its offset into its containing
+     * byte array
+     *
+     * @param offset of the field within its byte array
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is
+     *            negative
+     */
+
+    public IntegerField(final int offset)
+        throws ArrayIndexOutOfBoundsException
+    {
+        if (offset < 0)
+        {
+            throw new ArrayIndexOutOfBoundsException("negative offset");
+        }
+        _offset = offset;
+    }
+
+
+    /**
+     * Construct the IntegerField with its offset into its containing
+     * byte array and initialize its value from its byte array
+     *
+     * @param offset of the field within its byte array
+     * @param data the byte array to read the value from
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is not
+     *            within the range of 0..(data.length - 1)
+     */
+
+    public IntegerField(final int offset, final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        this(offset);
+        readFromBytes(data);
+    }
+
+    /**
+     * construct the IntegerField with its offset into its containing
+     * byte array, initialize its value, and write the value to a byte
+     * array
+     *
+     * @param offset of the field within its byte array
+     * @param value the initial value
+     * @param data the byte array to write the value to
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is
+     *            negative or too large
+     */
+
+    public IntegerField(final int offset, final int value, final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        this(offset);
+        set(value, data);
+    }
+
+    /**
+     * get the IntegerField's current value
+     *
+     * @return current value
+     */
+
+    public int get()
+    {
+        return _value;
+    }
+
+
+    /**
+     * set the IntegerField's current value and write it to a byte
+     * array
+     *
+     * @param value to be set
+     * @param data the byte array to write the value to
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is too
+     *            large
+     */
+
+    public void set(final int value, final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        _value = value;
+        writeToBytes(data);
+    }
+
+    /* ********** START implementation of FixedField ********** */
+
+    /**
+     * set the value from its offset into an array of bytes
+     *
+     * @param data the byte array from which the value is to be read
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is too
+     *            large
+     */
+
+    public void readFromBytes(final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        _value = LittleEndian.getInt(data, _offset);
+    }
+
+
+    /**
+     * write the value out to an array of bytes at the appropriate
+     * offset
+     *
+     * @param data the array of bytes to which the value is to be
+     *             written
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is too
+     *            large
+     */
+
+    public void writeToBytes(final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        LittleEndian.putInt(data, _offset, _value);
+    }
+
+    /**
+     * return the value as a String
+     *
+     * @return the value as a String
+     */
+
+    public String toString()
+    {
+        return String.valueOf(_value);
+    }
+
+    /* **********  END  implementation of FixedField ********** */
+}   // end public class IntegerField
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/Internal.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/Internal.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/Internal.java	(revision 28000)
@@ -0,0 +1,38 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+
+/**
+ * Program elements annotated &#64;Internal are intended for
+ * POI internal use only. Such elements are not public by design
+ * and likely to be removed in future versions of POI  or access
+ * to such elements will be changed from 'public' to 'default' or less.
+ *
+ * @author Yegor Kozlov
+ * @since POI-3.6
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Internal {
+    String value() default "";     // NO_UCD
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndian.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndian.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndian.java	(revision 28000)
@@ -0,0 +1,205 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+
+/**
+ *  a utility class for handling little-endian numbers, which the 80x86 world is
+ *  replete with. The methods are all static, and input/output is from/to byte
+ *  arrays, or from InputStreams.
+ *
+ *@author     Marc Johnson (mjohnson at apache dot org)
+ *@author     Andrew Oliver (acoliver at apache dot org)
+ */
+public class LittleEndian implements LittleEndianConsts {
+
+    private LittleEndian() {
+        // no instances of this class
+    }
+
+    /**
+     *  get a short value from a byte array
+     *
+     *@param  data    the byte array
+     *@param  offset  a starting offset into the byte array
+     *@return         the short (16-bit) value
+     */
+    public static short getShort(byte[] data, int offset) {
+        int b0 = data[offset] & 0xFF;
+        int b1 = data[offset+1] & 0xFF;
+        return (short) ((b1 << 8) + (b0 << 0));
+    }
+
+
+    /**
+     *  get an unsigned short value from a byte array
+     *
+     *@param  data    the byte array
+     *@param  offset  a starting offset into the byte array
+     *@return         the unsigned short (16-bit) value in an integer
+     */
+    public static int getUShort(byte[] data, int offset) {
+        int b0 = data[offset] & 0xFF;
+        int b1 = data[offset+1] & 0xFF;
+        return (b1 << 8) + (b0 << 0);
+    }
+
+
+    /**
+     *  get an unsigned short value from the beginning of a byte array
+     *
+     *@param  data  the byte array
+     *@return       the unsigned short (16-bit) value in an int
+     */
+    public static int getUShort(byte[] data) {
+        return getUShort(data, 0);
+    }
+
+    /**
+     *  get an int value from a byte array
+     *
+     *@param  data    the byte array
+     *@param  offset  a starting offset into the byte array
+     *@return         the int (32-bit) value
+     */
+    public static int getInt(byte[] data, int offset) {
+        int i=offset;
+        int b0 = data[i++] & 0xFF;
+        int b1 = data[i++] & 0xFF;
+        int b2 = data[i++] & 0xFF;
+        int b3 = data[i++] & 0xFF;
+        return (b3 << 24) + (b2 << 16) + (b1 << 8) + (b0 << 0);
+    }
+
+
+
+
+    /**
+     *  get an unsigned int value from a byte array
+     *
+     *@param  data    the byte array
+     *@param  offset  a starting offset into the byte array
+     *@return         the unsigned int (32-bit) value in a long
+     */
+    public static long getUInt(byte[] data, int offset) {
+        long retNum = getInt(data, offset);
+        return retNum & 0x00FFFFFFFF;
+    }
+
+
+    /**
+     *  get a long value from a byte array
+     *
+     *@param  data    the byte array
+     *@param  offset  a starting offset into the byte array
+     *@return         the long (64-bit) value
+     */
+    public static long getLong(byte[] data, int offset) {
+        long result = 0;
+		
+		for (int j = offset + LONG_SIZE - 1; j >= offset; j--) {
+		    result <<= 8;
+		    result |= 0xff & data[j];
+		}
+		return result;
+    }
+
+    /**
+     *  get a double value from a byte array, reads it in little endian format
+     *  then converts the resulting revolting IEEE 754 (curse them) floating
+     *  point number to a happy java double
+     *
+     *@param  data    the byte array
+     *@param  offset  a starting offset into the byte array
+     *@return         the double (64-bit) value
+     */
+    public static double getDouble(byte[] data, int offset) {
+        return Double.longBitsToDouble(getLong(data, offset));
+    }
+
+    
+    /**
+     *  put a short value into a byte array
+     *
+     *@param  data    the byte array
+     *@param  offset  a starting offset into the byte array
+     *@param  value   the short (16-bit) value
+     */
+    public static void putShort(byte[] data, int offset, short value) {
+        int i = offset;
+        data[i++] = (byte)((value >>>  0) & 0xFF);
+        data[i++] = (byte)((value >>>  8) & 0xFF);
+    }
+
+    /**
+     *  put a short value into beginning of a byte array
+     *
+     *@param  data   the byte array
+     *@param  value  the short (16-bit) value
+     */
+    public static void putShort(byte[] data, short value) {
+        putShort(data, 0, value);
+    }
+
+
+    /**
+     *  put an int value into a byte array
+     *
+     *@param  data    the byte array
+     *@param  offset  a starting offset into the byte array
+     *@param  value   the int (32-bit) value
+     */
+    public static void putInt(byte[] data, int offset, int value) {
+        int i = offset;
+        data[i++] = (byte)((value >>>  0) & 0xFF);
+        data[i++] = (byte)((value >>>  8) & 0xFF);
+        data[i++] = (byte)((value >>> 16) & 0xFF);
+        data[i++] = (byte)((value >>> 24) & 0xFF);
+    }
+
+
+
+    /**
+     *  put a long value into a byte array
+     *
+     *@param  data    the byte array
+     *@param  offset  a starting offset into the byte array
+     *@param  value   the long (64-bit) value
+     */
+    public static void putLong(byte[] data, int offset, long value) {
+        int limit = LONG_SIZE + offset;
+        long v = value;
+        
+        for (int j = offset; j < limit; j++) {
+            data[j] = (byte) (v & 0xFF);
+            v >>= 8;
+        }
+    }
+
+
+    /**
+     *  put a double value into a byte array
+     *
+     *@param  data    the byte array
+     *@param  offset  a starting offset into the byte array
+     *@param  value   the double (64-bit) value
+     */
+    public static void putDouble(byte[] data, int offset, double value) {
+        putLong(data, offset, Double.doubleToLongBits(value));
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianByteArrayInputStream.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianByteArrayInputStream.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianByteArrayInputStream.java	(revision 28000)
@@ -0,0 +1,113 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+/**
+ * Adapts a plain byte array to {@link LittleEndianInput}
+ *
+ * @author Josh Micich
+ */
+public final class LittleEndianByteArrayInputStream implements LittleEndianInput {
+	private final byte[] _buf;
+	private final int _endIndex;
+	private int _readIndex;
+
+	public LittleEndianByteArrayInputStream(byte[] buf, int startOffset, int maxReadLen) {
+		_buf = buf;
+		_readIndex = startOffset;
+		_endIndex = startOffset + maxReadLen;
+	}
+	public LittleEndianByteArrayInputStream(byte[] buf) {
+		this(buf, 0, buf.length);
+	}
+
+	public int available() {
+		return _endIndex - _readIndex;
+	}
+	private void checkPosition(int i) {
+		if (i > _endIndex - _readIndex) {
+			throw new RuntimeException("Buffer overrun");
+		}
+	}
+
+	public byte readByte() {
+		checkPosition(1);
+		return _buf[_readIndex++];
+	}
+
+	public int readInt() {
+		checkPosition(4);
+		int i = _readIndex;
+
+		int b0 = _buf[i++] & 0xFF;
+		int b1 = _buf[i++] & 0xFF;
+		int b2 = _buf[i++] & 0xFF;
+		int b3 = _buf[i++] & 0xFF;
+		_readIndex = i;
+		return (b3 << 24) + (b2 << 16) + (b1 << 8) + (b0 << 0);
+	}
+	public long readLong() {
+		checkPosition(8);
+		int i = _readIndex;
+
+		int b0 = _buf[i++] & 0xFF;
+		int b1 = _buf[i++] & 0xFF;
+		int b2 = _buf[i++] & 0xFF;
+		int b3 = _buf[i++] & 0xFF;
+		int b4 = _buf[i++] & 0xFF;
+		int b5 = _buf[i++] & 0xFF;
+		int b6 = _buf[i++] & 0xFF;
+		int b7 = _buf[i++] & 0xFF;
+		_readIndex = i;
+		return (((long)b7 << 56) +
+				((long)b6 << 48) +
+				((long)b5 << 40) +
+				((long)b4 << 32) +
+				((long)b3 << 24) +
+				(b2 << 16) +
+				(b1 <<  8) +
+				(b0 <<  0));
+	}
+	public short readShort() {
+		return (short)readUShort();
+	}
+	public int readUByte() {
+		checkPosition(1);
+		return _buf[_readIndex++] & 0xFF;
+	}
+	public int readUShort() {
+		checkPosition(2);
+		int i = _readIndex;
+
+		int b0 = _buf[i++] & 0xFF;
+		int b1 = _buf[i++] & 0xFF;
+		_readIndex = i;
+		return (b1 << 8) + (b0 << 0);
+	}
+	public void readFully(byte[] buf, int off, int len) {
+		checkPosition(len);
+		System.arraycopy(_buf, _readIndex, buf, off, len);
+		_readIndex+=len;
+	}
+	public void readFully(byte[] buf) {
+		readFully(buf, 0, buf.length);
+	}
+	public double readDouble() {
+		return Double.longBitsToDouble(readLong());
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianByteArrayOutputStream.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianByteArrayOutputStream.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianByteArrayOutputStream.java	(revision 28000)
@@ -0,0 +1,106 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+
+/**
+ * Adapts a plain byte array to {@link LittleEndianOutput} 
+ * 
+ * 
+ * @author Josh Micich
+ */
+public final class LittleEndianByteArrayOutputStream implements DelayableLittleEndianOutput {
+	private final byte[] _buf;
+	private final int _endIndex;
+	private int _writeIndex;
+
+	public LittleEndianByteArrayOutputStream(byte[] buf, int startOffset, int maxWriteLen) {
+		if (startOffset < 0 || startOffset > buf.length) {
+			throw new IllegalArgumentException("Specified startOffset (" + startOffset 
+					+ ") is out of allowable range (0.." + buf.length + ")");
+		}
+		_buf = buf;
+		_writeIndex = startOffset;
+		_endIndex = startOffset + maxWriteLen;
+		if (_endIndex < startOffset ||  _endIndex > buf.length) {
+			throw new IllegalArgumentException("calculated end index (" + _endIndex 
+					+ ") is out of allowable range (" + _writeIndex + ".." + buf.length + ")");
+		}
+	}
+	public LittleEndianByteArrayOutputStream(byte[] buf, int startOffset) {
+		this(buf, startOffset, buf.length - startOffset);
+	}
+
+	private void checkPosition(int i) {
+		if (i > _endIndex - _writeIndex) {
+			throw new RuntimeException("Buffer overrun");
+		}
+	}
+
+	public void writeByte(int v) {
+		checkPosition(1);
+		_buf[_writeIndex++] = (byte)v;
+	}
+
+	public void writeDouble(double v) {
+		writeLong(Double.doubleToLongBits(v));
+	}
+
+	public void writeInt(int v) {
+		checkPosition(4);
+		int i = _writeIndex;
+		_buf[i++] = (byte)((v >>>  0) & 0xFF);
+		_buf[i++] = (byte)((v >>>  8) & 0xFF);
+		_buf[i++] = (byte)((v >>> 16) & 0xFF);
+		_buf[i++] = (byte)((v >>> 24) & 0xFF);
+		_writeIndex = i;
+	}
+
+	public void writeLong(long v) {
+		writeInt((int)(v >>  0));
+		writeInt((int)(v >> 32));
+	}
+
+	public void writeShort(int v) {
+		checkPosition(2);
+		int i = _writeIndex;
+		_buf[i++] = (byte)((v >>>  0) & 0xFF);
+		_buf[i++] = (byte)((v >>>  8) & 0xFF);
+		_writeIndex = i;
+	}
+	public void write(byte[] b) {
+		int len = b.length;
+		checkPosition(len);
+		System.arraycopy(b, 0, _buf, _writeIndex, len);
+		_writeIndex += len;
+	}
+	public void write(byte[] b, int offset, int len) {
+		checkPosition(len);
+		System.arraycopy(b, offset, _buf, _writeIndex, len);
+		_writeIndex += len;
+	}
+	public int getWriteIndex() {
+		return _writeIndex;
+	}
+	public LittleEndianOutput createDelayedOutput(int size) {
+		checkPosition(size);
+		LittleEndianOutput result = new LittleEndianByteArrayOutputStream(_buf, _writeIndex, size);
+		_writeIndex += size;
+		return result;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianConsts.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianConsts.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianConsts.java	(revision 28000)
@@ -0,0 +1,39 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+/**
+ * a repository for constants shared by classes within this package
+ *
+ * @author Marc Johnson
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ */
+
+public interface LittleEndianConsts
+{
+
+    // sizes of various numbers in this environment
+    public static final int BYTE_SIZE   = 1;
+    public static final int SHORT_SIZE  = 2;
+    public static final int INT_SIZE    = 4;
+    public static final int LONG_SIZE   = 8;
+    public static final int DOUBLE_SIZE = 8;
+}   // end public interface LittleEndianConsts
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianInput.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianInput.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianInput.java	(revision 28000)
@@ -0,0 +1,34 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+/**
+ *
+ * @author Josh Micich
+ */
+public interface LittleEndianInput {
+	int available();
+	byte readByte();
+	int readUByte();
+	short readShort();
+	int readUShort();
+	int readInt();
+	long readLong();
+	double readDouble();
+	void readFully(byte[] buf);
+	void readFully(byte[] buf, int off, int len);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianInputStream.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianInputStream.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianInputStream.java	(revision 28000)
@@ -0,0 +1,144 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Wraps an {@link InputStream} providing {@link LittleEndianInput}<p/>
+ *
+ * This class does not buffer any input, so the stream read position maintained
+ * by this class is consistent with that of the inner stream.
+ *
+ * @author Josh Micich
+ */
+public class LittleEndianInputStream extends FilterInputStream implements LittleEndianInput {
+	public LittleEndianInputStream(InputStream is) {
+		super(is);
+	}
+	public int available() {
+		try {
+			return super.available();
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+	}
+	public byte readByte() {
+		return (byte)readUByte();
+	}
+	public int readUByte() {
+		int ch;
+		try {
+			ch = in.read();
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+		checkEOF(ch);
+		return ch;
+	}
+	public double readDouble() {
+		return Double.longBitsToDouble(readLong());
+	}
+	public int readInt() {
+		int ch1;
+		int ch2;
+		int ch3;
+		int ch4;
+		try {
+			ch1 = in.read();
+			ch2 = in.read();
+			ch3 = in.read();
+			ch4 = in.read();
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+		checkEOF(ch1 | ch2 | ch3 | ch4);
+		return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
+	}
+	public long readLong() {
+		int b0;
+		int b1;
+		int b2;
+		int b3;
+		int b4;
+		int b5;
+		int b6;
+		int b7;
+		try {
+			b0 = in.read();
+			b1 = in.read();
+			b2 = in.read();
+			b3 = in.read();
+			b4 = in.read();
+			b5 = in.read();
+			b6 = in.read();
+			b7 = in.read();
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+		checkEOF(b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7);
+		return (((long)b7 << 56) +
+				((long)b6 << 48) +
+				((long)b5 << 40) +
+				((long)b4 << 32) +
+				((long)b3 << 24) +
+				(b2 << 16) +
+				(b1 <<  8) +
+				(b0 <<  0));
+	}
+	public short readShort() {
+		return (short)readUShort();
+	}
+	public int readUShort() {
+		int ch1;
+		int ch2;
+		try {
+			ch1 = in.read();
+			ch2 = in.read();
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+		checkEOF(ch1 | ch2);
+		return (ch2 << 8) + (ch1 << 0);
+	}
+	private static void checkEOF(int value) {
+		if (value <0) {
+			throw new RuntimeException("Unexpected end-of-file");
+		}
+	}
+
+	public void readFully(byte[] buf) {
+		readFully(buf, 0, buf.length);
+	}
+
+	public void readFully(byte[] buf, int off, int len) {
+		int max = off+len;
+		for(int i=off; i<max; i++) {
+			int ch;
+			try {
+				ch = in.read();
+			} catch (IOException e) {
+				throw new RuntimeException(e);
+			}
+			checkEOF(ch);
+			buf[i] = (byte) ch;
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianOutput.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianOutput.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/LittleEndianOutput.java	(revision 28000)
@@ -0,0 +1,31 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+/**
+ *
+ * @author Josh Micich
+ */
+public interface LittleEndianOutput {
+	void writeByte(int v);
+	void writeShort(int v);
+	void writeInt(int v);
+	void writeLong(long v);
+	void writeDouble(double v);
+	void write(byte[] b);
+	void write(byte[] b, int offset, int len);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/NullLogger.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/NullLogger.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/NullLogger.java	(revision 28000)
@@ -0,0 +1,461 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+/**
+ * A logger class that strives to make it as easy as possible for
+ * developers to write log calls, while simultaneously making those
+ * calls as cheap as possible by performing lazy evaluation of the log
+ * message.<p>
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @author Nicola Ken Barozzi (nicolaken at apache.org)
+ */
+public class NullLogger extends POILogger
+{
+    public void initialize(final String cat)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 The object to log.
+     */
+
+    public void log(final int level, final Object obj1)
+    {
+        //do nothing
+    }
+
+    /**
+     * Check if a logger is enabled to log at the specified level
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     */
+
+    public boolean check(final int level)
+    {
+       return false;
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first object to place in the message
+     * @param obj2 second object to place in the message
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third Object to place in the message
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2,
+                    final Object obj3)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third Object to place in the message
+     * @param obj4 fourth Object to place in the message
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2,
+                    final Object obj3, final Object obj4)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third Object to place in the message
+     * @param obj4 fourth Object to place in the message
+     * @param obj5 fifth Object to place in the message
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2,
+                    final Object obj3, final Object obj4, final Object obj5)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third Object to place in the message
+     * @param obj4 fourth Object to place in the message
+     * @param obj5 fifth Object to place in the message
+     * @param obj6 sixth Object to place in the message
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2,
+                    final Object obj3, final Object obj4, final Object obj5,
+                    final Object obj6)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third Object to place in the message
+     * @param obj4 fourth Object to place in the message
+     * @param obj5 fifth Object to place in the message
+     * @param obj6 sixth Object to place in the message
+     * @param obj7 seventh Object to place in the message
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2,
+                    final Object obj3, final Object obj4, final Object obj5,
+                    final Object obj6, final Object obj7)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third Object to place in the message
+     * @param obj4 fourth Object to place in the message
+     * @param obj5 fifth Object to place in the message
+     * @param obj6 sixth Object to place in the message
+     * @param obj7 seventh Object to place in the message
+     * @param obj8 eighth Object to place in the message
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2,
+                    final Object obj3, final Object obj4, final Object obj5,
+                    final Object obj6, final Object obj7, final Object obj8)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 The object to log.  This is converted to a string.
+     * @param exception An exception to be logged
+     */
+
+    public void log(final int level, final Object obj1,
+                    final Throwable exception)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param exception An exception to be logged
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2,
+                    final Throwable exception)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third object to place in the message
+     * @param exception An error message to be logged
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2,
+                    final Object obj3, final Throwable exception)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third object to place in the message
+     * @param obj4 fourth object to place in the message
+     * @param exception An exception to be logged
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2,
+                    final Object obj3, final Object obj4,
+                    final Throwable exception)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third object to place in the message
+     * @param obj4 fourth object to place in the message
+     * @param obj5 fifth object to place in the message
+     * @param exception An exception to be logged
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2,
+                    final Object obj3, final Object obj4, final Object obj5,
+                    final Throwable exception)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third object to place in the message
+     * @param obj4 fourth object to place in the message
+     * @param obj5 fifth object to place in the message
+     * @param obj6 sixth object to place in the message
+     * @param exception An exception to be logged
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2,
+                    final Object obj3, final Object obj4, final Object obj5,
+                    final Object obj6, final Throwable exception)
+    {
+       //do nothing
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third object to place in the message
+     * @param obj4 fourth object to place in the message
+     * @param obj5 fifth object to place in the message
+     * @param obj6 sixth object to place in the message
+     * @param obj7 seventh object to place in the message
+     * @param exception An exception to be logged
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2,
+                    final Object obj3, final Object obj4, final Object obj5,
+                    final Object obj6, final Object obj7,
+                    final Throwable exception)
+    {
+      //do nothing
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third object to place in the message
+     * @param obj4 fourth object to place in the message
+     * @param obj5 fifth object to place in the message
+     * @param obj6 sixth object to place in the message
+     * @param obj7 seventh object to place in the message
+     * @param obj8 eighth object to place in the message
+     * @param exception An exception to be logged
+     */
+
+    public void log(final int level, final Object obj1, final Object obj2,
+                    final Object obj3, final Object obj4, final Object obj5,
+                    final Object obj6, final Object obj7, final Object obj8,
+                    final Throwable exception)
+    {
+       //do nothing
+    }
+
+    /**
+     * Logs a formated message. The message itself may contain %
+     * characters as place holders. This routine will attempt to match
+     * the placeholder by looking at the type of parameter passed to
+     * obj1.<p>
+     *
+     * If the parameter is an array, it traverses the array first and
+     * matches parameters sequentially against the array items.
+     * Otherwise the parameters after <code>message</code> are matched
+     * in order.<p>
+     *
+     * If the place holder matches against a number it is printed as a
+     * whole number. This can be overridden by specifying a precision
+     * in the form %n.m where n is the padding for the whole part and
+     * m is the number of decimal places to display. n can be excluded
+     * if desired. n and m may not be more than 9.<p>
+     *
+     * If the last parameter (after flattening) is a Throwable it is
+     * logged specially.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param message The message to log.
+     * @param obj1 The first object to match against.
+     */
+
+    public void logFormatted(final int level, final String message,
+                             final Object obj1)
+    {
+       //do nothing
+    }
+
+    /**
+     * Logs a formated message. The message itself may contain %
+     * characters as place holders. This routine will attempt to match
+     * the placeholder by looking at the type of parameter passed to
+     * obj1.<p>
+     *
+     * If the parameter is an array, it traverses the array first and
+     * matches parameters sequentially against the array items.
+     * Otherwise the parameters after <code>message</code> are matched
+     * in order.<p>
+     *
+     * If the place holder matches against a number it is printed as a
+     * whole number. This can be overridden by specifying a precision
+     * in the form %n.m where n is the padding for the whole part and
+     * m is the number of decimal places to display. n can be excluded
+     * if desired. n and m may not be more than 9.<p>
+     *
+     * If the last parameter (after flattening) is a Throwable it is
+     * logged specially.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param message The message to log.
+     * @param obj1 The first object to match against.
+     * @param obj2 The second object to match against.
+     */
+
+    public void logFormatted(final int level, final String message,
+                             final Object obj1, final Object obj2)
+    {
+       //do nothing
+    }
+
+    /**
+     * Logs a formated message. The message itself may contain %
+     * characters as place holders. This routine will attempt to match
+     * the placeholder by looking at the type of parameter passed to
+     * obj1.<p>
+     *
+     * If the parameter is an array, it traverses the array first and
+     * matches parameters sequentially against the array items.
+     * Otherwise the parameters after <code>message</code> are matched
+     * in order.<p>
+     *
+     * If the place holder matches against a number it is printed as a
+     * whole number. This can be overridden by specifying a precision
+     * in the form %n.m where n is the padding for the whole part and
+     * m is the number of decimal places to display. n can be excluded
+     * if desired. n and m may not be more than 9.<p>
+     *
+     * If the last parameter (after flattening) is a Throwable it is
+     * logged specially.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param message The message to log.
+     * @param obj1 The first object to match against.
+     * @param obj2 The second object to match against.
+     * @param obj3 The third object to match against.
+     */
+
+    public void logFormatted(final int level, final String message,
+                             final Object obj1, final Object obj2,
+                             final Object obj3)
+    {
+       //do nothing
+    }
+
+    /**
+     * Logs a formated message. The message itself may contain %
+     * characters as place holders. This routine will attempt to match
+     * the placeholder by looking at the type of parameter passed to
+     * obj1.<p>
+     *
+     * If the parameter is an array, it traverses the array first and
+     * matches parameters sequentially against the array items.
+     * Otherwise the parameters after <code>message</code> are matched
+     * in order.<p>
+     *
+     * If the place holder matches against a number it is printed as a
+     * whole number. This can be overridden by specifying a precision
+     * in the form %n.m where n is the padding for the whole part and
+     * m is the number of decimal places to display. n can be excluded
+     * if desired. n and m may not be more than 9.<p>
+     *
+     * If the last parameter (after flattening) is a Throwable it is
+     * logged specially.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param message The message to log.
+     * @param obj1 The first object to match against.
+     * @param obj2 The second object to match against.
+     * @param obj3 The third object to match against.
+     * @param obj4 The forth object to match against.
+     */
+
+    public void logFormatted(final int level, final String message,
+                             final Object obj1, final Object obj2,
+                             final Object obj3, final Object obj4)
+    {
+       //do nothing
+    }
+
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/POILogFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/POILogFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/POILogFactory.java	(revision 28000)
@@ -0,0 +1,128 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Provides logging without clients having to mess with
+ * configuration/initialization.
+ *
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Marc Johnson (mjohnson at apache dot org)
+ * @author Nicola Ken Barozzi (nicolaken at apache.org)
+ */
+
+public class POILogFactory
+{
+
+    /**
+     * Map of POILogger instances, with classes as keys
+     */
+    private static Map<String, POILogger> _loggers = new HashMap<String, POILogger>();
+
+    /**
+     * A common instance of NullLogger, as it does nothing
+     *  we only need the one
+     */
+    private static POILogger _nullLogger = new NullLogger();
+    /**
+     * The name of the class to use. Initialised the
+     *  first time we need it
+     */
+    private static String _loggerClassName = null;
+
+    /**
+     * Construct a POILogFactory.
+     */
+    private POILogFactory()
+    {
+    }
+
+    /**
+     * Get a logger, based on a class name
+     *
+     * @param theclass the class whose name defines the log
+     *
+     * @return a POILogger for the specified class
+     */
+
+    public static POILogger getLogger(final Class<?> theclass)
+    {
+        return getLogger(theclass.getName());
+    }
+    
+    /**
+     * Get a logger, based on a String
+     *
+     * @param cat the String that defines the log
+     *
+     * @return a POILogger for the specified class
+     */
+
+    public static POILogger getLogger(final String cat)
+    {
+        POILogger logger = null;
+        
+        // If we haven't found out what logger to use yet,
+        //  then do so now
+        // Don't look it up until we're first asked, so
+        //  that our users can set the system property
+        //  between class loading and first use
+        if(_loggerClassName == null) {
+        	try {
+        		_loggerClassName = System.getProperty("org.apache.poi.util.POILogger");
+        	} catch(Exception e) {}
+        	
+        	// Use the default logger if none specified,
+        	//  or none could be fetched
+        	if(_loggerClassName == null) {
+        		_loggerClassName = _nullLogger.getClass().getName();
+        	}
+        }
+        
+        // Short circuit for the null logger, which
+        //  ignores all categories
+        if(_loggerClassName.equals(_nullLogger.getClass().getName())) {
+        	return _nullLogger;
+        }
+
+        
+        // Fetch the right logger for them, creating
+        //  it if that's required 
+        if (_loggers.containsKey(cat)) {
+            logger = _loggers.get(cat);
+        } else {
+            try {
+              Class<?> loggerClass = Class.forName(_loggerClassName);
+              logger = ( POILogger ) loggerClass.newInstance();
+              logger.initialize(cat);
+            } catch(Exception e) {
+              // Give up and use the null logger
+              logger = _nullLogger;
+            }
+            
+            // Save for next time
+            _loggers.put(cat, logger);
+        }
+        return logger;
+    }
+}   // end public class POILogFactory
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/POILogger.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/POILogger.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/POILogger.java	(revision 28000)
@@ -0,0 +1,664 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A logger interface that strives to make it as easy as possible for
+ * developers to write log calls, while simultaneously making those
+ * calls as cheap as possible by performing lazy evaluation of the log
+ * message.<p>
+ *
+ * @author Marc Johnson (mjohnson at apache dot org)
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @author Nicola Ken Barozzi (nicolaken at apache.org)
+ */
+public abstract class POILogger {
+
+    public static int DEBUG = 1;
+    public static int WARN  = 5;
+    public static int ERROR = 7;
+
+    /**
+     * package scope so it cannot be instantiated outside of the util
+     * package. You need a POILogger? Go to the POILogFactory for one
+     */
+    POILogger() {
+        // no fields to initialise
+    }
+
+    abstract public void initialize(String cat);
+
+    /**
+     * Log a message
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 The object to log.  This is converted to a string.
+     */
+    abstract public void log(int level, Object obj1);
+
+    /**
+     * Log a message
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 The object to log.  This is converted to a string.
+     * @param exception An exception to be logged
+     */
+    abstract public void log(int level, Object obj1,
+                    final Throwable exception);
+
+
+    /**
+     * Check if a logger is enabled to log at the specified level
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     */
+    abstract public boolean check(int level);
+
+   /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first object to place in the message
+     * @param obj2 second object to place in the message
+     */
+    public void log(int level, Object obj1, Object obj2)
+    {
+        if (check(level))
+        {
+            log(level, new StringBuffer(32).append(obj1).append(obj2));
+        }
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third Object to place in the message
+     */
+    public void log(int level, Object obj1, Object obj2,
+                    Object obj3)
+    {
+
+
+        if (check(level))
+        {
+            log(level,
+                    new StringBuffer(48).append(obj1).append(obj2)
+                        .append(obj3));
+        }
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third Object to place in the message
+     * @param obj4 fourth Object to place in the message
+     */
+    public void log(int level, Object obj1, Object obj2,
+                    Object obj3, Object obj4)
+    {
+
+
+        if (check(level))
+        {
+            log(level,
+                    new StringBuffer(64).append(obj1).append(obj2)
+                        .append(obj3).append(obj4));
+        }
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third Object to place in the message
+     * @param obj4 fourth Object to place in the message
+     * @param obj5 fifth Object to place in the message
+     */
+    public void log(int level, Object obj1, Object obj2,
+                    Object obj3, Object obj4, Object obj5)
+    {
+
+
+        if (check(level))
+        {
+            log(level,
+                    new StringBuffer(80).append(obj1).append(obj2)
+                        .append(obj3).append(obj4).append(obj5));
+        }
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third Object to place in the message
+     * @param obj4 fourth Object to place in the message
+     * @param obj5 fifth Object to place in the message
+     * @param obj6 sixth Object to place in the message
+     */
+    public void log(int level, Object obj1, Object obj2,
+                    Object obj3, Object obj4, Object obj5,
+                    Object obj6)
+    {
+
+
+        if (check(level))
+        {
+            log(level ,
+                    new StringBuffer(96).append(obj1).append(obj2)
+                        .append(obj3).append(obj4).append(obj5).append(obj6));
+        }
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third Object to place in the message
+     * @param obj4 fourth Object to place in the message
+     * @param obj5 fifth Object to place in the message
+     * @param obj6 sixth Object to place in the message
+     * @param obj7 seventh Object to place in the message
+     */
+    public void log(int level, Object obj1, Object obj2,
+                    Object obj3, Object obj4, Object obj5,
+                    Object obj6, Object obj7)
+    {
+
+
+        if (check(level))
+        {
+            log(level,
+                    new StringBuffer(112).append(obj1).append(obj2)
+                        .append(obj3).append(obj4).append(obj5).append(obj6)
+                        .append(obj7));
+        }
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third Object to place in the message
+     * @param obj4 fourth Object to place in the message
+     * @param obj5 fifth Object to place in the message
+     * @param obj6 sixth Object to place in the message
+     * @param obj7 seventh Object to place in the message
+     * @param obj8 eighth Object to place in the message
+     */
+    public void log(int level, Object obj1, Object obj2,
+                    Object obj3, Object obj4, Object obj5,
+                    Object obj6, Object obj7, Object obj8)
+    {
+
+
+        if (check(level))
+        {
+            log(level,
+                    new StringBuffer(128).append(obj1).append(obj2)
+                        .append(obj3).append(obj4).append(obj5).append(obj6)
+                        .append(obj7).append(obj8));
+        }
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param exception An exception to be logged
+     */
+    public void log(int level, Object obj1, Object obj2,
+                    final Throwable exception)
+    {
+
+
+        if (check(level))
+        {
+            log(level, new StringBuffer(32).append(obj1).append(obj2),
+                    exception);
+        }
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third object to place in the message
+     * @param exception An error message to be logged
+     */
+    public void log(int level, Object obj1, Object obj2,
+                    Object obj3, final Throwable exception)
+    {
+
+
+        if (check(level))
+        {
+            log(level, new StringBuffer(48).append(obj1).append(obj2)
+                .append(obj3), exception);
+        }
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third object to place in the message
+     * @param obj4 fourth object to place in the message
+     * @param exception An exception to be logged
+     */
+    public void log(int level, Object obj1, Object obj2,
+                    Object obj3, Object obj4,
+                    final Throwable exception)
+    {
+
+
+        if (check(level))
+        {
+            log(level, new StringBuffer(64).append(obj1).append(obj2)
+                .append(obj3).append(obj4), exception);
+        }
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third object to place in the message
+     * @param obj4 fourth object to place in the message
+     * @param obj5 fifth object to place in the message
+     * @param exception An exception to be logged
+     */
+    public void log(int level, Object obj1, Object obj2,
+                    Object obj3, Object obj4, Object obj5,
+                    final Throwable exception)
+    {
+
+
+        if (check(level))
+        {
+            log(level, new StringBuffer(80).append(obj1).append(obj2)
+                .append(obj3).append(obj4).append(obj5), exception);
+        }
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third object to place in the message
+     * @param obj4 fourth object to place in the message
+     * @param obj5 fifth object to place in the message
+     * @param obj6 sixth object to place in the message
+     * @param exception An exception to be logged
+     */
+    public void log(int level, Object obj1, Object obj2,
+                    Object obj3, Object obj4, Object obj5,
+                    Object obj6, final Throwable exception)
+    {
+
+
+        if (check(level))
+        {
+            log(level , new StringBuffer(96).append(obj1)
+                .append(obj2).append(obj3).append(obj4).append(obj5)
+                .append(obj6), exception);
+        }
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third object to place in the message
+     * @param obj4 fourth object to place in the message
+     * @param obj5 fifth object to place in the message
+     * @param obj6 sixth object to place in the message
+     * @param obj7 seventh object to place in the message
+     * @param exception An exception to be logged
+     */
+    public void log(int level, Object obj1, Object obj2,
+                    Object obj3, Object obj4, Object obj5,
+                    Object obj6, Object obj7,
+                    final Throwable exception)
+    {
+
+
+        if (check(level))
+        {
+            log(level, new StringBuffer(112).append(obj1).append(obj2)
+                .append(obj3).append(obj4).append(obj5).append(obj6)
+                .append(obj7), exception);
+        }
+    }
+
+    /**
+     * Log a message. Lazily appends Object parameters together.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param obj1 first Object to place in the message
+     * @param obj2 second Object to place in the message
+     * @param obj3 third object to place in the message
+     * @param obj4 fourth object to place in the message
+     * @param obj5 fifth object to place in the message
+     * @param obj6 sixth object to place in the message
+     * @param obj7 seventh object to place in the message
+     * @param obj8 eighth object to place in the message
+     * @param exception An exception to be logged
+     */
+    public void log(int level, Object obj1, Object obj2,
+                    Object obj3, Object obj4, Object obj5,
+                    Object obj6, Object obj7, Object obj8,
+                    final Throwable exception)
+    {
+
+
+        if (check(level))
+        {
+            log(level, new StringBuffer(128).append(obj1).append(obj2)
+                .append(obj3).append(obj4).append(obj5).append(obj6)
+                .append(obj7).append(obj8), exception);
+        }
+    }
+
+    /**
+     * Logs a formated message. The message itself may contain %
+     * characters as place holders. This routine will attempt to match
+     * the placeholder by looking at the type of parameter passed to
+     * obj1.<p>
+     *
+     * If the parameter is an array, it traverses the array first and
+     * matches parameters sequentially against the array items.
+     * Otherwise the parameters after <code>message</code> are matched
+     * in order.<p>
+     *
+     * If the place holder matches against a number it is printed as a
+     * whole number. This can be overridden by specifying a precision
+     * in the form %n.m where n is the padding for the whole part and
+     * m is the number of decimal places to display. n can be excluded
+     * if desired. n and m may not be more than 9.<p>
+     *
+     * If the last parameter (after flattening) is a Throwable it is
+     * logged specially.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param message The message to log.
+     * @param obj1 The first object to match against.
+     */
+    public void logFormatted(int level, String message,
+                             Object obj1)
+    {
+        commonLogFormatted(level, message, new Object[]
+        {
+            obj1
+        });
+    }
+
+    /**
+     * Logs a formated message. The message itself may contain %
+     * characters as place holders. This routine will attempt to match
+     * the placeholder by looking at the type of parameter passed to
+     * obj1.<p>
+     *
+     * If the parameter is an array, it traverses the array first and
+     * matches parameters sequentially against the array items.
+     * Otherwise the parameters after <code>message</code> are matched
+     * in order.<p>
+     *
+     * If the place holder matches against a number it is printed as a
+     * whole number. This can be overridden by specifying a precision
+     * in the form %n.m where n is the padding for the whole part and
+     * m is the number of decimal places to display. n can be excluded
+     * if desired. n and m may not be more than 9.<p>
+     *
+     * If the last parameter (after flattening) is a Throwable it is
+     * logged specially.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param message The message to log.
+     * @param obj1 The first object to match against.
+     * @param obj2 The second object to match against.
+     */
+    public void logFormatted(int level, String message,
+                             Object obj1, Object obj2)
+    {
+        commonLogFormatted(level, message, new Object[]
+        {
+            obj1, obj2
+        });
+    }
+
+    /**
+     * Logs a formated message. The message itself may contain %
+     * characters as place holders. This routine will attempt to match
+     * the placeholder by looking at the type of parameter passed to
+     * obj1.<p>
+     *
+     * If the parameter is an array, it traverses the array first and
+     * matches parameters sequentially against the array items.
+     * Otherwise the parameters after <code>message</code> are matched
+     * in order.<p>
+     *
+     * If the place holder matches against a number it is printed as a
+     * whole number. This can be overridden by specifying a precision
+     * in the form %n.m where n is the padding for the whole part and
+     * m is the number of decimal places to display. n can be excluded
+     * if desired. n and m may not be more than 9.<p>
+     *
+     * If the last parameter (after flattening) is a Throwable it is
+     * logged specially.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param message The message to log.
+     * @param obj1 The first object to match against.
+     * @param obj2 The second object to match against.
+     * @param obj3 The third object to match against.
+     */
+    public void logFormatted(int level, String message,
+                             Object obj1, Object obj2,
+                             Object obj3)
+    {
+        commonLogFormatted(level, message, new Object[]
+        {
+            obj1, obj2, obj3
+        });
+    }
+
+    /**
+     * Logs a formated message. The message itself may contain %
+     * characters as place holders. This routine will attempt to match
+     * the placeholder by looking at the type of parameter passed to
+     * obj1.<p>
+     *
+     * If the parameter is an array, it traverses the array first and
+     * matches parameters sequentially against the array items.
+     * Otherwise the parameters after <code>message</code> are matched
+     * in order.<p>
+     *
+     * If the place holder matches against a number it is printed as a
+     * whole number. This can be overridden by specifying a precision
+     * in the form %n.m where n is the padding for the whole part and
+     * m is the number of decimal places to display. n can be excluded
+     * if desired. n and m may not be more than 9.<p>
+     *
+     * If the last parameter (after flattening) is a Throwable it is
+     * logged specially.
+     *
+     * @param level One of DEBUG, INFO, WARN, ERROR, FATAL
+     * @param message The message to log.
+     * @param obj1 The first object to match against.
+     * @param obj2 The second object to match against.
+     * @param obj3 The third object to match against.
+     * @param obj4 The forth object to match against.
+     */
+    public void logFormatted(int level, String message,
+                             Object obj1, Object obj2,
+                             Object obj3, Object obj4)
+    {
+        commonLogFormatted(level, message, new Object[]
+        {
+            obj1, obj2, obj3, obj4
+        });
+    }
+
+    private void commonLogFormatted(int level, String message,
+                                    Object [] unflatParams)
+    {
+
+
+        if (check(level))
+        {
+            Object[] params = flattenArrays(unflatParams);
+
+            if (params[ params.length - 1 ] instanceof Throwable)
+            {
+                log(level, StringUtil.format(message, params),
+                    ( Throwable ) params[ params.length - 1 ]);
+            }
+            else
+            {
+                log(level, StringUtil.format(message, params));
+            }
+        }
+    }
+
+    /**
+     * Flattens any contained objects. Only tranverses one level deep.
+     */
+    private Object [] flattenArrays(Object [] objects)
+    {
+        List<Object> results = new ArrayList<Object>();
+
+        for (int i = 0; i < objects.length; i++)
+        {
+            results.addAll(objectToObjectArray(objects[ i ]));
+        }
+        return results.toArray(new Object[ results.size() ]);
+    }
+
+    private List<Object> objectToObjectArray(Object object)
+    {
+        List<Object> results = new ArrayList<Object>();
+
+        if (object instanceof byte [])
+        {
+            byte[] array = ( byte [] ) object;
+
+            for (int j = 0; j < array.length; j++)
+            {
+                results.add(Byte.valueOf(array[ j ]));
+            }
+        }
+        if (object instanceof char [])
+        {
+            char[] array = ( char [] ) object;
+
+            for (int j = 0; j < array.length; j++)
+            {
+                results.add(new Character(array[ j ]));
+            }
+        }
+        else if (object instanceof short [])
+        {
+            short[] array = ( short [] ) object;
+
+            for (int j = 0; j < array.length; j++)
+            {
+                results.add(Short.valueOf(array[ j ]));
+            }
+        }
+        else if (object instanceof int [])
+        {
+            int[] array = ( int [] ) object;
+
+            for (int j = 0; j < array.length; j++)
+            {
+                results.add(Integer.valueOf(array[ j ]));
+            }
+        }
+        else if (object instanceof long [])
+        {
+            long[] array = ( long [] ) object;
+
+            for (int j = 0; j < array.length; j++)
+            {
+                results.add(Long.valueOf(array[ j ]));
+            }
+        }
+        else if (object instanceof float [])
+        {
+            float[] array = ( float [] ) object;
+
+            for (int j = 0; j < array.length; j++)
+            {
+                results.add(new Float(array[ j ]));
+            }
+        }
+        else if (object instanceof double [])
+        {
+            double[] array = ( double [] ) object;
+
+            for (int j = 0; j < array.length; j++)
+            {
+                results.add(new Double(array[ j ]));
+            }
+        }
+        else if (object instanceof Object [])
+        {
+            Object[] array = ( Object [] ) object;
+
+            for (int j = 0; j < array.length; j++)
+            {
+                results.add(array[ j ]);
+            }
+        }
+        else
+        {
+            results.add(object);
+        }
+        return results;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/RecordFormatException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/RecordFormatException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/RecordFormatException.java	(revision 28000)
@@ -0,0 +1,40 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+/**
+ * A common exception thrown by our binary format parsers
+ *  (especially HSSF and DDF), when they hit invalid
+ *  format or data when processing a record.
+ */
+@SuppressWarnings("serial")
+public class RecordFormatException
+    extends RuntimeException
+{
+    public RecordFormatException(String exception)
+    {
+        super(exception);
+    }
+    
+    public RecordFormatException(String exception, Throwable thr) {
+      super(exception, thr);
+    }
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/ShortField.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/ShortField.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/ShortField.java	(revision 28000)
@@ -0,0 +1,171 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+
+/**
+ * representation of a short (16-bit) field at a fixed location within
+ * a byte array
+ *
+ * @author Marc Johnson (mjohnson at apache dot org
+ */
+
+public class ShortField
+    implements FixedField
+{
+    private short     _value;
+    private final int _offset;
+
+    /**
+     * construct the ShortField with its offset into its containing
+     * byte array
+     *
+     * @param offset of the field within its byte array
+     *
+     * @exception ArrayIndexOutOfBoundsException if offset is negative
+     */
+
+    public ShortField(final int offset)
+        throws ArrayIndexOutOfBoundsException
+    {
+        if (offset < 0)
+        {
+            throw new ArrayIndexOutOfBoundsException("Illegal offset: "
+                                                     + offset);
+        }
+        _offset = offset;
+    }
+
+
+    /**
+     * Construct the ShortField with its offset into its containing
+     * byte array and initialize its value from its byte array
+     *
+     * @param offset of the field within its byte array
+     * @param data the byte array to read the value from
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is not
+     *            within the range of 0..(data.length - 1)
+     */
+
+    public ShortField(final int offset, final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        this(offset);
+        readFromBytes(data);
+    }
+
+    /**
+     * construct the ShortField with its offset into its containing
+     * byte array, initialize its value, and write its value to its
+     * byte array
+     *
+     * @param offset of the field within its byte array
+     * @param value the initial value
+     * @param data the byte array to write the value to
+     *
+     * @exception ArrayIndexOutOfBoundsException if offset is negative
+     */
+
+    public ShortField(final int offset, final short value, final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        this(offset);
+        set(value, data);
+    }
+
+    /**
+     * get the ShortField's current value
+     *
+     * @return current value
+     */
+
+    public short get()
+    {
+        return _value;
+    }
+
+
+    /**
+     * set the ShortField's current value and write it to a byte array
+     *
+     * @param value to be set
+     * @param data the byte array to write the value to
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is out
+     *            of range
+     */
+
+    public void set(final short value, final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        _value = value;
+        writeToBytes(data);
+    }
+
+    /* ********** START implementation of FixedField ********** */
+
+    /**
+     * set the value from its offset into an array of bytes
+     *
+     * @param data the byte array from which the value is to be read
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is out
+     *            of range
+     */
+
+    public void readFromBytes(final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        _value = LittleEndian.getShort(data, _offset);
+    }
+
+
+    /**
+     * write the value out to an array of bytes at the appropriate
+     * offset
+     *
+     * @param data the array of bytes to which the value is to be
+     *             written
+     *
+     * @exception ArrayIndexOutOfBoundsException if the offset is out
+     *            of range
+     */
+
+    public void writeToBytes(final byte [] data)
+        throws ArrayIndexOutOfBoundsException
+    {
+        LittleEndian.putShort(data, _offset, _value);
+    }
+
+    /**
+     * return the value as a String
+     *
+     * @return the value as a String
+     */
+
+    public String toString()
+    {
+        return String.valueOf(_value);
+    }
+
+    /* **********  END  implementation of FixedField ********** */
+}   // end public class ShortField
+
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/StringUtil.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/StringUtil.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/StringUtil.java	(revision 28000)
@@ -0,0 +1,267 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.apache.poi.util;
+
+import java.io.UnsupportedEncodingException;
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+/**
+ *  Title: String Utility Description: Collection of string handling utilities<p/>
+ *
+ * Note - none of the methods in this class deals with {@link org.apache.poi.hssf.record.ContinueRecord}s.  For such
+ * functionality, consider using {@link RecordInputStream
+} *
+ *
+ *@author     Andrew C. Oliver
+ *@author     Sergei Kozello (sergeikozello at mail.ru)
+ *@author     Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp)
+ */
+public class StringUtil {
+	private static final String ENCODING_ISO_8859_1 = "ISO-8859-1";
+
+	private StringUtil() {
+		// no instances of this class
+	}
+
+
+
+	public static String readCompressedUnicode(LittleEndianInput in, int nChars) {
+		char[] buf = new char[nChars];
+		for (int i = 0; i < buf.length; i++) {
+			buf[i] = (char) in.readUByte();
+		}
+		return new String(buf);
+	}
+	/**
+	 * InputStream <tt>in</tt> is expected to contain:
+	 * <ol>
+	 * <li>ushort nChars</li>
+	 * <li>byte is16BitFlag</li>
+	 * <li>byte[]/char[] characterData</li>
+	 * </ol>
+	 * For this encoding, the is16BitFlag is always present even if nChars==0.
+	 * 
+	 * This structure is also known as a XLUnicodeString.
+	 */
+	public static String readUnicodeString(LittleEndianInput in) {
+
+		int nChars = in.readUShort();
+		byte flag = in.readByte();
+		if ((flag & 0x01) == 0) {
+			return readCompressedUnicode(in, nChars);
+		}
+		return readUnicodeLE(in, nChars);
+	}
+	/**
+	 * InputStream <tt>in</tt> is expected to contain:
+	 * <ol>
+	 * <li>byte is16BitFlag</li>
+	 * <li>byte[]/char[] characterData</li>
+	 * </ol>
+	 * For this encoding, the is16BitFlag is always present even if nChars==0.
+	 * <br/>
+	 * This method should be used when the nChars field is <em>not</em> stored
+	 * as a ushort immediately before the is16BitFlag. Otherwise, {@link
+	 * #readUnicodeString(LittleEndianInput)} can be used.
+	 */
+	public static String readUnicodeString(LittleEndianInput in, int nChars) {
+		byte is16Bit = in.readByte();
+		if ((is16Bit & 0x01) == 0) {
+			return readCompressedUnicode(in, nChars);
+		}
+		return readUnicodeLE(in, nChars);
+	}
+
+	/**
+	 * OutputStream <tt>out</tt> will get:
+	 * <ol>
+	 * <li>ushort nChars</li>
+	 * <li>byte is16BitFlag</li>
+	 * <li>byte[]/char[] characterData</li>
+	 * </ol>
+	 * For this encoding, the is16BitFlag is always present even if nChars==0.
+	 */
+	public static void writeUnicodeString(LittleEndianOutput out, String value) {
+
+		int nChars = value.length();
+		out.writeShort(nChars);
+		boolean is16Bit = hasMultibyte(value);
+		out.writeByte(is16Bit ? 0x01 : 0x00);
+		if (is16Bit) {
+			putUnicodeLE(value, out);
+		} else {
+			putCompressedUnicode(value, out);
+		}
+	}
+	/**
+	 * OutputStream <tt>out</tt> will get:
+	 * <ol>
+	 * <li>byte is16BitFlag</li>
+	 * <li>byte[]/char[] characterData</li>
+	 * </ol>
+	 * For this encoding, the is16BitFlag is always present even if nChars==0.
+	 * <br/>
+	 * This method should be used when the nChars field is <em>not</em> stored
+	 * as a ushort immediately before the is16BitFlag. Otherwise, {@link
+	 * #writeUnicodeString(LittleEndianOutput, String)} can be used.
+	 */
+	public static void writeUnicodeStringFlagAndData(LittleEndianOutput out, String value) {
+		boolean is16Bit = hasMultibyte(value);
+		out.writeByte(is16Bit ? 0x01 : 0x00);
+		if (is16Bit) {
+			putUnicodeLE(value, out);
+		} else {
+			putCompressedUnicode(value, out);
+		}
+	}
+
+	/**
+	 * @return the number of bytes that would be written by {@link #writeUnicodeString(LittleEndianOutput, String)}
+	 */
+	public static int getEncodedSize(String value) {
+		int result = 2 + 1;
+		result += value.length() * (StringUtil.hasMultibyte(value) ? 2 : 1);
+		return result;
+	}
+
+	public static void putCompressedUnicode(String input, LittleEndianOutput out) {
+		byte[] bytes;
+		try {
+			bytes = input.getBytes(ENCODING_ISO_8859_1);
+		} catch (UnsupportedEncodingException e) {
+			throw new RuntimeException(e);
+		}
+		out.write(bytes);
+	}
+
+	public static void putUnicodeLE(String input, LittleEndianOutput out) {
+		byte[] bytes;
+		try {
+			bytes = input.getBytes("UTF-16LE");
+		} catch (UnsupportedEncodingException e) {
+			throw new RuntimeException(e);
+		}
+		out.write(bytes);
+	}
+
+	public static String readUnicodeLE(LittleEndianInput in, int nChars) {
+		char[] buf = new char[nChars];
+		for (int i = 0; i < buf.length; i++) {
+			buf[i] = (char) in.readUShort();
+		}
+		return new String(buf);
+	}
+
+	/**
+	 *  Apply printf() like formatting to a string.
+	 *  Primarily used for logging.
+	 * @param  message  the string with embedded formatting info
+	 *                 eg. "This is a test %2.2"
+	 * @param  params   array of values to format into the string
+	 * @return          The formatted string
+	 */
+	public static String format(String message, Object[] params) {
+		int currentParamNumber = 0;
+		StringBuffer formattedMessage = new StringBuffer();
+		for (int i = 0; i < message.length(); i++) {
+			if (message.charAt(i) == '%') {
+				if (currentParamNumber >= params.length) {
+					formattedMessage.append("?missing data?");
+				} else if (
+					(params[currentParamNumber] instanceof Number)
+						&& (i + 1 < message.length())) {
+					i
+						+= matchOptionalFormatting(
+							(Number) params[currentParamNumber++],
+							message.substring(i + 1),
+							formattedMessage);
+				} else {
+					formattedMessage.append(
+						params[currentParamNumber++].toString());
+				}
+			} else {
+				if ((message.charAt(i) == '\\')
+					&& (i + 1 < message.length())
+					&& (message.charAt(i + 1) == '%')) {
+					formattedMessage.append('%');
+					i++;
+				} else {
+					formattedMessage.append(message.charAt(i));
+				}
+			}
+		}
+		return formattedMessage.toString();
+	}
+
+
+	private static int matchOptionalFormatting(
+		Number number,
+		String formatting,
+		StringBuffer outputTo) {
+		NumberFormat numberFormat = NumberFormat.getInstance();
+		if ((0 < formatting.length())
+			&& Character.isDigit(formatting.charAt(0))) {
+			numberFormat.setMinimumIntegerDigits(
+				Integer.parseInt(formatting.charAt(0) + ""));
+			if ((2 < formatting.length())
+				&& (formatting.charAt(1) == '.')
+				&& Character.isDigit(formatting.charAt(2))) {
+				numberFormat.setMaximumFractionDigits(
+					Integer.parseInt(formatting.charAt(2) + ""));
+				numberFormat.format(number, outputTo, new FieldPosition(0));
+				return 3;
+			}
+			numberFormat.format(number, outputTo, new FieldPosition(0));
+			return 1;
+		} else if (
+			(0 < formatting.length()) && (formatting.charAt(0) == '.')) {
+			if ((1 < formatting.length())
+				&& Character.isDigit(formatting.charAt(1))) {
+				numberFormat.setMaximumFractionDigits(
+					Integer.parseInt(formatting.charAt(1) + ""));
+				numberFormat.format(number, outputTo, new FieldPosition(0));
+				return 2;
+			}
+		}
+		numberFormat.format(number, outputTo, new FieldPosition(0));
+		return 1;
+	}
+
+
+	/**
+	 * check the parameter has multibyte character
+	 *
+	 * @param value string to check
+	 * @return boolean result true:string has at least one multibyte character
+	 */
+	public static boolean hasMultibyte(String value) {
+		if (value == null)
+			return false;
+		for (int i = 0; i < value.length(); i++) {
+			char c = value.charAt(i);
+			if (c > 0xFF) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/apache/poi/util/package.html	(revision 28000)
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+   ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Top-level util package are classes that are useful throughout the project.  These classes are
+generally generic enough to be useful in any project and should be contributed elsewhere!
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/ALLQuery.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/ALLQuery.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/ALLQuery.java	(revision 28000)
@@ -0,0 +1,236 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+
+import org.opengis.filter.Filter;
+import org.opengis.filter.sort.SortBy;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.geotools.factory.Hints;
+
+
+/**
+ * Implementation of Query.ALL.
+ *
+ * <p>
+ * This query is used to retrive all Features. Query.ALL is the only instance
+ * of this class.
+ * </p>
+ *
+ * <p>
+ * Example:
+ * </p>
+ * <pre><code>
+ * featureSource.getFeatures( Query.FIDS );
+ * </code></pre>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/ALLQuery.java $
+ */
+class ALLQuery extends Query {
+    public final String[] getPropertyNames() {
+        return null;
+    }
+
+    public final boolean retrieveAllProperties() {
+        return true;
+    }
+
+    public final int getMaxFeatures() {
+        return DEFAULT_MAX; // consider Integer.MAX_VALUE
+    }
+    
+    public Integer getStartIndex(){
+        return null;
+    }
+    
+    public final Filter getFilter() {
+        return Filter.INCLUDE;
+    }
+
+    public final String getTypeName() {
+        return null;
+    }
+
+    public URI getNamespace() {
+        return NO_NAMESPACE;
+    }
+
+    public final String getHandle() {
+        return "Request All Features";
+    }
+
+    public final String getVersion() {
+        return null;
+    }
+
+    /**
+     * Hashcode based on propertyName, maxFeatures and filter.
+     *
+     * @return hascode for filter
+     */
+    public int hashCode() {
+        String[] n = getPropertyNames();
+
+        return ((n == null) ? (-1) : ((n.length == 0) ? 0 : (n.length | n[0].hashCode())))
+        | getMaxFeatures() | ((getFilter() == null) ? 0 : getFilter().hashCode())
+        | ((getTypeName() == null) ? 0 : getTypeName().hashCode())
+        | ((getVersion() == null) ? 0 : getVersion().hashCode())
+        | ((getCoordinateSystem() == null) ? 0 : getCoordinateSystem().hashCode())
+        | ((getCoordinateSystemReproject() == null) ? 0 : getCoordinateSystemReproject().hashCode());
+    }
+
+    /**
+     * Equality based on propertyNames, maxFeatures, filter, typeName and
+     * version.
+     *
+     * <p>
+     * Changing the handle does not change the meaning of the Query.
+     * </p>
+     *
+     * @param obj Other object to compare against
+     *
+     * @return <code>true</code> if <code>obj</code> matches this filter
+     */
+    public boolean equals(Object obj) {
+        if ((obj == null) || !(obj instanceof Query)) {
+            return false;
+        }
+
+        if (this == obj) {
+            return true;
+        }
+
+        Query other = (Query) obj;
+
+        return Arrays.equals(getPropertyNames(), other.getPropertyNames())
+        && (retrieveAllProperties() == other.retrieveAllProperties())
+        && (getMaxFeatures() == other.getMaxFeatures())
+        && ((getFilter() == null) ? (other.getFilter() == null)
+                                  : getFilter().equals(other.getFilter()))
+        && ((getTypeName() == null) ? (other.getTypeName() == null)
+                                    : getTypeName().equals(other.getTypeName()))
+        && ((getVersion() == null) ? (other.getVersion() == null)
+                                   : getVersion().equals(other.getVersion()))
+        && ((getCoordinateSystem() == null) ? (other.getCoordinateSystem() == null)
+                                            : getCoordinateSystem()
+                                                  .equals(other.getCoordinateSystem()))
+        && ((getCoordinateSystemReproject() == null) ? (other.getCoordinateSystemReproject() == null)
+                                                     : getCoordinateSystemReproject()
+                                                           .equals(other
+            .getCoordinateSystemReproject()));
+    }
+
+    public String toString() {
+        return "Query.ALL";
+    }
+
+    /**
+     * Return <code>null</code> as ALLQuery does not require a CS.
+     *
+     * @return <code>null</code> as override is not required.
+     *
+     * @see org.geotools.data.Query#getCoordinateSystem()
+     */
+    public CoordinateReferenceSystem getCoordinateSystem() {
+        return null;
+    }
+
+    /**
+     * Return <code>null</code> as ALLQuery does not require a CS.
+     *
+     * @return <code>null</code> as reprojection is not required.
+     *
+     * @see org.geotools.data.Query#getCoordinateSystemReproject()
+     */
+    public CoordinateReferenceSystem getCoordinateSystemReproject() {
+        return null;
+    }
+
+    /**
+     * @return {@link SortBy#UNSORTED}.
+     */
+    public SortBy[] getSortBy() {
+        return SortBy.UNSORTED;
+    }
+
+    /**
+     * Returns an empty Hints set
+     */
+    public Hints getHints() {
+        return new Hints();
+    }
+    
+    //
+    // Not mutable; all values hard coded
+    //
+    @Override
+    public void setCoordinateSystem(CoordinateReferenceSystem system) {
+    	//new UnsupportedOperationException("Query.ALL cannot be changed, please just use as a default.");
+    }
+    @Override
+    public void setCoordinateSystemReproject(CoordinateReferenceSystem system) {
+    	//new UnsupportedOperationException("Query.ALL cannot be changed, please just use as a default.");
+    }
+    @Override
+    public void setFilter(Filter filter) {
+    	//new UnsupportedOperationException("Query.ALL cannot be changed, please just use as a default.");
+    }
+    @Override
+    public void setHandle(String handle) {
+    	//new UnsupportedOperationException("Query.ALL cannot be changed, please just use as a default.");
+    }
+    @Override
+    public void setHints(Hints hints) {
+    	//new UnsupportedOperationException("Query.ALL cannot be changed, please just use as a default.");
+    }
+    @Override
+    public void setMaxFeatures(int maxFeatures) {
+    	//new UnsupportedOperationException("Query.ALL cannot be changed, please just use as a default.");
+    }
+    @Override
+    public void setNamespace(URI namespace) {
+    	//new UnsupportedOperationException("Query.ALL cannot be changed, please just use as a default.");
+    }
+    @Override
+    public void setPropertyNames(List<String> propNames) {
+    	//new UnsupportedOperationException("Query.ALL cannot be changed, please just use as a default.");
+    }
+    @Override
+    public void setPropertyNames(String[] propNames) {
+    	//new UnsupportedOperationException("Query.ALL cannot be changed, please just use as a default.");
+    }
+    @Override
+    public void setSortBy(SortBy[] sortBy) {
+    	//new UnsupportedOperationException("Query.ALL cannot be changed, please just use as a default.");
+    }
+    @Override
+    public void setStartIndex(Integer startIndex) {
+    	//new UnsupportedOperationException("Query.ALL cannot be changed, please just use as a default.");
+    }
+    @Override
+    public void setTypeName(String typeName) {
+    	//new UnsupportedOperationException("Query.ALL cannot be changed, please just use as a default.");
+    }
+    @Override
+    public void setVersion(String version) {
+        //new UnsupportedOperationException("Query.ALL cannot be changed, please just use as a default.");
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractAttributeIO.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractAttributeIO.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractAttributeIO.java	(revision 28000)
@@ -0,0 +1,44 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import org.opengis.feature.type.AttributeDescriptor;
+
+/**
+ * Provides support for creating AttributeReaders.
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/AbstractAttributeIO.java $
+ * @version $Id: AbstractAttributeIO.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author  Ian Schneider
+ */
+public abstract class AbstractAttributeIO implements AttributeReader {
+    
+    protected AttributeDescriptor[] metaData;
+    
+    protected AbstractAttributeIO(AttributeDescriptor[] metaData) {
+        this.metaData = metaData;
+    }
+        
+    public final int getAttributeCount() {
+        return metaData.length;
+    }
+    
+    public final AttributeDescriptor getAttributeType(int position) {
+        return metaData[position];
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractDataStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractDataStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractDataStore.java	(revision 28000)
@@ -0,0 +1,604 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.data.simple.SimpleFeatureSource;
+import org.geotools.feature.FeatureTypes;
+import org.geotools.feature.SchemaException;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+
+
+/**
+ * Represents a stating point for implementing your own DataStore.
+ *
+ * <p>
+ * The goal is to have this class provide <b>everything</b> else if you can
+ * only provide:
+ * </p>
+ *
+ * <ul>
+ * <li>
+ * String[] getFeatureTypes()
+ * </li>
+ * <li>
+ * FeatureType getSchema(String typeName)
+ * </li>
+ * <li>
+ *  FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader( typeName )
+ * </li>
+ * <li>
+ * FeatureWriter getFeatureWriter( typeName )
+ * </li>
+ * </ul>
+ *
+ * and optionally this protected methods to allow custom query optimizations:
+ *
+ * <ul>
+ * <li>
+ * Filter getUnsupportedFilter(String typeName, Filter filter)
+ * </li>
+ * <li>
+ *  FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String typeName, Query query)
+ * </li>
+ * </ul>
+ *
+ * <p>
+ * All remaining functionality is implemented against these methods, including
+ * Transaction and Locking Support. These implementations will not be optimal
+ * but they will work.
+ * </p>
+ *
+ * <p>
+ * Pleae note that there may be a better place for you to start out from, (like
+ * JDBCDataStore).
+ * </p>
+ *
+ * @author jgarnett
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/AbstractDataStore.java $
+ */
+public abstract class AbstractDataStore implements DataStore {
+    /** The logger for the filter module. */
+    protected static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geotools.data");
+
+    /** Manages listener lists for SimpleFeatureSource implementation */
+    public FeatureListenerManager listenerManager = new FeatureListenerManager();
+
+    /**
+     * Flags AbstractDataStore to allow Modification.
+     * <p>
+     * GetFeatureSource will return a FeatureStore is this is true.
+     * </p>
+     */
+    protected final boolean isWriteable;
+
+    /**
+     * Manages InProcess locks for FeatureLocking implementations.
+     *
+     * <p>
+     * May be null if subclass is providing real locking.
+     * </p>
+     */
+    private InProcessLockingManager lockingManager;
+
+    /** Default (Writeable) DataStore */
+    public AbstractDataStore() {
+        this(true);
+    }
+
+    /**
+     * AbstractDataStore creation.
+     * 
+     * @param isWriteable true for writeable DataStore. 
+     */
+    public AbstractDataStore(boolean isWriteable) {
+        this.isWriteable = isWriteable;
+        lockingManager = createLockingManager();
+    }
+
+    /**
+     * Currently returns an InProcessLockingManager.
+     *
+     * <p>
+     * Subclasses that implement real locking may override this method to
+     * return <code>null</code>.
+     * </p>
+     *
+     * @return InProcessLockingManager or null.
+     */
+    protected InProcessLockingManager createLockingManager() {
+        return new InProcessLockingManager();
+    }
+
+//    public void fireAdded( Feature newFeature ){
+//        String typeName = newFeature.getFeatureType().getTypeName();
+//        listenerManager.fireFeaturesAdded( typeName, Transaction.AUTO_COMMIT, newFeature.getBounds(), false );
+//    }
+//    public void fireRemoved( Feature removedFeature ){
+//        String typeName = removedFeature.getFeatureType().getTypeName();
+//        listenerManager.fireFeaturesRemoved( typeName, Transaction.AUTO_COMMIT, removedFeature.getBounds(), false );
+//    }
+//    public void fireChanged( Feature before, Feature after ){
+//        String typeName = after.getFeatureType().getTypeName();
+//        Envelope bounds = new Envelope();
+//        bounds.expandToInclude( before.getBounds() );
+//        bounds.expandToInclude( after.getBounds() );
+//        listenerManager.fireFeaturesChanged( typeName, Transaction.AUTO_COMMIT, bounds, false );
+//    }
+           
+    /**
+     * Subclass override to provide access to metadata.
+     * <p>
+     * CreateTypeEntry uses this method to aquire metadata information,
+     * if available.
+     * </p>
+     */
+    protected Map createMetadata( String typeName ) {
+        return Collections.EMPTY_MAP;
+    }
+       
+    /** helper method for retrieving all the names. */
+    public abstract String[] getTypeNames() throws IOException;
+
+    public ServiceInfo getInfo() {
+        DefaultServiceInfo info = new DefaultServiceInfo();
+        info.setDescription("Features from "+getClass().getSimpleName() );
+        info.setSchema( FeatureTypes.DEFAULT_NAMESPACE );        
+        return info;
+    }
+    
+    /** Retrive schema information for typeName */
+    public abstract SimpleFeatureType getSchema(String typeName)
+        throws IOException;
+
+    /**
+     * Subclass must implement.
+     *
+     * @param typeName
+     *
+     * @return  FeatureReader<SimpleFeatureType, SimpleFeature> over contents of typeName
+     * 
+     */
+    protected abstract  FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String typeName)
+        throws IOException;
+    /**
+     * Subclass can implement this to provide writing support.
+     *
+     * @param typeName
+     *
+     * @return FeatureWriter over contents of typeName
+     * @throws IOException 
+     *
+     * @throws IOException Subclass may throw IOException
+     * @throws UnsupportedOperationException Subclass may implement
+     * @deprecated
+     */
+    protected FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriter(String typeName) throws IOException{
+        throw new UnsupportedOperationException("FeatureWriter not implemented - is this a Read-only DataStore?");    	
+    }
+
+    /**
+     * Subclass should implement this to provide writing support.
+     * <p>A feature writer writes to the resource so it should considered to always be committing.
+     * The transaction is passed in so that it can be known what FeatureListeners should be notified of the
+     * changes.  If the Transaction is AUTOCOMMIT then all listeners should be notified.  If not
+     * all listeners that are NOT registered with that transaction should be notified.<p>
+     * @param typeName
+     * @param transaction a feature writer
+     * @return FeatureWriter over contents of typeName
+     * @throws IOException 
+     *
+     * @throws IOException Subclass may throw IOException
+     * @throws UnsupportedOperationException Subclass may implement
+     */
+    protected FeatureWriter<SimpleFeatureType, SimpleFeature> createFeatureWriter(String typeName, Transaction transaction)
+    throws IOException {
+        throw new UnsupportedOperationException("FeatureWriter not supported");    	
+    }
+    /**
+     * Subclass should implement to provide writing support.
+     *
+     * @param featureType Requested FeatureType
+     * @throws IOException 
+     *
+     * @throws IOException Subclass may throw IOException
+     * @throws UnsupportedOperationException Subclass may implement
+     */
+    public void createSchema(SimpleFeatureType featureType) throws IOException{
+        throw new UnsupportedOperationException("Schema creation not supported");
+    }
+    /* (non-Javadoc)
+     * @see org.geotools.data.DataStore#updateSchema(java.lang.String, org.geotools.feature.FeatureType)
+     */
+    public void updateSchema(String typeName, SimpleFeatureType featureType){
+        throw new UnsupportedOperationException("Schema modification not supported");
+    }
+
+    /**
+     * Default implementation based on getFeatureReader and getFeatureWriter.
+     *
+     * <p>
+     * We should be able to optimize this to only get the RowSet once
+     * </p>
+     *
+     * @see org.geotools.data.DataStore#getFeatureSource(java.lang.String)
+     */
+    public SimpleFeatureSource getFeatureSource(final String typeName)
+        throws IOException {
+        final SimpleFeatureType featureType = getSchema(typeName);
+
+        if (isWriteable) {
+            if (lockingManager != null)
+                return new AbstractFeatureLocking(getSupportedHints()) {
+                    public DataStore getDataStore() {
+                        return AbstractDataStore.this;
+                    }
+                    public String toString() {
+                        return "AbstractDataStore.AbstractFeatureLocking("+typeName+")";
+                    }
+                    public void addFeatureListener(FeatureListener listener) {
+                        listenerManager.addFeatureListener(this, listener);
+                    }
+
+                    public void removeFeatureListener(
+                        FeatureListener listener) {
+                        listenerManager.removeFeatureListener(this, listener);
+                    }
+
+                    public SimpleFeatureType getSchema() {
+                        return featureType;
+                    }
+                };
+                return new AbstractFeatureStore(getSupportedHints()) {
+                    public DataStore getDataStore() {
+                        return AbstractDataStore.this;
+                    }
+                    public String toString() {
+                        return "AbstractDataStore.AbstractFeatureStore("+typeName+")";
+                    }
+                    public void addFeatureListener(FeatureListener listener) {
+                        listenerManager.addFeatureListener(this, listener);
+                    }
+
+                    public void removeFeatureListener(
+                        FeatureListener listener) {
+                        listenerManager.removeFeatureListener(this, listener);
+                    }
+
+                    public SimpleFeatureType getSchema() {
+                        return featureType;
+                    }
+                };
+        }
+            return new AbstractFeatureSource(getSupportedHints()) {
+                public DataStore getDataStore() {
+                    return AbstractDataStore.this;
+                }
+                public String toString() {
+                    return "AbstractDataStore.AbstractFeatureSource("+typeName+")";
+                }
+                public void addFeatureListener(FeatureListener listener) {
+                    listenerManager.addFeatureListener(this, listener);
+                }
+
+                public void removeFeatureListener(FeatureListener listener) {
+                    listenerManager.removeFeatureListener(this, listener);
+                }
+
+                public SimpleFeatureType getSchema() {
+                    return featureType;
+                }
+            };
+    }
+
+
+    // Jody - Recomend moving to the following
+    // When we are ready for CoordinateSystem support
+    public  FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(Query query,Transaction transaction) throws IOException {
+        Filter filter = query.getFilter();
+        String typeName = query.getTypeName();
+        String propertyNames[] = query.getPropertyNames();
+
+        if (filter == null) {
+            throw new NullPointerException("getFeatureReader requires Filter: "
+                + "did you mean Filter.INCLUDE?");
+        }
+        if( typeName == null ){
+            throw new NullPointerException(
+                "getFeatureReader requires typeName: "
+                + "use getTypeNames() for a list of available types");
+        }
+        if (transaction == null) {
+            throw new NullPointerException(
+                "getFeatureReader requires Transaction: "
+                + "did you mean to use Transaction.AUTO_COMMIT?");
+        }
+        SimpleFeatureType featureType = getSchema( query.getTypeName() );
+
+        if( propertyNames != null || query.getCoordinateSystem()!=null ){
+            try {
+                featureType = DataUtilities.createSubType( featureType, propertyNames, query.getCoordinateSystem() );
+            } catch (SchemaException e) {
+                LOGGER.log( Level.FINEST, e.getMessage(), e);
+                throw new DataSourceException( "Could not create Feature Type for query", e );
+
+            }
+        }
+        if ( filter == Filter.EXCLUDE || filter.equals( Filter.EXCLUDE )) {
+            return new EmptyFeatureReader<SimpleFeatureType, SimpleFeature>(featureType);
+        }
+        //GR: allow subclases to implement as much filtering as they can,
+        //by returning just it's unsupperted filter
+        filter = getUnsupportedFilter(typeName, filter);
+        if(filter == null){
+            throw new NullPointerException("getUnsupportedFilter shouldn't return null. Do you mean Filter.INCLUDE?");
+        }
+
+        // There are cases where the readers have to lock.  Take shapefile for example.  Getting a Reader causes
+        // the file to be locked.  However on a commit TransactionStateDiff locks before a writer is obtained.  In order to 
+        // prevent deadlocks either the diff has to obtained first or the reader has to be obtained first.
+        // Because shapefile writes to a buffer first the actual write lock is not flipped until the transaction has most of the work
+        // done.  As a result I suggest getting the diff first then getting the reader.
+        // JE
+        Diff diff=null;
+        if (transaction != Transaction.AUTO_COMMIT) {
+            TransactionStateDiff state = state(transaction);
+            if( state != null ){
+                diff = state.diff(typeName);
+            }
+        }
+        
+        // This calls our subclass "simple" implementation
+        // All other functionality will be built as a reader around
+        // this class
+        //
+         FeatureReader<SimpleFeatureType, SimpleFeature> reader = getFeatureReader(typeName, query);
+
+        if( diff!=null )
+            reader = new DiffFeatureReader<SimpleFeatureType, SimpleFeature>(reader, diff, query.getFilter());
+
+        if (!filter.equals( Filter.INCLUDE ) ) {
+            reader = new FilteringFeatureReader<SimpleFeatureType, SimpleFeature>(reader, filter);
+        }
+
+        if (!featureType.equals(reader.getFeatureType())) {
+            LOGGER.fine("Recasting feature type to subtype by using a ReTypeFeatureReader");
+            reader = new ReTypeFeatureReader(reader, featureType, false);
+        }
+
+        if (query.getMaxFeatures() != Query.DEFAULT_MAX) {
+			    reader = new MaxFeatureReader<SimpleFeatureType, SimpleFeature>(reader, query.getMaxFeatures());
+        }
+
+        return reader;
+    }
+
+    /**
+     * GR: this method is called from inside getFeatureReader(Query ,Transaction )
+     * to allow subclasses return an optimized  FeatureReader<SimpleFeatureType, SimpleFeature> wich supports the
+     * filter and attributes truncation specified in <code>query</code>
+     * <p>
+     * A subclass that supports the creation of such an optimized FeatureReader
+     * shold override this method. Otherwise, it just returns
+     * <code>getFeatureReader(typeName)</code>
+     * <p>
+     */
+    protected  FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String typeName, Query query)
+    throws IOException
+    {
+      return getFeatureReader(typeName);
+    }
+    /**
+     * GR: if a subclass supports filtering, it should override this method
+     * to return the unsupported part of the passed filter, so a
+     * FilteringFeatureReader will be constructed upon it. Otherwise it will
+     * just return the same filter.
+     * <p>
+     * If the complete filter is supported, the subclass must return <code>Filter.INCLUDE</code>
+     * </p>
+     */
+    protected Filter getUnsupportedFilter(String typeName, Filter filter)
+    {
+      return filter;
+    }
+
+    /**
+     * Used to retrive the TransactionStateDiff for this transaction.
+     * If you subclass is doing its own thing (ArcSDE I am talking to
+     * you) then you should arrange for this method to return null.
+     * <p>
+     * By default a TransactionStateDiff will be created that holds
+     * any changes in memory.
+     * <p>
+     * @param transaction
+     * @return TransactionStateDiff or null if subclass is handling differences
+     */
+    protected TransactionStateDiff state(Transaction transaction) {
+        synchronized (transaction) {
+            TransactionStateDiff state = (TransactionStateDiff) transaction
+                .getState(this);
+
+            if (state == null) {
+                state = new TransactionStateDiff(this);
+                transaction.putState(this, state);
+            }
+
+            return state;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.geotools.data.DataStore#getFeatureWriter(java.lang.String, org.geotools.filter.Filter, org.geotools.data.Transaction)
+     */
+    public FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriter(String typeName, Filter filter,
+        Transaction transaction) throws IOException {
+        if (filter == null) {
+            throw new NullPointerException("getFeatureReader requires Filter: "
+                + "did you mean Filter.INCLUDE?");
+        }
+
+        if (filter == Filter.EXCLUDE) {
+        	SimpleFeatureType featureType = getSchema(typeName);
+
+            return new EmptyFeatureWriter(featureType);
+        }
+
+        if (transaction == null) {
+            throw new NullPointerException(
+                "getFeatureWriter requires Transaction: "
+                + "did you mean to use Transaction.AUTO_COMMIT?");
+        }
+
+        FeatureWriter<SimpleFeatureType, SimpleFeature> writer;
+
+        if (transaction == Transaction.AUTO_COMMIT) {
+        	try{
+        		writer = createFeatureWriter(typeName, transaction);
+        	}catch (UnsupportedOperationException e) {
+				// This is for backward compatibility.
+            	try {
+            		writer = getFeatureWriter(typeName);
+            	}
+            	catch( UnsupportedOperationException eek){
+            		throw e; // throw original - our fallback did not work
+            	}
+			}
+        } else {
+            TransactionStateDiff state = state(transaction);
+            if( state != null ){
+                writer = state.writer(typeName, filter);
+            }
+            else {
+                throw new UnsupportedOperationException("Subclass sould implement");
+            }
+        }
+
+        if (lockingManager != null) {
+            // subclass has not provided locking so we will
+            // fake it with InProcess locks
+            writer = lockingManager.checkedWriter(writer, transaction);
+        }
+
+        if (filter != Filter.INCLUDE) {
+            writer = new FilteringFeatureWriter(writer, filter);
+        }
+
+        return writer;
+    }
+
+    /* (non-Javadoc)
+     * @see org.geotools.data.DataStore#getFeatureWriter(java.lang.String, org.geotools.data.Transaction)
+     */
+    public FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriter(String typeName,
+        Transaction transaction) throws IOException {
+
+    	return getFeatureWriter(typeName, Filter.INCLUDE, transaction);
+    }
+
+    /* (non-Javadoc)
+     * @see org.geotools.data.DataStore#getFeatureWriterAppend(java.lang.String, org.geotools.data.Transaction)
+     *
+     */
+    public FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriterAppend(String typeName,
+        Transaction transaction) throws IOException {
+        FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getFeatureWriter(typeName, transaction);
+
+        while (writer.hasNext()) {
+            writer.next(); // Hmmm this would be a use for skip() then?
+        }
+
+        return writer;
+    }
+
+    /**
+     * Locking manager used for this DataStore.
+     *
+     * <p>
+     * By default AbstractDataStore makes use of InProcessLockingManager.
+     * </p>
+     *
+     *
+     * @see org.geotools.data.DataStore#getLockingManager()
+     */
+    public LockingManager getLockingManager() {
+        return lockingManager;
+    }
+
+    /**
+     * Computes the bounds of the features for the specified feature type that
+     * satisfy the query provided that there is a fast way to get that result.
+     * <p>
+     * Will return null if there is not fast way to compute the bounds. Since
+     * it's based on some kind of header/cached information, it's not guaranteed
+     * to be real bound of the features
+     * </p>
+     * @param query
+     * @return the bounds, or null if too expensive
+     * @throws SchemaNotFoundException 
+     * @throws IOException
+     */
+    protected ReferencedEnvelope getBounds(Query query) throws IOException{
+        return null; // too expensive
+    }
+
+
+    /**
+     * Gets the number of the features that would be returned by this query for
+     * the specified feature type.
+     * <p>
+     * If getBounds(Query) returns <code>-1</code> due to expense consider
+     * using <code>getFeatures(Query).getCount()</code> as a an alternative.
+     * </p>
+     *
+     * @param query Contains the Filter and MaxFeatures to find the bounds for.
+     * @return The number of Features provided by the Query or <code>-1</code>
+     *         if count is too expensive to calculate or any errors or occur.
+     * @throws IOException 
+     *
+     * @throws IOException if there are errors getting the count
+     */
+    protected int getCount(Query query) throws IOException{
+        return -1; // too expensive
+    }
+    
+    /**
+     * If you are using the automated FeatureSource/Store/Locking creation, this method
+     * allows for the specification of the supported hints. 
+     * @return
+     */
+    protected Set getSupportedHints() {
+        return Collections.EMPTY_SET;
+    }
+    
+    /**
+     * Dummy implementation, it's a no-op. Subclasses holding to system resources must
+     * override this method and release them.
+     */
+    public void dispose() {
+        // nothing to do
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractFeatureLocking.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractFeatureLocking.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractFeatureLocking.java	(revision 28000)
@@ -0,0 +1,251 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.data.simple.SimpleFeatureLocking;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.filter.Filter;
+
+/**
+ * A Starting point for your own FeatureLocking implementations.
+ * 
+ * <p>
+ * This class extends AbstractFeatureSource and depends on getDataStore().
+ * </p>
+ * The implementation of the following functions depends on
+ * getDataStore().getLockingManger() not being <code>null</code>:
+ * 
+ * <ul>
+ * <li>
+ * lockFeatures( Query )
+ * </li>
+ * <li>
+ * unLockFeatures( Query )
+ * </li>
+ * <li>
+ * releaseLock( AuthorizationID )
+ * </li>
+ * <li>
+ * refreshLock( AuthorizationID )
+ * </li>
+ * </ul>
+ * 
+ * <p>
+ * FeatureStores that have provided their own locking to will need to override
+ * the above methods, or provide a custom LockingManger.
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/AbstractFeatureLocking.java $
+ */
+public abstract class AbstractFeatureLocking extends AbstractFeatureStore
+    implements SimpleFeatureLocking {
+    FeatureLock featureLock = FeatureLock.TRANSACTION;
+    
+    public AbstractFeatureLocking() {
+        // just to keep the default constructor around
+    }
+    
+    /**
+     * This constructors allows to set the supported hints 
+     * @param hints
+     */
+    public AbstractFeatureLocking(Set hints) {
+        super(hints);
+    }
+
+    /**
+     * Provide a FeatureLock for locking opperations to opperate against.
+     * 
+     * <p>
+     * Initial Transactional duration locks can be restored with
+     * setFeatureLock( FetaureLock.TRANSACTION )
+     * </p>
+     *
+     * @param lock FeatureLock (or FeatureLock.TRANSACTION );
+     *
+     * @throws NullPointerException If lock was <code>null</code>
+     *
+     * @see org.geotools.data.FeatureLocking#setFeatureLock(org.geotools.data.FeatureLock)
+     */
+    public void setFeatureLock(FeatureLock lock) {
+        if (lock == null) {
+            throw new NullPointerException(
+                "A FeatureLock is required - did you mean FeatureLock.TRANSACTION?");
+        }
+
+        featureLock = lock;
+    }
+
+    /**
+     * Lock all Features
+     *
+     * @return Number of Locked features
+     *
+     * @throws IOException
+     *
+     * @see org.geotools.data.FeatureLocking#lockFeatures()
+     */
+    public int lockFeatures() throws IOException {
+        return lockFeatures(Filter.INCLUDE);
+    }
+
+    /**
+     * Lock features matching <code>filter</code>.
+     *
+     * @param filter
+     *
+     * @return Number of locked Features
+     *
+     * @throws IOException
+     */
+    public int lockFeatures(Filter filter) throws IOException {
+        return lockFeatures(new DefaultQuery(getSchema().getTypeName(),filter));
+    }
+    
+    /**
+     * Lock features matching Query.
+     * 
+     * <p>
+     * FeatureStores that have provided their own locking to will need to
+     * override this method.
+     * </p>
+     *
+     * @param query
+     *
+     * @return Number of locked Features
+     *
+     * @throws IOException If we could not determine which feature to lock
+     *         based on Query
+     * @throws UnsupportedOperationException When DataStore does not provide a
+     *         LockingManager
+     * @throws DataSourceException If feature to be locked does not exist
+     *
+     * @see org.geotools.data.FeatureLocking#lockFeatures(org.geotools.data.Query)
+     */
+    public int lockFeatures(Query query) throws IOException {
+        LockingManager lockingManager = getDataStore().getLockingManager();
+
+        if (lockingManager == null) {
+            throw new UnsupportedOperationException(
+                "DataStore not using lockingManager, must provide alternate implementation");
+        }
+
+        // Could we reduce the Query to only return the FetureID here?
+        //
+        SimpleFeatureIterator reader = getFeatures(query).features();
+        String typeName = query.getTypeName();
+        SimpleFeature feature;
+        int count = 0;
+
+        try {
+            while (reader.hasNext()) {
+                try {
+                    feature = reader.next();
+                    lockingManager.lockFeatureID(typeName, feature.getID(),
+                        getTransaction(), featureLock);
+                    count++;
+                } catch (FeatureLockException locked) {
+                    // could not aquire - don't increment count                
+                } catch (NoSuchElementException nosuch) {
+                    throw new DataSourceException("Problem with "
+                        + query.getHandle() + " while locking", nosuch);
+                }
+            }
+        } finally {
+            reader.close();
+        }
+
+        return count;
+    }
+
+    /**
+     * Unlock all Features.
+     *
+     * @throws IOException
+     *
+     * @see org.geotools.data.FeatureLocking#unLockFeatures()
+     */
+    public void unLockFeatures() throws IOException {
+        unLockFeatures(Filter.INCLUDE);
+    }
+
+    /**
+     * Unlock Features specified by <code>filter</code>.
+     *
+     * @param filter
+     *
+     * @throws IOException
+     */
+    public void unLockFeatures(Filter filter) throws IOException {
+        unLockFeatures(new DefaultQuery(getSchema().getTypeName(),filter));
+    }
+
+    /**
+     * Unlock features specified by the <code>query</code>.
+     * 
+     * <p>
+     * FeatureStores that have provided their own locking to will need to
+     * override this method.
+     * </p>
+     *
+     * @param query
+     *
+     * @throws IOException
+     * @throws UnsupportedOperationException If lockingManager is not provided
+     *         by DataStore subclass
+     * @throws DataSourceException Filter describes an unlocked Feature, or
+     *         authorization not held
+     *
+     * @see org.geotools.data.FeatureLocking#unLockFeatures(org.geotools.data.Query)
+     */
+    public void unLockFeatures(Query query) throws IOException {
+        LockingManager lockingManager = getDataStore().getLockingManager();
+
+        if (lockingManager == null) {
+            throw new UnsupportedOperationException(
+                "DataStore not using lockingManager, must provide alternate implementation");
+        }
+
+        // Could we reduce the Query to only return the FetureID here?
+        //
+        SimpleFeatureIterator reader = getFeatures(query).features();
+        String typeName = query.getTypeName();
+        SimpleFeature feature;
+
+        try {
+            while (reader.hasNext()) {
+                try {
+                    feature = reader.next();
+                    lockingManager.unLockFeatureID(typeName, feature.getID(),
+                        getTransaction(), featureLock);
+                } catch (NoSuchElementException nosuch) {
+                    throw new DataSourceException("Problem with "
+                        + query.getHandle() + " while locking", nosuch);
+                }
+            }
+        } finally {
+            reader.close();
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractFeatureSource.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractFeatureSource.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractFeatureSource.java	(revision 28000)
@@ -0,0 +1,332 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureSource;
+import org.geotools.data.store.EmptyFeatureCollection;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+
+/**
+ * This is a starting point for providing your own SimpleFeatureSource implementation.
+ *
+ * <p>
+ * Subclasses must implement:
+ * </p>
+ *
+ * <ul>
+ * <li>
+ * getDataStore()
+ * </li>
+ * <li>
+ * getSchema()
+ * </li>
+ * <li>
+ * addFeatureListener()
+ * </li>
+ * <li>
+ * removeFeatureListener()
+ * </li>
+ * </ul>
+ *
+ * <p>
+ * You may find a SimpleFeatureSource implementations that is more specific to your needs - such as
+ * JDBCFeatureSource.
+ * </p>
+ *
+ * <p>
+ * For an example of this class customized for use please see MemoryDataStore.
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research Inc
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/AbstractFeatureSource.java $
+ */
+public abstract class AbstractFeatureSource implements SimpleFeatureSource {
+    
+    protected Set hints = Collections.EMPTY_SET;
+    
+    protected QueryCapabilities queryCapabilities = new QueryCapabilities();
+    
+    public AbstractFeatureSource() {
+        // just to keep the default constructor around
+    }
+    
+    /**
+     * Overrides to explicitly type narrow the return type to {@link DataStore}
+     */
+    public abstract DataStore getDataStore();
+    
+    /**
+     * Returns the same name than the feature type (ie,
+     * {@code getSchema().getName()} to honor the simple feature land common
+     * practice of calling the same both the Features produces and their types
+     * 
+     * @since 2.5
+     * @see FeatureSource#getName()
+     */
+    public Name getName() {
+        return getSchema().getName();
+    }
+    
+    /**
+     * This constructors allows to set the supported hints 
+     * @param hints
+     */
+    public AbstractFeatureSource(Set hints) {
+        this.hints = Collections.unmodifiableSet(new HashSet(hints));
+    }
+    
+    public QueryCapabilities getQueryCapabilities(){
+        return queryCapabilities;
+    }
+    
+    /**
+     * Retrieve the Transaction this SimpleFeatureSource is operating against.
+     *
+     * <p>
+     * For a plain SimpleFeatureSource that cannot modify this will always be Transaction.AUTO_COMMIT.
+     * </p>
+     *
+     * @return Transacstion SimpleFeatureSource is operating against
+     */
+    public Transaction getTransaction() {
+        return Transaction.AUTO_COMMIT;
+    }
+    
+    /**
+     * Provides an interface to for the Results of a Query.
+     *
+     * <p>
+     * Various queries can be made against the results, the most basic being to retrieve Features.
+     * </p>
+     *
+     * @param query
+     *
+     *
+     * @see org.geotools.data.FeatureSource#getFeatures(org.geotools.data.Query)
+     */
+    public SimpleFeatureCollection getFeatures(Query query) throws IOException {
+    	SimpleFeatureType schema = getSchema();        
+        String typeName = schema.getTypeName();
+        
+        if( query.getTypeName() == null ){ // typeName unspecified we will "any" use a default
+            DefaultQuery defaultQuery = new DefaultQuery(query);
+            defaultQuery.setTypeName( typeName );
+        }
+        else if ( !typeName.equals( query.getTypeName() ) ){
+            return new EmptyFeatureCollection( schema );
+        }
+        
+        final QueryCapabilities queryCapabilities = getQueryCapabilities();
+        if(!queryCapabilities.supportsSorting(query.getSortBy())){
+            throw new DataSourceException("DataStore cannot provide the requested sort order");
+        }
+        
+        SimpleFeatureCollection collection = new DefaultFeatureResults(this, query);
+        if( collection.getSchema().getGeometryDescriptor() == null ){
+            return collection; // no geometry no reprojection needed
+        }
+        return collection;
+    }
+    
+    /**
+     * Retrieve all Feature matching the Filter.
+     *
+     * @param filter Indicates features to retrieve
+     *
+     * @return FeatureResults indicating features matching filter
+     *
+     * @throws IOException If results could not be obtained
+     */
+    public SimpleFeatureCollection getFeatures(Filter filter) throws IOException {
+        return getFeatures(new DefaultQuery(getSchema().getTypeName(), filter));
+    }
+    
+    /**
+     * Retrieve all Features.
+     *
+     * @return FeatureResults of all Features in FeatureSource
+     *
+     * @throws IOException If features could not be obtained
+     */
+    public SimpleFeatureCollection getFeatures() throws IOException {
+        return getFeatures(Filter.INCLUDE);
+    }
+    
+    /**
+     * Retrieve Bounds of all Features.
+     *
+     * <p>
+     * Currently returns null, consider getFeatures().getBounds() instead.
+     * </p>
+     *
+     * <p>
+     * Subclasses may override this method to perform the appropriate optimization for this result.
+     * </p>
+     *
+     * @return null representing the lack of an optimization
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    public ReferencedEnvelope getBounds() throws IOException {
+//        return getBounds(Query.ALL); // DZ should this not return just the bounds for this type?
+        return getBounds(getSchema()==null?Query.ALL:new DefaultQuery(getSchema().getTypeName()));
+    }
+    
+    /**
+     * Retrieve Bounds of Query results.
+     *
+     * <p>
+     * Currently returns null, consider getFeatures( query ).getBounds() instead.
+     * </p>
+     *
+     * <p>
+     * Subclasses may override this method to perform the appropriate optimization for this result.
+     * </p>
+     *
+     * @param query Query we are requesting the bounds of
+     *
+     * @return null representing the lack of an optimization
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    public ReferencedEnvelope getBounds(Query query) throws IOException {
+        if (query.getFilter() == Filter.EXCLUDE) {
+            return new ReferencedEnvelope(new Envelope(), getSchema().getCoordinateReferenceSystem());
+        }
+        
+        DataStore dataStore = getDataStore();
+        
+        if ((dataStore == null) || !(dataStore instanceof AbstractDataStore)) {
+            // too expensive
+            return null;
+        } else {
+            // ask the abstract data store
+            return ((AbstractDataStore) dataStore).getBounds( namedQuery( query ) );
+        }
+    }
+    /**
+     * Ensure query modified with typeName.
+     * <p>
+     * This method will make copy of the provided query, using
+     * DefaultQuery, if query.getTypeName is not equal to
+     * getSchema().getTypeName().
+     * </p>
+     * @param query Original query
+     * @return Query with getTypeName() equal to getSchema().getTypeName()
+     */
+    protected Query namedQuery( Query query ){
+        String typeName = getSchema().getTypeName();
+        if( query.getTypeName() == null ||
+                !query.getTypeName().equals( typeName )){
+            
+            return new DefaultQuery(
+                    typeName,
+                    query.getFilter(),
+                    query.getMaxFeatures(),
+                    query.getPropertyNames(),
+                    query.getHandle()
+                    );
+        }
+        return query;
+    }
+    
+    /**
+     * Retrieve total number of Query results.
+     *
+     * <p>
+     * Currently returns -1, consider getFeatures( query ).getCount() instead.
+     * </p>
+     *
+     * <p>
+     * Subclasses may override this method to perform the appropriate optimization for this result.
+     * </p>
+     *
+     * @param query Query we are requesting the count of
+     *
+     * @return -1 representing the lack of an optimization
+     */
+    public int getCount(Query query) throws IOException {
+        if (query.getFilter() == Filter.EXCLUDE) {
+            return 0;
+        }
+        
+        DataStore dataStore = getDataStore();
+        if ((dataStore == null) || !(dataStore instanceof AbstractDataStore)) {
+            // too expensive
+            return -1;
+        } 
+        // ask the abstract data store
+        Transaction t = getTransaction();
+        
+        int nativeCount = ((AbstractDataStore) dataStore).getCount( namedQuery(query));
+        if(nativeCount == -1)
+        	return -1;
+        
+        //State state = t.getState(dataStore);
+        int delta = 0;
+        if(t != Transaction.AUTO_COMMIT) { 
+        	if(t.getState(dataStore) == null)
+        		return nativeCount;
+        	
+            if (!(t.getState(dataStore) instanceof TransactionStateDiff)) {
+            	//we cannot proceed; abort!
+            	return -1;
+            }
+        	Diff diff = ((AbstractDataStore)dataStore).state(t).diff(namedQuery(query).getTypeName());
+        	synchronized (diff) {
+        		Iterator it = diff.added.values().iterator();
+        		while(it.hasNext()){
+        			Object feature = it.next();
+        			if( query.getFilter().evaluate(feature) )
+        				delta++;
+        		}
+        		
+        		it = diff.modified2.values().iterator();
+        		while(it.hasNext()){
+        			Object feature = it.next();
+        			
+        			if(feature == TransactionStateDiff.NULL && query.getFilter().evaluate(feature)) {
+        				delta--;
+        			}
+        		}
+        	}
+        }
+        
+		return nativeCount + delta;
+    }
+    
+    /**
+     * By default, no Hints are supported
+     */
+    public Set getSupportedHints() {
+        return hints;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractFeatureStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractFeatureStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractFeatureStore.java	(revision 28000)
@@ -0,0 +1,368 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.geotools.data.simple.SimpleFeatureStore;
+import org.geotools.factory.Hints;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.IllegalAttributeException;
+import org.geotools.feature.NameImpl;
+import org.geotools.filter.identity.FeatureIdImpl;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+import org.opengis.filter.identity.FeatureId;
+
+
+/**
+ * This is a starting point for providing your own FeatureStore implementation.
+ *
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/AbstractFeatureStore.java $
+ */
+public abstract class AbstractFeatureStore extends AbstractFeatureSource
+    implements SimpleFeatureStore {
+    /** Current Transaction this SimpleFeatureSource is opperating against */
+    protected Transaction transaction = Transaction.AUTO_COMMIT;
+    
+    public AbstractFeatureStore() {
+        // just to keep the default constructor around
+    }
+    
+    /**
+     * This constructors allows to set the supported hints 
+     * @param hints
+     */
+    public AbstractFeatureStore(Set hints) {
+        super(hints);
+    }
+
+    /**
+     * Retrieve the Transaction this SimpleFeatureSource is opperating against.
+     *
+     * @return Transaction SimpleFeatureSource is operating against
+     */
+    public Transaction getTransaction() {
+        return transaction;
+    }
+
+    // 
+    // FeatureStore implementation against DataStore API
+    // 
+
+    /**
+     * Modifies features matching <code>filter</code>.
+     * 
+     * <p>
+     * Equivelent to:
+     * </p>
+     * <pre><code>
+     * FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriter( typeName, filter, transaction );
+     * while( writer.hasNext() ){
+     *    feature = writer.next();
+     *    feature.setAttribute( type.getName(), value );
+     *    writer.write();
+     * }
+     * writer.close();
+     * </code>
+     * </pre>
+     * 
+     * <p>
+     * Subclasses may override this method to perform the appropriate
+     * optimization for this result.
+     * </p>
+     *
+     * @param type Attribute to modify
+     * @param value Modification being made to type
+     * @param filter Identifies features to modify
+     *
+     * @throws IOException If modification could not be made
+     */
+    public final void modifyFeatures(AttributeDescriptor type, Object value, Filter filter)
+        throws IOException {
+        Name attributeName = type.getName();
+        modifyFeatures( attributeName, value, filter);
+    }
+    
+    public void modifyFeatures(Name attributeName, Object attributeValue, Filter filter)  throws IOException {
+        modifyFeatures(new Name[] { attributeName, }, new Object[] { attributeValue, },
+                filter);
+    }
+    
+    public void modifyFeatures(String name, Object attributeValue, Filter filter)
+            throws IOException {
+        modifyFeatures(new Name[] { new NameImpl( name ), }, new Object[] { attributeValue, },
+                filter);
+    }
+
+    public void modifyFeatures(String[] names, Object[] values, Filter filter)
+            throws IOException {
+        Name attributeNames[] = new Name[ names.length ];
+        for( int i=0; i < names.length; i ++){
+            attributeNames[i] = new NameImpl(names[i]);
+        }
+        modifyFeatures( attributeNames, values, filter ); 
+    }
+
+    /**
+     * Modifies features matching <code>filter</code>.
+     * 
+     * <p>
+     * Equivelent to:
+     * </p>
+     * <pre><code>
+     * FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriter( typeName, filter, transaction );
+     * Feature feature;
+     * while( writer.hasNext() ){
+     *    feature = writer.next();
+     *    feature.setAttribute( type[0].getName(), value[0] );
+     *    feature.setAttribute( type[1].getName(), value[1] );
+     *    ...
+     *    feature.setAttribute( type[N].getName(), value[N] ); 
+     *    writer.write();
+     * }
+     * writer.close();
+     * </code>
+     * </pre>
+     * 
+     * <p>
+     * Subclasses may override this method to perform the appropriate
+     * optimization for this result.
+     * </p>
+     *
+     * @param type Attributes to modify
+     * @param value Modifications being made to type
+     * @param filter Identifies features to modify
+     *
+     * @throws IOException If we could not modify Feature
+     * @throws DataSourceException See IOException
+     */
+    public final void modifyFeatures(AttributeDescriptor[] type, Object[] value,
+        Filter filter) throws IOException {
+        
+        Name attributeNames[] = new Name[ type.length ];
+        for( int i=0; i < type.length; i ++){
+            attributeNames[i] = type[i].getName();
+        }
+        modifyFeatures( attributeNames, value, filter );       
+    }
+
+    public void modifyFeatures(Name[] attributeNames, Object[] attributeValues, Filter filter)  throws IOException{
+        String typeName = getSchema().getTypeName();
+        if ( filter == null ) {
+            String msg = "Must specify a filter, must not be null.";
+            throw new IllegalArgumentException( msg );
+        }
+        FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getDataStore()
+                .getFeatureWriter(typeName, filter, getTransaction());
+        SimpleFeature feature;        
+        for( Name attributeName : attributeNames ){
+            if( getSchema().getDescriptor( attributeName) == null ){
+                throw new DataSourceException("Cannot modify "+attributeName+" as it is not an attribute of "+getSchema().getName() );
+            }
+        }
+        try {
+            while (writer.hasNext()) {
+                feature = writer.next();
+
+                for (int i = 0; i < attributeNames.length; i++) {
+                    try {
+                        feature.setAttribute(attributeNames[i], attributeValues[i]);
+                    } catch (Exception e) {
+                        throw new DataSourceException(
+                            "Could not update feature " + feature.getID()
+                            + " with " + attributeNames[i] + "=" + attributeValues[i], e);
+                    }
+                }
+
+                writer.write();
+            }
+        } finally {
+            writer.close();
+        }
+    }
+
+    public List<FeatureId> addFeatures(FeatureCollection<SimpleFeatureType,SimpleFeature> collection)
+            throws IOException {
+    	List<FeatureId> addedFids = new LinkedList<FeatureId>();
+        String typeName = getSchema().getTypeName();
+        SimpleFeature feature = null;
+        SimpleFeature newFeature;
+        FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getDataStore()
+                .getFeatureWriterAppend(typeName, getTransaction());
+
+        Iterator iterator = collection.iterator();
+        try {
+        	
+            while (iterator.hasNext()) {
+                feature = (SimpleFeature) iterator.next();
+                newFeature = writer.next();
+                try {
+                    newFeature.setAttributes(feature.getAttributes());
+                } catch (Exception writeProblem) {
+                    throw new DataSourceException("Could not create "
+                        + typeName + " out of provided feature: "
+                        + feature.getID(), writeProblem);
+                }
+                
+                boolean useExisting = Boolean.TRUE.equals(feature.getUserData().get(Hints.USE_PROVIDED_FID));
+                if(getQueryCapabilities().isUseProvidedFIDSupported() && useExisting) {
+                    ((FeatureIdImpl) newFeature.getIdentifier()).setID(feature.getID());
+                }
+
+                writer.write();
+                addedFids.add(newFeature.getIdentifier());
+            }
+        } finally {
+            collection.close( iterator );
+            writer.close();
+        }
+        return addedFids;
+    }
+    
+    /**
+     * Removes features indicated by provided filter.
+     * 
+     * <p>
+     * Equivelent to:
+     * </p>
+     * <pre><code>
+     * FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriter( typeName, filter, transaction );
+     * Feature feature;
+     * while( writer.hasNext() ){
+     *    feature = writer.next();
+     *    writer.remove();
+     * }
+     * writer.close();
+     * </code>
+     * </pre>
+     * 
+     * <p>
+     * Subclasses may override this method to perform the appropriate
+     * optimization for this result.
+     * </p>
+     *
+     * @param filter Identifies features to remove
+     *
+     * @throws IOException
+     */
+    public void removeFeatures(Filter filter) throws IOException {
+        String typeName = getSchema().getTypeName();
+        FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getDataStore().getFeatureWriter(typeName,
+                filter, getTransaction());
+
+        try {
+            while (writer.hasNext()) {
+                writer.next();
+                writer.remove();
+            }
+        } finally {
+            writer.close();
+        }
+    }
+
+    /**
+     * Replace with contents of reader.
+     * 
+     * <p>
+     * Equivelent to:
+     * </p>
+     * <pre><code>
+     * FeatureWriter<SimpleFeatureType, SimpleFeature> writer = dataStore.getFeatureWriter( typeName, false, transaction );
+     * Feature feature, newFeature;
+     * while( writer.hasNext() ){
+     *    feature = writer.next();
+     *    writer.remove();
+     * }
+     * while( reader.hasNext() ){
+     *    newFeature = reader.next();
+     *    feature = writer.next();
+     *    newFeature.setAttributes( feature.getAttributes( null ) );
+     *    writer.write();
+     * }
+     * reader.close();
+     * writer.close();
+     * </code>
+     * </pre>
+     * 
+     * <p>
+     * Subclasses may override this method to perform the appropriate
+     * optimization for this result.
+     * </p>
+     *
+     * @param reader Contents to replace with
+     *
+     * @throws IOException if anything goes wrong during replacement
+     * @throws DataSourceException See IOException
+     */
+    public void setFeatures(FeatureReader <SimpleFeatureType, SimpleFeature> reader) throws IOException {
+        String typeName = getSchema().getTypeName();
+        FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getDataStore().getFeatureWriter(typeName,
+                getTransaction());
+        SimpleFeature feature;
+        SimpleFeature newFeature;
+
+        try {
+            while (writer.hasNext()) {
+                feature = writer.next();
+                writer.remove();
+            }
+
+            while (reader.hasNext()) {
+                try {
+                    feature = reader.next();
+                } catch (Exception readProblem) {
+                    throw new DataSourceException("Could not add Features, problem with provided reader",
+                        readProblem);
+                }
+
+                newFeature = writer.next();
+
+                try {
+                    newFeature.setAttributes(feature.getAttributes());
+                } catch (IllegalAttributeException writeProblem) {
+                    throw new DataSourceException("Could not create "
+                        + typeName + " out of provided feature: "
+                        + feature.getID(), writeProblem);
+                }
+
+                writer.write();
+            }
+        } finally {
+            reader.close();
+            writer.close();
+        }
+    }
+
+    public void setTransaction(Transaction transaction) {
+        if (transaction == null) {
+            throw new IllegalArgumentException(
+                "Transaction cannot be null, did you mean Transaction.AUTO_COMMIT?");
+        }
+
+        this.transaction = transaction;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractFileDataStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractFileDataStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AbstractFileDataStore.java	(revision 28000)
@@ -0,0 +1,58 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+
+/**
+ * <p>
+ * This class assumes the DataStore represents a single source,  represented by
+ * a URL. In many cases the default functionality  is chained off to the
+ * parent class (AbstractDataStore).
+ * </p>
+ *
+ * @author dzwiers
+ *
+ * @see AbstractDataStore
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/AbstractFileDataStore.java $
+ */
+public abstract class AbstractFileDataStore extends AbstractDataStore implements FileDataStore {
+    /**
+     * Singular version, returns the FeatureType for the url being read.
+     *
+     * @see org.geotools.data.DataStore#getSchema(java.lang.String)
+     */
+    public SimpleFeatureType getSchema() throws IOException {
+        return this.getSchema( getTypeNames()[0] );
+    }
+
+    /**
+     * Singular version, which must be implemented to represent a Reader  for
+     * the url being read.
+     *
+     * @see org.geotools.data.DataStore#getFeatureReader(java.lang.String)
+     */
+    public FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader()
+        throws IOException{
+        return getFeatureReader( getTypeNames()[0] );
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AttributeReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AttributeReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AttributeReader.java	(revision 28000)
@@ -0,0 +1,77 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+
+import org.opengis.feature.type.AttributeDescriptor;
+
+
+/**
+ * The low-level attribute reading API.  An AttributeReader is responsible for
+ * reading a finite set of attributes from an underlying storage format. It
+ * provides meta-data regarding the data it can provide, and an iterative,
+ * row-based approach for accessing the data.
+ *
+ * @author Ian Schneider
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/AttributeReader.java $
+ * @version $Id: AttributeReader.java 37298 2011-05-25 05:16:15Z mbedward $
+ *
+ * @see AttributeAcceptor
+ */
+public interface AttributeReader {
+    /**
+     * The number of attributes this reader can read, i.e the length of a row.
+     *
+     * @return Number of attribtues this reader can read
+     */
+    int getAttributeCount();
+
+    /**
+     * Retrieve the AttributeType at the given index.
+     *
+     * @return AttributeType at given index
+     */
+    AttributeDescriptor getAttributeType(int index)
+        throws ArrayIndexOutOfBoundsException;
+
+    /**
+     * Release any resources associated with this reader
+     */
+    void close() throws IOException;
+
+    /**
+     * Does another set of attributes exist in this reader?
+     *
+     * @return <code>true</code> if additional content exists for
+     *         AttributeReader
+     */
+    boolean hasNext() throws IOException;
+
+    /**
+     * Advance the reader to the next set of attributes.
+     */
+    void next() throws IOException;
+
+    /**
+     * Read the attribute at the given index.
+     *
+     * @return Object Attribute at given index
+     */
+    Object read(int index) throws IOException, ArrayIndexOutOfBoundsException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AutoCommitTransaction.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AutoCommitTransaction.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/AutoCommitTransaction.java	(revision 28000)
@@ -0,0 +1,87 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.util.Set;
+
+
+/**
+ * This is used to represent the absense of a Transaction and the use of
+ * AutoCommit.
+ *
+ * <p>
+ * This class serves as the implementation of the constant Transaction.NONE.
+ * It is a NullObject and we feel no need to make this class public.
+ * </p>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/AutoCommitTransaction.java $
+ */
+class AutoCommitTransaction implements Transaction {
+    /**
+     * Authorization IDs are not stored by AutoCommit.
+     *
+     * <p>
+     * Authorization IDs are only stored for the duration of a Transaction.
+     * </p>
+     *
+     * @return Set of authorizations
+     *
+     * @throws UnsupportedOperationException AUTO_COMMIT does not support this
+     */
+    public Set<String> getAuthorizations() {
+        throw new UnsupportedOperationException(
+            "Authorization IDs are not valid for AutoCommit Transaction");
+    }
+
+    /**
+     * AutoCommit does not save State.
+     *
+     * <p>
+     * While symetry would be good, state should be commited not stored for
+     * later.
+     * </p>
+     *
+     * @param key Key that is not used to Store State
+     * @param state State we are not going to externalize
+     *
+     * @throws UnsupportedOperationException AutoCommit does not support State
+     */
+    public void putState(Object key, State state) {
+        throw new UnsupportedOperationException(
+            "AutoCommit does not support the putState opperations");
+    }
+
+    /**
+     * I am not sure should AutoCommit be able to save sate?
+     *
+     * <p>
+     * While symetry would be good, state should be commited not stored for
+     * later.
+     * </p>
+     *
+     * @param key Key used to retrieve State
+     *
+     * @return State earlier provided with putState
+     *
+     * @throws UnsupportedOperationException As Autocommit does not support
+     *         State
+     */
+    public State getState(Object key) {
+        throw new UnsupportedOperationException(
+            "AutoCommit does not support the getState opperations");
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/CurrentTransactionLock.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/CurrentTransactionLock.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/CurrentTransactionLock.java	(revision 28000)
@@ -0,0 +1,70 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+
+/**
+ * A request for a Lock that last the duration of a transaction.
+ *
+ * <p>
+ * The single instance of this class is available as
+ * <code>FeatureLock.TRANSACTION</code>.
+ * </p>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/CurrentTransactionLock.java $
+ */
+class CurrentTransactionLock extends FeatureLock {
+    
+    CurrentTransactionLock() {
+        super( null, -1 );
+    }
+    /**
+     * Transaction locks do not require Authorization.
+     *
+     * <p>
+     * Authorization is based on being on "holding" the Transaction rather than
+     * supplying an authorization id.
+     * </p>
+     *
+     * @return <code>CURRENT_TRANSACTION</code> to aid in debugging.
+     *
+     * @see org.geotools.data.FeatureLock#getAuthorization()
+     */
+    public String getAuthorization() {
+        return toString();
+    }
+
+    /**
+     * Transaciton locks are not held for a duration.
+     *
+     * <p>
+     * Any locking performed against the current Transaction is expected to
+     * expire when the transaction finishes with a close or rollback
+     * </p>
+     *
+     * @return <code>-1</code> representing an invalid duration
+     *
+     * @see org.geotools.data.FeatureLock#getDuration()
+     */
+    public long getDuration() {
+        return -1;
+    }
+
+    public String toString() {
+        return "CURRENT_TRANSACTION";
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataAccess.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataAccess.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataAccess.java	(revision 28000)
@@ -0,0 +1,135 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+
+import org.geotools.feature.FeatureCollection;
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+
+/**
+ * This is the top-level interface for access to {@code FeatureData}.
+ *
+ * <p>
+ * <h2>Description</h2>
+ * The DataAccess interface provides the following information about its contents:
+ * <ul>
+ * <li>{@link DataAccess.getInfo()} - information about the file or server itself
+ * <li>{@link DataAccess.getNames()} - list of the available contents (each is an individual resource)
+ * <li>{@link DataAccess.getSchema( Name )} - FeatureType describing the information available in the named resource
+ * </ul>
+ * <p>
+ * <h2>Contents</h2>
+ * You can access the contents of a service or file using getFeatureSource( Name ). Depending the
+ * abilities of your implementation and your credentials you will have access to
+ * <ul>
+ * <li>{@link FeatureSource}: read-only api similar to the WFS getFeature operations. Please note the reutrned
+ *    FeatureCollection may be *lazy*; for many implementations no actual access will occur until you
+ *    use the FetaureCollection for the first time.
+ * <li>{@link FeatureStore}: read/write api similar to the WFS Transaction operation. Batch changes such as 
+ *    addFeatures, modifyFeatures and removeFeatures are supported.
+ * <li>{@link FeatureLocking}: concurrency control; the Data Access API is thread safe; one consequence of this
+ * is modifications being held up while other threads read the contents. You may wish to Lock a selection
+ * of features for your exclusive use. Locks are timed; and will expire after the indicated period.
+ * </ul>
+ * <p>
+ * Please note that all interaction occurs within the context of a Transaction, this
+ * facility provides session management and is strongly advised. Please note that
+ * your application is responsible for managing its own Transactions; as an example
+ * they are often associated with a single Map in a desktop application; or a single
+ * session in a J2EE web app.
+ * <p>
+ * The use of Transaction.AUTO_COMMIT is suitable for read-only access when you wish
+ * to minimize the number of connections in use, when used for writing performance
+ * will often be terrible.
+ * 
+ * <h2>Lifecycle</h2>
+ * 
+ * Normal use:
+ * <ul>
+ * <li>Connect using a DataAccessFactory.createDataStore using a set of connection parameters
+ * <li>Application is responsible for holding a single instance to the service or file, DataAccess
+ * implementations will hold onto database connections, internal caches and so on - and as such
+ * should not be duplicated.
+ * <li>DataAccess.dispose() is called when the application is shut down
+ * </ul>
+ * 
+ * Creation:
+ * <ul>
+ * <li>Created using a DataAccessFactory.createNewDataStore using a set of creation parameters
+ * <li>DataAccess.createSchema( T ) is called to set up the contents
+ * <li>DataAccess.getFetaureSource( Name ) is called, and FeatureStore.addFeatures( collection ) used to populate the contents
+ * <li>DataAccess.dispose() is called when the application is shut down
+ * </ul>
+ * <p>
+ * Applications are responsible for holding a single instance to the service or file, The
+ * DataAccess implementations will hold onto database connections, internal caches and so on - and as such
+ * should not be duplicated.
+ * 
+ * @see DataStore Subclass restricted to working with simple content
+ * @param <T> Type of Feature Content, may be SimpleFeatureType
+ * @param <F> Feature Content, may be SimpleFetaure
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/DataAccess.java $
+ */
+public interface DataAccess<T extends FeatureType, F extends Feature> {
+
+    /**
+     * Creates storage for a new <code>featureType</code>.
+     *
+     * <p>
+     * The provided <code>featureType</code> we be accessable by the typeName
+     * provided by featureType.getTypeName().
+     * </p>
+     *
+     * @param featureType FetureType to add to DataStore
+     *
+     * @throws IOException If featureType cannot be created
+     */
+    void createSchema(T featureType) throws IOException;
+
+    /**
+     * Disposes of this data store and releases any resource that it is using.
+     * <p>
+     * A <code>DataStore</code> cannot be used after <code>dispose</code> has
+     * been called, neither can any data access object it helped create, such
+     * as {@link FeatureReader}, {@link FeatureSource} or {@link FeatureCollection}.
+     * <p>
+     * This operation can be called more than once without side effects.
+     * <p>
+     * There is no thread safety assurance associated with this method. For example,
+     * client code will have to make sure this method is not called while retrieving/saving data
+     * from/to the storage, or be prepared for the consequences.
+     */
+    void dispose();
+
+    //FeatureSource<T,F> getView(Query query) throws IOException, SchemaException;
+
+    //FeatureReader<T,F> getFeatureReader(Query query, Transaction transaction)
+    //    throws IOException;
+    
+    //FeatureWriter<T,F> getFeatureWriter(Name typeName, Filter filter, Transaction transaction)
+    //    throws IOException;
+
+    //FeatureWriter<T,F> getFeatureWriter(Name typeName, Transaction transaction)
+    //    throws IOException;
+
+    //FeatureWriter<T,F> getFeatureWriterAppend(Name typeName, Transaction transaction)
+    //    throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataAccessFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataAccessFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataAccessFactory.java	(revision 28000)
@@ -0,0 +1,474 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.geotools.factory.Factory;
+import org.geotools.util.SimpleInternationalString;
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * Constructs a live DataAccess from a set of connection parameters.
+ * <p>
+ * The following example shows how a user might connect to a PostGIS database,
+ * and maintain the resulting datastore in a Registry:
+ * </p>
+ *
+ * <p>
+ * <pre><code>
+ * HashMap params = new HashMap();
+ * params.put("namespace", "leeds");
+ * params.put("dbtype", "postgis");
+ * params.put("host","feathers.leeds.ac.uk");
+ * params.put("port", "5432");
+ * params.put("database","postgis_test");
+ * params.put("user","postgis_ro");
+ * params.put("passwd","postgis_ro");
+ *
+ * DefaultRegistry registry = new DefaultRegistry();
+ * registry.addDataStore("leeds", params);
+ *
+ * DataStore postgis = registry.getDataStore( "leeds" );
+ * SimpleFeatureSource = postgis.getFeatureSource( "table" );
+ * </code></pre>
+ * </p>
+ * The required parameters are described by the getParameterInfo() method. Client
+ * 
+ * <h2>Implementation Notes</h2>
+ * <p>
+ * An instance of this interface should exist for all DataAccess implementations
+ * that want to advantage of the dynamic plug-in system. In addition to implementing
+ * this interface a DataAccess implementation should provide a services file:
+ * </p>
+ *
+ * <p>
+ * <code>META-INF/services/org.geotools.data.DataAccessFactory</code>
+ * </p>
+ *
+ * <p>
+ * The file should contain a single line which gives the full name of the
+ * implementing class.
+ * </p>
+ *
+ * <p>
+ * Example:<br/><code>e.g.
+ * org.geotools.data.mytype.MyTypeDataSourceFacotry</code>
+ * </p>
+ *
+ * <p>
+ * The factories are never called directly by client code, instead the
+ * DataStoreFinder class is used.
+ * </p>
+ * 
+ * @author Jody Garnett (Refractions Research)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/DataAccessFactory.java $
+ */
+public interface DataAccessFactory extends Factory {
+    /**
+     * Construct a live DataAccess using the connection parameters provided.
+     * <p>
+     * You can think of this class as setting up a connection to the back end data source. The
+     * required parameters are described by the getParameterInfo() method.
+     * </p>
+     *
+     * <p>
+     * Magic Params: the following params are magic and are honoured by
+     * convention by the GeoServer and uDig application.
+     *
+     * <ul>
+     * <li>
+     * "user": is taken to be the user name
+     * </li>
+     * <li>
+     * "passwd": is taken to be the password
+     * </li>
+     * <li>
+     * "namespace": is taken to be the namespace prefix (and will be kept in
+     * sync with GeoServer namespace management.
+     * </li>
+     * </ul>
+     *
+     * When we eventually move over to the use of OpperationalParam we will
+     * have to find someway to codify this convention.
+     * </p>
+     *
+     * @param params The full set of information needed to construct a live
+     *        data store. Typical key values for the map include: url -
+     *        location of a resource, used by file reading datasources. dbtype
+     *        - the type of the database to connect to, e.g. postgis, mysql
+     *
+     * @return The created DataStore, this may be null if the required resource
+     *         was not found or if insufficent parameters were given. Note
+     *         that canProcess() should have returned false if the problem is
+     *         to do with insuficent parameters.
+     *
+     * @throws IOException if there were any problems setting up (creating or
+     *         connecting) the datasource.
+     */
+    DataAccess<? extends FeatureType, ? extends Feature> createDataStore(Map<String, Serializable> params) throws IOException;
+
+    /**
+     * Describe the nature of the datasource constructed by this factory.
+     *
+     * <p>
+     * A non localized description of this data store type.
+     * </p>
+     *
+     * @return A human readable description that is suitable for inclusion in a
+     *         list of available datasources.
+     */
+    String getDescription();
+
+    /**
+     * Test to see if the implementation is available for use.
+     * This method ensures all the appropriate libraries to construct
+     * the DataAccess are available. 
+     * <p>
+     * Most factories will simply return <code>true</code> as GeoTools will
+     * distribute the appropriate libraries. Though it's not a bad idea for
+     * DataStoreFactories to check to make sure that the  libraries are there.
+     * <p>
+     * OracleDataStoreFactory is an example of one that may generally return
+     * <code>false</code>, since GeoTools can not distribute the oracle jars.
+     * (they must be added by the client.)
+     * <p>
+     * One may ask how this is different than canProcess, and basically available
+     * is used by the DataStoreFinder getAvailableDataStore method, so that
+     * DataStores that can not even be used do not show up as options in gui
+     * applications.
+     *
+     * @return <tt>true</tt> if and only if this factory has all the
+     *         appropriate jars on the classpath to create DataStores.
+     */
+    boolean isAvailable();
+
+    /**
+     * Data class used to capture Parameter requirements.
+     *
+     * <p>
+     * Subclasses may provide specific setAsText()/getAsText() requirements
+     * </p>
+     *
+     * <p>
+     * Warning: We would like to start moving towards a common paraemters
+     * framework with GridCoverageExchnage. Param will be maintained as a
+     * wrapper for one point release (at which time it will be deprecated).
+     * </p>
+     */
+    @SuppressWarnings("unchecked")
+    public static class Param extends Parameter {
+
+        /**
+         * Provides support for text representations
+         *
+         * @param key Key used to file this Param in the Parameter Map for
+         *        createDataStore
+         * @param type Class type intended for this Param
+         * @param description User description of Param (40 chars or less)
+         * @param required <code>true</code> is param is required
+         */
+        public Param(String key, Class<?> type, String description, boolean required) {
+            this(key, type, description, required, null);
+        }
+
+        /**
+         * Provides support for text representations
+         *
+         * @param key Key used to file this Param in the Parameter Map for
+         *        createDataStore
+         * @param type Class type intended for this Param
+         * @param description User description of Param (40 chars or less)
+         * @param required <code>true</code> is param is required
+         * @param sample Sample value as an example for user input
+         */
+        public Param(String key, Class<?> type, String description, boolean required, Object sample) {
+            this(key, type, description == null? null : new SimpleInternationalString(description),
+                    required, sample, null);
+        }
+
+        /**
+         * Provides support for text representations
+         *
+         * @param key Key used to file this Param in the Parameter Map for
+         *        createDataStore
+         * @param type Class type intended for this Param
+         * @param description User description of Param (40 chars or less)
+         * @param required <code>true</code> is param is required
+         * @param sample Sample value as an example for user input
+         * @param extra metadata information, preferably keyed by known identifiers 
+         * like {@link Parameter#IS_PASSWORD}
+         */
+        public Param(String key,
+                     Class type,
+                     String description,
+                     boolean required,
+                     Object sample,
+                     Map<String, ?> metadata) {
+            this(key, type, new SimpleInternationalString(description), required, sample, metadata);
+        }
+
+        /**
+         * Provides support for text representations
+         *
+         * @param key Key used to file this Param in the Parameter Map for
+         *        createDataStore
+         * @param type Class type intended for this Param
+         * @param description User description of Param (40 chars or less)
+         * @param required <code>true</code> is param is required
+         * @param sample Sample value as an example for user input
+         * @param extra metadata information, preferably keyed by known identifiers 
+         * like {@link Parameter#IS_PASSWORD}
+         */
+        public Param(String key,
+                     Class type,
+                     InternationalString description,
+                     boolean required,
+                     Object sample,
+                     Map<String, ?> metadata) {
+            super(key, type, new SimpleInternationalString(key), description, required, 1, 1, sample, metadata);
+        }
+        
+        /**
+         * Lookup Param in a user supplied map.
+         *
+         * <p>
+         * Type conversion will occur if required, this may result in an
+         * IOException. An IOException will be throw in the Param is required
+         * and the Map does not contain the Map.
+         * </p>
+         *
+         * <p>
+         * The handle method is used to process the user's value.
+         * </p>
+         *
+         * @param map Map of user input
+         *
+         * @return Parameter as specified in map
+         *
+         * @throws IOException if parse could not handle value
+         */
+        public Object lookUp(Map<String, ?> map) throws IOException {
+            if (!map.containsKey(key)) {
+                if (required) {
+                    throw new IOException("Parameter " + key + " is required:" + description);
+                } else {
+                    return null;
+                }
+            }
+
+            Object value = map.get(key);
+
+            if (value == null) {
+                return null;
+            }
+
+            if (value instanceof String && (type != String.class)) {
+                value = handle((String) value);
+            }
+
+            if (value == null) {
+                return null;
+            }
+
+            if (!type.isInstance(value)) {
+                throw new IOException(type.getName() + " required for parameter " + key + ": not "
+                    + value.getClass().getName());
+            }
+
+            return value;
+        }
+
+        /**
+         * Convert value to text representation for this Parameter
+         *
+         * @param value DOCUMENT ME!
+         *
+         * @return DOCUMENT ME!
+         */
+        public String text(Object value) {
+            return value.toString();
+        }
+
+        /**
+         * Handle text in a sensible manner.
+         *
+         * <p>
+         * Performs the most common way of handling text value:
+         * </p>
+         *
+         * <ul>
+         * <li>
+         * null: If text is null
+         * </li>
+         * <li>
+         * origional text: if type == String.class
+         * </li>
+         * <li>
+         * null: if type != String.class and text.getLength == 0
+         * </li>
+         * <li>
+         * parse( text ): if type != String.class
+         * </li>
+         * </ul>
+         *
+         *
+         * @param text
+         *
+         * @return Value as processed by text
+         *
+         * @throws IOException If text could not be parsed
+         */
+        public Object handle(String text) throws IOException {
+            if (text == null) {
+                return null;
+            }
+
+            if (type == String.class) {
+                return text;
+            }
+
+            if (text.length() == 0) {
+                return null;
+            }
+
+            // if type is an array, tokenize the string and have the reflection
+            // parsing be tried on each element, then build the array as a result
+            if (type.isArray()) {
+                StringTokenizer tokenizer = new StringTokenizer(text, " ");
+                List<Object> result = new ArrayList<Object>();
+
+                while (tokenizer.hasMoreTokens()) {
+                    String token = tokenizer.nextToken();
+                    Object element;
+
+                    try {
+                        if (type.getComponentType() == String.class) {
+                            element = token;
+                        } else {
+                            element = parse(token);
+                        }
+                    } catch (IOException ioException) {
+                        throw ioException;
+                    } catch (Throwable throwable) {
+                        throw new DataSourceException("Problem creating " + type.getName()
+                            + " from '" + text + "'", throwable);
+                    }
+
+                    result.add(element);
+                }
+
+                Object array = Array.newInstance(type.getComponentType(), result.size());
+
+                for (int i = 0; i < result.size(); i++) {
+                    Array.set(array, i, result.get(i));
+                }
+
+                return array;
+            }
+
+            try {
+                return parse(text);
+            } catch (IOException ioException) {
+                throw ioException;
+            } catch (Throwable throwable) {
+                throw new DataSourceException("Problem creating " + type.getName() + " from '"
+                    + text + "'", throwable);
+            }
+        }
+
+        /**
+         * Provides support for text representations
+         *
+         * <p>
+         * Provides basic support for common types using reflection.
+         * </p>
+         *
+         * <p>
+         * If needed you may extend this class to handle your own custome
+         * types.
+         * </p>
+         *
+         * @param text Text representation of type should not be null or empty
+         *
+         * @return Object converted from text representation
+         *
+         * @throws Throwable DOCUMENT ME!
+         * @throws IOException If text could not be parsed
+         * @throws DataSourceException DOCUMENT ME!
+         */
+        public Object parse(String text) throws Throwable {
+            Constructor<?> constructor;
+
+            try {
+                constructor = type.getConstructor(new Class[] { String.class });
+            } catch (SecurityException e) {
+                //  type( String ) constructor is not public
+                throw new IOException("Could not create " + type.getName() + " from text");
+            } catch (NoSuchMethodException e) {
+                // No type( String ) constructor
+                throw new IOException("Could not create " + type.getName() + " from text");
+            }
+
+            try {
+                return constructor.newInstance(new Object[] { text, });
+            } catch (IllegalArgumentException illegalArgumentException) {
+                throw new DataSourceException("Could not create " + type.getName() + ": from '"
+                    + text + "'", illegalArgumentException);
+            } catch (InstantiationException instantiaionException) {
+                throw new DataSourceException("Could not create " + type.getName() + ": from '"
+                    + text + "'", instantiaionException);
+            } catch (IllegalAccessException illegalAccessException) {
+                throw new DataSourceException("Could not create " + type.getName() + ": from '"
+                    + text + "'", illegalAccessException);
+            } catch (InvocationTargetException targetException) {
+                throw targetException.getCause();
+            }
+        }
+
+        /**
+         * key=Type description
+         */
+        public String toString() {
+            StringBuffer buf = new StringBuffer();
+            buf.append(key);
+            buf.append('=');
+            buf.append(type.getName());
+            buf.append(' ');
+
+            if (required) {
+                buf.append("REQUIRED ");
+            }
+
+            buf.append(description);
+
+            return buf.toString();
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataSourceException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataSourceException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataSourceException.java	(revision 28000)
@@ -0,0 +1,53 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+
+/**
+ * Thrown when there is an error in a datasource.
+ * <p>
+ * This class was used back in Java 1.3 before the initCause() method
+ * was available for IOException. Since this class is used to pass on
+ * problems from external services, providing the root cause is
+ * important.
+ * </p>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/DataSourceException.java $
+ */
+public class DataSourceException extends java.io.IOException {
+    private static final long serialVersionUID = -602847953059978370L;
+
+    /**
+     * Constructs a new instance of DataSourceException
+     *
+     * @param msg A message explaining the exception
+     */
+    public DataSourceException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Constructs a new instance of DataSourceException
+     *
+     * @param msg A message explaining the exception
+     * @param cause the throwable object which caused this exception
+     */
+    public DataSourceException(String msg, Throwable cause) {
+        super(msg);
+        initCause(cause);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataStore.java	(revision 28000)
@@ -0,0 +1,207 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+
+import org.geotools.data.simple.SimpleFeatureSource;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+
+
+/**
+ * This represents a physical source of feature data, such as a shapefiles or
+ * database, where the features will be instances of {@code SimpleFeature}.
+ * It is derived from the {@code DataAccess} interface (which works at the more
+ * general {@code Feature} level.
+ *
+ * @see DataAccess
+ * @see org.opengis.feature.Feature
+ * @see SimpleFeature
+ *
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/DataStore.java $
+ * @version $Id: DataStore.java 37280 2011-05-24 07:53:02Z mbedward $
+ */
+public interface DataStore extends DataAccess<SimpleFeatureType, SimpleFeature>{
+   
+    /**
+     * Applies a new schema to the given feature type. This can be used
+     * to add or remove properties. The resulting update will be persistent.
+     *
+     * @param typeName name of the feature type to update
+     *
+     * @param featureType the new schema to apply
+     *
+     * @throws IOException on error
+     */
+    void updateSchema(String typeName, SimpleFeatureType featureType)
+        throws IOException;
+
+    /**
+     * Gets the names of feature types available in this {@code DataStore}.
+     * Please note that this is not guaranteed to return a list of unique
+     * names since the same unqualified name may be present in separate
+     * namespaces within the {@code DataStore}.
+     *
+     * @return names of feature types available in this {@code DataStore}
+     *
+     * @throws IOException if data access errors occur
+     */
+    String[] getTypeNames() throws IOException;
+    
+    /**
+     * Gets the type information (schema) for the specified feature type.
+     *
+     * @param typeName the feature type name
+     *
+     * @return the requested feature type
+     *
+     * @throws IOException if {@code typeName} is not available
+     */
+    SimpleFeatureType getSchema(String typeName) throws IOException;
+
+    /**
+     * Gets a {@code SimpleFeatureSource} for features of the specified
+     * type. {@code SimpleFeatureSource} provides a high-level API for
+     * feature operations.
+     * <p>
+     * The resulting {@code SimpleFeatureSource} may implment more functionality
+     * as in this example:
+     * <pre><code>
+     *
+     * SimpleFeatureSource fsource = dataStore.getFeatureSource("roads");
+     * if (fsource instanceof SimpleFeatureStore) {
+     *     // we have write access to the feature data
+     *     SimpleFeatureStore fstore = (SimpleFeatureStore) fs;
+     * }
+     * else {
+     *     System.out.println("We do not have write access to roads");
+     * }
+     * </code></pre>
+     *
+     * @param typeName the feature type
+     *
+     * @return a {@code SimpleFeatureSource} (or possibly a subclass) providing
+     *         operations for features of the specified type
+     *
+     * @throws IOException if data access errors occur
+     *
+     * @see SimpleFeatureSource
+     * @see org.geotools.data.simple.SimpleFeatureStore
+     */
+    SimpleFeatureSource getFeatureSource(String typeName) throws IOException;
+
+    /**
+     * Gets a {@code FeatureReader} for features selected by the given
+     * {@code Query}.  {@code FeatureReader} provies an iterator-style
+     * API to feature data.
+     * <p>
+     * The {@code Query} provides the schema for the form of the returned
+     * features as well as a {@code Filter} to constrain the features
+     * available via the reader.
+     * <p>
+     * The {@code Transaction} can be used to externalize the state of the
+     * {@code DataStore}. Examples of this include a {@code JDBCDataStore}
+     * sharing a connection for use across several {@code FeatureReader} requests;
+     * and a {@code ShapefileDataStore} redirecting requests to an alternate file
+     * during the course of a {@code Transaction}.
+     *
+     * @param query a query providing the schema and constraints for
+     *        features that the reader will return
+     *
+     * @param transaction a transaction that this reader will operate against
+     *
+     * @throws IOException if data access errors occur
+     *
+     * @return an instance of {@code FeatureReader}
+     */
+    FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(Query query,
+            Transaction transaction) throws IOException;
+
+    /**
+     * Gets a {@code FeatureWriter} to modify features in this {@code DataStore}.
+     * {@code FeatureWriter} provides an iterator style API to features.
+     * <p>
+     * The returned writer does <b>not</b> allow features to be added.
+     *
+     * @param typeName the type name for features that will be accessible
+     *
+     * @param filter defines additional constraints on the features that will
+     *        be accessible
+     *
+     * @param transaction the transation that the returned writer operates
+     *        against
+     *
+     * @return an instance of {@code FeatureWriter}
+     *
+     * @throws IOException if data access errors occur
+     *
+     * @see #getFeatureWriterAppend(String, Transaction)
+     */
+    FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriter(String typeName,
+            Filter filter, Transaction transaction) throws IOException;
+
+    /**
+     * Gets a {@code FeatureWriter} to modify features in this {@code DataStore}.
+     * {@code FeatureWriter} provides an iterator style API to features.
+     * <p>
+     * The returned writer does <b>not</b> allow features to be added.
+     *
+     * @param typeName the type name for features that will be accessible
+     *
+     * @param transaction the transation that the returned writer operates
+     *        against
+     *
+     * @return an instance of {@code FeatureWriter}
+     *
+     * @throws IOException if data access errors occur
+     *
+     * @see #getFeatureWriterAppend(String, Transaction)
+     */
+    FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriter(String typeName,
+            Transaction transaction) throws IOException;
+
+    /**
+     * Gets a {@code FeatureWriter} that can add new features to the {@code DataStore}.
+     * <p>
+     * The {@code FeatureWriter} will return {@code false} when its {@code hasNext()}
+     * method is called, but {@code next()} can be used to acquire new features.
+     *
+     * @param typeName name of the feature type for which features will be added
+     *
+     * @param transaction the transaction to operate against
+     *
+     * @return an instance of {@code FeatureWriter} that can only be used to
+     *         append new features
+     *
+     * @throws IOException if data access errors occur
+     */
+    FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriterAppend(String typeName,
+            Transaction transaction) throws IOException;
+
+    /**
+     * Retrieve a per featureID based locking service from this {@code DataStore}.
+     *
+     * @return an instance of {@code LockingManager}; or {@code null} if locking
+     *         is handled by the {@code DataStore} in a different fashion
+     */
+    LockingManager getLockingManager();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataStoreFactorySpi.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataStoreFactorySpi.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataStoreFactorySpi.java	(revision 28000)
@@ -0,0 +1,138 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Factory used to construct a DataStore from a set of parameters.
+ * <p>
+ * The following example shows how a user might connect to a PostGIS database,
+ * and maintain the resulting DataStore in a Registry:
+ * </p>
+ *
+ * <p>
+ * <pre><code>
+ * HashMap params = new HashMap();
+ * params.put("namespace", "leeds");
+ * params.put("dbtype", "postgis");
+ * params.put("host","feathers.leeds.ac.uk");
+ * params.put("port", "5432");
+ * params.put("database","postgis_test");
+ * params.put("user","postgis_ro");
+ * params.put("passwd","postgis_ro");
+ *
+ * DefaultRegistry registry = new DefaultRegistry();
+ * registry.addDataStore("leeds", params);
+ *
+ * DataStore postgis = registry.getDataStore( "leeds" );
+ * SimpleFeatureSource = postgis.getFeatureSource( "table" );
+ * </code></pre>
+ * </p> 
+ * <h2>Implementation Notes</h2>
+ * <p>
+ * An instance of this interface should exist for all data stores which want to
+ * take advantage of the dynamic plug-in system. In addition to implementing
+ * this factory interface each DataStore implementation should have a services file:
+ * </p>
+ *
+ * <p>
+ * <code>META-INF/services/org.geotools.data.DataStoreFactorySpi</code>
+ * </p>
+ *
+ * <p>
+ * The file should contain a single line which gives the full name of the
+ * implementing class.
+ * </p>
+ *
+ * <p>
+ * example:<br/><code>e.g.
+ * org.geotools.data.mytype.MyTypeDataSourceFacotry</code>
+ * </p>
+ *
+ * <p>
+ * The factories are never called directly by client code, instead the
+ * DataStoreFinder class is used.
+ * </p>
+ * 
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/DataStoreFactorySpi.java $
+ */
+public interface DataStoreFactorySpi extends DataAccessFactory {
+    /**
+     * Construct a live data source using the params specifed.
+     *
+     * <p>
+     * You can think of this as setting up a connection to the back end data
+     * source.
+     * </p>
+     *
+     * <p>
+     * Magic Params: the following params are magic and are honoured by
+     * convention by the GeoServer and uDig application.
+     *
+     * <ul>
+     * <li>
+     * "user": is taken to be the user name
+     * </li>
+     * <li>
+     * "passwd": is taken to be the password
+     * </li>
+     * <li>
+     * "namespace": is taken to be the namespace prefix (and will be kept in
+     * sync with GeoServer namespace management.
+     * </li>
+     * </ul>
+     *
+     * When we eventually move over to the use of OpperationalParam we will
+     * have to find someway to codify this convention.
+     * </p>
+     *
+     * @param params The full set of information needed to construct a live
+     *        data store. Typical key values for the map include: url -
+     *        location of a resource, used by file reading datasources. dbtype
+     *        - the type of the database to connect to, e.g. postgis, mysql
+     *
+     * @return The created DataStore, this may be null if the required resource
+     *         was not found or if insufficent parameters were given. Note
+     *         that canProcess() should have returned false if the problem is
+     *         to do with insuficent parameters.
+     *
+     * @throws IOException if there were any problems setting up (creating or
+     *         connecting) the datasource.
+     */
+    DataStore createDataStore(Map<String, java.io.Serializable> params) throws IOException;
+
+    //    /**
+    //     * Construct a simple MetadataEntity providing internationlization information
+    //     * for the data source that *would* be created by createDataStore.
+    //     * <p>
+    //     * Suitable for use by CatalogEntry, unknown if this will make
+    //     * a DataStore behind the scenes or not. It is possible it will
+    //     * communicate with the data source though (hense the IOException).
+    //     * </p>
+    //     * @param params The full set of information needed to construct a live
+    //     *        data store
+    //     * @return MetadataEntity with descriptive information (including
+    //     *         internationlization support). 
+    //     * @throws IOException
+    //     */
+    //    DataSourceMetadataEnity createMetadata( Map params ) throws IOException;
+    DataStore createNewDataStore(Map<String, java.io.Serializable> params) throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataUtilities.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataUtilities.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DataUtilities.java	(revision 28000)
@@ -0,0 +1,860 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Array;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.factory.Hints;
+import org.geotools.feature.AttributeTypeBuilder;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.feature.SchemaException;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
+import org.geotools.filter.visitor.PropertyNameResolvingVisitor;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.util.Utilities;
+import org.opengis.feature.Feature;
+import org.opengis.feature.FeatureVisitor;
+import org.opengis.feature.IllegalAttributeException;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.FeatureType;
+import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory;
+import org.opengis.filter.expression.PropertyName;
+import org.opengis.filter.sort.SortBy;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.MultiLineString;
+import com.vividsolutions.jts.geom.MultiPoint;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+
+/**
+ * Utility functions for use when implementing working with data classes.
+ * <p>
+ * TODO: Move FeatureType manipulation to feature package
+ * </p>
+ * 
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/DataUtilities.java $
+ *         http://svn.osgeo.org/geotools/trunk/modules/library/main/src/main/java/org/geotools/
+ *         data/DataUtilities.java $
+ */
+public class DataUtilities {
+
+    static Map<String, Class> typeMap = new HashMap<String, Class>();
+
+    static Map<Class, String> typeEncode = new HashMap<Class, String>();
+
+    static FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
+
+    static {
+        typeEncode.put(String.class, "String");
+        typeMap.put("String", String.class);
+        typeMap.put("string", String.class);
+        typeMap.put("\"\"", String.class);
+
+        typeEncode.put(Integer.class, "Integer");
+        typeMap.put("Integer", Integer.class);
+        typeMap.put("int", Integer.class);
+        typeMap.put("0", Integer.class);
+
+        typeEncode.put(Double.class, "Double");
+        typeMap.put("Double", Double.class);
+        typeMap.put("double", Double.class);
+        typeMap.put("0.0", Double.class);
+
+        typeEncode.put(Float.class, "Float");
+        typeMap.put("Float", Float.class);
+        typeMap.put("float", Float.class);
+        typeMap.put("0.0f", Float.class);
+
+        typeEncode.put(Boolean.class, "Boolean");
+        typeMap.put("Boolean", Boolean.class);
+        typeMap.put("true", Boolean.class);
+        typeMap.put("false", Boolean.class);
+
+        typeEncode.put(Geometry.class, "Geometry");
+        typeMap.put("Geometry", Geometry.class);
+
+        typeEncode.put(Point.class, "Point");
+        typeMap.put("Point", Point.class);
+
+        typeEncode.put(LineString.class, "LineString");
+        typeMap.put("LineString", LineString.class);
+
+        typeEncode.put(Polygon.class, "Polygon");
+        typeMap.put("Polygon", Polygon.class);
+
+        typeEncode.put(MultiPoint.class, "MultiPoint");
+        typeMap.put("MultiPoint", MultiPoint.class);
+
+        typeEncode.put(MultiLineString.class, "MultiLineString");
+        typeMap.put("MultiLineString", MultiLineString.class);
+
+        typeEncode.put(MultiPolygon.class, "MultiPolygon");
+        typeMap.put("MultiPolygon", MultiPolygon.class);
+
+        typeEncode.put(GeometryCollection.class, "GeometryCollection");
+        typeMap.put("GeometryCollection", GeometryCollection.class);
+
+        typeEncode.put(Date.class, "Date");
+        typeMap.put("Date", Date.class);
+    }
+
+    /**
+     * A replacement for File.toURI().toURL().
+     * <p>
+     * The handling of file.toURL() is broken; the handling of file.toURI().toURL() is known to be
+     * broken on a few platforms like mac. We have the urlToFile( URL ) method that is able to
+     * untangle both these problems and we use it in the geotools library.
+     * <p>
+     * However occasionally we need to pick up a file and hand it to a third party library like EMF;
+     * this method performs a couple of sanity checks which we can use to prepare a good URL
+     * reference to a file in these situtations.
+     * 
+     * @param file
+     * @return URL
+     */
+    public static URL fileToURL(File file) {
+        try {
+            URL url = file.toURI().toURL();
+            String string = url.toExternalForm();
+            if (string.contains("+")) {
+                // this represents an invalid URL created using either
+                // file.toURL(); or
+                // file.toURI().toURL() on a specific version of Java 5 on Mac
+                string = string.replace("+", "%2B");
+            }
+            if (string.contains(" ")) {
+                // this represents an invalid URL created using either
+                // file.toURL(); or
+                // file.toURI().toURL() on a specific version of Java 5 on Mac
+                string = string.replace(" ", "%20");
+            }
+            return new URL(string);
+        } catch (MalformedURLException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Takes a URL and converts it to a File. The attempts to deal with Windows UNC format specific
+     * problems, specifically files located on network shares and different drives.
+     * 
+     * If the URL.getAuthority() returns null or is empty, then only the url's path property is used
+     * to construct the file. Otherwise, the authority is prefixed before the path.
+     * 
+     * It is assumed that url.getProtocol returns "file".
+     * 
+     * Authority is the drive or network share the file is located on. Such as "C:", "E:",
+     * "\\fooServer"
+     * 
+     * @param url
+     *            a URL object that uses protocol "file"
+     * @return a File that corresponds to the URL's location
+     */
+    public static File urlToFile(URL url) {
+        if (!"file".equals(url.getProtocol())) {
+            return null; // not a File URL
+        }
+        String string = url.toExternalForm();
+        if (string.contains("+")) {
+            // this represents an invalid URL created using either
+            // file.toURL(); or
+            // file.toURI().toURL() on a specific version of Java 5 on Mac
+            string = string.replace("+", "%2B");
+        }
+        try {
+            string = URLDecoder.decode(string, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("Could not decode the URL to UTF-8 format", e);
+        }
+
+        String path3;
+
+        String simplePrefix = "file:/";
+        String standardPrefix = "file://";
+        String os = System.getProperty("os.name");
+
+        if (os.toUpperCase().contains("WINDOWS") && string.startsWith(standardPrefix)) {
+            // win32: host/share reference
+            path3 = string.substring(standardPrefix.length() - 2);
+        } else if (string.startsWith(standardPrefix)) {
+            path3 = string.substring(standardPrefix.length());
+        } else if (string.startsWith(simplePrefix)) {
+            path3 = string.substring(simplePrefix.length() - 1);
+        } else {
+            String auth = url.getAuthority();
+            String path2 = url.getPath().replace("%20", " ");
+            if (auth != null && !auth.equals("")) {
+                path3 = "//" + auth + path2;
+            } else {
+                path3 = path2;
+            }
+        }
+
+        return new File(path3);
+    }
+
+    /**
+     * Performs a deep copy of the provided object.
+     * 
+     * @param src Source object
+     * @return copy of source object
+     */
+    public static Object duplicate(Object src) {
+        // JD: this method really needs to be replaced with somethign better
+
+        if (src == null) {
+            return null;
+        }
+
+        //
+        // The following are things I expect
+        // Features will contain.
+        // 
+        if (src instanceof String || src instanceof Integer || src instanceof Double
+                || src instanceof Float || src instanceof Byte || src instanceof Boolean
+                || src instanceof Short || src instanceof Long || src instanceof Character
+                || src instanceof Number) {
+            return src;
+        }
+
+        if (src instanceof Date) {
+            return new Date(((Date) src).getTime());
+        }
+
+        if (src instanceof URL || src instanceof URI) {
+            return src; // immutable
+        }
+
+        if (src instanceof Object[]) {
+            Object[] array = (Object[]) src;
+            Object[] copy = new Object[array.length];
+
+            for (int i = 0; i < array.length; i++) {
+                copy[i] = duplicate(array[i]);
+            }
+
+            return copy;
+        }
+
+        if (src instanceof Geometry) {
+            Geometry geometry = (Geometry) src;
+
+            return geometry.clone();
+        }
+
+        if (src instanceof SimpleFeature) {
+            SimpleFeature feature = (SimpleFeature) src;
+            return SimpleFeatureBuilder.copy(feature);
+        }
+
+        // 
+        // We are now into diminishing returns
+        // I don't expect Features to contain these often
+        // (eveything is still nice and recursive)
+        //
+        Class<? extends Object> type = src.getClass();
+
+        if (type.isArray() && type.getComponentType().isPrimitive()) {
+            int length = Array.getLength(src);
+            Object copy = Array.newInstance(type.getComponentType(), length);
+            System.arraycopy(src, 0, copy, 0, length);
+
+            return copy;
+        }
+
+        if (type.isArray()) {
+            int length = Array.getLength(src);
+            Object copy = Array.newInstance(type.getComponentType(), length);
+
+            for (int i = 0; i < length; i++) {
+                Array.set(copy, i, duplicate(Array.get(src, i)));
+            }
+
+            return copy;
+        }
+
+        if (src instanceof List) {
+            List list = (List) src;
+            List<Object> copy = new ArrayList<Object>(list.size());
+
+            for (Iterator i = list.iterator(); i.hasNext();) {
+                copy.add(duplicate(i.next()));
+            }
+
+            return Collections.unmodifiableList(copy);
+        }
+
+        if (src instanceof Map) {
+            Map map = (Map) src;
+            Map copy = new HashMap(map.size());
+
+            for (Iterator i = map.entrySet().iterator(); i.hasNext();) {
+                Map.Entry entry = (Map.Entry) i.next();
+                copy.put(entry.getKey(), duplicate(entry.getValue()));
+            }
+
+            return Collections.unmodifiableMap(copy);
+        }
+
+        //
+        // I have lost hope and am returning the orgional reference
+        // Please extend this to support additional classes.
+        //
+        // And good luck getting Cloneable to work
+        throw new IllegalAttributeException(null,"Do not know how to deep copy " + type.getName());
+    }
+
+    /**
+     * Returns a non-null default value for the class that is passed in. This is a helper class an
+     * can't create a default class for any type but it does support:
+     * <ul>
+     * <li>String</li>
+     * <li>Object - will return empty string</li>
+     * <li>Number</li>
+     * <li>Character</li>
+     * <li>JTS Geometries</li>
+     * </ul>
+     * 
+     * 
+     * @param type
+     * @return
+     */
+    public static Object defaultValue(Class type) {
+        if (type == String.class || type == Object.class) {
+            return "";
+        }
+        if (type == Integer.class) {
+            return new Integer(0);
+        }
+        if (type == Double.class) {
+            return new Double(0);
+        }
+        if (type == Long.class) {
+            return new Long(0);
+        }
+        if (type == Short.class) {
+            return new Short((short) 0);
+        }
+        if (type == Float.class) {
+            return new Float(0.0f);
+        }
+        if (type == BigDecimal.class) {
+            return BigDecimal.valueOf(0);
+        }
+        if (type == BigInteger.class) {
+            return BigInteger.valueOf(0);
+        }
+        if (type == Character.class) {
+            return new Character(' ');
+        }
+        if (type == Boolean.class) {
+            return Boolean.FALSE;
+        }
+        if (type == Timestamp.class)
+            return new Timestamp(System.currentTimeMillis());
+        if (type == java.sql.Date.class)
+            return new java.sql.Date(System.currentTimeMillis());
+        if (type == java.sql.Time.class)
+            return new java.sql.Time(System.currentTimeMillis());
+        if (type == java.util.Date.class)
+            return new java.util.Date();
+
+        GeometryFactory fac = new GeometryFactory();
+        Coordinate coordinate = new Coordinate(0, 0);
+        Point point = fac.createPoint(coordinate);
+
+        if (type == Point.class) {
+            return point;
+        }
+        if (type == MultiPoint.class) {
+            return fac.createMultiPoint(new Point[] { point });
+        }
+        if (type == LineString.class) {
+            return fac.createLineString(new Coordinate[] { coordinate, coordinate, coordinate,
+                    coordinate });
+        }
+        LinearRing linearRing = fac.createLinearRing(new Coordinate[] { coordinate, coordinate,
+                coordinate, coordinate });
+        if (type == LinearRing.class) {
+            return linearRing;
+        }
+        if (type == MultiLineString.class) {
+            return fac.createMultiLineString(new LineString[] { linearRing });
+        }
+        Polygon polygon = fac.createPolygon(linearRing, new LinearRing[0]);
+        if (type == Polygon.class) {
+            return polygon;
+        }
+        if (type == MultiPolygon.class) {
+            return fac.createMultiPolygon(new Polygon[] { polygon });
+        }
+
+        throw new IllegalArgumentException(type + " is not supported by this method");
+    }
+    
+    /**
+     * Copies the provided fetaures into a List.
+     * 
+     * @param featureCollection
+     * @return List of features copied into memory
+     */
+    public static List<SimpleFeature> list(
+            FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection) {
+        final ArrayList<SimpleFeature> list = new ArrayList<SimpleFeature>();
+        try {
+            featureCollection.accepts(new FeatureVisitor() {
+                public void visit(Feature feature) {
+                    list.add((SimpleFeature) feature);
+                }
+            }, null);
+        } catch (IOException ignore) {
+        }
+        return list;
+    }
+
+    /**
+     * Create a derived FeatureType
+     * 
+     * <p>
+     * </p>
+     * 
+     * @param featureType
+     * @param properties
+     *            - if null, every property of the feature type in input will be used
+     * @param override
+     * 
+     * 
+     * @throws SchemaException
+     */
+    public static SimpleFeatureType createSubType(SimpleFeatureType featureType,
+            String[] properties, CoordinateReferenceSystem override) throws SchemaException {
+        URI namespaceURI = null;
+        if (featureType.getName().getNamespaceURI() != null) {
+            try {
+                namespaceURI = new URI(featureType.getName().getNamespaceURI());
+            } catch (URISyntaxException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        return createSubType(featureType, properties, override, featureType.getTypeName(),
+                namespaceURI);
+
+    }
+
+    public static SimpleFeatureType createSubType(SimpleFeatureType featureType,
+            String[] properties, CoordinateReferenceSystem override, String typeName, URI namespace)
+            throws SchemaException {
+
+        if ((properties == null) && (override == null)) {
+            return featureType;
+        }
+
+        if (properties == null) {
+            properties = new String[featureType.getAttributeCount()];
+            for (int i = 0; i < properties.length; i++) {
+                properties[i] = featureType.getDescriptor(i).getLocalName();
+            }
+        }
+
+        String namespaceURI = namespace != null ? namespace.toString() : null;
+        boolean same = featureType.getAttributeCount() == properties.length
+                && featureType.getTypeName().equals(typeName)
+                && Utilities.equals(featureType.getName().getNamespaceURI(), namespaceURI);
+
+        for (int i = 0; (i < featureType.getAttributeCount()) && same; i++) {
+            AttributeDescriptor type = featureType.getDescriptor(i);
+            same = type.getLocalName().equals(properties[i])
+                    && (((override != null) && type instanceof GeometryDescriptor) ? assertEquals(
+                            override, ((GeometryDescriptor) type).getCoordinateReferenceSystem())
+                            : true);
+        }
+
+        if (same) {
+            return featureType;
+        }
+
+        AttributeDescriptor[] types = new AttributeDescriptor[properties.length];
+
+        for (int i = 0; i < properties.length; i++) {
+            types[i] = featureType.getDescriptor(properties[i]);
+
+            if ((override != null) && types[i] instanceof GeometryDescriptor) {
+                AttributeTypeBuilder ab = new AttributeTypeBuilder();
+                ab.init(types[i]);
+                ab.setCRS(override);
+                types[i] = ab.buildDescriptor(types[i].getLocalName(), ab.buildGeometryType());
+            }
+        }
+
+        if (typeName == null)
+            typeName = featureType.getTypeName();
+        if (namespace == null && featureType.getName().getNamespaceURI() != null)
+            try {
+                namespace = new URI(featureType.getName().getNamespaceURI());
+            } catch (URISyntaxException e) {
+                throw new RuntimeException(e);
+            }
+
+        SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
+        tb.setName(typeName);
+        tb.setNamespaceURI(namespace);
+        tb.addAll(types);
+
+        return tb.buildFeatureType();
+    }
+
+    private static boolean assertEquals(Object o1, Object o2) {
+        return o1 == null && o2 == null ? true : (o1 != null ? o1.equals(o2) : false);
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @param featureType
+     *            DOCUMENT ME!
+     * @param properties
+     *            DOCUMENT ME!
+     * 
+     * @return DOCUMENT ME!
+     * 
+     * @throws SchemaException
+     *             DOCUMENT ME!
+     */
+    public static SimpleFeatureType createSubType(SimpleFeatureType featureType, String[] properties)
+            throws SchemaException {
+        if (properties == null) {
+            return featureType;
+        }
+
+        boolean same = featureType.getAttributeCount() == properties.length;
+
+        for (int i = 0; (i < featureType.getAttributeCount()) && same; i++) {
+            same = featureType.getDescriptor(i).getLocalName().equals(properties[i]);
+        }
+
+        if (same) {
+            return featureType;
+        }
+
+        SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
+        tb.setName(featureType.getName());
+
+        for (int i = 0; i < properties.length; i++) {
+            tb.add(featureType.getDescriptor(properties[i]));
+        }
+        return tb.buildFeatureType();
+    }
+
+    /**
+     * Factory method to produce Comparator based on provided Query SortBy information.
+     * <p>
+     * This method handles:
+     * <ul>
+     * <li>{@link SortBy#NATURAL_ORDER}: As sorting by FeatureID
+     * </ul>
+     * 
+     * @param sortBy
+     * @return Comparator suitable for use with Arrays.sort( SimpleFeature[], comparator )
+     */
+    public static Comparator<SimpleFeature> sortComparator(SortBy sortBy) {
+        if (sortBy == null) {
+            sortBy = SortBy.NATURAL_ORDER;
+        }
+        if (sortBy == SortBy.NATURAL_ORDER) {
+            return new Comparator<SimpleFeature>() {
+                public int compare(SimpleFeature f1, SimpleFeature f2) {
+                    return f1.getID().compareTo(f2.getID());
+                }
+            };
+        } else if (sortBy == SortBy.REVERSE_ORDER) {
+            return new Comparator<SimpleFeature>() {
+                public int compare(SimpleFeature f1, SimpleFeature f2) {
+                    int compare = f1.getID().compareTo(f2.getID());
+                    return -compare;
+                }
+            };
+        } else {
+            final PropertyName PROPERTY = sortBy.getPropertyName();
+            return new Comparator<SimpleFeature>() {
+                @SuppressWarnings("unchecked")
+                public int compare(SimpleFeature f1, SimpleFeature f2) {
+                    Object value1 = PROPERTY.evaluate(f1, Comparable.class);
+                    Object value2 = PROPERTY.evaluate(f2, Comparable.class);
+                    if (value1 == null || value2 == null) {
+                        return 0; // cannot perform comparison
+                    }
+                    if (value1 instanceof Comparable && value1.getClass().isInstance(value2)) {
+                        return ((Comparable<Object>) value1).compareTo(value2);
+                    } else {
+                        return 0; // cannot perform comparison
+                    }
+                }
+            };
+        }
+    }
+
+    /**
+     * Takes two {@link Query}objects and produce a new one by mixing the restrictions of both of
+     * them.
+     * 
+     * <p>
+     * The policy to mix the queries components is the following:
+     * 
+     * <ul>
+     * <li>
+     * typeName: type names MUST match (not checked if some or both queries equals to
+     * <code>Query.ALL</code>)</li>
+     * <li>
+     * handle: you must provide one since no sensible choice can be done between the handles of both
+     * queries</li>
+     * <li>
+     * maxFeatures: the lower of the two maxFeatures values will be used (most restrictive)</li>
+     * <li>
+     * attributeNames: the attributes of both queries will be joined in a single set of attributes.
+     * IMPORTANT: only <b><i>explicitly</i></b> requested attributes will be joint, so, if the
+     * method <code>retrieveAllProperties()</code> of some of the queries returns <code>true</code>
+     * it does not means that all the properties will be joined. You must create the query with the
+     * names of the properties you want to load.</li>
+     * <li>
+     * filter: the filtets of both queries are or'ed</li>
+     * <li>
+     * <b>any other query property is ignored</b> and no guarantees are made of their return values,
+     * so client code shall explicitly care of hints, startIndex, etc., if needed.</li>
+     * </ul>
+     * </p>
+     * 
+     * @param firstQuery
+     *            Query against this DataStore
+     * @param secondQuery
+     *            DOCUMENT ME!
+     * @param handle
+     *            DOCUMENT ME!
+     * 
+     * @return Query restricted to the limits of definitionQuery
+     * 
+     * @throws NullPointerException
+     *             if some of the queries is null
+     * @throws IllegalArgumentException
+     *             if the type names of both queries do not match
+     */
+    public static Query mixQueries(Query firstQuery, Query secondQuery, String handle) {
+        if ((firstQuery == null) && (secondQuery == null)) {
+            // throw new NullPointerException("Cannot combine two null queries");
+            return Query.ALL;
+        }
+        if (firstQuery == null || firstQuery.equals(Query.ALL)) {
+            return secondQuery;
+        } else if (secondQuery == null || secondQuery.equals(Query.ALL)) {
+            return firstQuery;
+        }
+        if ((firstQuery.getTypeName() != null) && (secondQuery.getTypeName() != null)) {
+            if (!firstQuery.getTypeName().equals(secondQuery.getTypeName())) {
+                String msg = "Type names do not match: " + firstQuery.getTypeName() + " != "
+                        + secondQuery.getTypeName();
+                throw new IllegalArgumentException(msg);
+            }
+        }
+
+        // mix versions, if possible
+        String version;
+        if (firstQuery.getVersion() != null) {
+            if (secondQuery.getVersion() != null
+                    && !secondQuery.getVersion().equals(firstQuery.getVersion()))
+                throw new IllegalArgumentException(
+                        "First and second query refer different versions");
+            version = firstQuery.getVersion();
+        } else {
+            version = secondQuery.getVersion();
+        }
+
+        // none of the queries equals Query.ALL, mix them
+        // use the more restrictive max features field
+        int maxFeatures = Math.min(firstQuery.getMaxFeatures(), secondQuery.getMaxFeatures());
+
+        // join attributes names
+        String[] propNames = joinAttributes(firstQuery.getPropertyNames(), secondQuery
+                .getPropertyNames());
+
+        // join filters
+        Filter filter = firstQuery.getFilter();
+        Filter filter2 = secondQuery.getFilter();
+
+        if ((filter == null) || filter.equals(Filter.INCLUDE)) {
+            filter = filter2;
+        } else if ((filter2 != null) && !filter2.equals(Filter.INCLUDE)) {
+            filter = ff.and(filter, filter2);
+        }
+        Integer start = 0;
+        if (firstQuery.getStartIndex() != null) {
+            start = firstQuery.getStartIndex();
+        }
+        if (secondQuery.getStartIndex() != null) {
+            start += secondQuery.getStartIndex();
+        }
+        // collect all hints
+        Hints hints = new Hints();
+        if(firstQuery.getHints() != null) {
+            hints.putAll(firstQuery.getHints());
+        } 
+        if(secondQuery.getHints() != null) {
+            hints.putAll(secondQuery.getHints());
+        }
+        // build the mixed query
+        String typeName = firstQuery.getTypeName() != null ? firstQuery.getTypeName() : secondQuery
+                .getTypeName();
+
+        Query mixed = new Query(typeName, filter, maxFeatures, propNames, handle);
+        mixed.setVersion(version);
+        mixed.setHints(hints);
+        if (start != 0) {
+            mixed.setStartIndex(start);
+        }
+        return mixed;
+    }
+
+    /**
+     * This method changes the query object so that all propertyName references are resolved to
+     * simple attribute names against the schema of the feature source.
+     * <p>
+     * For example, this method ensures that propertyName's such as "gml:name" are rewritten as
+     * simply "name".
+     *</p>
+     */
+    public static Query resolvePropertyNames(Query query, SimpleFeatureType schema) {
+        Filter resolved = resolvePropertyNames(query.getFilter(), schema);
+        if (resolved == query.getFilter()) {
+            return query;
+        }
+        Query newQuery = new Query(query);
+        newQuery.setFilter(resolved);
+        return newQuery;
+    }
+
+    /** Transform provided filter; resolving property names */
+    public static Filter resolvePropertyNames(Filter filter, SimpleFeatureType schema) {
+        if (filter == null || filter == Filter.INCLUDE || filter == Filter.EXCLUDE) {
+            return filter;
+        }
+        return (Filter) filter.accept(new PropertyNameResolvingVisitor(schema), null);
+    }
+
+    /**
+     * Creates a set of attribute names from the two input lists of names, maintaining the order of
+     * the first list and appending the non repeated names of the second.
+     * <p>
+     * In the case where both lists are <code>null</code>, <code>null</code> is returned.
+     * </p>
+     * 
+     * @param atts1
+     *            the first list of attribute names, who's order will be maintained
+     * @param atts2
+     *            the second list of attribute names, from wich the non repeated names will be
+     *            appended to the resulting list
+     * 
+     * @return Set of attribute names from <code>atts1</code> and <code>atts2</code>
+     */
+    private static String[] joinAttributes(String[] atts1, String[] atts2) {
+        String[] propNames = null;
+
+        if (atts1 == null && atts2 == null) {
+            return null;
+        }
+
+        List<String> atts = new LinkedList<String>();
+
+        if (atts1 != null) {
+            atts.addAll(Arrays.asList(atts1));
+        }
+
+        if (atts2 != null) {
+            for (int i = 0; i < atts2.length; i++) {
+                if (!atts.contains(atts2[i])) {
+                    atts.add(atts2[i]);
+                }
+            }
+        }
+
+        propNames = new String[atts.size()];
+        atts.toArray(propNames);
+
+        return propNames;
+    }
+
+    /**
+     * Manually calculates the bounds of a feature collection.
+     * 
+     * @param collection
+     * @return
+     */
+    public static Envelope bounds(
+            FeatureCollection<? extends FeatureType, ? extends Feature> collection) {
+        FeatureIterator<? extends Feature> i = collection.features();
+        try {
+            ReferencedEnvelope bounds = new ReferencedEnvelope(collection.getSchema()
+                    .getCoordinateReferenceSystem());
+            if (!i.hasNext()) {
+                bounds.setToNull();
+                return bounds;
+            }
+
+            bounds.init(((SimpleFeature) i.next()).getBounds());
+            return bounds;
+        } finally {
+            i.close();
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DefaultFeatureResults.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DefaultFeatureResults.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DefaultFeatureResults.java	(revision 28000)
@@ -0,0 +1,343 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.data.crs.ReprojectFeatureReader;
+import org.geotools.data.simple.SimpleFeatureSource;
+import org.geotools.data.simple.SimpleFeatureStore;
+import org.geotools.data.store.DataFeatureCollection;
+import org.geotools.feature.IllegalAttributeException;
+import org.geotools.feature.SchemaException;
+import org.geotools.feature.type.GeometryDescriptorImpl;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.referencing.CRS;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+
+
+/**
+ * Generic "results" of a query, class.
+ * <p>
+ * Please optimize this class when use with your own content.
+ * For example a "ResultSet" make a great cache for a JDBCDataStore,
+ * a temporary copy of an original file may work for shapefile etc. 
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/DefaultFeatureResults.java $
+ */
+public class DefaultFeatureResults extends DataFeatureCollection {
+    /** Shared package logger */
+    private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geotools.data");
+
+    /** Query used to define this subset of features from the feature source */
+    protected Query query;
+    
+    /**
+     * Feature source used to aquire features, note we are only a
+     * "view" of this FeatureSource, its contents, transaction and events
+     * need to be forwarded through this collection api to simplier code
+     * such as renderers.
+     */
+    protected SimpleFeatureSource featureSource;
+
+    protected MathTransform transform;
+    
+    /**
+     * FeatureResults query against featureSource.
+     * <p>
+     * Please note that is object will not be valid
+     * after the transaction has closed.
+     * </p>
+     * <p>
+     * Really? I think it would be, it would just reflect the
+     * same query against the SimpleFeatureSource using AUTO_COMMIT.
+     * </p>
+     * 
+     * @param source
+     * @param query
+     */
+    public DefaultFeatureResults(SimpleFeatureSource source, Query query)
+            throws IOException {
+    	super(null,getSchemaInternal(source,query));
+    	this.featureSource = source;        
+        
+        SimpleFeatureType originalType = source.getSchema();
+        
+        String typeName = originalType.getTypeName();        
+        if( typeName.equals( query.getTypeName() ) ){
+            this.query = query;
+        }
+        else {
+            // jg: this should be an error, we are deliberatly gobbling a mistake
+            // option 1: remove Query.getTypeName
+            // option 2: throw a warning
+            // option 3: restore exception code
+            this.query = new DefaultQuery(query);
+            ((DefaultQuery) this.query).setTypeName(typeName);
+            //((DefaultQuery) this.query).setCoordinateSystem(query.getCoordinateSystem());
+            //((DefaultQuery) this.query).setCoordinateSystemReproject(query.getCoordinateSystemReproject());
+        }
+       
+        if( originalType.getGeometryDescriptor() == null ){
+            return; // no transform needed
+        }
+        
+        CoordinateReferenceSystem cs = null;        
+        if (query.getCoordinateSystemReproject() != null) {
+            cs = query.getCoordinateSystemReproject();
+        } else if (query.getCoordinateSystem() != null) {
+            cs = query.getCoordinateSystem();
+        }     
+        CoordinateReferenceSystem originalCRS = originalType.getGeometryDescriptor().getCoordinateReferenceSystem();
+        if( query.getCoordinateSystem() != null ){
+            originalCRS = query.getCoordinateSystem();
+        }
+        if( cs != null && cs != originalCRS ){
+            try {
+                transform = CRS.findMathTransform( originalCRS, cs, true);
+            } catch (FactoryException noTransform) {
+                throw (IOException) new IOException("Could not reproject data to "+cs).initCause( noTransform );
+            }
+        }
+    }
+
+    static SimpleFeatureType getSchemaInternal(
+            SimpleFeatureSource featureSource, Query query) {
+    	SimpleFeatureType originalType = featureSource.getSchema();
+    	SimpleFeatureType schema = null;
+    	
+    	 CoordinateReferenceSystem cs = null;        
+         if (query.getCoordinateSystemReproject() != null) {
+             cs = query.getCoordinateSystemReproject();
+         } else if (query.getCoordinateSystem() != null) {
+             cs = query.getCoordinateSystem();
+         }
+         try {
+             if( cs == null ){
+                 if (query.retrieveAllProperties()) { // we can use the originalType as is                
+                     schema = featureSource.getSchema();
+                 } else { 
+                     schema = DataUtilities.createSubType(featureSource.getSchema(), query.getPropertyNames());                    
+                 } 
+             }
+             else {
+                 // we need to change the projection of the original type
+                 schema = DataUtilities.createSubType(originalType, query.getPropertyNames(), cs, query.getTypeName(), null);
+             }
+         }
+         catch (SchemaException e) {
+             // we were unable to create the schema requested!
+             //throw new DataSourceException("Could not create schema", e);
+             LOGGER.log( Level.WARNING, "Could not change projection to "+cs, e );
+             //schema = null; // client will notice something is amiss when getSchema() return null
+         }
+         
+         return schema;
+    }
+    /**
+     * FeatureSchema for provided query.
+     *
+     * <p>
+     * If query.retrieveAllProperties() is <code>true</code> the FeatureSource
+     * getSchema() will be returned.
+     * </p>
+     *
+     * <p>
+     * If query.getPropertyNames() is used to limit the result of the Query a
+     * sub type will be returned based on FeatureSource.getSchema().
+     * </p>
+     *
+     * @return DOCUMENT ME!
+     *
+     * @throws IOException DOCUMENT ME!
+     * @throws DataSourceException DOCUMENT ME!
+     */
+    public SimpleFeatureType getSchema() {
+        return super.getSchema();        
+    }
+
+    /**
+     * Returns transaction from SimpleFeatureSource (if it is a FeatureStore), or
+     * Transaction.AUTO_COMMIT if it is not.
+     *
+     * @return Transacstion this FeatureResults opperates against
+     */
+    protected Transaction getTransaction() {
+        if (featureSource instanceof FeatureStore) {
+            SimpleFeatureStore featureStore;
+            featureStore = (SimpleFeatureStore) featureSource;
+
+            return featureStore.getTransaction();
+        } else {
+            return Transaction.AUTO_COMMIT;
+        }
+    }
+
+    /**
+     * Retrieve a  FeatureReader<SimpleFeatureType, SimpleFeature> for this Query
+     *
+     * @return  FeatureReader<SimpleFeatureType, SimpleFeature> for this Query
+     *
+     * @throws IOException If results could not be obtained
+     */
+    public  FeatureReader<SimpleFeatureType, SimpleFeature> reader() throws IOException {
+        FeatureReader<SimpleFeatureType, SimpleFeature> reader;
+        reader = ((DataStore) featureSource.getDataStore()).getFeatureReader(query,
+                getTransaction());
+        
+        int maxFeatures = query.getMaxFeatures();
+        if (maxFeatures != Integer.MAX_VALUE) {
+            reader = new MaxFeatureReader<SimpleFeatureType, SimpleFeature>(reader, maxFeatures);
+        }        
+        if( transform != null ){
+            reader = new ReprojectFeatureReader( reader, getSchema(), transform );
+        }
+        return reader;
+    }   
+
+    
+    /**
+     * Retrieve a  FeatureReader<SimpleFeatureType, SimpleFeature> for the geometry attributes only, designed for bounds computation
+     */
+    protected  FeatureReader<SimpleFeatureType, SimpleFeature> boundsReader() throws IOException {
+        List attributes = new ArrayList();
+        SimpleFeatureType schema = featureSource.getSchema();
+        for (int i = 0; i < schema.getAttributeCount(); i++) {
+            AttributeDescriptor at = schema.getDescriptor(i);
+            if(at instanceof GeometryDescriptorImpl)
+                attributes.add(at.getLocalName());
+        }
+        
+        DefaultQuery q = new DefaultQuery(query);
+        q.setPropertyNames(attributes);
+         FeatureReader<SimpleFeatureType, SimpleFeature> reader = ((DataStore) featureSource
+                .getDataStore()).getFeatureReader(q, getTransaction());
+        int maxFeatures = query.getMaxFeatures();
+
+        if (maxFeatures == Integer.MAX_VALUE) {
+            return reader;
+        } else {
+            return new MaxFeatureReader<SimpleFeatureType, SimpleFeature>(reader, maxFeatures);
+        }
+    }
+
+    /**
+     * Returns the bounding box of this FeatureResults
+     *
+     * <p>
+     * This implementation will generate the correct results from reader() if
+     * the provided SimpleFeatureSource does not provide an optimized result via
+     * FeatureSource.getBounds( Query ).
+     * </p>
+     * If the feature has no geometry, then an empty envelope is returned.
+     *
+     *
+     * @throws DataSourceException See IOException
+     *
+     * @see org.geotools.data.FeatureResults#getBounds()
+     */
+    public ReferencedEnvelope getBounds() {
+        ReferencedEnvelope bounds;
+
+        try {
+            bounds = featureSource.getBounds(query);
+        } catch (IOException e1) {
+            bounds = new ReferencedEnvelope((CoordinateReferenceSystem)null);
+        }
+
+        if (bounds == null) {
+        	try {
+	            SimpleFeature feature;
+	            bounds = new ReferencedEnvelope();
+	
+	             FeatureReader<SimpleFeatureType, SimpleFeature> reader = boundsReader();
+	             try {
+	            	 while (reader.hasNext()) {
+	            		 feature = reader.next();
+	            		 bounds.include(feature.getBounds());
+	            	 }
+	             } finally {
+	            	 reader.close();
+	             }
+        	} catch (IllegalAttributeException e) {
+	            //throw new DataSourceException("Could not read feature ", e);
+	            bounds = new ReferencedEnvelope();
+	        } catch (IOException e) {
+	            bounds = new ReferencedEnvelope();
+	        }
+        }
+        
+        return bounds;
+    }
+
+    /**
+     * Number of Features in this query.
+     *
+     * <p>
+     * This implementation will generate the correct results from reader() if
+     * the provided SimpleFeatureSource does not provide an optimized result via
+     * FeatureSource.getCount( Query ).
+     * </p>
+     *
+     *
+     * @throws IOException If feature could not be read
+     * @throws DataSourceException See IOException
+     *
+     * @see org.geotools.data.FeatureResults#getCount()
+     */
+    public int getCount() throws IOException {
+        int count;
+        count = featureSource.getCount(query);
+
+        if (count != -1) {
+            // optimization worked, return maxFeatures if count is
+            // greater.
+            int maxFeatures = query.getMaxFeatures();
+            return (count < maxFeatures) ? count : maxFeatures;
+        }
+
+        // Okay lets count the FeatureReader
+        try {
+            count = 0;
+
+            FeatureReader<SimpleFeatureType, SimpleFeature> reader = reader();
+            try {
+            	for (; reader.hasNext(); count++) {
+            		reader.next();
+            	}
+            } finally {
+            	reader.close();
+            }
+
+            return count;
+        } catch (IllegalAttributeException e) {
+            throw new DataSourceException("Could not read feature ", e);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DefaultQuery.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DefaultQuery.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DefaultQuery.java	(revision 28000)
@@ -0,0 +1,145 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opengis.filter.Filter;
+import org.opengis.filter.expression.PropertyName;
+
+
+/**
+ * A Query class allowing content to be requested from a Datastore or FeatureSource.
+ * @deprecated This class is now synonymous with the {@linkplain Query} class.
+ * @see Query
+ * @author Chris Holmes
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/DefaultQuery.java $
+ */
+public class DefaultQuery extends Query {
+    
+    /**
+     * No argument constructor.
+     */
+    public DefaultQuery() {
+        // no arg
+    }
+
+    /**
+     * Query with typeName.
+     * <p>
+     * </p>
+     * @param typeName the name of the featureType to retrieve
+     */
+    public DefaultQuery( String typeName ){
+        this( typeName, Filter.INCLUDE );
+    }
+
+    /**
+     * Constructor with typeName and filter.  Note that current datasource
+     * implementations only have one type per datasource, so the typeName
+     * field will likely be ignored.
+     *
+     * @param typeName the name of the featureType to retrieve.
+     * @param filter the OGC filter to constrain the request.
+     */
+    public DefaultQuery(String typeName, Filter filter) {
+        this( typeName, filter, Query.ALL_NAMES );        
+    }
+    
+    /**
+     * Constructor that sets the filter and properties
+     * @param typeName 
+     *
+     * @param filter the OGC filter to constrain the request.
+     * @param properties an array of the properties to fetch.
+     */
+    public DefaultQuery(String typeName, Filter filter, String[] properties) {
+        this( typeName, null, filter, Query.DEFAULT_MAX, properties, null );        
+    }    
+    /**
+     * Constructor that sets all fields.
+     *
+     * @param typeName the name of the featureType to retrieve.
+     * @param filter the OGC filter to constrain the request.
+     * @param maxFeatures the maximum number of features to be returned.
+     * @param propNames an array of the properties to fetch.
+     * @param handle the name to associate with the query.
+     */
+    public DefaultQuery(String typeName, Filter filter, int maxFeatures,
+        String[] propNames, String handle) {
+        this(typeName, null, filter, maxFeatures, propNames, handle );
+    }
+    
+    /**
+     * Constructor that sets all fields.
+     *
+     * @param typeName the name of the featureType to retrieve.
+     * @param namespace Namespace for provided typeName, or null if unspecified
+     * @param filter the OGC filter to constrain the request.
+     * @param maxFeatures the maximum number of features to be returned.
+     * @param propNames an array of the properties to fetch.
+     * @param handle the name to associate with the query.
+     */
+    public DefaultQuery(String typeName, URI namespace, Filter filter, int maxFeatures,
+        String[] propNames, String handle) {
+        this.typeName = typeName;
+        this.filter = filter;
+        this.namespace = namespace;
+        this.maxFeatures = maxFeatures;
+        this.handle = handle;
+        setPropertyNames(propNames);
+    }
+    
+    /**
+     * Constructor that sets all fields.
+     *
+     * @param typeName the name of the featureType to retrieve.
+     * @param namespace Namespace for provided typeName, or null if unspecified
+     * @param filter the OGC filter to constrain the request.
+     * @param maxFeatures the maximum number of features to be returned.
+     * @param propNames a list of the properties to fetch.
+     * @param handle the name to associate with the query.
+     */
+    public DefaultQuery(String typeName, URI namespace, Filter filter, int maxFeatures,
+        List<PropertyName> propNames, String handle) {
+        this.typeName = typeName;
+        this.filter = filter;
+        this.namespace = namespace;
+        this.properties = propNames==null? null : new ArrayList<PropertyName>(propNames);
+        this.maxFeatures = maxFeatures;
+        this.handle = handle;
+    }
+    
+    /**
+     * Copy contructor, clones the state of a generic Query into a DefaultQuery
+     * @param query
+     */
+    public DefaultQuery(Query query) {
+      this(query.getTypeName(), query.getNamespace(), query.getFilter(), query.getMaxFeatures(),
+          query.getProperties(), query.getHandle());
+      this.sortBy = query.getSortBy();
+      this.coordinateSystem = query.getCoordinateSystem();
+      this.coordinateSystemReproject = query.getCoordinateSystemReproject();
+      this.version = query.getVersion();
+      this.hints = query.getHints();
+      this.startIndex = query.getStartIndex();
+    }
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DefaultServiceInfo.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DefaultServiceInfo.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DefaultServiceInfo.java	(revision 28000)
@@ -0,0 +1,85 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.Set;
+
+/**
+ * Implementation of DefaultServiceInfo as a java bean.
+ * 
+ * @author Jody Garnett (Refractions Research)
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/DefaultServiceInfo.java $
+ */
+public class DefaultServiceInfo implements ServiceInfo, Serializable {    
+    private static final long serialVersionUID = 7975308744804800859L;
+    
+    protected String description;
+    protected Set<String> keywords;
+    protected URI publisher;
+    protected URI schema;
+    protected String title;
+    private URI source;
+    
+    public DefaultServiceInfo(){                
+    }
+    /**
+     * @param description the description to set
+     */
+    public void setDescription( String description ) {
+        this.description = description;
+    }
+    /**
+     * @param schema the schema to set
+     */
+    public void setSchema( URI schema ) {
+        this.schema = schema;
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer buf = new StringBuffer();
+        buf.append("ServiceInfo ");
+        if( source != null ){
+            buf.append( source );            
+        }        
+        if( this.title != null ){
+            buf.append( "\n title=");
+            buf.append( title );
+        }
+        if( this.publisher != null ){
+            buf.append( "\n publisher=");
+            buf.append( publisher );
+        }
+        if( this.publisher != null ){
+            buf.append( "\n schema=");
+            buf.append( schema );
+        }
+        if( keywords != null ){
+            buf.append( "\n keywords=");
+            buf.append( keywords );            
+        }
+        if( description != null ){
+            buf.append( "\n description=");
+            buf.append( description );
+        }
+        return buf.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DelegatingFeatureReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DelegatingFeatureReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DelegatingFeatureReader.java	(revision 28000)
@@ -0,0 +1,34 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+
+/**
+ * Interface for wrapping feature readers which delegate to another feature reader.
+ * 
+ * @author Justin Deoliveira, OpenGEO
+ * @since 2.5
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/DelegatingFeatureReader.java $
+ */
+public interface DelegatingFeatureReader<T extends FeatureType,F extends Feature> extends FeatureReader<T, F> {
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DelegatingFeatureWriter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DelegatingFeatureWriter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DelegatingFeatureWriter.java	(revision 28000)
@@ -0,0 +1,34 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+
+/**
+ * Interface for wrapping feature writers which delegate to another feature writer.
+ * 
+ * @author Justin Deoliveira, OpenGEO
+ * @since 2.5
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/DelegatingFeatureWriter.java $
+ */
+public interface DelegatingFeatureWriter<T extends FeatureType,F extends Feature> extends FeatureWriter<T, F> {
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/Diff.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/Diff.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/Diff.java	(revision 28000)
@@ -0,0 +1,142 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.geometry.BoundingBox;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.index.SpatialIndex;
+import com.vividsolutions.jts.index.quadtree.Quadtree;
+
+public class Diff{
+	private final Map modifiedFeatures;
+	private final Map addedFeatures;
+	
+	/**
+	 * Unmodifiable view of modified features.
+     * It is imperative that the user manually synchronize on the
+     * map when iterating over any of its collection views:
+     * <pre>
+     *  Set s = diff.modified2.keySet();  // Needn't be in synchronized block
+     *      ...
+     *  synchronized(diff) {  // Synchronizing on diff, not diff.modified2 or s!
+     *      Iterator i = s.iterator(); // Must be in synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * </pre>
+     * Failure to follow this advice may result in non-deterministic behavior.
+     *
+     * <p>The returned map will be serializable if the specified map is
+     * serializable.
+	 */
+	public final Map modified2;
+	/**
+	 * Unmodifiable view of added features.
+     * It is imperative that the user manually synchronize on the
+     * map when iterating over any of its collection views:
+     * <pre>
+     *  Set s = diff.added.keySet();  // Needn't be in synchronized block
+     *      ...
+     *  synchronized(diff) {  // Synchronizing on m, not diff.added or s!
+     *      Iterator i = s.iterator(); // Must be in synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * </pre>
+     * Failure to follow this advice may result in non-deterministic behavior.
+     *
+     * <p>The returned map will be serializable if the specified map is
+     * serializable.
+	 */
+	public final Map added;
+	
+	public int nextFID=0;
+	private SpatialIndex spatialIndex;
+	Object mutex;
+	
+	public Diff( ){
+		modifiedFeatures=new ConcurrentHashMap();
+		addedFeatures=new ConcurrentHashMap();
+		modified2=Collections.unmodifiableMap(modifiedFeatures);
+		added=Collections.unmodifiableMap(addedFeatures);
+		spatialIndex=new Quadtree();
+		mutex=this;
+	}
+		
+	public void modify(String fid, SimpleFeature f) {
+		synchronized (mutex) {
+			SimpleFeature old;
+            if( addedFeatures.containsKey(fid) ){
+            	old=(SimpleFeature) addedFeatures.get(fid);
+                addedFeatures.put(fid, f);
+            }else{
+            	old=(SimpleFeature) modifiedFeatures.get(fid);
+                modifiedFeatures.put(fid, f);
+            }
+            if(old != null) {
+            	spatialIndex.remove(ReferencedEnvelope.reference(old.getBounds()), old);
+            }
+            addToSpatialIndex(f);
+		}
+	}
+	
+	public void add(String fid, SimpleFeature f) {
+		synchronized (mutex) {
+			addedFeatures.put(fid, f);
+			addToSpatialIndex(f);
+		}
+	}
+	
+	protected void addToSpatialIndex(SimpleFeature f) {
+		if (f.getDefaultGeometry() != null) {
+			BoundingBox bounds = f.getBounds();
+			if( !bounds.isEmpty() )
+				spatialIndex.insert(ReferencedEnvelope.reference(bounds), f);
+		}
+	}
+	
+	public void remove(String fid) {
+		synchronized (mutex) {
+			SimpleFeature old = null;
+			
+			if( addedFeatures.containsKey(fid) ){
+				old = (SimpleFeature) addedFeatures.get(fid);
+				addedFeatures.remove(fid);
+			} else {
+				old = (SimpleFeature) modifiedFeatures.get(fid);
+				modifiedFeatures.put(fid, TransactionStateDiff.NULL);
+			}
+			if( old != null ) {
+				spatialIndex.remove(ReferencedEnvelope.reference(old.getBounds()), old);
+			}			
+		}
+	}
+	
+	public List queryIndex(Envelope env) {
+		synchronized (mutex) {
+			return spatialIndex.query(env);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DiffFeatureReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DiffFeatureReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DiffFeatureReader.java	(revision 28000)
@@ -0,0 +1,207 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.geotools.feature.IllegalAttributeException;
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.filter.Id;
+import org.opengis.filter.identity.Identifier;
+
+/**
+ * A  FeatureReader that considers differences.
+ * <p>
+ * Used to implement In-Process Transaction support. This implementation will need to peek ahead in
+ * order to check for deletetions.
+ * </p>
+ * 
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/DiffFeatureReader.java $
+ */
+public class DiffFeatureReader<T extends FeatureType, F extends Feature> implements  FeatureReader<T, F> {
+    FeatureReader<T, F> reader;
+    Diff diff;
+
+    /** Next value as peeked by hasNext() */
+    F next = null;
+    private Filter filter;
+    private Set encounteredFids;
+
+	private Iterator<F> addedIterator;
+	private Iterator<F> modifiedIterator;
+	private Iterator<Identifier> fids;
+	
+	private boolean fidFilter = false;
+	
+    /**
+     * This constructor grabs a "copy" of the current diff.
+     * <p>
+     * This reader is not "live" to changes over the course of the Transaction. (Iterators are not
+     * always stable of the course of modifications)
+     * </p>
+     * 
+     * @param reader
+     * @param diff2 Differences of Feature by FID
+     */
+    public DiffFeatureReader(FeatureReader<T, F> reader, Diff diff2, Filter filter ) {
+        this.reader = reader;
+        this.diff = diff2;
+        this.filter = filter;
+        encounteredFids=new HashSet();
+
+        if( filter instanceof Id){
+        	fidFilter=true;
+        }
+        
+        synchronized (diff) {
+        	addedIterator=diff.added.values().iterator();
+        	modifiedIterator=diff.modified2.values().iterator();
+        }
+    }
+
+    /**
+     * @see org.geotools.data.FeatureReader#getFeatureType()
+     */
+    public T getFeatureType() {
+        return reader.getFeatureType();
+    }
+
+    /**
+     * @see org.geotools.data.FeatureReader#next()
+     */
+    public F next() throws IOException, IllegalAttributeException, NoSuchElementException {
+        if (hasNext()) {
+        	F live = next;
+        	next = null;
+
+            return live;
+        }
+
+        throw new NoSuchElementException("No more Feature exists");
+    }
+
+    /**
+     * @see org.geotools.data.FeatureReader#hasNext()
+     */
+    public boolean hasNext() throws IOException {
+        if (next != null) {
+            // We found it already
+            return true;
+        }
+        F peek;
+
+        if( filter==Filter.EXCLUDE)
+            return false;
+        
+        while( (reader != null) && reader.hasNext() ) {
+
+            try {
+                peek = reader.next();
+            } catch (NoSuchElementException e) {
+                throw new DataSourceException("Could not aquire the next Feature", e);
+            } catch (IllegalAttributeException e) {
+                throw new DataSourceException("Could not aquire the next Feature", e);
+            }
+
+            String fid = peek.getIdentifier().getID();
+            encounteredFids.add(fid);
+
+            if (diff.modified2.containsKey(fid)) {
+                F changed = (F) diff.modified2.get(fid);
+                if (changed == TransactionStateDiff.NULL || !filter.evaluate(changed) ) {
+                    continue;
+                } else {
+                    next = changed;
+                    return true;
+                }
+            } else {
+
+                next = peek; // found feature
+                return true;
+            }
+        }
+
+        queryDiff();
+        return next != null;
+    }
+
+    /**
+     * @see org.geotools.data.FeatureReader#close()
+     */
+    public void close() throws IOException {
+        if (reader != null) {
+            reader.close();
+            reader = null;
+        }
+
+        if (diff != null) {
+            diff = null;
+            addedIterator=null;
+        }
+    }
+    
+    protected void queryDiff() {
+        if( fidFilter ){
+            queryFidFilter();
+        } else {
+        	queryAdded();
+        	queryModified();
+         }
+    }
+    
+	protected void queryAdded() {
+		while( addedIterator.hasNext() && next == null ){
+			next = addedIterator.next();
+			if( encounteredFids.contains(next.getIdentifier().getID()) || !filter.evaluate(next)){
+				next = null;
+			}
+		}
+	}
+	
+	protected void queryModified() {
+		while( modifiedIterator.hasNext() && next == null ){
+			next = modifiedIterator.next();
+			if( next==TransactionStateDiff.NULL || encounteredFids.contains(next.getIdentifier().getID()) || !filter.evaluate(next) ){
+				next = null;
+			}
+		}
+	}
+	
+	protected void queryFidFilter() {
+		Id fidFilter = (Id) filter;
+		if (fids == null) {
+		    fids = fidFilter.getIdentifiers().iterator();
+		}
+        while( fids.hasNext() && next == null ) {
+		    String fid = fids.next().toString();
+		    if( !encounteredFids.contains(fid) ){
+    			next = (F) diff.modified2.get(fid);
+    		    if( next==null ){
+    		    	next = (F) diff.added.get(fid);
+    		    }
+		    }
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DiffFeatureWriter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DiffFeatureWriter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/DiffFeatureWriter.java	(revision 28000)
@@ -0,0 +1,235 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.geotools.feature.IllegalAttributeException;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+
+/**
+ * A FeatureWriter that captures modifications against a FeatureReader.
+ * 
+ * <p>
+ * You will eventually need to write out the differences, later.
+ * </p>
+ * 
+ * <p>
+ * The api has been implemented in terms of  FeatureReader<SimpleFeatureType, SimpleFeature> to make explicit that
+ * no Features are writen out by this Class.
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research
+ *
+ * @see TransactionStateDiff
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/DiffFeatureWriter.java $
+ */
+public abstract class DiffFeatureWriter implements FeatureWriter<SimpleFeatureType, SimpleFeature> {
+    protected  FeatureReader<SimpleFeatureType, SimpleFeature> reader;
+    protected Diff diff;
+    SimpleFeature next; // next value aquired by hasNext()
+    SimpleFeature live; // live value supplied by FeatureReader
+    SimpleFeature current; // duplicate provided to user
+
+    /**
+     * DiffFeatureWriter construction.
+     *
+     * @param reader
+     * @param diff
+     * @param filter
+     */
+    public DiffFeatureWriter(FeatureReader <SimpleFeatureType, SimpleFeature> reader, Diff diff, Filter filter) {
+        this.reader = new DiffFeatureReader<SimpleFeatureType, SimpleFeature>(reader, diff, filter);
+        this.diff = diff;
+    }
+
+    /**
+     * Supplys FeatureTypeFrom reader
+     *
+     * @see org.geotools.data.FeatureWriter#getFeatureType()
+     */
+    public SimpleFeatureType getFeatureType() {
+        return reader.getFeatureType();
+    }
+
+    /**
+     * Next Feature from reader or new content.
+     *
+     * @see org.geotools.data.FeatureWriter#next()
+     */
+    public SimpleFeature next() throws IOException {
+        SimpleFeatureType type = getFeatureType();
+        if (hasNext()) {
+            // hasNext() will take care recording
+            // any modifications to current
+            try {
+                live = next; // update live value
+                next = null; // hasNext will need to search again            
+                current = SimpleFeatureBuilder.copy(live);
+
+                return current;
+            } catch (IllegalAttributeException e) {
+                throw (IOException) new IOException("Could not modify content").initCause( e );
+            }
+        } else {
+            // Create new content
+            // created with an empty ID
+            // (The real writer will supply a FID later) 
+            try {
+                live = null;
+                next = null;
+                current = SimpleFeatureBuilder.build(type,new Object[type.getAttributeCount()],
+                        "new"+diff.nextFID);
+                diff.nextFID++;
+                return current;
+            } catch (IllegalAttributeException e) {
+                throw new IOException("Could not create new content");
+            }
+        }
+    }
+
+    /**
+     * @see org.geotools.data.FeatureWriter#remove()
+     */
+    public void remove() throws IOException {
+        if (live != null) {
+            // mark live as removed
+        	diff.remove(live.getID());
+        	fireNotification(FeatureEvent.FEATURES_REMOVED, ReferencedEnvelope.reference(live.getBounds()));
+        	live = null;
+        	current = null;
+        } else if (current != null) {
+            // cancel additional content
+            current = null;
+        }
+    }
+
+    /**
+     * Writes out the current feature.
+     *
+     * @throws IOException
+     *
+     * @see org.geotools.data.FeatureWriter#write()
+     */ 
+    public void write() throws IOException 
+	{
+    	//DJB: I modified this so it doesnt throw an error if you
+    	//     do an update and you didnt actually change anything.
+    	//     (We do the work)
+        if ((live != null) ) 
+        {
+            // We have a modification to record!
+            diff.modify(live.getID(), current);
+
+
+
+            ReferencedEnvelope bounds = new ReferencedEnvelope((CoordinateReferenceSystem)null);
+            bounds.include(live.getBounds());
+            bounds.include(current.getBounds());
+            fireNotification(FeatureEvent.FEATURES_CHANGED, bounds);
+            live = null;
+            current = null;
+        } else if ((live == null) && (current != null)) {
+            // We have new content to record
+            //
+            diff.add(current.getID(), current);
+            fireNotification(FeatureEvent.FEATURES_ADDED, ReferencedEnvelope.reference(current.getBounds()));
+            current = null;
+        } else {
+            throw new IOException("No feature available to write");
+        }
+    }
+
+    /**
+	 * Query for more content.
+	 *
+	 * @see org.geotools.data.FeatureWriter#hasNext()
+	 */
+	public boolean hasNext() throws IOException {
+	    if (next != null) {
+	        // we found next already
+	        return true;
+	    }
+	
+	    live = null;
+	    current = null;
+	
+	    if (reader.hasNext()) {
+	        try {
+	            next = reader.next();
+	        } catch (NoSuchElementException e) {
+	            throw new DataSourceException("No more content", e);
+	        } catch (IllegalAttributeException e) {
+	            throw new DataSourceException("No more content", e);
+	        }
+	
+	        return true;
+	    }
+	
+	    return false;
+	}
+
+    /**
+     * Clean up resources associated with this writer.
+     * 
+     * <p>
+     * Diff is not clear()ed as it is assumed that it belongs to a
+     * Transaction.State object and may yet be written out.
+     * </p>
+     *
+     * @see org.geotools.data.FeatureWriter#close()
+     */
+    public void close() throws IOException {
+        if (reader != null) {
+            reader.close();
+            reader = null;
+        }
+
+        current = null;
+        live = null;
+        next = null;
+        diff = null;
+    }
+
+    /**
+     * Subclass must provide the notification.
+     * 
+     * <p>
+     * Notification requirements for modifications against a Transaction should
+     * only be issued to SimpleFeatureSource instances that opperate against the
+     * same typeName and Transaction.
+     * </p>
+     * 
+     * <p>
+     * Other SimpleFeatureSource instances with the same typeName will be notified
+     * when the Transaction is committed.
+     * </p>
+     *
+     * @param eventType One of FeatureType.FEATURES_ADDED, FeatureType.CHANGED,
+     *        FeatureType.FEATURES_REMOVED
+     * @param bounds
+     */
+    protected abstract void fireNotification(int eventType, ReferencedEnvelope bounds);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/EmptyFeatureReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/EmptyFeatureReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/EmptyFeatureReader.java	(revision 28000)
@@ -0,0 +1,83 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.util.NoSuchElementException;
+
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+
+
+/**
+ * Represents an Empty, Typed, FeatureReader.
+ *
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/EmptyFeatureReader.java $
+ */
+public class EmptyFeatureReader<T extends FeatureType, F extends Feature> implements  FeatureReader<T, F> {
+	T featureType;
+
+    /**
+     * An Empty  FeatureReader<SimpleFeatureType, SimpleFeature> of the provided <code>featureType</code>.
+     *
+     * @param featureType
+     */
+    public EmptyFeatureReader(T featureType) {
+        this.featureType = featureType;
+    }
+
+    /**
+     * @see org.geotools.data.FeatureReader#getFeatureType()
+     */
+    public T getFeatureType() {
+        return featureType;
+    }
+
+    /**
+     * Throws NoSuchElementException as this is an Empty FeatureReader.
+     *
+     * @return Does not return
+     *
+     * @throws NoSuchElementException
+     *
+     * @see org.geotools.data.FeatureReader#next()
+     */
+    public F next() throws NoSuchElementException {
+        throw new NoSuchElementException("FeatureReader is empty");
+    }
+
+    /**
+     * There is no next Feature.
+     *
+     * @return <code>false</code>
+     *
+     * @see org.geotools.data.FeatureReader#hasNext()
+     */
+    public boolean hasNext() {
+        return false;
+    }
+
+    /**
+     * Cleans up after Empty FeatureReader.
+     *
+     * @see org.geotools.data.FeatureReader#close()
+     */
+    public void close() {
+        featureType = null;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/EmptyFeatureWriter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/EmptyFeatureWriter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/EmptyFeatureWriter.java	(revision 28000)
@@ -0,0 +1,99 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+/**
+ * Represents an Empty, Typed, FeatureWriter.
+ *
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/EmptyFeatureWriter.java $
+ */
+public class EmptyFeatureWriter implements FeatureWriter<SimpleFeatureType, SimpleFeature> {
+    SimpleFeatureType featureType;
+
+    /**
+     * An Empty FeatureWriter of the provided <code>featureType</code>.
+     *
+     * @param featureType
+     */
+    public EmptyFeatureWriter(SimpleFeatureType featureType) {
+        this.featureType = featureType;
+    }
+
+    /**
+     * @see org.geotools.data.FeatureWriter#getFeatureType()
+     */
+    public SimpleFeatureType getFeatureType() {
+        return featureType;
+    }
+
+    /**
+     * Throws NoSuchElementException as this is an Empty FeatureWriter.
+     *
+     * @return Does not return
+     *
+     * @throws NoSuchElementException
+     *
+     * @see org.geotools.data.FeatureWriter#next()
+     */
+    public SimpleFeature next() throws NoSuchElementException {
+        throw new NoSuchElementException("FeatureWriter is empty");
+    }
+
+    /**
+     * @see org.geotools.data.FeatureWriter#remove()
+     */
+    public void remove() throws IOException {
+        throw new IOException(
+            "FeatureWriter is empty and does not support remove()");
+    }
+
+    /**
+     * @see org.geotools.data.FeatureWriter#remove()
+     */
+    public void write() throws IOException {
+        throw new IOException(
+            "FeatureWriter is empty and does not support write()");
+    }
+
+    /**
+     * There is no next Feature.
+     *
+     * @return <code>false</code>
+     *
+     * @see org.geotools.data.FeatureWriter#hasNext()
+     */
+    public boolean hasNext() {
+        return false;
+    }
+
+    /**
+     * Cleans up after Empty FeatureWriter.
+     *
+     * @see org.geotools.data.FeatureWriter#close()
+     */
+    public void close() {
+        featureType = null;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FIDFeatureReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FIDFeatureReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FIDFeatureReader.java	(revision 28000)
@@ -0,0 +1,140 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.geotools.feature.IllegalAttributeException;
+import org.geotools.feature.SchemaException;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+
+/**
+ * Experimental  FeatureReader<SimpleFeatureType, SimpleFeature> that always takes the first column of the
+ * attributeReader as the FeatureID.  I want to get this working with postgis,
+ * but then will consider other options, for those who want featureIDs created
+ * automatically.  Perhaps a constructor param or a method to say that you
+ * would just like to have the  FeatureReader<SimpleFeatureType, SimpleFeature> increment one for each feature,
+ * prepending the typeName.  I'm also don't really like the one argument
+ * constructor defaulting to the xxx typename.  I feel that it should perhaps
+ * take a typename.  If people deliberately set to null then we could use xxx
+ * or something. ch
+ * 
+ * <p>
+ * This now feels sorta hacky, I'm not sure that I like it, but I'm going to
+ * commit as I need to go now and revisit it in a bit.  I think the idea of
+ * passing in an FIDAttributeReader might be cleaner, and if none is provided
+ * then do an auto-increment one.  This might then work as the
+ * DefaultFeatureReader.
+ * </p>
+ *
+ * @author Ian Schneider
+ * @author Chris Holmes, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/FIDFeatureReader.java $
+ * @version $Id: FIDFeatureReader.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public class FIDFeatureReader implements  FeatureReader<SimpleFeatureType, SimpleFeature> {
+    private final AttributeReader attributeReader;
+    private final SimpleFeatureType schema;
+    private final FIDReader fidReader;
+    private SimpleFeatureBuilder builder;
+    private Boolean hasNextFlag;
+
+    /**
+     * Creates a new instance of AbstractFeatureReader
+     *
+     * @param attributeReader AttributeReader
+     * @param fidReader FIDReader used to ID Features
+     * @param schema FeatureType to use, may be <code>null</code>
+     *
+     * @throws SchemaException if we could not determine the correct
+     *         FeatureType
+     */
+    public FIDFeatureReader(AttributeReader attributeReader,
+        FIDReader fidReader, SimpleFeatureType schema) throws SchemaException {
+        this.attributeReader = attributeReader;
+        this.fidReader = fidReader;
+
+        if (schema == null) {
+            schema = createSchema();
+        }
+
+        this.schema = schema;
+        this.builder = new SimpleFeatureBuilder(schema);
+    }
+
+    public SimpleFeature next()
+        throws IOException, IllegalAttributeException, NoSuchElementException {
+        if (hasNext()) {
+            hasNextFlag = null;
+            attributeReader.next();
+
+            return readFeature(attributeReader);
+        } else {
+            throw new NoSuchElementException(
+                "There are no more Features to be read");
+        }
+    }
+
+    protected SimpleFeatureType createSchema() throws SchemaException {
+        SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();
+        b.setName( "xxx" );
+        
+        for (int i = 0, ii = attributeReader.getAttributeCount(); i < ii;
+                i++) {
+            b.add(attributeReader.getAttributeType(i));
+        }
+
+        return b.buildFeatureType();
+    }
+
+    protected SimpleFeature readFeature(AttributeReader atts)
+        throws IllegalAttributeException, IOException {
+
+        //Seems like doing it here could be a bit expensive.
+        //The other option from this is to have this constructed with two
+        //attributeReaders, the FID one and real attributes one.  Could then
+        //have default FIDAttributeReader.
+        String fid = fidReader.next();
+
+        for (int i = 0, ii = atts.getAttributeCount(); i < ii; i++) {
+            builder.add(atts.read(i));
+        }
+        return builder.buildFeature(fid);
+    }
+
+    public void close() throws IOException {
+        fidReader.close();
+        attributeReader.close();
+    }
+
+    public SimpleFeatureType getFeatureType() {
+        return schema;
+    }
+
+    public boolean hasNext() throws IOException {
+        if(hasNextFlag == null) {
+            hasNextFlag = Boolean.valueOf(attributeReader.hasNext());
+        }
+        return hasNextFlag;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FIDReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FIDReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FIDReader.java	(revision 28000)
@@ -0,0 +1,64 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+
+
+/**
+ *  FeatureReader<SimpleFeatureType, SimpleFeature> customized for FeatureID handling.
+ * 
+ * <p>
+ * An experimental method for doing FIDs.   I'd like to see it and
+ * AttributeReader extend a similar base.  Perhaps BaseReader or something?
+ * And perhaps have  FeatureReader<SimpleFeatureType, SimpleFeature> extend it too? This reader just returns an
+ * incrementing index.  May be sufficient for files, representing rows in a
+ * file.  For jdbc datasources another fid reader should be used.
+ * </p>
+ * 
+ * <p>
+ * We could have FIDReader implement AttributeReader, but it doesn't seem to
+ * make sense, as the getAttributeType doesn't make much sense, as our
+ * featureID is just a string.  Or we could consider having a special FID
+ * attribute in our hierarchy.
+ * </p>
+ *
+ * @author Chris Holmes
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/FIDReader.java $
+ * @version $Id: FIDReader.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public interface FIDReader {
+    /**
+     * Release any resources associated with this reader
+     */
+    void close() throws IOException;
+
+    /**
+     * Returns whether another fid exists for this reader.
+     *
+     * @return <code>true</code> if more content exists
+     */
+    boolean hasNext() throws IOException;
+
+    /**
+     * Gets the next FID from the Reader.
+     *
+     * @return Next featureID
+     */
+    String next() throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureEvent.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureEvent.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureEvent.java	(revision 28000)
@@ -0,0 +1,165 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.util.EventObject;
+
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+
+/**
+ * Represents all events triggered by DataStore instances (typically change events).
+ *
+ * <p>
+ * The "Source" for FeatureEvents is taken to be a <code>FeatureSource</code>,
+ * rather than <code>DataStore</code>. The is due to SimpleFeatureSource having a
+ * hold of Transaction information.
+ * </p>
+ *
+ * <p>
+ * DataStore implementations will actually keep the list listeners sorted
+ * by TypeName, and can report FeatureWriter modifications as required
+ * (by filtering the Listener list by typeName and Transaction).
+ * </p>
+ *
+ * <p>
+ * The Transaction.commit() operation will also need to provide notification, this
+ * shows up as a CHANGE event; with a bit more detail being available in the subclass
+ * BatchFeatureEvent.
+ * </p>
+ * 
+ * @since GeoTools 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/FeatureEvent.java $
+ */
+public class FeatureEvent extends EventObject {
+    private static final long serialVersionUID = 3154238322369916485L;
+
+    /**
+     * FeatureWriter event type denoting the adding features.
+     *
+     * <p>
+     * This EventType is used when FeatureWriter.write() is called when
+     * <code>FeatureWriter.hasNext()</code> has previously returned
+     * <code>false</code>. This action represents a newly create Feature being
+     * passed to the DataStore.
+     * </p>
+     *
+     * <p>
+     * The FeatureWriter making the modification will need to check that
+     * <code>typeName</code> it is modifing matches the
+     * <code>FeatureSource.getSchema().getTypeName()</code> before sending
+     * notification to any listeners on the FeatureSource.
+     * </p>
+     *
+     * <p>
+     * If the FeatureWriter is opperating against a Transaction it will need
+     * ensure that to check the FeatureSource.getTransaction() for a match
+     * before sending notification to any listeners on the FeatureSource.
+     * </p>
+     *
+     * <p>
+     * FeatureEvent.getBounds() should reflect the the Bounding Box of the
+     * newly created Features.
+     * </p>
+     * @deprecated Please use FeatureEvent.getType() == Type.ADDED
+     */
+    public static final int FEATURES_ADDED = 1;
+
+    /**
+     * Event type constant denoting that features in the collection has been
+     * modified.
+     *
+     * <p>
+     * This EventType is used when a FeatureWriter.write() is called when
+     * <code>FeatureWriter.hasNext()</code> returns <code>true</code> and the
+     * current Feature has been changed. This EventType is also used when a
+     * Transaction <code>commit()</code> or <code>rolledback</code> is called.
+     * </p>
+     *
+     * <p>
+     * The FeatureWriter making the modification will need to check that
+     * <code>typeName</code> it is modifing matches the
+     * <code>FeatureSource.getSchema().getTypeName()</code> before sending
+     * notification to any listeners on the FeatureSource.
+     * </p>
+     *
+     * <p>
+     * If the FeatureWriter is opperating against a Transaction it will need
+     * ensure that to check the FeatureSource.getTransaction() for a match
+     * before sending notification to any listeners on the FeatureSource. All
+     * FeatureSources of the same typename will need to be informed of a
+     * <code>commit</code>, except ones in the same Transaction,  and only
+     * FeatureSources in the same Transaction will need to be informed of a
+     * rollback.
+     * </p>
+     *
+     * <p>
+     * FeatureEvent.getBounds() should reflect the the BoundingBox of the
+     * FeatureWriter modified Features. This may not be possible during a
+     * <code>commit()</code> or <code>rollback()</code> opperation.
+     * </p>
+     * @deprecated Please use FeatureEvent.getType() == Type.CHANGED 
+     */
+    public static final int FEATURES_CHANGED = 0;
+
+    /**
+     * Event type constant denoting the removal of a feature.
+     *
+     * <p>
+     * This EventType is used when FeatureWriter.remove() is called. This
+     * action represents a Feature being removed from the DataStore.
+     * </p>
+     *
+     * <p>
+     * The FeatureWriter making the modification will need to check that
+     * <code>typeName</code> it is modifing matches the
+     * <code>FeatureSource.getSchema().getTypeName()</code> before sending
+     * notification to any listeners on the FeatureSource.
+     * </p>
+     *
+     * <p>
+     * If the FeatureWriter is opperating against a Transaction it will need
+     * ensure that to check the FeatureSource.getTransaction() for a match
+     * before sending notification to any listeners on the FeatureSource.
+     * </p>
+     *
+     * <p>
+     * FeatureEvent.getBounds() should reflect the the Bounding Box of the
+     * removed Features.
+     * </p>
+     * @deprecated Please use FeatureEvent.getType() == Type.REMOVED 
+     */
+    public static final int FEATURES_REMOVED = -1;
+        
+    /**
+     * Constructs a new FeatureEvent.
+     *
+     * @param SimpleFeatureSource The DataStore that fired the event
+     * @param eventType One of FEATURE_CHANGED, FEATURE_REMOVED or
+     *        FEATURE_ADDED
+     * @param bounds The area modified by this change
+     * @deprecated Please use FeatureEvent( FeatureSource, Type, Envelope )
+     */
+    public FeatureEvent(FeatureSource<? extends FeatureType, ? extends Feature> featureSource,
+            int eventType, Envelope bounds) {
+        super(featureSource);        
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureListener.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureListener.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureListener.java	(revision 28000)
@@ -0,0 +1,45 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+
+/**
+ * Interface to be implemented by all listeners of FeatureEvents.
+ *
+ * <p>
+ * Event notification is based on p[roviding the Envelope of the modification
+ * (if known).
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research, Inc.
+ * @since GeoTools 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/FeatureListener.java $
+ */
+public interface FeatureListener extends java.util.EventListener {
+    /**
+     * Gets called when a FeatureEvent is fired.
+     *
+     * <p>
+     * Typically fired to signify that a change has occurred in the DataStore
+     * backing the FeatureSource.
+     * </p>
+     *
+     * @param featureEvent The FeatureEvent being fired
+     */
+    void changed(FeatureEvent featureEvent);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureListenerManager.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureListenerManager.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureListenerManager.java	(revision 28000)
@@ -0,0 +1,380 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javax.swing.event.EventListenerList;
+
+import org.geotools.data.simple.SimpleFeatureSource;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+
+/**
+ * This class is used by DataStore implementations to provide FeatureListener
+ * support for the FeatureSources they create.
+ * 
+ * <p>
+ * FeatureWriters created by the DataStore will need to make use of this class
+ * to provide the required FeatureEvents.
+ * </p>
+ * This class has been updated to store listeners using weak references
+ * in order to cut down on memory leaks.
+ *
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/FeatureListenerManager.java $
+ */
+public class FeatureListenerManager {
+    /**
+     * Hold on to provided FeatureListener using a weak reference.
+     * <p>
+     * If I was really smart I could do this with the DynamicProxy class; I am not 
+     * that smart...
+     * <p>
+     * @author Jody Garnett
+     */
+    class WeakFeatureListener implements FeatureListener {
+        WeakReference<FeatureListener> reference; 
+        
+        public void changed( FeatureEvent featureEvent ) {
+            FeatureListener listener = reference.get(); 
+            if(listener==null){ 
+                removeFeatureListener( this ); 
+            } else { 
+                listener.changed(featureEvent);
+            }
+        }        
+    }
+    
+    /**
+     * EvenListenerLists by FeatureSource, using a WeakHashMap to allow
+     * listener lists to be cleaned up after their FeatureSource is no longer referenced.
+     */
+    Map<FeatureSource<? extends FeatureType, ? extends Feature>, EventListenerList> listenerMap = new WeakHashMap<FeatureSource<? extends FeatureType, ? extends Feature>, EventListenerList>();
+
+    /**
+     * Used by FeaureSource implementations to provide listener support.
+     *
+     * @param featureSource
+     * @param featureListener
+     */
+    public void addFeatureListener(FeatureSource<? extends FeatureType, ? extends Feature> featureSource,
+        FeatureListener featureListener) {
+        eventListenerList(featureSource).add(FeatureListener.class,
+            featureListener);
+    }
+
+    /**
+     * Used to clean up a weak reference to a feature listener after
+     * it is no longer in use.
+     * 
+     * @param listener
+     */
+    void removeFeatureListener( WeakFeatureListener listener ){
+        for( EventListenerList list : listenerMap.values() ){
+            list.remove(FeatureListener.class, listener);
+        }
+    }
+            
+    /**
+     * Used by SimpleFeatureSource implementations to provide listener support.
+     *
+     * @param featureSource
+     * @param featureListener
+     */
+    public void removeFeatureListener(FeatureSource<? extends FeatureType, ? extends Feature> featureSource,
+        FeatureListener featureListener) {
+        EventListenerList list = eventListenerList(featureSource);
+        list.remove(FeatureListener.class, featureListener);
+        // don't keep references to feature sources if we have no
+        // more any listener. Since there's no way to know a feature source
+        // has ceased its existance, better remove references as soon as possible
+        if(list.getListenerCount() == 0){
+            cleanListenerList(featureSource);
+        }
+    }
+
+    /**
+     * Retrieve the EvenListenerList for the provided FeatureSource.
+     * 
+     * @param featureSource
+     * @return
+     */
+    private EventListenerList eventListenerList(FeatureSource<? extends FeatureType, ? extends Feature> featureSource) {
+        synchronized (listenerMap) {
+            if (listenerMap.containsKey(featureSource)) {
+                return listenerMap.get(featureSource);
+            } else {
+                EventListenerList listenerList = new EventListenerList();
+                listenerMap.put(featureSource, listenerList);
+
+                return listenerList;
+            }
+        }
+    }
+    
+    public void cleanListenerList(FeatureSource<? extends FeatureType, ? extends Feature> featureSource) {
+        synchronized (listenerMap) {
+            listenerMap.remove(featureSource);
+        }
+    }
+
+    /**
+     * Returns a Map of FeatureListener[] by SimpleFeatureSource for all matches with
+     * featureType and transaction.
+     * 
+     * <p>
+     * A SimpleFeatureSource is considered a match when typeName and Transaction
+     * agree.  Transaction.AUTO_COMMIT will match with any change.
+     * </p>
+     *
+     * @param typeName typeName to match against
+     * @param transaction Transaction to match against (may be AUTO_COMMIT)
+     *
+     */
+    Map<SimpleFeatureSource,FeatureListener[]> getListeners(String typeName, Transaction transaction) {
+        Map<SimpleFeatureSource,FeatureListener[]> map = new HashMap<SimpleFeatureSource,FeatureListener[]>();
+        //Map.Entry<SimpleFeatureSource,FeatureListener[]> entry;
+        SimpleFeatureSource featureSource;
+        EventListenerList listenerList;
+        FeatureListener[] listeners;
+
+        synchronized (listenerMap) {
+            for (Map.Entry entry : listenerMap.entrySet()) {
+                featureSource = (SimpleFeatureSource) entry.getKey();
+
+                if (!featureSource.getName().getLocalPart().equals(typeName)) {
+                    continue; // skip as typeName does not match
+                }
+
+                if ((transaction != Transaction.AUTO_COMMIT)
+                        && hasTransaction(featureSource)) {
+                    // need to ensure Transactions match
+                    if (transaction != getTransaction(featureSource)) {
+                        continue; // skip as transactions do not match        
+                    }
+                }
+
+                listenerList = (EventListenerList) entry.getValue();
+                listeners = listenerList.getListeners(FeatureListener.class);
+
+                if (listeners.length != 0) {
+                    map.put(featureSource, listeners);
+                }
+            }
+        }
+
+        return map;
+    }
+
+    private static boolean hasTransaction(
+            FeatureSource<? extends FeatureType, ? extends Feature> featureSource) {
+        return featureSource instanceof FeatureStore
+                && (((FeatureStore<? extends FeatureType, ? extends Feature>) featureSource)
+                        .getTransaction() != null);
+    }
+
+    private static Transaction getTransaction(
+            FeatureSource<? extends FeatureType, ? extends Feature> featureSource) {
+        if (hasTransaction(featureSource)) {
+            return ((FeatureStore<? extends FeatureType, ? extends Feature>) featureSource)
+                    .getTransaction();
+        }
+
+        return Transaction.AUTO_COMMIT;
+    }
+
+    /**
+     * Notify all listeners that have registered interest for notification on
+     * this event type.
+     * 
+     * <p>
+     * This method is called by:
+     * </p>
+     * 
+     * <ul>
+     * <li>
+     * FeatureWriter.next() with FeatureWriter.hasNext() == false<br>
+     * - when an existing Feature is removed with Tranasaction.AUTO_COMMIT all
+     * listeners registered with SimpleFeatureSource of typeName will be notified.
+     * </li>
+     * <li>
+     * FeatureWriter.next()with FeatureWriter.hasNext() == false<br>
+     * - when an existing Feature is removed with a Transaction all listeners
+     * registered with SimpleFeatureSource of typeName and with the same Transaction
+     * will be notified.
+     * </li>
+     * </ul>
+     * <p>
+     * <b>NOTE</b> requiring to fire this event at FeatureWriter.next() is quite
+     * a gap inherited from an old API when {@link FeatureWriter#write()} didn't
+     * exist yet. It's a good idea though to fire the event at FeatureWriter.write()
+     * instead of FeatureWriter.next() so there are actually changes to notify for.
+     * </p>
+     *
+     * @param typeName typeName being modified
+     * @param transaction Transaction used for change
+     * @param bounds BoundingBox of changes (may be <code>null</code> if unknown)
+     * @param commit true if
+     */
+    public void fireFeaturesAdded(String typeName, Transaction transaction,
+        ReferencedEnvelope bounds, boolean commit) {
+        if (commit) {
+            fireCommit(typeName, transaction, FeatureEvent.FEATURES_ADDED, bounds );
+        } else {
+            fireEvent(typeName, transaction, FeatureEvent.FEATURES_ADDED, bounds );
+        }
+    }
+    
+    /**
+     * Notify all listeners that have registered interest for notification on
+     * this event type.
+     * 
+     * <p>
+     * This method is called by:
+     * </p>
+     * 
+     * <ul>
+     * <li>
+     * FeatureWriter.next() with FeatureWriter.hasNext() == true <br>
+     * - when an existing Feature is modified with Tranasaction.AUTO_COMMIT
+     * all listeners registered with SimpleFeatureSource of typeName will be
+     * notified.
+     * </li>
+     * <li>
+     * FeatureWriter.next()with FeatureWriter.hasNext() == true <br>
+     * - when an existing Feature is modified, with a Transaction all
+     * listeners registered with SimpleFeatureSource of typeName and with the same
+     * Transaction will be notified.
+     * </li>
+     * </ul>
+     * <p>
+     * <b>NOTE</b> requiring to fire this event at FeatureWriter.next() is quite
+     * a gap inherited from an old API when {@link FeatureWriter#write()} didn't
+     * exist yet. It's a good idea though to fire the event at FeatureWriter.write()
+     * instead of FeatureWriter.next() so there are actually changes to notify for.
+     * </p>
+     * 
+     *
+     * @param typeName typeName being modified
+     * @param transaction Transaction used for change
+     * @param bounds BoundingBox of changes (may be <code>null</code> if
+     *        unknown)
+     */
+    public void fireFeaturesChanged(String typeName, Transaction transaction,
+        ReferencedEnvelope bounds, boolean commit) {
+        if (commit) {
+            fireCommit(typeName, transaction, FeatureEvent.FEATURES_CHANGED, bounds );
+        } else {
+            fireEvent(typeName, transaction, FeatureEvent.FEATURES_CHANGED, bounds );
+        }
+
+    }
+
+    /**
+     * Fire notifications out to everyone.
+     * 
+     * @param typeName
+     * @param transaction
+     */
+    private void fireCommit( String typeName, Transaction transaction, int type, ReferencedEnvelope bounds) {
+        FeatureSource<? extends FeatureType, ? extends Feature> featureSource;
+        FeatureListener[] listeners;
+        FeatureEvent event;
+        Map<SimpleFeatureSource,FeatureListener[]> map = getListeners(typeName, Transaction.AUTO_COMMIT);
+
+        for (Map.Entry entry : map.entrySet()) {
+            featureSource = (FeatureSource<? extends FeatureType, ? extends Feature>) entry.getKey();
+            listeners = (FeatureListener[]) entry.getValue();
+
+            if (hasTransaction(featureSource)
+                    && (getTransaction(featureSource) == transaction)) {
+                continue; // skip notify members of the same transaction
+            }
+
+            event = new FeatureEvent(featureSource, type, bounds);
+
+            for (int l = 0; l < listeners.length; l++) {
+                listeners[l].changed(event);
+            }
+        }
+    }
+    /**
+     * Fire notifications out to those listing on this transaction.
+     * @param typeName
+     * @param transaction
+     * @param type
+     * @param bounds
+     */
+    private void fireEvent( String typeName, Transaction transaction, int type, ReferencedEnvelope bounds) {        
+        FeatureSource<? extends FeatureType, ? extends Feature> featureSource;
+        FeatureListener[] listeners;
+        FeatureEvent event;
+        Map<SimpleFeatureSource,FeatureListener[]> map = getListeners(typeName, transaction);
+
+        for (Map.Entry entry : map.entrySet()) {
+            featureSource = (FeatureSource) entry.getKey();
+            listeners = (FeatureListener[]) entry.getValue();
+            
+            event = new FeatureEvent(featureSource,type, bounds);
+
+            for (int l = 0; l < listeners.length; l++) {
+                listeners[l].changed(event);
+            }
+        }
+    }
+    /**
+     * Notify all listeners that have registered interest for notification on
+     * this event type.
+     * 
+     * <p>
+     * This method is called by:
+     * </p>
+     * 
+     * <ul>
+     * <li>
+     * FeatureWrtier.remove() - when an existing Feature is removed with
+     * Tranasaction.AUTO_COMMIT all listeners registered with SimpleFeatureSource of
+     * typeName will be notified.
+     * </li>
+     * <li>
+     * FeatureWrtier.remove() - when an existing Feature is removed with a
+     * Transaction all listeners registered with SimpleFeatureSource of typeName and
+     * with the same Transaction will be notified.
+     * </li>
+     * </ul>
+     * 
+     *
+     * @param typeName typeName being modified
+     * @param transaction Transaction used for change
+     * @param bounds BoundingBox of changes (may be <code>null</code> if
+     *        unknown)
+     */
+    public void fireFeaturesRemoved(String typeName, Transaction transaction,
+        ReferencedEnvelope bounds, boolean commit ) {
+        if (commit) {
+            fireCommit(typeName, transaction, FeatureEvent.FEATURES_REMOVED, bounds );
+        } else {
+            fireEvent(typeName, transaction, FeatureEvent.FEATURES_REMOVED, bounds );
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureLock.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureLock.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureLock.java	(revision 28000)
@@ -0,0 +1,78 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+
+/**
+ * Used in conjuction with {@link FeatureLocking} to lock features during a
+ * transaction. This class is responsible for supplying a unique Authorization 
+ * ID and expiry period.
+ * <p>
+ * 
+ * A FeatureLock representing the Current Transaction has been provided as a 
+ * static constant: {@link #TRANSACTION}.
+ *
+ * @author Jody Garnett, Refractions Research, Inc.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/FeatureLock.java $
+ * @version $Id: FeatureLock.java 37280 2011-05-24 07:53:02Z mbedward $
+ *
+ * @see <a
+ *      href="http://vwfs.refractions.net/docs/Database_Research.pdf">Database
+ *      Reseach</a>
+ * @see <a
+ *      href="http://vwfs.refractions.net/docs/Transactional_WFS_Design.pdf">Transactional
+ *      WFS Design</a>
+ * @see <a
+ *      href="http://vwfs.refractions.net/docs/Design_Implications.pdf">Design
+ *      Implications</a>
+ * @see FeatureLockFactory
+ */
+public class FeatureLock {
+    public static final FeatureLock TRANSACTION = new CurrentTransactionLock();
+    protected String authorization;
+    protected long duration;
+    
+    /**
+     * Creates a new lock.
+     * 
+     * @param authorization LockId used to authorize the transaction
+     * @param duration expiry period of this lock (in minutes)
+     */
+    public FeatureLock(String authorization, long duration ){
+        this.authorization = authorization;
+        this.duration = duration;
+    }
+    
+    /**
+     * Gets the ID used for transaction authorization.
+     *
+     * @return the authorization ID
+     */
+    public String getAuthorization(){
+        return authorization;
+    }
+
+    /**
+     * Gets the expiry time for this lock (in minutes).
+     *
+     * @return expiry period
+     */
+    public long getDuration(){
+        return duration;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureLockException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureLockException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureLockException.java	(revision 28000)
@@ -0,0 +1,49 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+
+
+/**
+ * Indicates a lock contention, and attempt was made to modify or aquire with
+ * out Authroization.
+ *
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/FeatureLockException.java $
+ */
+public class FeatureLockException extends IOException {
+    private static final long serialVersionUID = 1L;
+
+    public FeatureLockException() {
+        super();
+    }
+
+    public FeatureLockException(String message) {
+        super(message);
+    }
+
+    public FeatureLockException(String message, String featureID) {
+        super(message);
+    }
+
+    public FeatureLockException(String message, String featureID, Throwable t) {
+        super(message);
+        initCause(t);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureLockFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureLockFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureLockFactory.java	(revision 28000)
@@ -0,0 +1,47 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.geotools.factory.Factory;
+
+/**
+ * This specifies the interface to create FeatureLocks.
+ * <p>
+ * Sample use:
+ * <code><pre>
+ * FeatureLock lock = FeatureLockFactory.generate( "MyLock", 3600 );
+ * </pre></code>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/FeatureLockFactory.java $
+ * @version $Id: FeatureLockFactory.java 37280 2011-05-24 07:53:02Z mbedward $
+ * @task REVISIT: Combine this with a factory to also make Query objects?
+ * @author Chris Holmes, TOPP
+ * 
+ * @deprecated Please use {@link FeatureLock} directly
+ */
+
+public abstract class FeatureLockFactory implements Factory {
+    /**
+     * Returns the implementation hints. The default implementation returns en empty map.
+     */
+    public Map getImplementationHints() {
+        return Collections.EMPTY_MAP;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureLocking.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureLocking.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureLocking.java	(revision 28000)
@@ -0,0 +1,188 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+import org.opengis.filter.Filter;
+
+
+/**
+ * Provides Feature based locking.
+ *
+ * <p>
+ * Features from individual shapefiles, database tables, etc. can be protected
+ * or reserved from modification through this interface.
+ * </p>
+ * <p>
+ * To use please cast your SimpleFeatureSource to this interface.
+ * <pre><code>
+ * SimpleFeatureSource source = dataStore.getFeatureSource("roads");
+ * if( source instanceof FeatureLocking ) {
+ *     FeatureLocking locking = (FeatureLocking<SimpleFeatureType, SimpleFeature>) source;
+ *     ...
+ * }
+ *
+ * @author Jody Garnett, Refractions Research, Inc.
+ * @author Ray Gallagher
+ * @author Rob Hranac, TOPP
+ * @author Chris Holmes, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/FeatureLocking.java $
+ * @version $Id: FeatureLocking.java 37280 2011-05-24 07:53:02Z mbedward $
+ */
+public interface FeatureLocking<T extends FeatureType, F extends Feature> extends FeatureStore<T, F> {
+    /**
+     * All locking operations will operate against the provided
+     * <code>lock</code>.
+     *
+     * <p>
+     * This in in keeping with the stateful spirit of DataSource in which
+     * operations are against the "current" transaction. If a FeatureLock is
+     * not provided lock operations will only be applicable for the current
+     * transaction (they will expire on the next commit or rollback).
+     * </p>
+     *
+     * <p>
+     * That is lockFeatures() operations will:
+     * </p>
+     *
+     * <ul>
+     * <li>
+     * Be recorded against the provided FeatureLock.
+     * </li>
+     * <li>
+     * Be recorded against the current transaction if no FeatureLock is
+     * provided.
+     * </li>
+     * </ul>
+     *
+     * <p>
+     * Calling this method with <code>setFeatureLock( FeatureLock.TRANSACTION
+     * )</code> will revert to per transaction operation.
+     * </p>
+     *
+     * <p>
+     * This design allows for the following:
+     * </p>
+     *
+     * <ul>
+     * <li>
+     * cross DataSource FeatureLock usage
+     * </li>
+     * <li>
+     * not having pass in the same FeatureLock object multiple times
+     * </li>
+     * </ul>
+     *
+     * @param lock DOCUMENT ME!
+     */
+    void setFeatureLock(FeatureLock lock);
+
+    /**
+     * FeatureLock features described by Query.
+     *
+     * <p>
+     * To implement WFS parcial Locking retrieve your features with a query
+     * operation first before trying to lock them individually. If you are not
+     * into WFS please don't ask what parcial locking is.
+     * </p>
+     *
+     * @param query Query describing the features to lock
+     *
+     * @return Number of features locked
+     *
+     * @throws IOException Thrown if anything goes wrong
+     */
+    int lockFeatures(Query query) throws IOException;
+
+    /**
+     * FeatureLock features described by Filter.
+     *
+     * <p>
+     * To implement WFS parcial Locking retrieve your features with a query
+     * operation first before trying to lock them individually. If you are not
+     * into WFS please don't ask what parcial locking is.
+     * </p>
+     *
+     * @param filter Filter describing the features to lock
+     *
+     * @return Number of features locked
+     *
+     * @throws IOException Thrown if anything goes wrong
+     */
+    int lockFeatures(Filter filter) throws IOException;
+
+    /**
+     * FeatureLock all Features.
+     *
+     * <p>
+     * The method does not prevent addFeatures() from being used (we could add
+     * a lockDataSource() method if this functionality is required.
+     * </p>
+     *
+     * @return Number of Features locked by this opperation
+     *
+     * @throws IOException
+     */
+    int lockFeatures() throws IOException;
+
+    /**
+     * Unlocks all Features.
+     *
+     * <p>
+     * Authorization must be provided prior before calling this method.
+     * </p>
+     * <pre><code>
+     * <b>void</b> releaseLock( String lockId, LockingDataSource ds ){
+     *    ds.setAuthorization( "LOCK534" );
+     *    ds.unLockFeatures();
+     * }
+     * </code></pre>
+     *
+     * @throws IOException
+     */
+    void unLockFeatures() throws IOException;
+
+    /**
+     * Unlock Features denoted by provided filter.
+     *
+     * <p>
+     * Authorization must be provided prior before calling this method.
+     * </p>
+     *
+     * @param filter
+     *
+     * @throws IOException
+     */
+    void unLockFeatures(Filter filter) throws IOException;
+
+    /**
+     * Unlock Features denoted by provided query.
+     *
+     * <p>
+     * Authorization must be provided prior before calling this method.
+     * </p>
+     *
+     * @param query Specifies fatures to unlock
+     *
+     * @throws IOException
+     */
+    void unLockFeatures(Query query) throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureReader.java	(revision 28000)
@@ -0,0 +1,123 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+
+/**
+ * The low-level interface for reading Features. Will use the underlying
+ * AttributeReader and the given FeatureType to create new Features.
+ *
+ * <p>
+ * Typical use is as follows:
+ * <pre><code>
+ *   FeatureReader reader = null;
+ *   try{
+ *      for( reader = data.getFeatureReader( filter ); reader.hasNext(); ){
+ *          f = reader.next();
+ *          ...
+ *      }
+ *   }
+ *   catch (IOException problem){
+ *      ...
+ *   }
+ *   finally {
+ *      if( reader != null ){
+ *          try {
+ *             reader.close();
+ *          }
+ *          catch( IOException eek){
+ *          }
+ *      }
+ *   }
+ * </code></pre>
+ *
+ * <h2>Questions and Suggestions</h2>
+ * <ul>
+ * <li>Q: Should FeatureReader provide access to the AttributeReaders it uses?
+ * <br>A:
+ *       No, it looks like we will make a lazy Feature in order to cleanly
+ *       allow for lazy parsing of attribtues.
+ * </li>
+ * <li>Q:FeatureReader has a close method, but no open method?
+ * <br>A: This is by design allowing FeatureReader to encapsulate its InputStream
+ *     or Rowset). Please assume that FeatureReaders are a single use proposition.
+ * </li>
+ * <li>Q: All that exception handling is a pain!
+ *     A:
+ *        Yes it is, we have constructed semi-normal Java iterators to cut down on the
+ *        pain. But you *do* still have to close 'em - this is IO after all.
+ * </li>
+ * <li>Q: Can we include skip(int) - SeanG
+ *     A:
+ *        The order of the contents is not "known" or predicatable to the end user, so
+ *        skip( int ) would be useless. For random access (a higher order
+ *        of abstraction then FeatureReader) please look at FeatureList.
+ * </li>
+ * </ul>
+ * </p>
+ *
+ * @author Ian Schneider
+ * @author Sean Geoghegan, Defence Science and Technology Organisation.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/FeatureReader.java $
+ * @version $Id: FeatureReader.java 37280 2011-05-24 07:53:02Z mbedward $
+ */
+public interface FeatureReader<T extends FeatureType, F extends Feature> {
+    /**
+     * Return the FeatureType this reader has been configured to create.
+     *
+     * @return the FeatureType of the Features this FeatureReader will create.
+     */
+    T getFeatureType();
+
+    /**
+     * Reads the next Feature in the FeatureReader.
+     *
+     * @return The next feature in the reader.
+     *
+     * @throws IOException If an error occurs reading the Feature.
+     * @throws IllegalAttributeException If the attributes read do not comply
+     *         with the FeatureType.
+     * @throws NoSuchElementException If there are no more Features in the
+     *         Reader.
+     */
+    F next() throws IOException, IllegalArgumentException, NoSuchElementException;
+
+    /**
+     * Query whether this FeatureReader has another Feature.
+     *
+     * @return True if there are more Features to be read. In other words, true
+     *         if calls to next would return a feature rather than throwing an
+     *         exception.
+     *
+     * @throws IOException If an error occurs determining if there are more
+     *         Features.
+     */
+    boolean hasNext() throws IOException;
+
+    /**
+     * Release the underlying resources associated with this stream.
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    void close() throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureSource.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureSource.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureSource.java	(revision 28000)
@@ -0,0 +1,240 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.awt.RenderingHints;
+import java.io.IOException;
+import java.util.Set;
+
+import org.geotools.factory.Hints;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+
+
+/**
+ * This class provides a high-level API for operations on feature data. Typically,
+ * when working with a data source such as a shapefile or database table you will
+ * initially create a {@code DataStore} object to connect
+ * to the physical source and then retrieve a {@code FeatureSource} to work with
+ * the feature data, as in this excerpt from the GeoTools Quickstart example
+ * (<a href="http://geotools.org/quickstart.html">http://geotools.org/quickstart.html</a>)
+ * <pre><code>
+ *     File file = ...
+ *     FileDataStore store = FileDataStoreFinder.getDataStore(file);
+ *     FeatureSource featureSource = store.getFeatureSource();
+ * </code></pre>
+ * @see DataStore
+ *
+ * @author Jody Garnett
+ * @author Ray Gallagher
+ * @author Rob Hranac, TOPP
+ * @author Chris Holmes, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/FeatureSource.java $
+ * @version $Id: FeatureSource.java 37280 2011-05-24 07:53:02Z mbedward $
+ */
+public interface FeatureSource<T extends FeatureType, F extends Feature>{
+    
+    /**
+     * Returns the name of the features (strictly, the name of the 
+     * {@code AttributeDescriptor} for the features) accessible through this
+     * {@code FeatureSource}.
+     * <p>
+     * The value returned by this method can be different to that returned by
+     * {@code featureSource.getSchema().getType().getName()}.
+     * This is because there is a distinction between the name applied to features
+     * and the name of a feature type. When working with {@code SimpleFeature} and
+     * {@code SimpleFeatureType}, for example with a shapefile data source, it is
+     * common practice for feature and feature type names to be the same. However, this
+     * is not the case more generally. For instance, a database can contain two
+     * tables with the same structure. The feature name will refer to the table
+     * while the feature type name refers to the schema (table structure).
+     *
+     * @since 2.5
+     * @return the name of the features accessible through this {@code FeatureSource}
+     */
+    Name getName();
+        
+    /**
+     * Returns the data source, as a {@code DataAccess} object, providing
+     * this {@code FeatureSource}.
+     *
+     * @return the data source providing this {@code FeatureSource}
+     */
+    DataAccess<T, F> getDataStore();
+
+    /**
+     * Enquire what what query capabilities this {@code FeatureSource}
+     * natively supports. For example, whether queries can return sorted
+     * results.
+     * 
+     * @return the native query capabilities of this {@code FeatureSource}
+     * @since 2.5
+     */
+    QueryCapabilities getQueryCapabilities();
+    
+    /**
+     * Registers a listening object that will be notified of changes to this
+     * {@code FeatureSource}.
+     *
+     * @param listener the new listener
+     */
+    void addFeatureListener(FeatureListener listener);
+
+    /**
+     * Removes an object from this {@code FeatureSource's} listeners.
+     *
+     * @param listener the listener to remove
+     */
+    void removeFeatureListener(FeatureListener listener);
+
+    /**
+     * Retrieves features, in the form of a {@code FeatureCollection}, based
+     * on an OGC {@code Filter}.
+     *
+     * @param filter the filter to select features; must not be {@code null}
+     *        (use {@linkplain Filter#INCLUDE} instead)
+     *
+     * @return features retrieved by the {@code Filter}
+     *
+     * @throws IOException if the underlying data source cannot be accessed.
+     *
+     * @see Filter
+     */
+    FeatureCollection<T, F> getFeatures(Filter filter) throws IOException;
+
+    /**
+     * Retrieves features, in the form of a {@code FeatureCollection}, based
+     * on a {@code Query}.
+     *
+     * @param query DataAccess query for requested information, such as typeName,
+     *        maxFeatures and filter.
+     *
+     * @return features retrieved by the {@code Query}
+     *
+     * @throws IOException if the underlying data source cannot be accessed.
+     *
+     * @see Query
+     */
+    FeatureCollection<T, F> getFeatures(Query query) throws IOException;
+
+    /**
+     * Retrieves all features in the form of a {@code FeatureCollection}.
+     * <p>
+     * The following statements are equivalent:
+     * <pre><code>
+     *     featureSource.getFeatures();
+     *     featureSource.getFeatures(Filter.INCLUDE);
+     *     featureSource.getFeatures(Query.ALL);
+     * </code></pre>
+     *
+     * @return features retrieved by the {@code Query}
+     *
+     * @throws IOException if the underlying data source cannot be accessed.
+     */
+    FeatureCollection<T, F> getFeatures() throws IOException;
+
+    /**
+     * Retrieves the schema (feature type) that will apply to features retrieved
+     * from this {@code FeatureSource}.
+     * <p>
+     * For a homogeneous data source such as a shapefile or a database table,
+     * this schema be that of all features. For a heterogeneous data source,
+     * e.g. a GML document, the schema returned is the lowest common denominator
+     * across all features.
+     *
+     * @return the schema that will apply to features retrieved from this
+     *         {@code FeatureSource}
+     */
+    T getSchema();
+
+    /**
+     * Get the spatial bounds of the feature data. This is equivalent
+     * to calling <code>getBounds(Query.ALL)</code>.
+     * <p>
+     * It is possible that this method will return null if the calculation
+     * of bounds is judged to be too costly by the implementing class. 
+     * In this case, you might call <code>getFeatures().getBounds()</code>
+     * instead.
+     *
+     * @return The bounding envelope of the feature data; or {@code null}
+     *         if the bounds are unknown or too costly to calculate.
+     *
+     * @throws IOException on any errors calculating the bounds
+     */
+    ReferencedEnvelope getBounds() throws IOException;
+
+    /**
+     * Get the spatial bounds of the features that would be returned by
+     * the given {@code Query}.
+     * <p>
+     * It is possible that this method will return null if the calculation
+     * of bounds is judged to be too costly by the implementing class.
+     * In this case, you might call <code>getFeatures(query).getBounds()</code>
+     * instead.
+     *
+     * @param query the query to select features
+     *
+     * @return The bounding envelope of the feature data; or {@code null}
+     *         if the bounds are unknown or too costly to calculate.
+     *
+     * @throws IOException on any errors calculating the bounds
+     */
+    ReferencedEnvelope getBounds(Query query) throws IOException;
+
+    /**
+     * Gets the number of the features that would be returned by the given
+     * {@code Query}, taking into account any settings for max features and
+     * start index set on the {@code Query}.
+     * <p>
+     * It is possible that this method will return {@code -1} if the calculation
+     * of number of features is judged to be too costly by the implementing class.
+     * In this case, you might call <code>getFeatures(query).getBounds()</code>
+     * instead.
+     *
+     * @param query the query to select features
+     *
+     * @return the numer of features that would be returned by the {@code Query};
+     *         or {@code -1} if this cannot be calculated.
+     *
+     * @throws IOException if there are errors getting the count
+     */
+    int getCount(Query query) throws IOException;
+
+    /**
+     * Returns the set of hints that this {@code FeatureSource} supports via {@code Query} requests.
+     * <p>
+     * Note: the existence of a specific hint does not guarantee that it will always be honored by
+     * the implementing class.
+     * 
+     * @see Hints#FEATURE_DETACHED
+     * @see Hints#JTS_GEOMETRY_FACTORY
+     * @see Hints#JTS_COORDINATE_SEQUENCE_FACTORY
+     * @see Hints#JTS_PRECISION_MODEL
+     * @see Hints#JTS_SRID
+     * @see Hints#GEOMETRY_DISTANCE
+     * @see Hints#FEATURE_2D
+     * @return a set of {@code RenderingHints#Key} objects; may be empty but never {@code null}
+     */
+    public Set<RenderingHints.Key> getSupportedHints();
+    
+    // FeatureReader getFeatureReader( Query query ); // ask justin for proposal
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureStore.java	(revision 28000)
@@ -0,0 +1,204 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.FeatureType;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+import org.opengis.filter.identity.FeatureId;
+import org.geotools.feature.FeatureCollection;
+
+
+/**
+ * This interface extends {@code FeatureSource}, adding methods to add and remove
+ * features and to modify existing features.
+ * <pre><code>
+ * DataStore myDataStore = ...
+ * FeatureSource featureSource = myDataStore.getFeatureSource("aname");
+ * if (featureSource instanceof FeatureStore) {
+ *     // we have write access to the feature data
+ *     FeatureStore featureStore = (FeatureStore) featureSource;
+ *
+ *     // add some new features
+ *     Transaction t = new DefaultTransaction("add");
+ *     featureStore.setTransaction(t);
+ *     try {
+ *         featureStore.addFeatures( someFeatures );
+ *         t.commit();
+ *     } catch (Exception ex) {
+ *         ex.printStackTrace();
+ *         t.rollback();
+ *     } finally {
+ *         t.close();
+ *     }
+ * }
+ * </code></pre>
+ *
+ * @author Jody Garnett
+ * @author Ray Gallagher
+ * @author Rob Hranac, TOPP
+ * @author Chris Holmes, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/FeatureStore.java $
+ * @version $Id: FeatureStore.java 37280 2011-05-24 07:53:02Z mbedward $
+ */
+public interface FeatureStore<T extends FeatureType, F extends Feature> extends FeatureSource<T, F> {
+    /**
+     * Adds all features from the feature collection.
+     * <p>
+     * A list of {@code FeatureIds} is returned, one for each feature in the order created.
+     * However, these might not be assigned until after a commit has been performed.
+     * 
+     * @param collection the collection of features to add
+     *
+     * @return the {@code FeatureIds} of the newly added features
+     *
+     * @throws IOException if an error occurs modifying the data source
+     */
+    List<FeatureId> addFeatures(FeatureCollection<T, F> collection) throws IOException;
+
+    /**
+     * Removes features selected by the given filter.
+     *
+     * @param filter an OpenGIS filter
+     *
+     * @throws IOException if an error occurs modifying the data source
+     */
+    void removeFeatures(Filter filter) throws IOException;
+
+    /**
+     * Modifies the attributes with the supplied values in all
+     * features selected by the given filter.
+     *
+     * @param attributeNames the attributes to modify
+     *
+     * @param attributeValues the new values for the attributes
+     *
+     * @param filter an OpenGIS filter
+     *
+     * @throws IOException if the attribute and object arrays are not equal
+     *         in length; if the value types do not match the attribute types;
+     *         if modification is not supported; or if there errors accessing the
+     *         data source
+     */
+    void modifyFeatures( Name[] attributeNames, Object[] attributeValues, Filter filter )  throws IOException;
+
+    /**
+     * For backwards compatibility; please be careful that your descriptor is
+     * actually compatible with the one declared.
+     * 
+     * @param type the attributes to modify
+     *
+     * @param value the new values for the attributes
+     *
+     * @param filter an OpenGIS filter
+     *
+     * @throws IOException
+     *
+     * @deprecated Please use the safer method {@link #modifyFeatures(Name[], Object[], Filter)}
+     */
+    void modifyFeatures(AttributeDescriptor[] type, Object[] value, Filter filter) throws IOException;
+    
+    /**
+     * Modifies an attribute with the supplied value in all features
+     * selected by the given filter.
+     *
+     * @param attributeName the attribute to modify
+     *
+     * @param attributeValue the new value for the attribute
+     *
+     * @param filter an OpenGIS filter
+     *
+     * @throws IOException if modification is not supported; if the value type does
+     *         not match the attribute type; or if there errors accessing the data source
+     */
+    void modifyFeatures( Name attributeName, Object attributeValue, Filter filter )  throws IOException;
+    
+    /**
+     * For backwards compatibility; please be careful that your descriptor is actually compatible
+     * with the one declared.
+     *
+     * @param type the attribute to modify
+     *
+     * @param value the new value for the attribute
+     *
+     * @param filter an OpenGIS filter
+     *
+     * @throws IOException
+     *
+     * @deprecated Please use the safer method {@link #modifyFeatures(Name, Object, Filter)}
+     */
+    void modifyFeatures(AttributeDescriptor type, Object value, Filter filter)
+        throws IOException;
+
+    /**
+     * Deletes any existing features in the data source and then
+     * inserts new features provided by the given reader. This is primarily used
+     * as a convenience method for file-based data sources.
+     *
+     * @param reader - the collection to be written
+     *
+     * @throws IOException if there are any datasource errors.
+     */
+    void setFeatures(FeatureReader<T, F> reader) throws IOException;
+
+    /**
+     * Provide a transaction for commit/rollback control of a modifying
+     * operation on this {@code FeatureStore}.
+     * <pre><code>
+     * Transation t = new DefaultTransaction();
+     * featureStore.setTransaction(t);
+     * try {
+     *     featureStore.addFeatures( someFeatures );
+     *     t.commit();
+     * } catch ( IOException ex ) {
+     *     // something went wrong;
+     *     ex.printStackTrace();
+     *     t.rollback();
+     * } finally {
+     *     t.close();
+     * }
+     * </code></pre>
+     *
+     * @param transaction the transaction
+     */
+    void setTransaction(Transaction transaction);
+
+    /**
+     * Gets the {@code Transaction} that this {@code FeatureStore} is
+     * currently operating against.
+     * <pre><code>
+     * Transaction t = featureStore.getTransaction();
+     * try {
+     *     featureStore.addFeatures( features );
+     *     t.commit();
+     * } catch( IOException erp ){
+     *     // something went wrong;
+     *     ex.printStackTrace();
+     *     t.rollback();
+     * }
+     * </code></pre>
+     *
+     * @return Transaction in use, or {@linkplain Transaction#AUTO_COMMIT}
+     */
+    Transaction getTransaction();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureWriter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureWriter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FeatureWriter.java	(revision 28000)
@@ -0,0 +1,181 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+
+
+/**
+ * Provides the ability to write Features information.
+ *
+ * <p>
+ * Capabilities:
+ * </p>
+ *
+ * <ul>
+ * <li>
+ * Similar API to FeatureReader
+ * </li>
+ * <li>
+ * After aquiring a feature using next() you may call remove() or after
+ * modification write().  If you do not call one of these two methods before
+ * calling hasNext(), or next() for that matter, the feature will be left
+ * unmodified.
+ * </li>
+ * <li>
+ * This API allows modification, and Filter based modification to be written.
+ * Please see AbstractDataStore for examples of implementing common
+ * opperations using this API.
+ * </li>
+ * <li>
+ * In order to add new Features, FeatureWriters capable of accepting new
+ * content allow next() to be called when hasNext() is <code>false</code> to
+ * allow new feature creation. These changes
+ * </li>
+ * </ul>
+ *
+ * <p>
+ * One thing that is really nice about the approach to adding content is that
+ * the generation of FID is not left in the users control.
+ * </p>
+ *
+ * @author Ian Schneider
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/FeatureWriter.java $
+ * @version $Id: FeatureWriter.java 37280 2011-05-24 07:53:02Z mbedward $
+ */
+public interface FeatureWriter<T extends FeatureType, F extends Feature> {
+    /**
+     * FeatureType this reader has been configured to create.
+     *
+     * @return FeatureType this writer has been configured to create.
+     */
+    T getFeatureType();
+
+    /**
+     * Reads a Feature from the underlying AttributeReader.
+     *
+     * <p>
+     * This method may return a Feature even though hasNext() returns
+     * <code>false</code>, this allows FeatureWriters to provide an ability to
+     * append content.
+     * </p>
+     *
+     * @return Feature from Query, or newly appended Feature
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    F next() throws IOException;
+
+    /**
+     * Removes current Feature, must be called before hasNext.
+     *
+     * <p>
+     * FeatureWriters will need to allow all FeatureSources of the same
+     * typeName to issue a FeatureEvent event of type
+     * <code>FeatureEvent.FEATURES_REMOVED</code> when this method is called.
+     * </p>
+     *
+     * <p>
+     * If this FeatureWriter is opperating against a Transaction
+     * FEATURES_REMOVED events should only be sent to FeatureSources operating
+     * on the same Transaction. When Transaction commit() is called other
+     * FeatureSources will be informed of the modifications.
+     * </p>
+     *
+     * <p>
+     * When the current Feature has been provided as new content, this method
+     * "cancels" the add opperation (and notification needed).
+     * </p>
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    void remove() throws IOException;
+
+    /**
+     * Wrties the current Feature, must be called before hasNext.
+     *
+     * <p>
+     * FeautreWriters will need to allow FeatureSources of the same typeName to
+     * issue a FeatureEvent:
+     * </p>
+     *
+     * <ul>
+     * <li>
+     * FeatureEvent.FEATURES_ADDED: when next() has been called with hasNext()
+     * equal to <code>false</code>.
+     * </li>
+     * <li>
+     * FeatureEvent.FEATURES_MODIFIED: when next has been called with hasNext()
+     * equal to <code>true</code> and the resulting Feature has indeed been
+     * modified.
+     * </li>
+     * </ul>
+     *
+     * <p>
+     * If this FeatureWriter is opperating against a Transaction the
+     * FEATURES_MODIFIED or FEATURES_ADDED events should only be sent to
+     * FeatureSources opperating on the same Transaction. When Transaction
+     * commit() is called other FeatureSources will be informed of the
+     * modifications.
+     * </p>
+     *
+     * <p>
+     * If you have not called write() when you call hasNext() or next(), no
+     * modification will occur().
+     * </p>
+     *
+     * @throws IOException
+     */
+    void write() throws IOException;
+
+    /**
+     * Query whether this FeatureWriter has another Feature.
+     *
+     * <p>
+     * Please note: it is more efficient to construct your FeatureWriter with a
+     * Filer (to skip entries you do not want), than to force the creation of
+     * entire Features only to skip over them.
+     * </p>
+     *
+     * <p>
+     * FeatureWriters that support append opperations will allow calls to next,
+     * even when haveNext() returns <code>false</code>.
+     * </p>
+     *
+     * @return <code>true</code> if an additional <code>Feature</code> is
+     *         available.
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    boolean hasNext() throws IOException;
+
+    /**
+     * Release the underlying resources.
+     *
+     * @throws IOException if there there are problems releasing underlying resources, or
+     * possibly if close has been called (up to the implementation).
+     */
+    void close() throws IOException;
+    
+    //FeatureWriter getFeatureWriter( Filter filter); // ask justin for proposal
+    //FeatureWriter getFeatureWriter( boolean append); // ask justin for proposal
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FileDataStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FileDataStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FileDataStore.java	(revision 28000)
@@ -0,0 +1,50 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+/**
+ * DataStore represents a single file of content.
+ * <p>
+ * Allows developer to skip refering to the typeName when a file contains
+ * only a single set of content.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/FileDataStore.java $
+ */
+public interface FileDataStore extends DataStore {
+    
+    /**
+     * FeatureType for the file being read.
+     * <p>
+     * This is the same as getSchema( getTypeName[0] )
+     * </p>
+     * 
+     * @return FeatureType of the file being read
+     * @see org.geotools.data.DataStore#getSchema(java.lang.String)
+     */
+    SimpleFeatureType getSchema() throws IOException;
+
+    /**
+     * @see org.geotools.data.DataStore#getFeatureReader(java.lang.String)
+     */
+    FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader() throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FileDataStoreFactorySpi.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FileDataStoreFactorySpi.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FileDataStoreFactorySpi.java	(revision 28000)
@@ -0,0 +1,62 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.net.URL;
+
+
+/**
+ * DataAccessFactory for working with formats based on a single URL.
+ * <p>
+ * This interface provides a mechanism of discovery for DataAccessFactories
+ * which support singular files.
+ * </p>
+ *
+ * @author dzwiers
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/FileDataStoreFactorySpi.java $
+ */
+public interface FileDataStoreFactorySpi extends DataStoreFactorySpi {
+
+    /**
+     * Tests if the provided url can be handled by this factory.
+     *
+     * @param url URL to a real file (may not be local)
+     *
+     * @return <code>true</code> if this url can when this dataStore can resolve and read the data specified
+     */
+    public boolean canProcess(URL url);
+
+    /**
+     * A DataStore attached to the provided url, may be created if needed.
+     * <p>
+     * Please note that additional configuration options may be available
+     * via the traditional createDataStore( Map ) method provided by the
+     * superclass.
+     * <p>
+     * @param url The data location for the
+     *
+     * @return Returns an AbstractFileDataStore created from the data source
+     *         provided.
+     *
+     * @throws IOException
+     *
+     * @see AbstractFileDataStore
+     */
+    public FileDataStore createDataStore(URL url) throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FileDataStoreFinder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FileDataStoreFinder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FileDataStoreFinder.java	(revision 28000)
@@ -0,0 +1,136 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.factory.CommonFactoryFinder;
+
+
+/**
+ * <p>
+ * Most of this code was copied from DataStoreFinder.  See the Documentation
+ * there for details.
+ * </p>
+ * 
+ * <p>
+ * This searches for DataStores which support a singular file  parsed in a
+ * particular file format.
+ * </p>
+ *
+ * @author dzwiers
+ *
+ * @see DataStoreFinder
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/FileDataStoreFinder.java $
+ */
+public class FileDataStoreFinder {
+    /** The logger for the filter module. */
+    protected static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geotools.data");
+
+    private FileDataStoreFinder() {
+    }
+
+    /**
+     * Checks each available datasource implementation in turn and returns the
+     * first one which claims to support the given file..
+     *
+     * @param file the file
+     *
+     * @return The first datasource which claims to process the required
+     *         resource, returns null if none can be found.
+     *
+     * @throws IOException If a suitable loader can be found, but it can not be
+     *         attached to the specified resource without errors.
+     */
+    public static FileDataStore getDataStore(File file) throws IOException {
+        return getDataStore(file.toURI().toURL());
+    }
+
+    /**
+     * Checks each available datasource implementation in turn and returns the
+     * first one which claims to support the resource identified by the params
+     * object.
+     *
+     * @param url URL for the input resource
+     *
+     * @return The first datasource which claims to process the required
+     *         resource, returns null if none can be found.
+     *
+     * @throws IOException If a suitable loader can be found, but it can not be
+     *         attached to the specified resource without errors.
+     */
+    public static FileDataStore getDataStore(URL url) throws IOException {
+        Iterator<FileDataStoreFactorySpi> ps = getAvailableDataStores();
+
+        while (ps.hasNext()) {
+            FileDataStoreFactorySpi fac = ps.next();
+            if( !fac.isAvailable() ){
+                continue;
+            }
+            try {
+                if (fac.canProcess(url)) {
+                    return fac.createDataStore(url);
+                }
+            } catch (Throwable t) {
+                /**
+                 * The logger for the filter module.
+                 */
+                LOGGER.log(Level.WARNING,
+                    "Could not aquire " + fac.getDescription() + ":" + t, t);
+
+                // Protect against DataStores that don't carefully
+                // code canProcess
+                continue;
+            }
+        }
+
+        return null;
+    }
+    
+    /**
+     * Returns an iterator of FileDataStoreFactorySpi to allow for the easy
+     * creation of a FileDataStore
+     *
+     *
+     * @see FileDataStoreFactorySpi
+     * @see FileDataStore
+     */
+    public static Iterator<FileDataStoreFactorySpi> getAvailableDataStores() {
+        Set availableDS = new HashSet();
+        
+        Set all = CommonFactoryFinder.getFileDataStoreFactories( null );
+        
+        for (Iterator it = all.iterator(); it.hasNext();) {
+            FileDataStoreFactorySpi dsFactory = (FileDataStoreFactorySpi) it
+                .next();
+
+            if (dsFactory.isAvailable()) {
+                availableDS.add(dsFactory);
+            }
+        }
+
+        return availableDS.iterator();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FilteringFeatureReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FilteringFeatureReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FilteringFeatureReader.java	(revision 28000)
@@ -0,0 +1,132 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.geotools.feature.IllegalAttributeException;
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+import org.opengis.filter.Filter;
+
+
+/**
+ * Basic support for a  FeatureReader<SimpleFeatureType, SimpleFeature> that does filtering.  I think that
+ * filtering should perhaps be done in the AttributeReader.  I'm still having
+ * a bit of trouble with the split between attributeReader and featureReader
+ * as to where the hooks for advanced processing like filtering should take
+ * place.  See my note on hasNext(), as the method is currently broken and
+ * there are more optimizations that could take place if we had a
+ * FilteringAttributeReader.  So this class may go, but I thought I'd put the
+ * ideas into code.
+ * 
+ * <p>
+ * Jody here - changed hasNext() to peek as required.
+ * </p>
+ *
+ * @author Chris Holmes
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/FilteringFeatureReader.java $
+ * @version $Id: FilteringFeatureReader.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public class FilteringFeatureReader<T extends FeatureType, F extends Feature> implements DelegatingFeatureReader<T,F> {
+    protected final FeatureReader<T, F> featureReader;
+    protected final Filter filter;
+    protected F next;
+
+    /**
+     * Creates a new instance of AbstractFeatureReader
+     * 
+     * <p>
+     * Please don't call this method with Filter.INCLUDE or Filter.EXCLUDE (consider
+     * not filtering and EmptyFeatureReader instead)
+     * </p>
+     *
+     * @param featureReader  FeatureReader<SimpleFeatureType, SimpleFeature> being filtered
+     * @param filter Filter used to limit the results of featureReader
+     */
+    public FilteringFeatureReader(FeatureReader<T, F> featureReader, Filter filter) {
+        this.featureReader = featureReader;
+        this.filter = filter;
+        next = null;
+    }
+    
+    public F next()
+        throws IOException, IllegalAttributeException, NoSuchElementException {
+        F f = null;
+
+        if (hasNext()) {
+            // hasNext() ensures that next != null
+            f = next;
+            next = null;
+
+            return f;
+        } else {
+            throw new NoSuchElementException("No such Feature exsists");
+        }
+    }
+
+    public void close() throws IOException {
+        featureReader.close();
+    }
+
+    public T getFeatureType() {
+        return featureReader.getFeatureType();
+    }
+
+    /**
+     * Query for additional content.
+     * 
+     * <p>
+     * This class will peek ahead to see if there is additional content.
+     * </p>
+     * 
+     * <p>
+     * Chris has pointed out that we could make use of AttributeReader based filtering:<br>
+     * <i>"Also doing things in the Attribute Reader would allow us to do the
+     * smart filtering, only looking at the attributes needed for comparison,
+     * whereas doing filtering here means we have to create an entire feature
+     * each time."</i>
+     * </p>
+     *
+     * @return <code>true</code> if we have additional content
+     *
+     * @throws IOException If the reader we are filtering encounters a problem
+     * @throws DataSourceException See IOException
+     */
+    public boolean hasNext() throws IOException {
+        if (next != null) {
+            return true;
+        }
+        try {
+            F peek;
+
+            while (featureReader.hasNext()) {
+                peek = featureReader.next();
+
+                if (filter.evaluate(peek)) {
+                    next = peek;
+                    return true;
+                }                                
+            }
+        } catch (IllegalAttributeException e) {
+            throw new DataSourceException("Could not peek ahead", e);
+        }
+        return next != null;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FilteringFeatureWriter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FilteringFeatureWriter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/FilteringFeatureWriter.java	(revision 28000)
@@ -0,0 +1,161 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+
+
+/**
+ * Filtering is performed on this hasNext() method.
+ * 
+ * <p>
+ * This implementation writes out content furing the hasNext() method. This
+ * allows the implementation to "peek" ahead.
+ * </p>
+ * 
+ * <p>
+ * This FeatureWriter does not support the addition of new content.
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/FilteringFeatureWriter.java $
+ */
+public class FilteringFeatureWriter implements FeatureWriter<SimpleFeatureType, SimpleFeature> {
+    FeatureWriter<SimpleFeatureType, SimpleFeature> writer;
+    Filter filter;
+    SimpleFeature next = null; // next feature as peeked by hasNext()
+    SimpleFeature current = null; // holds current Feature returned to user
+
+    public FilteringFeatureWriter(FeatureWriter<SimpleFeatureType, SimpleFeature> writer, Filter filter) {
+        this.writer = writer;
+        this.filter = filter;
+    }
+
+    public SimpleFeatureType getFeatureType() {
+        return writer.getFeatureType();
+    }
+
+    public SimpleFeature next() throws IOException {
+        if (hasNext()) {
+            // use hasNext() to and peek ahead
+            // 
+            current = next;
+            next = null;
+
+            return current;
+        }
+            // FilteringFeatureWriter Does not support the creation
+            // of new content
+            throw new NoSuchElementException(
+                "FeatureWriter does not have additional content");
+    }
+
+    public void remove() throws IOException {
+        if (writer == null) {
+            throw new IOException("FeatureWriter has been closed");
+        }
+
+        if (current == null) {
+            // We do not have a current Feature
+            // Either:
+            // - we have not started yet
+            // - hasNext() has already skipped current
+            // - write() has already writen current
+            // - remove() has already deleted current
+            throw new IOException("No feature available to remove");
+        }
+
+        current = null;
+        writer.remove();
+    }
+
+    public void write() throws IOException {
+        if (writer == null) {
+            throw new IOException("FeatureWriter has been closed");
+        }
+
+        if (current == null) {
+            // We do not have a current Feature
+            // Either:
+            // - we have not started yet
+            // - hasNext() has already skipped current
+            // - write() has already writen current
+            // - remove() has already deleted current
+            throw new IOException("No feature available to write");
+        }
+
+        writer.write();
+        current = null;
+    }
+
+    /**
+     * Query if we have more content.
+     *
+     * @return true if writer has additional content
+     *
+     * @throws IOException If writer we are filtering encounters a problem
+     */
+    public boolean hasNext() throws IOException {
+        if (next != null) {
+            return true; // we found next already
+        }
+
+        if (writer == null) {
+            return false; // writer is closed
+        }
+
+        if (current != null) {
+            // we are skipping ahead, the user will lose
+            // any changes to current
+            current = null;
+        }
+
+        SimpleFeature peek;
+
+        while (writer.hasNext()) {
+            peek = writer.next();
+
+            if (filter.evaluate(peek)) {
+                next = peek;
+
+                return true; // we have a match!
+            }
+        }
+
+        return false;
+    }
+
+    public void close() throws IOException {
+        if (writer != null) {
+            writer.close();
+            writer = null;
+        }
+
+        if (filter != null) {
+            filter = null;
+        }
+
+        current = null;
+        next = null;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/InProcessLockingManager.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/InProcessLockingManager.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/InProcessLockingManager.java	(revision 28000)
@@ -0,0 +1,691 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.geotools.data.Transaction.State;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+
+/**
+ * Provides In-Process FeatureLocking support for DataStore implementations.
+ * 
+ * <p>
+ * If at all possible DataStore implementations should provide a real Feature
+ * Locking support that is persisted to disk or database and resepected by
+ * other processes.
+ * </p>
+ * 
+ * <p>
+ * This class provides a stop gap solution that implementations may use for
+ * GeoServer compatability.
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research
+ * @author Chris Holmes, TOPP
+ *
+ * @task REVISIT: I'm not sure that the map within a map is a good idea, it
+ *       makes things perhaps too complicated.  A nasty bug came about with
+ *       releasing, as allLocks put locks into a new collection, and the
+ *       iterator just removed them from that set instead of from the storage.
+ *       This is now fixed, but the loop to do it is really damn complex.
+ *       I'm not sure of the solution, but there should be something that is
+ *       less confusing.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/InProcessLockingManager.java $
+ */
+public class InProcessLockingManager implements LockingManager {
+
+    /** lockTable access by typeName stores Transactions or MemoryLocks */
+    protected Map lockTables = new HashMap();
+
+    /**
+     * Aquire lock on featureID.
+     * 
+     * <p>
+     * This method will fail if Lock is already held by another.
+     * </p>
+     *
+     * @param typeName TypeName storing feature
+     * @param featureID FeatureID to lock
+     * @param transaction Transaction to lock against
+     * @param featureLock FeatureLock describing lock request
+     *
+     * @throws FeatureLockException Indicates a problem with the lock request
+     */
+    public synchronized void lockFeatureID(String typeName, String featureID,
+        Transaction transaction, FeatureLock featureLock)
+        throws FeatureLockException {
+        Lock lock = getLock(typeName, featureID);
+
+        // This is a loop so we can wait on Transaction Locks
+        //
+        while (lock != null) {
+            // we have a conflict
+            if (lock instanceof TransactionLock) {
+                TransactionLock tlock = (TransactionLock) lock;
+
+                if (transaction == tlock.transaction) {
+                    // lock already held by this transacstion
+                    // we could just consider returning here
+                    //
+                    throw new FeatureLockException("Transaction Lock is already held by this Transaction",
+                        featureID);
+                } else {
+                    // we should wait till it is available and then grab
+                    // the lock
+                    try {
+                        synchronized (tlock) {
+                            tlock.wait();
+                        }
+
+                        lock = getLock(typeName, featureID);
+                    } catch (InterruptedException interupted) {
+                        throw new FeatureLockException("Interupted while waiting for Transaction Lock",
+                            featureID, interupted);
+                    }
+                }
+            } else if (lock instanceof MemoryLock) {
+                MemoryLock mlock = (MemoryLock) lock;
+                throw new FeatureLockException(
+                    "Feature Lock is held by Authorization " + mlock.authID,
+                    featureID);
+            } else {
+                throw new FeatureLockException("Lock is already held " + lock,
+                    featureID);
+            }
+        }
+
+        // Lock is Available
+        //
+        lock = createLock(transaction, featureLock);
+        locks(typeName).put(featureID, lock);
+    }
+
+    /**
+     * Lock for typeName & featureID if it exists.
+     * 
+     * <p>
+     * This method will not return expired locks.
+     * </p>
+     *
+     * @param typeName
+     * @param featureID
+     *
+     * @return Lock if exists, or null
+     */
+    protected Lock getLock(String typeName, String featureID) {
+        Map locks = locks(typeName);
+        //LOGGER.info("checking for lock " + typeName + ", " + featureID
+        //    + " in locks " + locks);
+
+        synchronized (locks) {
+            if (locks.containsKey(featureID)) {
+                Lock lock = (Lock) locks.get(featureID);
+
+                if (lock.isExpired()) {
+                    locks.remove(featureID);
+                    //LOGGER.info("returning null");
+
+                    return null;
+                } else {
+                    //LOGGER.info("returing " + lock);
+
+                    return lock;
+                }
+            } else {
+                //LOGGER.info("locks did not contain key, returning null");
+
+                // not found
+                return null;
+            }
+        }
+    }
+
+    /**
+     * Creates the right sort of In-Process Lock.
+     *
+     * @param transaction
+     * @param featureLock
+     *
+     * @return In-Process Lock
+     *
+     * @throws FeatureLockException When a Transaction  lock is requested
+     *         against Transaction.AUTO_COMMIT
+     */
+    protected synchronized Lock createLock(Transaction transaction,
+        FeatureLock featureLock) throws FeatureLockException {
+        if (featureLock == FeatureLock.TRANSACTION) {
+            // we need a Transacstion Lock
+            if (transaction == Transaction.AUTO_COMMIT) {
+                throw new FeatureLockException(
+                    "We cannot issue a Transaction lock against AUTO_COMMIT");
+            }
+
+            TransactionLock lock = (TransactionLock) transaction.getState(this);
+
+            if (lock == null) {
+                lock = new TransactionLock();
+                transaction.putState(this, lock);
+
+                return lock;
+            } else {
+                return lock;
+            }
+        } else {
+            return new MemoryLock(featureLock);
+        }
+    }
+
+    /**
+     * Access to a Map of locks for typeName
+     *
+     * @param typeName typeName
+     *
+     * @return Map of Transaction or MemoryLock by featureID
+     */
+    protected Map locks(String typeName) {
+        synchronized (lockTables) {
+            if (lockTables.containsKey(typeName)) {
+                return (Map) lockTables.get(typeName);
+            } else {
+                Map locks = new HashMap();
+                lockTables.put(typeName, locks);
+
+                return locks;
+            }
+        }
+    }
+
+    /**
+     * Set of all locks.
+     *
+     * @return Set of all locks
+     */
+    protected Set allLocks() {
+        synchronized (lockTables) {
+            Set set = new HashSet();
+            Map fidLocks;
+
+            for (Iterator i = lockTables.values().iterator(); i.hasNext();) {
+                fidLocks = (Map) i.next();
+                set.addAll(fidLocks.values());
+            }
+
+            return set;
+        }
+    }
+
+    /**
+     * Checks mutability of featureID for this transaction.
+     * 
+     * <p>
+     * Two behaviors are defined by FeatureLocking:
+     * </p>
+     * 
+     * <ul>
+     * <li>
+     * TransactionLock (Blocking): lock held by a Transaction<br>
+     * Authorization is granted to the Transaction holding the Lock. Conflict
+     * will result in a block until the Transaction holding the lock
+     * completes. (This behavior is equivalent to a Database row-lock, or a
+     * java synchronized statement)
+     * </li>
+     * <li>
+     * FeatureLock (Error): lock held by a FeatureLock<br>
+     * Authorization is based on the set of Authorization IDs held by the
+     * provided Transaction. Conflict will result in an error.  (This behavior
+     * is equivalent to the WFS locking specification)
+     * </li>
+     * </ul>
+     * 
+     * <p>
+     * Right now we are just going to error out with an exception
+     * </p>
+     *
+     * @param typeName Feature type to check against
+     * @param featureID FeatureID to check
+     * @param transaction Provides Authorization
+     *
+     * @throws FeatureLockException If transaction does not have sufficient
+     *         authroization
+     */
+    public void assertAccess(String typeName, String featureID,
+        Transaction transaction) throws FeatureLockException {
+        Lock lock = getLock(typeName, featureID);
+
+        //LOGGER.info("asserting access on lock for " + typeName + ", fid: "
+	//  + featureID + ", transaction: " + transaction + ", lock " + lock);
+
+        if ((lock != null) && !lock.isAuthorized(transaction)) {
+            throw new FeatureLockException(
+                "Transaction does not have authorization for " + typeName + ":"
+                + featureID);
+        }
+    }
+
+    /**
+     * Provides a wrapper on the provided writer that checks locks.
+     *
+     * @param writer FeatureWriter requiring access control
+     * @param transaction Transaction being used
+     *
+     * @return FeatureWriter with lock checking
+     */
+    public FeatureWriter<SimpleFeatureType, SimpleFeature> checkedWriter(final FeatureWriter<SimpleFeatureType, SimpleFeature> writer,
+        final Transaction transaction) {
+        SimpleFeatureType featureType = writer.getFeatureType();
+        final String typeName = featureType.getTypeName();
+
+        return new DelegatingFeatureWriter<SimpleFeatureType, SimpleFeature>() {
+                SimpleFeature live = null;
+                
+                public SimpleFeatureType getFeatureType() {
+                    return writer.getFeatureType();
+                }
+
+                public SimpleFeature next() throws IOException {
+                    live = writer.next();
+
+                    return live;
+                }
+
+                public void remove() throws IOException {
+                    if (live != null) {
+                        assertAccess(typeName, live.getID(), transaction);
+                    }
+
+                    writer.remove();
+                    live = null;
+                }
+
+                public void write() throws IOException {
+                    if (live != null) {
+                        assertAccess(typeName, live.getID(), transaction);
+                    }
+
+                    writer.write();
+                    live = null;
+                }
+
+                public boolean hasNext() throws IOException {
+                    live = null;
+
+                    return writer.hasNext();
+                }
+
+                public void close() throws IOException {
+                    live = null;
+                    writer.close();
+                }
+            };
+    }
+
+    /**
+     * Release indicated featureID, must have correct authroization.
+     *
+     * @param typeName
+     * @param featureID
+     * @param transaction
+     * @param featureLock
+     *
+     * @throws IOException If lock could not be released
+     */
+    public synchronized void unLockFeatureID(String typeName, String featureID,
+        Transaction transaction, FeatureLock featureLock)
+        throws IOException {
+        assertAccess(typeName, featureID, transaction);
+        locks(typeName).remove(featureID);
+    }
+
+    /**
+     * Refresh locks held by the authorization <code>authID</code>.
+     * 
+     * <p>
+     * (remember that the lock may have expired)
+     * </p>
+     *
+     * @param authID Authorization identifing Lock to refresh
+     * @param transaction Transaction with authorization for lockID
+     *
+     * @return <code>true</code> if lock was found and refreshed
+     *
+     * @throws IOException If transaction not authorized to refresh authID
+     * @throws IllegalArgumentException If authID or transaction not provided
+     */
+    public synchronized boolean refresh(String authID, Transaction transaction)
+        throws IOException {
+        if (authID == null) {
+            throw new IllegalArgumentException("lockID required");
+        }
+
+        if ((transaction == null) || (transaction == Transaction.AUTO_COMMIT)) {
+            throw new IllegalArgumentException(
+                "Tansaction required (with authorization for " + authID + ")");
+        }
+
+        Lock lock;
+        boolean refresh = false;
+
+        for (Iterator i = allLocks().iterator(); i.hasNext();) {
+            lock = (Lock) i.next();
+
+            if (lock.isExpired()) {
+                i.remove();
+            } else if (lock.isMatch(authID)) {
+                if (lock.isAuthorized(transaction)) {
+                    lock.refresh();
+                    refresh = true;
+                } else {
+                    throw new IOException("Not authorized to refresh " + lock);
+                }
+            }
+        }
+
+        return refresh;
+    }
+
+    /**
+     * Release locks held by the authorization <code>authID</code>.
+     * 
+     * <p>
+     * (remember that the lock may have expired)
+     * </p>
+     *
+     * @param authID Authorization identifing Lock to release
+     * @param transaction Transaction with authorization for lockID
+     *
+     * @return <code>true</code> if lock was found and released
+     *
+     * @throws IOException If transaction not authorized to release authID
+     * @throws IllegalArgumentException If authID or transaction not provided
+     */
+    public boolean release(String authID, Transaction transaction)
+        throws IOException {
+        //LOGGER.info("release called on lock: " + authID + ", trans: "
+	//  + transaction);
+
+        if (authID == null) {
+            throw new IllegalArgumentException("lockID required");
+        }
+
+        if ((transaction == null) || (transaction == Transaction.AUTO_COMMIT)) {
+            throw new IllegalArgumentException(
+                "Tansaction required (with authorization for " + authID + ")");
+        }
+
+        Lock lock;
+        boolean release = false;
+
+        //This could be done more efficiently, and perhaps cleaner,
+        //but these maps within a map are just nasty.  The previous way of
+        //calling iterator.remove() didn't actually remove anything, as it
+        //was only iterating through the values of a map, which I believe
+        //java just copies, so it's immutable.  Or perhaps we just moved
+        //through too many iterator layers...
+        for (Iterator i = lockTables.values().iterator(); i.hasNext();) {
+            Map fidMap = (Map) i.next();
+            Set unLockedFids = new HashSet();
+
+            for (Iterator j = fidMap.keySet().iterator(); j.hasNext();) {
+                String fid = (String) j.next();
+                lock = (Lock) fidMap.get(fid);
+                //LOGGER.info("checking lock " + lock + ", is match "
+                //    + lock.isMatch(authID));
+
+                if (lock.isExpired()) {
+                    unLockedFids.add(fid);
+
+                    //fidMap.remove(fid); concurrent modification error.
+                } else if (lock.isMatch(authID)) {
+                    //LOGGER.info("matches, is authorized: "
+                    //    + lock.isAuthorized(transaction));
+
+                    if (lock.isAuthorized(transaction)) {
+                        unLockedFids.add(fid);
+
+                        //fidMap.remove(fid);
+                        release = true;
+                    } else {
+                        throw new IOException("Not authorized to release "
+                            + lock);
+                    }
+                }
+            }
+
+            for (Iterator k = unLockedFids.iterator(); k.hasNext();) {
+                fidMap.remove(k.next());
+            }
+        }
+
+        return release;
+    }
+
+    /**
+     * Implment lockExists.
+     * 
+     * <p>
+     * Remeber lock may have expired.
+     * </p>
+     *
+     * @param authID
+     *
+     * @return true if lock exists for authID
+     *
+     * @see org.geotools.data.LockingManager#lockExists(java.lang.String)
+     */
+    public boolean exists(String authID) {
+        //LOGGER.info("checking existence of lock: " + authID + " in "
+        //    + allLocks());
+
+        if (authID == null) {
+            return false;
+        }
+
+        Lock lock;
+
+        for (Iterator i = allLocks().iterator(); i.hasNext();) {
+            lock = (Lock) i.next();
+
+            if (lock.isExpired()) {
+                i.remove();
+            } else if (lock.isMatch(authID)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Represents In-Process locks for Transactions or FeatureLocks.
+     *
+     * @author Jody Garnett, Refractions Research
+     */
+    interface Lock {
+        /**
+         * Check if lock has expired, it will be removed if so
+         *
+         * @return <code>true</code> if Lock has gone stale
+         */
+        boolean isExpired();
+
+        /**
+         * Check if authID matches this lock
+         *
+         * @return <code>true</code> if authID matches
+         */
+        boolean isMatch(String authID);
+
+        /**
+         * Check if transaction is authorized for this lock
+         *
+         * @return <code>true</code> if transaction is authorized
+         */
+        boolean isAuthorized(Transaction transaction);
+
+        /**
+         * Refresh lock
+         */
+        void refresh();
+    }
+
+    /**
+     * Class representing TransactionDuration locks.
+     * 
+     * <p>
+     * Implements Transasction.State so it can remomve itself when commit() or
+     * rollback() is called.
+     * </p>
+     * 
+     * <p>
+     * Threads may wait on this object, it will notify when it releases the
+     * lock due to a commit or rollback opperation
+     * </p>
+     *
+     * @author Jody Garnett, Refractions Research
+     */
+    class TransactionLock implements Lock, State {
+        /** This will be non-null while lock is fresh */
+        Transaction transaction;
+
+        /**
+         * A new TranasctionLock for use.
+         * 
+         * <p>
+         * The lock will be stale until added to Tranasction.putState( key,
+         * Lock )
+         * </p>
+         */
+        TransactionLock() {
+        }
+
+        /**
+         * Transaction locks do not match authIDs
+         *
+         * @param authID Authorization ID being checked
+         *
+         * @return <code>false</code>
+         */
+        public boolean isMatch(String authID) {
+            return false;
+        }
+
+        /**
+         * <code>true</code> if Lock has gone stale
+         *
+         * @return <code>true</code> if lock is stale
+         */
+        public boolean isExpired() {
+            return transaction != null;
+        }
+
+        /**
+         * TransactionLocks do not need to be refreshed
+         */
+        public void refresh() {
+            // do not need to implement   
+        }
+
+        /**
+         * <code>true </code> if tranasction is the same one that provided this
+         * lock
+         *
+         * @param transaction Transaction to check authorization against
+         *
+         * @return true if transaction is authorized
+         */
+        public boolean isAuthorized(Transaction transaction) {
+            return this.transaction == transaction;
+        }
+
+        public String toString() {
+            return "TranasctionLock(" + !isExpired() + ")";
+        }
+    }
+
+    /**
+     * Class referenced by featureID in locks( typeName).
+     * 
+     * <p>
+     * FeatureLock is the request - MemoryLock is the result.
+     * </p>
+     *
+     * @author Jody Garnett, Refractions Reasearch Inc.
+     */
+    class MemoryLock implements Lock {
+        String authID;
+        long duration;
+        long expiry;
+
+        MemoryLock(FeatureLock lock) {
+            this(lock.getAuthorization(), lock.getDuration());
+        }
+
+        MemoryLock(String id, long length) {
+            authID = id;
+            this.duration = length;
+            expiry = System.currentTimeMillis() + length;
+        }
+
+        public boolean isMatch(String id) {
+            return authID.equals(id);
+        }
+
+        public void refresh() {
+            expiry = System.currentTimeMillis() + duration;
+        }
+
+        public boolean isExpired() {
+            if (duration == 0) {
+                return false; // perma lock
+            }
+
+            long now = System.currentTimeMillis();
+
+            return now >= expiry;
+        }
+
+        public boolean isAuthorized(Transaction transaction) {
+            //LOGGER.info("checking authorization on " + this.toString() + ", "
+	    //  + ((transaction != Transaction.AUTO_COMMIT)
+	    //  ? transaction.getAuthorizations().toString() : "autocommit"));
+
+            return (transaction != Transaction.AUTO_COMMIT)
+            && transaction.getAuthorizations().contains(authID);
+        }
+
+        public String toString() {
+            if (duration == 0) {
+                return "MemoryLock(" + authID + "|PermaLock)";
+            }
+
+            long now = System.currentTimeMillis();
+            long delta = (expiry - now);
+            long dur = duration;
+
+            return "MemoryLock(" + authID + "|" + delta + "ms|" + dur + "ms)";
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/LockingManager.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/LockingManager.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/LockingManager.java	(revision 28000)
@@ -0,0 +1,116 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+
+
+/**
+ * This class describes a featureID based locking service.
+ *
+ * <p>
+ * AbstractFeatureLocking, and others, may use this API to request locks on the
+ * basis of FeatureID.
+ * </p>
+ *
+ * <p>
+ * This class is also used as a public api to manage locks.
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/LockingManager.java $
+ */
+public interface LockingManager {
+    /**
+     * Check if any locks exist held by the authorization <code>lockID</code>.
+     *
+     * <p>
+     * (remember that the lock may have expired)
+     * </p>
+     *
+     * @param authID Authorization for lock
+     *
+     * @return <code>true</code> if lock was found
+     */
+    boolean exists(String authID);
+
+    /**
+     * Release locks held by the authorization <code>lockID</code>.
+     *
+     * <p>
+     * (remember that the lock may have expired)
+     * </p>
+     *
+     * @param authID Authorization for lock
+     * @param transaction Transaction with authorization for lockID
+     *
+     * @return <code>true</code> if lock was found and released
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    boolean release(String authID, Transaction transaction)
+        throws IOException;
+
+    /**
+     * Refresh locks held by the authorization <code>lockID</code>.
+     *
+     * <p>
+     * All features locked with the provied <code>lockID</code> will be locked
+     * for additional time (the origional duration requested).
+     * </p>
+     *
+     * <p>
+     * (remember that the lock may have expired)
+     * </p>
+     *
+     * @param authID Authorization for lock
+     * @param transaction Transaction with authorization for lockID
+     *
+     * @return <code>true</code> if lock was found and refreshed
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    boolean refresh(String authID, Transaction transaction)
+        throws IOException;
+
+    /**
+     * FeatureID based unlocking.
+     *
+     * @param typeName
+     * @param authID
+     * @param transaction
+     * @param featureLock
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    void unLockFeatureID(String typeName, String authID, Transaction transaction,
+        FeatureLock featureLock) throws IOException;
+
+    /**
+     * FeatureID based locking.
+     *
+     * @param typeName
+     * @param authID
+     * @param transaction
+     * @param featureLock
+     *
+     * @throws IOException DOCUMENT ME!
+     */
+    void lockFeatureID(String typeName, String authID, Transaction transaction,
+        FeatureLock featureLock) throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/MaxFeatureReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/MaxFeatureReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/MaxFeatureReader.java	(revision 28000)
@@ -0,0 +1,83 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.geotools.feature.IllegalAttributeException;
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+
+
+/**
+ * Basic support for a  FeatureReader<SimpleFeatureType, SimpleFeature> that limits itself to the number of
+ * features passed in.
+ *
+ * @author Chris Holmes
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/MaxFeatureReader.java $
+ * @version $Id: MaxFeatureReader.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public class MaxFeatureReader<T extends FeatureType, F extends Feature> implements DelegatingFeatureReader<T,F>{
+    
+    protected final  FeatureReader<T, F> featureReader;
+    protected final int maxFeatures;
+    protected int counter = 0;
+
+    /**
+     * Creates a new instance of MaxFeatureReader
+     *
+     * @param featureReader FeatureReader being maxed
+     * @param maxFeatures DOCUMENT ME!
+     */
+    public MaxFeatureReader(FeatureReader<T, F> featureReader, int maxFeatures) {
+        this.featureReader = featureReader;
+        this.maxFeatures = maxFeatures;
+    }
+    
+    public F next()
+        throws IOException, IllegalAttributeException, NoSuchElementException {
+        if (hasNext()) {
+            counter++;
+
+            return featureReader.next();
+        } else {
+            throw new NoSuchElementException("No such Feature exists");
+        }
+    }
+
+    public void close() throws IOException {
+        featureReader.close();
+    }
+
+    public T getFeatureType() {
+        return featureReader.getFeatureType();
+    }
+
+    /**
+     * <p></p>
+     *
+     * @return <code>true</code> if the featureReader has not passed the max
+     *         and still has more features.
+     *
+     * @throws IOException If the reader we are filtering encounters a problem
+     */
+    public boolean hasNext() throws IOException {
+        return (featureReader.hasNext() && (counter < maxFeatures));
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/Parameter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/Parameter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/Parameter.java	(revision 28000)
@@ -0,0 +1,139 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.geotools.referencing.CRS;
+import org.opengis.util.InternationalString;
+
+/**
+ * A Parameter defines information about a valid process parameter.
+ *
+ * @author gdavis
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/Parameter.java $
+ */
+public class Parameter<T> {
+    /**
+     * This is the key (ie machine readable text) used to represent this parameter in a
+     * java.util.Map.
+     * 
+     * @param key (or machine readable name) for this parameter.
+     */
+    public final String key;
+    
+    /**
+     * Human readable description of this parameter.
+     */
+    public final InternationalString description;
+    
+    /**
+     * Class binding for this parameter.
+     * <p>
+     * When a value is supplied for this key it should be of the provided type.
+     */
+    public final Class<T> type;
+    
+    /** Can the value be missing? Or is null allowed...
+     *@return true if a value is required to be both present and non null
+     **/
+    public final boolean required;
+    
+    /**
+     * Hints for the user interface
+     */
+    
+    /**
+     * File extension expected - "shp", "jpg", etc...
+     */
+    public static final String EXT = "ext";
+    
+    /**
+     * Level or Category of the parameter - "user", "advanced", "program"
+     * <p>
+     * <ul>
+     * <li>user - should be shown to all users and is used every time.<br>
+     *     example: user name and password
+     * </li>
+     * <li>advanced - advanced or expert parameter used in special cases<br>
+     *     example: choice between get and post requests for WFS
+     * </li>
+     * <li>program - intended for programs often tweaking settings for performance<br>
+     *     example: JDBC datasource for which it is hard for a user to type in
+     * </li>
+     * </ul>
+     */
+    public static final String LEVEL = "level";
+    
+    /**
+     * Refinement of type; such as the FeatureType of a FeatureCollection, or component type of a List.
+     * <p>
+     * This information is supplied (along with type) to allow a process implementor communicate
+     * additional restrictions on the allowed value beyond the strict type.
+     * <p>
+     * The following keys are understood at this time: LENGTH, FEATURE_TYPE, CRS, ELEMENT
+     * .. additional keys will be documented as static final fields over time.
+     * <p>
+     * Any restrictions mentioned here should be mentioned as part of your
+     * parameter description. This metadata is only used to help restrict what
+     * the user enters; not all client application will understand and respect
+     * these keys - please communicate with your end-user.
+     * 
+     * @see CRS
+     * @see ELEMENT
+     * @see FEATURE_TYPE
+     * @see IS_PASSWORD
+     * @see LENGTH
+     * @see MAX
+     * @see MIN
+     */
+    public final Map<String, Object> metadata;
+
+    /**
+     * Addition of optional parameters
+     * @param key machine readable key for use in a java.util.Map
+     * @param type Java class for the expected value
+     * @param title Human readable title used for use in a user interface
+     * @param description Human readable description
+     * @param required true if the value is required
+     * @param min Minimum value; or null if not needed
+     * @param max Maximum value; or null if not needed
+     * @param sample Sample value; may be used as a default in a user interface
+     * @param metadata Hints to the user interface (read the javadocs for each metadata key)
+     * 
+     * @see CRS
+     * @see ELEMENT
+     * @see FEATURE_TYPE
+     * @see IS_PASSWORD
+     * @see LENGTH
+     * @see MAX
+     * @see MIN
+     */
+    public Parameter(String key, Class<T> type, InternationalString title,
+    				 InternationalString description,
+                     boolean required, int min, int max, Object sample, 
+                     Map<String,Object> metadata) {
+        this.key = key;
+        this.type = type;
+        this.description = description;
+        this.required = required;
+        this.metadata = metadata == null ? null : Collections.unmodifiableMap(metadata);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/Query.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/Query.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/Query.java	(revision 28000)
@@ -0,0 +1,824 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory;
+import org.opengis.filter.expression.PropertyName;
+import org.opengis.filter.sort.SortBy;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.factory.Hints;
+
+/**
+ * Encapsulates a request for data, typically as:
+ * <pre><code>
+ * Query query = ...
+ * myFeatureSource.getFeatures(query);
+ * </code></pre>
+ *
+ * The query class is based on the Web Feature Server specification and offers a 
+ * few interesting capabilities such as the ability to sort results and use a filter
+ * (similar to the WHERE clause in SQL).
+ * <p>
+ * Additional capabilities:
+ * <ul>
+ * <li>
+ * {@linkplain #setMaxFeatures(int)} and {@linkplain #setStartIndex(Integer)} can be used
+ * implement 'paging' through the data source's content. This is useful if, for example, the
+ * FeatureSource has an upper limit on the number of features it can return in a single
+ * request or you are working with limited memory.
+ * </li>
+ * <li>
+ * {@linkplain #setHandle(String)} can be used to give the query a mnemonic name
+ * which will appear in error reporing and logs.
+ * </li>
+ * <li>
+ * {@linkplain #setCoordinateSystem(CoordinateReferenceSystem)} is used to to specify the
+ * coordinate system that retrieved features will be "forced" into.
+ * This is often used to correct a feature source when the application and the data
+ * format have different ideas about the coordinate system (for example, the "axis order"
+ * issue).
+ * </li>
+ * <li>
+ * {@linkplain #setCoordinateSystemReproject(CoordinateReferenceSystem)} is used to ask for
+ * the retrieved features to be reproejcted. 
+ * </li>
+ * </ul>
+ *
+ * Vendor specific:
+ * <ul>
+ * <li>{@linkplain setHints(Hints)} is used to specify venfor specific capabilities
+ * provided by a feature source implementation.
+ * </li>
+ * </ul>
+ * Example:<pre><code>
+ * Filter filter = CQL.toFilter("NAME like '%land'");
+ * Query query = new Query( "countries", filter );
+ *
+ * FeatureCollection features = featureSource.getFeatures( query );
+ * </code></pre>
+ *
+ * @author Chris Holmes
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/Query.java $
+ * @version $Id: Query.java 37280 2011-05-24 07:53:02Z mbedward $
+ */
+public class Query {
+    /**
+     * Constant (actually null) used to represent no namespace restrictions on the returned result, should be considered ANY_URI
+     */
+    public static final URI NO_NAMESPACE = null;
+
+    /** So getMaxFeatures does not return null we use a very large number. */
+    public static final int DEFAULT_MAX = Integer.MAX_VALUE;
+
+    /**
+     * Implements a query that will fetch all features from a datasource. This
+     * query should retrieve all properties, with no maxFeatures, no
+     * filtering, and the default featureType.
+     */
+    public static final Query ALL = new ALLQuery();
+
+    /**
+     * A constant (empty String array) that can be used with
+     * {@linkplain #setPropertyNames(String[])} to indicate that no
+     * properties are to be retrieved.
+     * <p>
+     * Note the query will still return a result - limited to FeatureIDs.
+     * </p>
+     */
+    public static final String[] NO_NAMES = new String[0];
+
+    /**
+     * A constant (value {@code null}) that can be used with
+     * {@linkplain #setPropertyNames(String[])} to indicate that all properties
+     * are to be retrieved.
+     */
+    public static final String[] ALL_NAMES = null;
+    
+    /**
+     * A constant (value {@code null}) that can be used with
+     * {@linkplain #setProperties(Collection<PropertyName>)} to indicate that all properties
+     * are to be retrieved.
+     */
+    public static final List<PropertyName> ALL_PROPERTIES = null;
+
+    /** The properties to fetch */
+    protected List<PropertyName> properties;
+
+    /** The maximum numbers of features to fetch */
+    protected int maxFeatures = Query.DEFAULT_MAX;
+
+    /** The index of the first feature to process */
+    protected Integer startIndex = null;
+    
+    /** The filter to constrain the request. */
+    protected Filter filter = Filter.INCLUDE;
+
+    /** The typeName to get */
+    protected String typeName;
+
+    /** The namespace to get */
+    protected URI namespace =Query.NO_NAMESPACE;
+
+    /** The handle associated with this query. */
+    protected String handle;
+
+    /** Coordinate System associated with this query */
+    protected CoordinateReferenceSystem coordinateSystem;
+    
+    /** Reprojection associated associated with this query */
+    protected CoordinateReferenceSystem coordinateSystemReproject;
+    
+    /** Sorting for the query */
+    protected SortBy[] sortBy;
+    
+    /** The version according to WFS 1.0 and 1.1 specs */
+    protected String version;
+    
+    /** The hints to be used during query execution */
+    protected Hints hints;
+    
+    /**
+     * Default constructor. Use setter methods to configure the Query
+     * before use (the default Query will retrieve all features).
+     */
+    public Query() {
+        // no arg
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param typeName the name of the featureType to retrieve
+     */
+    public Query( String typeName ){
+        this( typeName, Filter.INCLUDE );
+    }
+    
+    /**
+     * Constructor.
+     * 
+     * @param typeName the name of the featureType to retrieve.
+     * @param filter the OGC filter to constrain the request.
+     */
+    public Query(String typeName, Filter filter) {
+        this( typeName, filter, Query.ALL_NAMES );        
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param typeName the name of the featureType to retrieve.
+     * @param filter the OGC filter to constrain the request.
+     * @param properties an array of the properties to fetch.
+     */
+    public Query(String typeName, Filter filter, String[] properties) {
+        this( typeName, null, filter, Query.DEFAULT_MAX, properties, null );        
+    }
+    
+    /**
+     * Constructor.
+     *
+     * @param typeName the name of the featureType to retrieve.
+     * @param filter the OGC filter to constrain the request.
+     * @param maxFeatures the maximum number of features to be returned.
+     * @param propNames an array of the properties to fetch.
+     * @param handle the name to associate with this query.
+     */
+    public Query(String typeName, Filter filter, int maxFeatures,
+        String[] propNames, String handle) {
+        this(typeName, null, filter, maxFeatures, propNames, handle );
+    }
+            
+    /**
+     * Constructor.
+     *
+     * @param typeName the name of the featureType to retrieve.
+     * @param namespace Namespace for provided typeName, or null if unspecified
+     * @param filter the OGC filter to constrain the request.
+     * @param maxFeatures the maximum number of features to be returned.
+     * @param propNames an array of the properties to fetch.
+     * @param handle the name to associate with the query.
+     */
+    public Query( String typeName, URI namespace, Filter filter, int maxFeatures,
+        String[] propNames, String handle) {
+        this.typeName = typeName;
+        this.filter = filter;
+        this.namespace = namespace;
+        this.maxFeatures = maxFeatures;
+        this.handle = handle;
+        setPropertyNames(propNames);
+    }
+    
+    /**
+     * Constructor.
+     *
+     * @param typeName the name of the featureType to retrieve.
+     * @param namespace Namespace for provided typeName, or null if unspecified
+     * @param filter the OGC filter to constrain the request.
+     * @param maxFeatures the maximum number of features to be returned.
+     * @param properties a list of the property names to fetch.
+     * @param handle the name to associate with the query.
+     */
+    public Query( String typeName, URI namespace, Filter filter, int maxFeatures,
+        List<PropertyName> propNames, String handle) {
+        this.typeName = typeName;
+        this.filter = filter;
+        this.namespace = namespace;
+        this.maxFeatures = maxFeatures;
+        this.handle = handle;
+        this.properties = propNames==null? null : new ArrayList<PropertyName>(propNames);
+    }
+    
+    /**
+     * Copy contructor.
+     *
+     * @param query the query to copy
+     */
+    public Query(Query query) {
+      this(query.getTypeName(), query.getNamespace(), query.getFilter(), query.getMaxFeatures(),
+          query.getProperties(), query.getHandle());
+      this.sortBy = query.getSortBy();
+      this.coordinateSystem = query.getCoordinateSystem();
+      this.coordinateSystemReproject = query.getCoordinateSystemReproject();
+      this.version = query.getVersion();
+      this.hints = query.getHints();
+      this.startIndex = query.getStartIndex();
+    }
+
+    /**
+     * Get the names of the properties that this Query will retrieve as part of
+     * the returned {@linkplain org.geotools.feature.FeatureCollection}.
+     *
+     * @return the attributes to be used in the returned FeatureCollection.
+     *
+     * @see #retrieveAllProperties()
+     *
+     * @task REVISIT: make a FidProperties object, instead of an array size 0.
+     *       I think Query.FIDS fills this role to some degree.
+     *       Query.FIDS.equals( filter ) would meet this need?
+     */
+    public String[] getPropertyNames() {
+        if (properties == null) {
+            return null;
+        }
+        
+        String[] propertyNames = new String[properties.size()];
+        for (int i=0; i< properties.size(); i++) {
+            PropertyName propertyName = properties.get(i);
+            if( propertyName != null){
+                String xpath = propertyName.getPropertyName();
+                propertyNames[i] = xpath;
+            }
+        }
+        return propertyNames;
+    }
+
+    /**
+     * Set the names of the properties that this Query should retrieve as part of
+     * the returned {@linkplain org.geotools.feature.FeatureCollection}.
+     * As well as an array of names, the following constants can be used:
+     * <ul>
+     * <li>
+     * {@linkplain #ALL_NAMES} to retrieve all properties.
+     * </li>
+     * <li>
+     * {@linkplain #NO_NAMES} to indicate no properties are required, just feature IDs.
+     * </li>
+     * </ul>
+     * The available properties can be determined with {@linkplain FeatureSource#getSchema()}.
+     * If properties that are not part of the source's schema are requested
+     * an exception will be thrown.
+     *
+     * @param propNames the names of the properties to retrieve or one of
+     *        {@linkplain #ALL_NAMES} or {@linkplain #NO_NAMES}.
+     */
+    public void setPropertyNames(String[] propNames) {
+        if (propNames == null) {
+            properties = ALL_PROPERTIES;
+            return;
+        }
+        
+        final FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
+        properties = new ArrayList<PropertyName>(propNames.length);
+        for (int i=0; i< propNames.length; i++) {
+            String xpath = propNames[i];
+            if(xpath != null ){
+                properties.add(ff.property(xpath));
+            }
+        }
+    }
+    
+    /**
+     * Get the names of the properties that this Query will retrieve values for
+     * as part of the returned {@linkplain org.geotools.feature.FeatureCollection}.
+     *
+     * @return the xpath expressions to be used in the returned FeatureCollection.
+     *
+     * @see #retrieveAllProperties()
+     */
+    public List<PropertyName> getProperties() {
+        if (properties == ALL_PROPERTIES) {
+            return ALL_PROPERTIES;
+        }
+        return Collections.<PropertyName>unmodifiableList(properties) ;
+    }
+    
+    /**
+     * Set the names of the properties that this Query should retrieve as part of
+     * the returned {@linkplain org.geotools.feature.FeatureCollection}.
+     * <p>
+     * The available properties can be determined with {@linkplain FeatureSource#getSchema()}.
+     * If properties that are not part of the source's schema are requested
+     * an exception will be thrown.
+     *
+     * @param propNames the names of the properties to retrieve or
+     *        {@linkplain #ALL_NAMES}; an empty List can be passed in to
+     *        indicate that only feature IDs should be retrieved
+     *
+     * @task REVISIT: This syntax is really obscure.  Consider having an fid or
+     *       featureID propertyName that datasource implementors look for
+     *       instead of looking to see if the list size is 0.
+     */
+    public void setPropertyNames(List<String> propNames) {
+        if (propNames == null) {
+            this.properties = ALL_PROPERTIES;
+            return;
+        }
+
+        final FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
+        
+        properties = new ArrayList<PropertyName>(propNames.size());
+        for (int i=0; i< propNames.size(); i++) {
+            String xpath = propNames.get(i);
+            if(xpath != null ){
+                properties.add(ff.property(xpath));
+            }
+        }
+    }
+    
+    /**
+     * Convenience method to determine if the query should retrieve all
+     * properties defined in the schema of the feature data source. This
+     * is equivalent to testing if {@linkplain #getPropertyNames()} returns
+     * {@linkplain #ALL_NAMES}.
+     *
+     * @return true if all properties will be retrieved by this Query; false
+     *         otherwise
+     */
+    public boolean retrieveAllProperties() {
+        return properties == null;
+    }
+
+    /**
+     * Get the maximum number of features that will be retrieved by this
+     * Query.
+     * <p>
+     * Note: This is the only method that is not directly out of the Query element in
+     * the WFS specification.  It is instead a part of a GetFeature request, which can
+     * hold one or more queries.  But each of those in turn will need a
+     * maxFeatures, so it is needed here.
+     * </p>
+     * <p>
+     * If the value returned here is max integer then the number of features
+     * should not be limited.
+     * 
+     * @return the maximum number of features that will be retrieved by
+     *         this query
+     */
+    public int getMaxFeatures() {
+        return this.maxFeatures;
+    }
+    
+    /**
+     * Check if this query allows an unlimited number of features to be returned.
+     * <p>
+     * @return true maxFeatures is less then zero, or equal to Integer.MAX_VALUE.
+     */
+    public boolean isMaxFeaturesUnlimited(){
+        return maxFeatures < 0 || maxFeatures == Integer.MAX_VALUE;
+    }
+
+    /**
+     * Sets the maximum number of features that should be retrieved by this query.
+     * The default is to retrieve all features.
+     *
+     * @param maxFeatures the maximum number of features to retrieve
+     */
+    public void setMaxFeatures(int maxFeatures) {
+        this.maxFeatures = maxFeatures;
+    }
+
+    /**
+     * Get the index of the first feature to retrieve.
+     *
+     * @return the index of the first feature to retrieve or {@code null}
+     * if no start index is defined.
+     */
+    public Integer getStartIndex(){
+        return this.startIndex;
+    }
+
+    /**
+     * Set the index of the first feature to retrieve. This can be used in
+     * conjuction with {@linkplain #setMaxFeatures(int) } to 'page' through
+     * a feature data source.
+     *
+     * @param startIndex index of the first feature to retrieve or {@code null}
+     *        to indicate no start index
+     *
+     * @throws IllegalArgumentException if startIndex is less than 0
+     */
+    public void setStartIndex(Integer startIndex){
+        if(startIndex != null && startIndex.intValue() < 0){
+            throw new IllegalArgumentException("startIndex shall be a positive integer: " + startIndex);
+        }
+        this.startIndex = startIndex;
+    }
+    
+    /**
+     * Gets the filter used to define constraints on the features that will be
+     * retrieved by this Query.
+     *
+     * @return The filter that defines constraints on the query.
+     */
+    public Filter getFilter() {
+        return this.filter;
+    }
+
+    /**
+     * Sets the filter to constrain the features that will be retrieved by
+     * this Query. If no filter is set all features will be retrieved (taking
+     * into account any bounds set via {@linkplain #setMaxFeatures(int) } and
+     * {@linkplain #setStartIndex(java.lang.Integer) }).
+     * <p>
+     * The default is {@linkplain Filter#INCLUDE}.
+     *
+     * @param filter the OGC filter which features must pass through to
+     *        be retrieved by this Query.
+     */
+    public void setFilter(Filter filter) {
+        this.filter = filter;
+    }
+    
+    /**
+     * Get the name of the feature type to be queried.
+     * 
+     * @return the name of the feature type to be returned with this query.
+     */
+    public String getTypeName() {
+        return this.typeName;
+    }
+
+    /**
+     * Sets the  name of the feature type to be queried.  If no typename is specified,
+     * then the data source's default type will be used. When working with sources
+     * such as shapefiles that only support one feature type this method can be ignored.
+     *
+     * @param typeName the name of the featureType to retrieve.
+     */
+    public void setTypeName(String typeName) {
+        this.typeName = typeName;
+    }
+    
+    /**
+     * Get the namespace of the feature type to be queried.
+     *
+     * @return the gml namespace of the feature type to be returned with this
+     *         query
+     */
+    public URI getNamespace() {
+        return namespace;
+    }
+
+    /**
+     * Set the namespace of the feature type to be queried.
+     * 
+     * @return the gml namespace of the feature type to be returned with this
+     *         query
+     */
+    public void setNamespace(URI namespace) {
+        this.namespace = namespace;
+    }
+    
+    /**
+     * Get the handle (mnemonic name) that will be associated with this Query.
+     * The handle is used in logging and error reporting.
+     *
+     * @return the name to refer to this query.
+     */
+    public String getHandle() {
+        return this.handle;
+    }
+
+    /**
+     * Set the handle (mnemonic name) that will be associated with this Query.
+     * The handle is used in logging and error reporting.
+     *
+     * @param handle the name to refer to this query.
+     */
+    public void setHandle(String handle) {
+        this.handle = handle;
+    }
+    
+    /**
+     * From WFS Spec:  The version attribute is included in order to
+     * accommodate systems that  support feature versioning. A value of {@linkplain #ALL}
+     * indicates that all versions of a feature should be fetched. Otherwise
+     * an integer, n, can be specified  to return the n th version of a
+     * feature. The version numbers start at '1'  which is the oldest version.
+     * If a version value larger than the largest version is specified then
+     * the latest version is return. The default action shall be for the query
+     * to return the latest version. Systems that do not support versioning
+     * can ignore the parameter and return the only version  that they have.
+     *
+     * @return the version of the feature to return, or null for latest.
+     */
+    public String getVersion() {
+        return version; 
+    }
+    
+    /**
+     * Set the version of features to retrieve where this is supported by the
+     * data source being queried.
+     * @param version
+     * @see #getVersion() getVersion() for explanation
+     * @since 2.4
+     */
+    public void setVersion(String version) {
+        this.version = version;
+    }
+    
+    /**
+     * Get the coordinate system that applies to features retrieved by this Query.
+     * By default this is the coordinate system of the features in the data source
+     * but this can be overriden via {@linkplain #setCoordinateSystem( CoordinateReferenceSystem )}.
+     *
+     * @return The coordinate system to be returned for Features from this
+     *         Query (override the set coordinate system).
+     */
+    public CoordinateReferenceSystem getCoordinateSystem() {
+        return coordinateSystem;
+    }
+
+    /**
+     * Set the coordinate system to apply to features retrieved by this Query.
+     * <p>
+     * This denotes a request to <b>temporarily</b> override the coordinate system
+     * contained in the feature data source being queried. The same coordinate
+     * values will be used, but the features retrieved will appear in this
+     * Coordinate System.
+     *
+     * <p>
+     * This change is not persistant and only applies to the features
+     * returned by this Query. If used in conjunction with {@link #getCoordinateSystemReproject()}
+     * the reprojection will occur from {@link #getCoordinateSystem()} to
+     * {@link #getCoordinateSystemReproject()}.
+     * </p>
+     *
+     * @param system the coordinate system to apply to features retrieved by this Query
+     */
+    public void setCoordinateSystem(CoordinateReferenceSystem system) {
+        coordinateSystem = system;
+    }
+
+    /**
+     * If reprojection has been requested, this returns the coordinate system
+     * that features retrieved by this Query will be reprojected into.
+     *
+     * @return the coordinate system that features will be reprojected into (if set)
+     *
+     * @see #setCoordinateSystemReproject( CoordinateReferenceSystem )
+     */
+    public CoordinateReferenceSystem getCoordinateSystemReproject() {
+        return coordinateSystemReproject;
+    }
+    
+    /**
+     * Request that features retrieved by this Query be reprojected into the
+     * given coordinate system.
+     * <p>
+     * If used in conjunction with {@link #setCoordinateSystem(CoordinateReferenceSystem)}
+     * the reprojection will occur from the overridden coordinate system to the system
+     * specified here.
+     *
+     * @return the coordinate system that features should be reprojected into
+     */
+    public void setCoordinateSystemReproject(CoordinateReferenceSystem system) {
+        coordinateSystemReproject = system;
+    }
+    
+    /**
+     * SortBy results according to indicated property and order.
+     * <p>
+     * SortBy is part of the Filter 1.1 specification, it is referenced
+     * by WFS1.1 and Catalog 2.0.x specifications and is used to organize
+     * results.
+     * </p>
+     * The SortBy's are ment to be applied in order:
+     * <ul>
+     * <li>SortBy( year, ascending )
+     * <li>SortBy( month, decsending )
+     * </ul>
+     * Would produce something like: <pre><code>
+     * [year=2002 month=4],[year=2002 month=3],[year=2002 month=2],
+     * [year=2002 month=1],[year=2003 month=12],[year=2002 month=4],
+     * </code></pre>
+     * </p>
+     * <p>
+     *
+     * SortBy should be considered at the same level of abstraction as Filter,
+     * and like Filter you may sort using properties not listed in
+     * getPropertyNames.
+     * </p>
+     *
+     * <p>
+     * At a technical level the interface SortBy2 is used to indicate the
+     * additional requirements of a GeoTools implementation. The pure
+     * WFS 1.1 specification itself is limited to SortBy.
+     * </p>
+     *
+     * @return SortBy array or order of application
+     */
+    public SortBy[] getSortBy() {
+        return sortBy;
+    } 
+
+    /**
+     * Sets the sort by information.
+     * 
+     */
+    public void setSortBy(SortBy[] sortBy) {
+        this.sortBy = sortBy;
+    }
+    
+    /**
+     * Get hints that have been set to control the query execution.
+     *
+     * @return hints that are set (may be empty)
+     *
+     * @see #setHints(Hints) setHints(Hints) for more explanation
+     */
+    public Hints getHints() {
+        if(hints == null){
+            hints = new Hints(Collections.EMPTY_MAP);
+        }
+        return hints;
+    }
+    
+    /**
+     * Set hints to control the query execution.
+     * <p>
+     * Hints can control such things as:
+     * <ul>
+     * <li> the GeometryFactory to be used
+     * <li> a generalization distance to be applied
+     * <li> the fetch size to be used in JDBC queries
+     * </ul>
+     * The set of hints supported can be found by calling
+     * {@linkplain org.geotools.data.FeatureSource#getSupportedHints() }.
+     * <p>
+     * Note: Data sources may ignore hints (depending on their values) and no
+     * mechanism currently exists to discover which hints where actually used
+     * during the query's execution.
+     * @see Hints#FEATURE_DETACHED
+     * @see Hints#JTS_GEOMETRY_FACTORY
+     * @see Hints#JTS_COORDINATE_SEQUENCE_FACTORY
+     * @see Hints#JTS_PRECISION_MODEL
+     * @see Hints#JTS_SRID
+     * @see Hints#GEOMETRY_DISTANCE
+     * @see Hints#FEATURE_2D
+     * 
+     * @param hints the hints to apply
+     */
+    public void setHints(Hints hints) {
+        this.hints = hints;
+    }
+    
+    /**
+     * Hashcode based on all parameters other than the handle.
+     *
+     * @return hascode for this Query
+     */
+    @Override
+    public int hashCode() {
+        String[] n = getPropertyNames();
+
+        return ((n == null) ? (-1)
+                                    : ((n.length == 0) ? 0 : (n.length
+                | n[0].hashCode()))) | getMaxFeatures()
+                | ((getFilter() == null) ? 0 : getFilter().hashCode())
+                | ((getTypeName() == null) ? 0 : getTypeName().hashCode())
+                | ((getVersion() == null) ? 0 : getVersion().hashCode())
+                | ((getCoordinateSystem() == null) ? 0 : getCoordinateSystem().hashCode())
+                | ((getCoordinateSystemReproject() == null) ? 0 : getCoordinateSystemReproject().hashCode())
+                | getStartIndex();
+    }
+    
+    /**
+     * Equality based on all query parameters other than the handle.
+     * 
+     * @param obj Other object to compare against
+     *
+     * @return true if this Query matches the other object; false otherwise
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if ((obj == null) || !(obj instanceof Query)) {
+            return false;
+        }
+        if (this == obj) return true;        
+        Query other = (Query) obj;
+        
+        return Arrays.equals(getPropertyNames(), other.getPropertyNames())
+        && (retrieveAllProperties() == other.retrieveAllProperties())
+        && (getMaxFeatures() == other.getMaxFeatures())
+        && ((getFilter() == null) ? (other.getFilter() == null)
+                                  : getFilter().equals(other.getFilter()))
+        && ((getTypeName() == null) ? (other.getTypeName() == null)
+                                    : getTypeName().equals(other.getTypeName()))
+        && ((getVersion() == null) ? (other.getVersion() == null)
+                                   : getVersion().equals(other.getVersion()))
+        && ((getCoordinateSystem() == null) ? (other.getCoordinateSystem() == null)
+                                           : getCoordinateSystem().equals(other.getCoordinateSystem()))
+        && ((getCoordinateSystemReproject() == null) ? (other.getCoordinateSystemReproject() == null)
+                                                   : getCoordinateSystemReproject().equals(other.getCoordinateSystemReproject()))                                           
+        && (getStartIndex() == other.getStartIndex()) 
+        && (getHints() == null ? (other.getHints() == null) : getHints().equals(other.getHints()));
+    }
+    
+    /**
+     * Return a string representation of this Query.
+     *
+     * @return a string representation of this Query
+     */
+    @Override
+    public String toString() {
+        StringBuffer returnString = new StringBuffer("Query:");
+
+        if (handle != null) {
+            returnString.append(" [" + handle + "]");
+        }
+
+        returnString.append("\n   feature type: " + typeName);
+
+        if (filter != null) {
+            returnString.append("\n   filter: " + filter.toString());
+        }
+
+        returnString.append("\n   [properties: ");
+
+        if ((properties == null) || (properties.size() == 0)) {
+            returnString.append(" ALL ]");
+        } else {
+            for (int i = 0; i < properties.size(); i++) {
+                returnString.append(properties.get(i));
+
+                if (i < (properties.size() - 1)) {
+                    returnString.append(", ");
+                }
+            }
+
+            returnString.append("]");
+        }
+        
+        if(sortBy != null && sortBy.length > 0) {
+        returnString.append("\n   [sort by: ");
+            for (int i = 0; i < sortBy.length; i++) {
+                returnString.append(sortBy[i].getPropertyName().getPropertyName());
+                returnString.append(" ");
+                returnString.append(sortBy[i].getSortOrder().name());
+
+                if (i < (sortBy.length - 1)) {
+                    returnString.append(", ");
+                }
+            }
+
+            returnString.append("]");
+        }
+        
+        return returnString.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/QueryCapabilities.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/QueryCapabilities.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/QueryCapabilities.java	(revision 28000)
@@ -0,0 +1,110 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import org.geotools.factory.Hints;
+import org.opengis.feature.Feature;
+import org.opengis.filter.sort.SortBy;
+
+/**
+ * Describes the query capabilities for a specific FeatureType, so client code can request which
+ * features are natively supported by a FeatureSource.
+ * <p>
+ * This is the minimal Query capabilities we could come up in order to reliably support paging. Yet,
+ * the need for a more complete set of capabilities is well known and a new proposal should be done
+ * in order to define the complete set of capabilities a FeatureSource should advertise.
+ * </p>
+ * 
+ * @author Gabriel Roldan (TOPP)
+ * @version $Id: QueryCapabilities.java 37280 2011-05-24 07:53:02Z mbedward $
+ * @since 2.5.x
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/QueryCapabilities.java $
+ */
+public class QueryCapabilities {
+
+    /**
+     * Returns the list of filters natively supported by the underlaying storage. Every other filter
+     * will be emulated in memory (and thus will not enjoy any acceleration).
+     */
+    // GR: commenting out by now as its being an unexpected scope increase,
+    // gonna add it back once I have the paging use case handled
+    // FilterCapabilities getFilterCapabilities();
+    /**
+     * True if this feature source supports reprojection
+     */
+    // public boolean isReprojectionSupported();
+    /**
+     *
+     */
+    // public boolean isCRSForcingSupported();
+    /**
+     * Is offset supported. A value of true implies ability to have a consistent sort order. At
+     * least {@link SortBy#NATURAL_ORDER} shall be supported, and be the default order if a Query
+     * with offset but no SortBy is issued.
+     */
+    public boolean isOffsetSupported() {
+        return false;
+    }
+
+    /**
+     * Returns whether a list of properties can be used as SortBy keys.
+     * <p>
+     * May include current feature type properties as well as <code>"@id"</code> for sorting on
+     * the Feature ID. Note, however, that ability to sort by the fature id does not necessarily
+     * implies the same ordering than SortBy.NATURAL_ORDER, though its probable they match for
+     * datastores where the feature id is built up from a primary key.
+     * </p>
+     * <p>
+     * Returns true if passed a null or empty array, otherwise the actual attributes are checked.
+     * When the array is not null and not empty, by default returns false.
+     * FeatureSource implementations should override as needed.
+     * </p>
+     * 
+     * @return whether the FeatureType this query capabilities refers to can be natively sorted by
+     *         the provided list of attribtue/order pairs
+     */
+    public boolean supportsSorting(SortBy[] sortAttributes) {
+        return (sortAttributes == null) || (sortAttributes.length == 0);
+    }
+    
+    /**
+     * Returns whether the feature source is capable of producing "reliable" fids.
+     * <p>
+     * In this content the term "reliable" refers to the ability to read the same feature
+     * twice (with no transactions against the feature source in the interim) and get the 
+     * same feature id back both times.
+     * </p>
+     * @return True to indicate reliable fids are supported, otherwise false.
+     */
+    public boolean isReliableFIDSupported() {
+        return true;
+    }
+    
+    /**
+     * If true the datastore supports using the provided feature id in the data insertion
+     * workflow as opposed to generating a new id. In that case it will look into the user data 
+     * map ({@link Feature#getUserData()}) for a {@link Hints#USE_PROVIDED_FID} key associated to a
+     * {@link Boolean#TRUE} value, if the key/value pair is there an attempt to use the provided 
+     * id will be made, and the operation will fail of the key cannot be parsed into a valid 
+     * storage identifier.
+     * @return
+     */
+    public boolean isUseProvidedFIDSupported() {
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/ReTypeFeatureReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/ReTypeFeatureReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/ReTypeFeatureReader.java	(revision 28000)
@@ -0,0 +1,193 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.geotools.feature.FeatureTypes;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.resources.Classes;
+import org.opengis.feature.IllegalAttributeException;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+
+
+/**
+ * Supports on the fly retyping of  FeatureReader<SimpleFeatureType, SimpleFeature> contents.
+ * <p>
+ * This may be used to have a DataStore work with your own representation of
+ * Feature information.
+ * </p>
+ * <p>
+ * Example Use:
+ * </p>
+ * <pre><code>
+ *  FeatureReader<SimpleFeatureType, SimpleFeature> reader = dataStore.getFeatureReader( query, Transaction.AUTO_COMMIT );
+ * reader = new ReTypeFeatureReader( reader, myFeatureType );
+ * try {
+ *   while( reader.hasNext() ){
+ *     Feature f = reader.next();
+ *     System.out.println( f );
+ *   }
+ * }
+ * finally {
+ *   reader.close(); // will close both
+ * } 
+ * </code></pre>
+ * <p>
+ * This Reader makes a simple <b>one to one</b> between the original schema and the target schema based
+ * on descriptor name.
+ * 
+ * @author Jody Garnett (Refractions Research)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/ReTypeFeatureReader.java $
+ */
+public class ReTypeFeatureReader implements DelegatingFeatureReader<SimpleFeatureType,SimpleFeature> {
+    
+    /** The original reader we are grabbing content from */
+    FeatureReader<SimpleFeatureType, SimpleFeature> reader;
+    
+     /** This is the target feature type we are preparing data for */
+    SimpleFeatureType featureType;
+    
+    /** The descriptors we are going to from the original reader */
+    AttributeDescriptor[] types;
+    
+    /** Creates retyped features  */
+    SimpleFeatureBuilder builder;
+    
+    boolean clone;
+    
+    /**
+     * Constructs a FetureReader that will ReType streaming content.
+     *
+     * @param reader Original FeatureReader
+     * @param featureType Target FeatureType
+     * @param clone true to clone the content
+     * @since 2.3
+     */
+    public ReTypeFeatureReader(FeatureReader <SimpleFeatureType, SimpleFeature> reader, SimpleFeatureType featureType, boolean clone) {
+        this.reader = reader;
+        this.featureType = featureType;
+        this.clone = clone;
+        types = typeAttributes(featureType, reader.getFeatureType());
+        builder = new SimpleFeatureBuilder(featureType);
+    }
+    
+    /**
+     * Supplies mapping from original to target FeatureType.
+     * 
+     * <p>
+     * Will also ensure that mapping results in a valid selection of values
+     * from the original. Only the xpath expression and binding are checked.
+     * </p>
+     *
+     * @param target Desired FeatureType
+     * @param origional Original FeatureType
+     *
+     * @return Mapping from originoal to target FeatureType
+     *
+     * @throws IllegalArgumentException if unable to provide a mapping
+     */
+    protected AttributeDescriptor[] typeAttributes(SimpleFeatureType target,
+        SimpleFeatureType origional) {
+        if (FeatureTypes.equalsExact(origional, target)) {
+            throw new IllegalArgumentException(
+                "FeatureReader allready produces contents with the correct schema");
+        }
+
+        if (target.getAttributeCount() > origional.getAttributeCount()) {
+            throw new IllegalArgumentException(
+                "Unable to retype  FeatureReader<SimpleFeatureType, SimpleFeature> (origional does not cover requested type)");
+        }
+
+        String xpath;
+        AttributeDescriptor[] types = new AttributeDescriptor[target.getAttributeCount()];
+
+        for (int i = 0; i < target.getAttributeCount(); i++) {
+            AttributeDescriptor attrib = target.getDescriptor(i);
+            xpath = attrib.getLocalName();
+            
+            types[i] = attrib;
+            
+            AttributeDescriptor check = origional.getDescriptor( xpath );
+            Class<?> targetBinding = attrib.getType().getBinding();
+            Class<?> checkBinding = check.getType().getBinding();
+            if( !targetBinding.isAssignableFrom( checkBinding )){
+                throw new IllegalArgumentException(
+                    "Unable to retype FeatureReader for " + xpath +
+                    " as "+Classes.getShortName(checkBinding) + 
+                    " cannot be assigned to "+Classes.getShortName(targetBinding) );                
+            }
+        }
+
+        return types;
+    }
+
+    /**
+     * @see org.geotools.data.FeatureReader#getFeatureType()
+     */
+    public SimpleFeatureType getFeatureType() {
+        return featureType;
+    }
+
+    /**
+     * @see org.geotools.data.FeatureReader#next()
+     */
+    public SimpleFeature next()
+        throws IOException, IllegalAttributeException, NoSuchElementException {
+        if (reader == null) {
+            throw new IOException("FeatureReader has been closed");
+        }
+
+        SimpleFeature next = reader.next();
+        String id = next.getID();
+
+        String xpath;
+
+        for (int i = 0; i < types.length; i++) {
+            xpath = types[i].getLocalName();
+            if(clone)
+                builder.add(DataUtilities.duplicate(next.getAttribute(xpath)));
+            else
+                builder.add(next.getAttribute(xpath));
+        }
+
+        return builder.buildFeature(id);
+    }
+
+    /**
+     * @see org.geotools.data.FeatureReader#hasNext()
+     */
+    public boolean hasNext() throws IOException {
+        return reader.hasNext();
+    }
+
+    /**
+     * @see org.geotools.data.FeatureReader#close()
+     */
+    public void close() throws IOException {
+        if (reader != null) {
+            reader.close();
+            reader = null;
+            featureType = null;
+            types = null;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/ServiceInfo.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/ServiceInfo.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/ServiceInfo.java	(revision 28000)
@@ -0,0 +1,42 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+
+
+/**
+ * Information about a service.
+ * <p>
+ * You can treat this bean as a "summary view" on more complete metadata information
+ * that may be accessible as header or table information.
+ * </p>
+ * <p>
+ * The names used in this class have been taken from Dublin Code
+ * and it's application profile for RDF.
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research
+ * @author David Zwiers, Refractions Research
+ * @author Justin Deoliveira, The Open Planning Project
+ * @since 2.5
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/ServiceInfo.java $
+ */
+public interface ServiceInfo {
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/Transaction.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/Transaction.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/Transaction.java	(revision 28000)
@@ -0,0 +1,202 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.util.Set;
+
+
+/**
+ * The controller for Transaction with FeatureStore.
+ *
+ * <p>
+ * Shapefiles, databases, etc. are safely modified with the assistance of this
+ * interface. Transactions are also to provide authorization when working with
+ * locked features.
+ * </p>
+ *
+ * <p>
+ * All operations are considered to be working against a Transaction.
+ * Transaction.AUTO_COMMIT is used to represent an immidiate mode where
+ * requests are immidately commited.
+ * </p>
+ *
+ * <p>
+ * For more information please see DataStore and FeatureStore.
+ * </p>
+ *
+ * <p>
+ * Example Use:
+ * </p>
+ * <pre><code>
+ * Transaction t = new DefaultTransaction("handle");
+ * t.putProperty( "hint", new Integer(7) );
+ * try {
+ *     SimpleFeatureStore road = (SimpleFeatureStore) store.getFeatureSource("road");
+ *     FeatureStore river = (SimpleFeatureStore) store.getFeatureSource("river");
+ *
+ *     road.setTransaction( t );
+ *     river.setTransaction( t );
+ *
+ *     t.addAuthorization( lockID );  // provide authoriztion
+ *     road.removeFeatures( filter ); // operate against transaction
+ *     river.removeFeature( filter ); // operate against transaction
+ *
+ *     t.commit(); // commit operations
+ * }
+ * catch (IOException io){
+ *     t.rollback(); // cancel operations
+ * }
+ * finally {
+ *     t.close(); // free resources
+ * }
+ * </code></pre>
+ * <p>
+ * Example code walkthrough (from the perspective of Transaction):
+ * </p>
+ * <ol>
+ * <li>A new transaction is created (an instanceof DefaultTransaction with a handle)</li>
+ * <li>A hint is provided using Transaction.putProperty( key, value )</li>
+ * <li>Transaction is provided to two FeatureStores, this may result
+ *     in Transaction.State instances being registered</li>
+ *     <ul>
+ *     <li>TransactionStateDiff (stored by DataStore):
+ *         Used for in memory locking is used by many DataStore's
+ *         (like ShapefileDataStore).
+ *         Lazy creation by AbstractDataStore.state(transaction).
+ *         </li>
+ *     <li>JDBCTransactionState (stored by ConnectionPool):
+ *         Used to manage connection rollback/commit.
+ *         Lazy creation as part of JDBCDataStore.getConnection(transaction).
+ *         </li>
+ *     <li>InProcessLockingManager.FeatureLock (stored by LockingManger):
+ *         Used for per transaction FeatureLocks, used to free locked features
+ *         on Transaction commit/rollback.
+ *         </li>
+ *     </ul>
+ *     These instances of Transaction state may make use of any hint provided
+ *     to Transaction.putProperty( key, value ) when they are connected with
+ *     Transaction.State.setTransaction( transaction ).
+ * <li>t.addAuthorization(lockID) is called, each Transaction.State has its
+ *     addAuthroization(String) callback invoked with the value of lockID</li>
+ * <li>FeatureStore.removeFeatures methods are called on the two DataStores.
+ *     <ul>
+ *     <li>PostgisFeatureStore.removeFeatures(fitler) handles operation
+ *         without delegation.
+ *         </li>
+ *     <li>Most removeFeature(filter) implementations use the implementation
+ *         provided by AbstractFeatureStore which delegates to FeatureWriter.
+ *         </li>
+ *     </ul>
+ *     Any of these operations may make use of the
+ *     Transaction.putProperty( key, value ).
+ * <li>The transaction is commited, all of the Transaction.State methods have
+ *     there Transaction.State.commit() methods called gicing them a chance
+ *     to applyDiff maps, or commit various connections.
+ *     </li>
+ * <li>The transaction is closed, all of the Transaction.State methods have
+ *     there Transaction.State.setTransaction( null ) called, giving them a
+ *     chance to clean up diffMaps, or return connections to the pool.
+ *     </li>
+ * </ol>
+ * @author Jody Garnett
+ * @author Chris Holmes, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/Transaction.java $
+ * @version $Id: Transaction.java 37280 2011-05-24 07:53:02Z mbedward $
+ */
+public interface Transaction {
+    /** 
+     * Represents AUTO_COMMIT mode as opposed to operations with commit/rollback
+     * control under a user-supplied transaction.
+     */
+    static final Transaction AUTO_COMMIT = new AutoCommitTransaction();
+
+    /**
+     * List of Authorizations IDs held by this transaction.
+     *
+     * <p>
+     * This list is reset by the next call to commit() or rollback().
+     * </p>
+     *
+     * <p>
+     * Authorization IDs are used to provide FeatureLock support.
+     * </p>
+     *
+     * @return List of Authorization IDs
+     */
+    Set<String> getAuthorizations();
+
+    /**
+     * Allows SimpleFeatureSource to squirel away information( and callbacks ) for
+     * later.
+     *
+     * <p>
+     * The most common example is a JDBC DataStore saving the required
+     * connection for later operations.
+     * </p>
+     * <pre><code>
+     * ConnectionState implements State {
+     *     public Connection conn;
+     *     public addAuthorization() {}
+     *     public commit(){ conn.commit(); }
+     *     public rollback(){ conn.rollback(); }
+     * }
+     * </code></pre>
+     *
+     * <p>
+     * putState will call State.setTransaction( transaction ) to allow State a
+     * chance to configure itself.
+     * </p>
+     *
+     * @param key Key used to externalize State
+     * @param state Externalized State
+     */
+    void putState(Object key, State state);
+
+    /**
+     * Allows DataStores to squirel away information( and callbacks ) for
+     * later.
+     *
+     * <p>
+     * The most common example is a JDBC DataStore saving the required
+     * connection for later operations.
+     * </p>
+     *
+     * @return Current State externalized by key, or <code>null</code> if not
+     *         found
+     */
+    State getState(Object key);
+
+    /**
+     * DataStore implementations can use this interface to externalize the
+     * state they require to implement Transaction Support.
+     *
+     * <p>
+     * The commit and rollback methods will be called as required. The
+     * intension is that several DataStores can share common transaction state
+     * (example: Postgis DataStores sharing a connection to the same
+     * database).
+     * </p>
+     *
+     * @author jgarnett, Refractions Reasearch Inc.
+     * @version CVS Version
+     *
+     * @see org.geotools.data
+     */
+    static public interface State {
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/TransactionStateDiff.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/TransactionStateDiff.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/TransactionStateDiff.java	(revision 28000)
@@ -0,0 +1,257 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.data.Transaction.State;
+import org.geotools.feature.IllegalAttributeException;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.GeometryAttribute;
+import org.opengis.feature.Property;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+import org.opengis.filter.identity.FeatureId;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+
+/**
+ * A Transaction.State that keeps a difference table for use with
+ * AbstractDataStore.
+ *
+ * @author Jody Garnett, Refractions Research
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/TransactionStateDiff.java $
+ */
+public class TransactionStateDiff implements State {
+    /**
+     * DataStore used to commit() results of this transaction.
+     *
+     * @see TransactionStateDiff.commit();
+     */
+    AbstractDataStore store;
+
+    /** Tranasction this State is opperating against. */
+    Transaction transaction;
+
+    /**
+     * Map of differences by typeName.
+     * 
+     * <p>
+     * Differences are stored as a Map of Feature by fid, and are reset during
+     * a commit() or rollback().
+     * </p>
+     */
+    Map typeNameDiff = new HashMap();
+
+    public TransactionStateDiff(AbstractDataStore dataStore) {
+        store = dataStore;
+    }
+
+    public synchronized Diff diff(String typeName) throws IOException {
+        if (!exists(typeName)) {
+            throw new IOException(typeName + " not defined");
+        }
+
+        if (typeNameDiff.containsKey(typeName)) {
+            return (Diff) typeNameDiff.get(typeName);
+        } else {
+            Diff diff = new Diff();
+            typeNameDiff.put(typeName, diff);
+
+            return diff;
+        }
+    }
+    
+    boolean exists(String typeName) {
+        String[] types;
+        try {
+            types = store.getTypeNames();
+        } catch (IOException e) {
+            return false;
+        }
+        Arrays.sort(types);
+
+        return Arrays.binarySearch(types, typeName) != -1;
+    }
+
+    /**
+     * Convience Method for a Transaction based FeatureWriter
+     * 
+     * <p>
+     * Constructs a DiffFeatureWriter that works against this Transaction.
+     * </p>
+     *
+     * @param typeName Type Name to record differences against
+     * @param filter 
+     *
+     * @return A FeatureWriter that records Differences against a FeatureReader
+     *
+     * @throws IOException If a FeatureRader could not be constucted to record
+     *         differences against
+     */
+    public synchronized FeatureWriter<SimpleFeatureType, SimpleFeature> writer(final String typeName, Filter filter)
+        throws IOException {
+        Diff diff = diff(typeName);
+         FeatureReader<SimpleFeatureType, SimpleFeature> reader = new FilteringFeatureReader<SimpleFeatureType, SimpleFeature>(store.getFeatureReader(typeName, new DefaultQuery(typeName, filter)), filter);
+
+        return new DiffFeatureWriter(reader, diff, filter) {
+                public void fireNotification(int eventType, ReferencedEnvelope bounds) {
+                    switch (eventType) {
+                    case FeatureEvent.FEATURES_ADDED:
+                        store.listenerManager.fireFeaturesAdded(typeName,
+                            transaction, bounds, false);
+
+                        break;
+
+                    case FeatureEvent.FEATURES_CHANGED:
+                        store.listenerManager.fireFeaturesChanged(typeName,
+                            transaction, bounds, false);
+
+                        break;
+
+                    case FeatureEvent.FEATURES_REMOVED:
+                        store.listenerManager.fireFeaturesRemoved(typeName,
+                            transaction, bounds, false);
+
+                        break;
+                    }
+                }
+                public String toString() {
+                    return "<DiffFeatureWriter>("+reader.toString()+")";
+                }
+            };
+    }
+    /**
+     * A NullObject used to represent the absence of a SimpleFeature.
+     * <p>
+     * This class is used by TransactionStateDiff as a placeholder
+     * to represent features that have been removed. The concept
+     * is generally useful and may wish to be taken out as a separate
+     * class (used for example to represent deleted rows in a shapefile).
+     */
+    public static final SimpleFeature NULL=new SimpleFeature( ){
+        public Object getAttribute(String path) {
+            return null;
+        }
+
+        public Object getAttribute(int index) {
+            return null;
+        }
+
+        public ReferencedEnvelope getBounds() {
+            return null;
+        }
+
+        public Geometry getDefaultGeometry() {
+            return null;
+        }
+
+        public SimpleFeatureType getFeatureType() {
+            return null;
+        }
+
+        public String getID() {
+            return null;
+        }
+        public FeatureId getIdentifier() {
+        	return null;
+        }
+
+        public void setAttribute(int position, Object val) {
+        }
+
+        public void setAttribute(String path, Object attribute)
+                throws IllegalAttributeException {
+        }
+
+        public Object getAttribute(Name name) {
+            return null;
+        }
+
+        public List<Object> getAttributes() {
+            return null;
+        }
+
+        public SimpleFeatureType getType() {
+            return null;
+        }
+
+        public void setAttribute(Name name, Object value) {
+        }
+
+        public void setAttributes(List<Object> values) {
+        }
+
+        public GeometryAttribute getDefaultGeometryProperty() {
+            return null;
+        }
+
+        public Collection<Property> getProperties() {
+            return null;
+        }
+        
+        public Property getProperty(Name name) {
+            return null;
+        }
+
+        public Property getProperty(String name) {
+            return null;
+        }
+
+        public Collection<? extends Property> getValue() {
+            return null;
+        }
+
+        public AttributeDescriptor getDescriptor() {
+            return null;
+        }
+
+        public Name getName() {
+            return null;
+        }
+
+        public Map<Object, Object> getUserData() {
+            return null;
+        }
+
+        public boolean isNillable() {
+            return false;
+        }
+
+        public String toString() {
+            return "<NullFeature>";
+        }
+        public int hashCode() {
+            return 0;
+        }
+		public boolean equals( Object arg0 ) {
+		    return arg0 == this;
+		}
+		public void validate() {
+		}
+    };
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/collection/CollectionFeatureSource.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/collection/CollectionFeatureSource.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/collection/CollectionFeatureSource.java	(revision 28000)
@@ -0,0 +1,244 @@
+package org.geotools.data.collection;
+
+import java.awt.RenderingHints.Key;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.geotools.data.DataAccess;
+import org.geotools.data.DataUtilities;
+import org.geotools.data.FeatureListener;
+import org.geotools.data.Query;
+import org.geotools.data.QueryCapabilities;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureSource;
+import org.geotools.data.store.EmptyFeatureCollection;
+import org.geotools.data.store.ReTypingFeatureCollection;
+import org.geotools.data.store.ReprojectingFeatureCollection;
+import org.geotools.feature.collection.DecoratingSimpleFeatureCollection;
+import org.geotools.feature.collection.FilteringSimpleFeatureCollection;
+import org.geotools.feature.collection.MaxSimpleFeatureCollection;
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+import org.opengis.filter.sort.SortBy;
+
+/**
+ * This is a "port" of ContentFeatureSource to work with an iterator.
+ * <p>
+ * To use this class please "wrap" CollectionFeatureSource around your choice of FeatureCollection.
+ * 
+ * <pre>
+ * SimpleFeatureCollection collection = new ListFeatureCollection(schema);
+ * collection.add(feature1);
+ * collection.add(feature2);
+ * FeatureSource source = new CollectionFeatureSource(collection);
+ * </pre>
+ * <p>
+ * Note to implementors: If you are performing "real I/O" please use ContentFeatureSource as it
+ * provides support for IOException.
+ * 
+ * @author Jody
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/build/maven/javadoc/../../../modules/library/main/src/main/java/org/geotools/data/collection/CollectionFeatureSource.java $
+ */
+public class CollectionFeatureSource implements SimpleFeatureSource {
+    protected SimpleFeatureCollection collection;
+
+    /**
+     * observers
+     */
+    protected List<FeatureListener> listeners = null;
+
+    private QueryCapabilities capabilities;
+
+    private Set<Key> hints;
+
+    public CollectionFeatureSource(SimpleFeatureCollection collection) {
+        this.collection = collection;
+    }
+
+    public SimpleFeatureType getSchema() {
+        return collection.getSchema();
+    }
+
+    public synchronized void addFeatureListener(FeatureListener listener) {
+        if (listeners == null) {
+            listeners = Collections.synchronizedList(new ArrayList<FeatureListener>());
+        }
+        listeners.add(listener);
+    }
+
+    public synchronized void removeFeatureListener(FeatureListener listener) {
+        if (listeners == null) {
+            return;
+        }
+        listeners.remove(listener);
+    }
+
+    public ReferencedEnvelope getBounds() throws IOException {
+        return collection.getBounds();
+    }
+
+    public ReferencedEnvelope getBounds(Query query) throws IOException {
+        return getFeatures(query).getBounds();
+    }
+
+    public int getCount(Query query) throws IOException {
+        return getFeatures(query).size();
+    }
+
+    public DataAccess<SimpleFeatureType, SimpleFeature> getDataStore() {
+        throw new UnsupportedOperationException("CollectionFeatureSource is an inmemory wrapper");
+    }
+
+    public Name getName() {
+        return collection.getSchema().getName();
+    }
+
+    public synchronized QueryCapabilities getQueryCapabilities() {
+        if (capabilities == null) {
+            capabilities = new QueryCapabilities() {
+                public boolean isOffsetSupported() {
+                    return true;
+                }
+
+                public boolean isReliableFIDSupported() {
+                    return true;
+                }
+
+                public boolean supportsSorting(org.opengis.filter.sort.SortBy[] sortAttributes) {
+                    return true;
+                }
+            };
+        }
+        return capabilities;
+    }
+
+    public synchronized Set<Key> getSupportedHints() {
+        if (hints == null) {
+            Set<Key> supports = new HashSet<Key>();
+            // supports.add( Hints.FEATURE_DETACHED );
+            hints = Collections.unmodifiableSet(supports);
+        }
+        return hints;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder();
+        buf.append("CollectionFeatureSource:");
+        buf.append(collection);
+        return buf.toString();
+    }
+
+    //
+    // GET FEATURES
+    // This forms the heart of the CollectionFeatureSource implementation
+    // Use: DataUtilities.mixQueries(this.query, query, "subCollection" ) as needed
+    //
+    public SimpleFeatureCollection getFeatures() throws IOException {
+        return getFeatures( Query.ALL );
+    }
+
+    public SimpleFeatureCollection getFeatures(Filter filter) {
+        Query query = new Query(getSchema().getTypeName(), filter);
+        return getFeatures(query);
+    }
+
+    public SimpleFeatureCollection getFeatures(Query query) {
+        query = DataUtilities.resolvePropertyNames(query, getSchema());
+        final int offset = query.getStartIndex() != null ? query.getStartIndex() : 0;
+        if (offset > 0 & query.getSortBy() == null) {
+            if (!getQueryCapabilities().supportsSorting(query.getSortBy())){
+                throw new IllegalStateException("Feature source does not support this sorting "
+                        + "so there is no way a stable paging (offset/limit) can be performed");
+            }
+            Query copy = new Query(query);
+            copy.setSortBy(new SortBy[] { SortBy.NATURAL_ORDER });
+            query = copy;
+        }
+        SimpleFeatureCollection features = collection;
+        // step one: filter
+        if( query.getFilter() != null && query.getFilter().equals(Filter.EXCLUDE)){
+            return new EmptyFeatureCollection( getSchema() );
+        }
+        if (query.getFilter() != null && query.getFilter() != Filter.INCLUDE) {
+            features = new FilteringSimpleFeatureCollection(features, query.getFilter());
+        }
+        // step two: reproject
+        if (query.getCoordinateSystemReproject() != null) {
+            features = new ReprojectingFeatureCollection(features, query
+                    .getCoordinateSystemReproject());
+        }
+        // step two sort! (note this makes a sorted copy)
+        if (query.getSortBy() != null && query.getSortBy().length != 0) {
+            SimpleFeature array[] = features.toArray(new SimpleFeature[features.size()]);
+            // Arrays sort is stable (not resorting equal elements)
+            for (SortBy sortBy : query.getSortBy()) {
+                Comparator<SimpleFeature> comparator = DataUtilities.sortComparator(sortBy);
+                Arrays.sort(array, comparator);
+            }
+            ArrayList<SimpleFeature> list = new ArrayList<SimpleFeature>(Arrays.asList(array));
+            features = new ListFeatureCollection(getSchema(), list);
+        }
+
+        // step three skip to start and return max number of fetaures
+        if (offset > 0 || !query.isMaxFeaturesUnlimited()) {
+            long max = Long.MAX_VALUE;
+            if (!query.isMaxFeaturesUnlimited()) {
+                max = query.getMaxFeatures();
+            }
+            features = new MaxSimpleFeatureCollection(features, offset, max);
+        }
+
+        // step four - retyping
+        // (It would be nice to do this earlier so as to not have all the baggage
+        // of unneeded attributes)
+        if (query.getPropertyNames() != Query.ALL_NAMES) {
+            // rebuild the type and wrap the reader
+            SimpleFeatureType schema = features.getSchema();
+            SimpleFeatureType target = SimpleFeatureTypeBuilder.retype(schema, query
+                    .getPropertyNames());
+
+            // do an equals check because we may have needlessly retyped (that is,
+            // the subclass might be able to only partially retype)
+            if (!target.equals(schema)) {
+                features = new ReTypingFeatureCollection(features, target);
+            }
+        }
+        // Wrap up the results in a method that allows subCollection
+        return new SubCollection( query, features );
+    }
+
+    /**
+     * SubCollection for CollectionFeatureSource.
+     * <p>
+     * Will route any calls refining the feature collection back to CollectionFeatureSource. This is
+     * based on the success of ContentFeatureCollection.
+     * </p>
+     * 
+     * @author Jody
+     */
+    protected class SubCollection extends DecoratingSimpleFeatureCollection {
+        private Query query;
+        protected SubCollection(Query query, SimpleFeatureCollection features) {
+            super(features);
+            this.query = query;
+        }
+        public SimpleFeatureCollection subCollection(Filter filter) {
+            Query q = new Query(getSchema().getTypeName(), filter);
+            
+            Query subQuery = DataUtilities.mixQueries(query, q, q.getHandle() );
+            return CollectionFeatureSource.this.getFeatures( subQuery );
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/collection/DelegateFeatureReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/collection/DelegateFeatureReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/collection/DelegateFeatureReader.java	(revision 28000)
@@ -0,0 +1,78 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.collection;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.geotools.data.DataSourceException;
+import org.geotools.data.FeatureReader;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.feature.IllegalAttributeException;
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+
+/**
+ * A FeatureReader that wraps up a normal FeatureIterator.
+ * <p>
+ * This class is useful for faking (and testing) the Resource based
+ * API against in memory datastructures. You are warned that to
+ * complete the illusion that Resource based IO is occuring content
+ * will be duplicated.
+ * </p>
+ * @author Jody Garnett, Refractions Research, Inc.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/collection/DelegateFeatureReader.java $
+ */
+public class DelegateFeatureReader<T extends FeatureType, F extends Feature> implements FeatureReader<T, F> {
+	FeatureIterator<F> delegate;
+	T schema;
+	
+	public DelegateFeatureReader( T featureType, FeatureIterator<F> features ){
+		this.schema = featureType;
+		this.delegate = features;
+	}
+	
+	public T getFeatureType() {
+		return schema;
+	}
+
+	public F next() throws IOException, IllegalAttributeException, NoSuchElementException {
+		if (delegate == null) {
+            throw new IOException("Feature Reader has been closed");
+        }		
+        try {
+        	F feature = delegate.next();
+        	// obj = schema.duplicate( obj );
+        	return feature;        	
+        } catch (NoSuchElementException end) {
+            throw new DataSourceException("There are no more Features", end);
+        }		
+	}
+
+	public boolean hasNext() throws IOException {
+		return delegate != null && delegate.hasNext();			
+	}
+
+	public void close() throws IOException {
+		if( delegate != null ) delegate.close();
+		delegate = null;
+        schema = null;
+	}
+	
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/collection/ListFeatureCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/collection/ListFeatureCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/collection/ListFeatureCollection.java	(revision 28000)
@@ -0,0 +1,193 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2010-2011, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.collection;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.geotools.data.Query;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.factory.Hints;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.feature.collection.AbstractFeatureCollection;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.filter.sort.SortBy;
+import org.opengis.geometry.BoundingBox;
+
+/**
+ * FeatureCollection implementation wrapping around a java.util.List.
+ * <p>
+ * This implementation wraps around a java.util.List and is suitable
+ * for quickly getting something on screen.
+ * <p>
+ * Usage notes:
+ * <ul>
+ * <li>This implementation does not use a spatial index, please do not expect spatial operations to be fast.
+ * <li>FeatureCollections are not allowed to have duplicates
+ * </ul>
+ * <p>
+ * This implementation is intended to quickly wrap up a list of features and get them on screen; as such
+ * it respects various hints about the copying of internal content as provided by the renderer.
+ * 
+ * @see Hints#FEATURE_DETACHED
+ * @author Oliver Gottwald
+ * @author Jody
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/collection/ListFeatureCollection.java $
+ */
+@SuppressWarnings("unchecked")
+public class ListFeatureCollection extends AbstractFeatureCollection {
+    /** wrapped list of features containing the contents */
+     private List<SimpleFeature> list;
+     
+     /** Cached bounds */
+     private ReferencedEnvelope bounds = null;
+    
+     /**
+      * Create a ListFeatureCollection around the provided list. The contents
+      * of the list should all be of the provided schema for this to make sense.
+      * Please keep in mind the feature collection control, no two Features in the list
+      * should have the same feature id, and you should not insert the same feature more
+      * then once.
+      * <p>
+      * The provided list is directly used for storage, most feature collection
+      * operations just use a simple iterator so there is no performance advantaged
+      * to be gained over using an ArrayList vs a LinkedList (other then for the size()
+      * method of course).
+      * 
+      * @param schema
+      * @param list
+      */
+     public ListFeatureCollection(SimpleFeatureType schema, List<SimpleFeature> list ){
+         super(schema);
+         this.list = list;
+     }
+     
+     @Override
+     public int size() {
+         return list.size();
+     }
+    
+     @Override
+     protected Iterator openIterator() {
+         Iterator it = list.iterator();
+         return it;
+     }
+    
+     @Override
+     protected void closeIterator(Iterator close) {
+         // nothing to do there
+     }
+     
+    @Override
+    public boolean add(SimpleFeature f) {
+         //maintain the bounds
+          BoundingBox boundingBox = f.getBounds();
+          if (bounds == null){
+              bounds = new ReferencedEnvelope(
+                      boundingBox.getMinX(), boundingBox.getMaxX(),
+                      boundingBox.getMinY(), boundingBox.getMaxY(),
+                      schema.getCoordinateReferenceSystem());
+          } else {
+              bounds.expandToInclude(boundingBox.getMinX(), boundingBox.getMinY());   
+              bounds.expandToInclude(boundingBox.getMaxX(), boundingBox.getMaxY());   
+          }
+        return list.add(f);
+    }
+
+    @Override
+    public void clear() {
+        // maintain the bounds
+        bounds = null;
+        super.clear();
+    }
+
+    @Override
+    public SimpleFeatureIterator features() {
+        return new ListFeatureIterator(list);
+    }
+
+    @Override
+    public synchronized ReferencedEnvelope getBounds() {
+        if( bounds == null ){
+            bounds = calculateBounds();
+        }
+        return bounds;
+    }
+    /**
+     * Calculate bounds from features
+     * @return 
+     */
+    private ReferencedEnvelope calculateBounds() {
+        ReferencedEnvelope extent = new ReferencedEnvelope();
+        for( SimpleFeature feature : list ){
+            if( feature == null ) continue;
+            ReferencedEnvelope bbox = ReferencedEnvelope.reference( feature.getBounds() );
+            if( bbox == null || bbox.isEmpty() || bbox.isNull() ) continue;
+            extent.expandToInclude( bbox );
+        }
+        return new ReferencedEnvelope(extent, schema.getCoordinateReferenceSystem());
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return list.isEmpty();
+    }
+    /**
+     * SimpleFeatureIterator that will use collection close method.
+     * @author Jody
+     */
+    private class ListFeatureIterator implements SimpleFeatureIterator {
+        private Iterator<SimpleFeature> iter;
+       
+        public ListFeatureIterator(List<SimpleFeature> features) {
+            iter = features.iterator();
+        }
+       
+        public void close() {
+            if( iter instanceof FeatureIterator){
+                ((FeatureIterator)iter).close();
+            }
+        }
+        public boolean hasNext() {
+            return iter.hasNext();
+        }
+        public SimpleFeature next() throws NoSuchElementException {
+            return iter.next();
+        }
+    }
+    
+    @Override
+    public SimpleFeatureCollection subCollection(Filter filter) {
+        CollectionFeatureSource temp = new CollectionFeatureSource( this );
+        return temp.getFeatures(filter);
+    }
+    
+    @Override
+    public SimpleFeatureCollection sort(SortBy order) {
+        Query subQuery = new Query( getSchema().getTypeName() );
+        subQuery.setSortBy( new SortBy[]{ order } );
+       
+        CollectionFeatureSource temp = new CollectionFeatureSource( this );
+        return temp.getFeatures(subQuery);
+    }
+ }
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/crs/ReprojectFeatureReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/crs/ReprojectFeatureReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/crs/ReprojectFeatureReader.java	(revision 28000)
@@ -0,0 +1,193 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.crs;
+
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import org.geotools.data.DataSourceException;
+import org.geotools.data.DelegatingFeatureReader;
+import org.geotools.data.FeatureReader;
+import org.geotools.feature.IllegalAttributeException;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+
+/**
+ * ReprojectFeatureReader provides a reprojection for FeatureTypes.
+ * 
+ * <p>
+ * ReprojectFeatureReader  is a wrapper used to reproject  GeometryAttributes
+ * to a user supplied CoordinateReferenceSystem from the original
+ * CoordinateReferenceSystem supplied by the original FeatureReader.
+ * </p>
+ * 
+ * <p>
+ * Example Use:
+ * <pre><code>
+ * ReprojectFeatureReader reader =
+ *     new ReprojectFeatureReader( originalReader, reprojectCS );
+ * 
+ * CoordinateReferenceSystem originalCS =
+ *     originalReader.getFeatureType().getDefaultGeometry().getCoordinateSystem();
+ * 
+ * CoordinateReferenceSystem newCS =
+ *     reader.getFeatureType().getDefaultGeometry().getCoordinateSystem();
+ * 
+ * assertEquals( reprojectCS, newCS );
+ * </code></pre>
+ * </p>
+ * TODO: handle the case where there is more than one geometry and the other
+ * geometries have a different CS than the default geometry
+ *
+ * @author jgarnett, Refractions Research, Inc.
+ * @author aaime
+ * @author $Author: jive $ (last modification)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/crs/ReprojectFeatureReader.java $
+ * @version $Id: ReprojectFeatureReader.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public class ReprojectFeatureReader implements DelegatingFeatureReader<SimpleFeatureType, SimpleFeature>{
+    
+    FeatureReader<SimpleFeatureType, SimpleFeature> reader;
+    SimpleFeatureType schema;
+    GeometryCoordinateSequenceTransformer transformer = new GeometryCoordinateSequenceTransformer();
+    
+    /**
+     * Direct constructor reprojecting the provided reader into the schema indicated (using the supplied math transformation).
+     * <p>
+     * Please note schema is that of the expected results, You may need to use FeatureTypes.transform( FeatureType, crs ) to create the schema provider.
+     * 
+     * @param reader original reader with results in the original coordinate reference system
+     * @param schema This is the target schema describing the results in the expected coordinate reference system
+     * @param transform the math transform used to go from reader coordinate reference system to the provided schema coordinate reference system
+     */
+    public ReprojectFeatureReader(FeatureReader <SimpleFeatureType, SimpleFeature> reader, SimpleFeatureType schema,
+        MathTransform transform) {
+        this.reader = reader;
+        this.schema = schema;
+        transformer.setMathTransform(transform);
+    }
+    
+    /**
+     * Implement getFeatureType.
+     * 
+     * <p>
+     * Description ...
+     * </p>
+     *
+     *
+     * @throws IllegalStateException DOCUMENT ME!
+     *
+     * @see org.geotools.data.FeatureReader#getFeatureType()
+     */
+    public SimpleFeatureType getFeatureType() {
+        if (schema == null) {
+            throw new IllegalStateException("Reader has already been closed");
+        }
+
+        return schema;
+    }
+
+    /**
+     * Implement next.
+     * 
+     * <p>
+     * Description ...
+     * </p>
+     *
+     *
+     * @throws IOException
+     * @throws IllegalAttributeException
+     * @throws NoSuchElementException
+     * @throws IllegalStateException DOCUMENT ME!
+     * @throws DataSourceException DOCUMENT ME!
+     *
+     * @see org.geotools.data.FeatureReader#next()
+     */
+    public SimpleFeature next()
+        throws IOException, IllegalAttributeException, NoSuchElementException {
+        if (reader == null) {
+            throw new IllegalStateException("Reader has already been closed");
+        }
+
+        SimpleFeature next = reader.next();
+        Object[] attributes = next.getAttributes().toArray();
+
+        try {
+            for (int i = 0; i < attributes.length; i++) {
+                if (attributes[i] instanceof Geometry) {
+                    attributes[i] = transformer.transform((Geometry) attributes[i]);
+                }
+            }
+        } catch (TransformException e) {
+            throw new DataSourceException("A transformation exception occurred while reprojecting data on the fly",
+                e);
+        }
+
+        return SimpleFeatureBuilder.build(schema, attributes, next.getID());
+    }
+
+    /**
+     * Implement hasNext.
+     * 
+     * <p>
+     * Description ...
+     * </p>
+     *
+     *
+     * @throws IOException
+     * @throws IllegalStateException DOCUMENT ME!
+     *
+     * @see org.geotools.data.FeatureReader#hasNext()
+     */
+    public boolean hasNext() throws IOException {
+        if (reader == null) {
+            throw new IllegalStateException("Reader has already been closed");
+        }
+
+        return reader.hasNext();
+    }
+
+    /**
+     * Implement close.
+     * 
+     * <p>
+     * Description ...
+     * </p>
+     *
+     * @throws IOException
+     * @throws IllegalStateException DOCUMENT ME!
+     *
+     * @see org.geotools.data.FeatureReader#close()
+     */
+    public void close() throws IOException {
+        if (reader == null) {
+            throw new IllegalStateException("Reader has already been closed");
+        }
+
+        reader.close();
+        reader = null;
+        schema = null;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DataStoreSoftReference.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DataStoreSoftReference.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DataStoreSoftReference.java	(revision 28000)
@@ -0,0 +1,22 @@
+package org.geotools.data.directory;
+
+import java.lang.ref.SoftReference;
+
+import org.geotools.data.DataStore;
+import org.geotools.util.WeakCollectionCleaner;
+
+public class DataStoreSoftReference extends SoftReference<DataStore> {
+
+    public DataStoreSoftReference(DataStore referent) {
+        super(referent, WeakCollectionCleaner.DEFAULT.getReferenceQueue());
+    }
+    
+    @Override
+    public void clear() {
+        DataStore store = get();
+        if(store != null)
+            store.dispose();
+        super.clear();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryDataStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryDataStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryDataStore.java	(revision 28000)
@@ -0,0 +1,137 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.directory;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Set;
+
+import org.geotools.data.DataStore;
+import org.geotools.data.FeatureReader;
+import org.geotools.data.FeatureStore;
+import org.geotools.data.FeatureWriter;
+import org.geotools.data.LockingManager;
+import org.geotools.data.Query;
+import org.geotools.data.Transaction;
+import org.geotools.data.simple.SimpleFeatureLocking;
+import org.geotools.data.simple.SimpleFeatureSource;
+import org.geotools.data.simple.SimpleFeatureStore;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+
+public class DirectoryDataStore implements DataStore {
+    
+    DirectoryTypeCache cache;
+    DirectoryLockingManager lm;
+    
+    public DirectoryDataStore(File directory, FileStoreFactory dialect) throws IOException {
+        cache = new DirectoryTypeCache(directory, dialect);
+    }
+
+    public FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(
+            Query query, Transaction transaction) throws IOException {
+        String typeName = query.getTypeName();
+        return getDataStore(typeName).getFeatureReader(query, transaction);
+    }
+
+    public SimpleFeatureSource getFeatureSource(
+            String typeName) throws IOException {
+        SimpleFeatureSource fs = getDataStore(typeName).getFeatureSource(typeName);
+        if(fs instanceof SimpleFeatureLocking) {
+            return new DirectoryFeatureLocking((SimpleFeatureLocking) fs);
+        } else if(fs instanceof FeatureStore) {
+            return new DirectoryFeatureStore((SimpleFeatureStore) fs);
+        } else {
+            return new DirectoryFeatureSource(fs);
+        }
+    }
+
+    public FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriter(
+            String typeName, Filter filter, Transaction transaction)
+            throws IOException {
+        return getDataStore(typeName).getFeatureWriter(typeName, filter, transaction);
+    }
+
+    public FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriter(
+            String typeName, Transaction transaction) throws IOException {
+        return getDataStore(typeName).getFeatureWriter(typeName, transaction);
+    }
+
+    public FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriterAppend(
+            String typeName, Transaction transaction) throws IOException {
+        return getDataStore(typeName).getFeatureWriterAppend(typeName, transaction);
+    }
+
+    public LockingManager getLockingManager() {
+        if(lm == null) {
+            lm = new DirectoryLockingManager(cache);
+        }
+        return lm;
+    }
+
+    public SimpleFeatureType getSchema(String typeName) throws IOException {
+        return getDataStore(typeName).getSchema(typeName);
+    }
+
+    public String[] getTypeNames() throws IOException {
+        Set<String> typeNames = cache.getTypeNames();
+        return typeNames.toArray(new String[typeNames.size()]);
+    }
+
+    public void updateSchema(String typeName, SimpleFeatureType featureType)
+            throws IOException {
+        getDataStore(typeName).updateSchema(typeName, featureType);
+    }
+
+    public void createSchema(SimpleFeatureType featureType) throws IOException {
+        File f = new File(cache.directory, featureType.getTypeName()+".shp");
+        
+        String shpDataStoreClassName = "org.geotools.data.shapefile.ShapefileDataStore";
+        DataStore ds = null;
+        try {
+            ds = (DataStore) Class.forName(shpDataStoreClassName).getConstructor(URL.class)
+                .newInstance(f.toURL());
+            ds.createSchema(featureType);
+            ds.dispose();
+            cache.refreshCacheContents();
+        }
+        catch(Exception e) {
+            throw (IOException) new IOException("Error creating new data store").initCause(e);
+        }
+    }
+
+    public void dispose() {
+        cache.dispose();
+    }
+    
+    /**
+     * Returns the native store for a specified type name
+     * @param typeName
+     * @return
+     * @throws IOException
+     */
+    public DataStore getDataStore(String typeName) throws IOException {
+        // grab the store for a specific feature type, making sure it's actually there
+        DataStore store = cache.getDataStore(typeName, true);
+        if(store == null)
+            throw new IOException("Feature type " + typeName + " is unknown");
+        return store;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryFeatureLocking.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryFeatureLocking.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryFeatureLocking.java	(revision 28000)
@@ -0,0 +1,70 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.directory;
+
+import java.io.IOException;
+
+import org.geotools.data.FeatureLock;
+import org.geotools.data.Query;
+import org.geotools.data.simple.SimpleFeatureLocking;
+import org.opengis.filter.Filter;
+
+public class DirectoryFeatureLocking extends DirectoryFeatureStore implements
+        SimpleFeatureLocking {
+
+    SimpleFeatureLocking flocking;
+
+    public DirectoryFeatureLocking(
+            SimpleFeatureLocking locking) {
+        super(locking);
+        this.flocking = locking;
+    }
+
+    public int lockFeatures() throws IOException {
+        return flocking.lockFeatures();
+    }
+
+    public int lockFeatures(Filter filter) throws IOException {
+        return flocking.lockFeatures(filter);
+    }
+
+    public void setFeatureLock(FeatureLock lock) {
+        flocking.setFeatureLock(lock);
+    }
+
+    public int lockFeatures(Query query) throws IOException {
+        return flocking.lockFeatures(query);
+    }
+
+    public void unLockFeatures() throws IOException {
+        flocking.unLockFeatures();
+    }
+
+    public void unLockFeatures(Filter filter) throws IOException {
+        flocking.unLockFeatures(filter);
+    }
+
+    public void unLockFeatures(Query query) throws IOException {
+        flocking.unLockFeatures(query);
+    }
+    
+    @Override
+    public SimpleFeatureLocking unwrap() {
+        return flocking;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryFeatureSource.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryFeatureSource.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryFeatureSource.java	(revision 28000)
@@ -0,0 +1,103 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.directory;
+
+import java.awt.RenderingHints.Key;
+import java.io.IOException;
+import java.util.Set;
+
+import org.geotools.data.DataAccess;
+import org.geotools.data.FeatureListener;
+import org.geotools.data.Query;
+import org.geotools.data.QueryCapabilities;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureSource;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+
+public class DirectoryFeatureSource implements SimpleFeatureSource {
+    SimpleFeatureSource fsource;
+    
+    public DirectoryFeatureSource(
+            SimpleFeatureSource delegate) {
+        this.fsource = delegate;
+    }
+
+    public void addFeatureListener(FeatureListener listener) {
+        fsource.addFeatureListener(listener);
+    }
+
+    public ReferencedEnvelope getBounds() throws IOException {
+        return fsource.getBounds();
+    }
+
+    public ReferencedEnvelope getBounds(Query query) throws IOException {
+        return fsource.getBounds(query);
+    }
+
+    public int getCount(Query query) throws IOException {
+        return fsource.getCount(query);
+    }
+
+    public DataAccess<SimpleFeatureType, SimpleFeature> getDataStore() {
+        // this is done on purpose to avoid crippling the shapefile renderer optimizations
+        return fsource.getDataStore();
+    }
+
+    public SimpleFeatureCollection getFeatures()
+            throws IOException {
+        return fsource.getFeatures();
+    }
+
+    public SimpleFeatureCollection getFeatures(
+            Filter filter) throws IOException {
+        return fsource.getFeatures(filter);
+    }
+
+    public SimpleFeatureCollection getFeatures(
+            Query query) throws IOException {
+        return fsource.getFeatures(query);
+    }
+
+    public Name getName() {
+        return fsource.getName();
+    }
+
+    public QueryCapabilities getQueryCapabilities() {
+        return fsource.getQueryCapabilities();
+    }
+
+    public SimpleFeatureType getSchema() {
+        return fsource.getSchema();
+    }
+
+    public Set<Key> getSupportedHints() {
+        return fsource.getSupportedHints();
+    }
+
+    public void removeFeatureListener(FeatureListener listener) {
+        fsource.removeFeatureListener(listener);
+    }
+
+    public SimpleFeatureSource unwrap() {
+        return fsource;
+    }
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryFeatureStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryFeatureStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryFeatureStore.java	(revision 28000)
@@ -0,0 +1,106 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.directory;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.geotools.data.FeatureListener;
+import org.geotools.data.FeatureReader;
+import org.geotools.data.Transaction;
+import org.geotools.data.simple.SimpleFeatureStore;
+import org.geotools.feature.FeatureCollection;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+import org.opengis.filter.identity.FeatureId;
+
+public class DirectoryFeatureStore extends DirectoryFeatureSource implements
+        SimpleFeatureStore {
+
+    SimpleFeatureStore fstore;
+
+    public DirectoryFeatureStore(SimpleFeatureStore store) {
+        super(store);
+        this.fstore = store;
+    }
+
+    public Transaction getTransaction() {
+        return fstore.getTransaction();
+    }
+
+    public void modifyFeatures(Name attributeName, Object attributeValue, Filter filter)
+            throws IOException {
+        fstore.modifyFeatures(attributeName, attributeValue, filter);
+    }
+    
+    public void modifyFeatures(AttributeDescriptor type, Object value,
+            Filter filter) throws IOException {
+        fstore.modifyFeatures(type, value, filter);
+    }
+    
+    public void modifyFeatures(Name[] name, Object[] value,
+            Filter filter) throws IOException {
+        fstore.modifyFeatures(name, value, filter);
+    }
+
+    public void modifyFeatures(String name, Object value, Filter filter)
+            throws IOException {
+        fstore.modifyFeatures(name, value, filter);
+    }
+
+    public void modifyFeatures(String[] names, Object[] values, Filter filter) throws IOException {
+        fstore.modifyFeatures(names, values, filter);
+    }
+    
+    public void modifyFeatures(AttributeDescriptor[] type, Object[] value,
+            Filter filter) throws IOException {
+        fstore.modifyFeatures(type, value, filter);
+    }
+
+    public void removeFeatureListener(FeatureListener listener) {
+        fstore.removeFeatureListener(listener);
+    }
+
+    public void removeFeatures(Filter filter) throws IOException {
+        fstore.removeFeatures(filter);
+    }
+
+    public void setFeatures(
+            FeatureReader<SimpleFeatureType, SimpleFeature> reader)
+            throws IOException {
+        fstore.setFeatures(reader);
+    }
+
+    public void setTransaction(Transaction transaction) {
+        fstore.setTransaction(transaction);
+    }
+
+    public List<FeatureId> addFeatures(
+            FeatureCollection collection)
+            throws IOException {
+        return fstore.addFeatures(collection);
+    }
+    
+    @Override
+    public SimpleFeatureStore unwrap() {
+        return fstore;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryLockingManager.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryLockingManager.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryLockingManager.java	(revision 28000)
@@ -0,0 +1,104 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.directory;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.geotools.data.DataStore;
+import org.geotools.data.FeatureLock;
+import org.geotools.data.LockingManager;
+import org.geotools.data.Transaction;
+
+/**
+ * Locking manager that will delegate its work to the locking managers of the 
+ * delegate data stores 
+ * @author Andrea Aime - OpenGeo
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/data/src/main/java/org/geotools/data/directory/DirectoryLockingManager.java $
+ */
+public class DirectoryLockingManager implements LockingManager {
+    
+    DirectoryTypeCache cache;
+    
+    public DirectoryLockingManager(DirectoryTypeCache cache) {
+        this.cache = cache;
+    }
+
+    public boolean exists(String authID) {
+        List<DataStore> stores = cache.getDataStores();
+        for (DataStore store : stores) {
+            if ((store.getLockingManager() != null)
+                    && store.getLockingManager().exists(authID)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public boolean release(String authID, Transaction transaction)
+        throws IOException {
+        List<DataStore> stores = cache.getDataStores();
+        for (DataStore store : stores) {
+            if ((store.getLockingManager() != null)
+                    && store.getLockingManager().exists(authID)) {
+                return store.getLockingManager().release(authID, transaction);
+            }
+        }
+
+        return false;
+    }
+
+    public boolean refresh(String authID, Transaction transaction)
+        throws IOException {
+        List<DataStore> stores = cache.getDataStores();
+        for (DataStore store : stores) {
+            if ((store.getLockingManager() != null)
+                    && store.getLockingManager().exists(authID)) {
+                return store.getLockingManager().refresh(authID, transaction);
+            }
+        }
+
+        return false;
+    }
+
+    public void unLockFeatureID(String typeName, String authID,
+        Transaction transaction, FeatureLock featureLock)
+        throws IOException {
+        DataStore store = cache.getDataStore(typeName, false);
+
+        if ((store != null) && (store.getLockingManager() != null)) {
+            store.getLockingManager().unLockFeatureID(typeName, authID,
+                transaction, featureLock);
+        }
+    }
+
+    public void lockFeatureID(String typeName, String authID,
+        Transaction transaction, FeatureLock featureLock)
+        throws IOException {
+        DataStore store = cache.getDataStore(typeName, false);
+
+        if ((store != null) && (store.getLockingManager() != null)) {
+            store.getLockingManager().lockFeatureID(typeName, authID,
+                transaction, featureLock);
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryTypeCache.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryTypeCache.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryTypeCache.java	(revision 28000)
@@ -0,0 +1,328 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+
+package org.geotools.data.directory;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.ref.SoftReference;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.data.DataStore;
+import org.geotools.util.logging.Logging;
+
+/**
+ * <p>Handles all of the data stores that a directory data store relies onto,
+ * centralizing the gathering and caching policies and code.</p>
+ * <p>The class is completely thread safe</p>
+ * 
+ * @author Andrea Aime - OpenGeo
+ */
+class DirectoryTypeCache {
+    static final Logger LOGGER = Logging.getLogger(DirectoryTypeCache.class);
+
+    /**
+     * The feature type cache, a map from the feature type to the 
+     * information of where the feature type is coming from
+     */
+    Map<String, FileEntry> ftCache = new ConcurrentHashMap<String, FileEntry>();
+
+    /**
+     * The directory we're gathering data from
+     */
+    File directory;
+
+    /**
+     * The watcher, which is used to tell when the type cache is stale
+     * and needs updating
+     */
+    DirectoryWatcher watcher;
+    
+    /**
+     * A lock used for isolating cache updates
+     */
+    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
+    /**
+     * Will create the delegate stores
+     */
+    FileStoreFactory factory;
+    
+    /**
+     * Builds a new cache.
+     * 
+     * @param directory
+     *            a non null File pointing to an existing directory
+     * @throws IOException
+     */
+    DirectoryTypeCache(File directory, FileStoreFactory factory) throws IOException {
+        // some basic checks
+        if (directory == null)
+            throw new NullPointerException(
+                    "Directory parameter should be not null");
+
+        if (!directory.exists()) {
+            throw new IllegalArgumentException(
+                    "Specified directory does not exists: "
+                            + directory.getAbsolutePath());
+        }
+
+        if (!directory.isDirectory()) {
+            throw new IllegalArgumentException(
+                    "Specified path is not a directory, it'a s file instead: "
+                            + directory.getAbsolutePath());
+        }
+        
+        this.directory = directory;
+        this.factory = factory;
+
+        this.watcher = new ImmediateDirectoryWatcher(directory);
+    }
+
+    /**
+     * Returns the data store containing a specific feature type, or null if not
+     * found
+     * 
+     * @param typeName
+     * @param forceUpdate If true, it will force the update
+     * @return
+     */
+    DataStore getDataStore(String typeName, boolean forceUpdate) throws IOException {
+        lock.readLock().lock();
+        try {
+            if(forceUpdate)
+                updateCache();
+            // TODO: check about re-creating the datastore when the cache
+            // is turned into a soft map
+            return ftCache.get(typeName).getStore(true);
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+    
+    /**
+     * Returns all the type names known
+     * @return
+     */
+    Set<String> getTypeNames() throws IOException {
+        lock.readLock().lock();
+        
+        try {
+            updateCache();
+            return ftCache.keySet();
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+    
+    /**
+     * Returns all active data stores available in the cache. 
+     * Won't force the creation of a new data store if it has been disposed of and
+     * it's currently not needed for the functionality of the whole thing
+     */
+    List<DataStore> getDataStores() {
+        List<DataStore> stores = new ArrayList<DataStore>();
+        lock.readLock().lock();
+        
+        try {
+            for (FileEntry entry : ftCache.values()) {
+                try {
+                    DataStore store = entry.getStore(false);
+                    if(store != null)
+                        stores.add(store);
+                } catch(Exception e) {
+                    LOGGER.log(Level.FINE, "Error occurred trying to grab a datastore", e);
+                }
+            }
+        } finally {
+            lock.readLock().unlock();
+        }
+        
+        return stores;
+    }
+    
+    /**
+     * Checks if the feature type cache contents needs updating, does so in case.
+     * The code assumes the caller already owns a read only lock that needs upgrading
+     * in case the information is stale.
+     */
+    private void updateCache() throws IOException {
+        if(watcher.isStale()) {
+            // upgrade lock so that we have exclusive access to ftCache
+            lock.readLock().unlock();
+            lock.writeLock().lock();
+            
+            try {
+                // still stale?
+                if(watcher.isStale()) {
+                    watcher.mark();
+                    refreshCacheContents();
+                }
+            } finally {
+                // downgrade lock
+                lock.readLock().lock();
+                lock.writeLock().unlock();
+            }
+        }
+    }
+
+    /**
+     * Here we try to refresh the contents of the feature type cache.
+     * <p>
+     * Basically we want to:
+     * <ul>
+     * <li>remove all data stores associated to files that have been removed</li>
+     * <li>add all data stores associated to new files</li>
+     * <li>remove all feature types that are no more there, and add all feature
+     * types that are new
+     * <li>
+     * </ul>
+     * All of this should be done trying to avoid re-creating all of the
+     * datastores already loaded. We assume a properly written datastore will be
+     * able to detect changes in its own feature type list and feature type
+     * schemas on its own.
+     * 
+     * @throws IOException
+     */
+    void refreshCacheContents() throws IOException {
+        // prepare the replacement ft cache
+        Map<String, FileEntry> result = new TreeMap<String, FileEntry>();
+
+        // build support structure used to quickly find files that need updating
+        Map<File, FileEntry> fileCache = new HashMap<File, FileEntry>();
+        for (FileEntry entry : ftCache.values()) {
+            fileCache.put(entry.file, entry);
+        }
+        
+        // grab all the candidate files
+        for (File file : directory.listFiles()) {
+            // skip over directories, we don't recurse
+            if(file.isDirectory()) {
+                continue;
+            }
+            
+            // do we have the same datastore in the current cache? If so keep it, we don't
+            // want to rebuild over and over the same stores
+            FileEntry entry = fileCache.get(file);
+            
+            // if missing build a new one
+            if(entry == null) {
+                DataStore store = factory.getDataStore(file);
+                if(store != null) {
+                    entry = new FileEntry(file, store);
+                }
+            }
+            
+            // if we managed to build an entry collect its feature types
+            if(entry != null) {
+                for (String typeName : entry.getStore(true).getTypeNames()) {
+                    // don't override existing entries
+                    if (!result.containsKey(typeName))
+                        result.put(typeName, entry);
+                    else {
+                        LOGGER.log(Level.WARNING, "Type name " + typeName
+                                + " is available from multiple datastores");
+                    }
+                }
+            }
+        }
+        
+        // update the cache. We need to remove the missing elements, disposing
+        // the data stores that are not referenced anymore, and add the new ones
+        // we are going to update the ftCache as we go, this is thread safe
+        // since we are using a concurrent hash map for ftCache, and won't
+        // hinder users of live data stores since we are not going to touch
+        // the ones that are not being removed (the ones that we are going to
+        // remove should be not working anyways)
+        Set<String> removedFTs = new HashSet<String>(ftCache.keySet());
+        removedFTs.removeAll(result.keySet());
+        
+        // collect all data stores that are referred by a feature type that we 
+        // are going to remove, but are not referred by any feature type we're
+        // going to keep. Clean the ftCache from removed feature types at the same
+        // time.
+        Set<FileEntry> disposable = new HashSet<FileEntry>(); 
+        for (String removedFT : removedFTs) {
+            disposable.add(ftCache.remove(removedFT));
+        }
+        for (FileEntry entry : result.values()) {
+            disposable.remove(entry);
+        }
+        for (FileEntry entry : disposable) {
+            entry.dispose();
+        }
+        
+        // now let's add all the new ones
+        Set<String> added = new HashSet<String>(result.keySet());
+        added.removeAll(ftCache.keySet());
+        for (String newFeatureType : added) {
+            ftCache.put(newFeatureType, result.get(newFeatureType));
+        }
+    }
+ 
+    /**
+     * Disposes of the file cache and all the cached data stores
+     */
+    void dispose() {
+        // dispose all of the entries, they can be disposed more than
+        // once so just scanning the values is ok (generally speaking we'll
+        // find the same entry more than once among the values, once per
+        // registered feature type in the same data store in general)
+        for (FileEntry entry : ftCache.values()) {
+            entry.dispose();
+        }
+    }
+
+    class FileEntry {
+        File file;
+
+        SoftReference<DataStore> ref;
+        
+        public FileEntry(File file, DataStore store) {
+            this.file = file;
+            ref = new DataStoreSoftReference(store);
+        }
+        
+        DataStore getStore(boolean force) throws IOException {
+            DataStore store = ref != null ? ref.get() : null;
+            if(store == null && force) {
+                store = factory.getDataStore(file);
+                ref = new DataStoreSoftReference(store);
+            } 
+            return store;
+        }
+        
+        void dispose() {
+            DataStore store = ref != null ? ref.get() : null;
+            if(store != null)
+                store.dispose();
+            ref.clear();
+        }
+    }
+    
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryWatcher.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryWatcher.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/DirectoryWatcher.java	(revision 28000)
@@ -0,0 +1,38 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.directory;
+
+/**
+ * Implementors will provide a service that checks if directory contents are
+ * changed since last refresh.
+ * 
+ * @author Andrea Aime
+ * 
+ */
+interface DirectoryWatcher {
+
+    /**
+     * Reports if the directory last modified has changed since {@link #mark()}
+     * was last called
+     */
+    public boolean isStale();
+
+    /**
+     * Marks the time the directory has been last checked at
+     */
+    public void mark();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/FileStoreFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/FileStoreFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/FileStoreFactory.java	(revision 28000)
@@ -0,0 +1,23 @@
+package org.geotools.data.directory;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.geotools.data.DataStore;
+
+/**
+ * A delegate that finds the files managed by the directory store and
+ * @author Andrea Aime - OpenGeo
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/build/maven/javadoc/../../../modules/library/data/src/main/java/org/geotools/data/directory/FileStoreFactory.java $
+ */
+public interface FileStoreFactory {
+    
+    /**
+     * Returns a store for the specified file
+     * @param file
+     * @return
+     */
+    DataStore getDataStore(File file) throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/ImmediateDirectoryWatcher.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/ImmediateDirectoryWatcher.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/directory/ImmediateDirectoryWatcher.java	(revision 28000)
@@ -0,0 +1,47 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.directory;
+
+import java.io.File;
+
+/**
+ * Performs a last updated check each time isStale is called. Accurate, but will
+ * incur in scalability issues under heavy multithreaded load on servers (file
+ * access is typically expensive as it requires a switch to kernel space)
+ * 
+ * @author Andrea Aime
+ * 
+ */
+class ImmediateDirectoryWatcher implements DirectoryWatcher {
+
+    File directory;
+
+    Long lastUpdated;
+
+    public ImmediateDirectoryWatcher(File directory) {
+        this.directory = directory;
+    }
+
+    public synchronized boolean isStale() {
+        return lastUpdated == null || lastUpdated < directory.lastModified();
+    }
+
+    public synchronized void mark() {
+        lastUpdated = directory.lastModified();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/FileChannelDecorator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/FileChannelDecorator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/FileChannelDecorator.java	(revision 28000)
@@ -0,0 +1,148 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
+
+/**
+ * A FileChannel that delegates all calls to the underlying FileChannel but for
+ * {@link #implCloseChannel()} it also calls ShapefileFiles.unlock method to
+ * release the lock on the URL.
+ * 
+ * @author jesse
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/FileChannelDecorator.java $
+ */
+public class FileChannelDecorator extends FileChannel {
+
+    private final FileChannel wrapped;
+    private final ShpFiles shapefileFiles;
+    private final URL url;
+    private final FileReader reader;
+    private final FileWriter writer;
+    private boolean closed;
+
+    public FileChannelDecorator(FileChannel channel, ShpFiles shapefileFiles,
+            URL url, FileReader requestor) {
+        this.wrapped = channel;
+        this.shapefileFiles = shapefileFiles;
+        this.url = url;
+        this.reader = requestor;
+        writer = null;
+        this.closed = false;
+    }
+
+    public void force(boolean metaData) throws IOException {
+        wrapped.force(metaData);
+    }
+
+    public FileLock lock(long position, long size, boolean shared)
+            throws IOException {
+        return wrapped.lock(position, size, shared);
+    }
+
+    public MappedByteBuffer map(MapMode mode, long position, long size)
+            throws IOException {
+//    	return wrapped.map(mode, position, size)
+    	 return shapefileFiles.map(wrapped, url, mode, position, size);
+    }
+
+    public long position() throws IOException {
+        return wrapped.position();
+    }
+
+    public FileChannel position(long newPosition) throws IOException {
+        return wrapped.position(newPosition);
+    }
+
+    public int read(ByteBuffer dst, long position) throws IOException {
+        return wrapped.read(dst, position);
+    }
+
+    public int read(ByteBuffer dst) throws IOException {
+        return wrapped.read(dst);
+    }
+
+    public long read(ByteBuffer[] dsts, int offset, int length)
+            throws IOException {
+        return wrapped.read(dsts, offset, length);
+    }
+
+    public long size() throws IOException {
+        return wrapped.size();
+    }
+
+    public long transferFrom(ReadableByteChannel src, long position, long count)
+            throws IOException {
+        return wrapped.transferFrom(src, position, count);
+    }
+
+    public long transferTo(long position, long count, WritableByteChannel target)
+            throws IOException {
+        return wrapped.transferTo(position, count, target);
+    }
+
+    public FileChannel truncate(long size) throws IOException {
+        return wrapped.truncate(size);
+    }
+
+    public FileLock tryLock(long position, long size, boolean shared)
+            throws IOException {
+        return wrapped.tryLock(position, size, shared);
+    }
+
+    public int write(ByteBuffer src, long position) throws IOException {
+        return wrapped.write(src, position);
+    }
+
+    public int write(ByteBuffer src) throws IOException {
+        return wrapped.write(src);
+    }
+
+    public long write(ByteBuffer[] srcs, int offset, int length)
+            throws IOException {
+        return wrapped.write(srcs, offset, length);
+    }
+
+    @Override
+    protected void implCloseChannel() throws IOException {
+        try {
+            wrapped.close();
+        } finally {
+            if (!closed) {
+                closed = true;
+                if (reader != null) {
+                    shapefileFiles.unlockRead(url, reader);
+                } else {
+                    shapefileFiles.unlockWrite(url, writer);
+                }
+            }
+        }
+
+    }
+    
+    
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/FileReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/FileReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/FileReader.java	(revision 28000)
@@ -0,0 +1,29 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+/**
+ * Indicates that the object reads one of the Shapefile related files controlled
+ * by {@link ShpFiles}
+ * 
+ * @author jesse
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/FileReader.java $
+ */
+public interface FileReader {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/FileWriter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/FileWriter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/FileWriter.java	(revision 28000)
@@ -0,0 +1,29 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+/**
+ * Indicates that the object writes to one of the Shapefile related files
+ * controlled by {@link ShpFiles}
+ * 
+ * @author jesse
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/FileWriter.java $
+ */
+public interface FileWriter extends FileReader {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/MemoryMapCache.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/MemoryMapCache.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/MemoryMapCache.java	(revision 28000)
@@ -0,0 +1,133 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.data.DataUtilities;
+import org.geotools.resources.NIOUtilities;
+import org.geotools.util.SoftValueHashMap;
+import org.geotools.util.logging.Logging;
+
+/**
+ * A cache for memory mapped buffers, used to avoid generating over and over
+ * read only memory mapped buffers. Mapping a file is a synchronized operation,
+ * plus by generating light copies the same buffer can be shared by various threads
+ * @author Andrea Aime - OpenGeo
+ *
+ */
+class MemoryMapCache {
+	
+	static final Logger LOGGER = Logging.getLogger(MemoryMapCache.class);
+
+    SoftValueHashMap<MappingKey, MappedByteBuffer> buffers = new SoftValueHashMap<MappingKey, MappedByteBuffer>(0);
+    
+	MappedByteBuffer map(FileChannel wrapped, URL url, MapMode mode, long position, long size) throws IOException {
+		if(mode != MapMode.READ_ONLY) {
+			return wrapped.map(mode, position, size);
+		}
+		
+		File file = DataUtilities.urlToFile(url).getCanonicalFile();
+		MappingKey mk = new MappingKey(file, position, size);
+		MappedByteBuffer buffer = buffers.get(mk);
+		if(buffer == null) {
+			synchronized (this) {
+				buffer = buffers.get(mk);
+				if(buffer == null) {
+					buffer = wrapped.map(mode, position, size);
+					buffers.put(mk, buffer);
+					if(LOGGER.isLoggable(Level.FINE)) {
+						LOGGER.log(Level.FINE, "Mapping and caching " + file.getAbsolutePath());
+					}
+				}
+			}
+		} else {
+			if(LOGGER.isLoggable(Level.FINE)) {
+				LOGGER.log(Level.FINE, "Using cached map for " + file.getAbsolutePath());
+			}
+		}
+		
+		return (MappedByteBuffer) buffer.duplicate();
+	}
+		
+	void clean() {
+		List<MappingKey> keys = new ArrayList<MappingKey>(buffers.keySet());
+	    for (MappingKey key : keys) {
+            MappedByteBuffer buffer = buffers.remove(key);
+            NIOUtilities.clean(buffer, true);
+            if(LOGGER.isLoggable(Level.FINE)) {
+				LOGGER.log(Level.FINE, "Removed mapping for " + key.file.getAbsolutePath());
+            }
+        }
+	}
+	
+	/**
+	 * Tracks a memory mapped region of a certain file
+	 */
+	static class MappingKey {
+		File file;
+		long position;
+		long size;
+		
+		public MappingKey(File file, long position, long size) {
+			super();
+			this.file = file;
+			this.position = position;
+			this.size = size;
+		}
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ((file == null) ? 0 : file.hashCode());
+            result = prime * result + (int) (position ^ (position >>> 32));
+            result = prime * result + (int) (size ^ (size >>> 32));
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            MappingKey other = (MappingKey) obj;
+            if (file == null) {
+                if (other.file != null)
+                    return false;
+            } else if (!file.equals(other.file))
+                return false;
+            if (position != other.position)
+                return false;
+            if (size != other.size)
+                return false;
+            return true;
+        }
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ReadableByteChannelDecorator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ReadableByteChannelDecorator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ReadableByteChannelDecorator.java	(revision 28000)
@@ -0,0 +1,70 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.channels.ReadableByteChannel;
+
+/**
+ * A ReadableByteChannel that delegates all calls to the underlying
+ * ReadableByteChannel but for {@link #close()} it also calls
+ * ShapefileFiles.unlock method to release the lock on the URL.
+ * 
+ * @author jesse
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/ReadableByteChannelDecorator.java $
+ */
+public class ReadableByteChannelDecorator implements ReadableByteChannel {
+
+    private final ReadableByteChannel wrapped;
+    private final ShpFiles shapefileFiles;
+    private final URL url;
+    private final FileReader requestor;
+    private boolean closed;
+
+    public ReadableByteChannelDecorator(ReadableByteChannel newChannel,
+            ShpFiles shapefileFiles, URL url, FileReader requestor) {
+        this.wrapped = newChannel;
+        this.shapefileFiles = shapefileFiles;
+        this.url = url;
+        this.requestor = requestor;
+        this.closed = false;
+    }
+
+    public void close() throws IOException {
+        try {
+            wrapped.close();
+        } finally {
+            if (!closed) {
+                closed = true;
+                shapefileFiles.unlockRead(url, requestor);
+            }
+        }
+    }
+
+    public boolean isOpen() {
+        return wrapped.isOpen();
+    }
+
+    public int read(ByteBuffer dst) throws IOException {
+        return wrapped.read(dst);
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileAttributeReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileAttributeReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileAttributeReader.java	(revision 28000)
@@ -0,0 +1,222 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.geotools.data.AbstractAttributeIO;
+import org.geotools.data.shapefile.dbf.DbaseFileHeader;
+import org.geotools.data.shapefile.dbf.DbaseFileReader;
+import org.geotools.data.shapefile.indexed.RecordNumberTracker;
+import org.geotools.data.shapefile.shp.ShapefileReader;
+import org.opengis.feature.type.AttributeDescriptor;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * An AttributeReader implementation for Shapefile. Pretty straightforward.
+ * <BR/>The default geometry is at position 0, and all dbf columns follow.
+ * <BR/>The dbf file may not be necessary, if not, just pass null as the
+ * DbaseFileReader
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/ShapefileAttributeReader.java $
+ */
+public class ShapefileAttributeReader extends AbstractAttributeIO implements
+        /*AttributeReader,*/ RecordNumberTracker {
+
+    protected ShapefileReader shp;
+    protected DbaseFileReader dbf;
+    protected DbaseFileReader.Row row;
+    protected ShapefileReader.Record record;
+    protected int[] dbfindexes;
+    protected Envelope targetBBox;
+    protected Object geometry;
+    protected boolean featureAvailable = false;
+
+    public ShapefileAttributeReader(List<AttributeDescriptor> atts,
+            ShapefileReader shp, DbaseFileReader dbf) {
+        this(atts.toArray(new AttributeDescriptor[0]), shp, dbf);
+    }
+    
+    /**
+     * Sets a search area. If the geometry does not fall into it
+     * it won't be read and will return a null geometry instead 
+     * @param envelope
+     */
+    public void setTargetBBox(Envelope envelope) {
+        this.targetBBox = envelope;
+    }
+    
+    public void setSimplificationDistance(double distance) {
+    }
+    
+    /**
+     * Create the shapefile reader
+     * 
+     * @param atts -
+     *                the attributes that we are going to read.
+     * @param shp -
+     *                the shapefile reader, required
+     * @param dbf -
+     *                the dbf file reader. May be null, in this case no
+     *                attributes will be read from the dbf file
+     */
+    public ShapefileAttributeReader(AttributeDescriptor[] atts,
+            ShapefileReader shp, DbaseFileReader dbf) {
+        super(atts);
+        this.shp = shp;
+        this.dbf = dbf;
+        
+        if(dbf != null) {
+            dbfindexes = new int[atts.length];
+            DbaseFileHeader head = dbf.getHeader();
+            AT: for (int i = 0; i < atts.length; i++) {
+                String attName = atts[i].getLocalName();
+                int count = 0;
+                if (atts[i].getUserData().get(ShapefileDataStore.ORIGINAL_FIELD_NAME) != null){
+                	attName = (String)atts[i].getUserData().get(ShapefileDataStore.ORIGINAL_FIELD_NAME);
+                	count = (Integer)atts[i].getUserData().get(ShapefileDataStore.ORIGINAL_FIELD_DUPLICITY_COUNT);
+                }
+
+                for(int j = 0; j < head.getNumFields(); j++) {
+                    if(head.getFieldName(j).equals(attName) && count-- <= 0){
+                        dbfindexes[i] = j;
+                        continue AT;
+                    }
+                }
+                dbfindexes[i] = -1; // geometry
+            }
+        }
+    }
+
+    public void close() throws IOException {
+        try {
+            if (shp != null) {
+                shp.close();
+            }
+
+            if (dbf != null) {
+                dbf.close();
+            }
+        } finally {
+            row = null;
+            record = null;
+            shp = null;
+            dbf = null;
+        }
+    }
+
+    boolean internalReadersHaveNext() throws IOException {
+        int n = shp.hasNext() ? 1 : 0;
+
+        if (dbf != null) {
+            n += (dbf.hasNext() ? 2 : 0);
+        }
+
+        if ((n == 3) || ((n == 1) && (dbf == null))) {
+            return true;
+        }
+
+        if (n == 0) {
+            return false;
+        }
+
+        throw new IOException(((n == 1) ? "Shp" : "Dbf") + " has extra record");
+    }
+    
+    public boolean hasNext() throws IOException {
+        while(!featureAvailable && internalReadersHaveNext()) {
+            record = shp.nextRecord();
+            
+            // read the geometry, so that we can decide if this row is to be skipped or not
+            Envelope envelope = record.envelope();
+            boolean skip = false;
+            // ... if geometry is out of the target bbox, skip both geom and row
+            if (targetBBox != null && !targetBBox.isNull() && !targetBBox.intersects(envelope)) {
+                geometry = null;
+                skip = true;
+            // ... if the geometry is awfully small avoid reading it (unless it's a point)
+            /*} else if (simplificationDistance > 0 && envelope.getWidth() < simplificationDistance
+                    && envelope.getHeight() < simplificationDistance) {
+                try {
+                    if(screenMap != null && screenMap.checkAndSet(envelope)) {
+                        geometry = null;
+                        skip = true;
+                    } else {
+                        // if we are using the screenmap better provide a slightly modified
+                        // version of the geometry bounds or we'll end up with many holes
+                        // in the rendering
+                        geometry = record.getSimplifiedShape(screenMap);
+                    }
+                } catch(Exception e) {
+                    geometry = record.getSimplifiedShape();
+                }*/
+            // ... otherwise business as usual
+            } else {
+                geometry = record.shape();
+            }
+
+            // read the dbf only if the geometry was not skipped
+            if (dbf != null) {
+                if(skip) {
+                    dbf.skip();
+                    row = null;
+                } else {
+                    row = dbf.readRow();
+                }
+            } else {
+                row = null;
+            }
+            featureAvailable = !skip;
+        }
+        
+        return featureAvailable;
+    }
+
+    public void next() throws IOException {
+        if(!hasNext()) {
+            throw new NoSuchElementException("hasNext() returned false");
+        }
+        featureAvailable = false;
+    }
+
+    public Object read(int param) throws IOException,
+            java.lang.ArrayIndexOutOfBoundsException {
+        int index = dbfindexes != null ? dbfindexes[param] : -1;
+                   
+        switch (index) {
+        case -1:
+            return geometry; // geometry is considered dbf index -1
+
+        default:
+            if (row != null) {
+                return row.read( index );
+            }
+            return null;
+        }
+    }
+    
+    public int getRecordNumber() {
+        return this.record.number;
+    }
+
+    
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileDataStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileDataStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileDataStore.java	(revision 28000)
@@ -0,0 +1,850 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import static org.geotools.data.shapefile.ShpFileType.DBF;
+import static org.geotools.data.shapefile.ShpFileType.PRJ;
+import static org.geotools.data.shapefile.ShpFileType.SHP;
+import static org.geotools.data.shapefile.ShpFileType.SHP_XML;
+import static org.geotools.data.shapefile.ShpFileType.SHX;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.logging.Level;
+
+import org.geotools.data.AbstractFileDataStore;
+import org.geotools.data.DataSourceException;
+import org.geotools.data.DataUtilities;
+import org.geotools.data.FeatureReader;
+import org.geotools.data.FeatureWriter;
+import org.geotools.data.Query;
+import org.geotools.data.ServiceInfo;
+import org.geotools.data.Transaction;
+import org.geotools.data.shapefile.dbf.DbaseFileHeader;
+import org.geotools.data.shapefile.dbf.DbaseFileReader;
+import org.geotools.data.shapefile.indexed.ShapeFIDReader;
+import org.geotools.data.shapefile.prj.PrjFileReader;
+import org.geotools.data.shapefile.shp.IndexFile;
+import org.geotools.data.shapefile.shp.JTSUtilities;
+import org.geotools.data.shapefile.shp.ShapefileException;
+import org.geotools.data.shapefile.shp.ShapefileHeader;
+import org.geotools.data.shapefile.shp.ShapefileReader;
+import org.geotools.data.shapefile.shp.xml.ShpXmlFileReader;
+import org.geotools.data.simple.SimpleFeatureSource;
+import org.geotools.factory.Hints;
+import org.geotools.feature.AttributeTypeBuilder;
+import org.geotools.feature.SchemaException;
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
+import org.geotools.feature.type.BasicFeatureTypes;
+import org.geotools.filter.FilterAttributeExtractor;
+import org.geotools.filter.visitor.ExtractBoundsFilterVisitor;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.resources.Classes;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.feature.type.GeometryType;
+import org.opengis.filter.Filter;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import com.vividsolutions.jts.geom.CoordinateSequenceFactory;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.MultiLineString;
+import com.vividsolutions.jts.geom.MultiPoint;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+
+/**
+ * A DataStore implementation which allows reading and writing from Shapefiles.
+ * 
+ * @author Ian Schneider
+ * 
+ * @todo fix file creation bug
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/ShapefileDataStore.java $
+ */
+public class ShapefileDataStore extends AbstractFileDataStore {
+        
+    // User-data keyword names for storing the original field name and its
+    // instance number when the field name is replaced with a new name built
+    // using the original+count convention.
+    public static final String ORIGINAL_FIELD_NAME = "original";
+    public static final String ORIGINAL_FIELD_DUPLICITY_COUNT = "count";
+    
+    /**
+     * When true, the stack trace that got a lock that wasn't released is recorded and then
+     * printed out when warning the user about this.
+     */
+    protected static final Boolean TRACE_ENABLED = "true".equalsIgnoreCase(System.getProperty("gt2.shapefile.trace"));
+
+    protected ShpFiles shpFiles;
+    protected URI namespace = null; // namespace provided by the constructor's
+    // map
+    protected SimpleFeatureType schema; // read only
+    protected boolean useMemoryMappedBuffer = false; // windows is not up to use memory mapping in anger
+    protected Charset dbfCharset;
+    protected TimeZone dbfTimeZone = TimeZone.getDefault();
+    
+    private ServiceInfo info;
+
+    Exception trace;
+    
+	/**
+     * this sets the datastore's namespace during construction (so the schema -
+     * FeatureType - will have the correct value) You can call this with
+     * namespace = null, but I suggest you give it an actual namespace.
+     * 
+     * @param url
+     * @param namespace
+     * @param useMemoryMapped
+     * @param dbfCharset
+     */
+    public ShapefileDataStore(URL url, URI namespace, boolean useMemoryMapped,
+            boolean cacheMemoryMap, Charset dbfCharset) {
+        this.namespace = namespace;
+        shpFiles = new ShpFiles(url);
+        if (!isLocal() || !shpFiles.exists(SHP)) {
+            this.useMemoryMappedBuffer = false;
+        } else {
+            this.useMemoryMappedBuffer = useMemoryMapped;
+        }
+        shpFiles.setMemoryMapCacheEnabled(this.useMemoryMappedBuffer && cacheMemoryMap);
+        this.dbfCharset = dbfCharset;
+        if(TRACE_ENABLED) {
+        	trace = new Exception();
+        	trace.fillInStackTrace();
+        }
+    }
+
+    /**
+     * Access a ServiceInfo object for this shapefile.
+     * 
+     * @return ShapefileServiceInfo describing service.
+     */
+    public synchronized ServiceInfo getInfo(){
+        if( info == null ){
+            if( isLocal() ){
+                info = new ShapefileFileServiceInfo( this );
+            }
+            else {
+                info = new ShapefileURLServiceInfo( this );
+            }
+        }
+        return info;
+    }
+        
+    /**
+     * Sets the {@link TimeZone} used to parse dates in the DBF file
+     * @param dbftimeZone
+     */
+	public void setDbftimeZone(TimeZone dbftimeZone) {
+		this.dbfTimeZone = dbftimeZone;
+	}
+
+    /**
+     * Latch onto xmlURL if it is there, we may be able to get out of
+     * calculating the bounding box!
+     * 
+     * <p>
+     * This method is called by the createTypeEntry anonymous inner class
+     * DefaultTypeEntry.
+     * </p>
+     * 
+     * @param typeName
+     *                DOCUMENT ME!
+     * 
+     * @return Map with xmlURL parsed, or an EMPTY_MAP.
+     */
+    protected Map createMetadata(String typeName) {
+        String urlString = shpFiles.get(SHP_XML);
+        if (urlString == null) {
+            return Collections.EMPTY_MAP;
+        }
+
+        try {
+            // System.out.println("found metadata = " + xmlURL);
+
+            ShpXmlFileReader reader = new ShpXmlFileReader(shpFiles);
+
+            Map map = new HashMap();
+            map.put("shp.xml", reader.parse());
+            // System.out.println("parsed ..." + xmlURL);
+
+            return map;
+        } catch (Throwable t) {
+            LOGGER.warning("Could not parse " + urlString + ":"
+                    + t.getLocalizedMessage());
+
+            return Collections.EMPTY_MAP;
+        }
+    }
+
+    /**
+     * Determine if the location of this shapefile is local or remote.
+     * 
+     * @return true if local, false if remote
+     */
+    public boolean isLocal() {
+        return shpFiles.isLocal();
+    }
+
+    /**
+     * Create a  FeatureReader<SimpleFeatureType, SimpleFeature> for the provided type name.
+     * 
+     * @param typeName
+     *                The name of the FeatureType to create a reader for.
+     * 
+     * @return A new FeatureReader.
+     * 
+     * @throws IOException
+     *                 If an error occurs during creation
+     */
+    protected  FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String typeName)
+            throws IOException {
+        typeCheck(typeName);
+
+        return getFeatureReader();
+    }
+    
+    public FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader() throws IOException {
+        try {
+            return createFeatureReader(getSchema().getTypeName(),
+                    getAttributesReader(true, null), schema);
+        } catch (SchemaException se) {
+            throw new DataSourceException("Error creating schema", se);
+        }
+    }
+
+    /**
+     * Just like the basic version, but adds a small optimization: if no
+     * attributes are going to be read, don't uselessly open and read the dbf
+     * file. Makes sure to consider also attributes in the query.
+     * 
+     * @see org.geotools.data.AbstractDataStore#getFeatureReader(java.lang.String,
+     *      org.geotools.data.Query)
+     */
+    protected  FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String typeName, Query query)
+            throws IOException {
+        String[] propertyNames = query.getPropertyNames();
+        String defaultGeomName = schema.getGeometryDescriptor().getLocalName();
+        
+        // gather attributes needed by the query tool, they will be used by the
+        // query filter
+        FilterAttributeExtractor extractor = new FilterAttributeExtractor(schema);
+        Filter filter = query.getFilter();
+        filter.accept(extractor, null);
+        String[] filterAttnames = extractor.getAttributeNames();
+
+        // check if the geometry is the one and only attribute needed
+        // to return attribute _and_ to run the query filter
+        if ((propertyNames != null)
+                && (propertyNames.length == 1)
+                && propertyNames[0].equals(defaultGeomName)
+                && (filterAttnames.length == 0 || (filterAttnames.length == 1 && filterAttnames[0]
+                        .equals(defaultGeomName)))) {
+            try {
+                SimpleFeatureType newSchema = DataUtilities.createSubType(
+                        schema, propertyNames);
+
+                return createFeatureReader(typeName,
+                        getAttributesReader(false, query), newSchema);
+            } catch (SchemaException se) {
+                throw new DataSourceException("Error creating schema", se);
+            }
+        }
+
+        try {
+            return createFeatureReader(getSchema().getTypeName(),
+                    getAttributesReader(true, query), schema);
+        } catch (SchemaException se) {
+            throw new DataSourceException("Error creating schema", se);
+        }
+    }
+
+    /**
+     * Builds the most appropriate geometry factory depending on the available query hints
+     * @param query
+     * @return
+     */
+    protected GeometryFactory getGeometryFactory(Hints hints) {
+        // if no hints, use the default geometry factory
+        if(hints == null)
+            return new GeometryFactory();
+        
+        // grab a geometry factory... check for a special hint
+        GeometryFactory geometryFactory = (GeometryFactory) hints.get(Hints.JTS_GEOMETRY_FACTORY);
+        if (geometryFactory == null) {
+            // look for a coordinate sequence factory
+            CoordinateSequenceFactory csFactory = 
+                (CoordinateSequenceFactory) hints.get(Hints.JTS_COORDINATE_SEQUENCE_FACTORY);
+
+            if (csFactory != null) {
+                geometryFactory = new GeometryFactory(csFactory);
+            }
+        }
+
+        if (geometryFactory == null) {
+            // fall back on the default one
+            geometryFactory = new GeometryFactory();
+        }
+        return geometryFactory;
+    }
+
+    protected org.geotools.data.FIDFeatureReader createFeatureReader(String typeName,
+            ShapefileAttributeReader reader, SimpleFeatureType readerSchema)
+            throws SchemaException {
+
+        return new org.geotools.data.FIDFeatureReader(reader,
+                new ShapeFIDReader(readerSchema, reader), readerSchema);
+    }
+
+    /**
+     * Returns the attribute reader, allowing for a pure shapefile reader, or a
+     * combined dbf/shp reader.
+     * 
+     * @param readDbf -
+     *                if true, the dbf fill will be opened and read
+     * 
+     * 
+     * @throws IOException
+     */
+    protected ShapefileAttributeReader getAttributesReader(boolean readDbf, Query q)
+            throws IOException {
+
+        List<AttributeDescriptor> atts = (schema == null) ? readAttributes()
+                : schema.getAttributeDescriptors();
+        
+        GeometryFactory geometryFactory;
+        if(q != null) {
+            geometryFactory = getGeometryFactory(q.getHints());
+        } else {
+            geometryFactory = new GeometryFactory();
+        }
+
+        ShapefileAttributeReader result;
+        ShapefileReader shapeReader = openShapeReader(geometryFactory);
+        if (!readDbf) {
+            LOGGER.fine("The DBF file won't be opened since no attributes will be read from it");
+            atts = new ArrayList(1);
+            atts.add(schema.getGeometryDescriptor());
+            result =new ShapefileAttributeReader(atts, shapeReader, null);
+        } else {
+            result = new ShapefileAttributeReader(atts, shapeReader, openDbfReader());
+        }
+        
+        // setup the target bbox if any, and the generalization hints if available
+        if(q != null) {
+            Envelope bbox = new ReferencedEnvelope();
+            bbox = (Envelope) q.getFilter().accept(
+                ExtractBoundsFilterVisitor.BOUNDS_VISITOR, bbox);
+            if(bbox != null && !bbox.isNull()) {
+                result.setTargetBBox(bbox);
+            }
+
+            Hints hints = q.getHints();
+            if(hints != null) {
+                Number simplificationDistance = (Number) hints.get(Hints.GEOMETRY_DISTANCE);
+                if(simplificationDistance != null) {
+                    result.setSimplificationDistance(simplificationDistance.doubleValue());
+                }
+                
+                if(Boolean.TRUE.equals(hints.get(Hints.FEATURE_2D))) {
+                    shapeReader.setFlatGeometry(true);
+                }
+            }
+            
+            
+        }
+        
+        
+        return result;
+    }
+
+    /**
+     * Convenience method for opening a ShapefileReader.
+     * 
+     * @return A new ShapefileReader.
+     * 
+     * @throws IOException
+     *                 If an error occurs during creation.
+     */
+    protected ShapefileReader openShapeReader(GeometryFactory gf) throws IOException {
+        try {
+            return new ShapefileReader(shpFiles, true, useMemoryMappedBuffer, gf);
+        } catch (ShapefileException se) {
+            throw new DataSourceException("Error creating ShapefileReader", se);
+        }
+    }
+
+    /**
+     * Convenience method for opening a DbaseFileReader.
+     * 
+     * @return A new DbaseFileReader
+     * 
+     * @throws IOException
+     *                 If an error occurs during creation.
+     */
+    protected DbaseFileReader openDbfReader() throws IOException {
+
+        if (shpFiles.get(ShpFileType.DBF) == null) {
+            return null;
+        }
+
+        if (isLocal() && !shpFiles.exists(DBF)) {
+            return null;
+        }
+
+        try {
+            return new DbaseFileReader(shpFiles, useMemoryMappedBuffer,
+                    dbfCharset, dbfTimeZone);
+        } catch (IOException e) {
+            // could happen if dbf file does not exist
+            return null;
+        }
+    }
+
+    /**
+     * Convenience method for opening an index file.
+     * 
+     * @return An IndexFile
+     * 
+     * @throws IOException
+     */
+    protected IndexFile openIndexFile() throws IOException {
+        if (shpFiles.get(SHX) == null) {
+            return null;
+        }
+
+        if (isLocal() && !shpFiles.exists(SHX)) {
+            return null;
+        }
+
+        try {
+            return new IndexFile(shpFiles, this.useMemoryMappedBuffer);
+        } catch (IOException e) {
+            // could happen if shx file does not exist remotely
+            return null;
+        }
+    }
+
+    /**
+     * Convenience method for opening a DbaseFileReader.
+     * 
+     * @return A new DbaseFileReader
+     * 
+     * @throws IOException
+     *                 If an error occurs during creation.
+     * @throws FactoryException
+     *                 DOCUMENT ME!
+     */
+    protected PrjFileReader openPrjReader() throws IOException,
+            FactoryException {
+
+        if (shpFiles.get(PRJ) == null) {
+            return null;
+        }
+
+        if (isLocal() && !shpFiles.exists(PRJ)) {
+            return null;
+        }
+
+        try {
+            return new PrjFileReader(shpFiles);
+        } catch (IOException e) {
+            // could happen if prj file does not exist remotely
+            return null;
+        }
+    }
+
+    /**
+     * Get an array of type names this DataStore holds.<BR/>ShapefileDataStore
+     * will always return a single name.
+     * 
+     * @return An array of length one containing the single type held.
+     */
+    public String[] getTypeNames() {
+        return new String[] { getCurrentTypeName(), };
+    }
+
+    /**
+     * Create the type name of the single FeatureType this DataStore represents.<BR/>
+     * For example, if the urls path is file:///home/billy/mytheme.shp, the type
+     * name will be mytheme.
+     * 
+     * @return A name based upon the last path component of the url minus the
+     *         extension.
+     */
+    protected String createFeatureTypeName() {
+        return shpFiles.getTypeName();
+    }
+
+    protected String getCurrentTypeName() {
+        return (schema == null) ? createFeatureTypeName() : schema
+                .getTypeName();
+    }
+
+    /**
+     * A convenience method to check if a type name is correct.
+     * 
+     * @param requested
+     *                The type name requested.
+     * 
+     * @throws IOException
+     *                 If the type name is not available
+     */
+    protected void typeCheck(String requested) throws IOException {
+        if (!getCurrentTypeName().equals(requested)) {
+            throw new IOException("No such type : " + requested);
+        }
+    }
+
+    /**
+     * Create a FeatureWriter for the given type name.
+     * 
+     * @param typeName
+     *                The typeName of the FeatureType to write
+     * @param transaction
+     *                DOCUMENT ME!
+     * 
+     * @return A new FeatureWriter.
+     * 
+     * @throws IOException
+     *                 If the typeName is not available or some other error
+     *                 occurs.
+     */
+    protected FeatureWriter<SimpleFeatureType, SimpleFeature> createFeatureWriter(String typeName,
+            Transaction transaction) throws IOException {
+        return null;
+    }
+
+    /**
+     * Obtain the FeatureType of the given name. ShapefileDataStore contains
+     * only one FeatureType.
+     * 
+     * @param typeName
+     *                The name of the FeatureType.
+     * 
+     * @return The FeatureType that this DataStore contains.
+     * 
+     * @throws IOException
+     *                 If a type by the requested name is not present.
+     */
+    public SimpleFeatureType getSchema(String typeName) throws IOException {
+        typeCheck(typeName);
+        return getSchema();
+    }
+
+    public SimpleFeatureType getSchema() throws IOException {
+        if (schema == null) {
+
+            List<AttributeDescriptor> types = readAttributes();
+
+            SimpleFeatureType parent = null;
+            GeometryDescriptor geomDescriptor = (GeometryDescriptor) types.get(0);            
+			Class<?> geomBinding = geomDescriptor.getType().getBinding();
+
+            if ((geomBinding == Point.class) || (geomBinding == MultiPoint.class)) {
+                parent = BasicFeatureTypes.POINT;
+            } else if ((geomBinding == Polygon.class)
+                    || (geomBinding == MultiPolygon.class)) {
+                parent = BasicFeatureTypes.POLYGON;
+            } else if ((geomBinding == LineString.class)
+                    || (geomBinding == MultiLineString.class)) {
+                parent = BasicFeatureTypes.LINE;
+            }
+
+            SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
+            builder.setDefaultGeometry( geomDescriptor.getLocalName() );
+            builder.addAll(types);
+            builder.setName(createFeatureTypeName());
+            if (namespace != null) {
+                builder.setNamespaceURI(namespace);
+            } else {
+                builder.setNamespaceURI(BasicFeatureTypes.DEFAULT_NAMESPACE);
+            }
+            builder.setAbstract(false);
+            if (parent != null) {
+                builder.setSuperType(parent);
+            }
+            schema = builder.buildFeatureType();
+        }
+        return schema;
+    }
+
+    /**
+     * Create the AttributeDescriptor contained within this DataStore.
+     * 
+     * @return List of new AttributeDescriptor
+     * @throws IOException
+     *                 If AttributeType reading fails
+     */
+    protected List<AttributeDescriptor> readAttributes() throws IOException {
+        ShapefileReader shp = openShapeReader(new GeometryFactory());
+        DbaseFileReader dbf = openDbfReader();
+        CoordinateReferenceSystem crs = null;
+
+        PrjFileReader prj = null;
+        try {
+            prj = openPrjReader();
+
+            if (prj != null) {
+                crs = prj.getCoodinateSystem();
+            }
+        } catch (FactoryException fe) {
+        }
+
+        AttributeTypeBuilder build = new AttributeTypeBuilder();
+        List<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
+        try {
+            Class<?> geometryClass = JTSUtilities.findBestGeometryClass(shp
+                    .getHeader().getShapeType());
+            build.setName(Classes.getShortName( geometryClass ));
+            build.setNillable(true);
+            build.setCRS(crs);
+            build.setBinding(geometryClass);
+
+            GeometryType geometryType = build.buildGeometryType();
+            attributes.add(build.buildDescriptor(
+                    BasicFeatureTypes.GEOMETRY_ATTRIBUTE_NAME, geometryType));
+            Set<String> usedNames = new HashSet<String>(); // record names in
+            // case of
+            // duplicates
+            usedNames.add(BasicFeatureTypes.GEOMETRY_ATTRIBUTE_NAME);
+
+            // take care of the case where no dbf and query wants all =>
+            // geometry only
+            if (dbf != null) {
+                DbaseFileHeader header = dbf.getHeader();
+                for (int i = 0, ii = header.getNumFields(); i < ii; i++) {
+                    Class attributeClass = header.getFieldClass(i);
+                    String name = header.getFieldName(i);
+                    if (usedNames.contains(name)) {
+                        String origional = name;
+                        int count = 1;
+                        name = name + count;
+                        while (usedNames.contains(name)) {
+                            count++;
+                            name = origional + count;
+                        }
+                    	build.addUserData(ORIGINAL_FIELD_NAME, origional);
+                    	build.addUserData(ORIGINAL_FIELD_DUPLICITY_COUNT, count);
+                    }
+                    usedNames.add(name);
+                    int length = header.getFieldLength(i);
+
+                    build.setNillable(true);
+                    build.setLength(length);
+                    build.setBinding(attributeClass);
+                    attributes.add(build.buildDescriptor(name));
+                }
+            }
+            return attributes;
+        } finally {
+
+            try {
+                if (prj != null) {
+                    prj.close();
+                }
+            } catch (IOException ioe) {
+                // do nothing
+            }
+            try {
+                if (dbf != null) {
+                    dbf.close();
+                }
+            } catch (IOException ioe) {
+                // do nothing
+            }
+            try {
+                if (shp != null) {
+                    shp.close();
+                }
+            } catch (IOException ioe) {
+                // do nothing
+            }
+        }
+    }
+
+    /**
+     * Gets the bounding box of the file represented by this data store as a
+     * whole (that is, off all of the features in the shapefile)
+     * 
+     * @return The bounding box of the datasource or null if unknown and too
+     *         expensive for the method to calculate.
+     * 
+     * @throws DataSourceException
+     *                 DOCUMENT ME!
+     */
+    protected ReferencedEnvelope getBounds() throws DataSourceException {
+        // This is way quick!!!
+        ReadableByteChannel in = null;
+
+        try {
+            ByteBuffer buffer = ByteBuffer.allocate(100);
+            FileReader reader = new FileReader() {
+            };
+
+            in = shpFiles.getReadChannel(SHP, reader);
+            try {
+                in.read(buffer);
+                buffer.flip();
+
+                ShapefileHeader header = new ShapefileHeader();
+                header.read(buffer, true);
+
+                ReferencedEnvelope bounds = new ReferencedEnvelope(schema
+                        .getCoordinateReferenceSystem());
+                bounds.include(header.minX(), header.minY());
+                bounds.include(header.minX(), header.minY());
+
+                Envelope env = new Envelope(header.minX(), header.maxX(),
+                        header.minY(), header.maxY());
+
+                if (schema != null) {
+                    return new ReferencedEnvelope(env, schema.getCoordinateReferenceSystem());
+                }
+                return new ReferencedEnvelope(env, null);
+            } finally {
+                in.close();
+            }
+
+        } catch (IOException ioe) {
+            // What now? This seems arbitrarily appropriate !
+            throw new DataSourceException("Problem getting Bbox", ioe);
+        } finally {
+            try {
+                if (in != null) {
+                    in.close();
+                }
+            } catch (IOException ioe) {
+                // do nothing
+            }
+        }
+    }
+
+    protected ReferencedEnvelope getBounds(Query query) throws IOException {
+        if (query.getFilter().equals(Filter.INCLUDE)) {
+            return getBounds();
+        }
+
+        return null; // too expensive
+
+        // TODO should we just return the layer? matches the javadocs
+    }
+
+    /**
+     * @see org.geotools.data.DataStore#getFeatureSource(java.lang.String)
+     */
+    public SimpleFeatureSource getFeatureSource(final String typeName)
+            throws IOException {
+        final SimpleFeatureType featureType = getSchema(typeName);
+
+        if (isWriteable) {
+            if (getLockingManager() != null) {
+                return new ShapefileFeatureLocking(this, getSupportedHints(), featureType);
+            }
+            else {
+                return new ShapefileFeatureStore(this, getSupportedHints(), featureType);
+            }
+        }
+        return new ShapefileFeatureSource(this, getSupportedHints(), featureType);
+    }
+
+    /**
+     * @see org.geotools.data.AbstractDataStore#getCount(org.geotools.data.Query)
+     */
+    public int getCount(Query query) throws IOException {
+        if (query.getFilter() == Filter.INCLUDE) {
+            IndexFile file = openIndexFile();
+            if (file != null) {
+                try {
+                    return file.getRecordCount();
+                } finally {
+                    file.close();
+                }
+            }
+
+            // no Index file so use the number of shapefile records
+            ShapefileReader reader = openShapeReader(new GeometryFactory());
+            int count = -1;
+
+            try {
+                count = reader.getCount(count);
+            } catch (IOException e) {
+                throw e;
+            } finally {
+                reader.close();
+            }
+
+            return count;
+
+        }
+
+        return super.getCount(query);
+    }
+
+    @Override
+    public String toString() {
+        return "Shapefile datastore for :" + shpFiles.get(SHP);
+    }
+    @Override
+    public void dispose() {
+        super.dispose();
+        if(shpFiles != null) {
+	        shpFiles.dispose();
+	        shpFiles = null;
+        }
+    }
+    
+    @Override
+    protected void finalize() throws Throwable {
+    	super.finalize();
+    	if(shpFiles != null && trace != null) {
+    		LOGGER.log(Level.SEVERE, "Undisposed of shapefile, you should call dispose() on all shapefile stores", trace);
+    	}
+    	dispose();
+    }
+    
+    @Override
+    protected Set getSupportedHints() {
+        Set<Hints.Key> hints = new HashSet<Hints.Key>();
+        hints.add( Hints.FEATURE_DETACHED );
+        hints.add( Hints.JTS_GEOMETRY_FACTORY );
+        hints.add( Hints.JTS_COORDINATE_SEQUENCE_FACTORY );
+        hints.add( Hints.GEOMETRY_DISTANCE);
+        return hints;
+    }
+    
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileDataStoreFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileDataStoreFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileDataStoreFactory.java	(revision 28000)
@@ -0,0 +1,411 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.logging.Logger;
+
+import org.geotools.data.DataSourceException;
+import org.geotools.data.DataStore;
+import org.geotools.data.DataUtilities;
+import org.geotools.data.FileDataStore;
+import org.geotools.data.FileDataStoreFactorySpi;
+import org.geotools.data.directory.DirectoryDataStore;
+import org.geotools.data.directory.FileStoreFactory;
+import org.geotools.data.shapefile.indexed.IndexType;
+import org.geotools.data.shapefile.indexed.IndexedShapefileDataStore;
+import org.geotools.util.KVP;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * Implementation of the DataStore service provider interface for Shapefiles.
+ * <p>
+ * The specific implementation of ShapefileDataStore created by this class is
+ * not specified. For more information on the connection parameters please
+ * review the following public Param constants.
+ * <ul>
+ * <li>{@link URLP}
+ * <li>{@link NAMESPACEP}
+ * <li>{@link CREATE_SPATIAL_INDEX}
+ * <li>{@link MEMORY_MAPPED}
+ * <li>{@link DBFCHARSET}
+ * </ul>
+ * 
+ * @author Chris Holmes, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/ShapefileDataStoreFactory.java $
+ * @version $Id: ShapefileDataStoreFactory.java 27856 2007-11-12 17:23:35Z
+ *          desruisseaux $
+ */
+public class ShapefileDataStoreFactory implements FileDataStoreFactorySpi {
+
+    public static final Logger LOGGER = org.geotools.util.logging.Logging
+            .getLogger("org.geotools.data.shapefile");
+    /**
+     * url to the .shp file.
+     */
+    public static final Param URLP = new Param("url", URL.class,
+            "url to a .shp file",true, null,
+            new KVP(Param.EXT,"shp"));
+    
+
+    /**
+     * Optional - uri of the FeatureType's namespace
+     */
+    public static final Param NAMESPACEP = new Param("namespace", URI.class,
+            "uri to a the namespace", false, null,  // not required
+            new KVP(Param.LEVEL,"advanced") );
+
+    /**
+     * Optional - enable/disable the use of memory-mapped io
+     */
+    public static final Param MEMORY_MAPPED = new Param("memory mapped buffer",
+            Boolean.class, "enable/disable the use of memory-mapped io", false, false,
+            new KVP(Param.LEVEL,"advanced") );
+    
+    /**
+     * Optional - enable/disable the use of memory-mapped io
+     */
+    public static final Param CACHE_MEMORY_MAPS = new Param("cache and reuse memory maps",
+            Boolean.class, "only memory map a file one, then cache and reuse the map", false, true,
+            new KVP(Param.LEVEL,"advanced") );
+    
+    /**
+     * Optional - discriminator for directory stores
+     */
+    public static final Param FILE_TYPE = new Param("filetype",
+            String.class, "Discriminator for directory stores", false, "shapefile",
+            new KVP(Param.LEVEL,"advanced") );
+
+    /**
+     * Optional - Enable/disable the automatic creation of spatial index
+     */
+    public static final Param CREATE_SPATIAL_INDEX = new Param(
+            "create spatial index", Boolean.class,
+            "enable/disable the automatic creation of spatial index", false, true,
+            new KVP(Param.LEVEL,"advanced") );
+
+    /**
+     * Optional - character used to decode strings from the DBF file
+     */
+    public static final Param DBFCHARSET = new Param("charset", Charset.class,
+            "character used to decode strings from the DBF file", false,
+            Charset.forName("ISO-8859-1"),
+            new KVP(Param.LEVEL,"advanced")) {
+        /*
+         * This is an example of a non simple Param type where a custom parse
+         * method is required.
+         * 
+         * @see org.geotools.data.DataStoreFactorySpi.Param#parse(java.lang.String)
+         */
+        public Object parse(String text) throws IOException {
+            return Charset.forName(text);
+        }
+
+        public String text(Object value) {
+            return ((Charset) value).name();
+        }
+    };
+    
+    /**
+     * Optional - timezone to decode dates from the DBF file
+     */
+    public static final Param DBFTIMEZONE = new Param("timezone", TimeZone.class,
+            "time zone used to read dates from the DBF file", false,
+            TimeZone.getDefault(),
+            new KVP(Param.LEVEL,"advanced")) {
+
+    	public Object parse(String text) throws IOException {
+            return TimeZone.getTimeZone(text);
+        }
+
+        public String text(Object value) {
+            return ((TimeZone) value).getID();
+        }
+    };
+
+
+    /**
+     * Takes a map of parameters which describes how to access a DataStore and
+     * determines if it can be read by the ShapefileDataStore or
+     * IndexedShapefileDataStore implementations.
+     * 
+     * @param params
+     *                A map of parameters describing the location of a
+     *                datastore. Files should be pointed to by a 'url' param.
+     * 
+     * @return true iff params contains a url param which points to a file
+     *         ending in shp
+     */
+    public boolean canProcess(Map params) {
+        boolean accept = false;
+        if (params.containsKey(URLP.key)) {
+            try {
+                URL url = (URL) URLP.lookUp(params);
+                accept = canProcess(url);
+                if(!accept) {
+                    // maybe it's a directory?
+                    Object fileType = FILE_TYPE.lookUp(params);
+                    File dir = DataUtilities.urlToFile(url);
+                    // check for null fileType for backwards compatibility
+                    accept = dir.isDirectory() && (fileType == null || "shapefile".equals(fileType));  
+                }
+            } catch (IOException ioe) {
+                // yes, I am eating this - since it is my job to return a
+                // true/false
+            }
+        }
+        return accept;
+    }
+
+    /**
+     * Returns an instance of DataStore iff the resource pointed to the Map of
+     * paramers can be handled as a shapefile.
+     * <p>
+     * The specific implementation of ShapefileDataStore returned is not
+     * specified, and depends on the parameters given. For more information
+     * please review the public static Param instances available for this class.
+     * </p>
+     * <ul>
+     * <li>{@link URLP}
+     * <li>{@link NAMESPACEP}
+     * <li>{@link CREATE_SPATIAL_INDEX}
+     * <li>{@link MEMORY_MAPPED}
+     * <li>{@link DBFCHARSET}
+     * </ul>
+     * 
+     * @param params
+     *                A param list with information on the location of a
+     *                restore. For shapefiles this should contain a 'url' param
+     *                which points to a file which ends in shp.
+     * 
+     * @return DataStore A ShapefileDatastore
+     * @throws IOException
+     *                 If a connection error (such as the file not existing
+     *                 occurs)
+     * @throws DataSourceException
+     *                 Thrown if the datastore which is created cannot be
+     *                 attached to the restore specified in params.
+     */
+    public DataStore createDataStore(Map params) throws IOException {
+        return createNewDataStore(params);
+    }
+
+    /**
+     * Creates a new DataStore - for a file that does not exist yet.
+     * <p>
+     * This method has different logic than createDataStore. It is willing to be
+     * memory mapped, and generate an index for a local file that does not exist
+     * yet.
+     * 
+     */
+    public DataStore createNewDataStore(Map params) throws IOException {
+        // basic param lookup
+        URL url = (URL) URLP.lookUp(params);
+        Boolean isMemoryMapped = (Boolean) MEMORY_MAPPED.lookUp(params);
+        Boolean cacheMemoryMaps = (Boolean) CACHE_MEMORY_MAPS.lookUp(params);
+        URI namespace = (URI) NAMESPACEP.lookUp(params);
+        Charset dbfCharset = (Charset) DBFCHARSET.lookUp(params);
+        TimeZone dbfTimeZone = (TimeZone) DBFTIMEZONE.lookUp(params);
+        Boolean isCreateSpatialIndex = (Boolean) CREATE_SPATIAL_INDEX
+                .lookUp(params);
+        if (isCreateSpatialIndex == null) {
+            // should not be needed as default is TRUE
+            assert (true);
+            isCreateSpatialIndex = Boolean.TRUE;
+        }
+        if (dbfCharset == null) {
+            assert (true);
+            // this should not happen as Charset.forName("ISO-8859-1") was used
+            // as the param default?
+            dbfCharset = Charset.forName("ISO-8859-1");
+        }
+        if(dbfTimeZone == null) {
+        	dbfTimeZone = TimeZone.getDefault();
+        }
+        if (isMemoryMapped == null) {
+            assert (true);
+            // this should not happen as false was the default
+            isMemoryMapped = Boolean.FALSE;
+        }
+        if (cacheMemoryMaps == null) {
+        	cacheMemoryMaps = Boolean.FALSE;
+        }
+        
+        // are we creating a directory of shapefiles store, or a single one?
+        File dir = DataUtilities.urlToFile(url);
+        if(dir != null && dir.isDirectory()) {
+            return new DirectoryDataStore(DataUtilities.urlToFile(url), new ShpFileStoreFactory(this, params));
+        } else {
+            ShpFiles shpFiles = new ShpFiles(url);
+    
+            boolean isLocal = shpFiles.isLocal();
+            boolean useMemoryMappedBuffer = isLocal
+                    && isMemoryMapped.booleanValue();
+            boolean createIndex = isCreateSpatialIndex.booleanValue() && isLocal;
+    
+        	ShapefileDataStore store;
+            if (createIndex) {
+                store = new IndexedShapefileDataStore(url, namespace,
+                        useMemoryMappedBuffer, cacheMemoryMaps, true, IndexType.QIX, dbfCharset);
+            } else {
+                store = new ShapefileDataStore(url, namespace,
+                        useMemoryMappedBuffer, cacheMemoryMaps, dbfCharset);
+            }
+            store.setDbftimeZone(dbfTimeZone);
+            return store;
+        }
+    }
+
+    public String getDisplayName() {
+        return "Shapefile";
+    }
+
+    /**
+     * Describes the type of data the datastore returned by this factory works
+     * with.
+     * 
+     * @return String a human readable description of the type of restore
+     *         supported by this datastore.
+     */
+    public String getDescription() {
+        return "ESRI(tm) Shapefiles (*.shp)";
+    }
+
+    // public DataSourceMetadataEnity createMetadata( Map params )
+    // throws IOException {
+    //        
+    // URL url = (URL) URLP.lookUp(params);
+    // Boolean mm = (Boolean) MEMORY_MAPPED.lookUp(params);
+    //        
+    // String server;
+    // String name;
+    // if( url.getProtocol().equals("file")){
+    // server = "localhost";
+    // name = url.getPath();
+    // }
+    // else {
+    // server = url.getHost()+":"+url.getPort();
+    // name = url.getFile();
+    // }
+    // return new DataSourceMetadataEnity( server, name, "Shapefile access for
+    // "+url );
+    // }
+    /**
+     * Test to see if this datastore is available, if it has all the appropriate
+     * libraries to construct a datastore.
+     * 
+     * This datastore just checks for the ShapefileDataStore,
+     * IndexedShapefileDataStore and Geometry implementations.
+     * 
+     * @return <tt>true</tt> if and only if this factory is available to
+     *         create DataStores.
+     */
+    public boolean isAvailable() {
+        try {
+            ShapefileDataStore.class.getName();
+            IndexedShapefileDataStore.class.getName();
+            Geometry.class.getName();
+        } catch (Exception e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * @see org.geotools.data.dir.FileDataStoreFactorySpi#canProcess(java.net.URL)
+     */
+    public boolean canProcess(URL f) {
+        return f.getFile().toUpperCase().endsWith("SHP");
+    }
+
+    /**
+     * We may need to create a new datastore if the provided file does not
+     * exist.
+     * 
+     * @see org.geotools.data.dir.FileDataStoreFactorySpi#createDataStore(java.net.URL)
+     */
+    public FileDataStore createDataStore(URL url) throws IOException {
+        Map params = new HashMap();
+        params.put(URLP.key, url);
+
+        boolean isLocal = url.getProtocol().equalsIgnoreCase("file");
+        File file = DataUtilities.urlToFile(url);
+        if(file != null && file.isDirectory()) {
+            return null;
+        } else {
+            if (isLocal && !file.exists()) {
+                return (FileDataStore) createNewDataStore(params);
+            } else {
+                return (FileDataStore) createDataStore(params);
+            }
+        }
+    }
+
+    /**
+     * Returns the implementation hints. The default implementation returns an
+     * empty map.
+     * <p>
+     * When we have FeatureFactory, GeometryFactory and so on hooked up this map
+     * will return Hints we paid attention too when we were constructed.
+     * 
+     * @return An empty map.
+     */
+    public Map getImplementationHints() {
+        return Collections.EMPTY_MAP;
+    }
+
+    
+    /**
+     * A delegates that allow to build a directory of shapfiles store
+     * @author Andrea Aime - OpenGeo
+     */
+    public static class ShpFileStoreFactory implements FileStoreFactory {
+        
+        ShapefileDataStoreFactory shpFactory;
+        Map originalParams;
+        
+        public ShpFileStoreFactory(ShapefileDataStoreFactory factory, Map originalParams) {
+            this.shpFactory = factory;
+            this.originalParams = originalParams;
+        }
+        
+
+        public DataStore getDataStore(File file) throws IOException {
+            final URL url = DataUtilities.fileToURL(file);
+            if(shpFactory.canProcess(url)) {
+                Map params = new HashMap(originalParams);
+                params.put(URLP.key, url);
+                return shpFactory.createDataStore(params);
+            } else {
+                return null;
+            }
+        }
+        
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileDirectoryFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileDirectoryFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileDirectoryFactory.java	(revision 28000)
@@ -0,0 +1,61 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Map;
+
+import org.geotools.data.DataUtilities;
+
+/**
+ * Creates a directory datastore pointing to a directory of shapefiles
+ * 
+ * @author Andrea Aime
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/build/maven/javadoc/../../../modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/ShapefileDirectoryFactory.java $
+ *         main/java/org/geotools/data/dir/DirectoryDataStoreFactory.java $
+ */
+public class ShapefileDirectoryFactory extends ShapefileDataStoreFactory {
+    /** The directory to be scanned for file data stores */
+    public static final Param URLP = new Param("url", URL.class,
+            "Directory containing geospatial files", true);
+
+    public String getDisplayName() {
+        return "Directory of spatial files (shapefiles)";
+    }
+
+    public String getDescription() {
+        return "Takes a directory of shapefiles and exposes it as a data store";
+    }
+
+    public boolean canProcess(Map params) {
+        // we don't try to steal single shapefiles away from the main factory
+        if (super.canProcess(params)) {
+            try {
+                URL url = (URL) URLP.lookUp(params);
+                File f = DataUtilities.urlToFile(url);
+                return f != null && f.exists() && f.isDirectory();
+            } catch (Exception e) {
+                return false;
+            }
+        } else {
+            return false;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileFeatureLocking.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileFeatureLocking.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileFeatureLocking.java	(revision 28000)
@@ -0,0 +1,57 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.geotools.data.AbstractFeatureLocking;
+import org.geotools.data.DataStore;
+import org.geotools.data.FeatureListener;
+import org.geotools.data.Query;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+public class ShapefileFeatureLocking extends AbstractFeatureLocking {
+    /**
+     * 
+     */
+    private final ShapefileDataStore shapefile;
+    private final SimpleFeatureType featureType;
+    public ShapefileFeatureLocking( ShapefileDataStore shapefileDataStore, Set hints, SimpleFeatureType featureType ) {
+        super(hints);
+        shapefile = shapefileDataStore;
+        this.featureType = featureType;
+        this.queryCapabilities = new ShapefileQueryCapabilities();
+    }
+    public DataStore getDataStore() {
+        return shapefile;
+    }
+    public void addFeatureListener(FeatureListener listener) {
+        shapefile.listenerManager.addFeatureListener(this, listener);
+    }
+    public void removeFeatureListener(FeatureListener listener) {
+        shapefile.listenerManager.removeFeatureListener(this, listener);
+    }
+    public SimpleFeatureType getSchema() {
+        return featureType;
+    }
+    public ReferencedEnvelope getBounds(Query query)
+            throws IOException {
+        return shapefile.getBounds(query);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileFeatureSource.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileFeatureSource.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileFeatureSource.java	(revision 28000)
@@ -0,0 +1,59 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.geotools.data.AbstractFeatureSource;
+import org.geotools.data.DataStore;
+import org.geotools.data.FeatureListener;
+import org.geotools.data.Query;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+/**
+ * Allows transaction control when editing a shapefile.
+ * 
+ * @author Jody Garnett (Refractions Research Inc)
+ */
+class ShapefileFeatureSource extends AbstractFeatureSource {
+    private final ShapefileDataStore shapefile;
+    private final SimpleFeatureType featureType;
+    
+    ShapefileFeatureSource( ShapefileDataStore shapefileDataStore, Set hints, SimpleFeatureType featureType ) {
+        super(hints);
+        shapefile = shapefileDataStore;
+        this.featureType = featureType;
+        this.queryCapabilities = new ShapefileQueryCapabilities();
+    }
+    public DataStore getDataStore() {
+        return shapefile;
+    }
+    public void addFeatureListener(FeatureListener listener) {
+        shapefile.listenerManager.addFeatureListener(this, listener);
+    }
+    public void removeFeatureListener(FeatureListener listener) {
+        shapefile.listenerManager.removeFeatureListener(this, listener);
+    }
+    public SimpleFeatureType getSchema() {
+        return featureType;
+    }
+    public ReferencedEnvelope getBounds(Query query) throws IOException {
+        return shapefile.getBounds(query);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileFeatureStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileFeatureStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileFeatureStore.java	(revision 28000)
@@ -0,0 +1,62 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.geotools.data.AbstractFeatureStore;
+import org.geotools.data.DataStore;
+import org.geotools.data.FeatureListener;
+import org.geotools.data.Query;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeatureType;
+/**
+ * Allows read-write access to the contents of a shape file.
+ * 
+ * @author Jody Garnett (Refractions Research Inc)
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/ShapefileFeatureStore.java $
+ */
+public class ShapefileFeatureStore extends AbstractFeatureStore {
+    private final ShapefileDataStore shapefile;
+    private final SimpleFeatureType featureType;
+    
+    public ShapefileFeatureStore( ShapefileDataStore shapefileDataStore, Set hints, SimpleFeatureType featureType ) {
+        super(hints);
+        shapefile = shapefileDataStore;
+        this.featureType = featureType;
+        this.queryCapabilities = new ShapefileQueryCapabilities();
+    }
+    public DataStore getDataStore() {
+        return shapefile;
+    }
+    public void addFeatureListener(FeatureListener listener) {
+        shapefile.listenerManager.addFeatureListener(this, listener);
+    }
+    public void removeFeatureListener(FeatureListener listener) {
+        shapefile.listenerManager.removeFeatureListener(this, listener);
+    }
+    public SimpleFeatureType getSchema() {
+        return featureType;
+    }
+    public ReferencedEnvelope getBounds(Query query)
+            throws IOException {
+        return shapefile.getBounds(query);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileFileServiceInfo.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileFileServiceInfo.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileFileServiceInfo.java	(revision 28000)
@@ -0,0 +1,32 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import org.geotools.data.ServiceInfo;
+
+/**
+ * ServiceInfo for ShapefileDataStore.
+ * 
+ * @author Jody Garnett (Refractions Reserach)
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/ShapefileFileServiceInfo.java $
+ */
+public class ShapefileFileServiceInfo implements ServiceInfo {
+    ShapefileFileServiceInfo(ShapefileDataStore shapefile) {
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileQueryCapabilities.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileQueryCapabilities.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileQueryCapabilities.java	(revision 28000)
@@ -0,0 +1,39 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import org.geotools.data.QueryCapabilities;
+import org.opengis.filter.sort.SortBy;
+
+/**
+ * The usual capabilities, plug a twist: we always return features sorted according to the
+ * feature id
+ * 
+ * @author Andrea Aime - GeoSolutions
+ */
+class ShapefileQueryCapabilities extends QueryCapabilities {
+
+    @Override
+    public boolean supportsSorting(SortBy[] sortAttributes) {
+        // we always return features in the pk increasing order
+        if(sortAttributes != null && sortAttributes.length == 1 && sortAttributes[0] == SortBy.NATURAL_ORDER) {
+            return true;
+        } else {
+            return super.supportsSorting(sortAttributes);
+        }
+    }  
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileURLServiceInfo.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileURLServiceInfo.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShapefileURLServiceInfo.java	(revision 28000)
@@ -0,0 +1,33 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import org.geotools.data.ServiceInfo;
+
+/**
+ * ServiceInfo for ShapefileDataStore.
+ * 
+ * @author Jody Garnett (Refractions Reserach)
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/ShapefileURLServiceInfo.java $
+ */
+public class ShapefileURLServiceInfo implements ServiceInfo {
+    
+    ShapefileURLServiceInfo(ShapefileDataStore shapefile) {
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShpFileType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShpFileType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShpFileType.java	(revision 28000)
@@ -0,0 +1,110 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import java.io.File;
+import java.net.URL;
+
+/**
+ * Enumerates the known types of files associated with a shapefile.
+ * 
+ * @author jesse
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/ShpFileType.java $
+ */
+public enum ShpFileType {
+
+    /**
+     * The .shp file. It contains the geometries of the shapefile
+     */
+    SHP("shp"),
+    /**
+     * the .dbf file, it contains the attribute information of the shapefile
+     */
+    DBF("dbf"),
+    /**
+     * the .shx file, it contains index information of the existing features
+     */
+    SHX("shx"),
+    /**
+     * the .prj file, it contains the projection information of the shapefile
+     */
+    PRJ("prj"),
+    /**
+     * the .qix file, A quad tree spatial index of the shapefile. It is the same
+     * format the mapservers shptree tool generates
+     */
+    QIX("qix"),
+    /**
+     * the .fix file, it contains all the Feature IDs for constant time lookup
+     * by fid also so that the fids stay consistent across deletes and adds
+     */
+    FIX("fix"),
+    /**
+     * the .shp.xml file, it contains the metadata about the shapefile
+     */
+    SHP_XML("shp.xml");
+
+    public final String extension;
+    public final String extensionWithPeriod;
+
+    private ShpFileType(String extension) {
+        this.extension = extension.toLowerCase();
+        this.extensionWithPeriod = "." + this.extension;
+    }
+
+    /**
+     * Returns the base of the file or null if the file passed in is not of the
+     * correct type (has the correct extension.)
+     * <p>
+     * For example if the file is c:\shapefiles\file1.dbf. The DBF type will
+     * return c:\shapefiles\file1 but all other will return null.
+     */
+    public String toBase(File file) {
+        String path = file.getPath();
+        return toBase(path);
+    }
+
+    /**
+     * Returns the base of the file or null if the file passed in is not of the
+     * correct type (has the correct extension.)
+     * <p>
+     * For example if the file is c:\shapefiles\file1.dbf. The DBF type will
+     * return c:\shapefiles\file1 but all other will return null.
+     */
+    public String toBase(String path) {
+        if (!path.toLowerCase().endsWith(extensionWithPeriod)
+                || path.equalsIgnoreCase(extensionWithPeriod)) {
+            return null;
+        }
+
+        int indexOfExtension = path.toLowerCase().lastIndexOf(
+                extensionWithPeriod);
+        return path.substring(0, indexOfExtension);
+    }
+
+    /**
+     * Returns the base of the file or null if the file passed in is not of the
+     * correct type (has the correct extension.)
+     * <p>
+     * For example if the file is c:\shapefiles\file1.dbf. The DBF type will
+     * return c:\shapefiles\file1 but all other will return null.
+     */
+    public String toBase(URL url) {
+        return toBase( url.toExternalForm() );        
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShpFiles.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShpFiles.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShpFiles.java	(revision 28000)
@@ -0,0 +1,563 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import static org.geotools.data.shapefile.ShpFileType.SHP;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
+import java.nio.channels.ReadableByteChannel;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Level;
+
+import org.geotools.data.DataUtilities;
+
+/**
+ * The collection of all the files that are the shapefile and its metadata and
+ * indices.
+ * 
+ * <p>
+ * This class has methods for performing actions on the files. Currently mainly
+ * for obtaining read and write channels and streams. But in the future a move
+ * method may be introduced.
+ * </p>
+ * 
+ * <p>
+ * Note: The method that require locks (such as getInputStream()) will
+ * automatically acquire locks and the javadocs should document how to release
+ * the lock. Therefore the methods {@link #acquireRead(ShpFileType, FileReader)}
+ * and {@link #acquireWrite(ShpFileType, FileWriter)}svn
+ * </p>
+ * 
+ * @author jesse
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/ShpFiles.java $
+ */
+public class ShpFiles {
+   
+    /**
+     * The urls for each type of file that is associated with the shapefile. The
+     * key is the type of file
+     */
+    protected final Map<ShpFileType, URL> urls = new ConcurrentHashMap<ShpFileType, URL>();
+
+    /**
+     * A read/write lock, so that we can have concurrent readers 
+     */
+    private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
+
+    /**
+     * The set of locker sources per thread. Used as a debugging aid and to upgrade/downgrade
+     * the locks
+     */
+    private final Map<Thread, Collection<ShpFilesLocker>> lockers = new ConcurrentHashMap<Thread, Collection<ShpFilesLocker>>();
+
+    /**
+     * A cache for read only memory mapped buffers
+     */
+    private final MemoryMapCache mapCache = new MemoryMapCache();
+    
+    private boolean memoryMapCacheEnabled;
+
+    /**
+     * Searches for all the files and adds then to the map of files.
+     * 
+     * @param file
+     *                any one of the shapefile files
+     * 
+     */
+    public ShpFiles(URL url) throws IllegalArgumentException {
+        init(url);
+    }
+
+    private void init(URL url) {
+        String base = baseName(url);
+        if (base == null) {
+            throw new IllegalArgumentException(
+                    url.getPath()
+                            + " is not one of the files types that is known to be associated with a shapefile");
+        }
+
+        String urlString = url.toExternalForm();
+        char lastChar = urlString.charAt(urlString.length()-1);
+        boolean upperCase = Character.isUpperCase(lastChar);
+
+        for (ShpFileType type : ShpFileType.values()) {
+            
+            String extensionWithPeriod = type.extensionWithPeriod;
+            if( upperCase ){
+                extensionWithPeriod = extensionWithPeriod.toUpperCase();
+            }else{
+                extensionWithPeriod = extensionWithPeriod.toLowerCase();
+            }
+            
+            URL newURL;
+            String string = base + extensionWithPeriod;
+            try {
+                newURL = new URL(url, string);
+            } catch (MalformedURLException e) {
+                // shouldn't happen because the starting url was constructable
+                throw new RuntimeException(e);
+            }
+            urls.put(type, newURL);
+        }
+
+        // if the files are local check each file to see if it exists
+        // if not then search for a file of the same name but try all combinations of the 
+        // different cases that the extension can be made up of.
+        // IE Shp, SHP, Shp, ShP etc...
+        if( isLocal() ){
+            Set<Entry<ShpFileType, URL>> entries = urls.entrySet();
+            Map<ShpFileType, URL> toUpdate = new HashMap<ShpFileType, URL>();
+            for (Entry<ShpFileType, URL> entry : entries) {
+                if( !exists(entry.getKey()) ){
+                    url = findExistingFile(entry.getKey(), entry.getValue());
+                    if( url!=null ){
+                        toUpdate.put(entry.getKey(), url);
+                    }
+                }
+            }
+            
+            urls.putAll(toUpdate);
+            
+        }
+        
+    }
+
+    private URL findExistingFile(ShpFileType shpFileType, URL value) {
+        final File file = DataUtilities.urlToFile(value);
+        File directory = file.getParentFile();
+        if( directory==null || !directory.exists() ) {
+            // doesn't exist
+            return null;
+        }
+        File[] files = directory.listFiles(new FilenameFilter(){
+
+            public boolean accept(File dir, String name) {
+                return file.getName().equalsIgnoreCase(name);
+            }
+            
+        });
+        if( files.length>0 ){
+            try {
+                return files[0].toURI().toURL();
+            } catch (MalformedURLException e) {
+                ShapefileDataStoreFactory.LOGGER.log(Level.SEVERE, "", e);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * This verifies that this class has been closed correctly (nothing locking)
+     */
+    @Override
+    protected void finalize() throws Throwable {
+        super.finalize();
+        dispose();
+    }
+
+    public void dispose() {
+        if (numberOfLocks() != 0) {
+            logCurrentLockers(Level.SEVERE);
+            lockers.clear(); // so as not to get this log again.
+        }
+        mapCache.clean();
+    }
+
+    /**
+     * Writes to the log all the lockers and when they were constructed.
+     * 
+     * @param logLevel
+     *                the level at which to log.
+     */
+    public void logCurrentLockers(Level logLevel) {
+        for (Collection<ShpFilesLocker> lockerList : lockers.values()) {
+            for (ShpFilesLocker locker : lockerList) {
+                StringBuilder sb = new StringBuilder("The following locker still has a lock: ");
+                sb.append(locker);
+                ShapefileDataStoreFactory.LOGGER.log(logLevel, sb.toString());
+            }
+        }
+    }
+
+    protected String baseName(Object obj) {
+        for (ShpFileType type : ShpFileType.values()) {
+            String base = null;
+            if (obj instanceof File) {
+                File file = (File) obj;
+                base = type.toBase(file);
+            }
+            if (obj instanceof URL) {
+                URL file = (URL) obj;
+                base = type.toBase(file);
+            }
+            if (base != null) {
+                return base;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the string form of the url that identifies the file indicated by
+     * the type parameter or null if it is known that the file does not exist.
+     * 
+     * <p>
+     * Note: a URL should NOT be constructed from the string instead the URL
+     * should be obtained through calling one of the aquireLock methods.
+     * 
+     * @param type
+     *                indicates the type of file the caller is interested in.
+     * 
+     * @return the string form of the url that identifies the file indicated by
+     *         the type parameter or null if it is known that the file does not
+     *         exist.
+     */
+    public String get(ShpFileType type) {
+        return urls.get(type).toExternalForm();
+    }
+
+    /**
+     * Returns the number of locks on the current set of shapefile files. This
+     * is not thread safe so do not count on it to have a completely accurate
+     * picture but it can be useful debugging
+     * 
+     * @return the number of locks on the current set of shapefile files.
+     */
+    public int numberOfLocks() {
+        int count = 0;
+        for (Collection<ShpFilesLocker> lockerList : lockers.values()) {
+            count += lockerList.size();
+        }
+        return count;
+    }
+    
+    /**
+     * Acquire a URL for read only purposes.  It is recommended that get*Stream or
+     * get*Channel methods are used when reading or writing to the file is
+     * desired.
+     * 
+     * 
+     * @see #getInputStream(ShpFileType, FileReader)
+     * @see #getReadChannel(ShpFileType, FileReader)
+     * @see #getWriteChannel(ShpFileType, FileReader)
+     * 
+     * @param type
+     *                the type of the file desired.
+     * @param requestor
+     *                the object that is requesting the URL. The same object
+     *                must release the lock and is also used for debugging.
+     * @return the URL to the file of the type requested
+     */
+    public URL acquireRead(ShpFileType type, FileReader requestor) {
+        URL url = urls.get(type);
+        if (url == null)
+            return null;
+        
+        readWriteLock.readLock().lock();
+        Collection<ShpFilesLocker> threadLockers = getCurrentThreadLockers();
+        threadLockers.add(new ShpFilesLocker(url, requestor));
+        return url;
+    }
+
+    /**
+     * Unlocks a read lock. The url and requestor must be the the same as the
+     * one of the lockers.
+     * 
+     * @param url
+     *                url that was locked
+     * @param requestor
+     *                the class that requested the url
+     */
+    public void unlockRead(URL url, FileReader requestor) {
+        if (url == null) {
+            throw new NullPointerException("url cannot be null");
+        }
+        if (requestor == null) {
+            throw new NullPointerException("requestor cannot be null");
+        }
+
+        Collection threadLockers = getCurrentThreadLockers();
+        boolean removed = threadLockers.remove(new ShpFilesLocker(url, requestor));
+        if (!removed) {
+            throw new IllegalArgumentException(
+                    "Expected requestor "
+                            + requestor
+                            + " to have locked the url but it does not hold the lock for the URL");
+        }
+        if(threadLockers.size() == 0)
+            lockers.remove(Thread.currentThread());
+        readWriteLock.readLock().unlock();
+    }
+
+    /**
+     * Unlocks a read lock. The requestor must be have previously obtained a
+     * lock for the url.
+     * 
+     * 
+     * @param url
+     *                url that was locked
+     * @param requestor
+     *                the class that requested the url
+     */
+    public void unlockWrite(URL url, FileWriter requestor) {
+        if (url == null) {
+            throw new NullPointerException("url cannot be null");
+        }
+        if (requestor == null) {
+            throw new NullPointerException("requestor cannot be null");
+        }
+        Collection<ShpFilesLocker> threadLockers = getCurrentThreadLockers();
+        boolean removed = threadLockers.remove(new ShpFilesLocker(url, requestor));
+        if (!removed) {
+            throw new IllegalArgumentException(
+                    "Expected requestor "
+                            + requestor
+                            + " to have locked the url but it does not hold the lock for the URL");
+        }
+        
+        if(threadLockers.size() == 0) {
+            lockers.remove(Thread.currentThread());
+        } else {
+            // get back read locks before giving up the write one
+            regainReadLocks(threadLockers);
+        }
+        readWriteLock.writeLock().unlock();
+    }
+   
+    /**
+     * Returns the list of lockers attached to a given thread, or creates it if missing
+     * @return
+     */
+    private Collection<ShpFilesLocker> getCurrentThreadLockers() {
+        Collection<ShpFilesLocker> threadLockers = lockers.get(Thread.currentThread());
+        if(threadLockers == null) {
+            threadLockers = new ArrayList<ShpFilesLocker>();
+            lockers.put(Thread.currentThread(), threadLockers);
+        }
+        return threadLockers;
+    }
+    
+    /**
+     * Re-takes the read locks in preparation for lock downgrade
+     * @param threadLockers
+     */
+    private void regainReadLocks(Collection<ShpFilesLocker> threadLockers) {
+        for (ShpFilesLocker shpFilesLocker : threadLockers) {
+            if(shpFilesLocker.reader != null && shpFilesLocker.upgraded) {
+                readWriteLock.readLock().lock();
+                shpFilesLocker.upgraded = false;
+            }
+        }
+    }
+
+    /**
+     * Determine if the location of this shapefile is local or remote.
+     * 
+     * @return true if local, false if remote
+     */
+    public boolean isLocal() {
+        return urls.get(ShpFileType.SHP).toExternalForm().toLowerCase()
+                .startsWith("file:");
+    }
+
+    /**
+     * Opens a input stream for the indicated file. A read lock is requested at
+     * the method call and released on close.
+     * 
+     * @param type
+     *                the type of file to open the stream to.
+     * @param requestor
+     *                the object requesting the stream
+     * @return an input stream
+     * 
+     * @throws IOException
+     *                 if a problem occurred opening the stream.
+     */
+    public InputStream getInputStream(ShpFileType type,
+            final FileReader requestor) throws IOException {
+        final URL url = acquireRead(type, requestor);
+
+        try {
+            FilterInputStream input = new FilterInputStream(url.openStream()) {
+
+                private volatile boolean closed = false;
+
+                @Override
+                public void close() throws IOException {
+                    try {
+                        super.close();
+                    } finally {
+                        if (!closed) {
+                            closed = true;
+                            unlockRead(url, requestor);
+                        }
+                    }
+                }
+
+            };
+            return input;
+        }catch(Throwable e){
+            unlockRead(url, requestor);
+            if( e instanceof IOException ){
+                throw (IOException) e;
+            } else if( e instanceof RuntimeException){
+                throw (RuntimeException) e;
+            } else if( e instanceof Error ){
+                throw (Error) e;
+            } else {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    /**
+     * Obtain a ReadableByteChannel from the given URL. If the url protocol is
+     * file, a FileChannel will be returned. Otherwise a generic channel will be
+     * obtained from the urls input stream.
+     * <p>
+     * A read lock is obtained when this method is called and released when the
+     * channel is closed.
+     * </p>
+     * 
+     * @param type
+     *                the type of file to open the channel to.
+     * @param requestor
+     *                the object requesting the channel
+     * 
+     */
+    public ReadableByteChannel getReadChannel(ShpFileType type,
+            FileReader requestor) throws IOException {
+        URL url = acquireRead(type, requestor);
+        ReadableByteChannel channel = null;
+        try {
+            if (isLocal()) {
+
+                File file = DataUtilities.urlToFile(url);
+                
+                RandomAccessFile raf = new RandomAccessFile(file, "r");
+                channel = new FileChannelDecorator(raf.getChannel(), this, url,
+                        requestor);
+
+            } else {
+                InputStream in = url.openConnection().getInputStream();
+                channel = new ReadableByteChannelDecorator(Channels
+                        .newChannel(in), this, url, requestor);
+            }
+        } catch (Throwable e) {
+            unlockRead(url, requestor);
+            if (e instanceof IOException) {
+                throw (IOException) e;
+            } else if (e instanceof RuntimeException) {
+                throw (RuntimeException) e;
+            } else if (e instanceof Error) {
+                throw (Error) e;
+            } else {
+                throw new RuntimeException(e);
+            }
+        }
+        return channel;
+    }
+
+    public String getTypeName() {
+        String path = SHP.toBase(urls.get(SHP));
+        int slash = Math.max(0, path.lastIndexOf('/') + 1);
+        int dot = path.indexOf('.', slash);
+
+        if (dot < 0) {
+            dot = path.length();
+        }
+
+        return path.substring(slash, dot);
+    }
+    
+    /**
+     * Internal method that the file channel decorators will call to allow reuse of the memory mapped buffers
+     * @param wrapped
+     * @param url
+     * @param mode
+     * @param position
+     * @param size
+     * @return
+     * @throws IOException
+     */
+	MappedByteBuffer map(FileChannel wrapped, URL url, MapMode mode, long position, long size) throws IOException {
+		if(memoryMapCacheEnabled) {
+			return mapCache.map(wrapped, url, mode, position, size);
+		} else {
+			return wrapped.map(mode, position, size);
+		}
+	}
+	
+	/**
+	 * Enables the memory map cache. When enabled the memory mapped portions of the files are cached and shared
+	 * (giving each thread a clone of it)
+	 * @param memoryMapCacheEnabled
+	 */
+	public void setMemoryMapCacheEnabled(boolean memoryMapCacheEnabled) {
+		this.memoryMapCacheEnabled = memoryMapCacheEnabled;
+		if(!memoryMapCacheEnabled) {
+			mapCache.clean();
+		}
+	}
+
+    /**
+     * Returns true if the file exists. Throws an exception if the file is not
+     * local.
+     * 
+     * @param fileType
+     *                the type of file to check existance for.
+     * 
+     * @return true if the file exists.
+     * 
+     * @throws IllegalArgumentException
+     *                 if the files are not local.
+     */
+    public boolean exists(ShpFileType fileType) throws IllegalArgumentException {
+        if (!isLocal()) {
+            throw new IllegalArgumentException(
+                    "This method only makes sense if the files are local");
+        }
+        URL url = urls.get(fileType);
+        if (url == null) {
+            return false;
+        }
+
+        File file = DataUtilities.urlToFile(url);
+        return file.exists();
+    }
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShpFilesLocker.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShpFilesLocker.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/ShpFilesLocker.java	(revision 28000)
@@ -0,0 +1,102 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+class ShpFilesLocker {
+    
+    final URI uri;
+    final URL url;
+    final FileReader reader;
+    final FileWriter writer;
+    boolean upgraded;
+
+    public ShpFilesLocker( URL url, FileReader reader ) {
+        this.url = url;
+        this.reader = reader;
+        this.writer = null;
+        
+    	// extracts the URI from the URL, if possible
+        this.uri = getURI(url);
+    }
+
+    URI getURI(URL url) {
+        try {
+    		return url.toURI();
+    	} catch (URISyntaxException e) {
+    		// may fail if URL does not conform to RFC 2396
+ 		}
+        return null;
+    }
+
+    public ShpFilesLocker( URL url, FileWriter writer ) {
+        this.url = url;
+        this.reader = null;
+        this.writer = writer;
+        
+    	// extracts the URI from the URL, if possible
+        this.uri = getURI(url);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((reader == null) ? 0 : reader.hashCode());
+        result = prime * result + ((url == null) ? 0 : url.hashCode());
+        result = prime * result + ((writer == null) ? 0 : writer.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals( Object obj ) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final ShpFilesLocker other = (ShpFilesLocker) obj;
+        if (reader == null) {
+            if (other.reader != null)
+                return false;
+        } else if (!reader.equals(other.reader))
+            return false;
+        if (url == null) {
+            if (other.url != null)
+                return false;
+        } else {
+        	// calls URI.equals if a valid URI is available  
+        	if (uri != null) {
+        		if (!uri.equals(other.uri))
+            		return false;
+        	}
+        	// if URI is not available, calls URL.equals (which may take a long time)  
+        	else if (!url.equals(other.url))
+                return false;
+        }
+        if (writer == null) {
+            if (other.writer != null)
+                return false;
+        } else if (!writer.equals(other.writer))
+            return false;
+        return true;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/StreamLogging.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/StreamLogging.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/StreamLogging.java	(revision 28000)
@@ -0,0 +1,55 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class StreamLogging {
+    private static final Logger LOGGER = org.geotools.util.logging.Logging
+            .getLogger("org.geotools.data.shapefile");
+
+    private String name;
+    private int open = 0;
+
+    /**
+     * The name that will appear in the debug message
+     * 
+     * @param name
+     */
+    public StreamLogging(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Call when reader or writer is opened
+     */
+    public synchronized void open() {
+        open++;
+        if(LOGGER.isLoggable(Level.FINER)) {
+            LOGGER.finest(name + " has been opened. Number open: " + open);
+        }
+    }
+
+    public synchronized void close() {
+        open--;
+        if(LOGGER.isLoggable(Level.FINER)) {
+            LOGGER.finest(name + " has been closed. Number open: " + open);
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/dbf/DbaseFileHeader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/dbf/DbaseFileHeader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/dbf/DbaseFileHeader.java	(revision 28000)
@@ -0,0 +1,533 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This file is based on an origional contained in the GISToolkit project:
+ *    http://gistoolkit.sourceforge.net/
+ */
+package org.geotools.data.shapefile.dbf;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.charset.Charset;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import org.geotools.resources.NIOUtilities;
+
+/**
+ * Class to represent the header of a Dbase III file. Creation date: (5/15/2001
+ * 5:15:30 PM)
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/dbf/DbaseFileHeader.java $
+ */
+public class DbaseFileHeader {
+    // Constant for the size of a record
+    private static final int FILE_DESCRIPTOR_SIZE = 32;
+
+    // type of the file, must be 03h
+    private static final byte MAGIC = 0x03;
+
+    // Date the file was last updated.
+    private Date date = new Date();
+
+    private int recordCnt = 0;
+
+    private int fieldCnt = 0;
+
+    // set this to a default length of 1, which is enough for one "space"
+    // character which signifies an empty record
+    private int recordLength = 1;
+
+    // set this to a flagged value so if no fields are added before the write,
+    // we know to adjust the headerLength to MINIMUM_HEADER
+    private int headerLength = -1;
+
+    private int largestFieldSize = 0;
+
+    /**
+     * Returns the number of millis at January 1st 4713 BC
+     * 
+     *  Calendar refCal = (Calendar) new GregorianCalendar(TimeZone.getTimeZone("UTC"));
+     *   refCal.set(Calendar.ERA, GregorianCalendar.BC);
+     *   refCal.set(Calendar.YEAR, 4713);
+     *   refCal.set(Calendar.MONTH, Calendar.JANUARY);
+     *   refCal.set(Calendar.DAY_OF_MONTH, 1);
+     *   refCal.set(Calendar.HOUR, 12);
+     *   refCal.set(Calendar.MINUTE, 0);
+     *   refCal.set(Calendar.SECOND, 0);
+     *   refCal.set(Calendar.MILLISECOND, 0);
+     *   MILLIS_SINCE_4713 = refCal.getTimeInMillis() - 43200000L; 
+     *   //(43200000L: 12 hour correction factor taken from DBFViewer2000)
+     */
+    public static long MILLIS_SINCE_4713 = -210866803200000L;
+    
+    /**
+     * Class for holding the information associated with a record.
+     */
+    class DbaseField {
+
+        // Field Name
+        String fieldName;
+
+        // Field Type (C N L D @ or M)
+        char fieldType;
+
+        // Field Data Address offset from the start of the record.
+        int fieldDataAddress;
+
+        // Length of the data in bytes
+        int fieldLength;
+
+        // Field decimal count in Binary, indicating where the decimal is
+        int decimalCount;
+
+    }
+
+    // Collection of header records.
+    // lets start out with a zero-length array, just in case
+    private DbaseField[] fields = new DbaseField[0];
+
+    private void read(ByteBuffer buffer, ReadableByteChannel channel)
+            throws IOException {
+        while (buffer.remaining() > 0) {
+            if (channel.read(buffer) == -1) {
+                throw new EOFException("Premature end of file");
+            }
+        }
+    }
+
+    /**
+     * Determine the most appropriate Java Class for representing the data in
+     * the field.
+     * 
+     * <PRE>
+     * All packages are java.lang unless otherwise specified.
+     * C (Character) -&gt; String
+     * N (Numeric)   -&gt; Integer or Long or Double (depends on field's decimal count and fieldLength)
+     * F (Floating)  -&gt; Double
+     * L (Logical)   -&gt; Boolean
+     * D (Date)      -&gt; java.util.Date (Without time)
+     * @ (Timestamp) -&gt; java.sql.Timestamp (With time)
+     * Unknown       -&gt; String
+     * </PRE>
+     * 
+     * @param i
+     *                The index of the field, from 0 to
+     *                <CODE>getNumFields() - 1</CODE> .
+     * @return A Class which closely represents the dbase field type.
+     */
+    public Class getFieldClass(int i) {
+        Class typeClass = null;
+
+        switch (fields[i].fieldType) {
+        case 'C':
+            typeClass = String.class;
+            break;
+
+        case 'N':
+            if (fields[i].decimalCount == 0) {
+                if (fields[i].fieldLength < 10) {
+                    typeClass = Integer.class;
+                } else {
+                    typeClass = Long.class;
+                }
+            } else {
+                typeClass = Double.class;
+            }
+            break;
+
+        case 'F':
+            typeClass = Double.class;
+            break;
+
+        case 'L':
+            typeClass = Boolean.class;
+            break;
+
+        case 'D':
+            typeClass = Date.class;
+            break;
+            
+        case '@':
+            typeClass = Timestamp.class;
+            break;
+            
+        default:
+            typeClass = String.class;
+            break;
+        }
+
+        return typeClass;
+    }
+
+    // Retrieve the length of the field at the given index
+    /**
+     * Returns the field length in bytes.
+     * 
+     * @param inIndex
+     *                The field index.
+     * @return The length in bytes.
+     */
+    public int getFieldLength(int inIndex) {
+        return fields[inIndex].fieldLength;
+    }
+
+    // Retrieve the Name of the field at the given index
+    /**
+     * Get the field name.
+     * 
+     * @param inIndex
+     *                The field index.
+     * @return The name of the field.
+     */
+    public String getFieldName(int inIndex) {
+        return fields[inIndex].fieldName;
+    }
+
+    // Retrieve the type of field at the given index
+    /**
+     * Get the character class of the field.
+     * 
+     * @param inIndex
+     *                The field index.
+     * @return The dbase character representing this field.
+     */
+    public char getFieldType(int inIndex) {
+        return fields[inIndex].fieldType;
+    }
+
+    /**
+     * Get the date this file was last updated.
+     * 
+     * @return The Date last modified.
+     */
+    public Date getLastUpdateDate() { // NO_UCD
+        return date;
+    }
+
+    /**
+     * Return the number of fields in the records.
+     * 
+     * @return The number of fields in this table.
+     */
+    public int getNumFields() {
+        return fields.length;
+    }
+
+    /**
+     * Return the number of records in the file
+     * 
+     * @return The number of records in this table.
+     */
+    public int getNumRecords() {
+        return recordCnt;
+    }
+
+    /**
+     * Get the length of the records in bytes.
+     * 
+     * @return The number of bytes per record.
+     */
+    public int getRecordLength() {
+        return recordLength;
+    }
+
+    /**
+     * Get the length of the header
+     * 
+     * @return The length of the header in bytes.
+     */
+    public int getHeaderLength() {
+        return headerLength;
+    }
+    
+    /**
+     * Read the header data from the DBF file.
+     * 
+     * @param channel
+     *                A readable byte channel. If you have an InputStream you
+     *                need to use, you can call
+     *                java.nio.Channels.getChannel(InputStream in).
+     * @throws IOException
+     *                 If errors occur while reading.
+     */
+    public void readHeader(ReadableByteChannel channel, Charset charset) throws IOException {
+        // we'll read in chunks of 1K
+        ByteBuffer in = NIOUtilities.allocate(1024);
+        try {
+            // do this or GO CRAZY
+            // ByteBuffers come preset to BIG_ENDIAN !
+            in.order(ByteOrder.LITTLE_ENDIAN);
+    
+            // only want to read first 10 bytes...
+            in.limit(10);
+    
+            read(in, channel);
+            in.position(0);
+    
+            // type of file.
+            byte magic = in.get();
+            if (magic != MAGIC) {
+                throw new IOException("Unsupported DBF file Type "
+                        + Integer.toHexString(magic));
+            }
+    
+            // parse the update date information.
+            int tempUpdateYear = in.get();
+            int tempUpdateMonth = in.get();
+            int tempUpdateDay = in.get();
+            // ouch Y2K uncompliant
+            if (tempUpdateYear > 90) {
+                tempUpdateYear = tempUpdateYear + 1900;
+            } else {
+                tempUpdateYear = tempUpdateYear + 2000;
+            }
+            Calendar c = Calendar.getInstance();
+            c.set(Calendar.YEAR, tempUpdateYear);
+            c.set(Calendar.MONTH, tempUpdateMonth - 1);
+            c.set(Calendar.DATE, tempUpdateDay);
+            date = c.getTime();
+    
+            // read the number of records.
+            recordCnt = in.getInt();
+    
+            // read the length of the header structure.
+            // ahhh.. unsigned little-endian shorts
+            // mask out the byte and or it with shifted 2nd byte
+            headerLength = (in.get() & 0xff) | ((in.get() & 0xff) << 8);
+    
+            // if the header is bigger than our 1K, reallocate
+            if (headerLength > in.capacity()) {
+                NIOUtilities.clean(in, false);
+                in = NIOUtilities.allocate(headerLength - 10);
+            }
+            in.limit(headerLength - 10);
+            in.position(0);
+            read(in, channel);
+            in.position(0);
+    
+            // read the length of a record
+            // ahhh.. unsigned little-endian shorts
+            recordLength = (in.get() & 0xff) | ((in.get() & 0xff) << 8);
+    
+            // skip the reserved bytes in the header.
+            in.position(in.position() + 20);
+    
+            // calculate the number of Fields in the header
+            fieldCnt = (headerLength - FILE_DESCRIPTOR_SIZE - 1)
+                    / FILE_DESCRIPTOR_SIZE;
+    
+            // read all of the header records
+            List lfields = new ArrayList();
+            for (int i = 0; i < fieldCnt; i++) {
+                DbaseField field = new DbaseField();
+    
+                // read the field name
+                byte[] buffer = new byte[11];
+                in.get(buffer);
+                String name = new String(buffer, charset.name());
+                int nullPoint = name.indexOf(0);
+                if (nullPoint != -1) {
+                    name = name.substring(0, nullPoint);
+                }
+                field.fieldName = name.trim();
+    
+                // read the field type
+                field.fieldType = (char) in.get();
+    
+                // read the field data address, offset from the start of the record.
+                field.fieldDataAddress = in.getInt();
+    
+                // read the field length in bytes
+                int length = in.get();
+                if (length < 0) {
+                    length = length + 256;
+                }
+                field.fieldLength = length;
+    
+                if (length > largestFieldSize) {
+                    largestFieldSize = length;
+                }
+    
+                // read the field decimal count in bytes
+                field.decimalCount = in.get();
+    
+                // reserved bytes.
+                // in.skipBytes(14);
+                in.position(in.position() + 14);
+    
+                // some broken shapefiles have 0-length attributes. The reference
+                // implementation
+                // (ArcExplorer 2.0, built with MapObjects) just ignores them.
+                if (field.fieldLength > 0) {
+                    lfields.add(field);
+                }
+            }
+    
+            // Last byte is a marker for the end of the field definitions.
+            // in.skipBytes(1);
+            in.position(in.position() + 1);
+    
+            fields = new DbaseField[lfields.size()];
+            fields = (DbaseField[]) lfields.toArray(fields);
+        } finally {
+            NIOUtilities.clean(in, false);
+        }
+    }
+    
+    /**
+     * Read the header data from the DBF file.
+     * 
+     * @param channel
+     *                A readable byte channel. If you have an InputStream you
+     *                need to use, you can call
+     *                java.nio.Channels.getChannel(InputStream in).
+     * @throws IOException
+     *                 If errors occur while reading.
+     */
+    public void readHeader(ByteBuffer in) throws IOException {
+        // do this or GO CRAZY
+        // ByteBuffers come preset to BIG_ENDIAN !
+        in.order(ByteOrder.LITTLE_ENDIAN);
+
+        // type of file.
+        byte magic = in.get();
+        if (magic != MAGIC) {
+            throw new IOException("Unsupported DBF file Type "
+                    + Integer.toHexString(magic));
+        }
+
+        // parse the update date information.
+        int tempUpdateYear = in.get();
+        int tempUpdateMonth = in.get();
+        int tempUpdateDay = in.get();
+        // ouch Y2K uncompliant
+        if (tempUpdateYear > 90) {
+            tempUpdateYear = tempUpdateYear + 1900;
+        } else {
+            tempUpdateYear = tempUpdateYear + 2000;
+        }
+        Calendar c = Calendar.getInstance();
+        c.set(Calendar.YEAR, tempUpdateYear);
+        c.set(Calendar.MONTH, tempUpdateMonth - 1);
+        c.set(Calendar.DATE, tempUpdateDay);
+        date = c.getTime();
+
+        // read the number of records.
+        recordCnt = in.getInt();
+
+        // read the length of the header structure.
+        // ahhh.. unsigned little-endian shorts
+        // mask out the byte and or it with shifted 2nd byte
+        headerLength = (in.get() & 0xff) | ((in.get() & 0xff) << 8);
+
+        // if the header is bigger than our 1K, reallocate
+        if (headerLength > in.capacity()) {
+            throw new IllegalArgumentException("The contract says the buffer should be long enough to fit all the header!");
+        }
+
+        // read the length of a record
+        // ahhh.. unsigned little-endian shorts
+        recordLength = (in.get() & 0xff) | ((in.get() & 0xff) << 8);
+
+        // skip the reserved bytes in the header.
+        in.position(in.position() + 20);
+
+        // calculate the number of Fields in the header
+        fieldCnt = (headerLength - FILE_DESCRIPTOR_SIZE - 1)
+                / FILE_DESCRIPTOR_SIZE;
+
+        // read all of the header records
+        List lfields = new ArrayList();
+        for (int i = 0; i < fieldCnt; i++) {
+            DbaseField field = new DbaseField();
+
+            // read the field name
+            byte[] buffer = new byte[11];
+            in.get(buffer);
+            String name = new String(buffer);
+            int nullPoint = name.indexOf(0);
+            if (nullPoint != -1) {
+                name = name.substring(0, nullPoint);
+            }
+            field.fieldName = name.trim();
+
+            // read the field type
+            field.fieldType = (char) in.get();
+
+            // read the field data address, offset from the start of the record.
+            field.fieldDataAddress = in.getInt();
+
+            // read the field length in bytes
+            int length = in.get();
+            if (length < 0) {
+                length = length + 256;
+            }
+            field.fieldLength = length;
+
+            if (length > largestFieldSize) {
+                largestFieldSize = length;
+            }
+
+            // read the field decimal count in bytes
+            field.decimalCount = in.get();
+
+            // reserved bytes.
+            // in.skipBytes(14);
+            in.position(in.position() + 14);
+
+            // some broken shapefiles have 0-length attributes. The reference
+            // implementation
+            // (ArcExplorer 2.0, built with MapObjects) just ignores them.
+            if (field.fieldLength > 0) {
+                lfields.add(field);
+            }
+        }
+
+        // Last byte is a marker for the end of the field definitions.
+        // in.skipBytes(1);
+        in.position(in.position() + 1);
+
+        fields = new DbaseField[lfields.size()];
+        fields = (DbaseField[]) lfields.toArray(fields);
+    }
+
+    /**
+     * Get a simple representation of this header.
+     * 
+     * @return A String representing the state of the header.
+     */
+    public String toString() {
+        StringBuffer fs = new StringBuffer();
+        for (int i = 0, ii = fields.length; i < ii; i++) {
+            DbaseField f = fields[i];
+            fs.append(f.fieldName + " " + f.fieldType + " " + f.fieldLength
+                    + " " + f.decimalCount + " " + f.fieldDataAddress + "\n");
+        }
+
+        return "DB3 Header\n" + "Date : " + date + "\n" + "Records : "
+                + recordCnt + "\n" + "Fields : " + fieldCnt + "\n" + fs;
+
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/dbf/DbaseFileReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/dbf/DbaseFileReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/dbf/DbaseFileReader.java	(revision 28000)
@@ -0,0 +1,510 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This file is based on an origional contained in the GISToolkit project:
+ *    http://gistoolkit.sourceforge.net/
+ */
+package org.geotools.data.shapefile.dbf;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.charset.Charset;
+import java.util.Calendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.geotools.data.shapefile.FileReader;
+import org.geotools.data.shapefile.ShpFileType;
+import org.geotools.data.shapefile.ShpFiles;
+import org.geotools.data.shapefile.StreamLogging;
+import org.geotools.resources.NIOUtilities;
+
+/**
+ * A DbaseFileReader is used to read a dbase III format file. <br>
+ * The general use of this class is: <CODE><PRE>
+ * 
+ * FileChannel in = new FileInputStream(&quot;thefile.dbf&quot;).getChannel();
+ * DbaseFileReader r = new DbaseFileReader( in ) Object[] fields = new
+ * Object[r.getHeader().getNumFields()]; while (r.hasNext()) {
+ * r.readEntry(fields); // do stuff } r.close();
+ * 
+ * </PRE></CODE> For consumers who wish to be a bit more selective with their reading
+ * of rows, the Row object has been added. The semantics are the same as using
+ * the readEntry method, but remember that the Row object is always the same.
+ * The values are parsed as they are read, so it pays to copy them out (as each
+ * call to Row.read() will result in an expensive String parse). <br>
+ * <b>EACH CALL TO readEntry OR readRow ADVANCES THE FILE!</b><br>
+ * An example of using the Row method of reading: <CODE><PRE>
+ * 
+ * FileChannel in = new FileInputStream(&quot;thefile.dbf&quot;).getChannel();
+ * DbaseFileReader r = new DbaseFileReader( in ) int fields =
+ * r.getHeader().getNumFields(); while (r.hasNext()) { DbaseFileReader.Row row =
+ * r.readRow(); for (int i = 0; i &lt; fields; i++) { // do stuff Foo.bar(
+ * row.read(i) ); } } r.close();
+ * 
+ * </PRE></CODE>
+ * 
+ * @author Ian Schneider, Andrea Aaime
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/dbf/DbaseFileReader.java $
+ */
+public class DbaseFileReader implements FileReader {
+
+    public final class Row {
+        public Object read(final int column) throws IOException {
+            final int offset = fieldOffsets[column];
+            return readObject(offset, column);
+        }
+
+        public String toString() {
+            final StringBuffer ret = new StringBuffer("DBF Row - ");
+            for (int i = 0; i < header.getNumFields(); i++) {
+                ret.append(header.getFieldName(i)).append(": \"");
+                try {
+                    ret.append(this.read(i));
+                } catch (final IOException ioe) {
+                    ret.append(ioe.getMessage());
+                }
+                ret.append("\" ");
+            }
+            return ret.toString();
+        }
+    }
+
+    DbaseFileHeader header;
+
+    ByteBuffer buffer;
+
+    ReadableByteChannel channel;
+
+    byte[] bytes;
+
+    char[] fieldTypes;
+
+    int[] fieldLengths;
+    
+    int[] fieldOffsets;
+
+    int cnt = 1;
+
+    Row row;
+
+    protected boolean useMemoryMappedBuffer;
+
+    protected boolean randomAccessEnabled;
+
+    protected long currentOffset = 0;
+    private final StreamLogging streamLogger = new StreamLogging("Dbase File Reader");
+
+    private Charset stringCharset;
+    
+    private boolean oneBytePerChar;
+
+    private Calendar calendar;
+
+    private final long MILLISECS_PER_DAY = 24*60*60*1000;
+
+    
+    /**
+     * Creates a new instance of DBaseFileReader
+     * 
+     * @param shapefileFiles.
+     *                The readable channel to use.
+     * @throws IOException
+     *                 If an error occurs while initializing.
+     */
+    public DbaseFileReader(final ShpFiles shapefileFiles,
+            final boolean useMemoryMappedBuffer, final Charset charset, final TimeZone timeZone) throws IOException {
+        final ReadableByteChannel dbfChannel = shapefileFiles.getReadChannel(ShpFileType.DBF, this);
+        init(dbfChannel, useMemoryMappedBuffer, charset, timeZone);
+    }
+
+    private void init(final ReadableByteChannel dbfChannel, final boolean useMemoryMappedBuffer,
+            final Charset charset, final TimeZone timeZone) throws IOException {
+        this.channel = dbfChannel;
+        this.stringCharset = charset == null ? Charset.defaultCharset() : charset;
+        TimeZone calTimeZone = timeZone == null ? TimeZone.getDefault() : timeZone;
+        this.calendar = Calendar.getInstance(calTimeZone, Locale.US);
+
+        this.useMemoryMappedBuffer = useMemoryMappedBuffer;
+        this.randomAccessEnabled = (channel instanceof FileChannel);
+        streamLogger.open();
+        header = new DbaseFileHeader();
+
+        // create the ByteBuffer
+        // if we have a FileChannel, lets map it
+        if (channel instanceof FileChannel && this.useMemoryMappedBuffer) {
+            final FileChannel fc = (FileChannel) channel;
+            if((fc.size() - fc.position()) < Integer.MAX_VALUE) {
+                buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
+            } else {
+                buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, Integer.MAX_VALUE);
+            }
+            buffer.position((int) fc.position());
+            header.readHeader(buffer);
+            
+            this.currentOffset = 0;
+        } else {
+            // Force useMemoryMappedBuffer to false
+            this.useMemoryMappedBuffer = false;
+            header.readHeader(channel, charset);
+            // Some other type of channel
+            // size the buffer so that we can read 4 records at a time (and make the buffer cacheable)
+            //int size = (int) Math.pow(2, Math.ceil(Math.log(header.getRecordLength()) / Math.log(2)));
+            buffer = NIOUtilities.allocate(header.getRecordLength());
+            // fill it and reset
+            fill(buffer, channel);
+            buffer.flip();
+            this.currentOffset = header.getHeaderLength();
+        }
+        
+        // The entire file is in little endian
+        buffer.order(ByteOrder.LITTLE_ENDIAN);
+        
+        // Set up some buffers and lookups for efficiency
+        fieldTypes = new char[header.getNumFields()];
+        fieldLengths = new int[header.getNumFields()];
+        fieldOffsets = new int[header.getNumFields()];
+        for (int i = 0, ii = header.getNumFields(); i < ii; i++) {
+            fieldTypes[i] = header.getFieldType(i);
+            fieldLengths[i] = header.getFieldLength(i);
+            if(i > 0)
+                fieldOffsets[i] = fieldOffsets[i -1] + header.getFieldLength(i - 1);
+        }
+        bytes = new byte[header.getRecordLength() - 1];
+        
+
+        // check if we working with a latin-1 char Charset
+        final String cname = stringCharset.name();
+        oneBytePerChar = "ISO-8859-1".equals(cname) || "US-ASCII".equals(cname);
+        
+        row = new Row();
+    }
+
+    protected int fill(final ByteBuffer buffer, final ReadableByteChannel channel)
+            throws IOException {
+        int r = buffer.remaining();
+        // channel reads return -1 when EOF or other error
+        // because they a non-blocking reads, 0 is a valid return value!!
+        while (buffer.remaining() > 0 && r != -1) {
+            r = channel.read(buffer);
+        }
+        if (r == -1) {
+            buffer.limit(buffer.position());
+        }
+        return r;
+    }
+
+    private void bufferCheck() throws IOException {
+        // remaining is less than record length
+        // compact the remaining data and read again
+        if(useMemoryMappedBuffer) {
+            if(buffer.remaining() < header.getRecordLength()) {
+                // ops, we're dealing with a DBF whose size is > 2GB (and < 4 normally?)
+                FileChannel fc = (FileChannel) channel;
+                int position = buffer.position();
+                if(fc.size() > position + Integer.MAX_VALUE) {
+                    currentOffset = position;
+                } else {
+                    currentOffset = fc.size() - Integer.MAX_VALUE;
+                }
+                NIOUtilities.clean(buffer);
+                buffer = fc.map(MapMode.READ_ONLY, currentOffset, Integer.MAX_VALUE);
+                
+                buffer = ((FileChannel) channel).map(MapMode.READ_ONLY, buffer.position(), Integer.MAX_VALUE);
+            }
+        } else if (buffer.remaining() < header.getRecordLength()) {
+            this.currentOffset += buffer.position();
+            buffer.compact();
+            fill(buffer, channel);
+            buffer.position(0);
+        }
+    }
+
+    /**
+     * Get the header from this file. The header is read upon instantiation.
+     * 
+     * @return The header associated with this file or null if an error
+     *         occurred.
+     */
+    public DbaseFileHeader getHeader() {
+        return header;
+    }
+
+    /**
+     * Clean up all resources associated with this reader.<B>Highly recomended.</B>
+     * 
+     * @throws IOException
+     *                 If an error occurs.
+     */
+    public void close() throws IOException {
+        if (channel != null && channel.isOpen()) {
+            channel.close();
+            streamLogger.close();
+        }
+        if(buffer != null) {
+            NIOUtilities.clean(buffer, useMemoryMappedBuffer);
+        }
+
+        buffer = null;
+        channel = null;
+        bytes= null;
+        header = null;
+        row = null;
+    }
+
+    /**
+     * Query the reader as to whether there is another record.
+     * 
+     * @return True if more records exist, false otherwise.
+     */
+    public boolean hasNext() {
+        return cnt < header.getNumRecords() + 1;
+    }
+
+    public Row readRow() throws IOException {
+        read();
+        return row;
+    }
+
+    /**
+     * Skip the next record.
+     * 
+     * @throws IOException
+     *                 If an error occurs.
+     */
+    public void skip() throws IOException {
+        boolean foundRecord = false;
+        while (!foundRecord) {
+
+            bufferCheck();
+
+            // read the deleted flag
+            final char tempDeleted = (char) buffer.get();
+
+            // skip the next bytes
+            buffer.position(buffer.position() + header.getRecordLength() - 1); // the
+            // 1 is
+            // for
+            // the
+            // deleted
+            // flag
+            // just
+            // read.
+
+            // add the row if it is not deleted.
+            if (tempDeleted != '*') {
+                foundRecord = true;
+            }
+        }
+        cnt++;
+    }
+    
+    /**
+     * Reads the next record into memory. You need to use this directly when reading only
+     * a subset of the fields using {@link #readField(int)}. 
+     * @throws IOException
+     */
+    public void read() throws IOException {
+        boolean foundRecord = false;
+        while (!foundRecord) {
+
+            bufferCheck();
+
+            // read the deleted flag
+            final char deleted = (char) buffer.get();
+            if (deleted == '*') {
+                continue;
+            }
+
+            buffer.limit(buffer.position() + header.getRecordLength() - 1);
+            buffer.get(bytes); // SK: There is a side-effect here!!!
+            buffer.limit(buffer.capacity());
+
+            foundRecord = true;
+        }
+
+        cnt++;
+    }
+
+    private Object readObject(final int fieldOffset, final int fieldNum)
+            throws IOException {
+        final char type = fieldTypes[fieldNum];
+        final int fieldLen = fieldLengths[fieldNum];
+        Object object = null;
+        if (fieldLen > 0) {
+            switch (type) {
+            // (L)logical (T,t,F,f,Y,y,N,n)
+            case 'l':
+            case 'L':
+                final char c = (char) bytes[fieldOffset];
+                switch (c) {
+                case 't':
+                case 'T':
+                case 'Y':
+                case 'y':
+                    object = Boolean.TRUE;
+                    break;
+                case 'f':
+                case 'F':
+                case 'N':
+                case 'n':
+                    object = Boolean.FALSE;
+                    break;
+                default:
+                    // 0x20 should be interpreted as null, but we're going to be a bit more lax
+                    //object = null;
+                }
+                break;
+            // (C)character (String)
+            case 'c':
+            case 'C':
+                // if the string begins with a null terminator, the value is null
+                if (bytes[fieldOffset] != '\0') {
+                    // remember we need to skip trailing and leading spaces
+                    if(oneBytePerChar) {
+                        object = fastParse(bytes, fieldOffset, fieldLen).trim();
+                    } else {
+                        object = new String(bytes, fieldOffset, fieldLen, stringCharset.name()).trim();
+                    }
+                }
+                break;
+            // (D)date (Date)
+            case 'd':
+            case 'D':
+                // If the first 8 characters are '0', this is a null date
+                for (int i = 0; i < 8; i++) {
+                    if (bytes[fieldOffset+i] != '0') {
+                        try {
+                            String tempString = fastParse(bytes,fieldOffset,4); 
+                            final int tempYear = Integer.parseInt(tempString);
+                            tempString =  fastParse(bytes,fieldOffset + 4,2);
+                            final int tempMonth = Integer.parseInt(tempString) - 1;
+                            tempString = fastParse(bytes,fieldOffset + 6,2); 
+                            final int tempDay = Integer.parseInt(tempString);
+                            calendar.clear();
+                            calendar.set(Calendar.YEAR, tempYear);
+                            calendar.set(Calendar.MONTH, tempMonth);
+                            calendar.set(Calendar.DAY_OF_MONTH, tempDay);
+                            object = calendar.getTime();
+                        } catch (final NumberFormatException nfe) {
+                            // todo: use progresslistener, this isn't a grave error.
+                        }
+                        break;
+                    }
+                }
+                break;
+            // (@) Timestamp (Date)
+            case '@':
+                try {      
+                    //TODO: Find a smarter way to do this. 
+                    //timestampBytes = bytes[fieldOffset:fieldOffset+7]
+                    byte[] timestampBytes = {
+                        // Time in millis, after reverse.
+                        bytes[fieldOffset+7], bytes[fieldOffset+6], bytes[fieldOffset+5], bytes[fieldOffset+4],
+                        // Days, after reverse.
+                        bytes[fieldOffset+3], bytes[fieldOffset+2], bytes[fieldOffset+1], bytes[fieldOffset]                    
+                    };
+                       
+                    ByteArrayInputStream i_bytes = new ByteArrayInputStream(timestampBytes);
+                    DataInputStream i_stream = new DataInputStream(new BufferedInputStream(i_bytes));
+
+                    int time = i_stream.readInt();
+                    int days = i_stream.readInt();
+                              
+                    calendar.setTimeInMillis(days * MILLISECS_PER_DAY + DbaseFileHeader.MILLIS_SINCE_4713 + time);
+
+                    object = calendar.getTime();
+
+                } catch (final NumberFormatException nfe) {
+                   // todo: use progresslistener, this isn't a grave error.
+                }
+                break;                
+            // (N)umeric (Integer, Long or Fallthrough to Double)
+            case 'n':
+            case 'N':
+                // numbers that begin with '*' are considered null
+                if (bytes[fieldOffset] == '*') {
+                    break;
+                } else {
+                    final String string = fastParse(bytes,fieldOffset,fieldLen).trim();
+                    Class clazz = header.getFieldClass(fieldNum);
+                    if (clazz == Integer.class) {
+                        try {
+                            object = Integer.parseInt(string);
+                            break;
+                        } catch (NumberFormatException e) {
+                            // try to parse as long... 
+                            clazz = Long.class; 
+                        }
+                    } 
+                    if (clazz == Long.class) {
+                        try {
+                            object = Long.parseLong(string);
+                            break;
+                        } catch (final NumberFormatException e2) {
+                            // fall through to the floating point number
+                        }
+                    }
+                }
+                // do not break, fall through to the 'f' case
+
+            // (F)loating point number
+            case 'f':
+            case 'F': 
+                if (bytes[fieldOffset] != '*') {
+                    try {
+                        object = Double.parseDouble(fastParse(bytes,fieldOffset,fieldLen));
+                    } catch (final NumberFormatException e) {
+                        // okay, now whatever we got was truly indigestible. Lets go
+                        // with a zero Double.
+                        object = new Double(0.0);
+                    }
+                }
+                break;
+            default:
+                throw new IOException("Invalid field type : " + type);
+            }
+
+        }
+        return object;
+    }
+    
+    /**
+     * Performs a faster byte[] to String conversion under the assumption the content
+     * is represented with one byte per char 
+     * @param fieldLen
+     * @param fieldOffset
+     * @return
+     */
+    String fastParse(final byte[] bytes, final int fieldOffset, final int fieldLen) {
+        // faster reading path, the decoder is for some reason slower,
+        // probably because it has to make extra checks to support multibyte chars
+        final char[] chars = new char[fieldLen]; 
+        for (int i = 0; i < fieldLen; i++) {
+            // force the byte to a positive integer interpretation before casting to char
+            chars[i] = ((char) (0x00FF & bytes[fieldOffset+i]));
+        }
+        return new String(chars);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/dbf/IndexedDbaseFileReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/dbf/IndexedDbaseFileReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/dbf/IndexedDbaseFileReader.java	(revision 28000)
@@ -0,0 +1,117 @@
+/*
+ *    Geotools - OpenSource mapping toolkit
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This file is based on an origional contained in the GISToolkit project:
+ *    http://gistoolkit.sourceforge.net/
+ */
+package org.geotools.data.shapefile.dbf;
+
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
+import java.nio.charset.Charset;
+import java.util.TimeZone;
+
+import org.geotools.data.shapefile.ShpFiles;
+import org.geotools.resources.NIOUtilities;
+
+/**
+ * A DbaseFileReader is used to read a dbase III format file. <br>
+ * The general use of this class is: <CODE><PRE>
+ * FileChannel in = new FileInputStream(&quot;thefile.dbf&quot;).getChannel();
+ * DbaseFileReader r = new DbaseFileReader( in )
+ * Object[] fields = new Object[r.getHeader().getNumFields()];
+ * while (r.hasNext()) {
+ *    r.readEntry(fields);
+ *    // do stuff
+ * }
+ * r.close();
+ * </PRE></CODE> For consumers who wish to be a bit more selective with their reading
+ * of rows, the Row object has been added. The semantics are the same as using
+ * the readEntry method, but remember that the Row object is always the same.
+ * The values are parsed as they are read, so it pays to copy them out (as each
+ * call to Row.read() will result in an expensive String parse). <br>
+ * <b>EACH CALL TO readEntry OR readRow ADVANCES THE FILE!</b><br>
+ * An example of using the Row method of reading: <CODE><PRE>
+ * FileChannel in = new FileInputStream(&quot;thefile.dbf&quot;).getChannel();
+ * DbaseFileReader r = new DbaseFileReader( in )
+ * int fields = r.getHeader().getNumFields();
+ * while (r.hasNext()) {
+ *   DbaseFileReader.Row row = r.readRow();
+ *   for (int i = 0; i &lt; fields; i++) {
+ *     // do stuff
+ *     Foo.bar( row.read(i) );
+ *   }
+ * }
+ * r.close();
+ * </PRE></CODE>
+ * 
+ * @author Ian Schneider
+ * @author Tommaso Nolli
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/dbf/IndexedDbaseFileReader.java $
+ */
+public class IndexedDbaseFileReader extends DbaseFileReader {
+
+    public void goTo(int recno) throws IOException,
+            UnsupportedOperationException {
+
+        if (this.randomAccessEnabled) {
+            long newPosition = this.header.getHeaderLength()
+                    + this.header.getRecordLength() * (long) (recno - 1);
+
+            if (this.useMemoryMappedBuffer) {
+                if(newPosition < this.currentOffset || (this.currentOffset + buffer.limit()) < (newPosition + header.getRecordLength())) {
+                    NIOUtilities.clean(buffer);
+                    FileChannel fc = (FileChannel) channel;
+                    if(fc.size() > newPosition + Integer.MAX_VALUE) {
+                        currentOffset = newPosition;
+                    } else {
+                        currentOffset = fc.size() - Integer.MAX_VALUE;
+                    }
+                    buffer = fc.map(MapMode.READ_ONLY, currentOffset, Integer.MAX_VALUE);
+                    buffer.position((int) (newPosition - currentOffset));
+                } else {
+                    buffer.position((int) (newPosition - currentOffset));
+                }
+            } else {
+                if (this.currentOffset <= newPosition
+                        && this.currentOffset + buffer.limit() >= newPosition) {
+                    buffer.position((int) (newPosition - this.currentOffset));
+                    //System.out.println("Hit");
+                } else {
+                    //System.out.println("Jump");
+                    FileChannel fc = (FileChannel) this.channel;
+                    fc.position(newPosition);
+                    this.currentOffset = newPosition;
+                    buffer.limit(buffer.capacity());
+                    buffer.position(0);
+                    fill(buffer, fc);
+                    buffer.position(0);
+                }
+            }
+        } else {
+            throw new UnsupportedOperationException(
+                    "Random access not enabled!");
+        }
+
+    }
+    
+    public IndexedDbaseFileReader(ShpFiles shpFiles,
+            boolean useMemoryMappedBuffer, Charset stringCharset, TimeZone timeZone)
+            throws IOException {
+        super(shpFiles, useMemoryMappedBuffer, stringCharset, timeZone);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/CloseableIteratorWrapper.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/CloseableIteratorWrapper.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/CloseableIteratorWrapper.java	(revision 28000)
@@ -0,0 +1,32 @@
+package org.geotools.data.shapefile.indexed;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.geotools.index.CloseableIterator;
+
+public class CloseableIteratorWrapper<E> implements CloseableIterator<E> {
+    Iterator<E> delegate;
+
+    public CloseableIteratorWrapper(Iterator<E> delegate) {
+        this.delegate = delegate;
+    }
+
+    public boolean hasNext() {
+        return delegate.hasNext();
+    }
+
+    public E next() {
+        return delegate.next();
+    }
+
+    public void remove() {
+        delegate.remove();
+    }
+
+    public void close() throws IOException {
+        // TODO Auto-generated method stub
+
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/IndexType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/IndexType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/IndexType.java	(revision 28000)
@@ -0,0 +1,40 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.indexed;
+
+import org.geotools.data.shapefile.ShpFileType;
+
+/**
+ * Enumerates the different types of Shapefile geometry indices there are.
+ * 
+ * @author jesse
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/indexed/IndexType.java $
+ */
+public enum IndexType {
+    /**
+     * Don't use indexing
+     */
+    NONE(null),
+    /**
+     * The same index as mapserver. Its the most reliable and is the default
+     */
+    QIX(ShpFileType.QIX);
+
+    private IndexType(ShpFileType shpFileType) {
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/IndexedFidReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/IndexedFidReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/IndexedFidReader.java	(revision 28000)
@@ -0,0 +1,313 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.indexed;
+
+import static org.geotools.data.shapefile.ShpFileType.FIX;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.util.NoSuchElementException;
+import java.util.logging.Logger;
+
+import org.geotools.data.DataUtilities;
+import org.geotools.data.FIDReader;
+import org.geotools.data.shapefile.FileReader;
+import org.geotools.data.shapefile.ShpFiles;
+import org.geotools.data.shapefile.StreamLogging;
+import org.geotools.data.shapefile.shp.ShapefileReader;
+import org.geotools.resources.NIOUtilities;
+
+/**
+ * This object reads from a file the fid of a feature in a shapefile.
+ * 
+ * @author Jesse
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/indexed/IndexedFidReader.java $
+ */
+public class IndexedFidReader implements FIDReader, FileReader {
+    public static final int HEADER_SIZE = 13;
+    public static final int RECORD_SIZE = 12;
+    private static final Logger LOGGER = org.geotools.util.logging.Logging
+            .getLogger("org.geotools.data.shapefile");
+    private ReadableByteChannel readChannel;
+    private ByteBuffer buffer;
+    private long count;
+    private String typeName;
+    private boolean done;
+    private int removes;
+    private int currentShxIndex = -1;
+    private RecordNumberTracker reader;
+    private long currentId;
+    private StringBuilder fidBuilder;
+    
+    /**
+     * move the reader to the recno-th entry in the file.
+     * 
+     * @param recno
+     * @throws IOException
+     */
+    private long bufferStart = Long.MIN_VALUE;
+    StreamLogging streamLogger = new StreamLogging("IndexedFidReader");
+
+    public IndexedFidReader(ShpFiles shpFiles) throws IOException {
+        init( shpFiles, shpFiles.getReadChannel(FIX, this) );
+    }
+
+    public IndexedFidReader(ShpFiles shpFiles, RecordNumberTracker reader)
+            throws IOException {
+        this(shpFiles);
+        this.reader = reader;
+
+    }
+
+    private void init( ShpFiles shpFiles, ReadableByteChannel in ) throws IOException {
+        this.typeName = shpFiles.getTypeName() + ".";
+        this.fidBuilder = new StringBuilder(typeName);
+        this.readChannel = in;
+        streamLogger.open();
+        getHeader(shpFiles);
+
+        buffer = NIOUtilities.allocate(RECORD_SIZE * 1024);
+        buffer.position(buffer.limit());
+    }
+
+    private void getHeader(ShpFiles shpFiles) throws IOException {
+        ByteBuffer buffer = NIOUtilities.allocate(HEADER_SIZE);
+        try {
+            ShapefileReader.fill(buffer, readChannel);
+    
+            if (buffer.position() == 0) {
+                done = true;
+                count = 0;
+    
+                return;
+            }
+    
+            buffer.position(0);
+    
+            byte version = buffer.get();
+    
+            if (version != 1) {
+                throw new IOException(
+                        "File is not of a compatible version for this reader or file is corrupt.");
+            }
+    
+            this.count = buffer.getLong();
+            this.removes = buffer.getInt();
+            if (removes > getCount() / 2) {
+                URL url = shpFiles.acquireRead(FIX, this);
+                try {
+                    DataUtilities.urlToFile(url).deleteOnExit();
+                } finally {
+                    shpFiles.unlockRead(url, this);
+                }
+            }
+        } finally {
+            NIOUtilities.clean(buffer, false);
+        }
+    }
+
+    /**
+     * Returns the number of Fid Entries in the file.
+     * 
+     * @return Returns the number of Fid Entries in the file.
+     */
+    public long getCount() {
+        return count;
+    }
+
+    /**
+     * Returns the offset to the location in the SHX file that the fid
+     * identifies. This search take logN time.
+     * 
+     * @param fid
+     *                the fid to find.
+     * 
+     * @return Returns the record number of the record in the SHX file that the
+     *         fid identifies. Will return -1 if the fid was not found.
+     * 
+     * @throws IOException
+     * @throws IllegalArgumentException
+     *                 DOCUMENT ME!
+     */
+    public long findFid(String fid) throws IOException {
+        try {
+            int idx = typeName.length(); //typeName already contains the trailing "."
+            long desired = -1;
+            if(fid.startsWith(typeName)){
+                try{
+                    desired =  Long.parseLong(fid.substring(idx), 10);
+                }catch(NumberFormatException e){
+                    return -1;
+                }
+            }else{
+                return -1;
+            }
+
+            if ((desired < 0)) {
+                return -1;
+            }
+
+            if (desired < count) {
+                return search(desired, -1, this.count, desired - 1);
+            } else {
+                return search(desired, -1, this.count, count - 1);
+            }
+        } catch (NumberFormatException e) {
+            LOGGER
+                    .warning("Fid is not recognized as a fid for this shapefile: "
+                            + typeName);
+            return -1;
+        }
+    }
+
+    /**
+     * Searches for the desired record.
+     * 
+     * @param desired
+     *                the id of the desired record.
+     * @param minRec
+     *                the last record that is known to be <em>before</em> the
+     *                desired record.
+     * @param maxRec
+     *                the first record that is known to be <em>after</em> the
+     *                desired record.
+     * @param predictedRec
+     *                the record that is predicted to be the desired record.
+     * 
+     * @return returns the record number of the feature in the shx file.
+     * 
+     * @throws IOException
+     */
+    long search(long desired, long minRec, long maxRec, long predictedRec)
+            throws IOException {
+        if (minRec == maxRec) {
+            return -1;
+        }
+
+        goTo(predictedRec);
+        hasNext(); // force data reading
+        next();
+        buffer.limit(buffer.capacity());
+        if (currentId == desired) {
+            return currentShxIndex;
+        }
+
+        if (maxRec - minRec < 10) {
+            return search(desired, minRec + 1, maxRec, minRec + 1);
+        } else {
+            long newOffset = desired - currentId;
+            long newPrediction = predictedRec + newOffset;
+
+            if (newPrediction <= minRec) {
+                newPrediction = minRec + ((predictedRec - minRec) / 2);
+            }
+
+            if (newPrediction >= maxRec) {
+                newPrediction = predictedRec + ((maxRec - predictedRec) / 2);
+            }
+
+            if (newPrediction == predictedRec) {
+                return -1;
+            }
+
+            if (newPrediction < predictedRec) {
+                return search(desired, minRec, predictedRec, newPrediction);
+            } else {
+                return search(desired, predictedRec, maxRec, newPrediction);
+            }
+        }
+    }
+
+    public void goTo(long recno) throws IOException {
+        assert recno<count;
+        if (readChannel instanceof FileChannel) {
+            long newPosition = HEADER_SIZE
+                    + (recno * RECORD_SIZE);
+            if (newPosition >= bufferStart + buffer.limit()
+                    || newPosition < bufferStart) {
+                FileChannel fc = (FileChannel) readChannel;
+                fc.position(newPosition);
+                buffer.limit(buffer.capacity());
+                buffer.position(buffer.limit());
+            } else {
+                buffer.position((int) (newPosition - bufferStart));
+            }
+        } else {
+            throw new IOException(
+                    "Read Channel is not a File Channel so this is not possible.");
+        }
+    }
+
+    public void close() throws IOException {
+        try {
+            if (buffer != null) {
+                NIOUtilities.clean(buffer, false);
+            }
+            if (reader != null) {
+                reader.close();
+            }
+        } finally {
+            buffer = null;
+            reader = null;
+            readChannel.close();
+            streamLogger.close();
+        }
+    }
+
+    public boolean hasNext() throws IOException {
+        if (done) {
+            return false;
+        }
+
+        if (buffer.position() == buffer.limit()) {
+            buffer.position(0);
+
+            FileChannel fc = (FileChannel) readChannel;
+            bufferStart = fc.position();
+            int read = ShapefileReader.fill(buffer, readChannel);
+
+            if (read != 0) {
+                buffer.position(0);
+            }
+        }
+
+        return buffer.remaining() != 0;
+    }
+
+    public String next() throws IOException {
+        if (reader != null) {
+            goTo(reader.getRecordNumber() - 1);
+        }
+
+        if (!hasNext()) {
+            throw new NoSuchElementException(
+                    "Feature could not be read; a the index may be invalid");
+        }
+
+        currentId = buffer.getLong();
+        currentShxIndex = buffer.getInt();
+
+        fidBuilder.setLength(typeName.length());
+        fidBuilder.append(currentId);
+        return fidBuilder.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/IndexedShapefileAttributeReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/IndexedShapefileAttributeReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/IndexedShapefileAttributeReader.java	(revision 28000)
@@ -0,0 +1,147 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.indexed;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.geotools.data.shapefile.ShapefileAttributeReader;
+import org.geotools.data.shapefile.dbf.IndexedDbaseFileReader;
+import org.geotools.data.shapefile.shp.ShapefileReader;
+import org.geotools.index.CloseableIterator;
+import org.geotools.index.Data;
+import org.opengis.feature.type.AttributeDescriptor;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * An AttributeReader implementation for shape. Pretty straightforward. <BR/>The
+ * default geometry is at position 0, and all dbf columns follow. <BR/>The dbf
+ * file may not be necessary, if not, just pass null as the DbaseFileReader
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/indexed/IndexedShapefileAttributeReader.java $
+ */
+public class IndexedShapefileAttributeReader extends ShapefileAttributeReader {
+
+    protected CloseableIterator<Data> goodRecs;
+
+    private Data next;
+    
+    public IndexedShapefileAttributeReader(
+            List<AttributeDescriptor> attributes, ShapefileReader shp,
+            IndexedDbaseFileReader dbf, CloseableIterator<Data> goodRecs) {
+        this(attributes.toArray(new AttributeDescriptor[0]), shp, dbf, goodRecs);
+    }
+
+    /**
+     * Create the shape reader
+     * 
+     * @param atts -
+     *                the attributes that we are going to read.
+     * @param shp -
+     *                the shape reader, required
+     * @param dbf -
+     *                the dbf file reader. May be null, in this case no
+     *                attributes will be read from the dbf file
+     * @param goodRecs
+     *                Collection of good indexes that match the query.
+     */
+    public IndexedShapefileAttributeReader(AttributeDescriptor[] atts,
+            ShapefileReader shp, IndexedDbaseFileReader dbf,
+            CloseableIterator<Data> goodRecs) {
+        super(atts, shp, dbf);
+        this.goodRecs = goodRecs;
+    }
+
+    public void close() throws IOException {
+        try {
+            super.close();
+        } finally {
+            if( goodRecs != null ){
+                goodRecs.close();
+            }
+            goodRecs = null;
+        }
+    }
+
+    public boolean hasNext() throws IOException {
+        if (this.goodRecs != null) {
+            while (!featureAvailable && this.goodRecs.hasNext()) {
+                next = goodRecs.next();
+                
+                Long l = (Long) next.getValue(1);
+                shp.goTo((int) l.longValue());
+                
+                record = shp.nextRecord();
+                
+                // read the geometry, so that we can decide if this row is to be skipped or not
+                Envelope envelope = record.envelope();
+                // ... if geometry is out of the target bbox, skip both geom and row
+                if (targetBBox != null && !targetBBox.isNull() && !targetBBox.intersects(envelope)) {
+                    geometry = null;
+                    continue;
+                // ... if the geometry is awfully small avoid reading it (unless it's a point)
+                /*} else if (simplificationDistance > 0 && envelope.getWidth() < simplificationDistance
+                        && envelope.getHeight() < simplificationDistance) {
+                    try {
+                        if(screenMap != null && screenMap.checkAndSet(envelope)) {
+                            geometry = null;
+                            continue;
+                        } else {
+                            // if we are using the screenmap better provide a slightly modified
+                            // version of the geometry bounds or we'll end up with many holes
+                            // in the rendering
+                            geometry = record.getSimplifiedShape(screenMap);
+                        }
+                    } catch(Exception e) {
+                        geometry = record.getSimplifiedShape();
+                    }*/
+                // ... otherwise business as usual
+                } else {
+                    geometry = record.shape();
+                }
+
+                // read the dbf only if the geometry was not skipped
+                if (dbf != null) {
+                    ((IndexedDbaseFileReader) dbf).goTo(record.number);
+                    row = dbf.readRow();
+                } else {
+                    row = null;
+                }
+                
+                featureAvailable = true;
+            }
+            
+            return featureAvailable;
+        } else {
+            return super.hasNext();
+        }
+    }
+
+    public void next() throws IOException {
+        if (!hasNext())
+            throw new IndexOutOfBoundsException("No more features in reader");
+        featureAvailable = false;
+
+        
+    }
+
+    
+
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/IndexedShapefileDataStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/IndexedShapefileDataStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/IndexedShapefileDataStore.java	(revision 28000)
@@ -0,0 +1,854 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ * 
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.indexed;
+
+import static org.geotools.data.shapefile.ShpFileType.DBF;
+import static org.geotools.data.shapefile.ShpFileType.FIX;
+import static org.geotools.data.shapefile.ShpFileType.QIX;
+import static org.geotools.data.shapefile.ShpFileType.SHP;
+import static org.geotools.data.shapefile.ShpFileType.SHX;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.logging.Level;
+
+import org.geotools.data.DataSourceException;
+import org.geotools.data.DataUtilities;
+import org.geotools.data.EmptyFeatureReader;
+import org.geotools.data.FIDReader;
+import org.geotools.data.FeatureReader;
+import org.geotools.data.FeatureWriter;
+import org.geotools.data.InProcessLockingManager;
+import org.geotools.data.Query;
+import org.geotools.data.Transaction;
+import org.geotools.data.TransactionStateDiff;
+import org.geotools.data.shapefile.FileReader;
+import org.geotools.data.shapefile.ShapefileDataStore;
+import org.geotools.data.shapefile.ShapefileDataStoreFactory;
+import org.geotools.data.shapefile.ShpFileType;
+import org.geotools.data.shapefile.dbf.DbaseFileReader;
+import org.geotools.data.shapefile.dbf.IndexedDbaseFileReader;
+import org.geotools.data.shapefile.shp.IndexFile;
+import org.geotools.data.shapefile.shp.ShapefileException;
+import org.geotools.data.shapefile.shp.ShapefileReader;
+import org.geotools.data.shapefile.shp.ShapefileReader.Record;
+import org.geotools.factory.Hints;
+import org.geotools.feature.SchemaException;
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
+import org.geotools.feature.visitor.IdCollectorFilterVisitor;
+import org.geotools.filter.FilterAttributeExtractor;
+import org.geotools.filter.visitor.ExtractBoundsFilterVisitor;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.index.CachedQuadTree;
+import org.geotools.index.CloseableIterator;
+import org.geotools.index.Data;
+import org.geotools.index.DataDefinition;
+import org.geotools.index.TreeException;
+import org.geotools.index.quadtree.QuadTree;
+import org.geotools.index.quadtree.StoreException;
+import org.geotools.index.quadtree.fs.FileSystemIndexStore;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.filter.Filter;
+import org.opengis.filter.Id;
+import org.opengis.filter.identity.Identifier;
+
+import com.vividsolutions.jts.geom.CoordinateSequenceFactory;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.GeometryFactory;
+
+/**
+ * A DataStore implementation which allows reading and writing from Shapefiles.
+ * 
+ * @author Ian Schneider
+ * @author Tommaso Nolli
+ * @author jesse eichar
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/indexed/IndexedShapefileDataStore.java $
+ */
+public class IndexedShapefileDataStore extends ShapefileDataStore implements
+        FileReader {
+    private final static class IdentifierComparator implements Comparator<Identifier>
+    {
+        public int compare(Identifier o1, Identifier o2)
+        {
+            return o1.toString().compareTo(o2.toString());
+        }
+    }
+
+    IndexType treeType;
+
+    final boolean useIndex;
+    
+    final boolean createIndex;
+    
+    CachedQuadTree cachedTree;
+
+	int maxQixCacheSize = DEFAULT_MAX_QIX_CACHE_SIZE;
+	
+	static final int DEFAULT_MAX_QIX_CACHE_SIZE;
+	
+	static {
+		int max = -1;
+		try {
+			String smax = System.getProperty("org.geotools.shapefile.maxQixCacheSize");
+			if(smax != null) {
+				max = Integer.parseInt(smax);
+			}
+		} catch(Throwable t) {
+			LOGGER.log(Level.SEVERE, "Could not set the max qix cache size", t);
+		}
+		DEFAULT_MAX_QIX_CACHE_SIZE = max;
+	}
+    
+    public IndexedShapefileDataStore(URL url, URI namespace,
+            boolean useMemoryMappedBuffer, boolean cacheMemoryMaps, boolean createIndex,
+            IndexType treeType, Charset dbfCharset) {
+    	super(url, namespace, useMemoryMappedBuffer, cacheMemoryMaps, dbfCharset);
+
+        this.treeType = treeType;
+        this.useIndex = treeType != IndexType.NONE;
+        this.createIndex = createIndex;
+    }
+    
+    protected Filter getUnsupportedFilter(String typeName, Filter filter) {
+
+        if (filter instanceof Id && isLocal() && shpFiles.exists(FIX))
+            return Filter.INCLUDE;
+
+        return filter;
+    }
+
+    /**
+     * Creates a new instance of ShapefileDataStore.
+     * 
+     * @param url
+     *                The URL of the shp file to use for this DataSource.
+     * @param namespace
+     *                DOCUMENT ME!
+     * @param useMemoryMappedBuffer
+     *                enable/disable memory mapping of files
+     * @param cacheMemoryMaps
+     *                caches and reuses the read only memory mapped buffers                
+     * @param createIndex
+     *                enable/disable automatic index creation if needed
+     * @param treeType
+     *                The type of index used
+     * @param dbfCharset
+     *                {@link Charset} used to decode strings from the DBF
+     * 
+     * @throws NullPointerException
+     *                 DOCUMENT ME!
+     * @throws .
+     */
+    public FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriterAppend(String typeName,
+            Transaction transaction) throws IOException {
+        if (transaction == null) {
+            throw new NullPointerException(
+                    "getFeatureWriter requires Transaction: "
+                            + "did you mean to use Transaction.AUTO_COMMIT?");
+        }
+
+        FeatureWriter<SimpleFeatureType, SimpleFeature> writer;
+
+        if (transaction == Transaction.AUTO_COMMIT) {
+            return super.getFeatureWriterAppend(typeName, transaction);
+        } else {
+            writer = state(transaction).writer(typeName, Filter.EXCLUDE);
+        }
+
+        if (getLockingManager() != null) {
+            // subclass has not provided locking so we will
+            // fake it with InProcess locks
+            writer = ((InProcessLockingManager) getLockingManager())
+                    .checkedWriter(writer, transaction);
+        }
+
+        while (writer.hasNext())
+            writer.next();
+        return writer;
+    }
+
+    /**
+     * This method is identical to the super class WHY?
+     */
+    protected TransactionStateDiff state(Transaction transaction) {
+        synchronized (transaction) {
+            TransactionStateDiff state = (TransactionStateDiff) transaction
+                    .getState(this);
+
+            if (state == null) {
+                state = new TransactionStateDiff(this);
+                transaction.putState(this, state);
+            }
+
+            return state;
+        }
+    }
+
+    /**
+     * Use the spatial index if available and adds a small optimization: if no
+     * attributes are going to be read, don't uselessly open and read the dbf
+     * file.
+     * 
+     * @see org.geotools.data.AbstractDataStore#getFeatureReader(java.lang.String,
+     *      org.geotools.data.Query)
+     */
+    protected  FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String typeName, Query query)
+            throws IOException {
+        if (query.getFilter() == Filter.EXCLUDE)
+            return new EmptyFeatureReader<SimpleFeatureType, SimpleFeature>(getSchema());
+
+        String[] propertyNames = query.getPropertyNames() == null ? new String[0]
+                : query.getPropertyNames();
+        String defaultGeomName = schema.getGeometryDescriptor().getLocalName();
+
+
+        // add the attributes we need to read to keep the filtering going
+        if(propertyNames.length  > 0) {
+            FilterAttributeExtractor fae = new FilterAttributeExtractor(schema);
+            query.getFilter().accept(fae, null);
+    
+            Set<String> attributes = new LinkedHashSet<String>(Arrays.asList(propertyNames));
+            attributes.addAll(fae.getAttributeNameSet());
+    
+            propertyNames = attributes.toArray(new String[attributes
+                    .size()]);
+        }
+
+        // check what we actually have to read
+        SimpleFeatureType newSchema = schema;
+        boolean readDbf = true;
+        boolean readGeometry = true;
+        try {
+            if (((query.getPropertyNames() != Query.NO_NAMES)
+                    && (propertyNames.length == 1) && propertyNames[0]
+                    .equals(defaultGeomName))) {
+                readDbf = false;
+                newSchema = createSubType( propertyNames);
+            } else if ((query.getPropertyNames() == Query.NO_NAMES)
+                    && (propertyNames.length == 0)) {
+                readDbf = false;
+                readGeometry = false;
+                newSchema = createSubType( propertyNames);
+            } else if( propertyNames.length > 0 && !propertyNames[0].equals(defaultGeomName) ){
+                readGeometry = false;
+                newSchema = createSubType(propertyNames);
+            } else if(propertyNames.length > 0) {
+                newSchema = createSubType(propertyNames);
+            }
+
+            return createFeatureReader(typeName, getAttributesReader(readDbf,
+                    readGeometry, query, newSchema), newSchema);
+        } catch (SchemaException se) {
+            throw new DataSourceException("Error creating schema", se);
+        }
+    }
+    
+    /**
+     * Much like {@link DataUtilities#createSubType(SimpleFeatureType, String[])}, but makes
+     * sure to preserve the original attribute order
+     * @param properties
+     * @return
+     * @throws SchemaException
+     */
+    public SimpleFeatureType createSubType(String[] properties) throws SchemaException {
+        if (properties == null || properties.length == 0) {
+            return schema;
+        }
+
+        boolean same = schema.getAttributeCount() == properties.length;
+
+        for (int i = 0; (i < schema.getAttributeCount()) && same; i++) {
+            same = schema.getDescriptor(i).getLocalName().equals(properties[i]);
+        }
+
+        if (same) {
+            return schema;
+        }
+
+        SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
+        tb.setName( schema.getName() );
+        
+        Set<String> propIndex = new HashSet<String>(Arrays.asList(properties));
+        for(AttributeDescriptor ad : schema.getAttributeDescriptors()) {
+            if(propIndex.contains(ad.getLocalName()))
+                tb.add(ad);
+        }
+        return tb.buildFeatureType();
+    }
+
+    protected  FeatureReader<SimpleFeatureType, SimpleFeature> createFeatureReader(String typeName,
+            IndexedShapefileAttributeReader r, SimpleFeatureType readerSchema)
+            throws SchemaException, IOException {
+        
+        if(r == null) {
+            return new EmptyFeatureReader<SimpleFeatureType, SimpleFeature>(readerSchema);
+        }
+
+        FIDReader fidReader;
+        if (!indexUseable(FIX)) {
+            fidReader = new ShapeFIDReader(getCurrentTypeName(), r);
+        } else {
+            fidReader = new IndexedFidReader(shpFiles, r);
+        }
+        return new org.geotools.data.FIDFeatureReader(r, fidReader,
+                readerSchema);
+    }
+    
+    /**
+     * Returns the attribute reader, allowing for a pure shape reader, or a
+     * combined dbf/shp reader. Will return null if reading the indexes confirms there is nothing
+     * to read
+     * 
+     * @param readDbf -
+     *                if true, the dbf fill will be opened and read
+     * @param readGeometry
+     *                DOCUMENT ME!
+     * @param filter -
+     *                a Filter to use
+     * 
+     * 
+     * @throws IOException
+     */
+    protected IndexedShapefileAttributeReader getAttributesReader(
+            boolean readDbf, boolean readGeometry, Query query, SimpleFeatureType targetSchema)
+            throws IOException {
+        Envelope bbox = new ReferencedEnvelope(); // will be bbox.isNull() to
+        // start
+
+        Filter filter = query != null ? query.getFilter() : null;
+        CloseableIterator<Data> goodRecs = null;
+        if (filter instanceof Id && shpFiles.isLocal() && indexUseable(ShpFileType.FIX)) {
+            Id fidFilter = (Id) filter;
+
+            TreeSet idsSet = new TreeSet(new IdentifierComparator());
+            idsSet.addAll(fidFilter.getIdentifiers());
+            List<Data> records = queryFidIndex(idsSet);
+            if(records != null) {
+            	goodRecs = new CloseableIteratorWrapper<Data>(records.iterator());
+            }
+        } else {
+            if (filter != null) {
+                // Add additional bounds from the filter
+                // will be null for Filter.EXCLUDES
+                bbox = (Envelope) filter.accept(
+                        ExtractBoundsFilterVisitor.BOUNDS_VISITOR, bbox);
+                if (bbox == null) {
+                    bbox = new ReferencedEnvelope();
+                    // we hit Filter.EXCLUDES consider returning an empty
+                    // reader?
+                    // (however should simplify the filter to detect ff.not(
+                    // fitler.EXCLUDE )
+                }
+            }
+
+            if (!bbox.isNull() && this.useIndex) {
+                try {
+                    goodRecs = this.queryQuadTree(bbox);
+                } catch (TreeException e) {
+                    throw new IOException("Error querying index: "
+                            + e.getMessage());
+                }
+            }
+        }
+        List<AttributeDescriptor> atts = targetSchema.getAttributeDescriptors();
+
+        IndexedDbaseFileReader dbfR = null;
+        
+        // do we have anything to read at all? If not don't bother opening all the files
+        if(goodRecs != null && !goodRecs.hasNext()) {
+            // System.out.println("Empty results for " + targetSchema.getName().getLocalPart() + ", skipping read");
+            goodRecs.close();
+            return null;
+        }
+
+        if (!readDbf) {
+            LOGGER.fine("The DBF file won't be opened since no attributes "
+                    + "will be read from it");
+            atts = new ArrayList<AttributeDescriptor>(1);
+            atts.add(schema.getGeometryDescriptor());
+
+            if (!readGeometry) {
+                atts = new ArrayList<AttributeDescriptor>(1);
+            }
+        } else {
+            dbfR = (IndexedDbaseFileReader) openDbfReader();
+        }
+
+        Hints hints = query != null ? query.getHints() : null;
+        final ShapefileReader shapeReader = openShapeReader(getGeometryFactory(hints), goodRecs != null);
+        IndexedShapefileAttributeReader reader =  new IndexedShapefileAttributeReader(atts, 
+                shapeReader, dbfR, goodRecs);
+        reader.setTargetBBox(bbox);
+        if(hints != null) {
+            Number simplificationDistance = (Number) hints.get(Hints.GEOMETRY_DISTANCE);    
+            if(simplificationDistance != null) {
+                reader.setSimplificationDistance(simplificationDistance.doubleValue());
+            }
+            
+            if(Boolean.TRUE.equals(hints.get(Hints.FEATURE_2D))) {
+                shapeReader.setFlatGeometry(true);
+            }
+        }
+        
+        return reader;
+    }
+    
+    /**
+     * Convenience method for opening a ShapefileReader.
+     * 
+     * @return A new ShapefileReader.
+     * 
+     * @throws IOException
+     *                 If an error occurs during creation.
+     */
+    protected ShapefileReader openShapeReader(GeometryFactory gf, boolean onlyRandomAccess) throws IOException {
+        try {
+            return new ShapefileReader(shpFiles, true, useMemoryMappedBuffer, gf, onlyRandomAccess);
+        } catch (ShapefileException se) {
+            throw new DataSourceException("Error creating ShapefileReader", se);
+        }
+    }
+
+    /**
+     * Uses the Fid index to quickly lookup the shp offset and the record number
+     * for the list of fids
+     * 
+     * @param fids
+     *                the fids of the features to find.  If the set is sorted by alphabet the performance is likely to be better.
+     * @return a list of Data objects
+     * @throws IOException
+     * @throws TreeException
+     */
+    private List<Data> queryFidIndex(Set<Identifier> idsSet) throws IOException {
+
+        if (!indexUseable(FIX)) {
+            return null;
+        }
+
+        IndexedFidReader reader = new IndexedFidReader(shpFiles);
+
+        List<Data> records = new ArrayList(idsSet.size());
+        try {
+            IndexFile shx = openIndexFile();
+            try {
+
+                DataDefinition def = new DataDefinition("US-ASCII");
+                def.addField(Integer.class);
+                def.addField(Long.class);
+                for (Identifier identifier : idsSet) {
+                    String fid = identifier.toString();
+                    long recno = reader.findFid(fid);
+                    if (recno == -1){
+                        if(LOGGER.isLoggable(Level.FINEST)){
+                            LOGGER.finest("fid " + fid+ " not found in index, continuing with next queried fid...");
+                        }
+                        continue;
+                    }
+                    try {
+                        Data data = new Data(def);
+                        data.addValue(new Integer((int) recno + 1));
+                        data.addValue(new Long(shx
+                                .getOffsetInBytes((int) recno)));
+                        if(LOGGER.isLoggable(Level.FINEST)){
+                            LOGGER.finest("fid " + fid+ " found for record #"
+                                    + data.getValue(0) + " at index file offset "
+                                    + data.getValue(1));
+                        }
+                        records.add(data);
+                    } catch (Exception e) {
+                        IOException exception = new IOException();
+                        exception.initCause(e);
+                        throw exception;
+                    }
+                }
+            } finally {
+                shx.close();
+            }
+        } finally {
+            reader.close();
+        }
+
+        return records;
+    }
+
+    /**
+     * Returns true if the index for the given type exists and is useable.
+     * 
+     * @param indexType
+     *                the type of index to check
+     * 
+     * @return true if the index for the given type exists and is useable.
+     */
+    public boolean indexUseable(ShpFileType indexType) {
+        if (isLocal()) {
+            if (needsGeneration(indexType) || !shpFiles.exists(indexType)) {
+                return false;
+            }
+        } else {
+
+            ReadableByteChannel read = null;
+            try {
+                read = shpFiles.getReadChannel(indexType, this);
+            } catch (IOException e) {
+                return false;
+            } finally {
+                if (read != null) {
+                    try {
+                        read.close();
+                    } catch (IOException e) {
+                        ShapefileDataStoreFactory.LOGGER.log(Level.WARNING,
+                                "could not close stream", e);
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+
+    boolean needsGeneration(ShpFileType indexType) {
+        // happens if the IndexType.NONE.shpFileType is used)
+        if(indexType == null)
+            return false;
+        
+        if (!isLocal())
+            throw new IllegalStateException(
+                    "This method only applies if the files are local and the file can be created");
+
+        URL indexURL = shpFiles.acquireRead(indexType, this);
+        URL shpURL = shpFiles.acquireRead(SHP, this);
+        try {
+
+            if (indexURL == null) {
+                return true;
+            }
+            // indexes require both the SHP and SHX so if either or missing then
+            // you don't need to
+            // index
+            if (!shpFiles.exists(SHX) || !shpFiles.exists(SHP)) {
+                return false;
+            }
+
+            File indexFile = DataUtilities.urlToFile(indexURL);
+            File shpFile = DataUtilities.urlToFile(shpURL);
+            long indexLastModified = indexFile.lastModified();
+            long shpLastModified = shpFile.lastModified();
+            boolean shpChangedMoreRecently = indexLastModified < shpLastModified;
+            return !indexFile.exists() || shpChangedMoreRecently;
+        } finally {
+            if (shpURL != null) {
+                shpFiles.unlockRead(shpURL, this);
+            }
+            if (indexURL != null) {
+                shpFiles.unlockRead(indexURL, this);
+            }
+        }
+    }
+
+    // /**
+    // * RTree query
+    // *
+    // * @param bbox
+    // *
+    // *
+    // * @throws DataSourceException
+    // * @throws IOException
+    // */
+    // private List queryRTree(Envelope bbox) throws DataSourceException,
+    // IOException {
+    // List goodRecs = null;
+    // RTree rtree = this.openRTree();
+    //
+    // try {
+    // if ((rtree != null) && (rtree.getBounds() != null)
+    // && !bbox.contains(rtree.getBounds())) {
+    // goodRecs = rtree.search(bbox);
+    // }
+    // } catch (LockTimeoutException le) {
+    // throw new DataSourceException("Error querying RTree", le);
+    // } catch (TreeException re) {
+    // throw new DataSourceException("Error querying RTree", re);
+    // }
+    //
+    // return goodRecs;
+    // }
+
+    /**
+     * QuadTree Query
+     * 
+     * @param bbox
+     * 
+     * 
+     * @throws DataSourceException
+     * @throws IOException
+     * @throws TreeException
+     *                 DOCUMENT ME!
+     */
+    protected CloseableIterator<Data> queryQuadTree(Envelope bbox)
+            throws DataSourceException, IOException, TreeException {
+        CloseableIterator<Data> tmp = null;
+        
+        if(cachedTree == null) {
+            boolean canCache = false;
+            URL treeURL = shpFiles.acquireRead(QIX, this);
+            try {
+                File treeFile = DataUtilities.urlToFile(treeURL);
+
+                if (treeFile.exists() && treeFile.length() < 1024 * maxQixCacheSize) {
+                    canCache = true;
+                }
+            } finally {
+                shpFiles.unlockRead(treeURL, this);
+            }
+
+            if(canCache) {
+                QuadTree quadTree = openQuadTree();
+                if(quadTree != null) {
+                    LOGGER.warning("Experimental: loading in memory the quadtree for " + shpFiles.get(SHP));
+                    cachedTree = new CachedQuadTree(quadTree);
+                    quadTree.close();
+                }
+            }
+        }
+        if(cachedTree != null) {
+            if(!bbox.contains(cachedTree.getBounds())) {
+                return cachedTree.search(bbox);
+            } else {
+                return null;
+            }
+        } else {
+            try {
+                QuadTree quadTree = openQuadTree();
+                if ((quadTree != null)
+                        && !bbox.contains(quadTree.getRoot().getBounds())) {
+                    tmp = quadTree.search(bbox);
+                }
+                if (tmp == null && quadTree != null) {
+                    quadTree.close();
+                }
+            } catch (Exception e) {
+                throw new DataSourceException("Error querying QuadTree", e);
+            }
+        }
+
+        return tmp;
+    }
+
+    /**
+     * Convenience method for opening a DbaseFileReader.
+     * 
+     * @return A new DbaseFileReader
+     * 
+     * @throws IOException
+     *                 If an error occurs during creation.
+     */
+    protected DbaseFileReader openDbfReader() throws IOException {
+        if (shpFiles.get(DBF) == null) {
+            return null;
+        }
+
+        if (isLocal() && !shpFiles.exists(DBF)) {
+            return null;
+        }
+
+        return new IndexedDbaseFileReader(shpFiles, useMemoryMappedBuffer, dbfCharset, dbfTimeZone);
+    }
+
+    //
+    // /**
+    // * Convenience method for opening an RTree index.
+    // *
+    // * @return A new RTree.
+    // *
+    // * @throws IOException
+    // * If an error occurs during creation.
+    // * @throws DataSourceException
+    // * DOCUMENT ME!
+    // */
+    // protected RTree openRTree() throws IOException {
+    // if (!isLocal()) {
+    // return null;
+    // }
+    // URL treeURL = shpFiles.acquireRead(GRX, this);
+    // try {
+    // File treeFile = DataUtilities.urlToFile(treeURL);
+    //
+    // if (!treeFile.exists() || (treeFile.length() == 0)) {
+    // treeType = IndexType.NONE;
+    // return null;
+    // }
+    //
+    // try {
+    // FileSystemPageStore fps = new FileSystemPageStore(treeFile);
+    // rtree = new RTree(fps);
+    // } catch (TreeException re) {
+    // throw new DataSourceException("Error opening RTree", re);
+    // }
+    //
+    // return rtree;
+    // } finally {
+    // shpFiles.unlockRead(treeURL, this);
+    // }
+    // }
+
+    /**
+     * Convenience method for opening a QuadTree index.
+     * 
+     * @return A new QuadTree
+     * 
+     * @throws StoreException
+     */
+    protected QuadTree openQuadTree() throws StoreException {
+        if (!isLocal()) {
+            return null;
+        }
+        URL treeURL = shpFiles.acquireRead(QIX, this);
+        try {
+            File treeFile = DataUtilities.urlToFile(treeURL);
+
+            if (!treeFile.exists() || (treeFile.length() == 0)) {
+                treeType = IndexType.NONE;
+                return null;
+            }
+
+            try {
+                FileSystemIndexStore store = new FileSystemIndexStore(treeFile);
+                return store.load(openIndexFile(), useMemoryMappedBuffer);
+            } catch (IOException e) {
+                throw new StoreException(e);
+            }
+        } finally {
+            shpFiles.unlockRead(treeURL, this);
+        }
+
+    }
+
+    /**
+     * Create a FeatureWriter for the given type name.
+     * 
+     * @param typeName
+     *                The typeName of the FeatureType to write
+     * @param transaction
+     *                DOCUMENT ME!
+     * 
+     * @return A new FeatureWriter.
+     * 
+     * @throws IOException
+     *                 If the typeName is not available or some other error
+     *                 occurs.
+     */
+    protected FeatureWriter<SimpleFeatureType, SimpleFeature> createFeatureWriter(String typeName,
+            Transaction transaction) throws IOException {
+        return null;
+    }
+
+    /**
+     * @see org.geotools.data.AbstractDataStore#getBounds(org.geotools.data.Query)
+     */
+    protected ReferencedEnvelope getBounds(Query query) throws IOException {
+        ReferencedEnvelope ret = null;
+
+        Set records = new HashSet();
+        Filter filter = query.getFilter();
+        if (filter == Filter.INCLUDE || query == Query.ALL) {
+            return getBounds();
+        }
+        // else if (this.useIndex) {
+        // if (treeType == IndexType.GRX) {
+        // return getBoundsRTree(query);
+        // }
+        // }
+
+        Comparator<Identifier> identifierComparator = new IdentifierComparator();
+        Set<Identifier> fids = (Set<Identifier>) filter.accept(
+                IdCollectorFilterVisitor.IDENTIFIER_COLLECTOR, new TreeSet<Identifier>(identifierComparator));
+
+        if (!fids.isEmpty()) {
+            List<Data> recordsFound = queryFidIndex(fids);
+            if (recordsFound != null) {
+                records.addAll(recordsFound);
+            }
+        }
+
+        if (records.isEmpty())
+            return null;
+        
+        // grab a geometry factory... check for a special hint
+        Hints hints = query.getHints(); 
+        GeometryFactory geometryFactory = (GeometryFactory) hints.get(Hints.JTS_GEOMETRY_FACTORY);
+        if (geometryFactory == null) {
+            // look for a coordinate sequence factory
+            CoordinateSequenceFactory csFactory = 
+                (CoordinateSequenceFactory) hints.get(Hints.JTS_COORDINATE_SEQUENCE_FACTORY);
+
+            if (csFactory != null) {
+                geometryFactory = new GeometryFactory(csFactory);
+            }
+        }
+
+        if (geometryFactory == null) {
+            // fall back on the default one
+            geometryFactory = new GeometryFactory();
+        }
+
+        ShapefileReader reader = new ShapefileReader(shpFiles, false, false, geometryFactory);
+        try {
+            ret = new ReferencedEnvelope(getSchema().getCoordinateReferenceSystem());
+            for (Iterator iter = records.iterator(); iter.hasNext();) {
+                Data data = (Data) iter.next();
+                reader.goTo(((Long) data.getValue(1)).intValue());
+                Record record = reader.nextRecord();
+                ret.expandToInclude(new Envelope(record.minX, record.maxX,
+                        record.minY, record.maxY));
+            }
+            return ret;
+        } finally {
+            reader.close();
+        }
+    }
+
+    public String id() {
+        return getClass().getName() + ": " + getCurrentTypeName();
+    }
+ 
+    @Override
+    protected Set getSupportedHints() {
+        Set<Hints.Key> hints = new HashSet<Hints.Key>();
+        hints.add( Hints.FEATURE_DETACHED );
+        hints.add( Hints.JTS_GEOMETRY_FACTORY );
+        hints.add( Hints.JTS_COORDINATE_SEQUENCE_FACTORY );
+        hints.add( Hints.GEOMETRY_DISTANCE);
+        return hints;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/RecordNumberTracker.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/RecordNumberTracker.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/RecordNumberTracker.java	(revision 28000)
@@ -0,0 +1,35 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.indexed;
+
+import java.io.IOException;
+
+/**
+ * A simple interface so that the current feature's record number can be
+ * retrieved by the IndexedFidReader
+ * 
+ * @author Jesse
+ * @since 1.1.0
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/indexed/RecordNumberTracker.java $
+ */
+public interface RecordNumberTracker {
+    public int getRecordNumber();
+
+    public void close() throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/ShapeFIDReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/ShapeFIDReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/indexed/ShapeFIDReader.java	(revision 28000)
@@ -0,0 +1,102 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ * 
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.indexed;
+
+import java.io.IOException;
+
+import org.geotools.data.FIDReader;
+import org.geotools.data.shapefile.ShapefileAttributeReader;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+/**
+ * Reader that returns FeatureIds in a quick fashion.
+ * 
+ * @author Tommaso Nolli
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/indexed/ShapeFIDReader.java $
+ */
+public class ShapeFIDReader implements FIDReader {
+    protected static final String CLOSE_MESG = "Close has already been called"
+            + " on this FIDReader";
+    private boolean opened;
+    private ShapefileAttributeReader reader;
+    private int len;
+    protected StringBuffer buffer;
+
+    public ShapeFIDReader(String typeName,
+            ShapefileAttributeReader reader) {
+        buffer = new StringBuffer(typeName);
+        buffer.append('.');
+        len = typeName.length() + 1;
+        this.opened = true;
+        this.reader = reader;
+    }
+
+    public ShapeFIDReader(SimpleFeatureType featureType,
+            ShapefileAttributeReader reader) {
+        this(featureType.getTypeName(), reader);
+    }
+
+    /**
+     * Release any resources associated with this reader
+     */
+    public void close() {
+        this.opened = false;
+    }
+
+    /**
+     * This method always returns true, since it is built with a
+     * <code>ShapefileDataStore.Reader</code> you have to call
+     * <code>ShapefileDataStore.Reader.hasNext()</code>
+     * 
+     * @return always return <code>true</code>
+     * 
+     * @throws IOException
+     *                 If closed
+     */
+    public boolean hasNext() throws IOException {
+        if (!this.opened) {
+            throw new IOException(CLOSE_MESG);
+        }
+
+        /*
+         * In DefaultFIDReader this is always called after
+         * atttributesReader.hasNext so, as we use the same attributeReader,
+         * we'll return true
+         */
+        return true;
+    }
+
+    /**
+     * Read the feature id.
+     * 
+     * @return the Feature Id
+     * 
+     * @throws IOException
+     *                 If closed
+     */
+    public String next() throws IOException {
+        if (!this.opened) {
+            throw new IOException(CLOSE_MESG);
+        }
+
+        buffer.delete(len, buffer.length());
+        buffer.append(reader.getRecordNumber());
+
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/prj/PrjFileReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/prj/PrjFileReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/prj/PrjFileReader.java	(revision 28000)
@@ -0,0 +1,143 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.prj;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+
+import org.geotools.data.shapefile.FileReader;
+import org.geotools.data.shapefile.ShpFileType;
+import org.geotools.data.shapefile.ShpFiles;
+import org.geotools.data.shapefile.StreamLogging;
+import org.geotools.referencing.ReferencingFactoryFinder;
+import org.geotools.resources.NIOUtilities;
+import org.opengis.referencing.FactoryException;
+
+/**
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/prj/PrjFileReader.java $
+ */
+public class PrjFileReader implements FileReader {
+
+    ByteBuffer buffer;
+    ReadableByteChannel channel;
+    CharBuffer charBuffer;
+    CharsetDecoder decoder;
+    StreamLogging streamLogger = new StreamLogging("PRJ reader");
+
+    org.opengis.referencing.crs.CoordinateReferenceSystem cs;
+    private boolean memoryMapped=true;
+
+    // private int[] content;
+
+    /**
+     * Load the index file from the given channel.
+     * 
+     * @param shpFiles
+     *                The channel to read from.
+     * @throws IOException
+     *                 If an error occurs.
+     */
+    public PrjFileReader(ShpFiles shpFiles) throws IOException {
+        Charset chars = Charset.forName("ISO-8859-1");
+        decoder = chars.newDecoder();
+        this.channel = shpFiles.getReadChannel(ShpFileType.PRJ, this);
+        streamLogger.open();
+        init();
+
+        // ok, everything is ready...
+        decoder.decode(buffer, charBuffer, true);
+        buffer.limit(buffer.capacity());
+        charBuffer.flip();
+
+        String wkt = charBuffer.toString();
+
+        try {
+            cs = ReferencingFactoryFinder.getCRSFactory(null)
+                    .createFromWKT(wkt);
+        } catch (FactoryException e) {
+            cs = null;
+        }
+    }
+
+    public org.opengis.referencing.crs.CoordinateReferenceSystem getCoodinateSystem() {
+        return cs;
+    }
+
+    private int fill(ByteBuffer buffer, ReadableByteChannel channel)
+            throws IOException {
+        int r = buffer.remaining();
+        // channel reads return -1 when EOF or other error
+        // because they a non-blocking reads, 0 is a valid return value!!
+        while (buffer.remaining() > 0 && r != -1) {
+            r = channel.read(buffer);
+        }
+        if (r == -1) {
+            buffer.limit(buffer.position());
+        }
+        return r;
+    }
+
+    private void init() throws IOException {
+        // create the ByteBuffer
+        // if we have a FileChannel, lets map it
+        if (channel instanceof FileChannel) {
+            FileChannel fc = (FileChannel) channel;
+            buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
+            buffer.position((int) fc.position());
+            memoryMapped = true;
+        } else {
+            // Some other type of channel
+            // start with a 8K buffer, should be more than adequate
+            int size = 8 * 1024;
+            // if for some reason its not, resize it
+            // size = header.getRecordLength() > size ? header.getRecordLength()
+            // : size;
+            buffer = NIOUtilities.allocate(size);
+            // fill it and reset
+            fill(buffer, channel);
+            buffer.flip();
+        }
+
+        // The entire file is in little endian
+        buffer.order(ByteOrder.LITTLE_ENDIAN);
+
+        charBuffer = CharBuffer.allocate(8 * 1024);
+        Charset chars = Charset.forName("ISO-8859-1");
+        decoder = chars.newDecoder();
+
+    }
+
+    public void close() throws IOException {
+        if (buffer != null) {
+            NIOUtilities.clean(buffer, memoryMapped);
+            buffer = null;
+        }
+
+        if (channel.isOpen()) {
+            channel.close();
+            streamLogger.close();
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/IndexFile.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/IndexFile.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/IndexFile.java	(revision 28000)
@@ -0,0 +1,242 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.util.logging.Logger;
+
+import org.geotools.data.shapefile.FileReader;
+import org.geotools.data.shapefile.ShpFileType;
+import org.geotools.data.shapefile.ShpFiles;
+import org.geotools.data.shapefile.StreamLogging;
+import org.geotools.resources.NIOUtilities;
+
+/**
+ * IndexFile parser for .shx files.<br>
+ * For now, the creation of index files is done in the ShapefileWriter. But this
+ * can be used to access the index.<br>
+ * For details on the index file, see <br>
+ * <a href="http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf"><b>"ESRI(r)
+ * Shapefile - A Technical Description"</b><br> * <i>'An ESRI White Paper .
+ * May 1997'</i></a>
+ * 
+ * @author Ian Schneider
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/IndexFile.java $
+ */
+public class IndexFile implements FileReader {
+    private static final Logger LOGGER = org.geotools.util.logging.Logging
+            .getLogger("org.geotools.data.shapefile");
+
+    private static final int RECS_IN_BUFFER = 2000;
+
+    private boolean useMemoryMappedBuffer;
+    private FileChannel channel;
+    private int channelOffset;
+    private ByteBuffer buf = null;
+    private int lastIndex = -1;
+    private int recOffset;
+    private ShapefileHeader header = null;
+    private int[] content;
+    private StreamLogging streamLogger = new StreamLogging("IndexFile");
+
+    private volatile boolean closed = false;
+
+    /**
+     * Load the index file from the given channel.
+     * 
+     * @param shpFiles
+     *                The channel to read from.
+     * @throws IOException
+     *                 If an error occurs.
+     */
+    public IndexFile(ShpFiles shpFiles, boolean useMemoryMappedBuffer)
+            throws IOException {
+        this.useMemoryMappedBuffer = useMemoryMappedBuffer;
+        streamLogger.open();
+        ReadableByteChannel byteChannel = shpFiles.getReadChannel(
+                ShpFileType.SHX, this);
+        try {
+            if (byteChannel instanceof FileChannel) {
+
+                this.channel = (FileChannel) byteChannel;
+                if (useMemoryMappedBuffer) {
+                    LOGGER.finest("Memory mapping file...");
+                    this.buf = this.channel.map(FileChannel.MapMode.READ_ONLY,
+                            0, this.channel.size());
+
+                    this.channelOffset = 0;
+                } else {
+                    LOGGER.finest("Reading from file...");
+                    this.buf = NIOUtilities.allocate(8 * RECS_IN_BUFFER);
+                    channel.read(buf);
+                    buf.flip();
+                    this.channelOffset = 0;
+                }
+                
+                header = new ShapefileHeader();
+                header.read(buf, true);
+            } else {
+                LOGGER.finest("Loading all shx...");
+                readHeader(byteChannel);
+                readRecords(byteChannel);
+                byteChannel.close();
+            }
+        } catch (Throwable e) {
+            if (byteChannel != null) {
+                byteChannel.close();
+            }
+            throw (IOException) new IOException(e.getLocalizedMessage())
+                    .initCause(e);
+        }
+    }
+
+    private void check() {
+        if (closed) {
+            throw new IllegalStateException("Index file has been closed");
+        }
+
+    }
+
+    private void readHeader(ReadableByteChannel channel) throws IOException {
+        ByteBuffer buffer = NIOUtilities.allocate(100);
+        try {
+            while (buffer.remaining() > 0) {
+                channel.read(buffer);
+            }
+            buffer.flip();
+            header = new ShapefileHeader();
+            header.read(buffer, true);
+        } finally {
+            NIOUtilities.clean(buffer, false);
+        }
+    }
+
+    private void readRecords(ReadableByteChannel channel) throws IOException {
+        check();
+        int remaining = (header.getFileLength() * 2) - 100;
+        ByteBuffer buffer = NIOUtilities.allocate(remaining);
+        try {
+            buffer.order(ByteOrder.BIG_ENDIAN);
+            while (buffer.remaining() > 0) {
+                channel.read(buffer);
+            }
+            buffer.flip();
+            int records = remaining / 4;
+            content = new int[records];
+            IntBuffer ints = buffer.asIntBuffer();
+            ints.get(content);
+        } finally {
+            NIOUtilities.clean(buffer, false);
+        }
+    }
+
+    private void readRecord(int index) throws IOException {
+        check();
+        int pos = 100 + index * 8;
+        if (this.useMemoryMappedBuffer) {
+
+        } else {
+            if (pos - this.channelOffset < 0
+                    || this.channelOffset + buf.limit() <= pos
+                    || this.lastIndex == -1) {
+                LOGGER.finest("Filling buffer...");
+                this.channelOffset = pos;
+                this.channel.position(pos);
+                buf.clear();
+                this.channel.read(buf);
+                buf.flip();
+            }
+        }
+
+        buf.position(pos - this.channelOffset);
+        this.recOffset = buf.getInt();
+        /*this.recLen =*/ buf.getInt();
+        this.lastIndex = index;
+    }
+
+    public void close() throws IOException {
+        closed = true;
+        if (channel != null && channel.isOpen()) {
+            channel.close();
+            streamLogger.close();
+
+            NIOUtilities.clean(buf, useMemoryMappedBuffer);
+        }
+        this.buf = null;
+        this.content = null;
+        this.channel = null;
+    }
+
+    /**
+     * @see java.lang.Object#finalize()
+     */
+    protected void finalize() throws Throwable {
+        this.close();
+        super.finalize();
+    }
+
+    /**
+     * Get the number of records in this index.
+     * 
+     * @return The number of records.
+     */
+    public int getRecordCount() {
+        return (header.getFileLength() * 2 - 100) / 8;
+    }
+
+    /**
+     * Get the offset of the record (in 16-bit words).
+     * 
+     * @param index
+     *                The index, from 0 to getRecordCount - 1
+     * @return The offset in 16-bit words.
+     * @throws IOException
+     */
+    public int getOffset(int index) throws IOException {
+        int ret = -1;
+
+        if (this.channel != null) {
+            if (this.lastIndex != index) {
+                this.readRecord(index);
+            }
+
+            ret = this.recOffset;
+        } else {
+            ret = content[2 * index];
+        }
+
+        return ret;
+    }
+
+    /**
+     * Get the offset of the record (in real bytes, not 16-bit words).
+     * 
+     * @param index
+     *                The index, from 0 to getRecordCount - 1
+     * @return The offset in bytes.
+     * @throws IOException
+     */
+    public int getOffsetInBytes(int index) throws IOException {
+        return this.getOffset(index) * 2;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/JTSUtilities.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/JTSUtilities.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/JTSUtilities.java	(revision 28000)
@@ -0,0 +1,56 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.MultiLineString;
+import com.vividsolutions.jts.geom.MultiPoint;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Point;
+
+/**
+ * A collection of utility methods for use with JTS and the shapefile package.
+ * 
+ * @author aaime
+ * @author Ian Schneider
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/JTSUtilities.java $
+ */
+public class JTSUtilities {
+
+    private JTSUtilities() {
+    }
+
+    public static final Class findBestGeometryClass(ShapeType type) {
+        Class best;
+        if (type == null || type == ShapeType.NULL) {
+            best = Geometry.class;
+        } else if (type.isLineType()) {
+            best = MultiLineString.class;
+        } else if (type.isMultiPointType()) {
+            best = MultiPoint.class;
+        } else if (type.isPointType()) {
+            best = Point.class;
+        } else if (type.isPolygonType()) {
+            best = MultiPolygon.class;
+        } else {
+            throw new RuntimeException("Unknown ShapeType->GeometryClass : "
+                    + type);
+        }
+        return best;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/MultiLineHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/MultiLineHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/MultiLineHandler.java	(revision 28000)
@@ -0,0 +1,230 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp;
+
+import java.nio.ByteBuffer;
+import java.nio.DoubleBuffer;
+
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+
+/*
+ * $Id: MultiLineHandler.java 37305 2011-05-25 05:57:57Z mbedward $ @author
+ * aaime @author Ian Schneider
+ */
+/**
+ * The default JTS handler for shapefile. Currently uses the default JTS
+ * GeometryFactory, since it doesn't seem to matter.
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/MultiLineHandler.java $
+ */
+public class MultiLineHandler implements ShapeHandler {
+    final ShapeType shapeType;
+
+    GeometryFactory geometryFactory;
+
+    /**
+     * Create a MultiLineHandler for one of: <br>
+     * ShapeType.ARC,ShapeType.ARCM,ShapeType.ARCZ
+     * 
+     * @param type
+     *                The ShapeType to use.
+     * @throws ShapefileException
+     *                 If the ShapeType is not correct (see constructor).
+     */
+    public MultiLineHandler(ShapeType type, GeometryFactory gf) throws ShapefileException {
+        if ((type != ShapeType.ARC) && (type != ShapeType.ARCM)
+                && (type != ShapeType.ARCZ)) {
+            throw new ShapefileException(
+                    "MultiLineHandler constructor - expected type to be 3,13 or 23");
+        }
+
+        shapeType = type;
+        this.geometryFactory = gf;
+    }
+    
+    private Object createNull() {
+        return geometryFactory.createMultiLineString((LineString[]) null);
+    }
+
+    public Object read(ByteBuffer buffer, ShapeType type, boolean flatGeometry) {
+        if (type == ShapeType.NULL) {
+            return createNull();
+        }
+        int dimensions = (shapeType == ShapeType.ARCZ && !flatGeometry) ? 3 : 2;
+        // read bounding box (not needed)
+        buffer.position(buffer.position() + 4 * 8);
+
+        int numParts = buffer.getInt();
+        int numPoints = buffer.getInt(); // total number of points
+
+        int[] partOffsets = new int[numParts];
+
+        // points = new Coordinate[numPoints];
+        for (int i = 0; i < numParts; i++) {
+            partOffsets[i] = buffer.getInt();
+        }
+        // read the first two coordinates and start building the coordinate
+        // sequences
+        CoordinateSequence[] lines = new CoordinateSequence[numParts];
+        int finish, start = 0;
+        int length = 0;
+        boolean clonePoint = false;
+        final DoubleBuffer doubleBuffer = buffer.asDoubleBuffer();
+        for (int part = 0; part < numParts; part++) {
+            start = partOffsets[part];
+
+            if (part == (numParts - 1)) {
+                finish = numPoints;
+            } else {
+                finish = partOffsets[part + 1];
+            }
+
+            length = finish - start;
+            if (length == 1) {
+                length = 2;
+                clonePoint = true;
+            } else {
+                clonePoint = false;
+            }
+
+            CoordinateSequence cs = geometryFactory.getCoordinateSequenceFactory().create(length, dimensions);
+            double[] xy = new double[length * 2];
+            doubleBuffer.get(xy);
+            for (int i = 0; i < length; i++) {
+                cs.setOrdinate(i, 0, xy[i * 2]);
+                cs.setOrdinate(i, 1, xy[i * 2 + 1]);
+            }
+
+            if (clonePoint) {
+                cs.setOrdinate(1, 0, cs.getOrdinate(0, 0));
+                cs.setOrdinate(1, 1, cs.getOrdinate(0, 1));
+            }
+
+            lines[part] = cs;
+        }
+
+        // if we have another coordinate, read and add to the coordinate
+        // sequences
+        if (dimensions == 3) {
+            // z min, max
+            // buffer.position(buffer.position() + 2 * 8);
+            doubleBuffer.position(doubleBuffer.position() + 2);
+            for (int part = 0; part < numParts; part++) {
+                start = partOffsets[part];
+
+                if (part == (numParts - 1)) {
+                    finish = numPoints;
+                } else {
+                    finish = partOffsets[part + 1];
+                }
+
+                length = finish - start;
+                if (length == 1) {
+                    length = 2;
+                    clonePoint = true;
+                } else {
+                    clonePoint = false;
+                }
+
+                double[] z = new double[length];
+                doubleBuffer.get(z);
+                for (int i = 0; i < length; i++) {
+                    lines[part].setOrdinate(i, 2, z[i]);
+                }
+
+            }
+        }
+
+        // Prepare line strings and return the multilinestring
+        LineString[] lineStrings = new LineString[numParts];
+        for (int part = 0; part < numParts; part++) {
+            lineStrings[part] = geometryFactory.createLineString(lines[part]);
+        }
+
+        return geometryFactory.createMultiLineString(lineStrings);
+    }
+}
+
+/*
+ * $Log: MultiLineHandler.java,v $ Revision 1.4 2003/11/13 22:10:35 jmacgill
+ * cast a null to avoid ambigous call with JTS1.4
+ * 
+ * Revision 1.3 2003/07/23 23:41:09 ianschneider more testing updates
+ * 
+ * Revision 1.2 2003/07/23 00:59:59 ianschneider Lots of PMD fix ups
+ * 
+ * Revision 1.1 2003/05/14 17:51:20 ianschneider migrated packages
+ * 
+ * Revision 1.3 2003/04/30 23:19:45 ianschneider Added construction of multi
+ * geometries for default return values, even if only one geometry. This could
+ * have effects through system.
+ * 
+ * Revision 1.2 2003/03/30 20:21:09 ianschneider Moved buffer branch to main
+ * 
+ * Revision 1.1.2.3 2003/03/12 15:30:14 ianschneider made ShapeType final for
+ * handlers - once they're created, it won't change.
+ * 
+ * Revision 1.1.2.2 2003/03/07 00:36:41 ianschneider
+ * 
+ * Added back the additional ShapeType parameter in ShapeHandler.read.
+ * ShapeHandler's need return their own special "null" shape if needed. Fixed
+ * the ShapefileReader to not throw exceptions for "null" shapes. Fixed
+ * ShapefileReader to accomodate junk after the last valid record. The theory
+ * goes, if the shape number is proper, that is, one greater than the previous,
+ * we consider that a valid record and attempt to read it. I suppose, by chance,
+ * the junk could coincide with the next record number. Stupid ESRI. Fixed some
+ * record-length calculations which resulted in writing of bad shapefiles.
+ * 
+ * Revision 1.1.2.1 2003/03/06 01:16:34 ianschneider
+ * 
+ * The initial changes for moving to java.nio. Added some documentation and
+ * improved exception handling. Works for reading, may work for writing as of
+ * now.
+ * 
+ * Revision 1.1 2003/02/27 22:35:50 aaime New shapefile module, initial commit
+ * 
+ * Revision 1.2 2003/01/22 18:31:05 jaquino Enh: Make About Box configurable
+ * 
+ * Revision 1.3 2002/10/30 22:36:11 dblasby Line reader now returns
+ * LINESTRING(..) if there is only one part to the arc polyline.
+ * 
+ * Revision 1.2 2002/09/09 20:46:22 dblasby Removed LEDatastream refs and
+ * replaced with EndianData[in/out]putstream
+ * 
+ * Revision 1.1 2002/08/27 21:04:58 dblasby orginal
+ * 
+ * Revision 1.2 2002/03/05 10:23:59 jmacgill made sure geometries were created
+ * using the factory methods
+ * 
+ * Revision 1.1 2002/02/28 00:38:50 jmacgill Renamed files to more intuitve
+ * names
+ * 
+ * Revision 1.3 2002/02/13 00:23:53 jmacgill First semi working JTS version of
+ * Shapefile code
+ * 
+ * Revision 1.2 2002/02/11 18:42:45 jmacgill changed read and write statements
+ * so that they produce and take Geometry objects instead of specific MultiLine
+ * objects changed parts[] array name to partOffsets[] for clarity and
+ * consistency with ShapePolygon
+ * 
+ * Revision 1.1 2002/02/11 16:54:43 jmacgill added shapefile code and
+ * directories
+ * 
+ */
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/MultiPointHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/MultiPointHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/MultiPointHandler.java	(revision 28000)
@@ -0,0 +1,85 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp;
+
+import java.nio.ByteBuffer;
+import java.nio.DoubleBuffer;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.GeometryFactory;
+
+/**
+ * 
+ * @author aaime
+ * @author Ian Schneider
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/MultiPointHandler.java $
+ * 
+ */
+public class MultiPointHandler implements ShapeHandler {
+    final ShapeType shapeType;
+    GeometryFactory geometryFactory;
+
+    public MultiPointHandler(ShapeType type, GeometryFactory gf) throws ShapefileException {
+        if ((type != ShapeType.MULTIPOINT) && (type != ShapeType.MULTIPOINTM)
+                && (type != ShapeType.MULTIPOINTZ)) {
+            throw new ShapefileException(
+                    "Multipointhandler constructor - expected type to be 8, 18, or 28");
+        }
+
+        shapeType = type;
+        this.geometryFactory = gf;
+    }
+    
+    private Object createNull() {
+        Coordinate[] c = null;
+        return geometryFactory.createMultiPoint(c);
+    }
+
+    public Object read(ByteBuffer buffer, ShapeType type, boolean flatGeometry) {
+        if (type == ShapeType.NULL) {
+            return createNull();
+        }
+
+        // read bounding box (not needed)
+        buffer.position(buffer.position() + 4 * 8);
+
+        int numpoints = buffer.getInt();
+        int dimensions = shapeType == ShapeType.MULTIPOINTZ && !flatGeometry ? 3 : 2;
+        CoordinateSequence cs = geometryFactory.getCoordinateSequenceFactory().create(numpoints, dimensions);
+
+        DoubleBuffer dbuffer = buffer.asDoubleBuffer();
+        double[] ordinates = new double[numpoints * 2];
+        dbuffer.get(ordinates);
+        for (int t = 0; t < numpoints; t++) {
+            cs.setOrdinate(t, 0, ordinates[t * 2]);
+            cs.setOrdinate(t, 1, ordinates[t * 2 + 1]);
+        }
+
+        if (dimensions > 2) {
+            dbuffer.position(dbuffer.position() + 2);
+
+            dbuffer.get(ordinates, 0, numpoints);
+            for (int t = 0; t < numpoints; t++) {
+                cs.setOrdinate(t, 2, ordinates[t]); // z
+            }
+        }
+
+        return geometryFactory.createMultiPoint(cs);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/PointHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/PointHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/PointHandler.java	(revision 28000)
@@ -0,0 +1,79 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp;
+
+import java.nio.ByteBuffer;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.GeometryFactory;
+
+/**
+ * Wrapper for a Shapefile point.
+ * 
+ * @author aaime
+ * @author Ian Schneider
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/PointHandler.java $
+ * 
+ */
+public class PointHandler implements ShapeHandler {
+
+    final ShapeType shapeType;
+    GeometryFactory geometryFactory;
+
+    public PointHandler(ShapeType type, GeometryFactory gf) throws ShapefileException {
+        if ((type != ShapeType.POINT) && (type != ShapeType.POINTM)
+                && (type != ShapeType.POINTZ)) { // 2d, 2d+m, 3d+m
+            throw new ShapefileException(
+                    "PointHandler constructor: expected a type of 1, 11 or 21");
+        }
+
+        shapeType = type;
+        this.geometryFactory = gf;
+    }
+
+    public PointHandler() {
+        shapeType = ShapeType.POINT; // 2d
+    }
+    
+    public Object read(ByteBuffer buffer, ShapeType type, boolean flatGeometry) {
+        if (type == ShapeType.NULL) {
+            return createNull();
+        }
+        
+        int dimension = shapeType == ShapeType.POINTZ && !flatGeometry ? 3 : 2;
+        CoordinateSequence cs = geometryFactory.getCoordinateSequenceFactory().create(1, dimension);
+        cs.setOrdinate(0, 0, buffer.getDouble());
+        cs.setOrdinate(0, 1, buffer.getDouble());
+
+        if (shapeType == ShapeType.POINTM) {
+            buffer.getDouble();
+        }
+        
+        if (dimension > 2) {
+            cs.setOrdinate(0, 2, buffer.getDouble());
+        }
+
+        return geometryFactory.createPoint(cs);
+    }
+
+    private Object createNull() {
+        return geometryFactory.createPoint(new Coordinate(Double.NaN,
+                Double.NaN, Double.NaN));
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/PolygonHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/PolygonHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/PolygonHandler.java	(revision 28000)
@@ -0,0 +1,413 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp;
+
+import java.nio.ByteBuffer;
+import java.nio.DoubleBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.geotools.geometry.jts.coordinatesequence.CoordinateSequences;
+
+import com.vividsolutions.jts.algorithm.CGAlgorithms;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Polygon;
+
+/**
+ * Wrapper for a Shapefile polygon.
+ * 
+ * @author aaime
+ * @author Ian Schneider
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/PolygonHandler.java $
+ * @version $Id: PolygonHandler.java 37305 2011-05-25 05:57:57Z mbedward $
+ */
+public class PolygonHandler implements ShapeHandler {
+    
+    GeometryFactory geometryFactory;
+
+    final ShapeType shapeType;
+
+    public PolygonHandler(ShapeType type, GeometryFactory gf) throws ShapefileException {
+        if ((type != ShapeType.POLYGON) && (type != ShapeType.POLYGONM)
+                && (type != ShapeType.POLYGONZ)) {
+            throw new ShapefileException(
+                    "PolygonHandler constructor - expected type to be 5, 15, or 25.");
+        }
+
+        shapeType = type;
+        this.geometryFactory = gf;
+    }
+    
+    // returns true if testPoint is a point in the pointList list.
+    boolean pointInList(Coordinate testPoint, Coordinate[] pointList) {
+        Coordinate p;
+
+        for (int t = pointList.length - 1; t >= 0; t--) {
+            p = pointList[t];
+
+            // nan test; x!=x iff x is nan
+            if ((testPoint.x == p.x)
+                    && (testPoint.y == p.y)
+                    && ((testPoint.z == p.z) || (!(testPoint.z == testPoint.z))) 
+            ) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public Object read(ByteBuffer buffer, ShapeType type, boolean flatFeature) {
+        if (type == ShapeType.NULL) {
+            return createNull();
+        }
+        // bounds
+        buffer.position(buffer.position() + 4 * 8);
+
+        int[] partOffsets;
+
+        int numParts = buffer.getInt();
+        int numPoints = buffer.getInt();
+        int dimensions = (shapeType == ShapeType.POLYGONZ) && !flatFeature ? 3 : 2;
+
+        partOffsets = new int[numParts];
+
+        for (int i = 0; i < numParts; i++) {
+            partOffsets[i] = buffer.getInt();
+        }
+
+        ArrayList shells = new ArrayList();
+        ArrayList holes = new ArrayList();
+        CoordinateSequence coords = readCoordinates(buffer, numPoints, dimensions);
+
+        int offset = 0;
+        int start;
+        int finish;
+        int length;
+
+        for (int part = 0; part < numParts; part++) {
+            start = partOffsets[part];
+
+            if (part == (numParts - 1)) {
+                finish = numPoints;
+            } else {
+                finish = partOffsets[part + 1];
+            }
+
+            length = finish - start;
+            int close = 0; // '1' if the ring must be closed, '0' otherwise
+            if ((coords.getOrdinate(start, 0) != coords.getOrdinate(finish - 1, 0)) 
+                    || (coords.getOrdinate(start, 1) != coords.getOrdinate(finish - 1, 1))
+            ) {
+                close=1;
+            }
+            if (dimensions == 3) {
+                if(coords.getOrdinate(start, 2) != coords.getOrdinate(finish - 1, 2)) {
+                    close = 1;
+                }
+            }
+
+            CoordinateSequence csRing = geometryFactory.getCoordinateSequenceFactory().create(length + close, dimensions);
+            // double area = 0;
+            // int sx = offset;
+            for (int i = 0; i < length; i++) {
+                csRing.setOrdinate(i, 0, coords.getOrdinate(offset, 0));
+                csRing.setOrdinate(i, 1, coords.getOrdinate(offset, 1));
+                if(dimensions == 3) {
+                    csRing.setOrdinate(i, 2, coords.getOrdinate(offset, 2));
+                }
+                offset++;
+            }
+            if (close == 1) {
+                csRing.setOrdinate(length, 0, coords.getOrdinate(start, 0));
+                csRing.setOrdinate(length, 1, coords.getOrdinate(start, 1));
+                if(dimensions == 3) {
+                    csRing.setOrdinate(length, 2, coords.getOrdinate(start, 2));
+                }
+            }
+            // REVISIT: polygons with only 1 or 2 points are not polygons -
+            // geometryFactory will bomb so we skip if we find one.
+            if (csRing.size() == 0 || csRing.size() > 3) {
+                LinearRing ring = geometryFactory.createLinearRing(csRing);
+
+                if (CoordinateSequences.isCCW(csRing)) {
+                    // counter-clockwise
+                    holes.add(ring);
+                } else {
+                    // clockwise
+                    shells.add(ring);
+                }
+            }
+        }
+
+        // quick optimization: if there's only one shell no need to check
+        // for holes inclusion
+        if (shells.size() == 1) {
+            return createMulti((LinearRing) shells.get(0), holes);
+        }
+        // if for some reason, there is only one hole, we just reverse it and
+        // carry on.
+        else if (holes.size() == 1 && shells.size() == 0) {
+            return createMulti((LinearRing) holes.get(0));
+        } else {
+
+            // build an association between shells and holes
+            final ArrayList holesForShells = assignHolesToShells(shells, holes);
+
+            Geometry g = buildGeometries(shells, holes, holesForShells);
+
+            return g;
+        }
+    }
+
+    /**
+     * @param buffer
+     * @param numPoints
+     */
+    private CoordinateSequence readCoordinates(final ByteBuffer buffer,
+            final int numPoints, final int dimensions) {
+        CoordinateSequence cs = geometryFactory.getCoordinateSequenceFactory().create(numPoints, dimensions);
+
+        DoubleBuffer dbuffer = buffer.asDoubleBuffer();
+        double[] ordinates = new double[numPoints * 2];
+        dbuffer.get(ordinates);
+        for (int t = 0; t < numPoints; t++) {
+            cs.setOrdinate(t, 0, ordinates[t * 2]);
+            cs.setOrdinate(t, 1, ordinates[t * 2 + 1]);
+        }
+        
+        if (dimensions > 2) {
+            // z
+            dbuffer.position(dbuffer.position() + 2);
+            dbuffer.get(ordinates, 0, numPoints);
+
+            for (int t = 0; t < numPoints; t++) {
+                cs.setOrdinate(t, 2, ordinates[t]);
+            }
+        }
+
+        return cs;
+    }
+
+    /**
+     * @param shells
+     * @param holes
+     * @param holesForShells
+     */
+    private Geometry buildGeometries(final List shells, final List holes,
+            final List holesForShells) {
+        Polygon[] polygons;
+
+        // if we have shells, lets use them
+        if (shells.size() > 0) {
+            polygons = new Polygon[shells.size()];
+            // oh, this is a bad record with only holes
+        } else {
+            polygons = new Polygon[holes.size()];
+        }
+
+        // this will do nothing for the "only holes case"
+        for (int i = 0; i < shells.size(); i++) {
+            polygons[i] = geometryFactory.createPolygon((LinearRing) shells
+                    .get(i), (LinearRing[]) ((ArrayList) holesForShells.get(i))
+                    .toArray(new LinearRing[0]));
+        }
+
+        // this will take care of the "only holes case"
+        // we just reverse each hole
+        if (shells.size() == 0) {
+            for (int i = 0, ii = holes.size(); i < ii; i++) {
+                LinearRing hole = (LinearRing) holes.get(i);
+                polygons[i] = geometryFactory.createPolygon(hole, null);
+            }
+        }
+
+        Geometry g = geometryFactory.createMultiPolygon(polygons);
+
+        return g;
+    }
+
+    /**
+     * <b>Package private for testing</b>
+     * 
+     * @param shells
+     * @param holes
+     */
+    ArrayList assignHolesToShells(final ArrayList shells, final ArrayList holes) {
+        ArrayList holesForShells = new ArrayList(shells.size());
+        for (int i = 0; i < shells.size(); i++) {
+            holesForShells.add(new ArrayList());
+        }
+
+        // find homes
+        for (int i = 0; i < holes.size(); i++) {
+            LinearRing testRing = (LinearRing) holes.get(i);
+            LinearRing minShell = null;
+            Envelope minEnv = null;
+            Envelope testEnv = testRing.getEnvelopeInternal();
+            Coordinate testPt = testRing.getCoordinateN(0);
+            LinearRing tryRing;
+
+            for (int j = 0; j < shells.size(); j++) {
+                tryRing = (LinearRing) shells.get(j);
+
+                Envelope tryEnv = tryRing.getEnvelopeInternal();
+                if (minShell != null) {
+                    minEnv = minShell.getEnvelopeInternal();
+                }
+
+                boolean isContained = false;
+                Coordinate[] coordList = tryRing.getCoordinates();
+
+                if (tryEnv.contains(testEnv)
+                        && (CGAlgorithms.isPointInRing(testPt, coordList) || (pointInList(
+                                testPt, coordList)))) {
+                    isContained = true;
+                }
+
+                // check if this new containing ring is smaller than the current
+                // minimum ring
+                if (isContained) {
+                    if ((minShell == null) || minEnv.contains(tryEnv)) {
+                        minShell = tryRing;
+                    }
+                }
+            }
+
+            if (minShell == null) {
+                // now reverse this bad "hole" and turn it into a shell
+                shells.add(testRing);
+                holesForShells.add(new ArrayList());
+            } else {
+                ((ArrayList) holesForShells.get(shells.indexOf(minShell)))
+                        .add(testRing);
+            }
+        }
+
+        return holesForShells;
+    }
+
+    private MultiPolygon createMulti(LinearRing single) {
+        return createMulti(single, java.util.Collections.EMPTY_LIST);
+    }
+
+    private MultiPolygon createMulti(LinearRing single, List holes) {
+        return geometryFactory
+                .createMultiPolygon(new Polygon[] { geometryFactory
+                        .createPolygon(single, (LinearRing[]) holes
+                                .toArray(new LinearRing[holes.size()])) });
+    }
+
+    private MultiPolygon createNull() {
+        return geometryFactory.createMultiPolygon(null);
+    }
+}
+
+/*
+ * $Log: PolygonHandler.java,v $ Revision 1.9 2004/02/17 18:10:23 ianschneider
+ * changed to use GeometryFactory for Geometry creation
+ * 
+ * Revision 1.8 2003/07/24 19:10:02 ianschneider *** empty log message ***
+ * 
+ * Revision 1.7 2003/07/24 18:32:10 ianschneider more test updates, fixed Z type
+ * writing
+ * 
+ * Revision 1.6 2003/07/23 23:41:09 ianschneider more testing updates
+ * 
+ * Revision 1.5 2003/07/23 00:59:59 ianschneider Lots of PMD fix ups
+ * 
+ * Revision 1.4 2003/07/21 21:15:29 jmacgill small fix for shapefiles with an
+ * invalid hole (only 1 or 2 points)
+ * 
+ * Revision 1.3 2003/05/19 21:38:55 jmacgill refactored read method to break it
+ * up a little
+ * 
+ * Revision 1.2 2003/05/19 20:51:30 ianschneider removed System.out print
+ * statements
+ * 
+ * Revision 1.1 2003/05/14 17:51:21 ianschneider migrated packages
+ * 
+ * Revision 1.3 2003/04/30 23:19:46 ianschneider Added construction of multi
+ * geometries for default return values, even if only one geometry. This could
+ * have effects through system.
+ * 
+ * Revision 1.2 2003/03/30 20:21:09 ianschneider Moved buffer branch to main
+ * 
+ * Revision 1.1.2.5 2003/03/29 22:30:09 ianschneider For case of hole without
+ * shell - reverse hole, add to shell list
+ * 
+ * Revision 1.1.2.4 2003/03/26 19:30:30 ianschneider Made hack to reverse
+ * polygon records if they contains only holes
+ * 
+ * Revision 1.1.2.3 2003/03/12 15:30:18 ianschneider made ShapeType final for
+ * handlers - once they're created, it won't change.
+ * 
+ * Revision 1.1.2.2 2003/03/07 00:36:41 ianschneider
+ * 
+ * Added back the additional ShapeType parameter in ShapeHandler.read.
+ * ShapeHandler's need return their own special "null" shape if needed. Fixed
+ * the ShapefileReader to not throw exceptions for "null" shapes. Fixed
+ * ShapefileReader to accomodate junk after the last valid record. The theory
+ * goes, if the shape number is proper, that is, one greater than the previous,
+ * we consider that a valid record and attempt to read it. I suppose, by chance,
+ * the junk could coincide with the next record number. Stupid ESRI. Fixed some
+ * record-length calculations which resulted in writing of bad shapefiles.
+ * 
+ * Revision 1.1.2.1 2003/03/06 01:16:34 ianschneider
+ * 
+ * The initial changes for moving to java.nio. Added some documentation and
+ * improved exception handling. Works for reading, may work for writing as of
+ * now.
+ * 
+ * Revision 1.1 2003/02/27 22:35:50 aaime New shapefile module, initial commit
+ * 
+ * Revision 1.2 2003/01/22 18:31:05 jaquino Enh: Make About Box configurable
+ * 
+ * Revision 1.2 2002/09/09 20:46:22 dblasby Removed LEDatastream refs and
+ * replaced with EndianData[in/out]putstream
+ * 
+ * Revision 1.1 2002/08/27 21:04:58 dblasby orginal
+ * 
+ * Revision 1.3 2002/03/05 10:51:01 andyt removed use of factory from write
+ * method
+ * 
+ * Revision 1.2 2002/03/05 10:23:59 jmacgill made sure geometries were created
+ * using the factory methods
+ * 
+ * Revision 1.1 2002/02/28 00:38:50 jmacgill Renamed files to more intuitve
+ * names
+ * 
+ * Revision 1.4 2002/02/13 00:23:53 jmacgill First semi working JTS version of
+ * Shapefile code
+ * 
+ * Revision 1.3 2002/02/11 18:44:22 jmacgill replaced geometry constructions
+ * with calls to geometryFactory.createX methods
+ * 
+ * Revision 1.2 2002/02/11 18:28:41 jmacgill rewrote to have static read and
+ * write methods
+ * 
+ * Revision 1.1 2002/02/11 16:54:43 jmacgill added shapefile code and
+ * directories
+ * 
+ */
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapeHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapeHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapeHandler.java	(revision 28000)
@@ -0,0 +1,45 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp;
+
+import java.nio.ByteBuffer;
+
+/**
+ * A ShapeHandler defines what is needed to construct and persist geometries
+ * based upon the shapefile specification.
+ * 
+ * @author aaime
+ * @author Ian Schneider
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/ShapeHandler.java $
+ * 
+ */
+public interface ShapeHandler {
+
+	/**
+     * Read a geometry from the ByteBuffer. The buffer's position, byteOrder,
+     * and limit are set to that which is needed. The record has been read as
+     * well as the shape type integer. The handler need not worry about reading
+     * unused information as the ShapefileReader will correctly adjust the
+     * buffer position after this call.
+     * 
+     * @param buffer
+     *                The ByteBuffer to read from.
+     * @return A geometry object.
+     */
+    public Object read(ByteBuffer buffer, ShapeType type, boolean flatGeometry);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapeType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapeType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapeType.java	(revision 28000)
@@ -0,0 +1,219 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp;
+
+import com.vividsolutions.jts.geom.GeometryFactory;
+
+/**
+ * Not much but a type safe enumeration of file types as ints and names. The
+ * descriptions can easily be tied to a ResourceBundle if someone wants to do
+ * that.
+ * 
+ * @author Ian Schneider
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/ShapeType.java $
+ */
+public final class ShapeType {
+
+    /** Represents a Null shape (id = 0). */
+    public static final ShapeType NULL = new ShapeType(0, "Null");
+    /** Represents a Point shape (id = 1). */
+    public static final ShapeType POINT = new ShapeType(1, "Point");
+    /** Represents a PointZ shape (id = 11). */
+    public static final ShapeType POINTZ = new ShapeType(11, "PointZ");
+    /** Represents a PointM shape (id = 21). */
+    public static final ShapeType POINTM = new ShapeType(21, "PointM");
+    /** Represents an Arc shape (id = 3). */
+    public static final ShapeType ARC = new ShapeType(3, "Arc");
+    /** Represents an ArcZ shape (id = 13). */
+    public static final ShapeType ARCZ = new ShapeType(13, "ArcZ");
+    /** Represents an ArcM shape (id = 23). */
+    public static final ShapeType ARCM = new ShapeType(23, "ArcM");
+    /** Represents a Polygon shape (id = 5). */
+    public static final ShapeType POLYGON = new ShapeType(5, "Polygon");
+    /** Represents a PolygonZ shape (id = 15). */
+    public static final ShapeType POLYGONZ = new ShapeType(15, "PolygonZ");
+    /** Represents a PolygonM shape (id = 25). */
+    public static final ShapeType POLYGONM = new ShapeType(25, "PolygonM");
+    /** Represents a MultiPoint shape (id = 8). */
+    public static final ShapeType MULTIPOINT = new ShapeType(8, "MultiPoint");
+    /** Represents a MultiPointZ shape (id = 18). */
+    public static final ShapeType MULTIPOINTZ = new ShapeType(18, "MultiPointZ");
+    /** Represents a MultiPointZ shape (id = 28). */
+    public static final ShapeType MULTIPOINTM = new ShapeType(28, "MultiPointM");
+
+    /** Represents an Undefined shape (id = -1). */
+    public static final ShapeType UNDEFINED = new ShapeType(-1, "Undefined");
+
+    /** The integer id of this ShapeType. */
+    public final int id;
+    /**
+     * The human-readable name for this ShapeType.<br>
+     * Could easily use ResourceBundle for internationialization.
+     */
+    public final String name;
+
+    /**
+     * Creates a new instance of ShapeType. Hidden on purpose.
+     * 
+     * @param id
+     *                The id.
+     * @param name
+     *                The name.
+     */
+    protected ShapeType(int id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    /**
+     * Get the name of this ShapeType.
+     * 
+     * @return The name.
+     */
+    public String toString() {
+        return name;
+    }
+
+    /**
+     * Is this a multipoint shape? Hint- all shapes are multipoint except NULL,
+     * UNDEFINED, and the POINTs.
+     * 
+     * @return true if multipoint, false otherwise.
+     */
+    public boolean isMultiPoint() {
+        boolean mp = true;
+        if (this == UNDEFINED) {
+            mp = false;
+        } else if (this == NULL) {
+            mp = false;
+        } else if (this == POINT || this == POINTM || this == POINTZ) {
+            mp = false;
+        }
+        return mp;
+    }
+
+    public boolean isPointType() {
+        return id % 10 == 1;
+    }
+
+    public boolean isLineType() {
+        return id % 10 == 3;
+    }
+
+    public boolean isPolygonType() {
+        return id % 10 == 5;
+    }
+
+    public boolean isMultiPointType() {
+        return id % 10 == 8;
+    }
+
+    /**
+     * Determine the ShapeType for the id.
+     * 
+     * @param id
+     *                The id to search for.
+     * @return The ShapeType for the id.
+     */
+    public static ShapeType forID(int id) {
+        ShapeType t;
+        switch (id) {
+        case 0:
+            t = NULL;
+            break;
+        case 1:
+            t = POINT;
+            break;
+        case 11:
+            t = POINTZ;
+            break;
+        case 21:
+            t = POINTM;
+            break;
+        case 3:
+            t = ARC;
+            break;
+        case 13:
+            t = ARCZ;
+            break;
+        case 23:
+            t = ARCM;
+            break;
+        case 5:
+            t = POLYGON;
+            break;
+        case 15:
+            t = POLYGONZ;
+            break;
+        case 25:
+            t = POLYGONM;
+            break;
+        case 8:
+            t = MULTIPOINT;
+            break;
+        case 18:
+            t = MULTIPOINTZ;
+            break;
+        case 28:
+            t = MULTIPOINTM;
+            break;
+        default:
+            t = UNDEFINED;
+            break;
+        }
+        return t;
+    }
+
+    /**
+     * Each ShapeType corresponds to a handler. In the future this should
+     * probably go else where to allow different handlers, or something...
+     * 
+     * @throws ShapefileException
+     *                 If the ShapeType is bogus.
+     * @return The correct handler for this ShapeType. Returns a new one.
+     */
+    public ShapeHandler getShapeHandler(GeometryFactory gf) throws ShapefileException {
+        ShapeHandler handler;
+        switch (id) {
+        case 1:
+        case 11:
+        case 21:
+            handler = new PointHandler(this, gf);
+            break;
+        case 3:
+        case 13:
+        case 23:
+            handler = new MultiLineHandler(this, gf);
+            break;
+        case 5:
+        case 15:
+        case 25:
+            handler = new PolygonHandler(this, gf);
+            break;
+        case 8:
+        case 18:
+        case 28:
+            handler = new MultiPointHandler(this, gf);
+            break;
+        default:
+            handler = null;
+        }
+        return handler;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapefileException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapefileException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapefileException.java	(revision 28000)
@@ -0,0 +1,34 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp;
+
+import org.geotools.data.DataSourceException;
+
+/**
+ * Thrown when an error relating to the shapefile occures
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/ShapefileException.java $
+ */
+public class ShapefileException extends DataSourceException {
+
+    private static final long serialVersionUID = -6523799964553991364L;
+
+    public ShapefileException(String s) {
+        super(s);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapefileHeader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapefileHeader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapefileHeader.java	(revision 28000)
@@ -0,0 +1,134 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * 
+ * @author jamesm
+ * @author Ian Schneider
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/ShapefileHeader.java $
+ *         http://svn.geotools.org/geotools/trunk/gt/modules/plugin/shapefile/src/main/java/org
+ *         /geotools/data/shapefile/shp/ShapefileHeader.java $
+ */
+public class ShapefileHeader {
+
+    public static final int MAGIC = 9994;
+
+    public static final int VERSION = 1000;
+
+    private int fileCode = -1;
+
+    private int fileLength = -1;
+
+    private int version = -1;
+
+    private ShapeType shapeType = ShapeType.UNDEFINED;
+
+    private double minX;
+
+    private double maxX;
+
+    private double minY;
+
+    private double maxY;
+
+    private void checkMagic(boolean strict) throws java.io.IOException {
+        if (fileCode != MAGIC) {
+            String message = "Wrong magic number, expected " + MAGIC + ", got " + fileCode;
+            if (!strict) {
+                System.err.println(message);
+            } else {
+                throw new java.io.IOException(message);
+            }
+        }
+    }
+
+    private void checkVersion(boolean strict) throws java.io.IOException {
+        if (version != VERSION) {
+            String message = "Wrong version, expected " + MAGIC + ", got " + version;
+            if (!strict) {
+                System.err.println(message);
+            } else {
+                throw new java.io.IOException(message);
+            }
+        }
+    }
+
+    public void read(ByteBuffer file, boolean strict) throws java.io.IOException {
+        file.order(ByteOrder.BIG_ENDIAN);
+        fileCode = file.getInt();
+
+        checkMagic(strict);
+
+        // skip 5 ints...
+        file.position(file.position() + 20);
+
+        fileLength = file.getInt();
+
+        file.order(ByteOrder.LITTLE_ENDIAN);
+        version = file.getInt();
+        checkVersion(strict);
+        shapeType = ShapeType.forID(file.getInt());
+
+        minX = file.getDouble();
+        minY = file.getDouble();
+        maxX = file.getDouble();
+        maxY = file.getDouble();
+
+        // skip remaining unused bytes
+        file.order(ByteOrder.BIG_ENDIAN);// well they may not be unused
+        // forever...
+        file.position(file.position() + 32);
+
+    }
+
+    public ShapeType getShapeType() {
+        return shapeType;
+    }
+
+    public int getFileLength() {
+        return fileLength;
+    }
+
+    public double minX() {
+        return minX;
+    }
+
+    public double minY() {
+        return minY;
+    }
+
+    public double maxX() {
+        return maxX;
+    }
+
+    public double maxY() {
+        return maxY;
+    }
+
+    public String toString() {
+        String res = new String("ShapeFileHeader[ size " + fileLength + " version " + version
+                + " shapeType " + shapeType + " bounds " + minX + "," + minY + "," + maxX + ","
+                + maxY + " ]");
+        return res;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapefileReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapefileReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/ShapefileReader.java	(revision 28000)
@@ -0,0 +1,589 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.data.DataSourceException;
+import org.geotools.data.shapefile.FileReader;
+import org.geotools.data.shapefile.ShpFileType;
+import org.geotools.data.shapefile.ShpFiles;
+import org.geotools.data.shapefile.StreamLogging;
+import org.geotools.resources.NIOUtilities;
+import org.geotools.util.logging.Logging;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.GeometryFactory;
+
+/**
+ * The general use of this class is: <CODE><PRE>
+ * 
+ * FileChannel in = new FileInputStream(&quot;thefile.dbf&quot;).getChannel();
+ * ShapefileReader r = new ShapefileReader( in ) while (r.hasNext()) { Geometry
+ * shape = (Geometry) r.nextRecord().shape() // do stuff } r.close();
+ * 
+ * </PRE></CODE> You don't have to immediately ask for the shape from the record. The
+ * record will contain the bounds of the shape and will only read the shape when
+ * the shape() method is called. This ShapefileReader.Record is the same object
+ * every time, so if you need data from the Record, be sure to copy it.
+ * 
+ * @author jamesm
+ * @author aaime
+ * @author Ian Schneider
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/ShapefileReader.java $
+ */
+public class ShapefileReader implements FileReader {
+    private static final Logger LOGGER = Logging.getLogger(ShapefileReader.class);
+    
+    /**
+     *  Used to mark the current shape is not known, either because someone moved the reader
+     *  to a specific byte offset manually, or because the .shx could not be opened
+     */
+    private static final int UNKNOWN = Integer.MIN_VALUE;
+
+    /**
+     * The reader returns only one Record instance in its lifetime. The record
+     * contains the current record information.
+     */
+    public final class Record {
+        int length;
+
+        public int number = 0;
+
+        int start = 0; // Relative to the current loaded buffer
+
+        /** The minimum X value. */
+        public double minX;
+
+        /** The minimum Y value. */
+        public double minY;
+
+        /** The maximum X value. */
+        public double maxX;
+
+        /** The maximum Y value. */
+        public double maxY;
+
+        public ShapeType type;
+
+        int end = 0; // Relative to the whole file
+
+        Object shape = null;
+
+        /** Fetch the shape stored in this record. */
+        public Object shape() {
+            if (shape == null) {
+                buffer.position(start);
+                buffer.order(ByteOrder.LITTLE_ENDIAN);
+				if (type == ShapeType.NULL) {
+					shape = null;
+				} else {
+					shape = handler.read(buffer, type, flatGeometry);
+				}
+            }
+            return shape;
+        }
+
+        /** A summary of the record. */
+        public String toString() {
+            return "Record " + number + " length " + length + " bounds " + minX
+                    + "," + minY + " " + maxX + "," + maxY;
+        }
+        
+        public Envelope envelope() {
+            return new Envelope(minX, maxX, minY, maxY);
+        }
+    }
+
+    private ShapeHandler handler;
+
+    private ShapefileHeader header;
+
+    private ReadableByteChannel channel;
+
+    ByteBuffer buffer;
+
+    private ShapeType fileShapeType = ShapeType.UNDEFINED;
+
+    private ByteBuffer headerTransfer;
+
+    private final Record record = new Record();
+
+    private final boolean randomAccessEnabled;
+
+    private boolean useMemoryMappedBuffer;
+
+    private long currentOffset = 0L;
+    
+    private int currentShape = 0;
+    
+    private IndexFile shxReader;
+    
+    private StreamLogging streamLogger = new StreamLogging("Shapefile Reader");
+    
+    private boolean flatGeometry;
+    
+    /**
+     * Creates a new instance of ShapeFile.
+     * 
+     * @param shapefileFiles
+     *                The ReadableByteChannel this reader will use.
+     * @param strict
+     *                True to make the header parsing throw Exceptions if the
+     *                version or magic number are incorrect.
+     * @throws IOException
+     *                 If problems arise.
+     * @throws ShapefileException
+     *                 If for some reason the file contains invalid records.
+     */
+    public ShapefileReader(ShpFiles shapefileFiles, boolean strict,
+            boolean useMemoryMapped, GeometryFactory gf) throws IOException, ShapefileException {
+        this.channel = shapefileFiles.getReadChannel(ShpFileType.SHP, this);
+        this.useMemoryMappedBuffer = useMemoryMapped;
+        streamLogger.open();
+        randomAccessEnabled = channel instanceof FileChannel;
+        try {
+            shxReader = new IndexFile(shapefileFiles, this.useMemoryMappedBuffer);
+        } catch(Exception e) {
+            LOGGER.log(Level.WARNING, "Could not open the .shx file, continuing " +
+            		"assuming the .shp file is not sparse", e);
+            currentShape = UNKNOWN;
+        }
+        init(strict, gf);
+    }
+    
+    /**
+     * Creates a new instance of ShapeFile.
+     * 
+     * @param shapefileFiles
+     *                The ReadableByteChannel this reader will use.
+     * @param strict
+     *                True to make the header parsing throw Exceptions if the
+     *                version or magic number are incorrect.
+     * @param useMemoryMapped Wheter to enable memory mapping or not
+     * @param gf      The geometry factory used to build the geometries
+     * @param onlyRandomAccess When true sets up the reader to do exclusively read driven by goTo(x)
+     *                         and thus avoids opening the .shx file
+     * @throws IOException
+     *                 If problems arise.
+     * @throws ShapefileException
+     *                 If for some reason the file contains invalid records.
+     */
+    public ShapefileReader(ShpFiles shapefileFiles, boolean strict,
+            boolean useMemoryMapped, GeometryFactory gf, boolean onlyRandomAccess) throws IOException, ShapefileException {
+        this.channel = shapefileFiles.getReadChannel(ShpFileType.SHP, this);
+        this.useMemoryMappedBuffer = useMemoryMapped;
+        streamLogger.open();
+        randomAccessEnabled = channel instanceof FileChannel;
+        if(!onlyRandomAccess) {
+            try {
+                shxReader = new IndexFile(shapefileFiles, this.useMemoryMappedBuffer);
+            } catch(Exception e) {
+                LOGGER.log(Level.WARNING, "Could not open the .shx file, continuing " +
+                        "assuming the .shp file is not sparse", e);
+                currentShape = UNKNOWN;
+            }
+        }
+        init(strict, gf);
+    }
+    
+    /**
+     * Disables .shx file usage. By doing so you drop support for sparse shapefiles, the 
+     * .shp will have to be without holes, all the valid shapefile records will have to
+     * be contiguous.
+     * @throws IOException
+     */
+    public void disableShxUsage() throws IOException {
+        if(shxReader != null) {
+            shxReader.close();
+            shxReader = null;
+        }
+        currentShape = UNKNOWN;
+    }
+
+    // ensure the capacity of the buffer is of size by doubling the original
+    // capacity until it is big enough
+    // this may be naiive and result in out of MemoryError as implemented...
+    private ByteBuffer ensureCapacity(ByteBuffer buffer, int size,
+            boolean useMemoryMappedBuffer) {
+        // This sucks if you accidentally pass is a MemoryMappedBuffer of size
+        // 80M
+        // like I did while messing around, within moments I had 1 gig of
+        // swap...
+        if (buffer.isReadOnly() || useMemoryMappedBuffer) {
+            return buffer;
+        }
+
+        int limit = buffer.limit();
+        while (limit < size) {
+            limit *= 2;
+        }
+        if (limit != buffer.limit()) {
+            // clean up the old buffer and allocate a new one
+            buffer = NIOUtilities.allocate(limit);
+        }
+        return buffer;
+    }
+
+    // for filling a ReadableByteChannel
+    public static int fill(ByteBuffer buffer, ReadableByteChannel channel)
+            throws IOException {
+        int r = buffer.remaining();
+        // channel reads return -1 when EOF or other error
+        // because they a non-blocking reads, 0 is a valid return value!!
+        while (buffer.remaining() > 0 && r != -1) {
+            r = channel.read(buffer);
+        }
+        buffer.limit(buffer.position());
+        return r;
+    }
+
+    private void init(boolean strict, GeometryFactory gf) throws IOException, ShapefileException {
+        if (channel instanceof FileChannel && useMemoryMappedBuffer) {
+            FileChannel fc = (FileChannel) channel;
+            buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
+            buffer.position(0);
+            this.currentOffset = 0;
+        } else {
+            // force useMemoryMappedBuffer to false
+            this.useMemoryMappedBuffer = false;
+            // start small
+            buffer = NIOUtilities.allocate(1024);
+            fill(buffer, channel);
+            buffer.flip();
+            this.currentOffset = 0;
+        }
+        header = new ShapefileHeader();
+        header.read(buffer, strict);
+        fileShapeType = header.getShapeType();
+        handler = fileShapeType.getShapeHandler(gf);
+        if (handler == null) {
+            throw new IOException("Unsuported shape type:" + fileShapeType);
+        }
+
+        headerTransfer = ByteBuffer.allocate(8);
+        headerTransfer.order(ByteOrder.BIG_ENDIAN);
+
+        // make sure the record end is set now...
+        record.end = this.toFileOffset(buffer.position());
+    }
+
+    /**
+     * Get the header. Its parsed in the constructor.
+     * 
+     * @return The header that is associated with this file.
+     */
+    public ShapefileHeader getHeader() {
+        return header;
+    }
+
+    // do important cleanup stuff.
+    // Closes channel !
+    /**
+     * Clean up any resources. Closes the channel.
+     * 
+     * @throws IOException
+     *                 If errors occur while closing the channel.
+     */
+    public void close() throws IOException {
+        // don't throw NPE on double close
+        if(channel == null)
+            return;
+        try {
+            if (channel.isOpen()) {
+                channel.close();
+                streamLogger.close();
+            }
+            NIOUtilities.clean(buffer, useMemoryMappedBuffer);
+        } finally {
+            if(shxReader != null)
+                shxReader.close();
+        }
+        shxReader = null;
+        channel = null;
+        header = null;
+    }
+
+    /**
+     * If there exists another record. Currently checks the stream for the
+     * presence of 8 more bytes, the length of a record. If this is true and the
+     * record indicates the next logical record number, there exists more
+     * records.
+     * 
+     * @throws IOException
+     * @return True if has next record, false otherwise.
+     */
+    public boolean hasNext() throws IOException {
+        return this.hasNext(true);
+    }
+
+    /**
+     * If there exists another record. Currently checks the stream for the
+     * presence of 8 more bytes, the length of a record. If this is true and the
+     * record indicates the next logical record number (if checkRecord == true),
+     * there exists more records.
+     * 
+     * @param checkRecno
+     *                If true then record number is checked
+     * @throws IOException
+     * @return True if has next record, false otherwise.
+     */
+    private boolean hasNext(boolean checkRecno) throws IOException {
+        // don't read past the end of the file (provided currentShape accurately
+        // represents the current position)
+        if(currentShape > UNKNOWN && currentShape > shxReader.getRecordCount() - 1)
+            return false;
+        
+        // mark current position
+        int position = buffer.position();
+
+        // ensure the proper position, regardless of read or handler behavior
+        buffer.position(getNextOffset());
+
+        // no more data left
+        if (buffer.remaining() < 8)
+            return false;
+
+        // looks good
+        boolean hasNext = true;
+        if (checkRecno) {
+            // record headers in big endian
+            buffer.order(ByteOrder.BIG_ENDIAN);
+            int declaredRecNo = buffer.getInt();
+            hasNext = declaredRecNo == record.number + 1;
+        }
+
+        // reset things to as they were
+        buffer.position(position);
+
+        return hasNext;
+    }
+    
+    private int getNextOffset() throws IOException {
+        if(currentShape >= 0) {
+            return this.toBufferOffset(shxReader.getOffsetInBytes(currentShape));
+        } else {
+            return this.toBufferOffset(record.end);
+        }
+    }
+
+    /**
+     * Fetch the next record information.
+     * 
+     * @throws IOException
+     * @return The record instance associated with this reader.
+     */
+    public Record nextRecord() throws IOException {
+
+        // need to update position
+        buffer.position(getNextOffset());
+        if(currentShape != UNKNOWN)
+            currentShape++;
+
+        // record header is big endian
+        buffer.order(ByteOrder.BIG_ENDIAN);
+
+        // read shape record header
+        int recordNumber = buffer.getInt();
+        // silly ESRI say contentLength is in 2-byte words
+        // and ByteByffer uses bytes.
+        // track the record location
+        int recordLength = buffer.getInt() * 2;
+
+        if (!buffer.isReadOnly() && !useMemoryMappedBuffer) {
+            // capacity is less than required for the record
+            // copy the old into the newly allocated
+            if (buffer.capacity() < recordLength + 8) {
+                this.currentOffset += buffer.position();
+                ByteBuffer old = buffer;
+                // ensure enough capacity for one more record header
+                buffer = ensureCapacity(buffer, recordLength + 8,
+                        useMemoryMappedBuffer);
+                buffer.put(old);
+                NIOUtilities.clean(old, useMemoryMappedBuffer);
+                fill(buffer, channel);
+                buffer.position(0);
+            } else
+            // remaining is less than record length
+            // compact the remaining data and read again,
+            // allowing enough room for one more record header
+            if (buffer.remaining() < recordLength + 8) {
+                this.currentOffset += buffer.position();
+                buffer.compact();
+                fill(buffer, channel);
+                buffer.position(0);
+            }
+        }
+
+        // shape record is all little endian
+        buffer.order(ByteOrder.LITTLE_ENDIAN);
+
+        // read the type, handlers don't need it
+        ShapeType recordType = ShapeType.forID(buffer.getInt());
+
+        // this usually happens if the handler logic is bunk,
+        // but bad files could exist as well...
+        if (recordType != ShapeType.NULL && recordType != fileShapeType) {
+            throw new IllegalStateException("ShapeType changed illegally from "
+                    + fileShapeType + " to " + recordType);
+        }
+
+        // peek at bounds, then reset for handler
+        // many handler's may ignore bounds reading, but we don't want to
+        // second guess them...
+        buffer.mark();
+        if (recordType.isMultiPoint()) {
+            record.minX = buffer.getDouble();
+            record.minY = buffer.getDouble();
+            record.maxX = buffer.getDouble();
+            record.maxY = buffer.getDouble();
+        } else if (recordType != ShapeType.NULL) {
+            record.minX = record.maxX = buffer.getDouble();
+            record.minY = record.maxY = buffer.getDouble();
+        }
+        buffer.reset();
+
+        // update all the record info.
+        record.length = recordLength;
+        record.type = recordType;
+        record.number = recordNumber;
+        // remember, we read one int already...
+        record.end = this.toFileOffset(buffer.position()) + recordLength - 4;
+        // mark this position for the reader
+        record.start = buffer.position();
+        // clear any cached shape
+        record.shape = null;
+
+        return record;
+    }
+
+    /**
+     * Moves the reader to the specified byte offset in the file. Mind that:
+     * <ul>
+     * <li>it's your responsibility to ensure the offset corresponds to the
+     * actual beginning of a shape struct</li>
+     * <li>once you call this, reading with hasNext/next on sparse shapefiles
+     * will be broken (we don't know anymore at which shape we are)</li>
+     * </ul>
+     * 
+     * @param offset
+     * @throws IOException
+     * @throws UnsupportedOperationException
+     */
+    public void goTo(int offset) throws IOException,
+            UnsupportedOperationException {
+        disableShxUsage();
+        if (randomAccessEnabled) {
+            if (this.useMemoryMappedBuffer) {
+                buffer.position(offset);
+            } else {
+                /*
+                 * Check to see if requested offset is already loaded; ensure
+                 * that record header is in the buffer
+                 */
+                if (this.currentOffset <= offset
+                        && this.currentOffset + buffer.limit() >= offset + 8) {
+                    buffer.position(this.toBufferOffset(offset));
+                } else {
+                    FileChannel fc = (FileChannel) this.channel;
+                    fc.position(offset);
+                    this.currentOffset = offset;
+                    buffer.position(0);
+                    buffer.limit(buffer.capacity());
+                    fill(buffer, fc);
+                    buffer.position(0);
+                }
+            }
+
+            int oldRecordOffset = record.end;
+            record.end = offset;
+            try {
+                hasNext(false); // don't check for next logical record equality
+            } catch (IOException ioe) {
+                record.end = oldRecordOffset;
+                throw ioe;
+            }
+        } else {
+            throw new UnsupportedOperationException("Random Access not enabled");
+        }
+    }
+
+    /**
+     * Converts file offset to buffer offset
+     * 
+     * @param offset
+     *                The offset relative to the whole file
+     * @return The offset relative to the current loaded portion of the file
+     */
+    private int toBufferOffset(int offset) {
+        return (int) (offset - this.currentOffset);
+    }
+
+    /**
+     * Converts buffer offset to file offset
+     * 
+     * @param offset
+     *                The offset relative to the buffer
+     * @return The offset relative to the whole file
+     */
+    private int toFileOffset(int offset) {
+        return (int) (this.currentOffset + offset);
+    }
+
+    /**
+     * Parses the shpfile counting the records.
+     * 
+     * @return the number of non-null records in the shapefile
+     */
+    public int getCount(int count) throws DataSourceException {
+        try {
+            if (channel == null)
+                return -1;
+            count = 0;
+            long offset = this.currentOffset;
+            try {
+                goTo(100);
+            } catch (UnsupportedOperationException e) {
+                return -1;
+            }
+            while (hasNext()) {
+                count++;
+                nextRecord();
+            }
+
+            goTo((int) offset);
+
+        } catch (IOException ioe) {
+            count = -1;
+            // What now? This seems arbitrarily appropriate !
+            throw new DataSourceException("Problem reading shapefile record",
+                    ioe);
+        }
+        return count;
+    }
+
+    public void setFlatGeometry(boolean flatGeometry) {
+        this.flatGeometry = flatGeometry;        
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/xml/IdInfo.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/xml/IdInfo.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/xml/IdInfo.java	(revision 28000)
@@ -0,0 +1,42 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp.xml;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * Bean of idinfo element of shp.xml.
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/xml/IdInfo.java $
+ */
+public class IdInfo {
+
+    /**
+     * @param bounding
+     *                The bounding to set.
+     */
+    public void setBounding(Envelope bounding) {
+    }
+
+    /**
+     * @param lbounding
+     *                The lbounding to set.
+     */
+    public void setLbounding(Envelope lbounding) {
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/xml/Metadata.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/xml/Metadata.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/xml/Metadata.java	(revision 28000)
@@ -0,0 +1,44 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp.xml;
+
+/**
+ * Bean capturing shapefile metadata information.
+ * <p>
+ * To create please use the included ShpXmlFileReader, this is only a data
+ * object.
+ * </p>
+ * <p>
+ * Note: This bean currently extends MetadataEntity to allow for uses with
+ * Discovery.search( QueryRequest ). When QueryRequest can actually handle
+ * normal java beans we can remove this restrictions.
+ * </p>
+ * 
+ * @author jgarnett
+ * @since 0.3
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/xml/Metadata.java $
+ */
+public class Metadata {
+
+    /**
+     * @param idinfo
+     *                The idinfo to set.
+     */
+    public void setIdinfo(IdInfo idinfo) {
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/xml/ShpXmlFileReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/xml/ShpXmlFileReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/shapefile/shp/xml/ShpXmlFileReader.java	(revision 28000)
@@ -0,0 +1,93 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.shapefile.shp.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.geotools.data.shapefile.FileReader;
+import org.geotools.data.shapefile.ShpFileType;
+import org.geotools.data.shapefile.ShpFiles;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+public class ShpXmlFileReader implements FileReader {
+
+    Document dom;
+
+    /**
+     * Parse metadataFile (currently for bounding box information).
+     * <p>
+     * 
+     * </p>
+     * 
+     * @param shapefileFiles
+     * @throws JDOMException
+     * @throws IOException
+     */
+    public ShpXmlFileReader(ShpFiles shapefileFiles) throws JDOMException,
+            IOException {
+        SAXBuilder builder = new SAXBuilder(false);
+
+        InputStream inputStream = shapefileFiles.getInputStream(
+                ShpFileType.SHP_XML, this);
+        try {
+            dom = builder.build(inputStream);
+        } finally {
+            inputStream.close();
+        }
+    }
+
+    public Metadata parse() {
+        return parseMetadata(dom.getRootElement());
+    }
+
+    protected Metadata parseMetadata(Element root) {
+        Metadata meta = new Metadata();
+        meta.setIdinfo(parseIdInfo(root.getChild("idinfo")));
+
+        return meta;
+    }
+
+    protected IdInfo parseIdInfo(Element element) {
+        IdInfo idInfo = new IdInfo();
+
+        Element bounding = element.getChild("spdom").getChild("bounding");
+        idInfo.setBounding(parseBounding(bounding));
+
+        Element lbounding = element.getChild("spdom").getChild("lbounding");
+        idInfo.setLbounding(parseBounding(lbounding));
+
+        return idInfo;
+    }
+
+    protected Envelope parseBounding(Element bounding) {
+        if (bounding == null)
+            return new Envelope();
+
+        double minX = Double.parseDouble(bounding.getChildText("westbc"));
+        double maxX = Double.parseDouble(bounding.getChildText("eastbc"));
+        double minY = Double.parseDouble(bounding.getChildText("southbc"));
+        double maxY = Double.parseDouble(bounding.getChildText("northbc"));
+
+        return new Envelope(minX, maxX, minY, maxY);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureCollection.java	(revision 28000)
@@ -0,0 +1,22 @@
+package org.geotools.data.simple;
+
+import org.geotools.feature.FeatureCollection;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+
+/**
+ * Access to "simple" Feature content where each feature has the same SimpleFeatureType.
+ * <p>
+ * Please keep in mind that a FeatureCollection is similar to a result set; and may not
+ * necessarily load everything in to memory. Treat each iterator as a forward only cursor
+ * in the JDBC sense; and take care to close iterators when not in use.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/simple/SimpleFeatureCollection.java $
+ */
+public interface SimpleFeatureCollection extends FeatureCollection<SimpleFeatureType,SimpleFeature>{
+	
+    public SimpleFeatureIterator features();
+    
+    public SimpleFeatureCollection subCollection(Filter filter);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureIterator.java	(revision 28000)
@@ -0,0 +1,13 @@
+package org.geotools.data.simple;
+
+import org.geotools.feature.FeatureIterator;
+import org.opengis.feature.simple.SimpleFeature;
+
+/**
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/simple/SimpleFeatureIterator.java $
+ */
+public interface SimpleFeatureIterator extends FeatureIterator<SimpleFeature> {
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureLocking.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureLocking.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureLocking.java	(revision 28000)
@@ -0,0 +1,19 @@
+package org.geotools.data.simple;
+
+import org.geotools.data.FeatureLocking;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+/**
+ * Used to lock feature content to protect against other threads (or depending on the source of data other applications)
+ * making modifications when you are not looking.
+ * <p>
+ * The locks operate more as a lease for a specific period of time. In effect you are only
+ * locking for a set time period; so even if your application or machine crashes the lock
+ * will eventually be released allowing others to play.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/simple/SimpleFeatureLocking.java $
+ */
+public interface SimpleFeatureLocking extends SimpleFeatureStore, FeatureLocking<SimpleFeatureType, SimpleFeature> {
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureSource.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureSource.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureSource.java	(revision 28000)
@@ -0,0 +1,24 @@
+package org.geotools.data.simple;
+
+import java.io.IOException;
+
+import org.geotools.data.FeatureSource;
+import org.geotools.data.Query;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+
+/**
+ * FeatureSource explicitly working with SimpleFeatureCollection.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/simple/SimpleFeatureSource.java $
+ */
+public interface SimpleFeatureSource extends FeatureSource<SimpleFeatureType,SimpleFeature> {
+    public SimpleFeatureCollection getFeatures() throws IOException;
+
+    public SimpleFeatureCollection getFeatures(Filter filter)
+            throws IOException;
+
+    public SimpleFeatureCollection getFeatures(Query query)
+            throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/simple/SimpleFeatureStore.java	(revision 28000)
@@ -0,0 +1,31 @@
+package org.geotools.data.simple;
+
+import java.io.IOException;
+
+import org.geotools.data.FeatureStore;
+import org.geotools.data.Query;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+
+/**
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/data/simple/SimpleFeatureStore.java $
+ */
+public interface SimpleFeatureStore extends FeatureStore<SimpleFeatureType,SimpleFeature>, SimpleFeatureSource {
+    
+    public void modifyFeatures(String name, Object attributeValue, Filter filter)
+            throws IOException;
+
+    public void modifyFeatures(String[] names, Object[] attributeValues, Filter filter)
+            throws IOException;
+    
+    public SimpleFeatureCollection getFeatures() throws IOException;
+
+    public SimpleFeatureCollection getFeatures(Filter filter)
+            throws IOException;
+
+    public SimpleFeatureCollection getFeatures(Query query)
+            throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/DataFeatureCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/DataFeatureCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/DataFeatureCollection.java	(revision 28000)
@@ -0,0 +1,483 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.store;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.data.FeatureReader;
+import org.geotools.data.FeatureWriter;
+import org.geotools.data.collection.DelegateFeatureReader;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.feature.FeatureReaderIterator;
+import org.geotools.feature.collection.DelegateSimpleFeatureIterator;
+import org.geotools.feature.collection.SubFeatureCollection;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.util.NullProgressListener;
+import org.opengis.feature.IllegalAttributeException;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+
+
+/**
+ * A starting point for implementing FeatureCollection's backed onto a FeatureReader.
+ * <p>
+ * This implementation requires you to implement the following:
+ * <ul>
+ * <li>getSchema() - this should match reader.getSchema()
+ * <li>reader()</br>
+ *     features() - override one of these two method to access content
+ * <li>getBounds()
+ * <li>getCount()
+ * <li>collection()
+ * </p>
+ * <p>
+ * This class will implement the 'extra' methods required by FeatureCollection
+ * for you (in simple terms based on the FeatureResults API). Anything that is
+ * <i>often</i> customised is available to you as a constructor parameters.
+ * <p>
+ * Enjoy.
+ * </p>
+ * @author jgarnett
+ * @since 2.1.RC0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/store/DataFeatureCollection.java $
+ */
+public abstract class DataFeatureCollection implements SimpleFeatureCollection {
+    
+	/** logger */
+	static Logger LOGGER = org.geotools.util.logging.Logging.getLogger( "org.geotools.data" );
+	
+    static private int unique = 0;
+    
+    /**
+     * Collection based on a generic collection
+     */
+    protected DataFeatureCollection(){
+        this( "features"+(unique++) );
+    }
+    /**
+     * Collection based on a generic collection
+     */
+    protected DataFeatureCollection( String id ){
+    	this(id,null);
+    }
+    
+    /** Subclass must think about what consitructors it needs. */
+    protected DataFeatureCollection( String id, SimpleFeatureType memberType ){
+    	this.id = id == null ? "featureCollection" : id;
+        this.schema = memberType;
+    }
+        
+    public  FeatureReader<SimpleFeatureType, SimpleFeature> reader() throws IOException {
+    	return new DelegateFeatureReader<SimpleFeatureType, SimpleFeature>( getSchema(), features() );
+    }
+    
+    //
+    // Feature Results methods
+    // 
+    // To be implemented by subclass
+    //    
+
+    public abstract ReferencedEnvelope getBounds();
+
+    public abstract int getCount() throws IOException;;
+
+    //public abstract SimpleFeatureCollection collection() throws IOException;
+
+    //
+    // Additional Subclass "hooks"
+    //
+    /**
+     * Subclass may provide an implementation of this method to indicate
+     * that read/write support is provided.
+     * <p>
+     * All operations that attempt to modify the "data" will
+     * use this method, allowing them to throw an "UnsupportedOperationException"
+     * in the same manner as Collections.unmodifiableCollection(Collection c), or just
+     * return null.
+     * </p>
+     * @throws UnsupportedOperationException To indicate that write support is not avaiable
+     * @return the writer, or null if write support is not available
+     */
+    protected FeatureWriter<SimpleFeatureType, SimpleFeature> writer() throws IOException {
+        return null;
+    }
+    //
+    // SimpleFeatureCollection methods
+    // 
+    // implemented in terms of feature results
+    //
+    
+    //
+    // Content Access
+    //
+    /** Set of open resource iterators & featureIterators */
+    private final Set open = new HashSet();
+
+    /** 
+     * id used when serialized to gml
+     */
+    protected String id;
+
+    protected SimpleFeatureType schema;
+    /**
+     * SimpleFeatureIterator is entirely based on iterator().
+     * <p>
+     * So when we implement FeatureCollection.iterator() this will work
+     * out of the box.
+     */
+    public SimpleFeatureIterator features() {
+    	SimpleFeatureIterator iterator = new DelegateSimpleFeatureIterator( this, iterator() );
+        open.add( iterator );
+        return iterator;
+    }
+   
+    /**
+     * Iterator may (or may) not support modification.
+     */
+    final public Iterator<SimpleFeature> iterator() {
+    	Iterator<SimpleFeature> iterator;
+		try {
+			iterator = openIterator();
+		} 
+		catch (IOException e) {
+			throw new RuntimeException( e );
+		}
+		
+    	open.add( iterator );
+    	return iterator;    	    	
+    }
+    
+    /**
+     * Returns a FeatureWriterIterator, or FeatureReaderIterator over content.
+     * <p>
+     * If you have a way to tell that you are readonly please subclass with
+     * a less hardcore check - this implementations catches a
+     * UnsupportedOpperationsException from wrtier()!
+     * 
+     * @return Iterator, should be closed closeIterator 
+     */
+    protected Iterator<SimpleFeature> openIterator() throws IOException
+    {    	
+    	try {
+    	    FeatureWriter writer = writer();
+    	    if(writer != null) {
+    	        return new FeatureWriterIterator( writer() );
+    	    }
+        } catch (IOException badWriter) {
+            return new NoContentIterator( badWriter );
+        } catch( UnsupportedOperationException readOnly ){
+        }
+        
+        try {
+            return new FeatureReaderIterator( reader() );
+        } catch (IOException e) {
+            return new NoContentIterator( e );
+        }        
+    }
+
+    final public void close( Iterator<SimpleFeature> close ) {
+    	try {
+			closeIterator( close );
+		} 
+    	catch (IOException e) {
+			LOGGER.log( Level.WARNING, "Error closing iterator", e );
+		}
+    	open.remove( close );
+    }   
+    
+    protected void closeIterator( Iterator<SimpleFeature> close ) throws IOException
+    {
+    	if( close == null ){
+            // iterator probably failed during consturction !
+        }
+        else if( close instanceof FeatureReaderIterator ){
+            FeatureReaderIterator<SimpleFeature> iterator = (FeatureReaderIterator<SimpleFeature>) close;
+            iterator.close(); // only needs package visability
+        }
+        else if( close instanceof FeatureWriterIterator ){
+            FeatureWriterIterator iterator = (FeatureWriterIterator) close;
+            iterator.close(); // only needs package visability
+        }
+    }
+    
+    public void close( FeatureIterator<SimpleFeature> iterator) {
+    	iterator.close();
+        open.remove( iterator );        
+    }
+
+   
+    
+    /** Default implementation based on getCount() - this may be expensive */
+    public int size() {
+        try {
+            return getCount();
+        } catch (IOException e) {
+            if (LOGGER.isLoggable(Level.FINE))
+                LOGGER.log(Level.FINE, "IOException while calculating size() of FeatureCollection", e);
+            return 0;
+        }
+    }
+    public void purge(){    	
+    	for( Iterator i = open.iterator(); i.hasNext(); ){
+    		Object iterator =  i.next();
+    		try {
+    			if( iterator instanceof Iterator ){
+    				closeIterator( (Iterator) iterator );
+    			}
+    			if( iterator instanceof FeatureIterator){
+    				( (SimpleFeatureIterator) iterator ).close();
+    			}
+    		}
+    		catch( Throwable e){
+    			// TODO: Log e = ln
+    		}
+    		finally {
+    			i.remove();
+    		}
+    	}
+    }
+    //
+    // Off into implementation land!
+    //
+    /**
+     * Default implementation based on creating an reader, testing hasNext, and closing.
+     * <p>
+     * For once the Collections API does not give us an escape route, we *have* to check the data.
+     * </p>
+     */
+    public boolean isEmpty() {
+         FeatureReader<SimpleFeatureType, SimpleFeature> reader = null;
+        try {
+            reader = reader();
+            try {
+                return !reader.hasNext();
+            } catch (IOException e) {
+                return true; // error seems like no features are available 
+            }
+        } catch (IOException e) {
+            return true;
+        }
+        finally {
+            if( reader != null ){
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    // return value already set
+                }
+            }
+        }
+    }
+
+    public boolean contains( Object o ) {
+        if( !(o instanceof SimpleFeature) ) return false;
+        SimpleFeature value = (SimpleFeature) o;
+        String ID = value.getID();
+        
+         FeatureReader<SimpleFeatureType, SimpleFeature> reader = null;
+        try {
+            reader = reader();
+            try {
+                while( reader.hasNext() ){
+                    SimpleFeature feature = reader.next();
+                    if( !ID.equals( feature.getID() )){
+                        continue; // skip with out full equal check
+                    }
+                    if( value.equals( feature )) return true;
+                }
+                return false; // not found
+            } catch (IOException e) {
+                return false; // error seems like no features are available 
+            } catch (NoSuchElementException e) {
+                return false; // error seems like no features are available
+            } catch (IllegalAttributeException e) {
+                return false; // error seems like no features are available
+            }
+        } catch (IOException e) {
+            return false;
+        }
+        finally {
+            if( reader != null ){
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    // return value already set
+                }
+            }
+        }
+    }
+
+    public Object[] toArray() {
+        return toArray( new SimpleFeature[ size() ]);
+    }
+
+    public Object[] toArray( Object[] array ) {
+        List list = new ArrayList();
+        Iterator i = iterator();
+        try {
+            while( i.hasNext() ){
+                list.add( i.next() );
+            }
+        }
+        finally {
+            close( i );
+        }
+        return list.toArray( array );
+    }
+
+    public boolean add( SimpleFeature arg0 ) {
+        return false;
+    }
+
+    public boolean remove( Object arg0 ) {
+        return false;
+    }
+
+    public boolean containsAll( Collection<?> collection ) {
+    	for (Object o: collection) {
+    		if (contains(o)==false) return false;
+    	}
+    	return true;
+    }
+
+    /**
+     * Optimized implementation of addAll that recognizes the
+     * use of collections obtained with subCollection( filter ).
+     * <p>
+     * This method is constructed by either:
+     * <ul>
+     * <li>Filter OR
+     * <li>Removing an extact match of Filter AND
+     * </ul>
+     * 
+     */
+    public boolean addAll(Collection collection) {
+        if( collection instanceof FeatureCollection ){
+            return addAll( (FeatureCollection<?,?>) collection );
+        }
+        try {
+            FeatureWriter writer = writer();
+            if(writer == null) {
+                return false;
+            }
+            try {
+                // skip to end
+                 while( writer.hasNext() ){
+                    /*Feature feature =*/ writer.next();
+                }
+                for( Object obj : collection ){
+                    if( obj instanceof SimpleFeature){
+                        SimpleFeature copy = (SimpleFeature) obj;
+                        SimpleFeature feature = (SimpleFeature) writer.next();
+                        
+                        feature.setAttributes( copy.getAttributes() );
+                        writer.write();
+                    }
+                }
+            }
+            finally {
+                /*if( writer != null )*/ writer.close();
+            }
+            return true;
+        }
+        catch( IOException ignore ){
+            return false;
+        }
+    }
+    public boolean addAll(FeatureCollection resource) {
+        return false;
+    }
+    public boolean removeAll( Collection arg0 ) {        
+        return false;
+    }
+    public boolean retainAll( Collection arg0 ) {
+        return false;
+    }
+    public void clear() {        
+    }
+    
+    public void accepts(org.opengis.feature.FeatureVisitor visitor, org.opengis.util.ProgressListener progress) {
+    	Iterator iterator = null;
+        if (progress == null) progress = new NullProgressListener();
+        try{
+            float size = size();
+            float position = 0;            
+            progress.started();
+        	for( iterator = iterator(); !progress.isCanceled() && iterator.hasNext(); progress.progress( 100.0f * position++ / size )){
+                try {
+                    SimpleFeature feature = (SimpleFeature) iterator.next();
+                    visitor.visit(feature);
+                }
+                catch( Exception erp ){
+                    progress.exceptionOccurred( erp );
+                }
+	        }            
+        }
+        finally {
+            progress.complete();            
+        	close( iterator );
+        }
+    }
+    
+    /**
+     * Will return an optimized subCollection based on access
+     * to the origional FeatureSource.
+     * <p>
+     * The subCollection is constructed by using an AND Filter.
+     * For the converse of this opperation please see
+     * collection.addAll( Collection ), it has been optimized
+     * to be aware of these filter based SubCollections.
+     * </p>
+     * <p>
+     * This method is intended in a manner similar to subList,
+     * example use:
+     * <code>
+     * collection.subCollection( myFilter ).clear()
+     * </code>
+     * </p>    
+     * @param filter Filter used to determine sub collection.
+     * @since GeoTools 2.2, Filter 1.1
+     */
+    public SimpleFeatureCollection subCollection(Filter filter) {
+        if( filter == Filter.INCLUDE ){
+            return this;
+        }        
+    	return new SubFeatureCollection( this, filter );
+    }
+
+    public String getID() {
+    	return id;
+    }
+
+    public SimpleFeatureType getSchema() {
+    	return schema;
+    }
+ 
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/EmptyFeatureCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/EmptyFeatureCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/EmptyFeatureCollection.java	(revision 28000)
@@ -0,0 +1,73 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.store;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+public class EmptyFeatureCollection extends DataFeatureCollection {
+
+	/**
+	 * null bounds
+	 */
+	static ReferencedEnvelope bounds = new ReferencedEnvelope(new Envelope(),null);
+	static {
+		bounds.setToNull();
+	}
+	
+	public EmptyFeatureCollection( SimpleFeatureType schema ) {
+		super(null,schema);
+	}
+	
+	
+	public ReferencedEnvelope getBounds() {
+		return bounds;
+	}
+
+	public int getCount() throws IOException {
+		return 0;
+	}
+
+	protected Iterator openIterator() {
+		return new EmptyIterator();
+	}
+	
+	protected void closeIterator(Iterator close) {
+		//do nothing
+	}
+	
+	//read only access
+	public boolean add(SimpleFeature object) {
+		return false;
+	}
+	
+	
+	public boolean remove(Object object) {
+		return false;
+	}
+	
+	public boolean removeAll(Collection collection) {
+		return false;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/EmptyIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/EmptyIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/EmptyIterator.java	(revision 28000)
@@ -0,0 +1,43 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.store;
+
+import java.util.Iterator;
+
+/**
+ * An iterator that returns no content.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/store/EmptyIterator.java $
+ */
+public class EmptyIterator implements Iterator {
+
+	public void remove() {
+	}
+
+	public boolean hasNext() {
+		return false;
+	}
+
+	public Object next() {
+		return null;
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/FeatureWriterIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/FeatureWriterIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/FeatureWriterIterator.java	(revision 28000)
@@ -0,0 +1,103 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.store;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.geotools.data.FeatureWriter;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+/**
+ * An iterator wrapper for a FeatureWriter - for use with
+ * an AbstractFeatureCollection.
+ * <p>
+ * There is no reason modify this class, subclasses that wish
+ * to work with a custom iterator need just that - a custom iterator.
+ * <p>
+ * <p>
+ * The use of this class against a SimpleFeatureSource not backed by
+ * a Transaction may *really* cut into performance. Consider if
+ * you will the overhead involved in writing out each feature into
+ * a temporary file (when the user may not even modify anything).
+ * </p>
+ * @author jgarnett
+ * @since 2.1.RC0
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/store/FeatureWriterIterator.java $
+ */
+final class FeatureWriterIterator implements Iterator<SimpleFeature> {
+    FeatureWriter<SimpleFeatureType, SimpleFeature> writer;    
+    public FeatureWriterIterator( FeatureWriter<SimpleFeatureType, SimpleFeature> writer ){
+        this.writer = writer;
+    }
+    public boolean hasNext() {
+        try {
+            if( writer == null ) {
+                return false;
+            }
+            writer.write(); // write out any "changes" made
+            if( writer.hasNext() ){
+                return true;
+            }
+            else {
+                close();
+                return false;
+                // auto close because we don't trust client
+                // code to call close 
+            }
+        } catch (IOException e) {
+            close();
+            return false; // failure sounds like lack of next to me
+        }        
+    }
+
+    public SimpleFeature next() {
+        if( writer == null ) {
+            throw new NoSuchElementException( "Iterator has been closed" );            
+        }
+        try {
+            return writer.next();
+        } catch (IOException io) {
+            NoSuchElementException problem = new NoSuchElementException( "Could not obtain the next feature:"+io );
+            problem.initCause( io );
+            throw problem;
+        }       
+    }
+    public void remove() {
+        try {
+            writer.remove();
+        } catch (IOException problem) {
+            throw (IllegalStateException) new IllegalStateException( "Could not remove feature" ).initCause( problem ); 
+        }        
+    }
+    /**
+     * This method only needs package visability as only AbstractFeatureCollection
+     * is trusted enough to call it.
+     */
+    void close(){
+        if( writer != null){
+            try {
+                writer.close();
+            } catch (IOException e) {
+                // sorry but iterators die quitely in the night
+            }
+            writer = null;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/FilteringIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/FilteringIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/FilteringIterator.java	(revision 28000)
@@ -0,0 +1,84 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.store;
+
+import java.util.Iterator;
+
+import org.opengis.feature.Feature;
+import org.opengis.filter.Filter;
+
+/**
+ * Decorates a {@link org.geotools.feature.Feature} iterator with one that
+ * filters content.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/store/FilteringIterator.java $
+ */
+public class FilteringIterator<F extends Feature> implements Iterator<F> {
+
+	/**
+	 * Delegate iterator
+	 */
+	Iterator<F> delegate;
+	/**
+	 * The Filter
+	 */
+	Filter filter;
+	/**
+	 * Next feature
+	 */
+	F next;
+	
+	public FilteringIterator( Iterator<F> delegate, Filter filter ) {
+		this.delegate = delegate;
+		this.filter = filter;
+	}
+	
+	public Iterator<F> getDelegate() {
+		return delegate;
+	}
+	
+	public void remove() {
+		delegate.remove();
+	}
+
+	public boolean hasNext() {
+		if ( next != null ) {
+			return true;
+		}
+		
+		while( delegate.hasNext() ) {
+			F peek =  delegate.next();
+			if ( filter.evaluate( peek ) ) {
+				next = peek;
+				break;
+			}
+		}
+		
+		return next != null;
+	}
+
+	public F next() {
+		F f = next;
+		next = null;
+		return f;
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/MaxFeaturesIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/MaxFeaturesIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/MaxFeaturesIterator.java	(revision 28000)
@@ -0,0 +1,89 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.store;
+
+import java.util.Iterator;
+
+import org.opengis.feature.Feature;
+
+/**
+ * Iterator wrapper which caps the number of returned features;
+ * 
+ * @author Justin Deoliveira, The Open Planning Project
+ * 
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/store/MaxFeaturesIterator.java $
+ *         http://svn.osgeo.org/geotools/trunk/modules/library/main/src/main/java/org/geotools/
+ *         data/store/MaxFeaturesIterator.java $
+ */
+public class MaxFeaturesIterator<F extends Feature> implements Iterator<F> {
+
+    Iterator<F> delegate;
+
+    long start;
+
+    long end;
+
+    long counter;
+
+    public MaxFeaturesIterator(Iterator<F> delegate, long start, long max) {
+        this.delegate = delegate;
+        this.start = start;
+        this.end = start + max;
+        counter = 0;
+    }
+
+    public Iterator<F> getDelegate() {
+        return delegate;
+    }
+
+    public void remove() {
+        delegate.remove();
+    }
+
+    public boolean hasNext() {
+        if (counter < start) {
+            // skip to just before start if needed
+            skip();
+        }
+        return delegate.hasNext() && counter < end;
+    }
+
+    public F next() {
+        if (counter < start) {
+            // skip to just before start if needed
+            skip();
+        }
+        if (counter <= end) {
+            counter++;
+            F next = delegate.next();
+            return next;
+        }
+        return null;
+    }
+
+    private void skip() {
+        if (counter < start) {
+            while (delegate.hasNext() && counter < start) {
+                counter++;
+                /*F skip =*/ delegate.next(); // skip!
+            }
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/NoContentIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/NoContentIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/NoContentIterator.java	(revision 28000)
@@ -0,0 +1,71 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.store;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.opengis.feature.simple.SimpleFeature;
+
+/**
+ * This iterator is used to indicate that contents could not be aquired.
+ * <p>
+ * The normal Collection.iterator() method does not let us return an error
+ * (we always have to return an iterator). However Iterator.next() can
+ * be used to return an NoSuchElementException.
+ * </p>
+ * <p>
+ * So we are basically going to lie, we are going to pretend their is content
+ * *once*, and when they ask for it we are going to hit them with
+ * a NoSuchElementExcetion. This is a mean trick, but it does convey the idea
+ * of asking for content that is supposed to be there and failing to aquire it.
+ * </p>
+ * @author jgarnett
+ * @since 2.1.RC0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/store/NoContentIterator.java $
+ */
+public class NoContentIterator implements Iterator<SimpleFeature> {
+    Throwable origionalProblem;
+    public NoContentIterator( Throwable t ){
+        origionalProblem = t;
+    }
+    public boolean hasNext() {
+        return origionalProblem != null;
+    }
+    public SimpleFeature next() {
+        if( origionalProblem == null ){
+            // you only get the real error on the first offense
+            // (after that you are just silly)
+            //
+            throw new NoSuchElementException();            
+        }
+        NoSuchElementException cantFind = new NoSuchElementException( "Could not aquire feature:" + origionalProblem );
+        cantFind.initCause( origionalProblem );
+        origionalProblem = null;
+        throw cantFind;
+    }
+
+    public void remove() {
+        if( origionalProblem == null ){
+            // user did not call next first
+            throw new UnsupportedOperationException();
+        }
+        // User did not call next first
+        throw new IllegalStateException();        
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/ReTypingFeatureCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/ReTypingFeatureCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/ReTypingFeatureCollection.java	(revision 28000)
@@ -0,0 +1,63 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.store;
+
+import java.util.Iterator;
+
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.feature.collection.DecoratingSimpleFeatureCollection;
+import org.geotools.feature.collection.DelegateSimpleFeatureIterator;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+/**
+ * SimpleFeatureCollection decorator which decorates a feature collection "re-typing" 
+ * its schema based on attributes specified in a query.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/store/ReTypingFeatureCollection.java $
+ */
+public class ReTypingFeatureCollection extends DecoratingSimpleFeatureCollection {
+
+	SimpleFeatureType featureType;
+    
+	public ReTypingFeatureCollection ( SimpleFeatureCollection delegate, SimpleFeatureType featureType ) {
+		super(delegate);
+		this.featureType = featureType;
+	}
+	
+	public SimpleFeatureType getSchema() {
+	    return featureType;
+	}
+		
+	public SimpleFeatureIterator features() {
+		return new DelegateSimpleFeatureIterator( this, iterator() );
+	}
+
+	public Iterator<SimpleFeature> iterator() {
+		return new ReTypingIterator( delegate.iterator(), delegate.getSchema(), featureType );
+	}
+	
+	public void close(Iterator close) {
+		ReTypingIterator reType = (ReTypingIterator) close;
+		delegate.close( reType.getDelegate() );
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/ReTypingIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/ReTypingIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/ReTypingIterator.java	(revision 28000)
@@ -0,0 +1,130 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.store;
+
+import java.util.Iterator;
+
+import org.geotools.feature.IllegalAttributeException;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+
+/**
+ * Iterator wrapper which re-types features on the fly based on a target 
+ * feature type.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/store/ReTypingIterator.java $
+ */
+public class ReTypingIterator implements Iterator {
+
+	/**
+	 * The delegate iterator
+	 */
+	Iterator delegate;
+		
+	/**
+	 * The matching types from target 
+	 */
+	AttributeDescriptor[] types;
+	
+	SimpleFeatureBuilder builder;
+	
+	public ReTypingIterator( Iterator delegate, SimpleFeatureType source, SimpleFeatureType target ) {
+		this.delegate = delegate;
+		types = typeAttributes( source, target );
+		this.builder = new SimpleFeatureBuilder(target);
+	}
+	
+	public Iterator getDelegate() {
+		return delegate;
+	}
+
+	public void remove() {
+		delegate.remove();
+	}
+
+	public boolean hasNext() {
+		return delegate.hasNext();
+	}
+
+	public Object next() {
+		SimpleFeature next = (SimpleFeature) delegate.next();
+        String id = next.getID();
+
+        try {
+			for (int i = 0; i < types.length; i++) {
+			    final String xpath = types[i].getLocalName();
+			    builder.add(next.getAttribute(xpath));
+			}
+			
+			return builder.buildFeature(id);
+		} 
+        catch (IllegalAttributeException e) {
+        	throw new RuntimeException( e );
+		}
+	}
+	
+	 /**
+     * Supplies mapping from origional to target FeatureType.
+     * 
+     * <p>
+     * Will also ensure that origional can cover target
+     * </p>
+     *
+     * @param target Desired FeatureType
+     * @param origional Origional FeatureType
+     *
+     * @return Mapping from originoal to target FeatureType
+     *
+     * @throws IllegalArgumentException if unable to provide a mapping
+     */
+    protected AttributeDescriptor[] typeAttributes(SimpleFeatureType original,
+        SimpleFeatureType target) {
+        if (target.equals(original)) {
+            throw new IllegalArgumentException(
+                "FeatureReader allready produces contents with the correct schema");
+        }
+
+        if (target.getAttributeCount() > original.getAttributeCount()) {
+            throw new IllegalArgumentException(
+                "Unable to retype  FeatureReader<SimpleFeatureType, SimpleFeature> (origional does not cover requested type)");
+        }
+
+        String xpath;
+        AttributeDescriptor[] types = new AttributeDescriptor[target.getAttributeCount()];
+
+        for (int i = 0; i < target.getAttributeCount(); i++) {
+            AttributeDescriptor attrib = target.getDescriptor(i);
+            xpath = attrib.getLocalName();
+            types[i] = attrib;
+
+            if (!attrib.equals(original.getDescriptor(xpath))) {
+                throw new IllegalArgumentException(
+                    "Unable to retype  FeatureReader<SimpleFeatureType, SimpleFeature> (origional does not cover "
+                    + xpath + ")");
+            }
+        }
+
+        return types;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/ReprojectingFeatureCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/ReprojectingFeatureCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/ReprojectingFeatureCollection.java	(revision 28000)
@@ -0,0 +1,224 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.store;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.feature.FeatureTypes;
+import org.geotools.feature.SchemaException;
+import org.geotools.feature.collection.DecoratingSimpleFeatureCollection;
+import org.geotools.feature.collection.DelegateSimpleFeatureIterator;
+import org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.referencing.CRS;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.filter.sort.SortBy;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * SimpleFeatureCollection decorator that reprojects the default geometry.
+ * 
+ * @author Justin
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/data/store/ReprojectingFeatureCollection.java $
+ */
+public class ReprojectingFeatureCollection extends DecoratingSimpleFeatureCollection {
+
+    /**
+     * The transform to the target coordinate reference system
+     */
+    MathTransform transform;
+
+    /**
+     * The schema of reprojected features
+     */
+    SimpleFeatureType schema;
+
+    /**
+     * The target coordinate reference system
+     */
+    CoordinateReferenceSystem target;
+    
+    /**
+     * Transformer used to transform geometries;
+     */
+    GeometryCoordinateSequenceTransformer transformer;
+    
+    public ReprojectingFeatureCollection(SimpleFeatureCollection delegate,
+            CoordinateReferenceSystem target) {
+        this( delegate, delegate.getSchema().getGeometryDescriptor().getCoordinateReferenceSystem(), target );
+    }
+    
+    public ReprojectingFeatureCollection(
+            SimpleFeatureCollection delegate,
+            CoordinateReferenceSystem source, CoordinateReferenceSystem target) {
+        super(delegate);
+        this.target = target;
+        SimpleFeatureType schema = delegate.getSchema();
+        this.schema = reType(schema, target);
+       
+        if (source == null) {
+            throw new NullPointerException("source crs");
+        }
+        if ( target == null ) {
+        	throw new NullPointerException("destination crs");
+        }
+        
+        this.transform = transform(source, target);
+        transformer = new GeometryCoordinateSequenceTransformer();
+    }
+
+    private MathTransform transform(CoordinateReferenceSystem source,
+            CoordinateReferenceSystem target) {
+        try {
+            return CRS.findMathTransform(source, target);
+        } catch (FactoryException e) {
+            throw new IllegalArgumentException(
+                    "Could not create math transform");
+        }
+    }
+
+    private SimpleFeatureType reType(SimpleFeatureType type,
+            CoordinateReferenceSystem target) {
+        try {
+            return FeatureTypes.transform(type, target);
+        } catch (SchemaException e) {
+            throw new IllegalArgumentException(
+                    "Could not transform source schema", e);
+        }
+    }
+
+    public SimpleFeatureIterator features() {
+        return new DelegateSimpleFeatureIterator(this, iterator());
+    }
+
+    public Iterator<SimpleFeature> iterator() {
+        try {
+            return new ReprojectingIterator(delegate.iterator(), transform, schema, transformer);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void close(Iterator close) {
+        Iterator iterator = ((ReprojectingIterator) close).getDelegate();
+        delegate.close(iterator);
+    }
+
+    public SimpleFeatureType getSchema() {
+        return this.schema;
+    }
+
+    public SimpleFeatureCollection subCollection(Filter filter) {
+        Filter unFilter = unFilter(filter);
+        return new ReprojectingFeatureCollection(delegate
+                .subCollection(unFilter), target);
+        // TODO: return new delegate.subCollection( filter ).reproject( target
+        // );
+    }
+
+    /**
+     * Takes any literal geometry in the provided filter and backprojects it
+     * 
+     * @param FilterFactory
+     * @param MathTransform
+     */
+    private Filter unFilter(Filter filter) {
+        // need: filterFactory
+        // need: inverse of our transform
+        // FilterVisitor fv = new ReprojectingFilterVisitor(ff, transform);
+        // filter.accept(fv, null);
+        // TODO: create FilterVisitor that backproject literal geometry
+        return filter;
+    }
+
+    public SimpleFeatureCollection sort(SortBy order) {
+        // return new ReprojectingFeatureList( delegate.sort( order ), target );
+        throw new UnsupportedOperationException("Not yet");
+    }
+
+    public Object[] toArray() {
+        return toArray(new Object[size()]);
+    }
+
+    public Object[] toArray(Object[] a) {
+        List list = new ArrayList();
+        Iterator i = iterator();
+        try {
+            while (i.hasNext()) {
+                list.add(i.next());
+            }
+
+            return list.toArray(a);
+        } finally {
+            close(i);
+        }
+    }
+
+    public boolean add(SimpleFeature o) {
+        // must back project any geometry attributes
+        throw new UnsupportedOperationException("Not yet");
+        // return delegate.add( o );
+    }
+
+    /**
+     * This method computes reprojected bounds the hard way, but computing them
+     * feature by feature. This method could be faster if computed the
+     * reprojected bounds by reprojecting the original feature bounds a Shape
+     * object, thus getting the true shape of the reprojected envelope, and then
+     * computing the minimum and maximum coordinates of that new shape. The
+     * result would not a true representation of the new bounds.
+     * 
+     * @see org.geotools.data.FeatureResults#getBounds()
+     */
+    public ReferencedEnvelope getBounds() {
+        SimpleFeatureIterator r = features();
+        try {
+            Envelope newBBox = new Envelope();
+            Envelope internal;
+            SimpleFeature feature;
+
+            while (r.hasNext()) {
+                feature = r.next();
+                final Geometry geom = ((Geometry)feature.getDefaultGeometry());
+                if(geom != null) {
+                    internal = geom.getEnvelopeInternal();
+                    newBBox.expandToInclude(internal);
+                }
+            }
+            return ReferencedEnvelope.reference(newBBox);
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    "Exception occurred while computing reprojected bounds", e);
+        } finally {
+            r.close();
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/ReprojectingIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/ReprojectingIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/data/store/ReprojectingIterator.java	(revision 28000)
@@ -0,0 +1,113 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.data.store;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import org.geotools.factory.FactoryRegistryException;
+import org.geotools.feature.IllegalAttributeException;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.OperationNotFoundException;
+import org.opengis.referencing.operation.TransformException;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+public class ReprojectingIterator implements Iterator {
+
+    /**
+     * decorated iterator
+     */
+    Iterator delegate;
+
+    /**
+     * schema of reprojected features
+     */
+    SimpleFeatureType schema;
+
+    /**
+     * Transformer
+     */
+    GeometryCoordinateSequenceTransformer tx;
+
+    public ReprojectingIterator(
+		Iterator delegate, MathTransform transform, SimpleFeatureType schema, 
+		GeometryCoordinateSequenceTransformer transformer
+    ) throws OperationNotFoundException, FactoryRegistryException, FactoryException {
+        this.delegate = delegate;
+        
+        this.schema = schema;
+
+        tx = transformer;
+        tx.setMathTransform(transform);
+    }
+
+    public Iterator getDelegate() {
+        return delegate;
+    }
+
+    public void remove() {
+        delegate.remove();
+    }
+
+    public boolean hasNext() {
+        return delegate.hasNext();
+    }
+
+    public Object next() {
+        SimpleFeature feature = (SimpleFeature) delegate.next();
+        try {
+            return reproject(feature);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    SimpleFeature reproject(SimpleFeature feature) throws IOException {
+
+        List attributes = feature.getAttributes();
+
+        for (int i = 0; i < attributes.size(); i++) {
+            Object object = attributes.get(i);
+            if (object instanceof Geometry) {
+                // do the transformation
+                Geometry geometry = (Geometry) object;
+                try {
+                    attributes.set(i, tx.transform(geometry));
+                } catch (TransformException e) {
+                    String msg = "Error occured transforming "
+                            + geometry.toString();
+                    throw (IOException) new IOException(msg).initCause(e);
+                }
+            }
+        }
+
+        try {
+            return SimpleFeatureBuilder.build(schema, attributes, feature.getID());
+        } catch (IllegalAttributeException e) {
+            String msg = "Error creating reprojeced feature";
+            throw (IOException) new IOException(msg).initCause(e);
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/AbstractFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/AbstractFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/AbstractFactory.java	(revision 28000)
@@ -0,0 +1,467 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.IdentityHashMap;
+import java.util.Collections;
+import java.util.Iterator;
+import java.io.Writer;
+import java.io.IOException;
+import java.awt.RenderingHints;
+import javax.imageio.spi.ServiceRegistry;
+import javax.imageio.spi.RegisterableService;
+
+import org.opengis.referencing.AuthorityFactory;
+import org.geotools.util.Utilities;
+import org.geotools.io.TableWriter;
+import org.geotools.resources.Classes;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * Skeletal implementation of factories. This base classe provides no {@code createFoo} methods,
+ * (they must be provided by subclasses), but provides two convenience features:
+ * <p>
+ * <ul>
+ *   <li>An initially empty {@linkplain #hints map of hints} to be filled by subclasses
+ *       constructors. They are the hints to be returned by {@link #getImplementationHints}.</li>
+ *   <li>An automatic {@linkplain ServiceRegistry#setOrdering ordering} applied
+ *       on the basis of subclasses-provided {@linkplain #priority} rank.</li>
+ * </ul>
+ * <p>
+ * When more than one factory implementation is
+ * {@linkplain ServiceRegistry#registerServiceProvider registered} for the same category (i.e. they
+ * implement the same {@link Factory} sub-interface), the actual instance to be used is selected
+ * according their {@linkplain ServiceRegistry#setOrdering ordering} and user-supplied
+ * {@linkplain Hints hints}. Hints have precedence. If more than one factory matches the hints
+ * (including the common case where the user doesn't provide any hint at all), then ordering
+ * matter.
+ * <p>
+ * The ordering is unspecified for every pairs of factories with the same {@linkplain #priority}.
+ * This implies that the ordering is unspecified between all factories created with the
+ * {@linkplain #AbstractFactory() default constructor}, since they all have the same
+ * {@linkplain #NORMAL_PRIORITY default priority} level.
+ *
+ * <h3>How hints are set</h3>
+ * Hints are used for two purposes. The distinction is important because the set
+ * of hints may not be identical in both cases:
+ * <p>
+ * <ol>
+ *   <li>Hints are used for creating new factories.</li>
+ *   <li>Hints are used in order to check if an <em>existing</em> factory is suitable.</li>
+ * </ol>
+ * <p>
+ * {@code AbstractFactory} do <strong>not</strong> provides any facility for the first case.
+ * Factories implementations shall inspect themselves all relevant hints supplied by the user,
+ * and pass them to any dependencies. Do <strong>not</strong> use the {@link #hints} field for
+ * that; use the hints provided by the user in the constructor. If all dependencies are created
+ * at construction time (<cite>constructor injection</cite>), there is no need to keep user's hints
+ * once the construction is finished.
+ * <p>
+ * The {@link #hints} field is for the second case only. Implementations shall copy in this
+ * field only the user's hints that are know to be relevant to this factory. If a hint is
+ * relevant but the user didn't specified any value, the hint key should be added to the
+ * {@link #hints} map anyway with a {@code null} value. Only direct dependencies shall be put
+ * in the {@link #hints} map. Indirect dependencies (i.e. hints used by other factories used
+ * by this factory) will be inspected automatically by {@link FactoryRegistry} in a recursive way.
+ * <p>
+ * <strong>Note:</strong> The lack of constructor expecting a {@link Map} argument is intentional.
+ * This is in order to discourage blind-copy of all user-supplied hints to the {@link #hints} map.
+ * <p>
+ * <strong>Example:</strong> Lets two factories, A and B. Factory A need an instance of Factory B.
+ * Factory A can be implemented as below:
+ *
+ * <table border='1'>
+ * <tr><th>Code</th><th>Observations</th></tr>
+ * <tr><td><blockquote><pre>
+ * class FactoryA extends AbstractFactory {
+ *     FactoryB fb;
+ *
+ *     FactoryA(Hints userHints) {
+ *         fb = FactoryFinder.getFactoryB(userHints);
+ *         hints.put(Hints.FACTORY_B, fb);
+ *     }
+ * }
+ * </pre></blockquote></td>
+ * <td>
+ * <ul>
+ *   <li>The user-supplied map ({@code userHints}) is never modified.</li>
+ *   <li>All hints relevant to other factories are used in the constructor. Hints relevant to
+ *       factory B are used when {@code FactoryFinder.getFactoryB(...)} is invoked.</li>
+ *   <li>The {@code FactoryA} constructor stores only the hints relevant to {@code FactoryA}.
+ *       Indirect dependencies (e.g. hints relevant to {@code FactoryB}) will be inspected
+ *       recursively by {@link FactoryRegistry}.</li>
+ *   <li>In the above example, {@link #hints} will never be used for creating new factories.</li>
+ * </ul>
+ * </td></tr></table>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/AbstractFactory.java $
+ * @version $Id: AbstractFactory.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ */
+public class AbstractFactory implements Factory, RegisterableService {
+    /**
+     * The minimum priority for a factory, which is {@value}. Factories with lowest priority
+     * will be used only if there is no other factory in the same
+     * {@linkplain ServiceRegistry#getCategories category}.
+     *
+     * @see #priority
+     * @see #onRegistration
+     */
+    public static final int MINIMUM_PRIORITY = 1;
+
+    /**
+     * The default priority, which is {@value}.
+     *
+     * @see #priority
+     * @see #onRegistration
+     */
+    public static final int NORMAL_PRIORITY = 50;
+
+    /**
+     * The maximum priority for a factory, which is {@value}. Factories with highest
+     * priority will be preferred to any other factory in the same
+     * {@linkplain ServiceRegistry#getCategories category}.
+     *
+     * @see #priority
+     * @see #onRegistration
+     */
+    public static final int MAXIMUM_PRIORITY = 100;
+
+    /**
+     * The priority for this factory, as a number between {@link #MINIMUM_PRIORITY} and
+     * {@link #MAXIMUM_PRIORITY} inclusive. Priorities are used by {@link FactoryRegistry}
+     * for selecting a preferred factory when many are found for the same service.
+     *
+     * @see #getPriority
+     *
+     * @todo Consider deprecating this field. See
+     * <A HREF="http://jira.codehaus.org/browse/GEOT-1100">GEOT-1100</A> for details.
+     */
+    protected final int priority;
+
+    /**
+     * The {@linkplain Factory#getImplementationHints implementation hints}. This map should be
+     * filled by subclasses at construction time. If possible, constructors should not copy blindly
+     * all user-provided hints. They should select only the relevant hints and resolve them as of
+     * {@linkplain Factory#getImplementationHints implementation hints} contract.
+     * <p>
+     * <b>Note:</b> This field is not an instance of {@link Hints} because:
+     * <ul>
+     *   <li>The primary use of this map is to check if this factory can be reused.
+     *       It is not for creating new factories.</li>
+     *   <li>This map needs to allow {@code null} values, as of
+     *       {@linkplain Factory#getImplementationHints implementation hints} contract.</li>
+     * </ul>
+     */
+    protected final Map<RenderingHints.Key, Object> hints =
+            new LinkedHashMap<RenderingHints.Key, Object>();
+
+    /**
+     * An unmodifiable view of {@link #hints}. This is the actual map to be returned
+     * by {@link #getImplementationHints}. Its content reflects the {@link #hints}
+     * map even if the later is modified.
+     */
+    private final Map<RenderingHints.Key, Object> unmodifiableHints =
+            Collections.unmodifiableMap(hints);
+
+    /**
+     * Creates a new factory with the {@linkplain #NORMAL_PRIORITY default priority}.
+     */
+    protected AbstractFactory() {
+        this(NORMAL_PRIORITY);
+    }
+
+    /**
+     * Constructs a factory with the specified priority.
+     *
+     * @param priority The priority for this factory, as a number between
+     *        {@link #MINIMUM_PRIORITY} and {@link #MAXIMUM_PRIORITY} inclusive.
+     */
+    protected AbstractFactory(final int priority) {
+    	this.priority = priority;
+        if (priority<MINIMUM_PRIORITY || priority>MAXIMUM_PRIORITY) {
+            throw new IllegalArgumentException(
+                    Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2, "priority", priority));
+        }
+    }
+
+    /**
+     * Returns the priority for this factory, as a number between {@link #MINIMUM_PRIORITY} and
+     * {@link #MAXIMUM_PRIORITY} inclusive. Priorities are used by {@link FactoryRegistry} for
+     * selecting a preferred factory when many are found for the same service. The default
+     * implementation returns {@link #priority} with no change. Subclasses should override
+     * this method if they want to return a higher or lower priority.
+     *
+     * @since 2.3
+     */
+    public int getPriority() {
+        return priority;
+    }
+
+    /**
+     * Adds the specified hints to this factory {@linkplain #hints}. This method can be used
+     * as a replacement for <code>{@linkplain #hints}.putAll(map)</code> when the map is an
+     * instance of {@link Hints} - the above was allowed in Java 4, but is no longuer allowed
+     * since Java 5 and parameterized types.
+     *
+     * @param map The hints to add.
+     * @return {@code true} if at least one value changed as a result of this call.
+     *
+     * @since 2.5
+     */
+    protected boolean addImplementationHints(final RenderingHints map) {
+        /*
+         * Do NOT change the parameter signature to Map<?,?>. We want to keep type safety.
+         * Use hints.putAll(...) if you have a Map<RenderingHints.Key,?>,  or this method
+         * if you have a RenderingHints map. Furthermore this method implementation needs
+         * the garantee that the map do not contains null value (otherwise the 'changed'
+         * computation could be inacurate) - this condition is enforced by RenderingHints
+         * but not by Map.
+         *
+         * The implementation below strips non-RenderingHints.Key as a paranoiac check,
+         * which should not be necessary since RenderingHints implementation prevented
+         * that. If the parameter was changed to Map<?,?>, the stripping would be more
+         * likely and could surprise the user since it is performed without warnings.
+         */
+        boolean changed = false;
+        if (map != null) {
+            for (final Map.Entry<?,?> entry : map.entrySet()) {
+                final Object key = entry.getKey();
+                if (key instanceof RenderingHints.Key) {
+                    final Object value = entry.getValue();
+                    final Object old = hints.put((RenderingHints.Key) key, value);
+                    if (!changed && !Utilities.equals(value, old)) {
+                        changed = true;
+                    }
+                }
+            }
+        }
+        return changed;
+    }
+
+    /**
+     * Returns an {@linkplain Collections#unmodifiableMap unmodifiable} view of
+     * {@linkplain #hints}.
+     *
+     * @return The map of hints, or an empty map if none.
+     */
+    public Map<RenderingHints.Key, ?> getImplementationHints() {
+        return unmodifiableHints;
+    }
+
+    /**
+     * Called when this factory is added to the given {@code category} of the given
+     * {@code registry}. The factory may already be registered under another category
+     * or categories.
+     * <p>
+     * This method is invoked automatically when this factory is registered as a plugin,
+     * and should not be invoked directly by the user. The default implementation iterates
+     * through all services under the same category that extends the {@code AbstractFactory}
+     * class, and set the ordering according the priority given at construction time.
+     *
+     * @param registry A service registry where this factory has been registered.
+     * @param category The registry category under which this object has been registered.
+     *
+     * @see #MINIMUM_PRIORITY
+     * @see #MAXIMUM_PRIORITY
+     */
+    public void onRegistration(final ServiceRegistry registry, final Class category) {
+        for (final Iterator it=registry.getServiceProviders(category, false); it.hasNext();) {
+            final Object provider = it.next();
+            if (provider!=this && provider instanceof AbstractFactory) {
+                final AbstractFactory factory = (AbstractFactory) provider;
+                final int priority = getPriority();
+                final int compare  = factory.getPriority();
+                final Object first, second;
+                if (priority > compare) {
+                    first  = this;
+                    second = factory;
+                } else if (priority < compare) {
+                    first  = factory;
+                    second = this;
+                } else {
+                    continue; // No ordering
+                }
+                registry.setOrdering(category, first, second);
+            }
+        }
+    }
+
+    /**
+     * Called when this factory is removed from the given {@code category} of the given
+     * {@code registry}. The object may still be registered under another category or categories.
+     * <p>
+     * This method is invoked automatically when this factory is no longer registered as a plugin,
+     * and should not be invoked directly by the user.
+     *
+     * @param registry A service registry from which this object is being (wholly or partially)
+     *                 deregistered.
+     * @param category The registry category from which this object is being deregistered.
+     */
+    public void onDeregistration(final ServiceRegistry registry, final Class category) {
+        // No action needed.
+    }
+
+    /**
+     * Returns a hash value for this factory. The default implementation computes the hash
+     * value using only immutable properties. This computation do <strong>not</strong> relies
+     * on {@linkplain #getImplementationHints implementation hints}, since there is no garantee
+     * that they will not change.
+     *
+     * @since 2.3
+     */
+    @Override
+    public final int hashCode() {
+        return getClass().hashCode() + (37 * priority);
+    }
+
+    /**
+     * Compares this factory with the specified object for equality.
+     * The default implementation returns {@code true} if and only if:
+     * <p>
+     * <ul>
+     *   <li>Both objects are of the exact same class
+     *       (a <cite>is instance of</cite> relationship is not enough).</li>
+     *   <li>{@linkplain #getImplementationHints implementation hints} are
+     *       {@linkplain Map#equals equal}.</li>
+     * </ul>
+     * <p>
+     * The requirement for the <cite>exact same class</cite> is needed for consistency with the
+     * {@linkplain FactoryRegistry factory registry} working, since at most one instance of a given
+     * class {@linkplain FactoryRegistry#getServiceProviderByClass) is allowed} in a registry.
+     *
+     * @param object The object to compare.
+     * @return {@code true} if the given object is equals to this factory.
+     *
+     * @since 2.3
+     */
+    @Override
+    public final boolean equals(final Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (object!=null && object.getClass().equals(getClass())) {
+            final AbstractFactory that = (AbstractFactory) object;
+            if (this.priority == that.priority) {
+                final Set<FactoryComparator> comparators = new HashSet<FactoryComparator>();
+                return new FactoryComparator(this, that).compare(comparators);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a string representation of this factory. This method is mostly for debugging purpose,
+     * so the string format may vary across different implementations or versions. The default
+     * implementation formats all {@linkplain #getImplementationHints implementation hints} as a
+     * tree. If the implementation hints include some {@linkplain Factory factory} dependencies,
+     * then the implementation hints for those dependencies will appears under a tree branch.
+     *
+     * @since 2.3
+     */
+    @Override
+    public String toString() {
+        final String name = format(this);
+        final Map<Factory,String> done = new IdentityHashMap<Factory,String>();
+        // We used IdentityHashMap above because we don't want to rely on Factory.equals(...)
+        done.put(this, name);
+        final String tree = format(getImplementationHints(), done);
+        return name + System.getProperty("line.separator", "\n") + tree;
+    }
+
+    /**
+     * Returns a string representation of the specified hints. This is used by
+     * {@link Hints#toString} in order to share the code provided in this class.
+     */
+    static String toString(final Map<?,?> hints) {
+        return format(hints, new IdentityHashMap<Factory, String>());
+    }
+
+    /**
+     * Formats a name for the specified factory.
+     */
+    private static String format(final Factory factory) {
+        String name = Classes.getShortClassName(factory);
+        if (factory instanceof AuthorityFactory) {
+            name = name + "[\"" + ((AuthorityFactory) factory).getAuthority().getTitle() + "\"]";
+        }
+        return name;
+    }
+
+    /**
+     * Formats the specified hints. This method is just the starting
+     * point for {@link #format(Writer, Map, String, Map)} below.
+     */
+    private static String format(final Map<?,?> hints, final Map<Factory,String> done) {
+        final Writer table;
+        try {
+            table = new TableWriter(null, " ");
+            format(table, hints, "  ", done);
+        } catch (IOException e) {
+            // Should never happen, since we are writing in a buffer.
+            throw new AssertionError(e);
+        }
+        return table.toString();
+    }
+
+    /**
+     * Formats recursively the tree. This method invoke itself.
+     */
+    private static void format(final Writer              table,
+                               final Map<?,?>            hints,
+                               final String              indent,
+                               final Map<Factory,String> done)
+            throws IOException
+    {
+        for (final Map.Entry<?,?> entry : hints.entrySet()) {
+            final Object k = entry.getKey();
+            String key = (k instanceof RenderingHints.Key) ?
+                    Hints.nameOf((RenderingHints.Key) k) : String.valueOf(k);
+            Object value = entry.getValue();
+            table.write(indent);
+            table.write(key);
+            table.write("\t= ");
+            Factory recursive = null;
+            if (value instanceof Factory) {
+                recursive = (Factory) value;
+                value = format(recursive);
+                final String previous = done.put(recursive, key);
+                if (previous != null) {
+                    done.put(recursive, previous);
+                    table.write("(same as ");  // TODO: localize
+                    table.write(previous);
+                    value = ")";
+                    recursive = null;
+                }
+            }
+            table.write(String.valueOf(value));
+            table.write('\n');
+            if (recursive != null) {
+                final String nextIndent = Utilities.spaces(indent.length() + 2);
+                format(table, recursive.getImplementationHints(), nextIndent, done);
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/BufferedFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/BufferedFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/BufferedFactory.java	(revision 28000)
@@ -0,0 +1,30 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+
+/**
+ * A marker interface for factories that are buffering their objects in some way.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/BufferedFactory.java $
+ * @version $Id: BufferedFactory.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ */
+public interface BufferedFactory extends Factory {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/CommonFactoryFinder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/CommonFactoryFinder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/CommonFactoryFinder.java	(revision 28000)
@@ -0,0 +1,242 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+
+import org.geotools.data.FeatureLockFactory;
+import org.geotools.data.FileDataStoreFactorySpi;
+import org.geotools.feature.FeatureCollections;
+import org.geotools.filter.FunctionExpression;
+import org.geotools.filter.FunctionFactory;
+import org.geotools.resources.LazySet;
+import org.opengis.feature.FeatureFactory;
+import org.opengis.feature.type.FeatureTypeFactory;
+import org.opengis.filter.FilterFactory;
+import org.opengis.filter.FilterFactory2;
+import org.opengis.filter.expression.Function;
+
+
+/**
+ * Defines static methods used to access the application's default implementation for some
+ * common factories. Those "common" factories comprise the {@linkplain StyleFactory style}
+ * and {@linkplain FilterFactory filter} factories. Note that some specialized factories
+ * finder like {@linkplain org.geotools.referencing.ReferencingFactoryFinder referencing} and
+ * {@linkplain org.geotools.coverage.GeometryFactoryFinder coverage} are defined in specialized
+ * classes.
+ * <p>
+ * <b>Tip:</b> The {@link BasicFactories} classes provides an other way to access the various
+ * factories from a central point.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/factory/CommonFactoryFinder.java $
+ * @version $Id: CommonFactoryFinder.java 37280 2011-05-24 07:53:02Z mbedward $
+ * @author Martin Desruisseaux
+ * @author Jody Garnett
+ */
+public final class CommonFactoryFinder extends FactoryFinder {
+    /**
+     * The service registry for this manager.
+     * Will be initialized only when first needed.
+     */
+    private static FactoryRegistry registry;
+
+    /**
+     * Do not allows any instantiation of this class.
+     */
+    private CommonFactoryFinder() {
+        // singleton
+    }
+
+    /**
+     * Returns the service registry. The registry will be created the first
+     * time this method is invoked.
+     */
+    private static FactoryRegistry getServiceRegistry() {
+        assert Thread.holdsLock(CommonFactoryFinder.class);
+        if (registry == null) {
+            registry = new FactoryCreator(Arrays.asList(new Class<?>[] {
+                    FilterFactory.class,
+                    FeatureLockFactory.class,
+                    FileDataStoreFactorySpi.class,
+//                  FunctionImpl.class, // TODO: remove
+//                  FunctionExpression.class,//TODO: remove
+                    Function.class,
+                    FunctionFactory.class,
+                    FeatureFactory.class,
+                    FeatureTypeFactory.class,
+                    FeatureCollections.class}));
+        }
+        return registry;
+    }
+
+    /**
+     * Returns a set of all available implementations for the {@link FunctionExpression} interface.
+     *
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return Set of available style factory implementations.
+     * @deprecated Use FunctionExpression is now @deprecated
+     */
+    public static synchronized Set getFunctionExpressions(Hints hints) {
+        //hints = mergeSystemHints(hints);
+        //return new LazySet(getServiceRegistry().getServiceProviders(
+        //        FunctionExpression.class, null, hints));
+        return Collections.EMPTY_SET;
+    }
+
+    /**
+     * Returns a set of all available implementations for the {@link Function} interface.
+     * 
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return Set of available function expression implementations.
+     */
+    public static synchronized Set getFunctions(Hints hints) {
+        hints = mergeSystemHints(hints);
+        return new LazySet(getServiceRegistry().getServiceProviders(
+                Function.class, null, hints));
+    }
+
+    /**
+     * Returns a set of all available implementations of {@link FunctionFactory}.
+     * 
+     * @param hints An optional map of hints, or {@code null} if none.
+     * 
+     * @return Set of available function factory implementations.
+     */
+    public static synchronized Set<FunctionFactory> getFunctionFactories(Hints hints) {
+        hints = mergeSystemHints(hints);
+        return new LazySet(getServiceRegistry().getServiceProviders(
+                FunctionFactory.class, null, hints));
+    }
+    
+    /**
+     * Returns a set of all available implementations for the {@link FileDataStoreFactorySpi} interface.
+     * 
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return Set of available file data store factory implementations.
+     */
+    public static synchronized Set getFileDataStoreFactories(Hints hints) {
+        hints = mergeSystemHints(hints);
+        return new LazySet(getServiceRegistry().getServiceProviders(
+                FileDataStoreFactorySpi.class, null, hints));
+    }
+    
+    /** Return the first implementation of {@link FeatureFactory} matching the specified hints.
+     * <p>
+     * If no implementation matches, a new one is created if possible or an exception is thrown.
+     * 
+     * @param hints An optional map of hints; or {@code null} if none
+     * @return Instance of FeatureFactory matching the supplied hints
+     * @throws FactoryRegistryException if no implementation could be provided
+     * @see Hints#FEATURE_FACTORY
+     */
+    public static FeatureFactory getFeatureFactory(Hints hints) {
+        hints = mergeSystemHints(hints);
+        if(hints.get(Hints.FEATURE_FACTORY) == null){
+            try {
+                Class<?> lenient = Class.forName("org.geotools.feature.LenientFeatureFactoryImpl");
+                hints.put(Hints.FEATURE_FACTORY, lenient );
+            } catch (ClassNotFoundException e) {
+                e.printStackTrace();
+            }
+        }
+        return (FeatureFactory) lookup(FeatureFactory.class, hints, Hints.FEATURE_FACTORY);
+    }
+    
+    /**
+     * Returns the first implementation of {@link FilterFactory} matching the specified hints.
+     * If no implementation matches, a new one is created if possible or an exception is thrown
+     * otherwise.
+     *
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return The first filter factory that matches the supplied hints.
+     * @throws FactoryRegistryException if no implementation was found or can be created for the
+     *         {@link FilterFactory} interface.
+     *
+     * @see Hints#FILTER_FACTORY
+     */
+    public static FilterFactory getFilterFactory(Hints hints)
+            throws FactoryRegistryException
+    {
+        hints = mergeSystemHints(hints);
+        return (FilterFactory) lookup(FilterFactory.class, hints, Hints.FILTER_FACTORY);
+    }
+    
+    /**
+     * Looks up a certain factory using two methods:
+     * <ul><li>First and un-synchronized lookup in the hints, should the user have provided the
+     *         preferred factroy</li>
+     * <li>A standard SPI registry scan, which has to be fully synchronized</li>
+     * @param category
+     * @param hints
+     * @param key
+     * @return
+     */
+    private static Object lookup(Class category, Hints hints, Hints.Key key) {
+        // nulls?
+        if(hints == null || key == null) {
+            return null;
+        }
+        
+        // see if the user expressed a preference in the hints
+        final Object hint = hints.get(key);
+        if (hint != null) {
+            if (category.isInstance(hint)) {
+                return hint;
+            }
+        } 
+
+        // otherwise do the lousy slow system scan
+        synchronized (CommonFactoryFinder.class) {
+            return getServiceRegistry().getServiceProvider(category, null, hints, key);
+        }
+    }
+
+    /**
+     * Returns the first implementation of {@link FilterFactory2} matching the specified hints.
+     * This is a convenience method invoking {@link #getFilterFactory} with a hint value set
+     * for requerying a {@link FactoryFilter2} implementation.
+     *
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return The first filter factory that matches the supplied hints.
+     * @throws FactoryRegistryException if no implementation was found or can be created for the
+     *         {@link FilterFactory2} interface.
+     *
+     * @see Hints#FILTER_FACTORY
+     */
+    public static FilterFactory2 getFilterFactory2(Hints hints)
+            throws FactoryRegistryException
+    {
+        hints = mergeSystemHints(hints);
+        
+        final Object h = hints.get(Hints.FILTER_FACTORY);
+        if (!(h instanceof Class ? FilterFactory2.class.isAssignableFrom((Class) h)
+                                 : h instanceof FilterFactory2))
+        {
+            /*
+             * Add the hint value only if the user didn't provided a suitable hint.
+             * In any case, do not change the user-supplied hints; clone them first.
+             */
+            hints = new Hints(hints);
+            hints.put(Hints.FILTER_FACTORY, FilterFactory2.class);
+        }
+        return (FilterFactory2) getFilterFactory(hints);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/Factory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/Factory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/Factory.java	(revision 28000)
@@ -0,0 +1,131 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+import java.util.Map;
+import java.awt.RenderingHints;
+
+
+/**
+ * Base interface for Geotools factories (i.e. service discovery).
+ *
+ * <p>This interfaces forms the core of the Geotools plug-in system, by which capabilities
+ * can be added to the library at runtime. Each sub-interface defines a <cite>service</cite>.
+ * Most services are set up with concrete implementation being registered for use in
+ * a <cite>service registry</cite>, which acts as a container for service implementations.</p>
+ *
+ * <p>Service registries don't need to be a Geotools implementation. They can be (but are not
+ * limited to) any {@link javax.imageio.spi.ServiceRegistry} subclass. If the standard
+ * {@code ServiceRegistry} (or its Geotools extension {@link FactoryRegistry}) is selected
+ * as a container for services, then factory implementations should be declared as below
+ * (select only one way):</p>
+ *
+ * <ul>
+ *   <li><strong>Register for automatic discovery</strong></li>
+ *   <ul>
+ *     <li>Provide a public no-arguments constructor.</li>
+ *     <li>Add the fully qualified name of the <u>implementation</u> class in the
+ *         {@code META-INF/services/}<var>classname</var> file where <var>classname</var>
+ *         is the fully qualified name of the service <u>interface</u>.</li>
+ *     <li>The factory implementations will be discovered when
+ *         {@link FactoryRegistry#scanForPlugins} will be invoked.</li>
+ *   </ul>
+ *   <li><strong><u>Or</u> register explicitly by application code</strong></li>
+ *   <ul>
+ *     <li>Invoke {@link ServiceRegistry#registerServiceProvider} in application code.</li>
+ *   </ul>
+ * </ul>
+ *
+ * <p>In addition, it is recommended that implementations provide a constructor expecting
+ * a single {@link Hints} argument. This optional argument gives to the user some control
+ * of the factory's low-level details. The amount of control is factory specific. The geotools
+ * library defines a global class called {@link Hints} that is ment as API (i.e. you can assume
+ * these hints are supported). Factories may also provide information on their own custom hints
+ * as part of their javadoc class description.</p>
+ *
+ * <strong>Examples:</strong>
+ * <ul>
+ *   <li><p>An application supplied a {@linkplain Hints#DATUM_FACTORY datum factory hint}, being
+ *   passed to a {@linkplain org.opengis.referencing.datum.DatumAuthorityFactory datum authority
+ *   factory} so that all datum created from an authority code will come from the supplied datum
+ *   factory.</p></li>
+ *
+ *   <li><p>An application supplied a {@link org.geotools.feature.FeatureFactory} (ensuring all
+ *   constructed features support the Eclipse's {@code IAdaptable} interface), being passed to a
+ *   {@link org.geotools.feature.FeatureTypeFactory} so that all {@code FeatureTypes}
+ *   constructed will produce features supporting the indicated interface.<p></li>
+ * </ul>
+ *
+ * <p>As seen in those examples this concept of a hint becomes more interesting when
+ * the operation being controlled is discovery of other services used by the Factory.
+ * By supplying appropriate hints one can chain together several factories and retarget
+ * them to an application specific task.</p>
+ *
+ * @author Ian Schneider
+ * @author Martin Desruisseaux
+ * @author Jody Garnett
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/Factory.java $
+ * @version $Id: Factory.java 37298 2011-05-25 05:16:15Z mbedward $
+ *
+ * @see Hints
+ * @see FactoryRegistry
+ */
+public interface Factory {
+    /**
+     * Map of  hints (maybe {@linkplain java.util.Collections#unmodifiableMap unmodifiable})
+     * used by this factory to customize its use. This map is <strong>not</strong> guaranteed
+     * to contains all the hints supplied by the user; it may be only a subset. Consequently,
+     * hints provided here are usually not suitable for creating new factories, unless the
+     * implementation make some additional garantees
+     * (e.g. {@link FactoryUsingVolatileDependencies}).
+     * <p>
+     * The primary purpose of this method is to determine if an <strong>existing</strong>
+     * factory instance can be reused for a set of user-supplied hints. This method is invoked by
+     * {@link FactoryRegistry} in order to compare this factory's hints against user's hints.
+     * This is dependency introspection only; {@code FactoryRegistry} <strong>never</strong>
+     * invokes this method for creating new factories.
+     * <p>
+     * Keys are usually static constants from the {@link Hints} class, while values are
+     * instances of some key-dependent class. The {@linkplain Map#keySet key set} must contains
+     * at least all hints impacting functionality. While the key set may contains all hints
+     * supplied by the user, it is recommended to limit the set to only the hints used by this
+     * particular factory instance. A minimal set will helps {@link FactoryRegistry} to compare
+     * only hints that matter and avoid the creation of unnecessary instances of this factory.
+     * <p>
+     * The hint values may be different than the one supplied by the user. If a user supplied a
+     * hint as a {@link Class} object, this method shall replace it by the actual instance used,
+     * if possible.
+     * <p>
+     * Implementations of this method are usually quite simple. For example if a
+     * {@linkplain org.opengis.referencing.datum.DatumAuthorityFactory datum authority factory}
+     * uses an ordinary {@linkplain org.opengis.referencing.datum.DatumFactory datum factory},
+     * its method could be implemented as below (note that we should not check if the datum
+     * factory is null, since key with null value is the expected behaviour in this case).
+     * Example:
+     *
+     * <pre><code>
+     * Map hints = new HashMap();
+     * hints.put({@linkplain Hints#DATUM_FACTORY}, datumFactory);
+     * return hints;
+     * </code></pre>
+     *
+     * @return The map of hints, or an {@linkplain java.util.Collections#EMPTY_MAP empty map}
+     *         if none.
+     */
+    Map<RenderingHints.Key, ?> getImplementationHints();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryComparator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryComparator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryComparator.java	(revision 28000)
@@ -0,0 +1,101 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+import java.util.Set;
+import java.util.Map;
+import java.awt.RenderingHints;
+import org.geotools.util.Utilities;
+
+
+/**
+ * Compares two factories for equality.
+ * Used internally for {@link AbstractFactory#equals} implementation only.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/FactoryComparator.java $
+ * @version $Id: FactoryComparator.java 30640 2008-06-12 17:34:32Z acuster $
+ * @author Martin Desruisseaux
+ */
+final class FactoryComparator {
+    /**
+     * A pair of factory already compared.
+     */
+    private final Factory f1, f2;
+
+    /**
+     * Prepare a comparaison between the two specified factories.
+     */
+    FactoryComparator(final Factory f1, final Factory f2) {
+        this.f1 = f1;
+        this.f2 = f2;
+    }
+
+    /**
+     * Returns {@code true} if {@code f1} and {@code f2} are equals.
+     *
+     * @param done An initially empty set. Used internally for preventing infinite recursivity.
+     */
+    boolean compare(final Set<FactoryComparator> done) {
+        if (done.add(this)) {
+            final Map<RenderingHints.Key, ?> m1 = f1.getImplementationHints();
+            final Map<RenderingHints.Key, ?> m2 = f2.getImplementationHints();
+            if (m1.size() != m2.size()) {
+                return false;
+            }
+            for (final Map.Entry<RenderingHints.Key, ?> entry : m1.entrySet()) {
+                final Object key = entry.getKey();
+                final Object v1  = entry.getValue();
+                final Object v2  = m2.get(key);
+                if (v1 == v2) continue;
+                if (v1 instanceof Factory) {
+                    if (v2 == null || !v1.getClass().equals(v2.getClass()) ||
+                       !new FactoryComparator((Factory) v1, (Factory) v2).compare(done))
+                    {
+                        return false;
+                    }
+                } else if (!Utilities.equals(v1, v2)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * For internal use only. This implementation assumes that {@code f1.equals(f2)}
+     * is symetric (i.e. equivalents to {@code f2.equals(f1)}).
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object instanceof FactoryComparator) {
+            final FactoryComparator that = (FactoryComparator) object;
+            return (this.f1 == that.f1 && this.f2 == that.f2) ||
+                   (this.f1 == that.f2 && this.f2 == that.f1);
+        }
+        return false;
+    }
+
+    /**
+     * For internal use only. Must be compatible with the symetry assumption made in
+     * {@link #equals(Object)}: use a commutative operation (addition here) and do not
+     * multiply a term by some factor like the usual 37.
+     */
+    @Override
+    public int hashCode() {
+        return System.identityHashCode(f1) + System.identityHashCode(f2);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryCreator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryCreator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryCreator.java	(revision 28000)
@@ -0,0 +1,314 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+import java.util.*;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.InvocationTargetException;
+
+import org.geotools.util.logging.Logging;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * A {@linkplain FactoryRegistry factory registry} capable to creates factories if no appropriate
+ * instance was found in the registry.
+ * <p>
+ * This class maintains a cache of previously created factories, as {@linkplain WeakReference
+ * weak references}. Calls to {@link #getServiceProvider getServiceProvider} first check if a
+ * previously created factory can fit.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/FactoryCreator.java $
+ * @version $Id: FactoryCreator.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ * @author Jody Garnett
+ */
+public class FactoryCreator extends FactoryRegistry {
+    /**
+     * The array of classes for searching the one-argument constructor.
+     */
+    private static final Class[] HINTS_ARGUMENT = new Class[] {Hints.class};
+
+    /**
+     * List of factories already created. Used as a cache.
+     */
+    private final Map<Class<?>, List<Reference<?>>> cache = new HashMap<Class<?>, List<Reference<?>>>();
+
+    /**
+     * Objects under construction for each implementation class.
+     * Used by {@link #safeCreate} as a guard against infinite recursivity.
+     */
+    private final Set<Class<?>> underConstruction = new HashSet<Class<?>>();
+
+    /**
+     * Constructs a new registry for the specified categories.
+     *
+     * @param categories The categories.
+     *
+     * @since 2.4
+     */
+    public FactoryCreator(final Class<?>[] categories) {
+        super(categories);
+    }
+
+    /**
+     * Constructs a new registry for the specified categories.
+     *
+     * @param categories The categories.
+     */
+    public FactoryCreator(final Collection<Class<?>> categories) {
+        super(categories);
+    }
+
+    /**
+     * Returns the providers available in the cache. To be used by {@link FactoryRegistry}.
+     */
+    @Override
+    final <T> List<Reference<T>> getCachedProviders(final Class<T> category) {
+        List<Reference<?>> c = cache.get(category);
+        if (c == null) {
+            c = new LinkedList<Reference<?>>();
+            cache.put(category, c);
+        }
+        @SuppressWarnings("unchecked")
+        final List<Reference<T>> cheat = (List) c;
+        /*
+         * Should be safe because we created an empty list, there is no other place where this
+         * list is created and from this point we can only insert elements restricted to type T.
+         */
+        return cheat;
+    }
+
+    /**
+     * Caches the specified factory under the specified category.
+     */
+    private <T> void cache(final Class<T> category, final T factory) {
+        getCachedProviders(category).add(new WeakReference<T>(factory));
+    }
+
+    /**
+     * Returns a provider for the specified category, using the specified map of hints (if any).
+     * If a provider matching the requirements is found in the registry, it is returned. Otherwise,
+     * a new provider is created and returned. This creation step is the only difference between
+     * this method and the {@linkplain FactoryRegistry#getServiceProvider super-class method}.
+     *
+     * @param  category The category to look for.
+     * @param  filter   An optional filter, or {@code null} if none.
+     * @param  hints    A {@linkplain Hints map of hints}, or {@code null} if none.
+     * @param  key      The key to use for looking for a user-provided instance in the hints, or
+     *                  {@code null} if none.
+     * @return A factory for the specified category and hints (never {@code null}).
+     * @throws FactoryNotFoundException if no factory was found, and the specified hints don't
+     *         provide suffisient information for creating a new factory.
+     * @throws FactoryRegistryException if the factory can't be created for some other reason.
+     */
+    @Override
+    public <T> T getServiceProvider(final Class<T>  category,
+                                    final Filter    filter,
+                                    final Hints     hints,
+                                    final Hints.Key key)
+            throws FactoryRegistryException
+    {
+        final FactoryNotFoundException notFound;
+        try {
+            return super.getServiceProvider(category, filter, hints, key);
+        } catch (FactoryNotFoundException exception) {
+            // Will be rethrown later in case of failure to create the factory.
+            notFound = exception;
+        }
+        /*
+         * No existing factory found. Creates one using reflection. First, we
+         * check if an implementation class was explicitly specified by the user.
+         */
+        final Class<?>[] types;
+        if (hints==null || key==null) {
+            types = null;
+        } else {
+            final Object hint = hints.get(key);
+            if (hint == null) {
+                types = null;
+            } else {
+                if (hint instanceof Class<?>[]) {
+                    types = (Class<?>[]) hint;
+                } else {
+                    types = new Class<?>[] {(Class<?>) hint};
+                    // Should not fails, since non-class argument should
+                    // have been accepted by 'getServiceProvider(...)'.
+                }
+                final int length = types.length;
+                for (int i=0; i<length; i++) {
+                    final Class<?> type = types[i];
+                    if (type!=null && category.isAssignableFrom(type)) {
+                        final int modifiers = type.getModifiers();
+                        if (!Modifier.isAbstract(modifiers)) {
+                            final T candidate = createSafe(category, type, hints);
+                            if (candidate == null) {
+                                continue;
+                            }
+                            if (isAcceptable(candidate, category, hints, filter)) {
+                                cache(category, candidate);
+                                return candidate;
+                            }
+                            dispose(candidate);
+                        }
+                    }
+                }
+            }
+        }
+        /*
+         * No implementation hint provided. Search the first implementation
+         * accepting a Hints argument. No-args constructor will be ignored.
+         * Note: all Factory objects should be fully constructed by now,
+         * since the super-class has already iterated over all factories.
+         */
+        for (final Iterator<T> it=getUnfilteredProviders(category); it.hasNext();) {
+            final T factory = it.next();
+            final Class<?> implementation = factory.getClass();
+            if (types!=null && !isTypeOf(types, implementation)) {
+                continue;
+            }
+            if (filter!=null && !filter.filter(factory)) {
+                continue;
+            }
+            final T candidate;
+            try {
+                candidate = createSafe(category, implementation, hints);
+            } catch (FactoryNotFoundException exception) {
+                // The factory has a dependency which has not been found.
+                // Be tolerant to that kind of error.
+                Logging.recoverableException(LOGGER, FactoryCreator.class, "getServiceProvider", exception);
+                continue;
+            } catch (FactoryRegistryException exception) {
+                if (exception.getCause() instanceof NoSuchMethodException) {
+                    // No public constructor with the expected argument.
+                    // Try an other implementation.
+                    continue;
+                } else {
+                    // Other kind of error, probably unexpected.
+                    // Let the exception propagates.
+                    throw exception;
+                }
+            }
+            if (candidate == null) {
+                continue;
+            }
+            if (isAcceptable(candidate, category, hints, filter)) {
+                cache(category, candidate);
+                return candidate;
+            }
+            dispose(candidate);
+        }
+        throw notFound;
+    }
+
+    /**
+     * Returns {@code true} if the specified implementation is one of the specified types.
+     */
+    private static boolean isTypeOf(final Class<?>[] types, final Class<?> implementation) {
+        for (int i=0; i<types.length; i++) {
+            if (types[i].isAssignableFrom(implementation)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Invokes {@link #createServiceProvider}, but checks against recursive calls. If the specified
+     * implementation is already under construction, returns {@code null} in order to tell to
+     * {@link #getServiceProvider} that it need to search for an other implementation. This is
+     * needed for avoiding infinite recursivity when a factory is a wrapper around an ther factory
+     * of the same category. For example this is the case of
+     * {@link org.geotools.referencing.operation.BufferedCoordinateOperationFactory}.
+     */
+    private <T> T createSafe(final Class<T> category, final Class<?> implementation, final Hints hints) {
+        if (!underConstruction.add(implementation)) {
+            return null;
+        }
+        try {
+            return createServiceProvider(category, implementation, hints);
+        } finally {
+            if (!underConstruction.remove(implementation)) {
+                throw new AssertionError();
+            }
+        }
+    }
+
+    /**
+     * Creates a new instance of the specified factory using the specified hints.
+     * The default implementation tries to instantiate the given implementation class
+     * using the first of the following constructor found:
+     * <p>
+     * <ul>
+     *   <li>Constructor with a single {@link Hints} argument.</li>
+     *   <li>No-argument constructor.</li>
+     * </ul>
+     *
+     * @param  category The category to instantiate.
+     * @param  implementation The factory class to instantiate.
+     * @param  hints The implementation hints.
+     * @return The factory.
+     * @throws FactoryRegistryException if the factory creation failed.
+     */
+    protected <T> T createServiceProvider(final Class<T> category,
+                                          final Class<?> implementation,
+                                          final Hints hints)
+            throws FactoryRegistryException
+    {
+        Throwable cause;
+        try {
+            try {
+                return category.cast(implementation.getConstructor(HINTS_ARGUMENT)
+                        .newInstance(new Object[] {hints}));
+            } catch (NoSuchMethodException exception) {
+                // Constructor do not exists or is not public. We will fallback on the no-arg one.
+                cause = exception;
+            }
+            try {
+                return category.cast(implementation.getConstructor((Class[]) null)
+                        .newInstance((Object[]) null));
+            } catch (NoSuchMethodException exception) {
+                // No constructor accessible. Do not store the cause (we keep the one above).
+            }
+        } catch (IllegalAccessException exception) {
+            cause = exception; // constructor is not public (should not happen)
+        } catch (InstantiationException exception) {
+            cause = exception; // The class is abstract
+        } catch (InvocationTargetException exception) {
+            cause = exception.getCause(); // Exception in constructor
+            if (cause instanceof FactoryRegistryException) {
+                throw (FactoryRegistryException) cause;
+            }
+        }
+        throw new FactoryRegistryException(Errors.format(
+                ErrorKeys.CANT_CREATE_FACTORY_$1, implementation), cause);
+    }
+
+    /**
+     * Dispose the specified factory after. This method is invoked when a factory has been
+     * created, and then {@code FactoryCreator} determined that the factory doesn't meet
+     * user's requirements.
+     */
+    private static void dispose(final Object factory) {
+        // Empty for now. This method is merely a reminder for disposal in future Geotools versions.
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryFinder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryFinder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryFinder.java	(revision 28000)
@@ -0,0 +1,66 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+
+/**
+ * Base class for factory finders. {@code FactoryFinder}s are cover for {@link FactoryRegistry}
+ * adding type safety, default hints and synchronization for multi-thread environments.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/FactoryFinder.java $
+ * @version $Id: FactoryFinder.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ */
+public abstract class FactoryFinder {
+
+	/**
+     * Creates a new factory finder.
+     */
+    protected FactoryFinder() {
+    }
+
+    /**
+     * Returns new hints that combine user supplied hints with the
+     * {@linkplain GeoTools#getDefaultHints defaults hints}. If a hint is specified
+     * in both user and default hints, then user hints have precedence.
+     * <p>
+     * The returned hints should live only the time needed for invoking {@link FactoryRegistry}
+     * methods. No long-term reference should be held.
+     *
+     * @param hints The user hints, or {@code null} if none.
+     * @return New hints (never {@code null}).
+     */
+    public static Hints mergeSystemHints(final Hints hints) {
+        if (hints instanceof StrictHints) {
+            /*
+             * The hints have already been merged in a previous call to this method and we don't
+             * want to merge them again. This case happen typically in factory constructor fetching
+             * for dependencies. The constructor may have removed some hints. For example the
+             * "URN:OGC" factory may looks for the "EPSG" factory with FORCE_LONGITUDE_FIRST
+             * forced to FALSE.
+             */
+            return hints;
+        }
+        final Hints merged = Hints.getDefaults(true);
+        if (hints != null) {
+            merged.add(hints);
+        }
+        return merged;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryIteratorProvider.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryIteratorProvider.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryIteratorProvider.java	(revision 28000)
@@ -0,0 +1,50 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+import java.util.Iterator;
+
+
+/**
+ * Provides iterators over factories of specified categories. Users shall
+ * {@linkplain Factories#addFactoryIteratorProvider register} an implementation
+ * of this interface when the default lookup mechanism (namely scanning the content of the
+ * <code>META-INF/services/</code><var>category</var> file in every JARs found on the classpath)
+ * can not work. Such need may appear in the context of {@linkplain ClassLoader class loaders}
+ * restricting access to non-package directories as {@code META-INF}. This constraint occurs on
+ * the Eclipse platform for instance.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/FactoryIteratorProvider.java $
+ * @version $Id: FactoryIteratorProvider.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ *
+ * @see FactoryRegistry#addFactoryIteratorProvider
+ * @see CommonFactory#addFactoryIteratorProvider
+ */
+public interface FactoryIteratorProvider {
+    /**
+     * Returns an iterator over all {@linkplain Factory factories} of the specified category.
+     * The {@code category} argument should be the interface class to be implemented, not the
+     * actual implementation.
+     *
+     * @param  category The category for the factories to be returned.
+     * @return Factories that implement the specified category.
+     */
+    <T> Iterator<T> iterator(final Class<T> category);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryIteratorProviders.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryIteratorProviders.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryIteratorProviders.java	(revision 28000)
@@ -0,0 +1,126 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.LinkedHashSet;
+import org.geotools.resources.XArray;
+
+
+/**
+ * The list of registered {@linkplain FactoryIteratorProvider factory iterator providers}.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/FactoryIteratorProviders.java $
+ * @version $Id: FactoryIteratorProviders.java 30640 2008-06-12 17:34:32Z acuster $
+ * @author Martin Desruisseaux
+ *
+ * @todo Consider removing {@link FactoryRegistry#globalConfiguration} and use listeners instead.
+ */
+final class FactoryIteratorProviders {
+    /**
+     * The system-wide configuration. This is the instance configured by
+     * the public static methods provided in this class.
+     */
+    private static final FactoryIteratorProviders GLOBAL = new FactoryIteratorProviders();
+
+    /**
+     * Incremented every time a modification is performed.
+     */
+    private int modifications = 0;
+
+    /**
+     * Alternative scanning methods used by {@link FactoryRegistry#scanForPlugins(Collection,Class)}
+     * in addition of the default lookup mechanism. Will be created only when first needed.
+     */
+    private Set<FactoryIteratorProvider> iteratorProviders;
+
+    /**
+     * Creates an initially empty set of factories.
+     */
+    FactoryIteratorProviders() {
+    }
+
+    /**
+     * Synchronizes the content of the {@link #iteratorProviders} map with the {@linkplain #GLOBAL
+     * global} one. New providers are returned for later {@linkplain FactoryRegistry#register
+     * registration}. Note that this method is typically invoked in a different thread than
+     * {@link FactoryIteratorProviders} public static method calls.
+     *
+     * @return The new iterators providers {@linkplain #addFactoryIteratorProvider added} since
+     *         the last time this method was invoked, or {@code null} if none.
+     */
+    final FactoryIteratorProvider[] synchronizeIteratorProviders() {
+        FactoryIteratorProvider[] newProviders = null;
+        int count = 0;
+        synchronized (GLOBAL) {
+            if (modifications == GLOBAL.modifications) {
+                return null;
+            }
+            modifications = GLOBAL.modifications;
+            if (GLOBAL.iteratorProviders == null) {
+                /*
+                 * Should never happen. If GLOBAL.iteratorProviders was null, then every
+                 * 'modifications' count should be 0 and this method should have returned 'null'.
+                 */
+                throw new AssertionError(modifications);
+            }
+            /*
+             * If 'removeFactoryIteratorProvider(...)' has been invoked since the last time
+             * this method was run, then synchronize 'iteratorProviders' accordingly. Current
+             * implementation do not unregister the factories that were created by those iterators.
+             */
+            if (iteratorProviders != null) {
+                iteratorProviders.retainAll(GLOBAL.iteratorProviders);
+            } else if (!GLOBAL.iteratorProviders.isEmpty()) {
+                iteratorProviders = new LinkedHashSet<FactoryIteratorProvider>();
+            }
+            /*
+             * If 'addFactoryIteratorProvider(...)' has been invoked since the last time
+             * this method was run, then synchronize 'iteratorProviders' accordingly. We
+             * keep trace of new providers in order to allow 'FactoryRegistry' to use them
+             * for a immediate scanning.
+             */
+            int remaining = GLOBAL.iteratorProviders.size();
+            for (final Iterator it=GLOBAL.iteratorProviders.iterator(); it.hasNext();) {
+                final FactoryIteratorProvider candidate = (FactoryIteratorProvider) it.next();
+                if (iteratorProviders.add(candidate)) {
+                    if (newProviders == null) {
+                        newProviders = new FactoryIteratorProvider[remaining];
+                    }
+                    newProviders[count++] = candidate;
+                }
+                remaining--;
+            }
+        }
+        // Note: newProviders may be null.
+        return XArray.resize(newProviders, count);
+    }
+    /**
+     * Returns all iterator providers. This method do not returns any live collection
+     * since the array will be used outside the synchronized block.
+     */
+    static FactoryIteratorProvider[] getIteratorProviders() {
+        synchronized (GLOBAL) {
+            if (GLOBAL.iteratorProviders == null) {
+                return new FactoryIteratorProvider[0];
+            }
+            return GLOBAL.iteratorProviders.toArray(
+                    new FactoryIteratorProvider[GLOBAL.iteratorProviders.size()]);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryNotFoundException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryNotFoundException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryNotFoundException.java	(revision 28000)
@@ -0,0 +1,48 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+
+/**
+ * Thrown when a factory can't be found in the registery.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/FactoryNotFoundException.java $
+ * @version $Id: FactoryNotFoundException.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ */
+public class FactoryNotFoundException extends FactoryRegistryException {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 7555229653402417318L;
+
+    /**
+     * Creates a new exception with the specified detail message.
+     */
+    public FactoryNotFoundException(final String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new exception with the specified detail message and cause.
+     */
+    public FactoryNotFoundException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryRegistry.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryRegistry.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryRegistry.java	(revision 28000)
@@ -0,0 +1,1005 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import java.lang.ref.Reference;
+import java.awt.RenderingHints;
+import javax.imageio.spi.ServiceRegistry;
+
+import org.geotools.util.Utilities;
+import org.geotools.util.logging.Logging;
+import org.geotools.resources.Classes;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Loggings;
+import org.geotools.resources.i18n.LoggingKeys;
+
+
+/**
+ * A registry for factories, organized by categories (usualy by <strong>interface</strong>). For
+ * example <code>{@linkplain org.opengis.referencing.crs.CRSFactory}.class</code> is a category,
+ * and <code>{@linkplain org.opengis.referencing.operation.MathTransformFactory}.class</code> is
+ * an other category.
+ * <p>
+ * For each category, implementations are registered in a file placed in the
+ * {@code META-INF/services/} directory, as specified in the {@link ServiceRegistry}
+ * javadoc. Those files are usually bundled into the JAR file distributed by the vendor.
+ * If the same {@code META-INF/services/} file appears many time in different JARs,
+ * they are processed as if their content were merged.
+ * <p>
+ * Example use:
+ * <blockquote><code>
+ * Set&lt;Class&lt;?&gt;&gt; categories =
+ *     Collections.singleton(new Class&lt;?&gt;[] {<br>
+ * &npsp;&npsp;&npsp;&npsp;MathTransformProvider.class<br>
+ * });<br>
+ * FactoryRegistry registry = new FactoryRegistry(categories);<br>
+ * <br>
+ * // get the providers<br>
+ * Filter filter = null;<br>
+ * Hints hints = null;<br>
+ * Iterator&lt;MathTransform&gt; providers =
+ *     registry.getServiceProviders(MathTransformProvider.class, filter, hints);<br>
+ * </code></blockquote>
+ * <p>
+ * <strong>NOTE: This class is not thread safe</strong>. Users are responsable
+ * for synchronisation. This is usually done in an utility class wrapping this
+ * service registry (e.g. {@link org.geotools.referencing.ReferencingFactoryFinder}).
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/FactoryRegistry.java $
+ * @version $Id: FactoryRegistry.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ * @author Richard Gould
+ * @author Jody Garnett
+ *
+ * @see org.geotools.referencing.ReferencingFactoryFinder
+ * @see org.geotools.coverage.CoverageFactoryFinder
+ */
+public class FactoryRegistry extends ServiceRegistry {
+    /**
+     * The logger for all events related to factory registry.
+     */
+    protected static final Logger LOGGER = Logging.getLogger("org.geotools.factory");
+
+    /**
+     * The logger level for debug messages.
+     */
+    private static final Level DEBUG_LEVEL = Level.FINEST;
+
+    /**
+     * A copy of the global configuration defined through {@link FactoryIteratorProviders}
+     * static methods. We keep a copy in every {@code FactoryRegistry} instance in order to
+     * compare against the master {@link FactoryIteratorProviders#GLOBAL} and detect if the
+     * configuration changed since the last time this registry was used.
+     *
+     * @see #synchronizeIteratorProviders
+     */
+    private final FactoryIteratorProviders globalConfiguration = new FactoryIteratorProviders();
+
+    /**
+     * The set of category that need to be scanned for plugins, or {@code null} if none.
+     * On initialization, all categories need to be scanned for plugins. After a category
+     * has been first used, it is removed from this set so we don't scan for plugins again.
+     */
+    private Set<Class<?>> needScanForPlugins;
+
+    /**
+     * Categories under scanning. This is used by {@link #scanForPlugins(Collection,Class)}
+     * as a guard against infinite recursivity (i.e. when a factory to be scanned request
+     * an other dependency of the same category).
+     */
+    private final RecursionCheckingHelper scanningCategories = new RecursionCheckingHelper();
+
+    /**
+     * Factories under testing for availability. This is used by
+     * {@link #isAvailable} as a guard against infinite recursivity.
+     */
+    private final RecursionCheckingHelper testingAvailability = new RecursionCheckingHelper();
+
+    /**
+     * Factories under testing for hints compatibility. This is used by
+     * {@link #usesAcceptableHints} as a guard against infinite recursivity.
+     */
+    private final RecursionCheckingHelper testingHints = new RecursionCheckingHelper();
+
+    /**
+     * Constructs a new registry for the specified categories.
+     *
+     * @param categories The categories.
+     *
+     * @since 2.4
+     */
+    public FactoryRegistry(final Class<?>[] categories) {
+        this(Arrays.asList(categories));
+    }
+
+    /**
+     * Constructs a new registry for the specified categories.
+     *
+     * @param categories The categories.
+     */
+    public FactoryRegistry(final Collection<Class<?>> categories) {
+        super(categories.iterator());
+        for (final Iterator<Class<?>> it=getCategories(); it.hasNext();) {
+            if (needScanForPlugins == null) {
+                needScanForPlugins = new HashSet<Class<?>>();
+            }
+            needScanForPlugins.add(it.next());
+        }
+    }
+
+    /**
+     * Returns the providers in the registry for the specified category, filter and hints.
+     * Providers that are not {@linkplain OptionalFactory#isAvailable available} will be
+     * ignored. This method will {@linkplain #scanForPlugins() scan for plugins} the first
+     * time it is invoked for the given category.
+     *
+     * @param <T>      The class represented by the {@code category} argument.
+     * @param category The category to look for. Usually an interface class
+     *                 (not the actual implementation class).
+     * @param filter   The optional filter, or {@code null}.
+     * @param hints    The optional user requirements, or {@code null}.
+     * @return Factories ready to use for the specified category, filter and hints.
+     *
+     * @since 2.3
+     */
+    public synchronized <T> Iterator<T> getServiceProviders(final Class<T> category, final Filter filter, final Hints hints) {
+        /*
+         * The implementation of this method is very similar to the 'getUnfilteredProviders'
+         * one except for filter handling. See the comments in 'getUnfilteredProviders' for
+         * more implementation details.
+         */
+        if (scanningCategories.contains(category)) {
+            // Please note you will get errors here if you accidentally allow
+            // more than one thread to use your FactoryRegistry at a time.
+            throw new RecursiveSearchException(category);
+        }
+        final Filter hintsFilter = new Filter() {
+            public boolean filter(final Object provider) {
+                return isAcceptable(category.cast(provider), category, hints, filter);
+            }
+        };
+        synchronizeIteratorProviders();
+        scanForPluginsIfNeeded(category);
+        return getServiceProviders(category, hintsFilter, true);
+    }
+
+    /**
+     * Implementation of {@link #getServiceProviders(Class, Filter, Hints)} without the filtering
+     * applied by the {@link #isAcceptable(Object, Class, Hints, Filter)} method. If this filtering
+     * is not already presents in the filter given to this method, then it must be applied on the
+     * elements returned by the iterator. The later is preferrable when:
+     * <p>
+     * <ul>
+     *   <li>There is some cheaper tests to perform before {@code isAcceptable}.</li>
+     *   <li>We don't want a restrictive filter in order to avoid trigging a classpath
+     *       scan if this method doesn't found any element to iterate.</li>
+     * </ul>
+     * <p>
+     * <b>Note:</b>
+     * {@link #synchronizeIteratorProviders} should also be invoked once before this method.
+     *
+     * @todo Use Hints to match Constructor.
+     */
+    final <T> Iterator<T> getUnfilteredProviders(final Class<T> category) {
+        /*
+         * If the map is not empty, then this mean that a scanning is under progress, i.e.
+         * 'scanForPlugins' is currently being executed. This is okay as long as the user
+         * is not asking for one of the categories under scanning. Otherwise, the answer
+         * returned by 'getServiceProviders' would be incomplete because not all plugins
+         * have been found yet. This can lead to some bugs hard to spot because this methoud
+         * could complete normally but return the wrong plugin. It is safer to thrown an
+         * exception so the user is advised that something is wrong.
+         */
+        if (scanningCategories.contains(category)) {
+            throw new RecursiveSearchException(category);
+        }
+        scanForPluginsIfNeeded(category);
+        return getServiceProviders(category, true);
+    }
+
+    /**
+     * Returns the first provider in the registry for the specified category, using the specified
+     * map of hints (if any). This method may {@linkplain #scanForPlugins scan for plugins} the
+     * first time it is invoked. Except as a result of this scan, no new provider instance is
+     * created by the default implementation of this method. The {@link FactoryCreator} class
+     * change this behavior however.
+     *
+     * @param  <T>      The class represented by the {@code category} argument.
+     * @param  category The category to look for. Must be one of the categories declared to the
+     *                  constructor. Usually an interface class (not the actual implementation
+     *                  class).
+     * @param  filter   An optional filter, or {@code null} if none.
+     *                  This is used for example in order to select the first factory for some
+     *                  {@linkplain org.opengis.referencing.AuthorityFactory#getAuthority authority}.
+     * @param  hints    A {@linkplain Hints map of hints}, or {@code null} if none.
+     * @param  key      The key to use for looking for a user-provided instance in the hints, or
+     *                  {@code null} if none.
+     * @return A factory {@linkplain OptionalFactory#isAvailable available} for use for the
+     *         specified category and hints. The returns type is {@code Object} instead of
+     *         {@link Factory} because the factory implementation doesn't need to be a Geotools one.
+     * @throws FactoryNotFoundException if no factory was found for the specified category, filter
+     *         and hints.
+     * @throws FactoryRegistryException if a factory can't be returned for some other reason.
+     *
+     * @see #getServiceProviders(Class, Filter, Hints)
+     * @see FactoryCreator#getServiceProvider
+     */
+    public <T> T getServiceProvider(final Class<T> category, final Filter filter,
+                                    Hints hints, final Hints.Key key)
+            throws FactoryRegistryException
+    {
+        synchronizeIteratorProviders();
+        final boolean debug = LOGGER.isLoggable(DEBUG_LEVEL);
+        if (debug) {
+            /*
+             * We are not required to insert the method name ("GetServiceProvider") in the
+             * message because it is part of the informations already stored by LogRecord,
+             * and formatted by the default java.util.logging.SimpleFormatter.
+             *
+             * Conventions for the message part according java.util.logging.Logger javadoc:
+             * - "ENTRY"  at the begining of a method.
+             * - "RETURN" at the end of a method, if successful.
+             * - "THROW"  in case of failure.
+             * - "CHECK"  ... is our own addition to Sun's convention for this method ...
+             */
+            debug("ENTRY", category, key, null, null);
+        }
+        Class<?> implementation = null;
+        if (key != null) {
+            /*
+             * Sanity check: make sure that the key class is appropriate for the category.
+             */
+            final Class<?> valueClass = key.getValueClass();
+            if (!category.isAssignableFrom(valueClass)) {
+                if (debug) {
+                    debug("THROW", category, key, "unexpected type:", valueClass);
+                }
+                throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_KEY_$1, key));
+            }
+            if (hints != null) {
+                final Object hint = hints.get(key);
+                if (hint != null) {
+                    if (debug) {
+                        debug("CHECK", category, key, "user provided a", hint.getClass());
+                    }
+                    if (category.isInstance(hint)) {
+                        /*
+                         * The factory implementation was given explicitly by the user.
+                         * Nothing to do; we are done.
+                         */
+                        if (debug) {
+                            debug("RETURN", category, key, "return hint as provided.", null);
+                        }
+                        return category.cast(hint);
+                    }
+                    /*
+                     * Before to pass the hints to the private 'getServiceImplementation' method,
+                     * remove the hint for the user-supplied key.  This is because this hint has
+                     * been processed by this public 'getServiceProvider' method, and the policy
+                     * is to remove the processed hints before to pass them to child dependencies
+                     * (see the "Check recursively in factory dependencies" comment elswhere in
+                     * this class).
+                     *
+                     * Use case: DefaultDataSourceTest invokes indirectly 'getServiceProvider'
+                     * with a "CRS_AUTHORITY_FACTORY = ThreadedEpsgFactory.class" hint. However
+                     * ThreadedEpsgFactory (in the org.geotools.referencing.factory.epsg package)
+                     * is a wrapper around DirectEpsgFactory, and defines this dependency through
+                     * a "CRS_AUTHORITY_FACTORY = DirectEpsgFactory.class" hint. There is no way
+                     * to match this hint for both factories in same time. Since we must choose
+                     * one, we assume that the user is interrested in the most top level one and
+                     * discart this particular hint for the dependencies.
+                     */
+                    hints = new Hints(hints);
+                    if (hints.remove(key) != hint) {
+                        // Should never happen except on concurrent modification in an other thread.
+                        throw new AssertionError(key);
+                    }
+                    /*
+                     * If the user accepts many implementation classes, then try all of them in
+                     * the preference order given by the user. The last class (or the singleton
+                     * if the hint was not an array) will be tried using the "normal" path
+                     * (oustide the loop) in order to get the error message in case of failure.
+                     */
+                    if (hint instanceof Class<?>[]) {
+                        final Class<?>[] types = (Class<?>[]) hint;
+                        final int length = types.length;
+                        for (int i=0; i<length-1; i++) {
+                            final Class<?> type = types[i];
+                            if (debug) {
+                                debug("CHECK", category, key, "consider hint[" + i + ']', type);
+                            }
+                            final T candidate = getServiceImplementation(category, type, filter, hints);
+                            if (candidate != null) {
+                                if (debug) {
+                                    debug("RETURN", category, key, "found implementation", candidate.getClass());
+                                }
+                                return candidate;
+                            }
+                        }
+                        if (length != 0) {
+                            implementation = types[length-1]; // Last try to be done below.
+                        }
+                    } else {
+                        implementation = (Class<?>) hint;
+                    }
+                }
+            }
+        }
+        if (debug && implementation != null) {
+            debug("CHECK", category, key, "consider hint[last]", implementation);
+        }
+        final T candidate = getServiceImplementation(category, implementation, filter, hints);
+        if (candidate != null) {
+            if (debug) {
+                debug("RETURN", category, key, "found implementation", candidate.getClass());
+            }
+            return candidate;
+        }
+        if (debug) {
+            debug("THROW", category, key, "could not find implementation.", null);
+        }
+        throw new FactoryNotFoundException(Errors.format(ErrorKeys.FACTORY_NOT_FOUND_$1,
+                  implementation!=null ? implementation : category));
+    }
+
+    /**
+     * Logs a debug message for {@link #getServiceProvider} method. Note: we are not required
+     * to insert the method name ({@code "GetServiceProvider"}) in the message because it is
+     * part of the informations already stored by {@link LogRecord}, and formatted by the
+     * default {@link java.util.logging.SimpleFormatter}.
+     *
+     * @param status   {@code "ENTRY"}, {@code "RETURN"} or {@code "THROW"},
+     *                 according {@link Logger} conventions.
+     * @param category The category given to the {@link #getServiceProvider} method.
+     * @param key      The key being examined, or {@code null}.
+     * @param message  Optional message, or {@code null} if none.
+     * @param type     Optional class to format after the message, or {@code null}.
+     */
+    private static void debug(final String status, final Class<?> category,
+                              final Hints.Key key, final String message, final Class type)
+    {
+        final StringBuilder buffer = new StringBuilder(status);
+        buffer.append(Utilities.spaces(Math.max(1, 7-status.length())))
+              .append('(').append(Classes.getShortName(category));
+        if (key != null) {
+            buffer.append(", ").append(key);
+        }
+        buffer.append(')');
+        if (message != null) {
+            buffer.append(": ").append(message);
+        }
+        if (type != null) {
+            buffer.append(' ').append(Classes.getShortName(type)).append('.');
+        }
+        final LogRecord record = new LogRecord(DEBUG_LEVEL, buffer.toString());
+        record.setSourceClassName(FactoryRegistry.class.getName());
+        record.setSourceMethodName("getServiceProvider");
+        record.setLoggerName(LOGGER.getName());
+        LOGGER.log(record);
+    }
+
+    /**
+     * Searchs the first implementation in the registery matching the specified conditions.
+     * This method is invoked only by the {@link #getServiceProvider(Class, Filter, Hints,
+     * Hints.Key)} public method above; there is no recursivity there. This method do not
+     * creates new instance if no matching factory is found.
+     *
+     * @param  category       The category to look for. Usually an interface class.
+     * @param  implementation The desired class for the implementation, or {@code null} if none.
+     * @param  filter         An optional filter, or {@code null} if none.
+     * @param  hints          A {@linkplain Hints map of hints}, or {@code null} if none.
+     * @return A factory for the specified category and hints, or {@code null} if none.
+     */
+    private <T> T getServiceImplementation(final Class<T> category, final Class<?> implementation,
+                                           final Filter filter, final Hints hints)
+    {
+        for (final Iterator<T> it=getUnfilteredProviders(category); it.hasNext();) {
+            final T candidate = it.next();
+            // Implementation class must be tested before 'isAcceptable'
+            // in order to avoid StackOverflowError in some situations.
+            if (implementation!=null && !implementation.isInstance(candidate)) {
+                continue;
+            }
+            if (!isAcceptable(candidate, category, hints, filter)) {
+                continue;
+            }
+            return candidate;
+        }
+        final List<Reference<T>> cached = getCachedProviders(category);
+        if (cached != null) {
+            /*
+             * Checks if a factory previously created by FactoryCreator could fit. This
+             * block should never be executed if this instance is not a FactoryCreator.
+             */
+            for (final Iterator<Reference<T>> it=cached.iterator(); it.hasNext();) {
+                final T candidate = it.next().get();
+                if (candidate == null) {
+                    it.remove();
+                    continue;
+                }
+                if (implementation!=null && !implementation.isInstance(candidate)) {
+                    continue;
+                }
+                if (!isAcceptable(candidate, category, hints, filter)) {
+                    continue;
+                }
+                return candidate;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the providers available in the cache, or {@code null} if none.
+     * To be overridden by {@link FactoryCreator} only.
+     */
+    <T> List<Reference<T>> getCachedProviders(final Class<T> category) {
+        return null;
+    }
+
+    /**
+     * Returns {@code true} is the specified {@code factory} meets the requirements specified by
+     * a map of {@code hints} and the filter. This method is the entry point for the following
+     * public methods:
+     * <ul>
+     *   <li>Singleton {@link #getServiceProvider (Class category, Filter, Hints, Hints.Key)}</li>
+     *   <li>Iterator  {@link #getServiceProviders(Class category, Filter, Hints)}</li>
+     * </ul>
+     *
+     * @param candidate The factory to checks.
+     * @param category  The factory category. Usually an interface.
+     * @param hints     The optional user requirements, or {@code null}.
+     * @param filter    The optional filter, or {@code null}.
+     * @return {@code true} if the {@code factory} meets the user requirements.
+     */
+    final <T> boolean isAcceptable(final T candidate, final Class<T> category,
+                                   final Hints hints, final Filter filter)
+    {
+        if (filter!=null && !filter.filter(candidate)) {
+            return false;
+        }
+        /*
+         * Note: isAvailable(...) must be tested before checking the hints, because in current
+         * Geotools implementation (especially DeferredAuthorityFactory), some hints computation
+         * are deferred until a connection to the database is etablished (which 'isAvailable'
+         * does in order to test the connection).
+         */
+        if (!isAvailable(candidate)) {
+            return false;
+        }
+        if (hints != null) {
+            if (candidate instanceof Factory) {
+                if (!usesAcceptableHints((Factory) candidate, category, hints, (Set<Factory>) null)) {
+                    return false;
+                }
+            }
+        }
+        /*
+         * Checks for optional user conditions supplied in FactoryRegistry subclasses.
+         */
+        return isAcceptable(candidate, category, hints);
+    }
+
+    /**
+     * Returns {@code true} is the specified {@code factory} meets the requirements specified
+     * by a map of {@code hints}. This method checks only the hints; it doesn't check the
+     * {@link Filter}, the {@linkplain OptionalFactory#isAvailable availability} or the
+     * user-overrideable {@link #isAcceptable(Object, Class, Hints)} method. This method
+     * invokes itself recursively.
+     *
+     * @param factory     The factory to checks.
+     * @param category    The factory category. Usually an interface.
+     * @param hints       The user requirements ({@code null} not allowed).
+     * @param alreadyDone Should be {@code null} except on recursive calls (for internal use only).
+     * @return {@code true} if the {@code factory} meets the hints requirements.
+     */
+    private boolean usesAcceptableHints(final Factory  factory,
+                                        final Class<?> category,
+                                        final Hints    hints,
+                                        Set<Factory>   alreadyDone)
+    {
+        /*
+         * Ask for implementation hints with special care against infinite recursivity.
+         * Some implementations use deferred algorithms fetching dependencies only when
+         * first needed. The call to getImplementationHints() is sometime a trigger for
+         * fetching dependencies (in order to return accurate hints).   For example the
+         * BufferedCoordinateOperationFactory implementation asks for an other instance
+         * of CoordinateOperationFactory, the instance to cache behind a buffer,  which
+         * should not be itself. Of course BufferedCoordinateOperation will checks that
+         * it is not caching itself, but its test happen too late for preventing a never-
+         * ending loop if we don't put a 'testingHints' guard here. It is also a safety
+         * against broken factory implementations.
+         */
+        if (!testingHints.addAndCheck(factory)) {
+            return false;
+        }
+        final Map<RenderingHints.Key, ?> implementationHints;
+        try {
+            implementationHints = Hints.stripNonKeys(factory.getImplementationHints());
+        } finally {
+            testingHints.removeAndCheck(factory);
+        }
+        if (implementationHints == null) {
+            // factory was bad and did not meet contract - assume it used no Hints
+            return true;
+        }
+        /*
+         * We got the implementation hints. Now tests their compatibility.
+         */
+        Hints remaining = null;
+        for (final Map.Entry<?,?> entry : implementationHints.entrySet()) {
+            final Object    key   = entry.getKey();
+            final Object    value = entry.getValue();
+            final Object expected = hints.get(key);
+            if (expected != null) {
+                /*
+                 * We have found a hint that matter. Check if the
+                 * available factory meets the user's criterions.
+                 */
+                if (expected instanceof Class<?>) {
+                    if (!((Class<?>) expected).isInstance(value)) {
+                        return false;
+                    }
+                } else if (expected instanceof Class<?>[]) {
+                    final Class<?>[] types = (Class<?>[]) expected;
+                    int i = 0;
+                    do if (i >= types.length) return false;
+                    while (!types[i++].isInstance(value));
+                } else if (!expected.equals(value)) {
+                    return false;
+                }
+            }
+            /*
+             * Checks recursively in factory dependencies, if any. Note that the dependencies
+             * will be checked against a subset of user's hints. More specifically, all hints
+             * processed by the current pass will NOT be passed to the factories dependencies.
+             * This is because the same hint may appears in the "parent" factory and a "child"
+             * dependency with different value. For example the FORCE_LONGITUDE_FIRST_AXIS_ORDER
+             * hint has the value TRUE in OrderedAxisAuthorityFactory, but the later is basically
+             * a wrapper around the ThreadedEpsgFactory (typically), which has the value FALSE
+             * for the same hint.
+             *
+             * Additional note: The 'alreadyDone' set is a safety against cyclic dependencies,
+             * in order to protect ourself against never-ending loops. This is not the same
+             * kind of dependencies than 'testingHints'. It is a "factory A depends on factory
+             * B which depends on factory A" loop, which is legal.
+             */
+            if (value instanceof Factory) {
+                final Factory dependency = (Factory) value;
+                if (alreadyDone == null) {
+                    alreadyDone = new HashSet<Factory>();
+                }
+                if (!alreadyDone.contains(dependency)) {
+                    alreadyDone.add(factory);
+                    if (remaining == null) {
+                        remaining = new Hints(hints);
+                        remaining.keySet().removeAll(implementationHints.keySet());
+                    }
+                    final Class<?> type;
+                    if (key instanceof Hints.Key) {
+                        type = ((Hints.Key) key).getValueClass();
+                    } else {
+                        type = Factory.class; // Kind of unknown factory type...
+                    }
+                    // Recursive call to this method for scanning dependencies.
+                    if (!usesAcceptableHints(dependency, type, remaining, alreadyDone)) {
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns {@code true} if the specified {@code provider} meets the requirements specified by
+     * a map of {@code hints}. The default implementation always returns {@code true}. There is no
+     * need to override this method for {@link AbstractFactory} implementations, since their hints
+     * are automatically checked. Override this method for non-Geotools implementations.
+     * For example a JTS geometry factory finder may overrides this method in order to check
+     * if a {@link com.vividsolutions.jts.geom.GeometryFactory} uses the required
+     * {@link com.vividsolutions.jts.geom.CoordinateSequenceFactory}. Such method should be
+     * implemented as below, since this method may be invoked for various kind of objects:
+     *
+     * <blockquote><pre>
+     * if (provider instanceof GeometryFactory) {
+     *     // ... Check the GeometryFactory state here.
+     * }
+     * </pre></blockquote>
+     *
+     * @param <T>      The class represented by the {@code category} argument.
+     * @param provider The provider to checks.
+     * @param category The factory category. Usually an interface.
+     * @param hints    The user requirements, or {@code null} if none.
+     * @return {@code true} if the {@code provider} meets the user requirements.
+     */
+    protected <T> boolean isAcceptable(final T provider, final Class<T> category, final Hints hints) {
+        return true;
+    }
+
+    /**
+     * Returns {@code true} if the specified factory is available.
+     */
+    private boolean isAvailable(final Object provider) {
+        if (!(provider instanceof OptionalFactory)) {
+            return true;
+        }
+        final OptionalFactory factory = (OptionalFactory) provider;
+        final Class<? extends OptionalFactory> type = factory.getClass();
+        if (!testingAvailability.addAndCheck(type)) {
+            throw new RecursiveSearchException(type);
+        }
+        try {
+            return factory.isAvailable();
+        } finally {
+            testingAvailability.removeAndCheck(type);
+        }
+    }
+    
+    /**
+     * Returns all class loaders to be used for scanning plugins. Current implementation
+     * returns the following class loaders:
+     * <p>
+     * <ul>
+     *   <li>{@linkplain Class#getClassLoader This object class loader}</li>
+     *   <li>{@linkplain Thread#getContextClassLoader The thread context class loader}</li>
+     *   <li>{@linkplain ClassLoader#getSystemClassLoader The system class loader}</li>
+     * </ul>
+     *
+     * The actual number of class loaders may be smaller if redundancies was found.
+     * If some more classloaders should be scanned, they shall be added into the code
+     * of this method.
+     *
+     * @return All classloaders to be used for scanning plugins.
+     */
+    public final Set<ClassLoader> getClassLoaders() {
+        final Set<ClassLoader> loaders = new HashSet<ClassLoader>();
+        for (int i=0; i<4; i++) {
+            final ClassLoader loader;
+            try {
+                switch (i) {
+                    case 0:  loader = getClass().getClassLoader();                    break;
+                    case 1:  loader = FactoryRegistry.class.getClassLoader();         break;
+                    case 2:  loader = Thread.currentThread().getContextClassLoader(); break;
+                    case 3:  loader = ClassLoader.getSystemClassLoader();             break;
+                    // Add any supplementary class loaders here, if needed.
+                    default: throw new AssertionError(i); // Should never happen.
+                }
+            } catch (SecurityException exception) {
+                // We are not allowed to get a class loader.
+                // Continue; some other class loader may be available.
+                continue;
+            }
+            loaders.add(loader);
+        }
+        loaders.remove(null);
+        /*
+         * We now have a set of class loaders with duplicated object already removed
+         * (e.g. system classloader == context classloader). However, we may still
+         * have an other form of redundancie. A class loader may be the parent of an
+         * other one. Try to remove those dependencies.
+         */
+        final ClassLoader[] asArray = loaders.toArray(new ClassLoader[loaders.size()]);
+        for (int i=0; i<asArray.length; i++) {
+            ClassLoader loader = asArray[i];
+            try {
+                while ((loader=loader.getParent()) != null) {
+                    loaders.remove(loader);
+                }
+            } catch (SecurityException exception) {
+                // We are not allowed to fetch the parent class loader.
+                // Ignore (some redundancies may remains).
+            }
+        }
+        if (loaders.isEmpty()) {
+            LOGGER.warning("No class loaders available.");
+        }
+        return loaders;
+    }
+
+    /**
+     * Scans for factory plug-ins of the given category, with guard against recursivities.
+     * The recursivity check make debugging easier than inspecting a {@link StackOverflowError}.
+     *
+     * @param loader The class loader to use.
+     * @param category The category to scan for plug-ins.
+     */
+    private <T> void scanForPlugins(final Collection<ClassLoader> loaders, final Class<T> category) {
+        if (!scanningCategories.addAndCheck(category)) {
+            throw new RecursiveSearchException(category);
+        }
+        try {
+            final StringBuilder message = getLogHeader(category);
+            boolean newServices = false;
+            /*
+             * First, scan META-INF/services directories (the default mechanism).
+             */
+            for (final ClassLoader loader : loaders) {
+                newServices |= register(lookupProviders(category, loader), category, message);
+                newServices |= registerFromSystemProperty(loader, category, message);
+            }
+            /*
+             * Next, query the user-provider iterators, if any.
+             */
+            final FactoryIteratorProvider[] fip = FactoryIteratorProviders.getIteratorProviders();
+            for (int i=0; i<fip.length; i++) {
+                final Iterator<T> it = fip[i].iterator(category);
+                if (it != null) {
+                    newServices |= register(it, category, message);
+                }
+            }
+            /*
+             * Finally, log the list of registered factories.
+             */
+            if (newServices) {
+                log("scanForPlugins", message);
+            }
+        } finally {
+            scanningCategories.removeAndCheck(category);
+        }
+    }
+
+    /**
+     * Scans the given category for plugins only if needed. After this method has been
+     * invoked once for a given category, it will no longer scan for that category.
+     */
+    private <T> void scanForPluginsIfNeeded(final Class<?> category) {
+        if (needScanForPlugins != null && needScanForPlugins.remove(category)) {
+            if (needScanForPlugins.isEmpty()) {
+                needScanForPlugins = null;
+            }
+            scanForPlugins(getClassLoaders(), category);
+        }
+    }
+
+    /**
+     * {@linkplain #registerServiceProvider Registers} all factories given by the
+     * supplied iterator.
+     *
+     * @param factories The factories (or "service providers") to register.
+     * @param category  the category under which to register the providers.
+     * @param message   A buffer where to write the logging message.
+     * @return {@code true} if at least one factory has been registered.
+     */
+    private <T> boolean register(final Iterator<T> factories, final Class<T> category,
+                                 final StringBuilder message)
+    {
+        boolean newServices = false;
+        final String lineSeparator = System.getProperty("line.separator", "\n");
+        while (factories.hasNext()) {
+            T factory;
+            try {
+                factory = factories.next();
+            } catch (OutOfMemoryError error) {
+                // Makes sure that we don't try to handle this error.
+                throw error;
+            } catch (NoClassDefFoundError error) {
+                /*
+                 * A provider can't be registered because of some missing dependencies.
+                 * This occurs for example when trying to register the WarpTransform2D
+                 * math transform on a machine without JAI installation. Since the factory
+                 * may not be essential (this is the case of WarpTransform2D), just skip it.
+                 */
+                loadingFailure(category, error, false);
+                continue;
+            } catch (ExceptionInInitializerError error) {
+                /*
+                 * If an exception occured during class initialization, log the cause.
+                 * The ExceptionInInitializerError alone doesn't help enough.
+                 */
+                final Throwable cause = error.getCause();
+                if (cause != null) {
+                    loadingFailure(category, cause, true);
+                }
+                throw error;
+            } catch (Error error) {
+                if (!Classes.getShortClassName(error).equals("ServiceConfigurationError")) {
+                    // We want to handle sun.misc.ServiceConfigurationError only. Unfortunatly, we
+                    // need to rely on reflection because this error class is not a commited API.
+                    // TODO: Check if the error is catchable with JSE 6.
+                    throw error;
+                }
+                /*
+                 * Failed to register a factory for a reason probably related to the plugin
+                 * initialisation. It may be some factory-dependent missing resources.
+                 */
+                loadingFailure(category, error, true);
+                continue;
+            }
+            final Class<? extends T> factoryClass = factory.getClass().asSubclass(category);
+            /*
+             * If the factory implements more than one interface and an instance were
+             * already registered, reuse the same instance instead of duplicating it.
+             */
+            final T replacement = getServiceProviderByClass(factoryClass);
+            if (replacement != null) {
+                factory = replacement;
+                // Need to register anyway, because the category may not be the same.
+            }
+            if (registerServiceProvider(factory, category)) {
+                /*
+                 * The factory is now registered. Add it to the message to be logged. We will log
+                 * all factories together in a single log event because some registration (e.g.
+                 * MathTransformProviders) would be otherwise quite verbose.
+                 */
+                message.append(lineSeparator);
+                message.append("  ");
+                message.append(factoryClass.getName());
+                newServices = true;
+            }
+        }
+        return newServices;
+    }
+
+    /**
+     * If a system property was setup, load the class (if not already registered)
+     * and move it in front of any other factory. This is done for compatibility
+     * with legacy {@code FactoryFinder} implementation.
+     *
+     * @param loader   The class loader to use.
+     * @param category The category to scan for plug-ins.
+     * @param message  A buffer where to write the logging message.
+     * @return {@code true} if at least one factory has been registered.
+     */
+    private <T> boolean registerFromSystemProperty(final ClassLoader loader,
+            final Class<T> category, final StringBuilder message)
+    {
+        boolean newServices = false;
+        try {
+            final String classname = System.getProperty(category.getName());
+            if (classname != null) try {
+                final Class<?> candidate = loader.loadClass(classname);
+                if (category.isAssignableFrom(candidate)) {
+                    final Class<? extends T> factoryClass = candidate.asSubclass(category);
+                    T factory = getServiceProviderByClass(factoryClass);
+                    if (factory == null) try {
+                        factory = factoryClass.newInstance();
+                        if (registerServiceProvider(factory, category)) {
+                            message.append(System.getProperty("line.separator", "\n"));
+                            message.append("  ");
+                            message.append(factoryClass.getName());
+                            newServices = true;
+                        }
+                    } catch (IllegalAccessException exception) {
+                        throw new FactoryRegistryException(Errors.format(
+                                ErrorKeys.CANT_CREATE_FACTORY_$1, classname), exception);
+                    } catch (InstantiationException exception) {
+                        throw new FactoryRegistryException(Errors.format(
+                                ErrorKeys.CANT_CREATE_FACTORY_$1, classname), exception);
+                    }
+                    /*
+                     * Put this factory in front of every other factories (including the ones loaded
+                     * in previous class loaders, which is why we don't inline this ordering in the
+                     * 'register' loop). Note: if some factories were not yet registered, they will
+                     * not be properly ordered. Since this code exists more for compatibility reasons
+                     * than as a commited API, we ignore this short comming for now.
+                     */
+                    for (final Iterator<T> it=getServiceProviders(category, false); it.hasNext();) {
+                        final T other = it.next();
+                        if (other != factory) {
+                            setOrdering(category, factory, other);
+                        }
+                    }
+                }
+            } catch (ClassNotFoundException exception) {
+                // The class has not been found, maybe because we are not using the appropriate
+                // class loader. Ignore (do not thrown an exception), in order to give a chance
+                // to the caller to invokes this method again with a different class loader.
+            }
+        } catch (SecurityException exception) {
+            // We are not allowed to read property, probably
+            // because we are running in an applet. Ignore...
+        }
+        return newServices;
+    }
+
+    /**
+     * Invoked when a factory can't be loaded. Log a warning, but do not stop the process.
+     */
+    private static void loadingFailure(final Class<?> category, final Throwable error,
+                                       final boolean showStackTrace)
+    {
+        final String         name = Classes.getShortName(category);
+        final StringBuilder cause = new StringBuilder(Classes.getShortClassName(error));
+        final String      message = error.getLocalizedMessage();
+        if (message != null) {
+            cause.append(": ");
+            cause.append(message);
+        }
+        final LogRecord record = Loggings.format(Level.WARNING,
+                LoggingKeys.CANT_LOAD_SERVICE_$2, name, cause.toString());
+        if (showStackTrace) {
+            record.setThrown(error);
+        }
+        record.setSourceClassName(FactoryRegistry.class.getName());
+        record.setSourceMethodName("scanForPlugins");
+        record.setLoggerName(LOGGER.getName());
+        LOGGER.log(record);
+    }
+
+    /**
+     * Prepares a message to be logged if any provider has been registered.
+     */
+    private static StringBuilder getLogHeader(final Class<?> category) {
+        return new StringBuilder(Loggings.getResources(null).getString(
+                LoggingKeys.FACTORY_IMPLEMENTATIONS_$1, category));
+    }
+
+    /**
+     * Log the specified message after all provider for a given category have been registered.
+     */
+    private static void log(final String method, final StringBuilder message) {
+        final LogRecord record = new LogRecord(Level.CONFIG, message.toString());
+        record.setSourceClassName(FactoryRegistry.class.getName());
+        record.setSourceMethodName(method);
+        record.setLoggerName(LOGGER.getName());
+        LOGGER.log(record);
+    }
+
+    /**
+     * Synchronizes the content of the {@link #globalConfiguration} with
+     * {@link FactoryIteratorProviders#GLOBAL}. New providers are {@linkplain #register registered}
+     * immediately. Note that this method is typically invoked in a different thread than
+     * {@link FactoryIteratorProviders} method calls.
+     *
+     * @see FactoryIteratorProviders#addFactoryIteratorProvider
+     */
+    private void synchronizeIteratorProviders() {
+        final FactoryIteratorProvider[] newProviders =
+                globalConfiguration.synchronizeIteratorProviders();
+        if (newProviders == null) {
+            return;
+        }
+        for (final Iterator<Class<?>> categories=getCategories(); categories.hasNext();) {
+            final Class<?> category = categories.next();
+            if (needScanForPlugins == null || !needScanForPlugins.contains(category)) {
+                /*
+                 * Register immediately the factories only if some other factories were already
+                 * registered for this category,  because in such case scanForPlugin() will not
+                 * be invoked automatically. If no factory are registered for this category, do
+                 * nothing - we will rely on the lazy invocation of scanForPlugins() when first
+                 * needed. We perform this check because getServiceProviders(category).hasNext()
+                 * is the criterion used by FactoryRegistry in order to decide if it should invoke
+                 * automatically scanForPlugins().
+                 */
+                for (int i=0; i<newProviders.length; i++) {
+                    register(newProviders[i], category);
+                }
+            }
+        }
+    }
+
+    /**
+     * Registers every factories from the specified provider for the given category.
+     */
+    private <T> void register(final FactoryIteratorProvider provider, final Class<T> category) {
+        final Iterator<T> it = provider.iterator(category);
+        if (it != null) {
+            final StringBuilder message = getLogHeader(category);
+            if (register(it, category, message)) {
+                log("synchronizeIteratorProviders", message);
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryRegistryException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryRegistryException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/FactoryRegistryException.java	(revision 28000)
@@ -0,0 +1,48 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+
+/**
+ * Thrown when a factory can't be found or can't be instantiate.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/FactoryRegistryException.java $
+ * @version $Id: FactoryRegistryException.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ */
+public class FactoryRegistryException extends RuntimeException {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 8483095037433886648L;
+
+    /**
+     * Creates a new exception with the specified detail message.
+     */
+    public FactoryRegistryException(final String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new exception with the specified detail message and cause.
+     */
+    public FactoryRegistryException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/GeoTools.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/GeoTools.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/GeoTools.java	(revision 28000)
@@ -0,0 +1,306 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+import java.awt.RenderingHints;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.naming.InitialContext;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+
+import org.geotools.resources.Classes;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+import org.geotools.util.logging.Logging;
+
+
+/**
+ * Static methods relative to the global GeoTools configuration. GeoTools can be configured
+ * in a system-wide basis through {@linkplain System#getProperties system properties}, some
+ * of them are declared as {@link String} constants in this class.
+ * <p>
+ * There are many aspects to the configuration of GeoTools:
+ * <ul>
+ *   <li>Default Settings: Are handled as the Hints returned by {@link #getDefaultHints()}, the
+ *       default values can be provided in application code, or specified using system properties.</li>
+ *   <li>Integration JNDI: Telling the GeoTools library about the facilities of an application,
+ *       or application container takes several forms. This class provides the
+ *       {@link #init(InitialContext)} method allowing to tell GeoTools about the JNDI
+ *       context to use.</li>
+ *   <li>Integration Plugins: If hosting GeoTools in a alternate plugin system such as Spring
+ *       or OSGi, application may needs to hunt down the {@code FactoryFinder}s and register
+ *       additional "Factory Iterators" for GeoTools to search using the
+ *       {@link #addFactoryIteratorProvider} method.</li>
+ * </ul>
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/tags/2.7.4/modules/library/metadata/src/main/java/org/geotools/factory/GeoTools.java $
+ * @version $Id: GeoTools.java 38443 2011-12-21 15:17:43Z jdeolive $
+ * @author Jody Garnett
+ * @author Martin Desruisseaux
+ */
+public final class GeoTools {
+        
+    /**
+     * Object to inform about system-wide configuration changes.
+     * We use the Swing utility listener list since it is lightweight and thread-safe.
+     * Note that it doesn't involve any dependency to the remaining of Swing library.
+     */
+    private static final EventListenerList LISTENERS = new EventListenerList();
+
+    /**
+     * The bindings between {@linkplain System#getProperties system properties} and
+     * a hint key. This field must be declared before any call to the {@link #bind}
+     * method.
+     */
+    private static final Map<String, RenderingHints.Key> BINDINGS =
+            new HashMap<String, RenderingHints.Key>();
+
+    /**
+     * The {@linkplain System#getProperty(String) system property} key for the default value to be
+     * assigned to the {@link Hints#CRS_AUTHORITY_EXTRA_DIRECTORY CRS_AUTHORITY_EXTRA_DIRECTORY}
+     * hint.
+     *
+     * @see Hints#CRS_AUTHORITY_EXTRA_DIRECTORY
+     * @see #getDefaultHints
+     */
+    public static final String CRS_AUTHORITY_EXTRA_DIRECTORY =
+            "org.geotools.referencing.crs-directory";
+    static {
+        bind(CRS_AUTHORITY_EXTRA_DIRECTORY, Hints.CRS_AUTHORITY_EXTRA_DIRECTORY);
+    }
+
+    /**
+     * The {@linkplain System#getProperty(String) system property} key for the default
+     * value to be assigned to the {@link Hints#EPSG_DATA_SOURCE EPSG_DATA_SOURCE} hint.
+     *
+     * @see Hints#EPSG_DATA_SOURCE
+     * @see #getDefaultHints
+     */
+    public static final String EPSG_DATA_SOURCE =
+            "org.geotools.referencing.epsg-datasource";
+    static {
+        bind(EPSG_DATA_SOURCE, Hints.EPSG_DATA_SOURCE);
+    }
+
+    /**
+     * The {@linkplain System#getProperty(String) system property} key for the default
+     * value to be assigned to the {@link Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER
+     * FORCE_LONGITUDE_FIRST_AXIS_ORDER} hint.
+     *
+     * This setting can provide a transition path for projects expecting a (<var>longitude</var>,
+     * <var>latitude</var>) axis order on a system-wide level. Application developpers can set the
+     * default value as below:
+     *
+     * <blockquote><pre>
+     * System.setProperty(FORCE_LONGITUDE_FIRST_AXIS_ORDER, "true");
+     * </pre></blockquote>
+     *
+     * Note that this system property applies mostly to the default EPSG factory. Most other
+     * factories ({@code "CRS"}, {@code "AUTO"}, <cite>etc.</cite>) don't need this property
+     * since they use (<var>longitude</var>, <var>latitude</var>) axis order by design.
+     *
+     * @see Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER
+     * @see #getDefaultHints
+     */
+    public static final String FORCE_LONGITUDE_FIRST_AXIS_ORDER =
+            "org.geotools.referencing.forceXY";
+    static {
+        bind(FORCE_LONGITUDE_FIRST_AXIS_ORDER, Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER);
+    }
+    
+    /**
+     * The {@linkplain System#getProperty(String) system property} key for the default
+     * value to be assigned to the {@link Hints#
+     * RESAMPLE_TOLERANCE} hint.
+     *
+     * This setting specifies the tolerance used when linearizing warp transformation into
+     * piecewise linear ones, by default it is 0.333 pixels
+     *
+     * @see Hints#RESAMPLE_TOLERANCE
+     * @see #getDefaultHints
+     */
+    public static final String RESAMPLE_TOLERANCE =
+            "org.geotools.referencing.resampleTolerance";
+    static {
+        bind(RESAMPLE_TOLERANCE, Hints.RESAMPLE_TOLERANCE);
+    }
+
+    /**
+     * Do not allow instantiation of this class.
+     */
+    private GeoTools() {
+    }
+
+    /**
+     * Binds the specified {@linkplain System#getProperty(String) system property}
+     * to the specified key. Only one key can be binded to a given system property.
+     * However the same key can be binded to more than one system property names,
+     * in which case the extra system property names are aliases.
+     *
+     * @param  property The system property.
+     * @param  key The key to bind to the system property.
+     * @throws IllegalArgumentException if an other key is already bounds
+     *         to the given system property.
+     */
+    private static void bind(final String property, final RenderingHints.Key key) {
+        synchronized (BINDINGS) {
+            final RenderingHints.Key old = BINDINGS.put(property, key);
+            if (old == null) {
+                return;
+            }
+            // Roll back
+            BINDINGS.put(property, old);
+        }
+        throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2,
+                "property", property));
+    }
+
+    /**
+     * Scans {@linkplain System#getProperties system properties} for any property keys
+     * defined in this class, and add their values to the specified map of hints. For
+     * example if the {@value #FORCE_LONGITUDE_FIRST_AXIS_ORDER} system property is
+     * defined, then the {@link Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER
+     * FORCE_LONGITUDE_FIRST_AXIS_ORDER} hint will be added to the set of hints.
+     *
+     * @return {@code true} if at least one hint changed as a result of this scan,
+     *         or {@code false} otherwise.
+     */
+    static boolean scanForSystemHints(final Hints hints) {
+        assert Thread.holdsLock(hints);
+        boolean changed = false;
+        synchronized (BINDINGS) {
+            for (final Map.Entry<String, RenderingHints.Key> entry : BINDINGS.entrySet()) {
+                final String propertyKey = entry.getKey();
+                final String property;
+                try {
+                    property = System.getProperty(propertyKey);
+                } catch (SecurityException e) {
+                    unexpectedException(e);
+                    continue;
+                }
+                if (property != null) {
+                    /*
+                     * Converts the system property value from String to Object (java.lang.Boolean
+                     * or java.lang.Number). We perform this conversion only if the key is exactly
+                     * of kind Hints.Key,  not a subclass like ClassKey, in order to avoid useless
+                     * class loading on  'getValueClass()'  method invocation (ClassKey don't make
+                     * sense for Boolean and Number, which are the only types that we convert here).
+                     */
+                    Object value = property;
+                    final RenderingHints.Key hintKey = entry.getValue();
+                    if (hintKey.getClass().equals(Hints.Key.class)) {
+                        final Class<?> type = ((Hints.Key) hintKey).getValueClass();
+                        if (type.equals(Boolean.class)) {
+                            value = Boolean.valueOf(property);
+                        } else if (Number.class.isAssignableFrom(type)) try {
+                            value = Classes.valueOf(type, property);
+                        } catch (NumberFormatException e) {
+                            unexpectedException(e);
+                            continue;
+                        }
+                    }
+                    final Object old;
+                    try {
+                        old = hints.put(hintKey, value);
+                    } catch (IllegalArgumentException e) {
+                        // The property value is illegal for this hint.
+                        unexpectedException(e);
+                        continue;
+                    }
+                    if (!changed && !Utilities.equals(old, value)) {
+                        changed = true;
+                    }
+                }
+            }
+        }
+        return changed;
+    }
+
+    /**
+     * Logs an exception as if it originated from {@link Hints#scanSystemProperties},
+     * since it is the public API that may invokes this method.
+     */
+    private static void unexpectedException(final Exception exception) {
+        Logging.unexpectedException(Hints.class, "scanSystemProperties", exception);
+    }
+
+    /**
+     * Returns the default set of hints used for the various utility classes.
+     * This default set is determined by:
+     * <p>
+     * <ul>
+     *   <li>The {@linplain System#getProperties system properties} available. Some property
+     *       keys are enumerated in the {@link GeoTools} class.</li>
+     *   <li>Any hints added by call to the {@link Hints#putSystemDefault}
+     *       or {@link #init} method.</li>
+     * </ul>
+     * <p>
+     * <b>Long term plan:</b>
+     * We would like to transition the utility classes to being injected with their
+     * required factories, either by taking Hints as part of their constructor, or
+     * otherwise. Making this change would be a three step process 1) create instance
+     * methods for each static final class method 2) create an singleton instance of the
+     * class 3) change each static final class method into a call to the singleton. With
+     * this in place we could then encourage client code to make use of utility class
+     * instances before eventually retiring the static final methods.
+     *
+     * @return A copy of the default hints. It is safe to add to it.
+     */
+    public static Hints getDefaultHints() {
+        return Hints.getDefaults(false);
+    }
+
+    /**
+     * Adds the specified listener to the list of objects to inform when system-wide
+     * configuration changed.
+     *
+     * @param listener The listener to add.
+     */
+    public static void addChangeListener(final ChangeListener listener) {
+        removeChangeListener(listener); // Ensure singleton.
+        LISTENERS.add(ChangeListener.class, listener);
+    }
+
+    /**
+     * Removes the specified listener from the list of objects to inform when system-wide
+     * configuration changed.
+     *
+     * @param listener The listener to remove.
+     */
+    public static void removeChangeListener(final ChangeListener listener) {
+        LISTENERS.remove(ChangeListener.class, listener);
+    }
+
+    /**
+     * Informs every listeners that system-wide configuration changed.
+     */
+    public static void fireConfigurationChanged() {
+        final ChangeEvent event = new ChangeEvent(GeoTools.class);
+        final Object[] listeners = LISTENERS.getListenerList();
+        for (int i=0; i<listeners.length; i+=2) {
+            if (listeners[i] == ChangeListener.class) {
+                ((ChangeListener) listeners[i+1]).stateChanged(event);
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/Hints.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/Hints.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/Hints.java	(revision 28000)
@@ -0,0 +1,1173 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+import java.awt.RenderingHints;
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.naming.Name;
+import javax.sql.DataSource;
+
+import org.geotools.util.Utilities;
+import org.geotools.util.logging.Logging;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * A set of hints providing control on factories to be used. Those hints are typically used by
+ * renderers or {@linkplain org.opengis.coverage.processing.GridCoverageProcessor grid coverage
+ * processors} for example. They provides a way to control low-level details. Example:
+ * <p>
+ * <blockquote><pre>
+ * CoordinateOperationFactory myFactory = &amp;hellip
+ * Hints hints = new Hints(Hints.{@linkplain #COORDINATE_OPERATION_FACTORY}, myFactory);
+ * AbstractProcessor processor = new DefaultProcessor(hints);
+ * </pre></blockquote>
+ * <p>
+ * Any hint mentioned by this class is considered to be API, failure to make
+ * use of a hint by a GeoTools factory implementation is considered a bug (as
+ * it will prevent the use of this library for application specific tasks).
+ * <p>
+ * When hints are used in conjunction with the {@linkplain FactoryRegistry factory service
+ * discovery mechanism} we have the complete geotools plugin system. By using hints to
+ * allow application code to effect service discovery we allow client code to
+ * retarget the geotools library for their needs.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/Hints.java $
+ * @version $Id: Hints.java 38414 2011-12-13 09:39:22Z aaime $
+ * @author Martin Desruisseaux
+ * @author Jody Garnett
+ */
+public class Hints extends RenderingHints {
+    /**
+     * A set of system-wide hints to use by default.
+     */
+    private static final Hints GLOBAL = new Hints();
+
+    /**
+     * {@code true} if {@link #scanSystemProperties} needs to be invoked.
+     */
+    private static boolean needScan = true;
+
+
+
+    ////////////////////////////////////////////////////////////////////////
+    ////////                                                        ////////
+    ////////              Coordinate Reference Systems              ////////
+    ////////                                                        ////////
+    ////////////////////////////////////////////////////////////////////////
+
+    /**
+     * The {@link org.opengis.referencing.crs.CRSAuthorityFactory} instance to use.
+     *
+     * @see org.geotools.referencing.FactoryFinder#getCRSAuthorityFactory
+     */
+    public static final ClassKey CRS_AUTHORITY_FACTORY = new ClassKey(
+            "org.opengis.referencing.crs.CRSAuthorityFactory");
+
+    /**
+     * The {@link org.opengis.referencing.cs.CSAuthorityFactory} instance to use.
+     *
+     * @see org.geotools.referencing.FactoryFinder#getCSAuthorityFactory
+     */
+    public static final ClassKey CS_AUTHORITY_FACTORY = new ClassKey(
+            "org.opengis.referencing.cs.CSAuthorityFactory");
+
+    /**
+     * The {@link org.opengis.referencing.datum.DatumAuthorityFactory} instance to use.
+     *
+     * @see org.geotools.referencing.FactoryFinder#getDatumAuthorityFactory
+     */
+    public static final ClassKey DATUM_AUTHORITY_FACTORY = new ClassKey(
+            "org.opengis.referencing.datum.DatumAuthorityFactory");
+
+    /**
+     * The {@link org.opengis.referencing.crs.CRSFactory} instance to use.
+     *
+     * @see org.geotools.referencing.FactoryFinder#getCRSFactory
+     */
+    public static final ClassKey CRS_FACTORY = new ClassKey(
+            "org.opengis.referencing.crs.CRSFactory");
+
+    /**
+     * The {@link org.opengis.referencing.cs.CSFactory} instance to use.
+     *
+     * @see org.geotools.referencing.FactoryFinder#getCSFactory
+     */
+    public static final ClassKey CS_FACTORY = new ClassKey(
+            "org.opengis.referencing.cs.CSFactory");
+
+    /**
+     * The {@link org.opengis.referencing.datum.DatumFactory} instance to use.
+     *
+     * @see org.geotools.referencing.FactoryFinder#getDatumFactory
+     */
+    public static final ClassKey DATUM_FACTORY = new ClassKey(
+            "org.opengis.referencing.datum.DatumFactory");
+
+    /**
+     * The {@link org.opengis.referencing.operation.CoordinateOperationFactory} instance to use.
+     *
+     * @see org.geotools.referencing.FactoryFinder#getCoordinateOperationFactory
+     */
+    public static final ClassKey COORDINATE_OPERATION_FACTORY = new ClassKey(
+            "org.opengis.referencing.operation.CoordinateOperationFactory");
+
+    /**
+     * The {@link org.opengis.referencing.operation.CoordinateOperationAuthorityFactory} instance
+     * to use.
+     *
+     * @see org.geotools.referencing.FactoryFinder#getCoordinateOperationAuthorityFactory
+     */
+    public static final ClassKey COORDINATE_OPERATION_AUTHORITY_FACTORY = new ClassKey(
+            "org.opengis.referencing.operation.CoordinateOperationAuthorityFactory");
+
+    /**
+     * The {@link org.opengis.referencing.operation.MathTransformFactory} instance to use.
+     *
+     * @see org.geotools.referencing.FactoryFinder#getMathTransformFactory
+     */
+    public static final ClassKey MATH_TRANSFORM_FACTORY = new ClassKey(
+            "org.opengis.referencing.operation.MathTransformFactory");
+
+    /**
+     * Used to direct WKT CRS Authority to a directory containing extra definitions.
+     * The value should be an instance of {@link File} or {@link String} refering to
+     * an existing directory.
+     * <p>
+     * Filenames in the supplied directory should be of the form
+     * <code><var>authority</var>.properties</code> where <var>authority</var>
+     * is the authority name space to use. For example the
+     * {@value org.geotools.referencing.factory.epsg.FactoryUsingWKT#FILENAME}
+     * file contains extra CRS to add as new EPSG codes.
+     * <p>
+     * To set the directory on the command line:
+     *
+     * <blockquote><pre>
+     * -D{@value GeoTools#CRS_AUTHORITY_EXTRA_DIRECTORY}=<var>path</var>
+     * </pre></blockquote>
+     *
+     * @since 2.4
+     */
+    public static final FileKey CRS_AUTHORITY_EXTRA_DIRECTORY = new FileKey(false);
+
+    /**
+     * The {@linkplain javax.sql.DataSource data source} name to lookup from JNDI when
+     * initializing the {@linkplain org.geotools.referencing.factory.epsg EPSG factory}.
+     * Possible values:
+     * <ul>
+     *   <li>{@link String} - used with JNDI to locate datasource. This hint has no effect if
+     *       there is no {@linkplain javax.naming.InitialContext JNDI initial context} setup.</li>
+     *   <li>{@linkplain javax.sql.DataSource} - used as is.</li>
+     *   <li>missing - default to
+     *       {@value org.geotools.referencing.factory.epsg.ThreadedEpsgFactory#DATASOURCE_NAME}.</li>
+     * </ul>
+     * <p>
+     * To set on the command line:
+     * <blockquote><pre>
+     * -D{@value GeoTools#EPSG_DATA_SOURCE}=<var>jndiReference</var>
+     * </pre></blockquote>
+     *
+     * @since 2.4
+     */
+    public static final Key EPSG_DATA_SOURCE = new DataSourceKey();
+
+    /**
+     * The preferred datum shift method to use for
+     * {@linkplain org.opengis.referencing.operation.CoordinateOperation coordinate operations}.
+     * Valid values are {@code "Molodenski"}, {@code "Abridged_Molodenski"} or {@code "Geocentric"}.
+     * Other values may be supplied if a {@linkplain org.opengis.referencing.operation.MathTransform
+     * math transform} exists for that name, but this is not guaranteed to work.
+     *
+     * @see org.geotools.referencing.FactoryFinder#getCoordinateOperationFactory
+     */
+    public static final OptionKey DATUM_SHIFT_METHOD = new OptionKey(
+            "Molodenski", "Abridged_Molodenski", "Geocentric", "*");
+
+    /**
+     * Tells if {@linkplain org.opengis.referencing.operation.CoordinateOperation coordinate
+     * operations} should be allowed even when a datum shift is required while no method is
+     * found applicable. It may be for example that no
+     * {@linkplain org.geotools.referencing.datum.BursaWolfParameters Bursa Wolf parameters}
+     * were found for a datum shift. The default value is {@link Boolean#FALSE FALSE}, which means
+     * that {@linkplain org.geotools.referencing.operation.DefaultCoordinateOperationFactory
+     * coordinate operation factory} throws an exception if such a case occurs. If this hint is
+     * set to {@code TRUE}, then the user is strongly encouraged to check the
+     * {@linkplain org.opengis.referencing.operation.CoordinateOperation#getPositionalAccuracy
+     * positional accuracy} for every transformation created. If the set of positional accuracy
+     * contains {@link org.geotools.metadata.iso.quality.PositionalAccuracyImpl#DATUM_SHIFT_OMITTED
+     * DATUM_SHIFT_OMITTED}, this means that an "ellipsoid shift" were applied without real datum
+     * shift method available, and the transformed coordinates may have one kilometer error. The
+     * application should warn the user (e.g. popup a message dialog box) in such case.
+     *
+     * @see org.geotools.referencing.FactoryFinder#getCoordinateOperationFactory
+     */
+    public static final Key LENIENT_DATUM_SHIFT = new Key(Boolean.class);
+
+    /**
+     * Tells if the {@linkplain org.opengis.referencing.cs.CoordinateSystem coordinate systems}
+     * created by an {@linkplain org.opengis.referencing.cs.CSAuthorityFactory authority factory}
+     * should be forced to (<var>longitude</var>,<var>latitude</var>) axis order. This hint is
+     * especially useful for creating
+     * {@linkplan org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference system}
+     * objects from <A HREF="http://www.epsg.org">EPSG</A> codes. Most
+     * {@linkplan org.opengis.referencing.crs.GeographicCRS geographic CRS} defined in the EPSG
+     * database use (<var>latitude</var>,<var>longitude</var>) axis order. Unfortunatly, many data
+     * sources available in the world uses the opposite axis order and still claim to use a CRS
+     * described by an EPSG code. This hint allows to handle such data.
+     * <p>
+     * This hint shall be passed to the
+     * <code>{@linkplain org.geotools.referencing.FactoryFinder#getCRSAuthorityFactory
+     * FactoryFinder.getCRSAuthorityFactory}(...)</code> method. Whatever this hint is supported
+     * or not is authority dependent. In the default Geotools configuration, this hint is supported
+     * for the {@code "EPSG"} authority.
+     * <p>
+     * If this hint is not provided, then the default value depends on many factors including
+     * {@linkplain System#getProperties system properties} and plugins available in the classpath.
+     * In Geotools implementation, the default value is usually {@link Boolean#FALSE FALSE} with
+     * one exception: If the <code>{@value
+     * org.geotools.referencing.factory.epsg.LongitudeFirstFactory#SYSTEM_DEFAULT_KEY}</code>
+     * system property is set to {@code true}, then the default value is {@code true} at least
+     * for the {@linkplain org.geotools.referencing.factory.epsg.ThreadedEpsgFactory default EPSG
+     * factory}.
+     * <p>
+     * If both the above-cited system property and this hint are provided, then
+     * this hint has precedence. This allow axis order control on a data store
+     * basis, and keep the system-wide property as the default value only for
+     * cases where axis order is unspecified.
+     * <p>
+     * To set on the command line:
+     * <blockquote><pre>
+     * -D{@value GeoTools#FORCE_LONGITUDE_FIRST_AXIS_ORDER}=<var>longitudeFirst</var>
+     * </pre></blockquote>
+     *
+     * @see org.geotools.referencing.FactoryFinder#getCSFactory
+     * @see org.geotools.referencing.FactoryFinder#getCRSFactory
+     * @see org.geotools.referencing.factory.OrderedAxisAuthorityFactory
+     * @see org.geotools.referencing.factory.epsg.LongitudeFirstFactory
+     * @tutorial http://docs.codehaus.org/display/GEOTOOLS/The+axis+order+issue
+     *
+     * @since 2.3
+     */
+    public static final Key FORCE_LONGITUDE_FIRST_AXIS_ORDER = new Key(Boolean.class);
+
+    /**
+     * Tells if the {@linkplain org.opengis.referencing.cs.CoordinateSystem coordinate systems}
+     * created by an {@linkplain org.opengis.referencing.cs.CSAuthorityFactory authority factory}
+     * should be forced to standard
+     * {@linkplain org.opengis.referencing.cs.CoordinateSystemAxis#getDirection axis directions}.
+     * If {@code true}, then {@linkplain org.opengis.referencing.cs.AxisDirection#SOUTH South} axis
+     * directions are forced to {@linkplain org.opengis.referencing.cs.AxisDirection#NORTH North},
+     * {@linkplain org.opengis.referencing.cs.AxisDirection#WEST West} axis directions are forced to
+     * {@linkplain org.opengis.referencing.cs.AxisDirection#EAST East}, <cite>etc.</cite>
+     * If {@code false}, then the axis directions are left unchanged.
+     * <p>
+     * This hint shall be passed to the
+     * <code>{@linkplain org.geotools.referencing.FactoryFinder#getCRSAuthorityFactory
+     * FactoryFinder.getCRSAuthorityFactory}(...)</code>
+     * method. Whatever this hint is supported or not is authority dependent.
+     *
+     * @see org.geotools.referencing.FactoryFinder#getCSFactory
+     * @see org.geotools.referencing.FactoryFinder#getCRSFactory
+     * @see org.geotools.referencing.factory.OrderedAxisAuthorityFactory
+     *
+     * @since 2.3
+     */
+    public static final Key FORCE_STANDARD_AXIS_DIRECTIONS = new Key(Boolean.class);
+
+    /**
+     * Tells if the {@linkplain org.opengis.referencing.cs.CoordinateSystem coordinate systems}
+     * created by an {@linkplain org.opengis.referencing.cs.CSAuthorityFactory authority factory}
+     * should be forced to standard
+     * {@linkplain org.opengis.referencing.cs.CoordinateSystemAxis#getUnit axis units}.
+     * If {@code true}, then all angular units are forced to degrees and linear units to meters.
+     * If {@code false}, then the axis units are left unchanged.
+     * <p>
+     * This hint shall be passed to the
+     * <code>{@linkplain org.geotools.referencing.FactoryFinder#getCRSAuthorityFactory
+     * FactoryFinder.getCRSAuthorityFactory}(...)</code> method. Whatever this hint is
+     * supported or not is authority dependent.
+     *
+     * @see org.geotools.referencing.FactoryFinder#getCSFactory
+     * @see org.geotools.referencing.FactoryFinder#getCRSFactory
+     * @see org.geotools.referencing.factory.OrderedAxisAuthorityFactory
+     *
+     * @since 2.3
+     */
+    public static final Key FORCE_STANDARD_AXIS_UNITS = new Key(Boolean.class);
+      
+    ////////////////////////////////////////////////////////////////////////
+    ////////                                                        ////////
+    ////////              Query hints                               ////////
+    ////////                                                        ////////
+    ////////////////////////////////////////////////////////////////////////
+    
+
+    /**
+     * When this key is used in the user data section of a feature and the feature store
+     * query capabilities reports being able to use provided feature ids the store will
+     * try to use the user provided feature id during insertion, and will fail if the FID
+     * cannot be parsed into a valid storage identifier
+     *
+     * @since 2.7
+     */
+    public static final Key USE_PROVIDED_FID = new Key("org.geotools.fidPolicy.UseExisting");
+
+    ////////////////////////////////////////////////////////////////////////
+    ////////                                                        ////////
+    ////////                     JTS Geometries                     ////////
+    ////////                                                        ////////
+    ////////////////////////////////////////////////////////////////////////
+
+    /**
+     * The {@link com.vividsolutions.jts.geom.GeometryFactory} instance to use.
+     *
+     * @see #GEOMETRY_FACTORY
+     * @see org.geotools.geometry.jts.FactoryFinder#getGeometryFactory
+     */
+    public static final ClassKey JTS_GEOMETRY_FACTORY = new ClassKey(
+            "com.vividsolutions.jts.geom.GeometryFactory");
+
+    /**
+     * The {@link com.vividsolutions.jts.geom.CoordinateSequenceFactory} instance to use.
+     *
+     * @see org.geotools.geometry.jts.FactoryFinder#getCoordinateSequenceFactory
+     */
+    public static final ClassKey JTS_COORDINATE_SEQUENCE_FACTORY = new ClassKey(
+            "com.vividsolutions.jts.geom.CoordinateSequenceFactory");
+
+    ////////////////////////////////////////////////////////////////////////
+    ////////                                                        ////////
+    ////////                        Features                        ////////
+    ////////                                                        ////////
+    ////////////////////////////////////////////////////////////////////////
+
+    /**
+     * The {@link org.opengis.feature.FeatureFactory} instance to use.
+     * 
+     * @see CommonFactoryFinder.getFeatureFactory()
+     * @since 2.5
+     */
+    public static ClassKey FEATURE_FACTORY = new ClassKey( "org.opengis.feature.FeatureFactory");
+    
+    /**
+     * Indicates the features returned by the feature collections should be considered detached from
+     * the datastore. If true the features can be udpated without altering the backing store.
+     * <p>
+     * Examples of fetures that are "attached" are features are kept in memory or features managed
+     * by a transparent persistence mechanism like Hibernate.
+     *
+     * @since 2.4
+     */
+    public static final Key FEATURE_DETACHED = new Key(Boolean.class);
+
+    /**
+     * Request that the features returned by the feature collections should
+     * be 2D only. Can be used to prevent the request of the third ordinate
+     * when only two are going to be used.
+     *
+     * @since 2.4.1
+     */
+    public static final Key FEATURE_2D = new Key(Boolean.class);
+        
+    /**
+     * Asks a datastore having a vector pyramid (pre-generalized geometries)
+     * to return the geometry version whose points have been generalized
+     * less than the spefiedi distance (further generalization might be
+     * performed by the client in memory).<p>
+     * The geometries returned are supposed to be topologically valid.
+     */
+    public static final Key GEOMETRY_DISTANCE = new Key(Double.class);
+    
+    /**
+     * The {@link org.opengis.filter.FilterFactory} instance to use.
+     *
+     * @see CommonFactoryFinder#getFilterFactory
+     *
+     * @since 2.4
+     */
+    public static final ClassKey FILTER_FACTORY = new ClassKey(
+            "org.opengis.filter.FilterFactory");
+    
+    /**
+     * Resample tolerance (defaults to 0.333)
+     * 
+     * @since 2.7
+     */
+    public static final Key RESAMPLE_TOLERANCE = new Key(Double.class);
+
+    ////////////////////////////////////////////////////////////////////////
+    ////////                                                        ////////
+    ////////                         Caches                         ////////
+    ////////                                                        ////////
+    ////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Policy to use for caching referencing objects. Valid values are:
+     * <p>
+     * <ul>
+     *   <li>{@code "weak"} for holding values through {@linkplain java.lang.ref.WeakReference
+     *       weak references}. This option does not actually cache the objects since the garbage
+     *       collector cleans weak references aggressively, but it allows sharing the instances
+     *       already created and still in use.</li>
+     *   <li>{@code "fixed") for holding a fixed number of values specified by {@link #CACHE_LIMIT}.
+     *   <li>{@code "all"} for holding values through strong references.</li>
+     *   <li>{@code "none"} for disabling the cache.</li>
+     *   <li>{@code "soft"} for holding the value throuhg(@linkplain java.lang.ref.SoftReference 
+     *       soft references}.
+     * </ul>
+     *
+     * @since 2.5
+     */
+    public static final OptionKey CACHE_POLICY = new OptionKey("weak", "all", "fixed","none","default","soft");
+
+    /**
+     * The recommended maximum number of referencing objects to hold in a
+     * {@linkplain org.opengis.referencing.AuthorityFactory authority factory}.
+     *
+     * @since 2.5
+     */
+    public static final IntegerKey CACHE_LIMIT = new IntegerKey(50);
+    
+    /**
+     * Tolerance used in comparisons between floating point values. Two floating points A and B are
+     * considered the same if A * (1 - tol) <= B <= A * (1 + tol).
+     * The default value is 0, meaning the two doubles have to be exactly the same (a bit to bit
+     * comparison will be performed).
+     * 
+     * @since 2.6
+     */
+    public static final DoubleKey COMPARISON_TOLERANCE = new DoubleKey(0.0);
+
+    /**
+     * Constructs an initially empty set of hints.
+     *
+     * @since 2.5
+     */
+    public Hints() {
+        super(null);
+    }
+
+    /**
+     * Constructs a new object with the specified key/value pair.
+     *
+     * @param key   The key of the particular hint property.
+     * @param value The value of the hint property specified with {@code key}.
+     */
+    public Hints(final RenderingHints.Key key, final Object value) {
+        super(null); // Don't use 'super(key,value)' because it doesn't check validity.
+        super.put(key, value);
+    }
+
+    /**
+     * Constructs a new object with keys and values initialized from the
+     * specified map (which may be null).
+     *
+     * @param hints A map of key/value pairs to initialize the hints, or
+     *              {@code null} if the object should be empty.
+     */
+    public Hints(final Map<? extends RenderingHints.Key, ?> hints) {
+        super(stripNonKeys(hints));
+    }
+
+    /**
+     * Constructs a new object with keys and values initialized from the
+     * specified hints (which may be null).
+     *
+     * @param hints A map of key/value pairs to initialize the hints, or
+     *              {@code null} if the object should be empty.
+     *
+     * @since 2.5
+     */
+    public Hints(final RenderingHints hints) {
+        super(stripNonKeys(hints));
+    }
+
+    /**
+     * Returns a map with the same hints than the specified one, minus every (key,value)
+     * pairs where the key is not an instance of {@link RenderingHints.Key}. If the given
+     * map contains only valid keys, then it is returned unchanged.
+     *
+     * @param  hints The map of hints to filter.
+     * @return A map with filtered hints.
+     */
+    static Map<RenderingHints.Key, Object> stripNonKeys(final Map<?,?> hints) {
+        if (hints == null) {
+            return null;
+        }
+        /*
+         * We cheat in the next line since the map may contains illegal key. However when this
+         * method will finish, we garantee that it will contains only RenderingHints.Key keys,
+         * provided there is no concurrent changes in an other thread.
+         */
+        @SuppressWarnings("unchecked")
+        Map<RenderingHints.Key, Object> filtered = (Map) hints;
+        for (final Iterator it=hints.keySet().iterator(); it.hasNext();) {
+            final Object key = it.next();
+            if (!(key instanceof RenderingHints.Key)) {
+                if (filtered == hints) {
+                    // Copies the map only if needed.
+                    filtered = new HashMap<RenderingHints.Key, Object>(filtered);
+                }
+                filtered.remove(key);
+            }
+        }
+        return filtered;
+    }
+
+    /**
+     * Returns a new map of hints with the same content than this map.
+     *
+     * @since 2.5
+     */
+    @Override
+    public Hints clone() {
+        return (Hints) super.clone();
+    }
+
+    /**
+     * Invokes {@link GeoTools#scanSystemProperties} when first needed. The caller is
+     * responsible for invoking {@link GeoTools#fireConfigurationChanged} outside the
+     * synchronized block if this method returns {@code true}.
+     *
+     * @return {@code true} if at least one hint changed as a result of this scan,
+     *         or {@code false} otherwise.
+     */
+    private static boolean ensureSystemDefaultLoaded() {
+        assert Thread.holdsLock(GLOBAL);
+        if (needScan) {
+            needScan = false;
+            return GeoTools.scanForSystemHints(GLOBAL);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns a copy of the system hints. This is for
+     * {@link GeoTools#getDefaultHints} implementation only.
+     */
+    static Hints getDefaults(final boolean strict) {
+        final boolean changed;
+        final Hints hints;
+        synchronized (GLOBAL) {
+            changed = ensureSystemDefaultLoaded();
+            if (strict) {
+                hints = new StrictHints(GLOBAL);
+            } else {
+                hints = new Hints(GLOBAL);
+            }
+        }
+        if (changed) {
+            GeoTools.fireConfigurationChanged();
+        }
+        return hints;
+    }
+
+    /**
+     * Returns the hint {@linkplain GeoTools#getDefaultHints default value}
+     * for the specified key.
+     *
+     * @param  key The hints key.
+     * @return The value for the specified key, or {@code null}
+     *         if the key did not have a mapping.
+     *
+     * @since 2.4
+     */
+    public static Object getSystemDefault(final RenderingHints.Key key) {
+        final boolean changed;
+        final Object value;
+        synchronized (GLOBAL) {
+            changed = ensureSystemDefaultLoaded();
+            value = GLOBAL.get(key);
+        }
+        if (changed) {
+            GeoTools.fireConfigurationChanged();
+        }
+        return value;
+    }
+
+    /**
+     * Adds a hint value to the set of {@linkplain GeoTools#getDefaultHints default hints}.
+     * Default hints can be added by call to this {@code putDefaultHint} method, to the
+     * {@link GeoTools#init} method or by {@linkplain System#getProperties system properties}
+     * with keys defined by the {@link String} constants in the {@link GeoTools} class.
+     *
+     * @param key   The hint key.
+     * @param value The hint value.
+     * @return The previous value of the specified key, or {@code null} if none.
+     * @throws IllegalArgumentException If {@link Hints.Key#isCompatibleValue()}
+     *         returns {@code false} for the specified value.
+     *
+     * @since 2.4
+     */
+    public static Object putSystemDefault(final RenderingHints.Key key, final Object value) {
+        final boolean changed;
+        final Object old;
+        synchronized (GLOBAL) {
+            changed = ensureSystemDefaultLoaded();
+            old = GLOBAL.put(key, value);
+        }
+        if (changed || !Utilities.equals(value, old)) {
+            GeoTools.fireConfigurationChanged();
+        }
+        return old;
+    }
+
+    /**
+     * Removes the specified hints from the set of
+     * {@linkplain GeoTools#getDefaultHints default hints}.
+     *
+     * @param  key The hints key that needs to be removed.
+     * @return The value to which the key had previously been mapped,
+     *         or {@code null} if the key did not have a mapping.
+     *
+     * @since 2.4
+     */
+    public static Object removeSystemDefault(final RenderingHints.Key key) {
+        final boolean changed;
+        final Object old;
+        synchronized (GLOBAL) {
+            changed = ensureSystemDefaultLoaded();
+            old = GLOBAL.remove(key);
+        }
+        if (changed || old != null) {
+            GeoTools.fireConfigurationChanged();
+        }
+        return old;
+    }
+
+    /**
+     * Returns a string representation of the hints. This method formats the set of hints
+     * as a tree. If some system-wide {@linkplain GeoTools#getDefaultHints default hints}
+     * exist, they are formatted after those hints for completeness.
+     *
+     * @since 2.4
+     */
+    @Override
+    public String toString() {
+        final String lineSeparator = System.getProperty("line.separator", "\n");
+        final StringBuilder buffer = new StringBuilder("Hints:"); // TODO: localize
+        buffer.append(lineSeparator).append(AbstractFactory.toString(this));
+        Map<?,?> extra = null;
+        final boolean changed;
+        synchronized (GLOBAL) {
+            changed = ensureSystemDefaultLoaded();
+            if (!GLOBAL.isEmpty()) {
+                extra = new HashMap<Object,Object>(GLOBAL);
+            }
+        }
+        if (changed) {
+            GeoTools.fireConfigurationChanged();
+        }
+        if (extra != null) {
+            extra.keySet().removeAll(keySet());
+            if (!extra.isEmpty()) {
+                buffer.append("System defaults:")  // TODO: localize
+                      .append(lineSeparator).append(AbstractFactory.toString(extra));
+            }
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Tries to find the name of the given key, using reflection.
+     */
+    static String nameOf(final RenderingHints.Key key) {
+        if (key instanceof Key) {
+            return key.toString();
+        }
+        int t = 0;
+        while (true) {
+            final Class<?> type;
+            switch (t++) {
+                case 0: {
+                    type = RenderingHints.class;
+                    break;
+                }
+                case 1: {
+                    try {
+                        type = Class.forName("javax.media.jai.JAI");
+                        break;
+                    } catch (ClassNotFoundException e) {
+                        continue;
+                    } catch (NoClassDefFoundError e) {
+                        // May occurs because of indirect JAI dependencies.
+                        continue;
+                    }
+                }
+                default: {
+                    return key.toString();
+                }
+            }
+            final String name = nameOf(type, key);
+            if (name != null) {
+                return name;
+            }
+        }
+    }
+
+    /**
+     * If the given key is declared in the given class, returns its name.
+     * Otherwise returns {@code null}.
+     */
+    private static String nameOf(final Class<?> type, final RenderingHints.Key key) {
+        final Field[] fields = type.getFields();
+        for (int i=0; i<fields.length; i++) {
+            final Field f = fields[i];
+            if (Modifier.isStatic(f.getModifiers())) {
+                final Object v;
+                try {
+                    v = f.get(null);
+                } catch (IllegalAccessException e) {
+                    continue;
+                }
+                if (v == key) {
+                    return f.getName();
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * The type for keys used to control various aspects of the factory
+     * creation. Factory creation impacts rendering (which is why extending
+     * {@linkplain java.awt.RenderingHints.Key rendering key} is not a complete
+     * non-sense), but may impact other aspects of an application as well.
+     *
+     * @since 2.1
+     * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/Hints.java $
+     * @version $Id: Hints.java 38414 2011-12-13 09:39:22Z aaime $
+     * @author Martin Desruisseaux
+     */
+    public static class Key extends RenderingHints.Key {
+        /**
+         * The number of key created up to date.
+         */
+        private static int count;
+
+        /**
+         * The class name for {@link #valueClass}.
+         */
+        private final String className;
+
+        /**
+         * Base class of all values for this key. Will be created from {@link #className} only when
+         * first required, in order to avoid too early class loading. This is significant for the
+         * {@link #JAI_INSTANCE} key for example, in order to avoid JAI dependencies in applications
+         * that do not need it.
+         */
+        private transient Class<?> valueClass;
+
+        /**
+         * Constructs a new key for values of the given class.
+         *
+         * @param classe The base class for all valid values.
+         */
+        public Key(final Class<?> classe) {
+            this(classe.getName());
+            valueClass = classe;
+        }
+
+        /**
+         * Constructs a new key for values of the given class. The class is
+         * specified by name instead of a {@link Class} object. This allows to
+         * defer class loading until needed.
+         *
+         * @param className Name of base class for all valid values.
+         */
+        Key(final String className) {
+            super(count());
+            this.className = className;
+        }
+
+        /**
+         * Workaround for RFE #4093999 ("Relax constraint on placement of this()/super()
+         * call in constructors"): {@code count++} need to be executed in a synchronized
+         * block since it is not an atomic operation.
+         */
+        private static synchronized int count() {
+            return count++;
+        }
+
+        /**
+         * Returns the expected class for values stored under this key.
+         *
+         * @return The class of values stored under this key.
+         */
+        public Class<?> getValueClass() {
+            if (valueClass == null) {
+                try {
+                    valueClass = Class.forName(className);
+                } catch (ClassNotFoundException exception) {
+                    Logging.unexpectedException(Key.class, "getValueClass", exception);
+                    valueClass = Object.class;
+                }
+            }
+            return valueClass;
+        }
+
+        /**
+         * Returns {@code true} if the specified object is a valid value for
+         * this key. The default implementation checks if the specified value
+         * {@linkplain Class#isInstance is an instance} of the {@linkplain
+         * #getValueClass value class}.
+         * <p>
+         * Note that many hint keys defined in the {@link Hints} class relax this rule and accept
+         * {@link Class} object assignable to the expected {@linkplain #getValueClass value class}
+         * as well.
+         *
+         * @param value
+         *            The object to test for validity.
+         * @return {@code true} if the value is valid; {@code false} otherwise.
+         *
+         * @see Hints.ClassKey#isCompatibleValue
+         * @see Hints.FileKey#isCompatibleValue
+         * @see Hints.IntegerKey#isCompatibleValue
+         * @see Hints.OptionKey#isCompatibleValue
+         */
+        public boolean isCompatibleValue(final Object value) {
+            return getValueClass().isInstance(value);
+        }
+
+        /**
+         * Returns a string representation of this key. The string
+         * representation is mostly for debugging purpose. The default
+         * implementation tries to infer the key name using reflection.
+         */
+        @Override
+        public String toString() {
+            int t = 0;
+            while (true) {
+                final Class<?> type;
+                switch (t++) {
+                    case 0:  type = Hints.class;      break;
+                    case 1:  type = getValueClass();  break;
+                    default: return super.toString();
+                }
+                final String name = nameOf(type, this);
+                if (name != null) {
+                    return name;
+                }
+            }
+        }
+    }
+
+    /**
+     * A key for value that may be specified either as instance of {@code T}, or as
+     * {@code Class<T>}.
+     *
+     * @since 2.4
+     * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/Hints.java $
+     * @version $Id: Hints.java 38414 2011-12-13 09:39:22Z aaime $
+     * @author Martin Desruisseaux
+     */
+    public static final class ClassKey extends Key {
+        
+        /**
+         * Constructs a new key for values of the given class. The class is
+         * specified by name instead of a {@link Class} object. This allows to
+         * defer class loading until needed.
+         *
+         * @param className Name of base class for all valid values.
+         */
+        ClassKey(final String className) {
+            super(className);
+        }
+
+        /**
+         * Returns {@code true} if the specified object is a valid value for
+         * this key. This method checks if the specified value is non-null and
+         * is one of the following:
+         * <p>
+         * <ul>
+         *   <li>An instance of the {@linkplain #getValueClass expected value class}.</li>
+         *   <li>A {@link Class} assignable to the expected value class.</li>
+         *   <li>An array of {@code Class} objects assignable to the expected value class.</li>
+         * </ul>
+         */
+        @Override
+        public boolean isCompatibleValue(final Object value) {
+            if (value == null) {
+                return false;
+            }
+            /*
+             * If the value is an array of classes, invokes this method recursively
+             * in order to check the validity of each elements in the array.
+             */
+            if (value instanceof Class<?>[]) {
+                final Class<?>[] types = (Class<?>[]) value;
+                for (int i=0; i<types.length; i++) {
+                    if (!isCompatibleValue(types[i])) {
+                        return false;
+                    }
+                }
+                return types.length != 0;
+            }
+            /*
+             * If the value is a class, checks if it is assignable to the expected value class.
+             * As a special case, if the value is not assignable but is an abstract class while
+             * we expected an interface, we will accept this class anyway because the some sub-
+             * classes may implement the interface (we dont't really know). For example the
+             * AbstractAuthorityFactory class doesn't implements the CRSAuthorityFactory interface,
+             * but sub-classe of it do. We make this relaxation in order to preserve compatibility,
+             * but maybe we will make the check stricter in the future.
+             */
+            if (value instanceof Class<?>) {
+                final Class<?> type = (Class<?>) value;
+                final Class<?> expected = getValueClass();
+                if (expected.isAssignableFrom(type)) {
+                    return true;
+                }
+                if (expected.isInterface() && !type.isInterface()) {
+                    final int modifiers = type.getModifiers();
+                    if (Modifier.isAbstract(modifiers) && !Modifier.isFinal(modifiers)) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+            return super.isCompatibleValue(value);
+        }
+    }
+
+    /**
+     * Key for hints to be specified as a {@link File}.
+     * The file may also be specified as a {@link String} object.
+     *
+     * @since 2.4
+     * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/Hints.java $
+     * @version $Id: Hints.java 38414 2011-12-13 09:39:22Z aaime $
+     * @author Jody Garnett
+     * @author Martin Desruisseaux
+     */
+    public static final class FileKey extends Key {
+        /**
+         * {@code true} if write operations need to be allowed.
+         */
+        private final boolean writable;
+
+        /**
+         * Creates a new key for {@link File} value.
+         *
+         * @param writable {@code true} if write operations need to be allowed.
+         */
+        public FileKey(final boolean writable) {
+            super(File.class);
+            this.writable = writable;
+        }
+
+        /**
+         * Returns {@code true} if the specified object is a valid file or directory.
+         */
+        @Override
+        public boolean isCompatibleValue(final Object value) {
+            final File file;
+            if (value instanceof File) {
+                file = (File) value;
+            } else if (value instanceof String) {
+                file = new File((String) value);
+            } else {
+                return false;
+            }
+            if (file.exists()) {
+                return !writable || file.canWrite();
+            }
+            final File parent = file.getParentFile();
+            return parent!=null && parent.canWrite();
+        }
+    }
+
+    /**
+     * A hint used to capture a configuration setting as an integer.
+     * A default value is provided and may be checked with {@link #getDefault()}.
+     *
+     * @since 2.4
+     * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/Hints.java $
+     * @version $Id: Hints.java 38414 2011-12-13 09:39:22Z aaime $
+     * @author Jody Garnett
+     */
+    public static final class IntegerKey extends Key {
+
+        /**
+         * Creates a new key with the specified default value.
+         *
+         * @param number The default value.
+         */
+        public IntegerKey(final int number) {
+            super(Integer.class);
+        }
+
+        /**
+         * Returns {@code true} if the specified object is a valid integer.
+         */
+        @Override
+        public boolean isCompatibleValue(final Object value) {
+            if (value instanceof Short || value instanceof Integer) {
+                return true;
+            }
+            if (value instanceof String || value instanceof InternationalString) {
+                try {
+                    Integer.parseInt(value.toString());
+                } catch (NumberFormatException e) {
+                    Logging.getLogger(IntegerKey.class).finer(e.toString());
+                }
+            }
+            return false;
+        }
+    }
+    
+    /**
+     * A hint used to capture a configuration setting as double.
+     * A default value is provided and may be checked with {@link #getDefault()}.
+     *
+     * @since 2.6
+     * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/Hints.java $
+     * @version $Id: Hints.java 38414 2011-12-13 09:39:22Z aaime $
+     * @author Jody Garnett
+     */
+    public static final class DoubleKey extends Key {
+        /**
+         * The default value.
+         */
+        private final double number;
+
+        /**
+         * Creates a new key with the specified default value.
+         *
+         * @param number The default value.
+         */
+        public DoubleKey(final double number) {
+            super(Integer.class);
+            this.number = number;
+        }
+
+        /**
+         * Returns the default value.
+         *
+         * @return The default value.
+         */
+        public double getDefault(){
+            return number;
+        }
+
+        /**
+         * Returns {@code true} if the specified object is a valid integer.
+         */
+        @Override
+        public boolean isCompatibleValue(final Object value) {
+            if (value instanceof Float || value instanceof Double) {
+                return true;
+            }
+            if (value instanceof String || value instanceof InternationalString) {
+                try {
+                    Double.parseDouble(value.toString());
+                } catch (NumberFormatException e) {
+                    Logging.getLogger(DoubleKey.class).finer(e.toString());
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Key that allows the choice of several options.
+     * You can use {@code "*"} as a wild card to indicate that undocumented options
+     * may be supported (but there is no assurances - {@link Hints#DATUM_SHIFT_METHOD}).
+     *
+     * @since 2.4
+     * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/Hints.java $
+     * @version $Id: Hints.java 38414 2011-12-13 09:39:22Z aaime $
+     * @author Jody Garnett
+     */
+    public static final class OptionKey extends Key {
+        /**
+         * The set of options allowed.
+         */
+        private final Set<String> options;
+
+        /**
+         * {@code true} if the {@code "*"} wildcard was given in the set of options.
+         */
+        private final boolean wildcard;
+
+        /**
+         * Creates a new key for a configuration option.
+         *
+         * @param alternatives The available options.
+         */
+        public OptionKey(final String... alternatives) {
+            super(String.class);
+            final Set<String> options = new TreeSet<String>(Arrays.asList(alternatives));
+            this.wildcard = options.remove("*");
+            this.options  = Collections.unmodifiableSet(options);
+        }
+
+        /**
+         * Returns {@code true} if the specified object is one of the valid options. If the
+         * options specified at construction time contains the {@code "*"} wildcard, then
+         * this method returns {@code true} for every {@link String} object.
+         */
+        @Override
+        public boolean isCompatibleValue(final Object value) {
+            return wildcard ? (value instanceof String) : options.contains(value);
+        }
+    }
+
+    /**
+     * Key for hints to be specified as a {@link javax.sql.DataSource}.
+     * The file may also be specified as a {@link String} or {@link Name} object.
+     * <p>
+     * Different JNDI implementations build up their name differently (so we may need
+     * to look for "jdbc:EPSG" in JBoss and "jdbc/EPSG" in Websphere. The
+     * InitialContext.combineNames( String, String ) should be used to put together
+     * your nam
+     *
+     * @since 2.4
+     * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/Hints.java $
+     * @version $Id: Hints.java 38414 2011-12-13 09:39:22Z aaime $
+     * @author Martin Desruisseaux
+     */
+    static final class DataSourceKey extends Key {
+        /**
+         * Creates a new key for {@link javax.sql.DataSource} value.
+         */
+        public DataSourceKey() {
+            super(DataSource.class);
+        }
+
+        /**
+         * Returns {@code true} if the specified object is a data source or data source name.
+         */
+        @Override
+        public boolean isCompatibleValue(final Object value) {
+            return (value instanceof DataSource) || (value instanceof String) || (value instanceof Name);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/OptionalFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/OptionalFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/OptionalFactory.java	(revision 28000)
@@ -0,0 +1,62 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+
+/**
+ * An optional factory that may not be available in all configurations.
+ * <p>
+ * Such factories often need some external resources. For example the default
+ * {@linkplain org.geotools.referencing.factory.epsg.AccessDialectEpsgFactory EPSG factory}
+ * need a MS-Access database installed on the client machine. This database is not bundle in
+ * Geotools distribution; if the user have not installed it, the factory can't work.
+ * <p>
+ * This interface is <strong>not</strong> a manager for automatic download of external resources.
+ * It is just a way to tell to {@link FactoryFinder} that this factory exists, but can't do its
+ * job for whatever reasons (usually a missing resource that the user shall download and install
+ * himself), so {@code FactoryFinder} has to choose an other factory. In other words, the
+ * {@code OptionalFactory} interface is used as a filter, nothing else. The process is as follows:
+ * <p>
+ * <ul>
+ *   <li>When {@link FactoryRegistry#getServiceProvider} is invoked, it starts to iterate over all
+ *       registered factories. If an {@linkplain FactoryRegistry#setOrdering(Class,Object,Object)
+ *       ordering is set}, it is taken in account for the iteration order.</li>
+ *   <li>If no suitable factory was found before the iterator reachs this optional factory, then
+ *       {@link #isAvailable} is invoked. If it returns {@code true}, then this optional factory
+ *       is processed like any other factories. Otherwise it is ignored.</li>
+ * </ul>
+ * <p>
+ * <strong>NOTE:</strong> {@code OptionalFactory} is not designed for factories with intermittent
+ * state (i.e. return value of {@link #isAvailable} varying in an unpredictable way). The behavior
+ * is undetermined if the {@code isAvailable()} state changes with time.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/OptionalFactory.java $
+ * @version $Id: OptionalFactory.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ *
+ * @see org.geotools.data.DataStoreFactorySpi#isAvailable
+ */
+public interface OptionalFactory extends Factory {
+    /**
+     * Returns {@code true} if this factory is ready for use.
+     * An optional factory may returns {@code false} for now but returns {@code true} later.
+     * However, the converse is not recommended.
+     */
+    boolean isAvailable();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/RecursionCheckingHelper.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/RecursionCheckingHelper.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/RecursionCheckingHelper.java	(revision 28000)
@@ -0,0 +1,39 @@
+package org.geotools.factory;
+
+import java.util.HashSet;
+import java.util.Set;
+
+class RecursionCheckingHelper {
+
+    private final ThreadLocal<Set> threadLocalSet = new ThreadLocal<Set>();
+    
+    boolean addAndCheck(Object item) {
+        Set set = threadLocalSet.get();
+        if(set == null) {
+            set = new HashSet<Class<?>>();
+            threadLocalSet.set(set);
+        }
+        return set.add(item);
+    }
+    
+    boolean contains(Object item) {
+        Set<Class<?>> set = threadLocalSet.get();
+        if(set == null) {
+            return false;
+        }
+        return set.contains(item);
+    }
+    
+    void removeAndCheck(Object item) {
+        Set<Class<?>> set = threadLocalSet.get();
+        if(set == null) {
+            throw new AssertionError(null); // Should never happen.
+        } else if(!set.remove(item)) {
+            throw new AssertionError(item); // Should never happen.
+        } 
+        if(set.isEmpty()) {
+            threadLocalSet.remove();
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/RecursiveSearchException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/RecursiveSearchException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/RecursiveSearchException.java	(revision 28000)
@@ -0,0 +1,53 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * Thrown when {@link FactoryRegistry} is invoked recursively for the same category. This exception
+ * is often the result of a programming error. It happen typically when an implementation of some
+ * {@code FooFactory} interface queries in their constructor, directly or indirectly,
+ * {@link FactoryRegistry#getServiceProvider getServiceProvider} for the same category (namely
+ * {@code FooFactory.class}). Factories implemented as wrappers around other factories of the same
+ * kind are the most likely to fall in this canvas. If this {@code RecursiveSearchException}
+ * was not throw, the application would typically dies with a {@link StackOverflowError}.
+ * <p>
+ * A workaround for this exception is to invoke {@code getServiceProvider} outside the constuctor,
+ * when a method first need it.
+ *
+ * @since 2.3
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/RecursiveSearchException.java $
+ * @version $Id: RecursiveSearchException.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ */
+public class RecursiveSearchException extends FactoryRegistryException {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -2028654588882874110L;
+
+    /**
+     * Creates a new exception with a default message determined from the specified category.
+     */
+    public RecursiveSearchException(final Class<?> category) {
+        super(Errors.format(ErrorKeys.RECURSIVE_CALL_$1, category));
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/StrictHints.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/StrictHints.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/factory/StrictHints.java	(revision 28000)
@@ -0,0 +1,37 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.factory;
+
+
+
+/**
+ * Hints which should not be merged with global hints, usually because the global hints have
+ * already been merged.
+ *
+ * @since 2.4
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/factory/StrictHints.java $
+ * @version $Id: StrictHints.java 30640 2008-06-12 17:34:32Z acuster $
+ * @author Martin Desruisseaux
+ */
+class StrictHints extends Hints {
+    /**
+     * Creates a set of strict hints which is a copy of the specified hints.
+     */
+    public StrictHints(final Hints hints) {
+        super(hints);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/AbstractFeatureFactoryImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/AbstractFeatureFactoryImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/AbstractFeatureFactoryImpl.java	(revision 28000)
@@ -0,0 +1,56 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature;
+
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.feature.simple.SimpleFeatureImpl;
+import org.opengis.feature.FeatureFactory;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.FilterFactory2;
+
+/**
+ * Factory for creating instances of the Attribute family of classes.
+ * 
+ * @author Ian Schneider
+ * @author Gabriel Roldan
+ * @author Justin Deoliveira
+ * 
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/AbstractFeatureFactoryImpl.java $
+ * @version $Id: AbstractFeatureFactoryImpl.java 37680 2011-07-19 15:18:56Z groldan $
+ */
+public abstract class AbstractFeatureFactoryImpl implements FeatureFactory {
+ 
+    
+    FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);
+    
+    /**
+     * Whether the features to be built should be self validating on construction and value setting, or not.
+     * But default, not, subclasses do override this value
+     */
+    boolean validating = false;
+	
+    public SimpleFeature createSimpleFeature(Object[] array,
+            SimpleFeatureType type, String id) {
+        if( type.isAbstract() ){
+            throw new IllegalArgumentException("Cannot create an feature of an abstract FeatureType "+type.getTypeName());
+        }
+        return new SimpleFeatureImpl(array, type, ff.featureId(id), validating);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/AttributeImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/AttributeImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/AttributeImpl.java	(revision 28000)
@@ -0,0 +1,164 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature;
+
+import org.geotools.feature.type.Types;
+import org.geotools.util.Converters;
+import org.geotools.util.Utilities;
+import org.opengis.feature.Attribute;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.filter.identity.Identifier;
+
+/**
+ * Simple, mutable class to store attributes.
+ * 
+ * @author Rob Hranac, VFNY
+ * @author Chris Holmes, TOPP
+ * @author Ian Schneider
+ * @author Jody Garnett
+ * @author Gabriel Roldan
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/AttributeImpl.java $
+ * @version $Id: AttributeImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public class AttributeImpl extends PropertyImpl implements Attribute {
+
+	/**
+	 * id of the attribute.
+	 */
+	protected Identifier id = null;
+
+	public AttributeImpl(Object content, AttributeDescriptor descriptor,
+			Identifier id) {
+	    super( content, descriptor );
+	    this.id = id;	    
+	}
+
+	public Identifier getIdentifier() {
+        return id;
+    }
+	
+	public AttributeDescriptor getDescriptor() {
+	    return (AttributeDescriptor) super.getDescriptor();
+	}
+	
+	public AttributeType getType() {
+	    return (AttributeType) super.getType();
+	}
+	
+	/**
+	 * Override of setValue to convert the newValue to specified type if need
+	 * be.
+	 */
+	public void setValue(Object newValue) throws IllegalArgumentException,
+			IllegalStateException {
+
+		newValue = parse(newValue);
+		super.setValue( newValue );
+	}
+
+	/**
+	 * Override of hashCode.
+	 * 
+	 * @return hashCode for this object.
+	 */
+	public int hashCode() {
+	    return super.hashCode() + ( 37 * (id == null ? 0 : id.hashCode()) );
+	}
+
+	/**
+	 * Override of equals.
+	 * 
+	 * @param other
+	 *            the object to be tested for equality.
+	 * 
+	 * @return whether other is equal to this attribute Type.
+	 */
+	public boolean equals(Object obj) {
+	    if ( this == obj ) {
+	        return true;
+	    }
+	    
+		if (!(obj instanceof Attribute)) {
+			return false;
+		}
+
+		if (!super.equals(obj)) {
+		    return false;
+		}
+		
+		Attribute att = (Attribute) obj;
+		
+		return Utilities.equals( id, att.getIdentifier() );
+	}
+	
+	public void validate() {
+	    Types.validate(this, this.getValue() );
+	}
+	
+	public String toString() {
+		StringBuffer sb = new StringBuffer(getClass().getSimpleName()).append(":");
+        sb.append(getDescriptor().getName().getLocalPart());
+        if(!getDescriptor().getName().getLocalPart().equals(getDescriptor().getType().getName().getLocalPart()) ||
+                id != null){
+            sb.append("<");
+            sb.append(getDescriptor().getType().getName().getLocalPart());
+            if( id != null ){
+                sb.append( " id=");
+                sb.append( id );
+            }
+            sb.append(">");
+        }
+        sb.append("=");
+        sb.append(value);
+        return sb.toString();
+	}
+	
+	/**
+	 * Allows this Attribute to convert an argument to its prefered storage
+	 * type. If no parsing is possible, returns the original value. If a parse
+	 * is attempted, yet fails (i.e. a poor decimal format) throw the Exception.
+	 * This is mostly for use internally in Features, but implementors should
+	 * simply follow the rules to be safe.
+	 * 
+	 * @param value
+	 *            the object to attempt parsing of.
+	 * 
+	 * @return <code>value</code> converted to the preferred storage of this
+	 *         <code>AttributeType</code>. If no parsing was possible then
+	 *         the same object is returned.
+	 * 
+	 * @throws IllegalArgumentException
+	 *             if parsing is attempted and is unsuccessful.
+	 */
+	protected Object parse(Object value) throws IllegalArgumentException {
+    	if ( value != null ) {
+    		Class target = getType().getBinding(); 
+    		if ( !target.isAssignableFrom( value.getClass() ) ) {
+    			// attempt to convert
+    			Object converted = Converters.convert(value,target);
+    			if ( converted != null ) {
+    				value = converted;
+    			}
+    		}
+    	}
+    	
+    	return value;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/AttributeTypeBuilder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/AttributeTypeBuilder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/AttributeTypeBuilder.java	(revision 28000)
@@ -0,0 +1,493 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.data.DataUtilities;
+import org.geotools.feature.type.FeatureTypeFactoryImpl;
+import org.geotools.resources.Classes;
+import org.geotools.util.SimpleInternationalString;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.FeatureTypeFactory;
+import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.feature.type.GeometryType;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.util.InternationalString;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * Builder for attribute types and descriptors.
+ * <p>
+ * Building an attribute type:
+ * <pre>
+ * <code>
+ *  //create the builder
+ * 	AttributeTypeBuilder builder = new AttributeTypeBuilder();
+ *  
+ *  //set type information
+ *  builder.setName( "intType" ):
+ *  builder.setBinding( Integer.class );
+ *  builder.setNillable( false );
+ *  
+ *  //build the type
+ *  AttributeType type = builder.buildType();
+ * </code>
+ * </pre>
+ * </p>
+ * <p>
+ * Building an attribute descriptor:
+ * <pre>
+ * <code>
+ *  //create the builder
+ * 	AttributeTypeBuilder builder = new AttributeTypeBuilder();
+ *  
+ *  //set type information
+ *  builder.setName( "intType" ):
+ *  builder.setBinding( Integer.class );
+ *  builder.setNillable( false );
+ *  
+ *  //set descriptor information
+ *  builder.setMinOccurs(0);
+ *  builder.setMaxOccurs(1);
+ *  builder.setNillable(true);
+ *  
+ *  //build the descriptor
+ *  AttributeDescriptor descriptor = builder.buildDescriptor("intProperty");
+ * </code>
+ * </pre>
+ * <p>
+ * This class maintains state and is not thread safe.
+ * </p>
+ * 
+ * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/AttributeTypeBuilder.java $
+ */
+public class AttributeTypeBuilder {
+
+	/**
+	 * factory
+	 */
+	protected FeatureTypeFactory factory;
+	
+	//AttributeType
+	//
+	/**
+	 * Local name used to name a descriptor; or combined with namespaceURI to name a type.
+	 */
+	protected String name;
+	
+	/**
+	 * Separator used to combine namespaceURI and name.
+	 */
+	private String separator = ":";
+
+	/**
+	 * namespace used to distingish between otherwise identical type names.
+	 */
+	protected String namespaceURI;
+	/**
+	 * abstract flag
+	 */
+	protected boolean isAbstract = false;
+	/**
+	 * restrictions
+	 */
+	protected List<Filter> restrictions;
+	/**
+	 * string description
+	 */
+	protected String description;
+	/**
+	 * identifiable flag
+	 */
+	protected boolean isIdentifiable = false;
+	/**
+	 * bound java class
+	 */
+	protected Class binding;
+	/**
+	 * super type
+	 */
+	protected AttributeType superType;
+	/**
+	 * default value
+	 */
+	protected Object defaultValue;
+	protected boolean isDefaultValueSet = false;
+	
+	//GeometryType
+	//
+	protected CoordinateReferenceSystem crs;
+	protected boolean isCrsSet = false;
+	
+	//AttributeDescriptor
+	//
+	/**
+	 * Minimum number of occurrences allowed.
+	 * See minOccurs() function for the default value
+	 * based on nillable if not explicitly set.
+	 */
+	protected Integer minOccurs = null;
+	
+    /**
+     * Maximum number of occurrences allowed.
+     * See maxOccurs() function for the default value (of 1).
+     */
+	protected Integer maxOccurs = null;
+	
+	/**
+	 * True if value is allowed to be null.
+	 * <p>
+	 * Depending on this value minOccurs, maxOccurs and defaultValue()
+	 * will return different results.
+	 * <p>
+	 * The default value is <code>true</code>.
+	 */
+	protected boolean isNillable = true;
+	
+    /**
+     * User data for the attribute.
+     */
+    protected Map userData = null;
+
+	/**
+	 * Constructs the builder.
+	 *
+	 */
+    public AttributeTypeBuilder() {
+		this( new FeatureTypeFactoryImpl() );
+		init();
+		
+	}
+	
+	/**
+	 * Constructs the builder specifying the factory used to build attribute 
+	 * types.
+	 * 
+	 */
+	public AttributeTypeBuilder( FeatureTypeFactory factory ) {
+		this.factory = factory;
+		init();
+	}
+	
+	/**
+	 * Resets all internal state.
+	 */
+	protected void init() {
+	    resetTypeState();
+	    resetDescriptorState();
+	}
+	
+	/**
+	 * Resets all builder state used to build the attribute type.
+	 * <p>
+	 * This method is called automatically after {@link #buildType()} and 
+	 * {@link #buildGeometryType()}.
+	 * </p>
+	 */
+	protected void resetTypeState() {
+		name = null;
+		namespaceURI = null;
+		isAbstract = false;
+		restrictions = null;
+		description = null;
+		isIdentifiable = false;
+		binding = null;
+		defaultValue = null;
+		superType = null;
+		crs = null;
+		isCrsSet = false;
+		isDefaultValueSet = false;
+	}
+	
+	protected void resetDescriptorState() {
+		minOccurs = null;
+		maxOccurs = null;
+		isNillable = true;
+		userData = new HashMap();
+	}
+		
+	/**
+	 * Initializes builder state from another attribute type.
+	 */
+	public AttributeTypeBuilder init( AttributeType type ) {
+		name = type.getName().getLocalPart();
+		separator = type.getName().getSeparator();
+		namespaceURI = type.getName().getNamespaceURI();
+		isAbstract = type.isAbstract();
+		
+		if ( type.getRestrictions() != null ) {
+			restrictions().addAll( type.getRestrictions() );	
+		}
+		
+		description = type.getDescription() != null ? type.getDescription().toString() : null;
+		isIdentifiable = type.isIdentified();
+		binding = type.getBinding();
+		superType = type.getSuper();
+		
+		if ( type instanceof GeometryType ) {
+			crs = ((GeometryType)type).getCoordinateReferenceSystem();
+		}
+		return this;
+	}
+	
+	/**
+	 * Initializes builder state from another attribute descriptor.
+	 */
+
+	public void init( AttributeDescriptor descriptor ) {
+		init( descriptor.getType() );
+		minOccurs = descriptor.getMinOccurs();
+		maxOccurs = descriptor.getMaxOccurs();
+		isNillable = descriptor.isNillable();
+	}
+	
+	// Type methods
+	//
+	
+	public void setBinding(Class binding) {
+		this.binding = binding;
+		
+		//JD: tidbit here
+		if ( !isDefaultValueSet ) {
+		    //genereate a good default value based on class
+		    try {
+		        defaultValue = DataUtilities.defaultValue(binding);
+		    }
+		    catch( Exception e ) {
+		        //do nothing
+		    }
+		}
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public void setCRS(CoordinateReferenceSystem crs) {
+		this.crs = crs;
+		isCrsSet = true;
+	}
+
+	public boolean isCRSSet() {
+        return isCrsSet;
+    }
+	
+	public void setLength(int length) {
+    }
+	
+	public void addUserData( Object key, Object value ) {
+	    userData.put( key, value );
+	}
+	
+	// Descriptor methods
+	//
+	
+	public void setNillable(boolean isNillable) {
+		this.isNillable = isNillable;
+	}
+
+	public void setMaxOccurs(int maxOccurs) {
+		this.maxOccurs = maxOccurs;
+	}
+
+	public void setMinOccurs(int minOccurs) {
+		this.minOccurs = minOccurs;
+	}
+	
+	public void setDefaultValue(Object defaultValue) {
+		this.defaultValue = defaultValue;
+		isDefaultValueSet = true;
+	}
+	
+	// construction methods
+	//
+	
+	/**
+	 * Builds the attribute type.
+	 * <p>
+	 * This method resets all state after the attribute is built.
+	 * </p>
+	 */
+	public AttributeType buildType() {
+		AttributeType type = factory.createAttributeType(
+			name(), binding, isIdentifiable, isAbstract, 
+			restrictions(), superType, description());
+		resetTypeState();
+		
+		return type;
+	}
+
+	protected String typeName(){
+		if( name == null ){
+			return Classes.getShortName( binding );
+		}
+		return name;
+	}
+    private InternationalString description() {
+        return description != null ? new SimpleInternationalString(description) : null;
+    }
+	
+	/**
+	 * Builds the geometry attribute type.
+	 * <p>
+	 * This method resets all state after the attribute is built.
+	 * </p>
+	 */
+	public GeometryType buildGeometryType() {
+		GeometryType type = factory.createGeometryType(
+			name(), binding, crs, isIdentifiable, isAbstract, 
+			restrictions(), superType, description());
+		
+		resetTypeState();
+		
+		return type;
+	}
+
+	/**
+	 * Builds an attribute descriptor first building an attribute type from 
+	 * internal state.
+	 * <p>
+	 * If {@link #crs} has been set via {@link #setCRS(CoordinateReferenceSystem)}
+	 * the internal attribute type will be built via {@link #buildGeometryType()}, 
+	 * otherwise it will be built via {@link #buildType()}.
+	 * </p>
+	 * <p>
+	 * This method calls through to {@link #buildDescriptor(String, AttributeType)}.
+	 * </p>
+	 * @param name The name of the descriptor.
+	 * 
+	 * @see #buildDescriptor(String, AttributeType) 
+	 */
+	public AttributeDescriptor buildDescriptor( String name ) {
+	    setName(name);
+		if(binding == null)
+			throw new IllegalStateException("No binding has been provided for this attribute");
+		if ( crs != null || Geometry.class.isAssignableFrom(binding)) {
+			return buildDescriptor(name, buildGeometryType());
+		}
+		else {
+			return buildDescriptor(name, buildType());
+		}
+	}
+	
+	/**
+	 * Builds an attribute descriptor specifying its attribute type.
+	 * <p>
+	 * Internal state is reset after the descriptor is built.
+	 * </p>
+	 * @param name The name of the descriptor.
+	 * @param type The type referenced by the descriptor.
+	 *
+	 */
+	public AttributeDescriptor buildDescriptor(String name, AttributeType type) {
+		return buildDescriptor(new NameImpl(name), type );
+	}
+	   
+    /**
+     * Builds a geometry descriptor specifying its attribute type.
+     * <p>
+     * Internal state is reset after the descriptor is built.
+     * </p>
+     * @param name The name of the descriptor.
+     * @param type The geometry type referenced by the descriptor.
+     *
+     */
+	public GeometryDescriptor buildDescriptor(String name, GeometryType type) {
+	    return buildDescriptor( new NameImpl(name), type );
+	}
+	
+	public AttributeDescriptor buildDescriptor(Name name, AttributeType type ) {
+		
+	    //build the descriptor
+	    AttributeDescriptor descriptor = factory.createAttributeDescriptor(
+			type, name, minOccurs(), maxOccurs(), isNillable, defaultValue());
+	
+	    //set the user data
+		descriptor.getUserData().putAll( userData );
+		resetDescriptorState();
+		return descriptor;
+	}
+	
+	public GeometryDescriptor buildDescriptor(Name name, GeometryType type ) {
+	    GeometryDescriptor descriptor = factory.createGeometryDescriptor(
+            type, name, minOccurs(), maxOccurs(), isNillable, defaultValue());
+    
+	    // set the user data
+        descriptor.getUserData().putAll( userData );
+        resetDescriptorState();
+        return descriptor;
+    }
+	
+	/**
+	 * This is not actually right but we do it for backwards compatibility.
+	 * @return minOccurs if set or a default based on isNillable.
+	 */
+	private int minOccurs(){
+	    if( minOccurs == null ){
+	        return isNillable ? 0 : 1;
+	    }
+	    return minOccurs;
+	}
+    /**
+     * This is not actually right but we do it for backwards compatibility.
+     * @return minOccurs if set or a default based on isNillable.
+     */
+    private int maxOccurs(){
+        if( maxOccurs == null ){
+            return 1;
+        }
+        return maxOccurs;
+    }
+	
+    private Name name(){
+    	if( separator == null ){
+    		return new NameImpl( namespaceURI, typeName() );
+    	}
+    	else {
+    		return new NameImpl( namespaceURI, separator, typeName() );
+    	}
+    }
+	private Object defaultValue(){
+	    if( defaultValue == null && !isNillable && binding != null){
+	        defaultValue = DataUtilities.defaultValue( binding );
+	    }
+	    return defaultValue;
+	}
+	
+	// internal / subclass api
+	//
+	
+	protected List<Filter> restrictions() {
+		if (restrictions == null ) {
+			restrictions = new ArrayList();		
+		}
+		
+		return restrictions;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureCollection.java	(revision 28000)
@@ -0,0 +1,413 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.Feature;
+import org.opengis.feature.FeatureVisitor;
+import org.opengis.feature.type.FeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.util.ProgressListener;
+
+
+/**
+ * Represents a collection of features.
+ * <p>
+ * Implementations (and client code) should adhere to the rules set forth
+ * by java.util.Collection. That is, some methods are
+ * optional to implement, and may throw an UnsupportedOperationException.
+ * </p>
+ * <p>
+ * SimpleFeatureCollection house rules:
+ * <ul>
+ * <li>FeatureCollection.close( iterator ) must be called (see example below)
+ * <li>Features are not specifically ordered within the SimpleFeatureCollection (see FeatureList)
+ * <li>Two instances cannot exist with the same Feature ID (Feature contract)
+ * <li>(unsure) the same Instance can be in the collection more then once
+ * </ul>
+ * In programmer speak a SimpleFeatureCollection is a "Bag" with an index based ID.
+ * </p>
+ * <p>
+ * <h3>Life Cycle of Iterator</h3>
+ * <p>
+ * We have also adopted an additional constraint on the use of iterator.
+ * You must call FeatureCollection.close( iterator ) to allow FeatureCollection
+ * to clean up any operating system resources used to acces information.
+ * </p>
+ * <p>
+ * Example (safe) use:<pre><code>
+ * Iterator iterator = collection.iterator();
+ * try {
+ *     for( Iterator i=collection.iterator(); i.hasNext();){
+ *          Feature feature = (Feature) i.hasNext();
+ *          System.out.println( feature.getID() );
+ *     }
+ * }
+ * finally {
+ *     collection.close( iterator );
+ * }
+ * </code></pre>
+ * </p>
+ * <p>
+ * Handy Tip: Although many resource backed collections will choose
+ * to release resources at when the iterator has reached the end of its contents
+ * this is not something you should rely on.
+ * </p>
+ * <h2>Notes for SimpleFeatureCollection Implementors</h2>
+ * <p>
+ * Many users will be treating this as a straight forward Collection,
+ * there code will break often enough due to latency - try and close
+ * up resources for them when you can detect that an Iterator is not
+ * useful anymore.
+ * </p>
+ * <p>
+ * Collections are used in two fashions, basically as you see them,
+ * and also as "range" for common opperations. You can see this with
+ * List.subCollection( Filter ). Existing RnD effort is
+ * going towards supporting this kind of use at the FeatureCollection
+ * level.
+ * </p>
+ *
+ * @see java.util.Collection, org.geotools.Feature
+ * @author Ian Turton, CCG
+ * @author Rob Hranac, VFNY
+ * @author Ian Schneider, USDA-ARS
+ * @author Jody Garnett, Refractions Research, Inc.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/feature/FeatureCollection.java $
+ * @version $Id: FeatureCollection.java 37280 2011-05-24 07:53:02Z mbedward $
+ *
+ */
+public interface FeatureCollection<T extends FeatureType, F extends Feature> {
+    /**
+     * Obtain a FeatureIterator<SimpleFeature> of the Features within this collection.
+     * <p>
+     * The implementation of Collection must adhere to the rules of
+     * fail-fast concurrent modification. In addition (to allow for
+     * resource backed collections, the <code>close( Iterator )</code>
+     * method must be called.
+     * <p>
+     *
+     * This is almost equivalent to:
+     * <ul>
+     * <li>a Type-Safe call to:
+     * <code>getAttribute(getFeatureType().getAttributeType(0).getName()).iterator();</code>.
+     * <li>A Java 5:<code>Iterator&lt;Feature&gt;</code>
+     * </ul>
+     * </p>
+     * Example (safe) use:<pre><code>
+     * FeatureIterator<SimpleFeature> iterator=collection.features();
+     * try {
+     *     while( iterator.hasNext()  ){
+     *          Feature feature = iterator.next();
+     *          System.out.println( feature.getID() );
+     *     }
+     * }
+     * finally {
+     *     collection.close( iterator );
+     * }
+     * </code></pre>
+     * </p>
+     *
+     * <p>
+     * GML Note: The contents of this iterator are considered to be defined by
+     * <b>featureMember</b> tags (and/or the single allowed <b>FeatureMembers</b> tag).
+     * Please see getFeatureType for more details.
+     * </p>
+     *
+     * @return A FeatureIterator.
+     */
+    FeatureIterator<F> features();
+
+    /**
+     * Clean up after any resources associated with this FeatureIterator in a manner similar to JDO collections.
+     * </p>
+     * Example (safe) use:<pre><code>
+     * Iterator iterator = collection.iterator();
+     * try {
+     *     for( Iterator i=collection.iterator(); i.hasNext();){
+     *          Feature feature = i.hasNext();
+     *          System.out.println( feature.getID() );
+     *     }
+     * }
+     * finally {
+     *     collection.close( iterator );
+     * }
+     * </code></pre>
+     * </p>
+     * @param close
+     * @deprecated Please FeatureIterator.close()
+     */
+    public void close(FeatureIterator<F> close);
+    
+    /**
+     * Clean up after any resources associated with this itterator in a manner similar to JDO collections.
+     * </p>
+     * Example (safe) use:<pre><code>
+     * Iterator iterator = collection.iterator();
+     * try {
+     *     for( Iterator i=collection.iterator(); i.hasNext();){
+     *          Feature feature = (Feature) i.hasNext();
+     *          System.out.println( feature.getID() );
+     *     }
+     * }
+     * finally {
+     *     collection.close( iterator );
+     * }
+     * </code></pre>
+     * </p>
+     * @deprecated Please use features() to obtain a FeatureIterator
+     */
+    public void close(Iterator<F> close);
+    
+    /**
+     * Gets a reference to the type of this feature collection.
+     * <p>
+     * There are several limitations on the use of FeatureType with respect to a FeatureCollection.
+     * </p>
+     * <p>
+     * GML 3.x: all FeatureCollections decend from gml:AbstractFeatureCollectionType:
+     * <ul>
+     * <li>featureMember 0..* allows _Feature or xlink:ref
+     * <li>featureMembers 0..1 contents treated as _Feature
+     * </ul>
+     * The contents defined in this manner is returned the collection
+     * iterator() method.
+     * </p>
+     * <p>
+     * GML 3.x: gml:AbstractFeatureCollectionType decends from gml:BoundedFeatureType:
+     * <ul>
+     * <li>metaDataProperty 0..*
+     * <li>description 0..1
+     * <li>name 0..*
+     * <li>boundedBy 1..1 (required)
+     * <li>location 0..1
+     * </ul>
+     * The value of the boundedBy attribute should be derived from the contents
+     * of the collection.
+     * </p>
+     * <h3>Implementation Notes</h3>
+     * <p>
+     * There is a difference between getFeatureType() and getSchema(), getSchema is named
+     * for historical reasons and reprensets the LCD FeatureType that best represents the
+     * contents of this collection.
+     * <ul>
+     * <li>The degenerate case returns the "_Feature" FeatureType, where the
+     * onlything known is that the contents are Features.
+     * <li>For a collection backed by a shapefiles (or database tables) the
+     *     FeatureType returned by getSchema() will complete describe each and every child in the collection.
+     * <li>For mixed content FeatureCollections you will need to check the FeatureType
+     *     of each Feature as it is retrived from the collection
+     * </ul>
+     * </p>
+     *
+     * @return A reference to this collections type
+     */
+
+    //FeatureType getFeatureType();
+
+    /**
+     * The schema for the child features of this collection.
+     * <p>
+     * There is a difference between getFeatureType() and getSchema()represents the LCD
+     * FeatureType that best represents the contents of this collection.
+     * <ul>
+     * <li>The degenerate case returns the "_Feature" FeatureType, where the
+     * onlything known is that the contents are Features.
+     * <li>For a collection backed by a shapefiles (or database tables) the FeatureType returned by getSchema() will
+     * complete describe each and every child in the collection.
+     * <li>For mixed content FeatureCollections you will need to check the FeatureType of each Feature as it
+     * is retrived from the collection
+     * </ul>
+     * </p>
+     * <p>
+     * The method getSchema() is named for compatability with the geotools 2.0 API. In the
+     * Geotools 2.2 time frame we should be able to replace this method with a careful check
+     * of getFeatureType() and its attributes.
+     *  </p>
+     * @return FeatureType describing the "common" schema to all child features of this collection
+     */
+    T getSchema();
+
+    /** ID used when serializing to GML */
+    String getID();
+    
+    /**
+     * Visit the contents of a feature collection.
+     * <p>
+     * The order of traversal is dependent on the FeatureCollection implementation; some
+     * collections are able to make efficient use of an internal index in order to quickly
+     * visit features located in the same region.
+     * </p>
+     * 
+     * @param visitor Closure applied to each feature in turn.
+     * @param progress Used to report progress, may be used to interrupt the operation
+     *
+     * @since 2.5
+     */
+    void accepts(FeatureVisitor visitor, ProgressListener progress) throws IOException;
+
+    /**
+     * SimpleFeatureCollection "view" indicated by provided filter.
+     * <p>
+     * The contents of the returned SimpleFeatureCollection are determined by
+     * applying the provider Filter to the entire contents of this
+     * FeatureCollection. The result is "live" and modifications will
+     * be shared.
+     * <p>
+     * This method is used cut down on the number of filter based methods
+     * required for a useful SimpleFeatureCollection construct. The FeatureCollections
+     * returned really should be considered as a temporary "view" used to
+     * control the range of a removeAll, or modify operation.
+     * <p>
+     * Example Use:
+     * <pre><code>
+     * collection.subCollection( filter ).clear();
+     * </code></pre>
+     * The above recommended use is agreement with the Collections API precident of
+     * List.subList( start, end ).
+     * <p>
+     * The results of subCollection:
+     * <ul>
+     * <li>are to be considered unordered
+     * <li>may be an ordered FeatureList if requested when sortBy is indicated
+     * </ul>
+     * </p>
+     * @see FeatureList
+     * @param filter
+     * @return SimpleFeatureCollection identified as subset.
+     */
+    public FeatureCollection<T, F> subCollection(Filter filter);
+
+    /**
+     * Get the total bounds of this collection which is calculated by doing a
+     * union of the bounds of each feature inside of it
+     *
+     * @return An Envelope containing the total bounds of this collection.
+     */
+    ReferencedEnvelope getBounds();
+    
+    //
+    // ResourceCollection methods
+    //
+    /**
+     * An iterator over this collection, which must be closed after use.
+     * <p>
+     * Collection is not guaranteed to be ordered in any manner.
+     * </p>
+     * <p>
+     * The implementation of Collection must adhere to the rules of
+     * fail-fast concurrent modification. In addition (to allow for
+     * resource backed collections, the <code>close( Iterator )</code>
+     * method must be called.
+     * <p>
+     * </p>
+     * Example (safe) use:<pre><code>
+     * Iterator iterator = collection.iterator();
+     * try {
+     *     while( iterator.hasNext();){
+     *          Feature feature = (Feature) iterator.hasNext();
+     *          System.out.println( feature.getID() );
+     *     }
+     * }
+     * finally {
+     *     collection.close( iterator );
+     * }
+     * </code></pre>
+     * </p>
+     * @return Iterator
+     * @deprecated Please use features() to obtain a FeatureIterator
+     */
+    public Iterator<F> iterator();
+
+    /**
+     * Close any outstanding resources released by this resources.
+     * <p>
+     * This method should be used with great caution, it is however available
+     * to allow the use of the ResourceCollection with algorthims that are
+     * unaware of the need to close iterators after use.
+     * </p>
+     * <p>
+     * Example of using a normal Collections utility method:<pre><code>
+     * Collections.sort( collection );
+     * collection.purge();
+     * </code></pre>
+     * @deprecated Please use features() to obtain a FeatureIterator
+     */
+    public void purge();
+    
+    /**
+     * Add object to this collection. 
+     * <p>
+     * This method is often not impelmented for collections produced as the result of a query.
+     * 
+     * @return true of the element was added
+     * @see java.util.Collection#add(Object)
+     */
+    boolean add(F obj);
+    
+    /**
+     * Add all the objects to the collection.
+     * <p>
+     * This method is often not implemented for collections produced as the results of a query.
+     * @see java.util.Collection#addAll(Collection)
+     */
+    boolean addAll(Collection<? extends F> collection);
+
+    /** @see #addAll(Collection) */
+    boolean addAll(FeatureCollection<? extends T,? extends F> resource);
+    
+    /** @see java.util.Collection#clear() */
+    void clear();
+    
+    /**
+     * @see java.util.Collection#contains(Object)
+     */
+    boolean contains(Object o);
+    
+    /**
+     * @see java.util.Collection#containsAll(Collection)
+     */
+    boolean containsAll(Collection<?> o);
+
+    /** @see java.util.Collection#isEmpty() */
+    boolean isEmpty();
+    
+    /** @see java.util.Collection#remove(Object) */
+    boolean remove(Object o);
+    
+    /** @see java.util.Collection#removeAll(Collection) */
+    public boolean removeAll(Collection<?> c);
+    
+    /** @see java.util.Collection#retainAll(Collection) */   
+    public boolean retainAll(Collection<?> c);
+      
+    /**
+     * @see java.util.Collection#size()
+     */
+    int size();
+    
+    /** @see java.util.Collection#toArray() */    
+    Object[] toArray();
+    
+    /** @see java.util.Collection#toArray(Object[]) */ 
+    <O> O[] toArray(O[] a);    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureCollections.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureCollections.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureCollections.java	(revision 28000)
@@ -0,0 +1,39 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.geotools.factory.Factory;
+
+/**
+ * A utility class for working with FeatureCollections.
+ * Provides a mechanism for obtaining a SimpleFeatureCollection instance.
+ * @author  Ian Schneider
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/feature/FeatureCollections.java $
+ */
+public abstract class FeatureCollections implements Factory {
+  
+  /**
+   * Returns the implementation hints. The default implementation returns en empty map.
+   */
+  public Map getImplementationHints() {
+    return Collections.EMPTY_MAP;
+  }  
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureIterator.java	(revision 28000)
@@ -0,0 +1,51 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature;
+
+import org.opengis.feature.Feature;
+
+/**
+ * A drop in replacement for Iterator<Feature> supporting a close method.
+ * 
+ * @author Ian Schneider
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/feature/FeatureIterator.java $
+ */
+public interface FeatureIterator<F extends Feature> {
+    /**
+     * Does another Feature exist in this Iteration.
+     * <p>
+     * Iterator defin: Returns true if the iteration has more elements. (In other words, returns true if next would return an element rather than throwing an exception.)
+     * </p>
+     * @return true if more Features exist, false otherwise.
+     */
+    public boolean hasNext();
+
+    /**
+     * Get the next Feature in this iteration.
+     *
+     * @return The next Feature
+     *
+     * @throws java.util.NoSuchElementException If no more Features exist.
+     */
+    public F next() throws java.util.NoSuchElementException;
+
+    /**
+     * Required so SimpleFeatureCollection classes can implement close( FeatureIterator<SimpleFeature> ).
+     */
+    public void close();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureReaderIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureReaderIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureReaderIterator.java	(revision 28000)
@@ -0,0 +1,111 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ */
+package org.geotools.feature;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.geotools.data.FeatureReader;
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+
+/**
+ * An iterator that wraps around a FeatureReader.
+ * <p>
+ * The Iterator's hasNext() will return false if the wrapped feature reader's hasNext method throws
+ * an exception. If next() throws an exception a NoSuchElementException will be thrown.
+ * </p>
+ * <p>
+ * {@link #close()} shall be called before disposing the iterator. Before propagating an exception
+ * from {@link #next()} or eating an exception from the underlying feature reader at
+ * {@link #hasNext()}, this iterator will auto-close.
+ * </p>
+ * 
+ * @author jeichar
+ * @author Jody Garnett
+ * @author Gabriel Roldan
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/FeatureReaderIterator.java $
+ */
+public class FeatureReaderIterator<F extends Feature> implements Iterator<F> {
+
+    FeatureReader<? extends FeatureType, F> reader;
+
+    public FeatureReaderIterator(FeatureReader<? extends FeatureType, F> reader) {
+        this.reader = reader;
+    }
+
+    public boolean hasNext() {
+        try {
+            if (reader == null)
+                return false;
+            if (reader.hasNext()) {
+                return true;
+            } else {
+                // auto close because we don't trust
+                // client code to call closed :-)
+                close();
+                return false;
+            }
+        } catch (Exception e) {
+            close();
+            return false; // failure sounds like lack of next to me
+        }
+    }
+
+    public F next() {
+        if (reader == null) {
+            throw new NoSuchElementException("Iterator has been closed");
+        }
+        try {
+            return reader.next();
+        } catch (IOException io) {
+            close();
+            NoSuchElementException problem = new NoSuchElementException(
+                    "Could not obtain the next feature:" + io);
+            problem.initCause(io);
+            throw problem;
+        } catch (org.opengis.feature.IllegalAttributeException create) {
+            close();
+            NoSuchElementException problem = new NoSuchElementException(
+                    "Could not create the next feature:" + create);
+            problem.initCause(create);
+            throw problem;
+        }
+    }
+
+    /** If this is a problem, a different iterator can be made based on FeatureWriter */
+    public void remove() {
+        throw new UnsupportedOperationException("Modification of contents is not supported");
+    }
+
+    /**
+     * Close the reader please.
+     */
+    public void close() {
+        if (reader != null) {
+            try {
+                reader.close();
+            } catch (Exception e) {
+                // sorry but iterators die quitely in the night
+            }
+            reader = null;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureTypes.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureTypes.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/FeatureTypes.java	(revision 28000)
@@ -0,0 +1,384 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.geotools.factory.FactoryRegistryException;
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.FeatureType;
+import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+/**
+ * Utility methods for working against the FeatureType interface.
+ * <p>
+ * Many methods from DataUtilities should be refractored here.
+ * </p>
+ * <p>
+ * Responsibilities:
+ * <ul>
+ * <li>Schema construction from String spec
+ * <li>Schema Force CRS
+ * </ul>
+ *
+ * @author Jody Garnett, Refractions Research
+ * @since 2.1.M3
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/FeatureTypes.java $
+ */
+public class FeatureTypes {
+
+	/** the default namespace for feature types */
+	//public static final URI = GMLSchema.NAMESPACE;
+	public static final URI DEFAULT_NAMESPACE;
+	static {
+		URI uri;
+		try {
+			uri = new URI( "http://www.opengis.net/gml" );
+		}
+		catch (URISyntaxException e) {
+			uri = null;	//will never happen
+		}
+		DEFAULT_NAMESPACE = uri;
+	}
+
+	/** abstract base type for all feature types */
+    public final static SimpleFeatureType ABSTRACT_FEATURE_TYPE;
+    static {
+        SimpleFeatureType featureType = null;
+        try {
+            featureType = FeatureTypes.newFeatureType(null, "Feature",new URI("http://www.opengis.net/gml"), true);
+        }
+        catch(Exception e ) {
+            //shold not happen
+        }
+        ABSTRACT_FEATURE_TYPE = featureType;
+    }
+
+    /**
+     * Forces the specified CRS on all geometry attributes
+     * @param schema the original schema
+     * @param crs the forced crs
+     * @return
+     * @throws SchemaException
+     */
+    public static SimpleFeatureType transform( SimpleFeatureType schema, CoordinateReferenceSystem crs )
+        throws SchemaException {
+        return transform(schema, crs, false);
+    }
+
+    /**
+     * Forces the specified CRS on geometry attributes (all or some, depends on the parameters).
+     * @param schema the original schema
+     * @param crs the forced crs
+     * @param forceOnlyMissing if true, will force the specified crs only on the attributes that
+     *        do miss one
+     * @return
+     * @throws SchemaException
+     */
+    public static SimpleFeatureType transform( SimpleFeatureType schema, CoordinateReferenceSystem crs, boolean forceOnlyMissing)
+            throws SchemaException {
+        SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
+        tb.setName(schema.getTypeName());
+        tb.setNamespaceURI( schema.getName().getNamespaceURI() );
+        tb.setAbstract(schema.isAbstract());
+
+        for( int i = 0; i < schema.getAttributeCount(); i++ ) {
+            AttributeDescriptor attributeType = schema.getDescriptor(i);
+            if (attributeType instanceof GeometryDescriptor) {
+                GeometryDescriptor geometryType = (GeometryDescriptor) attributeType;
+
+                tb.descriptor( geometryType );
+                if ( !forceOnlyMissing || geometryType.getCoordinateReferenceSystem() == null ) {
+                    tb.crs( crs );
+                }
+
+                tb.add( geometryType.getLocalName(), geometryType.getType().getBinding() );
+            } else {
+                tb.add(attributeType);
+            }
+        }
+        if (schema.getGeometryDescriptor() != null) {
+            tb.setDefaultGeometry(schema.getGeometryDescriptor().getLocalName());
+        }
+
+        tb.setSuperType((SimpleFeatureType) schema.getSuper());
+
+        return tb.buildFeatureType();
+    }
+
+    /**
+     * The most specific way to create a new FeatureType.
+     *
+     * @param types The AttributeTypes to create the FeatureType with.
+     * @param name The typeName of the FeatureType. Required, may not be null.
+     * @param ns The namespace of the FeatureType. Optional, may be null.
+     * @param isAbstract True if this created type should be abstract.
+     * @param superTypes A Collection of types the FeatureType will inherit from. Currently, all
+     *        types inherit from feature in the opengis namespace.
+     * @return A new FeatureType created from the given arguments.
+     * @throws FactoryRegistryException If there are problems creating a factory.
+     * @throws SchemaException If the AttributeTypes provided are invalid in some way.
+     */
+    public static SimpleFeatureType newFeatureType( AttributeDescriptor[] types, String name, URI ns,
+            boolean isAbstract, SimpleFeatureType[] superTypes ) throws FactoryRegistryException,
+            SchemaException {
+        return newFeatureType(types, name, ns, isAbstract, superTypes, null);
+    }
+
+    /**
+     * The most specific way to create a new FeatureType.
+     *
+     * @param types The AttributeTypes to create the FeatureType with.
+     * @param name The typeName of the FeatureType. Required, may not be null.
+     * @param ns The namespace of the FeatureType. Optional, may be null.
+     * @param isAbstract True if this created type should be abstract.
+     * @param superTypes A Collection of types the FeatureType will inherit from. Currently, all
+     *        types inherit from feature in the opengis namespace.
+     * @return A new FeatureType created from the given arguments.
+     * @throws FactoryRegistryException If there are problems creating a factory.
+     * @throws SchemaException If the AttributeTypes provided are invalid in some way.
+     */
+    public static SimpleFeatureType newFeatureType( AttributeDescriptor[] types, String name, URI ns,
+            boolean isAbstract, SimpleFeatureType[] superTypes, AttributeDescriptor defaultGeometry )
+            throws FactoryRegistryException, SchemaException {
+        SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
+
+        tb.setName(name);
+        tb.setNamespaceURI(ns);
+        tb.setAbstract(isAbstract);
+        if(types != null) {
+            tb.addAll(types);
+        }
+
+        if ( defaultGeometry != null ) {
+            //make sure that the default geometry was one of the types specified
+            boolean add = true;
+            for ( int i = 0; i < types.length; i++ ) {
+                if (types[i] == defaultGeometry) {
+                    add = false;
+                    break;
+                }
+            }
+            if ( add ) {
+                tb.add(defaultGeometry);
+            }
+            tb.setDefaultGeometry(defaultGeometry.getLocalName());
+        }
+        if ( superTypes != null && superTypes.length > 0) {
+            if ( superTypes.length > 1 ) {
+                throw new SchemaException("Can only specify a single super type");
+            }
+            tb.setSuperType(superTypes[0]);
+
+        }
+        else {
+            //use the default super type
+            tb.setSuperType(ABSTRACT_FEATURE_TYPE);
+        }
+        return tb.buildFeatureType();
+    }
+
+    /**
+     * The most specific way to create a new FeatureType.
+     *
+     * @param types The AttributeTypes to create the FeatureType with.
+     * @param name The typeName of the FeatureType. Required, may not be null.
+     * @param ns The namespace of the FeatureType. Optional, may be null.
+     * @param isAbstract True if this created type should be abstract.
+     * @param superTypes A Collection of types the FeatureType will inherit from. Currently, all
+     *        types inherit from feature in the opengis namespace.
+     * @return A new FeatureType created from the given arguments.
+     * @throws FactoryRegistryException If there are problems creating a factory.
+     * @throws SchemaException If the AttributeTypes provided are invalid in some way.
+     */
+    public static SimpleFeatureType newFeatureType( AttributeDescriptor[] types, String name, URI ns,
+            boolean isAbstract, SimpleFeatureType[] superTypes, GeometryDescriptor   defaultGeometry )
+            throws FactoryRegistryException, SchemaException {
+        return newFeatureType(types,name,ns,isAbstract,superTypes,(AttributeDescriptor)defaultGeometry);
+    }
+
+    /**
+     * Create a new FeatureType with the given AttributeTypes. A short cut for calling
+     * <code>newFeatureType(types,name,ns,isAbstract,null)</code>.
+     *
+     * @param types The AttributeTypes to create the FeatureType with.
+     * @param name The typeName of the FeatureType. Required, may not be null.
+     * @param ns The namespace of the FeatureType. Optional, may be null.
+     * @param isAbstract True if this created type should be abstract.
+     * @return A new FeatureType created from the given arguments.
+     * @throws FactoryRegistryException If there are problems creating a factory.
+     * @throws SchemaException If the AttributeTypes provided are invalid in some way.
+     */
+    public static SimpleFeatureType newFeatureType( AttributeDescriptor[] types, String name, URI ns,
+            boolean isAbstract ) throws FactoryRegistryException, SchemaException {
+        return newFeatureType(types, name, ns, isAbstract, null);
+    }
+
+    /**
+     * Walks up the type hierarchy of the feature returning all super types of the specified feature
+     * type. The search terminates when a non-FeatureType or null is found. The original featureType
+     * is not included as an ancestor, only its strict ancestors.
+     */
+    public static List<FeatureType> getAncestors(FeatureType featureType) {
+        List<FeatureType> ancestors = new ArrayList<FeatureType>();
+        while (featureType.getSuper() instanceof FeatureType) {
+            FeatureType superType = (FeatureType) featureType.getSuper();
+            ancestors.add(superType);
+            featureType = superType;
+        }
+        return ancestors;
+    }
+
+    /** Exact equality based on typeNames, namespace, attributes and ancestors, including the user maps contents */
+    public static boolean equalsExact( SimpleFeatureType typeA, SimpleFeatureType typeB ) {
+        return equals(typeA, typeB, true);
+    }
+    
+    /** Exact equality based on typeNames, namespace, attributes and ancestors */
+    static boolean equals( SimpleFeatureType typeA, SimpleFeatureType typeB, boolean compareUserMaps) {
+        if (typeA == typeB)
+            return true;
+
+        if (typeA == null || typeB == null) {
+            return false;
+        }
+        
+        if(compareUserMaps) {
+            if(!equals(typeA.getUserData(), typeB.getUserData()))
+                return false;
+        }
+        
+        return equalsId(typeA, typeB)
+                && equals(typeA.getAttributeDescriptors(), typeB.getAttributeDescriptors(), compareUserMaps) &&
+                equalsAncestors( typeA, typeB );
+    }
+    
+    static boolean equals( List attributesA, List attributesB, boolean compareUserMaps) {
+        return equals(
+            (AttributeDescriptor[]) attributesA.toArray(new AttributeDescriptor[attributesA.size()]),
+            (AttributeDescriptor[]) attributesB.toArray(new AttributeDescriptor[attributesB.size()]), 
+            compareUserMaps);
+    }
+
+    static boolean equals( AttributeDescriptor attributesA[], AttributeDescriptor attributesB[], boolean compareUserMaps ) {
+        if (attributesA.length != attributesB.length)
+            return false;
+
+        for( int i = 0, length = attributesA.length; i < length; i++ ) {
+            if (!equals(attributesA[i], attributesB[i], compareUserMaps))
+                return false;
+        }
+        return true;
+    }
+    /**
+     * This method depends on the correct implementation of FeatureType equals
+     * <p>
+     * We may need to write an implementation that can detect cycles,
+     * </p>
+     *
+     * @param typeA
+     * @param typeB
+     */
+    public static boolean equalsAncestors( SimpleFeatureType typeA, SimpleFeatureType typeB ) {
+        return ancestors( typeA ).equals( ancestors(typeB) );
+    }
+
+    public static Set ancestors( SimpleFeatureType featureType ) {
+        if (featureType == null || getAncestors(featureType).isEmpty()) {
+            return Collections.EMPTY_SET;
+        }
+        return new HashSet(getAncestors(featureType));
+    }
+    
+    static boolean equals( AttributeDescriptor a, AttributeDescriptor b, boolean compareUserMaps) {
+        if(a == b)
+            return true;
+        
+        if(a == null)
+            return true;
+        
+        if(!a.equals(b))
+            return false;
+        
+        if(compareUserMaps) {
+            if(!equals(a.getUserData(), b.getUserData()))
+                return false;
+            if(!equals(a.getType().getUserData(), b.getType().getUserData()))
+                return false;
+        }
+        
+        return true;
+            
+    }
+    
+    /**
+     * Tolerant map comparison. Two maps are considered to be equal if they express the
+     * same content. So for example two null maps are equal, but also a null and an 
+     * empty one are
+     */
+    static boolean equals(Map a, Map b) {
+        if(a == b)
+            return true;
+        
+        // null == null handled above
+        if(a == null || b == null)
+            return false;
+        
+        return a.equals(b);
+    }
+    
+    /** Quick check of namespace and typename */
+    public static boolean equalsId( SimpleFeatureType typeA, SimpleFeatureType typeB ) {
+        if (typeA == typeB)
+            return true;
+
+        if (typeA == null || typeB == null) {
+            return false;
+        }
+
+        String typeNameA = typeA.getTypeName();
+        String typeNameB = typeB.getTypeName();
+        if (typeNameA == null && typeNameB != null)
+            return false;
+        else if (!typeNameA.equals(typeNameB))
+            return false;
+
+        String namespaceA = typeA.getName().getNamespaceURI();
+        String namespaceB = typeB.getName().getNamespaceURI();
+        if(namespaceA == null && namespaceB == null)
+            return true;
+        
+        if (namespaceA == null && namespaceB != null)
+            return false;
+        else if (!namespaceA.equals(namespaceB))
+            return false;
+
+        return true;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/GeometryAttributeImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/GeometryAttributeImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/GeometryAttributeImpl.java	(revision 28000)
@@ -0,0 +1,213 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature;
+
+
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.util.Utilities;
+import org.opengis.feature.GeometryAttribute;
+import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.feature.type.GeometryType;
+import org.opengis.filter.identity.Identifier;
+import org.opengis.geometry.BoundingBox;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.MultiLineString;
+import com.vividsolutions.jts.geom.MultiPoint;
+import com.vividsolutions.jts.geom.MultiPolygon;
+
+/**
+ * TODO: rename to GeometricAttribute Provides ...TODO summary sentence
+ * <p>
+ * TODO Description
+ * </p>
+ * <p>
+ * </p>
+ * <p>
+ * Example Use:
+ * 
+ * <pre><code>
+ *         GeometryAttributeType x = new GeometryAttributeType( ... );
+ *         TODO code example
+ * </code></pre>
+ * 
+ * </p>
+ * 
+ * @author Leprosy
+ * @since 0.3 TODO: test wkt geometry parse.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/GeometryAttributeImpl.java $
+ */
+public class GeometryAttributeImpl extends AttributeImpl implements
+		GeometryAttribute {
+	/**
+	 * bounds, derived
+	 */
+    protected BoundingBox bounds;
+
+	public GeometryAttributeImpl( Object content, GeometryDescriptor descriptor, Identifier id ) {
+		super(content, descriptor, id);
+	}
+
+	public GeometryType getType() {
+	    return (GeometryType) super.getType();
+	}
+	
+	public GeometryDescriptor getDescriptor() {
+	    return (GeometryDescriptor) super.getDescriptor();
+	}
+	
+	public Geometry getValue() {
+		return (Geometry) super.getValue();
+	}
+
+	public void setValue(Object newValue) throws IllegalArgumentException,
+	        IllegalStateException {
+	    setValue( (Geometry) newValue );
+	}
+	
+	public void setValue(Geometry geometry) {
+		super.setValue(geometry);
+	}
+
+	/**
+	 * Returns the non null envelope of this attribute. If the attribute's
+	 * geometry is <code>null</code> the returned Envelope
+	 * <code>isNull()</code> is true.
+	 * 
+	 * @return 
+	 */
+	public synchronized BoundingBox getBounds() {
+		if( bounds == null ){
+			ReferencedEnvelope bbox = new ReferencedEnvelope(getType().getCoordinateReferenceSystem());
+			Geometry geom = getValue();
+			if (geom != null) {
+				bbox.expandToInclude(geom.getEnvelopeInternal());
+			}
+			else {
+			    bbox.setToNull();
+			}
+			bounds =  bbox;
+		}
+		return bounds;
+	}
+
+	public boolean equals(Object o) {
+	    if ( this == o ) {
+	        return true;
+	    }
+	    
+		if (!(o instanceof GeometryAttributeImpl)) {
+			return false;
+		}
+		
+		GeometryAttributeImpl att = (GeometryAttributeImpl) o;
+
+		//JD: since Geometry does not implement equals(Object) "properly",( ie
+		// if you dont call equals(Geomtery) two geometries which are equal 
+		// will not be equal) we dont call super.equals()
+		
+		if (!Utilities.equals(descriptor, att.descriptor))
+			return false;
+
+		if (!Utilities.equals(id, att.id))
+			return false;
+
+		if ( value != null && att.value != null ) {
+		    //another lovley jts thing... comparing geometry collections that 
+		    // arent multi point/line/poly throws an exception, so we nee dto 
+		    // that comparison
+		    if ( att.value instanceof GeometryCollection && 
+	            !(att.value instanceof MultiPoint) && 
+	            !(att.value instanceof MultiLineString) &&
+	            !(att.value instanceof MultiPolygon) ) {
+		        
+		        if ( value instanceof GeometryCollection ) {
+		            //compare the two collections 
+		            GeometryCollection c1 = (GeometryCollection) value;
+		            GeometryCollection c2 = (GeometryCollection) att.value;
+		            
+		            if ( c1.getNumGeometries() !=  c2.getNumGeometries() ) {
+		                return false;
+		            }
+		            
+		            for ( int i = 0; i < c1.getNumGeometries(); i++ ) {
+		                Geometry g1 = c1.getGeometryN(i);
+		                Geometry g2 = c2.getGeometryN(i);
+		                
+		                if ( !g1.equals(g2) ) {
+		                    return false;
+		                }
+		            }
+		            
+		            return true;
+		        }
+		        else {
+		            return false;
+		        }
+		    }
+		   if ( !((Geometry)value).equals((Geometry)att.value)) {
+				return false;
+			}
+		}
+		else {
+		    return Utilities.deepEquals(value, this.value);    
+		}
+		
+		return true;
+	}	
+	
+	public int hashCode() {
+		int hash = descriptor.hashCode(); 
+		
+		if ( id != null ) {
+		    hash += 37 * id.hashCode();
+		}
+		
+		return hash;
+	}
+	
+	   public String toString() {
+	        StringBuffer sb = new StringBuffer(getClass().getSimpleName()).append(":");
+	        sb.append(getDescriptor().getName().getLocalPart());
+	        CoordinateReferenceSystem crs = getDescriptor().getType().getCoordinateReferenceSystem();
+	        if(!getDescriptor().getName().getLocalPart().equals(getDescriptor().getType().getName().getLocalPart()) ||
+	                id != null || crs != null){
+	            sb.append("<");
+	            sb.append(getDescriptor().getType().getName().getLocalPart());
+	            if( id != null ){
+	                sb.append( " id=");
+	                sb.append( id );
+	            }
+	            if( crs != null ){
+	                sb.append( " crs=");
+	                sb.append( crs );
+	            }
+    	        if( id != null ){
+    	            sb.append( " id=");
+    	            sb.append( id );
+    	        }
+    	        sb.append(">");
+	        }
+	        sb.append("=");
+	        sb.append(value);
+	        return sb.toString();
+	    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/IllegalAttributeException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/IllegalAttributeException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/IllegalAttributeException.java	(revision 28000)
@@ -0,0 +1,85 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature;
+
+import java.util.Map;
+
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.Name;
+
+
+/**
+ * Indicates client class has attempted to create an invalid feature.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/feature/IllegalAttributeException.java $
+ * @deprecated Please use org.opengis.feature.IllegalAttributeException
+ */
+public class IllegalAttributeException extends org.opengis.feature.IllegalAttributeException {
+    
+    private static final AttributeDescriptor NULL_ATTRIBUTE_DESCRIPTOR = new NullAttributeDescriptor();
+    
+    /**
+     * Constructor with message argument.
+     *
+     * @param message Reason for the exception being thrown
+     */
+    public IllegalAttributeException(String message) {
+        super(NULL_ATTRIBUTE_DESCRIPTOR,null,message);
+    }
+    
+    /**
+     * A descriptor for an attribute that does not exist. An ugly, ugly workaround for
+     * GEOT-2111/GEO-156.
+     */
+    private static class NullAttributeDescriptor implements AttributeDescriptor {
+
+        public int getMaxOccurs() {
+            return 0;
+        }
+
+        public int getMinOccurs() {
+            return 0;
+        }
+
+        public Name getName() {
+            return null;
+        }
+
+        public Map<Object, Object> getUserData() {
+            return null;
+        }
+
+        public boolean isNillable() {
+            return false;
+        }
+
+        public Object getDefaultValue() {
+            return null;
+        }
+
+        public String getLocalName() {
+            return null;
+        }
+
+        public AttributeType getType() {
+            return null;
+        }
+        
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/LenientFeatureFactoryImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/LenientFeatureFactoryImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/LenientFeatureFactoryImpl.java	(revision 28000)
@@ -0,0 +1,7 @@
+package org.geotools.feature;
+
+public class LenientFeatureFactoryImpl extends AbstractFeatureFactoryImpl { // NO_UCD
+    public LenientFeatureFactoryImpl() {
+        validating = false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/NameImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/NameImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/NameImpl.java	(revision 28000)
@@ -0,0 +1,158 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature;
+
+import java.io.Serializable;
+
+import org.geotools.util.Utilities;
+import org.opengis.feature.type.Name;
+
+
+/**
+ * Simple implementation of Name.
+ * <p>
+ * This class emulates QName, and is used as the implementation of both AttributeName and
+ * TypeName (so when the API settles down we should have a quick fix.
+ * <p>
+ * Its is advantageous to us to be able to:
+ * <ul>
+ * <li>Have a API in agreement with QName - considering our target audience
+ * <li>Strongly type AttributeName and TypeName separately
+ * </ul>
+ * The ISO interface move towards combining the AttributeName and Attribute classes,
+ * and TypeName and Type classes, while we understand the attractiveness of this on a
+ * UML diagram it is very helpful to keep these concepts separate when playing with
+ * a strongly typed language like java.
+ * </p>
+ * <p>
+ * It case it is not obvious this is a value object and equality is based on
+ * namespace and name.
+ * </p>
+ * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/feature/NameImpl.java $
+ */
+public class NameImpl implements org.opengis.feature.type.Name, Serializable, Comparable<NameImpl> {
+    private static final long serialVersionUID = 4564070184645559899L;
+
+    /** namespace / scope */
+    protected String namespace;
+
+    /** local part */
+    protected String local;
+
+    private String separator;
+
+    /**
+     * Constructs an instance with the local part set. Namespace / scope is
+     * set to null.
+     *
+     * @param local The local part of the name.
+     */
+    public NameImpl(String local) {
+        this(null, local);
+    }
+
+    /**
+     * Constructs an instance with the local part and namespace set.
+     *
+     * @param namespace The namespace or scope of the name.
+     * @param local The local part of the name.
+     *
+     */
+    public NameImpl(String namespace, String local) {
+        this( namespace, ":", local );
+    }
+    /**
+     * Constructs an instance with the local part and namespace set.
+     *
+     * @param namespace The namespace or scope of the name.
+     * @param local The local part of the name.
+     *
+     */
+    public NameImpl(String namespace, String separator, String local) {
+        this.namespace = namespace;
+        this.separator = separator;
+        this.local = local;
+    }
+
+	public String getSeparator() {
+		return separator;
+	}
+    public String getNamespaceURI() {
+        return namespace;
+    }
+
+    public String getLocalPart() {
+        return local;
+    }
+
+    public String getURI() {
+        if ((namespace == null) && (local == null)) {
+            return null;
+        }
+        if (namespace == null) {
+            return local;
+        }
+        if (local == null) {
+            return namespace;
+        }
+        return new StringBuffer(namespace).append(separator).append(local).toString();
+    }
+
+    /**
+     * Returns a hash code value for this operand.
+     */
+    @Override
+    public int hashCode() {
+    	return (namespace== null ? 0 : namespace.hashCode()) +
+    	        37*(local== null ? 0 : local.hashCode());
+    }
+
+    /**
+     * value object with equality based on name and namespace.
+     */
+    public boolean equals(Object obj) {
+        if(obj == this)
+            return true;
+        
+        if (obj instanceof Name) {
+            NameImpl other = (NameImpl) obj;            
+            if(!Utilities.equals(this.namespace, other.getNamespaceURI())){
+            	return false;
+            }
+            if(!Utilities.equals(this.local, other.getLocalPart())){
+                return false;                
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /** name or namespace:name */
+    public String toString() {
+        return getURI();
+    }
+
+    public int compareTo(NameImpl other) {
+        if( other == null ){
+            return 1; // we are greater than null!
+        }
+        return getURI().compareTo(other.getURI());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/PropertyImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/PropertyImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/PropertyImpl.java	(revision 28000)
@@ -0,0 +1,125 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.geotools.util.Utilities;
+import org.opengis.feature.Property;
+import org.opengis.feature.type.Name;
+import org.opengis.feature.type.PropertyDescriptor;
+import org.opengis.feature.type.PropertyType;
+
+/**
+ * Implementation of Property.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/PropertyImpl.java $
+ */
+public abstract class PropertyImpl implements Property {
+    /**
+     * content of the property
+     */
+    protected Object value;
+    /**
+     * descriptor of the property
+     */
+    protected PropertyDescriptor descriptor;
+    /**
+     * user data
+     */
+    protected final Map<Object,Object> userData;
+
+    protected PropertyImpl( Object value, PropertyDescriptor descriptor ) {
+        this.value = value;
+        this.descriptor = descriptor;
+        userData = new HashMap<Object, Object>();
+        
+        if ( descriptor == null ) {
+            throw new NullPointerException("descriptor");
+        }
+    }
+    
+    public Object getValue() {
+        return value;
+    }
+    
+    public void setValue(Object value) {
+        this.value = value;
+    }
+    
+    public PropertyDescriptor getDescriptor() {
+        return descriptor;
+    }
+
+    public Name getName() {
+        return getDescriptor().getName();
+    }
+
+    public PropertyType getType() {
+        return getDescriptor().getType();
+    }
+
+    public boolean isNillable() {
+        return getDescriptor().isNillable();
+    }
+    
+    public Map<Object, Object> getUserData() {
+        return userData;
+    }
+    
+    public boolean equals(Object obj) {
+        if ( this == obj ) {
+            return true;
+        }
+        
+        if (!(obj instanceof PropertyImpl)) {
+            return false;
+        }
+
+        PropertyImpl other = (PropertyImpl) obj;
+
+        if (!Utilities.equals(descriptor, other.descriptor))
+            return false;
+
+        if (!Utilities.deepEquals(value, other.value))
+            return false;   
+    
+        return true;
+    }
+    
+    public int hashCode() {
+        return 37 * descriptor.hashCode()
+            + (37 * (value == null ? 0 : value.hashCode()));
+    }
+    
+    public String toString() {
+        StringBuffer sb = new StringBuffer(getClass().getSimpleName()).append(":");
+        sb.append(getDescriptor().getName().getLocalPart());
+        sb.append("<");
+        sb.append(getDescriptor().getType().getName().getLocalPart());
+        sb.append(">=");
+        sb.append(value);
+
+        return sb.toString();
+    }
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/SchemaException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/SchemaException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/SchemaException.java	(revision 28000)
@@ -0,0 +1,39 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature;
+
+
+/**
+ * Indicates client class has attempted to create an invalid schema.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/feature/SchemaException.java $
+ */
+public class SchemaException extends Exception {
+    /**
+     *
+     */
+    private static final long serialVersionUID = 5453903672192802976L;
+
+    /**
+     * Constructor with message argument.
+     *
+     * @param message Reason for the exception being thrown
+     */
+    public SchemaException(String message) {
+        super(message);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/ValidatingFeatureFactoryImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/ValidatingFeatureFactoryImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/ValidatingFeatureFactoryImpl.java	(revision 28000)
@@ -0,0 +1,36 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature;
+
+
+/**
+ * Factory for creating instances of the Attribute family of classes.
+ * 
+ * @author Andrea Aime
+ * 
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/ValidatingFeatureFactoryImpl.java $
+ * @version $Id: ValidatingFeatureFactoryImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public class ValidatingFeatureFactoryImpl extends AbstractFeatureFactoryImpl { // NO_UCD
+    
+    public ValidatingFeatureFactoryImpl() {
+        validating = true;
+    }
+ }
+
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/AbstractFeatureCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/AbstractFeatureCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/AbstractFeatureCollection.java	(revision 28000)
@@ -0,0 +1,554 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.collection;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.util.NullProgressListener;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.filter.sort.SortBy;
+
+/**
+ * Implement a feature collection just based on provision of iterator.
+ * 
+ * @author Jody Garnett (Refractions Research Inc)
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/collection/AbstractFeatureCollection.java $
+ */
+public abstract class AbstractFeatureCollection implements SimpleFeatureCollection {
+
+    /** 
+     * id used when serialized to gml
+     */
+    protected String id;
+    protected SimpleFeatureType schema;
+
+    protected AbstractFeatureCollection(SimpleFeatureType memberType) {
+        this.id = id == null ? "featureCollection" : id;
+        this.schema = memberType;
+    }
+
+    //
+    // SimpleFeatureCollection - Feature Access
+    // 
+    @SuppressWarnings("unchecked")
+	public SimpleFeatureIterator features() {
+        SimpleFeatureIterator iter = new DelegateSimpleFeatureIterator( this, openIterator() );
+        getOpenIterators().add( iter );
+        return iter;
+    }
+    /**
+     * Clean up after any resources associated with this iteartor in a manner similar to JDO collections.
+     * </p>
+     * Example (safe) use:<pre><code>
+     * Iterator iterator = collection.iterator();
+     * try {
+     *     for( Iterator i=collection.iterator(); i.hasNext();){
+     *          Feature feature = (Feature) i.hasNext();
+     *          System.out.println( feature.getID() );
+     *     }
+     * }
+     * finally {
+     *     collection.close( iterator );
+     * }
+     * </code></pre>
+     * </p>
+     * @param close
+     */
+    @SuppressWarnings("unchecked")
+	final public void close( Iterator close ){
+        if( close == null ) return;
+        try {
+            closeIterator( close );
+        }
+        catch ( Throwable e ){
+            // TODO Log e = ln
+        }
+        finally {
+            open.remove( close );
+        }       
+    }
+    
+    public void close(FeatureIterator<SimpleFeature> close) {
+        if( close != null ){
+            close.close();
+        }
+    }
+    
+    /**
+     * Open a resource based Iterator, we will call close( iterator ).
+     * <p>
+     * Please subclass to provide your own iterator for the the ResourceCollection,
+     * note <code>iterator()</code> is implemented to call <code>open()</code>
+     * and track the results in for later <code>purge()</code>.
+     * 
+     * @return Iterator based on resource use
+     */
+    abstract protected Iterator<SimpleFeature> openIterator();
+    
+    /**
+     * Please override to cleanup after your own iterators, and
+     * any used resources.
+     * <p>
+     * As an example if the iterator was working off a File then
+     * the inputstream should be closed.
+     * </p>
+     * <p>
+     * Subclass must call super.close( close ) to allow the list
+     * of open iterators to be adjusted.
+     * </p>
+     * 
+     * @param close Iterator, will not be <code>null</code>
+     */
+    abstract protected void closeIterator( Iterator<SimpleFeature> close );
+    
+    /**
+     * Close any outstanding resources released by this resources.
+     * <p>
+     * This method should be used with great caution, it is however available
+     * to allow the use of the ResourceCollection with algorthims that are
+     * unaware of the need to close iterators after use.
+     * </p>
+     * <p>
+     * Example of using a normal Collections utility method:<pre><code>
+     * Collections.sort( collection );
+     * collection.purge(); 
+     * </code></pre>
+     */
+    @SuppressWarnings("unchecked")
+	public void purge(){        
+        for( Iterator i = open.iterator(); i.hasNext(); ){
+            Object resource = i.next();
+            if( resource instanceof Iterator ){
+                Iterator resourceIterator = (Iterator) resource;
+                try {
+                    closeIterator( resourceIterator );
+                }
+                catch( Throwable e){
+                    // TODO: Log e = ln
+                }
+                finally {
+                    i.remove();
+                }
+            }
+        }
+    }
+    
+    /**
+     * Returns the number of elements in this collection.
+     * 
+     * @return Number of items, or Interger.MAX_VALUE
+     */
+    public abstract int size();
+    /**
+     * Implement to support modification.
+     * 
+     * @param o element whose presence in this collection is to be ensured.
+     * @return <tt>true</tt> if the collection changed as a result of the call.
+     * 
+     * @throws UnsupportedOperationException if the <tt>add</tt> method is not
+     *        supported by this collection.
+     * 
+     * @throws NullPointerException if this collection does not permit
+     *        <tt>null</tt> elements, and the specified element is
+     *        <tt>null</tt>.
+     * 
+     * @throws ClassCastException if the class of the specified element
+     *        prevents it from being added to this collection.
+     * 
+     * @throws IllegalArgumentException if some aspect of this element
+     *         prevents it from being added to this collection.
+     */
+    public boolean add(SimpleFeature o) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Adds all of the elements in the specified collection to this collection
+     * (optional operation).
+     *
+     * @param c collection whose elements are to be added to this collection.
+     * @return <tt>true</tt> if this collection changed as a result of the
+     *         call.
+     * @throws UnsupportedOperationException if this collection does not
+     *         support the <tt>addAll</tt> method.
+     * @throws NullPointerException if the specified collection is null.
+     * 
+     * @see #add(Object)
+     */
+    @SuppressWarnings("unchecked")
+	public boolean addAll(Collection<? extends SimpleFeature> c) {
+        boolean modified = false;
+        Iterator<? extends SimpleFeature> e = c.iterator();
+        try {
+            while (e.hasNext()) {
+                if (add(e.next()))
+                modified = true;
+            }
+        }
+        finally {
+            if( c instanceof FeatureCollection){
+                FeatureCollection other = (FeatureCollection) c;
+                other.close( e );
+            }
+        }
+        return modified;
+    } 
+
+    public boolean addAll(FeatureCollection<? extends SimpleFeatureType,? extends SimpleFeature> c) {
+        boolean modified = false;
+        FeatureIterator<? extends SimpleFeature> e = c.features();
+        try {
+            while (e.hasNext()) {
+                if (add(e.next()))
+                modified = true;
+            }
+        }
+        finally {
+            e.close();
+        }
+        return modified;
+    }
+    
+    /**
+     * Removes all of the elements from this collection (optional operation).
+     * 
+     * @throws UnsupportedOperationException if the <tt>clear</tt> method is
+     *        not supported by this collection.
+     */
+    public void clear() {
+        Iterator<SimpleFeature> e = iterator();
+        try {
+            while (e.hasNext()) {
+                e.next();
+                e.remove();
+            }
+        }finally {
+            close( e );            
+        }
+    }
+
+    /**
+     * Returns <tt>true</tt> if this collection contains the specified
+     * element.
+     * <tt></tt>.<p>
+     *
+     * This implementation iterates over the elements in the collection,
+     * checking each element in turn for equality with the specified element.
+     *
+     * @param o object to be checked for containment in this collection.
+     * @return <tt>true</tt> if this collection contains the specified element.
+     */
+    public boolean contains(Object o) {
+        Iterator<SimpleFeature> e = null;
+        try {
+            e = iterator();
+            if (o==null) {
+                while (e.hasNext())
+                if (e.next()==null)
+                    return true;
+            } else {
+                while (e.hasNext())
+                if (o.equals(e.next()))
+                    return true;
+            }
+            return false;
+        }
+        finally {
+            close( e );
+        }
+    }
+
+    /**
+     * Returns <tt>true</tt> if this collection contains all of the elements
+     * in the specified collection. <p>
+     * 
+     * @param c collection to be checked for containment in this collection.
+     * @return <tt>true</tt> if this collection contains all of the elements
+     *         in the specified collection.
+     * @throws NullPointerException if the specified collection is null.
+     * 
+     * @see #contains(Object)
+     */
+    public boolean containsAll(Collection<?> c) {
+        Iterator<?> e = c.iterator();
+        try {
+            while (e.hasNext())
+                if(!contains(e.next()))
+                return false;
+            return true;
+        } finally {
+            close( e );
+        }
+    }
+    //
+    // Contents
+    //
+    //
+    /** Set of open resource iterators */
+    @SuppressWarnings("unchecked")
+	protected final Set open = new HashSet<Iterator<SimpleFeature>>();
+
+    /**
+     * Returns the set of open iterators.
+     * <p>
+     * Contents are a mix of Iterator<SimpleFeature> and SimpleFeatureIterator
+     */
+    @SuppressWarnings("unchecked")
+	final public Set getOpenIterators() {
+        return open;
+    }
+    
+    /**
+     * Please implement!
+     * <p>
+     * Note: If you return a ResourceIterator, the default implemntation of close( Iterator )
+     * will know what to do.
+     * 
+     */
+    @SuppressWarnings("unchecked")
+	final public Iterator<SimpleFeature> iterator(){
+    	Iterator<SimpleFeature> iterator = openIterator();
+    	getOpenIterators().add( iterator );
+        return iterator;
+    }
+    
+    /**
+     * @return <tt>true</tt> if this collection contains no elements.
+     */
+    public boolean isEmpty() {
+        Iterator<SimpleFeature> iterator = iterator();
+        try {
+            return !iterator.hasNext();
+        }
+        finally {
+            close( iterator );
+        }
+    }
+
+    /**
+     * Removes a single instance of the specified element from this
+     * collection, if it is present (optional operation). 
+     * 
+     * @param o element to be removed from this collection, if present.
+     * @return <tt>true</tt> if the collection contained the specified
+     *         element.
+     * @throws UnsupportedOperationException if the <tt>remove</tt> method is
+     *        not supported by this collection.
+     */
+    public boolean remove(Object o) {
+        Iterator<SimpleFeature> e = iterator();
+        try {
+            if (o==null) {
+                while (e.hasNext()) {
+                if (e.next()==null) {
+                    e.remove();
+                    return true;
+                }
+                }
+            } else {
+                while (e.hasNext()) {
+                if (o.equals(e.next())) {
+                    e.remove();
+                    return true;
+                }
+            }
+        }
+        return false;
+        }
+        finally {
+            close( e );
+        }
+    }
+
+    /**
+     * Removes from this collection all of its elements that are contained in
+     * the specified collection (optional operation). <p>
+     *
+     * @param c elements to be removed from this collection.
+     * @return <tt>true</tt> if this collection changed as a result of the
+     *         call.
+     * @throws UnsupportedOperationException if the <tt>removeAll</tt> method
+     *         is not supported by this collection.
+     * @throws NullPointerException if the specified collection is null.
+     *
+     * @see #remove(Object)
+     * @see #contains(Object)
+     */
+    @SuppressWarnings("unchecked")
+	final public boolean removeAll(Collection<?> c) {
+        boolean modified = false;
+        Iterator e = iterator();
+        try {
+            while (e.hasNext()) {
+                if (c.contains(e.next())) {
+                e.remove();
+                modified = true;
+                }
+            }
+            return modified;
+        }
+        finally {
+            if( c instanceof FeatureCollection){
+                FeatureCollection other = (FeatureCollection) c;
+                other.close( e );
+            }
+        }
+    }
+
+    /**
+     * Retains only the elements in this collection that are contained in the
+     * specified collection (optional operation).
+     *
+     * @param c elements to be retained in this collection.
+     * @return <tt>true</tt> if this collection changed as a result of the
+     *         call.
+     * @throws UnsupportedOperationException if the <tt>retainAll</tt> method
+     *         is not supported by this Collection.
+     * @throws NullPointerException if the specified collection is null.
+     *
+     * @see #remove(Object)
+     * @see #contains(Object)
+     */
+    @SuppressWarnings("unchecked")
+    final public boolean retainAll(Collection<?> c) {
+        boolean modified = false;
+        Iterator e = iterator();
+        try {
+            while (e.hasNext()) {
+                if (!c.contains(e.next())) {
+                e.remove();
+                modified = true;
+                }
+            }
+            return modified;
+        }
+        finally {
+            if( c instanceof FeatureCollection){
+                FeatureCollection other = (FeatureCollection) c;
+                other.close( e );
+            }
+        }
+    }
+
+    
+    /**
+     * Array of all the elements.
+     * 
+     * @return an array containing all of the elements in this collection.
+     */
+    public Object[] toArray() {
+        Object[] result = new Object[size()];
+        Iterator<SimpleFeature> e = null;
+        try {
+            e = iterator();
+            for (int i=0; e.hasNext(); i++)
+                result[i] = e.next();
+            return result;
+        } finally {
+            close( e );
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T[] toArray(T[] a) { // NO_UCD
+        int size = size();
+        if (a.length < size){
+            a = (T[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
+         }
+        Iterator<SimpleFeature> it = iterator();
+        try {
+            
+            Object[] result = a;
+            for (int i=0; i<size; i++)
+                result[i] = it.next();
+            if (a.length > size)
+            a[size] = null;
+            return a;
+        }
+        finally {
+            close( it );
+        }
+    }
+
+	public void accepts(org.opengis.feature.FeatureVisitor visitor, org.opengis.util.ProgressListener progress) {
+    	Iterator<SimpleFeature> iterator = null;
+    	if( progress == null ) progress = new NullProgressListener();
+        try{
+            float size = size();
+            float position = 0;            
+            progress.started();
+            for( iterator = iterator(); !progress.isCanceled() && iterator.hasNext();){
+                if (size > 0) progress.progress( position++/size );
+                try {
+                    SimpleFeature feature = iterator.next();
+                    visitor.visit(feature);
+                }
+                catch( Exception erp ){
+                    progress.exceptionOccurred( erp );
+                }
+            }            
+        }
+        finally {
+            progress.complete();            
+            close( iterator );
+        }
+    }
+    
+    //
+    // Feature Collections API
+    //
+    public SimpleFeatureCollection subList( Filter filter ) {
+        return new SubFeatureList(this, filter );
+    }
+    
+    public SimpleFeatureCollection subCollection( Filter filter ) {
+        if( filter == Filter.INCLUDE ){
+            return this;
+        }        
+        return new SubFeatureCollection( this, filter );
+    }
+
+    public SimpleFeatureCollection sort( SortBy order ) {
+        return new SubFeatureList(this, order );
+    }
+
+    public String getID() {
+    	return id;
+    }
+
+    public SimpleFeatureType getSchema() {
+    	return schema;
+    }
+
+    /**
+     * Subclasses need to override this.
+     */
+    public abstract ReferencedEnvelope getBounds();
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/DecoratingSimpleFeatureCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/DecoratingSimpleFeatureCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/DecoratingSimpleFeatureCollection.java	(revision 28000)
@@ -0,0 +1,176 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.collection;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+
+/**
+ * A FeatureCollection which completley delegates to another FeatureCollection.
+ * <p>
+ * This class should be subclasses by classes which must somehow decorate 
+ * another SimpleFeatureCollection and override the relevant methods. 
+ * </p>
+ * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
+ * @since 2.5
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/build/maven/javadoc/../../../modules/library/main/src/main/java/org/geotools/feature/collection/DecoratingSimpleFeatureCollection.java $
+ */
+public class DecoratingSimpleFeatureCollection implements SimpleFeatureCollection {
+
+    /**
+     * the delegate
+     */
+    protected SimpleFeatureCollection delegate;
+
+    protected DecoratingSimpleFeatureCollection(SimpleFeatureCollection delegate) {
+        this.delegate = delegate;
+    }
+
+    public void accepts(org.opengis.feature.FeatureVisitor visitor,
+            org.opengis.util.ProgressListener progress) {
+        SimpleFeatureIterator it = features();
+
+        try {
+            Exception exception = null;
+            while (it.hasNext()) {
+                try {
+                    visitor.visit(it.next());
+                } catch (Exception e) {
+                    if (exception != null)
+                        exception = e;
+                }
+            }
+
+            if (exception != null) {
+                if (exception instanceof RuntimeException) {
+                    throw (RuntimeException) exception;
+                } else {
+                    throw new RuntimeException(exception);
+                }
+            }
+        } finally {
+            close(it);
+        }
+    }
+    
+    public boolean add(SimpleFeature o) {
+        return delegate.add(o);
+    }
+
+    public boolean addAll(Collection c) {
+        return delegate.addAll(c);
+    }
+
+    public boolean addAll(FeatureCollection c) {
+        return delegate.addAll(c);
+    }
+    
+    public void clear() {
+        delegate.clear();
+    }
+
+    public void close(FeatureIterator<SimpleFeature> close) {
+        delegate.close(close);
+    }
+
+    public void close(Iterator<SimpleFeature> close) {
+        delegate.close(close);
+    }
+
+    public boolean contains(Object o) {
+        return delegate.contains(o);
+    }
+
+    public boolean containsAll(Collection c) {
+        return delegate.containsAll(c);
+    }
+
+    public boolean equals(Object o) {
+        return delegate.equals(o);
+    }
+
+    public SimpleFeatureIterator features() {
+        return delegate.features();
+    }
+
+    public ReferencedEnvelope getBounds() {
+        return delegate.getBounds();
+    }
+
+    public SimpleFeatureType getSchema() {
+        return delegate.getSchema();
+    }
+
+    public int hashCode() {
+        return delegate.hashCode();
+    }
+
+    public boolean isEmpty() {
+        return delegate.isEmpty();
+    }
+
+    public Iterator iterator() {
+        return delegate.iterator();
+    }
+
+    public void purge() {
+        delegate.purge();
+    }
+
+    public boolean remove(Object o) {
+        return delegate.remove(o);
+    }
+
+    public boolean removeAll(Collection c) {
+        return delegate.removeAll(c);
+    }
+
+    public boolean retainAll(Collection c) {
+        return delegate.retainAll(c);
+    }
+
+    public int size() {
+        return delegate.size();
+    }
+
+    public SimpleFeatureCollection subCollection(Filter filter) {
+        return delegate.subCollection(filter);
+    }
+
+    public Object[] toArray() {
+        return delegate.toArray();
+    }
+
+    public Object[] toArray(Object[] a) {
+        return delegate.toArray(a);
+    }
+	public String getID() {
+		return delegate.getID();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/DelegateFeatureIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/DelegateFeatureIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/DelegateFeatureIterator.java	(revision 28000)
@@ -0,0 +1,66 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.collection;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureIterator;
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+
+/**
+ * A feature iterator that completely delegates to a normal
+ * Iterator, simply allowing Java 1.4 code to escape the caste (sic)
+ * system.
+ * <p>
+ * This implementation is not suitable for use with collections
+ * that make use of system resources. As an alterantive please
+ * see ResourceFetaureIterator.
+ * </p>
+ * @author Jody Garnett, Refractions Research, Inc.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/collection/DelegateFeatureIterator.java $
+ */
+public class DelegateFeatureIterator<F extends Feature> implements FeatureIterator<F> {
+	Iterator<F> delegate;
+	private FeatureCollection<? extends FeatureType, F> collection;
+	/**
+	 * Wrap the provided iterator up as a FeatureIterator.
+	 * 
+	 * @param iterator Iterator to be used as a delegate.
+	 */
+	public DelegateFeatureIterator( FeatureCollection<? extends FeatureType, F> collection, Iterator<F> iterator ){
+		delegate = iterator;
+		this.collection=collection;
+	}
+	public boolean hasNext() {
+		return delegate != null && delegate.hasNext();
+	}
+	public F next() throws NoSuchElementException {
+		if( delegate == null ) throw new NoSuchElementException();
+		return  delegate.next();
+	}
+	public void close() {
+		if( collection!=null && delegate!=null)
+			collection.close(delegate);
+		collection =null;
+		delegate = null;
+		
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/DelegateSimpleFeatureIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/DelegateSimpleFeatureIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/DelegateSimpleFeatureIterator.java	(revision 28000)
@@ -0,0 +1,48 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.collection;
+
+import java.util.Iterator;
+
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.feature.FeatureCollection;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+/**
+ * A feature iterator that completely delegates to a normal
+ * Iterator, simply allowing Java 1.4 code to escape the caste (sic)
+ * system.
+ * <p>
+ * This implementation is not suitable for use with collections
+ * that make use of system resources. As an alterantive please
+ * see ResourceFetaureIterator.
+ * </p>
+ * @author Jody Garnett, Refractions Research, Inc.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/build/maven/javadoc/../../../modules/library/main/src/main/java/org/geotools/feature/collection/DelegateSimpleFeatureIterator.java $
+ */
+public class DelegateSimpleFeatureIterator extends DelegateFeatureIterator<SimpleFeature> implements SimpleFeatureIterator {
+	/**
+	 * Wrap the provided iterator up as a FeatureIterator.
+	 * 
+	 * @param iterator Iterator to be used as a delegate.
+	 */
+	public DelegateSimpleFeatureIterator( FeatureCollection<SimpleFeatureType,SimpleFeature> collection, Iterator<SimpleFeature> iterator ){
+		super( collection, iterator );
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/FilteredIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/FilteredIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/FilteredIterator.java	(revision 28000)
@@ -0,0 +1,101 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.collection;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.geotools.feature.FeatureCollection;
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.FeatureType;
+import org.opengis.filter.Filter;
+
+/**
+ * Provides an implementation of Iterator that will filter
+ * contents using the provided filter.
+ * <p>
+ * This is a *Generic* iterator not limited to Feature, this
+ * will become more interesting as Filter is able to evaulate
+ * itself with more things then just Features.
+ * </p>
+ * <p>
+ * This also explains the use of Collection (where you may
+ * have expected a FeatureCollection). However
+ * <code>FeatureCollectoin.close( iterator )</code> will be
+ * called on the internal delgate.
+ * </p>
+ *  
+ * @author Jody Garnett, Refractions Research, Inc.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/collection/FilteredIterator.java $
+ */
+public class FilteredIterator<F extends Feature> implements Iterator<F> {
+	/** Used to close the delgate, or null */
+	private FeatureCollection<? extends FeatureType, F> collection;
+	private Iterator<F> delegate;
+	private Filter filter;
+
+	private F next;
+	
+	public FilteredIterator(FeatureCollection<? extends FeatureType, F> collection, Filter filter) {
+		this.collection = collection;
+		this.delegate = collection.iterator();
+		this.filter = filter;
+		next = getNext();
+	}
+	
+	/** Package protected, please use SubFeatureCollection.close( iterator ) */
+	void close(){
+		if( collection != null ){
+			collection.close( delegate );
+		}
+		collection = null;
+		delegate = null;
+		filter = null;
+		next = null;
+	}
+	
+	private F getNext() {
+		F item = null;
+		while (delegate.hasNext()) {
+			item = delegate.next();
+			if (filter.evaluate( item )){
+				return item;
+			}
+		}
+		return null;
+	}
+
+	public boolean hasNext() {
+		return next != null;
+	}
+
+	public F next() {
+		if(next == null){
+			throw new NoSuchElementException();
+		}
+		F current = next;
+		next = getNext();
+		return current;
+	}
+
+	public void remove() {
+		if( delegate == null ) throw new IllegalStateException();
+		
+	    delegate.remove();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/FilteringSimpleFeatureCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/FilteringSimpleFeatureCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/FilteringSimpleFeatureCollection.java	(revision 28000)
@@ -0,0 +1,150 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.collection;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.geotools.data.DataUtilities;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.data.store.FilteringIterator;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.filter.Filter;
+
+/**
+ * Decorates a feature collection with one that filters content.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/build/maven/javadoc/../../../modules/library/main/src/main/java/org/geotools/feature/collection/FilteringSimpleFeatureCollection.java $
+ */
+public class FilteringSimpleFeatureCollection extends DecoratingSimpleFeatureCollection  {
+
+	/**
+	 * The original feature collection.
+	 */
+	SimpleFeatureCollection delegate;
+	/**
+	 * the filter
+	 */
+	Filter filter;
+	
+	public FilteringSimpleFeatureCollection( SimpleFeatureCollection delegate, Filter filter ) {
+		super(delegate);
+		this.delegate = delegate;
+		this.filter = filter;
+	}
+	
+	public SimpleFeatureIterator features() {
+		return new DelegateSimpleFeatureIterator( this, iterator() );
+	}
+
+	public Iterator<SimpleFeature> iterator() {
+		return new FilteringIterator<SimpleFeature>( delegate.iterator(), filter );
+	}
+	
+	public void close(Iterator<SimpleFeature> close) {
+		FilteringIterator<SimpleFeature> filtering = (FilteringIterator<SimpleFeature>) close;
+		delegate.close( filtering.getDelegate() );
+	}
+
+	public SimpleFeatureCollection subCollection(Filter filter) {
+		throw new UnsupportedOperationException();
+	}
+
+	public int size() {
+		int count = 0;
+		Iterator<SimpleFeature> i = iterator();
+		try {
+			while( i.hasNext() ) {
+				count++; i.next();
+			}
+			
+			return count;
+		}
+		finally {
+			close( i );
+		}
+	}
+
+	public boolean isEmpty() {
+		return size() == 0;
+	}
+
+	public Object[] toArray() {
+		return toArray( new Object[ size() ] );
+	}
+
+	public Object[] toArray(Object[] a) {
+		List list = new ArrayList();
+		Iterator i = iterator();
+		try {
+			while( i.hasNext() ) {
+				list.add( i.next() );
+			}
+			
+			return list.toArray( a );
+		}
+		finally {
+			close( i );
+		}
+	}
+	
+	public boolean add(SimpleFeature o) {
+		if ( !filter.evaluate( o ) ) {
+			return false;
+		}
+		
+		return delegate.add( o );
+	}
+
+	public boolean contains(Object o) {
+		return delegate.contains( o ) && filter.evaluate( o );
+	}
+
+	public boolean addAll(Collection c) {
+		boolean changed = false;
+		
+		for ( Iterator<SimpleFeature> i = c.iterator(); i.hasNext(); ) {
+			changed = changed | add( i.next() );
+		}
+		
+		return changed;
+	}
+
+	public boolean containsAll(Collection c) {
+		for ( Iterator i = c.iterator(); i.hasNext(); ) {
+			if ( !contains( i.next() ) ) {
+				return false;
+			}
+		}
+		
+		return true;
+	}
+
+	public ReferencedEnvelope getBounds() {
+		//calculate manually
+		return ReferencedEnvelope.reference( DataUtilities.bounds( this ) );
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/MaxSimpleFeatureCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/MaxSimpleFeatureCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/MaxSimpleFeatureCollection.java	(revision 28000)
@@ -0,0 +1,138 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.collection;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.geotools.data.DataUtilities;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.data.store.MaxFeaturesIterator;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.filter.Filter;
+
+/**
+ * SimpleFeatureCollection wrapper which limits the number of features returned.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/build/maven/javadoc/../../../modules/library/main/src/main/java/org/geotools/feature/collection/MaxSimpleFeatureCollection.java $
+ */
+public class MaxSimpleFeatureCollection extends
+        DecoratingSimpleFeatureCollection {
+
+	SimpleFeatureCollection delegate;
+	long start;
+	long max;
+	
+    public MaxSimpleFeatureCollection(SimpleFeatureCollection delegate, long start, long max) {
+        super(delegate);
+        this.delegate = delegate;
+        this.start = start;
+        this.max = max;
+    }
+		
+	public SimpleFeatureIterator features() {
+		return new DelegateSimpleFeatureIterator( this, iterator() );
+	}
+
+	public Iterator<SimpleFeature> iterator() {
+		return new MaxFeaturesIterator<SimpleFeature>( delegate.iterator(), start, max );
+	}
+	
+	public void close(Iterator<SimpleFeature> close) {
+		Iterator<SimpleFeature> iterator = ((MaxFeaturesIterator<SimpleFeature>)close).getDelegate();
+		delegate.close( iterator );
+	}
+
+	public SimpleFeatureCollection subCollection(Filter filter) {
+		throw new UnsupportedOperationException();
+	}
+
+	public int size() {
+		int size = delegate.size();
+		if(size < start) {
+		    return 0;
+		} else {
+		    return (int) Math.min( size - start, max );
+		}
+        
+	}
+
+	public boolean isEmpty() {
+		return delegate.isEmpty() || max == 0;
+	}
+
+	public Object[] toArray() {
+		return toArray( new Object[ size() ] );
+	}
+
+	public Object[] toArray(Object[] a) {
+		List list = new ArrayList();
+		Iterator i = iterator();
+		try {
+			while( i.hasNext() ) {
+				list.add( i.next() );
+			}
+			
+			return list.toArray( a );
+		}
+		finally {
+			close( i );
+		}
+	}
+	
+	public boolean add(SimpleFeature o) {
+		long size = delegate.size();
+		if ( size < max ) {
+			return delegate.add( o );	
+		}
+		
+		return false;
+	}
+
+	public boolean addAll(Collection c) {
+		boolean changed = false;
+		
+		for ( Iterator<SimpleFeature> i = c.iterator(); i.hasNext(); ) {
+			changed = changed | add( i.next() );
+		}
+		
+		return changed;
+	}
+
+	public boolean containsAll(Collection c) {
+		for ( Iterator i = c.iterator(); i.hasNext(); ) {
+			if ( !contains( i.next() ) ) {
+				return false;
+			}
+		}
+		
+		return true;
+	}
+
+	public ReferencedEnvelope getBounds() {
+		//calculate manually
+		return ReferencedEnvelope.reference( DataUtilities.bounds( this ) );
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/RandomFeatureAccess.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/RandomFeatureAccess.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/RandomFeatureAccess.java	(revision 28000)
@@ -0,0 +1,55 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.collection;
+
+import java.util.NoSuchElementException;
+
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.opengis.feature.simple.SimpleFeature;
+
+
+/**
+ * Access Feature content using Feature "Id".
+ * <p>
+ * Many SimpleFeatureCollection classes will make use of this
+ * API to avoid unnecessary caching of content. Supporting
+ * this interface will allow SubCollections to occur based
+ * on FeatureIds, with a suitable improvement in memory
+ * consumption.
+ * </p>
+ * <p>
+ * For an addition improvement in memory comsumption SubCollections
+ * may use of a sparse reprsentation where only (beginId,endId] ranges
+ * are kept in memory.
+ * </p>
+ * @author Jody Garnett, Refractions Research Inc.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/feature/collection/RandomFeatureAccess.java $
+ */
+public interface RandomFeatureAccess extends SimpleFeatureCollection {
+    /**
+     * Access Feature content by feature id.
+     *
+     * @param id
+     * @return Feature with the indicated or id
+     * @throws NoSuchElementException if a Feature with the indicated id is not present
+     */
+    public SimpleFeature getFeatureMember(String id) throws NoSuchElementException;
+
+    /** Optional Method */
+    public SimpleFeature removeFeatureMember(String id);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/SubFeatureCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/SubFeatureCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/SubFeatureCollection.java	(revision 28000)
@@ -0,0 +1,202 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.collection;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.geotools.data.DataUtilities;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.feature.visitor.BoundsVisitor;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.util.NullProgressListener;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory;
+import org.opengis.filter.sort.SortBy;
+
+/**
+ * Used as a reasonable default implementation for subCollection.
+ * <p>
+ * Note: to implementors, this is not optimal, please do your own
+ * thing - your users will thank you.
+ * </p>
+ * 
+ * @author Jody Garnett, Refractions Research, Inc.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/collection/SubFeatureCollection.java $
+ */
+public class SubFeatureCollection extends AbstractFeatureCollection {
+    
+    /** Filter */
+    protected Filter filter;
+    
+    /** Original Collection */
+	protected SimpleFeatureCollection collection;
+	
+    protected FilterFactory ff = CommonFactoryFinder.getFilterFactory( null );
+     
+	public SubFeatureCollection(SimpleFeatureCollection collection, Filter subfilter ){
+	    super( collection.getSchema() );	    
+		if (subfilter == null ) subfilter = Filter.INCLUDE;
+		if (subfilter.equals(Filter.EXCLUDE)) {
+			throw new IllegalArgumentException("A subcollection with Filter.EXCLUDE would be empty");
+		}		
+        if( collection instanceof SubFeatureCollection){
+			SubFeatureCollection filtered = (SubFeatureCollection) collection;
+			if( subfilter.equals(Filter.INCLUDE)){
+                this.collection = filtered.collection;
+			    this.filter = filtered.filter();
+			}
+			else {
+			    this.collection = filtered.collection;	            			    
+			    this.filter = ff.and( filtered.filter(), subfilter );
+			}
+		} else {
+			this.collection = collection;
+			this.filter = subfilter;
+		}
+    }
+	
+	public Iterator openIterator() {
+		return new FilteredIterator<SimpleFeature>( collection, filter() );
+	}
+
+	public void closeIterator(Iterator iterator) {
+		if( iterator == null ) return;
+		
+		if( iterator instanceof FilteredIterator){
+			FilteredIterator filtered = (FilteredIterator) iterator;			
+			filtered.close();
+		}
+	}
+    		
+	public int size() {
+		int count = 0;
+		Iterator i = null;		
+		try {
+			for( i = iterator(); i.hasNext(); count++) i.next();
+		}
+		finally {
+			close( i );
+		}
+		return count;
+	}
+    
+	protected Filter filter(){
+	    if( filter == null ){
+            filter = createFilter();
+        }
+        return filter;
+    }
+	
+    /** Override to implement subsetting */
+    protected Filter createFilter(){
+        return Filter.INCLUDE;
+    }
+    
+	public SimpleFeatureIterator features() {
+		return new DelegateSimpleFeatureIterator( this, iterator() );		
+	}
+	
+	
+
+    //
+    //
+    //
+	public SimpleFeatureCollection subCollection(Filter filter) {
+		if (filter.equals(Filter.INCLUDE)) {
+			return this;
+		}
+		if (filter.equals(Filter.EXCLUDE)) {
+			// TODO implement EmptyFeatureCollection( schema )
+		}
+		return new SubFeatureCollection(this, filter);
+	}
+
+	
+	public boolean isEmpty() {
+		Iterator iterator = iterator();
+		try {
+			return !iterator.hasNext();
+		}
+		finally {
+			close( iterator );
+		}
+	}
+	
+	public void accepts(org.opengis.feature.FeatureVisitor visitor, org.opengis.util.ProgressListener progress) {
+		Iterator iterator = null;
+        // if( progress == null ) progress = new NullProgressListener();
+        try{
+            float size = size();
+            float position = 0;            
+            progress.started();
+            for( iterator = iterator(); !progress.isCanceled() && iterator.hasNext(); progress.progress( position++/size )){
+                try {
+                    SimpleFeature feature = (SimpleFeature) iterator.next();
+                    visitor.visit(feature);
+                }
+                catch( Exception erp ){
+                    progress.exceptionOccurred( erp );
+                }
+            }            
+        }
+        finally {
+            progress.complete();            
+            close( iterator );
+        }
+	}	
+
+	public SimpleFeatureCollection sort(SortBy order) {
+		return new SubFeatureList( collection, filter, order );
+	}
+	
+	public boolean add(SimpleFeature o) {
+		return collection.add(o); 
+	}
+	
+	public void clear() {
+		List toDelete = DataUtilities.list( this );
+		removeAll( toDelete );
+	}
+			
+	public boolean remove(Object o) {
+		return collection.remove( o );
+	}
+	
+    public String getID() {
+    	return collection.getID();
+    }
+
+	/**
+	 * Calculates the bounds of the features without caching.
+	 *  
+	 * TODO Have some pro look at this code.
+	 * author by Stefan Krueger 
+	 */
+	@Override
+	public ReferencedEnvelope getBounds() {
+	    BoundsVisitor bounds = new BoundsVisitor();
+	    accepts( bounds, new NullProgressListener() );            
+            return bounds.getBounds();
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/SubFeatureList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/SubFeatureList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/collection/SubFeatureList.java	(revision 28000)
@@ -0,0 +1,298 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.collection;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.factory.CommonFactoryFinder;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory;
+import org.opengis.filter.Id;
+import org.opengis.filter.expression.PropertyName;
+import org.opengis.filter.identity.FeatureId;
+import org.opengis.filter.sort.SortBy;
+import org.opengis.filter.sort.SortOrder;
+
+public class SubFeatureList extends SubFeatureCollection implements RandomFeatureAccess {
+    /** Order by which content should be sorted */
+    List<SortBy> sort; 
+    
+    /** List of FeatureIDs in sorted order */
+    List<FeatureId> index;
+    
+    public SubFeatureList(SimpleFeatureCollection list, Filter filter){
+        this( list, filter, SortBy.NATURAL_ORDER );
+    }
+    public SubFeatureList(SimpleFeatureCollection list, SortBy sort ){
+        this( list, Filter.INCLUDE, sort );
+    }
+    /**
+	 * Create a simple SubFeatureList with the provided
+	 * filter.
+	 * 
+	 * @param filter
+	 */
+	public SubFeatureList(SimpleFeatureCollection list, Filter filter, SortBy subSort) {
+		super( list,  filter );
+		
+        if( subSort == null || subSort.equals( SortBy.NATURAL_ORDER ) ){
+            sort = Collections.emptyList();
+        } else {
+            sort = new ArrayList<SortBy>();                
+            if (collection instanceof SubFeatureList) {
+                SubFeatureList sorted = (SubFeatureList) collection;                    
+                sort.addAll( sorted.sort );
+            }
+            sort.add( subSort );
+        }
+        index = null;
+	}
+    
+    /**
+     * item at the specified index.
+     * 
+     * @param index
+     *            index of item
+     * @return the item at the specified index.
+     * @throws IndexOutOfBoundsException
+     *             if index is not between 0 and size
+     */
+    public SimpleFeature get( int position ) {
+        if( collection instanceof RandomFeatureAccess){
+            RandomFeatureAccess random = (RandomFeatureAccess) collection;
+            FeatureId fid = index().get( position);
+            return random.getFeatureMember( fid.getID() );
+        }
+        Iterator<SimpleFeature> it = iterator();
+        try {
+            for( int i=0; it.hasNext(); i++){
+                SimpleFeature feature = it.next();
+                if( i == position ){
+                    return feature;
+                }
+            }
+            throw new IndexOutOfBoundsException();
+        }
+        finally {
+            close( it );
+        }
+    }
+    			 			    
+    /** Lazy create a filter based on index */
+    protected Filter createFilter() {
+        FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
+        Set featureIds = new HashSet();
+        for(Iterator it = index().iterator(); it.hasNext();){
+           featureIds.add(ff.featureId((String) it.next())); 
+        }
+        Id fids = ff.id(featureIds);
+            
+        return fids;
+    }
+    
+    protected List<FeatureId> index(){
+        if( index == null ){
+            index = createIndex();
+        }
+        return index;
+    }
+
+    /** Put this SubFeatureList in touch with its inner index */
+    protected List<FeatureId> createIndex(){
+        List<FeatureId> fids = new ArrayList<FeatureId>();        
+        Iterator<SimpleFeature> it = collection.iterator();
+        try {            
+            while( it.hasNext() ){
+                SimpleFeature feature = it.next();
+                if( filter.evaluate(feature ) ){
+                    fids.add( feature.getIdentifier() );
+                }
+            }
+            if( sort != null && !sort.isEmpty()){
+                final SortBy initialOrder = sort.get( sort.size() -1 );                
+                Collections.sort( fids, new Comparator<FeatureId>(){
+                    public int compare( FeatureId key1, FeatureId key2 ) {
+                        SimpleFeature feature1 = getFeatureMember( key1.getID() );
+                        SimpleFeature feature2 = getFeatureMember( key2.getID() );
+                        
+                        int compare = compare( feature1, feature2, initialOrder );
+                        if( compare == 0 && sort.size() > 1 ){
+                            for( int i=sort.size()-1; compare == 0 && i>=0; i--){
+                                compare = compare( feature1, feature2, sort.get( i ));
+                            }                            
+                        }                        
+                        return compare;
+                    }
+                    @SuppressWarnings("unchecked")
+                    protected int compare( SimpleFeature feature1, SimpleFeature feature2, SortBy order){
+                        PropertyName name = order.getPropertyName();
+                        Comparable value1 = (Comparable) name.evaluate( feature1 );
+                        Comparable value2 = (Comparable) name.evaluate( feature2 );
+                        
+                        if( order.getSortOrder() == SortOrder.ASCENDING ){
+                            return value1.compareTo( value2 );
+                        }
+                        else return value2.compareTo( value1 );                        
+                    }
+                });
+            }
+        }
+        finally {
+            collection.close( it );
+        }
+        return fids;
+    }
+
+    /**
+     * Appends element.
+     * <p>
+     * This implementation calls <tt>add(size(), o)</tt>.
+     * <p>
+     * Note that this implementation throws an
+     * <tt>UnsupportedOperationException</tt> unless <tt>add(int, Object)</tt>
+     * is overridden.
+     * 
+     * @param item
+     *            the Object element to be appended to this list.
+     * @return <tt>true</tt> (as per the general contract of
+     *         <tt>Collection.add</tt>).
+     * @throws UnsupportedOperationException
+     *             if the <tt>add</tt> method is not supported by this Set.
+     * @throws ClassCastException
+     *             if the class of the specified element prevents it from being
+     *             added to this set.
+     * @throws IllegalArgumentException
+     *             some aspect of this element prevents it from being added to
+     *             this collection.
+     */
+    public boolean add(SimpleFeature feature) {
+        boolean added = collection.add( feature );
+        if( added ){
+            index().add( feature.getIdentifier() );
+        }
+        return true;
+    }
+    
+	//
+    // Feature Collection methods
+    //
+    /**
+     * Sublist of this sublist!
+     * <p>
+     * Implementation will ensure this does not get out of hand, order
+     * is maintained and only indexed once.
+     * </p>
+     */
+    public SimpleFeatureCollection subList(Filter subfilter) {
+        if (filter.equals(Filter.INCLUDE)) {
+            return this;
+        }
+        if (filter.equals(Filter.EXCLUDE)) {
+            // TODO implement EmptyFeatureCollection( schema )
+        }        
+        return new SubFeatureList(collection, ff.and( filter, subfilter), sort.get(0) );
+    }
+    //
+    // RandomFeatureAccess
+    //
+    
+    public SimpleFeature getFeatureMember( String id ) throws NoSuchElementException {
+        int position = index.indexOf( id );
+        if( position == -1){
+            throw new NoSuchElementException(id);
+        }        
+        if( collection instanceof RandomFeatureAccess ){
+            RandomFeatureAccess random = (RandomFeatureAccess) collection;
+            random.getFeatureMember( id ); 
+        }
+        return get( position );
+    }
+    public SimpleFeature removeFeatureMember( String id ) {
+        int position = index.indexOf( ff.featureId(id) );
+        if( position == -1){
+            throw new NoSuchElementException(id);
+        }        
+        if( collection instanceof RandomFeatureAccess ){
+            RandomFeatureAccess random = (RandomFeatureAccess) collection;
+            if( index != null ) index.remove( id );
+            return random.removeFeatureMember( id );            
+        }
+        return remove( position );
+    }
+    public SimpleFeature remove( int position ){
+        if( collection instanceof RandomFeatureAccess){
+            RandomFeatureAccess random = (RandomFeatureAccess) collection;
+            FeatureId fid = index().get( position );
+            return random.removeFeatureMember( fid.getID() );
+        }
+        Iterator<SimpleFeature> it = iterator();
+        try {
+            for( int i=0; it.hasNext(); i++){
+                SimpleFeature feature = it.next();
+                if( i == position ){
+                    collection.remove( feature );                    
+                    return feature;
+                }
+            }
+            throw new IndexOutOfBoundsException();
+        }
+        finally {
+            close( it );
+        }
+    }    
+    
+    /**
+     * Returns a quick iterator that uses get and size methods.
+     * <p>
+     * As with all resource collections it is assumed that the iterator will be
+     * closed after use.
+     * </p>
+     * 
+     * @return an iterator over the elements in this list in proper sequence.
+     * @see #modCount
+     */
+    public Iterator<SimpleFeature> openIterator() {
+        return new SortedIteratory();
+    }
+    
+    private class SortedIteratory implements Iterator<SimpleFeature> {
+        Iterator<FeatureId> iterator = index().iterator();
+        String id;
+        public boolean hasNext() {
+            return iterator != null && iterator.hasNext();
+        }
+        public SimpleFeature next() {
+            FeatureId fid = iterator.next();
+            id = fid.getID();
+            return getFeatureMember( id );
+        }
+        public void remove() {
+            removeFeatureMember(id);
+        }
+
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleFeatureBuilder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleFeatureBuilder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleFeatureBuilder.java	(revision 28000)
@@ -0,0 +1,424 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.simple;
+
+import java.rmi.server.UID;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.data.DataUtilities;
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.feature.type.Types;
+import org.geotools.util.Converters;
+import org.opengis.feature.FeatureFactory;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.Name;
+
+/**
+ * A builder for features.
+ * <p>
+ * Simple Usage:
+ * <code>
+ *  <pre>
+ *  //type of features we would like to build ( assume schema = (geom:Point,name:String) )
+ *  SimpleFeatureType featureType = ...  
+ * 
+ *   //create the builder
+ *  SimpleFeatureBuilder builder = new SimpleFeatureBuilder();
+ *  
+ *  //set the type of created features
+ *  builder.setType( featureType );
+ *  
+ *  //add the attributes
+ *  builder.add( new Point( 0 , 0 ) );
+ *  builder.add( "theName" );
+ *  
+ *  //build the feature
+ *  SimpleFeature feature = builder.buildFeature( "fid" );
+ *  </pre>
+ * </code>
+ * </p>
+ * <p>
+ * This builder builds a feature by maintaining state. Each call to {@link #add(Object)}
+ * creates a new attribute for the feature and stores it locally. When using the 
+ * add method to add attributes to the feature, values added must be added in the 
+ * same order as the attributes as defined by the feature type. The methods 
+ * {@link #set(String, Object)} and {@link #set(int, Object)} are used to add 
+ * attributes out of order.
+ * </p>
+ * <p>
+ * Each time the builder builds a feature with a call to {@link #buildFeature(String)}
+ * the internal state is reset. 
+ * </p>
+ * <p>
+ * This builder can be used to copy features as well. The following code sample
+ * demonstrates:
+ * <code>
+ * <pre>
+ *  //original feature
+ *  SimpleFeature original = ...;
+ * 
+ *  //create and initialize the builder
+ *  SimpleFeatureBuilder builder = new SimpleFeatureBuilder();
+ *  builder.init(original);
+ * 
+ *  //create the new feature
+ *  SimpleFeature copy = builder.buildFeature( original.getID() );
+ * 
+ *  </pre>
+ * </code>
+ * </p>
+ * <p>
+ * The builder also provides a number of static "short-hand" methods which can 
+ * be used when its not ideal to instantiate a new builder, thought this will
+ * trigger some extra object allocations. In time critical code sections it's
+ * better to instantiate the builder once and use it to build all the required
+ * features.
+ * <code>
+ *   <pre>
+ *   SimpleFeatureType type = ..;
+ *   Object[] values = ...;
+ *   
+ *   //build a new feature
+ *   SimpleFeature feature = SimpleFeatureBuilder.build( type, values, "fid" );
+ *   
+ *   ...
+ *   
+ *   SimpleFeature original = ...;
+ *   
+ *   //copy the feature
+ *   SimpleFeature feature = SimpleFeatureBuilder.copy( original );
+ *   </pre>
+ * </code>
+ * </p>
+ * <p>
+ * This class is not thread safe nor should instances be shared across multiple 
+ * threads.
+ * </p>
+ *  
+ * @author Justin Deoliveira
+ * @author Jody Garnett
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/simple/SimpleFeatureBuilder.java $
+ */
+public class SimpleFeatureBuilder {
+    
+    /** the feature type */
+    SimpleFeatureType featureType;
+    
+    /** the feature factory */
+    FeatureFactory factory;
+    
+    /** the attribute name to index index */
+    Map<String, Integer> index;
+
+    /** the values */
+    //List<Object> values;
+    Object[] values;
+    
+    /** pointer for next attribute */
+    int next;
+    
+    Map<Object, Object>[] userData;
+    
+    Map<Object, Object> featureUserData;
+    
+    boolean validating;
+    
+    public SimpleFeatureBuilder(SimpleFeatureType featureType) {
+        this(featureType, CommonFactoryFinder.getFeatureFactory(null));
+    }
+    
+    public SimpleFeatureBuilder(SimpleFeatureType featureType, FeatureFactory factory) {
+        this.featureType = featureType;
+        this.factory = factory;
+
+        if(featureType instanceof SimpleFeatureTypeImpl) {
+            index = ((SimpleFeatureTypeImpl) featureType).index;
+        } else {
+            this.index = SimpleFeatureTypeImpl.buildIndex(featureType);
+        }
+        reset();
+    }
+    
+    public void reset() {
+        values = new Object[featureType.getAttributeCount()];
+        next = 0;
+        userData = null;
+        featureUserData = null;
+    }
+    
+    /**
+     * Returns the simple feature type used by this builder as a feature template
+     * @return
+     */
+    public SimpleFeatureType getFeatureType() {
+        return featureType;
+    }
+    
+    /**
+     * Initialize the builder with the provided feature.
+     * <p>
+     * This method adds all the attributes from the provided feature. It is 
+     * useful when copying a feature. 
+     * </p>
+     */
+    public void init( SimpleFeature feature ) {
+        reset();
+        
+        // optimize the case in which we just build
+        if(feature instanceof SimpleFeatureImpl) {
+            SimpleFeatureImpl impl = (SimpleFeatureImpl) feature;
+            System.arraycopy(impl.values, 0, values, 0, impl.values.length);
+        } else {
+            for (Object value : feature.getAttributes()) {
+                add(value);
+            }
+        }
+    }
+    
+    
+
+    /**
+     * Adds an attribute.
+     * <p>
+     * This method should be called repeatedly for the number of attributes as
+     * specified by the type of the feature.
+     * </p>
+     */
+    public void add(Object value) {
+        set(next, value);
+        next++;
+    }
+
+    /**
+     * Adds a list of attributes.
+     */
+    public void addAll(List<Object> values) {
+        for (int i = 0; i < values.size(); i++) {
+            add(values.get(i));
+        }
+    }
+
+    /**
+     * Adds an array of attributes.
+     */
+    public void addAll(Object[] values) {
+       addAll(Arrays.asList(values));
+    }
+
+    /**
+     * Adds an attribute value by name.
+     * <p>
+     * This method can be used to add attribute values out of order.
+     * </p>
+     * 
+     * @param name
+     *            The name of the attribute.
+     * @param value
+     *            The value of the attribute.
+     * 
+     * @throws IllegalArgumentException
+     *             If no such attribute with teh specified name exists.
+     */
+    public void set(Name name, Object value) {
+        set(name.getLocalPart(), value);
+    }
+
+    /**
+     * Adds an attribute value by name.
+     * <p>
+     * This method can be used to add attribute values out of order.
+     * </p>
+     * 
+     * @param name
+     *            The name of the attribute.
+     * @param value
+     *            The value of the attribute.
+     * 
+     * @throws IllegalArgumentException
+     *             If no such attribute with teh specified name exists.
+     */
+    public void set(String name, Object value) {
+        int index = featureType.indexOf(name);
+        if (index == -1) {
+            throw new IllegalArgumentException("No such attribute:" + name);
+        }
+        set(index, value);
+    }
+
+    /**
+     * Adds an attribute value by index. *
+     * <p>
+     * This method can be used to add attribute values out of order.
+     * </p>
+     * 
+     * @param index
+     *            The index of the attribute.
+     * @param value
+     *            The value of the attribute.
+     */
+    public void set(int index, Object value) {
+        if(index >= values.length)
+            throw new ArrayIndexOutOfBoundsException("Can handle " 
+                    + values.length + " attributes only, index is " + index);
+        
+        AttributeDescriptor descriptor = featureType.getDescriptor(index);
+        values[index] = convert(value, descriptor);
+        if(validating)
+            Types.validate(descriptor, values[index]);
+    }
+
+    private Object convert(Object value, AttributeDescriptor descriptor) {
+        //make sure the type of the value and the binding of the type match up
+        if ( value != null ) {
+            Class<?> target = descriptor.getType().getBinding(); 
+            Object converted = Converters.convert(value, target);
+            if(converted != null)
+                value = converted;
+        } else {
+            //if the content is null and the descriptor says isNillable is false, 
+            // then set the default value
+            if (!descriptor.isNillable()) {
+                value = descriptor.getDefaultValue();
+                if ( value == null ) {
+                    //no default value, try to generate one
+                    value = DataUtilities.defaultValue(descriptor.getType().getBinding());
+                }
+            }
+        }
+        return value;
+    }
+
+    /**
+     * Builds the feature.
+     * <p>
+     * The specified <tt>id</tt> may be <code>null</code>. In this case an
+     * id will be generated internally by the builder.
+     * </p>
+     * <p>
+     * After this method returns, all internal builder state is reset.
+     * </p>
+     * 
+     * @param id
+     *            The id of the feature, or <code>null</code>.
+     * 
+     * @return The new feature.
+     */
+    public SimpleFeature buildFeature(String id) {
+        // ensure id
+        if (id == null) {
+            id = SimpleFeatureBuilder.createDefaultFeatureId();
+        }
+
+        Object[] values = this.values;
+        Map<Object,Object>[] userData = this.userData;
+        Map<Object,Object> featureUserData = this.featureUserData;
+        reset();
+        SimpleFeature sf = factory.createSimpleFeature(values, featureType, id);
+        
+        // handle the per attribute user data
+        if(userData != null) {
+            for (int i = 0; i < userData.length; i++) {
+                if(userData[i] != null) {
+                    sf.getProperty(featureType.getDescriptor(i).getName()).getUserData().putAll(userData[i]);
+                }
+            }
+        }
+        
+        // handle the feature wide user data
+        if(featureUserData != null) {
+            sf.getUserData().putAll(featureUserData);
+        }
+        
+        return sf;
+    }
+    
+    /**
+     * Internal method for creating feature id's when none is specified.
+     */
+    public static String createDefaultFeatureId() {
+          // According to GML and XML schema standards, FID is a XML ID
+        // (http://www.w3.org/TR/xmlschema-2/#ID), whose acceptable values are those that match an
+        // NCNAME production (http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName):
+        // NCName ::= (Letter | '_') (NCNameChar)* /* An XML Name, minus the ":" */
+        // NCNameChar ::= Letter | Digit | '.' | '-' | '_' | CombiningChar | Extender
+        // We have to fix the generated UID replacing all non word chars with an _ (it seems
+        // they area all ":")
+        //return "fid-" + NON_WORD_PATTERN.matcher(new UID().toString()).replaceAll("_");
+        // optimization, since the UID toString uses only ":" and converts long and integers
+        // to strings for the rest, so the only non word character is really ":"
+        return "fid-" + new UID().toString().replace(':', '_');
+    }
+    
+    /**
+     * Static method to build a new feature.
+     * <p>
+     * If multiple features need to be created, this method should not be used
+     * and instead an instance should be instantiated directly.
+     * </p>
+     * <p>
+     * This method is a short-hand convenience which creates a builder instance
+     * internally and adds all the specified attributes.
+     * </p>
+     * @param type SimpleFeatureType defining the structure for the created feature
+     * @param values Attribute values, must be in the order defined by SimpleFeatureType
+     * @param id FeatureID for the generated feature, use null to allow one to be supplied for you
+     */
+    public static SimpleFeature build( SimpleFeatureType type, Object[] values, String id ) {
+        SimpleFeatureBuilder builder = new SimpleFeatureBuilder(type);
+        builder.addAll(values);
+        return builder.buildFeature(id);
+    }
+    
+    /**
+     * * Static method to build a new feature.
+     * <p>
+     * If multiple features need to be created, this method should not be used
+     * and instead an instance should be instantiated directly.
+     * </p>
+     * @param type SimpleFeatureType defining the structure for the created feature
+     * @param values Attribute values, must be in the order defined by SimpleFeatureType
+     * @param id FeatureID for the generated feature, use null to allow one to be supplied for you
+     */
+    public static SimpleFeature build( SimpleFeatureType type, List<Object> values, String id ) {
+        return build( type, values.toArray(), id );
+    }
+    
+    /**
+     * Copy an existing feature (the values are reused so be careful with mutable values).
+     * <p>
+     * If multiple features need to be copied, this method should not be used
+     * and instead an instance should be instantiated directly.
+     * </p>
+     * <p>
+     * This method is a short-hand convenience which creates a builder instance
+     * and initializes it with the attributes from the specified feature.
+     * </p>
+     */
+    public static SimpleFeature copy(SimpleFeature original) {
+        if( original == null ) return null;
+        
+        SimpleFeatureBuilder builder = new SimpleFeatureBuilder(original.getFeatureType());
+        builder.init(original); // this is a shallow copy
+        return builder.buildFeature(original.getID());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleFeatureImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleFeatureImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleFeatureImpl.java	(revision 28000)
@@ -0,0 +1,538 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.simple;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.feature.GeometryAttributeImpl;
+import org.geotools.feature.IllegalAttributeException;
+import org.geotools.feature.type.AttributeDescriptorImpl;
+import org.geotools.feature.type.Types;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.util.Converters;
+import org.geotools.util.Utilities;
+import org.opengis.feature.GeometryAttribute;
+import org.opengis.feature.Property;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.feature.type.GeometryType;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.identity.FeatureId;
+import org.opengis.filter.identity.Identifier;
+import org.opengis.geometry.BoundingBox;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * An implementation of {@link SimpleFeature} geared towards speed and backed by an Object[].
+ * 
+ * @author Justin
+ * @author Andrea Aime
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/simple/SimpleFeatureImpl.java $
+ */
+public class SimpleFeatureImpl implements SimpleFeature {
+    
+    protected FeatureId id;
+    protected SimpleFeatureType featureType;
+    /**
+     * The actual values held by this feature
+     */
+    protected Object[] values;
+    /**
+     * The attribute name -> position index
+     */
+    protected Map<String,Integer> index;
+    /**
+     * The set of user data attached to the feature (lazily created)
+     */
+    protected Map<Object, Object> userData;
+    /**
+     * The set of user data attached to each attribute (lazily created)
+     */
+    protected Map<Object, Object>[] attributeUserData;
+    
+    /**
+     * Whether this feature is self validating or not
+     */
+    protected  boolean validating;
+        
+    /**
+     * Fast construction of a new feature. The object takes owneship of the provided value array,
+     * do not modify after calling the constructor
+     * @param values
+     * @param featureType
+     * @param id
+     * @param validating
+     */
+    public SimpleFeatureImpl(Object[] values, SimpleFeatureType featureType, FeatureId id, boolean validating) {
+        this.id = id;
+        this.featureType = featureType;
+        this.values = values;
+        this.validating = validating;
+        
+        // in the most common case reuse the map cached in the feature type
+        if(featureType instanceof SimpleFeatureTypeImpl) {
+            index = ((SimpleFeatureTypeImpl) featureType).index;
+        } else {
+            // if we're not lucky, rebuild the index completely... 
+            // TODO: create a separate cache for this case?
+            this.index = SimpleFeatureTypeImpl.buildIndex(featureType);
+        }
+        
+        // if we're self validating, do validation right now
+        if(validating)
+            validate();
+    }
+    
+    public FeatureId getIdentifier() {
+        return id;
+    }
+    public String getID() {
+    	return id.getID();
+    }
+        
+    public Object getAttribute(int index) throws IndexOutOfBoundsException {
+        return values[ index ];
+    }
+    
+    public Object getAttribute(String name) {
+        Integer idx = index.get(name);
+        if(idx != null)
+            return getAttribute(idx);
+        else
+            return null;
+    }
+
+    public Object getAttribute(Name name) {
+        return getAttribute( name.getLocalPart() );
+    }
+
+    public List<Object> getAttributes() {
+        return new ArrayList(Arrays.asList( values ));
+    }
+
+    public Object getDefaultGeometry() {
+        // should be specified in the index as the default key (null)
+        Integer idx = index.get(null);
+        Object defaultGeometry = idx != null ? getAttribute( idx ) : null;
+           
+       // not found? do we have a default geometry at all?
+       if(defaultGeometry == null){
+           GeometryDescriptor geometryDescriptor = featureType.getGeometryDescriptor();
+           if(geometryDescriptor != null){
+               Integer defaultGeomIndex = index.get(geometryDescriptor.getName().getLocalPart());
+               defaultGeometry = getAttribute(defaultGeomIndex.intValue());
+           }
+       }
+    
+       return defaultGeometry;
+    }
+
+    public SimpleFeatureType getFeatureType() {
+        return featureType;
+    }
+
+    public SimpleFeatureType getType() {
+        return featureType;
+    }
+
+    public void setAttribute(int index, Object value)
+        throws IndexOutOfBoundsException {
+        // first do conversion
+        Object converted = Converters.convert(value, getFeatureType().getDescriptor(index).getType().getBinding());
+        // if necessary, validation too
+        if(validating)
+            Types.validate(featureType.getDescriptor(index), converted);
+        // finally set the value into the feature
+        values[index] = converted;
+    }
+    
+    public void setAttribute(String name, Object value) {
+        final Integer idx = index.get(name);
+        if(idx == null)
+            throw new IllegalAttributeException("Unknown attribute " + name);
+        setAttribute( idx.intValue(), value );
+    }
+
+    public void setAttribute(Name name, Object value) {
+        setAttribute( name.getLocalPart(), value );
+    }
+
+    public void setAttributes(List<Object> values) {
+        for (int i = 0; i < this.values.length; i++) {
+            this.values[i] = values.get(i);
+        }
+    }
+
+    public BoundingBox getBounds() {
+        //TODO: cache this value
+        ReferencedEnvelope bounds = new ReferencedEnvelope( featureType.getCoordinateReferenceSystem() );
+        for ( Object o : values ) {
+            if ( o instanceof Geometry ) {
+                Geometry g = (Geometry) o;
+                //TODO: check userData for crs... and ensure its of the same 
+                // crs as the feature type
+                if ( bounds.isNull() ) {
+                    bounds.init(g.getEnvelopeInternal());
+                }
+                else {
+                    bounds.expandToInclude(g.getEnvelopeInternal());
+                }
+            }
+        }
+        
+        return bounds;
+    }
+
+    public GeometryAttribute getDefaultGeometryProperty() {
+        GeometryDescriptor geometryDescriptor = featureType.getGeometryDescriptor();
+        GeometryAttribute geometryAttribute = null;
+        if(geometryDescriptor != null){
+            Object defaultGeometry = getDefaultGeometry();
+            geometryAttribute = new GeometryAttributeImpl(defaultGeometry, geometryDescriptor, null);            
+        }
+        return geometryAttribute;
+    }
+
+    public Collection<Property> getProperties() {
+        return new AttributeList();
+    }
+
+    public Property getProperty(Name name) {
+        return getProperty( name.getLocalPart() );
+    }
+
+    public Property getProperty(String name) {
+        final Integer idx = index.get(name);
+        if(idx == null){
+            return null;
+        } else {
+            int index = idx.intValue();
+            AttributeDescriptor descriptor = featureType.getDescriptor(index);
+            if(descriptor instanceof GeometryDescriptor){
+                return new GeometryAttributeImpl(values[index], (GeometryDescriptor) descriptor, null); 
+            }else{
+                return new Attribute( index );
+            }
+        }
+    }
+
+    public Collection<? extends Property> getValue() {
+        return getProperties();
+    }
+    
+    /**
+     * @see org.opengis.feature.Attribute#getDescriptor()
+     */
+    public AttributeDescriptor getDescriptor() {
+        return new AttributeDescriptorImpl(featureType, featureType.getName(), 0,
+                Integer.MAX_VALUE, true, null);
+    }
+
+    /**
+     * @return same name than this feature's {@link SimpleFeatureType}
+     * @see org.opengis.feature.Property#getName()
+     */
+    public Name getName() {
+        return featureType.getName();
+    }
+
+    public boolean isNillable() {
+        return true;
+    }
+
+    public Map<Object, Object> getUserData() {
+        if(userData == null)
+            userData = new HashMap<Object, Object>();
+        return userData;
+    }
+    
+    /**
+     * returns a unique code for this feature
+     *
+     * @return A unique int
+     */
+    public int hashCode() {
+        return id.hashCode() * featureType.hashCode();
+    }
+
+    /**
+     * override of equals.  Returns if the passed in object is equal to this.
+     *
+     * @param obj the Object to test for equality.
+     *
+     * @return <code>true</code> if the object is equal, <code>false</code>
+     *         otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+
+        if (obj == this) {
+            return true;
+        }
+
+        if (!(obj instanceof SimpleFeatureImpl)) {
+            return false;
+        }
+
+        SimpleFeatureImpl feat = (SimpleFeatureImpl) obj;
+        
+        // this check shouldn't exist, by contract, 
+        //all features should have an ID.
+        if (id == null) {
+            if (feat.getIdentifier() != null) {
+                return false;
+            }
+        }
+
+        if (!id.equals(feat.getIdentifier())) {
+            return false;
+        }
+
+        if (!feat.getFeatureType().equals(featureType)) {
+            return false;
+        }
+
+        for (int i = 0, ii = values.length; i < ii; i++) {
+            Object otherAtt = feat.getAttribute(i);
+
+            if (values[i] == null) {
+                if (otherAtt != null) {
+                    return false;
+                }
+            } else {
+                if (!values[i].equals(otherAtt)) {
+                    if (values[i] instanceof Geometry
+                            && otherAtt instanceof Geometry) {
+                        // we need to special case Geometry
+                        // as JTS is broken Geometry.equals( Object ) 
+                        // and Geometry.equals( Geometry ) are different 
+                        // (We should fold this knowledge into AttributeType...)
+                        if (!((Geometry) values[i]).equals(
+                                    (Geometry) otherAtt)) {
+                            return false;
+                        }
+                    } else {
+                        return false;
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+    
+    public void validate() {
+        for (int i = 0; i < values.length; i++) {
+            AttributeDescriptor descriptor = getType().getDescriptor(i);
+            Types.validate(descriptor, values[i]);
+        }
+    }
+
+    /**
+     * Live collection backed directly on the value array
+     */
+    class AttributeList extends AbstractList<Property> {
+
+        public Property get(int index) {
+            AttributeDescriptor descriptor = featureType.getDescriptor(index);
+            if (descriptor instanceof GeometryDescriptor) {
+                return new SimpleGeometryAttribute(index);
+            }
+            return new Attribute(index);
+        }
+        
+        public Attribute set(int index, Property element) {
+            values[index] =  element.getValue();
+            return null;
+        }
+        
+        public int size() {
+            return values.length;
+        }
+    }
+    
+    public String toString() {
+        StringBuffer sb = new StringBuffer("SimpleFeatureImpl:");
+        sb.append( getType().getName().getLocalPart());
+        sb.append("=");
+        sb.append( getValue() );
+        return sb.toString();
+    }
+    
+
+    /**
+     * Attribute that delegates directly to the value array
+     */
+    class Attribute implements org.opengis.feature.Attribute {
+        int index;
+        
+        Attribute( int index ) {
+            this.index = index;
+        }
+        
+        public Identifier getIdentifier() {
+            return null;
+        }
+
+        public AttributeDescriptor getDescriptor() {
+            return featureType.getDescriptor(index);
+        }
+
+        public AttributeType getType() {
+            return featureType.getType(index);
+        }
+
+        public Name getName() {
+            return getDescriptor().getName();
+        }
+
+        public Map<Object, Object> getUserData() {
+            // lazily create the user data holder
+            if(attributeUserData == null)
+                attributeUserData = new HashMap[values.length];
+            // lazily create the attribute user data
+            if(attributeUserData[index] == null)
+                attributeUserData[index] = new HashMap<Object, Object>();
+            return attributeUserData[index];
+        }
+
+        public Object getValue() {
+            return values[index];
+        }
+
+        public boolean isNillable() {
+            return getDescriptor().isNillable();
+        }
+
+        /**
+         * Override of hashCode; uses descriptor name to agree with AttributeImpl
+         * 
+         * @return hashCode for this object.
+         */
+        public int hashCode() {
+            return 37 * getDescriptor().hashCode()
+                    + (37 * (getValue() == null ? 0 : getValue().hashCode()));
+        }
+
+        /**
+         * Override of equals.
+         * 
+         * @param other
+         *            the object to be tested for equality.
+         * 
+         * @return whether other is equal to this attribute Type.
+         */
+        public boolean equals(Object obj) {
+            if ( this == obj ) {
+                return true;
+            }
+            
+            if (!(obj instanceof Attribute)) {
+                return false;
+            }
+            Attribute other = (Attribute) obj;
+            if (!Utilities.equals(getDescriptor(), other.getDescriptor())){
+                return false;
+            }
+            if (!Utilities.deepEquals(getValue(), other.getValue())){
+                return false;   
+            }
+            return Utilities.equals( getIdentifier(), other.getIdentifier());
+        }
+        
+        public void validate() {
+            Types.validate(getDescriptor(), values[index]);
+        }
+
+        public String toString() {
+            StringBuffer sb = new StringBuffer("SimpleFeatureImpl.Attribute: ");
+            sb.append(getDescriptor().getName().getLocalPart());
+            if (!getDescriptor().getName().getLocalPart().equals(
+                    getDescriptor().getType().getName().getLocalPart())
+                    || id != null) {
+                sb.append("<");
+                sb.append(getDescriptor().getType().getName().getLocalPart());
+                if (id != null) {
+                    sb.append(" id=");
+                    sb.append(id);
+                }
+                sb.append(">");
+            }
+            sb.append("=");
+            sb.append( values[index] );
+            return sb.toString();
+        }
+    }
+    
+    class SimpleGeometryAttribute extends Attribute implements GeometryAttribute {
+
+        SimpleGeometryAttribute(int index) {
+            super(index);
+        }
+
+        @Override
+        public GeometryType getType() {
+            return (GeometryType) super.getType();
+        }
+
+        @Override
+        public GeometryDescriptor getDescriptor() {
+            return (GeometryDescriptor) super.getDescriptor();
+        }
+
+        public BoundingBox getBounds() {
+            ReferencedEnvelope bounds = new ReferencedEnvelope(
+                    featureType.getCoordinateReferenceSystem());
+            Object value = getAttribute(index);
+            if (value instanceof Geometry) {
+                bounds.init(((Geometry) value).getEnvelopeInternal());
+            }
+            return bounds;
+        }
+
+        @Override
+        public int hashCode() {
+            return 17 * super.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+
+            if (!(obj instanceof SimpleGeometryAttribute)) {
+                return false;
+            }
+            return super.equals(obj);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleFeatureTypeBuilder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleFeatureTypeBuilder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleFeatureTypeBuilder.java	(revision 28000)
@@ -0,0 +1,628 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.simple;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.feature.AttributeTypeBuilder;
+import org.geotools.feature.NameImpl;
+import org.geotools.feature.type.BasicFeatureTypes;
+import org.geotools.feature.type.FeatureTypeFactoryImpl;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.FeatureTypeFactory;
+import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.feature.type.GeometryType;
+import org.opengis.feature.type.Name;
+import org.opengis.feature.type.Schema;
+import org.opengis.filter.Filter;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.util.InternationalString;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * A builder for simple feature types.
+ * <p>
+ * Simple Usage:
+ * <pre>
+ *  <code>
+ *  //create the builder
+ *  SimpleTypeBuilder builder = new SimpleTypeBuilder();
+ *  
+ *  //set global state
+ *  builder.setName( "testType" );
+ *  builder.setNamespaceURI( "http://www.geotools.org/" );
+ *  builder.setSRS( "EPSG:4326" );
+ *  
+ *  //add attributes
+ *  builder.add( "intProperty", Integer.class );
+ *  builder.add( "stringProperty", String.class );
+ *  builder.add( "pointProperty", Point.class );
+ *  
+ *  //add attribute setting per attribute state
+ *  builder.minOccurs(0).maxOccurs(2).nillable(false).add("doubleProperty",Double.class);
+ *  
+ *  //build the type
+ *  SimpleFeatureType featureType = builder.buildFeatureType();
+ *  </code>
+ * </pre>
+ * </p>
+ * This builder builds type by maintaining state. Two types of state are maintained:
+ * <i>Global Type State</i> and <i>Per Attribute State</i>. Methods which set
+ * global state are named <code>set&lt;property>()</code>. Methods which set per attribute 
+ * state are named <code>&lt;property>()</code>. Furthermore calls to per attribute 
+ * </p>
+ * <p>
+ * Global state is reset after a call to {@link #buildFeatureType()}. Per 
+ * attribute state is reset after a call to {@link #add}.
+ * </p>
+ * <p>
+ * A default geometry for the feature type can be specified explictly via 
+ * {@link #setDefaultGeometry(String)}. However if one is not set the first
+ * geometric attribute ({@link GeometryType}) added will be resulting default.
+ * So if only specifying a single geometry for the type there is no need to 
+ * call the method. However if specifying multiple geometries then it is good
+ * practice to specify the name of the default geometry type. For instance:
+ * <code>
+ * 	<pre>
+ *  builder.add( "pointProperty", Point.class );
+ *  builder.add( "lineProperty", LineString.class );
+ *  builder.add( "polygonProperty", Polygon.class );
+ *  
+ *  builder.setDefaultGeometry( "lineProperty" );
+ * 	</pre>
+ * </code>
+ * </p>
+ * 
+ * @author Justin Deolivera
+ * @author Jody Garnett
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/simple/SimpleFeatureTypeBuilder.java $
+ */
+public class SimpleFeatureTypeBuilder {
+	/**
+	 * factories
+	 */
+	protected FeatureTypeFactory factory;
+
+	/**
+	 * Map of java class bound to properties types.
+	 */
+	protected Map/* <Class,AttributeType> */bindings;
+	
+	// Global state for the feature type
+	//
+	/**
+	 * Naming: local name
+	 */
+	protected String local;
+
+	/**
+	 * Naming: uri indicating scope
+	 */
+	protected String uri;
+
+	/**
+	 * Description of type.
+	 */
+	protected InternationalString description;
+
+	/**
+	 * List of attributes.
+	 */
+	protected List<AttributeDescriptor> attributes;
+
+	/**
+	 * Additional restrictions on the type.
+	 */
+	protected List<Filter> restrictions;
+
+	/** 
+	 * Name of the default geometry to use 
+	 */
+	protected String defaultGeometry;
+
+	/** 
+	 * coordinate reference system of the type 
+	 */
+	protected CoordinateReferenceSystem crs;
+
+	/**
+	 * flag controlling if the type is abstract.
+	 */
+	protected boolean isAbstract = false;
+	
+	/**
+	 * the parent type.
+	 */
+	protected SimpleFeatureType superType;
+	
+	/**
+	 * attribute builder
+	 */
+	protected AttributeTypeBuilder attributeBuilder;
+	
+	/**
+	 * Constructs the builder.
+	 */
+	public SimpleFeatureTypeBuilder() {
+		this( new FeatureTypeFactoryImpl() );
+	}
+	
+	/**
+	 * Constructs the builder specifying the factory for creating feature and 
+	 * feature collection types.
+	 */
+	public SimpleFeatureTypeBuilder(FeatureTypeFactory factory) {
+		this.factory = factory;
+		
+		attributeBuilder = new AttributeTypeBuilder();
+		setBindings( new SimpleSchema() );
+		reset();
+	}
+		
+	// Builder methods
+	//
+	/**
+	 * Initializes the builder with state from a pre-existing feature type.
+	 */
+	public void init(SimpleFeatureType type) {
+		init();
+		if (type == null)
+			return;
+
+		uri = type.getName().getNamespaceURI();
+		local = type.getName().getLocalPart();
+		description = type.getDescription();
+		restrictions = null;
+		restrictions().addAll(type.getRestrictions());
+
+		attributes = null;
+		attributes().addAll(type.getAttributeDescriptors());
+		
+		isAbstract = type.isAbstract();
+		superType = (SimpleFeatureType) type.getSuper();
+	}
+
+	/**
+	 * Clears the running list of attributes. 
+	 */
+	protected void init() {
+		attributes = null;
+	}
+	
+	/**
+	 * Completely resets all builder state.
+	 *
+	 */
+	protected void reset() {
+		uri = BasicFeatureTypes.DEFAULT_NAMESPACE;
+		local = null;
+		description = null;
+		restrictions = null;
+		attributes = null;
+		crs = null;
+		isAbstract = false;
+		superType = BasicFeatureTypes.FEATURE;
+	}
+	
+	/**
+	 * Set the namespace uri of the built type.
+	 */
+	public void setNamespaceURI(String namespaceURI) {
+		this.uri = namespaceURI;
+	}
+	public void setNamespaceURI(URI namespaceURI) {
+	    if ( namespaceURI != null ) {
+	        setNamespaceURI( namespaceURI.toString() );
+	    }
+	    else {
+	        setNamespaceURI( (String) null );
+	    }
+	}
+	
+	/**
+	 * Sets the name of the built type.
+	 */
+	public void setName(String name) {
+		this.local = name;
+	}
+		
+	/**
+	 * Sets the local name and namespace uri of the built type.
+	 */
+	public void setName(Name name) {
+	    setName( name.getLocalPart() );
+	    setNamespaceURI( name.getNamespaceURI() );
+	}
+		
+	/**
+	 * Sets the name of the default geometry attribute of the built type.
+	 */
+	public void setDefaultGeometry(String defaultGeometryName) {
+		this.defaultGeometry = defaultGeometryName;
+	}
+		
+	/**
+	 * Sets the flag controlling if the resulting type is abstract.
+	 */
+	public void setAbstract(boolean isAbstract) {
+        this.isAbstract = isAbstract;
+    }
+	
+	/**
+	 * Sets the super type of the built type.
+	 */
+	public void setSuperType(SimpleFeatureType superType) {
+        this.superType = superType;
+    }
+	
+	/**
+	 * Specifies an attribute type binding.
+	 * <p>
+	 * This method is used to associate an attribute type with a java class. 
+	 * The class is retreived from <code>type.getBinding()</code>. When the
+	 * {@link #add(String, Class)} method is used to add an attribute to the 
+	 * type being built, this binding is used to locate the attribute type.
+	 * </p>
+	 * 
+	 * @param type The attribute type.
+	 */
+	public void addBinding(AttributeType type) {
+		bindings().put(type.getBinding(), type);
+	}
+	
+	/**
+	 * Specifies a number of attribute type bindings.
+	 * 
+	 * @param schema The schema containing the attribute types.
+	 * 
+	 * @see {@link #addBinding(AttributeType)}.
+	 */
+	public void addBindings( Schema schema ) {
+		for (Iterator itr = schema.values().iterator(); itr.hasNext();) {
+			AttributeType type = (AttributeType) itr.next();
+			addBinding(type);
+		}
+	}
+	
+	/**
+	 * Specifies a number of attribute type bindings clearing out all existing
+	 * bindings.
+	 * 
+	 * @param schema The schema contianing attribute types.
+	 * 
+	 * @see {@link #addBinding(AttributeType)}.
+	 */
+	public void setBindings( Schema schema ) {
+		bindings().clear();
+		addBindings( schema );
+	}
+		
+	// per attribute methods
+	//
+	/**
+	 * Sets the minOccurs of the next attribute added to the feature type.
+	 * <p>
+	 * This value is reset after a call to {@link #add(String, Class)}
+	 * </p>
+	 */
+	public SimpleFeatureTypeBuilder minOccurs( int minOccurs ) {
+		attributeBuilder.setMinOccurs(minOccurs);
+		return this;
+	}
+	/**
+	 * Sets the maxOccurs of the next attribute added to the feature type.
+	 * <p>
+	 * This value is reset after a call to {@link #add(String, Class)}
+	 * </p>
+	 */
+	public SimpleFeatureTypeBuilder maxOccurs( int maxOccurs ) {
+		attributeBuilder.setMaxOccurs(maxOccurs);
+		return this;
+	}
+	/**
+	 * Sets the nullability of the next attribute added to the feature type.
+	 * <p>
+	 * This value is reset after a call to {@link #add(String, Class)}
+	 * </p>
+	 */
+	public SimpleFeatureTypeBuilder nillable( boolean isNillable ) {
+		attributeBuilder.setNillable(isNillable);
+		return this;
+	}
+	
+	/**
+	 * Sets the default value of the next attribute added to the feature type.
+	 * <p>
+	 * This value is reset after a call to {@link #add(String, Class)}
+	 * </p>
+	 */
+	public SimpleFeatureTypeBuilder defaultValue( Object defaultValue ) {
+		attributeBuilder.setDefaultValue( defaultValue );
+		return this;
+	}
+	/**
+	 * Sets the crs of the next attribute added to the feature type.
+	 * <p>
+	 * This only applies if the attribute added is geometric.
+	 * </p>
+	 * <p>
+	 * This value is reset after a call to {@link #add(String, Class)}
+	 * </p>
+	 */
+	public SimpleFeatureTypeBuilder crs( CoordinateReferenceSystem crs ) {
+		attributeBuilder.setCRS(crs);
+		return this;
+	}
+		
+	/**
+	 * Sets all the attribute specific state from a single descriptor.
+	 * <p>
+	 * This method is convenience for:
+	 * <code>
+	 * builder.minOccurs( descriptor.getMinOccurs() ).maxOccurs( descriptor.getMaxOccurs() )
+	 *     .nillable( descriptor.isNillable() )...
+	 * </code>
+	 * </p>
+	 */
+	public SimpleFeatureTypeBuilder descriptor( AttributeDescriptor descriptor ) {
+	    minOccurs( descriptor.getMinOccurs() );
+	    maxOccurs( descriptor.getMaxOccurs() );
+	    nillable( descriptor.isNillable() );
+	    //namespaceURI( descriptor.getName().getNamespaceURI() );
+	    defaultValue( descriptor.getDefaultValue() );
+	    
+	    if ( descriptor instanceof GeometryDescriptor ) {
+	        crs( ( (GeometryDescriptor) descriptor).getCoordinateReferenceSystem() );
+	    }
+	    
+	    return this;
+	}
+	
+	/**
+	 * Adds a new attribute w/ provided name and class.
+	 * 
+	 * <p>
+	 * The provided class is used to locate an attribute type binding previously 
+	 * specified by {@link #addBinding(AttributeType)},{@link #addBindings(Schema)}, 
+	 * or {@link #setBindings(Schema)}. 
+	 * </p>
+	 * <p>
+	 * If not such binding exists then an attribute type is created on the fly.
+	 * </p>
+	 * @param name The name of the attribute.
+	 * @param bind The class the attribute is bound to.
+	 * 
+	 */
+	public void add(String name, Class binding) {
+
+	    AttributeDescriptor descriptor = null;
+	    
+	    attributeBuilder.setBinding(binding);
+        attributeBuilder.setName(name);
+        
+		//check if this is the name of the default geomtry, in that case we 
+		// better make it a geometry type
+		//also check for jts geometry, if we ever actually get to a point where a
+        // feature can be backed by another geometry model (like iso), we need 
+        // to remove this check
+        //
+        if ( ( defaultGeometry != null && defaultGeometry.equals( name ) ) 
+            || Geometry.class.isAssignableFrom(binding) ) {
+		
+            //if no crs was set, set to the global
+            if ( !attributeBuilder.isCRSSet() ) {
+                attributeBuilder.setCRS(crs);
+            }
+            
+            GeometryType type = attributeBuilder.buildGeometryType();
+            descriptor = attributeBuilder.buildDescriptor(name, type);
+		}
+        else {
+            AttributeType type = attributeBuilder.buildType();
+            descriptor = attributeBuilder.buildDescriptor(name, type );
+        }
+		
+        
+		attributes().add(descriptor);
+	}
+	
+	/**
+	 * Adds a descriptor directly to the builder.
+	 * <p>
+	 * Use of this method is discouraged. Consider using {@link #add(String, Class)}. 
+	 * </p>
+	 */
+	public void add( AttributeDescriptor descriptor ) {
+	    attributes().add(descriptor);
+	}
+		
+    /**
+     * Adds a list of descriptors directly to the builder.
+     * <p>
+     * Use of this method is discouraged. Consider using {@link #add(String, Class)}.
+     * </p>
+     */
+    public void addAll( List<AttributeDescriptor>  descriptors ) {
+        if(descriptors != null)
+            for ( AttributeDescriptor ad : descriptors ) {
+                add( ad );
+            }
+    }
+	/**
+     * Adds an array of descriptors directly to the builder.
+     * <p>
+     * Use of this method is discouraged. Consider using {@link #add(String, Class)}.
+     * </p>
+     */
+	public void addAll( AttributeDescriptor[] descriptors ) {
+            if (descriptors != null) {
+	        for ( AttributeDescriptor ad : descriptors ) {
+	            add( ad );
+                }
+	    }
+	}
+		
+	/**
+	 * Builds a feature type from compiled state.
+	 * <p>
+	 * After the type is built the running list of attributes is cleared.
+	 * </p>
+	 * @return The built feature type.
+	 */
+	public SimpleFeatureType buildFeatureType() {
+	    GeometryDescriptor defGeom = null;
+		
+		//was a default geometry set?
+		if ( this.defaultGeometry != null ) {
+			List<AttributeDescriptor> atts = attributes();
+			for ( int i = 0; i < atts.size(); i++) {
+				AttributeDescriptor att = atts.get(i);
+				if ( this.defaultGeometry.equals( att.getName().getLocalPart() ) ) {
+					//ensure the attribute is a geometry attribute
+					if ( !(att instanceof GeometryDescriptor ) ) {
+						attributeBuilder.init( att );
+						attributeBuilder.setCRS(crs);
+						GeometryType type = attributeBuilder.buildGeometryType();						
+						att = attributeBuilder.buildDescriptor(att.getName(),type);
+						atts.set( i, att );
+					}
+					defGeom = (GeometryDescriptor)att;
+					break;
+				}
+			}
+			
+			if (defGeom == null) {
+			    String msg = "'" + this.defaultGeometry + " specified as default" +
+		    		" but could find no such attribute.";
+			    throw new IllegalArgumentException( msg );
+			}
+		}
+		
+		if ( defGeom == null ) {
+			//none was set by name, look for first geometric type
+			for ( AttributeDescriptor att : attributes() ) {
+				if ( att instanceof GeometryDescriptor ) {
+					defGeom = (GeometryDescriptor) att;
+					break;
+				}
+			}
+		}
+		
+		SimpleFeatureType built = factory.createSimpleFeatureType(
+			name(), attributes(), defGeom, isAbstract,
+			restrictions(), superType, description);
+		
+		init();
+		return built;
+	}
+	
+	// Internal api available for subclasses to override
+	
+	/**
+	 * Creates a new list instance, this default impelementation returns {@link ArrayList}.
+	 */
+	protected List newList() {
+		return new ArrayList();
+	}
+	
+	/**
+	 * Creates a new map instance, this default implementation returns {@link HashMap}
+	 */
+	protected Map newMap() {
+		return new HashMap();
+	}
+		
+	// Helper methods, 
+	//
+	/**
+	 * Naming: Accessor which returns type name as follows:
+	 * <ol>
+	 * <li>If <code>typeName</code> has been set, its value is returned.
+	 * <li>If <code>name</code> has been set, it + <code>namespaceURI</code>
+	 * are returned.
+	 * </ol>
+	 * 
+	 */
+	protected Name name() {
+		if (local == null)
+			return null;
+		
+		return new NameImpl(uri, local);
+	}
+
+	/**
+	 * Accessor for attributes.
+	 */
+	protected List<AttributeDescriptor> attributes() {
+		if (attributes == null) {
+			attributes = newList();
+		}
+		return attributes;
+	}
+	/**
+	 * Accessor for restrictions.
+	 */
+	protected List<Filter> restrictions(){
+		if (restrictions == null) {
+			restrictions = newList();
+		}
+		return restrictions;		
+	}
+	/**
+	 * Accessor for bindings.
+	 */
+	protected Map bindings() {
+		if (bindings == null) {
+			bindings = newMap();
+		}
+		return bindings;
+	}
+		
+	/**
+	 * Create a SimpleFeatureType containing just the descriptors indicated.
+	 * @param original SimpleFeatureType
+	 * @param types name of types to include in result
+	 * @return SimpleFeatureType containing just the types indicated by name
+	 */
+	public static SimpleFeatureType retype( SimpleFeatureType original, String[] types ) {
+	    SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();
+	    
+	    //initialize the builder
+	    b.init( original );
+	    
+	    //clear the attributes
+	    b.attributes().clear();
+	    
+	    //add attributes in order
+	    for ( int i = 0; i < types.length; i++ ) {
+	        b.add( original.getDescriptor( types[i] ) );
+	    }
+	    
+	    return b.buildFeatureType();
+	}
+	
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleFeatureTypeImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleFeatureTypeImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleFeatureTypeImpl.java	(revision 28000)
@@ -0,0 +1,140 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2009, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.simple;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.feature.type.FeatureTypeImpl;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+import org.opengis.util.InternationalString;
+
+/**
+ * Implementation fo SimpleFeatureType, subtypes must be atomic and are stored
+ * in a list.
+ * 
+ * @author Justin
+ * @author Ben Caradoc-Davies, CSIRO Exploration and Mining
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/simple/SimpleFeatureTypeImpl.java $
+ */
+public class SimpleFeatureTypeImpl extends FeatureTypeImpl implements
+        SimpleFeatureType {
+
+    // list of types
+    List<AttributeType> types = null;
+
+    Map<String, Integer> index;
+
+    @SuppressWarnings("unchecked")
+    public SimpleFeatureTypeImpl(Name name, List<AttributeDescriptor> schema,
+            GeometryDescriptor defaultGeometry, boolean isAbstract,
+            List<Filter> restrictions, AttributeType superType,
+            InternationalString description) {
+        // Note intentional circumvention of generics type checking;
+        // this is only valid if schema is not modified.
+        super(name, (List) schema, defaultGeometry, isAbstract, restrictions,
+                superType, description);
+        index = buildIndex(this);
+    }
+
+    /**
+     * @see org.opengis.feature.simple.SimpleFeatureType#getAttributeDescriptors()
+     */
+    @SuppressWarnings("unchecked")
+    public final List<AttributeDescriptor> getAttributeDescriptors() {
+        // Here we circumvent the generics type system. Because we provide the schema and know it is
+        // copied into an ArrayList in ComplexTypeImpl, this must work. Ugly, but then so are simple
+        // features.
+        return (List) getDescriptors();
+    }
+
+    public List<AttributeType> getTypes() {
+        if (types == null) {
+            synchronized (this) {
+                if (types == null) {
+                    types = new ArrayList<AttributeType>();
+                    for (AttributeDescriptor ad : getAttributeDescriptors()) {
+                        types.add(ad.getType());
+                    }
+                }
+            }
+        }
+        return types;
+    }
+
+    public AttributeType getType(int index) {
+        return getTypes().get(index);
+    }
+
+    public AttributeDescriptor getDescriptor(Name name) {
+        return (AttributeDescriptor) super.getDescriptor(name);
+    }
+
+    public AttributeDescriptor getDescriptor(String name) {
+        return (AttributeDescriptor) super.getDescriptor(name);
+    }
+
+    public AttributeDescriptor getDescriptor(int index) {
+        return getAttributeDescriptors().get(index);
+    }
+
+    public int indexOf(String name) {
+        Integer idx = index.get(name);
+        if(idx != null) {
+            return idx.intValue();
+        } else {
+            return -1;
+        }
+    }
+
+    public int getAttributeCount() {
+        return getAttributeDescriptors().size();
+    }
+
+    public String getTypeName() {
+        return getName().getLocalPart();
+    }
+
+    /**
+     * Builds the name -> position index used by simple features for fast attribute lookup
+     * @param featureType
+     * @return
+     */
+    static Map<String, Integer> buildIndex(SimpleFeatureType featureType) {
+        // build an index of attribute name to index
+        Map<String, Integer> index = new HashMap<String, Integer>();
+        int i = 0;
+        for (AttributeDescriptor ad : featureType.getAttributeDescriptors()) {
+            index.put(ad.getLocalName(), i++);
+        }
+        if (featureType.getGeometryDescriptor() != null) {
+            index.put(null, index.get(featureType.getGeometryDescriptor()
+                    .getLocalName()));
+        }
+        return index;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleSchema.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleSchema.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/simple/SimpleSchema.java	(revision 28000)
@@ -0,0 +1,234 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.simple;
+
+import java.math.BigInteger;
+import java.net.URI;
+import java.sql.Date;
+import java.sql.Timestamp;
+import java.util.Collections;
+
+import javax.xml.namespace.QName;
+
+import org.geotools.feature.NameImpl;
+import org.geotools.feature.type.FeatureTypeFactoryImpl;
+import org.geotools.feature.type.SchemaImpl;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.FeatureTypeFactory;
+import org.opengis.feature.type.GeometryType;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.MultiLineString;
+import com.vividsolutions.jts.geom.MultiPoint;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+
+/**
+ * Schema containing a set of "simple" types. 
+ * <p>
+ * This schema is used to create features with simple content. It contains 
+ * attribute types which correspond to xml schema types from the xml schema 
+ * and gml namespaces.
+ * </p>
+ * <p>
+ * The attribute types in this schema maintain a unique mapping to java classes
+ * so it can be used to map from java class to attribute type and vice versa.
+ * </p>
+ * 
+ * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/simple/SimpleSchema.java $
+ */
+public class SimpleSchema extends SchemaImpl {
+   
+	//internal factory
+	private static FeatureTypeFactory factory = new FeatureTypeFactoryImpl();
+	
+	//schema namespace
+	public static final String NAMESPACE = "http://www.geotools.org/simple";
+	//
+    // Builtin Java Types
+    //
+    /** BOOLEAN to Boolean.class */        
+    public static final AttributeType BOOLEAN = factory.createAttributeType(
+		new NameImpl(NAMESPACE,"boolean"), Boolean.class, false, false,
+		Collections.EMPTY_LIST, (AttributeType) null, null 
+	);
+    /** STRING to String.class */ 
+    public static final AttributeType STRING = factory.createAttributeType(
+        new NameImpl(NAMESPACE,"string"), String.class, false,
+        false,Collections.EMPTY_LIST, (AttributeType) null, null
+    );
+    /** QNAME to byte[].class */
+    public static final AttributeType QNAME = factory.createAttributeType(
+        new NameImpl(NAMESPACE,"QName"), QName.class, false,
+        false,Collections.EMPTY_LIST, (AttributeType) null, null
+    );
+    /** QNAME to byte[].class */
+    public static final AttributeType URI = factory.createAttributeType(
+        new NameImpl(NAMESPACE,"anyUri"), URI.class, false,
+        false,Collections.EMPTY_LIST, (AttributeType) null, null
+    );
+    //
+    // Numerics
+    //
+//    /** NUMBER to Number.class */    
+//    public static final AttributeType NUMBER = factory.createAttributeType(
+//        new Name(NAMESPACE,"number"), Number.class, false,
+//        false,Collections.EMPTY_LIST, (AttributeType) null, null
+//    );
+    /**
+     * INTEGER to BigInteger
+     */
+    public static final AttributeType INTEGER = factory.createAttributeType(
+        new NameImpl(NAMESPACE,"integer"), BigInteger.class, false,
+        false,Collections.EMPTY_LIST,null, null
+    );
+    /**
+     * FLOAT to java Float.class
+     */      
+    public static final AttributeType FLOAT = factory.createAttributeType(
+        new NameImpl(NAMESPACE,"float"), Float.class, false,
+        false,Collections.EMPTY_LIST,null, null
+    );
+    /** DOUBLE to Double.class */
+    public static final AttributeType DOUBLE = factory.createAttributeType(
+        new NameImpl(NAMESPACE,"double"), Double.class, false,
+        false,Collections.EMPTY_LIST,null, null
+    );
+    /** LONG to Long.class */
+    public static final AttributeType LONG = factory.createAttributeType(
+        new NameImpl(NAMESPACE,"long"), Long.class, false,
+        false,Collections.EMPTY_LIST,null, null
+    );
+    /** SHORT to Short.class */
+    public static final AttributeType SHORT = factory.createAttributeType(
+        new NameImpl(NAMESPACE,"short"), Short.class, false,
+        false,Collections.EMPTY_LIST,null, null
+    );
+    /** BYTE to Byte.class */
+    public static final AttributeType BYTE = factory.createAttributeType(
+        new NameImpl(NAMESPACE,"byte"), Byte.class, false,
+        false,Collections.EMPTY_LIST,null, null
+    );
+
+    //
+    // TEMPORAL
+    //
+    /** DATE to java.sql.Date.class */
+    public static final AttributeType DATE = factory.createAttributeType(
+        new NameImpl(NAMESPACE,"date"), Date.class, false,
+        false,Collections.EMPTY_LIST, (AttributeType) null, null
+    );
+    /**
+     * DATETIME to java.sql.Timestamp
+     * <p>
+     * Data and a Time like a timestamp.
+     */    
+    public static final AttributeType DATETIME = factory.createAttributeType(
+        new NameImpl(NAMESPACE,"datetime"), Timestamp.class, false,
+        false,Collections.EMPTY_LIST, (AttributeType) null, null
+    );
+    
+    //
+    // Geomtries
+    //
+    /** Geometry to Geometry.class */
+    public static final GeometryType GEOMETRY = factory.createGeometryType(
+        new NameImpl(NAMESPACE,"GeometryPropertyType"), Geometry.class, null, false, false, 
+        Collections.EMPTY_LIST, null, null
+    );
+    /** POINT (extends GEOMETRY) binds to Point.class */    
+    public static final GeometryType POINT = factory.createGeometryType(
+        new NameImpl(NAMESPACE,"PointPropertyType"), Point.class, null, false, false, 
+        Collections.EMPTY_LIST, null, null
+    );
+    /** LINESTRING (extends GEOMETRY) binds to LineString.class */        
+    public static final GeometryType LINESTRING = factory.createGeometryType(
+        new NameImpl(NAMESPACE,"LineStringPropertyType"), LineString.class, null, false, 
+        false, Collections.EMPTY_LIST, null, null
+    );
+//    /** LINEARRING (extends GEOMETRY) binds to LinearRing.class */            
+//    public static final GeometryType LINEARRING = factory.createGeometryType(
+//        new Name(NAMESPACE,"LinearRingPropertyType"), LinearRing.class, null, false, 
+//        false, Collections.EMPTY_LIST, LINESTRING, null
+//    );
+    /**  POLYGON (extends GEOMETRY) binds to Polygon.class */            
+    public static final GeometryType POLYGON = factory.createGeometryType(
+        new NameImpl(NAMESPACE,"PolygonPropertyType"), Polygon.class, null, false, 
+        false, Collections.EMPTY_LIST, null, null
+    );
+    /**  MULTIGEOMETRY (extends GEOMETRY) binds to GeometryCollection.class */                
+    public static final GeometryType MULTIGEOMETRY = factory.createGeometryType(
+        new NameImpl(NAMESPACE,"MultiGeometryPropertyType"), GeometryCollection.class, null,
+        false, false, Collections.EMPTY_LIST, null, null
+    );
+    
+    /**  MULTIPOINT (extends MULTIGEOMETRY) binds to MultiPoint.class */            
+    public static final GeometryType MULTIPOINT = factory.createGeometryType(
+        new NameImpl(NAMESPACE,"MultiPointPropertyType"), MultiPoint.class, null, false, false, 
+        Collections.EMPTY_LIST, null, null
+    );
+    
+    /**  MULTILINESTRING (extends MULTIGEOMETRY) binds to MultiLineString.class */            
+    public static final GeometryType MULTILINESTRING = factory.createGeometryType(
+        new NameImpl(NAMESPACE,"MultiLineStringPropertyType"), MultiLineString.class, null, 
+        false, false, Collections.EMPTY_LIST, null, null
+    );
+    
+    /** MULTIPOLYGON (extends MULTIGEOMETRY) binds to MultiPolygon.class */            
+    public static final GeometryType MULTIPOLYGON = factory.createGeometryType(
+        new NameImpl(NAMESPACE,"MultiPolytonPropertyType"), MultiPolygon.class, null, false, 
+        false, Collections.EMPTY_LIST, MULTIGEOMETRY, null
+    );
+    
+    public SimpleSchema() {
+        super(NAMESPACE);
+        
+        put(INTEGER.getName(),INTEGER);
+        put(DOUBLE.getName(),DOUBLE);
+        put(LONG.getName(),LONG);
+        put(FLOAT.getName(),FLOAT);
+        put(SHORT.getName(),SHORT);
+        put(BYTE.getName(),BYTE);
+        //put(NUMBER.getName(),NUMBER);
+        put(STRING.getName(),STRING);
+        put(BOOLEAN.getName(),BOOLEAN);
+        put(QNAME.getName(),QNAME);
+        put(URI.getName(),URI);
+        
+        put(DATE.getName(),DATE);
+        put(DATETIME.getName(),DATETIME);
+        
+        put(GEOMETRY.getName(),GEOMETRY);
+        put(POINT.getName(),POINT);
+        put(LINESTRING.getName(),LINESTRING);
+        //put(LINEARRING.getName(),LINEARRING);
+        put(POLYGON.getName(),POLYGON);
+        put(MULTIGEOMETRY.getName(),MULTIGEOMETRY);
+        put(MULTIGEOMETRY.getName(),MULTIGEOMETRY);
+        put(MULTIPOINT.getName(),MULTIPOINT);
+        put(MULTILINESTRING.getName(),MULTILINESTRING);
+        put(MULTIPOLYGON.getName(),MULTIPOLYGON);
+        
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/AttributeDescriptorImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/AttributeDescriptorImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/AttributeDescriptorImpl.java	(revision 28000)
@@ -0,0 +1,106 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.type;
+
+import java.util.Map;
+
+import org.geotools.resources.Classes;
+import org.geotools.util.Utilities;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.Name;
+
+public class AttributeDescriptorImpl extends PropertyDescriptorImpl 
+	implements AttributeDescriptor {
+	
+	protected final Object defaultValue;
+	
+	public AttributeDescriptorImpl(
+		AttributeType type, Name name, int min, int max, boolean isNillable, Object defaultValue
+	) {
+	    super(type,name,min,max,isNillable);
+		
+		this.defaultValue = defaultValue;
+	}
+	
+	public AttributeType getType() {
+		return (AttributeType) super.getType();
+	}
+    
+	public Object getDefaultValue() {
+		return defaultValue;
+	}
+	
+    public int hashCode(){
+		return super.hashCode() ^ 
+		    (defaultValue != null ? defaultValue.hashCode() : 0 ); 
+	}
+	
+	public boolean equals(Object o){
+		if(!(o instanceof AttributeDescriptorImpl))
+			return false;
+		
+		AttributeDescriptorImpl d = (AttributeDescriptorImpl)o;
+	
+		return super.equals(o) && Utilities.deepEquals( defaultValue, d.defaultValue );
+	}	
+	
+	public String toString() {
+	    StringBuffer sb = new StringBuffer(Classes.getShortClassName(this));
+        sb.append(" ");
+        sb.append( getName() );
+        if( type != null ){
+            sb.append( " <" );
+            sb.append( type.getName().getLocalPart()  );
+            sb.append(":");
+            sb.append( Classes.getShortName( type.getBinding() ));
+            sb.append( ">" );
+        }
+        if( isNillable  ){
+            sb.append( " nillable" );            
+        }
+        if( minOccurs == 1 && maxOccurs == 1 ){
+            // ignore the 1:1
+        }
+        else {
+            sb.append( " " );
+            sb.append( minOccurs );
+            sb.append(  ":" );
+            sb.append( maxOccurs );            
+        }
+        if( defaultValue != null ){
+            sb.append( "\ndefault= " );
+            sb.append( defaultValue );
+        }
+        if( userData != null && !userData.isEmpty() ){
+            sb.append("\nuserData=(");
+            for( Map.Entry entry : userData.entrySet() ){
+                sb.append("\n\t");
+                sb.append( entry.getKey() );
+                sb.append( " ==> " );
+                sb.append( entry.getValue() );
+            }
+            sb.append(")");
+        }
+        return sb.toString();
+	}
+
+	public String getLocalName() {
+		return getName().getLocalPart();
+	}
+	
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/AttributeTypeImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/AttributeTypeImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/AttributeTypeImpl.java	(revision 28000)
@@ -0,0 +1,132 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.type;
+
+import java.util.List;
+
+import org.geotools.resources.Classes;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+import org.opengis.util.InternationalString;
+
+/**
+ * Base class for attribute types.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/type/AttributeTypeImpl.java $
+ */
+public class AttributeTypeImpl extends PropertyTypeImpl implements AttributeType {
+	
+	final protected boolean identified;
+
+	public AttributeTypeImpl(
+		Name name, Class<?> binding, boolean identified, boolean isAbstract,
+		List<Filter> restrictions, AttributeType superType, InternationalString description
+	) {
+		super(name, binding, isAbstract, restrictions, superType, description);
+		
+		this.identified = identified;
+	}
+
+	public boolean isIdentified() {
+		return identified;
+	}
+	
+	public AttributeType getSuper() {
+	    return (AttributeType) super.getSuper();
+	}
+	
+	/**
+	 * Override of hashcode.
+	 */
+	public int hashCode() {
+	    return super.hashCode() ^ Boolean.valueOf(identified).hashCode();
+	   
+	}
+	
+	/**
+	 * Override of equals.
+	 * 
+	 * @param other
+	 *            the object to be tested for equality.
+	 * 
+	 * @return whether other is equal to this attribute Type.
+	 */
+	public boolean equals(Object other) {
+	    if(this == other)
+            return true;
+	    
+		if (!(other instanceof AttributeType)) {
+			return false;
+		}
+
+		if (!super.equals(other)) 
+			return false;
+		
+		AttributeType att = (AttributeType) other;
+		
+		if (identified != att.isIdentified()) {
+			return false;
+		}
+	
+		return true;
+	}
+	
+    public String toString() {
+        StringBuffer sb = new StringBuffer(Classes.getShortClassName(this));
+        sb.append(" ");
+        sb.append( getName() );
+        if( isAbstract() ){
+            sb.append( " abstract" );           
+        }
+        if( isIdentified() ){
+            sb.append( " identified" );
+        }
+        if( superType != null ){
+            sb.append( " extends ");
+            sb.append( superType.getName().getLocalPart() );
+        }
+        if( binding != null ){
+            sb.append( "<" );
+            sb.append( Classes.getShortName( binding ) );
+            sb.append( ">" );
+        }
+        if( description != null ){
+            sb.append("\n\tdescription=");
+            sb.append( description );            
+        }
+        if( restrictions != null && !restrictions.isEmpty() ){
+            sb.append("\nrestrictions=");
+            boolean first = true;
+            for( Filter filter : restrictions ){
+                if( first ){
+                    first = false;
+                }
+                else {
+                    sb.append( " AND " );
+                }
+                sb.append( filter );
+            }
+        }
+        return sb.toString();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/BasicFeatureTypes.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/BasicFeatureTypes.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/BasicFeatureTypes.java	(revision 28000)
@@ -0,0 +1,124 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.type;
+
+import java.util.Collections;
+import java.util.logging.Level;
+
+import org.geotools.feature.NameImpl;
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
+import org.geotools.feature.simple.SimpleFeatureTypeImpl;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+/**
+ * Defines required attributes for Annotations.
+ *
+ * <p>
+ * Annotations represent a text based geographic feature.
+ * The geometry stored in the feature indicates where the
+ * text should be drawn and the attribute indicated by
+ * the {@link #ANNOTATION_ATTRIBUTE_NAME} attribute holds
+ * the text to be displayed for the feature.
+ * </p>
+ *
+ * <p>Example:
+ * <pre>
+ *   if ( feature.getFeatureType().isDescendedFrom( AnnotationFeatureType.ANNOTATION ) )
+ *   {
+ *     String attributeName = (String)feature.getAttribute( AnnotationFeatureType.ANNOTATION_ATTRIBUTE_NAME );
+ *     String annotationText = (String)feature.getAttribute( attributeName );
+ *     ... // Do something with the annotation text and feature
+ *   }
+ * </pre>
+ * </p>
+ *
+ * @author John Meagher
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/type/BasicFeatureTypes.java $
+ */
+public class BasicFeatureTypes
+{
+
+	/**
+	 * The base type for all features
+	 */
+	public static final SimpleFeatureType FEATURE;
+	
+    /**
+     * The FeatureType reference that should be used for Polygons
+     */
+    public static final SimpleFeatureType POLYGON;
+    
+    /**
+     * The FeatureType reference that should be used for Points
+     */
+    public static final SimpleFeatureType POINT;
+    
+    /**
+     * The FeatureType reference that should be used for Lines
+     */
+    public static final SimpleFeatureType LINE;
+
+    /**
+     * The attribute name used to store the geometry
+     */
+    public static final String GEOMETRY_ATTRIBUTE_NAME = "the_geom";
+
+    /**
+     * Default namespace used for our POINT, LINE, POLYGON types.
+     */
+    public static final String DEFAULT_NAMESPACE = "http://www.opengis.net/gml";
+    
+    // Static initializer for the tyoe variables
+    static {
+        SimpleFeatureType tmpPoint = null;
+        SimpleFeatureType tmpPolygon = null;
+        SimpleFeatureType tmpLine = null;
+        
+        // Feature is the base of everything else, must be created directly instead
+    	// of going thru the builder because the builder assumes it as the default base type
+    	FEATURE = new SimpleFeatureTypeImpl(new NameImpl("Feature"), 
+    			Collections.EMPTY_LIST, null, true, 
+    			Collections.EMPTY_LIST, null, null);
+        
+        try {
+            SimpleFeatureTypeBuilder build = new SimpleFeatureTypeBuilder();
+            
+            //AttributeDescriptor[] types =  new AttributeDescriptor[] {};
+            
+            build.setName( "pointFeature" );
+            tmpPoint = build.buildFeatureType();
+            
+            build.setName( "lineFeature" );
+            tmpLine = build.buildFeatureType();
+            
+            build.setName( "polygonFeature" );
+            tmpPolygon = build.buildFeatureType();
+        } catch (Exception ex) {
+            org.geotools.util.logging.Logging.getLogger( "org.geotools.feature.type.BasicFeatureTypes" ).log(
+               Level.SEVERE, "Error creating basic feature types", ex );
+        }
+        POINT = tmpPoint;
+        LINE = tmpLine;
+        POLYGON = tmpPolygon;
+    }
+
+    /**
+     * Noone else should be able to build me.
+     */
+    private BasicFeatureTypes(){}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/ComplexTypeImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/ComplexTypeImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/ComplexTypeImpl.java	(revision 28000)
@@ -0,0 +1,191 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.type;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.feature.NameImpl;
+import org.geotools.resources.Classes;
+import org.opengis.feature.Property;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.ComplexType;
+import org.opengis.feature.type.Name;
+import org.opengis.feature.type.PropertyDescriptor;
+import org.opengis.filter.Filter;
+import org.opengis.util.InternationalString;
+
+/**
+ * Base class for complex types.
+ * 
+ * @author gabriel
+ * @author Ben Caradoc-Davies, CSIRO Exploration and Mining
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/type/ComplexTypeImpl.java $
+ */
+public class ComplexTypeImpl extends AttributeTypeImpl implements ComplexType {
+
+        /**
+         * Immutable copy of the properties list with which we were constructed.
+         */
+        final private Collection<PropertyDescriptor> properties;
+        
+	/**
+	 * Map to locate properties by name.
+	 */
+	final private Map<Name, PropertyDescriptor> propertyMap;
+	
+	public ComplexTypeImpl(
+		Name name, Collection<PropertyDescriptor> properties, boolean identified, 
+		boolean isAbstract, List<Filter> restrictions, AttributeType superType, 
+		InternationalString description
+	) {
+	super(name, Collection.class, identified, isAbstract, restrictions, superType, description);
+	List<PropertyDescriptor> localProperties;
+	Map<Name, PropertyDescriptor> localPropertyMap;
+	if (properties == null) {
+	    localProperties = Collections.emptyList();
+            localPropertyMap = Collections.emptyMap();
+	} else {
+	    localProperties = new ArrayList<PropertyDescriptor>(properties);
+            localPropertyMap = new HashMap<Name, PropertyDescriptor>();
+            for (PropertyDescriptor pd : properties) {
+                if( pd == null ){
+                    // descriptor entry may be null if a request was made for a property that does not exist
+                    throw new NullPointerException("PropertyDescriptor is null - did you request a property that does not exist?");
+                }
+                localPropertyMap.put(pd.getName(), pd);
+            }
+            
+        }
+	this.properties = Collections.unmodifiableList(localProperties);
+        this.propertyMap = Collections.unmodifiableMap(localPropertyMap);
+    }
+
+	public Class<Collection<Property>> getBinding() {
+	    return (Class<Collection<Property>>) super.getBinding();
+	}
+	
+	public Collection<PropertyDescriptor> getDescriptors() {
+		return properties;
+	}
+	
+	public PropertyDescriptor getDescriptor(Name name) {
+	    return propertyMap.get(name);
+	}
+	
+    public PropertyDescriptor getDescriptor(String name) {
+        PropertyDescriptor result = getDescriptor(new NameImpl(name));
+        if (result == null) {
+            // look in the same namespace as the complex type
+            result = getDescriptor(new NameImpl(getName().getNamespaceURI(), name));
+            if (result == null) {
+                // full scan
+                for (PropertyDescriptor pd : properties) {
+                    if (pd.getName().getLocalPart().equals(name)) {
+                        return pd;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+	
+	public boolean equals(Object o){
+	    if(this == o) {
+	        return true;
+	    }
+	    if(!super.equals(o)){
+	        return false;
+	    }
+	    if (getClass() != o.getClass()) {
+	        return false;
+	    }
+	    ComplexTypeImpl other = (ComplexTypeImpl)o;
+	    if ( !properties.equals(other.properties) ) {
+	        return false;
+	    }
+	    return true;
+	}
+    
+	public int hashCode(){
+	    return 59 * super.hashCode() + properties.hashCode();
+	}
+    
+	public String toString() {
+		StringBuffer sb = new StringBuffer(Classes.getShortClassName(this));
+		sb.append(" ");
+		sb.append( getName() );
+		if( isAbstract() ){
+			sb.append( " abstract" );			
+		}
+		if( isIdentified() ){
+			sb.append( " identified" );
+		}
+		if( superType != null ){
+		    sb.append( " extends ");
+			sb.append( superType.getName().getLocalPart() );
+		}
+		if( List.class.isAssignableFrom( binding )){
+			sb.append( "[" );
+		}
+		else {
+			sb.append( "(" );
+		}
+		boolean first = true;
+		for( PropertyDescriptor property : getDescriptors() ){
+			if( first ){
+				first = false;				
+			}
+			else {
+				sb.append( ",");
+			}
+			sb.append( property.getName().getLocalPart() );
+			sb.append( ":" );
+			sb.append( property.getType().getName().getLocalPart() );			
+		}
+		if( List.class.isAssignableFrom( binding )){
+			sb.append( "]" );
+		}
+		else {
+			sb.append( ")" );
+		}
+		if( description != null ){
+            sb.append("\n\tdescription=");
+            sb.append( description );            
+        }
+        if( restrictions != null && !restrictions.isEmpty() ){
+            sb.append("\nrestrictions=");
+            first = true;
+            for( Filter filter : restrictions ){
+                if( first ){
+                    first = false;
+                }
+                else {
+                    sb.append( " AND " );
+                }
+                sb.append( filter );
+            }
+        }
+		return sb.toString();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/FeatureTypeFactoryImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/FeatureTypeFactoryImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/FeatureTypeFactoryImpl.java	(revision 28000)
@@ -0,0 +1,91 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.type;
+
+import java.util.List;
+
+import org.geotools.feature.simple.SimpleFeatureTypeImpl;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.FeatureTypeFactory;
+import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.feature.type.GeometryType;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.util.InternationalString;
+
+/**
+ * This implementation is capable of creating a good default implementation of
+ * the Types used in the feature model.
+ * <p>
+ * The implementation focus here is on corretness rather then efficiency or even
+ * strict error messages. The code serves as a good example, but is not
+ * optimized for any particular use.
+ * </p>
+ * 
+ * @author Jody Garnett
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/type/FeatureTypeFactoryImpl.java $
+ */
+public class FeatureTypeFactoryImpl implements FeatureTypeFactory {
+
+	/** Rely on setter injection */
+	public FeatureTypeFactoryImpl() {
+	}
+
+	public AttributeDescriptor createAttributeDescriptor(AttributeType type,
+		Name name, int minOccurs, int maxOccurs, boolean isNillable, Object defaultValue) {
+		
+		return new AttributeDescriptorImpl(type, name, minOccurs, maxOccurs, isNillable,defaultValue);
+	}
+
+	public GeometryDescriptor createGeometryDescriptor(GeometryType type,
+	        Name name, int minOccurs, int maxOccurs, boolean isNillable,
+	        Object defaultValue) {
+	    return new GeometryDescriptorImpl(type, name, minOccurs, maxOccurs, isNillable, defaultValue);
+	}
+	
+	public AttributeType createAttributeType(Name name, Class binding,
+			boolean isIdentifiable, boolean isAbstract, List restrictions,
+			AttributeType superType, InternationalString description) {
+
+		return new AttributeTypeImpl(name, binding, isIdentifiable, isAbstract,
+				restrictions, superType, description);
+	}
+
+	public GeometryType createGeometryType(Name name, Class binding,
+			CoordinateReferenceSystem crs, boolean isIdentifiable,
+			boolean isAbstract, List restrictions, AttributeType superType,
+			InternationalString description) {
+
+		return new GeometryTypeImpl(name, binding, crs, isIdentifiable,
+				isAbstract, restrictions, superType, description);
+	}
+
+	public SimpleFeatureType createSimpleFeatureType(Name name,
+	        List<AttributeDescriptor> schema,
+	        GeometryDescriptor defaultGeometry, boolean isAbstract,
+	        List<Filter> restrictions, AttributeType superType,
+	        InternationalString description) {
+	    
+	    return new SimpleFeatureTypeImpl(name,schema,defaultGeometry,isAbstract,
+            restrictions,superType,description);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/FeatureTypeImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/FeatureTypeImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/FeatureTypeImpl.java	(revision 28000)
@@ -0,0 +1,121 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.type;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.geotools.util.Utilities;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.FeatureType;
+import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.feature.type.Name;
+import org.opengis.feature.type.PropertyDescriptor;
+import org.opengis.filter.Filter;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.util.InternationalString;
+
+/**
+ * 
+ * Base implementation of FeatureType.
+ * 
+ * @author gabriel
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/type/FeatureTypeImpl.java $
+ */
+public class FeatureTypeImpl extends ComplexTypeImpl implements FeatureType {
+	
+	private GeometryDescriptor defaultGeometry;
+	private CoordinateReferenceSystem crs;
+
+	public FeatureTypeImpl(
+		Name name, Collection<PropertyDescriptor> schema, GeometryDescriptor defaultGeometry, 
+		boolean isAbstract, List<Filter> restrictions, AttributeType superType, 
+		InternationalString description
+	) {
+		super(name, schema, true, isAbstract, restrictions, superType, description);
+		this.defaultGeometry = defaultGeometry;
+		
+		if ( defaultGeometry != null && 
+		        defaultGeometry.getType() == null)  {
+		    throw new IllegalArgumentException( "defaultGeometry must have a GeometryType");
+		}
+        
+	}
+
+	public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+	    if(crs == null) {
+    	    if ( getGeometryDescriptor() != null && getGeometryDescriptor().getType().getCoordinateReferenceSystem() != null) {
+                crs = defaultGeometry.getType().getCoordinateReferenceSystem();
+            }
+    	    if(crs == null) {
+        	    for (PropertyDescriptor property : getDescriptors()) {
+                    if ( property instanceof GeometryDescriptor ) {
+                        GeometryDescriptor geometry = (GeometryDescriptor) property;
+                        if ( geometry.getType().getCoordinateReferenceSystem() != null ) {
+                            crs = geometry.getType().getCoordinateReferenceSystem();
+                            break;
+                        }
+                    }
+                }
+    	    }
+	    }
+        
+        return crs;
+	}
+	
+	public GeometryDescriptor getGeometryDescriptor() {
+	    if (defaultGeometry == null) {
+            for (PropertyDescriptor property : getDescriptors()) {
+                if (property instanceof GeometryDescriptor ) {
+                    defaultGeometry = (GeometryDescriptor) property; 
+                    break;
+                }
+            }
+        }
+        return defaultGeometry;
+	}
+	
+	public boolean equals(Object o) {
+	    if(this == o) {
+	        return true;
+	    }
+	    if(!super.equals(o)){
+	        return false;
+	    }
+	    if (getClass() != o.getClass()) {
+            return false;
+        }
+	    FeatureType other = (FeatureType) o;
+	    if (!Utilities.equals( getGeometryDescriptor(), other.getGeometryDescriptor())) {
+	        return false;
+	    }
+	    return true;
+	}
+	
+	public int hashCode() {
+		int hashCode = super.hashCode();
+		
+		if ( defaultGeometry != null ) {
+			hashCode = hashCode ^ defaultGeometry.hashCode();
+		}
+		
+		return hashCode;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/GeometryDescriptorImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/GeometryDescriptorImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/GeometryDescriptorImpl.java	(revision 28000)
@@ -0,0 +1,44 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.type;
+
+import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.feature.type.GeometryType;
+import org.opengis.feature.type.Name;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+public class GeometryDescriptorImpl extends AttributeDescriptorImpl 
+    implements GeometryDescriptor {
+
+    public GeometryDescriptorImpl(GeometryType type, Name name, int min,
+            int max, boolean isNillable, Object defaultValue) {
+        super(type, name, min, max, isNillable, defaultValue);
+        
+    }
+
+    public GeometryType getType() {
+        return (GeometryType) super.getType();
+    }
+
+	public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+		return getType().getCoordinateReferenceSystem();
+	}
+
+	public String getLocalName() {
+		return getName().getLocalPart();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/GeometryTypeImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/GeometryTypeImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/GeometryTypeImpl.java	(revision 28000)
@@ -0,0 +1,51 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.type;
+
+import java.util.List;
+
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.GeometryType;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.Filter;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.util.InternationalString;
+
+/**
+ * AttributeType for hold geometry implementations, maintains CRS information.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/type/GeometryTypeImpl.java $
+ */
+public class GeometryTypeImpl extends AttributeTypeImpl implements GeometryType {
+
+	protected CoordinateReferenceSystem CRS;
+
+	public GeometryTypeImpl(
+		Name name, Class binding, CoordinateReferenceSystem crs, 
+		boolean identified, boolean isAbstract, List<Filter> restrictions, 
+		AttributeType superType, InternationalString description
+	) {
+		super(name, binding, identified, isAbstract, restrictions, superType, description);
+		CRS = crs;
+	}
+
+	public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+		return CRS;
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/ProfileImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/ProfileImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/ProfileImpl.java	(revision 28000)
@@ -0,0 +1,154 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.type;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.Name;
+import org.opengis.feature.type.Schema;
+
+/**
+ * A "sub" Schema used to select types for a specific use.
+ * <p>
+ * This class uses a custom key set to subset a parent Schema, and
+ * is used as the return type of {@link SchemaImpl.profile}.
+ * <p>
+ * This Schema is <b>not</b> mutable, serving only as a view, you
+ * may however define a more specific subset if needed.
+ * <p>
+ * Schema is often used to place limitation on expressed content
+ * (as in the case of the GML Level 0 Profile), or used to define
+ * a non conflicting set of "bindings" for the TypeBuilder(s).
+ * </p>
+ * @author Jody Garnett, Refractions Research Inc.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/type/ProfileImpl.java $
+ */
+public class ProfileImpl implements Schema {
+
+	/**
+	 * Parent Schema
+	 */
+	private Schema parent;
+	
+	/**
+	 * Keyset used by this profile (immutable).
+	 */
+	private Set<Name> profile;
+	
+	/**
+	 * Profile contents (created in a lazy fashion).
+	 */
+	private Map contents = null;
+	
+	/**
+	 * Subset parent schema with profile keys.
+	 * 
+	 * @param parent
+	 * @param profile
+	 */
+	public ProfileImpl( Schema parent, Set<Name> profile ){
+		this.parent = parent;
+		
+		this.profile = Collections.unmodifiableSet(profile);
+	}
+	
+	public Set<Name> keySet() {
+		return profile;
+	}
+
+	public String getURI() {
+		return parent.getURI();
+	}
+
+	public Schema profile(Set<Name> profile) {
+	    if( !this.profile.containsAll( profile ) ){
+	        Set<Name> set = new TreeSet<Name>( profile );
+	        set.removeAll( this.profile );
+	        throw new IllegalArgumentException("Unable to profile the following names: "+set );
+	    }
+	    return parent.profile( profile );
+	}
+
+	public int size() {
+		return profile.size();
+	}
+
+	public boolean isEmpty() {
+		return profile.isEmpty();
+	}
+
+	public boolean containsKey(Object key) {
+		return profile.contains( key );
+	}
+
+	public boolean containsValue(Object value) {
+		return values().contains( value );
+	}
+
+	public AttributeType get(Object key) {
+		if( profile.contains( key )){
+			return parent.get( key );
+		}
+		return null;
+	}
+
+	public AttributeType put(Name key, AttributeType value) {
+	    throw new UnsupportedOperationException("Profile not mutable");
+	}
+	
+	public AttributeType remove(Object key) {
+	 	throw new UnsupportedOperationException("Profile not mutable");
+	}
+
+	public void putAll(Map<? extends Name, ? extends AttributeType> t) {
+    	throw new UnsupportedOperationException("Profile not mutable");
+	}
+
+	public void clear() {
+	    throw new UnsupportedOperationException("Profile not mutable");
+	}
+
+	//public Collection values() {
+	public Collection<AttributeType> values() {
+	 	return contents().values();
+	}
+
+	//public Set<Name> entrySet() {
+	public Set<Entry<Name, AttributeType>> entrySet() {
+	 	return contents().entrySet();
+	}
+	
+	private synchronized Map<Name,AttributeType> contents(){
+		if( contents == null){
+			contents = new LinkedHashMap();
+			for( Iterator i=profile.iterator();i.hasNext();){
+				Object key = i.next();
+				contents.put( key, parent.get(key));
+			}
+		}
+		return contents;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/PropertyDescriptorImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/PropertyDescriptorImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/PropertyDescriptorImpl.java	(revision 28000)
@@ -0,0 +1,134 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.type;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.geotools.resources.Classes;
+import org.geotools.util.Utilities;
+import org.opengis.feature.type.Name;
+import org.opengis.feature.type.PropertyDescriptor;
+import org.opengis.feature.type.PropertyType;
+
+public class PropertyDescriptorImpl implements PropertyDescriptor {
+
+    final protected PropertyType type;
+    final protected Name name;
+    final protected int minOccurs;
+    final protected int maxOccurs;
+    final protected boolean isNillable;
+    final Map<Object, Object> userData;
+    
+    protected PropertyDescriptorImpl(PropertyType type, Name name, int min, int max, boolean isNillable) {
+        this.type = type;
+        this.name = name;
+        this.minOccurs = min;
+        this.maxOccurs = max;
+        this.isNillable = isNillable;
+        userData = new HashMap();
+        
+        if ( type == null ) {
+            throw new NullPointerException("type");
+        }
+        
+        if ( name == null ) {
+            throw new NullPointerException("name");
+        }
+                
+        if (max > 0 && (max < min) ) {
+            throw new IllegalArgumentException("max must be -1, or < min");
+        }
+    }
+    
+    public PropertyType getType() {
+        return type;
+    }
+    
+    public Name getName() {
+        return name;
+    }
+
+    public int getMinOccurs() {
+        return minOccurs;
+    }
+
+    public int getMaxOccurs() {
+        return maxOccurs;
+    }
+    
+    public boolean isNillable() {
+        return isNillable;
+    }
+    
+    public Map<Object, Object> getUserData() {
+        return userData;
+    }
+    
+    public boolean equals(Object obj) {
+        if (!(obj instanceof PropertyDescriptorImpl)) {
+            return false;
+        }
+        
+        PropertyDescriptorImpl other = (PropertyDescriptorImpl) obj;
+        return Utilities.equals(type,other.type) && 
+            Utilities.equals(name,other.name) && 
+            (minOccurs == other.minOccurs) && (maxOccurs == other.maxOccurs) &&
+            (isNillable == other.isNillable);
+    }
+    
+    public int hashCode() {
+        return (37 * minOccurs + 37 * maxOccurs ) ^ type.hashCode() ^ name.hashCode();
+    }
+
+    public String toString() {        
+        StringBuffer sb = new StringBuffer(Classes.getShortClassName(this));
+        sb.append(" ");
+        sb.append( getName() );
+        if( type != null ){
+            sb.append( " <" );
+            sb.append( type.getName().getLocalPart()  );
+            sb.append(":");
+            sb.append( Classes.getShortName( type.getBinding() ));
+            sb.append( ">" );
+        }
+        if( isNillable  ){
+            sb.append( " nillable" );            
+        }
+        if( minOccurs == 1 && maxOccurs == 1 ){
+            // ignore the 1:1
+        }
+        else {
+            sb.append( " " );
+            sb.append( minOccurs );
+            sb.append(  ":" );
+            sb.append( maxOccurs );
+        }
+        if( userData != null && !userData.isEmpty() ){
+            sb.append("\nuserData=(");
+            for( Map.Entry entry : userData.entrySet() ){
+                sb.append("\n\t");
+                sb.append( entry.getKey() );
+                sb.append( " ==> " );
+                sb.append( entry.getValue() );
+            }
+            sb.append(")");
+        }
+        return sb.toString();
+    }
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/PropertyTypeImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/PropertyTypeImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/PropertyTypeImpl.java	(revision 28000)
@@ -0,0 +1,193 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.type;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.resources.Classes;
+import org.geotools.util.Utilities;
+import org.opengis.feature.type.Name;
+import org.opengis.feature.type.PropertyType;
+import org.opengis.filter.Filter;
+import org.opengis.util.InternationalString;
+
+public abstract class PropertyTypeImpl implements PropertyType {
+    
+    private static final List<Filter> NO_RESTRICTIONS =  Collections.emptyList();
+
+	protected final Name name;
+	protected final Class<?> binding;
+	protected final boolean isAbstract;
+	protected final PropertyType superType;
+	protected final List<Filter> restrictions;
+	protected final InternationalString description;
+	protected final Map<Object,Object> userData;
+	
+	public PropertyTypeImpl(
+		Name name, Class<?> binding, boolean isAbstract, List<Filter> restrictions, 
+		PropertyType superType, InternationalString description 
+	) {
+		if(name== null){
+			throw new NullPointerException("Name is required for PropertyType");
+		}
+		if(binding == null) {
+		    if( superType != null && superType.getBinding() != null){
+	            // FIXME: This should be optional as the superType may have the required information?
+		        throw new NullPointerException("Binding to a Java class, did you mean to bind to "+superType.getBinding());
+		    }
+		    throw new NullPointerException("Binding to a Java class is required");
+		}
+		this.name = name;
+		this.binding = binding;
+		this.isAbstract = isAbstract;
+		
+		if (restrictions == null) {
+			this.restrictions = NO_RESTRICTIONS;
+		} else {
+			this.restrictions = Collections.unmodifiableList(restrictions);
+		}
+		
+		this.superType = superType;
+		this.description = description;
+		this.userData = new HashMap<Object,Object>();		
+	}
+	
+	public Name getName() {
+		return name;
+	}
+
+	public Class<?> getBinding() {
+	    return binding;
+	}
+	
+	public boolean isAbstract() {
+		return isAbstract;
+	}
+
+	public List<Filter> getRestrictions() {
+		return restrictions;
+	}
+
+    public PropertyType getSuper() {
+        return superType;
+    }
+	    
+	public InternationalString getDescription() {
+		return description;
+	}
+	
+	public int hashCode() {
+		return getName().hashCode() ^ getBinding().hashCode()
+				^ (getDescription() != null ? getDescription().hashCode() : 17);
+	}
+
+	
+	public boolean equals(Object other) {
+	    if(this == other)
+            return true;
+	    
+		if (!(other instanceof PropertyType)) {
+			return false;
+		}
+		
+		PropertyType prop = (PropertyType) other;
+		
+		if (!Utilities.equals(name,prop.getName())) {
+			return false;
+		}
+
+		if (!Utilities.equals(binding, prop.getBinding())) {
+		    return false;
+		}
+		
+		if (isAbstract != prop.isAbstract()) {
+			return false;
+		}
+
+		if (!equals(getRestrictions(), prop.getRestrictions())) {
+			return false;
+		}
+		
+		if (!Utilities.equals(superType, prop.getSuper())) {
+		    return false;
+		}
+		
+		if (!Utilities.equals(description,prop.getDescription())) {
+			return false;
+		}
+
+		return true;
+	}
+	
+	/**
+     * Convenience method for testing two lists for equality. One or both objects may be null,
+     * and considers null and emtpy list as equal
+     */
+    private boolean equals(final List object1, final List object2) {
+        if((object1==object2) || (object1!=null && object1.equals(object2)))
+        	return true;
+        if(object1 == null && object2.size() == 0)
+        	return true;
+        if(object2 == null && object1.size() == 0)
+        	return true;
+        return false;
+    }
+
+	public Map<Object,Object> getUserData() {
+	    return userData;
+	}
+	
+	public String toString() {
+	    StringBuffer sb = new StringBuffer(Classes.getShortClassName(this));
+        sb.append(" ");
+        sb.append( getName() );
+        if( isAbstract() ){
+            sb.append( " abstract" );           
+        }
+        if( superType != null ){
+            sb.append( " extends ");
+            sb.append( superType.getName().getLocalPart() );
+        }
+        if( binding != null ){
+            sb.append( "<" );
+            sb.append( Classes.getShortName( binding ) );
+            sb.append( ">" );
+        }
+        if( description != null ){
+            sb.append("\n\tdescription=");
+            sb.append( description );            
+        }
+        if( restrictions != null && !restrictions.isEmpty() ){
+            sb.append("\nrestrictions=");
+            boolean first = true;
+            for( Filter filter : restrictions ){
+                if( first ){
+                    first = false;
+                }
+                else {
+                    sb.append( " AND " );
+                }
+                sb.append( filter );
+            }
+        }
+        return sb.toString();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/SchemaImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/SchemaImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/SchemaImpl.java	(revision 28000)
@@ -0,0 +1,117 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.type;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.Name;
+import org.opengis.feature.type.Schema;
+
+/**
+ * Implementation of Schema.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/type/SchemaImpl.java $
+ */
+public class SchemaImpl implements Schema {
+	HashMap<Name,AttributeType> contents;		
+	String uri;
+	
+	/** Schema constructed w/ respect to provided URI */
+	public SchemaImpl( String uri) {
+		super();		
+		this.uri = uri;
+		this.contents = new HashMap();
+	}
+
+	public Set<Name> keySet() {
+		return contents.keySet();
+	}
+	
+	public int size() {
+		return contents.size();
+	}
+
+	public boolean isEmpty() {
+		return contents.isEmpty();
+	}
+
+	public boolean containsKey(Object key) {
+		return contents.containsKey( key );
+	}
+
+	public boolean containsValue(Object value) {
+		return contents.containsValue( value );
+	}
+
+	public AttributeType get(Object key) {
+		return contents.get( key );
+	}
+
+	public AttributeType put(Name name, AttributeType type) {
+		if( !(name.toString().startsWith(uri.toString() ))){
+			throw new IllegalArgumentException("Provided name was not in schema:"+uri );
+		}
+		
+		return contents.put( name, type );
+	}
+
+	public AttributeType remove(Object key) {
+	    return contents.remove( key );
+	}
+
+	public void putAll(Map<? extends Name, ? extends AttributeType> t) {
+		contents.putAll( t );
+	}
+
+	public void clear() {
+		contents.clear();
+	}
+
+	public Collection<AttributeType> values() {
+	    return contents.values();
+	}
+	
+	public Set<Entry<Name, AttributeType>> entrySet() {
+	 	return contents.entrySet();
+	}
+	
+	public int hashCode() {
+		return contents.hashCode();
+	}
+	public boolean equals(Object obj) {
+		return contents.equals(obj);
+	}
+	public String toString() {
+		return contents.toString();
+	}
+	
+	public String getURI() {
+	    return uri;
+	}
+	
+	public Schema profile(Set<Name> profile) {
+		return new ProfileImpl(this, profile);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/Types.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/Types.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/type/Types.java	(revision 28000)
@@ -0,0 +1,167 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.type;
+
+import org.geotools.feature.IllegalAttributeException;
+import org.opengis.feature.Attribute;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.filter.Filter;
+
+
+/**
+ * This is a set of utility methods used when <b>implementing</b> types.
+ * <p>
+ * This set of classes captures the all important how does it work questions,
+ * particularly with respect to super types.
+ * </p>
+ * FIXME: These methods need a Q&A check to confirm correct use of Super TODO:
+ * Cannot tell the difference in intent from FeatureTypes
+ * 
+ * @author Jody Garnett, LISAsoft
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/type/Types.java $
+ */
+public class Types {
+    /**
+     * Validates content against an attribute.
+     * 
+     * @param attribute
+     *            The attribute.
+     * @param attributeContent
+     *            Content of attribute (often attribute.getValue() 
+     * 
+     * @throws IllegalAttributeException
+     *             In the event that content violates any restrictions specified
+     *             by the attribute.
+     */
+    public static void validate(Attribute attribute, Object attributeContent)
+            throws IllegalAttributeException {
+
+        validate(attribute.getType(), attribute, attributeContent, false);
+    }
+    
+    /**
+     * 
+     * @param type AttributeType (often attribute.getType() )
+     * @param attribute Attribute being tested
+     * @param attributeContent Content of the attribute (often attribute.getValue() )
+     * @param isSuper True if super type is being checked
+     * @throws IllegalAttributeException
+     */
+    protected static void validate(AttributeType type, Attribute attribute,
+            Object attributeContent, boolean isSuper) throws IllegalAttributeException {
+
+        if (type == null) {
+            throw new IllegalAttributeException("null type");
+        }
+
+        if (attributeContent == null) {
+            if (!attribute.isNillable()) {
+                throw new IllegalAttributeException(type.getName() + " not nillable");
+            }
+            return;
+        }
+
+        if (type.isIdentified() && attribute.getIdentifier() == null) {
+            throw new NullPointerException(type.getName() + " is identified, null id not accepted");
+        }
+
+        if (!isSuper) {
+
+            // JD: This is an issue with how the xml simpel type hierarchy
+            // maps to our current Java Type hiearchy, the two are inconsitent.
+            // For instance, xs:integer, and xs:int, the later extend the
+            // former, but their associated java bindings, (BigDecimal, and
+            // Integer)
+            // dont.
+            Class clazz = attributeContent.getClass();
+            Class binding = type.getBinding();
+            if (binding != null && binding != clazz && !binding.isAssignableFrom(clazz)) {
+                throw new IllegalAttributeException(clazz.getName()
+                        + " is not an acceptable class for " + type.getName()
+                        + " as it is not assignable from " + binding);
+            }
+        }
+
+        if (type.getRestrictions() != null) {
+            for (Filter f : type.getRestrictions()) {
+                if (!f.evaluate(attribute)) {
+                    throw new IllegalAttributeException("Attribute instance (" + attribute.getIdentifier() + ")"
+                            + "fails to pass filter: " + f);
+                }
+            }
+        }
+
+        // move up the chain,
+        if (type.getSuper() != null) {
+            validate(type.getSuper(), attribute, attributeContent, true);
+        }
+    }
+
+    /**
+     * Ensure that attributeContent is a good value for descriptor.
+     */
+    public static void validate(AttributeDescriptor descriptor,
+            Object value) throws IllegalAttributeException {
+
+        if (descriptor == null) {
+            throw new NullPointerException("Attribute descriptor required for validation");
+        }
+        
+        if (value == null) {
+            if (!descriptor.isNillable()) {
+                throw new IllegalArgumentException(descriptor.getName() + " requires a non null value");
+            }           
+        } else {
+            validate( descriptor.getType(), value, false );
+        }
+    }
+        
+    protected static void validate(final AttributeType type, final Object value, boolean isSuper) throws IllegalAttributeException {
+        if (!isSuper) {
+            // JD: This is an issue with how the xml simpel type hierarchy
+            // maps to our current Java Type hiearchy, the two are inconsitent.
+            // For instance, xs:integer, and xs:int, the later extend the
+            // former, but their associated java bindings, (BigDecimal, and
+            // Integer)
+            // dont.
+            Class clazz = value.getClass();
+            Class binding = type.getBinding();
+            if (binding != null && !binding.isAssignableFrom(clazz)) {
+                throw new IllegalAttributeException(clazz.getName()
+                        + " is not an acceptable class for " + type.getName()
+                        + " as it is not assignable from " + binding);
+            }
+        }
+
+        if (type.getRestrictions() != null && type.getRestrictions().size() > 0) {
+            for (Filter filter : type.getRestrictions()) {
+                if (!filter.evaluate(value)) {
+                    throw new IllegalAttributeException( type.getName() + " restriction "+ filter + " not met by: " + value);
+                }
+            }
+        }
+
+        // move up the chain,
+        if (type.getSuper() != null) {
+            validate(type.getSuper(), value, true );
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/AbstractCalcResult.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/AbstractCalcResult.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/AbstractCalcResult.java	(revision 28000)
@@ -0,0 +1,58 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.visitor;
+
+
+
+/**
+ * An abstract implementation for CalcResults. Each subclass should implement
+ * its own getValue(), merge(), and constructor methods.
+ * 
+ * @author Cory Horner, Refractions
+ * 
+ * @since 2.2.M2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/visitor/AbstractCalcResult.java $
+ */
+public class AbstractCalcResult implements CalcResult {
+    public boolean isCompatible(CalcResult targetResults) {
+        return targetResults == CalcResult.NULL_RESULT;
+    }
+
+    public CalcResult merge(CalcResult resultsToAdd) {
+    	if(resultsToAdd == CalcResult.NULL_RESULT) {
+    		return this;
+    	} else {
+    		if (!isCompatible(resultsToAdd)) {
+                throw new IllegalArgumentException(
+                    "Parameter is not a compatible type");
+            } else {
+            	throw new IllegalArgumentException(
+				"The CalcResults claim to be compatible, but the appropriate merge " +
+				"method has not been implemented.");
+            }
+    	}
+    }
+
+    public Object getValue() {
+        return null;
+    }
+
+    public String toString() {
+        return getValue().toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/BoundsVisitor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/BoundsVisitor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/BoundsVisitor.java	(revision 28000)
@@ -0,0 +1,41 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.visitor;
+
+import org.geotools.geometry.jts.ReferencedEnvelope;
+
+
+/**
+ * Calculates the extents (envelope) of the features it visits.
+ *
+ * @author Cory Horner, Refractions
+ *
+ * @since 2.2.M2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/visitor/BoundsVisitor.java $
+ */
+public class BoundsVisitor implements FeatureCalc {
+    ReferencedEnvelope bounds = new ReferencedEnvelope();    
+        
+    public void visit(org.opengis.feature.Feature feature) {
+        bounds.include( feature.getBounds() );
+    }
+
+    public ReferencedEnvelope getBounds() {
+        return bounds;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/CalcResult.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/CalcResult.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/CalcResult.java	(revision 28000)
@@ -0,0 +1,77 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.visitor;
+
+
+
+/**
+ * Encapsulates the results from a FeatureCalc, and includes methods for
+ * obtaining and merging results.
+ *
+ * @author Cory Horner, Refractions
+ *
+ * @see FeatureCalc
+ * @since 2.2.M2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/visitor/CalcResult.java $
+ */
+public interface CalcResult {
+	/**
+	 * The result obtained when a FeatureCalc found no features to visit.
+	 * It lets itself merge with any other result by just returning the other result
+	 * as the output of the merge
+	 */
+	public static final CalcResult NULL_RESULT = new AbstractCalcResult() {
+		/**
+		 * Always compatible
+		 */
+		public boolean isCompatible(CalcResult targetResults) {
+			return true;
+		};
+		
+		/**
+		 * Just returns the other result
+		 */
+		public CalcResult merge(CalcResult resultsToAdd) {
+			return resultsToAdd;
+		};
+	};
+	
+    /**
+     * Returns true if the target results is a compatible type with the current
+     * results, with compatible meaning that the two results may be merged.
+     *
+     * @param targetResults the second CalcResult Object
+     *
+     * @return true if the targetResults can be merged with the current results
+     */
+    public boolean isCompatible(CalcResult targetResults);
+
+    /**
+     * Actual answer
+     *
+     * @return the calculation result as a generic object
+     */
+    public Object getValue();
+
+    /**
+     * Access getValue as a string
+     *
+     * @return the calculation result as a string (or "" if not applicable)
+     */
+    public String toString();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/FeatureCalc.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/FeatureCalc.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/FeatureCalc.java	(revision 28000)
@@ -0,0 +1,33 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.visitor;
+
+import org.opengis.feature.FeatureVisitor;
+
+/**
+ * A visitor which performs a calculation on a FeatureCollection. A FeatureCalc
+ * will not modify the features visited.
+ *
+ * @author Cory Horner, Refractions
+ *
+ * @see FeatureVisitor
+ * @since 2.2.M2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/visitor/FeatureCalc.java $
+ */
+public interface FeatureCalc extends FeatureVisitor {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/IdCollectorFilterVisitor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/IdCollectorFilterVisitor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/feature/visitor/IdCollectorFilterVisitor.java	(revision 28000)
@@ -0,0 +1,62 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.feature.visitor;
+
+import java.util.Set;
+
+import org.geotools.filter.visitor.DefaultFilterVisitor;
+import org.opengis.filter.Id;
+
+/**
+ * Gather up all FeatureId strings into a provided HashSet.
+ * <p>
+ * Example:<code>Set<String> fids = (Set<String>) filter.accept( IdCollectorFilterVisitor.ID_COLLECTOR, new HashSet() );</code>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/feature/visitor/IdCollectorFilterVisitor.java $
+ */
+public class IdCollectorFilterVisitor extends DefaultFilterVisitor {
+    public static final IdCollectorFilterVisitor IDENTIFIER_COLLECTOR = new IdCollectorFilterVisitor(false);
+    private final boolean mCollectStringIds;
+
+    /**
+     * @deprecated use {@link #IdCollectorFilterVisitor(boolean)}
+     */
+    protected IdCollectorFilterVisitor(){
+        mCollectStringIds = true;
+    }
+    
+    protected IdCollectorFilterVisitor(boolean collectStringIds){
+        mCollectStringIds = collectStringIds;
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object visit( Id filter, Object data ) {
+     
+        if( mCollectStringIds){
+            Set set = (Set) data;
+            set.addAll( filter.getIDs() );        
+            return set;
+        }else{
+            Set set = (Set) data;
+            set.addAll( filter.getIdentifiers());        
+            return set;
+        }
+
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AbstractFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AbstractFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AbstractFilter.java	(revision 28000)
@@ -0,0 +1,87 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+
+/**
+ * Implements Filter interface, with constants and default behaviors for
+ * methods.
+ *
+ * @author Rob Hranac, Vision for New York
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/AbstractFilter.java $
+ * @version $Id: AbstractFilter.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public abstract class AbstractFilter extends FilterAbstract implements Filter {
+
+    /** Defines filter type (all valid types defined below). */
+    protected short filterType;
+
+    /** Sets the permissiveness of the filter construction handling. */
+    protected boolean permissiveConstruction = true;
+
+    /**
+     * 
+     * @param factory
+     */
+    protected AbstractFilter(org.opengis.filter.FilterFactory factory) {
+		super(factory);
+	}
+        
+    /**
+     * This method checks if the object is an instance of {@link Feature} and 
+     * if so, calls through to {@link Filter#evaluate(Feature)}. This is done 
+     * to maintain backwards compatability with previous version of Filter api 
+     * which depended on Feature. If the object is not an instance of feature 
+     * the super implementation is called.
+     */
+    /*
+    public boolean evaluate(Object object) {
+    	if (object instanceof Feature  || object == null ) {
+    		return evaluate((Feature)object);
+    	}
+    	
+    	return false;
+    }*/
+    
+    /**
+     * Checks to see if passed type is math.
+     *
+     * @param filterType Type of filter for check.
+     *
+     * @return Whether or not this is a math filter type.
+     */
+    protected static boolean isMathFilter(short filterType) {
+        return ((filterType == COMPARE_LESS_THAN)
+        || (filterType == COMPARE_GREATER_THAN)
+        || (filterType == COMPARE_LESS_THAN_EQUAL)
+        || (filterType == COMPARE_GREATER_THAN_EQUAL));
+    }
+
+    /**
+     * Retrieves the type of filter.
+     *
+     * @return a short representation of the filter type.
+     * 
+     * @deprecated The enumeration base type system is replaced with a class 
+     * 	based type system. An 'instanceof' check should be made instead of 
+     * 	calling this method.
+     */
+    public short getFilterType() {
+        return filterType;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AbstractFilterImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AbstractFilterImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AbstractFilterImpl.java	(revision 28000)
@@ -0,0 +1,39 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *    
+ *    Created on 23 October 2002, 17:19
+ */
+package org.geotools.filter;
+
+import org.opengis.filter.FilterFactory;
+
+
+/**
+ * Abstract filter implementation provides or and and methods for child filters
+ * to use.
+ *
+ * @author Ian Turton, CCG
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/AbstractFilterImpl.java $
+ * @version $Id: AbstractFilterImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public abstract class AbstractFilterImpl
+    extends org.geotools.filter.AbstractFilter {
+   
+	protected AbstractFilterImpl(FilterFactory factory) {
+		super(factory);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AndImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AndImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AndImpl.java	(revision 28000)
@@ -0,0 +1,67 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.filter.And;
+import org.opengis.filter.FilterVisitor;
+
+/**
+ * Direct implementation of And filter.
+ *
+ * @author jdeolive
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/AndImpl.java $
+ */
+public class AndImpl extends LogicFilterImpl implements And {
+	
+	protected AndImpl(org.opengis.filter.FilterFactory factory, List/*<Filter>*/ children) {
+		super(factory, children );
+		
+		//backwards compatability with old type system
+		this.filterType = LOGIC_AND;
+	}
+	
+	//@Override
+	public boolean evaluate(SimpleFeature feature) {        
+		for (Iterator itr = children.iterator(); itr.hasNext();) {
+            org.opengis.filter.Filter filter = (org.opengis.filter.Filter)itr.next();
+			if( !filter.evaluate( feature )) {
+                return false; // short circuit
+            }
+		}
+		return true;
+	}
+    public boolean evaluate( Object object ) {
+        for (Iterator itr = children.iterator(); itr.hasNext();) {
+            org.opengis.filter.Filter filter = (org.opengis.filter.Filter) itr.next();
+            if( !filter.evaluate( object )) {
+                return false; // short circuit
+            }
+        }
+        return true;
+    }
+	
+	public Object accept(FilterVisitor visitor, Object extraData) {
+		return visitor.visit(this,extraData);
+	}
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AttributeExpression.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AttributeExpression.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AttributeExpression.java	(revision 28000)
@@ -0,0 +1,45 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import org.opengis.filter.expression.PropertyName;
+
+
+/**
+ * The geotools representation of the PropertyName tag in an xml encoded
+ * filter.
+ * <p>
+ * It should handle xpath attributePaths of features, and should
+ * report the attribute found at the attributePath of a feature.
+ * </p>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/AttributeExpression.java $
+ * @version $Id: AttributeExpression.java 37280 2011-05-24 07:53:02Z mbedward $
+ *
+ * @deprecated use {@link org.opengis.filter.expression.PropertyName}
+ */
+public interface AttributeExpression extends Expression, PropertyName {
+
+    /**
+     * Gets the attribute path of this expression.
+     *
+     * @return the attribute to be queried.
+     *
+     * @deprecated use {@link PropertyName#getPropertyName()}
+     */
+    String getAttributePath();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AttributeExpressionImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AttributeExpressionImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/AttributeExpressionImpl.java	(revision 28000)
@@ -0,0 +1,291 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.factory.Hints;
+import org.geotools.filter.expression.PropertyAccessor;
+import org.geotools.filter.expression.PropertyAccessorFactory;
+import org.geotools.filter.expression.PropertyAccessors;
+import org.geotools.util.Converters;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.expression.ExpressionVisitor;
+import org.xml.sax.helpers.NamespaceSupport;
+
+
+/**
+ * Defines a complex filter (could also be called logical filter). This filter
+ * holds one or more filters together and relates them logically in an
+ * internally defined manner.
+ *
+ * @author Rob Hranac, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/AttributeExpressionImpl.java $
+ * @version $Id: AttributeExpressionImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public class AttributeExpressionImpl extends DefaultExpression
+    implements AttributeExpression {
+            
+    /** The logger for the default core module. */
+    private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geotools.core");
+
+    /** Holds all sub filters of this filter. */
+    protected String attPath;
+
+    /** Used to validate attribute references to ensure they match the provided schema */
+    protected SimpleFeatureType schema = null;
+    
+    /** NamespaceSupport used to defining the prefix information for the xpath expression */
+    NamespaceSupport namespaceSupport;
+    
+    /**
+     * Configures whether evaluate should return null if it cannot find a working
+     * property accessor, rather than throwing an exception (default behaviour).
+     * */
+    protected boolean lenient = true;
+    
+    /**
+     * Hints passed to the property accessor gathering up additional context information
+     * used during evaluation.
+     */
+    private Hints hints;
+
+    /**
+     * Constructor with schema and path to the attribute.
+     * 
+     * @param xpath the String xpath to the attribute.
+     */
+    public AttributeExpressionImpl( String xpath ){
+        this.attPath = xpath;
+        this.schema = null;
+        this.namespaceSupport = null;
+        this.hints = null;
+        this.expressionType = ATTRIBUTE;
+    }
+        
+    /**
+     * Constructor with schema and path to the attribute.
+     * 
+     * @param xpath the String xpath to the attribute.
+     * @param namespaceContext Defining the prefix information for the xpath expression 
+     */
+    public AttributeExpressionImpl( String xpath, NamespaceSupport namespaceContext ){
+        attPath = xpath;
+        schema = null;
+        this.namespaceSupport = namespaceContext;
+        this.expressionType = ATTRIBUTE;
+    }   
+        
+    public NamespaceSupport getNamespaceContext() {
+        return namespaceSupport;
+    }
+    
+    /**
+     * This method calls {@link #getPropertyName()}.
+     * 
+     * @deprecated use {@link #getPropertyName()}
+     */
+    public final String getAttributePath() {
+      	return getPropertyName();
+    }
+
+    /**
+     * Gets the path to the attribute to be evaluated by this expression.
+     *
+     * {@link org.opengis.filter.expression.PropertyName#getPropertyName()}
+     */
+   public String getPropertyName() {
+		return attPath;
+   }	
+    
+    /**
+      * Gets the value of this attribute from the passed feature.
+      *
+      * @param feature Feature from which to extract attribute value.
+      */
+    public Object evaluate(SimpleFeature feature) {
+       //NC - is exact copy of code anyway, don't need to keep changing both
+       //this method can probably be removed all together
+        return evaluate(feature, null); 
+       
+    }
+  
+    /**
+     * Gets the value of this property from the passed object.
+     *
+     * @param obj Object from which we need to extract a property value.
+     */
+   public Object evaluate(Object obj) {
+        return evaluate(obj, null);
+   }
+   
+   
+   /**
+    * Gets the value of this attribute from the passed object.
+    *
+    * @param obj Object from which to extract attribute value.
+    * @param target Target Class 
+    */
+    public Object evaluate(Object obj, Class target) {
+        // NC- new method
+
+        PropertyAccessor accessor = getLastPropertyAccessor();
+        AtomicReference<Object> value = new AtomicReference<Object>();
+        AtomicReference<Exception> e = new AtomicReference<Exception>();
+
+        if (accessor == null || !accessor.canHandle(obj, attPath, target)
+                || !tryAccessor(accessor, obj, target, value, e)) {
+            boolean success = false;
+            if( namespaceSupport != null && hints == null ){
+                hints = new Hints(PropertyAccessorFactory.NAMESPACE_CONTEXT, namespaceSupport);
+            }
+            List<PropertyAccessor> accessors = PropertyAccessors.findPropertyAccessors(obj,
+                    attPath, target, hints );
+
+            if (accessors != null) {
+                Iterator<PropertyAccessor> it = accessors.iterator();
+                while (!success && it.hasNext()) {
+                    accessor = it.next();
+                    success = tryAccessor(accessor, obj, target, value, e);
+                }
+
+            }
+
+            if (!success) {
+                if (lenient) return null;
+                else throw new IllegalArgumentException(
+                        "Could not find working property accessor for attribute (" + attPath
+                                + ") in object (" + obj + ")", e.get());
+            } else {
+                setLastPropertyAccessor(accessor);
+            }
+
+        }
+
+        if (target == null) {
+            return value.get();
+        }
+
+        return Converters.convert(value.get(), target);
+
+    }
+
+    // NC - helper method for evaluation - attempt to use property accessor
+    private boolean tryAccessor(PropertyAccessor accessor, Object obj, Class target,
+            AtomicReference<Object> value, AtomicReference<Exception> ex) {
+        try {
+            value.set(accessor.get(obj, attPath, target));
+            return true;
+        } catch (Exception e) {
+            ex.set(e);
+            return false;
+        }
+
+    }
+
+    // accessor caching, scanning the registry every time is really very expensive
+    private PropertyAccessor lastAccessor;
+
+    private synchronized PropertyAccessor getLastPropertyAccessor() {
+        return lastAccessor;
+    }
+
+    private synchronized void setLastPropertyAccessor(PropertyAccessor accessor) {
+        lastAccessor = accessor;
+    }
+   
+     /**
+     * Return this expression as a string.
+     *
+     * @return String representation of this attribute expression.
+     */
+    public String toString() {
+        return attPath;
+    }
+
+    /**
+     * Compares this filter to the specified object.  Returns true  if the
+     * passed in object is the same as this expression.  Checks  to make sure
+     * the expression types are the same as well as  the attribute paths and
+     * schemas.
+     *
+     * @param obj - the object to compare this ExpressionAttribute against.
+     *
+     * @return true if specified object is equal to this filter; else false
+     */
+    public boolean equals(Object obj) {
+        if(obj == null)
+            return false;
+        
+        if (obj.getClass() == this.getClass()) {
+            AttributeExpressionImpl expAttr = (AttributeExpressionImpl) obj;
+
+            boolean isEqual = (expAttr.getType() == this.expressionType);
+            if(LOGGER.isLoggable(Level.FINEST))
+                LOGGER.finest("expression type match:" + isEqual + "; in:"
+                + expAttr.getType() + "; out:" + this.expressionType);
+            isEqual = (expAttr.attPath != null)
+                ? (isEqual && expAttr.attPath.equals(this.attPath))
+                : (isEqual && (this.attPath == null));
+            if(LOGGER.isLoggable(Level.FINEST))
+                LOGGER.finest("attribute match:" + isEqual + "; in:"
+                + expAttr.getAttributePath() + "; out:" + this.attPath);
+            isEqual = (expAttr.schema != null)
+                ? (isEqual && expAttr.schema.equals(this.schema))
+                : (isEqual && (this.schema == null));
+            if(LOGGER.isLoggable(Level.FINEST))
+                LOGGER.finest("schema match:" + isEqual + "; in:" + expAttr.schema
+                + "; out:" + this.schema);
+
+            return isEqual;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Override of hashCode method.
+     *
+     * @return a code to hash this object by.
+     */
+    public int hashCode() {
+        int result = 17;
+        result = (37 * result) + (attPath == null ? 0 : attPath.hashCode());
+        result = (37 * result) + (schema == null ? 0 : schema.hashCode());
+        return result;
+    }
+
+    /**
+     * Used by FilterVisitors to perform some action on this filter instance.
+     * Typicaly used by Filter decoders, but may also be used by any thing
+     * which needs infomration from filter structure. Implementations should
+     * always call: visitor.visit(this); It is importatant that this is not
+     * left to a parent class unless the  parents API is identical.
+     *
+     * @param visitor The visitor which requires access to this filter, the
+     *        method must call visitor.visit(this);
+     */
+    public Object accept(ExpressionVisitor visitor, Object extraData) {
+    	return visitor.visit(this,extraData);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/BBoxExpression.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/BBoxExpression.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/BBoxExpression.java	(revision 28000)
@@ -0,0 +1,39 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+
+/**
+ * A convenience expression to form a geometry literal from an  envelope.
+ *
+ * @author Ian Turton, CCG
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/BBoxExpression.java $
+ * @version $Id: BBoxExpression.java 37280 2011-05-24 07:53:02Z mbedward $
+ */
+public interface BBoxExpression extends LiteralExpression {
+    /**
+     * Set the bbox for this expression
+     *
+     * @param env The envelope to set as the bounds.
+     *
+     * @throws IllegalFilterException If the box can not be created.
+     */
+    void setBounds(Envelope env) throws IllegalFilterException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/BBoxExpressionImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/BBoxExpressionImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/BBoxExpressionImpl.java	(revision 28000)
@@ -0,0 +1,103 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+
+import org.geotools.geometry.jts.ReferencedEnvelope;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geom.TopologyException;
+
+
+/**
+ * Implements a Bounding Box expression.
+ * <p>
+ * Please note this is exactly the same as doing:
+ * <code>
+ * filterFactory.literal( JTS.toGeometry( bounds ) );
+ * </code>
+ * 
+ * @author Ian Turton, CCG
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/BBoxExpressionImpl.java $
+ * @version $Id: BBoxExpressionImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public class BBoxExpressionImpl
+    extends org.geotools.filter.LiteralExpressionImpl implements BBoxExpression {
+    /** Factory for creating geometries */
+    private GeometryFactory gfac = new GeometryFactory();
+
+    /**
+     * Creates a new instance of BBoxExpression
+     *
+     * @throws IllegalFilterException if there are problems.
+     */
+    protected BBoxExpressionImpl() throws IllegalFilterException {
+        this(new Envelope());
+    }
+
+    /**
+     * Creates a new instance of BBoxExpression, with an initial box.
+     *
+     * @param env the envelope to set as the box.
+     *
+     * @throws IllegalFilterException if there are problems.
+     */
+    protected BBoxExpressionImpl(Envelope env) throws IllegalFilterException {
+        expressionType = DefaultExpression.LITERAL_GEOMETRY;
+        setBounds(env);
+        
+    }
+
+    /**
+     * Set the bbox for this expression
+     *
+     * @param env The envelope to set as the bounds.
+     *
+     * @throws IllegalFilterException If the box can not be created.
+     *
+     * @task HACK: currently sets the SRID to null, which can cause problems
+     *       with JTS when it comes to doing spatial tests
+     */
+    public final void setBounds(Envelope env) throws IllegalFilterException {
+        Coordinate[] coords = new Coordinate[5];
+        coords[0] = new Coordinate(env.getMinX(), env.getMinY());
+        coords[1] = new Coordinate(env.getMinX(), env.getMaxY());
+        coords[2] = new Coordinate(env.getMaxX(), env.getMaxY());
+        coords[3] = new Coordinate(env.getMaxX(), env.getMinY());
+        coords[4] = new Coordinate(env.getMinX(), env.getMinY());
+
+        LinearRing ring = null;
+
+        try {
+            ring = gfac.createLinearRing(coords);
+        } catch (TopologyException tex) {
+            throw new IllegalFilterException(tex.toString());
+        }
+
+        Polygon polygon = gfac.createPolygon(ring, null);
+        if (env instanceof ReferencedEnvelope) {
+            ReferencedEnvelope refEnv = (ReferencedEnvelope) env;
+            polygon.setUserData(refEnv.getCoordinateReferenceSystem());
+        }
+        super.setValue(polygon);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/BinaryComparisonAbstract.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/BinaryComparisonAbstract.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/BinaryComparisonAbstract.java	(revision 28000)
@@ -0,0 +1,64 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import org.opengis.filter.BinaryComparisonOperator;
+import org.opengis.filter.expression.Expression;
+
+/**
+ * Abstract implemention for binary filters.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/BinaryComparisonAbstract.java $
+ */
+public abstract class BinaryComparisonAbstract extends AbstractFilter 
+	implements BinaryComparisonOperator {
+
+	protected Expression expression1;
+	protected Expression expression2;
+
+	boolean matchingCase;
+	
+	protected BinaryComparisonAbstract(org.opengis.filter.FilterFactory factory, Expression expression1, Expression expression2 ) {
+		this(factory,expression1,expression2,true);
+	}
+	
+	protected BinaryComparisonAbstract(org.opengis.filter.FilterFactory factory, Expression expression1, Expression expression2, boolean matchingCase ) {
+		super(factory);
+		this.expression1 = expression1;
+		this.expression2 = expression2;		
+		this.matchingCase = matchingCase;
+	} 
+	
+	public Expression getExpression1() {
+		return expression1;
+	}
+
+	public void setExpression1(Expression expression) {
+		this.expression1 = expression;
+	}
+	
+	public Expression getExpression2() {
+		return expression2;
+	}
+	
+	public void setExpression2(Expression expression) {
+		this.expression2 = expression;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/BinaryLogicAbstract.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/BinaryLogicAbstract.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/BinaryLogicAbstract.java	(revision 28000)
@@ -0,0 +1,52 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.util.List;
+
+import org.opengis.filter.BinaryLogicOperator;
+
+/**
+ * @author jdeolive
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/BinaryLogicAbstract.java $
+ */
+public abstract class BinaryLogicAbstract extends AbstractFilter implements BinaryLogicOperator {
+	protected List/*<Filter>*/ children;
+	
+	protected BinaryLogicAbstract(org.opengis.filter.FilterFactory factory, List/*<Filter>*/ children ) {
+		super(factory);
+		this.children = children;
+	}
+	
+	public List/*<Filter>*/ getChildren() {
+		return children;
+	}
+	
+	public Filter and(org.opengis.filter.Filter filter) {
+		return (Filter) factory.and(this, filter);
+	}
+
+	public Filter or(org.opengis.filter.Filter filter) {
+		return (Filter) factory.or(this, filter);
+	}
+
+	public Filter not() {
+		return (Filter) factory.not(this);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/CompareFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/CompareFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/CompareFilter.java	(revision 28000)
@@ -0,0 +1,63 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import org.opengis.filter.BinaryComparisonOperator;
+
+
+/**
+ * Defines a comparison filter (can be a math comparison or generic equals).
+ * This filter implements a comparison - of some sort - between two
+ * expressions. The comparison may be a math comparison or a generic equals
+ * comparison.  If it is a math comparison, only math expressions are allowed;
+ * if it is an equals comparison, any expression types are allowed. Note that
+ * this comparison does not attempt to restrict its expressions to be
+ * meaningful.  This means that it considers itself a valid filter as long as
+ * the expression comparison returns a valid result.  It does no checking to
+ * see whether or not the expression comparison is meaningful with regard to
+ * checking feature attributes.  In other words, this is a valid filter: <b>52
+ * = 92</b>, even though it will always return the same result and could be
+ * simplified away.  It is up the the filter creator, therefore, to attempt to
+ * simplify/make meaningful filter logic.
+ *
+ * @author Rob Hranac, Vision for New York
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/CompareFilter.java $
+ * @version $Id: CompareFilter.java 37280 2011-05-24 07:53:02Z mbedward $
+ *
+ * @deprecated use {@link org.opengis.filter.BinaryComparisonOperator}
+ */
+public interface CompareFilter extends Filter, BinaryComparisonOperator {
+
+    /**
+     * Gets the left expression.
+     *
+     * @return The expression on the left of the comparison.
+     *
+     * @deprecated use {@link BinaryComparisonOperator#getExpression1()}
+     */
+    Expression getLeftValue();
+
+    /**
+     * Gets the right expression.
+     *
+     * @return The expression on the right of the comparison.
+     *
+     * @deprecated use {@link BinaryComparisonOperator#getExpression2()}
+     */
+    Expression getRightValue();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/DefaultExpression.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/DefaultExpression.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/DefaultExpression.java	(revision 28000)
@@ -0,0 +1,111 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import org.geotools.filter.expression.ExpressionAbstract;
+import org.opengis.feature.Feature;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.filter.expression.Add;
+import org.opengis.filter.expression.Divide;
+import org.opengis.filter.expression.Multiply;
+import org.opengis.filter.expression.Subtract;
+
+
+/**
+ * Implements a default expression, with helpful variables and static methods.
+ *
+ * @author Rob Hranac, Vision for New York
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/DefaultExpression.java $
+ * @version $Id: DefaultExpression.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public abstract class DefaultExpression extends ExpressionAbstract implements Expression {
+    
+  	/** Defines the type of this expression. */
+    protected short expressionType;
+    /**
+     * Gets the type of this expression.
+     *
+     * @return The short representation of the expression type.
+     */
+    public short getType() {
+        return expressionType;
+    }
+    
+    /**
+     * Returns a value for this expression.  If the expression is an attribute
+     * expression then the attribute of the feature should be returned.  If a
+     * literal then the feature is ignored, the literal is returned as it has
+     * no relation to the feature.
+     *
+     * @param feature Specified feature to use when returning value.
+     *
+     * @return The value of this expression based on the feature.
+     *
+     * @task REVISIT: make abstract?
+     */
+    public Object evaluate(SimpleFeature feature) {
+    	return evaluate((Object)feature);
+    }
+    
+    /**
+     * 
+     * This method checks if the object is an instance of {@link Feature} and 
+     * if so, calls through to {@link #evaluate(Feature)}. This is done 
+     * to maintain backwards compatability with previous version of Expression api 
+     * which depended on Feature. If the object is not an instance of feature 
+     * the super implementation is called.
+     */
+    public Object evaluate(Object object) {
+    	return new Object();
+    }
+        
+    /* ***********************************************************************
+     * Following static methods check for certain aggregate types, based on
+     * (above) declared types.  Note that these aggregate types do not
+     * necessarily map directly to the sub-classes of FilterDefault.  In most,
+     * but not all, cases, a single class implements an aggregate type.
+     * However, there are aggregate types that are implemented by multiple
+     * classes (ie. the Math type is implemented by two separate classes).
+     ************************************************************************/
+
+    /**
+     * Checks to see if this expression is a math expresson based on its type.
+     * 
+     * @param expression expression to check.
+     *
+     * @return Whether or not this is a math expression.
+     */
+    protected static boolean isMathExpression(org.opengis.filter.expression.Expression expression) {
+    	return expression instanceof Add || 
+    		expression instanceof Subtract || 
+    		expression instanceof Multiply || 
+    		expression instanceof Divide;
+    }
+    /**
+     * Checks to see if passed type is geometry.
+     *
+     * @param expressionType Type of expression for check.
+     *
+     * @return Whether or not this is a geometry expression type.
+     */
+    protected static boolean isGeometryExpression(short expressionType) {
+        return ((expressionType == ATTRIBUTE_GEOMETRY)
+        || (expressionType == LITERAL_GEOMETRY));
+    }
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/Expression.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/Expression.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/Expression.java	(revision 28000)
@@ -0,0 +1,54 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import org.opengis.feature.Feature;
+import org.opengis.feature.simple.SimpleFeature;
+
+
+/**
+ * Defines an expression, the units that make up Filters.   This filter holds
+ * one or more filters together and relates them logically in an internally
+ * defined manner.
+ *
+ * @author Rob Hranac, Vision for New York
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/Expression.java $
+ * @version $Id: Expression.java 37280 2011-05-24 07:53:02Z mbedward $
+ *
+ * @deprecated use {@link org.opengis.filter.expression.Expression}
+ */
+public interface Expression extends ExpressionType, org.opengis.filter.expression.Expression {
+    /**
+     * Gets the type of this expression.
+     *
+     * @return Expression type.
+     *
+     * @deprecated The enumeration based type system has been replaced by a
+     * class based type system.
+     */
+    short getType();
+
+    /**
+     * Evaluates the expression against an instance of {@link Feature}.
+     *
+     * @param feature The feature being evaluated.
+     *
+     * @return The result.
+     */
+    Object evaluate(SimpleFeature feature);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/ExpressionType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/ExpressionType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/ExpressionType.java	(revision 28000)
@@ -0,0 +1,76 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+
+/**
+ * The ExpressionType interface lists all the possible type of filter. Should
+ * be replaced by a type safe enum when we move to Java 1.5
+ *
+ * @author wolf
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/ExpressionType.java $
+ */
+public interface ExpressionType {
+    /* This is a listing of all possible expression types, grouped by
+       expressions that are implemented by a single expression class
+       (ie. all math types are implemented by ExpressionMath). */
+
+    /* Types implemented by ExpressionLiteral */
+    /** Defines a literal expression with an undeclared type. */
+    public static final short LITERAL_UNDECLARED = 115;
+
+    /** Defines a literal expression with a declared double type. */
+    public static final short LITERAL_DOUBLE = 101;
+
+    /** Defines a literal expression with a declared integer type. */
+    public static final short LITERAL_INTEGER = 102;
+
+    /** Defines a literal expression with a declared string type. */
+    public static final short LITERAL_STRING = 103;
+
+    /** Defines a literal expression with a declared geometry type. */
+    public static final short LITERAL_GEOMETRY = 104;
+
+    /**
+     *  Defines a literal expression with a declared long type.
+     *  @since 2.4
+     **/
+    public static final short LITERAL_LONG = 99;
+
+    /* Types implemented by ExpressionMath. */
+    /** Defines a math expression for adding. */
+    public static final short MATH_ADD = 105;
+
+    /** Defines a math expression for subtracting. */
+    public static final short MATH_SUBTRACT = 106;
+
+    /** Defines a math expression for multiplying. */
+    public static final short MATH_MULTIPLY = 107;
+
+    /** Defines a math expression for dividing. */
+    public static final short MATH_DIVIDE = 108;
+
+    /** Defines an attribute expression with a declared string type. */
+    public static final short ATTRIBUTE_GEOMETRY = 112;
+
+    /** Defines an attribute expression with a declared string type. */
+    public static final short ATTRIBUTE = 113;
+
+    /** Defines a function expression */
+    public static final short FUNCTION = 114;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FallbackFunction.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FallbackFunction.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FallbackFunction.java	(revision 28000)
@@ -0,0 +1,53 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.util.List;
+
+import org.opengis.filter.expression.Literal;
+
+/**
+ * A placeholder class used to track a function the user requested
+ * that is not supported by our java implementation.
+ * <p>
+ * This can be used to construct expressions that are to be executed
+ * by another systems (say as SQL or as a WFS request).
+ * 
+ * @author Jody Garnett
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/FallbackFunction.java $
+ */
+public class FallbackFunction extends FunctionExpressionImpl {
+
+    public FallbackFunction(String name, List params, Literal fallback) {
+        super(name, fallback);
+        this.setParameters(params);
+    }
+    public int getArgCount() {
+        return 0;
+    }
+    @Override
+    public Object evaluate(Object object) {
+        return fallback.evaluate(object);
+    }
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object evaluate(Object object, Class context) {
+        return fallback.evaluate( object, context );
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FidFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FidFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FidFilter.java	(revision 28000)
@@ -0,0 +1,35 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import org.opengis.filter.Id;
+
+
+/**
+ * Defines a feature ID filter, which holds a list of feature IDs. This filter
+ * stores a series of feature IDs, which are used to distinguish features
+ * uniquely.
+ *
+ * @author Rob Hranac, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/FidFilter.java $
+ * @version $Id: FidFilter.java 37280 2011-05-24 07:53:02Z mbedward $
+ *
+ * @deprecated use {@link org.opengis.filter.identity.FeatureId}
+ */
+public interface FidFilter extends Filter, Id {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FidFilterImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FidFilterImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FidFilterImpl.java	(revision 28000)
@@ -0,0 +1,223 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+// Geotools dependencies
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.filter.expression.PropertyAccessor;
+import org.geotools.filter.expression.SimpleFeaturePropertyAccessorFactory;
+import org.opengis.filter.FilterVisitor;
+import org.opengis.filter.identity.Identifier;
+
+/**
+ * Defines a ID filter, which holds a list of IDs ( usually feature id;s ). This
+ * filter stores a series of IDs, which are used to distinguish features
+ * uniquely.
+ * <p>
+ * Please note that addAllFids( Collection ) may be a performance hog; uDig
+ * makes use of its own implementation of FidFilter in order to reuse the
+ * internal set of fids between uses.
+ * </p>
+ * 
+ * @author Rob Hranac, TOPP
+ * @author Justin Deoliveira, TOPP
+ * 
+ * TODO: this class shoul be renamed to IdFilterImpl
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/FidFilterImpl.java $
+ * @version $Id: FidFilterImpl.java 37615 2011-07-12 00:47:13Z groldan $
+ */
+public class FidFilterImpl extends AbstractFilterImpl implements FidFilter {
+    /** Logger for the default core module. */
+    private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geotools.core");
+
+    /** List of the Identifer. */
+    private Set fids = new HashSet();
+
+    /**
+     * Empty constructor.
+     * 
+     * @deprecated use {@link #FidFilterImpl(Set)}
+     */
+    protected FidFilterImpl() {
+        super(CommonFactoryFinder.getFilterFactory(null));
+        filterType = AbstractFilter.FID;
+    }
+
+    /**
+     * Constructor which takes {@link org.opengis.filter.identity.Identifier},
+     * not String.
+     * 
+     */
+    protected FidFilterImpl(Set/* <Identifier> */fids) {
+        super(CommonFactoryFinder.getFilterFactory(null));
+        filterType = AbstractFilter.FID;
+        // check these are really identifiers
+        for (Iterator it = fids.iterator(); it.hasNext();) {
+            Object next = it.next();
+            if (!(next instanceof Identifier))
+                throw new ClassCastException("Fids must implement Identifier, "
+                        + next.getClass() + " does not");
+        }
+        this.fids = fids;
+    }
+
+    /**
+     * @see org.opengis.filter.Id#getIDs()
+     */
+    public Set getIDs() {
+        return getFidsSet();
+    }
+
+    /**
+     * @see org.opengis.filter.Id#getIdentifiers()
+     */
+    public Set getIdentifiers() {
+        return fids;
+    }
+
+    /**
+     * Accessor method for fid set as Strings.
+     * 
+     * @return the internally stored fids.
+     */
+    public Set getFidsSet() {
+        return fids();
+    }
+
+    /**
+     * Helper method to pull out strings from featureId set.
+     * 
+     * @return
+     */
+    private Set fids() {
+        Set set = new TreeSet();
+        for (Iterator i = fids.iterator(); i.hasNext();) {
+            Identifier id = (Identifier) i.next();
+            set.add(id.toString());
+        }
+
+        return set;
+    }
+
+    /**
+     * Determines whether or not the given feature's ID matches this filter.
+     * <p>
+     * In order to get the object's ID, the {@link PropertyAccessor} capable of
+     * dealing with <code>feature</code> has to support the request of the
+     * expression <code>"@id"</code>
+     * </p>
+     * 
+     * @param feature
+     *            Specified feature to examine.
+     * 
+     * @return <tt>true</tt> if the feature's ID matches an fid held by this
+     *         filter, <tt>false</tt> otherwise.
+     * @see SimpleFeaturePropertyAccessorFactory
+     */
+    public boolean evaluate(Object feature) {
+            if (feature == null) {
+                return false;
+            }
+    
+            final Set fids = fids();
+		
+		
+            //NC - updated, using attributeexpressionimpl will be easiest, don't have to copy and paste lots of code				
+            Object evaluate = CommonFactoryFinder.getFilterFactory(null).property("@id").evaluate(feature);
+            return evaluate == null? false : fids.contains(evaluate);		
+	}
+	
+    /**
+     * Returns a string representation of this filter.
+     * 
+     * @return String representation of the compare filter.
+     */
+    public String toString() {
+        StringBuffer fidFilter = new StringBuffer();
+
+        Iterator fidIterator = fids.iterator();
+
+        while (fidIterator.hasNext()) {
+            fidFilter.append(fidIterator.next().toString());
+
+            if (fidIterator.hasNext()) {
+                fidFilter.append(", ");
+            }
+        }
+
+        return "[ " + fidFilter.toString() + " ]";
+    }
+
+    /**
+     * Used by FilterVisitors to perform some action on this filter instance.
+     * Typicaly used by Filter decoders, but may also be used by any thing which
+     * needs infomration from filter structure. Implementations should always
+     * call: visitor.visit(this); It is importatant that this is not left to a
+     * parent class unless the parents API is identical.
+     * 
+     * @param visitor
+     *            The visitor which requires access to this filter, the method
+     *            must call visitor.visit(this);
+     */
+    public Object accept(FilterVisitor visitor, Object extraData) {
+        return visitor.visit(this, extraData);
+    }
+
+    /**
+     * Returns a flag indicating object equality.
+     * 
+     * @param filter
+     *            the filter to test equality on.
+     * 
+     * @return String representation of the compare filter.
+     */
+    public boolean equals(Object filter) {
+        LOGGER.finest("condition: " + filter);
+
+        if ((filter != null) && (filter.getClass() == this.getClass())) {
+            if(LOGGER.isLoggable(Level.FINEST)) {
+                LOGGER.finest("condition: " + ((FidFilterImpl) filter).filterType);
+            }
+
+            if (((FidFilterImpl) filter).filterType == AbstractFilter.FID) {
+                return fids.equals(((FidFilterImpl) filter).fids);
+            } else {
+                return false;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Override of hashCode method.
+     * 
+     * @return a hash code value for this fid filter object.
+     */
+    public int hashCode() {
+        return fids.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/Filter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/Filter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/Filter.java	(revision 28000)
@@ -0,0 +1,45 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+
+
+/**
+ * Defines an OpenGIS Filter object, with default behaviors for all methods.
+ *
+ * @author Rob Hranac, Vision for New York
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/Filter.java $
+ * @version $Id: Filter.java 37280 2011-05-24 07:53:02Z mbedward $
+ *
+ * @deprecated use {@link org.opengis.filter.Filter}
+ */
+public interface Filter extends FilterType, org.opengis.filter.Filter {
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     *
+     * @task Gets a short representation of the type of this filter.
+     *
+     * @deprecated The enumeration base type system is replaced with a class
+     * based type system. An 'instanceof' check should be made instead of
+     * calling this method.
+     */
+    short getFilterType();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterAbstract.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterAbstract.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterAbstract.java	(revision 28000)
@@ -0,0 +1,90 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.filter.FilterVisitor;
+
+/**
+ * Abstract implementation for Filter.
+ *
+ * @author Jody Garnett
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/FilterAbstract.java $
+ */
+public abstract class FilterAbstract implements org.opengis.filter.Filter 
+	 {
+	
+	/** filter factory **/
+	protected org.opengis.filter.FilterFactory factory;
+	
+	/**
+	 * @param factory FilterFactory injected into the filter.
+	 */
+	protected FilterAbstract(org.opengis.filter.FilterFactory factory) {
+		this.factory = factory;
+	}
+	
+	/**
+	 * Subclass should overrride.
+	 * 
+	 * Default value is false
+	 */
+	public boolean evaluate(SimpleFeature feature) {
+		return evaluate((Object)feature);
+	}
+	
+	/**
+	 * Subclass should overrride.
+	 *
+	 * Default value is false
+	 */
+        /*force subclass to implement
+	public boolean evaluate(Object object) {
+		return false;
+	}
+        */
+        
+	
+	/** Subclass should override, default implementation just returns extraData */
+	public Object accept(FilterVisitor visitor, Object extraData) {
+		return extraData;
+	}
+		
+	/**
+	 * Helper method for subclasses to reduce null checks
+     * 
+	 * @param expression
+	 * @param object
+	 * @return value or null
+	 */
+	protected Object eval(org.opengis.filter.expression.Expression expression, Object object) {
+		if( expression == null ) return null;
+		Object value = expression.evaluate( object );
+        //HACK as this method is used internally for filter 
+        //evaluation comparisons, etc, they work over the
+        //contents (i.e. comparing an attexpresion with a literal)
+        //so, lacking a better way of doing so, I'm putting this
+        //check here
+        if(value instanceof org.opengis.feature.Attribute){
+            value = ((org.opengis.feature.Attribute)value).getValue();
+        }
+        return value;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterAttributeExtractor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterAttributeExtractor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterAttributeExtractor.java	(revision 28000)
@@ -0,0 +1,112 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.geotools.filter.visitor.DefaultFilterVisitor;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.filter.expression.PropertyName;
+
+
+
+/**
+ * A simple visitor that extracts every attribute used by a filter or an expression
+ * <p>
+ * Access to this class is available via:
+ * <ul>
+ * <li>DataUtilities.attributeNames( Filter )</li>
+ * <li>DataUtilities.attributeNames( Filter, FeatureType )</li>
+ * <li>DataUtilities.attributeNames( Expression )</li>
+ * <li>DataUtilities.attributeNames( Expression, FeatureType )</li>
+ * </ul>
+ * 
+ * The class can also be used to determine if an expression is "static", that is, 
+ * despite a complex structure does not use attribute or volatile functions, and can
+ * be thus replaced by a constant: for this use case refer to the 
+ * {@link #isConstantExpression()} method
+ * 
+ * @author Andrea Aime - GeoSolutions
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/FilterAttributeExtractor.java $
+ */
+public class FilterAttributeExtractor extends DefaultFilterVisitor {
+    /** Last set visited */
+    protected Set<String> attributeNames = new HashSet<String>();
+
+    /** feature type to evaluate against */
+    protected SimpleFeatureType featureType;
+
+    /**
+     * Just extract the property names; don't check against a feature type.
+     */
+    public FilterAttributeExtractor() {
+        this(null);
+    }
+    /**
+     * Use the provided feature type as a sanity check when extracting
+     * property names.
+     * 
+     * @param featureType
+     */
+    public FilterAttributeExtractor(SimpleFeatureType featureType) {
+        this.featureType = featureType;
+    }
+    /**
+     * DOCUMENT ME!
+     *
+     * @return an unmofiable set of the attribute names found so far during the visit
+     */
+    public Set<String> getAttributeNameSet() {
+        return Collections.unmodifiableSet(attributeNames);
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return an array of the attribute names found so far during the visit
+     */
+    public String[] getAttributeNames() {
+        return attributeNames.toArray(new String[attributeNames.size()]);
+    }
+
+    public Object visit( PropertyName expression, Object data ) {
+        if( data != null && data != attributeNames ){
+            attributeNames = (Set<String>) data;
+        }
+        if (featureType != null) {
+            //evaluate against the feature type instead of using straight name
+            // since the path from the property name may be an xpath or a 
+            // namespace prefixed string
+            AttributeDescriptor type = (AttributeDescriptor) expression.evaluate( featureType );
+            if ( type != null ) {
+               attributeNames.add( type.getLocalName() );
+            }
+            else {
+               attributeNames.add( expression.getPropertyName() );
+            }
+        }
+        else {
+            attributeNames.add( expression.getPropertyName() );
+        }
+
+        return attributeNames;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterFactory.java	(revision 28000)
@@ -0,0 +1,60 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import org.geotools.factory.Factory;
+import org.opengis.feature.type.FeatureTypeFactory;
+
+
+/**
+ * This specifies the interface to create filters.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/FilterFactory.java $
+ * @version $Id: FilterFactory.java 37280 2011-05-24 07:53:02Z mbedward $
+ *
+ * @task TODO: This needs to be massively overhauled.  This should be the
+ *       source of immutability of filters.  See {@link FeatureTypeFactory},
+ *       as that provides a good example of what this should look like.  The
+ *       mutable factory to create immutable objects is a good model for this.
+ *       The creation methods should only create fully formed filters.  This
+ *       in turn means that all the set functions in the filters should be
+ *       eliminated.  When rewriting this class/package, keep in mind
+ *       FilterSAXParser in the filter module, as the factory should fit
+ *       cleanly with that, and should handle sax parsing without too much
+ *       memory overhead.
+ * @task REVISIT: resolve errors, should all throw errors?
+ *
+ * @deprecated use {@link org.opengis.filter.FilterFactory}
+ */
+public interface FilterFactory extends Factory, org.opengis.filter.FilterFactory2 {
+
+    /**
+     * @deprecated use {@link org.opengis.filter.FilterFactory#or(org.opengis.filter.Filter, org.opengis.filter.Filter)}
+     */
+    public Filter or(Filter f1, Filter f2);
+
+    /**
+     * @deprecated use {@link org.opengis.filter.FilterFactory#and(org.opengis.filter.Filter, org.opengis.filter.Filter)}
+     */
+    public Filter and(Filter f1, Filter f2);
+
+    /**
+     * @deprecated use {@link org.opengis.filter.FilterFactory#not(org.opengis.filter.Filter)}
+     */
+    public Filter not(Filter f);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterFactoryImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterFactoryImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterFactoryImpl.java	(revision 28000)
@@ -0,0 +1,190 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *
+ * Created on 24 October 2002, 16:16
+ */
+package org.geotools.filter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.geotools.factory.Hints;
+import org.geotools.filter.capability.FunctionNameImpl;
+import org.geotools.filter.expression.AddImpl;
+import org.geotools.filter.expression.DivideImpl;
+import org.geotools.filter.expression.MultiplyImpl;
+import org.geotools.filter.expression.SubtractImpl;
+import org.geotools.filter.identity.FeatureIdImpl;
+import org.opengis.filter.And;
+import org.opengis.filter.Filter;
+import org.opengis.filter.Id;
+import org.opengis.filter.Not;
+import org.opengis.filter.Or;
+import org.opengis.filter.capability.FunctionName;
+import org.opengis.filter.expression.Add;
+import org.opengis.filter.expression.Divide;
+import org.opengis.filter.expression.Expression;
+import org.opengis.filter.expression.Function;
+import org.opengis.filter.expression.Literal;
+import org.opengis.filter.expression.Multiply;
+import org.opengis.filter.expression.PropertyName;
+import org.opengis.filter.expression.Subtract;
+import org.opengis.filter.identity.FeatureId;
+import org.xml.sax.helpers.NamespaceSupport;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+
+/**
+ * Implementation of the FilterFactory, generates the filter implementations in
+ * defaultcore.
+ *
+ * @author Ian Turton, CCG
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/FilterFactoryImpl.java $
+ * @version $Id: FilterFactoryImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public class FilterFactoryImpl implements FilterFactory {
+        
+    private FunctionFinder functionFinder;
+
+    /**
+     * Creates a new instance of FilterFactoryImpl
+     */
+    public FilterFactoryImpl() {
+        this( null );
+    }
+    public FilterFactoryImpl( Hints hints ){
+        functionFinder = new FunctionFinder( null );
+    }
+
+    public FeatureId featureId(String id) {
+        return new FeatureIdImpl( id );
+    } 
+        
+    public And and(Filter f, Filter g ) {
+        List/*<Filter>*/ list = new ArrayList/*<Filter>*/( 2 );
+        list.add( f );
+        list.add( g );
+        return new AndImpl( this, list );
+    }
+    
+    public And and(List/*<Filter>*/ filters) {
+        return new AndImpl( this, filters );
+    }
+    
+    public Or or(Filter f, Filter g) {
+        List/*<Filter>*/ list = new ArrayList/*<Filter>*/( 2 );
+        list.add( f );
+        list.add( g );
+        return new OrImpl( this, list );
+    }    
+
+    public Or or(List/*<Filter>*/ filters) {
+        return new OrImpl( this, filters );
+    }
+    
+    /** Java 5 type narrowing used to advertise explicit implementation for chaining */
+    public Not /*NotImpl*/ not(Filter filter) {
+        return new NotImpl( this, filter );
+    }
+    
+    public Id id( Set id ){
+        return new FidFilterImpl( id );
+    }
+    
+    public PropertyName property(String name) {
+        return new AttributeExpressionImpl(name);
+    }
+
+    public Add add(Expression expr1, Expression expr2) {
+        return new AddImpl(expr1,expr2);
+    }
+
+    public Divide divide(Expression expr1, Expression expr2) {
+        return new DivideImpl(expr1,expr2);
+    }
+
+    public Multiply multiply(Expression expr1, Expression expr2) {
+        return new MultiplyImpl(expr1,expr2);
+    }
+
+    public Subtract subtract(Expression expr1, Expression expr2) {
+        return new SubtractImpl(expr1,expr2);
+    }
+
+    public Function function(String name, Expression[] args) {
+        Function function = functionFinder.findFunction( name, Arrays.asList(args) );
+        return function;
+    }
+    
+    public Literal literal(Object obj) {
+        try {
+            return new LiteralExpressionImpl(obj);
+        } 
+        catch (IllegalFilterException e) {
+            new IllegalArgumentException().initCause(e);
+        }
+        
+        return null;
+    }
+
+    /**
+     * Creates a BBox Expression from an envelope.
+     *
+     * @param env the envelope to use for this bounding box.
+     *
+     * @return The newly created BBoxExpression.
+     *
+     * @throws IllegalFilterException if there were creation problems.
+     */
+    public BBoxExpression createBBoxExpression(Envelope env)
+        throws IllegalFilterException {
+        return new BBoxExpressionImpl(env);
+    }
+
+    public Map getImplementationHints() {
+            return Collections.EMPTY_MAP;
+    }
+
+    public org.geotools.filter.Filter and( org.geotools.filter.Filter filter1, org.geotools.filter.Filter filter2 ) {
+        return (org.geotools.filter.Filter) and( (Filter) filter1, (Filter) filter2 );         
+    } 
+
+    public org.geotools.filter.Filter not( org.geotools.filter.Filter filter ) {
+        return (org.geotools.filter.Filter) not( (Filter) filter );
+    }
+
+    public org.geotools.filter.Filter or( org.geotools.filter.Filter filter1, org.geotools.filter.Filter filter2 ) {
+        return (org.geotools.filter.Filter) or( (Filter) filter1, (Filter) filter2 );
+    }
+    
+    public PropertyName property( String name, NamespaceSupport namespaceContext ) {
+        if (namespaceContext == null) {
+            return property(name);
+        }
+        return new AttributeExpressionImpl(name, namespaceContext );
+    }
+    
+    public FunctionName functionName(String name, int nargs) {
+        return new FunctionNameImpl( name, nargs );
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FilterType.java	(revision 28000)
@@ -0,0 +1,106 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+
+/**
+ * The FilterType interface lists all the possible type of filter.
+ * <p>
+ * Example:<pre><code>
+ * BEFORE: filter.getFilterType() == FilterType.GEOMETRY_CONTAINS
+ * QUICK:  Filters.getFilterType( filter ) == FilterType.GEOMETRY_CONTAINS
+ * AFTER: filter instanceof Contains
+ * </code></pre>
+ *
+ * @author aaime
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/FilterType.java $
+ * @deprecated please use instance of check against geoapi class.
+ */
+public interface FilterType {
+    /* ***********************************************************************
+     * This is a listing of all possible filter types, grouped by types that
+     * are implemented by a single filter (ie. all logic types are implemented
+     * by FilterLogic).
+     * **********************************************************************/
+
+    /* Types implemented by FilterLogic */
+    /** Defines a logical 'OR' filter. */
+    public static final short LOGIC_OR = 1;
+
+    /** Defines a logical 'AND' filter. */
+    public static final short LOGIC_AND = 2;
+
+    /** Defines a logical 'NOT' filter. */
+    public static final short LOGIC_NOT = 3;
+
+    /* Types implemented by FilterGeometry */
+    /** Defines a geometric bounding box filter. */
+    public static final short GEOMETRY_BBOX = 4;
+
+    /** Defines a geometric 'EQUALS' operator. */
+    public static final short GEOMETRY_EQUALS = 5;
+
+    /** Defines a geometric 'DISJOINT' operator. */
+    public static final short GEOMETRY_DISJOINT = 6;
+
+    /** Defines a geometric 'INTERSECTS' operator. */
+    public static final short GEOMETRY_INTERSECTS = 7;
+
+    /** Defines a geometric 'CROSSES' operator. */
+    public static final short GEOMETRY_CROSSES = 9;
+
+    /** Defines a geometric 'WITHIN' operator. */
+    public static final short GEOMETRY_WITHIN = 10;
+
+    /** Defines a geometric 'CONTAINS' operator. */
+    public static final short GEOMETRY_CONTAINS = 11;
+
+    /** Defines a geometric 'OVERLAPS' operator. */
+    public static final short GEOMETRY_OVERLAPS = 12;
+
+    /** Defines a geometric 'BEYOND' operator. */
+    public static final short GEOMETRY_BEYOND = 13;
+
+    /** Defines a geometric 'DWITHIN' operator. */
+    public static final short GEOMETRY_DWITHIN = 24;
+
+    /* Types implemented by FilterCompare */
+    /** Defines a comparative equals filter (may be a math filter). */
+    public static final short COMPARE_EQUALS = 14;
+
+    /** Defines a comparative less than filter (is a math filter). */
+    public static final short COMPARE_LESS_THAN = 15;
+
+    /** Defines a comparative greater than filter (is a math filter). */
+    public static final short COMPARE_GREATER_THAN = 16;
+
+    /** Defines a comparative less than/equals filter (is a math filter). */
+    public static final short COMPARE_LESS_THAN_EQUAL = 17;
+
+    /** Defines a comparative greater than/equals filter (is a math filter). */
+    public static final short COMPARE_GREATER_THAN_EQUAL = 18;
+
+    /** Defines a comparative not equals filter (may be a math filter). */
+    public static final short COMPARE_NOT_EQUALS = 23;
+
+    /** Defines a null filter, which is implemented by FilterNull. */
+    public static final short NULL = 21;
+
+    /** Defines a fid filter, which is implemented by FidFilterImpl. */
+    public static final short FID = 22;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/Filters.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/Filters.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/Filters.java	(revision 28000)
@@ -0,0 +1,199 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *        
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.awt.Color;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.geotools.factory.CommonFactoryFinder;
+import org.opengis.filter.expression.Expression;
+
+/**
+ * Utility class for working with Filters & Expression.
+ * <p>
+ * To get the full benifit you will need to create an instanceof
+ * this Object (supports your own custom FilterFactory!). Additional
+ * methods to help create expressions are available.
+ * </p>
+ * <p>
+ * Example use:
+ * <pre><code>
+ * Filters filters = new Filters( factory );
+ * filters.duplicate( origional );
+ * </code></pre>
+ * The above example creates a copy of the provided Filter,
+ * the factory provided will be used when creating the duplicated
+ * content.
+ * </p>
+ * <h3>Expression</h3>
+ * <p>
+ * Expressions form an interesting little semi scripting languge,
+ * intended for queries.  A interesting Feature of Filter as a language
+ * is that it is not strongly typed. This utility class many helper
+ * methods that ease the transition from Strongly typed Java to the more
+ * relaxed setting of Expression where most everything can be a string.
+ * </p>
+ * <pre><code>
+ * double sum = Filters.number( Object ) + Filters.number( Object );
+ * </code></pre>
+ * The above example will support the conversion of many things into a format
+ * suitable for addition - the complete list is something like:
+ * <ul>
+ * <li>Any instance of Number
+ * <li>"1234" - aka Integer
+ * <li>"#FFF" - aka Integer 
+ * <li>"123.0" - aka Double
+ * </ul>
+ * A few things (like Geometry and "ABC") will not be considered addative.
+ * </p>
+ * In general the scope of these functions should be similar to that
+ * allowed by the XML Atomic Types, aka those that can be seperated by
+ * whitespace to form a list.
+ * </p>
+ * <p>
+ * We do our best to be forgiving, any Java class which takes a String as
+ * a constructor can be tried, and toString() assumed to be the inverse. This
+ * lets many things (like URL and Date) function without modification.
+ * </p>
+ * 
+ * @author Jody Garnett, Refractions Research
+ * @since GeoTools 2.2.M3
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/Filters.java $
+ */
+public class Filters {
+	
+	public Filters(){
+		this( CommonFactoryFinder.getFilterFactory2(null) );
+	}	
+	public Filters( org.opengis.filter.FilterFactory2 factory ){
+	}
+
+      
+    /**
+     * Treat provided value as a Number, used for math opperations.
+     * <p>
+     * This function allows for the non stongly typed Math Opperations
+     * favoured by the Expression standard.
+     * </p>
+     * <p>
+     * Able to hanle:
+     * <ul>
+     * <li>null - to NaN
+     * <li>Number
+     * <li>String - valid Integer and Double encodings
+     * </ul>
+     * 
+     * </p>
+     * @param value
+     * @return double or Double.NaN;
+     * @throws IllegalArgumentException For non numerical among us -- like Geometry 
+     */
+    public static double number(Object value) {
+    	if( value == null ) return Double.NaN;
+    	if( value instanceof Number ){
+    		Number number = (Number) value;
+    		return number.doubleValue();
+    	}
+    	if( value instanceof String ){
+    		String text = (String) value;
+    		try {
+				Number number = (Number) gets( text, Number.class );
+				return number.doubleValue();
+			} catch (Throwable e) {
+				throw new IllegalArgumentException("Unable to decode '"+text+"' as a number" );				
+			}    		
+    	}
+    	if( value instanceof Expression ){
+    		throw new IllegalArgumentException("Cannot deal with un evaulated Expression");
+    	}
+    	throw new IllegalArgumentException("Unable to evaulate "+value.getClass()+" in a numeric context");
+    }
+    
+    /**
+     * Used to upcovnert a "Text Value" into the provided TYPE.
+     * <p>
+     * Used to tread softly on the Java typing system, because
+     * Filter/Expression is not strongly typed. Values in in
+     * Expression land are often not the the real Java Objects
+     * we wish they were - it is reall a small, lax, query
+     * language and Java objects need a but of help getting
+     * through.
+     * <p>
+     * </p>
+     * A couple notes:
+     * <ul>
+     * <li>Usual trick of reflection for a Constructors that
+     *     supports a String parameter is used as a last ditch effort.
+     *     </li>
+     * <li>will do its best to turn Object into the indicated Class
+     * <li>will be used for ordering literals against attribute values
+     *     are calculated at runtime (like Date.)
+     * </ul>
+     * Remember Strong typing is for whimps who know what they are
+     * doing ahead of time. Real programmers let their program
+     * learn at runtime... :-)
+     * </p>
+     * 
+     * @param text
+     * @param TYPE
+     * @throws open set of Throwable reflection for TYPE( String ) 
+     */
+    public static Object gets( String text, Class TYPE ) throws Throwable {
+    	if( text == null ) return null;
+    	if( TYPE == String.class ) return text;
+    	if( TYPE == Integer.class ) {
+    		return Integer.decode( text );    		
+    	}
+    	if( TYPE == Double.class ){
+    		return Double.valueOf( text );
+    	}
+    	if( TYPE == Number.class ){
+    		try {
+    			return Double.valueOf( text );
+    		}
+    		catch( NumberFormatException ignore ){
+    		}
+    		return Integer.decode( text );    		
+    	}
+    	if( TYPE == Color.class ){
+    		return new Color( Integer.decode( text ).intValue() );
+    	}    	
+    	try {
+			Constructor create = TYPE.getConstructor( new Class[]{String.class});
+			return create.newInstance( new Object[]{ text } );
+		} catch (SecurityException e) {
+			// hates you
+		} catch (NoSuchMethodException e) {
+			// nope
+		} catch (IllegalArgumentException e) {
+			// should not occur
+		} catch (InstantiationException e) {
+			// should not occur, perhaps the class was abstract?
+			// eg. Number.class is a bad idea
+		} catch (IllegalAccessException e) {
+			// hates you
+		} catch (InvocationTargetException e) {
+			// should of worked but we got a real problem,
+			// an actual problem
+			throw e.getCause();
+		}    	
+    	return null;
+    }
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionExpression.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionExpression.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionExpression.java	(revision 28000)
@@ -0,0 +1,72 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.util.List;
+
+import org.geotools.factory.Factory;
+import org.opengis.filter.expression.Function;
+
+
+/**
+ * Interface for a function expression implementation
+ *
+ * @author James Macgill, PSU
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/FunctionExpression.java $
+ *
+ * @deprecated use {@link org.opengis.filter.expression.Function}
+ */
+public interface FunctionExpression extends Expression, Factory, Function {
+    /**
+     *   Returns the number of arguments this <Function> requires.
+     *
+     *   For example <Function name="strCat"> [arg1][arg2]</Function>.
+     *   This function must have EXACTLY 2 arguments, so this function
+     *   would return 2.
+     *
+     *   The parser might use this information to ensure validity,
+     *   and its also for reporting <Function> capabilities.
+     *
+     *  NOTE: this was previously javadoc-ed incorrectly, please note
+     *        the new definition.
+     *  NOTE: you cannot have a function with a variable number of
+     *        arguments.
+     *
+     * @return the number of args required by this function.
+     */
+    int getArgCount();
+
+    /**
+     * Gets the type of this expression.
+     *
+     * @return the short representation of a function expression.
+     */
+    short getType();
+
+    /**
+     * Gets the name of this function.
+     *
+     * @return the name of the function.
+     */
+    String getName();
+
+    /**
+     * Sets the paramters for the function.
+     */
+    void setParameters(List parameters);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionExpressionImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionExpressionImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionExpressionImpl.java	(revision 28000)
@@ -0,0 +1,162 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *        
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.opengis.filter.expression.ExpressionVisitor;
+import org.opengis.filter.expression.Function;
+import org.opengis.filter.expression.Literal;
+
+/**
+ * Abstract class for a function expression implementation
+ *
+ * @author James Macgill, PSU
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/FunctionExpressionImpl.java $
+ */
+public abstract class FunctionExpressionImpl
+    extends org.geotools.filter.DefaultExpression implements FunctionExpression {
+	
+	/** function name **/
+	protected String name;
+
+	/** function params **/
+	protected List params;
+	
+    protected Literal fallback;
+	
+    protected FunctionExpressionImpl(String name ){
+        this( name, null );
+    }
+    /**
+     * Creates a new instance of FunctionExpression
+     */
+    protected FunctionExpressionImpl(String name, Literal fallback) {
+        this.name = name;
+        this.fallback = fallback;
+        params = new ArrayList();
+    }
+
+     /**
+     * Gets the type of this expression.
+     *
+     * @return the short representation of a function expression.
+     */
+    public short getType() {
+        return FUNCTION;
+    }
+
+    /**
+     * Gets the name of this function.
+     *
+     * @return the name of the function.
+     * 
+     */
+    public String getName() {
+    	return name;
+    }
+
+    /**
+     * Returns the function parameters.
+     */
+    public List getParameters() {
+    	return params;
+    }
+    
+    /**
+     * Sets the function parameters.
+     */
+    public void setParameters(List params) {
+        if(params == null){
+            throw new NullPointerException("params can't be null");
+        }
+        final int argCount = getArgCount();
+        final int paramsSize = params.size();
+        if(argCount > 0 && argCount != paramsSize){
+            throw new IllegalArgumentException("Function "+name+" expected " + argCount + 
+                    " arguments, got " + paramsSize);
+        }
+    	this.params = new ArrayList(params);
+    }
+    
+    /**
+     * Gets the number of arguments that are set.
+     *
+     * @return the number of args.
+     */
+    public abstract int getArgCount();
+
+    /**
+     * @see org.opengis.filter.expression.Expression#accept(ExpressionVisitor, Object)
+     */
+    public Object accept(ExpressionVisitor visitor, Object extraData) {
+    	return visitor.visit(this, extraData);
+    }
+    
+    /**
+     * Returns the implementation hints. The default implementation returns an empty map.
+     */
+    public Map getImplementationHints() {
+        return Collections.EMPTY_MAP;
+    }
+    
+    /**
+     * Creates a String representation of this Function with
+     * the function name and the arguments. The String created
+     * should be good for most subclasses
+     */
+    public String toString(){
+        StringBuffer sb = new StringBuffer();
+        sb.append(getName());
+        sb.append("(");
+        List params = getParameters();
+        if(params != null){
+            org.opengis.filter.expression.Expression exp;
+            for(Iterator it = params.iterator(); it.hasNext();){
+                exp = (Expression) it.next();
+                sb.append("[");
+                sb.append(exp);
+                sb.append("]");
+                if(it.hasNext()){
+                    sb.append(", ");
+                }
+            }
+        }
+        sb.append(")");
+        return sb.toString();
+    }
+        
+    public boolean equals(Object obj) {
+    	if( obj == null || !(obj instanceof Function)){
+    		return false;
+    	}
+    	Function other = (Function) obj;
+    	if( ( getName() == null && other.getName() != null ) ||
+    	    (getName() != null && !getName().equalsIgnoreCase( other.getName() ))){
+    		return false;
+    	}
+    	if( getParameters() == null && other.getClass() != null ){
+    		return false;
+    	}
+    	return getParameters() != null && getParameters().equals( other.getParameters() );
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionFactory.java	(revision 28000)
@@ -0,0 +1,53 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2010, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.util.List;
+
+import org.opengis.filter.capability.FunctionName;
+import org.opengis.filter.expression.Expression;
+import org.opengis.filter.expression.Function;
+import org.opengis.filter.expression.Literal;
+
+/**
+ * Factory interface for filter functions.
+ * 
+ * @author Justin Deoliveira, OpenGeo
+ *
+ * @since 2.7
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/FunctionFactory.java $
+ */
+public interface FunctionFactory {
+
+    /**
+     * Returns the list of function names the factory provides. 
+     * 
+     * @return A list of function names, possibly empty, never null.
+     */
+    List<FunctionName> getFunctionNames();
+    
+    /**
+     * Returns a function with the specified name.
+     * 
+     * @param name The name of the function
+     * @param args Variable list of expression arguments for the function.
+     * @param fallback A fallback literal to use in cases where the function does not exist or 
+     *   can not be created. This argument may be {@code null}.
+     */
+    Function function(String name, List<Expression> args, Literal fallback);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionFinder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionFinder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionFinder.java	(revision 28000)
@@ -0,0 +1,138 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.factory.Hints;
+import org.opengis.filter.capability.FunctionName;
+import org.opengis.filter.expression.Function;
+import org.opengis.filter.expression.Literal;
+
+/**
+ * Isolate function lookup code from Factory implementation(s).
+ * <p>
+ * This is done to look for two things:
+ * <ul>
+ * <li>org.geotools.filter.Function
+ * <li>org.opengis.filter.expression.Function
+ * </ul>
+ * This is done as a proper utility class that accepts Hints.
+ * 
+ * @author Jody Garnett
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/FunctionFinder.java $
+ */
+public class FunctionFinder {
+    private volatile Map<String,FunctionFactory> functionFactoryCache;
+    
+    public FunctionFinder(Hints hints) {
+        // currently hints are not used, need help :-P
+    }
+    
+    /**
+     * Look up a function for the provided name.
+     * 
+     * @param name Function name; this will need to be an exact match
+     * @param parameters Set of parameters required
+     * @return Generated function
+     * @throws a RuntimeException if an implementation for name could not be found
+     */
+    public Function findFunction(String name, List/* <Expression> */parameters){
+    	return findFunction(name, parameters, null );
+	}
+    
+    /**
+     * Look up a function for the provided name, may return a FallbackFunction if
+     * an implementation could not be found.
+     * <p>
+     * You can create a function to represent an SQL function or a function hosted on
+     * an external service; the fallback value will be used if you evulate 
+     * by a Java implementation on the classpath.
+     * @param name Function name; this will need to be an exact match
+     * @param parameters Set of Expressions to use as function parameters
+     * @param fallbackValue Literal to use if an implementation could not be found
+     * @return Function for the provided name, may be a FallbackFunction if an implementation could not be found
+     */
+    public Function findFunction(String name, List parameters, Literal fallback) {
+        //try name as is
+        Function f = findFunctionInternal(name, parameters, fallback);
+        if (f == null) {
+            //try by trimming "Function" off of name
+            if (name.endsWith("Function")) {
+                name = name.substring(0, name.length()-"Function".length());
+                f = findFunctionInternal(name, parameters, fallback);
+            }
+        }
+        if( f == null && fallback != null ){
+            return new FallbackFunction( name, parameters, fallback );
+        }
+        
+        
+        if (f != null) {
+            return f;
+        }
+        
+        throw new RuntimeException("Unable to find function " + name);
+
+    }
+
+    Function findFunctionInternal(String name, List parameters, Literal fallback) {
+        if (functionFactoryCache == null) {
+            synchronized (this) {
+                if (functionFactoryCache == null) {
+                    functionFactoryCache = lookupFunctions();
+                }
+            }
+        }
+        
+        if (functionFactoryCache.containsKey(name)) {
+            return functionFactoryCache.get(name).function(name, parameters, fallback);
+        }
+        
+        //do a lookup from all factories, this is because of the name tricks the default
+        // factory does
+        Function f = null;
+        for (FunctionFactory ff : CommonFactoryFinder.getFunctionFactories(null)) {
+            f = ff.function(name, parameters, fallback);
+            if (f != null) return f;
+        }
+
+        return null;
+    }
+    
+    private HashMap lookupFunctions() {
+        // get all filter functions via function factory
+        HashMap result = new HashMap();
+        
+        Set<FunctionFactory> functionFactories = 
+            CommonFactoryFinder.getFunctionFactories(null);
+        for (FunctionFactory ff : functionFactories) {
+            for (FunctionName functionName : ff.getFunctionNames()) {
+                result.put(functionName.getName(), ff);
+            }
+        }
+        
+        return result;
+    }
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/FunctionImpl.java	(revision 28000)
@@ -0,0 +1,94 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.geotools.filter.expression.ExpressionAbstract;
+import org.opengis.filter.expression.Expression;
+import org.opengis.filter.expression.ExpressionVisitor;
+import org.opengis.filter.expression.Function;
+import org.opengis.filter.expression.Literal;
+
+/**
+ * Default implementation of a Function; you may extend this class to
+ * implement specific functionality.
+ * <p>
+ * 
+ * @author Cory Horner, Refractions Research
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/FunctionImpl.java $
+ */
+public class FunctionImpl extends ExpressionAbstract implements Function {
+
+    /** function name **/
+    String name;
+
+    /** function params **/
+    List<Expression> params = Collections.emptyList();
+    
+    Literal fallbackValue;
+    
+    /**
+     * Gets the name of this function.
+     *
+     * @return the name of the function.
+     * 
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the function parameters.
+     */
+    public List<Expression> getParameters() {
+        return new ArrayList<Expression>(params);
+    }
+    
+    /**
+     * Default implementation simply returns the fallbackValue.
+     * <p>
+     * Please override this method to produce a value based on the
+     * provided arguments.
+     * @param object Object being evaluated; often a Feature
+     * @return value for the provided object
+     */
+    public Object evaluate(Object object) {
+    	return fallbackValue.evaluate( object );
+    }
+    
+    /**
+     * Sets the function parameters.
+     */
+    @SuppressWarnings("unchecked")
+    public void setParameters(List<Expression> params) {
+        this.params = params == null? Collections.EMPTY_LIST : new ArrayList<Expression>(params);
+    }
+
+    public void setFallbackValue(Literal fallbackValue) {
+        this.fallbackValue = fallbackValue;
+    }
+        
+    public Object accept(ExpressionVisitor visitor, Object extraData) {
+    	return visitor.visit( this, extraData );
+    }	
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/GeometryDistanceFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/GeometryDistanceFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/GeometryDistanceFilter.java	(revision 28000)
@@ -0,0 +1,67 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import org.opengis.filter.spatial.DistanceBufferOperator;
+
+
+/**
+ * Defines geometry filters with a distance element.
+ *
+ * <p>
+ * These filters are defined in the filter spec by the DistanceBufferType,
+ * which contains an additioinal field for a distance.  The two filters that
+ * use the distance buffer type are Beyond and DWithin.
+ * </p>
+ *
+ * <p>
+ * From the spec: The spatial operators DWithin and Beyond test whether the
+ * value of a geometric property is within or beyond a specified distance of
+ * the specified literal geometric value.  Distance values are expressed using
+ * the Distance element.
+ * </p>
+ *
+ * <p>
+ * For now this code does not take into account the units of distance,  we will
+ * assume that the filter units are the same as the geometry being filtered.
+ * </p>
+ *
+ * <p></p>
+ *
+ * @author Chris Holmes, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/GeometryDistanceFilter.java $
+ * @version $Id: GeometryDistanceFilter.java 37280 2011-05-24 07:53:02Z mbedward $
+ *
+ * @task REVISIT: add units for distance.  Should it just be a string?  Or
+ *       should it actually resolve the definition?
+ *
+ * @deprecated use {@link org.opengis.filter.spatial.DistanceBufferOperator}
+ *
+ */
+public interface GeometryDistanceFilter extends GeometryFilter, DistanceBufferOperator {
+    /**
+     * Returns true if the passed in object is the same as this filter.  Checks
+     * to make sure the filter types are the same as well as all three of the
+     * values.
+     *
+     * @param obj The filter to test equality against.
+     *
+     * @return True if the objects are equal.
+     */
+    boolean equals(Object obj);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/GeometryFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/GeometryFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/GeometryFilter.java	(revision 28000)
@@ -0,0 +1,64 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import org.opengis.filter.spatial.BinarySpatialOperator;
+
+
+/**
+ * Implements a geometry filter.
+ *
+ * <p>
+ * This filter implements a relationship - of some sort -  between two geometry
+ * expressions. Note that this comparison does not attempt to restict its
+ * expressions to be meaningful.  This means that it considers itself a valid
+ * filter as long as it contains two <b>geometry</b> sub-expressions. It is
+ * also slightly less  restrictive than the OGC Filter specification because
+ * it does not require that one sub-expression be an geometry attribute and
+ * the other be a geometry literal.
+ * </p>
+ *
+ * <p>
+ * In other words, you may use this filter to compare two geometries in the
+ * same feature, such as: attributeA inside attributeB?  You may also compare
+ * two literal geometries, although this is fairly meaningless, since it could
+ * be reduced (ie. it is always either true or false).  This approach is very
+ * similar to that taken in the FilterCompare class.
+ * </p>
+ *
+ * @author Rob Hranac, TOPP
+ * @author Chris Holmes, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/GeometryFilter.java $
+ * @version $Id: GeometryFilter.java 37280 2011-05-24 07:53:02Z mbedward $
+ *
+ * @todo REVISIT: make this class (and all filters) immutable, implement
+ *       cloneable and return new filters when calling addLeftGeometry and
+ *       addRightG Issues to think through: would be cleaner immutability to
+ *       have constructor called with left and right Geometries, but this does
+ *       not jive with SAX parsing, which is one of the biggest uses of
+ *       filters.  But the alternative is not incredibly efficient either, as
+ *       there will be two filters that  are just thrown away every time we
+ *       make a full geometry filter.  These issues extend to most filters, as
+ *       just about all of them are mutable when creating them.  Other issue
+ *       is that lots of code will need to  be changed for immutability.
+ *       (comments by cholmes) - MUTABLE FACTORIES!  Sax and immutability.
+ *
+ *  @deprecated use {@link org.opengis.filter.spatial.BinarySpatialOperator}.
+ */
+public interface GeometryFilter extends Filter, BinarySpatialOperator {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/GeometryFilterImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/GeometryFilterImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/GeometryFilterImpl.java	(revision 28000)
@@ -0,0 +1,258 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *        
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.opengis.feature.simple.SimpleFeature;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+
+/**
+ * Implements a geometry filter.
+ * 
+ * <p>
+ * This filter implements a relationship - of some sort -  between two geometry
+ * expressions. Note that this comparison does not attempt to restict its
+ * expressions to be meaningful.  This means that it considers itself a valid
+ * filter as long as it contains two <b>geometry</b> sub-expressions. It is
+ * also slightly less  restrictive than the OGC Filter specification because
+ * it does not require that one sub-expression be an geometry attribute and
+ * the other be a geometry literal.
+ * </p>
+ * 
+ * <p>
+ * In other words, you may use this filter to compare two geometries in the
+ * same feature, such as: attributeA inside attributeB?  You may also compare
+ * two literal geometries, although this is fairly meaningless, since it could
+ * be reduced (ie. it is always either true or false).  This approach is very
+ * similar to that taken in the FilterCompare class.
+ * </p>
+ *
+ * @author Rob Hranac, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/GeometryFilterImpl.java $
+ * @version $Id: GeometryFilterImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ *
+ * @task REVISIT: make this class (and all filters) immutable, implement
+ *       cloneable and return new filters when calling addLeftGeometry and
+ *       addRightG Issues to think through: would be cleaner immutability to
+ *       have constructor called with left and right Geometries, but this does
+ *       not jive with SAX parsing, which is one of the biggest uses of
+ *       filters.  But the alternative is not incredibly efficient either, as
+ *       there will be two filters that  are just thrown away every time we
+ *       make a full geometry filter.  These issues extend to most filters, as
+ *       just about all of them are mutable when creating them.  Other issue
+ *       is that lots of code will need to  be changed for immutability.
+ *       (comments by cholmes) - MUTABLE FACTORIES!  Sax and immutability.
+ */
+public abstract class GeometryFilterImpl extends BinaryComparisonAbstract
+    implements GeometryFilter {
+    /** Class logger */
+    private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geotools.filter");
+    
+    protected GeometryFilterImpl(org.opengis.filter.FilterFactory factory,org.opengis.filter.expression.Expression e1,org.opengis.filter.expression.Expression e2) {
+        super(factory,e1,e2);
+    }
+    
+    public void setExpression1(org.opengis.filter.expression.Expression expression) {
+        if (expression instanceof Expression) {
+            Expression leftGeometry = (Expression) expression;
+
+            // Checks if this is geometry filter or not and handles appropriately
+            if (DefaultExpression.isGeometryExpression(leftGeometry.getType())
+                    || permissiveConstruction) {
+                super.setExpression1(leftGeometry);
+            } else {
+                throw new IllegalFilterException("Attempted to add (left)"
+                        + " non-geometry expression" + " to geometry filter.");
+            }
+        } else {
+            // I guess we assume it is a good expression...
+            super.setExpression1(expression);
+        }
+
+    }
+  
+    public void setExpression2(org.opengis.filter.expression.Expression expression) {
+        if (expression instanceof Expression) {
+            Expression rightGeometry = (Expression) expression;
+
+            // Checks if this is math filter or not and handles appropriately
+            if (DefaultExpression.isGeometryExpression(rightGeometry.getType())
+                    || permissiveConstruction) {
+                super.setExpression2(rightGeometry);
+            } else {
+                throw new IllegalFilterException("Attempted to add (right)" + " non-geometry"
+                        + "expression to geometry filter.");
+            }
+        } else {
+            // I guess we assume it is a good expression...
+            super.setExpression2(expression);
+        }
+    }
+
+    /**
+     * Subclass convenience method for returning left expression as a 
+     * JTS geometry.
+     */
+    protected Geometry getLeftGeometry(Object feature) {
+        org.opengis.filter.expression.Expression leftGeometry = getExpression1();
+        
+         if (leftGeometry != null) {
+             Object obj = leftGeometry.evaluate(feature,Geometry.class);
+
+             //LOGGER.finer("leftGeom = " + o.toString()); 
+             return (Geometry) obj;
+         } else if (feature instanceof SimpleFeature) {
+             return (Geometry) ((SimpleFeature)feature).getDefaultGeometry();
+         }
+         return null;
+    }
+    
+    /**
+     * Subclass convenience method for returning right expression as a 
+     * JTS geometry.
+     */
+    protected Geometry getRightGeometry(Object feature) {
+        org.opengis.filter.expression.Expression rightGeometry = getExpression2();
+        
+         if (rightGeometry != null) {
+             return rightGeometry.evaluate(feature,Geometry.class);
+         } else if(feature instanceof SimpleFeature){
+             return (Geometry) ((SimpleFeature)feature).getDefaultGeometry();
+         }
+         return null;
+    }
+    
+    /**
+     * Determines whether or not a given feature is 'inside' this filter.
+     *
+     * @param feature Specified feature to examine.
+     *
+     * @return Flag confirming whether or not this feature is inside filter.
+     */
+    public boolean evaluate(SimpleFeature feature) {
+        return evaluate((Object)feature);
+    }
+
+    /**
+     * Return this filter as a string.
+     *
+     * @return String representation of this geometry filter.
+     */
+    public String toString() {
+        String operator = null;
+
+        // Handles all normal geometry cases
+        if (filterType == GEOMETRY_EQUALS) {
+            operator = " equals ";
+        } else if (filterType == GEOMETRY_DISJOINT) {
+            operator = " disjoint ";
+        } else if (filterType == GEOMETRY_INTERSECTS) {
+            operator = " intersects ";
+        } else if (filterType == GEOMETRY_CROSSES) {
+            operator = " crosses ";
+        } else if (filterType == GEOMETRY_WITHIN) {
+            operator = " within ";
+        } else if (filterType == GEOMETRY_CONTAINS) {
+            operator = " contains ";
+        } else if (filterType == GEOMETRY_OVERLAPS) {
+            operator = " overlaps ";
+        } else if (filterType == GEOMETRY_BEYOND) {
+            operator = " beyond ";
+        } else if (filterType == GEOMETRY_BBOX) {
+            operator = " bbox ";
+        }
+
+        org.opengis.filter.expression.Expression leftGeometry = getExpression1();
+        org.opengis.filter.expression.Expression rightGeometry = getExpression2();
+        
+        if ((expression1 == null) && (rightGeometry == null)) {
+            return "[ " + "null" + operator + "null" + " ]";
+        } else if (leftGeometry == null) {
+            return "[ " + "null" + operator + rightGeometry.toString() + " ]";
+        } else if (rightGeometry == null) {
+            return "[ " + leftGeometry.toString() + operator + "null" + " ]";
+        }
+
+        return "[ " + leftGeometry.toString() + operator
+        + rightGeometry.toString() + " ]";
+    }
+
+    /**
+     * Compares this filter to the specified object.  Returns true  if the
+     * passed in object is the same as this filter.  Checks  to make sure the
+     * filter types are the same as well as the left and right geometries.
+     *
+     * @param obj - the object to compare this GeometryFilter against.
+     *
+     * @return true if specified object is equal to this filter; else false
+     */
+    public boolean equals(Object obj) {
+        if (obj instanceof GeometryFilterImpl) {
+            GeometryFilterImpl geomFilter = (GeometryFilterImpl) obj;
+            boolean isEqual = true;
+
+            isEqual = geomFilter.getFilterType() == this.filterType;
+            if( LOGGER.isLoggable(Level.FINEST) ) {
+                LOGGER.finest("filter type match:" + isEqual + "; in:"
+                        + geomFilter.getFilterType() + "; out:" + this.filterType);
+            }
+            isEqual = (geomFilter.expression1 != null)
+                ? (isEqual && geomFilter.expression1.equals(this.expression1))
+                : (isEqual && (this.expression1 == null));
+            if( LOGGER.isLoggable(Level.FINEST) ) {
+                LOGGER.finest("left geom match:" + isEqual + "; in:"
+                        + geomFilter.expression1 + "; out:" + this.expression1);
+            }
+            isEqual = (geomFilter.expression2 != null)
+                ? (isEqual
+                && geomFilter.expression2.equals(this.expression2))
+                : (isEqual && (this.expression2 == null));
+            if( LOGGER.isLoggable(Level.FINEST) ) {
+                LOGGER.finest("right geom match:" + isEqual + "; in:"
+                        + geomFilter.expression2 + "; out:" + this.expression2);
+            }
+            return isEqual;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Override of hashCode method.
+     *
+     * @return a hash code value for this geometry filter.
+     */
+    public int hashCode() {
+        org.opengis.filter.expression.Expression leftGeometry = getExpression1();
+        org.opengis.filter.expression.Expression rightGeometry = getExpression2();
+         
+        int result = 17;
+        result = (37 * result) + filterType;
+        result = (37 * result)
+            + ((leftGeometry == null) ? 0 : leftGeometry.hashCode());
+        result = (37 * result)
+            + ((rightGeometry == null) ? 0 : rightGeometry.hashCode());
+
+        return result;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/IllegalFilterException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/IllegalFilterException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/IllegalFilterException.java	(revision 28000)
@@ -0,0 +1,41 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+
+/**
+ * Defines an exception for illegal filters.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/IllegalFilterException.java $
+ * TODO: JD: Changed this exception to runtime exception. Go through all methods
+ * that throw this expception and reflect the new geoapi method throws it with
+ * a javadoc.
+ */
+public class IllegalFilterException extends RuntimeException {
+    /** Prevent warning. */
+    private static final long serialVersionUID = 6991878877158220201L;
+
+    /**
+     * Constructor with a message.
+     *
+     * @param message information on the error.
+     */
+    public IllegalFilterException(String message) {
+        super(message);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/LiteralExpression.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/LiteralExpression.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/LiteralExpression.java	(revision 28000)
@@ -0,0 +1,51 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import org.opengis.filter.expression.Literal;
+
+
+/**
+ * Defines an expression that holds a literal for return.
+ *
+ * @author Rob Hranac, Vision for New York
+ * @author Chris Holmes, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/LiteralExpression.java $
+ * @version $Id: LiteralExpression.java 37280 2011-05-24 07:53:02Z mbedward $
+ *
+ * @deprecated use {@link org.opengis.filter.expression.Literal}
+ */
+public interface LiteralExpression extends Expression, Literal {
+    /**
+     * Sets the literal.
+     *
+     * @param literal The literal to store inside this expression.
+     *
+     * @throws IllegalFilterException This literal type is not in scope.
+     *
+     * @deprecated use {@link Literal#setValue(Object)}
+     */
+    void setLiteral(Object literal) throws IllegalFilterException;
+
+    /**
+     * Returns the literal type.
+     *
+     * @return the short representation of the literal expression type.
+     */
+    short getType();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/LiteralExpressionImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/LiteralExpressionImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/LiteralExpressionImpl.java	(revision 28000)
@@ -0,0 +1,315 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *        
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.math.BigDecimal;
+
+import org.geotools.util.Converters;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.filter.expression.ExpressionVisitor;
+import org.opengis.filter.expression.Literal;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+
+/**
+ * Defines an expression that holds a literal for return.
+ *
+ * @author Rob Hranac, Vision for New York
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/LiteralExpressionImpl.java $
+ * @version $Id: LiteralExpressionImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public class LiteralExpressionImpl extends DefaultExpression
+    implements LiteralExpression {
+    
+    private static BigDecimal MAX_LONG = BigDecimal.valueOf(Long.MAX_VALUE);
+    private static BigDecimal MIN_LONG = BigDecimal.valueOf(Long.MIN_VALUE);
+    
+    /** Holds a reference to the literal. */
+    private Object literal = null;
+    
+    /** The converted value guessed inside evaluate(Feature) **/
+    private Object parsedValue = null;
+
+    /**
+     * Constructor with literal.
+     */
+    protected LiteralExpressionImpl() {
+    }
+
+    /**
+     * Constructor with literal.
+     *
+     * @param literal The literal to store inside this expression.
+     *
+     * @throws IllegalFilterException This literal type is not in scope.
+     */
+    protected LiteralExpressionImpl(Object literal)
+        throws IllegalFilterException {
+        this.setLiteral(literal);
+    }
+
+    /**
+     * Constructor with literal. This alternative constructor is a convinience
+     * one for integers an Integer object will be constructed, and no
+     * IllegalFilterException can ever be thrown.
+     *
+     * @param value The integer to store inside this expression.
+     */
+    protected LiteralExpressionImpl(int value) {
+        try {
+            this.setLiteral(new Integer(value));
+        } catch (IllegalFilterException ile) {
+            //this is imposible as this is only thrown for
+            //invalid types, and Integer is a valid type
+            throw new AssertionError(
+                "LiteralExpressionImpl is broken, it should accept Integers");
+        }
+    }
+    
+    /**
+     * Returns the literal type.
+     *
+     * @return the short representation of the expression type.
+     */
+    public short getType() {
+        return expressionType;
+    }
+
+    /**
+     * This method calls {@link #setValue(Object)}.
+     * 
+     * @deprecated use {@link #setValue(Object)}.
+     * 
+     */
+    public final void setLiteral(Object literal) throws IllegalFilterException {
+        setValue(literal);
+    }
+
+    /**
+     * Retrieves the literal of this expression.
+     *
+     * @return the literal held by this expression.
+     * 
+     */
+    public Object getValue() {
+    	return literal;
+    }
+    
+    /**
+     * Sets the literal.
+     *
+     * @param literal The literal to store inside this expression.
+     *
+     * @throws IllegalFilterException This literal type is not in scope.
+     */
+    public final void setValue(Object literal) {
+    	if (literal instanceof Double) {
+            expressionType = LITERAL_DOUBLE;
+        } else if (literal instanceof Integer) {
+            expressionType = LITERAL_INTEGER;
+        } else if (literal instanceof Long) {
+            expressionType = LITERAL_LONG;
+        } else if (literal instanceof String) {
+            expressionType = LITERAL_STRING;
+        } else if (literal instanceof Geometry) {
+            expressionType = LITERAL_GEOMETRY;
+        } else {
+            expressionType = LITERAL_UNDECLARED;
+        }
+
+        this.literal = literal;
+    }
+    
+    
+    /**
+     * Gets the value of this literal.
+     *
+     * @param feature Required by the interface but not used.
+     *
+     * @return the literal held by this expression.  Ignores the passed in
+     *         feature.  The literal held by this expression is almost invariably
+     *         a java.lang.String (so that no leading-zeros are lost during a string->
+     *         Class conversion.  This method will attempt to form the internal
+     *         String into a Integer, Double or BigInteger, before failing and
+     *         defaulting to a String.  To speed things up significantly, use the
+     *         evaluate(Object, Class) method so that we don't have to guess
+     *         at what you expect back from this evaluate method!
+     *
+     * @throws IllegalArgumentException Feature does not match declared schema.
+     */
+    public Object evaluate(SimpleFeature feature)
+    	throws IllegalArgumentException {
+    	return evaluate((Object)feature);
+    }
+
+    public Object evaluate(Object feature) {
+        //hrm.  Well, now that' we're always storing the internals of 
+        //Literals as strings, we need to be slightly smart about how we
+        //return what's inside.  Some (err, lots) of code relies on this
+        //method to return an instance of the correct TYPE.  I guess we should
+        //try and be somewhat smart about this.
+        
+        //ASSERTION: literal is always a string.
+        
+        // caching, don't try to reparse over and over the same literal
+        if(parsedValue != null)
+            return parsedValue;
+        
+        // actual parsing
+        if (literal == null || !(literal instanceof String)) {
+            parsedValue = literal;
+        } else {
+            String s = (String) literal;
+            
+            // check if it's a number
+            try {
+                BigDecimal bd = new BigDecimal(s);
+                
+                // check if it has a decimal part 
+                if(bd.scale() > 0) {
+                    double d = bd.doubleValue();
+                    // if too big for double, it will become infinite
+                    if(!Double.isInfinite(d))
+                        parsedValue = d;
+                    else
+                        parsedValue = bd;
+                } else {
+                    // it's integral, see if we can convert it to a long or int
+                    if(bd.compareTo(MIN_LONG) >= 0 && bd.compareTo(MAX_LONG) <= 0) {
+                        // in range to be a long 
+                        long l = bd.longValue();
+                        // if this test passes, it's actually an int
+                        if((int) l == l)
+                            parsedValue = new Integer((int) l);
+                        else
+                            parsedValue = new Long(l);
+                    } else {
+                        // out of range, switch to big decimal
+                        parsedValue = bd.toBigInteger();
+                    }
+                }
+            } catch(Exception e) {
+                // ok, it's not a number, let's keep it as it is
+                parsedValue = literal;
+            }
+            
+            
+        }  
+        return parsedValue;
+    }
+    
+    public Object evaluate(Object feature, Class context) {
+        return Converters.convert(literal, context);
+    }
+
+    /**
+     * Return this filter as a string.
+     *
+     * @return String representation of this geometry filter.
+     */
+    public String toString() {
+        return literal == null ? "NULL" : literal.toString();
+    }
+
+    /**
+     * Compares this filter to the specified object.  Returns true  if the
+     * passed in object is the same as this expression.  Checks  to make sure
+     * the expression types are the same as well as the literals.
+     *
+     * @param obj - the object to compare this ExpressionLiteral against.
+     *
+     * @return true if specified object is equal to this expression; false
+     *         otherwise.
+     *
+     * @task REVISIT: missmatched types now considered not equal. This may be a
+     *       problem when comparing Doubles and Integers
+     */
+    public boolean equals(Object obj) {
+        if (obj instanceof LiteralExpressionImpl) {
+            LiteralExpressionImpl expLit = (LiteralExpressionImpl) obj;
+            // This is a problem.  The Expression with type String of "2.0"
+            // should be equals to the Expression with type Integer of "2.0"
+            // Same thing with doubles and integers (as noted in the javadocs)
+
+            if (this.literal == null) {
+                return expLit.literal == null;
+            }
+            if (this.expressionType == expLit.expressionType) {
+                if(this.literal.equals(expLit.literal)) {
+                    return true;
+                } else if(expressionType == LITERAL_GEOMETRY && this.literal instanceof Geometry &&
+                        expLit.literal instanceof Geometry) {
+                    // deal with JTS stupid equal implementation
+                    if(((Geometry) literal).equals((Geometry) expLit.literal)) {
+                        return true;
+                    }
+                }
+            }
+
+            if (expressionType == LITERAL_GEOMETRY) {
+                return ((Geometry) this.literal).equals((Geometry) expLit.evaluate(null, Geometry.class));
+            } else if (expressionType == LITERAL_INTEGER) {
+                return ((Integer) this.literal).equals(expLit.evaluate(null, Integer.class));
+            } else if (expressionType == LITERAL_STRING) {
+                return ((String) this.literal).equals(expLit.evaluate(null, String.class));
+            } else if (expressionType == LITERAL_DOUBLE) {
+                return ((Double) this.literal).equals(expLit.evaluate(null, Double.class));
+            } else if (expressionType == LITERAL_LONG) {
+                return ((Long) this.literal).equals(expLit.evaluate(null, Long.class));                
+            } else {
+                return true;
+            }
+        }
+        else if (obj instanceof Literal) {
+            // some other Literal implementation like ConstantExpression
+            Literal other = (Literal) obj;
+            return equals( new LiteralExpressionImpl( other.getValue() ) );
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Override of hashCode method.
+     *
+     * @return the hash code for this literal expression
+     */
+    public int hashCode() {
+        int result = 17;
+
+        result = (37 * result) + ((literal == null) ? 0 : literal.hashCode());
+        result = (37 * result) + expressionType;
+
+        return result;
+    }
+
+    /**
+     * Used by FilterVisitors to perform some action on this filter instance.
+     * Typicaly used by Filter decoders, but may also be used by any thing
+     * which needs infomration from filter structure. Implementations should
+     * always call: visitor.visit(this); It is importatant that this is not
+     * left to a parent class unless the parents API is identical.
+     *
+     * @param visitor The visitor which requires access to this filter, the
+     *        method must call visitor.visit(this);
+     */
+    public Object accept(ExpressionVisitor visitor, Object extraData) {
+    	return visitor.visit(this,extraData);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/LogicFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/LogicFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/LogicFilter.java	(revision 28000)
@@ -0,0 +1,36 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import org.opengis.filter.BinaryLogicOperator;
+
+
+/**
+ * Defines a logic filter (the only filter type that contains other filters).
+ * This filter holds one or more filters together and relates them logically
+ * with an internally defined type (AND, OR, NOT).
+ *
+ * @author Rob Hranac, TOPP
+ * @author Chris Holmes, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/LogicFilter.java $
+ * @version $Id: LogicFilter.java 37280 2011-05-24 07:53:02Z mbedward $
+ *
+ * @deprecated use {@link org.opengis.filter.BinaryLogicOperator}
+ */
+public interface LogicFilter extends Filter, BinaryLogicOperator {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/LogicFilterImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/LogicFilterImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/LogicFilterImpl.java	(revision 28000)
@@ -0,0 +1,232 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *        
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+
+// Geotools dependencies
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.opengis.filter.And;
+import org.opengis.filter.FilterVisitor;
+import org.opengis.filter.Or;
+
+
+
+/**
+ * Defines a logic filter (the only filter type that contains other filters).
+ * This filter holds one or more filters together and relates them logically
+ * with an internally defined type (AND, OR, NOT).
+ *
+ * @author Rob Hranac, TOPP
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/LogicFilterImpl.java $
+ * @version $Id: LogicFilterImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public abstract class LogicFilterImpl extends BinaryLogicAbstract implements LogicFilter {
+    /** The logger for the default core module. */
+    private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geotools.core");
+
+      protected LogicFilterImpl(org.opengis.filter.FilterFactory factory) {
+        this(factory,new ArrayList());
+    }
+    
+    protected LogicFilterImpl(org.opengis.filter.FilterFactory factory, List children) {
+        super(factory,children);
+    }
+       
+    /**
+     * Implements a logical OR with this filter and returns the merged filter.
+     *
+     * @param filter Parent of the filter: must implement GMLHandlerGeometry.
+     *
+     * @return ORed filter.
+     *
+     * @task REVISIT: make immutable, should not modify the subfilters of the
+     *       filter being ored.
+     */
+    public Filter or(org.opengis.filter.Filter filter) {
+        // Just makes sure that we are not creating unnecessary new filters
+        //  by popping onto stack if current filter is OR
+        //HACK: not sure what should be returned by this method
+        //HACK: assuming it is the result of each method
+        //REVISIT: should return a new copy, must implement cloneable to do so.
+        if (filterType == FilterType.LOGIC_OR) {
+            if( filter instanceof Or ){
+                Or more = (Or) filter;
+                children.addAll( more.getChildren() );
+            }
+            else {
+                children.add(filter);
+            }
+            return this;
+        } else {
+            return super.or(filter);
+        }
+    }
+
+    /**
+     * Implements a logical AND with this filter and returns the merged filter.
+     *
+     * @param filter Parent of the filter: must implement GMLHandlerGeometry.
+     *
+     * @return ANDed filter.
+     *
+     * @task REVISIT: make immutable, should not modify the subfilters of the
+     *       filter being anded.
+     */
+    public Filter and(org.opengis.filter.Filter filter) {
+        // Just makes sure that we are not creating unnecessary new filters
+        //  by popping onto stack if current filter is AND
+        //HACK: not sure what should be returned by this method
+        //HACK: assuming it is the result of each method
+        if (filterType == FilterType.LOGIC_AND) {
+            if( filter instanceof And ){
+                And more = (And) filter;
+                children.addAll( more.getChildren() );
+            }
+            else {
+                children.add(filter);
+            }
+            return this;
+        } else {
+            return super.and(filter);
+        }
+    }
+
+    /**
+     * Implements a logical NOT with this filter and returns the merged filter.
+     *
+     * @return NOTed filter.
+     */
+    public Filter not() {
+        // Just makes sure that we are not creating unnecessary new filters
+        //  by popping off sub filter if current filter is NOT
+        //HACK: not sure what should be returned by this method
+        //HACK: assuming it is the result of each method
+        if (filterType == FilterType.LOGIC_NOT) {
+            return (Filter) children.get(0);
+        } else {
+            return super.not();
+        }
+    }
+
+    /**
+     * package private method to get the internal storage of filters.
+     *
+     * @return the internal sub filter list.
+     * 
+     * @deprecated use {@link #getChildren()}
+     */
+    List getSubFilters() {
+        return children;
+    }
+    
+    /**
+     * Returns a string representation of this filter.
+     *
+     * @return String representation of the logic filter.
+     */
+    public String toString() {
+        String returnString = "[";
+        String operator = "";
+        Iterator iterator = children.iterator();
+
+        if (filterType == LOGIC_OR) {
+            operator = " OR ";
+        } else if (filterType == LOGIC_AND) {
+            operator = " AND ";
+        } else if (filterType == LOGIC_NOT) {
+            return "[ NOT " + iterator.next().toString() + " ]";
+        }
+
+        while (iterator.hasNext()) {
+            returnString = returnString + iterator.next().toString();
+
+            if (iterator.hasNext()) {
+                returnString = returnString + operator;
+            }
+        }
+
+        return returnString + "]";
+    }
+
+    /**
+     * Compares this filter to the specified object.  Returns true  if the
+     * passed in object is the same as this filter.  Checks  to make sure the
+     * filter types are the same, and then checks that the subFilters lists
+     * are the same size and that one list contains the other.  This means
+     * that logic filters with different internal orders of subfilters are
+     * equal.
+     *
+     * @param obj - the object to compare this LogicFilter against.
+     *
+     * @return true if specified object is equal to this filter; false
+     *         otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (obj == this )
+            return true;
+        if ((obj != null) && (obj.getClass() == this.getClass())) {
+            LogicFilterImpl logFilter = (LogicFilterImpl) obj;
+            if( LOGGER.isLoggable(Level.FINEST)) {
+                LOGGER.finest("filter type match:"
+                        + (logFilter.getFilterType() == this.filterType));
+                LOGGER.finest("same size:"
+                        + (logFilter.getSubFilters().size() == this.children.size())
+                        + "; inner size: " + logFilter.getSubFilters().size()
+                        + "; outer size: " + this.children.size());
+                LOGGER.finest("contains:"
+                        + logFilter.getSubFilters().containsAll(this.children));
+            }
+
+            return ((logFilter.getFilterType() == this.filterType)
+            && (logFilter.getSubFilters().size() == this.children.size())
+            && logFilter.getSubFilters().containsAll(this.children));
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Override of hashCode method.
+     *
+     * @return a code to hash this object by.
+     */
+    public int hashCode() {
+        int result = 17;
+        result = (37 * result) + filterType;
+        result = (37 * result) + children.hashCode();
+
+        return result;
+    }
+
+    /**
+     * Used by FilterVisitors to perform some action on this filter instance.
+     * Typicaly used by Filter decoders, but may also be used by any thing
+     * which needs infomration from filter structure. Implementations should
+     * always call: visitor.visit(this); It is importatant that this is not
+     * left to a parent class unless the parents API is identical.
+     *
+     * @param visitor The visitor which requires access to this filter, the
+     *        method must call visitor.visit(this);
+     */
+    public abstract Object accept(FilterVisitor visitor, Object extraData);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/MathExpression.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/MathExpression.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/MathExpression.java	(revision 28000)
@@ -0,0 +1,50 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import org.opengis.filter.expression.BinaryExpression;
+
+
+/**
+ * Holds a mathematical relationship between two expressions. Note that the sub
+ * expressions must be math expressions.  In other words, they must be a math
+ * literal, another math expression, or a feature attribute with a declared
+ * math type.  You may create math expressions of arbitrary complexity by
+ * nesting other math expressions as sub expressions in one or more math
+ * expressions. This filter defines left and right values to clarify the sub
+ * expression precedence for non-associative operations, such as subtraction
+ * and division. For example, the left value is the numerator and the right is
+ * the denominator in an ExpressionMath division operation.
+ *
+ * @author Rob Hranac, Vision for New York
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/MathExpression.java $
+ * @version $Id: MathExpression.java 37280 2011-05-24 07:53:02Z mbedward $
+ *
+ * @deprecated use {@link org.opengis.filter.expression.BinaryExpression}
+ */
+public interface MathExpression extends Expression, BinaryExpression {
+
+    /**
+     * Gets the type of this expression.
+     *
+     * @return Expression type.
+     * @deprecated The expression type system has been replaced by an actual
+     * class type system.
+     */
+    short getType();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/MathExpressionImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/MathExpressionImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/MathExpressionImpl.java	(revision 28000)
@@ -0,0 +1,105 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *        
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+
+
+/**
+ * Holds a mathematical relationship between two expressions. Note that the sub
+ * expressions must be math expressions.  In other words, they must be a math
+ * literal, another math expression, or a feature attribute with a declared
+ * math type.  You may create math expressions of arbitrary complexity by
+ * nesting other math expressions as sub expressions in one or more math
+ * expressions. This filter defines left and right values to clarify the sub
+ * expression precedence for non-associative operations, such as subtraction
+ * and division. For example, the left value is the numerator and the right is
+ * the denominator in an ExpressionMath division operation.
+ *
+ * @author Rob Hranac, Vision for New York
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/MathExpressionImpl.java $
+ * @version $Id: MathExpressionImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public abstract class MathExpressionImpl extends DefaultExpression
+    implements MathExpression {
+	
+    /** Holds the 'left' value of this math expression. */
+    private org.opengis.filter.expression.Expression leftValue = null;
+
+    /** Holds the 'right' value of this math expression. */
+    private org.opengis.filter.expression.Expression rightValue = null;
+
+    
+    /**
+     * No argument constructor.
+     */
+    protected MathExpressionImpl() {
+    	
+    }
+    
+    protected MathExpressionImpl(org.opengis.filter.expression.Expression e1,org.opengis.filter.expression.Expression e2) {
+    	this.leftValue = e1;
+    	this.rightValue = e2;
+    }
+    
+    /**
+     * 
+     * Gets the left or first expression.
+     *
+     * @return the expression on the first side of the comparison.
+     */
+    public org.opengis.filter.expression.Expression getExpression1() {
+	    return leftValue;
+    }
+        
+    /**
+     * Gets the second expression.
+     *
+     * @return the expression on the second side of the comparison.
+     */
+    public org.opengis.filter.expression.Expression getExpression2() {
+	    return rightValue;
+    }
+    
+    /**
+     * Gets the type of this expression.
+     *
+     * @return Expression type.
+     */
+    public short getType() {
+        return expressionType;
+    }
+    
+    /** 
+     * Convenience method which ensures that both expressions have been 
+     * set. If any of operands not set an exception is thrown.
+     */
+    protected void ensureOperandsSet() throws IllegalArgumentException {
+    	  // Checks to make sure both sub expressions exist.
+        if ((leftValue == null) || (rightValue == null)) {
+            throw new IllegalArgumentException(
+                "Attempted read math expression with missing sub expressions.");
+        } 
+    }
+
+   
+    protected Object number( double number ){
+    	//return Filters.puts( number );  // non strongly typed
+    	return new Double( number );      // Getools 2.1 style
+    }
+    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/NotImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/NotImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/NotImpl.java	(revision 28000)
@@ -0,0 +1,51 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *        
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterVisitor;
+import org.opengis.filter.Not;
+/**
+ * @author jdeolive
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/NotImpl.java $
+ */
+public class NotImpl extends LogicFilterImpl implements Not {
+		
+	protected NotImpl(org.opengis.filter.FilterFactory factory, Filter filter) {
+		super(factory);
+		this.children.add(filter);
+		
+		//backwards compatability with old type system
+		filterType = LOGIC_NOT;
+	}
+
+	public Filter getFilter() {
+		return (Filter)children.get(0);
+	}
+	
+	//@Override
+	public boolean evaluate(Object feature) {
+		return !getFilter().evaluate(feature);
+	}
+	
+	public Object accept(FilterVisitor visitor, Object extraData) {
+		return visitor.visit(this,extraData);
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/OrImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/OrImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/OrImpl.java	(revision 28000)
@@ -0,0 +1,55 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *        
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterVisitor;
+import org.opengis.filter.Or;
+/**
+ * @author jdeolive
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/OrImpl.java $
+ */
+public class OrImpl extends LogicFilterImpl implements Or {
+	
+	protected OrImpl(org.opengis.filter.FilterFactory factory, List/*<Filter>*/ children) {
+		super(factory, children );
+		
+		//backwards compatability with old type system
+		filterType = LOGIC_OR;
+	}
+	
+	public boolean evaluate(Object feature) {
+		for (Iterator itr = children.iterator(); itr.hasNext();) {
+			Filter filter = (Filter)itr.next();
+			if( filter.evaluate( feature )) {
+                return true;
+            }
+		}
+		return false;
+	}
+	
+	public Object accept(FilterVisitor visitor, Object extraData) {
+		return visitor.visit(this,extraData);
+	}
+	
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/capability/FunctionNameImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/capability/FunctionNameImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/capability/FunctionNameImpl.java	(revision 28000)
@@ -0,0 +1,65 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.capability;
+
+import java.util.List;
+
+import org.opengis.filter.capability.FunctionName;
+
+/**
+ * Implementation of the FunctionName interface.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/capability/FunctionNameImpl.java $
+ */
+public class FunctionNameImpl extends OperatorImpl implements FunctionName {
+    /** Number of required arguments */
+    int argumentCount;
+    
+    List<String> argumentNames;
+    
+    public FunctionNameImpl( String name, int argumentCount ) {
+        super( name );
+        this.argumentCount = argumentCount;
+        this.argumentNames = null;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + argumentCount;
+        return result;
+    }
+
+    @Override
+    public boolean equals( Object obj ) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final FunctionNameImpl other = (FunctionNameImpl) obj;
+        if (argumentCount != other.argumentCount)
+            return false;
+        return true;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/capability/OperatorImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/capability/OperatorImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/capability/OperatorImpl.java	(revision 28000)
@@ -0,0 +1,68 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.capability;
+
+import org.opengis.filter.capability.Operator;
+
+/**
+ * Implementation of the Operator interface.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/capability/OperatorImpl.java $
+ */
+public class OperatorImpl implements Operator {
+    private String name;
+    
+    public OperatorImpl( String name ) {
+        this.name = name;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        return result;
+    }
+    
+    @Override
+    public boolean equals( Object obj ) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final OperatorImpl other = (OperatorImpl) obj;
+        if (name == null) {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name))
+            return false;
+        return true;
+    }
+    @Override
+    public String toString() {
+        return getName();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/AddImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/AddImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/AddImpl.java	(revision 28000)
@@ -0,0 +1,91 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.expression;
+
+import org.geotools.filter.Filters;
+import org.geotools.filter.MathExpressionImpl;
+import org.geotools.util.Utilities;
+import org.opengis.filter.expression.Add;
+import org.opengis.filter.expression.Expression;
+import org.opengis.filter.expression.ExpressionVisitor;
+
+/**
+ * Implementation of Add expression.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/expression/AddImpl.java $
+ */
+public class AddImpl extends MathExpressionImpl implements Add {
+
+	public AddImpl(Expression expr1, Expression expr2) {
+		super(expr1,expr2);
+		//backwards compatability with old type system
+		expressionType = MATH_ADD;
+	}
+	
+	public Object evaluate(Object feature) throws IllegalArgumentException {
+		ensureOperandsSet();
+		
+		double leftDouble = Filters.number( getExpression1().evaluate(feature) );
+		double rightDouble = Filters.number( getExpression2().evaluate(feature) );
+      
+		return number(leftDouble + rightDouble);
+    }
+	
+	public Object accept(ExpressionVisitor visitor, Object extraData) {
+		return visitor.visit(this,extraData);
+	}
+
+    /**
+     * Compares this expression to the specified object. Returns true if the 
+     *
+     * @param obj - the object to compare this expression against.
+     *
+     * @return true if specified object is equal to this expression; false
+     *         otherwise.
+     */
+    public boolean equals(Object obj) {
+    	if (obj instanceof AddImpl) {
+            AddImpl other = (AddImpl) obj;
+
+            return Utilities.equals(getExpression1(),other.getExpression1())
+            	&& Utilities.equals(getExpression2(),other.getExpression2());
+        } else {
+            return false;
+        }
+    }
+    /**
+     * Override of hashCode method.
+     *
+     * @return a hash code value for this add expression.
+     */
+    public int hashCode() {
+        int result = 23;
+        
+        result = (37 * result) + getExpression1().hashCode();
+        result = (37 * result) + getExpression2().hashCode();
+
+        return result;
+    }
+    
+    public String toString() {
+    	return "(" + getExpression1().toString() + "+" + getExpression2().toString()+ ")";
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/DirectPropertyAccessorFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/DirectPropertyAccessorFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/DirectPropertyAccessorFactory.java	(revision 28000)
@@ -0,0 +1,74 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.expression;
+
+import org.geotools.factory.Hints;
+import org.opengis.feature.Property;
+import org.opengis.feature.type.Name;
+
+/**
+ * This class will *directly* access a Property with the name equal to xpath.
+ * 
+ * @author Jody Garnett
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/expression/DirectPropertyAccessorFactory.java $
+ */
+public class DirectPropertyAccessorFactory implements PropertyAccessorFactory {
+
+    static PropertyAccessor DIRECT = new DirectPropertyAccessor();
+
+    public PropertyAccessor createPropertyAccessor(Class type, String xpath,
+            Class target, Hints hints) {
+            return DIRECT;
+    }
+
+    
+    /**
+     * Grab a value from a Property with matching name.
+     * <p>
+     * This restriction is used by Types.validate to ensure
+     * the provided value is good.
+     * 
+     * @author Jody Garnett (Refractions Research Inc)
+     */
+    static class DirectPropertyAccessor implements PropertyAccessor {
+        
+        /**
+         * We can handle *one* case and one case only 
+         */
+        public boolean canHandle(Object object, String xpath, Class target) {
+            if( object instanceof Property ){
+                Property property = (Property) object;
+                final Name name = property.getName();
+                if( name != null ){
+                    return name.getLocalPart().equals( xpath );
+                } else {
+                    // A property with no name? this is probably a place holder
+                    // or Null Object (such as TransactionStateDiff.NULL).
+                    return false;
+                }
+            }
+            return false;
+        }
+        
+        public Object get(Object object, String xpath, Class target)
+                throws IllegalArgumentException {
+            return ((Property)object).getValue();
+        }
+    }    
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/DivideImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/DivideImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/DivideImpl.java	(revision 28000)
@@ -0,0 +1,94 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.expression;
+
+import org.geotools.filter.Filters;
+import org.geotools.filter.MathExpressionImpl;
+import org.geotools.util.Utilities;
+import org.opengis.filter.expression.Divide;
+import org.opengis.filter.expression.Expression;
+import org.opengis.filter.expression.ExpressionVisitor;
+
+/**
+ * Implementation of divide expression.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/expression/DivideImpl.java $
+ */
+public class DivideImpl extends MathExpressionImpl implements Divide {
+
+	public DivideImpl(Expression expr1, Expression expr2) {
+		super(expr1,expr2);
+		
+		//	backwards compatability with old type system
+		expressionType = MATH_DIVIDE;
+	}
+	
+	public Object evaluate(Object feature) throws IllegalArgumentException {
+		ensureOperandsSet();
+		
+		double leftDouble = Filters.number( getExpression1().evaluate(feature) );
+		double rightDouble = Filters.number( getExpression2().evaluate(feature) );
+      
+		return number(leftDouble / rightDouble);
+	}
+
+	public Object accept(ExpressionVisitor visitor, Object extraData) {
+		return visitor.visit(this,extraData);
+	}
+	
+	/**
+     * Compares this expression to the specified object. Returns true if the 
+     *
+     * @param obj - the object to compare this expression against.
+     *
+     * @return true if specified object is equal to this expression; false
+     *         otherwise.
+     */
+    public boolean equals(Object obj) {
+    	if (obj instanceof DivideImpl) {
+            DivideImpl other = (DivideImpl) obj;
+
+            return Utilities.equals(getExpression1(),other.getExpression1())
+            	&& Utilities.equals(getExpression2(),other.getExpression2());
+        } else {
+            return false;
+        }
+    }
+    
+    /**
+     * Override of hashCode method.
+     *
+     * @return a hash code value for this divide expression.
+     */
+    public int hashCode() {
+        int result = 23;
+        
+        result = (37 * result) + getExpression1().hashCode();
+        result = (37 * result) + getExpression2().hashCode();
+
+        return result;
+    }
+    
+    public String toString() {
+    	return "(" + getExpression1().toString() + "/" + getExpression2().toString()+ ")";
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/ExpressionAbstract.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/ExpressionAbstract.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/ExpressionAbstract.java	(revision 28000)
@@ -0,0 +1,90 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.expression;
+
+import org.geotools.util.Converters;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.filter.expression.Expression;
+//
+/**
+ * Abstract superclass of these Expression implementations.
+ * <p>
+ * Contains additional support for "Expression chaining". This allows
+ * Expressions to be constructed as a chain of Java commands similar to the use
+ * of the java collections api.
+ * </p>
+ * <p>
+ * Note: Expression chaining is a simple developer convience, it has no effect
+ * on the data model exposed by the GeoAPI interfaces.
+ * </p>
+ * <p>
+ * Idea: We may also be able to teach this implementation to make use of
+ * JXPath to extract "attribute values" from Java Beans, DOM, JDOM in addition
+ * to the geotools & geoapi FeatureType models. It is a cunning plan - any
+ * implementation will make use of this abstract base class.
+ * </p>
+ * 
+ * @author Jody Garnett
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/expression/ExpressionAbstract.java $
+ */
+public abstract class ExpressionAbstract implements Expression {
+	
+	/** Subclass should overide, default implementation returns null */
+	public Object evaluate(Object object) {
+		return null;
+	}
+	
+    /**
+     * Default implementation delegates handling of context
+     * conversion to Value utility class.
+     * <p>
+     * Subclasses are expected to make use of the Value utility class
+     * (as the easiest way to provide value morphing in confirmance with
+     *  the Filter specification).
+     */
+	public Object evaluate(Object object, Class context) {
+	    return Converters.convert(evaluate( object ), context);
+	}
+	
+    /**
+     * Helper method for subclasses to reduce null checks
+     * @param expression
+     * @param feature
+     * @return value or null
+     */
+    protected Object eval( Expression expression, SimpleFeature feature ){
+        if( expression == null || feature == null ) return null;
+        return expression.evaluate( feature );
+    }
+
+    /**
+     * Helper method for subclasses to reduce null checks
+     * 
+     * @param expression
+     * @param feature
+     * @return value or null
+     */
+    protected Object eval(org.geotools.filter.Expression expression,
+    		SimpleFeature feature) {
+        if (expression == null || feature == null)
+            return null;
+        return expression.evaluate(feature);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/MultiplyImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/MultiplyImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/MultiplyImpl.java	(revision 28000)
@@ -0,0 +1,93 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.expression;
+
+import org.geotools.filter.Filters;
+import org.geotools.filter.MathExpressionImpl;
+import org.geotools.util.Utilities;
+import org.opengis.filter.expression.Expression;
+import org.opengis.filter.expression.ExpressionVisitor;
+import org.opengis.filter.expression.Multiply;
+
+/**
+ * Implementation of Multiply expression.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/expression/MultiplyImpl.java $
+ */
+public class MultiplyImpl extends MathExpressionImpl implements Multiply {
+
+	
+	public MultiplyImpl(Expression expr1, Expression expr2) {
+		super(expr1,expr2);
+		
+		//backwards compatability with old type system
+		expressionType = MATH_MULTIPLY;
+	}
+	
+	public Object evaluate(Object feature) throws IllegalArgumentException {
+		ensureOperandsSet();
+		
+		double leftDouble = Filters.number( getExpression1().evaluate(feature) );
+		double rightDouble = Filters.number( getExpression2().evaluate(feature) );
+      
+		return number(leftDouble * rightDouble);
+	}
+
+	public Object accept(ExpressionVisitor visitor, Object extraData) {
+		return visitor.visit(this,extraData);
+	}
+	
+	/**
+     * Compares this expression to the specified object. Returns true if the 
+     *
+     * @param obj - the object to compare this expression against.
+     *
+     * @return true if specified object is equal to this expression; false
+     *         otherwise.
+     */
+    public boolean equals(Object obj) {
+    	if (obj instanceof MultiplyImpl) {
+            MultiplyImpl other = (MultiplyImpl) obj;
+
+            return Utilities.equals(getExpression1(),other.getExpression1())
+            	&& Utilities.equals(getExpression2(),other.getExpression2());
+        } else {
+            return false;
+        }
+    }
+    /**
+     * Override of hashCode method.
+     *
+     * @return a hash code value for this multiply expression.
+     */
+    public int hashCode() {
+        int result = 23;
+        
+        result = (37 * result) + getExpression1().hashCode();
+        result = (37 * result) + getExpression2().hashCode();
+
+        return result;
+    }
+    
+    public String toString() {
+    	return "(" + getExpression1().toString() + "*" + getExpression2().toString()+ ")";
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/NullPropertyAccessorFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/NullPropertyAccessorFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/NullPropertyAccessorFactory.java	(revision 28000)
@@ -0,0 +1,62 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+
+package org.geotools.filter.expression;
+
+import org.geotools.factory.Hints;
+
+/**
+ * This class supports the use of Expression/NIL for referring to a 'null' value.
+ * 
+ * @author Niels Charlier, Curtin University Of Technology
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/build/maven/javadoc/../../../modules/library/main/src/main/java/org/geotools/filter/expression/NullPropertyAccessorFactory.java $
+ *         http://svn.osgeo.org/geotools/trunk/modules/library/main/src/main/java/org/geotools/
+ *         filter/expression/NullPropertyAccessorFactory.java $
+ */
+public class NullPropertyAccessorFactory implements PropertyAccessorFactory {
+
+    static private PropertyAccessor NULLPA = new NullPropertyAccessor();
+
+    public PropertyAccessor createPropertyAccessor(Class type, String xpath, Class target,
+            Hints hints) {
+        return NULLPA;
+    }
+
+    /**
+     * Return null for Expression/NIL
+     * 
+     * @author Niels Charlier, CSIRO
+     */
+    static class NullPropertyAccessor implements PropertyAccessor {
+
+        /**
+         * We can handle *one* case and one case only
+         */
+        public boolean canHandle(Object object, String xpath, Class target) {
+            return "Expression/NIL".equals(xpath); // case sensitive
+
+        }
+
+        public Object get(Object object, String xpath, Class target)
+                throws IllegalArgumentException {
+            return null;
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/PropertyAccessor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/PropertyAccessor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/PropertyAccessor.java	(revision 28000)
@@ -0,0 +1,60 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.expression;
+
+
+
+/**
+ * Used to get and set object properties based on an xpath expression.
+ *
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/expression/PropertyAccessor.java $
+ */
+public interface PropertyAccessor {
+    /**
+     * Determines if the property accessor can handle the property denoted by <param>xpath</param>.
+     * <p>
+     * Can be used to perform checks against schema to ensure that the propery accessor
+     * will actually work with the provided instance.
+     * </p>
+     *
+     * @param object The target object.
+     * @param xpath An xpath expression denoting a property of the target object.
+     *
+     * @return <code>true</code> if the property can be accessed, otherwise <code>false</code>
+     */
+    boolean canHandle(Object object, String xpath, Class target);
+
+    /**
+     * Accesses a property of <param>object</param> via xpath expression.
+     * <p>
+     * {@link #canHandle(Object, String)} should be called before calling this method to ensure
+     * that the property can be safely accessed.
+     * </p>
+     * @param object The target object.
+     * @param xpath An xpath expression denoting a property of the target object.
+     * @param target Target context we intend to access (often null or Geometry.class)
+     * @return The property, which might be <code>null</code>
+     *
+     * @throws IllegalArgumentException In the even that xpath is not supported.
+     */
+    Object get(Object object, String xpath, Class target)
+        throws IllegalArgumentException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/PropertyAccessorFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/PropertyAccessorFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/PropertyAccessorFactory.java	(revision 28000)
@@ -0,0 +1,53 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.expression;
+
+import org.geotools.factory.Hints;
+import org.geotools.factory.Hints.Key;
+
+/**
+ * Factory used to create instances of {@link PropertyAccessor}
+ *
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/filter/expression/PropertyAccessorFactory.java $
+ */
+public interface PropertyAccessorFactory {
+		    
+	/**
+	 * {@link Hints} key used to pass namespace context to
+	 * {@link #createPropertyAccessor(Class, String, Class, Hints)} in the form of a
+	 * {@link NamespaceSupport} instance with the prefix/namespaceURI mappings
+	 */
+	public static final Key NAMESPACE_CONTEXT = new Hints.Key(org.xml.sax.helpers.NamespaceSupport.class);
+	
+	
+    /**
+     * Creates a property accessor for a particular class.
+     *
+     * @param type The type of object to be accessed.
+     * @param xpath The xpath expression to evaluate.
+     * @param target The kind of result we are expecting (ie Geometry)
+     * @param hints Hints to be used when creatign the accessor.
+     *
+     * @return The property accessor, or <code>null</code> if this factory cannot create
+     * an accessor for the specified type.
+     */
+    PropertyAccessor createPropertyAccessor(Class type, String xpath, Class target, Hints hints);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/PropertyAccessors.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/PropertyAccessors.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/PropertyAccessors.java	(revision 28000)
@@ -0,0 +1,98 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.expression;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.geotools.factory.FactoryRegistry;
+import org.geotools.factory.Hints;
+
+/**
+ * Convenience class for looking up a property accessor for a particular object type.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project
+ * 
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/expression/PropertyAccessors.java $
+ */
+public class PropertyAccessors {
+    static final PropertyAccessorFactory[] FACTORY_CACHE;
+    
+    static {
+        List<PropertyAccessorFactory> cache = new ArrayList<PropertyAccessorFactory>();
+
+        // add the simple feature property accessor factory first for performance
+        // reasons         
+        cache.add( new NullPropertyAccessorFactory()); //NC - added       
+        cache.add( new SimpleFeaturePropertyAccessorFactory());
+        cache.add( new DirectPropertyAccessorFactory());       
+        Iterator factories = FactoryRegistry
+                 .lookupProviders(PropertyAccessorFactory.class);
+         while (factories.hasNext()) {
+            Object factory = factories.next();
+            if ( factory instanceof SimpleFeaturePropertyAccessorFactory || factory instanceof DirectPropertyAccessorFactory
+                 || factory instanceof NullPropertyAccessorFactory )
+                continue;
+            
+            cache.add((PropertyAccessorFactory) factory);
+         }
+         FACTORY_CACHE = cache.toArray(new PropertyAccessorFactory[cache.size()]);
+    }
+    
+    /**
+     * Make sure this class won't be instantianted
+     */
+    private PropertyAccessors() {}
+    
+    /**
+     * Looks up a list of {@link PropertyAccessor} for a particular object.
+     * <p>
+     * This method will return all accessors that is capable of handling the object and xpath
+     * expression provided, no order is guaranteed.
+     * </p>
+     * 
+     * @param object
+     *            The target object.
+     * @param xpath
+     *            An xpath expression denoting a property of the target object.
+     * @param hints
+     *            Hints to pass on to factories.
+     * 
+     * @return List of Property accessors, or <code>null</code> if object is null
+     */
+    public static List<PropertyAccessor> findPropertyAccessors(Object object, String xpath,
+            Class target, Hints hints) {
+        if (object == null)
+            return null;
+
+        List<PropertyAccessor> list = new ArrayList<PropertyAccessor>();
+
+        for (PropertyAccessorFactory factory : FACTORY_CACHE) {
+            PropertyAccessor accessor = factory.createPropertyAccessor(object.getClass(), xpath,
+                    target, hints);
+            if (accessor != null && accessor.canHandle(object, xpath, target)) {
+                list.add(accessor);
+            }
+        }
+        return list;
+    }
+    
+    
+ }
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/SimpleFeaturePropertyAccessorFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/SimpleFeaturePropertyAccessorFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/SimpleFeaturePropertyAccessorFactory.java	(revision 28000)
@@ -0,0 +1,201 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.expression;
+
+import java.util.regex.Pattern;
+
+import org.geotools.factory.Hints;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.GeometryDescriptor;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * Creates a property accessor for simple features.
+ * <p>
+ * The created accessor handles a small subset of xpath expressions, a
+ * non-nested "name" which corresponds to a feature attribute, and "@id",
+ * corresponding to the feature id.
+ * </p>
+ * <p>
+ * THe property accessor may be run against {@link SimpleFeature}, or 
+ * against {@link SimpleFeature}. In the former case the feature property 
+ * value is returned, in the latter the feature property type is returned. 
+ * </p>
+ * 
+ * @author Justin Deoliveira, The Open Planning Project
+ * 
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/expression/SimpleFeaturePropertyAccessorFactory.java $
+ */
+public class SimpleFeaturePropertyAccessorFactory implements
+        PropertyAccessorFactory {
+
+    /** Single instnace is fine - we are not stateful */
+    static PropertyAccessor ATTRIBUTE_ACCESS = new SimpleFeaturePropertyAccessor();
+    static PropertyAccessor DEFAULT_GEOMETRY_ACCESS = new DefaultGeometrySimpleFeaturePropertyAccessor();
+    static PropertyAccessor FID_ACCESS = new FidSimpleFeaturePropertyAccessor();
+    static Pattern idPattern = Pattern.compile("@(\\w+:)?id");
+    static Pattern propertyPattern = Pattern.compile("(\\w+:)?(\\w+)");
+
+    public PropertyAccessor createPropertyAccessor(Class type, String xpath,
+            Class target, Hints hints) {
+
+    	if ( xpath == null ) 
+    		return null;
+    	
+        if (!SimpleFeature.class.isAssignableFrom(type) && !SimpleFeatureType.class.isAssignableFrom(type))
+            return null; // we only work with simple feature
+
+        //if ("".equals(xpath) && target == Geometry.class)
+        if ("".equals(xpath))
+            return DEFAULT_GEOMETRY_ACCESS;
+
+        //check for fid access
+        if (idPattern.matcher(xpath).matches())
+            return FID_ACCESS;
+
+        //check for simple property acess
+        if (propertyPattern.matcher(xpath).matches()) {
+        	return ATTRIBUTE_ACCESS;	
+        }
+        
+        return null;
+    }
+
+    /**
+     * We strip off namespace prefix, we need new feature model to do this
+     * property
+     * <ul>
+     * <li>BEFORE: foo:bar
+     * <li>AFTER: bar
+     * </ul>
+     * 
+     * @param xpath
+     * @return xpath with any XML prefixes removed
+     */
+    static String stripPrefix(String xpath) {
+        int split = xpath.indexOf(":");
+        if (split != -1) {
+            return xpath.substring(split + 1);
+        }
+        return xpath;
+    }
+
+    /**
+     * Access to SimpleFeature Identifier.
+     * 
+     * @author Jody Garnett, Refractions Research Inc.
+     */
+    static class FidSimpleFeaturePropertyAccessor implements PropertyAccessor {        
+        public boolean canHandle(Object object, String xpath, Class target) {
+        	//we only work against feature, not feature type
+            return object instanceof SimpleFeature && xpath.matches("@(\\w+:)?id");
+        }
+        public Object get(Object object, String xpath, Class target) {
+            SimpleFeature feature = (SimpleFeature) object;
+            return feature.getID();
+        }
+    }
+    static class DefaultGeometrySimpleFeaturePropertyAccessor implements PropertyAccessor {
+        
+        public boolean canHandle(Object object, String xpath, Class target) {
+        	if ( !"".equals( xpath ) )
+        		return false;
+        	
+//        	if ( target != Geometry.class ) 
+//        		return false;
+        	
+        	if ( !( object instanceof SimpleFeature || object instanceof SimpleFeatureType ) ) {
+        		return false;
+        	}
+        	
+        	return true;
+            
+        }
+        public Object get(Object object, String xpath, Class target) {
+        	if ( object instanceof SimpleFeature ) {
+        	    SimpleFeature f = (SimpleFeature) object;
+        	    Object defaultGeometry = f.getDefaultGeometry();
+
+                    // not found? Ok, let's do a lookup then...
+                    if ( defaultGeometry == null ) {
+                        for ( Object o : f.getAttributes() ) {
+                            if ( o instanceof Geometry ) {
+                                defaultGeometry = o;
+                                break;
+                            }
+                        }
+                    }
+                    
+                    return defaultGeometry;
+        	}
+        	
+                if ( object instanceof SimpleFeatureType ) {
+                    SimpleFeatureType ft = (SimpleFeatureType) object;
+                    GeometryDescriptor gd = ft.getGeometryDescriptor();
+                
+                    if ( gd == null ) {
+                        //look for any geometry descriptor
+                        for ( AttributeDescriptor ad : ft.getAttributeDescriptors() ) {
+                            if ( Geometry.class.isAssignableFrom( ad.getType().getBinding() ) ) {
+                                return ad;
+                            }
+                        }
+                    }
+                    
+                    return gd;
+                }
+            
+        	return null;
+        }
+    }
+
+    static class SimpleFeaturePropertyAccessor implements PropertyAccessor {
+        public boolean canHandle(Object object, String xpath, Class target) {
+        	xpath = stripPrefix(xpath);
+        	
+        	if ( object instanceof SimpleFeature ) {
+        		return ((SimpleFeature) object).getType().getDescriptor(xpath) != null;
+        	}
+        	
+        	if ( object instanceof SimpleFeatureType ) {
+        		return ((SimpleFeatureType) object).getDescriptor( xpath ) != null;
+        	}
+        	
+        	return false;
+        }
+        
+        public Object get(Object object, String xpath, Class target) {
+        	xpath = stripPrefix(xpath);
+        	
+        	if ( object instanceof SimpleFeature ) {
+        		return ((SimpleFeature) object).getAttribute( xpath );
+        	}
+        	
+        	if ( object instanceof SimpleFeatureType ) {
+        		return ((SimpleFeatureType) object).getDescriptor( xpath );
+        	}
+        	
+        	return null;
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/SubtractImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/SubtractImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/expression/SubtractImpl.java	(revision 28000)
@@ -0,0 +1,93 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.expression;
+
+import org.geotools.filter.Filters;
+import org.geotools.filter.MathExpressionImpl;
+import org.geotools.util.Utilities;
+import org.opengis.filter.expression.Expression;
+import org.opengis.filter.expression.ExpressionVisitor;
+import org.opengis.filter.expression.Subtract;
+
+/**
+ * Implementation of Subtract expression.
+ * 
+ * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/expression/SubtractImpl.java $
+ */
+public class SubtractImpl extends MathExpressionImpl implements Subtract {
+
+	public SubtractImpl(Expression expr1, Expression expr2) {
+		super(expr1,expr2);
+		
+		//backwards compatability with old type system
+		expressionType = MATH_SUBTRACT;
+	}
+	
+	public Object evaluate(Object feature) throws IllegalArgumentException {
+		ensureOperandsSet();
+		
+		double leftDouble = Filters.number( getExpression1().evaluate(feature) );
+		double rightDouble = Filters.number( getExpression2().evaluate(feature) );
+      
+		return number(leftDouble - rightDouble);
+    }
+	
+	public Object accept(ExpressionVisitor visitor, Object extraData) {
+		return visitor.visit(this,extraData);
+	}
+	
+	/**
+     * Compares this expression to the specified object. Returns true if the 
+     *
+     * @param obj - the object to compare this expression against.
+     *
+     * @return true if specified object is equal to this expression; false
+     *         otherwise.
+     */
+    public boolean equals(Object obj) {
+    	if (obj instanceof SubtractImpl) {
+            SubtractImpl other = (SubtractImpl) obj;
+
+            return Utilities.equals(getExpression1(),other.getExpression1())
+            	&& Utilities.equals(getExpression2(),other.getExpression2());
+        } else {
+            return false;
+        }
+    }
+    /**
+     * Override of hashCode method.
+     *
+     * @return a hash code value for this subtract expression.
+     */
+    public int hashCode() {
+        int result = 23;
+        
+        result = (37 * result) + getExpression1().hashCode();
+        result = (37 * result) + getExpression2().hashCode();
+
+        return result;
+    }
+    
+    public String toString() {
+    	return "(" + getExpression1().toString() + "-" + getExpression2().toString()+ ")";
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/function/DefaultFunctionFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/function/DefaultFunctionFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/function/DefaultFunctionFactory.java	(revision 28000)
@@ -0,0 +1,182 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2010, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    reated on October 27, 2004, 11:27 AM
+ */
+package org.geotools.filter.function;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.filter.FunctionExpression;
+import org.geotools.filter.FunctionFactory;
+import org.geotools.filter.FunctionImpl;
+import org.geotools.util.logging.Logging;
+import org.opengis.filter.FilterFactory;
+import org.opengis.filter.capability.FunctionName;
+import org.opengis.filter.expression.Expression;
+import org.opengis.filter.expression.Function;
+import org.opengis.filter.expression.Literal;
+
+/**
+ * Filter function facotry that uses the spi lookup mechanism to create functions.
+ * 
+ * @author Justin Deoliveira, OpenGeo
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/build/maven/javadoc/../../../modules/library/main/src/main/java/org/geotools/filter/function/DefaultFunctionFactory.java $
+ */
+public class DefaultFunctionFactory implements FunctionFactory {
+    private static final Logger LOGGER = Logging.getLogger("org.geotools.filter");
+    private FilterFactory filterFactory = CommonFactoryFinder.getFilterFactory(null);
+    
+    private Map<String,FunctionDescriptor> functionCache;
+
+    public List<FunctionName> getFunctionNames() {
+        ArrayList list = new ArrayList(functionCache().size());
+        for (FunctionDescriptor fd : functionCache().values()) {
+            list.add(fd.name);
+        }
+        return list;
+    }
+    
+    public Function function(String name, List<Expression> parameters, Literal fallback) {
+        
+        // cache lookup
+        FunctionDescriptor fd = functionCache().get(functionName(name));
+        if (fd == null) {
+            //no such function
+            return null;
+        }
+        
+        try {
+            return fd.newFunction(parameters, fallback);
+        }
+        catch(Exception e){
+            LOGGER.log( Level.FINER, "Unable to create function " + name + "Function", e);
+            //just continue on to return null
+        }
+        
+        return null;
+    }
+    
+    private Map<String,FunctionDescriptor> functionCache() {
+        if (functionCache == null) {
+            synchronized(this) {
+                if (functionCache == null) {
+                    loadFunctions();
+                }
+            }
+        }
+        
+        return functionCache;
+    }
+    
+    private void loadFunctions() {
+        functionCache = new HashMap();
+        
+        // Get all the GeoTools FunctionExpression implementations
+        // and store in functionExpressionCache
+        // (these are implementations of the legacy GeoTools FunctionExpression
+        // interface)
+        Set functions = CommonFactoryFinder.getFunctionExpressions(null);
+        for (Iterator it = functions.iterator(); it.hasNext();) {
+            FunctionExpression function = (FunctionExpression) it.next();
+            FunctionDescriptor fd = new FunctionDescriptor(
+                filterFactory.functionName(function.getName(), function.getArgCount()), 
+                function.getClass()); 
+            
+            functionCache.put(functionName(function.getName()), fd);
+        }
+        
+        // Get all the GeoAPI Function implementations
+        functions = CommonFactoryFinder.getFunctions(null);
+        for (Iterator i = functions.iterator(); i.hasNext();) {
+            Function function = (Function) i.next();
+            int argc = function instanceof FunctionExpression ? 
+                ((FunctionExpression)function).getArgCount() : function.getParameters().size();
+            
+            FunctionDescriptor fd = new FunctionDescriptor(
+                filterFactory.functionName(function.getName(), argc), function.getClass());
+            functionCache.put(functionName(function.getName()), fd);
+        }
+    }
+    
+    private String functionName(String name) {
+        
+        //strip off "Function" prefix
+        int index = -1;
+
+        if ((index = name.indexOf("Function")) != -1) {
+            name = name.substring(0, index);
+        }
+
+        //convert to lower case
+        name = name.toLowerCase().trim();
+        
+        //JD: not sure why the first character is converted back to upper case, disabling this and
+        // just keeping everything lower case, as this is only used internally to store functions
+        // it should affect any existing clients
+        //char c = name.charAt(0);
+        //name = name.replaceFirst("" + c, "" + Character.toUpperCase(c));
+
+        return name;
+    }
+
+    static class FunctionDescriptor {
+        FunctionName name;
+        Class clazz;
+        
+        FunctionDescriptor(FunctionName name, Class clazz) {
+            this.name = name;
+            this.clazz = clazz;
+        }
+        
+        Function newFunction(List<Expression> parameters, Literal fallback) throws Exception {
+            // cache lookup
+            if (FunctionExpression.class.isAssignableFrom(clazz)) {
+                FunctionExpression function = (FunctionExpression) clazz.newInstance();
+                if(parameters != null) {
+                    function.setParameters(parameters);
+                }
+                
+                return function;
+            }
+
+            if(FunctionImpl.class.isAssignableFrom(clazz)) {
+                FunctionImpl function = (FunctionImpl) clazz.newInstance();
+                if(parameters != null){
+                    function.setParameters( parameters );
+                }
+                if(fallback != null)
+                        function.setFallbackValue( fallback );
+                return function;
+            }
+            
+            //Function function = (Function) functionClass.newInstance();
+            Constructor<Function> constructor = clazz.getConstructor( new Class[]{ List.class, Literal.class} );
+            return constructor.newInstance( parameters, fallback );
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/identity/FeatureIdImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/identity/FeatureIdImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/identity/FeatureIdImpl.java	(revision 28000)
@@ -0,0 +1,76 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.identity;
+
+import org.opengis.filter.identity.FeatureId;
+
+/**
+ * Implementation of {@link org.opengis.filter.identity.FeatureId}
+ * <p>
+ * This class is mutable under one condition only; during a commit
+ * a datastore can update the internal fid to reflect the real identify
+ * assigned by the database or wfs.
+ * <p>
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/identity/FeatureIdImpl.java $
+ */
+public class FeatureIdImpl implements FeatureId {
+
+	/** underlying fid */
+	protected String fid;
+	protected String origionalFid;
+	public FeatureIdImpl( String fid ) {
+		this.fid = fid;
+		if ( fid == null ) {
+			throw new NullPointerException( "fid must not be null" );
+		}
+	}
+	
+	public String getID() {
+		return fid;
+	}
+
+	public void setID( String id ){
+		if ( id == null ) {
+			throw new NullPointerException( "fid must not be null" );
+		}	
+		if( origionalFid == null ){
+                    origionalFid = fid;
+                }
+		fid = id;			
+	}
+	
+	public String toString() {
+		return fid;
+	}
+	
+	public boolean equals(Object obj) {
+		if ( obj instanceof FeatureId) {
+			return fid.equals( ((FeatureId)obj).getID() );
+		}
+		
+		return false;
+	}
+	
+	public int hashCode() {
+		return fid.hashCode();
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/DefaultFilterVisitor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/DefaultFilterVisitor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/DefaultFilterVisitor.java	(revision 28000)
@@ -0,0 +1,150 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.visitor;
+
+import org.opengis.filter.And;
+import org.opengis.filter.ExcludeFilter;
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterVisitor;
+import org.opengis.filter.Id;
+import org.opengis.filter.IncludeFilter;
+import org.opengis.filter.Not;
+import org.opengis.filter.Or;
+import org.opengis.filter.expression.Add;
+import org.opengis.filter.expression.Divide;
+import org.opengis.filter.expression.Expression;
+import org.opengis.filter.expression.ExpressionVisitor;
+import org.opengis.filter.expression.Function;
+import org.opengis.filter.expression.Literal;
+import org.opengis.filter.expression.Multiply;
+import org.opengis.filter.expression.NilExpression;
+import org.opengis.filter.expression.PropertyName;
+import org.opengis.filter.expression.Subtract;
+
+/**
+ * Abstract implementation of FilterVisitor that simply walks the data structure.
+ * <p>
+ * This class implements the full FilterVisitor interface and will visit every Filter member of a
+ * Filter object. This class performs no actions and is not intended to be used directly, instead
+ * extend it and overide the methods for the Filter type you are interested in. Remember to call the
+ * super method if you want to ensure that the entire filter tree is still visited.
+ * 
+ * <pre><code>
+ * FilterVisitor allFids = new DefaultFilterVisitor(){
+ *     public Object visit( Id filter, Object data ) {
+ *         Set set = (Set) data;
+ *         set.addAll(filter.getIDs());
+ *         return set;
+ *     }
+ * };
+ * Set set = (Set) myFilter.accept(allFids, new HashSet());
+ * </code></pre>
+ * 
+ * @author Jody
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/visitor/DefaultFilterVisitor.java $
+ */
+public abstract class DefaultFilterVisitor implements FilterVisitor, ExpressionVisitor {
+
+    public DefaultFilterVisitor() {
+    }
+
+    public Object visit( ExcludeFilter filter, Object data ) {
+        return data;
+    }
+
+    public Object visit( IncludeFilter filter, Object data ) {
+        return data;
+    }
+
+    public Object visit( And filter, Object data ) {
+        if (filter.getChildren() != null) {
+            for( Filter child : filter.getChildren()) {
+                data = child.accept(this, data);
+            }
+        }
+        return data;
+    }
+
+    public Object visit( Id filter, Object data ) {
+        return data;
+    }
+
+    public Object visit( Not filter, Object data ) {
+        Filter child = filter.getFilter();
+        if (child != null) {
+            data = child.accept(this, data);
+        }
+        return data;
+    }
+
+    public Object visit( Or filter, Object data ) {
+        if (filter.getChildren() != null) {
+            for( Filter child : filter.getChildren()) {
+                data = child.accept(this, data);
+            }
+        }
+        return data;
+    }
+
+    public Object visit( NilExpression expression, Object data ) {        
+        return data;
+    }
+
+    public Object visit( Add expression, Object data ) {
+        data = expression.getExpression1().accept( this, data);
+        data = expression.getExpression2().accept( this, data);
+        return data;
+    }
+
+    public Object visit( Divide expression, Object data ) {
+        data = expression.getExpression1().accept( this, data);
+        data = expression.getExpression2().accept( this, data);        
+        return data;
+    }
+
+    public Object visit( Function expression, Object data ) {
+        if( expression.getParameters() != null ){
+            for( Expression parameter : expression.getParameters() ){
+                data =  parameter.accept( this, data);
+            }
+        }
+        return data;
+    }
+
+    public Object visit( Literal expression, Object data ) {        
+        return data;
+    }
+
+    public Object visit( Multiply expression, Object data ) {
+        data = expression.getExpression1().accept( this, data);
+        data = expression.getExpression2().accept( this, data);                
+        return data;
+    }
+
+    public Object visit( PropertyName expression, Object data ) {
+        return data;
+    }
+
+    public Object visit( Subtract expression, Object data ) {
+        data = expression.getExpression1().accept( this, data);
+        data = expression.getExpression2().accept( this, data);                
+        return data;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/DuplicatingFilterVisitor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/DuplicatingFilterVisitor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/DuplicatingFilterVisitor.java	(revision 28000)
@@ -0,0 +1,174 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.visitor;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.factory.GeoTools;
+import org.opengis.filter.And;
+import org.opengis.filter.ExcludeFilter;
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory2;
+import org.opengis.filter.FilterVisitor;
+import org.opengis.filter.Id;
+import org.opengis.filter.IncludeFilter;
+import org.opengis.filter.Not;
+import org.opengis.filter.Or;
+import org.opengis.filter.expression.Add;
+import org.opengis.filter.expression.Divide;
+import org.opengis.filter.expression.Expression;
+import org.opengis.filter.expression.ExpressionVisitor;
+import org.opengis.filter.expression.Function;
+import org.opengis.filter.expression.Literal;
+import org.opengis.filter.expression.Multiply;
+import org.opengis.filter.expression.NilExpression;
+import org.opengis.filter.expression.PropertyName;
+import org.opengis.filter.expression.Subtract;
+
+/**
+ * Used to duplication Filters and/or Expressions - returned object is a copy.
+ * <p>
+ * Extra data can be used to provide a {@link FilterFactory2} but this is NOT required.
+ * This class is thread safe.
+ * </ul>
+ * @author Jesse
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/visitor/DuplicatingFilterVisitor.java $
+ */
+public class DuplicatingFilterVisitor implements FilterVisitor, ExpressionVisitor {
+
+	protected final FilterFactory2 ff;
+
+	public DuplicatingFilterVisitor() {
+		this(CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints()));
+		
+	}
+	
+	public DuplicatingFilterVisitor(FilterFactory2 factory) {
+		this.ff = factory;
+	}
+	
+	protected FilterFactory2 getFactory(Object extraData) {
+		if( extraData instanceof FilterFactory2)
+			return (FilterFactory2) extraData;
+		return ff;
+	}
+
+	public Object visit(ExcludeFilter filter, Object extraData) {
+		return filter;
+	}
+
+
+	public Object visit(IncludeFilter filter, Object extraData) {
+		return filter;
+	}
+	
+	/**
+	 * Null safe expression cloning
+	 * @param expression
+	 * @param extraData
+	 * @return
+	 */
+	Expression visit(Expression expression, Object extraData) {
+	    if(expression == null)
+	        return null;
+	    return (Expression) expression.accept(this, extraData);
+	}
+
+	public Object visit(And filter, Object extraData) {
+		List children = filter.getChildren();
+		List newChildren = new ArrayList();
+		for (Iterator iter = children.iterator(); iter.hasNext();) {
+			Filter child = (Filter) iter.next();
+			if( child!=null )
+				newChildren.add(child.accept(this, extraData));
+		}
+		return getFactory(extraData).and(newChildren);
+	}
+
+	public Object visit(Id filter, Object extraData) {
+		return getFactory(extraData).id(filter.getIdentifiers());
+	}
+
+	public Object visit(Not filter, Object extraData) {
+		return getFactory(extraData).not((Filter) filter.getFilter().accept(this, extraData));
+	}
+
+	public Object visit(Or filter, Object extraData) {
+		List children = filter.getChildren();
+		List newChildren = new ArrayList();
+		for (Iterator iter = children.iterator(); iter.hasNext();) {
+			Filter child = (Filter) iter.next();
+			if( child!=null )
+				newChildren.add(child.accept(this, extraData));
+		}
+		return getFactory(extraData).or(newChildren);
+	}
+
+	public Object visit(NilExpression expression, Object extraData) {
+		return expression;
+	}
+
+	public Object visit(Add expression, Object extraData) {
+	    Expression expr1= visit(expression.getExpression1(), extraData);
+	    Expression expr2= visit(expression.getExpression2(), extraData);
+		return getFactory(extraData).add(expr1, expr2);
+	}
+
+	public Object visit(Divide expression, Object extraData) {
+	    Expression expr1= visit(expression.getExpression1(), extraData);
+        Expression expr2= visit(expression.getExpression2(), extraData);
+		return getFactory(extraData).divide(expr1, expr2);
+	}
+
+	public Object visit(Function expression, Object extraData) {
+		List old = expression.getParameters();
+		Expression[] args = new Expression[old.size()];
+		int i = 0;
+		for (Iterator iter = old.iterator(); iter.hasNext(); i++) {
+			Expression exp = (Expression) iter.next();
+			args[i]= visit(exp, extraData);
+		}
+		return getFactory(extraData).function(expression.getName(), args);
+	}
+
+	public Object visit(Literal expression, Object extraData) {
+		return getFactory(extraData).literal(expression.getValue());
+	}
+
+	public Object visit(Multiply expression, Object extraData) {
+	    Expression expr1= visit(expression.getExpression1(), extraData);
+        Expression expr2= visit(expression.getExpression2(), extraData);
+		return getFactory(extraData).multiply(expr1, expr2);
+	}
+
+	public Object visit(PropertyName expression, Object extraData) {
+		return getFactory(extraData).property(expression.getPropertyName(), expression.getNamespaceContext());
+	}
+
+	public Object visit(Subtract expression, Object extraData) {
+	    Expression expr1= visit(expression.getExpression1(), extraData);
+        Expression expr2= visit(expression.getExpression2(), extraData);
+		return getFactory(extraData).subtract(expr1, expr2);
+	}
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/ExtractBoundsFilterVisitor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/ExtractBoundsFilterVisitor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/ExtractBoundsFilterVisitor.java	(revision 28000)
@@ -0,0 +1,227 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.visitor;
+
+import java.util.logging.Logger;
+
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.filter.And;
+import org.opengis.filter.ExcludeFilter;
+import org.opengis.filter.Filter;
+import org.opengis.filter.Id;
+import org.opengis.filter.IncludeFilter;
+import org.opengis.filter.Not;
+import org.opengis.filter.Or;
+import org.opengis.filter.expression.Add;
+import org.opengis.filter.expression.Divide;
+import org.opengis.filter.expression.Function;
+import org.opengis.filter.expression.Literal;
+import org.opengis.filter.expression.Multiply;
+import org.opengis.filter.expression.NilExpression;
+import org.opengis.filter.expression.PropertyName;
+import org.opengis.filter.expression.Subtract;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * Extract a maximal envelope from the provided Filter.
+ * <p>
+ * The maximal envelope is generated from:
+ * <ul>
+ * <li>all the literal geometry instances involved if spatial operations - using
+ * geom.getEnvelopeInternal().
+ * <li>Filter.EXCLUDES will result in an empty envelope
+ * <li>Filter.INCLUDES will result in a "world" envelope with range Double.NEGATIVE_INFINITY to
+ * Double.POSITIVE_INFINITY for each axis.
+ * <li>all other non spatial filters will result in a world envelope
+ * <li>combinations in and will return the intersection of the envelopes, or an empty envelope
+ *     if an exclude is in the mix, or null if the and is mixing non spatial filters</li>
+ * <li>combinations in or will return the intersection of 
+ * </ul>
+ * Since geometry literals do not contains CRS information we can only produce a ReferencedEnvelope
+ * without CRS information. You can call this function with an existing ReferencedEnvelope 
+ * or with your data CRS to correct for this limitation.
+ * ReferencedEnvelope example:<pre><code>
+ * ReferencedEnvelope bbox = (ReferencedEnvelope)
+ *     filter.accepts(new ExtractBoundsFilterVisitor(), dataCRS );
+ * </code></pre>
+ * You can also call this function with an existing Envelope; if you are building up bounds based on
+ * several filters.
+ * <p>
+ * This is a replacement for FilterConsumer.
+ * 
+ * @author Jody Garnett
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/visitor/ExtractBoundsFilterVisitor.java $
+ */
+public class ExtractBoundsFilterVisitor extends NullFilterVisitor {
+    static public NullFilterVisitor BOUNDS_VISITOR = new ExtractBoundsFilterVisitor();
+    
+    private static Logger LOGGER = org.geotools.util.logging.Logging
+            .getLogger("org.geotools.index.rtree");
+
+    /**
+     * This FilterVisitor is stateless - use ExtractBoundsFilterVisitor.BOUNDS_VISITOR.
+     * <p>
+     * You may also subclass in order to reuse this functionality in your own
+     * FilterVisitor implementation.
+     */
+    protected ExtractBoundsFilterVisitor(){        
+    }
+    
+    /**
+     * Produce an ReferencedEnvelope from the provided data parameter.
+     * 
+     * @param data
+     * @return ReferencedEnvelope
+     */
+    private ReferencedEnvelope bbox( Object data ) {
+        if( data == null ){
+            return null;
+        }
+        else if (data instanceof ReferencedEnvelope) {
+            return (ReferencedEnvelope) data;
+        }
+        else if (data instanceof Envelope){
+            return new ReferencedEnvelope( (Envelope) data, null );
+        }
+        else if (data instanceof CoordinateReferenceSystem){
+            return new ReferencedEnvelope( (CoordinateReferenceSystem) data );
+        }
+        throw new ClassCastException("Could not cast data to ReferencedEnvelope");        
+    }
+
+    public Object visit( ExcludeFilter filter, Object data ) {
+        return new Envelope();
+    }
+
+    public Object visit( IncludeFilter filter, Object data ) {
+        return infinity();
+    }
+
+	Envelope infinity() {
+		return new Envelope(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
+                Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
+	}
+
+    /**
+     * Please note we are only visiting literals involved in spatial operations.
+     * @param literal, hopefully a Geometry or Envelope
+     * @param data Incoming BoundingBox (or Envelope or CRS)
+     * 
+     * @return ReferencedEnvelope updated to reflect literal
+     */
+    public Object visit( Literal expression, Object data ) {        
+        ReferencedEnvelope bbox = bbox( data );
+
+        Object value = expression.getValue();
+        if (value instanceof Geometry) {
+                        
+            Geometry geometry = (Geometry) value;
+            Envelope bounds = geometry.getEnvelopeInternal();
+            
+            if(bbox != null) {
+            	bbox.expandToInclude(bounds);
+            	return bbox;
+            } else {
+            	return bbox(bounds);
+            }
+        } else {
+            LOGGER.finer("LiteralExpression ignored!");
+        }
+        return bbox;
+    }
+    
+	@Override
+	public Object visit(And filter, Object data) {
+		Envelope mixed = infinity();
+		for (Filter f : filter.getChildren()) {
+			Envelope env = (Envelope) f.accept(this, data);
+    		mixed = mixed.intersection(env);
+		}
+		return mixed;
+	}
+	
+	public Object visit(Not filter, Object data) {
+		// no matter what we have to return an infinite envelope
+		// rationale
+		// !(finite envelope) -> an unbounded area -> infinite
+		// !(non spatial filter) -> infinite (no spatial concern)
+		// !(infinite) -> ... infinite, as the first infinite could be the result 
+		// of !(finite envelope) 
+		
+		return infinity();
+	}
+	
+	@Override
+	public Object visit(Or filter, Object data) {
+		Envelope mixed = new Envelope();
+		for (Filter f : filter.getChildren()) {
+			Envelope env = (Envelope) f.accept(this, data);
+		    mixed.expandToInclude(env);
+		}
+		return mixed;
+	}
+
+	@Override
+	public Object visit(Add expression, Object data) {
+		return infinity();
+	}
+
+	@Override
+	public Object visit(Divide expression, Object data) {
+		return infinity();
+	}
+
+	@Override
+	public Object visit(Function expression, Object data) {
+		return infinity();
+	}
+
+	@Override
+	public Object visit(Id filter, Object data) {
+		return infinity();
+	}
+
+	@Override
+	public Object visit(Multiply expression, Object data) {
+		return infinity();
+	}
+
+	@Override
+	public Object visit(NilExpression expression, Object data) {
+		return infinity();
+	}
+
+	@Override
+	public Object visit(PropertyName expression, Object data) {
+		return null;
+	}
+
+	@Override
+	public Object visit(Subtract expression, Object data) {
+		return infinity();
+	}
+
+	@Override
+	public Object visitNullFilter(Object data) {
+		return infinity();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/NullFilterVisitor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/NullFilterVisitor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/NullFilterVisitor.java	(revision 28000)
@@ -0,0 +1,152 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.visitor;
+
+import org.opengis.filter.And;
+import org.opengis.filter.ExcludeFilter;
+import org.opengis.filter.Filter;
+import org.opengis.filter.FilterVisitor;
+import org.opengis.filter.Id;
+import org.opengis.filter.IncludeFilter;
+import org.opengis.filter.Not;
+import org.opengis.filter.Or;
+import org.opengis.filter.expression.Add;
+import org.opengis.filter.expression.Divide;
+import org.opengis.filter.expression.ExpressionVisitor;
+import org.opengis.filter.expression.Function;
+import org.opengis.filter.expression.Literal;
+import org.opengis.filter.expression.Multiply;
+import org.opengis.filter.expression.NilExpression;
+import org.opengis.filter.expression.PropertyName;
+import org.opengis.filter.expression.Subtract;
+
+/**
+ * Abstract implementation of FilterVisitor simple returns the provided data.
+ * <p>
+ * This class can be used as is as a placeholder that does nothing:<pre><code>
+ * Integer one = (Integer) filter.accepts( NullFilterVisitor.NULL_VISITOR, 1 );
+ * </code></pre>
+ * 
+ * The class can also be used as an alternative to DefaultFilterVisitor if
+ * you want to only walk part of the data structure:
+ * <pre><code>
+ * FilterVisitor allFids = new NullFilterVisitor(){
+ *     public Object visit( Id filter, Object data ) {
+ *         if( data == null) return null;
+ *         Set set = (Set) data;
+ *         set.addAll(filter.getIDs());
+ *         return set;
+ *     }
+ * };
+ * Set set = (Set) myFilter.accept(allFids, new HashSet());
+ * Set set2 = (Set) myFilter.accept(allFids, null ); // set2 will be null
+ * </code></pre>
+ * The base class provides implementations for:
+ * <ul>
+ * <li>walking And, Or, and Not data structures, returning null at any point will exit early
+ * <li>a default implementation for every other construct that will return the provided data
+ * </ul>
+ * 
+ * @author Jody Garnett (Refractions Research)
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/visitor/NullFilterVisitor.java $
+ */
+public abstract class NullFilterVisitor implements FilterVisitor, ExpressionVisitor {
+    public NullFilterVisitor() {        
+    }
+
+    public Object visit( ExcludeFilter filter, Object data ) {
+        return data;
+    }
+
+    public Object visit( IncludeFilter filter, Object data ) {
+        return data;
+    }
+
+    public Object visit( And filter, Object data ) {
+        if( data == null ) return null;
+        if (filter.getChildren() != null) {
+            for( Filter child : filter.getChildren() ) {
+                data = child.accept(this, data);
+                if( data == null ) return null;
+            }
+        }
+        return data;
+    }
+
+    public Object visit( Id filter, Object data ) {
+        return data;
+    }
+
+    public Object visit( Not filter, Object data ) {
+        if( data == null ) return data;
+
+        Filter child = filter.getFilter();
+        if ( child != null) {
+            data = child.accept(this, data);
+        }
+        return data;
+    }
+
+    public Object visit( Or filter, Object data ) {
+        if( data == null ) return null;
+        if (filter.getChildren() != null) {
+            for( Filter child : filter.getChildren() ) {
+                data = child.accept(this, data);
+                if( data == null ) return null;
+            }
+        }
+        return data;
+    }
+
+    public Object visitNullFilter( Object data ) {
+        return data;
+    }
+
+    public Object visit( NilExpression expression, Object data ) {        
+        return null;
+    }
+
+    public Object visit( Add expression, Object data ) {
+        return data;
+    }
+
+    public Object visit( Divide expression, Object data ) {
+        return data;
+    }
+
+    public Object visit( Function expression, Object data ) {
+        return data;
+    }
+
+    public Object visit( Literal expression, Object data ) {        
+        return data;
+    }
+
+    public Object visit( Multiply expression, Object data ) {
+        return data;
+    }
+
+    public Object visit( PropertyName expression, Object data ) {
+        return data;
+    }
+
+    public Object visit( Subtract expression, Object data ) {
+        return data;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/PropertyNameResolvingVisitor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/PropertyNameResolvingVisitor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/filter/visitor/PropertyNameResolvingVisitor.java	(revision 28000)
@@ -0,0 +1,57 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.filter.visitor;
+
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.filter.expression.PropertyName;
+
+/**
+ * Resolves all property name references in a filter against a particular feature type. 
+ * <p>
+ * This visitor is used to handle property accesses such as "gml:name", "//foo" etc..  Each 
+ * such reference is resolved against the feature type and replaced with the actual name of
+ * the attribute, ie "gml:name" => "name", "//foo" => "foo".
+ * </p>
+ * 
+ * @author Justin Deoliveira, OpenGEO
+ * @since 2.6
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/filter/visitor/PropertyNameResolvingVisitor.java $
+ */
+public class PropertyNameResolvingVisitor extends DuplicatingFilterVisitor {
+
+    /** the feature type */
+    SimpleFeatureType featureType;
+
+    public PropertyNameResolvingVisitor( SimpleFeatureType featureType ) {
+        if ( featureType == null ) {
+            throw new NullPointerException( "featureType" );
+        }
+        
+        this.featureType = featureType;
+    }
+    
+    public Object visit(PropertyName expression, Object extraData) {
+        AttributeDescriptor att = expression.evaluate( featureType, null);
+        if ( att != null ) {
+            return getFactory(extraData).property( att.getLocalName() );
+        }
+        return super.visit(expression, extraData);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/AbstractDirectPosition.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/AbstractDirectPosition.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/AbstractDirectPosition.java	(revision 28000)
@@ -0,0 +1,186 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.geometry;
+
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import org.geotools.util.Utilities;
+import org.geotools.resources.Classes;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * Base class for {@linkplain DirectPosition direct position} implementations. This base class
+ * provides default implementations for {@link #toString}, {@link #equals} and {@link #hashCode}
+ * methods.
+ * <p>
+ * This class do not holds any state. The decision to implement {@link java.io.Serializable}
+ * or {@link org.geotools.util.Cloneable} interfaces is left to implementors.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/geometry/AbstractDirectPosition.java $
+ * @version $Id: AbstractDirectPosition.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public abstract class AbstractDirectPosition implements DirectPosition {
+    /**
+     * Constructs a direct position.
+     */
+    protected AbstractDirectPosition() {
+    }
+
+    /**
+     * Returns a sequence of numbers that hold the coordinate of this position in its
+     * reference system.
+     *
+     * @return The coordinates.
+     */
+    public double[] getCoordinate() {
+        final double[] ordinates = new double[getDimension()];
+        for (int i=0; i<ordinates.length; i++) {
+            ordinates[i] = getOrdinate(i);
+        }
+        return ordinates;
+    }
+
+    /**
+     * Convenience method for checking coordinate reference system validity.
+     *
+     * @param  crs The coordinate reference system to check.
+     * @param  expected the dimension expected.
+     * @throws MismatchedDimensionException if the CRS dimension is not valid.
+     */
+    static void checkCoordinateReferenceSystemDimension(final CoordinateReferenceSystem crs,
+                                                        final int expected)
+            throws MismatchedDimensionException
+    {
+        if (crs != null) {
+            final int dimension = crs.getCoordinateSystem().getDimension();
+            if (dimension != expected) {
+                throw new MismatchedDimensionException(Errors.format(ErrorKeys.MISMATCHED_DIMENSION_$3,
+                          crs.getName().getCode(), dimension, expected));
+            }
+        }
+    }
+
+    /**
+     * Convenience method for checking object dimension validity.
+     * This method is usually invoked for argument checking.
+     *
+     * @param  name The name of the argument to check.
+     * @param  dimension The object dimension.
+     * @param  expectedDimension The Expected dimension for the object.
+     * @throws MismatchedDimensionException if the object doesn't have the expected dimension.
+     */
+    static void ensureDimensionMatch(final String name,
+                                     final int dimension,
+                                     final int expectedDimension)
+            throws MismatchedDimensionException
+    {
+        if (dimension != expectedDimension) {
+            throw new MismatchedDimensionException(Errors.format(ErrorKeys.MISMATCHED_DIMENSION_$3,
+                        name, dimension, expectedDimension));
+        }
+    }
+
+    /**
+     * Returns a string representation of this coordinate. The default implementation is okay
+     * for occasional formatting (for example for debugging purpose). But if there is a lot
+     * of positions to format, users will get more control by using their own instance of
+     * {@link org.geotools.measure.CoordinateFormat}.
+     */
+    @Override
+    public String toString() {
+        return toString(this);
+    }
+
+    /**
+     * Formats the specified position.
+     */
+    static String toString(final DirectPosition position) {
+        final StringBuilder buffer = new StringBuilder(Classes.getShortClassName(position)).append('[');
+        final int dimension = position.getDimension();
+        for (int i=0; i<dimension; i++) {
+            if (i != 0) {
+                buffer.append(", ");
+            }
+            buffer.append(position.getOrdinate(i));
+        }
+        return buffer.append(']').toString();
+    }
+
+    /**
+     * Returns a hash value for this coordinate.
+     *
+     * @return A hash code value for this position.
+     */
+    @Override
+    public int hashCode() {
+        return hashCode(this);
+    }
+
+    /**
+     * Returns a hash value for the given coordinate.
+     */
+    static int hashCode(final DirectPosition position) {
+        final int dimension = position.getDimension();
+        int code = 1;
+        for (int i=0; i<dimension; i++) {
+            final long bits = Double.doubleToLongBits(position.getOrdinate(i));
+            code = 31 * code + ((int)(bits) ^ (int)(bits >>> 32));
+        }
+        final CoordinateReferenceSystem crs = position.getCoordinateReferenceSystem();
+        if (crs != null) {
+            code += crs.hashCode();
+        }
+        return code;
+    }
+
+    /**
+     * Returns {@code true} if the specified object is also a {@linkplain DirectPosition
+     * direct position} with equals {@linkplain #getCoordinate coordinate} and
+     * {@linkplain #getCoordinateReferenceSystem CRS}.
+     *
+     * @param object The object to compare with this position.
+     * @return {@code true} if the given object is equals to this position.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object instanceof DirectPosition) {
+            final DirectPosition that = (DirectPosition) object;
+            final int dimension = getDimension();
+            if (dimension == that.getDimension()) {
+                for (int i=0; i<dimension; i++) {
+                    if (!Utilities.equals(this.getOrdinate(i), that.getOrdinate(i))) {
+                        return false;
+                    }
+                }
+                if (Utilities.equals(this.getCoordinateReferenceSystem(),
+                                     that.getCoordinateReferenceSystem()))
+                {
+                    assert hashCode() == that.hashCode() : this;
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/AbstractEnvelope.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/AbstractEnvelope.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/AbstractEnvelope.java	(revision 28000)
@@ -0,0 +1,230 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.geometry;
+
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.Envelope;
+import org.opengis.geometry.MismatchedReferenceSystemException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import org.geotools.util.Utilities;
+import org.geotools.resources.Classes;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * Base class for {@linkplain Envelope envelope} implementations. This base class
+ * provides default implementations for {@link #toString}, {@link #equals} and
+ * {@link #hashCode} methods.
+ * <p>
+ * This class do not holds any state. The decision to implement {@link java.io.Serializable}
+ * or {@link org.geotools.util.Cloneable} interfaces is left to implementors.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/geometry/AbstractEnvelope.java $
+ * @version $Id: AbstractEnvelope.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public abstract class AbstractEnvelope implements Envelope {
+    /**
+     * Constructs an envelope.
+     */
+    protected AbstractEnvelope() {
+    }
+
+    /**
+     * Returns the common CRS of specified points.
+     *
+     * @param  minDP The first position.
+     * @param  maxDP The second position.
+     * @return Their common CRS, or {@code null} if none.
+     * @throws MismatchedReferenceSystemException if the two positions don't use the same CRS.
+     */
+    static CoordinateReferenceSystem getCoordinateReferenceSystem(final DirectPosition minDP,
+            final DirectPosition maxDP) throws MismatchedReferenceSystemException
+    {
+        final CoordinateReferenceSystem crs1 = minDP.getCoordinateReferenceSystem();
+        final CoordinateReferenceSystem crs2 = maxDP.getCoordinateReferenceSystem();
+        if (crs1 == null) {
+            return crs2;
+        } else {
+            if (crs2!=null && !crs1.equals(crs2)) {
+                throw new MismatchedReferenceSystemException(
+                          Errors.format(ErrorKeys.MISMATCHED_COORDINATE_REFERENCE_SYSTEM));
+            }
+            return crs1;
+        }
+    }
+
+    /**
+     * A coordinate position consisting of all the {@linkplain #getMinimum minimal ordinates}.
+     * The default implementation returns a direct position backed by this envelope, so changes
+     * in this envelope will be immediately reflected in the direct position.
+     *
+     * @return The lower corner.
+     */
+    public DirectPosition getLowerCorner() {
+        return new LowerCorner();
+    }
+
+    /**
+     * A coordinate position consisting of all the {@linkplain #getMaximum maximal ordinates}.
+     * The default implementation returns a direct position backed by this envelope, so changes
+     * in this envelope will be immediately reflected in the direct position.
+     *
+     * @return The upper corner.
+     */
+    public DirectPosition getUpperCorner() {
+        return new UpperCorner();
+    }
+
+    /**
+     * Returns a string representation of this envelope. The default implementation returns a
+     * string containing {@linkplain #getLowerCorner lower corner} coordinates first, followed
+     * by {@linkplain #getUpperCorner upper corner} coordinates. Other informations like the
+     * CRS or class name may or may not be presents at implementor choice.
+     * <p>
+     * This string is okay for occasional formatting (for example for debugging purpose). But
+     * if there is a lot of envelopes to format, users will get more control by using their own
+     * instance of {@link org.geotools.measure.CoordinateFormat}.
+     */
+    @Override
+    public String toString() {
+        return toString(this);
+    }
+
+    /**
+     * Formats the specified envelope. The returned string will contain the
+     * {@linkplain #getLowerCorner lower corner} coordinates first, followed by
+     * {@linkplain #getUpperCorner upper corner} coordinates.
+     */
+    static String toString(final Envelope envelope) {
+        final StringBuilder buffer = new StringBuilder(Classes.getShortClassName(envelope));
+        final int dimension = envelope.getDimension();
+        if (dimension != 0) {
+            String separator = "[(";
+            for (int i=0; i<dimension; i++) {
+                buffer.append(separator).append(envelope.getMinimum(i));
+                separator = ", ";
+            }
+            separator = "), (";
+            for (int i=0; i<dimension; i++) {
+                buffer.append(separator).append(envelope.getMaximum(i));
+                separator = ", ";
+            }
+            buffer.append(")]");
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Returns a hash value for this envelope.
+     */
+    @Override
+    public int hashCode() {
+        final int dimension = getDimension();
+        int code = 1;
+        boolean p = true;
+        do {
+            for (int i=0; i<dimension; i++) {
+                final long bits = Double.doubleToLongBits(p ? getMinimum(i) : getMaximum(i));
+                code = 31 * code + ((int)(bits) ^ (int)(bits >>> 32));
+            }
+        } while ((p = !p) == false);
+        final CoordinateReferenceSystem crs = getCoordinateReferenceSystem();
+        if (crs != null) {
+            code += crs.hashCode();
+        }
+        return code;
+    }
+
+    /**
+     * Returns {@code true} if the specified object is also an {@linkplain Envelope envelope}
+     * with equals coordinates and {@linkplain #getCoordinateReferenceSystem CRS}.
+     *
+     * @param object The object to compare with this envelope.
+     * @return {@code true} if the given object is equals to this envelope.
+     *
+     * @todo Current implementation requires that {@code object} is of the same class.
+     *       We can not relax this rule before we ensure that every implementations in
+     *       the Geotools code base follow the same contract.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object!=null && object.getClass().equals(getClass())) {
+            final Envelope that = (Envelope) object;
+            final int dimension = getDimension();
+            if (dimension == that.getDimension()) {
+                for (int i=0; i<dimension; i++) {
+                    if (!Utilities.equals(this.getMinimum(i), that.getMinimum(i)) ||
+                        !Utilities.equals(this.getMaximum(i), that.getMaximum(i)))
+                    {
+                        return false;
+                    }
+                }
+                if (Utilities.equals(this.getCoordinateReferenceSystem(),
+                                     that.getCoordinateReferenceSystem()))
+                {
+                    assert hashCode() == that.hashCode() : this;
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Base class for direct position from an envelope.
+     * This class delegates its work to the enclosing envelope.
+     */
+    private abstract class Corner extends AbstractDirectPosition {
+        /** The coordinate reference system in which the coordinate is given. */
+        public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+            return AbstractEnvelope.this.getCoordinateReferenceSystem();
+        }
+
+        /** The length of coordinate sequence (the number of entries). */
+        public int getDimension() {
+            return AbstractEnvelope.this.getDimension();
+        }
+
+        /** Sets the ordinate value along the specified dimension. */
+        public void setOrdinate(int dimension, double value) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    /**
+     * The corner returned by {@link AbstractEnvelope#getLowerCorner}.
+     */
+    private final class LowerCorner extends Corner {
+        public double getOrdinate(final int dimension) throws IndexOutOfBoundsException {
+            return getMinimum(dimension);
+        }
+    }
+
+    /**
+     * The corner returned by {@link AbstractEnvelope#getUpperCorner}.
+     */
+    private final class UpperCorner extends Corner {
+        public double getOrdinate(final int dimension) throws IndexOutOfBoundsException {
+            return getMaximum(dimension);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/DirectPosition1D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/DirectPosition1D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/DirectPosition1D.java	(revision 28000)
@@ -0,0 +1,162 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.geometry;
+
+import java.io.Serializable;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.util.Cloneable;
+
+
+/**
+ * Holds the coordinates for a one-dimensional position within some coordinate reference system.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/geometry/DirectPosition1D.java $
+ * @version $Id: DirectPosition1D.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see DirectPosition2D
+ * @see GeneralPosition
+ */
+public class DirectPosition1D extends AbstractDirectPosition implements Serializable, Cloneable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 3235094562875693710L;
+
+    /**
+     * The coordinate reference system for this position;
+     */
+    private CoordinateReferenceSystem crs;
+
+    /**
+     * The ordinate value.
+     */
+    public double ordinate;
+
+    /**
+     * Constructs a position initialized to (0) with a {@code null}
+     * coordinate reference system.
+     */
+    public DirectPosition1D() {
+    }
+
+    /**
+     * Constructs a 1D position from the specified ordinate.
+     *
+     * @param ordinate The ordinate value.
+     */
+    public DirectPosition1D(final double ordinate) {
+        this.ordinate = ordinate;
+    }
+
+    /**
+     * Returns the coordinate reference system in which the coordinate is given.
+     * May be {@code null} if this particular {@code DirectPosition} is included
+     * in a larger object with such a reference to a {@linkplain CoordinateReferenceSystem
+     * coordinate reference system}.
+     *
+     * @return The coordinate reference system, or {@code null}.
+     */
+    public final CoordinateReferenceSystem getCoordinateReferenceSystem() {
+        return crs;
+    }
+
+    /**
+     * The length of coordinate sequence (the number of entries).
+     * This is always 1 for <code>DirectPosition1D</code> objects.
+     *
+     * @return The dimensionality of this position.
+     */
+    public final int getDimension() {
+        return 1;
+    }
+
+    /**
+     * Returns a sequence of numbers that hold the coordinate of this position in its
+     * reference system.
+     *
+     * @return The coordinates.
+     */
+    @Override
+    public double[] getCoordinate() {
+        return new double[] {ordinate};
+    }
+
+    /**
+     * Returns the ordinate at the specified dimension.
+     *
+     * @param  dimension The dimension, which must be 0.
+     * @return The {@linkplain #ordinate}.
+     * @throws IndexOutOfBoundsException if the specified dimension is out of bounds.
+     *
+     * @todo Provides a more detailled error message.
+     */
+    public final double getOrdinate(final int dimension) throws IndexOutOfBoundsException {
+        if (dimension == 0) {
+            return ordinate;
+        } else {
+            throw new IndexOutOfBoundsException(String.valueOf(dimension));
+        }
+    }
+
+    /**
+     * Sets the ordinate value along the specified dimension.
+     *
+     * @param  dimension The dimension, which must be 0.
+     * @param  value the ordinate value.
+     * @throws IndexOutOfBoundsException if the specified dimension is out of bounds.
+     *
+     * @todo Provides a more detailled error message.
+     */
+    public final void setOrdinate(int dimension, double value) throws IndexOutOfBoundsException {
+        if (dimension == 0) {
+            ordinate = value;
+        } else {
+            throw new IndexOutOfBoundsException(String.valueOf(dimension));
+        }
+    }
+
+    /**
+     * Returns a hash value for this coordinate.
+     */
+    @Override
+    public int hashCode() {
+        final long value = Double.doubleToLongBits(ordinate);
+        int code = 31 + ((int)value ^ (int)(value >>> 32));
+        if (crs != null) {
+            code += crs.hashCode();
+        }
+        assert code == super.hashCode();
+        return code;
+    }
+
+    /**
+     * Returns a copy of this position.
+     */
+    @Override
+    public DirectPosition1D clone() {
+        try {
+            return (DirectPosition1D) super.clone();
+        } catch (CloneNotSupportedException exception) {
+            // Should not happen, since we are cloneable.
+            throw new AssertionError(exception);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/GeneralDirectPosition.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/GeneralDirectPosition.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/GeneralDirectPosition.java	(revision 28000)
@@ -0,0 +1,217 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.geometry;
+
+import java.awt.geom.Point2D;
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.util.Cloneable;
+
+
+/**
+ * Holds the coordinates for a position within some coordinate reference system. Since
+ * {@code DirectPosition}s, as data types, will often be included in larger objects
+ * (such as {@linkplain org.geotools.geometry.Geometry geometries}) that have references
+ * to {@link CoordinateReferenceSystem}, the {@link #getCoordinateReferenceSystem} method
+ * may returns {@code null} if this particular {@code DirectPosition} is included
+ * in a larger object with such a reference to a {@linkplain CoordinateReferenceSystem
+ * coordinate reference system}. In this case, the cordinate reference system is implicitly
+ * assumed to take on the value of the containing object's {@link CoordinateReferenceSystem}.
+ * <p>
+ * This particular implementation of {@code DirectPosition} is said "General" because it
+ * uses an {@linkplain #ordinates array of ordinates} of an arbitrary length. If the direct
+ * position is know to be always two-dimensional, then {@link DirectPosition2D} may provides
+ * a more efficient implementation.
+ * <p>
+ * Most methods in this implementation are final for performance reason.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/geometry/GeneralDirectPosition.java $
+ * @version $Id: GeneralDirectPosition.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see DirectPosition1D
+ * @see DirectPosition2D
+ * @see java.awt.geom.Point2D
+ */
+public class GeneralDirectPosition extends AbstractDirectPosition implements Serializable, Cloneable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 9071833698385715524L;
+
+    /**
+     * The ordinates of the direct position.
+     */
+    public final double[] ordinates;
+
+    /**
+     * The coordinate reference system for this position, or {@code null}.
+     */
+    private CoordinateReferenceSystem crs;
+
+    /**
+     * Constructs a position with the specified number of dimensions.
+     *
+     * @param  numDim Number of dimensions.
+     * @throws NegativeArraySizeException if {@code numDim} is negative.
+     */
+    public GeneralDirectPosition(final int numDim) throws NegativeArraySizeException {
+        ordinates = new double[numDim];
+    }
+
+    /**
+     * Constructs a position with the specified ordinates.
+     * The {@code ordinates} array will be copied.
+     *
+     * @param ordinates The ordinate values to copy.
+     */
+    public GeneralDirectPosition(final double[] ordinates) {
+        this.ordinates = ordinates.clone();
+    }
+
+    /**
+     * Constructs a 2D position from the specified ordinates. Despite their name, the
+     * (<var>x</var>,<var>y</var>) coordinates don't need to be oriented toward
+     * ({@linkplain org.opengis.referencing.cs.AxisDirection#EAST  East},
+     *  {@linkplain org.opengis.referencing.cs.AxisDirection#NORTH North}).
+     * See the {@link DirectPosition2D} javadoc for details.
+     *
+     * @param x The first ordinate value.
+     * @param y The second ordinate value.
+     */
+    public GeneralDirectPosition(final double x, final double y) {
+        ordinates = new double[] {x,y};
+    }
+
+    /**
+     * Constructs a position from the specified {@link Point2D}.
+     *
+     * @param point The position to copy.
+     */
+    public GeneralDirectPosition(final Point2D point) {
+        this(point.getX(), point.getY());
+    }
+
+    /**
+     * Constructs a position initialized to the same values than the specified point.
+     *
+     * @param point The position to copy.
+     *
+     * @since 2.2
+     */
+    public GeneralDirectPosition(final DirectPosition point) {
+        ordinates = point.getCoordinate(); // Should already be cloned.
+        crs = point.getCoordinateReferenceSystem();
+    }
+
+    /**
+     * Returns the coordinate reference system in which the coordinate is given.
+     * May be {@code null} if this particular {@code DirectPosition} is included
+     * in a larger object with such a reference to a {@linkplain CoordinateReferenceSystem
+     * coordinate reference system}.
+     *
+     * @return The coordinate reference system, or {@code null}.
+     */
+    public final CoordinateReferenceSystem getCoordinateReferenceSystem() {
+        return crs;
+    }
+
+    /**
+     * Set the coordinate reference system in which the coordinate is given.
+     *
+     * @param crs The new coordinate reference system, or {@code null}.
+     * @throws MismatchedDimensionException if the specified CRS doesn't have the expected
+     *         number of dimensions.
+     */
+    public void setCoordinateReferenceSystem(final CoordinateReferenceSystem crs)
+            throws MismatchedDimensionException
+    {
+        checkCoordinateReferenceSystemDimension(crs, getDimension());
+        this.crs = crs;
+    }
+
+    /**
+     * The length of coordinate sequence (the number of entries).
+     * This may be less than or equal to the dimensionality of the
+     * {@linkplain #getCoordinateReferenceSystem() coordinate reference system}.
+     *
+     * @return The dimensionality of this position.
+     */
+    public final int getDimension() {
+        return ordinates.length;
+    }
+
+    /**
+     * Returns a sequence of numbers that hold the coordinate of this position in its
+     * reference system.
+     *
+     * @return A copy of the {@linkplain #ordinates coordinates}.
+     */
+    @Override
+    public final double[] getCoordinate() {
+        return ordinates.clone();
+    }
+
+    /**
+     * Returns the ordinate at the specified dimension.
+     *
+     * @param  dimension The dimension in the range 0 to {@linkplain #getDimension dimension}-1.
+     * @return The coordinate at the specified dimension.
+     * @throws IndexOutOfBoundsException if the specified dimension is out of bounds.
+     */
+    public final double getOrdinate(int dimension) throws IndexOutOfBoundsException {
+        return ordinates[dimension];
+    }
+
+    /**
+     * Sets the ordinate value along the specified dimension.
+     *
+     * @param dimension the dimension for the ordinate of interest.
+     * @param value the ordinate value of interest.
+     * @throws IndexOutOfBoundsException if the specified dimension is out of bounds.
+     */
+    public final void setOrdinate(int dimension, double value) throws IndexOutOfBoundsException {
+        ordinates[dimension] = value;
+    }
+
+    /**
+     * Returns a hash value for this coordinate.
+     */
+    @Override
+    public int hashCode() {
+        int code = Arrays.hashCode(ordinates);
+        if (crs != null) {
+            code += crs.hashCode();
+        }
+        assert code == super.hashCode();
+        return code;
+    }
+
+    /**
+     * Returns a deep copy of this position.
+     */
+    @Override
+    public GeneralDirectPosition clone() {
+        return new GeneralDirectPosition(ordinates);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/GeneralEnvelope.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/GeneralEnvelope.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/GeneralEnvelope.java	(revision 28000)
@@ -0,0 +1,559 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.geometry;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.geotools.referencing.CRS;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.Envelope;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.geometry.MismatchedReferenceSystemException;
+import org.opengis.parameter.InvalidParameterValueException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.util.Cloneable;
+
+/**
+ * A minimum bounding box or rectangle. Regardless of dimension, an {@code Envelope} can be
+ * represented without ambiguity as two {@linkplain DirectPosition direct positions} (coordinate
+ * points). To encode an {@code Envelope}, it is sufficient to encode these two points.
+ * <p>
+ * This particular implementation of {@code Envelope} is said "General" because it uses coordinates
+ * of an arbitrary dimension.
+ * <p>
+ * <strong>Tip:</strong> The metadata package provides a
+ * {@link org.opengis.metadata.extent.GeographicBoundingBox}, which can be used as a kind of
+ * envelope with a coordinate reference system fixed to WGS 84 (EPSG:4326).
+ * 
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/geometry/GeneralEnvelope.java $
+ *         http://svn.osgeo.org/geotools/branches/2.6.x/modules/library/referencing/src/main/java
+ *         /org/geotools/geometry/GeneralEnvelope.java $
+ * @version $Id: GeneralEnvelope.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Simone Giannecchini
+ * 
+ * @see Envelope2D
+ * @see org.geotools.geometry.jts.ReferencedEnvelope
+ * @see org.opengis.metadata.extent.GeographicBoundingBox
+ */
+public class GeneralEnvelope extends AbstractEnvelope implements Cloneable, Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 1752330560227688940L;
+
+    /**
+     * Minimum and maximum ordinate values. The first half contains minimum ordinates, while the
+     * last half contains maximum ordinates. This layout is convenient for the creation of lower and
+     * upper corner direct positions.
+     * <p>
+     * Consider this reference as final; it is modified by {@link #clone} only.
+     */
+    private double[] ordinates;
+
+    /**
+     * The coordinate reference system, or {@code null}.
+     */
+    private CoordinateReferenceSystem crs;
+
+    /**
+     * Constructs a envelope defined by two positions.
+     * 
+     * @param minDP
+     *            Minimum ordinate values.
+     * @param maxDP
+     *            Maximum ordinate values.
+     * @throws MismatchedDimensionException
+     *             if the two positions don't have the same dimension.
+     * @throws IllegalArgumentException
+     *             if an ordinate value in the minimum point is not less than or equal to the
+     *             corresponding ordinate value in the maximum point.
+     */
+    public GeneralEnvelope(final double[] minDP, final double[] maxDP)
+            throws IllegalArgumentException {
+        ensureNonNull("minDP", minDP);
+        ensureNonNull("maxDP", maxDP);
+        ensureSameDimension(minDP.length, maxDP.length);
+        ordinates = new double[minDP.length + maxDP.length];
+        System.arraycopy(minDP, 0, ordinates, 0, minDP.length);
+        System.arraycopy(maxDP, 0, ordinates, minDP.length, maxDP.length);
+        checkCoordinates(ordinates);
+    }
+
+    /**
+     * Constructs a envelope defined by two positions. The coordinate reference system is inferred
+     * from the supplied direct position.
+     * 
+     * @param minDP
+     *            Point containing minimum ordinate values.
+     * @param maxDP
+     *            Point containing maximum ordinate values.
+     * @throws MismatchedDimensionException
+     *             if the two positions don't have the same dimension.
+     * @throws MismatchedReferenceSystemException
+     *             if the two positions don't use the same CRS.
+     * @throws IllegalArgumentException
+     *             if an ordinate value in the minimum point is not less than or equal to the
+     *             corresponding ordinate value in the maximum point.
+     */
+    public GeneralEnvelope(final GeneralDirectPosition minDP, final GeneralDirectPosition maxDP)
+            throws MismatchedReferenceSystemException, IllegalArgumentException {
+        // Uncomment next lines if Sun fixes RFE #4093999
+        // ensureNonNull("minDP", minDP);
+        // ensureNonNull("maxDP", maxDP);
+        this(minDP.ordinates, maxDP.ordinates);
+        crs = getCoordinateReferenceSystem(minDP, maxDP);
+        AbstractDirectPosition.checkCoordinateReferenceSystemDimension(crs, ordinates.length / 2);
+    }
+
+    /**
+     * Constructs a new envelope with the same data than the specified envelope.
+     * 
+     * @param envelope
+     *            The envelope to copy.
+     */
+    public GeneralEnvelope(final Envelope envelope) {
+        ensureNonNull("envelope", envelope);
+        if (envelope instanceof GeneralEnvelope) {
+            final GeneralEnvelope e = (GeneralEnvelope) envelope;
+            ordinates = e.ordinates.clone();
+            crs = e.crs;
+        } else {
+            crs = envelope.getCoordinateReferenceSystem();
+            final int dimension = envelope.getDimension();
+            ordinates = new double[2 * dimension];
+            for (int i = 0; i < dimension; i++) {
+                ordinates[i] = envelope.getMinimum(i);
+                ordinates[i + dimension] = envelope.getMaximum(i);
+            }
+            checkCoordinates(ordinates);
+        }
+    }
+
+    /**
+     * Makes sure an argument is non-null.
+     * 
+     * @param name
+     *            Argument name.
+     * @param object
+     *            User argument.
+     * @throws InvalidParameterValueException
+     *             if {@code object} is null.
+     */
+    private static void ensureNonNull(final String name, final Object object)
+            throws IllegalArgumentException {
+        if (object == null) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1, name));
+        }
+    }
+
+    /**
+     * Makes sure the specified dimensions are identical.
+     */
+    private static void ensureSameDimension(final int dim1, final int dim2)
+            throws MismatchedDimensionException {
+        if (dim1 != dim2) {
+            throw new MismatchedDimensionException(Errors.format(ErrorKeys.MISMATCHED_DIMENSION_$2,
+                    dim1, dim2));
+        }
+    }
+
+    /**
+     * Checks if ordinate values in the minimum point are less than or equal to the corresponding
+     * ordinate value in the maximum point.
+     * <p>
+     * This code will recognize the following exceptions:
+     * <ul>
+     * <li>ordinates encoding isNil</li>
+     * <li>ordinates encoding isEmpty</li>
+     * </ul>
+     * @throws IllegalArgumentException
+     *             if an ordinate value in the minimum point is not less than or equal to the
+     *             corresponding ordinate value in the maximum point.
+     */
+    private static void checkCoordinates(final double[] ordinates) throws IllegalArgumentException {
+        if( isNilCoordinates( ordinates )){
+            return; // null ordinates are okay            
+        }
+        if( isEmptyOrdinates(ordinates)){
+            return; // empty ordinates are also a valid encoding....
+        }
+        final int dimension = ordinates.length / 2;
+        for (int i = 0; i < dimension; i++) {
+            if (!(ordinates[i] <= ordinates[dimension + i])) { // Use '!' in order to catch 'NaN'.
+                throw new IllegalArgumentException(Errors.format(
+                        ErrorKeys.ILLEGAL_ENVELOPE_ORDINATE_$1, i));
+            }
+        }
+    }
+
+    /**
+     * Returns the coordinate reference system in which the coordinates are given.
+     * 
+     * @return The coordinate reference system, or {@code null}.
+     */
+    public final CoordinateReferenceSystem getCoordinateReferenceSystem() {
+        assert crs == null || crs.getCoordinateSystem().getDimension() == getDimension();
+        return crs;
+    }
+
+    /**
+     * Sets the coordinate reference system in which the coordinate are given. This method
+     * <strong>do not</strong> reproject the envelope, and do not check if the envelope is contained
+     * in the new domain of validity. The later can be enforced by a call to {@link #normalize}.
+     * 
+     * @param crs
+     *            The new coordinate reference system, or {@code null}.
+     * @throws MismatchedDimensionException
+     *             if the specified CRS doesn't have the expected number of dimensions.
+     */
+    public void setCoordinateReferenceSystem(final CoordinateReferenceSystem crs)
+            throws MismatchedDimensionException {
+        AbstractDirectPosition.checkCoordinateReferenceSystemDimension(crs, getDimension());
+        this.crs = crs;
+    }
+
+    /**
+     * Returns the number of dimensions.
+     */
+    public final int getDimension() {
+        return ordinates.length / 2;
+    }
+
+    /**
+     * A coordinate position consisting of all the {@linkplain #getMinimum minimal ordinates} for
+     * each dimension for all points within the {@code Envelope}.
+     * 
+     * @return The lower corner.
+     */
+    @Override
+    public DirectPosition getLowerCorner() {
+        final int dim = ordinates.length / 2;
+        final GeneralDirectPosition position = new GeneralDirectPosition(dim);
+        System.arraycopy(ordinates, 0, position.ordinates, 0, dim);
+        position.setCoordinateReferenceSystem(crs);
+        return position;
+    }
+
+    /**
+     * A coordinate position consisting of all the {@linkplain #getMaximum maximal ordinates} for
+     * each dimension for all points within the {@code Envelope}.
+     * 
+     * @return The upper corner.
+     */
+    @Override
+    public DirectPosition getUpperCorner() {
+        final int dim = ordinates.length / 2;
+        final GeneralDirectPosition position = new GeneralDirectPosition(dim);
+        System.arraycopy(ordinates, dim, position.ordinates, 0, dim);
+        position.setCoordinateReferenceSystem(crs);
+        return position;
+    }
+
+    /**
+     * Creates an exception for an index out of bounds.
+     */
+    private static IndexOutOfBoundsException indexOutOfBounds(final int dimension) {
+        return new IndexOutOfBoundsException(Errors.format(ErrorKeys.INDEX_OUT_OF_BOUNDS_$1,
+                dimension));
+    }
+
+    /**
+     * Returns the minimal ordinate along the specified dimension.
+     * 
+     * @param dimension
+     *            The dimension to query.
+     * @return The minimal ordinate value along the given dimension.
+     * @throws IndexOutOfBoundsException
+     *             If the given index is out of bounds.
+     */
+    public final double getMinimum(final int dimension) throws IndexOutOfBoundsException {
+        if (dimension < ordinates.length / 2) {
+            return ordinates[dimension];
+        } else {
+            throw indexOutOfBounds(dimension);
+        }
+    }
+
+    /**
+     * Returns the maximal ordinate along the specified dimension.
+     * 
+     * @param dimension
+     *            The dimension to query.
+     * @return The maximal ordinate value along the given dimension.
+     * @throws IndexOutOfBoundsException
+     *             If the given index is out of bounds.
+     */
+    public final double getMaximum(final int dimension) throws IndexOutOfBoundsException {
+        if (dimension >= 0) {
+            return ordinates[dimension + ordinates.length / 2];
+        } else {
+            throw indexOutOfBounds(dimension);
+        }
+    }
+
+    /**
+     * Returns the center ordinate along the specified dimension.
+     * 
+     * @param dimension
+     *            The dimension to query.
+     * @return The mid ordinate value along the given dimension.
+     * 
+     * @deprecated Renamed as {@link #getMedian(int)}.
+     */
+    @Deprecated
+    public final double getCenter(final int dimension) {
+        return getMedian(dimension);
+    }
+
+    /**
+     * Returns the median ordinate along the specified dimension. The result should be equals (minus
+     * rounding error) to <code>({@linkplain #getMaximum getMaximum}(dimension) -
+     * {@linkplain #getMinimum getMinimum}(dimension)) / 2</code>.
+     * 
+     * @param dimension
+     *            The dimension to query.
+     * @return The mid ordinate value along the given dimension.
+     * @throws IndexOutOfBoundsException
+     *             If the given index is out of bounds.
+     */
+    public final double getMedian(final int dimension) throws IndexOutOfBoundsException {
+        return 0.5 * (ordinates[dimension] + ordinates[dimension + ordinates.length / 2]);
+    }
+
+    /**
+     * Returns the envelope length along the specified dimension. This length is equals to the
+     * maximum ordinate minus the minimal ordinate.
+     * 
+     * @param dimension
+     *            The dimension to query.
+     * @return The difference along maximal and minimal ordinates in the given dimension.
+     * 
+     * @deprecated Renamed as {@link #getSpan(int)}.
+     */
+    @Deprecated
+    public final double getLength(final int dimension) {
+        return getSpan(dimension);
+    }
+
+    /**
+     * Returns the envelope span (typically width or height) along the specified dimension. The
+     * result should be equals (minus rounding error) to <code>{@linkplain #getMaximum
+     * getMaximum}(dimension) - {@linkplain #getMinimum getMinimum}(dimension)</code>.
+     * 
+     * @param dimension
+     *            The dimension to query.
+     * @return The difference along maximal and minimal ordinates in the given dimension.
+     * @throws IndexOutOfBoundsException
+     *             If the given index is out of bounds.
+     */
+    public final double getSpan(final int dimension) throws IndexOutOfBoundsException {
+        return ordinates[dimension + ordinates.length / 2] - ordinates[dimension];
+    }
+
+    /**
+     * Returns {@code false} if at least one ordinate value is not {@linkplain Double#NaN NaN}. The
+     * {@code isNull()} check is a little bit different than {@link #isEmpty()} since it returns
+     * {@code false} for a partially initialized envelope, while {@code isEmpty()} returns {@code
+     * false} only after all dimensions have been initialized. More specifically, the following
+     * rules apply:
+     * <p>
+     * <ul>
+     * <li>If <code>isNull() == true</code>, then <code>{@linkplain #isEmpty()} == true</code></li>
+     * <li>If <code>{@linkplain #isEmpty()} == false</code>, then <code>isNull() == false</code></li>
+     * <li>The converse of the above-cited rules are not always true.</li>
+     * </ul>
+     * 
+     * @return {@code true} if this envelope has NaN values.
+     * 
+     * @since 2.2
+     */
+    public boolean isNull() {
+        if (!isNilCoordinates(ordinates)) {
+            return false;
+        }
+        assert isEmpty() : this;
+        return true;
+    }
+
+    /**
+     * Check if the ordinates indicate a "nil" envelope.
+     * @param ordinates
+     * @return
+     * @throws IllegalArgumentException
+     */
+    private static boolean isNilCoordinates(final double[] ordinates)
+            throws IllegalArgumentException {
+        for (int i = 0; i < ordinates.length; i++) {
+            if (!Double.isNaN(ordinates[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Determines whether or not this envelope is empty. An envelope is non-empty only if it has at
+     * least one {@linkplain #getDimension dimension}, and the {@linkplain #getLength length} is
+     * greater than 0 along all dimensions. Note that a non-empty envelope is always non-
+     * {@linkplain #isNull null}, but the converse is not always true.
+     * 
+     * @return {@code true} if this envelope is empty.
+     */
+    public boolean isEmpty() {
+        if( isEmptyOrdinates(ordinates)){
+            return true;
+        }
+        assert !isNull() : this; // JG I worry that this is circular
+        return false;
+    }
+    /**
+     * Static method used to recognize an empty encoding of ordindates
+     * @param ordinates
+     * @return true of the ordinates indicate an empty envelope
+     * @see #isEmpty()
+     */
+    private static boolean isEmptyOrdinates( double ordinates[] ){
+        final int dimension = ordinates.length / 2;
+        if (dimension == 0) {
+            return true;
+        }
+        for (int i = 0; i < dimension; i++) {
+            if (!(ordinates[i] < ordinates[i + dimension])) { // Use '!' in order to catch NaN
+                return true;
+            }
+        }
+        return false;
+    }
+    /**
+     * Returns {@code true} if at least one of the specified CRS is null, or both CRS are equals.
+     * This special processing for {@code null} values is different from the usual contract of an
+     * {@code equals} method, but allow to handle the case where the CRS is unknown.
+     */
+    private static boolean equalsIgnoreMetadata(final CoordinateReferenceSystem crs1,
+            final CoordinateReferenceSystem crs2) {
+        return crs1 == null || crs2 == null || CRS.equalsIgnoreMetadata(crs1, crs2);
+    }
+
+    /**
+     * Adds a point to this envelope. The resulting envelope is the smallest envelope that contains
+     * both the original envelope and the specified point. After adding a point, a call to
+     * {@link #contains} with the added point as an argument will return {@code true}, except if one
+     * of the point's ordinates was {@link Double#NaN} (in which case the corresponding ordinate
+     * have been ignored).
+     * <p>
+     * This method assumes that the specified point uses the same CRS than this envelope. For
+     * performance reason, it will no be verified unless J2SE assertions are enabled.
+     * 
+     * @param position
+     *            The point to add.
+     * @throws MismatchedDimensionException
+     *             if the specified point doesn't have the expected dimension.
+     */
+    public void add(final DirectPosition position) throws MismatchedDimensionException {
+        ensureNonNull("position", position);
+        final int dim = ordinates.length / 2;
+        AbstractDirectPosition.ensureDimensionMatch("position", position.getDimension(), dim);
+        assert equalsIgnoreMetadata(crs, position.getCoordinateReferenceSystem()) : position;
+        for (int i = 0; i < dim; i++) {
+            final double value = position.getOrdinate(i);
+            if (value < ordinates[i])
+                ordinates[i] = value;
+            if (value > ordinates[i + dim])
+                ordinates[i + dim] = value;
+        }
+        assert isEmpty() || contains(position);
+    }
+
+    /**
+     * Tests if a specified coordinate is inside the boundary of this envelope.
+     * <p>
+     * This method assumes that the specified point uses the same CRS than this envelope. For
+     * performance reason, it will no be verified unless J2SE assertions are enabled.
+     * 
+     * @param position
+     *            The point to text.
+     * @return {@code true} if the specified coordinates are inside the boundary of this envelope;
+     *         {@code false} otherwise.
+     * @throws MismatchedDimensionException
+     *             if the specified point doesn't have the expected dimension.
+     */
+    public boolean contains(final DirectPosition position) throws MismatchedDimensionException {
+        ensureNonNull("position", position);
+        final int dim = ordinates.length / 2;
+        AbstractDirectPosition.ensureDimensionMatch("point", position.getDimension(), dim);
+        assert equalsIgnoreMetadata(crs, position.getCoordinateReferenceSystem()) : position;
+        for (int i = 0; i < dim; i++) {
+            final double value = position.getOrdinate(i);
+            if (!(value >= ordinates[i]))
+                return false;
+            if (!(value <= ordinates[i + dim]))
+                return false;
+            // Use '!' in order to take 'NaN' in account.
+        }
+        return true;
+    }
+
+    /**
+     * Returns a hash value for this envelope.
+     */
+    @Override
+    public int hashCode() {
+        int code = Arrays.hashCode(ordinates);
+        if (crs != null) {
+            code += crs.hashCode();
+        }
+        assert code == super.hashCode();
+        return code;
+    }
+
+    /**
+     * Compares the specified object with this envelope for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object != null && object.getClass().equals(getClass())) {
+            final GeneralEnvelope that = (GeneralEnvelope) object;
+            return Arrays.equals(this.ordinates, that.ordinates)
+                    && Utilities.equals(this.crs, that.crs);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a deep copy of this envelope.
+     * 
+     * @return A clone of this envelope.
+     */
+    @Override
+    public GeneralEnvelope clone() {
+        try {
+            GeneralEnvelope e = (GeneralEnvelope) super.clone();
+            e.ordinates = e.ordinates.clone();
+            return e;
+        } catch (CloneNotSupportedException exception) {
+            // Should not happen, since we are cloneable.
+            throw new AssertionError(exception);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/CoordinateSequenceTransformer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/CoordinateSequenceTransformer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/CoordinateSequenceTransformer.java	(revision 28000)
@@ -0,0 +1,49 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.geometry.jts;
+
+
+// JTS dependencies
+import com.vividsolutions.jts.geom.CoordinateSequence;
+
+// OpenGIS dependencies
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+
+
+/**
+ * Interface that should be implemented by classes able to apply the provided
+ * {@linkplain MathTransform transformation} to a
+ * {@linkplain CoordinateSequence coordinate sequence}.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/geometry/jts/CoordinateSequenceTransformer.java $
+ * @version $Id: CoordinateSequenceTransformer.java 37280 2011-05-24 07:53:02Z mbedward $
+ * @author Andrea Aime
+ */
+public interface CoordinateSequenceTransformer {
+    /**
+     * Returns a transformed coordinate sequence.
+     *
+     * @param  sequence The sequence to transform.
+     * @param  transform The transformation to apply.
+     * @throws TransformException if at least one coordinate can't be transformed.
+     */
+    public CoordinateSequence transform(CoordinateSequence sequence, MathTransform transform)
+        throws TransformException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/DefaultCoordinateSequenceTransformer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/DefaultCoordinateSequenceTransformer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/DefaultCoordinateSequenceTransformer.java	(revision 28000)
@@ -0,0 +1,147 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.geometry.jts;
+
+
+// JTS dependencies
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.CoordinateSequenceFactory;
+import com.vividsolutions.jts.geom.DefaultCoordinateSequenceFactory;
+
+
+/**
+ * A default implementation of {@linkplain CoordinateSequenceTransformer coordinate sequence
+ * transformer}. This transformer applies the coordinate transformations immediately (which
+ * means that caller are immediately notified if a transformation fails).
+ * <p>
+ * This transformer support {@linkplain MathTransform math transform} with up to 3 source
+ * or target dimensions. This transformer is not thread-safe.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/geometry/jts/DefaultCoordinateSequenceTransformer.java $
+ * @version $Id: DefaultCoordinateSequenceTransformer.java 37280 2011-05-24 07:53:02Z mbedward $
+ * @author Andrea Aime
+ * @author Martin Desruisseaux
+ */
+public class DefaultCoordinateSequenceTransformer implements CoordinateSequenceTransformer {
+    /**
+     * A buffer for coordinate transformations. We choose a length which is divisible by
+     * both 2 and 3, since JTS coordinates may be up to three-dimensional. If the number
+     * of coordinates point to transform is greater than the buffer capacity, then the
+     * buffer will be flushed to the destination array before to continue. We avoid to
+     * create a buffer as large than the number of point to transforms, because it would
+     * consume a large amount of memory for big geometries.
+     */
+    private final transient double[] buffer = new double[96];
+
+    /**
+     * The coordinate sequence factory to use.
+     */
+    private final CoordinateSequenceFactory csFactory;
+
+    /**
+     * Constructs a default coordinate sequence transformer.
+     */
+    public DefaultCoordinateSequenceTransformer() {
+        csFactory = DefaultCoordinateSequenceFactory.instance();
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    public CoordinateSequence transform(final CoordinateSequence sequence,
+        final MathTransform transform) throws TransformException {
+        final int sourceDim = transform.getSourceDimensions();
+        final int targetDim = transform.getTargetDimensions();
+        final int size = sequence.size();
+        final Coordinate[] tcs = new Coordinate[size];
+        final int bufferCapacity = buffer.length / Math.max(sourceDim, targetDim);
+        int remainingBeforeFlush = Math.min(bufferCapacity, size);
+        int ib = 0; // Index in the buffer array.
+        int it = 0; // Index in the target sequence.
+        
+        // create a target CS so that the dimensions not contemplated in the source CS  
+        // are copied over (think Z or M with a 2d CRS)
+        int targetCSDim = targetDim + (sequence.getDimension() - sourceDim);
+		CoordinateSequence result =  csFactory.create(sequence.size(), targetCSDim);
+
+        for (int i = 0; i < size; i++) {
+            switch (sourceDim) {
+            default:
+                throw new MismatchedDimensionException();
+
+            case 3:
+                buffer[ib + 2] = sequence.getOrdinate(i, 2); // Fall through
+
+            case 2:
+                buffer[ib + 1] = sequence.getY(i); // Fall through
+
+            case 1:
+                buffer[ib] = sequence.getX(i); // Fall through
+
+            case 0:
+                break;
+            }
+
+            ib += sourceDim;
+
+            if (--remainingBeforeFlush == 0) {
+                /*
+                 * The buffer is full, or we just copied the last coordinates.
+                 * Transform the coordinates and flush to the destination array.
+                 */
+                assert (ib % sourceDim) == 0;
+
+                final int n = ib / sourceDim;
+                transform.transform(buffer, 0, buffer, 0, n);
+                ib = 0;
+
+                for (int j = 0; j < n; j++) {
+                    
+                    // copy the transformed portion
+                    int oi = 0;
+                    for (; oi < targetDim; oi++) {
+                        result.setOrdinate(it, oi, buffer[ib++]);   
+                    }
+                    // copy over the non transformed portion
+                    for (; oi < targetCSDim; oi++) {
+                        result.setOrdinate(it, oi, sequence.getOrdinate(it, oi + (targetDim - sourceDim)));   
+                    }
+                    // force to NaN eventual extra ordinates the sequence has (some are fixed size, wont'
+                    // care about us trying to tell them a size). This works around a bug in the default
+                    // JTS coordinate sequence implementation
+                    for (; oi < result.getDimension(); oi++) {
+                        result.setOrdinate(it, oi, Double.NaN);   
+                    }
+                    it++;
+                }
+                assert ib == (n * targetDim);
+                ib = 0;
+                remainingBeforeFlush = Math.min(bufferCapacity, size - (i + 1));
+            }
+        }
+        assert it == tcs.length : tcs.length - it;
+
+        return result;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/GeometryCoordinateSequenceTransformer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/GeometryCoordinateSequenceTransformer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/GeometryCoordinateSequenceTransformer.java	(revision 28000)
@@ -0,0 +1,188 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.geometry.jts;
+
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.MultiLineString;
+import com.vividsolutions.jts.geom.MultiPoint;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+
+
+/**
+ * Service object that takes a geometry an applies a MathTransform on top
+ * of it.
+ * @author Andrea Aime
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/geometry/jts/GeometryCoordinateSequenceTransformer.java $
+ */
+public class GeometryCoordinateSequenceTransformer {
+    private MathTransform transform;
+    private CoordinateSequenceTransformer csTransformer;
+    private CoordinateReferenceSystem crs;
+    
+    public GeometryCoordinateSequenceTransformer() {
+        csTransformer = new DefaultCoordinateSequenceTransformer();
+    }
+
+    /**
+     * Sets the math transform to be used for transformation
+     * @param transform
+     */
+    public void setMathTransform(MathTransform transform) {
+        this.transform = transform;
+    }
+    
+    /**
+     * Applies the transform to the provided geometry, given
+     * @param g
+     * @throws TransformException
+     */
+    public Geometry transform(Geometry g) throws TransformException {
+        GeometryFactory factory = g.getFactory();
+        Geometry transformed = null;
+        
+        if (g instanceof Point) {
+            transformed = transformPoint((Point) g, factory);
+        } else if (g instanceof MultiPoint) {
+            MultiPoint mp = (MultiPoint) g;
+            Point[] points = new Point[mp.getNumGeometries()];
+
+            for (int i = 0; i < points.length; i++) {
+                points[i] = transformPoint((Point) mp.getGeometryN(i), factory);
+            }
+
+            transformed = factory.createMultiPoint(points);
+        } else if (g instanceof LineString) {
+            transformed = transformLineString((LineString) g, factory);
+        } else if (g instanceof MultiLineString) {
+            MultiLineString mls = (MultiLineString) g;
+            LineString[] lines = new LineString[mls.getNumGeometries()];
+
+            for (int i = 0; i < lines.length; i++) {
+                lines[i] = transformLineString((LineString) mls.getGeometryN(i), factory);
+            }
+
+            transformed = factory.createMultiLineString(lines);
+        } else if (g instanceof Polygon) {
+            transformed = transformPolygon((Polygon) g, factory);
+        } else if (g instanceof MultiPolygon) {
+            MultiPolygon mp = (MultiPolygon) g;
+            Polygon[] polygons = new Polygon[mp.getNumGeometries()];
+
+            for (int i = 0; i < polygons.length; i++) {
+                polygons[i] = transformPolygon((Polygon) mp.getGeometryN(i), factory);
+            }
+
+            transformed = factory.createMultiPolygon(polygons);
+        } else if (g instanceof GeometryCollection) {
+            GeometryCollection gc = (GeometryCollection) g;
+            Geometry[] geoms = new Geometry[gc.getNumGeometries()];
+
+            for (int i = 0; i < geoms.length; i++) {
+                geoms[i] = transform(gc.getGeometryN(i));
+            }
+
+            transformed = factory.createGeometryCollection(geoms);
+        } else {
+            throw new IllegalArgumentException("Unsupported geometry type " + g.getClass());
+        }
+        
+        //copy over user data, do a special check for coordinate reference 
+        // systme
+        transformed.setUserData(g.getUserData());
+
+        if ((g.getUserData() == null) || g.getUserData() instanceof CoordinateReferenceSystem) {
+            //set the new one to be the target crs
+            if (crs != null) {
+                transformed.setUserData(crs);
+            }
+        }
+        
+        return transformed;
+    }
+
+    /**
+     *
+     * @throws TransformException
+     */
+    public LineString transformLineString(LineString ls, GeometryFactory gf)
+        throws TransformException {
+        CoordinateSequence cs = projectCoordinateSequence(ls.getCoordinateSequence());
+        LineString transformed = null;
+        
+        if (ls instanceof LinearRing) {
+            transformed = gf.createLinearRing(cs);
+        } else {
+            transformed = gf.createLineString(cs);
+        }
+        
+        transformed.setUserData( ls.getUserData() );
+        return transformed;
+    }
+
+    /**
+     * @param point
+     *
+     * @throws TransformException
+     */
+    public Point transformPoint(Point point, GeometryFactory gf)
+        throws TransformException {
+        CoordinateSequence cs = projectCoordinateSequence(point.getCoordinateSequence());
+        Point transformed = gf.createPoint(cs);
+        transformed.setUserData( point.getUserData() );
+        return transformed; 
+    }
+
+    /**
+     * @param cs a CoordinateSequence
+     *
+     * @throws TransformException
+     */
+    public CoordinateSequence projectCoordinateSequence(CoordinateSequence cs)
+        throws TransformException {
+        return csTransformer.transform(cs, transform);
+    }
+
+    /**
+     * @param polygon
+     * @throws TransformException
+     */
+    public Polygon transformPolygon(Polygon polygon, GeometryFactory gf)
+        throws TransformException {
+        LinearRing exterior = (LinearRing) transformLineString(polygon.getExteriorRing(), gf);
+        LinearRing[] interiors = new LinearRing[polygon.getNumInteriorRing()];
+
+        for (int i = 0; i < interiors.length; i++) {
+            interiors[i] = (LinearRing) transformLineString(polygon.getInteriorRingN(i), gf);
+        }
+
+        Polygon transformed = gf.createPolygon(exterior, interiors);
+        transformed.setUserData( polygon.getUserData() );
+        return transformed;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/JTS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/JTS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/JTS.java	(revision 28000)
@@ -0,0 +1,71 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.geometry.jts;
+
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+
+/**
+ * JTS Geometry utility methods, bringing Geotools to JTS.
+ * <p>
+ * Offers geotools based services such as reprojection.
+ * <p>
+ * Responsibilities:
+ * <ul>
+ *   <li>transformation</li>
+ *   <li>coordinate sequence editing</li>
+ *   <li>common coordinate sequence implementations for specific uses</li>
+ * </ul>
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/geometry/jts/JTS.java $
+ * @version $Id: JTS.java 37744 2011-07-29 08:59:05Z mbedward $
+ * @author Jody Garnett
+ * @author Martin Desruisseaux
+ * @author Simone Giannecchini, GeoSolutions.
+ */
+public final class JTS {
+
+    /**
+     * Do not allow instantiation of this class.
+     */
+    private JTS() {
+    }
+
+    /**
+     * Transforms the geometry using the default transformer.
+     *
+     * @param  geom The geom to transform
+     * @param  transform the transform to use during the transformation.
+     * @return the transformed geometry.  It will be a new geometry.
+     * @throws MismatchedDimensionException if the geometry doesn't have the expected dimension
+     *         for the specified transform.
+     * @throws TransformException if a point can't be transformed.
+     */
+    public static Geometry transform(final Geometry geom, final MathTransform transform)
+        throws MismatchedDimensionException, TransformException {
+        final GeometryCoordinateSequenceTransformer transformer = new GeometryCoordinateSequenceTransformer();
+        transformer.setMathTransform(transform);
+
+        return transformer.transform(geom);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/ReferencedEnvelope.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/ReferencedEnvelope.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/ReferencedEnvelope.java	(revision 28000)
@@ -0,0 +1,530 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.geometry.jts;
+
+import org.geotools.referencing.CRS;
+import org.geotools.resources.Classes;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.opengis.geometry.BoundingBox;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.geometry.MismatchedReferenceSystemException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * A JTS envelope associated with a
+ * {@linkplain CoordinateReferenceSystem coordinate reference system}. In
+ * addition, this JTS envelope also implements the GeoAPI
+ * {@linkplain org.opengis.geometry.coordinate.Envelope envelope} interface
+ * for interoperability with GeoAPI.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/geometry/jts/ReferencedEnvelope.java $
+ * @version $Id: ReferencedEnvelope.java 38435 2011-12-20 08:11:41Z aaime $
+ * @author Jody Garnett
+ * @author Martin Desruisseaux
+ * @author Simone Giannecchini
+ *
+ * @see org.geotools.geometry.Envelope2D
+ * @see org.geotools.geometry.GeneralEnvelope
+ * @see org.opengis.metadata.extent.GeographicBoundingBox
+ */
+public class ReferencedEnvelope extends Envelope implements BoundingBox {
+    
+    /** A ReferencedEnvelope containing "everything" */
+    public static ReferencedEnvelope EVERYTHING = new ReferencedEnvelope(Double.NEGATIVE_INFINITY,
+            Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, null) {
+        private static final long serialVersionUID = -3188702602373537164L;
+
+        public boolean contains(BoundingBox bbox) {
+            return true;
+        }
+
+        public boolean contains(Coordinate p) {
+            return true;
+        }
+
+        public boolean contains(DirectPosition pos) {
+            return true;
+        }
+
+        public boolean contains(double x, double y) {
+            return true;
+        }
+
+        public boolean contains(Envelope other) {
+            return true;
+        }
+
+        public boolean isEmpty() {
+            return false;
+        }
+
+        public boolean isNull() {
+            return true;
+        }
+        
+        public double getArea() {
+            //return super.getArea();
+            return Double.POSITIVE_INFINITY;
+        }
+        
+        public void setBounds(BoundingBox arg0) {
+            throw new IllegalStateException("Cannot modify ReferencedEnvelope.EVERYTHING");
+        }
+        public Coordinate centre() {
+            return new Coordinate();
+        }
+        public void setToNull() {
+            // um ignore this as we are already "null"
+        }
+        public boolean equals(Object obj) {
+            if( obj == EVERYTHING ){
+                return true;
+            }
+            if( obj instanceof ReferencedEnvelope ){
+                ReferencedEnvelope other = (ReferencedEnvelope) obj;
+                if( other.crs != EVERYTHING.crs ) return false;
+                if( other.getMinX() != EVERYTHING.getMinX() ) return false;
+                if( other.getMinY() != EVERYTHING.getMinY() ) return false;
+                if( other.getMaxX() != EVERYTHING.getMaxX() ) return false;
+                if( other.getMaxY() != EVERYTHING.getMaxY() ) return false;
+                
+                return true;
+            }
+            return super.equals(obj);
+        }
+        
+        public String toString() {
+            return "ReferencedEnvelope.EVERYTHING";
+        }
+    };
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = -3188702602373537163L;
+
+    /**
+     * The coordinate reference system, or {@code null}.
+     */
+    private CoordinateReferenceSystem crs;
+
+    /**
+     * Creates a null envelope with a null coordinate reference system.
+     */
+    public ReferencedEnvelope() {
+        this((CoordinateReferenceSystem) null);
+    }
+
+    /**
+     * Creates a null envelope with the specified coordinate reference system.
+     *
+     * @param crs The coordinate reference system.
+     * @throws MismatchedDimensionException if the CRS dimension is not valid.
+     */
+    public ReferencedEnvelope(CoordinateReferenceSystem crs)
+        throws MismatchedDimensionException {
+        this.crs = crs;
+        checkCoordinateReferenceSystemDimension();
+    }
+
+    /**
+     * Creates an envelope for a region defined by maximum and minimum values.
+     *
+     * @param x1  The first x-value.
+     * @param x2  The second x-value.
+     * @param y1  The first y-value.
+     * @param y2  The second y-value.
+     * @param crs The coordinate reference system.
+     *
+     * @throws MismatchedDimensionException if the CRS dimension is not valid.
+     */
+    public ReferencedEnvelope(final double x1, final double x2, final double y1, final double y2,
+        final CoordinateReferenceSystem crs) throws MismatchedDimensionException {
+        super(x1, x2, y1, y2);
+        this.crs = crs;
+        checkCoordinateReferenceSystemDimension();
+    }
+
+    /**
+     * Creates a new envelope from an existing bounding box.
+     *
+     * @param bbox The bounding box to initialize from.
+     * @throws MismatchedDimensionException if the CRS dimension is not valid.
+     *
+     * @since 2.4
+     */
+    public ReferencedEnvelope(final BoundingBox bbox) throws MismatchedDimensionException {
+        this(bbox.getMinX(), bbox.getMaxX(), bbox.getMinY(), bbox.getMaxY(),
+            bbox.getCoordinateReferenceSystem());
+    }
+
+    /**
+     * Creates a new envelope from an existing JTS envelope.
+     *
+     * @param envelope The envelope to initialize from.
+     * @param crs The coordinate reference system.
+     * @throws MismatchedDimensionExceptionif the CRS dimension is not valid.
+     */
+    public ReferencedEnvelope(final Envelope envelope, final CoordinateReferenceSystem crs)
+        throws MismatchedDimensionException {
+        super(envelope);
+        this.crs = crs;
+        checkCoordinateReferenceSystemDimension();
+    }
+
+    /**
+     * Sets this envelope to the specified bounding box.
+     */
+    public void init(BoundingBox bounds) {
+        super.init(bounds.getMinimum(0), bounds.getMaximum(0), bounds.getMinimum(1),
+            bounds.getMaximum(1));
+        this.crs = bounds.getCoordinateReferenceSystem();
+    }
+
+    /**
+     * Returns the specified bounding box as a JTS envelope.
+     */
+    private static Envelope getJTSEnvelope(final BoundingBox bbox) {
+        if( bbox == null ){
+            throw new NullPointerException("Provided bbox envelope was null");
+        }
+        if (bbox instanceof Envelope) {
+            return (Envelope) bbox;
+        }        
+        return new ReferencedEnvelope(bbox);
+    }
+
+    /**
+     * Convenience method for checking coordinate reference system validity.
+     *
+     * @throws IllegalArgumentException if the CRS dimension is not valid.
+     */
+    private void checkCoordinateReferenceSystemDimension()
+        throws MismatchedDimensionException {
+        if (crs != null) {
+            final int expected = getDimension();
+            final int dimension = crs.getCoordinateSystem().getDimension();
+            if (dimension != expected) {
+                throw new MismatchedDimensionException(Errors.format(
+                        ErrorKeys.MISMATCHED_DIMENSION_$3, crs.getName().getCode(),
+                        new Integer(dimension), new Integer(expected)));
+            }
+        }
+    }
+
+    /**
+     * Make sure that the specified bounding box uses the same CRS than this one.
+     * 
+     * @param  bbox The other bounding box to test for compatibility.
+     * @throws MismatchedReferenceSystemException if the CRS are incompatibles.
+     */
+    private void ensureCompatibleReferenceSystem(final BoundingBox bbox)
+        throws MismatchedReferenceSystemException {
+        if (crs != null) {
+            final CoordinateReferenceSystem other = bbox.getCoordinateReferenceSystem();
+            if (other != null) {
+                if (!CRS.equalsIgnoreMetadata(crs, other)) {
+                    throw new MismatchedReferenceSystemException(Errors.format(
+                            ErrorKeys.MISMATCHED_COORDINATE_REFERENCE_SYSTEM));
+                }
+            }
+        }
+    }
+    
+    /**
+     * Returns the coordinate reference system associated with this envelope.
+     */
+    public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+        return crs;
+    }
+
+    /**
+     * Returns the number of dimensions.
+     */
+    public int getDimension() {
+        return 2;
+    }
+
+    /**
+     * Returns the minimal ordinate along the specified dimension.
+     */
+    public double getMinimum(final int dimension) {
+        switch (dimension) {
+        case 0:
+            return getMinX();
+
+        case 1:
+            return getMinY();
+
+        default:
+            throw new IndexOutOfBoundsException(String.valueOf(dimension));
+        }
+    }
+
+    /**
+     * Returns the maximal ordinate along the specified dimension.
+     */
+    public double getMaximum(final int dimension) {
+        switch (dimension) {
+        case 0:
+            return getMaxX();
+
+        case 1:
+            return getMaxY();
+
+        default:
+            throw new IndexOutOfBoundsException(String.valueOf(dimension));
+        }
+    }
+
+    /**
+     * @deprecated Use {@link #getMedian}.
+     */
+    public double getCenter(final int dimension) {
+        return getMedian(dimension);
+    }
+
+    /**
+     * Returns the center ordinate along the specified dimension.
+     */
+    public double getMedian(final int dimension) {
+        switch (dimension) {
+        case 0:
+            return 0.5 * (getMinX() + getMaxX());
+
+        case 1:
+            return 0.5 * (getMinY() + getMaxY());
+
+        default:
+            throw new IndexOutOfBoundsException(String.valueOf(dimension));
+        }
+    }
+
+    /**
+     * @deprecated Use {@link #getSpan}.
+     */
+    public double getLength(final int dimension) {
+        return getSpan(dimension);
+    }
+
+    /**
+     * Returns the envelope length along the specified dimension. This length is
+     * equals to the maximum ordinate minus the minimal ordinate.
+     */
+    public double getSpan(final int dimension) {
+        switch (dimension) {
+        case 0:
+            return getWidth();
+
+        case 1:
+            return getHeight();
+
+        default:
+            throw new IndexOutOfBoundsException(String.valueOf(dimension));
+        }
+    }
+
+    /**
+     * Returns {@code true} if lengths along all dimension are zero.
+     *
+     * @since 2.4
+     */
+    public boolean isEmpty() {
+        return super.isNull();
+    }
+
+    /**
+     * Returns {@code true} if the provided location is contained by this bounding box.
+     *
+     * @since 2.4
+     */
+    public boolean contains(DirectPosition pos) {
+        return super.contains(pos.getOrdinate(0), pos.getOrdinate(1));
+    }
+
+    /**
+     * Returns {@code true} if the provided bounds are contained by this bounding box.
+     *
+     * @since 2.4
+     */
+    public boolean contains(final BoundingBox bbox) {
+        ensureCompatibleReferenceSystem(bbox);
+
+        return super.contains(getJTSEnvelope(bbox));
+    }
+
+    /**
+     * Check if this bounding box intersects the provided bounds.
+     */    
+    @Override
+    public Envelope intersection(Envelope env) {
+        if( env instanceof BoundingBox ){
+            BoundingBox bbox = (BoundingBox) env;
+            ensureCompatibleReferenceSystem( bbox );
+        }
+        return super.intersection(env);
+    }    
+    /**
+     * Include the provided bounding box, expanding as necessary.
+     *
+     * @since 2.4
+     */
+    public void include(final BoundingBox bbox) {
+        if( crs == null ){
+            this.crs = bbox.getCoordinateReferenceSystem();
+        }
+        else {
+            ensureCompatibleReferenceSystem(bbox);
+        }
+        super.expandToInclude(getJTSEnvelope(bbox));        
+    }
+
+    /**
+     * Include the provided envelope, expanding as necessary.
+     */
+    @Override
+    public void expandToInclude(Envelope other) {
+        if( other instanceof BoundingBox ){
+            BoundingBox bbox = (BoundingBox) other;
+            ensureCompatibleReferenceSystem( bbox );
+        }
+        super.expandToInclude(other);
+    }
+    
+    /**
+     * Include the provided coordinates, expanding as necessary.
+     *
+     * @since 2.4
+     */
+    public void include(double x, double y) {
+        super.expandToInclude(x, y);
+    }
+
+    /**
+     * Initialize the bounding box with another bounding box.
+     *
+     * @since 2.4
+     */
+    public void setBounds(final BoundingBox bbox) {
+        ensureCompatibleReferenceSystem(bbox);
+        super.init(getJTSEnvelope(bbox));
+    }
+
+    /**
+     * Returns a hash value for this envelope. This value need not remain
+     * consistent between different implementations of the same class.
+     */
+    @Override
+    public int hashCode() {
+        int code = super.hashCode() ^ (int) serialVersionUID;
+        if (crs != null) {
+            code ^= crs.hashCode();
+        }
+        return code;
+    }
+
+    /**
+     * Compares the specified object with this envelope for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (super.equals(object)) {
+            final CoordinateReferenceSystem otherCRS = (object instanceof ReferencedEnvelope)
+                ? ((ReferencedEnvelope) object).crs : null;
+
+            if(otherCRS == null) {
+                return crs == null;
+            } else {
+                return CRS.equalsIgnoreMetadata(crs, otherCRS);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a string representation of this envelope. The default implementation
+     * is okay for occasional formatting (for example for debugging purpose).
+     */
+    @Override
+    public String toString() {
+        final StringBuilder buffer = new StringBuilder(Classes.getShortClassName(this)).append('[');
+        final int dimension = getDimension();
+
+        for (int i = 0; i < dimension; i++) {
+            if (i != 0) {
+                buffer.append(", ");
+            }
+
+            buffer.append(getMinimum(i)).append(" : ").append(getMaximum(i));
+        }
+
+        return buffer.append(']').toString();
+    }
+    
+    /**
+     * Utility method to ensure that an Envelope if a ReferencedEnvelope.
+     * <p>
+     * This method first checks if <tt>e</tt> is an instanceof {@link ReferencedEnvelope},
+     * if it is, itself is returned. If not <code>new ReferencedEnvelpe(e,null)</code>
+     * is returned.
+     * </p>
+     * <p>
+     * If e is null, null is returned.
+     * </p>
+     * @param e The envelope.  Can be null.
+     * @return A ReferencedEnvelope using the specified envelope, or null if the envelope was null.
+     */
+    public static ReferencedEnvelope reference(Envelope e) {
+        if (e == null) {
+            return null;
+        } else {
+            if (e instanceof ReferencedEnvelope) {
+                return (ReferencedEnvelope) e;
+            }
+
+            return new ReferencedEnvelope(e, null);
+        }
+    }
+
+    /**
+     * Utility method to ensure that an BoundingBox in a ReferencedEnvelope.
+     * <p>
+     * This method first checks if <tt>e</tt> is an instanceof {@link ReferencedEnvelope},
+     * if it is, itself is returned. If not <code>new ReferencedEnvelpe(e)</code>
+     * is returned.
+     * </p>
+     * @param e The envelope.
+     * @return
+     */
+    public static ReferencedEnvelope reference(BoundingBox e) {
+        if (e == null) {
+            return null;
+        }
+
+        if (e instanceof ReferencedEnvelope) {
+            return (ReferencedEnvelope) e;
+        }
+
+        return new ReferencedEnvelope(e);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/coordinatesequence/CoordinateSequences.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/coordinatesequence/CoordinateSequences.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/jts/coordinatesequence/CoordinateSequences.java	(revision 28000)
@@ -0,0 +1,127 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    Created on 31-dic-2004
+ */
+package org.geotools.geometry.jts.coordinatesequence;
+
+import com.vividsolutions.jts.algorithm.RobustDeterminant;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+
+/**
+ * Utility functions for coordinate sequences (extends the same named JTS class)
+ * @author Andrea Aime - OpenGeo
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/build/maven/javadoc/../../../modules/library/main/src/main/java/org/geotools/geometry/jts/coordinatesequence/CoordinateSequences.java $
+ */
+public class CoordinateSequences extends com.vividsolutions.jts.geom.CoordinateSequences {
+    
+    /**
+     * Computes whether a ring defined by an array of {@link Coordinate}s is
+     * oriented counter-clockwise.
+     * <ul>
+     * <li>The list of points is assumed to have the first and last points equal.
+     * <li>This will handle coordinate lists which contain repeated points.
+     * </ul>
+     * This algorithm is <b>only</b> guaranteed to work with valid rings.
+     * If the ring is invalid (e.g. self-crosses or touches),
+     * the computed result may not be correct.
+     *
+     * @param ring an array of Coordinates forming a ring
+     * @return true if the ring is oriented counter-clockwise.
+     */
+    public static boolean isCCW(CoordinateSequence ring) {
+      // # of points without closing endpoint
+      int nPts = ring.size() - 1;
+
+      // find highest point
+      double hiy = ring.getOrdinate(0, 1);
+      int hiIndex = 0;
+      for (int i = 1; i <= nPts; i++) {
+        if (ring.getOrdinate(i, 1) > hiy) {
+          hiy = ring.getOrdinate(i, 1);
+          hiIndex = i;
+        }
+      }
+
+      // find distinct point before highest point
+      int iPrev = hiIndex;
+      do {
+        iPrev = iPrev - 1;
+        if (iPrev < 0) iPrev = nPts;
+      } while (equals2D(ring, iPrev, hiIndex) && iPrev != hiIndex);
+
+      // find distinct point after highest point
+      int iNext = hiIndex;
+      do {
+        iNext = (iNext + 1) % nPts;
+      } while (equals2D(ring, iNext, hiIndex) && iNext != hiIndex);
+
+     /**
+       * This check catches cases where the ring contains an A-B-A configuration of points.
+       * This can happen if the ring does not contain 3 distinct points
+       * (including the case where the input array has fewer than 4 elements),
+       * or it contains coincident line segments.
+       */
+      if (equals2D(ring, iPrev, hiIndex) || equals2D(ring, iNext, hiIndex)|| equals2D(ring, iPrev, iNext))
+        return false;
+
+      int disc = computeOrientation(ring, iPrev, hiIndex, iNext);
+
+      /**
+       *  If disc is exactly 0, lines are collinear.  There are two possible cases:
+       *  (1) the lines lie along the x axis in opposite directions
+       *  (2) the lines lie on top of one another
+       *
+       *  (1) is handled by checking if next is left of prev ==> CCW
+       *  (2) will never happen if the ring is valid, so don't check for it
+       *  (Might want to assert this)
+       */
+      boolean isCCW = false;
+      if (disc == 0) {
+        // poly is CCW if prev x is right of next x
+        isCCW = (ring.getOrdinate(iPrev, 0) > ring.getOrdinate(iNext, 0));
+      } else {
+        // if area is positive, points are ordered CCW
+        isCCW = (disc > 0);
+      }
+      return isCCW;
+    }
+    
+    private static boolean equals2D(CoordinateSequence cs, int i, int j) {
+        return cs.getOrdinate(i, 0) ==  cs.getOrdinate(j, 0) &&
+               cs.getOrdinate(i, 1) ==  cs.getOrdinate(j, 1); 
+    }
+    
+    public static int computeOrientation(CoordinateSequence cs, int p1, int p2, int q) {
+        // travelling along p1->p2, turn counter clockwise to get to q return 1,
+        // travelling along p1->p2, turn clockwise to get to q return -1,
+        // p1, p2 and q are colinear return 0.
+        double p1x = cs.getOrdinate(p1, 0);
+        double p1y = cs.getOrdinate(p1, 1);
+        double p2x = cs.getOrdinate(p2, 0);
+        double p2y = cs.getOrdinate(p2, 1);
+        double qx = cs.getOrdinate(q, 0);
+        double qy = cs.getOrdinate(q, 1);
+        double dx1 = p2x - p1x;
+        double dy1 = p2y - p1y;
+        double dx2 = qx - p2x;
+        double dy2 = qy - p2y;
+        return RobustDeterminant.signOfDet2x2(dx1, dy1, dx2, dy2);
+      }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/geometry/package.html	(revision 28000)
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.geometry</TITLE>
+  </HEAD>
+  <BODY>
+  {@linkplain org.geotools.geometry.Geometry} implementation. An explanation for this
+  package is provided in the {@linkplain org.opengis.spatialschema.geometry OpenGIS&reg;
+  javadoc}. The remaining discussion on this page is specific to the Geotools implementation.
+
+  <P ALIGN="justify">The {@link org.geotools.geometry.GeneralDirectPosition} class represents a
+  point in a multi-dimensional space. This space may have an arbitrary number of dimensions. For
+  a two-dimensional space, <CODE>DirectPosition</CODE> is conceptually equivalent to
+  {@link java.awt.geom.Point2D}.</P>
+
+  <P ALIGN="justify">The class {@link org.geotools.geometry.GeneralEnvelope} represents a box in
+  a multi-dimensional space. For a two-dimensional space, <CODE>Envelope</CODE> is conceptually
+  equivalent to {@link java.awt.geom.Rectangle2D}.</P>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/index/CachedQuadTree.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/index/CachedQuadTree.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/index/CachedQuadTree.java	(revision 28000)
@@ -0,0 +1,236 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+
+package org.geotools.index;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.NoSuchElementException;
+
+import org.geotools.data.shapefile.shp.IndexFile;
+import org.geotools.index.quadtree.Node;
+import org.geotools.index.quadtree.QuadTree;
+import org.geotools.index.quadtree.StoreException;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * An experimental QIX in memory index cache. It loads the tree into a packed
+ * memory structure that 
+ * @author Andrea Aime - OpenGeo
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/build/maven/javadoc/../../../modules/plugin/shapefile/src/main/java/org/geotools/index/CachedQuadTree.java $
+ */
+public class CachedQuadTree {
+    static final DataDefinition DATA_DEFINITION = new DataDefinition("US-ASCII");
+    static {
+        DATA_DEFINITION.addField(Integer.class);
+        DATA_DEFINITION.addField(Long.class);
+    };
+    
+    MemoryNode root;
+    Indices offsets;
+    
+    public CachedQuadTree(QuadTree tree) throws IOException {
+    	offsets = new Indices();
+        this.root = cloneAndTranslate(tree.getRoot(), tree.getIndexfile());
+    }
+    
+    public Envelope getBounds() {
+        return new Envelope(root.minx, root.maxx, root.miny, root.maxy);
+    }
+
+    private MemoryNode cloneAndTranslate(Node node, IndexFile indexfile) throws IOException {
+    	// copy the shape ids and clean up
+    	node.pack();
+        int[] shapeIds = node.getShapesId();
+        int start = -1;
+        int end = -1;
+        if(shapeIds != null && shapeIds.length > 0) {
+        	start = offsets.size();
+            // turn the shape ids into offsets so that we won't need to open the index file anymore
+            for (int i = 0; i < shapeIds.length; i++) {
+                offsets.add(indexfile.getOffsetInBytes(shapeIds[i]));
+            }
+            end = offsets.size();
+        }
+        node.clean();
+        
+        // recurse and then clean up the subnodes as well
+        MemoryNode mem = new MemoryNode(node.getBounds(), start, end, node.getNumSubNodes());
+        for (int i = 0; i < node.getNumSubNodes(); i++) {
+            mem.subnodes[i] =  cloneAndTranslate(node.getSubNode(i), indexfile);
+        }
+        node.clearSubNodes();
+        
+        return mem;
+    }
+    
+
+    public CloseableIterator<Data> search(final Envelope bounds) throws StoreException {
+        final Indices indices = new Indices();
+        collectIndices(indices, root, bounds);
+        indices.sort();
+        final Data data = new Data(DATA_DEFINITION);
+        return new CloseableIterator<Data>() {
+            boolean read = true;
+            int idx = 0;
+
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+            
+            public Data next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
+                
+                read = true;
+                return data;
+            }
+            
+            public boolean hasNext() {
+                if(!read) {
+                    return true;
+                }
+                
+                if(idx >= indices.size()) {
+                    return false;
+                }
+                
+                try {
+                  data.clear();
+                  data.addValue(0);
+                  data.addValue((long) indices.get(idx));
+                  idx++;
+                  read = false;
+                } catch(Exception e) {
+                    throw new RuntimeException(e);
+                }
+                
+                return true;
+            }
+            
+            public void close() throws IOException {
+                indices.clear();
+            }
+        };
+    }
+    
+    void collectIndices(Indices indices, MemoryNode node, Envelope bounds) throws StoreException {
+        if(!node.intersects(bounds)) {
+            return;
+        }
+        
+        if(node.start > -1 && node.end >= node.start) {
+        	for(int i = node.start; i < node.end; i++) {
+        		indices.add(offsets.get(i));
+        	}
+        }
+        
+        for (MemoryNode child : node.subnodes) {
+            collectIndices(indices, child, bounds);
+        }
+    }
+
+    /**
+     * An efficient wrapper around an array of integers
+     */
+    class Indices {
+        /**
+         * The current coordinate
+         */
+        int curr;
+        
+        /**
+         * The ordinates holder
+         */
+        int[] indices;
+        
+        public Indices() {
+            indices = new int[100];
+            curr = -1;
+        }
+        
+        /**
+         * The number of coordinates
+         * @return
+         */
+        int size() {
+            return curr + 1;
+        }
+        
+        /**
+         * Adds a coordinate to this list
+         * @param x
+         * @param y
+         */
+        void add(int index) {
+            curr++;
+            if((curr * 2 + 1) >= indices.length) {
+                int newSize = indices.length * 3 / 2;
+                if(newSize < 10) {
+                    newSize = 10;
+                }
+                int[] resized = new int[newSize];
+                System.arraycopy(indices, 0, resized, 0, indices.length);
+                indices = resized;
+            }
+            indices[curr] = index;
+        }
+        
+        /**
+         * Resets the indices
+         */
+        void clear() {
+            curr = -1;
+        }
+        
+        int get(int position) {
+            return indices[position];
+        }
+        
+        void sort() {
+            Arrays.sort(indices, 0, curr + 1);
+        }
+    }
+
+    static class MemoryNode {
+    	float minx, miny, maxx, maxy;
+    	int start;
+    	int end;
+    	MemoryNode[] subnodes;
+		
+    	public MemoryNode(Envelope envelope, int start, int end, int numSubnodes) {
+			this.minx = (float) envelope.getMinX();
+			this.miny = (float) envelope.getMinY();
+			this.maxx = (float) envelope.getMaxX();
+			this.maxy = (float) envelope.getMaxY();
+			this.start = start;
+			this.end = end;
+			this.subnodes = new MemoryNode[numSubnodes];
+		}
+
+		public boolean intersects(Envelope bounds) {
+			// TODO: optimize this one
+			return new Envelope(minx, maxx, miny, maxy).intersects(bounds);
+		}
+    	
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/index/CloseableIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/index/CloseableIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/index/CloseableIterator.java	(revision 28000)
@@ -0,0 +1,31 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.index;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+/**
+ * An iterator backed by some resource that needs closing when done using
+ * @author Andrea Aime - OpenGeo
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/index/CloseableIterator.java $
+ */
+public interface CloseableIterator<E> extends Iterator<E> {
+
+    public void close() throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/index/Data.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/index/Data.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/index/Data.java	(revision 28000)
@@ -0,0 +1,100 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.index;
+
+import java.util.ArrayList;
+
+/**
+ * Holds values (with associated DataDefinition)
+ * 
+ * @author Tommaso Nolli
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/index/Data.java $
+ */
+public class Data {
+    private DataDefinition def;
+    private ArrayList values;
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @param def
+     */
+    public Data(DataDefinition def) {
+        this.def = def;
+        this.values = new ArrayList(def.getFieldsCount());
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @param val
+     * 
+     * @return - this Data object
+     * 
+     * @throws TreeException
+     */
+    public Data addValue(Object val) throws TreeException {
+        if (this.values.size() == def.getFieldsCount()) {
+            throw new TreeException("Max number of values reached!");
+        }
+
+        int pos = this.values.size();
+
+        if (!val.getClass().equals(def.getField(pos).getFieldClass())) {
+            throw new TreeException("Wrong class type, was expecting "
+                    + def.getField(pos).getFieldClass());
+        }
+
+        this.values.add(val);
+
+        return this;
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @param i
+     * 
+     */
+    public Object getValue(int i) {
+        return this.values.get(i);
+    }
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        StringBuffer ret = new StringBuffer();
+
+        for (int i = 0; i < this.values.size(); i++) {
+            if (i > 0) {
+                ret.append(" - ");
+            }
+
+            ret.append(this.def.getField(i).getFieldClass());
+            ret.append(": ");
+            ret.append(this.values.get(i));
+        }
+
+        return ret.toString();
+    }
+    
+    public void clear() {
+        values.clear();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/index/DataDefinition.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/index/DataDefinition.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/index/DataDefinition.java	(revision 28000)
@@ -0,0 +1,160 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ * 
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.index;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+
+/**
+ * Field definition
+ * 
+ * @author Tommaso Nolli
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/index/DataDefinition.java $
+ */
+public class DataDefinition {
+    private Charset charset;
+    private ArrayList<Field> fields;
+
+    public DataDefinition(String charset) {
+        fields = new ArrayList<Field>();
+        this.charset = Charset.forName(charset);
+    }
+
+    public int getFieldsCount() {
+        return this.fields.size();
+    }
+
+    public Field getField(int i) {
+        return this.fields.get(i);
+    }
+
+    /**
+     * Well known classes
+     * 
+     * <ul>
+     * <li> Short </li>
+     * <li> Integer </li>
+     * <li> Long </li>
+     * <li> Float </li>
+     * <li> Double </li>
+     * <li> Date </li>
+     * </ul>
+     * 
+     * 
+     * @param clazz
+     * 
+     * @throws TreeException
+     *                 DOCUMENT ME!
+     */
+    public void addField(Class clazz) {
+        if (clazz.isAssignableFrom(Short.class)) {
+            this.fields.add(new Field(clazz, 2));
+        } else if (clazz.isAssignableFrom(Integer.class)) {
+            this.fields.add(new Field(clazz, 4));
+        } else if (clazz.isAssignableFrom(Long.class)) {
+            this.fields.add(new Field(clazz, 8));
+        } else if (clazz.isAssignableFrom(Float.class)) {
+            // TODO: Are you sure of 4 bytes?
+            this.fields.add(new Field(clazz, 4));
+        } else if (clazz.isAssignableFrom(Double.class)) {
+            this.fields.add(new Field(clazz, 8));
+        } else {
+            throw new IllegalArgumentException("Unknow len of class " + clazz
+                    + "use addField(int)");
+        }
+    }
+
+    /**
+     * Gets the max len of the data
+     */
+    public int getLen() {
+        int len = 0;
+
+        Field field = null;
+
+        for (int i = 0; i < this.fields.size(); i++) {
+            field = this.fields.get(i);
+            len += field.getLen();
+        }
+
+        return len;
+    }
+
+    /**
+     * Gets the len of this field after the encoding, this method may be
+     * different from getLen() only if exists strings in the definition
+     * 
+     */
+    public int getEncodedLen() {
+        int len = 0;
+
+        Field field = null;
+
+        for (int i = 0; i < this.fields.size(); i++) {
+            field = this.fields.get(i);
+            len += field.getEncodedLen();
+        }
+
+        return len;
+    }
+
+    /**
+     * Inner class for Data fields
+     * 
+     * @author Tommaso Nolli
+     */
+    public class Field {
+        private Class clazz;
+        private int len;
+
+        public Field(Class clazz, int len) {
+            this.clazz = clazz;
+            this.len = len;
+        }
+
+        /**
+         * DOCUMENT ME!
+         * 
+         */
+        public Class getFieldClass() {
+            return clazz;
+        }
+
+        /**
+         * DOCUMENT ME!
+         * 
+         */
+        public int getLen() {
+            return len;
+        }
+
+        /**
+         * DOCUMENT ME!
+         * 
+         */
+        public int getEncodedLen() {
+            int ret = this.len;
+
+            if (this.clazz.equals(String.class)) {
+                ret = (int) charset.newEncoder().maxBytesPerChar() * this.len;
+            }
+
+            return ret;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/index/TreeException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/index/TreeException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/index/TreeException.java	(revision 28000)
@@ -0,0 +1,44 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.index;
+
+import java.io.IOException;
+
+/**
+ * DOCUMENT ME!
+ * 
+ * @author Tommaso Nolli
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/index/TreeException.java $
+ */
+public class TreeException extends IOException {
+
+    private static final long serialVersionUID = 1988241322009839486L;
+
+    public TreeException() {
+        super();
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @param message
+     */
+    public TreeException(String message) {
+        super(message);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/IndexStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/IndexStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/IndexStore.java	(revision 28000)
@@ -0,0 +1,38 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.index.quadtree;
+
+import org.geotools.data.shapefile.shp.IndexFile;
+
+/**
+ * DOCUMENT ME!
+ * 
+ * @author Tommaso Nolli
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/index/quadtree/IndexStore.java $
+ */
+public interface IndexStore {
+
+    /**
+     * Loads a <code>QuadTree</code>
+     * 
+     * @return the loaded <code>QuadTree</code>
+     * 
+     * @throws StoreException
+     */
+    public QuadTree load(IndexFile indexfile, boolean useMemoryMapping) throws StoreException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/LazySearchIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/LazySearchIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/LazySearchIterator.java	(revision 28000)
@@ -0,0 +1,235 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.index.quadtree;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.geotools.data.shapefile.shp.IndexFile;
+import org.geotools.index.CloseableIterator;
+import org.geotools.index.Data;
+import org.geotools.index.DataDefinition;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * Iterator that search the quad tree depth first. 32000 indices are cached at a
+ * time and each time a node is visited the indices are removed from the node so
+ * that the memory footprint is kept small. Note that if other iterators operate
+ * on the same tree then they can interfere with each other.
+ * 
+ * @author Jesse
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/index/quadtree/LazySearchIterator.java $
+ */
+public class LazySearchIterator implements CloseableIterator<Data> {
+    
+    static final DataDefinition DATA_DEFINITION = new DataDefinition("US-ASCII");
+
+    private static final int MAX_INDICES = 32768;
+    static {
+        DATA_DEFINITION.addField(Integer.class);
+        DATA_DEFINITION.addField(Long.class);
+    }
+
+    Data next = null;
+
+    Node current;
+
+    int idIndex = 0;
+
+    private boolean closed;
+
+    private Envelope bounds;
+
+    Iterator data;
+
+    private IndexFile indexfile;
+    
+    ArrayList<Node> parents = new ArrayList<Node>();
+    
+    Indices indices = new Indices();
+
+    QuadTree tree;
+
+    public LazySearchIterator(QuadTree tree, Envelope bounds) {
+        super();
+        this.tree = tree;
+        this.indexfile = tree.getIndexfile();
+        tree.registerIterator(this);
+        this.current = tree.getRoot();
+        this.bounds = bounds;
+        this.closed = false;
+        this.next = null;
+    }
+
+    public boolean hasNext() {
+        if (closed)
+            throw new IllegalStateException("Iterator has been closed!");
+        if (next != null)
+            return true;
+        if (data != null && data.hasNext()) {
+            next = (Data) data.next();
+        } else {
+            data = null;
+            fillCache();
+            if (data != null && data.hasNext())
+                next = (Data) data.next();
+        }
+        return next != null;
+    }
+
+    private void fillCache() {
+        indices.clear();
+        ArrayList dataList = null;
+        try {
+            while (indices.size() < MAX_INDICES && current != null) {
+                if (idIndex < current.getNumShapeIds() && !current.isVisited()
+                        && current.getBounds().intersects(bounds)) {
+                    indices.add(current.getShapeId(idIndex));
+                    idIndex++;
+                } else {
+                    // free the shapes id array of the current node and prepare to move to the next
+                    current.setShapesId(new int[0]);
+                    idIndex = 0;
+                    
+                    boolean foundUnvisited = false;
+                    for (int i = 0; i < current.getNumSubNodes(); i++) {
+                        Node node = current.getSubNode(i);
+                        if (!node.isVisited()
+                                && node.getBounds().intersects(bounds)) {
+                            foundUnvisited = true;
+                            parents.add(current);
+                            current = node;
+                            break;
+                        }
+                    }
+                    if (!foundUnvisited) {
+                        // mark as visited and free the subnodes
+                        current.setVisited(true);
+                        current.clean();
+                        
+                        // move up to parent
+                        if(parents.isEmpty())
+                            current = null;
+                        else
+                            current = parents.remove(parents.size() - 1);
+                    }
+                }
+            }
+            
+            // sort so offset lookup is faster
+            indices.sort();
+            int size = indices.size();
+            dataList = new ArrayList(size);
+            for (int i = 0; i < size; i++) {
+                int recno = indices.get(i);
+                Data data = new Data(DATA_DEFINITION);
+                data.addValue(recno + 1);
+                data.addValue(new Long(indexfile.getOffsetInBytes(recno)));
+                dataList.add(data);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        data = dataList.iterator();
+    }
+
+    public Data next() {
+        if (!hasNext())
+            throw new NoSuchElementException("No more elements available");
+        Data temp = next;
+        next = null;
+        return temp;
+    }
+
+    public void remove() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void close() throws IOException {
+        tree.close(this);
+        tree.close();
+        this.closed = true;
+    }
+
+    /**
+     * An efficient wrapper around an array of integers
+     */
+    class Indices {
+        /**
+         * The current coordinate
+         */
+        int curr;
+        
+        /**
+         * The ordinates holder
+         */
+        int[] indices;
+        
+        public Indices() {
+            indices = new int[100];
+            curr = -1;
+        }
+        
+        /**
+         * The number of coordinates
+         * @return
+         */
+        int size() {
+            return curr + 1;
+        }
+        
+        /**
+         * Adds a coordinate to this list
+         * @param x
+         * @param y
+         */
+        void add(int index) {
+            curr++;
+            if((curr * 2 + 1) >= indices.length) {
+                int newSize = indices.length * 3 / 2;
+                if(newSize < 10) {
+                    newSize = 10;
+                }
+                int[] resized = new int[newSize];
+                System.arraycopy(indices, 0, resized, 0, indices.length);
+                indices = resized;
+            }
+            indices[curr] = index;
+        }
+        
+        /**
+         * Resets the indices
+         */
+        void clear() {
+            curr = -1;
+        }
+        
+        int get(int position) {
+            return indices[position];
+        }
+        
+        void sort() {
+            Arrays.sort(indices, 0, curr + 1);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/Node.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/Node.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/Node.java	(revision 28000)
@@ -0,0 +1,249 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.index.quadtree;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * DOCUMENT ME!
+ * 
+ * @author Tommaso Nolli
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/index/quadtree/Node.java $
+ */
+public class Node {
+    protected int numShapesId;
+    private boolean visited = false;
+    private Envelope bounds;
+    protected int[] shapesId;
+    protected List subNodes;
+
+    public Node(Envelope bounds) {
+        this.bounds = new Envelope(bounds);
+        this.subNodes = new ArrayList(4);
+        this.shapesId = null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @return Returns the bounds.
+     */
+    public Envelope getBounds() {
+        return this.bounds;
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @param bounds
+     *                The bounds to set.
+     */
+    public void setBounds(Envelope bounds) {
+        this.bounds = bounds;
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @return Returns the numSubNodes.
+     */
+    public int getNumSubNodes() {
+        return this.subNodes.size();
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @return Returns the number of records stored.
+     */
+    public int getNumShapeIds() {
+        return this.numShapesId;
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @param node
+     * 
+     * @throws NullPointerException
+     *                 DOCUMENT ME!
+     */
+    public void addSubNode(Node node) {
+        if (node == null) {
+            throw new NullPointerException("Cannot add null to subnodes");
+        }
+
+        this.subNodes.add(node);
+    }
+
+    /**
+     * Removes a subnode
+     * 
+     * @param node
+     *                The subnode to remove
+     * 
+     * @return true if the subnode has been removed
+     */
+    public boolean removeSubNode(Node node) {
+        return this.subNodes.remove(node);
+    }
+
+    /**
+     * 
+     * 
+     */
+    public void clearSubNodes() {
+        this.subNodes.clear();
+    }
+
+    /**
+     * Gets the Node at the requested position
+     * 
+     * @param pos
+     *                The position
+     * 
+     * @return A Node
+     * 
+     * @throws StoreException
+     *                 DOCUMENT ME!
+     */
+    public Node getSubNode(int pos) throws StoreException {
+        return (Node) this.subNodes.get(pos);
+    }
+
+    /**
+     * Add a shape id
+     * 
+     * @param id
+     */
+    public void addShapeId(int id) {
+        if(this.shapesId == null) {
+            this.shapesId = new int[4];
+            Arrays.fill(this.shapesId, -1);
+        } else if (this.shapesId.length == this.numShapesId) {
+            // Increase the array
+            int[] newIds = new int[(int) Math.ceil(this.numShapesId * 3.0 / 2.0)];
+            Arrays.fill(newIds, -1);
+            System.arraycopy(this.shapesId, 0, newIds, 0, this.numShapesId);
+            this.shapesId = newIds;
+        }
+
+        this.shapesId[this.numShapesId] = id;
+        this.numShapesId++;
+    }
+
+    /**
+     * Gets a shape id
+     * 
+     * @param pos
+     *                The position
+     * 
+     * @return The shape id (or recno) at the requested position
+     * 
+     * @throws ArrayIndexOutOfBoundsException
+     *                 DOCUMENT ME!
+     */
+    public int getShapeId(int pos) {
+        if (pos >= this.numShapesId) {
+            throw new ArrayIndexOutOfBoundsException("Requsted " + pos
+                    + " but size = " + this.numShapesId);
+        }
+
+        return this.shapesId[pos];
+    }
+
+    /**
+     * Sets the shape ids
+     * 
+     * @param ids
+     */
+    public void setShapesId(int[] ids) {
+        if (ids == null) {
+            this.numShapesId = 0;
+        } else {
+            this.shapesId = ids;
+            this.numShapesId = 0;
+
+            for (int i = 0; i < ids.length; i++) {
+                if (ids[i] == -1) {
+                    break;
+                }
+
+                this.numShapesId++;
+            }
+        }
+    }
+    
+    /**
+     * DOCUMENT ME!
+     * 
+     * @return Returns the shapesId.
+     */
+    public int[] getShapesId() {
+        return this.shapesId;
+    }
+
+    public boolean isVisited() {
+        return visited;
+    }
+
+    public void setVisited(boolean visited) {
+        this.visited = visited;
+    }
+
+    public Node copy() throws IOException {
+        Node copy = new Node(bounds);
+        copy.setShapesId(shapesId);
+        copy.numShapesId = numShapesId;
+        
+        return copy;
+    }
+
+    /**
+     * Clears up whatever resources the node is hanging onto
+     */
+    public void close() {
+        // TODO Auto-generated method stub
+    }
+    
+    /**
+     * To be used only against in memory nodes, allows to start over on
+     * rebuilding this node
+     */
+    public void clean() {
+        shapesId = null;
+        numShapesId = 0;
+        subNodes.clear();
+    }
+
+    public void pack() {
+        if(numShapesId == 0) {
+            shapesId = null;
+        } else if(shapesId != null && shapesId.length > numShapesId) {
+            int[] ids = new int[numShapesId];
+            System.arraycopy(shapesId, 0, ids, 0, numShapesId);
+            shapesId = ids;
+        }
+        
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/QuadTree.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/QuadTree.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/QuadTree.java	(revision 28000)
@@ -0,0 +1,332 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.index.quadtree;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.data.shapefile.shp.IndexFile;
+import org.geotools.index.CloseableIterator;
+import org.geotools.index.Data;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * Java porting of mapserver quadtree implementation.<br>
+ * <br>
+ * Note that this implementation is <b>not thread safe</b>, so don't share the
+ * same instance across two or more threads.
+ * 
+ * TODO: example of typical use...
+ * 
+ * @author Tommaso Nolli
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/index/quadtree/QuadTree.java $
+ */
+public class QuadTree {
+
+    private static final double SPLITRATIO = 0.55d;
+
+    private static final Logger LOGGER = org.geotools.util.logging.Logging
+            .getLogger("org.geotools.index.quadtree");
+
+    private Node root;
+    private int maxDepth;
+
+    private IndexFile indexfile;
+
+    private Set iterators = new HashSet();
+
+    /**
+     * Constructor.
+     * 
+     * @param numShapes
+     *                The total number of shapes to index
+     * @param maxDepth
+     *                The max depth of the index, must be <= 65535
+     * @param maxBounds
+     *                The bounds of all geometries to be indexed
+     */
+    public QuadTree(int numShapes, int maxDepth, Envelope maxBounds,
+            IndexFile file) {
+        if (maxDepth > 65535) {
+            throw new IllegalArgumentException("maxDepth must be <= 65535");
+        }
+
+        this.maxDepth = maxDepth;
+
+        if (maxBounds != null)
+            this.root = new Node(new Envelope(maxBounds));
+
+        if (maxDepth < 1) {
+            /*
+             * No max depth was defined, try to select a reasonable one that
+             * implies approximately 8 shapes per node.
+             */
+            int numNodes = 1;
+            this.maxDepth = 0;
+
+            while (numNodes * 4 < numShapes) {
+                this.maxDepth += 1;
+                numNodes = numNodes * 2;
+            }
+        }
+        this.indexfile = file;
+    }
+
+    /**
+     * Constructor. WARNING: using this constructor, you have to manually set
+     * the root
+     * 
+     * @param numShapes
+     *                The total number of shapes to index
+     * @param maxDepth
+     *                The max depth of the index, must be <= 65535
+     */
+    public QuadTree(int numShapes, int maxDepth, IndexFile file) {
+        this(numShapes, maxDepth, null, file);
+    }
+
+    /**
+     * Inserts a shape record id in the quadtree
+     * 
+     * @param recno
+     *                The record number
+     * @param bounds
+     *                The bounding box
+     */
+    public void insert(int recno, Envelope bounds) throws StoreException {
+        this.insert(this.root, recno, bounds, this.maxDepth);
+    }
+
+    /**
+     * Inserts a shape record id in the quadtree
+     * 
+     * @param node
+     * @param recno
+     * @param bounds
+     * @param maxDepth
+     * @throws StoreException
+     */
+    public void insert(Node node, int recno, Envelope bounds, int maxDepth)
+            throws StoreException {
+
+        if (maxDepth > 1 && node.getNumSubNodes() > 0) {
+            /*
+             * If there are subnodes, then consider whether this object will fit
+             * in them.
+             */
+            Node subNode = null;
+            for (int i = 0; i < node.getNumSubNodes(); i++) {
+                subNode = node.getSubNode(i);
+                if (subNode.getBounds().contains(bounds)) {
+                    this.insert(subNode, recno, bounds, maxDepth - 1);
+                    return;
+                }
+            }
+        } 
+        if (maxDepth > 1 && node.getNumSubNodes() < 4) {
+            /*
+             * Otherwise, consider creating four subnodes if could fit into
+             * them, and adding to the appropriate subnode.
+             */
+            Envelope half1, half2, quad1, quad2, quad3, quad4;
+
+            Envelope[] tmp = this.splitBounds(node.getBounds());
+            half1 = tmp[0];
+            half2 = tmp[1];
+
+            tmp = this.splitBounds(half1);
+            quad1 = tmp[0];
+            quad2 = tmp[1];
+
+            tmp = this.splitBounds(half2);
+            quad3 = tmp[0];
+            quad4 = tmp[1];
+
+            Node subnode = null;            
+            if (quad1.contains(bounds)) {
+                subnode = new Node(quad1);
+            } else if(quad2.contains(bounds)) {
+                subnode = new Node(quad2);
+            } else if(quad3.contains(bounds)) {
+                subnode = new Node(quad3);
+            } else if(quad4.contains(bounds)) {
+                subnode = new Node(quad4);
+            }
+            
+            if(subnode != null) {
+                node.addSubNode(subnode);
+                this.insert(subnode, recno, bounds, maxDepth - 1);
+                return;
+            }
+        }
+
+        // If none of that worked, just add it to this nodes list.
+        node.addShapeId(recno);
+    }
+
+    /**
+     * 
+     * @param bounds
+     * @return A List of Integer
+     */
+    public CloseableIterator<Data> search(Envelope bounds) throws StoreException {
+        if (LOGGER.isLoggable(Level.FINEST)) {
+            LOGGER.log(Level.FINEST, "Querying " + bounds);
+        }
+
+        try {
+            return new LazySearchIterator(this, bounds);
+        } catch (RuntimeException e) {
+            LOGGER.warning("IOException occurred while reading root");
+            return null;
+        }
+    }
+
+    /**
+     * Closes this QuadTree after use...
+     * 
+     * @throws StoreException
+     */
+    public void close(Iterator iter) throws IOException {
+        iterators.remove(iter);
+    }
+
+    /**
+     * 
+     */
+    public boolean trim() throws StoreException {
+        LOGGER.fine("Trimming the tree...");
+        return this.trim(this.root);
+    }
+
+    /**
+     * Trim subtrees, and free subnodes that come back empty.
+     * 
+     * @param node
+     *                The node to trim
+     * @return true if this node has been trimmed
+     */
+    private boolean trim(Node node) throws StoreException {
+        Node[] dummy = new Node[node.getNumSubNodes()];
+        for (int i = 0; i < node.getNumSubNodes(); i++) {
+            dummy[i] = node.getSubNode(i);
+        }
+
+        for (int i = 0; i < dummy.length; i++) {
+            if (this.trim(dummy[i])) {
+                node.removeSubNode(dummy[i]);
+            }
+        }
+
+        /*
+         * If I have only 1 subnode and no shape records, promote that subnode
+         * to my position.
+         */
+        if (node.getNumSubNodes() == 1 && node.getNumShapeIds() == 0) {
+            Node subNode = node.getSubNode(0);
+
+            node.clearSubNodes();
+            for (int i = 0; i < subNode.getNumSubNodes(); i++) {
+                node.addSubNode(subNode.getSubNode(i));
+            }
+
+            node.setShapesId(subNode.getShapesId());
+            node.setBounds(subNode.getBounds());
+        }
+
+        return (node.getNumSubNodes() == 0 && node.getNumShapeIds() == 0);
+    }
+
+    /**
+     * Splits the specified Envelope
+     * 
+     * @param in
+     *                an Envelope to split
+     * @return an array of 2 Envelopes
+     */
+    private Envelope[] splitBounds(Envelope in) {
+        Envelope[] ret = new Envelope[2];
+        double range, calc;
+
+        if ((in.getMaxX() - in.getMinX()) > (in.getMaxY() - in.getMinY())) {
+            // Split in X direction
+            range = in.getMaxX() - in.getMinX();
+
+            calc = in.getMinX() + range * SPLITRATIO;
+            ret[0] = new Envelope(in.getMinX(), calc, in.getMinY(), in
+                    .getMaxY());
+
+            calc = in.getMaxX() - range * SPLITRATIO;
+            ret[1] = new Envelope(calc, in.getMaxX(), in.getMinY(), in
+                    .getMaxY());
+        } else {
+            // Split in Y direction
+            range = in.getMaxY() - in.getMinY();
+
+            calc = in.getMinY() + range * SPLITRATIO;
+            ret[0] = new Envelope(in.getMinX(), in.getMaxX(), in.getMinY(),
+                    calc);
+
+            calc = in.getMaxY() - range * SPLITRATIO;
+            ret[1] = new Envelope(in.getMinX(), in.getMaxX(), calc, in
+                    .getMaxY());
+        }
+
+        return ret;
+    }
+
+    /**
+     * @return Returns the root.
+     */
+    public Node getRoot() {
+        return this.root;
+    }
+
+    /**
+     * @param root
+     *                The root to set.
+     */
+    public void setRoot(Node root) {
+        this.root = root;
+    }
+
+    public void close() throws StoreException {
+        try {
+            indexfile.close();
+            root.close();
+        } catch (IOException e) {
+            throw new StoreException("error closing indexfile", e.getCause());
+        }
+        if (!iterators.isEmpty()) {
+            throw new StoreException("There are still open iterators!!");
+        }
+    }
+
+    public void registerIterator(Iterator object) {
+        iterators.add(object);
+    }
+
+    public IndexFile getIndexfile() {
+        return indexfile;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/StoreException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/StoreException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/StoreException.java	(revision 28000)
@@ -0,0 +1,49 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.index.quadtree;
+
+import java.io.IOException;
+
+/**
+ * DOCUMENT ME!
+ * 
+ * @author Tommaso Nolli
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/index/quadtree/StoreException.java $
+ */
+public class StoreException extends IOException {
+
+    private static final long serialVersionUID = -3356954193373344773L;
+
+    public StoreException() {
+        super();
+    }
+
+    public StoreException(String message) {
+        super(message);
+    }
+
+    public StoreException(Throwable cause) {
+        super();
+        initCause(cause);
+    }
+
+    public StoreException(String message, Throwable cause) {
+        super(message);
+        initCause(cause);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/fs/FileSystemIndexStore.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/fs/FileSystemIndexStore.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/fs/FileSystemIndexStore.java	(revision 28000)
@@ -0,0 +1,144 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.index.quadtree.fs;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.data.shapefile.shp.IndexFile;
+import org.geotools.index.quadtree.IndexStore;
+import org.geotools.index.quadtree.QuadTree;
+import org.geotools.index.quadtree.StoreException;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * DOCUMENT ME!
+ * 
+ * @author Tommaso Nolli
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/index/quadtree/fs/FileSystemIndexStore.java $
+ */
+public class FileSystemIndexStore implements IndexStore {
+    private static final Logger LOGGER = org.geotools.util.logging.Logging
+            .getLogger("org.geotools.index.quadtree");
+    private File file;
+
+    /**
+     * Constructor. The byte order defaults to NEW_MSB_ORDER
+     * 
+     * @param file
+     */
+    public FileSystemIndexStore(File file) {
+        this.file = file;
+    }
+
+    /**
+     * Loads a quadrtee stored in a '.qix' file. <b>WARNING:</b> The resulting
+     * quadtree will be immutable; if you perform an insert, an
+     * <code>UnsupportedOperationException</code> will be thrown.
+     * 
+     * @see org.geotools.index.quadtree.IndexStore#load()
+     */
+    public QuadTree load(IndexFile indexfile, boolean useMemoryMapping) throws StoreException {
+        QuadTree tree = null;
+
+        try {
+            if (LOGGER.isLoggable(Level.FINEST)) {
+                LOGGER.finest("Opening QuadTree "
+                        + this.file.getCanonicalPath());
+            }
+
+            final FileInputStream fis = new FileInputStream(file);
+            final FileChannel channel = fis.getChannel();
+
+            IndexHeader header = new IndexHeader(channel);
+
+            ByteOrder order = byteToOrder(header.getByteOrder());
+            ByteBuffer buf = ByteBuffer.allocate(8);
+            buf.order(order);
+            channel.read(buf);
+            buf.flip();
+
+            tree = new QuadTree(buf.getInt(), buf.getInt(), indexfile) {
+                public void insert(int recno, Envelope bounds) {
+                    throw new UnsupportedOperationException(
+                            "File quadtrees are immutable");
+                }
+
+                public boolean trim() {
+                    return false;
+                }
+
+                public void close() throws StoreException {
+                    super.close();
+                    try {
+                        channel.close();
+                        fis.close();
+                    } catch (IOException e) {
+                        throw new StoreException(e);
+                    }
+                }
+            };
+
+            tree.setRoot(FileSystemNode.readNode(0, null, channel, order, useMemoryMapping));
+
+            LOGGER.finest("QuadTree opened");
+        } catch (IOException e) {
+            throw new StoreException(e);
+        }
+
+        return tree;
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @param order
+     * 
+     */
+    private static ByteOrder byteToOrder(byte order) {
+        ByteOrder ret = null;
+
+        switch (order) {
+        case IndexHeader.NATIVE_ORDER:
+            ret = ByteOrder.nativeOrder();
+
+            break;
+
+        case IndexHeader.LSB_ORDER:
+        case IndexHeader.NEW_LSB_ORDER:
+            ret = ByteOrder.LITTLE_ENDIAN;
+
+            break;
+
+        case IndexHeader.MSB_ORDER:
+        case IndexHeader.NEW_MSB_ORDER:
+            ret = ByteOrder.BIG_ENDIAN;
+
+            break;
+        }
+
+        return ret;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/fs/FileSystemNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/fs/FileSystemNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/fs/FileSystemNode.java	(revision 28000)
@@ -0,0 +1,319 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.index.quadtree.fs;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
+
+import org.geotools.index.quadtree.Node;
+import org.geotools.index.quadtree.StoreException;
+import org.geotools.resources.NIOUtilities;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * DOCUMENT ME!
+ * 
+ * @author Tommaso Nolli
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/index/quadtree/fs/FileSystemNode.java $
+ */
+public class FileSystemNode extends Node {
+    static final int[] ZERO = new int[0];
+    
+    private ScrollingBuffer buffer;
+    private int subNodeStartByte;
+    private int subNodesLength;
+    private int numSubNodes;
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @param bounds
+     * @param channel
+     *                DOCUMENT ME!
+     * @param order
+     *                DOCUMENT ME!
+     * @param startByte
+     *                DOCUMENT ME!
+     * @param subNodesLength
+     *                DOCUMENT ME!
+     */
+    FileSystemNode(Envelope bounds, ScrollingBuffer buffer, int startByte, int subNodesLength) {
+        super(bounds);
+        this.buffer = buffer;
+        this.subNodeStartByte = startByte;
+        this.subNodesLength = subNodesLength;
+    }
+
+    public Node copy() throws IOException {
+        FileSystemNode copy = new FileSystemNode(getBounds(), buffer, subNodeStartByte, subNodesLength);
+        copy.numShapesId = numShapesId;
+        copy.shapesId = new int[numShapesId];
+        System.arraycopy(shapesId, 0, copy.shapesId, 0, numShapesId);
+        copy.numSubNodes = numSubNodes;
+        return copy;
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @return Returns the numSubNodes.
+     */
+    public int getNumSubNodes() {
+        return this.numSubNodes;
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @param numSubNodes
+     *                The numSubNodes to set.
+     */
+    public void setNumSubNodes(int numSubNodes) {
+        this.numSubNodes = numSubNodes;
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @return Returns the subNodeStartByte.
+     */
+    public int getSubNodeStartByte() {
+        return this.subNodeStartByte;
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @return Returns the subNodesLength.
+     */
+    public int getSubNodesLength() {
+        return this.subNodesLength;
+    }
+
+    /**
+     * @see org.geotools.index.quadtree.Node#getSubNode(int)
+     */
+    public Node getSubNode(int pos) throws StoreException {
+        if (this.subNodes.size() > pos) {
+            return super.getSubNode(pos);
+        }
+
+        try {
+            FileSystemNode subNode = null;
+
+            // Getting prec subNode...
+            int offset = this.subNodeStartByte;
+
+            if (pos > 0) {
+                subNode = (FileSystemNode) getSubNode(pos - 1);
+                offset = subNode.getSubNodeStartByte()
+                        + subNode.getSubNodesLength();
+            }
+
+            buffer.goTo(offset);
+            for (int i = 0, ii = subNodes.size(); i < ((pos + 1) - ii); i++) {
+                subNode = readNode(pos, this, buffer);
+                this.addSubNode(subNode);
+            }
+        } catch (IOException e) {
+            throw new StoreException(e);
+        }
+
+        return super.getSubNode(pos);
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @param channel
+     * @param order
+     *                DOCUMENT ME!
+     * 
+     * 
+     * @throws IOException
+     */
+    public static FileSystemNode readNode(int id, Node parent,
+            FileChannel channel, ByteOrder order, boolean useMemoryMapping) throws IOException {
+        ScrollingBuffer buffer = new ScrollingBuffer(channel, order, useMemoryMapping);
+        return readNode(id, parent, buffer);
+    }
+
+    static FileSystemNode readNode(int id, Node parent, ScrollingBuffer buf)
+            throws IOException {
+        // offset
+        int offset = buf.getInt();
+
+        // envelope
+        Envelope env = buf.getEnvelope();
+
+        // shapes in this node
+        int numShapesId = buf.getInt();
+        int[] ids = null;
+        if(numShapesId > 0) { 
+            ids = new int[numShapesId];
+            buf.getIntArray(ids);
+        } else {
+            ids = ZERO;
+        }
+        int numSubNodes = buf.getInt();
+
+        // let's create the new node
+        FileSystemNode node = new FileSystemNode(env, buf, (int) buf.getPosition(), offset);
+        node.setShapesId(ids);
+        node.setNumSubNodes(numSubNodes);
+
+        return node;
+    }
+    
+    @Override
+    public void close() {
+        if(buffer != null) {
+            buffer.close();
+        }
+        buffer = null;
+    }
+
+    /**
+     * A utility class to access file contents by using a single scrolling
+     * buffer reading file contents with a minimum of 8kb per access
+     */
+    private static class ScrollingBuffer {
+        FileChannel channel;
+        ByteOrder order;
+        ByteBuffer buffer;
+        /** the initial position of the buffer in the channel */
+        long bufferStart;
+        double[] envelope = new double[4];
+        boolean useMemoryMapping;
+
+        public ScrollingBuffer(FileChannel channel, ByteOrder order, boolean useMemoryMapping)
+                throws IOException {
+            this.channel = channel;
+            this.order = order;
+            this.useMemoryMapping = useMemoryMapping;
+            
+            this.bufferStart = channel.position();
+            if(useMemoryMapping) {
+                this.buffer = channel.map(MapMode.READ_ONLY, channel.position(), channel.size() - channel.position());
+                this.buffer.order(order);
+            } else {
+                // start with an 8kb buffer
+                this.buffer = NIOUtilities.allocate(8 * 1024);
+                this.buffer.order(order);
+                channel.read(buffer);
+                buffer.flip();
+            }
+        }
+
+        public void close() {
+            if(buffer != null) {
+                NIOUtilities.clean(buffer, useMemoryMapping);
+                buffer = null;
+            }
+            
+        }
+
+        public int getInt() throws IOException {
+            if(!useMemoryMapping && buffer.remaining() < 4) {
+                refillBuffer(4);
+            }
+            return buffer.getInt();
+        }
+
+        public Envelope getEnvelope() throws IOException {
+            if (!useMemoryMapping && buffer.remaining() < 32)
+                refillBuffer(32);
+            
+            buffer.asDoubleBuffer().get(envelope);
+            buffer.position(buffer.position() + 32);
+            return new Envelope(envelope[0], envelope[2], envelope[1], envelope[3]);
+        }
+
+        public void getIntArray(int[] array) throws IOException {
+            int size = array.length * 4;
+            if (buffer.remaining() < size)
+                refillBuffer(size);
+            // read the array using a view
+            IntBuffer intView = buffer.asIntBuffer();
+            intView.limit(array.length);
+            intView.get(array);
+            // don't forget to update the original buffer position, since the
+            // view is independent
+            buffer.position(buffer.position() + size);
+        }
+
+        /**
+         * 
+         * @param requiredSize
+         * @throws IOException
+         */
+        void refillBuffer(int requiredSize) throws IOException {
+            // compute the actual position up to we have read something
+            long currentPosition = bufferStart + buffer.position();
+            // if the buffer is not big enough enlarge it
+            if (buffer.capacity() < requiredSize) {
+                int size = buffer.capacity();
+                while (size < requiredSize)
+                    size *= 2;
+                buffer = NIOUtilities.allocate(size);
+                buffer.order(order);
+            }
+            readBuffer(currentPosition);
+        }
+
+        private void readBuffer(long currentPosition) throws IOException {
+            channel.position(currentPosition);
+            buffer.clear();
+            channel.read(buffer);
+            buffer.flip();
+            bufferStart = currentPosition;
+        }
+
+        /**
+         * Jumps the buffer to the specified position in the file
+         * 
+         * @param newPosition
+         * @throws IOException
+         */
+        public void goTo(long newPosition) throws IOException {
+            // if the new position is already in the buffer, just move the
+            // buffer position
+            // otherwise we have to reload it
+            if (useMemoryMapping || newPosition >= bufferStart
+                    && newPosition <= bufferStart + buffer.limit()) {
+                buffer.position((int) (newPosition - bufferStart));
+            } else {
+                readBuffer(newPosition);
+            }
+        }
+
+        /**
+         * Returns the absolute position of the next byte that will be read
+         * 
+         * @return
+         */
+        public long getPosition() {
+            return bufferStart + buffer.position();
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/fs/IndexHeader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/fs/IndexHeader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/index/quadtree/fs/IndexHeader.java	(revision 28000)
@@ -0,0 +1,96 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ * 
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.index.quadtree.fs;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ReadableByteChannel;
+import java.util.logging.Logger;
+
+import org.geotools.index.quadtree.StoreException;
+
+/**
+ * DOCUMENT ME!
+ * 
+ * @author Tommaso Nolli
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/shapefile/src/main/java/org/geotools/index/quadtree/fs/IndexHeader.java $
+ */
+public class IndexHeader {
+    public static final byte LSB_ORDER = -1;
+    public static final byte MSB_ORDER = -2;
+    public static final byte NATIVE_ORDER = 0;
+    public static final byte NEW_LSB_ORDER = 1;
+    public static final byte NEW_MSB_ORDER = 2;
+    private static final String SIGNATURE = "SQT";
+    private static final Logger LOGGER = org.geotools.util.logging.Logging
+            .getLogger("org.geotools.index.quadtree");
+    private byte byteOrder;
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @param channel
+     * 
+     * @throws IOException
+     * @throws StoreException
+     */
+    public IndexHeader(ReadableByteChannel channel) throws IOException,
+            StoreException {
+        ByteBuffer buf = ByteBuffer.allocate(8);
+
+        channel.read(buf);
+        buf.flip();
+
+        byte[] tmp = new byte[3];
+        buf.get(tmp);
+
+        String s = new String(tmp, "US-ASCII");
+
+        if (!s.equals(SIGNATURE)) {
+            // Old file format
+            LOGGER.warning("Old qix file format; this file format "
+                    + "is deprecated; It is strongly recommended "
+                    + "to regenerate it in new format.");
+
+            buf.position(0);
+            tmp = buf.array();
+
+            boolean lsb;
+
+            if ((tmp[4] == 0) && (tmp[5] == 0) && (tmp[6] == 0)
+                    && (tmp[7] == 0)) {
+                lsb = !((tmp[0] == 0) && (tmp[1] == 0));
+            } else {
+                lsb = !((tmp[4] == 0) && (tmp[5] == 0));
+            }
+
+            this.byteOrder = lsb ? LSB_ORDER : MSB_ORDER;
+        } else {
+            this.byteOrder = buf.get();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     * 
+     * @return Returns the byteOrder.
+     */
+    public byte getByteOrder() {
+        return this.byteOrder;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/io/ExpandedTabWriter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/io/ExpandedTabWriter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/io/ExpandedTabWriter.java	(revision 28000)
@@ -0,0 +1,151 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.io;
+
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.Writer;
+
+import org.geotools.util.Utilities;
+
+
+/**
+ * Writes characters to a stream while expanding tabs ({@code '\t'}) into spaces.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/io/ExpandedTabWriter.java $
+ * @version $Id: ExpandedTabWriter.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @since 2.0
+ */
+public class ExpandedTabWriter extends FilterWriter {
+    /**
+     * Tab width (in number of spaces).
+     */
+    private int tabWidth = 8;
+
+    /**
+     * Current column position. Columns are numbered from 0.
+     */
+    private int column = 0;
+
+    /**
+     * Constructs a filter which replaces tab characters ({@code '\t'})
+     * by spaces. Tab widths default to 8 characters.
+     *
+     * @param out A writer object to provide the underlying stream.
+     */
+    public ExpandedTabWriter(final Writer out) {
+        super(out);
+    }
+
+    /**
+     * Writes spaces for a tab character.
+     *
+     * @throws IOException If an I/O error occurs.
+     */
+    private void expand() throws IOException {
+        final int width = tabWidth - (column % tabWidth);
+        out.write(Utilities.spaces(width));
+        column += width;
+    }
+
+    /**
+     * Writes a single character.
+     *
+     * @throws IOException If an I/O error occurs.
+     */
+    @Override
+    public void write(final int c) throws IOException {
+        synchronized (lock) {
+            switch (c) {
+                case '\r': // fall through
+                case '\n': column=0; break;
+                case '\t': expand(); return;
+                default  : column++; break;
+            }
+            out.write(c);
+        }
+    }
+
+    /**
+     * Writes a portion of an array of characters.
+     *
+     * @param  buffer  Buffer of characters to be written
+     * @param  offset  Offset from which to start reading characters
+     * @param  length  Number of characters to be written
+     * @throws IOException If an I/O error occurs.
+     */
+    @Override
+    public void write(final char[] buffer, final int offset, int length) throws IOException {
+        synchronized (lock) {
+            int start = offset;
+            length += offset;
+            for (int end=offset; end<length; end++) {
+                final char c = buffer[end];
+                switch (c) {
+                    case '\r': // fall through
+                    case '\n': column = 0;
+                               break;
+
+                    case '\t': out.write(buffer, start, end-start);
+                               start = end+1;
+                               expand();
+                               break;
+
+                    default  : column++;
+                               break;
+                }
+            }
+            out.write(buffer, start, length-start);
+        }
+    }
+
+    /**
+     * Writes a portion of a string.
+     *
+     * @param  string  String to be written
+     * @param  offset  Offset from which to start reading characters
+     * @param  length  Number of characters to be written
+     * @throws IOException If an I/O error occurs.
+     */
+    @Override
+    public void write(final String string, final int offset, int length) throws IOException {
+        synchronized (lock) {
+            int start = offset;
+            length += offset;
+            for (int end=offset; end<length; end++) {
+                final char c = string.charAt(end);
+                switch (c) {
+                    case '\r': // fall through
+                    case '\n': column = 0;
+                               break;
+
+                    case '\t': out.write(string, start, end-start);
+                               start = end+1;
+                               expand();
+                               break;
+
+                    default  : column++;
+                               break;
+                }
+            }
+            out.write(string, start, length-start);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/io/TableWriter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/io/TableWriter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/io/TableWriter.java	(revision 28000)
@@ -0,0 +1,861 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.io;
+
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.StringTokenizer;
+import javax.swing.text.StyleConstants;
+
+import org.geotools.util.Utilities;
+import org.geotools.resources.XArray;
+
+
+/**
+ * A character stream that can be used to format tables. Columns are separated
+ * by tabulations (<code>'\t'</code>) and rows are separated by line terminators
+ * (<code>'\r'</code>, <code>'\n'</code> or <code>"\r\n"</code>). Every table's
+ * cells are stored in memory until {@link #flush()} is invoked. When invoked,
+ * {@link #flush()} copy cell's contents to the underlying stream while replacing
+ * tabulations by some amount of spaces. The exact number of spaces is computed
+ * from cell's widths. {@code TableWriter} produces correct output when
+ * displayed with a monospace font.
+ * <br><br>
+ * For example, the following code...
+ *
+ * <blockquote><pre>
+ *     TableWriter out = new TableWriter(new OutputStreamWriter(System.out), 3);
+ *     out.write("Prénom\tNom\n");
+ *     out.nextLine('-');
+ *     out.write("Idéphonse\tLaporte\nSarah\tCoursi\nYvan\tDubois");
+ *     out.flush();
+ * </pre></blockquote>
+ *
+ * ...produces the following output:
+ *
+ * <blockquote><pre>
+ *      Prénom      Nom
+ *      ---------   -------
+ *      Idéphonse   Laporte
+ *      Sarah       Coursi
+ *      Yvan        Dubois
+ * </pre></blockquote>
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/io/TableWriter.java $
+ * @version $Id: TableWriter.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class TableWriter extends FilterWriter {
+    /**
+     * A possible value for cell alignment. This specifies that the text is aligned
+     * to the left indent and extra whitespace should be placed on the right.
+     */
+    public static final int ALIGN_LEFT = StyleConstants.ALIGN_LEFT;
+
+    /**
+     * A possible value for cell alignment. This specifies that the text is aligned
+     * to the right indent and extra whitespace should be placed on the left.
+     */
+    public static final int ALIGN_RIGHT = StyleConstants.ALIGN_RIGHT;
+
+    /**
+     * A possible value for cell alignment. This specifies that the text is aligned
+     * to the center and extra whitespace should be placed equally on the left and right.
+     */
+    public static final int ALIGN_CENTER = StyleConstants.ALIGN_CENTER;
+
+    /**
+     * Drawing-box characters. The last two characters
+     * are horizontal and vertical line respectively.
+     */
+    private static final char[][] BOX = new char[][] {
+        {// [0000]: single horizontal, single vertical
+            '\u250C','\u252C','\u2510',
+            '\u251C','\u253C','\u2524',
+            '\u2514','\u2534','\u2518',
+            '\u2500','\u2502'
+        },
+        {// [0001]: single horizontal, double vertical
+            '\u2553','\u2565','\u2556',
+            '\u255F','\u256B','\u2562',
+            '\u2559','\u2568','\u255C',
+            '\u2500','\u2551'
+        },
+        {// [0010]: double horizontal, single vertical
+            '\u2552','\u2564','\u2555',
+            '\u255E','\u256A','\u2561',
+            '\u2558','\u2567','\u255B',
+            '\u2550','\u2502'
+        },
+        {// [0011]: double horizontal, double vertical
+            '\u2554','\u2566','\u2557',
+            '\u2560','\u256C','\u2563',
+            '\u255A','\u2569','\u255D',
+            '\u2550','\u2551'
+        },
+        {// [0100]: ASCII characters only
+            '+','+','+',
+            '+','+','+',
+            '+','+','+',
+            '-','|'
+        }
+    };
+
+    /**
+     * Default character for space.
+     */
+    private static final char SPACE = ' ';
+
+    /**
+     * Temporary string buffer. This buffer contains only one cell's content.
+     */
+    private final StringBuilder buffer = new StringBuilder();
+
+    /**
+     * List of {@link Cell} objects, from left to right and top to bottom.
+     * By convention, a {@code null} value or a {@link Cell} object
+     * with <code>{@link Cell#text}==null</code> are move to the next line.
+     */
+    private final List<Cell> cells = new ArrayList<Cell>();
+
+    /**
+     * Alignment for current and next cells.
+     */
+    private int alignment = ALIGN_LEFT;
+
+    /**
+     * Column position of the cell currently being written. The field
+     * is incremented each time {@link #nextColumn()} is invoked.
+     */
+    private int column;
+
+    /**
+     * Line position of the cell currently being written. The field
+     * is incremented each time {@link #nextLine()} is invoked.
+     */
+    private int row;
+
+    /**
+     * Maximum width for each columns. This array's length must
+     * be equals to the number of columns in this table.
+     */
+    private int width[] = new int[0];
+
+    /**
+     * The column separator.
+     */
+    private final String separator;
+
+    /**
+     * The left table border.
+     */
+    private final String leftBorder;
+
+    /**
+     * The right table border.
+     */
+    private final String rightBorder;
+
+    /**
+     * Tells if cells can span more than one line. If {@code true}, then EOL characters likes
+     * {@code '\n'} move to the next line <em>inside</em> the current cell. If {@code false},
+     * then EOL characters move to the next table's row. Default value is {@code false}.
+     */
+    private boolean multiLinesCells;
+
+    /**
+     * {@code true} if this {@code TableWriter} has been constructed with the no-arg constructor.
+     */
+    private final boolean stringOnly;
+
+    /**
+     * Tells if the next '\n' character must be ignored. This field is
+     * used in order to avoid writing two EOL in place of {@code "\r\n"}.
+     */
+    private boolean skipCR;
+
+    /**
+     * Creates a new table writer with the specified amount of spaces as column separator.
+     *
+     * @param out Writer object to provide the underlying stream, or {@code null} if there is no
+     *        underlying stream. If {@code out} is null, then the {@link #toString} method is the
+     *        only way to get the table's content.
+     * @param spaces Amount of white spaces to use as column separator.
+     */
+    public TableWriter(final Writer out, final int spaces) {
+        this(out, Utilities.spaces(spaces));
+    }
+
+    /**
+     * Creates a new table writer with the specified column separator.
+     *
+     * @param out Writer object to provide the underlying stream, or {@code null} if there is no
+     *        underlying stream. If {@code out} is null, then the {@link #toString} method is the
+     *        only way to get the table's content.
+     * @param separator String to write between columns. Drawing box characters are treated
+     *        specially. For example {@code " \\u2502 "} can be used for a single-line box.
+     *
+     * @see #SINGLE_VERTICAL_LINE
+     * @see #DOUBLE_VERTICAL_LINE
+     */
+    public TableWriter(final Writer out, final String separator) {
+        super(out!=null ? out : new StringWriter());
+        stringOnly = (out == null);
+        final int length = separator.length();
+        int lower = 0;
+        int upper = length;
+        while (lower<length && Character.isSpaceChar(separator.charAt(lower  ))) lower++;
+        while (upper>0      && Character.isSpaceChar(separator.charAt(upper-1))) upper--;
+        this.leftBorder  = separator.substring(lower);
+        this.rightBorder = separator.substring(0, upper);
+        this.separator   = separator;
+    }
+
+    /**
+     * Writes a border or a corner to the specified stream.
+     *
+     * @param out              The destination stream.
+     * @param horizontalBorder -1 for left border, +1 for right border,  0 for center.
+     * @param verticalBorder   -1 for top  border, +1 for bottom border, 0 for center.
+     * @param horizontalChar   Character to use for horizontal line.
+     * @throws IOException     if the writting operation failed.
+     */
+    private void writeBorder(final Writer out,
+                             final int horizontalBorder,
+                             final int verticalBorder,
+                             final char horizontalChar) throws IOException
+    {
+        /*
+         * Obtient les ensembles de caractères qui
+         * conviennent pour la ligne horizontale.
+         */
+        int boxCount = 0;
+        final char[][] box = new char[BOX.length][];
+        for (int i=0; i<BOX.length; i++) {
+            if (BOX[i][9] == horizontalChar) {
+                box[boxCount++] = BOX[i];
+            }
+        }
+        /*
+         * Obtient une chaine contenant les lignes verticales à
+         * dessiner à gauche, à droite ou au centre de la table.
+         */
+        final String border;
+        switch (horizontalBorder) {
+            case -1: border = leftBorder;  break;
+            case +1: border = rightBorder; break;
+            case  0: border = separator;   break;
+            default: throw new IllegalArgumentException(String.valueOf(horizontalBorder));
+        }
+        if (verticalBorder<-1 || verticalBorder>+1) {
+            throw new IllegalArgumentException(String.valueOf(verticalBorder));
+        }
+        /*
+         * Remplace les espaces par la ligne horizontale,
+         * et les lignes verticales par une intersection.
+         */
+        final int index = (horizontalBorder+1) + (verticalBorder+1)*3;
+        final int borderLength = border.length();
+        for (int i=0; i<borderLength; i++) {
+            char c=border.charAt(i);
+            if (Character.isSpaceChar(c)) {
+                c = horizontalChar;
+            } else {
+                for (int j=0; j<boxCount; j++) {
+                    if (box[j][10] == c) {
+                        c = box[j][index];
+                        break;
+                    }
+                }
+            }
+            out.write(c);
+        }
+    }
+
+    /**
+     * Sets the desired behavior for EOL and tabulations characters.
+     * <ul>
+     *   <li>If {@code true}, EOL (<code>'\r'</code>, <code>'\n'</code> or
+     *       <code>"\r\n"</code>) and tabulations (<code>'\t'</code>) characters
+     *       are copied straight into the current cell, which mean that next write
+     *       operations will continue inside the same cell.</li>
+     *   <li>If {@code false}, then tabulations move to next column and EOL move
+     *       to the first cell of next row (i.e. tabulation and EOL are equivalent to
+     *       {@link #nextColumn()} and {@link #nextLine()} calls respectively).</li>
+     * </ul>
+     * The default value is {@code false}.
+     *
+     * @param multiLines {@code true} true if EOL are used for line feeds inside
+     *        current cells, or {@code false} if EOL move to the next row.
+     */
+    public void setMultiLinesCells(final boolean multiLines) {
+        synchronized (lock) {
+            multiLinesCells = multiLines;
+        }
+    }
+
+    /**
+     * Returns the number of rows in this table. This count is reset to 0 by {@link #flush}.
+     *
+     * @return The number of rows in this table.
+     *
+     * @since 2.5
+     */
+    public int getRowCount() {
+        int count = row;
+        if (column != 0) {
+            count++;
+        }
+        return count;
+    }
+
+    /**
+     * Write a single character. If {@link #isMultiLinesCells()}
+     * is {@code false} (which is the default), then:
+     * <ul>
+     *   <li>Tabulations (<code>'\t'</code>) are replaced by {@link #nextColumn()} invocations.</li>
+     *   <li>Line separators (<code>'\r'</code>, <code>'\n'</code> or <code>"\r\n"</code>)
+     *       are replaced by {@link #nextLine()} invocations.</li>
+     * </ul>
+     *
+     * @param c Character to write.
+     */
+    @Override
+    public void write(final int c) {
+        synchronized (lock) {
+            if (!multiLinesCells) {
+                switch (c) {
+                    case '\t': {
+                        nextColumn();
+                        skipCR = false;
+                        return;
+                    }
+                    case '\r': {
+                        nextLine();
+                        skipCR = true;
+                        return;
+                    }
+                    case '\n': {
+                        if (!skipCR) {
+                            nextLine();
+                        }
+                        skipCR = false;
+                        return;
+                    }
+                }
+            }
+            if (c<Character.MIN_VALUE || c>Character.MAX_VALUE) {
+                throw new IllegalArgumentException(String.valueOf(c));
+            }
+            buffer.append((char)c);
+            skipCR = false;
+        }
+    }
+
+    /**
+     * Writes a string. Tabulations and line separators are interpreted as by {@link #write(int)}.
+     *
+     * @param string String to write.
+     */
+    @Override
+    public void write(final String string) {
+        write(string, 0, string.length());
+    }
+
+    /**
+     * Writes a portion of a string. Tabulations and line
+     * separators are interpreted as by {@link #write(int)}.
+     *
+     * @param string String to write.
+     * @param offset Offset from which to start writing characters.
+     * @param length Number of characters to write.
+     */
+    @Override
+    public void write(final String string, int offset, int length) {
+        if (offset<0 || length<0 || (offset+length)>string.length()) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (length == 0) {
+            return;
+        }
+        synchronized (lock) {
+            if (skipCR && string.charAt(offset)=='\n') {
+                offset++;
+                length--;
+            }
+            if (!multiLinesCells) {
+                int upper = offset;
+                for (; length!=0; length--) {
+                    switch (string.charAt(upper++)) {
+                        case '\t': {
+                            buffer.append(string.substring(offset, upper-1));
+                            nextColumn();
+                            offset = upper;
+                            break;
+                        }
+                        case '\r': {
+                            buffer.append(string.substring(offset, upper-1));
+                            nextLine();
+                            if (length!=0 && string.charAt(upper)=='\n') {
+                                upper++;
+                                length--;
+                            }
+                            offset = upper;
+                            break;
+                        }
+                        case '\n': {
+                            buffer.append(string.substring(offset, upper-1));
+                            nextLine();
+                            offset = upper;
+                            break;
+                        }
+                    }
+                }
+                length = upper-offset;
+            }
+            skipCR = (string.charAt(offset+length-1) == '\r');
+            buffer.append(string.substring(offset, offset+length));
+        }
+    }
+
+    /**
+     * Writes an array of characters. Tabulations and line
+     * separators are interpreted as by {@link #write(int)}.
+     *
+     * @param cbuf Array of characters to be written.
+     */
+    @Override
+    public void write(final char cbuf[]) {
+        write(cbuf, 0, cbuf.length);
+    }
+
+    /**
+     * Writes a portion of an array of characters. Tabulations and
+     * line separators are interpreted as by {@link #write(int)}.
+     *
+     * @param cbuf   Array of characters.
+     * @param offset Offset from which to start writing characters.
+     * @param length Number of characters to write.
+     */
+    @Override
+    public void write(final char cbuf[], int offset, int length) {
+        if (offset<0 || length<0 || (offset+length)>cbuf.length) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (length == 0) {
+            return;
+        }
+        synchronized (lock) {
+            if (skipCR && cbuf[offset]=='\n') {
+                offset++;
+                length--;
+            }
+            if (!multiLinesCells) {
+                int upper = offset;
+                for (; length!=0; length--) {
+                    switch (cbuf[upper++]) {
+                        case '\t': {
+                            buffer.append(cbuf, offset, upper-offset-1);
+                            nextColumn();
+                            offset = upper;
+                            break;
+                        }
+                        case '\r': {
+                            buffer.append(cbuf, offset, upper-offset-1);
+                            nextLine();
+                            if (length!=0 && cbuf[upper]=='\n') {
+                                upper++;
+                                length--;
+                            }
+                            offset = upper;
+                            break;
+                        }
+                        case '\n': {
+                            buffer.append(cbuf, offset, upper-offset-1);
+                            nextLine();
+                            offset = upper;
+                            break;
+                        }
+                    }
+                }
+                length = upper-offset;
+            }
+            skipCR = (cbuf[offset+length-1] == '\r');
+            buffer.append(cbuf, offset, length);
+        }
+    }
+
+    /**
+     * Moves one column to the right. Next write operations will occur in a new cell on the
+     * same row.
+     */
+    public void nextColumn() {
+        nextColumn(SPACE);
+    }
+
+    /**
+     * Moves one column to the right. Next write operations will occur in a new cell on the
+     * same row. This method fill every remaining space in the current cell with the specified
+     * character. For example calling {@code nextColumn('*')} from the first character of a cell
+     * is a convenient way to put a pad value in this cell.
+     *
+     * @param fill Character filling the cell (default to whitespace).
+     */
+    public void nextColumn(final char fill) {
+        synchronized (lock) {
+            final String cellText = buffer.toString();
+            cells.add(new Cell(cellText, alignment, fill));
+            if (column >= width.length) {
+                width = XArray.resize(width, column+1);
+            }
+            int length = 0;
+            final StringTokenizer tk = new StringTokenizer(cellText, "\r\n");
+            while (tk.hasMoreTokens()) {
+                final int lg = tk.nextToken().length();
+                if (lg > length) {
+                    length = lg;
+                }
+            }
+            if (length>width[column]) {
+                width[column] = length;
+            }
+            column++;
+            buffer.setLength(0);
+        }
+    }
+
+    /**
+     * Moves to the first column on the next row.
+     * Next write operations will occur on a new row.
+     */
+    public void nextLine() {
+        nextLine(SPACE);
+    }
+
+    /**
+     * Moves to the first column on the next row. Next write operations will occur on a new
+     * row. This method fill every remaining cell in the current row with the specified character.
+     * Calling {@code nextLine('-')} from the first column of a row is a convenient way to fill
+     * this row with a line separator.
+     *
+     * @param fill Character filling the rest of the line (default to whitespace).
+     *             This caracter may be use as a row separator.
+     *
+     * @see #SINGLE_HORIZONTAL_LINE
+     * @see #DOUBLE_HORIZONTAL_LINE
+     */
+    public void nextLine(final char fill) {
+        synchronized (lock) {
+            if (buffer.length() != 0) {
+                nextColumn(fill);
+            }
+            assert buffer.length() == 0;
+            cells.add(!Character.isSpaceChar(fill) ? new Cell(null, alignment, fill) : null);
+            column = 0;
+            row++;
+        }
+    }
+
+    /**
+     * Flushs the table content to the underlying stream. This method should not be called
+     * before the table is completed (otherwise, columns may have the wrong width).
+     *
+     * @throws IOException if an output operation failed.
+     */
+    @Override
+    public void flush() throws IOException {
+        synchronized (lock) {
+            if (buffer.length() != 0) {
+                nextLine();
+                assert buffer.length() == 0;
+            }
+            flushTo(out);
+            row = column = 0;
+            cells.clear();
+            if (!(out instanceof TableWriter)) {
+                /*
+                 * Flush only if this table is not included in an outer (bigger) table.
+                 * This is because flushing the outer table would break its formatting.
+                 */
+                out.flush();
+            }
+        }
+    }
+
+    /**
+     * Flushs the table content and close the underlying stream.
+     *
+     * @throws IOException if an output operation failed.
+     */
+    @Override
+    public void close() throws IOException {
+        synchronized (lock) {
+            flush();
+            out.close();
+        }
+    }
+
+    /**
+     * Écrit vers le flot spécifié toutes les cellules qui avaient été disposées
+     * dans le tableau. Ces cellules seront automatiquement alignées en colonnes.
+     * Cette méthode peut être appelée plusieurs fois pour écrire le même tableau
+     * par exemple vers plusieurs flots.
+     *
+     * @param  out Flot vers où écrire les données.
+     * @throws IOException si une erreur est survenue lors de l'écriture dans {@code out}.
+     */
+    private void flushTo(final Writer out) throws IOException {
+        final String columnSeparator = this.separator;
+        final String   lineSeparator = System.getProperty("line.separator", "\n");
+        final Cell[]     currentLine = new Cell[width.length];
+        final int          cellCount = cells.size();
+        for (int cellIndex=0; cellIndex<cellCount; cellIndex++) {
+            /*
+             * Copie dans  {@code currentLine}  toutes les données qui seront à écrire
+             * sur la ligne courante de la table. Ces données excluent le {@code null}
+             * terminal.  La liste {@code currentLine} ne contiendra donc initialement
+             * aucun élément nul, mais ses éléments seront progressivement modifiés (et mis
+             * à {@code null}) pendant l'écriture de la ligne dans la boucle qui suit.
+             */
+            Cell lineFill = null;
+            int currentCount = 0;
+            do {
+                final Cell cell = cells.get(cellIndex);
+                if (cell == null) {
+                    break;
+                }
+                if (cell.text == null) {
+                    lineFill = new Cell("", cell.alignment, cell.fill);
+                    break;
+                }
+                currentLine[currentCount++] = cell;
+            }
+            while (++cellIndex < cellCount);
+            Arrays.fill(currentLine, currentCount, currentLine.length, lineFill);
+            /*
+             * La boucle suivante sera exécutée tant qu'il reste des lignes à écrire
+             * (c'est-à-dire tant qu'au moins un élément de {@code currentLine}
+             * est non-nul). Si une cellule contient un texte avec des caractères EOL,
+             * alors cette cellule devra s'écrire sur plusieurs lignes dans la cellule
+             * courante.
+             */
+            while (!isEmpty(currentLine)) {
+                for (int j=0; j<currentLine.length; j++) {
+                    final boolean isFirstColumn = (j   == 0);
+                    final boolean isLastColumn  = (j+1 == currentLine.length);
+                    final Cell cell = currentLine[j];
+                    final int cellWidth = width[j];
+                    if (cell == null) {
+                        if (isFirstColumn) {
+                            out.write(leftBorder);
+                        }
+                        repeat(out, SPACE, cellWidth);
+                        out.write(isLastColumn ? rightBorder : columnSeparator);
+                        continue;
+                    }
+                    String cellText = cell.toString();
+                    int endCR = cellText.indexOf('\r');
+                    int endLF = cellText.indexOf('\n');
+                    int end   = (endCR<0) ? endLF : (endLF<0) ? endCR : Math.min(endCR,endLF);
+                    if (end >= 0) {
+                        /*
+                         * Si un retour chariot a été trouvé, n'écrit que la première
+                         * ligne de la cellule. L'élément {@code currentLine[j]}
+                         * sera modifié pour ne contenir que les lignes restantes qui
+                         * seront écrites lors d'un prochain passage dans la boucle.
+                         */
+                        int top = end+1;
+                        if (endCR>=0 && endCR+1==endLF) top++;
+                        int scan = top;
+                        final int textLength = cellText.length();
+                        while (scan<textLength && Character.isWhitespace(cellText.charAt(scan))) {
+                            scan++;
+                        }
+                        currentLine[j] = (scan<textLength) ? cell.substring(top) : null;
+                        cellText = cellText.substring(0, end);
+                    }
+                    else currentLine[j] = null;
+                    final int textLength = cellText.length();
+                    /*
+                     * Si la cellule à écrire est en fait une bordure,
+                     * on fera un traitement spécial pour utiliser les
+                     * caractres de jointures {@link #BOX}.
+                     */
+                    if (currentCount == 0) {
+                        assert textLength == 0;
+                        final int verticalBorder;
+                        if      (cellIndex==0)           verticalBorder = -1;
+                        else if (cellIndex>=cellCount-1) verticalBorder = +1;
+                        else                             verticalBorder =  0;
+                        if (isFirstColumn) {
+                            writeBorder(out, -1, verticalBorder, cell.fill);
+                        }
+                        repeat(out, cell.fill, cellWidth);
+                        writeBorder(out, isLastColumn ? +1 : 0, verticalBorder, cell.fill);
+                        continue;
+                    }
+                    /*
+                     * Si la cellule n'est pas une bordure, il s'agit
+                     * d'une cellule "normale".  Procde maintenant à
+                     * l'écriture d'une ligne de la cellule.
+                     */
+                    if (isFirstColumn) {
+                        out.write(leftBorder);
+                    }
+                    final Writer tabExpander = (cellText.indexOf('\t')>=0) ?
+                                               new ExpandedTabWriter(out) : out;
+                    switch (cell.alignment) {
+                        default: {
+                            // Should not happen.
+                            throw new AssertionError(cell.alignment);
+                        }
+                        case ALIGN_LEFT: {
+                            tabExpander.write(cellText);
+                            repeat(tabExpander, cell.fill, cellWidth-textLength);
+                            break;
+                        }
+                        case ALIGN_RIGHT: {
+                            repeat(tabExpander, cell.fill, cellWidth-textLength);
+                            tabExpander.write(cellText);
+                            break;
+                        }
+                        case ALIGN_CENTER: {
+                            final int rightMargin = (cellWidth-textLength)/2;
+                            repeat(tabExpander, cell.fill, rightMargin);
+                            tabExpander.write(cellText);
+                            repeat(tabExpander, cell.fill, (cellWidth-rightMargin)-textLength);
+                            break;
+                        }
+                    }
+                    out.write(isLastColumn ? rightBorder : columnSeparator);
+                }
+                out.write(lineSeparator);
+            }
+        }
+    }
+
+    /**
+     * Checks if {@code array} contains only {@code null} elements.
+     */
+    private static boolean isEmpty(final Object[] array) {
+        for (int i=array.length; --i>=0;) {
+            if (array[i] != null) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Repeats a character.
+     *
+     * @param out   The destination stream.
+     * @param car   Character to write (usually ' ').
+     * @param count Number of repetition.
+     */
+    private static void repeat(final Writer out, final char car, int count) throws IOException {
+        while (--count >= 0) {
+            out.write(car);
+        }
+    }
+
+    /**
+     * Returns the table content as a string.
+     */
+    @Override
+    public String toString() {
+        synchronized (lock) {
+            int capacity = 2; // Room for EOL.
+            for (int i=0; i<width.length; i++) {
+                capacity += width[i];
+            }
+            capacity *= getRowCount();
+            final StringWriter writer;
+            if (stringOnly) {
+                writer = (StringWriter) out;
+                final StringBuffer buffer = writer.getBuffer();
+                buffer.setLength(0);
+                buffer.ensureCapacity(capacity);
+            } else {
+                writer = new StringWriter(capacity);
+            }
+            try {
+                flushTo(writer);
+            } catch (IOException exception) {
+                // Should not happen
+                throw new AssertionError(exception);
+            }
+            return writer.toString();
+        }
+    }
+
+    /**
+     * A class wrapping a cell's content and its text's alignment.
+     * This class if for internal use only.
+     *
+     * @version $Id: TableWriter.java 37298 2011-05-25 05:16:15Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     */
+    private static final class Cell {
+        /**
+         * The text to write inside the cell.
+         */
+        public final String text;
+
+        /**
+         * The alignment for {@link #text} inside the cell.
+         */
+        public int alignment;
+
+        /**
+         * The fill character, used for filling space inside the cell.
+         */
+        public final char fill;
+
+        /**
+         * Returns a new cell wrapping the specified string with the
+         * specified alignment and fill character.
+         */
+        public Cell(final String text, final int alignment, final char fill) {
+            this.text      = text;
+            this.alignment = alignment;
+            this.fill      = fill;
+        }
+
+        /**
+         * Returns a new cell which contains substring of this cell.
+         */
+        public Cell substring(final int lower) {
+            return new Cell(text.substring(lower), alignment, fill);
+        }
+
+        /**
+         * Returns the cell's content.
+         */
+        @Override
+        public String toString() {
+            return text;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/io/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/io/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/io/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.io</TITLE>
+  </HEAD>
+  <BODY>
+    Extensions to standard {@link java.io.Reader} and {@link java.io.Writer}.
+    Classes provided in this package are filters for expanding the tab character
+    ({@code '\t'}), replaces various EOL characters with the platform-dependent
+    ones, etc.
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/math/XMath.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/math/XMath.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/math/XMath.java	(revision 28000)
@@ -0,0 +1,93 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.math;
+
+import static org.geotools.resources.XMath.next;
+import static org.geotools.resources.XMath.previous;
+
+
+/**
+ * Simple mathematical functions in addition to the ones provided in {@link Math}.
+ *
+ * @since 2.5
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/math/XMath.java $
+ * @version $Id: XMath.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public final class XMath {
+
+    /**
+     * Do not allow instantiation of this class.
+     */
+    private XMath() {
+    }
+
+    /**
+     * Tries to remove at least {@code n} fraction digits in the decimal representation of
+     * the specified value. This method tries small changes to {@code value}, by adding or
+     * substracting up to {@code maxULP} (Unit in the Last Place). If there is no small
+     * change that remove at least {@code n} fraction digits, then the value is returned
+     * unchanged. This method is used for hiding rounding errors, like in conversions from
+     * radians to degrees.
+     * <P>
+     * Example:
+     * {@code XMath.trimLastDecimalDigits(-61.500000000000014, 12, 4)} returns {@code -61.5}.
+     *
+     * @param  value The value to fix.
+     * @param  maxULP The maximal change allowed in ULPs (Unit in the Last Place).
+     *         A typical value is 4.
+     * @param  n The minimum amount of fraction digits.
+     * @return The trimmed value, or the unchanged {@code value} if there is no small change
+     *         that remove at least {@code n} fraction digits.
+     */
+    public static double trimDecimalFractionDigits(final double value, final int maxULP, int n) {
+        double lower = value;
+        double upper = value;
+        n = countDecimalFractionDigits(value) - n;
+        if (n > 0) {
+            for (int i=0; i<maxULP; i++) {
+                if (countDecimalFractionDigits(lower = previous(lower)) <= n) return lower;
+                if (countDecimalFractionDigits(upper = next    (upper)) <= n) return upper;
+            }
+        }
+        return value;
+    }
+
+    /**
+     * Counts the fraction digits in the string representation of the specified value. This method
+     * is equivalent to a calling <code>{@linkplain Double#toString(double) Double.toString}(value)</code>
+     * and counting the number of digits after the decimal separator.
+     *
+     * @param value The value for which to count the fraction digits.
+     * @return The number of fraction digits.
+     */
+    public static int countDecimalFractionDigits(final double value) {
+        final String asText = Double.toString(value);
+        final int exp = asText.indexOf('E');
+        int upper, power;
+        if (exp >= 0) {
+            upper = exp;
+            power = Integer.parseInt(asText.substring(exp+1));
+        } else {
+            upper = asText.length();
+            power = 0;
+        }
+        while ((asText.charAt(--upper)) == '0');
+        return Math.max(upper - asText.indexOf('.') - power, 0);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/math/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/math/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/math/package.html	(revision 28000)
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>Package org.geotools.math</TITLE>
+  </HEAD>
+  <BODY>
+    A set of mathematical objects and algebraic utilities.
+
+    <P>&nbsp;</P>
+    <TABLE BORDER="3" ALIGN="center" CELLPADDING="6" BGCOLOR="#FEF3D6">
+      <TR>
+        <TD ALIGN="center" BGCOLOR="#FFD6AC"><font COLOR="#804040" SIZE="5" FACE="Arial Black"><STRONG>References</STRONG></FONT></TD>
+      </TR>
+      <TR>
+        <TD NOWRAP>
+          <UL>
+            <LI><A HREF="http://mathworld.wolfram.com/">Eric Weisstein's World of Mathematic</A></LI>
+            <LI><A HREF="http://www.worldserver.com/turk/opensource/">Ken Turkiwski's Open Source Repository</A></LI>
+        </TD>
+      </TR>
+    </TABLE>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Angle.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Angle.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Angle.java	(revision 28000)
@@ -0,0 +1,106 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 1999-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.measure;
+
+import java.io.Serializable;
+
+import org.geotools.resources.ClassChanger;
+
+
+/**
+ * An angle in degrees. An angle is the amount of rotation needed to bring one line or plane
+ * into coincidence with another, generally measured in degrees, sexagesimal degrees or grads.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/measure/Angle.java $
+ * @version $Id: Angle.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (PMO, IRD)
+ *
+ * @see Latitude
+ * @see Longitude
+ * @see AngleFormat
+ */
+public class Angle implements Comparable<Angle>, Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 1158747349433104534L;
+
+    /**
+     * Define how angle can be converted to {@link Number} objects.
+     */
+    static {
+        ClassChanger.register(new ClassChanger<Angle,Double>(Angle.class, Double.class) {
+            protected Double convert(final Angle o) {
+                return o.theta;
+            }
+
+            protected Angle inverseConvert(final Double value) {
+                return new Angle(value);
+            }
+        });
+    }
+
+    /**
+     * Angle value in degres.
+     */
+    private final double theta;
+
+    /**
+     * Contructs a new angle with the specified value.
+     *
+     * @param theta Angle in degrees.
+     */
+    public Angle(final double theta) {
+        this.theta = theta;
+    }
+
+    /**
+     * Returns a hash code for this {@code Angle} object.
+     */
+    @Override
+    public int hashCode() {
+        final long code = Double.doubleToLongBits(theta);
+        return (int) code ^ (int) (code >>> 32);
+    }
+
+    /**
+     * Compares the specified object with this angle for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (object!=null && getClass().equals(object.getClass())) {
+            final Angle that = (Angle) object;
+            return Double.doubleToLongBits(this.theta) ==
+                   Double.doubleToLongBits(that.theta);
+        }  else {
+            return false;
+        }
+    }
+
+    /**
+     * Compares two {@code Angle} objects numerically. The comparaison
+     * is done as if by the {@link Double#compare(double,double)} method.
+     */
+    public int compareTo(final Angle that) {
+        return Double.compare(this.theta, that.theta);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Latitude.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Latitude.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Latitude.java	(revision 28000)
@@ -0,0 +1,57 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 1999-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.measure;
+
+
+/**
+ * A latitude angle. Positive latitudes are North, while negative
+ * latitudes are South. This class has no direct OpenGIS equivalent.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/measure/Latitude.java $
+ * @version $Id: Latitude.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (PMO, IRD)
+ *
+ * @see Longitude
+ * @see AngleFormat
+ */
+public final class Latitude extends Angle {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -4496748683919618976L;
+
+    /**
+     * Minimum legal value for latitude (-90°).
+     */
+    public static final double MIN_VALUE = -90;
+
+    /**
+     * Maximum legal value for latitude (+90°).
+     */
+    public static final double MAX_VALUE = +90;
+
+    /**
+     * Contruct a new latitude with the specified value.
+     *
+     * @param theta Angle in degrees.
+     */
+    public Latitude(final double theta) {
+        super(theta);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Longitude.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Longitude.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Longitude.java	(revision 28000)
@@ -0,0 +1,56 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 1999-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.measure;
+
+
+/**
+ * A longitude angle. Positive longitudes are East, while negative longitudes are West.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/measure/Longitude.java $
+ * @version $Id: Longitude.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (PMO, IRD)
+ *
+ * @see Latitude
+ * @see AngleFormat
+ */
+public final class Longitude extends Angle {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -8614900608052762636L;
+
+    /**
+     * Minimum legal value for longitude (-180°).
+     */
+    public static final double MIN_VALUE = -180;
+
+    /**
+     * Maximum legal value for longitude (+180°).
+     */
+    public static final double MAX_VALUE = +180;
+
+    /**
+     * Contruct a new longitude with the specified value.
+     *
+     * @param theta Angle in degrees.
+     */
+    public Longitude(final double theta) {
+        super(theta);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Measure.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Measure.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Measure.java	(revision 28000)
@@ -0,0 +1,102 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 1999-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.measure;
+
+import javax.measure.unit.Unit;
+import org.geotools.util.Utilities;
+
+
+/**
+ * A scalar with an unit.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/measure/Measure.java $
+ * @version $Id: Measure.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (PMO, IRD)
+ */
+public final class Measure extends Number {
+    /**
+     * For compatibility with different versions.
+     */
+    private static final long serialVersionUID = 6917234039472328164L;
+
+    /**
+     * The scalar value.
+     */
+    private final double value;
+
+    /**
+     * The unit.
+     */
+    private final Unit<?> unit;
+
+    /**
+     * Creates a new measure with the specified value and unit.
+     *
+     * @param value The value.
+     * @param unit The unit of measurement for the given value.
+     */
+    public Measure(final double value, final Unit<?> unit) {
+        this.value = value;
+        this.unit  = unit;
+    }
+
+    /** Returns the scalar value. */           public double doubleValue() {return         value;}
+    /** Returns the scalar value. */           public float   floatValue() {return (float) value;}
+    /** Returns the scalar value. */           public long     longValue() {return (long)  value;}
+    /** Returns the scalar value. */           public int       intValue() {return (int)   value;}
+    /** Returns the scalar value. */ @Override public short   shortValue() {return (short) value;}
+    /** Returns the scalar value. */ @Override public byte     byteValue() {return (byte)  value;}
+
+    /**
+     * Returns a hash code value for this measure.
+     */
+    @Override
+    public int hashCode() {
+        long code = Double.doubleToLongBits(value);
+        return (int) code ^ (int)(code >>> 32) ^ unit.hashCode();
+    }
+
+    /**
+     * Compares this measure with the specified object for equality.
+     *
+     * @param object The object to compare with this measure.
+     * @return {@code true} if the given object is equals to this measure.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object instanceof Measure) {
+            final Measure that = (Measure) object;
+            return Utilities.equals(value, that.value) &&
+                   Utilities.equals(unit,  that.unit);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a string representation of this measure.
+     */
+    @Override
+    public String toString() {
+        final StringBuilder buffer = new StringBuilder();
+        buffer.append(value);
+        buffer.append(' ');
+        buffer.append(unit);
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/SexagesimalConverter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/SexagesimalConverter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/SexagesimalConverter.java	(revision 28000)
@@ -0,0 +1,176 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2000-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.measure;
+
+import javax.measure.converter.ConversionException;
+import javax.measure.converter.UnitConverter;
+
+
+/**
+ * A converter from fractional degrees to sexagesimal degrees.
+ * Sexagesimal degrees are pseudo-unit in the format
+ *
+ * <cite>sign - degrees - decimal point - minutes (two digits) - integer seconds (two digits) -
+ * fraction of seconds (any precision)</cite>.
+ *
+ * Unfortunatly, this pseudo-unit is extensively used in the EPSG database.
+ *
+ * @since 2.1
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/measure/SexagesimalConverter.java $
+ * @version $Id: SexagesimalConverter.java 30776 2008-06-20 17:00:11Z desruisseaux $
+ * @author Martin Desruisseaux (IRD)
+ */
+class SexagesimalConverter extends UnitConverter {
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = 3873494343412121773L;
+
+    /**
+     * Small tolerance factor for rounding errors.
+     */
+    private static final double EPS = 1E-8;
+
+    /**
+     * The value to divide DMS unit by.
+     * For "degree minute second" (EPSG code 9107), this is 1.
+     * For "sexagesimal degree" (EPSG code 9110), this is 10000.
+     */
+    final int divider;
+
+    /**
+     * The inverse of this converter.
+     */
+    private final UnitConverter inverse;
+
+    /**
+     * Constructs a converter for sexagesimal units.
+     *
+     * @param divider The value to divide DMS unit by.
+     *        For "degree minute second" (EPSG code 9107), this is 1.
+     *        For "sexagesimal degree" (EPSG code 9110), this is 10000.
+     */
+    private SexagesimalConverter(final int divider) {
+        this.divider = divider;
+        this.inverse = new Inverse(this);
+    }
+
+    /**
+     * Constructs a converter for sexagesimal units.
+     * This constructor is for {@link Inverse} usage only.
+     */
+    private SexagesimalConverter(final int divider, final UnitConverter inverse) {
+        this.divider = divider;
+        this.inverse = inverse;
+    }
+
+    /**
+     * Returns the inverse of this converter.
+     */
+    public final UnitConverter inverse() {
+        return inverse;
+    }
+
+    /**
+     * Performs a conversion from fractional degrees to sexagesimal degrees.
+     */
+    public double convert(double value) throws ConversionException {
+        final int deg,min,sec;  deg = (int) value; // Round toward 0
+        value = (value-deg)*60; min = (int) value; // Round toward 0
+        value = (value-min)*60; sec = (int) value; // Round toward 0
+        value -= sec;          // The remainer (fraction of seconds)
+        return (((deg*100 + min)*100 + sec) + value)/divider;
+    }
+
+    /**
+     * Returns {@code false} since this converter is non-linear.
+     */
+    public final boolean isLinear() {
+        return false;
+    }
+
+    /**
+     * Compares this converter with the specified object.
+     */
+    @Override
+    public final boolean equals(final Object object) {
+        return object != null && object.getClass().equals(getClass()) &&
+                ((SexagesimalConverter) object).divider == divider;
+    }
+
+    /**
+     * Returns a hash value for this converter.
+     */
+    @Override
+    public int hashCode() {
+        return (int) serialVersionUID + divider;
+    }
+
+    /**
+     * The inverse of {@link SexagesimalConverter}.
+     */
+    private static final class Inverse extends SexagesimalConverter {
+        /**
+         * Serial number for compatibility with different versions.
+         */
+        private static final long serialVersionUID = -7171869900634417819L;
+
+        /**
+         * Constructs a converter.
+         */
+        public Inverse(final SexagesimalConverter inverse) {
+            super(inverse.divider, inverse);
+        }
+
+        /**
+         * Performs a conversion from sexagesimal degrees to fractional degrees.
+         */
+        @Override
+        public double convert(double value) throws ConversionException {
+            value *= this.divider;
+            int deg,min;
+            deg = (int) (value/10000); value -= 10000*deg;
+            min = (int) (value/  100); value -=   100*min;
+            if (min<=-60 || min>=60) {  // Accepts NaN
+                if (Math.abs(Math.abs(min) - 100) <= EPS) {
+                    if (min >= 0) deg++; else deg--;
+                    min = 0;
+                } else {
+                    throw new ConversionException("Invalid minutes: "+min);
+                }
+            }
+            if (value<=-60 || value>=60) { // Accepts NaN
+                if (Math.abs(Math.abs(value) - 100) <= EPS) {
+                    if (value >= 0) min++; else min--;
+                    value = 0;
+                } else {
+                    throw new ConversionException("Invalid secondes: "+value);
+                }
+            }
+            value = ((value/60) + min)/60 + deg;
+            return value;
+        }
+
+        /**
+         * Returns a hash value for this converter.
+         */
+        @Override
+        public int hashCode() {
+            return (int) serialVersionUID + divider;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Units.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Units.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/Units.java	(revision 28000)
@@ -0,0 +1,43 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.measure;
+
+import javax.measure.quantity.Dimensionless;
+import javax.measure.unit.Unit;
+
+
+/**
+ * A set of units to use in addition of {@link SI} and {@link NonSI}.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/measure/Units.java $
+ * @version $Id: Units.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public final class Units {
+    /**
+     * Do not allows instantiation of this class.
+     */
+    private Units() {
+    }
+
+    /**
+     * Parts per million.
+     */
+    public static final Unit<Dimensionless> PPM = Unit.ONE.times(1E-6);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/measure/package.html	(revision 28000)
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.measure</TITLE>
+  </HEAD>
+  <BODY>
+    Measures (like {@linkplain org.geotools.measure.Angle angles}) and their
+    formatter.
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/AbstractMetadata.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/AbstractMetadata.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/AbstractMetadata.java	(revision 28000)
@@ -0,0 +1,206 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.metadata;
+
+import java.util.Map;
+import java.util.logging.Logger;
+
+import org.geotools.util.logging.Logging;
+
+
+/**
+ * Base class for metadata implementations. Subclasses must implement the interfaces
+ * of some {@linkplain MetadataStandard metadata standard}. This class uses
+ * {@linkplain java.lang.reflect Java reflection} in order to provide default
+ * implementation of {@linkplain #AbstractMetadata(Object) copy constructor},
+ * {@link #equals} and {@link #hashCode} methods.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/AbstractMetadata.java $
+ * @version $Id: AbstractMetadata.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (Geomatys)
+ */
+public abstract class AbstractMetadata {
+    /**
+     * The logger for metadata implementation.
+     */
+    protected static final Logger LOGGER = Logging.getLogger("org.geotools.metadata");
+
+    /**
+     * Hash code value, or 0 if not yet computed. This field is reset to 0 by
+     * {@link #invalidate} in order to account for a change in metadata content.
+     */
+    private transient int hashCode;
+
+    /**
+     * A view of this metadata as a map. Will be created only when first needed.
+     */
+    private transient Map<String,Object> asMap;
+
+    /**
+     * Creates an initially empty metadata.
+     */
+    protected AbstractMetadata() {
+    }
+
+    /**
+     * Constructs a metadata entity initialized with the values from the specified metadata.
+     * The {@code source} metadata must implements the same metadata interface (defined by
+     * the {@linkplain #getStandard standard}) than this class, but don't need to be the same
+     * implementation class. The copy is performed using Java reflections.
+     *
+     * @param  source The metadata to copy values from.
+     * @throws ClassCastException if the specified metadata don't implements the expected
+     *         metadata interface.
+     * @throws UnmodifiableMetadataException if this class don't define {@code set} methods
+     *         corresponding to the {@code get} methods found in the implemented interface,
+     *         or if this instance is not modifiable for some other reason.
+     */
+    protected AbstractMetadata(final Object source)
+            throws ClassCastException, UnmodifiableMetadataException
+    {
+        getStandard().shallowCopy(source, this, true);
+    }
+
+    /**
+     * Returns the metadata standard implemented by subclasses.
+     *
+     * @return The metadata standard implemented.
+     */
+    public abstract MetadataStandard getStandard();
+
+    /**
+     * Returns {@code true} if this metadata is modifiable. The default implementation
+     * uses heuristic rules which return {@code false} if and only if:
+     * <p>
+     * <ul>
+     *   <li>this class do not contains any {@code set*(...)} method</li>
+     *   <li>All {@code get*()} methods return a presumed immutable object.
+     *       The maining of "<cite>presumed immutable</cite>" may vary in
+     *       different Geotools versions.</li>
+     * </ul>
+     * <p>
+     * Otherwise, this method conservatively returns {@code true}. Subclasses
+     * should override this method if they can provide a more rigorous analysis.
+     */
+    boolean isModifiable() {
+        return getStandard().isModifiable(getClass());
+    }
+
+    /**
+     * Invoked when the metadata changed. Some cached informations will need
+     * to be recomputed.
+     */
+    void invalidate() {
+        assert Thread.holdsLock(this);
+        hashCode = 0; // Will recompute when needed.
+    }
+
+    /**
+     * Returns a view of this metadata object as a {@linkplain Map map}. The map is backed by this
+     * metadata object using Java reflection, so changes in the underlying metadata object are
+     * immediately reflected in the map. The keys are the property names as determined by the list
+     * of {@code get*()} methods declared in the {@linkplain #getInterface metadata interface}.
+     * <p>
+     * The map supports the {@link Map#put put} operations if the underlying
+     * metadata object contains {@link #set*(...)} methods.
+     *
+     * @return A view of this metadata object as a map.
+     */
+    public synchronized Map<String,Object> asMap() {
+        if (asMap == null) {
+            asMap = getStandard().asMap(this);
+        }
+        return asMap;
+    }
+
+    /**
+     * Compares this metadata with the specified object for equality. The default
+     * implementation uses Java reflection. Subclasses may override this method
+     * for better performances.
+     * <p>
+     * This method performs a <cite>deep</cite> comparaison (i.e. if this metadata contains
+     * other metadata, the comparaison will walk through the other metadata content as well)
+     * providing that every childs implement the {@link Object#equals} method as well. This
+     * is the case by default if every childs are subclasses of {@code AbstractMetadata}.
+     *
+     * @param  object The object to compare with this metadata.
+     * @return {@code true} if the given object is equals to this metadata.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (object==null || !object.getClass().equals(getClass())) {
+            return false;
+        }
+        /*
+         * Opportunist usage of hash code if they are already computed. If they are not, we will
+         * not compute them - they are not sure to be faster than checking directly for equality,
+         * and hash code could be invalidated later anyway if the object change. Note that we
+         * don't need to synchronize since reading int fields are garanteed to be atomic in Java.
+         */
+        final int c0 = hashCode;
+        if (c0 != 0) {
+            final int c1 = ((AbstractMetadata) object).hashCode;
+            if (c1 != 0 && c0 != c1) {
+                return false;
+            }
+        }
+        final MetadataStandard standard = getStandard();
+        /*
+         * DEADLOCK WARNING: A deadlock may occur if the same pair of objects is being compared
+         * in an other thread (see http://jira.codehaus.org/browse/GEOT-1777). Ideally we would
+         * synchronize on 'this' and 'object' atomically (RFE #4210659). Since we can't in Java
+         * a workaround is to always get the locks in the same order. Unfortunatly we have no
+         * garantee that the caller didn't looked the object himself. For now the safest approach
+         * is to not synchronize at all.
+         */
+        return standard.shallowEquals(this, object, false);
+    }
+
+    /**
+     * Computes a hash code value for this metadata using Java reflection. The hash code
+     * is defined as the sum of hash code values of all non-null properties. This is the
+     * same contract than {@link java.util.Set#hashCode} and ensure that the hash code
+     * value is insensitive to the ordering of properties.
+     */
+    @Override
+    public synchronized int hashCode() {
+        int code = hashCode;
+        if (code == 0) {
+            code = getStandard().hashCode(this);
+            if (!isModifiable()) {
+                // In current implementation, we do not store the hash code if this metadata is
+                // modifiable because we can not track change in dependencies (e.g. a change in
+                // a metadata contained in this metadata).
+                hashCode = code;
+            }
+        }
+        return code;
+    }
+
+    /**
+     * Returns a string representation of this metadata.
+     */
+    @Override
+    public synchronized String toString() {
+        return getStandard().toString(this);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/InvalidMetadataException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/InvalidMetadataException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/InvalidMetadataException.java	(revision 28000)
@@ -0,0 +1,44 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.metadata;
+
+
+/**
+ * Thrown when a {@linkplain org.geotools.metadata.iso.MetadataEntity metadata entity}
+ * is in a invalid state, usually because a mandatory attribute is missing.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/InvalidMetadataException.java $
+ * @version $Id: InvalidMetadataException.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (Geomatys)
+ */
+public class InvalidMetadataException extends IllegalStateException {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 3219759595538181102L;
+
+    /**
+     * Creates a new exception with the specified detail message.
+     *
+     * @param message The detail message.
+     */
+    public InvalidMetadataException(final String message) {
+        super(message);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/MetadataStandard.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/MetadataStandard.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/MetadataStandard.java	(revision 28000)
@@ -0,0 +1,309 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.metadata;
+
+import java.util.AbstractMap;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+
+
+/**
+ * Enumeration of some metadata standards. A standard is defined by a set of Java interfaces
+ * in a specific package or subpackages. For example the {@linkplain #ISO_19115 ISO 19115}
+ * standard is defined by <A HREF="http://geoapi.sourceforge.net">GeoAPI</A> interfaces in
+ * the {@link org.opengis.metadata} package and subpackages.
+ * <p>
+ * This class provides some methods operating on metadata instances through
+ * {@linkplain java.lang.reflect Java reflection}. The following rules are
+ * assumed:
+ * <p>
+ * <ul>
+ *   <li>Properties (or metadata attributes) are defined by the set of {@code get*()}
+ *       (arbitrary return type) or {@code is*()} (boolean return type) methods found
+ *       in the <strong>interface</strong>. Getters declared in the implementation
+ *       only are ignored.</li>
+ *   <li>A property is <cite>writable</cite> if a {@code set*(...)} method is defined
+ *       in the implementation class for the corresponding {@code get*()} method. The
+ *       setter don't need to be defined in the interface.</li>
+ * </ul>
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/MetadataStandard.java $
+ * @version $Id: MetadataStandard.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (Geomatys)
+ */
+public final class MetadataStandard {
+    /**
+     * An instance working on ISO 19115 standard as defined by
+     * <A HREF="http://geoapi.sourceforge.net">GeoAPI</A> interfaces
+     * in the {@link org.opengis.metadata} package and subpackages.
+     */
+    public static final MetadataStandard ISO_19115 = new MetadataStandard("org.opengis.metadata.");
+
+    /**
+     * The root packages for metadata interfaces. Must ends with {@code "."}.
+     */
+    private final String interfacePackage;
+
+    /**
+     * Accessors for the specified implementations.
+     */
+    private final Map<Class<?>,PropertyAccessor> accessors = new HashMap<Class<?>,PropertyAccessor>();
+
+    /**
+     * Shared pool of {@link PropertyTree} instances, once for each thread
+     * (in order to avoid the need for thread synchronization).
+     */
+    private final ThreadLocal<PropertyTree> treeBuilders = new ThreadLocal<PropertyTree>() {
+        @Override
+        protected PropertyTree initialValue() {
+            return new PropertyTree(MetadataStandard.this);
+        }
+    };
+
+    /**
+     * Creates a new instance working on implementation of interfaces defined
+     * in the specified package. For the ISO 19115 standard reflected by GeoAPI
+     * interfaces, it should be the {@link org.opengis.metadata} package.
+     *
+     * @param interfacePackage The root package for metadata interfaces.
+     */
+    public MetadataStandard(String interfacePackage) {
+        if (!interfacePackage.endsWith(".")) {
+            interfacePackage += '.';
+        }
+        this.interfacePackage = interfacePackage;
+    }
+
+    /**
+     * Returns the accessor for the specified implementation.
+     *
+     * @throws ClassCastException if the specified implementation class do
+     *         not implements a metadata interface of the expected package.
+     */
+    private PropertyAccessor getAccessor(final Class<?> implementation)
+            throws ClassCastException
+    {
+        final PropertyAccessor accessor = getAccessorOptional(implementation);
+        if (accessor == null) {
+            throw new ClassCastException(Errors.format(ErrorKeys.UNKNOW_TYPE_$1,
+                                         implementation.getName()));
+        }
+        return accessor;
+    }
+
+    /**
+     * Returns the accessor for the specified implementation, or {@code null} if none.
+     */
+    final PropertyAccessor getAccessorOptional(final Class<?> implementation) {
+        synchronized (accessors) {
+            PropertyAccessor accessor = accessors.get(implementation);
+            if (accessor == null) {
+                Class<?> type = getType(implementation);
+                if (type != null) {
+                    accessor = new PropertyAccessor(implementation, type);
+                    accessors.put(implementation, accessor);
+                }
+            }
+            return accessor;
+        }
+    }
+
+    /**
+     * Returns the metadata interface implemented by the specified implementation.
+     * Only one metadata interface can be implemented.
+     *
+     * @param  metadata The metadata implementation to wraps.
+     * @return The single interface, or {@code null} if none where found.
+     */
+    private Class<?> getType(final Class<?> implementation) {
+        return PropertyAccessor.getType(implementation, interfacePackage);
+    }
+
+    /**
+     * Returns the metadata interface implemented by the specified implementation class.
+     *
+     * @param  implementation The implementation class.
+     * @return The interface implemented by the given implementation class.
+     * @throws ClassCastException if the specified implementation class do
+     *         not implements a metadata interface of the expected package.
+     *
+     * @see AbstractMap#getInterface
+     */
+    public Class<?> getInterface(final Class<?> implementation) throws ClassCastException {
+        return getAccessor(implementation).type;
+    }
+
+    /**
+     * Returns a view of the specified metadata object as a {@linkplain Map map}.
+     * The map is backed by the metadata object using Java reflection, so changes
+     * in the underlying metadata object are immediately reflected in the map.
+     * The keys are the property names as determined by the list of {@code get*()}
+     * methods declared in the {@linkplain #getInterface metadata interface}.
+     * <p>
+     * The map supports the {@link Map#put put} operations if the underlying
+     * metadata object contains {@link #set*(...)} methods.
+     *
+     * @param  metadata The metadata object to view as a map.
+     * @return A map view over the metadata object.
+     * @throws ClassCastException if at the metadata object don't
+     *         implements a metadata interface of the expected package.
+     *
+     * @see AbstractMap#asMap
+     */
+    public Map<String,Object> asMap(final Object metadata) throws ClassCastException {
+        return new PropertyMap(metadata, getAccessor(metadata.getClass()));
+    }
+
+    /**
+     * Returns {@code true} if this metadata is modifiable. This method is not public because it
+     * uses heuristic rules. In case of doubt, this method conservatively returns {@code true}.
+     *
+     * @throws ClassCastException if the specified implementation class do
+     *         not implements a metadata interface of the expected package.
+     *
+     * @see AbstractMap#isModifiable
+     */
+    final boolean isModifiable(final Class implementation) throws ClassCastException {
+        return getAccessor(implementation).isModifiable();
+    }
+
+    /**
+     * Replaces every properties in the specified metadata by their
+     * {@linkplain ModifiableMetadata#unmodifiable unmodifiable variant.
+     *
+     * @throws ClassCastException if the specified implementation class do
+     *         not implements a metadata interface of the expected package.
+     *
+     * @see ModifiableMetadata#freeze()
+     */
+    final void freeze(final Object metadata) throws ClassCastException {
+        getAccessor(metadata.getClass()).freeze(metadata);
+    }
+
+    /**
+     * Copies all metadata from source to target. The source must implements the same
+     * metadata interface than the target.
+     *
+     * @param  source The metadata to copy.
+     * @param  target The target metadata.
+     * @param  skipNulls If {@code true}, only non-null values will be copied.
+     * @throws ClassCastException if the source or target object don't
+     *         implements a metadata interface of the expected package.
+     * @throws UnmodifiableMetadataException if the target metadata is unmodifiable,
+     *         or if at least one setter method was required but not found.
+     *
+     * @see AbstractMap#AbstractMap(Object)
+     */
+    public void shallowCopy(final Object source, final Object target, final boolean skipNulls)
+            throws ClassCastException, UnmodifiableMetadataException
+    {
+        ensureNonNull("target", target);
+        final PropertyAccessor accessor = getAccessor(target.getClass());
+        if (!accessor.type.isInstance(source)) {
+            ensureNonNull("source", source);
+            throw new ClassCastException(Errors.format(ErrorKeys.ILLEGAL_CLASS_$2,
+                    source.getClass(), accessor.type));
+        }
+        if (!accessor.shallowCopy(source, target, skipNulls)) {
+            throw new UnmodifiableMetadataException(Errors.format(ErrorKeys.UNMODIFIABLE_METADATA));
+        }
+    }
+
+    /**
+     * Compares the two specified metadata objects. The comparaison is <cite>shallow</cite>,
+     * i.e. all metadata attributes are compared using the {@link Object#equals} method without
+     * recursive call to this {@code shallowEquals(...)} method for child metadata.
+     * <p>
+     * This method can optionaly excludes null values from the comparaison. In metadata,
+     * null value often means "don't know", so in some occasion we want to consider two
+     * metadata as different only if an attribute value is know for sure to be different.
+     * <p>
+     * The first arguments must be an implementation of a metadata interface, otherwise an
+     * exception will be thrown. The two argument do not need to be the same implementation
+     * however.
+     *
+     * @param metadata1 The first metadata object to compare.
+     * @param metadata2 The second metadata object to compare.
+     * @param skipNulls If {@code true}, only non-null values will be compared.
+     * @return {@code true} if the given metadata objects are equals.
+     * @throws ClassCastException if at least one metadata object don't
+     *         implements a metadata interface of the expected package.
+     *
+     * @see AbstractMetadata#equals
+     */
+    public boolean shallowEquals(final Object metadata1, final Object metadata2, final boolean skipNulls)
+            throws ClassCastException
+    {
+        if (metadata1 == metadata2) {
+            return true;
+        }
+        if (metadata1 == null || metadata2 == null) {
+            return false;
+        }
+        final PropertyAccessor accessor = getAccessor(metadata1.getClass());
+        if (!accessor.type.equals(getType(metadata2.getClass()))) {
+            return false;
+        }
+        return accessor.shallowEquals(metadata1, metadata2, skipNulls);
+    }
+
+    /**
+     * Computes a hash code for the specified metadata. The hash code is defined as the
+     * sum of hash code values of all non-null properties. This is the same contract than
+     * {@link java.util.Set#hashCode} and ensure that the hash code value is insensitive
+     * to the ordering of properties.
+     *
+     * @param  metadata The metadata object to compute hash code.
+     * @return A hash code value for the specified metadata.
+     * @throws ClassCastException if at the metadata object don't
+     *         implements a metadata interface of the expected package.
+     *
+     * @see AbstractMap#hashCode
+     */
+    public int hashCode(final Object metadata) throws ClassCastException {
+        return getAccessor(metadata.getClass()).hashCode(metadata);
+    }
+
+    /**
+     * Returns a string representation of the specified metadata.
+     *
+     * @param  metadata The metadata object to formats as a string.
+     * @return A string representation of the specified metadata.
+     * @throws ClassCastException if at the metadata object don't
+     *         implements a metadata interface of the expected package.
+     *
+     * @see AbstractMap#toString
+     */
+    public String toString(final Object metadata) throws ClassCastException {
+        final PropertyTree builder = treeBuilders.get();
+        return PropertyTree.toString(builder.asTree(metadata));
+    }
+
+    /**
+     * Ensures that the specified argument is non-null.
+     */
+    private static void ensureNonNull(final String name, final Object value) {
+        if (value == null) {
+            throw new NullPointerException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1, name));
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/ModifiableMetadata.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/ModifiableMetadata.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/ModifiableMetadata.java	(revision 28000)
@@ -0,0 +1,467 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.metadata;
+
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.Map;
+import java.util.List;
+import java.util.Iterator;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.geotools.util.CheckedArrayList;
+import org.geotools.util.CheckedHashSet;
+import org.geotools.util.logging.Logging;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.UnmodifiableArrayList;
+
+
+/**
+ * Base class for metadata that may (or may not) be modifiable. Implementations will typically
+ * provide {@code set*(...)} methods for each corresponding {@code get*()} method. An initially
+ * modifiable metadata may become unmodifiable at a later stage (typically after its construction
+ * is completed) by the call to the {@link #freeze} method.
+ * <p>
+ * Subclasses should follow the pattern below for every {@code get} and {@code set} methods,
+ * with a special processing for {@linkplain Collection collections}:
+ *
+ * <blockquote><pre>
+ * private Foo property;
+ *
+ * public Foo getProperty() {
+ *     return property;
+ * }
+ *
+ * public synchronized void setProperty(Foo newValue) {
+ *     {@linkplain #checkWritePermission()};
+ *     property = newValue;
+ * }
+ * </pre></blockquote>
+ *
+ * For collections (note that the call to {@link #checkWritePermission()} is implicit):
+ *
+ * <blockquote><pre>
+ * private Collection&lt;Foo&gt; properties;
+ *
+ * public synchronized Collection&lt;Foo&gt; getProperties() {
+ *     return properties = {@linkplain #nonNullCollection nonNullCollection}(properties, Foo.class);
+ * }
+ *
+ * public synchronized void setProperties(Collection&lt;Foo&gt; newValues) {
+ *     properties = {@linkplain #copyCollection copyCollection}(newValues, properties, Foo.class);
+ * }
+ * </pre></blockquote>
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/ModifiableMetadata.java $
+ * @version $Id: ModifiableMetadata.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ */
+public abstract class ModifiableMetadata extends AbstractMetadata implements Cloneable {
+    /**
+     * A null implementation for the {@link #FREEZING} constant.
+     */
+    private static final class Null extends ModifiableMetadata {
+        public MetadataStandard getStandard() {
+            return null;
+        }
+    }
+
+    /**
+     * A flag used for {@link #unmodifiable} in order to specify that {@link #freeze}
+     * is under way.
+     */
+    private static final ModifiableMetadata FREEZING = new Null();
+
+    /**
+     * An unmodifiable copy of this metadata. Will be created only when first needed.
+     * If {@code null}, then no unmodifiable entity is available.
+     * If {@code this}, then this entity is itself unmodifiable.
+     */
+    private transient ModifiableMetadata unmodifiable;
+
+    /**
+     * Constructs an initially empty metadata.
+     */
+    protected ModifiableMetadata() {
+        super();
+    }
+
+    /**
+     * Constructs a metadata entity initialized with the values from the specified metadata.
+     * This constructor behavior is as in {@linkplain AbstractMetadata#AbstractMetadata(Object)
+     * superclass constructor}.
+     *
+     * @param  source The metadata to copy values from.
+     * @throws ClassCastException if the specified metadata don't implements the expected
+     *         metadata interface.
+     * @throws UnmodifiableMetadataException if this class don't define {@code set} methods
+     *         corresponding to the {@code get} methods found in the implemented interface,
+     *         or if this instance is not modifiable for some other reason.
+     */
+    protected ModifiableMetadata(final Object source)
+            throws ClassCastException, UnmodifiableMetadataException
+    {
+        super(source);
+    }
+
+    /**
+     * Returns {@code true} if this metadata is modifiable. This method returns
+     * {@code false} if {@link #freeze()} has been invoked on this object.
+     *
+     * @return {@code true} if this metadata is modifiable.
+     */
+    @Override
+    public final boolean isModifiable() {
+        return unmodifiable != this;
+    }
+
+    /**
+     * Returns an unmodifiable copy of this metadata. Any attempt to modify an attribute of the
+     * returned object will throw an {@link UnmodifiableMetadataException}. If this metadata is
+     * already unmodifiable, then this method returns {@code this}.
+     * <p>
+     * The default implementation {@linkplain #clone() clone} this metadata and
+     * {@linkplain #freeze() freeze} the clone before to return it.
+     *
+     * @return An unmodifiable copy of this metadata.
+     */
+    public synchronized AbstractMetadata unmodifiable() {
+        // Reminder: 'unmodifiable' is reset to null by checkWritePermission().
+        if (unmodifiable == null) {
+            final ModifiableMetadata candidate;
+            try {
+                /*
+                 * Need a SHALLOW copy of this metadata, because some attributes
+                 * may already be unmodifiable and we don't want to clone them.
+                 */
+                candidate = clone();
+            } catch (CloneNotSupportedException exception) {
+                /*
+                 * The metadata is not cloneable for some reason left to the user
+                 * (for example it may be backed by some external database).
+                 * Assumes that the metadata is unmodifiable.
+                 */
+                Logging.unexpectedException(LOGGER, exception);
+                return this;
+            }
+            candidate.freeze();
+            // Set the field only after success. The 'unmodifiable' field must
+            // stay null if an exception occured during clone() or freeze().
+            unmodifiable = candidate;
+        }
+        assert !unmodifiable.isModifiable();
+        return unmodifiable;
+    }
+
+    /**
+     * Returns an unmodifiable copy of the specified object. This method performs the
+     * following heuristic tests:
+     * <p>
+     * <ul>
+     *   <li>If the specified object is an instance of {@code ModifiableMetadata},
+     *       then {@link #unmodifiable()} is invoked on this object.</li>
+     *   <li>Otherwise, if the object is a {@linkplain Collection collection}, then the
+     *       content is copied into a new collection of similar type, with values replaced
+     *       by their unmodifiable variant.</li>
+     *   <li>Otherwise, if the object implements the {@link org.opengis.util.Cloneable}
+     *       interface, then a clone is returned.</li>
+     *   <li>Otherwise, the object is assumed immutable and returned unchanged.</li>
+     * </ul>
+     *
+     * @param  object The object to convert in an immutable one.
+     * @return A presumed immutable view of the specified object.
+     */
+    @SuppressWarnings("unchecked") // We really don't know the collection types.
+    static Object unmodifiable(final Object object) {
+        /*
+         * CASE 1 - The object is an implementation of ModifiableMetadata. It may have
+         *          its own algorithm for creating an unmodifiable view of metadata.
+         */
+        if (object instanceof ModifiableMetadata) {
+            return ((ModifiableMetadata) object).unmodifiable();
+        }
+        /*
+         * CASE 2 - The object is a collection. All elements are replaced by their
+         *          unmodifiable variant and stored in a new collection of similar
+         *          type.
+         */
+        if (object instanceof Collection) {
+            Collection<?> collection = (Collection) object;
+            if (collection.isEmpty()) {
+                if (collection instanceof List) {
+                    collection = Collections.EMPTY_LIST;
+                } else {
+                    collection = Collections.EMPTY_SET;
+                }
+            } else {
+                final Object[] array = collection.toArray();
+                for (int i=0; i<array.length; i++) {
+                    array[i] = unmodifiable(array[i]);
+                }
+                // Uses standard Java collections rather than Geotools Checked* classes,
+                // since we don't need anymore synchronization or type checking.
+                collection = UnmodifiableArrayList.wrap(array);
+                if (collection instanceof Set) {
+                    collection = Collections.unmodifiableSet(new LinkedHashSet<Object>(collection));
+                } else {
+                    // Conservatively assumes a List if we are not sure to have a Set,
+                    // since the list is less destructive (no removal of duplicated).
+                }
+            }
+            return collection;
+        }
+        /*
+         * CASE 3 - The object is a map. Copies all entries in a new map and replaces all values
+         *          by their unmodifiable variant. The keys are assumed already immutable.
+         */
+        if (object instanceof Map) {
+            Map map = (Map) object;
+            if (map.isEmpty()) {
+                return Collections.EMPTY_MAP;
+            }
+            map = new LinkedHashMap(map);
+            for (final Iterator<Map.Entry> it=map.entrySet().iterator(); it.hasNext();) {
+                final Map.Entry entry = it.next();
+                entry.setValue(unmodifiable(entry.getValue()));
+            }
+            return Collections.unmodifiableMap(map);
+        }
+        /*
+         * CASE 4 - The object is cloneable.
+         */
+        if (object instanceof org.opengis.util.Cloneable) {
+            return ((org.opengis.util.Cloneable) object).clone();
+        }
+        /*
+         * CASE 5 - Any other case. The object is assumed immutable and returned unchanged.
+         */
+        return object;
+    }
+
+    /**
+     * Declares this metadata and all its attributes as unmodifiable. This method is invoked
+     * automatically by the {@link #unmodifiable()} method. Subclasses usually don't need to
+     * override it since the default implementation performs its work using Java reflection.
+     */
+    public synchronized void freeze() {
+        ModifiableMetadata success = null;
+        try {
+            unmodifiable = FREEZING;
+            getStandard().freeze(this);
+            success = this;
+        } finally {
+            unmodifiable = success;
+        }
+    }
+
+    /**
+     * Checks if changes in the metadata are allowed. All {@code setFoo(...)} methods in
+     * subclasses should invoke this method (directly or indirectly) before to apply any
+     * change.
+     *
+     * @throws UnmodifiableMetadataException if this metadata is unmodifiable.
+     */
+    protected void checkWritePermission() throws UnmodifiableMetadataException {
+        assert Thread.holdsLock(this);
+        if (!isModifiable()) {
+            throw new UnmodifiableMetadataException(Errors.format(ErrorKeys.UNMODIFIABLE_METADATA));
+        }
+        invalidate();
+    }
+
+    /**
+     * Invoked when the metadata changed. Some cached informations will need
+     * to be recomputed.
+     */
+    @Override
+    final void invalidate() {
+        super.invalidate();
+        unmodifiable = null;
+    }
+
+    /**
+     * Tests if the specified collection is modifiable. This method should
+     * be used for assertions only since it destroy the collection content
+     * in case of assertion failure.
+     */
+    private static boolean isModifiable(final Collection collection) {
+        if (!collection.isEmpty()) try {
+            collection.clear();
+            return true;
+        } catch (UnsupportedOperationException e) {
+            // This is the expected exception.
+        }
+        return false;
+    }
+
+    /**
+     * Copies the content of one collection ({@code source}) into an other ({@code target}).
+     * If the target collection is {@code null}, or if its type ({@link List} vs {@link Set})
+     * doesn't matches the type of the source collection, a new target collection is created.
+     * <p>
+     * A call to {@link #checkWritePermission} is implicit before the copy is performed.
+     *
+     * @param  <E>         The type of elements in the collection.
+     * @param  source      The source collection. {@code null} is synonymous to empty.
+     * @param  target      The target collection, or {@code null} if not yet created.
+     * @param  elementType The base type of elements to put in the collection.
+     * @return {@code target}, or a newly created collection.
+     * @throws UnmodifiableMetadataException if this metadata is unmodifiable.
+     */
+    protected final <E> Collection<E> copyCollection(final Collection<? extends E> source,
+            Collection<E> target, final Class<E> elementType)
+            throws UnmodifiableMetadataException
+    {
+        if (unmodifiable == FREEZING) {
+            /*
+             * freeze() method is under progress. The source collection is already
+             * an unmodifiable instance created by unmodifiable(Object).
+             */
+            assert !isModifiable(source);
+            @SuppressWarnings("unchecked")
+            final Collection<E> unmodifiable = (Collection<E>) source;
+            return unmodifiable;
+        }
+        checkWritePermission();
+        /*
+         * It is not worth to copy the content if the current and the new instance are the
+         * same. This is safe only using the != operator, not the equals(Object) method.
+         * This optimization is required for efficient working of PropertyAccessor.set(...).
+         */
+        if (source != target) {
+            if (source == null) {
+                if (target != null) {
+                    target.clear();
+                }
+            } else {
+                final boolean isList = (source instanceof List);
+                if (target != null && (target instanceof List) == isList) {
+                    target.clear();
+                } else {
+                    int capacity = source.size();
+                    if (isList) {
+                        target = new MutableList<E>(elementType, capacity);
+                    } else {
+                        capacity = Math.round(capacity / 0.75f) + 1;
+                        target = new MutableSet<E>(elementType, capacity);
+                    }
+                }
+                target.addAll(source);
+            }
+        }
+        return target;
+    }
+
+    /**
+     * Returns the specified collection, or a new one if {@code c} is null.
+     * This is a convenience method for implementation of {@code getFoo()}
+     * methods.
+     *
+     * @param  <E> The type of elements in the collection.
+     * @param  c The collection to checks.
+     * @param  elementType The element type (used only if {@code c} is null).
+     * @return {@code c}, or a new collection if {@code c} is null.
+     */
+    protected final <E> Collection<E> nonNullCollection(
+            final Collection<E> c, final Class<E> elementType)
+    {
+        assert Thread.holdsLock(this);
+        if (c != null) {
+            return c;
+        }
+        if (isModifiable()) {
+            return new MutableSet<E>(elementType);
+        }
+        return Collections.emptySet();
+    }
+
+    /**
+     * A checked set synchronized on the enclosing {@link ModifiableMetadata}.
+     * Used for mutable sets only. Note that the lock most be modified after
+     * {@link #clone}. This is currently done in {@link #unmodifiable(Object)}.
+     */
+    private final class MutableSet<E> extends CheckedHashSet<E> {
+        private static final long serialVersionUID = 2337350768744454264L;
+
+        public MutableSet(Class<E> type) {
+            super(type);
+        }
+
+        public MutableSet(Class<E> type, int capacity) {
+            super(type, capacity);
+        }
+
+        @Override
+        protected Object getLock() {
+            return ModifiableMetadata.this;
+        }
+
+        @Override
+        protected void checkWritePermission() throws UnsupportedOperationException {
+            ModifiableMetadata.this.checkWritePermission();
+        }
+    }
+
+    /**
+     * A checked list synchronized on the enclosing {@link ModifiableMetadata}.
+     * Used for mutable lists only. Note that the lock most be modified after
+     * {@link #clone}. This is currently done in {@link #unmodifiable(Object)}.
+     */
+    private final class MutableList<E> extends CheckedArrayList<E> {
+        private static final long serialVersionUID = -5016778173550153002L;
+
+        public MutableList(Class<E> type) {
+            super(type);
+        }
+
+        public MutableList(Class<E> type, int capacity) {
+            super(type, capacity);
+        }
+
+        @Override
+        protected Object getLock() {
+            return ModifiableMetadata.this;
+        }
+
+        @Override
+        protected void checkWritePermission() throws UnsupportedOperationException {
+            ModifiableMetadata.this.checkWritePermission();
+        }
+    }
+
+    /**
+     * Returns a shallow copy of this metadata.
+     * <P>
+     * While {@linkplain Cloneable cloneable}, this class do not provides the {@code clone()}
+     * operation as part of the public API. The clone operation is required for the internal
+     * working of the {@link #unmodifiable()} method, which expect from {@code clone()} a
+     * <strong>shallow</strong> copy of this metadata entity. The default implementation of
+     * {@link Object#clone()} is suffisient for most use.
+     *
+     * @return A <strong>shallow</strong> copy of this metadata.
+     * @throws CloneNotSupportedException if the clone is not supported.
+     */
+    @Override
+    protected ModifiableMetadata clone() throws CloneNotSupportedException {
+        return (ModifiableMetadata) super.clone();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/PropertyAccessor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/PropertyAccessor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/PropertyAccessor.java	(revision 28000)
@@ -0,0 +1,806 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.metadata;
+
+import java.io.File;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URISyntaxException;
+import java.net.MalformedURLException;
+import java.util.LinkedHashSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.opengis.annotation.UML;
+import org.opengis.util.InternationalString;
+
+import org.geotools.util.Utilities;
+import org.geotools.resources.XArray;
+import org.geotools.resources.Classes;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.util.CheckedCollection;
+import org.geotools.util.SimpleInternationalString;
+
+
+/**
+ * The getters declared in a GeoAPI interface, together with setters (if any)
+ * declared in the Geotools implementation.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/PropertyAccessor.java $
+ * @version $Id: PropertyAccessor.java 31451 2008-09-08 08:27:50Z desruisseaux $
+ * @author Martin Desruisseaux
+ */
+final class PropertyAccessor {
+    /**
+     * The locale to use for changing character case.
+     */
+    private static final Locale LOCALE = Locale.US;
+
+    /**
+     * The prefix for getters on boolean values.
+     */
+    private static final String IS = "is";
+
+    /**
+     * The prefix for getters (general case).
+     */
+    private static final String GET = "get";
+
+    /**
+     * The prefix for setters.
+     */
+    private static final String SET = "set";
+
+    /**
+     * Methods to exclude from {@link #getGetters}. They are method inherited from
+     * {@link java.lang.Object}. Some of them, especially {@link Object#hashCode()}
+     * {@link Object#toString()} and {@link Object#clone()}, may be declared explicitly
+     * in some interface with a formal contract. Note: only no-argument methods need to
+     * be declared in this list.
+     */
+    private static final String[] EXCLUDES = {
+        "clone", "finalize", "getClass", "hashCode", "notify", "notifyAll", "toString", "wait"
+    };
+
+    /**
+     * Getters shared between many instances of this class. Two different implementations
+     * may share the same getters but different setters.
+     */
+    private static final Map<Class<?>, Method[]> SHARED_GETTERS = new HashMap<Class<?>, Method[]>();
+
+    /**
+     * The implemented metadata interface.
+     */
+    final Class<?> type;
+
+    /**
+     * The implementation class. The following condition must hold:
+     *
+     * <blockquote><pre>
+     * type.{@linkplain Class#isAssignableFrom isAssignableFrom}(implementation);
+     * </pre></blockquote>
+     */
+    final Class<?> implementation;
+
+    /**
+     * The getter methods. This array should not contain any null element.
+     */
+    private final Method[] getters;
+
+    /**
+     * The corresponding setter methods, or {@code null} if none. This array must have
+     * the same length than {@link #getters}. For every {@code getters[i]} element,
+     * {@code setters[i]} is the corresponding setter or {@code null} if there is none.
+     */
+    private final Method[] setters;
+
+    /**
+     * Index of getter or setter for a given name. The name must be all lower cases with
+     * conversion done using {@link #LOCALE}. This map must be considered as immutable
+     * after construction.
+     */
+    private final Map<String,Integer> mapping;
+
+    /**
+     * Creates a new property reader for the specified metadata implementation.
+     *
+     * @param  metadata The metadata implementation to wrap.
+     * @param  type The interface implemented by the metadata.
+     *         Should be the value returned by {@link #getType}.
+     */
+    PropertyAccessor(final Class<?> implementation, final Class<?> type) {
+        this.implementation = implementation;
+        this.type = type;
+        assert type.isAssignableFrom(implementation) : implementation;
+        getters = getGetters(type);
+        mapping = new HashMap<String,Integer>(getters.length + (getters.length + 3) / 4);
+        Method[] setters = null;
+        final Class<?>[] arguments = new Class[1];
+        for (int i=0; i<getters.length; i++) {
+            /*
+             * Fetch the getter and remind its name. We do the same for
+             * the UML tag attached to the getter, if any.
+             */
+            final Integer index = i;
+            Method getter  = getters[i];
+            String name    = getter.getName();
+            final int base = prefix(name).length();
+            addMapping(name.substring(base), index);
+            final UML annotation = getter.getAnnotation(UML.class);
+            if (annotation != null) {
+                addMapping(annotation.identifier(), index);
+            }
+            /*
+             * Now try to infer the setter from the getter. We replace the "get" prefix by
+             * "set" and look for a parameter of the same type than the getter return type.
+             */
+            Class<?> returnType = getter.getReturnType();
+            arguments[0] = returnType;
+            if (name.length() > base) {
+                final char lo = name.charAt(base);
+                final char up = Character.toUpperCase(lo);
+                if (lo != up) {
+                    name = SET + up + name.substring(base + 1);
+                } else {
+                    name = SET + name.substring(base);
+                }
+            }
+            Method setter;
+            try {
+                setter = implementation.getMethod(name, arguments);
+            } catch (NoSuchMethodException e) {
+                /*
+                 * If we found no setter method expecting an argument of the same type than the
+                 * argument returned by the GeoAPI method,  try again with the type returned by
+                 * the implementation class. It is typically the same type, but sometime it may
+                 * be a subtype.
+                 */
+                try {
+                    getter = implementation.getMethod(getter.getName(), (Class[]) null);
+                } catch (NoSuchMethodException error) {
+                    // Should never happen, since the implementation class
+                    // implements the the interface where the getter come from.
+                    throw new AssertionError(error);
+                }
+                if (returnType.equals(returnType = getter.getReturnType())) {
+                    continue;
+                }
+                arguments[0] = returnType;
+                try {
+                    setter = implementation.getMethod(name, arguments);
+                } catch (NoSuchMethodException ignore) {
+                    continue;
+                }
+            }
+            if (setters == null) {
+                setters = new Method[getters.length];
+            }
+            setters[i] = setter;
+        }
+        this.setters = setters;
+    }
+
+    /**
+     * Adds the given (name, index) pair to {@link #mapping}, making sure we don't
+     * overwrite an existing entry with different value.
+     */
+    private void addMapping(String name, final Integer index) throws IllegalArgumentException {
+        name = name.trim();
+        if (name.length() != 0) {
+            final String lower = name.toLowerCase(LOCALE);
+            final Integer old = mapping.put(lower, index);
+            if (old != null && !old.equals(index)) {
+                throw new IllegalArgumentException(Errors.format(
+                        ErrorKeys.PARAMETER_NAME_CLASH_$4, name, index, lower, old));
+            }
+        }
+    }
+
+    /**
+     * Returns the metadata interface implemented by the specified implementation.
+     * Only one metadata interface can be implemented.
+     *
+     * @param  metadata The metadata implementation to wraps.
+     * @param  interfacePackage The root package for metadata interfaces.
+     * @return The single interface, or {@code null} if none where found.
+     */
+    static Class<?> getType(Class<?> implementation, final String interfacePackage) {
+        if (implementation != null && !implementation.isInterface()) {
+            /*
+             * Gets every interfaces from the supplied package in declaration order,
+             * including the ones declared in the super-class.
+             */
+            final Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();
+            do {
+                getInterfaces(implementation, interfacePackage, interfaces);
+                implementation = implementation.getSuperclass();
+            } while (implementation != null);
+            /*
+             * If we found more than one interface, removes the
+             * ones that are sub-interfaces of the other.
+             */
+            for (final Iterator<Class<?>> it=interfaces.iterator(); it.hasNext();) {
+                final Class<?> candidate = it.next();
+                for (final Class<?> child : interfaces) {
+                    if (candidate != child && candidate.isAssignableFrom(child)) {
+                        it.remove();
+                        break;
+                    }
+                }
+            }
+            final Iterator<Class<?>> it=interfaces.iterator();
+            if (it.hasNext()) {
+                final Class<?> candidate = it.next();
+                if (!it.hasNext()) {
+                    return candidate;
+                }
+                // Found more than one interface; we don't know which one to pick.
+                // Returns 'null' for now; the caller will thrown an exception.
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Puts every interfaces for the given type in the specified collection.
+     * This method invokes itself recursively for scanning parent interfaces.
+     */
+    private static void getInterfaces(final Class<?> type, final String interfacePackage,
+            final Collection<Class<?>> interfaces)
+    {
+        for (final Class<?> candidate : type.getInterfaces()) {
+            if (candidate.getName().startsWith(interfacePackage)) {
+                interfaces.add(candidate);
+            }
+            getInterfaces(candidate, interfacePackage, interfaces);
+        }
+    }
+
+    /**
+     * Returns the getters. The returned array should never be modified,
+     * since it may be shared among many instances of {@code PropertyAccessor}.
+     *
+     * @param  type The metadata interface.
+     * @return The getters declared in the given interface (never {@code null}).
+     */
+    private static Method[] getGetters(final Class<?> type) {
+        synchronized (SHARED_GETTERS) {
+            Method[] getters = SHARED_GETTERS.get(type);
+            if (getters == null) {
+                getters = type.getMethods();
+                int count = 0;
+                for (int i=0; i<getters.length; i++) {
+                    final Method candidate = getters[i];
+                    if (candidate.getAnnotation(Deprecated.class) != null) {
+                        // Ignores deprecated methods.
+                        continue;
+                    }
+                    if (!candidate.getReturnType().equals(Void.TYPE) &&
+                         candidate.getParameterTypes().length == 0)
+                    {
+                        /*
+                         * We do not require a name starting with "get" or "is" prefix because some
+                         * methods do not begin with such prefix, as in "ConformanceResult.pass()".
+                         * Consequently we must provide special cases for no-arg methods inherited
+                         * from java.lang.Object because some interfaces declare explicitly the
+                         * contract for those methods.
+                         *
+                         * Note that testing candidate.getDeclaringClass().equals(Object.class)
+                         * is not suffisient because the method may be overriden in a subclass.
+                         */
+                        final String name = candidate.getName();
+                        if (!name.startsWith(SET) && !isExcluded(name)) {
+                            getters[count++] = candidate;
+                        }
+                    }
+                }
+                getters = XArray.resize(getters, count);
+                SHARED_GETTERS.put(type, getters);
+            }
+            return getters;
+        }
+    }
+
+    /**
+     * Returns {@code true} if the specified method is on the exclusion list.
+     */
+    private static boolean isExcluded(final String name) {
+        for (int i=0; i<EXCLUDES.length; i++) {
+            if (name.equals(EXCLUDES[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the prefix of the specified method name. If the method name don't starts with
+     * a prefix (for example {@link org.opengis.metadata.quality.ConformanceResult#pass()}),
+     * then this method returns an empty string.
+     */
+    private static String prefix(final String name) {
+        if (name.startsWith(GET)) {
+            return GET;
+        }
+        if (name.startsWith(IS)) {
+            return IS;
+        }
+        if (name.startsWith(SET)) {
+            return SET;
+        }
+        return "";
+    }
+
+    /**
+     * Returns the number of properties that can be read.
+     */
+    final int count() {
+        return getters.length;
+    }
+
+    /**
+     * Returns the index of the specified property, or -1 if none.
+     * The search is case-insensitive.
+     *
+     * @param  key The property to search.
+     * @return The index of the given key, or -1 if none.
+     */
+    final int indexOf(String key) {
+        key = key.trim().toLowerCase(LOCALE);
+        final Integer index = mapping.get(key);
+        return (index != null) ? index.intValue() : -1;
+    }
+
+    /**
+     * Always returns the index of the specified property (never -1).
+     * The search is case-insensitive.
+     *
+     * @param  key The property to search.
+     * @return The index of the given key.
+     * @throws IllegalArgumentException if the given key is not found.
+     */
+    final int requiredIndexOf(String key) throws IllegalArgumentException {
+        key = key.trim();
+        final Integer index = mapping.get(key.toLowerCase(LOCALE));
+        if (index != null) {
+            return index;
+        }
+        throw new IllegalArgumentException(Errors.format(ErrorKeys.UNKNOW_PARAMETER_NAME_$1, key));
+    }
+
+    /**
+     * Returns {@code true} if the specified string starting at the specified index contains
+     * no lower case characters. The characters don't have to be in upper case however (e.g.
+     * non-alphabetic characters)
+     */
+    private static boolean isAcronym(final String name, int offset) {
+        final int length = name.length();
+        while (offset < length) {
+            if (Character.isLowerCase(name.charAt(offset++))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns the name of the property at the given index, or {@code null} if none.
+     */
+    final String name(final int index) {
+        if (index >= 0 && index < getters.length) {
+            String name = getters[index].getName();
+            final int base = prefix(name).length();
+            /*
+             * Remove the "get" or "is" prefix and turn the first character after the
+             * prefix into lower case. For example the method name "getTitle" will be
+             * replaced by the property name "title". We will performs this operation
+             * only if there is at least 1 character after the prefix.
+             */
+            if (name.length() > base) {
+                if (isAcronym(name, base)) {
+                    name = name.substring(base);
+                } else {
+                    final char up = name.charAt(base);
+                    final char lo = Character.toLowerCase(up);
+                    if (up != lo) {
+                        name = lo + name.substring(base + 1);
+                    } else {
+                        name = name.substring(base);
+                    }
+                }
+            }
+            return name;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the value for the specified metadata, or {@code null} if none.
+     */
+    final Object get(final int index, final Object metadata) {
+        return (index >= 0 && index < getters.length) ? get(getters[index], metadata) : null;
+    }
+
+    /**
+     * Gets a value from the specified metadata. We do not expect any checked exception to
+     * be thrown, since {@code org.opengis.metadata} do not declare any.
+     *
+     * @param method The method to use for the query.
+     * @param metadata The metadata object to query.
+     */
+    private static Object get(final Method method, final Object metadata) {
+        assert !method.getReturnType().equals(Void.TYPE) : method;
+        try {
+            return method.invoke(metadata, (Object[]) null);
+        } catch (IllegalAccessException e) {
+            // Should never happen since 'getters' should contains only public methods.
+            throw new AssertionError(e);
+        } catch (InvocationTargetException e) {
+            final Throwable cause = e.getTargetException();
+            if (cause instanceof RuntimeException) {
+                throw (RuntimeException) cause;
+            }
+            if (cause instanceof Error) {
+                throw (Error) cause;
+            }
+            throw new UndeclaredThrowableException(cause);
+        }
+    }
+
+    /**
+     * Sets a value for the specified metadata.
+     *
+     * @param  index The index of the property to set.
+     * @param  metadata The metadata object on which to set the value.
+     * @param  value The new value.
+     * @return The old value.
+     * @throws IllegalArgumentException if the specified property can't be set.
+     * @throws ClassCastException if the given value is not of the expected type.
+     */
+    final Object set(final int index, final Object metadata, final Object value)
+            throws IllegalArgumentException, ClassCastException
+    {
+        String key;
+        if (index >= 0 && index < getters.length && setters != null) {
+            final Method getter = getters[index];
+            final Method setter = setters[index];
+            if (setter != null) {
+                final Object old = get(getter, metadata);
+                set(getter, setter, metadata, new Object[] {value});
+                return old;
+            } else {
+                key = getter.getName();
+                key = key.substring(prefix(key).length());
+            }
+        } else {
+            key = String.valueOf(index);
+        }
+        throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$1, key));
+    }
+
+    /**
+     * Sets a value for the specified metadata. We do not expect any checked exception to
+     * be thrown.
+     *
+     * @param getter The method to use for fetching the previous value.
+     * @param setter The method to use for setting the new value.
+     * @param metadata The metadata object to query.
+     * @param arguments The argument to give to the method to be invoked.
+     * @throws ClassCastException if at least one element of the {@code arguments} array
+     *         is not of the expected type.
+     */
+    private static void set(final Method getter, final Method setter,
+                            final Object metadata, final Object[] arguments)
+            throws ClassCastException
+    {
+        final Class<?>[] paramTypes = setter.getParameterTypes();
+        for (int i=0; i<paramTypes.length; i++) {
+            final Object argument = arguments[i];
+            if (argument == null) {
+                continue; // Null argument (which is valid): nothing to do.
+            }
+            final Class<?> paramType = paramTypes[i];
+            if (Classes.primitiveToWrapper(paramType).isInstance(argument)) {
+                continue; // Argument is of the expected type: nothing to do.
+            }
+            /*
+             * If an argument is not of the expected type, tries to convert it.
+             * We handle two cases:
+             *
+             *   - Strings to be converted to Number, File, URL, etc.
+             *   - Singleton to be added into an existing collection.
+             *
+             * We check for the collection case first in order to extract the element
+             * type, which will be used for String conversions (if applicable) later.
+             * The collections are handled in one of the two ways below:
+             *
+             *   - If the user gives a collection, the user's collection replaces any
+             *     previous one. The content of the previous collection is discarted.
+             *
+             *   - If the user gives a singleton, the single value is added to existing
+             *     collection (if any). The previous values are not discarted. This
+             *     allow for incremental filling of an attribute.
+             */
+            final Collection<?> addTo;
+            final Class<?> elementType;
+            if (Collection.class.isAssignableFrom(paramType) && !(argument instanceof Collection)) {
+                // Expected a collection but got a singleton.
+                addTo = (Collection) get(getter, metadata);
+                if (addTo instanceof CheckedCollection) {
+                    elementType = ((CheckedCollection) addTo).getElementType();
+                } else {
+                    Class<?> c = Classes.boundOfParameterizedAttribute(setter);
+                    if (c == null) {
+                        c = Classes.boundOfParameterizedAttribute(getter);
+                        if (c == null) {
+                            c = Object.class;
+                        }
+                    }
+                    elementType = c;
+                }
+            } else {
+                addTo = null;
+                elementType = paramType;
+            }
+            /*
+             * Handles the strings in a special way (converting to URI, URL, File,
+             * Number, etc.). If there is no known way to parse the string, or if
+             * the parsing failed, an exception is thrown.
+             */
+            Object parsed = null;
+            Exception failure = null;
+            if (elementType.isInstance(argument)) {
+                parsed = argument;
+            } else if (argument instanceof CharSequence) {
+                final String text = argument.toString();
+                if (InternationalString.class.isAssignableFrom(elementType)) {
+                    parsed = new SimpleInternationalString(text);
+                } else if (File.class.isAssignableFrom(elementType)) {
+                    parsed = new File(text);
+                } else if (URL.class.isAssignableFrom(elementType)) try {
+                    parsed = new URL(text);
+                } catch (MalformedURLException e) {
+                    failure = e;
+                } else if (URI.class.isAssignableFrom(elementType)) try {
+                    parsed = new URI(text);
+                } catch (URISyntaxException e) {
+                    failure = e;
+                } else try {
+                    parsed = Classes.valueOf(elementType, text);
+                } catch (RuntimeException e) {
+                    // Include IllegalArgumentException and NumberFormatException
+                    failure = e;
+                }
+            }
+            /*
+             * Checks if there is no known conversion, or if the conversion failed. In the later
+             * case the parse failure is saved as the cause. We still throw a ClassCastException
+             * since we get here because the argument was not of the expected type.
+             */
+            if (parsed == null) {
+                final ClassCastException e = new ClassCastException(Errors.format(
+                        ErrorKeys.ILLEGAL_CLASS_$2, argument.getClass(), elementType));
+                e.initCause(failure);
+                throw e;
+            }
+            /*
+             * We now have an object of the appropriate type. If this is a singleton to be added in
+             * an existing collection, add it now and set the new value to the whole collection. In
+             * the later case, we rely on ModifiableMetadata.copyCollection(...) optimization for
+             * detecting that the new collection is the same instance than the old one so there is
+             * nothing to do. We could exit from the method, but let it goes in case the user define
+             * (or override) the 'setFoo(...)' method in an other way.
+             */
+            if (addTo != null) {
+                addUnsafe(addTo, parsed);
+                parsed = addTo;
+            }
+            arguments[i] = parsed;
+        }
+        try {
+            setter.invoke(metadata, arguments);
+        } catch (IllegalAccessException e) {
+            // Should never happen since 'setters' should contains only public methods.
+            throw new AssertionError(e);
+        } catch (InvocationTargetException e) {
+            final Throwable cause = e.getTargetException();
+            if (cause instanceof RuntimeException) {
+                throw (RuntimeException) cause;
+            }
+            if (cause instanceof Error) {
+                throw (Error) cause;
+            }
+            throw new UndeclaredThrowableException(cause);
+        }
+    }
+
+    /**
+     * Unsafe addition into a collection. In GeoTools implementation, the collection is actually
+     * an instance of {@link CheckedCollection}, so the check will be performed at runtime.
+     * However other implementations could use unchecked collection. There is not much we can do.
+     */
+    @SuppressWarnings("unchecked")
+    private static void addUnsafe(final Collection<?> addTo, final Object element) {
+        ((Collection) addTo).add(element);
+    }
+
+    /**
+     * Compares the two specified metadata objects. The comparaison is <cite>shallow</cite>,
+     * i.e. all metadata attributes are compared using the {@link Object#equals} method without
+     * recursive call to this {@code shallowEquals} method for other metadata.
+     * <p>
+     * This method can optionaly excludes null values from the comparaison. In metadata,
+     * null value often means "don't know", so in some occasion we want to consider two
+     * metadata as different only if an attribute value is know for sure to be different.
+     *
+     * @param metadata1 The first metadata object to compare.
+     * @param metadata2 The second metadata object to compare.
+     * @param skipNulls If {@code true}, only non-null values will be compared.
+     */
+    public boolean shallowEquals(final Object metadata1, final Object metadata2, final boolean skipNulls) {
+        assert type.isInstance(metadata1) : metadata1;
+        assert type.isInstance(metadata2) : metadata2;
+        for (int i=0; i<getters.length; i++) {
+            final Method  method = getters[i];
+            final Object  value1 = get(method, metadata1);
+            final Object  value2 = get(method, metadata2);
+            final boolean empty1 = isEmpty(value1);
+            final boolean empty2 = isEmpty(value2);
+            if (empty1 && empty2) {
+                continue;
+            }
+            if (!Utilities.equals(value1, value2)) {
+                if (!skipNulls || (!empty1 && !empty2)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Copies all metadata from source to target. The source can be any implementation of
+     * the metadata interface, but the target must be the implementation expected by this
+     * class.
+     *
+     * @param  source The metadata to copy.
+     * @param  target The target metadata.
+     * @param  skipNulls If {@code true}, only non-null values will be copied.
+     * @return {@code true} in case of success, or {@code false} if at least
+     *         one setter method was not found.
+     * @throws UnmodifiableMetadataException if the target metadata is unmodifiable.
+     */
+    public boolean shallowCopy(final Object source, final Object target, final boolean skipNulls)
+            throws UnmodifiableMetadataException
+    {
+        boolean success = true;
+        assert type          .isInstance(source) : source;
+        assert implementation.isInstance(target) : target;
+        final Object[] arguments = new Object[1];
+        for (int i=0; i<getters.length; i++) {
+            final Method getter = getters[i];
+            arguments[0] = get(getter, source);
+            if (!skipNulls || !isEmpty(arguments[0])) {
+                if (setters == null) {
+                    return false;
+                }
+                final Method setter = setters[i];
+                if (setter != null) {
+                    set(getter, setter, target, arguments);
+                } else {
+                    success = false;
+                }
+            }
+        }
+        return success;
+    }
+
+    /**
+     * Replaces every properties in the specified metadata by their
+     * {@linkplain ModifiableMetadata#unmodifiable unmodifiable variant.
+     */
+    final void freeze(final Object metadata) {
+        assert implementation.isInstance(metadata) : metadata;
+        if (setters != null) {
+            final Object[] arguments = new Object[1];
+            for (int i=0; i<getters.length; i++) {
+                final Method setter = setters[i];
+                if (setter != null) {
+                    final Method getter = getters[i];
+                    final Object source = get(getter, metadata);
+                    final Object target = ModifiableMetadata.unmodifiable(source);
+                    if (source != target) {
+                        arguments[0] = target;
+                        set(getter, setter, metadata, arguments);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns {@code true} if the metadata is modifiable. This method is not public because it
+     * uses heuristic rules. In case of doubt, this method conservatively returns {@code true}.
+     */
+    final boolean isModifiable() {
+        if (setters != null) {
+            return true;
+        }
+        for (int i=0; i<getters.length; i++) {
+            // Immutable objects usually don't need to be cloned. So if
+            // an object is cloneable, it is probably not immutable.
+            if (Cloneable.class.isAssignableFrom(getters[i].getReturnType())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code for the specified metadata. The hash code is defined as the
+     * sum of hash code values of all non-null properties. This is the same contract than
+     * {@link java.util.Set#hashCode} and ensure that the hash code value is insensitive
+     * to the ordering of properties.
+     */
+    public int hashCode(final Object metadata) {
+        assert type.isInstance(metadata) : metadata;
+        int code = 0;
+        for (int i=0; i<getters.length; i++) {
+            final Object value = get(getters[i], metadata);
+            if (!isEmpty(value)) {
+                code += value.hashCode();
+            }
+        }
+        return code;
+    }
+
+    /**
+     * Counts the number of non-null properties.
+     */
+    public int count(final Object metadata, final int max) {
+        assert type.isInstance(metadata) : metadata;
+        int count = 0;
+        for (int i=0; i<getters.length; i++) {
+            if (!isEmpty(get(getters[i], metadata))) {
+                if (++count >= max) {
+                    break;
+                }
+            }
+        }
+        return count;
+    }
+
+    /**
+     * Returns {@code true} if the specified object is null or an empty collection,
+     * array or string.
+     */
+    static boolean isEmpty(final Object value) {
+        return value == null ||
+                ((value instanceof Collection) && ((Collection) value).isEmpty()) ||
+                ((value instanceof CharSequence) && value.toString().trim().length() == 0) ||
+                (value.getClass().isArray() && Array.getLength(value) == 0);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/PropertyMap.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/PropertyMap.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/PropertyMap.java	(revision 28000)
@@ -0,0 +1,337 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.metadata;
+
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.geotools.util.Utilities;
+
+
+/**
+ * A view of a metadata object as a map. Keys are property names and values
+ * are the value returned by the {@code getFoo()} method using reflection.
+ *
+ * @since 2.4
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/PropertyMap.java $
+ * @version $Id: PropertyMap.java 30852 2008-07-03 15:59:42Z desruisseaux $
+ * @author Martin Desruisseaux (Geomatys)
+ *
+ * @see MetadataStandard#asMap
+ */
+final class PropertyMap extends AbstractMap<String,Object> {
+    /**
+     * The metadata object to wrap.
+     */
+    private final Object metadata;
+
+    /**
+     * The accessor to use for the metadata.
+     */
+    private final PropertyAccessor accessor;
+
+    /**
+     * A view of the mappings contained in this map.
+     */
+    private final Set<Map.Entry<String,Object>> entrySet;
+
+    /**
+     * Creates a property map for the specified metadata and accessor.
+     */
+    public PropertyMap(final Object metadata, final PropertyAccessor accessor) {
+        this.metadata = metadata;
+        this.accessor = accessor;
+        entrySet = new Entries();
+    }
+
+    /**
+     * Returns {@code true} if this map contains no key-value mappings.
+     */
+    @Override
+    public boolean isEmpty() {
+        return entrySet().isEmpty();
+    }
+
+    /**
+     * Returns {@code true} if this map contains a mapping for the specified key.
+     */
+    @Override
+    public boolean containsKey(final Object key) {
+        return get(key) != null;
+    }
+
+    /**
+     * Returns the value to which the specified key is mapped, or {@code null}
+     * if this map contains no mapping for the key.
+     */
+    @Override
+    public Object get(final Object key) {
+        if (key instanceof String) {
+            final Object value = accessor.get(accessor.indexOf((String) key), metadata);
+            if (!PropertyAccessor.isEmpty(value)) {
+                return value;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Associates the specified value with the specified key in this map.
+     *
+     * @throws IllegalArgumentException if the specified property can't be set.
+     * @throws ClassCastException if the given value is not of the expected type.
+     */
+    @Override
+   public Object put(final String key, final Object value)
+            throws IllegalArgumentException, ClassCastException
+    {
+        return accessor.set(accessor.requiredIndexOf(key), metadata, value);
+    }
+
+    /**
+     * Removes the mapping for a key from this map if it is present.
+     */
+    @Override
+    public Object remove(final Object key) {
+        if (key instanceof String) {
+            return put((String) key, null);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns a view of the mappings contained in this map.
+     */
+    @Override
+    public Set<Map.Entry<String,Object>> entrySet() {
+        return entrySet;
+    }
+
+
+
+
+    /**
+     * A map entry for a given property.
+     *
+     * @author Martin Desruisseaux
+     */
+    private final class Property implements Map.Entry<String,Object> {
+        /**
+         * The property index.
+         */
+        final int index;
+
+        /**
+         * Creates an entry for the given property.
+         */
+        Property(final int index) {
+            this.index = index;
+        }
+
+        /**
+         * Creates an entry for the given property.
+         */
+        Property(final String property) {
+            index = accessor.indexOf(property);
+        }
+
+        /**
+         * Returns the key corresponding to this entry.
+         */
+        public String getKey() {
+            return accessor.name(index);
+        }
+
+        /**
+         * Returns the value corresponding to this entry.
+         */
+        public Object getValue() {
+            final Object value = accessor.get(index, metadata);
+            return PropertyAccessor.isEmpty(value) ? null : value;
+        }
+
+        /**
+         * Replaces the value corresponding to this entry with the specified value.
+         *
+         * @throws ClassCastException if the given value is not of the expected type.
+         */
+        public Object setValue(Object value) throws ClassCastException {
+            return accessor.set(index, metadata, value);
+        }
+
+        /**
+         * Compares the specified entry with this one for equality.
+         */
+        public boolean equals(final Map.Entry<?,?> entry) {
+            return Utilities.equals(getKey(),   entry.getKey()) &&
+                   Utilities.equals(getValue(), entry.getValue());
+        }
+
+        /**
+         * Compares the specified object with this entry for equality.
+         * Criterions are specified by the {@link Map.Entry} contract.
+         */
+        @Override
+        public boolean equals(final Object object) {
+            return (object instanceof Map.Entry) && equals((Map.Entry) object);
+        }
+
+        /**
+         * Returns the hash code value for this map entry. The
+         * formula is specified by the {@link Map.Entry} contract.
+         */
+        @Override
+        public int hashCode() {
+            Object x = getKey();
+            int code = (x != null) ? x.hashCode() : 0;
+            x = getValue();
+            if (x != null) {
+                code ^= x.hashCode();
+            }
+            return code;
+        }
+    }
+
+
+
+
+    /**
+     * The iterator over the {@link Property} elements contained in a {@link Entries} set.
+     *
+     * @author Martin Desruisseaux
+     */
+    private final class Iter implements Iterator<Map.Entry<String,Object>> {
+        /**
+         * The current and the next property, or {@code null} if the iteration is over.
+         */
+        private Property current, next;
+
+        /**
+         * Creates en iterator.
+         */
+        Iter() {
+            move(0);
+        }
+
+        /**
+         * Move {@link #next} to the first property with a valid value,
+         * starting at the specified index.
+         */
+        private void move(int index) {
+            final int count = accessor.count();
+            while (index < count) {
+                if (!PropertyAccessor.isEmpty(accessor.get(index, metadata))) {
+                    next = new Property(index);
+                    return;
+                }
+                index++;
+            }
+            next = null;
+        }
+
+        /**
+         * Returns {@code true} if the iteration has more elements.
+         */
+        public boolean hasNext() {
+            return next != null;
+        }
+
+        /**
+         * Returns the next element in the iteration.
+         */
+        public Map.Entry<String,Object> next() {
+            if (next != null) {
+                current = next;
+                move(next.index + 1);
+                return current;
+            } else {
+                throw new NoSuchElementException();
+            }
+        }
+
+        /**
+         * Removes from the underlying collection the last element returned by the iterator.
+         */
+        public void remove() {
+            if (current != null) {
+                current.setValue(null);
+                current = null;
+            } else {
+                throw new IllegalStateException();
+            }
+        }
+    }
+
+
+
+
+    /**
+     * View of the mapping contained in the map.
+     *
+     * @author Martin Desruisseaux
+     */
+    private final class Entries extends AbstractSet<Map.Entry<String,Object>> {
+        /**
+         * Creates an entry set.
+         */
+        Entries() {
+        }
+
+        /**
+         * Returns an iterator over the elements contained in this collection.
+         */
+        @Override
+        public Iterator<Map.Entry<String,Object>> iterator() {
+            return new Iter();
+        }
+
+        /**
+         * Returns the number of elements in this collection.
+         */
+        public int size() {
+            return accessor.count(metadata, Integer.MAX_VALUE);
+        }
+
+        /**
+         * Returns true if this collection contains no elements.
+         */
+        @Override
+        public boolean isEmpty() {
+            return accessor.count(metadata, 1) == 0;
+        }
+
+        /**
+         * Returns {@code true} if this collection contains the specified element.
+         */
+        @Override
+        public boolean contains(final Object object) {
+            if (object instanceof Map.Entry) {
+                final Map.Entry entry = (Map.Entry) object;
+                final Object key = entry.getKey();
+                if (key instanceof String) {
+                    return new Property((String) key).equals(entry);
+                }
+            }
+            return false;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/PropertyTree.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/PropertyTree.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/PropertyTree.java	(revision 28000)
@@ -0,0 +1,310 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.metadata;
+
+import java.text.DateFormat;
+import java.text.NumberFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+import java.util.Iterator;
+import java.util.Locale;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.MutableTreeNode;
+import javax.swing.tree.TreeNode;
+
+import org.opengis.util.CodeList;
+import org.opengis.util.InternationalString;
+import org.geotools.util.Utilities;
+import org.geotools.resources.Classes;
+import org.geotools.resources.OptionalDependencies;
+
+
+/**
+ * Represents the metadata property as a tree made from {@linkplain TreeNode tree nodes}.
+ * Note that while {@link TreeNode} is defined in the {@link javax.swing.tree} package,
+ * it can be seen as a data structure independent of Swing.
+ * <p>
+ * Note: this method is called {@code PropertyTree} because it may implements
+ * {@link javax.swing.tree.TreeModel} in some future Geotools implementation.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/PropertyTree.java $
+ * @version $Id: PropertyTree.java 30640 2008-06-12 17:34:32Z acuster $
+ * @author Martin Desruisseaux (Geomatys)
+ */
+final class PropertyTree {
+    /**
+     * The default number of significant digits (may or may not be fraction digits).
+     */
+    private static final int PRECISION = 12;
+
+    /**
+     * The expected standard implemented by the metadata.
+     */
+    private final MetadataStandard standard;
+
+    /**
+     * The locale to use for {@linkplain Date date}, {@linkplain Number number}
+     * and {@linkplain InternationalString international string} formatting.
+     */
+    private final Locale locale;
+
+    /**
+     * The object to use for formatting numbers.
+     * Will be created only when first needed.
+     */
+    private transient NumberFormat numberFormat;
+
+    /**
+     * The object to use for formatting dates.
+     * Will be created only when first needed.
+     */
+    private transient DateFormat dateFormat;
+
+    /**
+     * Creates a new tree builder using the default locale.
+     *
+     * @param standard The expected standard implemented by the metadata.
+     */
+    public PropertyTree(final MetadataStandard standard) {
+        this(standard, Locale.getDefault());
+    }
+
+    /**
+     * Creates a new tree builder.
+     *
+     * @param standard The expected standard implemented by the metadata.
+     * @param locale   The locale to use for {@linkplain Date date}, {@linkplain Number number}
+     *                 and {@linkplain InternationalString international string} formatting.
+     */
+    public PropertyTree(final MetadataStandard standard, final Locale locale) {
+        this.standard = standard;
+        this.locale   = locale;
+    }
+
+    /**
+     * Creates a tree for the specified metadata.
+     */
+    public MutableTreeNode asTree(final Object metadata) {
+        final String name = Classes.getShortName(standard.getInterface(metadata.getClass()));
+        final DefaultMutableTreeNode root =
+                OptionalDependencies.createTreeNode(localize(name), metadata, true);
+        append(root, metadata);
+        return root;
+    }
+
+    /**
+     * Appends the specified value to a branch. The value may be a metadata
+     * (treated {@linkplain AbstractMetadata#asMap as a Map} - see below),
+     * a collection or a singleton.
+     * <p>
+     * Map or metadata are constructed as a sub tree where every nodes is a
+     * property name, and the childs are the value(s) for that property.
+     */
+    private void append(final DefaultMutableTreeNode branch, final Object value) {
+        if (value instanceof Map) {
+            appendMap(branch, (Map) value);
+            return;
+        }
+        if (value instanceof AbstractMetadata) {
+            appendMap(branch, ((AbstractMetadata) value).asMap());
+            return;
+        }
+        if (value != null) {
+            final PropertyAccessor accessor = standard.getAccessorOptional(value.getClass());
+            if (accessor != null) {
+                appendMap(branch, new PropertyMap(value, accessor));
+                return;
+            }
+        }
+        if (value instanceof Collection) {
+            for (final Iterator it=((Collection) value).iterator(); it.hasNext();) {
+                final Object element = it.next();
+                if (!PropertyAccessor.isEmpty(element)) {
+                    append(branch, element);
+                }
+            }
+            return;
+        }
+        final String asText;
+        if (value instanceof CodeList) {
+            asText = localize((CodeList) value);
+        } else if (value instanceof Date) {
+            asText = format((Date) value);
+        } else if (value instanceof Number) {
+            asText = format((Number) value);
+        } else if (value instanceof InternationalString) {
+            asText = ((InternationalString) value).toString(locale);
+        } else {
+            asText = String.valueOf(value);
+        }
+        branch.add(OptionalDependencies.createTreeNode(asText, value, false));
+    }
+
+    /**
+     * Appends the specified map (usually a metadata) to a branch. Each map keys
+     * is a child in the specified {@code branch}, and each value is a child of
+     * the map key. There is often only one value for a map key, but not always;
+     * some are collections, which are formatted as many childs for the same key.
+     */
+    private void appendMap(final DefaultMutableTreeNode branch, final Map asMap) {
+        for (final Iterator it=asMap.entrySet().iterator(); it.hasNext();) {
+            final Map.Entry entry = (Map.Entry) it.next();
+            final Object value = entry.getValue();
+            if (!PropertyAccessor.isEmpty(value)) {
+                final String name = localize((String) entry.getKey());
+                final DefaultMutableTreeNode child =
+                        OptionalDependencies.createTreeNode(name, value, true);
+                append(child, value);
+                branch.add(child);
+            }
+        }
+    }
+
+    /**
+     * Formats the specified number.
+     */
+    private String format(final Number value) {
+        if (numberFormat == null) {
+            numberFormat = NumberFormat.getNumberInstance(locale);
+            numberFormat.setMinimumFractionDigits(0);
+        }
+        int precision = 0;
+        if (!Classes.isInteger(value.getClass())) {
+            precision = PRECISION;
+            final double v = Math.abs(value.doubleValue());
+            if (v > 0) {
+                final int digits = (int) Math.log10(v);
+                if (Math.abs(digits) >= PRECISION) {
+                    // TODO: Switch to exponential notation when a convenient API will be available in J2SE.
+                    return value.toString();
+                }
+                if (digits >= 0) {
+                    precision -= digits;
+                }
+                precision = Math.max(0, PRECISION - precision);
+            }
+        }
+        numberFormat.setMaximumFractionDigits(precision);
+        return numberFormat.format(value);
+    }
+
+    /**
+     * Formats the specified date.
+     */
+    private String format(final Date value) {
+        if (dateFormat == null) {
+            dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
+        }
+        return dateFormat.format(value);
+    }
+
+    /**
+     * Localize the specified property name. In current version, this is merely
+     * a hook for future development. For now we reformat the programatic name.
+     */
+    private String localize(String name) {
+        name = name.trim();
+        final int length = name.length();
+        if (length != 0) {
+            final StringBuilder buffer = new StringBuilder();
+            buffer.append(Character.toUpperCase(name.charAt(0)));
+            boolean previousIsUpper = true;
+            int base = 1;
+            for (int i=1; i<length; i++) {
+                final boolean currentIsUpper = Character.isUpperCase(name.charAt(i));
+                if (currentIsUpper != previousIsUpper) {
+                    /*
+                     * When a case change is detected (lower case to upper case as in "someName",
+                     * or "someURL", or upper case to lower case as in "HTTPProxy"), then insert
+                     * a space just before the upper case letter.
+                     */
+                    int split = i;
+                    if (previousIsUpper) {
+                        split--;
+                    }
+                    if (split > base) {
+                        buffer.append(name.substring(base, split)).append(' ');
+                        base = split;
+                    }
+                }
+                previousIsUpper = currentIsUpper;
+            }
+            final String candidate = buffer.append(name.substring(base)).toString();
+            if (!candidate.equals(name)) {
+                // Holds a reference to this new String object only if it worth it.
+                name = candidate;
+            }
+        }
+        return name;
+    }
+
+    /**
+     * Localize the specified property name. In current version, this is merely
+     * a hook for future development.  For now we reformat the programatic name.
+     */
+    private String localize(final CodeList code) {
+        return code.name().trim().replace('_', ' ').toLowerCase(locale);
+    }
+
+    /**
+     * Returns a string representation of the specified tree node.
+     */
+    public static String toString(final TreeNode node) {
+        final StringBuilder buffer = new StringBuilder();
+        toString(node, buffer, 0, System.getProperty("line.separator", "\n"));
+        return buffer.toString();
+    }
+
+    /**
+     * Append a string representation of the specified node to the specified buffer.
+     */
+    private static void toString(final TreeNode      node,
+                                 final StringBuilder buffer,
+                                 final int           indent,
+                                 final String        lineSeparator)
+    {
+        final int count = node.getChildCount();
+        if (count == 0) {
+            if (node.isLeaf()) {
+                /*
+                 * If the node has no child and is a leaf, then it is some value like a number,
+                 * a date or a string.  We just display this value, which is usually part of a
+                 * collection. If the node has no child and is NOT a leaf, then it is an empty
+                 * metadata and we just ommit it.
+                 */
+                buffer.append(Utilities.spaces(indent)).append(node).append(lineSeparator);
+            }
+            return;
+        }
+        buffer.append(Utilities.spaces(indent)).append(node).append(':');
+        if (count == 1) {
+            final TreeNode child = node.getChildAt(0);
+            if (child.isLeaf()) {
+                buffer.append(' ').append(child).append(lineSeparator);
+                return;
+            }
+        }
+        for (int i=0; i<count; i++) {
+            final TreeNode child = node.getChildAt(i);
+            if (i == 0) {
+                buffer.append(lineSeparator);
+            }
+            toString(child, buffer, indent+2, lineSeparator);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/UnmodifiableMetadataException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/UnmodifiableMetadataException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/UnmodifiableMetadataException.java	(revision 28000)
@@ -0,0 +1,44 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.metadata;
+
+
+/**
+ * Thrown when a setter method is invoked on a {@linkplain org.geotools.metadata.iso.MetadataEntity
+ * metadata entity}, but this entity was declared unmodifiable.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/UnmodifiableMetadataException.java $
+ * @version $Id: UnmodifiableMetadataException.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (Geomatys)
+ */
+public class UnmodifiableMetadataException extends UnsupportedOperationException {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -1885135341334523675L;
+
+    /**
+     * Creates a new exception with the specified detail message.
+     *
+     * @param message The detail message.
+     */
+    public UnmodifiableMetadataException(final String message) {
+        super(message);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/IdentifierImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/IdentifierImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/IdentifierImpl.java	(revision 28000)
@@ -0,0 +1,102 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso;
+
+import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.Citation;
+
+
+/**
+ * Value uniquely identifying an object within a namespace.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/IdentifierImpl.java $
+ * @version $Id: IdentifierImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Touraïvane
+ *
+ * @since 2.1
+ */
+public class IdentifierImpl extends MetadataEntity implements Identifier {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 7459062382170865919L;
+
+    /**
+     * Alphanumeric value identifying an instance in the namespace.
+     */
+    private String code;
+
+    /**
+     * Organization or party responsible for definition and maintenance of the
+     * {@linkplain #getCode code}.
+     */
+    private Citation authority;
+
+    /**
+     * Construct an initially empty identifier.
+     */
+    public IdentifierImpl() {
+    }
+
+    /**
+     * Creates an identifier initialized to the given code.
+     */
+    public IdentifierImpl(final String code) {
+        setCode(code);
+    }
+
+    /**
+     * Alphanumeric value identifying an instance in the namespace.
+     *
+     * @return The code.
+     */
+    public String getCode() {
+        return code;
+    }
+
+    /**
+     * Set the alphanumeric value identifying an instance in the namespace.
+     */
+    public synchronized void setCode(final String newValue) {
+        checkWritePermission();
+        code = newValue;
+    }
+
+    /**
+     * Organization or party responsible for definition and maintenance of the
+     * {@linkplain #getCode code}.
+     *
+     * @return The authority, or {@code null} if not available.
+     */
+    public Citation getAuthority() {
+        return authority;
+    }
+
+    /**
+     * Set the organization or party responsible for definition and maintenance of the
+     * {@linkplain #getCode code}.
+     */
+    public synchronized void setAuthority(final Citation newValue) {
+        checkWritePermission();
+        authority = newValue;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/MetadataEntity.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/MetadataEntity.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/MetadataEntity.java	(revision 28000)
@@ -0,0 +1,94 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.metadata.iso;
+
+import java.io.Serializable;
+
+import org.geotools.metadata.MetadataStandard;
+import org.geotools.metadata.ModifiableMetadata;
+import org.geotools.metadata.InvalidMetadataException;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * A superclass for implementing ISO 19115 metadata interfaces. Subclasses
+ * must implement at least one of the ISO MetaData interface provided by
+ * <A HREF="http://geoapi.sourceforge.net">GeoAPI</A>.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/MetadataEntity.java $
+ * @version $Id: MetadataEntity.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Jody Garnett
+ * @author Martin Desruisseaux
+ */
+public class MetadataEntity extends ModifiableMetadata implements Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 5730550742604669102L;
+
+    /**
+     * Constructs an initially empty metadata entity.
+     */
+    protected MetadataEntity() {
+        super();
+    }
+
+    /**
+     * Constructs a metadata entity initialized with the values from the specified metadata.
+     * The {@code source} metadata must implements the same metadata interface than this class.
+     *
+     * @param  source The metadata to copy values from.
+     * @throws ClassCastException if the specified metadata don't implements the expected
+     *         metadata interface.
+     *
+     * @since 2.4
+     */
+    protected MetadataEntity(final Object source) throws ClassCastException {
+        super(source);
+    }
+
+    /**
+     * Returns the metadata standard implemented by subclasses,
+     * which is {@linkplain MetadataStandard#ISO_19115 ISO 19115}.
+     *
+     * @since 2.4
+     */
+    public MetadataStandard getStandard() {
+        return MetadataStandard.ISO_19115;
+    }
+
+    /**
+     * Makes sure that an argument is non-null. This is used for checking if
+     * a mandatory attribute is presents.
+     *
+     * @param  name   Argument name.
+     * @param  object User argument.
+     * @throws InvalidMetadataException if {@code object} is null.
+     *
+     * @since 2.4
+     */
+    protected static void ensureNonNull(final String name, final Object object)
+            throws InvalidMetadataException
+    {
+        if (object == null) {
+            throw new InvalidMetadataException(Errors.format(ErrorKeys.NULL_ATTRIBUTE_$1, name));
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/CitationImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/CitationImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/CitationImpl.java	(revision 28000)
@@ -0,0 +1,404 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso.citation;
+
+import java.util.Collection;
+import java.util.Date;
+import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.metadata.citation.CitationDate;
+import org.opengis.metadata.citation.PresentationForm;
+import org.opengis.metadata.citation.ResponsibleParty;
+import org.opengis.metadata.citation.Series;
+import org.opengis.util.InternationalString;
+import org.geotools.metadata.iso.MetadataEntity;
+import org.geotools.metadata.iso.IdentifierImpl;
+import org.geotools.util.SimpleInternationalString;
+
+
+/**
+ * Standardized resource reference.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/citation/CitationImpl.java $
+ * @version $Id: CitationImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Jody Garnett
+ */
+public class CitationImpl extends MetadataEntity implements Citation {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -4415559967618358778L;
+
+    /**
+     * Name by which the cited resource is known.
+     */
+    private InternationalString title;
+
+    /**
+     * Short name or other language name by which the cited information is known.
+     * Example: "DCW" as an alternative title for "Digital Chart of the World.
+     */
+    private Collection<InternationalString> alternateTitles;
+
+    /**
+     * Reference date for the cited resource.
+     */
+    private Collection<CitationDate> dates;
+
+    /**
+     * Version of the cited resource.
+     */
+    private InternationalString edition;
+
+    /**
+     * Date of the edition in millisecondes ellapsed sine January 1st, 1970,
+     * or {@link Long#MIN_VALUE} if none.
+     */
+    private long editionDate = Long.MIN_VALUE;
+
+    /**
+     * Unique identifier for the resource. Example: Universal Product Code (UPC),
+     * National Stock Number (NSN).
+     */
+    private Collection<Identifier> identifiers;
+
+    /**
+     * Name and position information for an individual or organization that is responsible
+     * for the resource. Returns an empty string if there is none.
+     */
+    private Collection<ResponsibleParty> citedResponsibleParties;
+
+    /**
+     * Mode in which the resource is represented, or an empty string if none.
+     */
+    private Collection<PresentationForm> presentationForm;
+
+    /**
+     * Information about the series, or aggregate dataset, of which the dataset is a part.
+     * May be {@code null} if none.
+     */
+    private Series series;
+
+    /**
+     * Other information required to complete the citation that is not recorded elsewhere.
+     * May be {@code null} if none.
+     */
+    private InternationalString otherCitationDetails;
+
+    /**
+     * Common title with holdings note. Note: title identifies elements of a series
+     * collectively, combined with information about what volumes are available at the
+     * source cited. May be {@code null} if there is no title.
+     */
+    private InternationalString collectiveTitle;
+
+    /**
+     * International Standard Book Number, or {@code null} if none.
+     */
+    private String ISBN;
+
+    /**
+     * International Standard Serial Number, or {@code null} if none.
+     */
+    private String ISSN;
+
+    /**
+     * Constructs an initially empty citation.
+     */
+    public CitationImpl() {
+    }
+
+    /**
+     * Constructs a new citation initialized to the values specified by the given object.
+     * This constructor performs a shallow copy (i.e. each source attributes are reused
+     * without copying them).
+     */
+    public CitationImpl(final Citation source) {
+        super(source);
+    }
+
+    /**
+     * Constructs a citation with the specified title.
+     *
+     * @param title The title, as a {@link String} or an {@link InternationalString} object.
+     */
+    public CitationImpl(final CharSequence title) {
+        final InternationalString t;
+        if (title instanceof InternationalString) {
+            t = (InternationalString) title;
+        } else {
+            t = new SimpleInternationalString(title.toString());
+        }
+        setTitle(t);
+    }
+
+    /**
+     * Constructs a citation with the specified responsible party. This convenience constructor
+     * initialize the citation title to the first non-null of the following properties:
+     * {@linkplain ResponsibleParty#getOrganisationName organisation name},
+     * {@linkplain ResponsibleParty#getPositionName position name} or
+     * {@linkplain ResponsibleParty#getIndividualName individual name}.
+     *
+     * @since 2.2
+     */
+    public CitationImpl(final ResponsibleParty party) {
+        InternationalString title = party.getOrganisationName();
+        if (title == null) {
+            title = party.getPositionName();
+            if (title == null) {
+                String name = party.getIndividualName();
+                if (name != null) {
+                    title = new SimpleInternationalString(name);
+                }
+            }
+        }
+        setTitle(title);
+        getCitedResponsibleParties().add(party);
+    }
+
+    /**
+     * Adds the specified identifier as a CRS authority factory. This is used as a convenience
+     * method for the creation of constants, and for making sure that all of them use the same
+     * identifier type.
+     */
+    final void addAuthority(final String identifier, final boolean asTitle) {
+        if (asTitle) {
+            getAlternateTitles().add(new SimpleInternationalString(identifier));
+        }
+        getIdentifiers().add(new IdentifierImpl(identifier));
+    }
+
+    /**
+     * Returns the name by which the cited resource is known.
+     */
+    public InternationalString getTitle() {
+        return title;
+    }
+
+    /**
+     * Set the name by which the cited resource is known.
+     */
+    public synchronized void setTitle(final InternationalString newValue) {
+        checkWritePermission();
+        title = newValue;
+    }
+
+    /**
+     * Returns the short name or other language name by which the cited information is known.
+     * Example: "DCW" as an alternative title for "Digital Chart of the World".
+     */
+    public synchronized Collection<InternationalString> getAlternateTitles() {
+        return (alternateTitles = nonNullCollection(alternateTitles, InternationalString.class));
+    }
+
+    /**
+     * Set the short name or other language name by which the cited information is known.
+     */
+    public synchronized void setAlternateTitles(
+            final Collection<? extends InternationalString> newValues)
+    {
+        alternateTitles = copyCollection(newValues, alternateTitles, InternationalString.class);
+    }
+
+    /**
+     * Returns the reference date for the cited resource.
+     */
+    public synchronized Collection<CitationDate> getDates() {
+        return dates = nonNullCollection(dates, CitationDate.class);
+    }
+
+    /**
+     * Set the reference date for the cited resource.
+     */
+    public synchronized void setDates(final Collection<? extends CitationDate> newValues) {
+        dates = copyCollection(newValues, dates, CitationDate.class);
+    }
+
+    /**
+     * Returns the version of the cited resource.
+     */
+    public InternationalString getEdition() {
+        return edition;
+    }
+
+    /**
+     * Set the version of the cited resource.
+     */
+    public synchronized void setEdition(final InternationalString newValue) {
+        checkWritePermission();
+        edition = newValue;
+    }
+
+    /**
+     * Returns the date of the edition, or {@code null} if none.
+     */
+    public synchronized Date getEditionDate() {
+        return (editionDate!=Long.MIN_VALUE) ? new Date(editionDate) : null;
+    }
+
+    /**
+     * Set the date of the edition, or {@code null} if none.
+     *
+     * @todo Use an unmodifiable {@link Date} here.
+     */
+    public synchronized void setEditionDate(final Date newValue) {
+        checkWritePermission();
+        editionDate = (newValue!=null) ? newValue.getTime() : Long.MIN_VALUE;
+    }
+
+    /**
+     * Returns the unique identifier for the resource. Example: Universal Product Code (UPC),
+     * National Stock Number (NSN).
+     */
+    public synchronized Collection<Identifier> getIdentifiers() {
+        return (identifiers = nonNullCollection(identifiers, Identifier.class));
+    }
+
+    /**
+     * Set the unique identifier for the resource. Example: Universal Product Code (UPC),
+     * National Stock Number (NSN).
+     */
+    public synchronized void setIdentifiers(final Collection<? extends Identifier> newValues) {
+        identifiers = copyCollection(newValues, identifiers, Identifier.class);
+    }
+
+    /**
+     * Returns the name and position information for an individual or organization that is
+     * responsible for the resource. Returns an empty string if there is none.
+     */
+    public synchronized Collection<ResponsibleParty> getCitedResponsibleParties() {
+        return (citedResponsibleParties = nonNullCollection(citedResponsibleParties,
+                ResponsibleParty.class));
+    }
+
+    /**
+     * Set the name and position information for an individual or organization that is responsible
+     * for the resource. Returns an empty string if there is none.
+     */
+    public synchronized void setCitedResponsibleParties(
+            final Collection<? extends ResponsibleParty> newValues)
+    {
+        citedResponsibleParties = copyCollection(newValues, citedResponsibleParties,
+                                                 ResponsibleParty.class);
+    }
+
+    /**
+     * Returns the mode in which the resource is represented, or an empty string if none.
+     */
+    public synchronized Collection<PresentationForm> getPresentationForm() {
+        return (presentationForm = nonNullCollection(presentationForm, 
+                PresentationForm.class));
+    }
+
+    /**
+     * Set the mode in which the resource is represented, or an empty string if none.
+     */
+    public synchronized void setPresentationForm(
+            final Collection<? extends PresentationForm> newValues)
+    {
+        presentationForm = copyCollection(newValues, presentationForm, PresentationForm.class);
+    }
+
+    /**
+     * Returns the information about the series, or aggregate dataset, of which the dataset is
+     * a part. Returns {@code null} if none.
+     */
+    public Series getSeries() {
+        return series;
+    }
+
+    /**
+     * Set the information about the series, or aggregate dataset, of which the dataset is
+     * a part. Set to {@code null} if none.
+     */
+    public synchronized void setSeries(final Series newValue) {
+        checkWritePermission();
+        series = newValue;
+    }
+
+    /**
+     * Returns other information required to complete the citation that is not recorded elsewhere.
+     * Returns {@code null} if none.
+     */
+    public InternationalString getOtherCitationDetails() {
+        return otherCitationDetails;
+    }
+
+    /**
+     * Set other information required to complete the citation that is not recorded elsewhere.
+     * Set to {@code null} if none.
+     */
+    public synchronized void setOtherCitationDetails(final InternationalString newValue) {
+        checkWritePermission();
+        otherCitationDetails = newValue;
+    }
+
+    /**
+     * Returns the common title with holdings note. Note: title identifies elements of a series
+     * collectively, combined with information about what volumes are available at the
+     * source cited. Returns {@code null} if there is no title.
+     */
+    public InternationalString getCollectiveTitle() {
+        return collectiveTitle;
+    }
+
+    /**
+     * Set the common title with holdings note. Note: title identifies elements of a series
+     * collectively, combined with information about what volumes are available at the
+     * source cited. Set to {@code null} if there is no title.
+     */
+    public synchronized void setCollectiveTitle(final InternationalString newValue) {
+        checkWritePermission();
+        collectiveTitle = newValue;
+    }
+
+    /**
+     * Returns the International Standard Book Number, or {@code null} if none.
+     */
+    public String getISBN() {
+        return ISBN;
+    }
+
+    /**
+     * Set the International Standard Book Number, or {@code null} if none.
+     */
+    public synchronized void setISBN(final String newValue) {
+        checkWritePermission();
+        ISBN = newValue;
+    }
+
+    /**
+     * Returns the International Standard Serial Number, or {@code null} if none.
+     */
+    public String getISSN() {
+        return ISSN;
+    }
+
+    /**
+     * Set the International Standard Serial Number, or {@code null} if none.
+     */
+    public synchronized void setISSN(final String newValue) {
+        checkWritePermission();
+        ISSN = newValue;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/Citations.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/Citations.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/Citations.java	(revision 28000)
@@ -0,0 +1,565 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso.citation;
+
+import java.util.Collection;
+import java.util.Iterator;
+import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.metadata.citation.OnLineFunction;
+import org.opengis.metadata.citation.PresentationForm;
+import org.opengis.metadata.citation.ResponsibleParty;
+import org.opengis.metadata.citation.Role;
+import org.opengis.util.InternationalString;
+import org.geotools.util.SimpleInternationalString;
+
+
+/**
+ * A set of pre-defined constants and static methods working on {@linkplain Citation citations}.
+ * Pre-defined metadata constants are usually declared in implementation classes like
+ * {@link ResponsiblePartyImpl}. But citations are an exception since they are extensively
+ * referenced in the Geotools library, and handling citations requires some convenience methods.
+ * They are factored out in this {@code Citations} class for clarity.
+ * <p>
+ * Citations may be about an <cite>organisation</cite> (e.g. {@linkplain #OPEN_GIS OpenGIS}),
+ * a <cite>specification</cite> (e.g. {@linkplain #WMS}) or an <cite>authority</cite> that
+ * maintains definitions of codes (e.g. {@linkplain #EPSG}). In the later case, the citation
+ * contains an {@linkplain Citation#getIdentifiers identifier} which is the namespace of the
+ * codes maintained by the authority. For example the identifier for the {@link #EPSG} citation
+ * is {@code "EPSG"}, and EPSG codes look like {@code "EPSG:4326"}.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/citation/Citations.java $
+ * @version $Id: Citations.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Jody Garnett
+ *
+ * @todo Classify the pre-defined constants using the javadoc {@code @category} tag
+ *       once it will be available (targeted for J2SE 1.6).
+ */
+public final class Citations {
+    /**
+     * Do not allows instantiation of this class.
+     */
+    private Citations() {
+    }
+
+
+
+
+    ///////////////////////////////////////////////////////////////////////
+    ////////                                                       ////////
+    ////////               O R G A N I S A T I O N S               ////////
+    ////////                                                       ////////
+    ///////////////////////////////////////////////////////////////////////
+
+    /**
+     * The <A HREF="http://www.opengeospatial.org">Open Geospatial consortium</A> organisation.
+     * "Open Geospatial consortium" is the new name for "OpenGIS consortium".
+     * An {@linkplain Citation#getAlternateTitles alternate title} for this citation is "OGC"
+     * (according ISO 19115, alternate titles often contain abreviations).
+     *
+     * @see ResponsiblePartyImpl#OGC
+     * @see #OPEN_GIS
+     */
+    public static final Citation OGC;
+    static {
+        final CitationImpl c = new CitationImpl(ResponsiblePartyImpl.OGC);
+        c.getAlternateTitles().add(new SimpleInternationalString("OGC"));
+        // NOTE: all OGC alternate titles will be copied in OPEN_GIS as well.
+        c.getPresentationForm().add(PresentationForm.DOCUMENT_DIGITAL);
+        c.freeze();
+        OGC = c;
+    }
+
+    /**
+     * The <A HREF="http://www.opengis.org">OpenGIS consortium</A> organisation.
+     * "OpenGIS consortium" is the old name for "Open Geospatial consortium".
+     * {@linkplain Citation#getAlternateTitles Alternate titles} for this citation are
+     * "OpenGIS" and "OGC" (according ISO 19115, alternate titles often contain abreviations).
+     *
+     * @see ResponsiblePartyImpl#OPEN_GIS
+     * @see #OGC
+     */
+    public static final Citation OPEN_GIS;
+    static {
+        final CitationImpl c = new CitationImpl(ResponsiblePartyImpl.OPEN_GIS);
+        final Collection<InternationalString> alt = c.getAlternateTitles();
+        alt.add(new SimpleInternationalString("OpenGIS"));
+        alt.addAll(OGC.getAlternateTitles());
+        c.getPresentationForm().add(PresentationForm.DOCUMENT_DIGITAL);
+        c.freeze();
+        OPEN_GIS = c;
+    }
+
+    /**
+     * The <A HREF="http://www.esri.com">ESRI</A> organisation.
+     *
+     * @see ResponsiblePartyImpl#ESRI
+     */
+    public static final Citation ESRI;
+    static {
+        final CitationImpl c = new CitationImpl(ResponsiblePartyImpl.ESRI);
+        c.addAuthority("ESRI", true);
+        c.freeze();
+        ESRI = c;
+    }
+
+    /**
+     * The <A HREF="http://www.oracle.com">Oracle</A> organisation.
+     *
+     * @see ResponsiblePartyImpl#ORACLE
+     */
+    public static final Citation ORACLE;
+    static {
+        final CitationImpl c = new CitationImpl(ResponsiblePartyImpl.ORACLE);
+        c.freeze();
+        ORACLE = c;
+    }
+
+    /**
+     * The <A HREF="http://www.geotools.org">Geotools</A> project.
+     *
+     * @see ResponsiblePartyImpl#GEOTOOLS
+     */
+    public static final Citation GEOTOOLS;
+    static {
+        final CitationImpl c = new CitationImpl(ResponsiblePartyImpl.GEOTOOLS);
+        c.freeze();
+        GEOTOOLS = c;
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    ////////                                                       ////////
+    ////////              S P E C I F I C A T I O N S              ////////
+    ////////                                                       ////////
+    ///////////////////////////////////////////////////////////////////////
+
+    // Do not put the ...files/?artifact... link in the head sentence: it break javadoc formatting.
+    /**
+     * The Web Map Service specification. {@linkplain Citation#getAlternateTitles Alternate titles}
+     * for this citation are "WMS", "WMS 1.3.0", "OGC 04-024" and "ISO 19128". Note that the
+     * version numbers may be upgrated in future Geotools versions.
+     *
+     * @see <A HREF="http://www.opengeospatial.org/">Open Geospatial Consortium</A>
+     * @see <A HREF="http://www.opengis.org/docs/01-068r3.pdf">WMS 1.1.1 specification</A>
+     * @see <A HREF="http://portal.opengis.org/files/?artifact_id=5316">WMS 1.3.0 specification</A>
+     * @see ResponsiblePartyImpl#OGC
+     * @see OnLineResourceImpl#WMS
+     */
+    public static final Citation WMS;
+    static {
+        final CitationImpl c = new CitationImpl("Web Map Service");
+        final Collection<InternationalString> titles = c.getAlternateTitles();
+        titles.add(new SimpleInternationalString("WMS"));
+        titles.add(new SimpleInternationalString("WMS 1.3.0"));
+        titles.add(new SimpleInternationalString("OGC 04-024"));
+        titles.add(new SimpleInternationalString("ISO 19128"));
+
+        final Collection<ResponsibleParty> parties = c.getCitedResponsibleParties();
+        parties.add(ResponsiblePartyImpl.OGC);
+        parties.add(ResponsiblePartyImpl.OGC(Role.PUBLISHER, OnLineResourceImpl.WMS));
+        /*
+         * The WMS specification is a model in a programming point of view, but this is not
+         * the purpose of ISO 19115 PresentationForm.MODEL_DIGITAL in my understanding. The
+         * later rather looks like the output of a numerical model (e.g. meteorological model).
+         * The WMS specification is distributed as a PDF document.
+         */
+        c.getPresentationForm().add(PresentationForm.DOCUMENT_DIGITAL);
+        c.freeze();
+        WMS = c;
+    }
+
+    /**
+     * The <A HREF="http://www.remotesensing.org/geotiff/geotiff.html">GeoTIFF</A> specification.
+     *
+     * @see ResponsiblePartyImpl#GEOTIFF
+     */
+    public static final Citation GEOTIFF;
+    static {
+        final CitationImpl c = new CitationImpl(ResponsiblePartyImpl.GEOTIFF);
+        c.getPresentationForm().add(PresentationForm.DOCUMENT_DIGITAL);
+        c.freeze();
+        GEOTIFF = c;
+    }
+
+    /**
+     * The <A HREF="http://java.sun.com/products/java-media/jai">Java Advanced Imaging</A> library.
+     * An {@linkplain Citation#getAlternateTitles alternate title} for this citation is "JAI"
+     * (according ISO 19115, alternate titles often contain abreviations).
+     *
+     * @see ResponsiblePartyImpl#SUN_MICROSYSTEMS
+     */
+    public static final Citation JAI;
+    static {
+        final CitationImpl c = new CitationImpl("Java Advanced Imaging");
+        c.getAlternateTitles().add(new SimpleInternationalString("JAI"));
+        c.getCitedResponsibleParties().add(ResponsiblePartyImpl.SUN_MICROSYSTEMS);
+        c.freeze();
+        JAI = c;
+    }
+
+
+
+
+    ///////////////////////////////////////////////////////////////////////
+    ////////                                                       ////////
+    ////////             C R S   A U T H O R I T I E S             ////////
+    ////////                                                       ////////
+    ///////////////////////////////////////////////////////////////////////
+
+    /**
+     * The <A HREF="http://www.epsg.org">European Petroleum Survey Group</A> authority.
+     * An {@linkplain Citation#getAlternateTitles alternate title} for this citation is
+     * "EPSG" (according ISO 19115, alternate titles often contain abreviations). In
+     * addition, this citation contains the "EPSG" {@linkplain Citation#getIdentifiers identifier}
+     * for the "Authority name" {@linkplain Citation#getIdentifierTypes identifier type}.
+     * <p>
+     * This citation is used as an authority for
+     * {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference system}
+     * identifiers. When searching an {@linkplain org.opengis.referencing.crs.CRSAuthorityFactory CRS
+     * authority factory} on EPSG data, Geotools compares the {@code "EPSG"} string against the
+     * {@linkplain Citation#getIdentifiers identifiers} (or against the {@linkplain Citation#getTitle
+     * title} and {@linkplain Citation#getAlternateTitles alternate titles} if there is no identifier)
+     * using the {@link #identifierMatches(Citation,String) identifierMatches} method.
+     *
+     * @see ResponsiblePartyImpl#EPSG
+     * @see #AUTO
+     * @see #AUTO2
+     * @see #CRS
+     */
+    public static final Citation EPSG;
+    static {
+        final CitationImpl c = new CitationImpl(ResponsiblePartyImpl.EPSG);
+        c.addAuthority("EPSG", true);
+        c.getPresentationForm().add(PresentationForm.TABLE_DIGITAL);
+        c.freeze();
+        EPSG = c;
+    }
+
+    /**
+     * The <A HREF="http://www.opengis.org/docs/01-068r3.pdf">WMS 1.1.1</A> "Automatic Projections"
+     * authority. An {@linkplain Citation#getAlternateTitles alternate title} for this citation is
+     * "AUTO" (according ISO 19115, alternate titles often contain abreviations). In addition, this
+     * citation contains the "AUTO" {@linkplain Citation#getIdentifiers identifier} for the
+     * "Authority name" {@linkplain Citation#getIdentifierTypes identifier type}.
+     * <p>
+     * <strong>Warning:</strong> {@code AUTO} is different from {@link #AUTO2} used for WMS 1.3.0.
+     * <p>
+     * This citation is used as an authority for
+     * {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference system}
+     * identifiers. When searching an {@linkplain org.opengis.referencing.crs.CRSAuthorityFactory CRS
+     * authority factory} on AUTO data, Geotools compares the {@code "AUTO"} string against the
+     * {@linkplain Citation#getIdentifiers identifiers} (or against the {@linkplain Citation#getTitle
+     * title} and {@linkplain Citation#getAlternateTitles alternate titles} if there is no identifier)
+     * using the {@link #identifierMatches(Citation,String) identifierMatches} method.
+     *
+     * @see <A HREF="http://www.opengeospatial.org/">Open Geospatial Consortium</A>
+     * @see <A HREF="http://www.opengis.org/docs/01-068r3.pdf">WMS 1.1.1 specification</A>
+     * @see #WMS
+     * @see #AUTO2
+     * @see #CRS
+     * @see #EPSG
+     */
+    public static final Citation AUTO;
+    static { // Sanity check ensure that all @see tags are actually available in the metadata
+        final CitationImpl c = new CitationImpl("Automatic Projections");
+        c.addAuthority("AUTO", false);
+        /*
+         * Do not put "WMS 1.1.1" and "OGC 01-068r3" as alternative titles. They are alternative
+         * titles for the WMS specification (see the WMS constant in this class), not for the
+         * AUTO authority name.
+         */
+        final Collection<ResponsibleParty> parties = c.getCitedResponsibleParties();
+        parties.add(ResponsiblePartyImpl.OGC);
+        parties.add(ResponsiblePartyImpl.OGC(Role.PUBLISHER, OnLineFunction.DOWNLOAD,
+                                             "http://www.opengis.org/docs/01-068r3.pdf"));
+        c.getPresentationForm().add(PresentationForm.DOCUMENT_DIGITAL); // See comment in WMS.
+        c.freeze();
+        AUTO = c;
+    }
+
+    // Do not put the ...files/?artifact... link in the head sentence: it break javadoc formatting.
+    /**
+     * The WMS 1.3.0 "Automatic Projections" authority. An {@linkplain Citation#getAlternateTitles
+     * alternate title} for this citation is "AUTO2" (according ISO 19115, alternate titles often
+     * contain abreviations). In addition, this citation contains the "AUTO2"
+     * {@linkplain Citation#getIdentifiers identifier} for the "Authority name"
+     * {@linkplain Citation#getIdentifierTypes identifier type}.
+     * <p>
+     * <strong>Warning:</strong> {@code AUTO2} is different from {@link #AUTO} used for WMS 1.1.1
+     * and earlier.
+     * <p>
+     * This citation is used as an authority for
+     * {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference system}
+     * identifiers. When searching an {@linkplain org.opengis.referencing.crs.CRSAuthorityFactory CRS
+     * authority factory} on AUTO2 data, Geotools compares the {@code "AUTO2"} string against the
+     * {@linkplain Citation#getIdentifiers identifiers} (or against the {@linkplain Citation#getTitle
+     * title} and {@linkplain Citation#getAlternateTitles alternate titles} if there is no identifier)
+     * using the {@link #identifierMatches(Citation,String) identifierMatches} method.
+     *
+     * @see <A HREF="http://www.opengeospatial.org/">Open Geospatial Consortium</A>
+     * @see <A HREF="http://portal.opengis.org/files/?artifact_id=5316">WMS 1.3.0 specification</A>
+     * @see #WMS
+     * @see #AUTO
+     * @see #CRS
+     * @see #EPSG
+     */
+    public static final Citation AUTO2;
+    static {
+        final CitationImpl c = new CitationImpl("Automatic Projections");
+        c.addAuthority("AUTO2", false);
+        /*
+         * Do not put "WMS 1.3.0" and "OGC 04-024" as alternative titles. They are alternative
+         * titles for the WMS specification (see the WMS constant in this class), not for the
+         * AUTO2 authority name.
+         */
+        final Collection<ResponsibleParty> parties = c.getCitedResponsibleParties();
+        parties.add(ResponsiblePartyImpl.OGC);
+        parties.add(ResponsiblePartyImpl.OGC(Role.PUBLISHER, OnLineResourceImpl.WMS));
+        c.getPresentationForm().add(PresentationForm.DOCUMENT_DIGITAL); // See comment in WMS.
+        c.freeze();
+        AUTO2 = c;
+    }
+
+    // Do not put the ...files/?artifact... link in the head sentence: it break javadoc formatting.
+    /**
+     * The WMS 1.3.0 "CRS" authority. This is defined in the same document than {@link #AUTO2}.
+     *
+     * @see #WMS
+     * @see #AUTO
+     * @see #AUTO2
+     * @see #CRS
+     * @see #EPSG
+     */
+    public static final Citation CRS;
+    static {
+        final CitationImpl c = new CitationImpl("Web Map Service CRS");
+        c.addAuthority("CRS", false);
+        c.getCitedResponsibleParties().addAll(AUTO2.getCitedResponsibleParties());
+        c.getPresentationForm().add(PresentationForm.DOCUMENT_DIGITAL); // See comment in WMS.
+        c.freeze();
+        CRS = c;
+    }
+
+    ///////////////////////////////////////////////////////////////////////
+    ////////                                                       ////////
+    ////////             End of constants declarations             ////////
+    ////////                                                       ////////
+    ///////////////////////////////////////////////////////////////////////
+
+    /**
+     * List of citations declared in this class.
+     */
+    private static final Citation[] AUTHORITIES = {
+        OGC, OPEN_GIS, ESRI, ORACLE, GEOTOOLS, WMS, GEOTIFF, JAI, EPSG, AUTO, AUTO2, CRS
+    };
+
+    /**
+     * Returns a citation of the given name. If the given name matches a {@linkplain
+     * Citation#getTitle title} or an {@linkplain Citation#getAlternateTitles alternate titles}
+     * of one of the pre-defined constants ({@link #EPSG}, {@link #GEOTIFF}, <cite>etc.</cite>),
+     * then this constant is returned. Otherwise, a new citation is created with the specified
+     * name as the title.
+     *
+     * @param  title The citation title (or alternate title).
+     * @return A citation using the specified name
+     */
+    public static Citation fromName(final String title) {
+        for (int i=0; i<AUTHORITIES.length; i++) {
+            final Citation citation = AUTHORITIES[i];
+            if (titleMatches(citation, title)) {
+                return citation;
+            }
+        }
+        return new CitationImpl(title);
+    }
+
+    /**
+     * Returns {@code true} if at least one {@linkplain Citation#getTitle title} or
+     * {@linkplain Citation#getAlternateTitles alternate title} in {@code c1} is equals to a title
+     * or alternate title in {@code c2}. The comparaison is case-insensitive and ignores leading
+     * and trailing spaces. The titles ordering is not significant.
+     *
+     * @param  c1 The first citation to compare.
+     * @param  c2 the second citation to compare.
+     * @return {@code true} if at least one title or alternate title matches.
+     */
+    public static boolean titleMatches(final Citation c1, final Citation c2) {
+        InternationalString candidate = c2.getTitle();
+        Iterator<? extends InternationalString> iterator = null;
+        do {
+            // The "null" locale argument is required for getting the unlocalized version.
+            final String asString = candidate.toString(null);
+            if (titleMatches(c1, asString)) {
+                return true;
+            }
+            final String asLocalized = candidate.toString();
+            if (asLocalized!=asString && titleMatches(c1, asLocalized)) {
+                return true;
+            }
+            if (iterator == null) {
+                final Collection<? extends InternationalString> titles = c2.getAlternateTitles();
+                if (titles == null) {
+                    break;
+                }
+                iterator = titles.iterator();
+            }
+            if (!iterator.hasNext()) {
+                break;
+            }
+            candidate = iterator.next();
+        } while (true);
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if the {@linkplain Citation#getTitle title} or any
+     * {@linkplain Citation#getAlternateTitles alternate title} in the given citation
+     * matches the given string. The comparaison is case-insensitive and ignores leading
+     * and trailing spaces.
+     *
+     * @param  citation The citation to check for.
+     * @param  title The title or alternate title to compare.
+     * @return {@code true} if the title or alternate title matches the given string.
+     */
+    public static boolean titleMatches(final Citation citation, String title) {
+        title = title.trim();
+        InternationalString candidate = citation.getTitle();
+        Iterator<? extends InternationalString> iterator = null;
+        do {
+            // The "null" locale argument is required for getting the unlocalized version.
+            final String asString = candidate.toString(null);
+            if (asString.trim().equalsIgnoreCase(title)) {
+                return true;
+            }
+            final String asLocalized = candidate.toString();
+            if (asLocalized!=asString && asLocalized.trim().equalsIgnoreCase(title)) {
+                return true;
+            }
+            if (iterator == null) {
+                final Collection<? extends InternationalString> titles = citation.getAlternateTitles();
+                if (titles == null) {
+                    break;
+                }
+                iterator = titles.iterator();
+            }
+            if (!iterator.hasNext()) {
+                break;
+            }
+            candidate = iterator.next();
+        } while (true);
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if at least one {@linkplain Citation#getIdentifiers identifier} in
+     * {@code c1} is equals to an identifier in {@code c2}. The comparaison is case-insensitive
+     * and ignores leading and trailing spaces. The identifier ordering is not significant.
+     * <p>
+     * If (and <em>only</em> if) the citations do not contains any identifier, then this method
+     * fallback on titles comparaison using the {@link #titleMatches(Citation,Citation)
+     * titleMatches} method. This fallback exists for compatibility with client codes using
+     * citation {@linkplain Citation#getTitle titles} without identifiers.
+     *
+     * @param  c1 The first citation to compare.
+     * @param  c2 the second citation to compare.
+     * @return {@code true} if at least one identifier, title or alternate title matches.
+     */
+    public static boolean identifierMatches(Citation c1, Citation c2) {
+        /*
+         * If there is no identifier in both citations, fallback on title comparaisons. If there is
+         * identifiers in only one citation, make sure that this citation is the second one (c2) in
+         * order to allow at least one call to 'identifierMatches(c1, String)'.
+         */
+        Iterator<? extends Identifier> iterator = c2.getIdentifiers().iterator();
+        if (!iterator.hasNext()) {
+            iterator = c1.getIdentifiers().iterator();
+            if (!iterator.hasNext()) {
+                return titleMatches(c1, c2);
+            }
+            c1 = c2;
+            c2 = null; // Just for make sure that we don't use it by accident.
+        }
+        do {
+            final String id = iterator.next().getCode().trim();
+            if (identifierMatches(c1, id)) {
+                return true;
+            }
+        } while (iterator.hasNext());
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if any {@linkplain Citation#getIdentifiers identifiers} in the given
+     * citation matches the given string. The comparaison is case-insensitive and ignores leading
+     * and trailing spaces. If (and <em>only</em> if) the citation do not contains any identifier,
+     * then this method fallback on titles comparaison using the {@link #titleMatches(Citation,
+     * String) titleMatches} method. This fallback exists for compatibility with client codes using
+     * citation {@linkplain Citation#getTitle titles} without identifiers.
+     *
+     * @param  citation The citation to check for.
+     * @param  identifier The identifier to compare.
+     * @return {@code true} if the title or alternate title matches the given string.
+     */
+    public static boolean identifierMatches(final Citation citation, String identifier) {
+        identifier = identifier.trim();
+        final Collection<? extends Identifier> identifiers = citation.getIdentifiers();
+        for (final Identifier id : identifiers) {
+            final String code = id.getCode().trim();
+            if (identifier.equalsIgnoreCase(code)) {
+                return true;
+            }
+        }
+        if (identifiers.isEmpty()) {
+            return titleMatches(citation, identifier);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns the shortest identifier for the specified citation, or the title if there is
+     * no identifier. This method is useful for extracting the namespace from an authority,
+     * for example {@code "EPSG"}.
+     *
+     * @param citation The citation for which to get the identifier.
+     * @return The shortest identifier of the given citation.
+     *
+     * @since 2.4
+     */
+    public static String getIdentifier(final Citation citation) {
+        String identifier = null;
+        for (final Identifier id : citation.getIdentifiers()) {
+            final String candidate = id.getCode().trim();
+            final int length = candidate.length();
+            if (length != 0) {
+                if (identifier == null || length < identifier.length()) {
+                    identifier = candidate;
+                }
+            }
+        }
+        if (identifier == null) {
+            identifier = String.valueOf(citation.getTitle());
+        }
+        return identifier;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/ContactImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/ContactImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/ContactImpl.java	(revision 28000)
@@ -0,0 +1,269 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso.citation;
+
+import org.opengis.metadata.citation.Address;
+import org.opengis.metadata.citation.Contact;
+import org.opengis.metadata.citation.OnLineResource;
+import org.opengis.metadata.citation.Telephone;
+import org.opengis.util.InternationalString;
+import org.geotools.metadata.iso.MetadataEntity;
+
+
+/**
+ * Information required to enable contact with the responsible person and/or organization.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/citation/ContactImpl.java $
+ * @version $Id: ContactImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Touraïvane
+ */
+public class ContactImpl extends MetadataEntity implements Contact {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 3283637180253117382L;
+
+    /**
+     * Contact informations for the <A HREF="http://www.opengeospatial.org">Open Geospatial consortium</A>.
+     * "Open Geospatial consortium" is the new name for "OpenGIS consortium".
+     *
+     * @see OnLineResourceImpl#OGC
+     */
+    public static final Contact OGC;
+    static {
+        final ContactImpl c = new ContactImpl(OnLineResourceImpl.OGC);
+        c.freeze();
+        OGC = c;
+    }
+    /**
+     * Contact informations for the <A HREF="http://www.opengis.org">OpenGIS consortium</A>.
+     * "OpenGIS consortium" is the old name for "Open Geospatial consortium".
+     *
+     * @see OnLineResourceImpl#OPEN_GIS
+     */
+    public static final Contact OPEN_GIS;
+    static {
+        final ContactImpl c = new ContactImpl(OnLineResourceImpl.OPEN_GIS);
+        c.freeze();
+        OPEN_GIS = c;
+    }
+
+    /**
+     * Contact informations for the
+     * <A HREF="http://www.epsg.org">European Petroleum Survey Group</A>.
+     *
+     * @see OnLineResourceImpl#EPSG
+     */
+    public static final Contact EPSG;
+    static {
+        final ContactImpl c = new ContactImpl(OnLineResourceImpl.EPSG);
+        c.freeze();
+        EPSG = c;
+    }
+
+    /**
+     * Contact informations for the
+     * <A HREF="http://www.remotesensing.org/geotiff/geotiff.html">GeoTIFF</A> group.
+     *
+     * @see OnLineResourceImpl#GEOTIFF
+     */
+    public static final Contact GEOTIFF;
+    static {
+        final ContactImpl c = new ContactImpl(OnLineResourceImpl.GEOTIFF);
+        c.freeze();
+        GEOTIFF = c;
+    }
+
+    /**
+     * Contact informations for <A HREF="http://www.esri.com">ESRI</A>.
+     *
+     * @see OnLineResourceImpl#ESRI
+     */
+    public static final Contact ESRI;
+    static {
+        final ContactImpl c = new ContactImpl(OnLineResourceImpl.ESRI);
+        c.freeze();
+        ESRI = c;
+    }
+
+    /**
+     * Contact informations for <A HREF="http://www.oracle.com">Oracle</A>.
+     *
+     * @see OnLineResourceImpl#ORACLE
+     */
+    public static final Contact ORACLE;
+    static {
+        final ContactImpl c = new ContactImpl(OnLineResourceImpl.ORACLE);
+        c.freeze();
+        ORACLE = c;
+    }
+
+    /**
+     * Contact informations for <A HREF="http://www.sun.com/">Sun Microsystems</A>.
+     *
+     * @see OnLineResourceImpl#SUN_MICROSYSTEMS
+     *
+     * @since 2.2
+     */
+    public static final Contact SUN_MICROSYSTEMS;
+    static {
+        final ContactImpl c = new ContactImpl(OnLineResourceImpl.SUN_MICROSYSTEMS);
+        c.freeze();
+        SUN_MICROSYSTEMS = c;
+    }
+
+    /**
+     * Contact informations for the <A HREF="http://www.geotools.org">Geotools</A> project.
+     *
+     * @see OnLineResourceImpl#GEOTOOLS
+     */
+    public static final Contact GEOTOOLS;
+    static {
+        final ContactImpl c = new ContactImpl(OnLineResourceImpl.GEOTOOLS);
+        c.freeze();
+        GEOTOOLS = c;
+    }
+
+    /**
+     * Supplemental instructions on how or when to contact the individual or organization.
+     */
+    private InternationalString contactInstructions;
+
+    /**
+     * Time period (including time zone) when individuals can contact the organization or
+     * individual.
+     */
+    private InternationalString hoursOfService;
+
+    /**
+     * On-line information that can be used to contact the individual or organization.
+     */
+    private OnLineResource onLineResource;
+
+    /**
+     * Physical and email address at which the organization or individual may be contacted.
+     */
+    private Address address;
+
+    /**
+     * Telephone numbers at which the organization or individual may be contacted.
+     */
+    private Telephone phone;
+
+    /**
+     * Constructs an initially empty contact.
+     */
+    public ContactImpl() {
+        // empty constructor, please use set methods and call
+        // freeze before returning this instance to client code
+    }
+
+    /**
+     * Constructs a contact initialized to the specified online resource.
+     */
+    public ContactImpl(final OnLineResource resource) {
+        setOnLineResource(resource);
+    }
+
+    /**
+     * Returns the physical and email address at which the organization or individual may be contacted.
+     * Returns {@code null} if none.
+     */
+    public Address getAddress() {
+        return address;
+    }
+
+    /**
+     * Set the physical and email address at which the organization or individual may be contacted.
+     */
+    public synchronized void setAddress(final Address newValue) {
+        checkWritePermission();
+        address = newValue;
+    }
+
+    /**
+     * Returns supplemental instructions on how or when to contact the individual or organization.
+     * Returns {@code null} if none.
+     */
+    public InternationalString getContactInstructions() {
+        return contactInstructions;
+    }
+
+    /**
+     * Set supplemental instructions on how or when to contact the individual or organization.
+     */
+    public synchronized void setContactInstructions(final InternationalString newValue) {
+        checkWritePermission();
+        contactInstructions = newValue;
+    }
+
+    /**
+     * Return on-line information that can be used to contact the individual or organization.
+     * Returns {@code null} if none.
+     */
+    public OnLineResource getOnLineResource() {
+        return onLineResource;
+    }
+
+    /**
+     * Set on-line information that can be used to contact the individual or organization.
+     */
+    public synchronized void setOnLineResource(final OnLineResource newValue) {
+        checkWritePermission();
+        onLineResource = newValue;
+    }
+
+    /**
+     * Returns telephone numbers at which the organization or individual may be contacted.
+     * Returns {@code null} if none.
+     */
+    public Telephone getPhone() {
+        return phone;
+    }
+
+    /**
+     * Set telephone numbers at which the organization or individual may be contacted.
+     */
+    public synchronized void setPhone(final Telephone newValue) {
+        checkWritePermission();
+        phone = newValue;
+    }
+
+    /**
+     * Returns time period (including time zone) when individuals can contact the organization or
+     * individual.
+     * Returns {@code null} if none.
+     */
+    public InternationalString getHoursOfService() {
+        return hoursOfService;
+    }
+
+    /**
+     * Set time period (including time zone) when individuals can contact the organization or
+     * individual.
+     */
+    public synchronized void setHoursOfService(final InternationalString newValue) {
+        checkWritePermission();
+        hoursOfService = newValue;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/OnLineResourceImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/OnLineResourceImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/OnLineResourceImpl.java	(revision 28000)
@@ -0,0 +1,300 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso.citation;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import org.opengis.metadata.citation.OnLineFunction;
+import org.opengis.metadata.citation.OnLineResource;
+import org.opengis.util.InternationalString;
+import org.geotools.metadata.iso.MetadataEntity;
+
+
+/**
+ * Information about on-line sources from which the dataset, specification, or
+ * community profile name and extended metadata elements can be obtained.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/citation/OnLineResourceImpl.java $
+ * @version $Id: OnLineResourceImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Touraïvane
+ */
+public class OnLineResourceImpl extends MetadataEntity implements OnLineResource {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 5412370008274334799L;
+
+    /**
+     * The online resources for the <A HREF="http://www.opengeospatial.org">Open Geospatial Consortium</A>.
+     * "Open Geospatial consortium" is the new name for "OpenGIS consortium".
+     *
+     * @see #OPEN_GIS
+     */
+    public static final OnLineResource OGC;
+    static {
+        final OnLineResourceImpl r;
+        OGC = r = new OnLineResourceImpl("http://www.opengeospatial.org/");
+        r.freeze();
+    }
+
+    /**
+     * The online resources for the <A HREF="http://www.opengis.org">OpenGIS consortium</A>.
+     * "OpenGIS consortium" is the old name for "Open Geospatial consortium".
+     *
+     * @see #OGC
+     */
+    public static final OnLineResource OPEN_GIS;
+    static {
+        final OnLineResourceImpl r;
+        OPEN_GIS = r = new OnLineResourceImpl("http://www.opengis.org");
+        r.freeze();
+    }
+
+    /**
+     * The online resources for the
+     * <A HREF="http://www.epsg.org">European Petroleum Survey Group</A>.
+     */
+    public static final OnLineResource EPSG;
+    static {
+        final OnLineResourceImpl r;
+        EPSG = r = new OnLineResourceImpl("http://www.epsg.org");
+        r.freeze();
+    }
+
+    /**
+     * The online resources for the
+     * <A HREF="http://www.remotesensing.org/geotiff/geotiff.html">GeoTIFF</A> group.
+     */
+    public static final OnLineResource GEOTIFF;
+    static {
+        final OnLineResourceImpl r;
+        GEOTIFF = r = new OnLineResourceImpl("http://www.remotesensing.org/geotiff");
+        r.freeze();
+    }
+
+    /**
+     * The online resources for <A HREF="http://www.esri.com">ESRI</A>.
+     */
+    public static final OnLineResource ESRI;
+    static {
+        final OnLineResourceImpl r;
+        ESRI = r = new OnLineResourceImpl("http://www.esri.com");
+        r.freeze();
+    }
+
+    /**
+     * The online resources for <A HREF="http://www.oracle.com">Oracle</A>.
+     */
+    public static final OnLineResource ORACLE;
+    static {
+        final OnLineResourceImpl r;
+        ORACLE = r = new OnLineResourceImpl("http://www.oracle.com");
+        r.freeze();
+    }
+
+    /**
+     * The online resources for <A HREF="http://java.sun.com/">Sun Microsystems</A>.
+     * This online resources point to the Java developper site.
+     *
+     * @since 2.2
+     */
+    public static final OnLineResource SUN_MICROSYSTEMS;
+    static {
+        final OnLineResourceImpl r;
+        SUN_MICROSYSTEMS = r = new OnLineResourceImpl("http://java.sun.com");
+        r.freeze();
+    }
+
+    /**
+     * The online resources for the <A HREF="http://www.geotools.org">Geotools</A> project.
+     */
+    public static final OnLineResource GEOTOOLS;
+    static {
+        final OnLineResourceImpl r;
+        GEOTOOLS = r = new OnLineResourceImpl("http://www.geotools.org");
+        r.freeze();
+    }
+
+    /**
+     * The download link for <A HREF="http://portal.opengis.org/files/?artifact_id=5316">Web Map
+     * Service</A> specification. The download link may change in future Geotools versions in
+     * order to point toward the latest specification.
+     *
+     * @since 2.2
+     */
+    public static final OnLineResource WMS;
+    static {
+        final OnLineResourceImpl r;
+        WMS = r = new OnLineResourceImpl("http://portal.opengis.org/files/?artifact_id=5316");
+        r.setFunction(OnLineFunction.DOWNLOAD);
+        r.freeze();
+    }
+
+    /**
+     * Name of an application profile that can be used with the online resource.
+     */
+    private String applicationProfile;
+
+    /**
+     * Detailed text description of what the online resource is/does.
+     */
+    private InternationalString description;
+
+    /**
+     * Code for function performed by the online resource.
+     */
+    private OnLineFunction function;
+
+    /**
+     * Location (address) for on-line access using a Uniform Resource Locator address or
+     * similar addressing scheme such as http://www.statkart.no/isotc211.
+     */
+    private URI linkage;
+
+    /**
+     * Name of the online resources.
+     */
+    private String name;
+
+    /**
+     * Creates an initially empty on line resource.
+     */
+    public OnLineResourceImpl() {
+    }
+
+    /**
+     * Creates an on line resource initialized to the given URI.
+     * This method is private for now since, if this constructor was public, some
+     * users may expect a string argument to be for the description text instead.
+     * Furthermore, a public method should not catch the {@link URISyntaxException}
+     * and should not set a function.
+     */
+    private OnLineResourceImpl(final String linkage) {
+        try {
+            setLinkage(new URI(linkage));
+        } catch (URISyntaxException exception) {
+            throw new IllegalArgumentException(exception);
+        }
+        setFunction(OnLineFunction.INFORMATION);
+    }
+
+    /**
+     * Creates an on line resource initialized to the given URI.
+     */
+    public OnLineResourceImpl(final URI linkage) {
+        setLinkage(linkage);
+    }
+
+    /**
+     * Returns the name of an application profile that can be used with the online resource.
+     * Returns {@code null} if none.
+     */
+    public String getApplicationProfile() {
+        return applicationProfile;
+    }
+
+    /**
+     * Set the name of an application profile that can be used with the online resource.
+     */
+    public synchronized void setApplicationProfile(final String newValue) {
+        checkWritePermission();
+        applicationProfile = newValue;
+    }
+
+    /**
+     * Name of the online resource. Returns {@code null} if none.
+     *
+     * @since 2.4
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Set the name of the online resource.
+     *
+     * @since 2.4
+     */
+    public synchronized void setName(final String newValue) {
+        checkWritePermission();
+        name = newValue;
+    }
+
+    /**
+     * Returns the detailed text description of what the online resource is/does.
+     * Returns {@code null} if none.
+     */
+    public InternationalString getDescription() {
+        return description;
+    }
+
+    /**
+     * Set the detailed text description of what the online resource is/does.
+     */
+    public synchronized void setDescription(final InternationalString newValue) {
+        checkWritePermission();
+        description = newValue;
+    }
+
+    /**
+     * Returns the code for function performed by the online resource.
+     * Returns {@code null} if unspecified.
+     */
+    public OnLineFunction getFunction() {
+        return function;
+    }
+
+    /**
+     * Set the code for function performed by the online resource.
+     */
+    public synchronized void setFunction(final OnLineFunction newValue) {
+        checkWritePermission();
+        function = newValue;
+    }
+
+    /**
+     * Returns the location (address) for on-line access using a Uniform Resource Locator address or
+     * similar addressing scheme such as http://www.statkart.no/isotc211.
+     */
+    public URI getLinkage() {
+        return linkage;
+    }
+
+    /**
+     * Set the location (address) for on-line access using a Uniform Resource Locator address or
+     * similar addressing scheme such as http://www.statkart.no/isotc211.
+     */
+    public synchronized void setLinkage(final URI newValue) {
+        checkWritePermission();
+        linkage = newValue;
+    }
+
+    /**
+     * Returns the connection protocol to be used.
+     * Returns {@code null} if none.
+     */
+    public String getProtocol() {
+        final URI linkage = this.linkage;
+        return (linkage!=null) ? linkage.getScheme() : null;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/ResponsiblePartyImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/ResponsiblePartyImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/citation/ResponsiblePartyImpl.java	(revision 28000)
@@ -0,0 +1,367 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso.citation;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import org.opengis.metadata.citation.Contact;
+import org.opengis.metadata.citation.OnLineFunction;
+import org.opengis.metadata.citation.OnLineResource;
+import org.opengis.metadata.citation.ResponsibleParty;
+import org.opengis.metadata.citation.Role;
+import org.opengis.util.InternationalString;
+import org.geotools.metadata.iso.MetadataEntity;
+import org.geotools.util.logging.Logging;
+import org.geotools.util.SimpleInternationalString;
+
+
+/**
+ * Identification of, and means of communication with, person(s) and
+ * organizations associated with the dataset.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/citation/ResponsiblePartyImpl.java $
+ * @version $Id: ResponsiblePartyImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Touraïvane
+ */
+public class ResponsiblePartyImpl extends MetadataEntity implements ResponsibleParty {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -2477962229031486552L;
+
+    /**
+     * The name of Open Geospatial Consortium as an international string.
+     *
+     * @todo Localize.
+     */
+    static final InternationalString OGC_NAME =
+            new SimpleInternationalString("Open Geospatial Consortium");
+
+    /**
+     * Creates a responsible party metadata entry for OGC involvement.
+     * The organisation name is automatically set to "Open Geospatial Consortium".
+     *
+     * @param role     The OGC role (point of contact, owner, etc.) for a resource.
+     * @param resource The URI to the resource.
+     * @return Responsible party describing OGC involvement.
+     *
+     * @since 2.2
+     */
+    public static ResponsibleParty OGC(final Role role, final OnLineResource resource) {
+        final ContactImpl contact = new ContactImpl(resource);
+        contact.freeze();
+
+        final ResponsiblePartyImpl ogc = new ResponsiblePartyImpl(role);
+        ogc.setOrganisationName(OGC_NAME);
+        ogc.setContactInfo(contact);
+        ogc.freeze();
+
+        return ogc;
+    }
+
+    /**
+     * Creates a responsible party metadata entry for OGC involvement.
+     * The organisation name is automatically set to "Open Geospatial Consortium".
+     *
+     * @param role           The OGC role (point of contact, owner, etc.) for a resource.
+     * @param function       The OGC function (information, download, etc.) for a resource.
+     * @param onlineResource The URI to the resource.
+     * @return Responsible party describing OGC involvement.
+     */
+    public static ResponsibleParty OGC(final Role role,
+                                       final OnLineFunction function,
+                                       final URI onlineResource)
+    {
+        final OnLineResourceImpl resource = new OnLineResourceImpl(onlineResource);
+        resource.setFunction(function);
+        resource.freeze();
+        return OGC(role, resource);
+    }
+
+    /**
+     * Creates a responsible party metadata entry for OGC involvement.
+     * The organisation name is automatically set to "Open Geospatial Consortium".
+     *
+     * @param role           The OGC role (point of contact, owner, etc.) for a resource.
+     * @param function       The OGC function (information, download, etc.) for a resource.
+     * @param onlineResource The URI on the resource.
+     * @return Responsible party describing OGC involvement.
+     */
+    static ResponsibleParty OGC(final Role role,
+                                final OnLineFunction function,
+                                final String onlineResource)
+    {
+        try {
+            return OGC(role, function, new URI(onlineResource));
+        }
+        catch (URISyntaxException badContact) {
+            Logging.unexpectedException("org.geotools.metadata.iso", ResponsibleParty.class, "OGC",
+                                        badContact);
+            return OGC;
+        }
+    }
+
+    /**
+     * The <A HREF="http://www.opengeospatial.org">Open Geospatial consortium</A> responsible party.
+     * "Open Geospatial consortium" is the new name for "OpenGIS consortium".
+     *
+     * @see ContactImpl#OGC
+     */
+    public static ResponsibleParty OGC;
+    static {
+        final ResponsiblePartyImpl r = new ResponsiblePartyImpl(Role.RESOURCE_PROVIDER);
+        r.setOrganisationName(OGC_NAME);
+        r.setContactInfo(ContactImpl.OGC);
+        r.freeze();
+        OGC = r;
+    }
+
+    /**
+     * The <A HREF="http://www.opengis.org">OpenGIS consortium</A> responsible party.
+     * "OpenGIS consortium" is the old name for "Open Geospatial consortium".
+     *
+     * @see ContactImpl#OPEN_GIS
+     */
+    public static ResponsibleParty OPEN_GIS;
+    static {
+        final ResponsiblePartyImpl r = new ResponsiblePartyImpl(Role.RESOURCE_PROVIDER);
+        r.setOrganisationName(new SimpleInternationalString("OpenGIS consortium"));
+        r.setContactInfo(ContactImpl.OPEN_GIS);
+        r.freeze();
+        OPEN_GIS = r;
+    }
+
+    /**
+     * The <A HREF="http://www.epsg.org">European Petroleum Survey Group</A> responsible party.
+     *
+     * @see ContactImpl#EPSG
+     */
+    public static ResponsibleParty EPSG;
+    static {
+        final ResponsiblePartyImpl r = new ResponsiblePartyImpl(Role.PRINCIPAL_INVESTIGATOR);
+        r.setOrganisationName(new SimpleInternationalString("European Petroleum Survey Group"));
+        r.setContactInfo(ContactImpl.EPSG);
+        r.freeze();
+        EPSG = r;
+    }
+
+    /**
+     * The <A HREF="http://www.remotesensing.org/geotiff/geotiff.html">GeoTIFF</A> responsible
+     * party.
+     *
+     * @see ContactImpl#GEOTIFF
+     */
+    public static ResponsibleParty GEOTIFF;
+    static {
+        final ResponsiblePartyImpl r = new ResponsiblePartyImpl(Role.PRINCIPAL_INVESTIGATOR);
+        r.setOrganisationName(new SimpleInternationalString("GeoTIFF"));
+        r.setContactInfo(ContactImpl.GEOTIFF);
+        r.freeze();
+        GEOTIFF = r;
+    }
+
+    /**
+     * The <A HREF="http://www.esri.com">ESRI</A> responsible party.
+     *
+     * @see ContactImpl#ESRI
+     */
+    public static ResponsibleParty ESRI;
+    static {
+        final ResponsiblePartyImpl r = new ResponsiblePartyImpl(Role.OWNER);
+        r.setOrganisationName(new SimpleInternationalString("ESRI"));
+        r.setContactInfo(ContactImpl.ESRI);
+        r.freeze();
+        ESRI = r;
+    }
+
+    /**
+     * The <A HREF="http://www.oracle.com">Oracle</A> responsible party.
+     *
+     * @see ContactImpl#ORACLE
+     */
+    public static ResponsibleParty ORACLE;
+    static {
+        final ResponsiblePartyImpl r = new ResponsiblePartyImpl(Role.OWNER);
+        r.setOrganisationName(new SimpleInternationalString("Oracle"));
+        r.setContactInfo(ContactImpl.ORACLE);
+        r.freeze();
+        ORACLE = r;
+    }
+
+    /**
+     * The <A HREF="http://www.sun.com/">Sun Microsystems</A> party.
+     *
+     * @see ContactImpl#SUN_MICROSYSTEMS
+     *
+     * @since 2.2
+     */
+    public static ResponsibleParty SUN_MICROSYSTEMS;
+    static {
+        final ResponsiblePartyImpl r = new ResponsiblePartyImpl(Role.PRINCIPAL_INVESTIGATOR);
+        r.setOrganisationName(new SimpleInternationalString("Sun Microsystems"));
+        r.setContactInfo(ContactImpl.SUN_MICROSYSTEMS);
+        r.freeze();
+        SUN_MICROSYSTEMS = r;
+    }
+
+    /**
+     * The <A HREF="http://www.geotools.org">Geotools</A> project.
+     *
+     * @see ContactImpl#GEOTOOLS
+     */
+    public static ResponsibleParty GEOTOOLS;
+    static {
+        final ResponsiblePartyImpl r = new ResponsiblePartyImpl(Role.PRINCIPAL_INVESTIGATOR);
+        r.setOrganisationName(new SimpleInternationalString("Geotools"));
+        r.setContactInfo(ContactImpl.GEOTOOLS);
+        r.freeze();
+        GEOTOOLS = r;
+    }
+
+    /**
+     * Name of the responsible person- surname, given name, title separated by a delimiter.
+     */
+    private String individualName;
+
+    /**
+     * Name of the responsible organization.
+     */
+    private InternationalString organisationName;
+
+    /**
+     * Role or position of the responsible person
+     */
+    private InternationalString positionName;
+
+    /**
+     * Address of the responsible party.
+     */
+    private Contact contactInfo;
+
+    /**
+     * Function performed by the responsible party.
+     */
+    private Role role;
+
+    /**
+     * Constructs an initially empty responsible party.
+     */
+    public ResponsiblePartyImpl() {
+    }
+
+    /**
+     * Constructs a responsability party with the given role.
+     */
+    public ResponsiblePartyImpl(final Role role) {
+        setRole(role);
+    }
+
+    /**
+     * Returns the name of the responsible person- surname, given name, title separated by a delimiter.
+     * Only one of {@code individualName}, {@link #getOrganisationName organisationName}
+     * and {@link #getPositionName positionName} should be provided.
+     */
+    public String getIndividualName() {
+        return individualName;
+    }
+
+    /**
+     * Set the name of the responsible person- surname, given name, title separated by a delimiter.
+     * Only one of {@code individualName}, {@link #getOrganisationName organisationName}
+     * and {@link #getPositionName positionName} should be provided.
+     */
+    public synchronized void setIndividualName(final String newValue) {
+        checkWritePermission();
+        individualName = newValue;
+    }
+
+    /**
+     * Returns the name of the responsible organization.
+     * Only one of {@link #getIndividualName individualName}, </code>organisationName</code>
+     * and {@link #getPositionName positionName} should be provided.
+     */
+    public InternationalString getOrganisationName() {
+        return organisationName;
+    }
+
+    /**
+     * Set the name of the responsible organization.
+     * Only one of {@link #getIndividualName individualName}, </code>organisationName</code>
+     * and {@link #getPositionName positionName} should be provided.
+     */
+    public synchronized void setOrganisationName(final InternationalString newValue) {
+        checkWritePermission();
+        organisationName = newValue;
+    }
+
+    /**
+     * Returns the role or position of the responsible person
+     * Only one of {@link #getIndividualName individualName},
+     * {@link #getOrganisationName organisationName} and {@code positionName}
+     * should be provided.
+     */
+    public InternationalString getPositionName() {
+        return positionName;
+    }
+
+    /**
+     * set the role or position of the responsible person
+     * Only one of {@link #getIndividualName individualName},
+     * {@link #getOrganisationName organisationName} and {@code positionName}
+     * should be provided.
+     */
+    public synchronized void setPositionName(final InternationalString newValue) {
+        checkWritePermission();
+        positionName = newValue;
+    }
+
+    /**
+     * Returns the address of the responsible party.
+     */
+    public Contact getContactInfo() {
+        return contactInfo;
+    }
+
+    /**
+     * Set the address of the responsible party.
+     */
+    public synchronized void setContactInfo(final Contact newValue) {
+        checkWritePermission();
+        contactInfo = newValue;
+    }
+
+    /**
+     * Returns the function performed by the responsible party.
+     */
+    public Role getRole() {
+        return role;
+    }
+
+    /**
+     * Set the function performed by the responsible party.
+     */
+    public synchronized void setRole(final Role newValue) {
+        checkWritePermission();
+        role = newValue;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/extent/ExtentImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/extent/ExtentImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/extent/ExtentImpl.java	(revision 28000)
@@ -0,0 +1,82 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso.extent;
+
+import java.util.Collection;
+
+import org.geotools.metadata.iso.MetadataEntity;
+import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.extent.GeographicExtent;
+
+
+/**
+ * Information about spatial, vertical, and temporal extent.
+ * This interface has four optional attributes
+ * ({@linkplain #getGeographicElements geographic elements},
+ *  {@linkplain #getTemporalElements temporal elements}, and
+ *  {@linkplain #getVerticalElements vertical elements}) and an element called
+ *  {@linkplain #getDescription description}.
+ *  At least one of the four shall be used.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/extent/ExtentImpl.java $
+ * @version $Id: ExtentImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Touraïvane
+ *
+ * @since 2.1
+ */
+public class ExtentImpl extends MetadataEntity implements Extent {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 7812213837337326257L;
+
+    /**
+     * A geographic extent ranging from 180°W to 180°E and 90°S to 90°N.
+     *
+     * @since 2.2
+     */
+    public static final Extent WORLD;
+    static {
+        final ExtentImpl world = new ExtentImpl();
+        world.getGeographicElements().add(GeographicBoundingBoxImpl.WORLD);
+        world.freeze();
+        WORLD = world;
+    }
+
+    /**
+     * Provides geographic component of the extent of the referring object
+     */
+    private Collection<GeographicExtent> geographicElements;
+
+    /**
+     * Constructs an initially empty extent.
+     */
+    public ExtentImpl() {
+    }
+
+    /**
+     * Provides geographic component of the extent of the referring object
+     */
+    public synchronized Collection<GeographicExtent> getGeographicElements() {
+        return (geographicElements = nonNullCollection(geographicElements, GeographicExtent.class));
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/extent/GeographicBoundingBoxImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/extent/GeographicBoundingBoxImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/extent/GeographicBoundingBoxImpl.java	(revision 28000)
@@ -0,0 +1,399 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso.extent;
+
+import static java.lang.Double.doubleToLongBits;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.util.Locale;
+
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+import org.opengis.metadata.extent.GeographicBoundingBox;
+
+
+/**
+ * Geographic position of the dataset. This is only an approximate so specifying the coordinate
+ * reference system is unnecessary. The CRS shall be geographic with Greenwich prime meridian,
+ * but the datum doesn't need to be WGS84.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/extent/GeographicBoundingBoxImpl.java $
+ * @version $Id: GeographicBoundingBoxImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Touraïvane
+ */
+public class GeographicBoundingBoxImpl extends GeographicExtentImpl
+        implements GeographicBoundingBox
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -3278089380004172514L;
+
+    /**
+     * The method for constructing a string representation of this box.
+     * Will be obtained only when first needed.
+     */
+    private static Method toString;
+
+    /**
+     * A bounding box ranging from 180°W to 180°E and 90°S to 90°N.
+     *
+     * @since 2.2
+     */
+    public static final GeographicBoundingBox WORLD;
+    static {
+        final GeographicBoundingBoxImpl world = new GeographicBoundingBoxImpl(-180, 180, -90, 90);
+        world.freeze();
+        WORLD = world;
+    }
+
+    /**
+     * The western-most coordinate of the limit of the dataset extent.
+     * The value is expressed in longitude in decimal degrees (positive east).
+     */
+    private double westBoundLongitude;
+
+    /**
+     * The eastern-most coordinate of the limit of the dataset extent.
+     * The value is expressed in longitude in decimal degrees (positive east).
+     */
+    private double eastBoundLongitude;
+
+    /**
+     * The southern-most coordinate of the limit of the dataset extent.
+     * The value is expressed in latitude in decimal degrees (positive north).
+     */
+    private double southBoundLatitude;
+
+    /**
+     * The northern-most, coordinate of the limit of the dataset extent.
+     * The value is expressed in latitude in decimal degrees (positive north).
+     */
+    private double northBoundLatitude;
+
+    /**
+     * Constructs an initially empty geographic bounding box.
+     */
+    public GeographicBoundingBoxImpl() {
+    }
+
+    /**
+     * Constructs a geographic bounding box initialized to the same values than the specified one.
+     *
+     * @param box The existing box to use for initializing this geographic bounding box.
+     *
+     * @since 2.2
+     */
+    public GeographicBoundingBoxImpl(final GeographicBoundingBox box) {
+        /*
+         * We could invokes super(box), but we will perform the assignations explicitly here
+         * for performance reason. Warning: it may be a problem if the user creates a subclass
+         * and relies on the default MetadataEntity(Object) behavior. Rather than bothering
+         * the user with a javadoc warning, I would prefer to find some trick to avoid this
+         * issue (todo).
+         */
+        super();
+        setBounds(box);
+    }
+
+    /**
+     * Creates a geographic bounding box initialized to the specified values.
+     * <p>
+     * <strong>Caution:</strong> Arguments are expected in the same order than they appear in the
+     * ISO 19115 specification. This is different than the order commonly found in Java world,
+     * which is rather (<var>x</var><sub>min</sub>, <var>y</var><sub>min</sub>,
+     * <var>x</var><sub>max</sub>, <var>y</var><sub>max</sub>).
+     *
+     * @param westBoundLongitude The minimal <var>x</var> value.
+     * @param eastBoundLongitude The maximal <var>x</var> value.
+     * @param southBoundLatitude The minimal <var>y</var> value.
+     * @param northBoundLatitude The maximal <var>y</var> value.
+     */
+    public GeographicBoundingBoxImpl(final double westBoundLongitude,
+                                     final double eastBoundLongitude,
+                                     final double southBoundLatitude,
+                                     final double northBoundLatitude)
+    {
+        super(true);
+        setBounds(westBoundLongitude, eastBoundLongitude,
+                  southBoundLatitude, northBoundLatitude);
+    }
+
+    /**
+     * Returns the western-most coordinate of the limit of the
+     * dataset extent. The value is expressed in longitude in
+     * decimal degrees (positive east).
+     *
+     * @return The western-most longitude between -180 and +180°.
+     */
+    public double getWestBoundLongitude() {
+        return westBoundLongitude;
+    }
+
+    /**
+     * Returns the eastern-most coordinate of the limit of the
+     * dataset extent. The value is expressed in longitude in
+     * decimal degrees (positive east).
+     *
+     * @return The eastern-most longitude between -180 and +180°.
+     */
+    public double getEastBoundLongitude() {
+        return eastBoundLongitude;
+    }
+
+    /**
+     * Returns the southern-most coordinate of the limit of the
+     * dataset extent. The value is expressed in latitude in
+     * decimal degrees (positive north).
+     *
+     * @return The southern-most latitude between -90 and +90°.
+     */
+    public double getSouthBoundLatitude()  {
+        return southBoundLatitude;
+    }
+
+    /**
+     * Returns the northern-most, coordinate of the limit of the
+     * dataset extent. The value is expressed in latitude in
+     * decimal degrees (positive north).
+     *
+     * @return The northern-most latitude between -90 and +90°.
+     */
+    public double getNorthBoundLatitude()   {
+        return northBoundLatitude;
+    }
+
+    /**
+     * Sets the bounding box to the specified values.
+     * <p>
+     * <strong>Caution:</strong> Arguments are expected in the same order than they appear in the
+     * ISO 19115 specification. This is different than the order commonly found in Java world,
+     * which is rather (<var>x</var><sub>min</sub>, <var>y</var><sub>min</sub>,
+     * <var>x</var><sub>max</sub>, <var>y</var><sub>max</sub>).
+     *
+     * @param westBoundLongitude The minimal <var>x</var> value.
+     * @param eastBoundLongitude The maximal <var>x</var> value.
+     * @param southBoundLatitude The minimal <var>y</var> value.
+     * @param northBoundLatitude The maximal <var>y</var> value.
+     *
+     * @since 2.5
+     */
+    public synchronized void setBounds(final double westBoundLongitude,
+                                       final double eastBoundLongitude,
+                                       final double southBoundLatitude,
+                                       final double northBoundLatitude)
+    {
+        checkWritePermission();
+        this.westBoundLongitude = westBoundLongitude;
+        this.eastBoundLongitude = eastBoundLongitude;
+        this.southBoundLatitude = southBoundLatitude;
+        this.northBoundLatitude = northBoundLatitude;
+    }
+
+    /**
+     * Sets the bounding box to the same values than the specified box.
+     *
+     * @param box The geographic bounding box to use for setting the values of this box.
+     *
+     * @since 2.5
+     */
+    public void setBounds(final GeographicBoundingBox box) {
+        ensureNonNull("box", box);
+        setInclusion(box.getInclusion());
+        setBounds(box.getWestBoundLongitude(), box.getEastBoundLongitude(),
+                  box.getSouthBoundLatitude(), box.getNorthBoundLatitude());
+    }
+
+    /**
+     * Adds a geographic bounding box to this box. If the {@linkplain #getInclusion inclusion}
+     * status is the same for this box and the box to be added, then the resulting bounding box
+     * is the union of the two boxes. If the {@linkplain #getInclusion inclusion} status are
+     * opposite (<cite>exclusion</cite>), then this method attempt to exclude some area of
+     * specified box from this box. The resulting bounding box is smaller if the exclusion can
+     * be performed without ambiguity.
+     *
+     * @param box The geographic bounding box to add to this box.
+     *
+     * @since 2.2
+     */
+    public synchronized void add(final GeographicBoundingBox box) {
+        checkWritePermission();
+        final double xmin = box.getWestBoundLongitude();
+        final double xmax = box.getEastBoundLongitude();
+        final double ymin = box.getSouthBoundLatitude();
+        final double ymax = box.getNorthBoundLatitude();
+        /*
+         * Reminder: 'inclusion' is a mandatory attribute, so it should never be null for a
+         * valid metadata object.  If the metadata object is invalid, it is better to get a
+         * an exception than having a code doing silently some inappropriate work.
+         */
+        final Boolean inc1 =     getInclusion(); ensureNonNull("inclusion", inc1);
+        final Boolean inc2 = box.getInclusion(); ensureNonNull("inclusion", inc2);
+        if (inc1.booleanValue() == inc2.booleanValue()) {
+            if (xmin < westBoundLongitude) westBoundLongitude = xmin;
+            if (xmax > eastBoundLongitude) eastBoundLongitude = xmax;
+            if (ymin < southBoundLatitude) southBoundLatitude = ymin;
+            if (ymax > northBoundLatitude) northBoundLatitude = ymax;
+        } else {
+            if (ymin <= southBoundLatitude && ymax >= northBoundLatitude) {
+                if (xmin > westBoundLongitude) westBoundLongitude = xmin;
+                if (xmax < eastBoundLongitude) eastBoundLongitude = xmax;
+            }
+            if (xmin <= westBoundLongitude && xmax >= eastBoundLongitude) {
+                if (ymin > southBoundLatitude) southBoundLatitude = ymin;
+                if (ymax < northBoundLatitude) northBoundLatitude = ymax;
+            }
+        }
+    }
+
+    /**
+     * Compares this geographic bounding box with the specified object for equality.
+     *
+     * @param object The object to compare for equality.
+     * @return {@code true} if the given object is equals to this box.
+     */
+    @Override
+    public synchronized boolean equals(final Object object) {
+        if (object == this) {
+            return true;
+        }
+        // Above code really requires GeographicBoundingBoxImpl.class, not getClass().
+        if (object!=null && object.getClass().equals(GeographicBoundingBoxImpl.class)) {
+            final GeographicBoundingBoxImpl that = (GeographicBoundingBoxImpl) object;
+            return Utilities.equals(this.getInclusion(), that.getInclusion()) &&
+                   doubleToLongBits(this.southBoundLatitude) ==
+                   doubleToLongBits(that.southBoundLatitude) &&
+                   doubleToLongBits(this.northBoundLatitude) ==
+                   doubleToLongBits(that.northBoundLatitude) &&
+                   doubleToLongBits(this.eastBoundLongitude) ==
+                   doubleToLongBits(that.eastBoundLongitude) &&
+                   doubleToLongBits(this.westBoundLongitude) ==
+                   doubleToLongBits(that.westBoundLongitude);
+        }
+        return super.equals(object);
+    }
+
+    /**
+     * Returns a hash code value for this extent.
+     *
+     * @todo Consider relying on the default implementation, since it cache the hash code.
+     */
+    @Override
+    public synchronized int hashCode() {
+        if (!getClass().equals(GeographicBoundingBoxImpl.class)) {
+            return super.hashCode();
+        }
+        final Boolean inclusion = getInclusion();
+        int code = (inclusion != null) ? inclusion.hashCode() : 0;
+        code += hashCode(southBoundLatitude);
+        code += hashCode(northBoundLatitude);
+        code += hashCode(eastBoundLongitude);
+        code += hashCode(westBoundLongitude);
+        return code;
+    }
+
+    /**
+     * Returns a hash code value for the specified {@code double}.
+     */
+    private static int hashCode(final double value) {
+        final long code = doubleToLongBits(value);
+        return (int)code ^ (int)(code >>> 32);
+    }
+
+    /**
+     * Returns a string representation of this extent using a default angle pattern.
+     */
+    @Override
+    public String toString() {
+        return toString(this, "DD°MM'SS.s\"", null);
+    }
+
+    /**
+     * Returns a string representation of the specified extent using the specified angle pattern
+     * and locale. See {@link AngleFormat} for a description of angle patterns.
+     *
+     * @param box     The bounding box to format.
+     * @param pattern The angle pattern (e.g. {@code DD°MM'SS.s"}.
+     * @param locale  The locale, or {@code null} for the default one.
+     * @return A string representation of the given box in the given locale.
+     *
+     * @since 2.2
+     */
+    public static String toString(final GeographicBoundingBox box,
+                                  final String                pattern,
+                                  final Locale                locale)
+    {
+        if (toString == null) {
+            // No need to synchronize.
+            toString = getMethod("toString",  new Class[] {
+                        GeographicBoundingBox.class, String.class, Locale.class});
+        }
+        try {
+            return String.valueOf(invoke(toString, new Object[] {box, pattern, locale}));
+        } catch (InvocationTargetException exception) {
+            throw new UndeclaredThrowableException(exception.getTargetException());
+        }
+    }
+
+    /**
+     * Returns a helper method which depends on the referencing module. We use reflection
+     * since we can't have a direct dependency to this module.
+     */
+    private static Method getMethod(final String name, final Class<?>[] arguments) {
+        try {
+            return Class.forName("org.geotools.resources.BoundingBoxes").getMethod(name, arguments);
+        } catch (ClassNotFoundException exception) {
+            throw new UnsupportedOperationException(Errors.format(
+                    ErrorKeys.MISSING_MODULE_$1, "referencing"), exception);
+        } catch (NoSuchMethodException exception) {
+            // Should never happen if we didn't broke our BoundingBoxes helper class.
+            throw new AssertionError(exception);
+        }
+    }
+
+    /**
+     * Invokes the specified method with the specified arguments.
+     */
+    private static Object invoke(final Method method, final Object[] arguments)
+            throws InvocationTargetException
+    {
+        try {
+            return method.invoke(null, arguments);
+        } catch (IllegalAccessException exception) {
+            // Should never happen if our BoundingBoxes helper class is not broken.
+            throw new AssertionError(exception);
+        } catch (InvocationTargetException exception) {
+            final Throwable cause = exception.getTargetException();
+            if (cause instanceof RuntimeException) {
+                throw (RuntimeException) cause;
+            }
+            if (cause instanceof Error) {
+                throw (Error) cause;
+            }
+            throw exception;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/extent/GeographicExtentImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/extent/GeographicExtentImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/extent/GeographicExtentImpl.java	(revision 28000)
@@ -0,0 +1,80 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso.extent;
+
+import org.opengis.metadata.extent.GeographicExtent;
+import org.geotools.metadata.iso.MetadataEntity;
+
+
+/**
+ * Base class for geographic area of the dataset.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/extent/GeographicExtentImpl.java $
+ * @version $Id: GeographicExtentImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Touraïvane
+ *
+ * @since 2.1
+ */
+public class GeographicExtentImpl extends MetadataEntity implements GeographicExtent {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -8844015895495563161L;
+
+    /**
+     * Indication of whether the bounding polygon encompasses an area covered by the data
+     * (<cite>inclusion</cite>) or an area where data is not present (<cite>exclusion</cite>).
+     */
+    private Boolean inclusion;
+
+    /**
+     * Constructs an initially empty geographic extent.
+     */
+    public GeographicExtentImpl() {
+    }
+
+    /**
+     * Constructs a geographic extent initialized with the specified inclusion value.
+     */
+    public GeographicExtentImpl(final boolean inclusion) {
+        setInclusion(Boolean.valueOf(inclusion));
+    }
+
+    /**
+     * Indication of whether the bounding polygon encompasses an area covered by the data
+     * (<cite>inclusion</cite>) or an area where data is not present (<cite>exclusion</cite>).
+     *
+     * @return {@code true} for inclusion, or {@code false} for exclusion.
+     */
+    public Boolean getInclusion() {
+        return inclusion;
+    }
+
+    /**
+     * Set whether the bounding polygon encompasses an area covered by the data
+     * (<cite>inclusion</cite>) or an area where data is not present (<cite>exclusion</cite>).
+     */
+    public synchronized void setInclusion(final Boolean newValue) {
+        checkWritePermission();
+        inclusion = newValue;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/AbsoluteExternalPositionalAccuracyImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/AbsoluteExternalPositionalAccuracyImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/AbsoluteExternalPositionalAccuracyImpl.java	(revision 28000)
@@ -0,0 +1,57 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso.quality;
+
+import org.opengis.metadata.quality.Result;
+import org.opengis.metadata.quality.AbsoluteExternalPositionalAccuracy;
+
+
+/**
+ * Closeness of reported coordinate values to values accepted as or being true.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/quality/AbsoluteExternalPositionalAccuracyImpl.java $
+ * @version $Id: AbsoluteExternalPositionalAccuracyImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Touraïvane
+ *
+ * @since 2.1
+ */
+public class AbsoluteExternalPositionalAccuracyImpl extends PositionalAccuracyImpl
+       implements AbsoluteExternalPositionalAccuracy
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 4116627805950579738L;
+
+    /**
+     * Constructs an initially empty absolute external positional accuracy.
+     */
+    public AbsoluteExternalPositionalAccuracyImpl() {
+    }
+
+    /**
+     * Creates an positional accuracy initialized to the given result.
+     */
+    public AbsoluteExternalPositionalAccuracyImpl(final Result result) {
+        super(result);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/ConformanceResultImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/ConformanceResultImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/ConformanceResultImpl.java	(revision 28000)
@@ -0,0 +1,124 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso.quality;
+
+import org.opengis.metadata.citation.Citation;
+import org.opengis.metadata.quality.ConformanceResult;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * Information about the outcome of evaluating the obtained value (or set of values) against
+ * a specified acceptable conformance quality level.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/quality/ConformanceResultImpl.java $
+ * @version $Id: ConformanceResultImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Touraïvane
+ *
+ * @since 2.1
+ */
+public class ConformanceResultImpl extends ResultImpl implements ConformanceResult {
+
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = 6429932577869033286L;
+
+    /**
+     * Citation of product specification or user requirement against which data is being evaluated.
+     */
+    private Citation specification;
+
+    /**
+     * Explanation of the meaning of conformance for this result.
+     */
+    private InternationalString explanation;
+
+    /**
+     * Indication of the conformance result.
+     */
+    private boolean pass;
+
+    /**
+     * Constructs an initially empty conformance result.
+     */
+    public ConformanceResultImpl() {
+    }
+
+    /**
+     * Creates a conformance result initialized to the given values.
+     */
+    public ConformanceResultImpl(final Citation            specification,
+                                 final InternationalString explanation,
+                                 final boolean             pass)
+    {
+        setSpecification(specification);
+        setExplanation  (explanation);
+        setPass         (pass);
+    }
+
+    /**
+     * Citation of product specification or user requirement against which data is being evaluated.
+     */
+    public Citation getSpecification() {
+        return specification;
+    }
+
+    /**
+     * Set the citation of product specification or user requirement against which data
+     * is being evaluated.
+     */
+    public synchronized void setSpecification(final Citation newValue) {
+        checkWritePermission();
+        specification = newValue;
+    }
+
+    /**
+     * Explanation of the meaning of conformance for this result.
+     */
+    public InternationalString getExplanation() {
+        return explanation;
+    }
+
+    /**
+     * Set the explanation of the meaning of conformance for this result.
+     */
+    public synchronized void setExplanation(final InternationalString newValue) {
+        checkWritePermission();
+        explanation = newValue;
+    }
+
+    /**
+     * Indication of the conformance result.
+     */
+    public boolean pass() {
+        return pass;
+    }
+
+    /**
+     * Set the indication of the conformance result.
+     */
+    public synchronized void setPass(final boolean newValue) {
+        checkWritePermission();
+        pass = newValue;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/ElementImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/ElementImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/ElementImpl.java	(revision 28000)
@@ -0,0 +1,151 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso.quality;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.geotools.metadata.iso.MetadataEntity;
+import org.opengis.metadata.quality.Element;
+import org.opengis.metadata.quality.EvaluationMethodType;
+import org.opengis.metadata.quality.Result;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * Type of test applied to the data specified by a data quality scope.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/quality/ElementImpl.java $
+ * @version $Id: ElementImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Touraïvane
+ *
+ * @since 2.1
+ */
+public class ElementImpl extends MetadataEntity implements Element {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -3542504624077298894L;
+
+    /**
+     * Description of the measure being determined.
+     */
+    private InternationalString measureDescription;
+
+    /**
+     * Type of method used to evaluate quality of the dataset, or {@code null} if unspecified.
+     */
+    private EvaluationMethodType evaluationMethodType;
+
+    /**
+     * Description of the evaluation method.
+     */
+    private InternationalString evaluationMethodDescription;
+
+    /**
+     * Value (or set of values) obtained from applying a data quality measure or the out
+     * come of evaluating the obtained value (or set of values) against a specified
+     * acceptable conformance quality level.
+     */
+    private Collection<Result> results;
+
+    /**
+     * Constructs an initially empty element.
+     */
+    public ElementImpl() {
+    }
+
+    /**
+     * Creates an element initialized to the given result.
+     */
+    public ElementImpl(final Result result) {
+        setResults(Collections.singleton(result));
+    }
+
+    /**
+     * Returns the description of the measure being determined.
+     */
+    public InternationalString getMeasureDescription() {
+        return measureDescription;
+    }
+
+    /**
+     * Set the description of the measure being determined.
+     */
+    public synchronized void setMeasureDescription(final InternationalString newValue)  {
+        checkWritePermission();
+        measureDescription = newValue;
+    }
+
+    /**
+     * Returns the type of method used to evaluate quality of the dataset,
+     * or {@code null} if unspecified.
+     */
+    public EvaluationMethodType getEvaluationMethodType() {
+        return evaluationMethodType;
+    }
+
+    /**
+     * Set the ype of method used to evaluate quality of the dataset.
+     */
+    public synchronized void setEvaluationMethodType(final EvaluationMethodType newValue)  {
+        checkWritePermission();
+        evaluationMethodType = newValue;
+    }
+
+    /**
+     * Returns the description of the evaluation method.
+     */
+    public InternationalString getEvaluationMethodDescription() {
+        return evaluationMethodDescription;
+    }
+
+    /**
+     * Set the description of the evaluation method.
+     */
+    public synchronized void setEvaluationMethodDescription(final InternationalString newValue)  {
+        checkWritePermission();
+        evaluationMethodDescription = newValue;
+    }
+
+    /**
+     * Returns the value (or set of values) obtained from applying a data quality measure or
+     * the out come of evaluating the obtained value (or set of values) against a specified
+     * acceptable conformance quality level.
+     *
+     * @since 2.4
+     */
+    public synchronized Collection<Result> getResults() {
+        return results = nonNullCollection(results, Result.class);
+    }
+
+    /**
+     * Set the value (or set of values) obtained from applying a data quality measure or
+     * the out come of evaluating the obtained value (or set of values) against a specified
+     * acceptable conformance quality level.
+     *
+     * @since 2.4
+     */
+    public synchronized void setResults(final Collection<? extends Result> newValues) {
+        results = copyCollection(newValues, results, Result.class);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/PositionalAccuracyImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/PositionalAccuracyImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/PositionalAccuracyImpl.java	(revision 28000)
@@ -0,0 +1,105 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso.quality;
+
+import org.opengis.metadata.quality.Result;
+import org.opengis.metadata.quality.EvaluationMethodType;
+import org.opengis.metadata.quality.PositionalAccuracy;
+import org.opengis.util.InternationalString;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.util.SimpleInternationalString;
+
+
+/**
+ * Accuracy of the position of features.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/quality/PositionalAccuracyImpl.java $
+ * @version $Id: PositionalAccuracyImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Touraïvane
+ *
+ * @since 2.1
+ */
+public class PositionalAccuracyImpl extends ElementImpl implements PositionalAccuracy {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 6043381860937480828L;
+
+    /**
+     * Indicates that a {@linkplain org.opengis.referencing.operation.Transformation transformation}
+     * requires a datum shift and some method has been applied. Datum shift methods often use
+     * {@linkplain org.geotools.referencing.datum.BursaWolfParameters Bursa Wolf parameters},
+     * but other kind of method may have been applied as well.
+     *
+     * @see org.opengis.referencing.operation.Transformation#getPositionalAccuracy
+     * @see org.geotools.referencing.operation.AbstractCoordinateOperationFactory#DATUM_SHIFT
+     */
+    public static final PositionalAccuracy DATUM_SHIFT_APPLIED;
+
+    /**
+     * Indicates that a {@linkplain org.opengis.referencing.operation.Transformation transformation}
+     * requires a datum shift, but no method has been found applicable. This usually means that no
+     * {@linkplain org.geotools.referencing.datum.BursaWolfParameters Bursa Wolf parameters} have
+     * been found. Such datum shifts are approximative and may have 1 kilometer error. This
+     * pseudo-transformation is allowed by
+     * {@linkplain org.geotools.referencing.operation.DefaultCoordinateOperationFactory coordinate
+     * operation factory} only if it was created with
+     * {@link org.geotools.factory.Hints#LENIENT_DATUM_SHIFT} set to {@link Boolean#TRUE}.
+     *
+     * @see org.opengis.referencing.operation.Transformation#getPositionalAccuracy
+     * @see org.geotools.referencing.operation.AbstractCoordinateOperationFactory#ELLIPSOID_SHIFT
+     */
+    public static final PositionalAccuracy DATUM_SHIFT_OMITTED;
+    static {
+        // TODO: localize.
+        final InternationalString   desc = new SimpleInternationalString("Transformation accuracy");
+        final InternationalString   eval = new SimpleInternationalString("Is a datum shift method applied?");
+        final ConformanceResultImpl pass = new ConformanceResultImpl(Citations.GEOTOOLS, eval, true );
+        final ConformanceResultImpl fail = new ConformanceResultImpl(Citations.GEOTOOLS, eval, false);
+        pass.freeze();
+        fail.freeze();
+        final PositionalAccuracyImpl APPLIED, OMITTED;
+        DATUM_SHIFT_APPLIED = APPLIED = new AbsoluteExternalPositionalAccuracyImpl(pass);
+        DATUM_SHIFT_OMITTED = OMITTED = new AbsoluteExternalPositionalAccuracyImpl(fail);
+        APPLIED.setMeasureDescription(desc);
+        OMITTED.setMeasureDescription(desc);
+        APPLIED.setEvaluationMethodDescription(eval);
+        OMITTED.setEvaluationMethodDescription(eval);
+        APPLIED.setEvaluationMethodType(EvaluationMethodType.DIRECT_INTERNAL);
+        OMITTED.setEvaluationMethodType(EvaluationMethodType.DIRECT_INTERNAL);
+        APPLIED.freeze();
+        OMITTED.freeze();
+    }
+
+    /**
+     * Constructs an initially empty positional accuracy.
+     */
+    public PositionalAccuracyImpl() {
+    }
+
+    /**
+     * Creates an positional accuracy initialized to the given result.
+     */
+    public PositionalAccuracyImpl(final Result result) {
+        super(result);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/ResultImpl.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/ResultImpl.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/iso/quality/ResultImpl.java	(revision 28000)
@@ -0,0 +1,48 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.metadata.iso.quality;
+
+import org.opengis.metadata.quality.Result;
+import org.geotools.metadata.iso.MetadataEntity;
+
+
+/**
+ * Type of test applied to the data specified by a data quality scope.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/metadata/iso/quality/ResultImpl.java $
+ * @version $Id: ResultImpl.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Touraïvane
+ *
+ * @since 2.1
+ */
+public class ResultImpl extends MetadataEntity implements Result {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 2961355780515174732L;
+
+    /**
+     * Constructs an initially empty result.
+     */
+    public ResultImpl() {
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/metadata/package.html	(revision 28000)
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.metadata</TITLE>
+  </HEAD>
+  <BODY>
+  Root package for various metadata implementations. This root package is not
+  linked to any particular metadata standard. It assumes that a standard is
+  defined through a set of Java interfaces (for example {@link org.opengis.metadata})
+  and uses reflection for performing basic operations like comparaisons and copies.
+  <p>
+  Possible metadata implementations (already available or planed in a future
+  Geotools version) are:
+  <UL>
+    <LI><P>{@link org.geotools.metadata.iso}: concrete implementation of ISO
+        interfaces, including ISO 19115.</P></LI>
+    <LI><P>{@code org.geotools.metadata.dublin}: concrete implementation of
+        Dublin core interfaces. <EM>Not yet implemented.</EM></P></LI>
+    <LI><P>{@link org.geotools.metadata.sql}: implementation of metadata interfaces
+        backed by a SQL database. The metadata interfaces doesn't need to be ISO ones,
+        which is why this package is not a sub-package of the ISO's one.</P></LI>
+    <LI><P>{@code org.geotools.metadata.xml}: implementation of metadata interfaces
+        backed by a XML files. The metadata interfaces doesn't need to be ISO ones,
+        which is why this package is not a sub-package of the ISO's one.
+        <EM>Not yet implemented.</EM></P></LI>
+  </UL>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/AbstractParameter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/AbstractParameter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/AbstractParameter.java	(revision 28000)
@@ -0,0 +1,316 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.parameter;
+
+import java.io.Writer;
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.Iterator;
+
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.parameter.GeneralParameterDescriptor;
+
+import org.geotools.util.Utilities;
+import org.geotools.io.TableWriter;
+import org.geotools.referencing.wkt.Formattable;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * Abstract parameter value or group of parameter values.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/parameter/AbstractParameter.java $
+ * @version $Id: AbstractParameter.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see AbstractParameterDescriptor
+ */
+public abstract class AbstractParameter extends Formattable
+           implements GeneralParameterValue, Serializable
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 8458179223988766398L;
+
+    /**
+     * The abstract definition of this parameter or group of parameters.
+     */
+    final GeneralParameterDescriptor descriptor;
+
+    /**
+     * Constructs a parameter value from the specified descriptor.
+     *
+     * @param descriptor The abstract definition of this parameter or group of parameters.
+     */
+    protected AbstractParameter(final GeneralParameterDescriptor descriptor) {
+        this.descriptor = descriptor;
+        ensureNonNull("descriptor", descriptor);
+    }
+
+    /**
+     * Returns the abstract definition of this parameter or group of parameters.
+     */
+    public GeneralParameterDescriptor getDescriptor() {
+        return descriptor;
+    }
+
+    /**
+     * Makes sure that an argument is non-null. This method was already defined in
+     * {@link org.geotools.referencing.AbstractIdentifiedObject}, but is defined here again
+     * in order to get a more appropriate stack trace, and for access by class which do not
+     * inherit from {@link org.geotools.referencing.AbstractIdentifiedObject}.
+     *
+     * @param  name   Argument name.
+     * @param  object User argument.
+     * @throws IllegalArgumentException if {@code object} is null.
+     */
+    static void ensureNonNull(final String name, final Object object)
+            throws IllegalArgumentException
+    {
+        if (object == null) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1, name));
+        }
+    }
+
+    /**
+     * Makes sure an array element is non-null. This is
+     * a convenience method for subclass constructors.
+     *
+     * @param  name  Argument name.
+     * @param  array The array to look at.
+     * @param  index Index of the element to check.
+     * @throws IllegalArgumentException if {@code array[i]} is null.
+     */
+    static void ensureNonNull(final String name, final Object[] array, final int index)
+        throws IllegalArgumentException
+    {
+        if (array[index] == null) {
+            throw new IllegalArgumentException(Errors.format(
+                      ErrorKeys.NULL_ARGUMENT_$1, name+'['+index+']'));
+        }
+    }
+
+    /**
+     * Verify that the specified value is of the specified class.
+     *
+     * @param  expectedClass the expected class.
+     * @param  value The expected value, or {@code null}.
+     * @throws IllegalArgumentException if {@code value} is non-null and has a non-assignable
+     *         class.
+     */
+    static <T> void ensureValidClass(final Class<?> expectedClass, final Object value)
+            throws IllegalArgumentException
+    {
+        if (value != null) {
+            final Class<?> valueClass = value.getClass();
+            if (!expectedClass.isAssignableFrom(valueClass)) {
+                throw new IllegalArgumentException(Errors.format(
+                        ErrorKeys.ILLEGAL_CLASS_$2, valueClass, expectedClass));
+            }
+        }
+    }
+
+    /**
+     * Returns an exception initialized with a "Unitless parameter" error message for the
+     * specified descriptor.
+     */
+    static IllegalStateException unitlessParameter(final GeneralParameterDescriptor descriptor) {
+        return new IllegalStateException(Errors.format(ErrorKeys.UNITLESS_PARAMETER_$1,
+                                                       getName(descriptor)));
+    }
+
+    /**
+     * Convenience method returning the name of the specified descriptor. This method is used
+     * mostly for output to be read by human, not for processing. Consequently, we may consider
+     * to returns a localized name in a future version.
+     */
+    static String getName(final GeneralParameterDescriptor descriptor) {
+        return descriptor.getName().getCode();
+    }
+
+    /**
+     * Returns a copy of this parameter value or group.
+     */
+    @Override
+    public AbstractParameter clone() {
+        try {
+            return (AbstractParameter) super.clone();
+        } catch (CloneNotSupportedException exception) {
+            // Should not happen, since we are cloneable
+            throw new AssertionError(exception);
+        }
+    }
+
+    /**
+     * Compares the specified object with this parameter for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object!=null && object.getClass().equals(getClass())) {
+            final AbstractParameter that = (AbstractParameter) object;
+            return Utilities.equals(this.descriptor, that.descriptor);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this parameter. This value doesn't need
+     * to be the same in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return descriptor.hashCode() ^ (int)serialVersionUID;
+    }
+
+    /**
+     * Returns a string representation of this parameter. The default implementation
+     * delegates the work to {@link #write}, which should be overridden by subclasses.
+     */
+    @Override
+    public final String toString() {
+        final TableWriter table = new TableWriter(null, 1);
+        table.setMultiLinesCells(true);
+        try {
+            write(table);
+        } catch (IOException exception) {
+            // Should never happen, since we write to a StringWriter.
+            throw new AssertionError(exception);
+        }
+        return table.toString();
+    }
+
+    /**
+     * Write the content of this parameter to the specified table. This method make it easier
+     * to align values properly than overriding the {@link #toString} method. The table's columns
+     * are defined as below:
+     * <ol>
+     *   <li>The parameter name</li>
+     *   <li>The separator</li>
+     *   <li>The parameter value</li>
+     * </ol>
+     *
+     * <P>The default implementation is suitable for most cases. However, subclasses are free to
+     * override this method with the following idiom:</P>
+     *
+     * <blockquote><pre>
+     * table.{@linkplain TableWriter#write(String) write}("<var>parameter name</var>");
+     * table.{@linkplain TableWriter#nextColumn() nextColumn}()
+     * table.{@linkplain TableWriter#write(String) write}('=');
+     * table.{@linkplain TableWriter#nextColumn() nextColumn}()
+     * table.{@linkplain TableWriter#write(String) write}("<var>parameter value</var>");
+     * table.{@linkplain TableWriter#nextLine() nextLine}()
+     * </pre></blockquote>
+     *
+     * @param  table The table where to format the parameter value.
+     * @throws IOException if an error occurs during output operation.
+     */
+    protected void write(final TableWriter table) throws IOException {
+        table.write(getName(descriptor));
+        table.nextColumn();
+        if (this instanceof ParameterValue) {
+            /*
+             * Provides a default implementation for parameter value. This implementation doesn't
+             * need to be a Geotools's one. Putting a default implementation here avoid duplication
+             * in all subclasses implementing the same interface.
+             */
+            table.write('=');
+            table.nextColumn();
+            append(table, ((ParameterValue) this).getValue());
+        } else if (this instanceof ParameterValueGroup) {
+            /*
+             * Provides a default implementation for parameter value group, for the same reasons
+             * then the previous block. Reminder: the above 'instanceof' check for interface, not
+             * for subclass. This explain why we use it instead of method overriding.
+             */
+            table.write(':');
+            table.nextColumn();
+            TableWriter inner = null;
+            for (final Iterator it=((ParameterValueGroup) this).values().iterator(); it.hasNext();) {
+                final GeneralParameterValue value = (GeneralParameterValue) it.next();
+                if (value instanceof AbstractParameter) {
+                    if (inner == null) {
+                        inner = new TableWriter(table, 1);
+                    }
+                    ((AbstractParameter) value).write(inner);
+                } else {
+                    // Unknow implementation. It will break the formatting. Too bad...
+                    if (inner != null) {
+                        inner.flush();
+                        inner = null;
+                    }
+                    table.write(value.toString());
+                    table.write(System.getProperty("line.separator", "\r"));
+                }
+            }
+            if (inner != null) {
+                inner.flush();
+            }
+        } else {
+            /*
+             * No know parameter value for this default implementation.
+             */
+        }
+        table.nextLine();
+    }
+
+    /**
+     * Append the specified value to a stream. If the value is an array, then
+     * the array element are appended recursively (i.e. the array may contains
+     * sub-array).
+     */
+    private static void append(final Writer buffer, final Object value) throws IOException {
+        if (value == null) {
+            buffer.write("null");
+        } else if (value.getClass().isArray()) {
+            buffer.write('{');
+            final int length = Array.getLength(value);
+            final int limit = Math.min(5, length);
+            for (int i=0; i<limit; i++) {
+                if (i != 0) {
+                    buffer.write(", ");
+                }
+                append(buffer, Array.get(value, i));
+            }
+            if (length > limit) {
+                buffer.write(", ...");
+            }
+            buffer.write('}');
+        } else {
+            final boolean isNumeric = (value instanceof Number);
+            if (!isNumeric) {
+                buffer.write('"');
+            }
+            buffer.write(value.toString());
+            if (!isNumeric) {
+                buffer.write('"');
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/AbstractParameterDescriptor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/AbstractParameterDescriptor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/AbstractParameterDescriptor.java	(revision 28000)
@@ -0,0 +1,141 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.parameter;
+
+import java.util.Map;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.parameter.GeneralParameterValue;
+
+
+/**
+ * Abstract definition of a parameter or group of parameters used by an operation method.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/parameter/AbstractParameterDescriptor.java $
+ * @version $Id: AbstractParameterDescriptor.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see AbstractParameter
+ */
+public abstract class AbstractParameterDescriptor extends AbstractIdentifiedObject
+           implements GeneralParameterDescriptor
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -2630644278783845276L;
+
+    /**
+     * The minimum number of times that values for this parameter group or
+     * parameter are required.
+     */
+    private final int minimumOccurs;
+
+    /**
+     * Constructs a parameter from a set of properties. The properties map is given unchanged to the
+     * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param minimumOccurs The {@linkplain #getMinimumOccurs minimum number of times}
+     *        that values for this parameter group or parameter are required.
+     * @param maximumOccurs The {@linkplain #getMaximumOccurs maximum number of times} that values
+     *        for this parameter group or parameter are required. This value is used in order to
+     *        check the range. For {@link org.opengis.parameter.ParameterValue}, it should always
+     *        be 1.
+     */
+    protected AbstractParameterDescriptor(final Map<String,?> properties,
+                                          final int minimumOccurs,
+                                          final int maximumOccurs)
+    {
+        super(properties);
+        this.minimumOccurs = minimumOccurs;
+        if (minimumOccurs < 0  ||  maximumOccurs < minimumOccurs) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.BAD_RANGE_$2,
+                        minimumOccurs, maximumOccurs));
+        }
+    }
+
+    /**
+     * Creates a new instance of {@linkplain AbstractParameter parameter value or group} initialized
+     * with the {@linkplain DefaultParameterDescriptor#getDefaultValue default value(s)}.
+     * The {@linkplain AbstractParameter#getDescriptor parameter value descriptor} for the
+     * created parameter value(s) will be {@code this} object.
+     * <p>
+     * Example implementation:
+     * <pre>
+     * <b>return</b> new {@linkplain Parameter}(this);
+     * </pre>
+     */
+    public abstract GeneralParameterValue createValue();
+
+    /**
+     * The minimum number of times that values for this parameter group or
+     * parameter are required. The default value is one. A value of 0 means
+     * an optional parameter.
+     *
+     * @see #getMaximumOccurs
+     */
+    public int getMinimumOccurs() {
+        return minimumOccurs;
+    }
+
+    /**
+     * The maximum number of times that values for this parameter group or parameter
+     * can be included. For a {@linkplain DefaultParameterDescriptor single parameter},
+     * the value is always 1. For a {@linkplain DefaultParameterDescriptorGroup parameter group},
+     * it may vary.
+     *
+     * @see #getMinimumOccurs
+     */
+    public abstract int getMaximumOccurs();
+
+    /**
+     * Compares the specified object with this parameter for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (super.equals(object, compareMetadata)) {
+            final AbstractParameterDescriptor that = (AbstractParameterDescriptor) object;
+            return this.minimumOccurs == that.minimumOccurs;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this parameter.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ minimumOccurs;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/DefaultParameterDescriptor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/DefaultParameterDescriptor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/DefaultParameterDescriptor.java	(revision 28000)
@@ -0,0 +1,427 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.parameter;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.measure.unit.Unit;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterValue;
+
+
+/**
+ * The definition of a parameter used by an operation method.
+ * For {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem Coordinate
+ * Reference Systems} most parameter values are numeric, but other types
+ * of parameter values are possible.
+ * <P>
+ * For numeric values, the {@linkplain #getValueClass value class} is usually
+ * <code>{@linkplain Double}.class</code>, <code>{@linkplain Integer}.class</code> or
+ * some other Java wrapper class.
+ * <P>
+ * This class contains numerous convenience constructors. But all of them ultimately invoke
+ * {@linkplain #DefaultParameterDescriptor(Map,Class,Object[],Object,Comparable,Comparable,Unit,boolean)
+ * a single, full-featured constructor}. All other constructors are just shortcuts.
+ *
+ * @param <T> The type of elements to be returned by {@link ParameterValue#getValue}.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/parameter/DefaultParameterDescriptor.java $
+ * @version $Id: DefaultParameterDescriptor.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see Parameter
+ * @see DefaultParameterDescriptorGroup
+ */
+public class DefaultParameterDescriptor<T> extends AbstractParameterDescriptor
+        implements ParameterDescriptor<T>
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -295668622297737705L;
+
+    /**
+     * The class that describe the type of the parameter.
+     * This is the value class that the user specified at construction time.
+     */
+    private final Class<T> valueClass;
+
+    /**
+     * A immutable, finite set of valid values (usually from a {linkplain org.opengis.util.CodeList
+     * code list}) or {@code null} if it doesn't apply. This set is immutable.
+     */
+    private final Set<T> validValues;
+
+    /**
+     * The default value for the parameter, or {@code null}.
+     */
+    private final T defaultValue;
+
+    /**
+     * The minimum parameter value, or {@code null}.
+     */
+    private final Comparable<T> minimum;
+
+    /**
+     * The maximum parameter value, or {@code null}.
+     */
+    private final Comparable<T> maximum;
+
+    /**
+     * The unit for default, minimum and maximum values, or {@code null}.
+     */
+    private final Unit<?> unit;
+
+    /**
+     * Constructs a parameter from a set of properties. The properties map is
+     * given unchanged to the {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map)
+     * super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param valueClass The class that describe the type of the parameter.
+     * @param validValues A finite set of valid values (usually from a
+     *        {linkplain org.opengis.util.CodeList code list}) or {@code null}
+     *        if it doesn't apply.
+     * @param defaultValue The default value for the parameter, or {@code null}.
+     * @param minimum  The minimum parameter value, or {@code null}.
+     * @param maximum  The maximum parameter value, or {@code null}.
+     * @param unit     The unit for default, minimum and maximum values.
+     * @param required {@code true} if this parameter is required,
+     *                 or {@code false} if it is optional.
+     */
+    public DefaultParameterDescriptor(final Map<String,?> properties,
+                                      final Class<T>      valueClass,
+                                      final T[]           validValues,
+                                      final T             defaultValue,
+                                      final Comparable<T> minimum,
+                                      final Comparable<T> maximum,
+                                      final Unit<?>       unit,
+                                      final boolean       required)
+    {
+        this(properties, required, valueClass, validValues, defaultValue, minimum, maximum, unit);
+    }
+
+    /**
+     * Constructs a parameter from a set of properties. The properties map is given unchanged to the
+     * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
+     * <p>
+     * This constructor assumes that minimum, maximum and default values are
+     * already replaced by their cached values, if available.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param required {@code true} if this parameter is required, or {@code false}
+     *        if it is optional.
+     * @param valueClass The class that describe the type of the parameter.
+     * @param validValues A finite set of valid values (usually from a
+     *        {linkplain org.opengis.util.CodeList code list}) or {@code null}
+     *        if it doesn't apply.
+     * @param defaultValue The default value for the parameter, or {@code null}.
+     * @param minimum The minimum parameter value, or {@code null}.
+     * @param maximum The maximum parameter value, or {@code null}.
+     * @param unit    The unit for default, minimum and maximum values.
+     */
+    private DefaultParameterDescriptor(final Map<String,?> properties,
+                                       final boolean       required,
+                                       final Class<T>      valueClass,
+                                       final T[]           validValues,
+                                       final T             defaultValue,
+                                       final Comparable<T> minimum,
+                                       final Comparable<T> maximum,
+                                       final Unit<?>       unit)
+    {
+        super(properties, required ? 1 : 0, 1);
+        this.valueClass     = valueClass;
+        this.defaultValue   = defaultValue;
+        this.minimum        = minimum;
+        this.maximum        = maximum;
+        this.unit           = unit;
+        ensureNonNull("valueClass", valueClass);
+        AbstractParameter.ensureValidClass(valueClass, defaultValue);
+        AbstractParameter.ensureValidClass(valueClass, minimum);
+        AbstractParameter.ensureValidClass(valueClass, maximum);
+        if (minimum!=null && maximum!=null) {
+            if (minimum.compareTo(valueClass.cast(maximum)) > 0) {
+                throw new IllegalArgumentException(Errors.format(
+                          ErrorKeys.BAD_RANGE_$2, minimum, maximum));
+            }
+        }
+        if (validValues != null) {
+            final Set<T> valids = new HashSet<T>(Math.max(validValues.length*4/3 + 1, 8), 0.75f);
+            for (int i=0; i<validValues.length; i++) {
+                final T value = validValues[i];
+                AbstractParameter.ensureValidClass(valueClass, value);
+                valids.add(value);
+            }
+            this.validValues = Collections.unmodifiableSet(valids);
+        } else {
+            this.validValues = null;
+        }
+        if (defaultValue != null) {
+            Parameter.ensureValidValue(this, defaultValue);
+        }
+    }
+
+    /**
+     * Constructs a descriptor for a mandatory parameter in a range of integer values.
+     *
+     * @param  name         The parameter name.
+     * @param  defaultValue The default value for the parameter.
+     * @param  minimum      The minimum parameter value, or {@link Integer#MIN_VALUE} if none.
+     * @param  maximum      The maximum parameter value, or {@link Integer#MAX_VALUE} if none.
+     * @return The parameter descriptor for the given range of values.
+     *
+     * @since 2.5
+     */
+    public static DefaultParameterDescriptor<Integer> create(final String name,
+            final int defaultValue, final int minimum, final int maximum)
+    {
+        return create(Collections.singletonMap(NAME_KEY, name),
+                defaultValue, minimum, maximum, true);
+    }
+
+    /**
+     * Constructs a descriptor for a parameter in a range of integer values.
+     *
+     * @param  properties   The parameter properties (name, identifiers, alias...).
+     * @param  defaultValue The default value for the parameter.
+     * @param  minimum      The minimum parameter value, or {@link Integer#MIN_VALUE} if none.
+     * @param  maximum      The maximum parameter value, or {@link Integer#MAX_VALUE} if none.
+     * @param  required     {@code true} if this parameter is required, {@code false} otherwise.
+     * @return The parameter descriptor for the given range of values.
+     *
+     * @since 2.5
+     */
+    public static DefaultParameterDescriptor<Integer> create(final Map<String,?> properties,
+            final int defaultValue, final int minimum, final int maximum, final boolean required)
+    {
+        return new DefaultParameterDescriptor<Integer>(properties, required,
+                 Integer.class, null, Integer.valueOf(defaultValue),
+                 minimum == Integer.MIN_VALUE ? null :Integer.valueOf( minimum),
+                 maximum == Integer.MAX_VALUE ? null : Integer.valueOf(maximum), 
+                		 null);
+    }
+
+    /**
+     * Constructs a descriptor for a mandatory parameter in a range of floating point values.
+     *
+     * @param  name         The parameter name.
+     * @param  defaultValue The default value for the parameter, or {@link Double#NaN} if none.
+     * @param  minimum      The minimum parameter value, or {@link Double#NEGATIVE_INFINITY} if none.
+     * @param  maximum      The maximum parameter value, or {@link Double#POSITIVE_INFINITY} if none.
+     * @param  unit         The unit for default, minimum and maximum values.
+     * @return The parameter descriptor for the given range of values.
+     *
+     * @since 2.5
+     */
+    public static DefaultParameterDescriptor<Double> create(final String name,
+            final double defaultValue, final double minimum, final double maximum, final Unit<?> unit)
+    {
+        return create(Collections.singletonMap(NAME_KEY, name),
+                defaultValue, minimum, maximum, unit, true);
+    }
+
+    /**
+     * Constructs a descriptor for a parameter in a range of floating point values.
+     *
+     * @param  properties   The parameter properties (name, identifiers, alias...).
+     * @param  defaultValue The default value for the parameter, or {@link Double#NaN} if none.
+     * @param  minimum      The minimum parameter value, or {@link Double#NEGATIVE_INFINITY} if none.
+     * @param  maximum      The maximum parameter value, or {@link Double#POSITIVE_INFINITY} if none.
+     * @param  unit         The unit of measurement for default, minimum and maximum values.
+     * @param  required     {@code true} if this parameter is required, {@code false} otherwise.
+     * @return The parameter descriptor for the given range of values.
+     *
+     * @since 2.5
+     */
+    public static DefaultParameterDescriptor<Double> create(final Map<String,?> properties,
+            final double defaultValue, final double minimum, final double maximum,
+            final Unit<?> unit, final boolean required)
+    {
+        return new DefaultParameterDescriptor<Double>(properties, required, Double.class, null,
+                Double.isNaN(defaultValue)          ? null : Double.valueOf(defaultValue),
+                minimum == Double.NEGATIVE_INFINITY ? null : Double.valueOf(minimum),
+                maximum == Double.POSITIVE_INFINITY ? null : Double.valueOf(maximum), unit);
+    }
+
+    /**
+     * The maximum number of times that values for this parameter group or
+     * parameter can be included. For a {@linkplain DefaultParameterDescriptor
+     * single parameter}, the value is always 1.
+     *
+     * @return The maximum occurence.
+     *
+     * @see #getMinimumOccurs
+     */
+    public int getMaximumOccurs() {
+        return 1;
+    }
+
+    /**
+     * Creates a new instance of {@linkplain org.geotools.parameter.Parameter parameter value}
+     * initialized with the {@linkplain #getDefaultValue default value}.
+     * The {@linkplain org.geotools.parameter.Parameter#getDescriptor parameter value
+     * descriptor} for the created parameter value will be {@code this} object.
+     *
+     * @return A parameter initialized to the default value.
+     */
+    @SuppressWarnings("unchecked")
+    public ParameterValue<T> createValue() {
+        if (Double.class.equals(valueClass) && unit == null) {
+            return (ParameterValue) new FloatParameter((ParameterDescriptor) this);
+        }
+        return new Parameter<T>(this);
+    }
+
+    /**
+     * Returns the class that describe the type of the parameter.
+     *
+     * @return The parameter value class.
+     */
+    public Class<T> getValueClass() {
+        return valueClass;
+    }
+
+    /**
+     * If this parameter allows only a finite set of values, returns this set.
+     * This set is usually a {linkplain org.opengis.util.CodeList code list} or
+     * enumerations. This method returns {@code null} if this parameter
+     * doesn't limits values to a finite set.
+     *
+     * @return A finite set of valid values (usually from a
+     *         {linkplain org.opengis.util.CodeList code list}),
+     *         or {@code null} if it doesn't apply.
+     */
+    public Set<T> getValidValues() {
+        return validValues;
+    }
+
+    /**
+     * Returns the default value for the parameter. The return type can be any type
+     * including a {@link Number} or a {@link String}. If there is no default value,
+     * then this method returns {@code null}.
+     *
+     * @return The default value, or {@code null} in none.
+     */
+    public T getDefaultValue() {
+        return defaultValue;
+    }
+
+    /**
+     * Returns the minimum parameter value. If there is no minimum value, or if minimum
+     * value is inappropriate for the {@linkplain #getValueClass parameter type}, then
+     * this method returns {@code null}.
+     *
+     * @return The minimum parameter value (often an instance of {@link Double}), or {@code null}.
+     */
+    public Comparable<T> getMinimumValue() {
+        return minimum;
+    }
+
+    /**
+     * Returns the maximum parameter value. If there is no maximum value, or if maximum
+     * value is inappropriate for the {@linkplain #getValueClass parameter type}, then
+     * this method returns {@code null}.
+     *
+     * @return The minimum parameter value (often an instance of {@link Double}), or {@code null}.
+     */
+    public Comparable<T> getMaximumValue() {
+        return maximum;
+    }
+
+    /**
+     * Returns the unit for
+     * {@linkplain #getDefaultValue default},
+     * {@linkplain #getMinimumValue minimum} and
+     * {@linkplain #getMaximumValue maximum} values.
+     * This attribute apply only if the values is of numeric type (usually an instance
+     * of {@link Double}).
+     *
+     * @return The unit for numeric value, or {@code null} if it
+     *         doesn't apply to the value type.
+     */
+    public Unit<?> getUnit() {
+        return unit;
+    }
+
+    /**
+     * Compares the specified object with this parameter for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true;
+        }
+        if (super.equals(object, compareMetadata)) {
+            if (!compareMetadata) {
+                /*
+                 * Tests for name, since parameters with different name have
+                 * completly different meaning. For example there is no difference
+                 * between "semi_major" and "semi_minor" parameters except the name.
+                 * We don't perform this comparaison if the user asked for metadata
+                 * comparaison, because in such case the names have already been
+                 * compared by the subclass.
+                 */
+                if (!nameMatches(object. getName().getCode()) &&
+                    !nameMatches(object, getName().getCode()))
+                {
+                    return false;
+                }
+            }
+            final DefaultParameterDescriptor that = (DefaultParameterDescriptor) object;
+            return Utilities.equals(this.validValues,    that.validValues)    &&
+                   Utilities.equals(this.defaultValue,   that.defaultValue)   &&
+                   Utilities.equals(this.minimum,        that.minimum)        &&
+                   Utilities.equals(this.maximum,        that.maximum)        &&
+                   Utilities.equals(this.unit,           that.unit);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this parameter.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        int code = super.hashCode()*37 + valueClass.hashCode();
+        if (defaultValue != null) code += (37)      *defaultValue.hashCode();
+        if (minimum      != null) code += (37*37)   *minimum     .hashCode();
+        if (maximum      != null) code += (37*37*37)*maximum     .hashCode();
+        if (unit         != null) code +=            unit        .hashCode();
+        return code;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/DefaultParameterDescriptorGroup.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/DefaultParameterDescriptorGroup.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/DefaultParameterDescriptorGroup.java	(revision 28000)
@@ -0,0 +1,291 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.parameter;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.resources.UnmodifiableArrayList;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.parameter.InvalidParameterNameException;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValueGroup;
+
+
+/**
+ * The definition of a group of related parameters used by an operation method.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/parameter/DefaultParameterDescriptorGroup.java $
+ * @version $Id: DefaultParameterDescriptorGroup.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see ParameterGroup
+ * @see DefaultParameterDescriptor
+ */
+public class DefaultParameterDescriptorGroup extends AbstractParameterDescriptor
+        implements ParameterDescriptorGroup
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -4613190550542423839L;
+
+    /**
+     * The maximum number of times that values for this parameter group or
+     * parameter are required.
+     */
+    private final int maximumOccurs;
+
+    /**
+     * The {@linkplain #descriptors() parameter descriptors} for this group.
+     */
+    private final GeneralParameterDescriptor[] parameters;
+
+    /**
+     * A view of {@link #parameters} as an immutable list. Will be constructed
+     * only when first needed.
+     */
+    private transient List<GeneralParameterDescriptor> asList;
+
+    /**
+     * Constructs a parameter group from a name.
+     * This parameter group will be required exactly once.
+     *
+     * @param name The parameter group name.
+     * @param parameters The {@linkplain #descriptors() parameter descriptors} for this group.
+     */
+    public DefaultParameterDescriptorGroup(final String name,
+                                           final GeneralParameterDescriptor[] parameters)
+    {
+        this(Collections.singletonMap(NAME_KEY, name), parameters);
+    }
+
+    /**
+     * Constructs a parameter group from a set of properties.
+     * This parameter group will be required exactly once. The properties map is given unchanged to
+     * the {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param parameters The {@linkplain #descriptors() parameter descriptors} for this group.
+     */
+    public DefaultParameterDescriptorGroup(final Map<String,?> properties,
+                                           final GeneralParameterDescriptor[] parameters)
+    {
+        this(properties, 1, 1, parameters);
+    }
+
+    /**
+     * Constructs a parameter group from a set of properties. The properties map is given
+     * unchanged to the {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map)
+     * super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param minimumOccurs The {@linkplain #getMinimumOccurs minimum number of times}
+     *        that values for this parameter group are required.
+     * @param maximumOccurs The {@linkplain #getMaximumOccurs maximum number of times}
+     *        that values for this parameter group are required.
+     * @param parameters The {@linkplain #descriptors() parameter descriptors} for this group.
+     */
+    public DefaultParameterDescriptorGroup(final Map<String,?> properties,
+                                           final int minimumOccurs,
+                                           final int maximumOccurs,
+                                           GeneralParameterDescriptor[] parameters)
+    {
+        super(properties, minimumOccurs, maximumOccurs);
+        this.maximumOccurs = maximumOccurs;
+        ensureNonNull("parameters", parameters);
+        this.parameters = new GeneralParameterDescriptor[parameters.length];
+        for (int i=0; i<parameters.length; i++) {
+            this.parameters[i] = parameters[i];
+            ensureNonNull("parameters", parameters, i);
+        }
+        /*
+         * Ensure there is no conflict in parameter names.
+         */
+        parameters = this.parameters;
+        for (int i=0; i<parameters.length; i++) {
+            final String name = parameters[i].getName().getCode();
+            for (int j=0; j<parameters.length; j++) {
+                if (i != j) {
+                    if (nameMatches(parameters[j], name)) {
+                        throw new InvalidParameterNameException(Errors.format(
+                            ErrorKeys.PARAMETER_NAME_CLASH_$4,
+                            parameters[j].getName().getCode(), j, name, i), name);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * The maximum number of times that values for this parameter group are required.
+     *
+     * @see #getMinimumOccurs
+     */
+    public int getMaximumOccurs() {
+        return maximumOccurs;
+    }
+
+    /**
+     * Creates a new instance of {@linkplain ParameterGroup parameter value group}
+     * initialized with the {@linkplain ParameterDescriptor#getDefaultValue default values}.
+     * The {@linkplain org.opengis.parameter.ParameterValueGroup#getDescriptor parameter
+     * value descriptor} for the created group will be {@code this} object.
+     */
+    public ParameterValueGroup createValue() {
+        return new ParameterGroup(this);
+    }
+
+    /**
+     * A view of {@link #parameters} as an unmodifiable list. This class overides
+     * {@link #contains} with a faster implementation based on {@link HashSet}.
+     * It can help for map projection implementations (among other), which test
+     * often for a parameter validity.
+     */
+    private static final class AsList extends UnmodifiableArrayList<GeneralParameterDescriptor> {
+        /** For compatibility with different versions. */
+        private static final long serialVersionUID = -2116304004367396735L;
+
+        /** The element as a set. Will be constructed only when first needed. */
+        private transient Set<GeneralParameterDescriptor> asSet;
+
+        /** Constructs a list for the specified array. */
+        public AsList(final GeneralParameterDescriptor[] array) {
+            super(array);
+        }
+
+        /** Tests for the inclusion of the specified descriptor. */
+        @Override
+        public boolean contains(final Object object) {
+            if (asSet == null) {
+                asSet = new HashSet<GeneralParameterDescriptor>(this);
+            }
+            return asSet.contains(object);
+        }
+    }
+
+    /**
+     * Returns the parameters in this group.
+     */
+    @SuppressWarnings("fallthrough")
+    public List<GeneralParameterDescriptor> descriptors() {
+        if (asList == null) {
+            if (parameters == null) {
+                asList = Collections.emptyList();
+            } else switch (parameters.length) {
+                case 0:  asList = Collections.emptyList();                  break;
+                case 1:  asList = Collections.singletonList(parameters[0]); break;
+                case 2:  // fall through
+                case 3:  asList = UnmodifiableArrayList.wrap(parameters);   break;
+                default: asList = new AsList(parameters);                   break;
+            }
+        }
+        return asList;
+    }
+
+    /**
+     * Returns the first parameter in this group for the specified
+     * {@linkplain org.opengis.metadata.Identifier#getCode identifier code}.
+     *
+     * @param  name The case insensitive identifier code of the parameter to search for.
+     * @return The parameter for the given identifier code.
+     * @throws ParameterNotFoundException if there is no parameter for the given identifier code.
+     */
+    public GeneralParameterDescriptor descriptor(String name) throws ParameterNotFoundException {
+        ensureNonNull("name", name);
+        name = name.trim();
+        List<DefaultParameterDescriptorGroup> subgroups = null;
+        List<GeneralParameterDescriptor> parameters = descriptors();
+        while (parameters != null) {
+            for (final GeneralParameterDescriptor param : parameters) {
+                if (param instanceof ParameterDescriptor) {
+                    if (nameMatches(param, name)) {
+                        return param;
+                    }
+                } else if (param instanceof DefaultParameterDescriptorGroup) {
+                    if (subgroups == null) {
+                        subgroups = new LinkedList<DefaultParameterDescriptorGroup>();
+                    }
+                    assert !subgroups.contains(param) : param;
+                    subgroups.add((DefaultParameterDescriptorGroup) param);
+                }
+            }
+            /*
+             * Looks in subgroups only after all parameters in the current group have been verified.
+             * Search in a "first in, first out" basis.
+             */
+            if (subgroups==null || subgroups.isEmpty()) {
+                break;
+            }
+            parameters = subgroups.remove(0).descriptors();
+        }
+        throw new ParameterNotFoundException(Errors.format(
+                  ErrorKeys.MISSING_PARAMETER_$1, name), name);
+    }
+
+    /**
+     * Compares the specified object with this parameter group for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            // Slight optimization
+            return true;
+        }
+        if (super.equals(object, compareMetadata)) {
+            final DefaultParameterDescriptorGroup that = (DefaultParameterDescriptorGroup) object;
+            return Arrays.equals(this.parameters, that.parameters);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this parameter.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        int code = super.hashCode();
+        // TODO: We should use Arrays.deepHashCode instead in J2SE 1.5.
+        for (int i=0; i<parameters.length; i++) {
+            code = code*37 + parameters[i].hashCode();
+        }
+        return code;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/FloatParameter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/FloatParameter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/FloatParameter.java	(revision 28000)
@@ -0,0 +1,279 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.parameter;
+
+import javax.measure.unit.Unit;
+
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.opengis.parameter.InvalidParameterTypeException;
+import org.opengis.parameter.InvalidParameterValueException;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterValue;
+
+
+/**
+ * A parameter value as a floating point (double precision) number.
+ * This class provides the same functionalities than {@link Parameter}, except that:
+ * <ul>
+ *   <li>Values are always floating point numbers of type {@code double}.</li>
+ *   <li>Units are the same than the {@linkplain ParameterDescriptor#getUnit default units}.</li>
+ * </ul>
+ * When those conditions are meet, {@code ParameterRealValue} is slightly more efficient
+ * than {@code ParameterValue} since it avoid the creation of {@link Double} objects.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/parameter/FloatParameter.java $
+ * @version $Id: FloatParameter.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see DefaultParameterDescriptor
+ * @see ParameterGroup
+ */
+public class FloatParameter extends AbstractParameter implements ParameterValue<Double> {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 9027797654033417816L;
+
+    /**
+     * The value.
+     */
+    private double value;
+
+    /**
+     * Constructs a parameter from the specified descriptor. The descriptor
+     * {@linkplain ParameterDescriptor#getValueClass() value class}
+     * must be <code>{@linkplain Double}.class</code>.
+     *
+     * @param  descriptor The abstract definition of this parameter.
+     * @throws IllegalArgumentException if the value class is not {@code Double.class}.
+     */
+    public FloatParameter(final ParameterDescriptor<Double> descriptor) {
+        super(descriptor);
+        final Class type = descriptor.getValueClass();
+        final Class expected = Double.class;
+        if (!expected.equals(type) && !Double.TYPE.equals(type)) {
+            throw new IllegalArgumentException(Errors.format(
+                    ErrorKeys.ILLEGAL_CLASS_$2, type, expected));
+        }
+        final Number value = descriptor.getDefaultValue();
+        this.value = (value!=null) ? value.doubleValue() : Double.NaN;
+    }
+
+    /**
+     * Constructs a parameter from the specified descriptor and value. This convenience
+     * constructor is equivalents to the one-argument constructor followed by a call to
+     * {@link #setValue(double)}.
+     *
+     * @param  descriptor The abstract definition of this parameter.
+     * @param  value The parameter value.
+     * @throws IllegalArgumentException if the value class is not {@code Double.class}.
+     */
+    public FloatParameter(final ParameterDescriptor<Double> descriptor, final double value) {
+        this(descriptor);
+        setValue(value);
+    }
+
+    /**
+     * Returns the abstract definition of this parameter.
+     */
+    @Override
+    @SuppressWarnings("unchecked") // Type should has been checked by the constructor.
+    public ParameterDescriptor<Double> getDescriptor() {
+        return (ParameterDescriptor) super.getDescriptor();
+    }
+
+    /**
+     * Returns the unit of measure of the {@linkplain #doubleValue() parameter value}. The default
+     * implementation always delegates to {@link ParameterDescriptor#getUnit}.
+     *
+     * @return The unit of measure, or {@code null} if none.
+     */
+    public Unit<?> getUnit() {
+        return ((ParameterDescriptor) descriptor).getUnit();
+    }
+
+    /**
+     * Returns the numeric value of the coordinate operation parameter in the specified unit
+     * of measure. This convenience method apply unit conversion on the fly as needed.
+     *
+     * @param  unit The unit of measure for the value to be returned.
+     * @return The numeric value represented by this parameter after conversion to type
+     *         {@code double} and conversion to {@code unit}.
+     * @throws IllegalArgumentException if the specified unit is invalid for this parameter.
+     */
+    public double doubleValue(final Unit<?> unit) throws IllegalArgumentException {
+        ensureNonNull("unit", unit);
+        final Unit<?> thisUnit = getUnit();
+        if (thisUnit == null) {
+            throw unitlessParameter(descriptor);
+        }
+        final int expectedID = Parameter.getUnitMessageID(thisUnit);
+        if (Parameter.getUnitMessageID(unit) != expectedID) {
+            throw new IllegalArgumentException(Errors.format(expectedID, unit));
+        }
+        return thisUnit.getConverterTo(unit).convert(value);
+    }
+
+    /**
+     * Returns the numeric value of the coordinate operation parameter with its
+     * associated {@linkplain #getUnit unit of measure}.
+     *
+     * @return The numeric value represented by this parameter after conversion to type {@code double}.
+     */
+    public double doubleValue() {
+        return value;
+    }
+
+    /**
+     * Returns the numeric value rounded to the nearest integer.
+     *
+     * @return The numeric value represented by this parameter after conversion to type {@code int}.
+     */
+    public int intValue() {
+        return (int) Math.round(value);
+    }
+
+    /**
+     * Format an error message for illegal method call for the current value type.
+     */
+    private static String getClassTypeError() {
+        return Errors.format(ErrorKeys.ILLEGAL_OPERATION_FOR_VALUE_CLASS_$1, Double.class);
+    }
+
+    /**
+     * Returns the parameter value as {{@link Double},
+     *
+     * @return The parameter value as an object.
+     */
+    public Double getValue() {
+        return Double.valueOf(value);
+    }
+
+    /**
+     * Set the parameter value as a floating point and its associated unit.
+     *
+     * @param  value The parameter value.
+     * @param  unit The unit for the specified value.
+     * @throws InvalidParameterValueException if the value is illegal for some reason
+     *         (for example a value out of range).
+     */
+    public void setValue(double value, final Unit<?> unit) throws InvalidParameterValueException {
+        ensureNonNull("unit", unit);
+        @SuppressWarnings("unchecked") // Checked by constructor.
+        final ParameterDescriptor<Double> descriptor = (ParameterDescriptor) this.descriptor;
+        final Unit<?> thisUnit = descriptor.getUnit();
+        if (thisUnit == null) {
+            throw unitlessParameter(descriptor);
+        }
+        final int expectedID = Parameter.getUnitMessageID(thisUnit);
+        if (Parameter.getUnitMessageID(unit) != expectedID) {
+            throw new IllegalArgumentException(Errors.format(expectedID, unit));
+        }
+        value = unit.getConverterTo(thisUnit).convert(value);
+        this.value = Parameter.ensureValidValue(descriptor, Double.valueOf(value));
+    }
+
+    /**
+     * Set the parameter value as a floating point.
+     *
+     * @param value The parameter value.
+     * @throws InvalidParameterValueException if the value is illegal for some reason
+     *         (for example a value out of range).
+     */
+    public void setValue(final double value) throws InvalidParameterValueException {
+        @SuppressWarnings("unchecked") // Checked by constructor.
+        final ParameterDescriptor<Double> descriptor = (ParameterDescriptor) this.descriptor;
+        this.value = Parameter.ensureValidValue(descriptor, Double.valueOf(value));
+    }
+
+    /**
+     * Set the parameter value as an integer.
+     *
+     * @param  value The parameter value.
+     * @throws InvalidParameterValueException if the value is illegal for some reason
+     *         (for example a value out of range).
+     */
+    public void setValue(final int value) throws InvalidParameterValueException {
+        setValue((double) value);
+    }
+
+    /**
+     * Set the parameter value as a {@link Double} object.
+     *
+     * @param  value The parameter value.
+     * @throws InvalidParameterValueException if the type of {@code value} is inappropriate
+     *         for this parameter, or if the value is illegal for some other reason (for example
+     *         the value is numeric and out of range).
+     */
+    public void setValue(final Object value) throws InvalidParameterValueException {
+        @SuppressWarnings("unchecked") // Checked by constructor.
+        final ParameterDescriptor<Double> descriptor = (ParameterDescriptor) this.descriptor;
+        this.value = Parameter.ensureValidValue(descriptor, value);
+    }
+
+    /**
+     * Always throws an exception, since this parameter is not an array.
+     */
+    public void setValue(double[] values, final Unit<?> unit)
+            throws InvalidParameterValueException
+    {
+        throw new InvalidParameterTypeException(getClassTypeError(),
+                  Parameter.getName(descriptor));
+    }
+
+    /**
+     * Compares the specified object with this parameter for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (super.equals(object)) {
+            final FloatParameter that = (FloatParameter) object;
+            return Double.doubleToLongBits(this.value) ==
+                   Double.doubleToLongBits(that.value);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this parameter.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        final long code = Double.doubleToLongBits(value);
+        return (int)code ^ (int)(code >>> 32) + super.hashCode()*37;
+    }
+
+    /**
+     * Returns a clone of this parameter.
+     */
+    @Override
+    public FloatParameter clone() {
+        return (FloatParameter) super.clone();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/MatrixParameterDescriptors.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/MatrixParameterDescriptors.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/MatrixParameterDescriptors.java	(revision 28000)
@@ -0,0 +1,433 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.parameter;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import javax.measure.unit.Unit;
+
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.parameter.InvalidParameterNameException;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.Matrix;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.operation.matrix.MatrixFactory;
+import org.geotools.resources.UnmodifiableArrayList;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+
+
+/**
+ * A parameter group for {@linkplain Matrix matrix} elements.  The amount of
+ * {@linkplain ParameterValue parameter values} is extensible, i.e. it can grown or
+ * shrink according the value of  <code>"num_row"</code> and <code>"num_col"</code>
+ * parameters. The parameters format may vary according the information provided to
+ * the constructor, but it is typically as below:
+ * <blockquote><pre>
+ * num_row
+ * num_col
+ * elt_0_0
+ * elt_0_1
+ * ...
+ * elt_0_<var>&lt;num_col-1&gt;</var>
+ * elt_1_0
+ * elt_1_1
+ * ...
+ * elt_<var>&lt;num_row-1&gt;</var>_<var>&lt;num_col-1&gt;</var>
+ * </pre></blockquote>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/parameter/MatrixParameterDescriptors.java $
+ * @version $Id: MatrixParameterDescriptors.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see MatrixParameters
+ */
+public class MatrixParameterDescriptors extends DefaultParameterDescriptorGroup {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -7386537348359343836L;
+
+    /**
+     * The default matrix size for the
+     * {@linkplain #MatrixParameterDescriptors(Map) one-argument constructor}.
+     */
+    public static final int DEFAULT_MATRIX_SIZE = 3;
+
+    /**
+     * The height and weight of the matrix of {@link #parameters} to cache. Descriptors
+     * for row or column indices greater than or equals to this value will not be cached.
+     */
+    private static final int CACHE_SIZE = 8;
+
+    /**
+     * The cached descriptors for each elements in a matrix. Descriptors do not depends
+     * on matrix element values. Consequently, the same descriptors can be reused for all
+     * {@link MatrixParameters} instances.
+     */
+    @SuppressWarnings("unchecked")
+    private final ParameterDescriptor<Double>[] parameters =
+            new ParameterDescriptor[CACHE_SIZE * CACHE_SIZE];
+
+    /**
+     * The descriptor for the {@code "num_row"} parameter.
+     */
+    protected final ParameterDescriptor<Integer> numRow;
+
+    /**
+     * The descriptor for the {@code "num_col"} parameter.
+     */
+    protected final ParameterDescriptor<Integer> numCol;
+
+    /**
+     * The prefix to insert in front of parameter name for each matrix elements.
+     */
+    protected final String prefix;
+
+    /**
+     * The separator between the row and the column index in parameter names.
+     */
+    protected final char separator;
+
+    /**
+     * Constructs a parameter group with default name format matching
+     * <cite><A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html">Well
+     * Known Text</A></cite> usages.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     */
+    public MatrixParameterDescriptors(final Map<String,?> properties) {
+        /*
+         * Note: the upper limit given in the operation parameters is arbitrary. A high
+         *       value doesn't make much sense anyway  since matrix size for projective
+         *       transform will usually not be much more than 5, and the storage scheme
+         *       used in this implementation is inefficient  for large amount of matrix
+         *       elements.
+         */
+        this(properties, new ParameterDescriptor[] {
+        		DefaultParameterDescriptor.create("num_row", DEFAULT_MATRIX_SIZE, 2, 50),
+        		DefaultParameterDescriptor.create("num_col", DEFAULT_MATRIX_SIZE, 2, 50)
+        }, "elt_", '_');
+    }
+
+    /**
+     * Constructs a parameter group. The properties map is given unchanged to the
+     * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
+     * The {@code parameters} array should contains parameters <strong>other</strong>
+     * than matrix elements. The first parameter is assumed to be the number of rows, and
+     * the second parameter the number of columns. All extra parameters are ignored.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param parameters The {@code "num_row"} and {@code "num_col"} parameters.
+     * @param prefix     The prefix to insert in front of parameter name for each matrix elements.
+     * @param separator  The separator between the row and the column index in parameter names.
+     */
+    public MatrixParameterDescriptors(final Map<String,?>      properties,
+                                      ParameterDescriptor<?>[] parameters,
+                                      final String             prefix,
+                                      final char               separator)
+    {
+        super(properties, parameters);
+        if (parameters.length < 2) {
+            // TODO: provide a localized message
+            throw new IllegalArgumentException();
+        }
+        numRow = Parameters.cast(parameters[0], Integer.class);
+        numCol = Parameters.cast(parameters[1], Integer.class);
+        ensureNonNull("prefix", prefix);
+        this.prefix    = prefix;
+        this.separator = separator;
+    }
+
+    /**
+     * Verify that the specified index is included in the expected range of values.
+     *
+     * @param  name  The parameter name. To be used for formatting error message.
+     * @param  index The indice to check.
+     * @param  upper The upper range value, exclusive.
+     * @throws IndexOutOfBoundsException if {@code index} is outside the expected range.
+     */
+    static void checkIndice(final String name, final int index, final int upper)
+            throws IndexOutOfBoundsException
+    {
+        if (index<0 || index>=upper) {
+            throw new IndexOutOfBoundsException(Errors.format(
+                      ErrorKeys.ILLEGAL_ARGUMENT_$2, name, index));
+        }
+    }
+
+    /**
+     * Returns the parameter in this group for the specified name. The name can be a matrix element
+     * if it uses the following syntax: <code>"elt_<var>row</var>_<var>col</var>"</code> where
+     * {@code "elt_"} is the {@linkplain #prefix} for all matrix elements, and <var>row</var>
+     * and <var>col</var> are row and column indices respectively. For example {@code "elt_2_1"}
+     * is the element name for the value at line 2 and row 1. The row and column index are 0 based.
+     *
+     * @param  name The case insensitive name of the parameter to search for.
+     * @return The parameter for the given name.
+     * @throws ParameterNotFoundException if there is no parameter for the given name.
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public final GeneralParameterDescriptor descriptor(final String name)
+            throws ParameterNotFoundException
+    {
+        return descriptor(name, ((Number) numRow.getMaximumValue()).intValue(),
+                                ((Number) numCol.getMaximumValue()).intValue());
+    }
+
+    /**
+     * Implementation of the {@link #descriptor(String)} method.
+     *
+     * @param  name   The case insensitive name of the parameter to search for.
+     * @param  numRow The maximum number of rows.
+     * @param  numCol The maximum number of columns.
+     * @return The parameter for the given name.
+     * @throws ParameterNotFoundException if there is no parameter for the given name.
+     */
+    final GeneralParameterDescriptor descriptor(String name, final int numRow, final int numCol)
+            throws ParameterNotFoundException
+    {
+        ensureNonNull("name", name);
+        name = name.trim();
+        RuntimeException cause = null;
+        if (name.regionMatches(true, 0, prefix, 0, prefix.length())) {
+            final int split = name.indexOf(separator, prefix.length());
+            if (split >= 0) try {
+                final int row = Integer.parseInt(name.substring(prefix.length(), split));
+                final int col = Integer.parseInt(name.substring(split+1));
+                return descriptor(row, col, numRow, numCol);
+            } catch (NumberFormatException exception) {
+                cause = exception;
+            } catch (IndexOutOfBoundsException exception) {
+                cause = exception;
+            }
+        }
+        /*
+         * The parameter name is not a matrix element name. Search in the super
+         * class for other parameters, especially "num_row" and "num_col".
+         */
+        try {
+            return super.descriptor(name);
+        } catch (ParameterNotFoundException exception) {
+            if (cause != null) try {
+                exception.initCause(cause);
+            } catch (IllegalStateException ignore) {
+                // A cause has already be given to the exception. Forget the cause then.
+            }
+            throw exception;
+        }
+    }
+
+    /**
+     * Returns the parameter in this group for a matrix element at the specified
+     * index. row and column indices are 0 based. Indices must be lower that the
+     * {@linkplain ParameterDescriptor#getMaximumValue maximum values}
+     * given to the {@link #numRow} and {@link #numCol} parameters.
+     *
+     * @param  row    The row indice.
+     * @param  column The column indice
+     * @return The parameter descriptor for the specified matrix element.
+     * @throws IndexOutOfBoundsException if {@code row} or {@code column} is out of bounds.
+     */
+    @SuppressWarnings("unchecked")
+    public final ParameterDescriptor<Double> descriptor(final int row, final int column)
+            throws IndexOutOfBoundsException
+    {
+        return descriptor(row, column, ((Number) numRow.getMaximumValue()).intValue(),
+                                       ((Number) numCol.getMaximumValue()).intValue());
+    }
+
+    /**
+     * Implementation of the {@link #descriptor(int,int)} method.
+     *
+     * @param  row    The row indice.
+     * @param  column The column indice
+     * @param  numRow The maximum number of rows.
+     * @param  numCol The maximum number of columns.
+     * @return The parameter descriptor for the specified matrix element.
+     * @throws IndexOutOfBoundsException if {@code row} or {@code column} is out of bounds.
+     */
+    final ParameterDescriptor<Double> descriptor(final int row,    final int column,
+                                                 final int numRow, final int numCol)
+            throws IndexOutOfBoundsException
+    {
+        checkIndice("row",    row,    numRow);
+        checkIndice("column", column, numCol);
+        int index = -1;
+        ParameterDescriptor<Double> param;
+        if (row<CACHE_SIZE && column<CACHE_SIZE) {
+            index = row*CACHE_SIZE + column;
+            param = parameters[index];
+            if (param != null) {
+                return param;
+            }
+        }
+        /*
+         * Parameter not found in the cache. Create a new one and cache it for future reuse.
+         * Note that this cache is shared by all MatrixParameterDescriptors instance. There
+         * is no need to synchronize since it is not a big deal if the same parameter is
+         * constructed twice.
+         */
+        param = new DefaultParameterDescriptor<Double>(
+                Collections.singletonMap(NAME_KEY, prefix + row + separator + column),
+                Double.class, null, (row == column) ? 1.0 : 0.0,
+                null, null, Unit.ONE, true);
+        if (index >= 0) {
+            parameters[index] = param;
+        }
+        return param;
+    }
+
+    /**
+     * Returns the parameters in this group. The number or elements is inferred from the
+     * {@linkplain ParameterDescriptor#getDefaultValue default values}
+     * given to the {@link #numRow} and {@link #numCol} parameters.
+     *
+     * @return The matrix parameters, including all elements.
+     */
+    @Override
+    public final List<GeneralParameterDescriptor> descriptors() {
+        return descriptors(this.numRow.getDefaultValue().intValue(),
+                           this.numCol.getDefaultValue().intValue());
+    }
+
+    /**
+     * Implementation of the {@link #descriptors()} method.
+     * Returns the parameters in this group for a matrix of the specified size.
+     *
+     * @param numRow The number of rows.
+     * @param numCol The number of columns.
+     * @return The matrix parameters, including all elements.
+     */
+    final List<GeneralParameterDescriptor> descriptors(final int numRow, final int numCol) {
+        final GeneralParameterDescriptor[] parameters = new GeneralParameterDescriptor[numRow*numCol + 2];
+        int k = 0;
+        parameters[k++] = this.numRow;
+        parameters[k++] = this.numCol;
+        for (int j=0; j<numRow; j++) {
+            for (int i=0; i<numCol; i++) {
+                parameters[k++] = descriptor(j,i, numRow, numCol);
+            }
+        }
+        assert k == parameters.length : k;
+        return UnmodifiableArrayList.wrap(parameters);
+    }
+
+    /**
+     * Creates a new instance of {@linkplain MatrixParameters parameter values} with
+     * elements initialized to the 1 on the diagonal, and 0 everywere else. The returned
+     * parameter group is extensible, i.e. the number of elements will depends upon the
+     * value associated to the {@link #numRow} and {@link #numCol numCol} parameters.
+     *
+     * @return A new parameter initialized to the default value.
+     */
+    @Override
+    public ParameterValueGroup createValue() {
+        return new MatrixParameters(this);
+    }
+
+    /**
+     * Constructs a matrix from a group of parameters.
+     *
+     * @param  parameters The group of parameters.
+     * @return A matrix constructed from the specified group of parameters.
+     * @throws InvalidParameterNameException if a parameter name was not recognized.
+     */
+    public Matrix getMatrix(final ParameterValueGroup parameters)
+            throws InvalidParameterNameException
+    {
+        if (parameters instanceof MatrixParameters) {
+            // More efficient implementation
+            return ((MatrixParameters) parameters).getMatrix();
+        }
+        // Fallback on the general case (others implementations)
+        final ParameterValue numRowParam = parameters.parameter(numRow.getName().toString());
+        final ParameterValue numColParam = parameters.parameter(numCol.getName().toString());
+        final int numRow = numRowParam.intValue();
+        final int numCol = numColParam.intValue();
+        final Matrix matrix = MatrixFactory.create(numRow, numCol);
+        final List<GeneralParameterValue> params = parameters.values();
+        if (params != null) {
+            for (final GeneralParameterValue param : params) {
+                if (param==numRowParam || param==numColParam) {
+                    continue;
+                }
+                RuntimeException cause = null;
+                final String name = param.getDescriptor().getName().toString();
+                if (name.regionMatches(true, 0, prefix, 0, prefix.length())) {
+                    final int split = name.indexOf(separator, prefix.length());
+                    if (split >= 0) try {
+                        final int row = Integer.parseInt(name.substring(prefix.length(), split));
+                        final int col = Integer.parseInt(name.substring(split+1));
+                        matrix.setElement(row, col, ((ParameterValue) param).doubleValue());
+                        continue;
+                    } catch (NumberFormatException exception) {
+                        cause = exception;
+                    } catch (IndexOutOfBoundsException exception) {
+                        cause = exception;
+                    }
+                }
+                final InvalidParameterNameException exception;
+                exception = new InvalidParameterNameException(Errors.format(
+                                ErrorKeys.UNEXPECTED_PARAMETER_$1, name), name);
+                if (cause != null) {
+                    exception.initCause(cause);
+                }
+                throw exception;
+            }
+        }
+        return matrix;
+    }
+
+    /**
+     * Compares the specified object with this parameter group for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (super.equals(object, compareMetadata)) {
+            final MatrixParameterDescriptors that = (MatrixParameterDescriptors) object;
+            return this.separator == that.separator && Utilities.equals(this.prefix, that.prefix);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this parameter.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ prefix.hashCode() ^ 37*separator;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/MatrixParameters.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/MatrixParameters.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/MatrixParameters.java	(revision 28000)
@@ -0,0 +1,453 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.parameter;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.util.InternationalString;
+import org.opengis.util.GenericName;
+
+import org.geotools.io.TableWriter;
+import org.geotools.referencing.operation.matrix.MatrixFactory;
+import org.geotools.resources.UnmodifiableArrayList;
+import org.geotools.resources.XArray;
+import org.geotools.util.Utilities;
+
+
+/**
+ * The values for a group of {@linkplain MatrixParameterDescriptors matrix parameters}. This value
+ * group is extensible, i.e. the number of <code>"elt_<var>row</var>_<var>col</var>"</code>
+ * parameters depends on the <code>"num_row"</code> and <code>"num_col"</code> parameter values.
+ * Consequently, this {@linkplain ParameterGroup parameter value group} is also its own mutable
+ * {@linkplain ParameterDescriptorGroup operation parameter group}.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/parameter/MatrixParameters.java $
+ * @version $Id: MatrixParameters.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see MatrixParameterDescriptors
+ */
+public class MatrixParameters extends ParameterGroup implements ParameterDescriptorGroup {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -7747712999115044943L;
+
+    /**
+     * The parameter values. Will be constructed only when first requested.
+     */
+    private ParameterValue<Double>[][] matrixValues;
+
+    /**
+     * The value for the {@link MatrixParameterDescriptors#numRow} parameter.
+     * Consider this field as final. It is not only for {@link #clone} implementation.
+     */
+    private ParameterValue<Integer> numRow;
+
+    /**
+     * The value for the {@link MatrixParameterDescriptors#numCol} parameter.
+     * Consider this field as final. It is not only for {@link #clone} implementation.
+     */
+    private ParameterValue<Integer> numCol;
+
+    /**
+     * Constructs default values for the specified
+     * {@linkplain MatrixParameterDescriptors matrix parameter descriptors}.
+     *
+     * @param descriptor The descriptor for this group of parameters.
+     */
+    public MatrixParameters(final MatrixParameterDescriptors descriptor) {
+        super(descriptor);
+        numRow = Parameters.cast((ParameterValue) parameter(0), Integer.class);
+        numCol = Parameters.cast((ParameterValue) parameter(1), Integer.class);
+    }
+
+    /**
+     * Returns a description of this parameter value group. Returns always {@code this},
+     * since the description depends on <code>"num_row"</code> and <code>"num_col"</code>
+     * parameter values.
+     */
+    @Override
+    public ParameterDescriptorGroup getDescriptor() {
+        return this;
+    }
+
+    /**
+     * Forward the call to the {@linkplain MatrixParameterDescriptors matrix parameter descriptors}
+     * specified at construction time.
+     */
+    public ReferenceIdentifier getName() {
+        return descriptor.getName();
+    }
+
+    /**
+     * Forward the call to the {@linkplain MatrixParameterDescriptors matrix parameter descriptors}
+     * specified at construction time.
+     */
+    public Collection<GenericName> getAlias() {
+        return descriptor.getAlias();
+    }
+
+    /**
+     * Forward the call to the {@linkplain MatrixParameterDescriptors matrix parameter descriptors}
+     * specified at construction time.
+     */
+    public Set<ReferenceIdentifier> getIdentifiers() {
+        return descriptor.getIdentifiers();
+    }
+
+    /**
+     * Forward the call to the {@linkplain MatrixParameterDescriptors matrix parameter descriptors}
+     * specified at construction time.
+     */
+    public InternationalString getRemarks() {
+        return descriptor.getRemarks();
+    }
+
+    /**
+     * Forward the call to the {@linkplain MatrixParameterDescriptors matrix parameter descriptors}
+     * specified at construction time.
+     */
+    public int getMinimumOccurs() {
+        return descriptor.getMinimumOccurs();
+    }
+
+    /**
+     * Forward the call to the {@linkplain MatrixParameterDescriptors matrix parameter descriptors}
+     * specified at construction time.
+     */
+    public int getMaximumOccurs() {
+        return descriptor.getMaximumOccurs();
+    }
+
+    /**
+     * Returns the parameter in this group for the specified name. The name can be a matrix element
+     * if it uses the following syntax: <code>"elt_<var>row</var>_<var>col</var>"</code> where
+     * <code>"elt_"</code> is the {@linkplain MatrixParameterDescriptors#prefix prefix} for all
+     * matrix elements, and <var>row</var> and <var>col</var> are row and column indices
+     * respectively. For example <code>"elt_2_1"</code> is the element name for the value at line 2
+     * and row 1. The row and column index are 0 based.
+     *
+     * @param  name The case insensitive name of the parameter to search for.
+     * @return The parameter for the given name.
+     * @throws ParameterNotFoundException if there is no parameter for the given name.
+     */
+    public GeneralParameterDescriptor descriptor(final String name)
+            throws ParameterNotFoundException
+    {
+        return ((MatrixParameterDescriptors) descriptor).descriptor(name,
+                numRow.intValue(), numCol.intValue());
+    }
+
+    /**
+     * Returns the value in this group for the specified name. The name can be a matrix element
+     * if it uses the following syntax: <code>"elt_<var>row</var>_<var>col</var>"</code> where
+     * <code>"elt_"</code> is the {@linkplain MatrixParameterDescriptors#prefix prefix} for all
+     * matrix elements, and <var>row</var> and <var>col</var> are row and column indices
+     * respectively. For example <code>"elt_2_1"</code> is the element name for the value at line
+     * 2 and row 1. The row and column index are 0 based.
+     *
+     * @param  name The case insensitive name of the parameter to search for.
+     * @return The parameter value for the given name.
+     * @throws ParameterNotFoundException if there is no parameter for the given name.
+     */
+    @Override
+    public ParameterValue<?> parameter(String name) throws ParameterNotFoundException {
+        ensureNonNull("name", name);
+        name = name.trim();
+        final MatrixParameterDescriptors descriptor = ((MatrixParameterDescriptors) this.descriptor);
+        final String prefix = descriptor.prefix;
+        RuntimeException cause = null;
+        if (name.regionMatches(true, 0, prefix, 0, prefix.length())) {
+            final int split = name.indexOf(descriptor.separator, prefix.length());
+            if (split >= 0) try {
+                final int row = Integer.parseInt(name.substring(prefix.length(), split));
+                final int col = Integer.parseInt(name.substring(split + 1));
+                return parameter(row, col);
+            } catch (NumberFormatException exception) {
+                cause = exception;
+            } catch (IndexOutOfBoundsException exception) {
+                cause = exception;
+            }
+        }
+        /*
+         * The parameter name is not a matrix element name. Search in the super
+         * class for other parameters, especially "num_row" and "num_col".
+         */
+        try {
+            return super.parameter(name);
+        } catch (ParameterNotFoundException exception) {
+            if (cause != null) try {
+                exception.initCause(cause);
+            } catch (IllegalStateException ignore) {
+                // A cause has already be given to the exception. Forget the cause then.
+            }
+            throw exception;
+        }
+    }
+
+    /**
+     * Returns the value in this group for a matrix element at the specified index.
+     * Row and column index are 0 based.
+     *
+     * @param  row    The row indice.
+     * @param  column The column indice
+     * @return The parameter value for the specified matrix element (never {@code null}).
+     * @throws IndexOutOfBoundsException if {@code row} or {@code column} is out of bounds.
+     */
+    public final ParameterValue<Double> parameter(final int row, final int column)
+            throws IndexOutOfBoundsException
+    {
+        return parameter(row, column, numRow.intValue(), numCol.intValue());
+    }
+
+    /**
+     * Implementation of {@link #parameter(int,int)}.
+     *
+     * @param  row    The row indice.
+     * @param  column The column indice
+     * @param  numRow The maximum number of rows.
+     * @param  numCol The maximum number of columns.
+     * @return The parameter value for the specified matrix element.
+     * @throws IndexOutOfBoundsException if {@code row} or {@code column} is out of bounds.
+     */
+    @SuppressWarnings("unchecked") // Because of array creation
+    private ParameterValue<Double> parameter(final int row,    final int column,
+                                             final int numRow, final int numCol)
+            throws IndexOutOfBoundsException
+    {
+        MatrixParameterDescriptors.checkIndice("row",    row,    numRow);
+        MatrixParameterDescriptors.checkIndice("column", column, numCol);
+        if (matrixValues == null) {
+            matrixValues = new ParameterValue[numRow][];
+        }
+        if (row >= matrixValues.length) {
+            matrixValues = XArray.resize(matrixValues, numRow);
+        }
+        ParameterValue<Double>[] rowValues = matrixValues[row];
+        if (rowValues == null) {
+            matrixValues[row] = rowValues = new ParameterValue[numCol];
+        }
+        if (column >= rowValues.length) {
+            matrixValues[row] = rowValues = XArray.resize(rowValues, numCol);
+        }
+        ParameterValue<Double> param = rowValues[column];
+        if (param == null) {
+            rowValues[column] = param = new FloatParameter(
+                ((MatrixParameterDescriptors) descriptor).descriptor(row, column, numRow, numCol));
+        }
+        return param;
+    }
+
+    /**
+     * Returns the parameters descriptors in this group. The amount of parameters depends
+     * on the value of <code>"num_row"</code> and <code>"num_col"</code> parameters.
+     */
+    public List<GeneralParameterDescriptor> descriptors() {
+        return ((MatrixParameterDescriptors) descriptor).descriptors(
+                numRow.intValue(), numCol.intValue());
+    }
+
+    /**
+     * Returns the parameters values in this group. The amount of parameters depends
+     * on the value of <code>"num_row"</code> and <code>"num_col"</code> parameters.
+     * The parameter array will contains only matrix elements which have been requested at
+     * least once by one of {@code parameter(...)} methods. Never requested elements
+     * are left to their default value and omitted from the returned array.
+     */
+    @Override
+    public List<GeneralParameterValue> values() {
+        final int numRow = this.numRow.intValue();
+        final int numCol = this.numCol.intValue();
+        final ParameterValue[] parameters = new ParameterValue[numRow*numCol + 2];
+        int k = 0;
+        parameters[k++] = this.numRow;
+        parameters[k++] = this.numCol;
+        if (matrixValues != null) {
+            final int maxRow = Math.min(numRow, matrixValues.length);
+            for (int j=0; j<maxRow; j++) {
+                final ParameterValue[] rowValues = matrixValues[j];
+                if (rowValues != null) {
+                    final int maxCol = Math.min(numCol, rowValues.length);
+                    for (int i=0; i<maxCol; i++) {
+                        final ParameterValue value = rowValues[i];
+                        if (value != null) {
+                            parameters[k++] = value;
+                        }
+                    }
+                }
+            }
+        }
+        return UnmodifiableArrayList.wrap((GeneralParameterValue[]) XArray.resize(parameters, k));
+    }
+
+    /**
+     * Forwards the call to the {@linkplain MatrixParameterDescriptors matrix parameter descriptors}
+     * specified at construction time.
+     */
+    public ParameterValueGroup createValue() {
+        return (ParameterValueGroup) descriptor.createValue();
+    }
+
+    /**
+     * Creates a matrix from this group of parameters.
+     *
+     * @return A matrix created from this group of parameters.
+     */
+    public Matrix getMatrix() {
+        final int numRow = this.numRow.intValue();
+        final int numCol = this.numCol.intValue();
+        final Matrix matrix = MatrixFactory.create(numRow, numCol);
+        if (matrixValues != null) {
+            for (int j=0; j<numRow; j++) {
+                final ParameterValue[] row = matrixValues[j];
+                if (row != null) {
+                    for (int i=0; i<numCol; i++) {
+                        final ParameterValue element = row[i];
+                        if (element != null) {
+                            matrix.setElement(j, i, element.doubleValue());
+                        }
+                    }
+                }
+            }
+        }
+        return matrix;
+    }
+
+    /**
+     * Sets all parameter values to the element value in the specified matrix.
+     * After this method call, {@link #values} will returns only the elements
+     * different from the default value.
+     *
+     * @param matrix The matrix to copy in this group of parameters.
+     */
+    @SuppressWarnings("unchecked") // Because of array creation
+    public void setMatrix(final Matrix matrix) {
+        final MatrixParameterDescriptors matrixDescriptor =
+            ((MatrixParameterDescriptors) this.descriptor);
+        final int numRow = matrix.getNumRow();
+        final int numCol = matrix.getNumCol();
+        this.numRow.setValue(numRow);
+        this.numCol.setValue(numCol);
+        for (int row=0; row<numRow; row++) {
+            for (int col=0; col<numCol; col++) {
+                final double element = matrix.getElement(row,col);
+                ParameterDescriptor<Double> descriptor = matrixDescriptor.descriptor(row, col);
+                final double value = descriptor.getDefaultValue();
+                if (Double.doubleToLongBits(element) == Double.doubleToLongBits(value)) {
+                    /*
+                     * Value matches the default value, so there is no need to keep it.
+                     * Remove entry to keep things sparse.
+                     */
+                    if (matrixValues != null  &&  matrixValues[row] != null) {
+                        matrixValues[row][col] = null;
+                    }
+                    continue;
+                }
+                if (matrixValues == null) {
+                    matrixValues = new ParameterValue[numRow][];
+                }
+                if (matrixValues[row] == null ){
+                    matrixValues[row] = new ParameterValue[numCol];
+                }
+                matrixValues[row][col] = new FloatParameter(descriptor, element);
+            }
+        }
+    }
+
+    /**
+     * Compare this object with the specified one for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object)) {
+            final MatrixParameters that = (MatrixParameters) object;
+            final int numRow = this.numRow.intValue();
+            final int numCol = this.numCol.intValue();
+            for (int j=0; j<numRow; j++) {
+                for (int i=0; i<numCol; i++) {
+                    if (!Utilities.equals(this.parameter(j,i, numRow, numCol),
+                                          that.parameter(j,i, numRow, numCol)))
+                    {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a clone of this parameter group.
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public MatrixParameters clone() {
+        final MatrixParameters copy = (MatrixParameters) super.clone();
+        if (copy.matrixValues != null) {
+            copy.numRow       = (ParameterValue) copy.parameter(0);
+            copy.numCol       = (ParameterValue) copy.parameter(1);
+            copy.matrixValues =                  copy.matrixValues.clone();
+            for (int j=0; j<copy.matrixValues.length; j++) {
+                ParameterValue[] array = copy.matrixValues[j];
+                if (array != null) {
+                    copy.matrixValues[j] = array = array.clone();
+                    for (int i=0; i<array.length; i++) {
+                        if (array[i] != null) {
+                            array[i] = array[i].clone();
+                        }
+                    }
+                }
+            }
+        }
+        return copy;
+    }
+
+    /**
+     * Writes the content of this parameter to the specified table.
+     *
+     * @param  table The table where to format the parameter value.
+     * @throws IOException if an error occurs during output operation.
+     */
+    @Override
+    protected void write(final TableWriter table) throws IOException {
+        table.write(getName(descriptor));
+        table.nextColumn();
+        table.write('=');
+        table.nextColumn();
+        table.write(getMatrix().toString());
+        table.nextLine();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/Parameter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/Parameter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/Parameter.java	(revision 28000)
@@ -0,0 +1,502 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.parameter;
+
+import java.net.URI;
+import java.util.Set;
+
+import javax.measure.converter.UnitConverter;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+import org.geotools.measure.Units;
+import org.geotools.resources.Classes;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+import org.opengis.parameter.InvalidParameterTypeException;
+import org.opengis.parameter.InvalidParameterValueException;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterValue;
+
+
+/**
+ * A parameter value used by an operation method.
+ * Most CRS parameter values are numeric, but other types of parameter values are possible.
+ * The parameter type can be fetch with the
+ * <code>{@linkplain #getValue()}.{@linkplain Object#getClass() getClass()}</code> idiom.
+ * The {@link #getValue()} and {@link #setValue(Object)} methods can be invoked at any time.
+ * Others getters and setters are parameter-type dependents.
+ *
+ * @param <T> The value type.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/parameter/Parameter.java $
+ * @version $Id: Parameter.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Jody Garnett (Refractions Research)
+ *
+ * @see DefaultParameterDescriptor
+ * @see ParameterGroup
+ */
+public class Parameter<T> extends AbstractParameter implements ParameterValue<T> {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -5837826787089486776L;
+
+    /**
+     * The value.
+     */
+    private T value;
+
+    /**
+     * The unit of measure for the value, or {@code null} if it doesn't apply.
+     */
+    private Unit<?> unit;
+
+//    /**
+//     * Constructs a parameter from the specified name and value. This convenience
+//     * constructor creates a {@link DefaultParameterDescriptor} object. But if such
+//     * an object was available, then the preferred way to get a {@code ParameterValue}
+//     * is to invokes {@link ParameterDescriptor#createValue}.
+//     *
+//     * @param name  The parameter name.
+//     * @param value The parameter value.
+//     *
+//     * @deprecated This constructor can not ensure type safety with parameterized types.
+//     *             Use the static {@code create} methods instead.
+//     */
+//    @Deprecated
+//    public Parameter(final String name, final int value) {
+//        this(DefaultParameterDescriptor.create(name, 0, Integer.MIN_VALUE, Integer.MAX_VALUE));
+//        this.value = (T) (Object) value;
+//    }
+//
+//    /**
+//     * Constructs a parameter from the specified name and value. This convenience
+//     * constructor creates a {@link DefaultParameterDescriptor} object. But if such
+//     * an object was available, then the preferred way to get a {@code ParameterValue} is
+//     * to invokes {@link ParameterDescriptor#createValue}.
+//     *
+//     * @param name  The parameter name.
+//     * @param value The parameter value.
+//     * @param unit  The unit for the parameter value.
+//     *
+//     * @deprecated This constructor can not ensure type safety with parameterized types.
+//     *             Use the static {@code create} methods instead.
+//     */
+//    @Deprecated
+//    public Parameter(final String name, final double value, final Unit<?> unit) {
+//        this(DefaultParameterDescriptor.create(name, Double.NaN, Double.NEGATIVE_INFINITY,
+//                                            Double.POSITIVE_INFINITY, normalize(unit)));
+//        this.value = (T) (Object) value;
+//        this.unit  = unit;
+//    }
+//
+//    /**
+//     * Constructs a parameter from the specified enumeration. This convenience
+//     * constructor creates a {@link DefaultParameterDescriptor} object. But if
+//     * such an object was available, then the preferred way to get a {@code ParameterValue}
+//     * is to invokes {@link ParameterDescriptor#createValue}.
+//     *
+//     * @param name  The parameter name.
+//     * @param value The parameter value.
+//     *
+//     * @deprecated This constructor can not ensure type safety with parameterized types.
+//     *             Use the static {@code create} methods instead.
+//     */
+//    @Deprecated
+//    public Parameter(final String name, final CodeList value) {
+//        this(new DefaultParameterDescriptor(name, value.getClass(), null,(CodeList)null));
+//        this.value = (T) (Object) value;
+//    }
+
+    /**
+     * Constructs a parameter value from the specified descriptor.
+     * The value will be initialized to the default value, if any.
+     *
+     * @param descriptor The abstract definition of this parameter.
+     */
+    public Parameter(final ParameterDescriptor<T> descriptor) {
+        super(descriptor);
+        value = descriptor.getDefaultValue();
+        unit  = descriptor.getUnit();
+    }
+
+    /**
+     * Ensures that the given value is valid according the specified parameter descriptor.
+     * This convenience method ensures that {@code value} is assignable to the
+     * {@linkplain ParameterDescriptor#getValueClass expected class}, is between the
+     * {@linkplain ParameterDescriptor#getMinimumValue minimum} and
+     * {@linkplain ParameterDescriptor#getMaximumValue maximum} values and is one of the
+     * {@linkplain ParameterDescriptor#getValidValues set of valid values}.
+     * If the value fails any of those tests, then an exception is thrown.
+     * <p>
+     * This method is similar to <code>{@linkplain Parameters#isValid
+     * Parameters#isValid}(descriptor, value)</code> except that the exception contains an
+     * error message formatted with a description of the failure reason.
+     *
+     * @param  <T> The type of parameter value. The given {@code value} should typically be an
+     *         instance of this class. This is not required by this method signature but is
+     *         checked by this method implementation.
+     * @param  descriptor The parameter descriptor to check against.
+     * @param  value The value to check, or {@code null}.
+     * @return The value casted to the descriptor parameterized type.
+     * @throws InvalidParameterValueException if the parameter value is invalid.
+     */
+    public static <T> T ensureValidValue(final ParameterDescriptor<T> descriptor, final Object value)
+            throws InvalidParameterValueException
+    {
+        if (value == null) {
+            return null;
+        }
+        final String error;
+        final Class<T> type = descriptor.getValueClass();
+        if (!type.isInstance(value)) {
+            error = Errors.format(ErrorKeys.ILLEGAL_OPERATION_FOR_VALUE_CLASS_$1, Classes.getClass(value));
+        } else {
+            @SuppressWarnings("unchecked") // Type checked in the above test case.
+            final Comparable<Object> minimum = (Comparable) descriptor.getMinimumValue();
+            @SuppressWarnings("unchecked")
+            final Comparable<Object> maximum = (Comparable) descriptor.getMaximumValue();
+            if ((minimum != null && minimum.compareTo(value) > 0) ||
+                (maximum != null && maximum.compareTo(value) < 0))
+            {
+                error = Errors.format(ErrorKeys.VALUE_OUT_OF_BOUNDS_$3, value, minimum, maximum);
+            } else {
+                final Set<?> validValues = descriptor.getValidValues();
+                if (validValues!=null && !validValues.contains(value)) {
+                    error = Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2, getName(descriptor), value);
+                } else {
+                    return type.cast(value);
+                }
+            }
+        }
+        throw new InvalidParameterValueException(error, getName(descriptor), value);
+    }
+
+    /**
+     * Format an error message for illegal method call for the current value type.
+     */
+    private String getClassTypeError() {
+        return Errors.format(ErrorKeys.ILLEGAL_OPERATION_FOR_VALUE_CLASS_$1,
+               ((ParameterDescriptor) descriptor).getValueClass());
+    }
+
+    /**
+     * Returns the abstract definition of this parameter.
+     */
+    @Override
+    @SuppressWarnings("unchecked") // Type checked by the constructor.
+    public ParameterDescriptor<T> getDescriptor() {
+        return (ParameterDescriptor) super.getDescriptor();
+    }
+
+    /**
+     * Returns the unit of measure of the {@linkplain #doubleValue() parameter value}.
+     * If the parameter value has no unit (for example because it is a {@link String} type),
+     * then this method returns {@code null}. Note that "no unit" doesn't means
+     * "dimensionless".
+     *
+     * @return The unit of measure, or {@code null} if none.
+     *
+     * @see #doubleValue()
+     * @see #doubleValueList()
+     * @see #getValue
+     */
+    public Unit<?> getUnit() {
+        return unit;
+    }
+
+    /**
+     * Returns the unit type as one of error message code. Used for checking unit with a better
+     * error message formatting if needed.
+     * <p>
+     * Note: It is difficult to differentiate scale and angular units, since both of them are
+     *       dimensionless. However, in EPSG database version 6.7, there is only 3 scale units
+     *       and all of them maps to {@link Unit#ONE} or {@link Units#PPM}. Consequently, they
+     *       are hard-coded and treated especially by this method.
+     *
+     * @todo Provides a better way to differentiate scale units (currently Unit.ONE)
+     *       and angular units. Both are dimensionless...
+     */
+    static int getUnitMessageID(final Unit<?> unit) {
+        // Note: ONE must be tested before RADIAN.
+        if (Unit.ONE .equals      (unit) ||
+            Units.PPM.equals      (unit)) return ErrorKeys.NON_SCALE_UNIT_$1;
+        if (SI.METER .isCompatible(unit)) return ErrorKeys.NON_LINEAR_UNIT_$1;
+        if (SI.SECOND.isCompatible(unit)) return ErrorKeys.NON_TEMPORAL_UNIT_$1;
+        if (SI.RADIAN.isCompatible(unit)) return ErrorKeys.NON_ANGULAR_UNIT_$1;
+        return ErrorKeys.INCOMPATIBLE_UNIT_$1;
+    }
+
+    /**
+     * Returns the numeric value of the coordinate operation parameter in the specified unit
+     * of measure. This convenience method apply unit conversion on the fly as needed.
+     *
+     * @param  unit The unit of measure for the value to be returned.
+     * @return The numeric value represented by this parameter after conversion to type
+     *         {@code double} and conversion to {@code unit}.
+     * @throws InvalidParameterTypeException if the value is not a numeric type.
+     * @throws IllegalArgumentException if the specified unit is invalid for this parameter.
+     *
+     * @see #getUnit
+     * @see #setValue(double,Unit)
+     * @see #doubleValueList(Unit)
+     */
+    public double doubleValue(final Unit<?> unit) throws InvalidParameterTypeException {
+        if (this.unit == null) {
+            throw unitlessParameter(descriptor);
+        }
+        ensureNonNull("unit", unit);
+        final int expectedID = getUnitMessageID(this.unit);
+        if (getUnitMessageID(unit) != expectedID) {
+            throw new IllegalArgumentException(Errors.format(expectedID, unit));
+        }
+        return this.unit.getConverterTo(unit).convert(doubleValue());
+    }
+
+    /**
+     * Returns the numeric value of the coordinate operation parameter with its
+     * associated {@linkplain #getUnit unit of measure}.
+     *
+     * @return The numeric value represented by this parameter after conversion to type {@code double}.
+     * @throws InvalidParameterTypeException if the value is not a numeric type.
+     *
+     * @see #getUnit
+     * @see #setValue(double)
+     * @see #doubleValueList()
+     */
+    public double doubleValue() throws InvalidParameterTypeException {
+        if (value instanceof Number) {
+            return ((Number) value).doubleValue();
+        }
+        final String name = getName(descriptor);
+        if (value == null) {
+            // This is the kind of exception expected by org.geotools.referencing.wkt.Formatter.
+            throw new IllegalStateException(Errors.format(ErrorKeys.MISSING_PARAMETER_$1, name));
+        }
+        // Reminder: the following is a specialization of IllegalStateException.
+        throw new InvalidParameterTypeException(getClassTypeError(), name);
+    }
+
+    /**
+     * Returns the positive integer value of an operation parameter, usually used
+     * for a count. An integer value does not have an associated unit of measure.
+     *
+     * @return The numeric value represented by this parameter after conversion to type {@code int}.
+     * @throws InvalidParameterTypeException if the value is not an integer type.
+     *
+     * @see #setValue(int)
+     * @see #intValueList
+     */
+    public int intValue() throws InvalidParameterTypeException {
+        if (value instanceof Number) {
+            return ((Number) value).intValue();
+        }
+        final String name = getName(descriptor);
+        if (value == null) {
+            throw new IllegalStateException(Errors.format(ErrorKeys.MISSING_PARAMETER_$1, name));
+        }
+        throw new InvalidParameterTypeException(getClassTypeError(), name);
+    }
+
+    /**
+     * Returns the parameter value as an object. The object type is typically a {@link Double},
+     * {@link Integer}, {@link Boolean}, {@link String}, {@link URI}, {@code double[]} or
+     * {@code int[]}.
+     *
+     * @return The parameter value as an object.
+     *
+     * @see #setValue(Object)
+     */
+    public T getValue() {
+        return value;
+    }
+
+    /**
+     * Sets the parameter value as a floating point and its associated unit.
+     *
+     * @param  value The parameter value.
+     * @param  unit The unit for the specified value.
+     * @throws InvalidParameterValueException if the floating point type is inappropriate for this
+     *         parameter, or if the value is illegal for some other reason (for example a value out
+     *         of range).
+     *
+     * @see #setValue(double)
+     * @see #doubleValue(Unit)
+     */
+    public void setValue(final double value, final Unit<?> unit)
+            throws InvalidParameterValueException
+    {
+        ensureNonNull("unit", unit);
+        @SuppressWarnings("unchecked") // Checked by constructor.
+        final ParameterDescriptor<T> descriptor = (ParameterDescriptor) this.descriptor;
+        final Unit<?> targetUnit = descriptor.getUnit();
+        if (targetUnit == null) {
+            throw unitlessParameter(descriptor);
+        }
+        final int expectedID = getUnitMessageID(targetUnit);
+        if (getUnitMessageID(unit) != expectedID) {
+            throw new InvalidParameterValueException(Errors.format(expectedID, unit),
+                      descriptor.getName().getCode(), value);
+        }
+        final Double converted = unit.getConverterTo(targetUnit).convert(value);
+        ensureValidValue(descriptor, converted);
+        // Really store the original value, not the converted one,
+        // because we store the unit as well.
+        this.value = descriptor.getValueClass().cast(value);
+        this.unit  = unit;
+    }
+
+    /**
+     * Sets the parameter value as a floating point.
+     * The unit, if any, stay unchanged.
+     *
+     * @param value The parameter value.
+     * @throws InvalidParameterValueException if the floating point type is inappropriate for this
+     *         parameter, or if the value is illegal for some other reason (for example a value out
+     *         of range).
+     *
+     * @see #setValue(double,Unit)
+     * @see #doubleValue()
+     */
+    public void setValue(final double value) throws InvalidParameterValueException {
+        final Double check = value;
+        @SuppressWarnings("unchecked") // Checked by constructor.
+        final ParameterDescriptor<T> descriptor = (ParameterDescriptor) this.descriptor;
+        this.value = ensureValidValue(descriptor, check);
+    }
+
+    /**
+     * Sets the parameter value as an integer.
+     *
+     * @param  value The parameter value.
+     * @throws InvalidParameterValueException if the integer type is inappropriate for this parameter,
+     *         or if the value is illegal for some other reason (for example a value out of range).
+     *
+     * @see #intValue
+     */
+    public void setValue(final int value) throws InvalidParameterValueException {
+        @SuppressWarnings("unchecked") // Checked by constructor.
+        final ParameterDescriptor<T> descriptor = (ParameterDescriptor) this.descriptor;
+        final Class<T> type = descriptor.getValueClass();
+        if (Double.class.equals(type) || Double.TYPE.equals(type)) {
+            setValue((double) value);
+            return;
+        }
+        final Integer check = value;
+        this.value = ensureValidValue(descriptor, check);
+    }
+
+    /**
+     * Set the parameter value as an object. The object type is typically a {@link Double},
+     * {@link Integer}, {@link Boolean}, {@link String}, {@link URI}, {@code double[]}
+     * or {@code int[]}.
+     *
+     * @param  value The parameter value.
+     * @throws InvalidParameterValueException if the type of {@code value} is inappropriate
+     *         for this parameter, or if the value is illegal for some other reason (for example
+     *         the value is numeric and out of range).
+     *
+     * @see #getValue
+     */
+    public void setValue(final Object value) throws InvalidParameterValueException {
+        @SuppressWarnings("unchecked") // Checked by constructor.
+        final ParameterDescriptor<T> descriptor = (ParameterDescriptor) this.descriptor;
+        this.value = ensureValidValue(descriptor, value);
+    }
+
+    /**
+     * Set the parameter value as an array of floating point and their associated unit.
+     *
+     * @param  values The parameter values.
+     * @param  unit The unit for the specified value.
+     * @throws InvalidParameterValueException if the floating point type is inappropriate for this
+     *         parameter, or if the value is illegal for some other reason (for example a value out
+     *         of range).
+     */
+    public void setValue(double[] values, final Unit<?> unit)
+            throws InvalidParameterValueException
+    {
+        ensureNonNull("unit", unit);
+        @SuppressWarnings("unchecked") // Checked by constructor.
+        final ParameterDescriptor<T> descriptor = (ParameterDescriptor) this.descriptor;
+        final Unit<?> targetUnit = descriptor.getUnit();
+        if (targetUnit == null) {
+            throw unitlessParameter(descriptor);
+        }
+        final int expectedID = getUnitMessageID(targetUnit);
+        if (getUnitMessageID(unit) != expectedID) {
+            throw new IllegalArgumentException(Errors.format(expectedID, unit));
+        }
+        final double[] converted = values.clone();
+        final UnitConverter converter = unit.getConverterTo(targetUnit);
+        for (int i=0; i<converted.length; i++) {
+            converted[i] = converter.convert(converted[i]);
+        }
+        this.value = ensureValidValue(descriptor, converted);
+        this.unit  = unit;
+    }
+
+    /**
+     * Compares the specified object with this parameter for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            // Slight optimization
+            return true;
+        }
+        if (super.equals(object)) {
+            final Parameter that = (Parameter) object;
+            return Utilities.equals(this.value, that.value) &&
+                   Utilities.equals(this.unit,  that.unit);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this parameter.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        int code = super.hashCode()*37;
+        if (value != null) code +=   value.hashCode();
+        if (unit  != null) code += 37*unit.hashCode();
+        return code ^ (int)serialVersionUID;
+    }
+
+    /**
+     * Returns a clone of this parameter.
+     */
+    @Override
+    public Parameter clone() {
+        return (Parameter) super.clone();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/ParameterGroup.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/ParameterGroup.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/ParameterGroup.java	(revision 28000)
@@ -0,0 +1,355 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.parameter;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+import org.opengis.metadata.Identifier;
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.parameter.InvalidParameterCardinalityException;
+import org.opengis.parameter.InvalidParameterTypeException;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+
+
+/**
+ * A group of related parameter values. The same group can be repeated more than once in an
+ * {@linkplain org.opengis.referencing.operation.Operation operation} or higher level
+ * {@link ParameterValueGroup}, if those instances contain different
+ * values of one or more {@link ParameterValue}s which suitably distinquish among
+ * those groups.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/parameter/ParameterGroup.java $
+ * @version $Id: ParameterGroup.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Jody Garnett (Refractions Research)
+ *
+ * @see DefaultParameterDescriptorGroup
+ * @see Parameter
+ */
+public class ParameterGroup extends AbstractParameter implements ParameterValueGroup {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -1985309386356545126L;
+
+    /**
+     * The {@linkplain #values() parameter values} for this group.
+     * Note: consider as final. This field is not final only in order
+     * to allows {@link #clone} to work.
+     */
+    private ArrayList<GeneralParameterValue> values;
+
+    /**
+     * A view of {@link #values} as an immutable list. Will be constructed only when first
+     * needed. Note that while this list may be immutable, <strong>elements</strong> in this
+     * list stay modifiable. The goal is to allows the following idiom:
+     *
+     * <blockquote><pre>
+     * values().get(i).setValue(myValue);
+     * </pre></blockquote>
+     */
+    private transient List<GeneralParameterValue> asList;
+
+    /**
+     * Constructs a parameter group from the specified descriptor.
+     * All {@linkplain #values parameter values} will be initialized
+     * to their default value.
+     *
+     * @param descriptor The descriptor for this group.
+     */
+    public ParameterGroup(final ParameterDescriptorGroup descriptor) {
+        super(descriptor);
+        final List<GeneralParameterDescriptor> parameters = descriptor.descriptors();
+        values = new ArrayList<GeneralParameterValue>(parameters.size());
+        for (final GeneralParameterDescriptor element : parameters) {
+            for (int count=element.getMinimumOccurs(); --count>=0;) {
+                final GeneralParameterValue value = element.createValue();
+                ensureNonNull("createValue", value);
+                values.add(value);
+            }
+        }
+    }
+
+    /**
+     * Constructs a parameter group from the specified descriptor and list of parameters.
+     *
+     * @param descriptor The descriptor for this group.
+     * @param values The list of parameter values.
+     *
+     * @throws IllegalStateException if the number of {@linkplain ParameterValue parameter}
+     *         occurences doesn't matches the number declared in the
+     *         {@linkplain ParameterDescriptorGroup descriptor}.
+     */
+    public ParameterGroup(final ParameterDescriptorGroup descriptor,
+                          final GeneralParameterValue[]  values)
+    {
+        super(descriptor);
+        ensureNonNull("values", values);
+        this.values = new ArrayList<GeneralParameterValue>(values.length);
+        for (int i=0; i<values.length; i++) {
+            this.values.add(values[i]);
+        }
+        final List<GeneralParameterDescriptor> parameters = descriptor.descriptors();
+        final Map<GeneralParameterDescriptor,int[]> occurences =
+                new LinkedHashMap<GeneralParameterDescriptor,int[]>(Math.round(parameters.size()/0.75f)+1, 0.75f);
+        for (final GeneralParameterDescriptor param : parameters) {
+            ensureNonNull("parameters", param);
+            occurences.put(param, new int[1]);
+            // The value 'int[1]' will be used by 'ensureValidOccurs'
+        }
+        ensureValidOccurs(values, occurences);
+    }
+
+    /**
+     * Make sure that the number of occurences of each values is inside the expected range.
+     *
+     * @param values The list of parameter values.
+     * @param occurences A map of the number of occurences of a value for each descriptor.
+     *        The key must be {@link GeneralParameterDescriptor} instances and the values
+     *        must be {@code int[]} array of length 1 initialized with the 0 value.
+     *
+     * @throws IllegalStateException if the number of {@linkplain ParameterValue parameter}
+     *         occurences doesn't matches the number declared in the
+     *         {@linkplain ParameterDescriptorGroup descriptor}.
+     */
+    private static void ensureValidOccurs(final GeneralParameterValue[] values,
+                                          final Map<GeneralParameterDescriptor,int[]> occurences)
+    {
+        /*
+         * Count the parameters occurences.
+         */
+        for (int i=0; i<values.length; i++) {
+            ensureNonNull("values", values, i);
+            final GeneralParameterDescriptor descriptor = values[i].getDescriptor();
+            final int[] count = occurences.get(descriptor);
+            if (count == null) {
+                final String name = getName(descriptor);
+                throw new InvalidParameterTypeException(Errors.format(
+                          ErrorKeys.ILLEGAL_DESCRIPTOR_FOR_PARAMETER_$1, name), name);
+            }
+            count[0]++;
+        }
+        /*
+         * Now check if the occurences are in the expected ranges.
+         */
+        for (final Map.Entry<GeneralParameterDescriptor,int[]> entry : occurences.entrySet()) {
+            final GeneralParameterDescriptor descriptor = entry.getKey();
+            final int count = entry.getValue()[0];
+            final int min   = descriptor.getMinimumOccurs();
+            final int max   = descriptor.getMaximumOccurs();
+            if (!(count>=min && count<=max)) {
+                final String name = getName(descriptor);
+                throw new InvalidParameterCardinalityException(Errors.format(
+                          ErrorKeys.ILLEGAL_OCCURS_FOR_PARAMETER_$4, name, count, min, max), name);
+            }
+        }
+    }
+
+    /**
+     * Returns the abstract definition of this group of parameters.
+     */
+    @Override
+    public ParameterDescriptorGroup getDescriptor() {
+        return (ParameterDescriptorGroup) super.getDescriptor();
+    }
+
+    /**
+     * Returns the values in this group. Changes in this list are reflected on this
+     * {@code ParameterValueGroup}. The returned list supports the
+     * {@link List#add(Object) add} operation.
+     */
+    public List<GeneralParameterValue> values() {
+        if (asList == null) {
+            asList = new ParameterValueList((ParameterDescriptorGroup) descriptor, values);
+        }
+        return asList;
+    }
+
+    /**
+     * Returns the parameter value at the specified index.
+     *
+     * @param  index The zero-based index.
+     * @return The parameter value at the specified index.
+     * @throws IndexOutOfBoundsException if the specified index is out of bounds.
+     */
+    final GeneralParameterValue parameter(final int index) throws IndexOutOfBoundsException {
+        return values.get(index);
+    }
+
+    /**
+     * Returns the value in this group for the specified
+     * {@linkplain Identifier#getCode identifier code}.
+     * If no {@linkplain ParameterValue parameter value} is found but
+     * a {@linkplain ParameterDescriptor parameter descriptor} is found
+     * (which may occurs if the parameter is optional, i.e.
+     * <code>{@linkplain ParameterDescriptor#getMinimumOccurs minimumOccurs} == 0</code>),
+     * then a {@linkplain ParameterValue parameter value} is
+     * automatically created and initialized to its
+     * {@linkplain ParameterDescriptor#getDefaultValue default value} (if any).
+     *
+     * <P>This convenience method provides a way to get and set parameter values by name. For
+     * example the following idiom fetches a floating point value for the
+     * <code>"false_easting"</code> parameter:</P>
+     *
+     * <blockquote><code>
+     * double value =
+     * parameter("false_easting").{@linkplain ParameterValue#doubleValue() doubleValue()};
+     * </code></blockquote>
+     *
+     * <P>This method do not search recursively in subgroups. This is because more than one
+     * subgroup may exist for the same {@linkplain ParameterDescriptorGroup descriptor}. The
+     * user must {@linkplain #groups query all subgroups} and select explicitly
+     * the appropriate one to use.</P>
+     *
+     * @param  name The case insensitive {@linkplain Identifier#getCode identifier code} of the
+     *              parameter to search for.
+     * @return The parameter value for the given identifier code.
+     * @throws ParameterNotFoundException if there is no parameter value for the given identifier
+     *         code.
+     */
+    public ParameterValue parameter(String name) throws ParameterNotFoundException {
+        ensureNonNull("name", name);
+        name = name.trim();
+        for (final GeneralParameterValue value : values) {
+            if (value instanceof ParameterValue) {
+                if (AbstractIdentifiedObject.nameMatches(value.getDescriptor(), name)) {
+                    return (ParameterValue) value;
+                }
+            }
+        }
+        /*
+         * No existing parameter found. Check if an optional parameter exists.
+         * If such a descriptor is found, create it, add it to the list of values
+         * and returns it.
+         */
+        for (final GeneralParameterDescriptor descriptor : getDescriptor().descriptors()) {
+            if (descriptor instanceof ParameterDescriptor) {
+                if (AbstractIdentifiedObject.nameMatches(descriptor, name)) {
+                    final ParameterValue value = ((ParameterDescriptor) descriptor).createValue();
+                    values.add(value);
+                    return value;
+                }
+            }
+        }
+        throw new ParameterNotFoundException(Errors.format(
+                  ErrorKeys.MISSING_PARAMETER_$1, name), name);
+    }
+
+    /**
+     * Returns all subgroups with the specified name. This method do not create new groups.
+     * If the requested group is optional (i.e.
+     * <code>{@linkplain ParameterDescriptor#getMinimumOccurs minimumOccurs} == 0</code>)
+     * and no value were set, then this method returns an empty set.
+     *
+     * @param  name The case insensitive {@linkplain Identifier#getCode identifier code}
+     *         of the parameter group to search for.
+     * @return The set of all parameter group for the given identifier code.
+     * @throws ParameterNotFoundException if no {@linkplain ParameterDescriptorGroup descriptor}
+     *         was found for the given name.
+     */
+    public List<ParameterValueGroup> groups(String name) throws ParameterNotFoundException {
+        ensureNonNull("name", name);
+        name = name.trim();
+        final List<ParameterValueGroup> groups =
+                new ArrayList<ParameterValueGroup>(Math.min(values.size(), 10));
+        for (final GeneralParameterValue value : values) {
+            if (value instanceof ParameterValueGroup) {
+                if (AbstractIdentifiedObject.nameMatches(value.getDescriptor(), name)) {
+                    groups.add((ParameterValueGroup) value);
+                }
+            }
+        }
+        /*
+         * No groups were found. Check if the group actually exists (i.e. is declared in the
+         * descriptor). If it doesn't exists, then an exception is thrown. If it exists (i.e.
+         * it is simply an optional group not yet defined), then returns an empty list.
+         */
+        if (groups.isEmpty()) {
+            final GeneralParameterDescriptor check =
+                    ((ParameterDescriptorGroup) descriptor).descriptor(name);
+            if (!(check instanceof ParameterDescriptorGroup)) {
+                throw new ParameterNotFoundException(Errors.format(
+                          ErrorKeys.MISSING_PARAMETER_$1, name), name);
+            }
+        }
+        return groups;
+    }
+
+    /**
+     * Compares the specified object with this parameter for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (super.equals(object)) {
+            final ParameterGroup that = (ParameterGroup) object;
+            return Utilities.equals(this.values, that.values);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this parameter.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ values.hashCode();
+    }
+
+    /**
+     * Returns a deep copy of this group of parameter values.
+     * Included parameter values and subgroups are cloned recursively.
+     *
+     * @return A copy of this group of parameter values.
+     */
+    @Override
+    public ParameterGroup clone() {
+        final ParameterGroup copy = (ParameterGroup) super.clone();
+        copy.values = (ArrayList<GeneralParameterValue>) copy.values.clone();
+        for (int i=copy.values.size(); --i>=0;) {
+            // TODO: remove cast with J2SE 1.5
+            copy.values.set(i, copy.values.get(i).clone());
+        }
+        copy.asList = null;
+        return copy;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/ParameterValueList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/ParameterValueList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/ParameterValueList.java	(revision 28000)
@@ -0,0 +1,216 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.parameter;
+
+import java.io.Serializable;
+import java.util.AbstractList;
+import java.util.List;
+import java.util.RandomAccess;
+
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.parameter.InvalidParameterCardinalityException;
+import org.opengis.parameter.InvalidParameterNameException;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterValue;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+
+
+/**
+ * The list to be returned by {@link Parameter#values}.
+ * This class performs check on the parameter value to be added or removed.
+ * This implementation supports {@link #add} and {@link #remove} operations.
+ *
+ * @since 2.1
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/parameter/ParameterValueList.java $
+ * @version $Id: ParameterValueList.java 30641 2008-06-12 17:42:27Z acuster $
+ * @author Martin Desruisseaux (IRD)
+ */
+final class ParameterValueList extends AbstractList<GeneralParameterValue>
+        implements RandomAccess, Serializable
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -7446077551686135264L;
+
+    /**
+     * The descriptor.
+     */
+    private final ParameterDescriptorGroup descriptor;
+
+    /**
+     * The parameter values for this list.
+     */
+    private final List<GeneralParameterValue> values;
+
+    /**
+     * Constructs a parameter list.
+     *
+     * @param descriptor The descriptor for this list.
+     * @param values The parameter values for this list.
+     */
+    public ParameterValueList(final ParameterDescriptorGroup descriptor,
+                              final List<GeneralParameterValue> values)
+    {
+        this.descriptor = descriptor;
+        this.values     = values;
+    }
+
+    /*
+     * CAUTION: Some methods are NOT forwarded to 'values', and this is on purpose!
+     *          This include all modification methods (add, set, remove, etc.).
+     *          We must rely on the default AbstractList implementation for them.
+     */
+    @Override public boolean                isEmpty    ()         {return values.isEmpty    ( );}
+              public int                    size       ()         {return values.size       ( );}
+              public GeneralParameterValue  get        (int i)    {return values.get        (i);}
+    @Override public int                    indexOf    (Object o) {return values.indexOf    (o);}
+    @Override public int                    lastIndexOf(Object o) {return values.lastIndexOf(o);}
+    @Override public boolean                equals     (Object o) {return values.equals     (o);}
+    @Override public int                    hashCode   ()         {return values.hashCode   ( );}
+    @Override public String                 toString   ()         {return values.toString   ( );}
+
+    /**
+     * Adds a {@linkplain ParameterValue parameter value} or an other
+     * {@linkplain ParameterGroup parameter group} to this group. If an existing parameter
+     * is already included for the same {@linkplain ParameterDescriptor#getName identifier},
+     * then there is a choice:
+     * <UL>
+     *   <LI>For <code>{@linkplain GeneralParameterDescriptor#getMaximumOccurs maximumOccurs}
+     *       == 1</code>, the new parameter will replace the existing parameter.</LI>
+     *   <LI>For <code>{@linkplain GeneralParameterDescriptor#getMaximumOccurs maximumOccurs}
+     *       &gt; 1</code>, the new parameter will be added. If adding the new parameter will
+     *       increase the number past what is allowable by {@code maximumOccurs}, then
+     *       an {@link IllegalStateException} will be thrown.</LI>
+     * </UL>
+     *
+     * @param  parameter New parameter to be added to this group.
+     * @return {@code true} if this object changed as a result of this call.
+     * @throws IllegalArgumentException if the specified parameter is not allowable by the
+     *         groups descriptor.
+     * @throws InvalidParameterCardinalityException if adding this parameter would result in
+     *         more parameters than allowed by {@code maximumOccurs}.
+     */
+    @Override
+    public boolean add(final GeneralParameterValue parameter) {
+        modCount++;
+        final GeneralParameterDescriptor type = parameter.getDescriptor();
+        final List<GeneralParameterDescriptor> descriptors = descriptor.descriptors();
+        final String name = type.getName().getCode();
+        if (!descriptors.contains(type)) {
+            /*
+             * For a more accurate error message, check if the operation failed because
+             * the parameter name was not found, or the parameter descriptor doesn't matches.
+             */
+            for (final GeneralParameterDescriptor descriptor : descriptors) {
+                if (AbstractIdentifiedObject.nameMatches(descriptor, name)) {
+                    /*
+                     * Found a matching name. Consequently, the operation failed because
+                     * the descriptor was illegal.
+                     */
+                    throw new IllegalArgumentException(Errors.format(
+                              ErrorKeys.ILLEGAL_DESCRIPTOR_FOR_PARAMETER_$1, name));
+                }
+            }
+            /*
+             * Found no matching name. Consequently, the operation failed because the name
+             * was invalid.
+             */
+            final Object value;
+            if (parameter instanceof ParameterValue) {
+                value = ((ParameterValue) parameter).getValue();
+            } else {
+                value = "(group)";
+            }
+            throw new InvalidParameterNameException(Errors.format(
+                      ErrorKeys.ILLEGAL_ARGUMENT_$2, name, value), name);
+        }
+        final int max = type.getMaximumOccurs();
+        if (max == 1) {
+            /*
+             * Optional or mandatory parameter - we will simply replace what is there.
+             */
+            for (int i=values.size(); --i>=0;) {
+                final GeneralParameterValue oldValue = values.get(i);
+                final GeneralParameterDescriptor oldDescriptor = oldValue.getDescriptor();
+                if (type.equals(oldDescriptor)) {
+                    assert AbstractIdentifiedObject.nameMatches(oldDescriptor, name) : parameter;
+                    final boolean same = parameter.equals(oldValue);
+                    values.set(i, parameter);
+                    return !same;
+                }
+            }
+            // Value will be added at the end of this method.
+        } else {
+            /*
+             * Parameter added (usually a group). Check the cardinality.
+             */
+            int count = 0;
+            for (final GeneralParameterValue value : values) {
+                if (AbstractIdentifiedObject.nameMatches(value.getDescriptor(), name)) {
+                    count++;
+                }
+            }
+            if (count >= max) {
+                throw new InvalidParameterCardinalityException(Errors.format(
+                          ErrorKeys.TOO_MANY_OCCURENCES_$2, name, count), name);
+            }
+        }
+        values.add(parameter);
+        return true;
+    }
+
+    /**
+     * Remove the value at the specified index.
+     *
+     * @param index The index of the value to remove.
+     */
+    @Override
+    public GeneralParameterValue remove(final int index) {
+        return remove(values.get(index).getDescriptor(), index);
+    }
+
+    /**
+     * Remove the value at the specified index.
+     *
+     * @param type  The descriptor of the value to remove.
+     * @param index The index of the value to remove.
+     */
+    private GeneralParameterValue remove(final GeneralParameterDescriptor type, final int index) {
+        modCount++;
+        int count = 0;
+        final String name = type.getName().getCode();
+        for (final GeneralParameterValue value : values) {
+            if (AbstractIdentifiedObject.nameMatches(value.getDescriptor(), name)) {
+                count++;
+            }
+        }
+        final int min = type.getMinimumOccurs();
+        if (count <= min) {
+            final int max = type.getMaximumOccurs();
+            throw new InvalidParameterCardinalityException(Errors.format(
+                      ErrorKeys.ILLEGAL_OCCURS_FOR_PARAMETER_$4, name, count-1, min, max), name);
+        }
+        final GeneralParameterValue value = values.remove(index);
+        assert value!=null && type.equals(value.getDescriptor()) : value;
+        return value;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/Parameters.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/Parameters.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/parameter/Parameters.java	(revision 28000)
@@ -0,0 +1,218 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.parameter;
+
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import javax.measure.unit.Unit;
+
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.logging.Logging;
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.parameter.InvalidParameterTypeException;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+
+
+/**
+ * Utility class for methods helping implementing, and working with the
+ * parameter API from {@link org.opengis.parameter} package.
+ * <p>
+ * <h3>Design note</h3>
+ * This class contains some methods working on a specific parameter in a group (e.g.
+ * {@linkplain #search searching}, {@linkplain #ensureSet setting a value}, <cite>etc.</cite>).
+ * Parameters are identified by their {@linkplain ParameterDescriptor#getName name} instead of
+ * their full {@linkplain ParameterDescriptor descriptor} object, because:
+ * <ul>
+ *   <li>The parameter descriptor may not be always available. For example a user may looks for
+ *       the {@code "semi_major"} axis length (because it is documented in OGC specification under
+ *       that name) but doesn't know and doesn't care about who is providing the implementation. In
+ *       such case, he doesn't have the parameter's descriptor. He only have the parameter's name,
+ *       and creating a descriptor from that name (a descriptor independent of any implementation)
+ *       is tedious.</li>.
+ *   <li>Parameter descriptors are implementation-dependent. For example if a user searchs for
+ *       the above-cited {@code "semi_major"} axis length using the {@linkplain
+ *       org.geotools.referencing.operation.projection.MapProjection.AbstractProvider#SEMI_MAJOR
+ *       Geotools's descriptor} for this parameter, we will fail to find this parameter in any
+ *       alternative {@link ParameterValueGroup} implementations. This is against GeoAPI's
+ *       inter-operability goal.</li>
+ * </ul>
+ * <p>
+ * The above doesn't mean that parameter's descriptor should not be used. They are used for
+ * inspecting meta-data about parameters, not as a key for searching parameters in a group.
+ * Since each parameter's name should be unique in a given parameter group (because
+ * {@linkplain ParameterDescriptor#getMaximumOccurs maximum occurs} is always 1 for single
+ * parameter), the parameter name is a suffisient key.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/parameter/Parameters.java $
+ * @version $Id: Parameters.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Jody Garnett (Refractions Research)
+ * @author Martin Desruisseaux
+ */
+public final class Parameters {
+    /**
+     * Small number for floating point comparaisons.
+     */
+    private static final double EPS = 1E-8;
+
+    /**
+     * An empty parameter group. This group contains no parameters.
+     */
+    public static ParameterDescriptorGroup EMPTY_GROUP =
+            new DefaultParameterDescriptorGroup("empty", // TODO: localize
+            new GeneralParameterDescriptor[0]);
+
+    /**
+     * Do not allows instantiation of this utility class.
+     */
+    private Parameters() {
+    }
+
+    /**
+     * Casts the given parameter descriptor to the given type. An exception is thrown
+     * immediately if the parameter does not have the expected value class. This
+     * is a helper method for type safety when using Java 5 parameterized types.
+     *
+     * @param <T> The expected value class.
+     * @param  descriptor The descriptor to cast.
+     * @param  type The expected value class.
+     * @return The descriptor casted to the given type.
+     * @throws ClassCastException if the given descriptor doesn't have the expected value class.
+     *
+     * @since 2.5
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> ParameterDescriptor<T> cast(ParameterDescriptor<?> descriptor, Class<T> type)
+            throws ClassCastException
+    {
+        if (descriptor != null) {
+            final Class<?> actual = descriptor.getValueClass();
+            // We require a strict equality - not type.isAssignableFrom(actual) - because in
+            // the later case we could have (to be strict) to return a <? extends T> type.
+            if (!type.equals(actual)) {
+                throw new ClassCastException(Errors.format(ErrorKeys.BAD_PARAMETER_TYPE_$2,
+                        descriptor.getName().getCode(), actual));
+            }
+        }
+        return (ParameterDescriptor) descriptor;
+    }
+
+    /**
+     * Casts the given parameter value to the given type. An exception is thrown
+     * immediately if the parameter does not have the expected value class. This
+     * is a helper method for type safety when using Java 5 parameterized types.
+     *
+     * @param <T> The expected value class.
+     * @param  value The value to cast.
+     * @param  type The expected value class.
+     * @return The value casted to the given type.
+     * @throws ClassCastException if the given value doesn't have the expected value class.
+     *
+     * @since 2.5
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> ParameterValue<T> cast(final ParameterValue<?> value, final Class<T> type)
+            throws ClassCastException
+    {
+        if (value != null) {
+            final ParameterDescriptor descriptor = value.getDescriptor();
+            final Class<?> actual = descriptor.getValueClass();
+            if (!type.equals(actual)) { // Same comment than cast(ParameterDescriptor)...
+                throw new ClassCastException(Errors.format(ErrorKeys.BAD_PARAMETER_TYPE_$2,
+                        descriptor.getName().getCode(), actual));
+            }
+        }
+        return (ParameterValue) value;
+    }
+
+    /**
+     * Ensures that the specified parameter is set. The {@code value} is set if and only if
+     * no value were already set by the user for the given {@code name}.
+     * <p>
+     * The {@code force} argument said what to do if the named parameter is already set. If the
+     * value matches, nothing is done in all case. If there is a mismatch and {@code force} is
+     * {@code true}, then the parameter is overridden with the specified {@code value}. Otherwise,
+     * the parameter is left unchanged but a warning is logged with the {@link Level#FINE FINE}
+     * level.
+     *
+     * @param parameters The set of projection parameters.
+     * @param name       The parameter name to set.
+     * @param value      The value to set, or to expect if the parameter is already set.
+     * @param unit       The value unit.
+     * @param force      {@code true} for forcing the parameter to the specified {@code value}
+     *                   is case of mismatch.
+     * @return {@code true} if the were a mismatch, or {@code false} if the parameters can be
+     *         used with no change.
+     */
+    public static boolean ensureSet(final ParameterValueGroup parameters,
+                                    final String name, final double value, final Unit<?> unit,
+                                    final boolean force)
+    {
+        final ParameterValue<?> parameter;
+        try {
+            parameter = parameters.parameter(name);
+        } catch (ParameterNotFoundException ignore) {
+            /*
+             * Parameter not found. This exception should not occurs most of the time.
+             * If it occurs, we will not try to set the parameter here, but the same
+             * exception is likely to occurs at MathTransform creation time. The later
+             * is the expected place for this exception, so we will let it happen there.
+             */
+            return false;
+        }
+        try {
+            if (Math.abs(parameter.doubleValue(unit) / value - 1) <= EPS) {
+                return false;
+            }
+        } catch (InvalidParameterTypeException exception) {
+            /*
+             * The parameter is not a floating point value. Don't try to set it. An exception is
+             * likely to be thrown at MathTransform creation time, which is the expected place.
+             */
+            return false;
+        } catch (IllegalStateException exception) {
+            /*
+             * No value were set for this parameter, and there is no default value.
+             */
+            parameter.setValue(value, unit);
+            return true;
+        }
+        /*
+         * A value was set, but is different from the expected value.
+         */
+        if (force) {
+            parameter.setValue(value, unit);
+        } else {
+            // TODO: localize
+            final LogRecord record = new LogRecord(Level.FINE, "Axis length mismatch.");
+            record.setSourceClassName(Parameters.class.getName());
+            record.setSourceMethodName("ensureSet");
+            final Logger logger = Logging.getLogger(Parameters.class);
+            record.setLoggerName(logger.getName());
+            logger.log(record);
+        }
+        return true;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/AbstractIdentifiedObject.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/AbstractIdentifiedObject.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/AbstractIdentifiedObject.java	(revision 28000)
@@ -0,0 +1,1131 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing;
+
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.wkt.Formattable;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.LoggingKeys;
+import org.geotools.resources.i18n.Loggings;
+import org.geotools.util.GrowableInternationalString;
+import org.geotools.util.NameFactory;
+import org.geotools.util.Utilities;
+import org.geotools.util.logging.Logging;
+import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.parameter.InvalidParameterValueException;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * A base class for metadata applicable to reference system objects. When
+ * {@link org.opengis.referencing.AuthorityFactory} is used to create an object, the
+ * {@linkplain ReferenceIdentifier#getAuthority authority} and
+ * {@linkplain ReferenceIdentifier#getCode authority code} values are set to the authority
+ * name of the factory object, and the authority code supplied by the client, respectively. When
+ * {@link org.opengis.referencing.ObjectFactory} creates an object, the {@linkplain #getName()
+ * name} is set to the value supplied by the client and all of the other metadata items are left
+ * empty.
+ * <p>
+ * This class is conceptually <cite>abstract</cite>, even if it is technically possible to
+ * instantiate it. Typical applications should create instances of the most specific subclass with
+ * {@code Default} prefix instead. An exception to this rule may occurs when it is not possible to
+ * identify the exact type. For example it is not possible to infer the exact coordinate system from
+ * <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well
+ * Known Text</cite></A> is some cases (e.g. in a {@code LOCAL_CS} element). In such exceptional
+ * situation, a plain {@link org.geotools.referencing.cs.AbstractCS} object may be instantiated.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/AbstractIdentifiedObject.java $
+ * @version $Id: AbstractIdentifiedObject.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class AbstractIdentifiedObject extends Formattable implements IdentifiedObject, Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -5173281694258483264L;
+
+    /**
+     * An empty array of identifiers. This is usefull for fetching identifiers as an array,
+     * using the following idiom:
+     * <blockquote><pre>
+     * {@linkplain #getIdentifiers()}.toArray(EMPTY_IDENTIFIER_ARRAY);
+     * </pre></blockquote>
+     */
+    public static final ReferenceIdentifier[] EMPTY_IDENTIFIER_ARRAY = new ReferenceIdentifier[0];
+
+    /**
+     * An empty array of alias. This is usefull for fetching alias as an array,
+     * using the following idiom:
+     * <blockquote><pre>
+     * {@linkplain #getAlias()}.toArray(EMPTY_ALIAS_ARRAY);
+     * </pre></blockquote>
+     */
+    public static final GenericName[] EMPTY_ALIAS_ARRAY = new GenericName[0];
+
+    /**
+     * A comparator for sorting identified objects by {@linkplain #getName() name}.
+     */
+    public static final Comparator<IdentifiedObject> NAME_COMPARATOR = new NameComparator();
+
+    /**
+     * {@link #NAME_COMPARATOR} implementation as a named class (rather than anonymous)
+     * for more predictable serialization.
+     */
+    private static final class NameComparator implements Comparator<IdentifiedObject>, Serializable {
+        /** For cross-version compatibility. */
+        private static final long serialVersionUID = -6605097017814062198L;
+
+        /** Compares the given identified objects for order. */
+        public int compare(final IdentifiedObject o1, final IdentifiedObject o2) {
+            return doCompare(o1.getName().getCode(), o2.getName().getCode());
+        }
+
+        /** Canonicalizes to the singleton on deserialization. */
+        protected Object readResolve() throws ObjectStreamException {
+            return NAME_COMPARATOR;
+        }
+    }
+
+    /**
+     * A comparator for sorting identified objects by {@linkplain #getIdentifiers identifiers}.
+     */
+    public static final Comparator<IdentifiedObject> IDENTIFIER_COMPARATOR = new IdentifierComparator();
+
+    /**
+     * {@link #IDENTIFIER_COMPARATOR} implementation as a named class (rather than anonymous)
+     * for more predictable serialization.
+     */
+    private static final class IdentifierComparator implements Comparator<IdentifiedObject>, Serializable {
+        /** For cross-version compatibility. */
+        private static final long serialVersionUID = -7315726806679993522L;
+
+        /** Compares the given identified objects for order. */
+        public int compare(final IdentifiedObject o1, final IdentifiedObject o2) {
+            Collection<ReferenceIdentifier> a1 = o1.getIdentifiers();
+            Collection<ReferenceIdentifier> a2 = o2.getIdentifiers();
+            if (a1 == null) a1 = Collections.emptySet();
+            if (a2 == null) a2 = Collections.emptySet();
+            final Iterator<ReferenceIdentifier> i1 = a1.iterator();
+            final Iterator<ReferenceIdentifier> i2 = a2.iterator();
+            boolean n1, n2;
+            while ((n1=i1.hasNext()) & (n2=i2.hasNext())) {  // Really '&', not '&&'
+                final int c = doCompare(i1.next().getCode(), i2.next().getCode());
+                if (c != 0) {
+                    return c;
+                }
+            }
+            if (n1) return +1;
+            if (n2) return -1;
+            return 0;
+        }
+
+        /** Canonicalizes to the singleton on deserialization. */
+        protected Object readResolve() throws ObjectStreamException {
+            return IDENTIFIER_COMPARATOR;
+        }
+    }
+
+    /**
+     * A comparator for sorting identified objects by {@linkplain #getRemarks remarks}.
+     */
+    public static final Comparator<IdentifiedObject> REMARKS_COMPARATOR = new RemarksComparator();
+
+    /**
+     * {@link #REMARKS_COMPARATOR} implementation as a named class (rather than anonymous)
+     * for more predictable serialization.
+     */
+    private static final class RemarksComparator implements Comparator<IdentifiedObject>, Serializable {
+        /** For cross-version compatibility. */
+        private static final long serialVersionUID = -6675419613224162715L;
+
+        /** Compares the given identified objects for order. */
+        public int compare(final IdentifiedObject o1, final IdentifiedObject o2) {
+            return doCompare(o1.getRemarks(), o2.getRemarks());
+        }
+
+        /** Canonicalizes to the singleton on deserialization. */
+        protected Object readResolve() throws ObjectStreamException {
+            return REMARKS_COMPARATOR;
+        }
+    }
+
+    /**
+     * The name for this object or code. Should never be {@code null}.
+     */
+    private final ReferenceIdentifier name;
+
+    /**
+     * An alternative name by which this object is identified.
+     */
+    private final Collection<GenericName> alias;
+
+    /**
+     * An identifier which references elsewhere the object's defining information.
+     * Alternatively an identifier by which this object can be referenced.
+     */
+    private final Set<ReferenceIdentifier> identifiers;
+
+    /**
+     * Comments on or information about this object, or {@code null} if none.
+     */
+    private final InternationalString remarks;
+
+    /**
+     * Constructs a new identified object with the same values than the specified one.
+     * This copy constructor provides a way to wrap an arbitrary implementation into a
+     * Geotools one or a user-defined one (as a subclass), usually in order to leverage
+     * some implementation-specific API. This constructor performs a shallow copy,
+     * i.e. the properties are not cloned.
+     *
+     * @param object The object to copy.
+     */
+    public AbstractIdentifiedObject(final IdentifiedObject object) {
+        name        = object.getName();
+        alias       = object.getAlias();
+        identifiers = object.getIdentifiers();
+        remarks     = object.getRemarks();
+    }
+
+    /**
+     * Constructs an object from a set of properties. Keys are strings from the table below.
+     * Key are case-insensitive, and leading and trailing spaces are ignored. The map given in
+     * argument shall contains at least a {@code "name"} property. Other properties listed
+     * in the table below are optional.
+     * <p>
+     * <table border='1'>
+     *   <tr bgcolor="#CCCCFF" class="TableHeadingColor">
+     *     <th nowrap>Property name</th>
+     *     <th nowrap>Value type</th>
+     *     <th nowrap>Value given to</th>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String} or {@link ReferenceIdentifier}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getName()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@value org.opengis.referencing.IdentifiedObject#ALIAS_KEY}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String}, <code>{@linkplain String}[]</code>,
+     *     {@link GenericName} or <code>{@linkplain GenericName}[]</code>&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getAlias}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@value org.opengis.metadata.Identifier#AUTHORITY_KEY}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String} or {@link Citation}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link ReferenceIdentifier#getAuthority} on the {@linkplain #getName() name}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@value org.opengis.referencing.ReferenceIdentifier#CODESPACE_KEY}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link ReferenceIdentifier#getCodeSpace} on the {@linkplain #getName() name}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@value org.opengis.referencing.ReferenceIdentifier#VERSION_KEY}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link ReferenceIdentifier#getVersion} on the {@linkplain #getName() name}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link ReferenceIdentifier} or <code>{@linkplain ReferenceIdentifier}[]</code>&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getIdentifiers}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@value org.opengis.referencing.IdentifiedObject#REMARKS_KEY}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String} or {@link InternationalString}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getRemarks}</td>
+     *   </tr>
+     * </table>
+     * <P>
+     * Additionally, all localizable attributes like {@code "remarks"} may have a language and
+     * country code suffix. For example the {@code "remarks_fr"} property stands for remarks in
+     * {@linkplain java.util.Locale#FRENCH French} and the {@code "remarks_fr_CA"} property stands
+     * for remarks in {@linkplain java.util.Locale#CANADA_FRENCH French Canadian}.
+     * <P>
+     * Note that the {@code "authority"} and {@code "version"} properties are ignored if the
+     * {@code "name"} property is already a {@link Citation} object instead of a {@link String}.
+     *
+     * @param properties The properties to be given to this identified object.
+     * @throws InvalidParameterValueException if a property has an invalid value.
+     * @throws IllegalArgumentException if a property is invalid for some other reason.
+     */
+    public AbstractIdentifiedObject(final Map<String,?> properties) throws IllegalArgumentException {
+        this(properties, null, null);
+    }
+
+    /**
+     * Constructs an object from a set of properties and copy unrecognized properties in the
+     * specified map. The {@code properties} argument is treated as in the {@linkplain
+     * AbstractIdentifiedObject#AbstractIdentifiedObject(Map) one argument constructor}. All
+     * properties unknow to this {@code AbstractIdentifiedObject} constructor are copied
+     * in the {@code subProperties} map, after their key has been normalized (usually
+     * lower case, leading and trailing space removed).
+     *
+     * <P>If {@code localizables} is non-null, then all keys listed in this argument are
+     * treated as localizable one (i.e. may have a suffix like "_fr", "_de", etc.). Localizable
+     * properties are stored in the {@code subProperties} map as {@link InternationalString}
+     * objects.</P>
+     *
+     * @param properties    Set of properties. Should contains at least {@code "name"}.
+     * @param subProperties The map in which to copy unrecognized properties.
+     * @param localizables  Optional list of localized properties.
+     *
+     * @throws InvalidParameterValueException if a property has an invalid value.
+     * @throws IllegalArgumentException if a property is invalid for some other reason.
+     */
+    protected AbstractIdentifiedObject(final Map<String,?>      properties,
+                                       final Map<String,Object> subProperties,
+                                       final String[]           localizables)
+            throws IllegalArgumentException
+    {
+        ensureNonNull("properties", properties);
+        Object name        = null;
+        Object alias       = null;
+        Object identifiers = null;
+        Object remarks     = null;
+        GrowableInternationalString       growable = null;
+        GrowableInternationalString[] subGrowables = null;
+        /*
+         * Iterate through each map entry. This have two purposes:
+         *
+         *   1) Ignore case (a call to properties.get("foo") can't do that)
+         *   2) Find localized remarks.
+         *
+         * This algorithm is sub-optimal if the map contains a lot of entries of no interest to
+         * this object. Hopefully, most users will fill a map only with usefull entries.
+         */
+NEXT_KEY: for (final Map.Entry<String,?> entry : properties.entrySet()) {
+            String    key   = entry.getKey().trim().toLowerCase();
+            Object    value = entry.getValue();
+            /*
+             * Note: String.hashCode() is part of J2SE specification,
+             *       so it should not change across implementations.
+             */
+            switch (key.hashCode()) {
+                // Fix case for common keywords. They are not used
+                // by this class, but are used by some subclasses.
+                case -1528693765: if (key.equalsIgnoreCase("anchorPoint"))                 key="anchorPoint";                 break;
+                case -1805658881: if (key.equalsIgnoreCase("bursaWolf"))                   key="bursaWolf";                   break;
+                case   109688209: if (key.equalsIgnoreCase("operationVersion"))            key="operationVersion";            break;
+                case  1479434472: if (key.equalsIgnoreCase("coordinateOperationAccuracy")) key="coordinateOperationAccuracy"; break;
+                case  1126917133: if (key.equalsIgnoreCase("positionalAccuracy"))          key="positionalAccuracy";          break;
+                case  1127093059: if (key.equalsIgnoreCase("realizationEpoch"))            key="realizationEpoch";            break;
+                case  1790520781: if (key.equalsIgnoreCase("domainOfValidity"))            key="domainOfValidity";            break;
+                case -1109785975: if (key.equalsIgnoreCase("validArea"))                   key="validArea";                   break;
+
+                // -------------------------------------
+                // "name": String or ReferenceIdentifier
+                // -------------------------------------
+                case 3373707: {
+                    if (key.equals(NAME_KEY)) {
+                        if (value instanceof String) {
+                            name = new NamedIdentifier(properties, false);
+                            assert value.equals(((Identifier) name).getCode()) : name;
+                        } else {
+                            // Should be an instance of ReferenceIdentifier, but we don't check
+                            // here. The type will be checked at the end of this method, which
+                            // will thrown an exception with detailed message in case of mismatch.
+                            name = value;
+                        }
+                        continue NEXT_KEY;
+                    }
+                    break;
+                }
+                // -------------------------------------------------------
+                // "alias": String, String[], GenericName or GenericName[]
+                // -------------------------------------------------------
+                case 92902992: {
+                    if (key.equals(ALIAS_KEY)) {
+                        alias = NameFactory.toArray(value);
+                        continue NEXT_KEY;
+                    }
+                    break;
+                }
+                // -----------------------------------------------------------
+                // "identifiers": ReferenceIdentifier or ReferenceIdentifier[]
+                // -----------------------------------------------------------
+                case 1368189162: {
+                    if (key.equals(IDENTIFIERS_KEY)) {
+                        if (value != null) {
+                            if (value instanceof ReferenceIdentifier) {
+                                identifiers = new ReferenceIdentifier[] {
+                                    (ReferenceIdentifier) value
+                                };
+                            } else {
+                                identifiers = value;
+                            }
+                        }
+                        continue NEXT_KEY;
+                    }
+                    break;
+                }
+                // ----------------------------------------
+                // "remarks": String or InternationalString
+                // ----------------------------------------
+                case 1091415283: {
+                    if (key.equals(REMARKS_KEY)) {
+                        if (value instanceof InternationalString) {
+                            remarks = value;
+                            continue NEXT_KEY;
+                        }
+                    }
+                    break;
+                }
+            }
+            /*
+             * Search for additional locales for remarks (e.g. "remarks_fr").
+             * 'growable.add(...)' will add the value only if the key starts
+             * with the "remarks" prefix.
+             */
+            if (value instanceof String) {
+                if (growable == null) {
+                    if (remarks instanceof GrowableInternationalString) {
+                        growable = (GrowableInternationalString) remarks;
+                    } else {
+                        growable = new GrowableInternationalString();
+                    }
+                }
+                if (growable.add(REMARKS_KEY, key, value.toString())) {
+                    continue NEXT_KEY;
+                }
+            }
+            /*
+             * Search for user-specified localizable properties.
+             */
+            if (subProperties == null) {
+                continue NEXT_KEY;
+            }
+            if (localizables != null) {
+                for (int i=0; i<localizables.length; i++) {
+                    final String prefix = localizables[i];
+                    if (key.equals(prefix)) {
+                        if (value instanceof InternationalString) {
+                            // Stores the value in 'subProperties' after the loop.
+                            break;
+                        }
+                    }
+                    if (value instanceof String) {
+                        if (subGrowables == null) {
+                            subGrowables = new GrowableInternationalString[localizables.length];
+                        }
+                        if (subGrowables[i] == null) {
+                            final Object previous = subProperties.get(prefix);
+                            if (previous instanceof GrowableInternationalString) {
+                                subGrowables[i] = (GrowableInternationalString) previous;
+                            } else {
+                                subGrowables[i] = new GrowableInternationalString();
+                            }
+                        }
+                        if (subGrowables[i].add(prefix, key, value.toString())) {
+                            continue NEXT_KEY;
+                        }
+                    }
+                }
+            }
+            subProperties.put(key, value);
+        }
+        /*
+         * Get the localized remarks, if it was not yet set. If a user specified remarks
+         * both as InternationalString and as String for some locales (which is a weird
+         * usage...), then current implementation discart the later with a warning.
+         */
+        if (growable!=null && !growable.getLocales().isEmpty()) {
+            if (remarks == null) {
+                remarks = growable;
+            } else if (!growable.isSubsetOf(remarks)) {
+                final Logger logger = Logging.getLogger(AbstractIdentifiedObject.class);
+                final LogRecord record = Loggings.format(Level.WARNING, LoggingKeys.LOCALES_DISCARTED);
+                record.setLoggerName(logger.getName());
+                logger.log(record);
+            }
+        }
+        /*
+         * Get the localized user-defined properties.
+         */
+        if (subProperties!=null && subGrowables!=null) {
+            for (int i=0; i<subGrowables.length; i++) {
+                growable = subGrowables[i];
+                if (growable!=null && !growable.getLocales().isEmpty()) {
+                    final String prefix = localizables[i];
+                    final Object current = subProperties.get(prefix);
+                    if (current == null) {
+                        subProperties.put(prefix, growable);
+                    } else if (!growable.isSubsetOf(current)) {
+                        final Logger logger = Logging.getLogger(AbstractIdentifiedObject.class);
+                        final LogRecord record = Loggings.format(Level.WARNING, LoggingKeys.LOCALES_DISCARTED);
+                        record.setLoggerName(logger.getName());
+                        logger.log(record);
+                    }
+                }
+            }
+        }
+        /*
+         * Stores the definitive reference to the attributes. Note that casts are performed only
+         * there (not before). This is a wanted feature, since we want to catch ClassCastExceptions
+         * are rethrown them as more informative exceptions.
+         */
+        String key=null; Object value=null;
+        try {
+            key = NAME_KEY;
+            this.name = (ReferenceIdentifier) (value = name);
+
+            key = ALIAS_KEY;
+            this.alias = asSet((GenericName[]) (value = alias));
+
+            key = IDENTIFIERS_KEY;
+            this.identifiers = asSet((ReferenceIdentifier[]) (value = identifiers));
+
+            key = REMARKS_KEY;
+            this.remarks = (InternationalString) (value = remarks);
+        } catch (ClassCastException exception) {
+            InvalidParameterValueException e = new InvalidParameterValueException(Errors.format(
+                    ErrorKeys.ILLEGAL_ARGUMENT_$2, key, value), key, value);
+            e.initCause(exception);
+            throw e;
+        }
+        ensureNonNull(NAME_KEY, name);
+        ensureNonNull(NAME_KEY, name.toString());
+    }
+
+    /**
+     * The primary name by which this object is identified.
+     *
+     * @see #getName(Citation)
+     */
+    public ReferenceIdentifier getName() {
+        return name;
+    }
+
+    /**
+     * An alternative name by which this object is identified.
+     *
+     * @return The aliases, or an empty array if there is none.
+     *
+     * @see #getName(Citation)
+     */
+    public Collection<GenericName> getAlias() {
+        if (alias == null) {
+            return Collections.emptySet();
+        }
+        return alias;
+    }
+
+    /**
+     * An identifier which references elsewhere the object's defining information.
+     * Alternatively an identifier by which this object can be referenced.
+     *
+     * @return This object identifiers, or an empty array if there is none.
+     *
+     * @see #getIdentifier(Citation)
+     */
+    public Set<ReferenceIdentifier> getIdentifiers() {
+        if (identifiers == null) {
+            return Collections.emptySet();
+        }
+        return identifiers;
+    }
+
+    /**
+     * Comments on or information about this object, including data source information.
+     */
+    public InternationalString getRemarks(){
+        return remarks;
+    }
+
+    /**
+     * Returns the informations provided in the specified indentified object as a map of
+     * properties. The returned map contains key such as {@link #NAME_KEY NAME_KEY}, and
+     * values from methods such as {@link #getName}.
+     *
+     * @param  info The identified object to view as a properties map.
+     * @return An view of the identified object as an immutable map.
+     */
+    public static Map<String,?> getProperties(final IdentifiedObject info) {
+        return new Properties(info);
+    }
+
+    /**
+     * Returns the properties to be given to an identified object derived from the specified one.
+     * This method is typically used for creating a new CRS identical to an existing one except
+     * for axis units. This method returns the same properties than the supplied argument (as of
+     * <code>{@linkplain #getProperties(IdentifiedObject) getProperties}(info)</code>), except for
+     * the following:
+     * <p>
+     * <ul>
+     *   <li>The {@linkplain #getName() name}'s authority is replaced by the specified one.</li>
+     *   <li>All {@linkplain #getIdentifiers identifiers} are removed, because the new object
+     *       to be created is probably not endorsed by the original authority.</li>
+     * </ul>
+     * <p>
+     * This method returns a mutable map. Consequently, callers can add their own identifiers
+     * directly to this map if they wish.
+     *
+     * @param  info The identified object to view as a properties map.
+     * @param  authority The new authority for the object to be created, or {@code null} if it
+     *         is not going to have any declared authority.
+     * @return An view of the identified object as a mutable map.
+     */
+    public static Map<String,Object> getProperties(final IdentifiedObject info, final Citation authority) {
+        final Map<String,Object> properties = new HashMap<String,Object>(getProperties(info));
+        properties.put(NAME_KEY, new NamedIdentifier(authority, info.getName().getCode()));
+        properties.remove(IDENTIFIERS_KEY);
+        return properties;
+    }
+
+    /**
+     * Returns an identifier according the given authority. This method first checks all
+     * {@linkplain #getIdentifiers identifiers} in their iteration order. It returns the first
+     * identifier with an {@linkplain ReferenceIdentifier#getAuthority authority} citation
+     * {@linkplain Citations#identifierMatches(Citation,Citation) matching} the specified
+     * authority.
+     *
+     * @param  authority The authority for the identifier to return, or {@code null} for
+     *         the first identifier regarless its authority.
+     * @return The object's identifier, or {@code null} if no identifier matching the specified
+     *         authority was found.
+     *
+     * @since 2.2
+     */
+    public ReferenceIdentifier getIdentifier(final Citation authority) {
+        return getIdentifier0(this, authority);
+    }
+
+    /**
+     * Returns an identifier according the given authority. This method performs the same search
+     * than {@link #getIdentifier(Citation)} on arbitrary implementations of GeoAPI interface.
+     *
+     * @param  info The object to get the identifier from.
+     * @param  authority The authority for the identifier to return, or {@code null} for
+     *         the first identifier regarless its authority.
+     * @return The object's identifier, or {@code null} if no identifier matching the specified
+     *         authority was found.
+     *
+     * @since 2.2
+     */
+    public static ReferenceIdentifier getIdentifier(final IdentifiedObject info, final Citation authority) {
+        if (info instanceof AbstractIdentifiedObject) {
+            // Gives a chances to subclasses to get their overridden method invoked.
+            return ((AbstractIdentifiedObject) info).getIdentifier(authority);
+        }
+        return getIdentifier0(info, authority);
+    }
+
+    /**
+     * Implementation of {@link #getIdentifier(Citation)}.
+     */
+    private static ReferenceIdentifier getIdentifier0(final IdentifiedObject info, final Citation authority) {
+        if (info == null) {
+            return null;
+        }
+        for (final Identifier candidate : info.getIdentifiers()) {
+            if (candidate instanceof ReferenceIdentifier) {
+                final ReferenceIdentifier identifier = (ReferenceIdentifier) candidate;
+                if (authority == null) {
+                    return identifier;
+                }
+                final Citation infoAuthority = identifier.getAuthority();
+                if (infoAuthority != null) {
+                    if (Citations.identifierMatches(authority, infoAuthority)) {
+                        return identifier;
+                    }
+                }
+            }
+        }
+        return (authority == null) ? info.getName() : null;
+    }
+
+    /**
+     * Returns this object's name according the given authority. This method checks first the
+     * {@linkplain #getName() primary name}, then all {@linkplain #getAlias() alias} in their
+     * iteration order.
+     *
+     * <ul>
+     *   <li><p>If the name or alias implements the {@link ReferenceIdentifier} interface,
+     *       then this method compares the {@linkplain ReferenceIdentifier#getAuthority
+     *       identifier authority} against the specified citation using the
+     *       {@link Citations#identifierMatches(Citation,Citation) identifierMatches}
+     *       method. If a matching is found, then this method returns the
+     *       {@linkplain ReferenceIdentifier#getCode identifier code} of this object.</p></li>
+     *
+     *   <li><p>Otherwise, if the alias implements the {@link GenericName} interface, then this
+     *       method compares the {@linkplain GenericName#getScope name scope} against the specified
+     *       citation using the {@linkplain Citations#identifierMatches(Citation,String)
+     *       identifierMatches} method. If a matching is found, then this method returns the
+     *       {@linkplain GenericName#asLocalName local name} of this object.</p></li>
+     * </ul>
+     *
+     * Note that alias may implement both the {@link ReferenceIdentifier} and {@link GenericName}
+     * interfaces (for example {@link NamedIdentifier}). In such cases, the identifier view has
+     * precedence.
+     *
+     * @param  authority The authority for the name to return.
+     * @return The object's name (either a {@linkplain ReferenceIdentifier#getCode code}
+     *         or a {@linkplain GenericName#asLocalName local name}), or {@code null} if
+     *         no name matching the specified authority was found.
+     *
+     * @see #getName()
+     * @see #getAlias()
+     *
+     * @since 2.2
+     */
+    public String getName(final Citation authority) {
+        return getName0(this, authority);
+    }
+
+    /**
+     * Returns an object's name according the given authority. This method performs the same search
+     * than {@link #getName(Citation)} on arbitrary implementations of GeoAPI interface.
+     *
+     * @param  info The object to get the name from.
+     * @param  authority The authority for the name to return.
+     * @return The object's name (either a {@linkplain ReferenceIdentifier#getCode code}
+     *         or a {@linkplain GenericName#asLocalName local name}), or {@code null} if
+     *         no name matching the specified authority was found.
+     *
+     * @since 2.2
+     */
+    public static String getName(final IdentifiedObject info, final Citation authority) {
+        if (info instanceof AbstractIdentifiedObject) {
+            // Gives a chances to subclasses to get their overridden method invoked.
+            return ((AbstractIdentifiedObject) info).getName(authority);
+        }
+        return getName0(info, authority);
+    }
+
+    /**
+     * Implementation of {@link #getName(Citation)}.
+     */
+    private static String getName0(final IdentifiedObject info, final Citation authority) {
+        Identifier identifier = info.getName();
+        if (authority == null) {
+            return identifier.getCode();
+        }
+        String name = null;
+        Citation infoAuthority = identifier.getAuthority();
+        if (infoAuthority != null) {
+            if (Citations.identifierMatches(authority, infoAuthority)) {
+                name = identifier.getCode();
+            } else {
+                for (final GenericName alias : info.getAlias()) {
+                    if (alias instanceof Identifier) {
+                        identifier = (Identifier) alias;
+                        infoAuthority = identifier.getAuthority();
+                        if (infoAuthority != null) {
+                            if (Citations.identifierMatches(authority, infoAuthority)) {
+                                name = identifier.getCode();
+                                break;
+                            }
+                        }
+                    } else {
+                        final GenericName scope = alias.scope().name();
+                        if (scope != null) {
+                            if (Citations.identifierMatches(authority, scope.toString())) {
+                                name = alias.tip().toString();
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return name;
+    }
+
+    /**
+     * Returns {@code true} if either the {@linkplain #getName() primary name} or at least
+     * one {@linkplain #getAlias alias} matches the specified string. This method performs
+     * the search in the following order, regardless of any authority:
+     * <ul>
+     *   <li>The {@linkplain #getName() primary name} of this object</li>
+     *   <li>The {@linkplain org.opengis.util.ScopedName fully qualified name} of an alias</li>
+     *   <li>The {@linkplain org.opengis.util.LocalName local name} of an alias</li>
+     * </ul>
+     *
+     * @param  name The name to compare.
+     * @return {@code true} if the primary name of at least one alias
+     *         matches the specified {@code name}.
+     */
+    public boolean nameMatches(final String name) {
+        return nameMatches(this, alias, name);
+    }
+
+    /**
+     * Returns {@code true} if either the {@linkplain #getName() primary name} or at least
+     * one {@linkplain #getAlias alias} matches the specified string. This method performs the
+     * same check than the {@linkplain #nameMatches(String) non-static method} on arbitrary
+     * object implementing the GeoAPI interface.
+     *
+     * @param  object The object to check.
+     * @param  name The name.
+     * @return {@code true} if the primary name of at least one alias
+     *         matches the specified {@code name}.
+     */
+    public static boolean nameMatches(final IdentifiedObject object, final String name) {
+        if (object instanceof AbstractIdentifiedObject) {
+            return ((AbstractIdentifiedObject) object).nameMatches(name);
+        } else {
+            return nameMatches(object, object.getAlias(), name);
+        }
+    }
+
+    /**
+     * Returns {@code true} if the {@linkplain #getName() primary name} of an object matches
+     * the primary name of one {@linkplain #getAlias alias} of the other object.
+     *
+     * @param o1 The first object to compare by name.
+     * @param o2 The second object to compare by name.
+     * @return {@code true} if both objects have a common name.
+     *
+     * @since 2.4
+     */
+    public static boolean nameMatches(final IdentifiedObject o1, final IdentifiedObject o2) {
+        return nameMatches(o1, o2.getName().getCode()) ||
+               nameMatches(o2, o1.getName().getCode());
+    }
+
+    /**
+     * Implementation of {@code nameMatches} method.
+     *
+     * @param  object The object to check.
+     * @param  alias  The list of alias in {@code object} (may be {@code null}).
+     *                This method will never modify this list. Consequently, it may be a
+     *                direct reference to an internal array.
+     * @param  name The name.
+     * @return {@code true} if the primary name of at least one alias
+     *         matches the specified {@code name}.
+     */
+    private static boolean nameMatches(final IdentifiedObject object,
+                                       final Collection<GenericName> alias, String name)
+    {
+        name = name.trim();
+        if (name.equalsIgnoreCase(object.getName().getCode().trim())) {
+            return true;
+        }
+        if (alias != null) {
+            for (final GenericName asName : alias) {
+                final GenericName asScoped = asName.toFullyQualifiedName();
+                if (asScoped!=asName && name.equalsIgnoreCase(asScoped.toString().trim())) {
+                    return true;
+                }
+                if (name.equalsIgnoreCase(asName.tip().toString().trim())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Compares the specified object with this object for equality.
+     *
+     * @param  object The other object (may be {@code null}).
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public final boolean equals(final Object object) {
+        return (object instanceof AbstractIdentifiedObject) &&
+                equals((AbstractIdentifiedObject) object, true);
+    }
+
+    /**
+     * Compares this object with the specified object for equality.
+     *
+     * If {@code compareMetadata} is {@code true}, then all available properties are
+     * compared including {@linkplain #getName() name}, {@linkplain #getRemarks remarks},
+     * {@linkplain #getIdentifiers identifiers code}, etc.
+     *
+     * If {@code compareMetadata} is {@code false}, then this method compare
+     * only the properties needed for computing transformations. In other words,
+     * {@code sourceCS.equals(targetCS, false)} returns {@code true} only if
+     * the transformation from {@code sourceCS} to {@code targetCS} is
+     * the identity transform, no matter what {@link #getName()} saids.
+     * <P>
+     * Some subclasses (especially {@link org.geotools.referencing.datum.AbstractDatum}
+     * and {@link org.geotools.parameter.AbstractParameterDescriptor}) will test for the
+     * {@linkplain #getName() name}, since objects with different name have completly
+     * different meaning. For example nothing differentiate the {@code "semi_major"} and
+     * {@code "semi_minor"} parameters except the name. The name comparaison may be loose
+     * however, i.e. we may accept a name matching an alias.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object!=null && object.getClass().equals(getClass())) {
+            if (!compareMetadata) {
+                return true;
+            }
+            return Utilities.equals(name,        object.name       ) &&
+                   Utilities.equals(alias,       object.alias      ) &&
+                   Utilities.equals(identifiers, object.identifiers) &&
+                   Utilities.equals(remarks,     object.remarks    );
+        }
+        return false;
+    }
+
+    /**
+     * Compares two Geotools's {@code AbstractIdentifiedObject} objects for equality. This
+     * method is equivalent to {@code object1.<b>equals</b>(object2, <var>compareMetadata</var>)}
+     * except that one or both arguments may be null. This convenience method is provided for
+     * implementation of {@code equals} in subclasses.
+     *
+     * @param  object1 The first object to compare (may be {@code null}).
+     * @param  object2 The second object to compare (may be {@code null}).
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    static boolean equals(final AbstractIdentifiedObject object1,
+                          final AbstractIdentifiedObject object2,
+                          final boolean          compareMetadata)
+    {
+        return (object1 == object2) || (object1!=null && object1.equals(object2, compareMetadata));
+    }
+
+    /**
+     * Compares two OpenGIS's {@code IdentifiedObject} objects for equality. This convenience
+     * method is provided for implementation of {@code equals} in subclasses.
+     *
+     * @param  object1 The first object to compare (may be {@code null}).
+     * @param  object2 The second object to compare (may be {@code null}).
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    protected static boolean equals(final IdentifiedObject object1,
+                                    final IdentifiedObject object2,
+                                    final boolean  compareMetadata)
+    {
+        if (!(object1 instanceof AbstractIdentifiedObject)) return Utilities.equals(object1, object2);
+        if (!(object2 instanceof AbstractIdentifiedObject)) return Utilities.equals(object2, object1);
+        return equals((AbstractIdentifiedObject) object1,
+                      (AbstractIdentifiedObject) object2, compareMetadata);
+    }
+
+    /**
+     * Compares two arrays of OpenGIS's {@code IdentifiedObject} objects for equality. This
+     * convenience method is provided for implementation of {@code equals} method in subclasses.
+     *
+     * @param  array1 The first array to compare (may be {@code null}).
+     * @param  array2 The second array to compare (may be {@code null}).
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both arrays are equal.
+     */
+    protected static boolean equals(final IdentifiedObject[] array1,
+                                    final IdentifiedObject[] array2,
+                                    final boolean   compareMetadata)
+    {
+        if (array1 != array2) {
+            if ((array1 == null) || (array2 == null) || (array1.length != array2.length)) {
+                return false;
+            }
+            for (int i=array1.length; --i>=0;) {
+                if (!equals(array1[i], array2[i], compareMetadata)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Compares two collectionss of OpenGIS's {@code IdentifiedObject} objects for equality. The
+     * comparaison take order in account, which make it more appropriate for {@link java.util.List}
+     * or {@link LinkedHashSet} comparaisons. This convenience method is provided for
+     * implementation of {@code equals} method in subclasses.
+     *
+     * @param  collection1 The first collection to compare (may be {@code null}).
+     * @param  collection2 The second collection to compare (may be {@code null}).
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both collections are equal.
+     */
+    protected static boolean equals(final Collection<? extends IdentifiedObject> collection1,
+                                    final Collection<? extends IdentifiedObject> collection2,
+                                    final boolean compareMetadata)
+    {
+        if (collection1 == collection2) {
+            return true;
+        }
+        if (collection1==null || collection2==null) {
+            return false;
+        }
+        final Iterator<? extends IdentifiedObject> it1 = collection1.iterator();
+        final Iterator<? extends IdentifiedObject> it2 = collection2.iterator();
+        while (it1.hasNext()) {
+            if (!it2.hasNext() || !equals(it1.next(), it2.next(), compareMetadata)) {
+                return false;
+            }
+        }
+        return !it2.hasNext();
+    }
+
+    /**
+     * Compares two objects for order. Any object may be null. This method is
+     * used for implementation of {@link #NAME_COMPARATOR} and its friends.
+     */
+    private static <E extends Comparable<E>> int doCompare(final E c1, final E c2) {
+        if (c1 == null) {
+            return (c2==null) ? 0 : -1;
+        }
+        if (c2 == null) {
+            return +1;
+        }
+        return c1.compareTo(c2);
+    }
+
+    /**
+     * Returns a hash value for this identified object. {@linkplain #getName() Name},
+     * {@linkplain #getIdentifiers identifiers} and {@linkplain #getRemarks remarks}
+     * are not taken in account. In other words, two identified objects will return
+     * the same hash value if they are equal in the sense of <code>{@linkplain
+     * #equals(AbstractIdentifiedObject,boolean) equals}(AbstractIdentifiedObject,
+     * <strong>false</strong>)</code>.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        // Subclasses need to overrides this!!!!
+        return (int)serialVersionUID ^ getClass().hashCode();
+    }
+
+    /**
+     * Returns the specified array as an immutable set, or {@code null} if the
+     * array is empty or null. This is a convenience method for sub-classes
+     * constructors.
+     *
+     * @param  <E> The type of array elements.
+     * @param  array The array to copy in a set. May be {@code null}.
+     * @return A set containing the array elements, or {@code null} if none or empty.
+     */
+    protected static <E> Set<E> asSet(final E[] array) {
+        if (array == null) {
+            return null;
+        }
+        switch (array.length) {
+            case 0:  return null;
+            case 1:  return Collections.singleton(array[0]);
+            default: return Collections.unmodifiableSet(new LinkedHashSet<E>(Arrays.asList(array)));
+        }
+    }
+
+    /**
+     * Makes sure that an argument is non-null. This is a
+     * convenience method for subclass constructors.
+     *
+     * @param  name   Argument name.
+     * @param  object User argument.
+     * @throws InvalidParameterValueException if {@code object} is null.
+     */
+    protected static void ensureNonNull(final String name, final Object object)
+            throws InvalidParameterValueException
+    {
+        if (object == null) {
+            throw new InvalidParameterValueException(Errors.format(
+                        ErrorKeys.NULL_ARGUMENT_$1, name), name, object);
+        }
+    }
+
+    /**
+     * Makes sure an array element is non-null. This is
+     * a convenience method for subclass constructors.
+     *
+     * @param  name  Argument name.
+     * @param  array User argument.
+     * @param  index Index of the element to check.
+     * @throws InvalidParameterValueException if {@code array[i]} is null.
+     */
+    protected static void ensureNonNull(final String name, final Object[] array, final int index)
+            throws InvalidParameterValueException
+    {
+        if (array[index] == null) {
+            throw new InvalidParameterValueException(Errors.format(
+                        ErrorKeys.NULL_ARGUMENT_$1, name+'['+index+']'), name, array);
+        }
+    }
+
+    /**
+     * Makes sure that the specified unit is a temporal one.
+     * This is a convenience method for subclass constructors.
+     *
+     * @param  unit Unit to check.
+     * @throws IllegalArgumentException if {@code unit} is not a temporal unit.
+     */
+    protected static void ensureTimeUnit(final Unit<?> unit) throws IllegalArgumentException {
+        if (!SI.SECOND.isCompatible(unit)) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.NON_TEMPORAL_UNIT_$1, unit));
+        }
+    }
+
+    /**
+     * Makes sure that the specified unit is a linear one.
+     * This is a convenience method for subclass constructors.
+     *
+     * @param  unit Unit to check.
+     * @throws IllegalArgumentException if {@code unit} is not a linear unit.
+     */
+    protected static void ensureLinearUnit(final Unit<?> unit) throws IllegalArgumentException {
+        if (!SI.METER.isCompatible(unit)) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.NON_LINEAR_UNIT_$1, unit));
+        }
+    }
+
+    /**
+     * Makes sure that the specified unit is an angular one.
+     * This is a convenience method for subclass constructors.
+     *
+     * @param  unit Unit to check.
+     * @throws IllegalArgumentException if {@code unit} is not an angular unit.
+     */
+    protected static void ensureAngularUnit(final Unit<?> unit) throws IllegalArgumentException {
+        if (!SI.RADIAN.isCompatible(unit) && !Unit.ONE.equals(unit)) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.NON_ANGULAR_UNIT_$1, unit));
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/AbstractReferenceSystem.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/AbstractReferenceSystem.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/AbstractReferenceSystem.java	(revision 28000)
@@ -0,0 +1,149 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.opengis.metadata.extent.Extent;
+import org.opengis.util.InternationalString;
+import org.opengis.referencing.ReferenceSystem;
+import org.geotools.util.Utilities;
+
+
+/**
+ * Description of a spatial and temporal reference system used by a dataset.
+ * <p>
+ * This class is conceptually <cite>abstract</cite>, even if it is technically possible to
+ * instantiate it. Typical applications should create instances of the most specific subclass with
+ * {@code Default} prefix instead. An exception to this rule may occurs when it is not possible to
+ * identify the exact type.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/AbstractReferenceSystem.java $
+ * @version $Id: AbstractReferenceSystem.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @since 2.1
+ */
+public class AbstractReferenceSystem extends AbstractIdentifiedObject implements ReferenceSystem {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 3337659819553899435L;
+
+    /**
+     * List of localizable properties. To be given to {@link AbstractIdentifiedObject} constructor.
+     */
+    private static final String[] LOCALIZABLES = {SCOPE_KEY};
+
+    /**
+     * Area for which the (coordinate) reference system is valid.
+     */
+    private final Extent domainOfValidity;
+
+    /**
+     * Description of domain of usage, or limitations of usage, for which this
+     * (coordinate) reference system object is valid.
+     */
+    private final InternationalString scope;
+
+    /**
+     * Constructs a reference system from a set of properties.
+     * The properties given in argument follow the same rules than for the
+     * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
+     * Additionally, the following properties are understood by this construtor:
+     * <p>
+     * <table border='1'>
+     *   <tr bgcolor="#CCCCFF" class="TableHeadingColor">
+     *     <th nowrap>Property name</th>
+     *     <th nowrap>Value type</th>
+     *     <th nowrap>Value given to</th>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@link #DOMAIN_OF_VALIDITY_KEY "domainOfValidity"}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link Extent}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getDomainOfValidity}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@link #SCOPE_KEY "scope"}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String} or {@link InternationalString}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getScope}</td>
+     *   </tr>
+     * </table>
+     *
+     * @param properties The properties to be given to this object.
+     */
+    public AbstractReferenceSystem(final Map<String,?> properties) {
+        this(properties, new HashMap<String,Object>());
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private AbstractReferenceSystem(final Map<String,?> properties, final Map<String,Object> subProperties) {
+        super(properties, subProperties, LOCALIZABLES);
+        domainOfValidity = (Extent)   subProperties.get(DOMAIN_OF_VALIDITY_KEY);
+        scope = (InternationalString) subProperties.get(SCOPE_KEY);
+    }
+
+    /**
+     * Area or region or timeframe in which this (coordinate) reference system is valid.
+     * Returns {@code null} if not available.
+     *
+     * @since 2.4
+     */
+    public Extent getDomainOfValidity() {
+        return domainOfValidity;
+    }
+
+    /**
+     * Description of domain of usage, or limitations of usage, for which this
+     * (coordinate) reference system object is valid.
+     * Returns {@code null} if not available.
+     */
+    public InternationalString getScope() {
+        return scope;
+    }
+
+    /**
+     * Compare this reference system with the specified object for equality.
+     * If {@code compareMetadata} is {@code true}, then all available properties are
+     * compared including {@linkplain #getValidArea valid area} and {@linkplain #getScope scope}.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (super.equals(object, compareMetadata)) {
+            if (!compareMetadata) {
+                return true;
+            }
+            final AbstractReferenceSystem that = (AbstractReferenceSystem) object;
+            return Utilities.equals(domainOfValidity, that.domainOfValidity) &&
+                   Utilities.equals(scope,            that.scope);
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/CRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/CRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/CRS.java	(revision 28000)
@@ -0,0 +1,727 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing;
+
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.geotools.factory.FactoryNotFoundException;
+import org.geotools.factory.FactoryRegistryException;
+import org.geotools.factory.GeoTools;
+import org.geotools.factory.Hints;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.metadata.iso.extent.GeographicBoundingBoxImpl;
+import org.geotools.referencing.factory.AbstractAuthorityFactory;
+import org.geotools.referencing.factory.IdentifiedObjectFinder;
+import org.geotools.referencing.operation.transform.IdentityTransform;
+import org.geotools.resources.CRSUtilities;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.GenericName;
+import org.geotools.util.logging.Logging;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.extent.GeographicBoundingBox;
+import org.opengis.metadata.extent.GeographicExtent;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.referencing.crs.CRSAuthorityFactory;
+import org.opengis.referencing.crs.CompoundCRS;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.datum.Datum;
+import org.opengis.referencing.datum.Ellipsoid;
+import org.opengis.referencing.datum.GeodeticDatum;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.CoordinateOperationFactory;
+import org.opengis.referencing.operation.MathTransform;
+
+
+/**
+ * Simple utility class for making use of the {@linkplain CoordinateReferenceSystem
+ * coordinate reference system} and associated {@linkplain org.opengis.referencing.Factory}
+ * implementations. This utility class is made up of static final functions. This class is
+ * not a factory or a builder. It makes use of the GeoAPI factory interfaces provided by
+ * {@link ReferencingFactoryFinder}.
+ * <p>
+ * The following methods may be added in a future version:
+ * <ul>
+ *   <li>{@code CoordinateReferenceSystem parseXML(String)}</li>
+ * </ul>
+ * <p>
+ * When using {@link CoordinateReferenceSystem} matching methods of this class 
+ * ({@link #equalsIgnoreMetadata(Object, Object)},{@link #lookupIdentifier(IdentifiedObject, boolean)}, 
+ * {@link #lookupEpsgCode(CoordinateReferenceSystem, boolean)}, 
+ * {@link #lookupIdentifier(IdentifiedObject, boolean)}, 
+ * {@link #lookupIdentifier(Citation, CoordinateReferenceSystem, boolean)})
+ * against objects derived from a database other than the 
+ * official EPSG one it may be advisable to set a non zero comparison tolerance with 
+ * {@link Hints#putSystemDefault(java.awt.RenderingHints.Key, Object)} using
+ * the {@link Hints#COMPARISON_TOLERANCE} key. A value of 10e-9 has proved to give satisfactory 
+ * results with definitions commonly found in .prj files accompaining shapefiles and georeferenced images.<br>
+ * <b>Warning</b>: the tolerance value is used in all internal comparison, this will also change 
+ * the way math transforms are setup. Use with care.
+ * 
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/CRS.java $
+ * @version $Id: CRS.java 37602 2011-07-10 19:20:25Z aaime $
+ * @author Jody Garnett (Refractions Research)
+ * @author Martin Desruisseaux
+ * @author Andrea Aime
+ *
+ * @tutorial http://docs.codehaus.org/display/GEOTOOLS/Coordinate+Transformation+Services+for+Geotools+2.1
+ */
+public final class CRS {
+    
+    static final Logger LOGGER = Logging.getLogger(CRS.class);
+    
+    /**
+     * Enumeration describing axis order for geographic coordinate reference systems.
+     */
+    public static enum AxisOrder {
+        /** 
+         * Ordering in which longitude comes before latitude, commonly referred to as x/y ordering. 
+         */
+        EAST_NORTH,
+        
+        NORTH_EAST,
+        
+        /**
+         * Indicates axis ordering is not applicable to the coordinate reference system.
+         */
+        INAPPLICABLE;
+    }
+    
+    /**
+     * A map with {@link Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER} set to {@link Boolean#TRUE}.
+     */
+    private static final Hints FORCE_LONGITUDE_FIRST_AXIS_ORDER = new Hints(
+            Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
+
+    /**
+     * A factory for CRS creation with (<var>latitude</var>, <var>longitude</var>) axis order
+     * (unless otherwise specified in system property). Will be created only when first needed.
+     */
+    private static CRSAuthorityFactory defaultFactory;
+
+    /**
+     * A factory for CRS creation with (<var>longitude</var>, <var>latitude</var>) axis order.
+     * Will be created only when first needed.
+     */
+    private static CRSAuthorityFactory xyFactory;
+
+    /**
+     * A factory for default (non-lenient) operations.
+     */
+    private static CoordinateOperationFactory strictFactory;
+
+    /**
+     * A factory for default lenient operations.
+     */
+    private static CoordinateOperationFactory lenientFactory;
+
+    /**
+     * Registers a listener automatically invoked when the system-wide configuration changed.
+     */
+    static {
+        GeoTools.addChangeListener(new ChangeListener() {
+            public void stateChanged(ChangeEvent e) {
+                synchronized (CRS.class) {
+                    defaultFactory = null;
+                    xyFactory      = null;
+                    strictFactory  = null;
+                    lenientFactory = null;
+                }
+            }
+        });
+    }
+
+    /**
+     * Do not allow instantiation of this class.
+     */
+    private CRS() {
+    }
+
+
+    //////////////////////////////////////////////////////////////
+    ////                                                      ////
+    ////        FACTORIES, CRS CREATION AND INSPECTION        ////
+    ////                                                      ////
+    //////////////////////////////////////////////////////////////
+
+    /**
+     * Returns the CRS authority factory used by the {@link #decode(String,boolean) decode} methods.
+     * This factory is {@linkplain org.geotools.referencing.factory.BufferedAuthorityFactory buffered},
+     * scans over {@linkplain org.geotools.referencing.factory.AllAuthoritiesFactory all factories} and
+     * uses additional factories as {@linkplain org.geotools.referencing.factory.FallbackAuthorityFactory
+     * fallbacks} if there is more than one {@linkplain ReferencingFactoryFinder#getCRSAuthorityFactories
+     * registered factory} for the same authority.
+     * <p>
+     * This factory can be used as a kind of <cite>system-wide</cite> factory for all authorities.
+     * However for more determinist behavior, consider using a more specific factory (as returned
+     * by {@link ReferencingFactoryFinder#getCRSAuthorityFactory} when the authority in known.
+     *
+     * @param  longitudeFirst {@code true} if axis order should be forced to
+     *         (<var>longitude</var>,<var>latitude</var>). Note that {@code false} means
+     *         "<cite>use default</cite>", <strong>not</strong> "<cite>latitude first</cite>".
+     * @return The CRS authority factory.
+     * @throws FactoryRegistryException if the factory can't be created.
+     *
+     * @since 2.3
+     */
+    public static synchronized CRSAuthorityFactory getAuthorityFactory(final boolean longitudeFirst)
+            throws FactoryRegistryException
+    {
+        CRSAuthorityFactory factory = (longitudeFirst) ? xyFactory : defaultFactory;
+        if (factory == null) try {
+            factory = new DefaultAuthorityFactory(longitudeFirst);
+            if (longitudeFirst) {
+                xyFactory = factory;
+            } else {
+                defaultFactory = factory;
+            }
+        } catch (NoSuchElementException exception) {
+            // No factory registered in FactoryFinder.
+            throw new FactoryNotFoundException(null, exception);
+        }
+        return factory;
+    }
+
+    /**
+     * Returns the coordinate operation factory used by
+     * {@link #findMathTransform(CoordinateReferenceSystem, CoordinateReferenceSystem)
+     * findMathTransform} convenience methods.
+     *
+     * @param lenient {@code true} if the coordinate operations should be created
+     *        even when there is no information available for a datum shift.
+     *
+     * @since 2.4
+     */
+    public static synchronized CoordinateOperationFactory getCoordinateOperationFactory(final boolean lenient) {
+        CoordinateOperationFactory factory = (lenient) ? lenientFactory : strictFactory;
+        if (factory == null) {
+            final Hints hints = GeoTools.getDefaultHints();
+            if (lenient) {
+                hints.put(Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE);
+            }
+            factory = ReferencingFactoryFinder.getCoordinateOperationFactory(hints);
+            if (lenient) {
+                lenientFactory = factory;
+            } else {
+                strictFactory = factory;
+            }
+        }
+        return factory;
+    }
+
+    /**
+     * Return a Coordinate Reference System for the specified code.
+     * Note that the code needs to mention the authority. Examples:
+     *
+     * <blockquote><pre>
+     * EPSG:1234
+     * AUTO:42001, ..., ..., ...
+     * </pre></blockquote>
+     *
+     * If there is more than one factory implementation for the same authority, then all additional
+     * factories are {@linkplain org.geotools.referencing.factory.FallbackAuthorityFactory fallbacks}
+     * to be used only when the first acceptable factory failed to create the requested CRS object.
+     * <p>
+     * CRS objects created by previous calls to this method are
+     * {@linkplain org.geotools.referencing.factory.BufferedAuthorityFactory cached in a buffer}
+     * using {@linkplain java.lang.ref.WeakReference weak references}. Subsequent calls to this
+     * method with the same authority code should be fast, unless the CRS object has been garbage
+     * collected.
+     *
+     * @param  code The Coordinate Reference System authority code.
+     * @return The Coordinate Reference System for the provided code.
+     * @throws NoSuchAuthorityCodeException If the code could not be understood.
+     * @throws FactoryException if the CRS creation failed for an other reason.
+     *
+     * @see #getSupportedCodes
+     * @see org.geotools.referencing.factory.AllAuthoritiesFactory#createCoordinateReferenceSystem
+     */
+    public static CoordinateReferenceSystem decode(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        /*
+         * Do not use Boolean.getBoolean(GeoTools.FORCE_LONGITUDE_FIRST_AXIS_ORDER).
+         * The boolean argument should be 'false', which means "use system default"
+         * (not "latitude first").
+         */
+        return decode(code, false);
+    }
+
+    /**
+     * Return a Coordinate Reference System for the specified code, maybe forcing the axis order
+     * to (<var>longitude</var>, <var>latitude</var>). The {@code code} argument value is parsed
+     * as in "<code>{@linkplain #decode(String) decode}(code)</code>". The {@code longitudeFirst}
+     * argument value controls the hints to be given to the {@linkplain ReferencingFactoryFinder
+     * factory finder} as in the following pseudo-code:
+     * <p>
+     * <blockquote><pre>
+     * if (longitudeFirst) {
+     *     hints.put({@linkplain Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER}, {@linkplain Boolean#TRUE});
+     * } else {
+     *     // Do not set the FORCE_LONGITUDE_FIRST_AXIS_ORDER hint to FALSE.
+     *     // Left it unset, which means "use system default".
+     * }
+     * </pre></blockquote>
+     *
+     * The following table compare this method {@code longitudeFirst} argument with the
+     * hint meaning:
+     * <p>
+     * <table border='1'>
+     * <tr>
+     *   <th>This method argument</th>
+     *   <th>{@linkplain Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER Hint} value</th>
+     *   <th>Meaning</th>
+     * </tr>
+     * <tr>
+     *   <td>{@code true}</td>
+     *   <td>{@link Boolean#TRUE TRUE}</td>
+     *   <td>All coordinate reference systems are forced to
+     *       (<var>longitude</var>, <var>latitude</var>) axis order.</td>
+     * </tr>
+     * <tr>
+     *   <td>{@code false}</td>
+     *   <td>{@code null}</td>
+     *   <td>Coordinate reference systems may or may not be forced to
+     *       (<var>longitude</var>, <var>latitude</var>) axis order. The behavior depends on user
+     *       setting, for example the value of the <code>{@value
+     *       org.geotools.referencing.factory.epsg.LongitudeFirstFactory#SYSTEM_DEFAULT_KEY}</code>
+     *       system property.</td>
+     * </tr>
+     * <tr>
+     *   <td></td>
+     *   <td>{@link Boolean#FALSE FALSE}</td>
+     *   <td>Forcing (<var>longitude</var>, <var>latitude</var>) axis order is not allowed,
+     *       no matter the value of the <code>{@value
+     *       org.geotools.referencing.factory.epsg.LongitudeFirstFactory#SYSTEM_DEFAULT_KEY}</code>
+     *       system property.</td>
+     * </tr>
+     * </table>
+     *
+     * @param  code The Coordinate Reference System authority code.
+     * @param  longitudeFirst {@code true} if axis order should be forced to
+     *         (<var>longitude</var>, <var>latitude</var>). Note that {@code false} means
+     *         "<cite>use default</cite>", <strong>not</strong> "<cite>latitude first</cite>".
+     * @return The Coordinate Reference System for the provided code.
+     * @throws NoSuchAuthorityCodeException If the code could not be understood.
+     * @throws FactoryException if the CRS creation failed for an other reason.
+     *
+     * @see #getSupportedCodes
+     * @see Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER
+     *
+     * @since 2.3
+     */
+    public static CoordinateReferenceSystem decode(String code, final boolean longitudeFirst)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        // @deprecated: 'toUpperCase()' is required only for epsg-wkt.
+        // Remove after we deleted the epsg-wkt module.
+        code = code.trim().toUpperCase();
+        return getAuthorityFactory(longitudeFirst).createCoordinateReferenceSystem(code);
+    }
+
+    /**
+     * Parses a
+     * <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well
+     * Known Text</cite></A> (WKT) into a CRS object. This convenience method is a
+     * shorthand for the following:
+     *
+     * <blockquote><code>
+     * FactoryFinder.{@linkplain ReferencingFactoryFinder#getCRSFactory getCRSFactory}(null).{@linkplain
+     * org.opengis.referencing.crs.CRSFactory#createFromWKT createFromWKT}(wkt);
+     * </code></blockquote>
+     */
+    public static CoordinateReferenceSystem parseWKT(final String wkt) throws FactoryException { // NO_UCD
+    	return ReferencingFactoryFinder.getCRSFactory(null).createFromWKT(wkt);
+    }
+
+    /**
+     * Returns the valid geographic area for the specified coordinate reference system,
+     * or {@code null} if unknown.
+     *
+     * This method fetchs the {@linkplain CoordinateReferenceSystem#getDomainOfValidity domain
+     * of validity} associated with the given CRS. Only {@linkplain GeographicExtent geographic
+     * extents} of kind {@linkplain GeographicBoundingBox geographic bounding box} are taken in
+     * account.
+     *
+     * @param  crs The coordinate reference system, or {@code null}.
+     * @return The geographic area, or {@code null} if none.
+     *
+     * @see #getEnvelope
+     *
+     * @since 2.3
+     */
+    public static GeographicBoundingBox getGeographicBoundingBox(final CoordinateReferenceSystem crs) { // NO_UCD
+        GeographicBoundingBox     bounds = null;
+        GeographicBoundingBoxImpl merged = null;
+        if (crs != null) {
+            final Extent domainOfValidity = crs.getDomainOfValidity();
+            if (domainOfValidity != null) {
+                for (final GeographicExtent extent : domainOfValidity.getGeographicElements()) {
+                    if (extent instanceof GeographicBoundingBox) {
+                        final GeographicBoundingBox candidate = (GeographicBoundingBox) extent;
+                        if (bounds == null) {
+                            bounds = candidate;
+                        } else {
+                            if (merged == null) {
+                                bounds = merged = new GeographicBoundingBoxImpl(bounds);
+                            }
+                            merged.add(candidate);
+                        }
+                    }
+                }
+            }
+        }
+        return bounds;
+    }
+
+    /**
+     * Returns the first ellipsoid found in a coordinate reference system,
+     * or {@code null} if there is none.
+     *
+     * @param  crs The coordinate reference system, or {@code null}.
+     * @return The ellipsoid, or {@code null} if none.
+     *
+     * @since 2.4
+     */
+    public static Ellipsoid getEllipsoid(final CoordinateReferenceSystem crs) { // NO_UCD
+        final Datum datum = CRSUtilities.getDatum(crs);
+        if (datum instanceof GeodeticDatum) {
+            return ((GeodeticDatum) datum).getEllipsoid();
+        }
+        if (crs instanceof CompoundCRS) {
+            final CompoundCRS cp = (CompoundCRS) crs;
+            for (final CoordinateReferenceSystem c : cp.getCoordinateReferenceSystems()) {
+                final Ellipsoid candidate = getEllipsoid(c);
+                if (candidate != null) {
+                    return candidate;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Compares the specified objects for equality. If both objects are Geotools
+     * implementations of class {@link AbstractIdentifiedObject}, then this method
+     * will ignore the metadata during the comparaison.
+     *
+     * @param  object1 The first object to compare (may be null).
+     * @param  object2 The second object to compare (may be null).
+     * @return {@code true} if both objects are equals.
+     *
+     * @since 2.2
+     */
+    public static boolean equalsIgnoreMetadata(final Object object1, final Object object2) {
+        if (object1 == object2) {
+            return true;
+        }
+        if (object1 instanceof AbstractIdentifiedObject &&
+            object2 instanceof AbstractIdentifiedObject)
+        {
+            return ((AbstractIdentifiedObject) object1).equals(
+                   ((AbstractIdentifiedObject) object2), false);
+        }
+        return object1!=null && object1.equals(object2);
+    }
+
+    /**
+     * Returns the <cite>Spatial Reference System</cite> identifier, or {@code null} if none. OGC
+     * Web Services have the concept of a Spatial Reference System identifier used to communicate
+     * CRS information between systems.
+     * <p>
+     * Spatial Reference System (ie SRS) values:
+     * <ul>
+     *   <li>{@code EPSG:4326} - this is the usual format understood to mean <cite>forceXY</cite>
+     *       order. Note that the axis order is <em>not necessarly</em> (<var>longitude</var>,
+     *       <var>latitude</var>), but this is the common behavior we observe in practice.</li>
+     *   <li>{@code AUTO:43200} - </li>
+     *   <li>{@code ogc:uri:.....} - understood to match the EPSG database axis order.</li>
+     *   <li>Well Known Text (WKT)</li>
+     * </ul>
+     *
+     * @param  crs The coordinate reference system, or {@code null}.
+     * @return SRS represented as a string for communication between systems, or {@code null}.
+     *
+     * @since 2.5
+     */
+    public static String toSRS(final CoordinateReferenceSystem crs) {
+        boolean forcedLonLat = false;
+        try {
+            forcedLonLat = Boolean.getBoolean("org.geotools.referencing.forceXY") || 
+                Boolean.TRUE.equals(Hints.getSystemDefault(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER));
+        } catch(Exception e) {
+            // all right it was a best effort attempt
+            LOGGER.log(Level.FINE, "Failed to determine if we are in forced lon/lat mode", e);
+        }
+        if (forcedLonLat && CRS.getAxisOrder(crs, false) == AxisOrder.NORTH_EAST) {
+            try {
+                // not usual axis order, check if we can have a EPSG code
+                Integer code = CRS.lookupEpsgCode(crs, false);
+                if (code != null) {
+                    return "urn:ogc:def:crs:EPSG::" + code;
+                }
+            } catch (Exception e) {
+                // all right it was a best effort attempt
+                LOGGER.log(Level.FINE, "Failed to determine EPSG code", e);
+            }
+        }
+        
+        // fall back on simple lookups
+        if( crs == null ){
+            return null;
+        }
+        final Set<ReferenceIdentifier> identifiers = crs.getIdentifiers();
+        if (identifiers.isEmpty()) {
+            // fallback unfortunately this often does not work
+            final ReferenceIdentifier name = crs.getName();
+            if (name != null) {
+                return name.toString();
+            }
+        } else {
+            return identifiers.iterator().next().toString();
+        }
+        return null;
+    }
+
+    /**
+     * Looks up an identifier of the specified authority for the given
+     * {@linkplain CoordinateReferenceSystem coordinate reference system}). This method is similar
+     * to <code>{@linkplain #lookupIdentifier(IdentifiedObject, boolean) lookupIdentifier}(object,
+     * fullScan)</code> except that the search is performed only among the factories of the given
+     * authority.
+     * <p>
+     * If the CRS does not have an {@linkplain ReferenceIdentifier identifier} which corresponds
+     * to the {@linkplain Citations#EPSG EPSG} authority, then:
+     * <ul>
+     *   <li>if {@code fullScan} is {@code true}, then this method scans the factories in search
+     *       for an object {@linkplain #equalsIgnoreMetadata equals, ignoring metadata}, to the
+     *       given object. If one is found, its identifier is returned.</li>
+     *   <li>Otherwise (if {@code fullScan} is {@code false} or if no identifier was found in the
+     *       previous step), this method returns {@code null}.</li>
+     * </ul>
+     *
+     * @param  authority The authority for the code to search.
+     * @param  crs The coordinate reference system instance, or {@code null}.
+     * @return The CRS identifier, or {@code null} if none was found.
+     * @throws FactoryException if an error occured while searching for the identifier.
+     *
+     * @since 2.5
+     */
+    public static String lookupIdentifier(final Citation authority,
+            final CoordinateReferenceSystem crs, final boolean fullScan)
+            throws FactoryException
+    {
+        ReferenceIdentifier id = AbstractIdentifiedObject.getIdentifier(crs, authority);
+        if (id != null) {
+            return id.getCode();
+        }
+        for (final CRSAuthorityFactory factory : ReferencingFactoryFinder
+                    .getCRSAuthorityFactories(FORCE_LONGITUDE_FIRST_AXIS_ORDER))
+        {
+            if (!Citations.identifierMatches(factory.getAuthority(), authority)) {
+                continue;
+            }
+            if (!(factory instanceof AbstractAuthorityFactory)) {
+                continue;
+            }
+            final AbstractAuthorityFactory f = (AbstractAuthorityFactory) factory;
+            final IdentifiedObjectFinder finder = f.getIdentifiedObjectFinder(crs.getClass());
+            finder.setFullScanAllowed(fullScan);
+            final String code = finder.findIdentifier(crs);
+            if (code != null) {
+                return code;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Looks up an EPSG code for the given {@linkplain CoordinateReferenceSystem
+     * coordinate reference system}). This is a convenience method for <code>{@linkplain
+     * #lookupIdentifier(Citations, IdentifiedObject, boolean) lookupIdentifier}({@linkplain
+     * Citations#EPSG}, crs, fullScan)</code> except that code is parsed as an integer.
+     *
+     * @param  crs The coordinate reference system instance, or {@code null}.
+     * @return The CRS identifier, or {@code null} if none was found.
+     * @throws FactoryException if an error occured while searching for the identifier.
+     *
+     * @since 2.5
+     */
+    public static Integer lookupEpsgCode(final CoordinateReferenceSystem crs, final boolean fullScan)
+            throws FactoryException
+    {
+        final String identifier = lookupIdentifier(Citations.EPSG, crs, fullScan);
+        if (identifier != null) {
+            final int split = identifier.lastIndexOf(GenericName.DEFAULT_SEPARATOR);
+            final String code = identifier.substring(split + 1);
+            // The above code works even if the separator was not found, since in such case
+            // split == -1, which implies a call to substring(0) which returns 'identifier'.
+            try {
+                return Integer.parseInt(code);
+            } catch (NumberFormatException e) {
+                throw new FactoryException(Errors.format(ErrorKeys.ILLEGAL_IDENTIFIER_$1, identifier), e);
+            }
+        }
+        return null;
+    }
+
+
+    /////////////////////////////////////////////////
+    ////                                         ////
+    ////          COORDINATE OPERATIONS          ////
+    ////                                         ////
+    /////////////////////////////////////////////////
+
+    /**
+     * Grab a transform between two Coordinate Reference Systems. This convenience method is a
+     * shorthand for the following:
+     *
+     * <blockquote><code>FactoryFinder.{@linkplain ReferencingFactoryFinder#getCoordinateOperationFactory
+     * getCoordinateOperationFactory}(null).{@linkplain CoordinateOperationFactory#createOperation
+     * createOperation}(sourceCRS, targetCRS).{@linkplain CoordinateOperation#getMathTransform
+     * getMathTransform}();</code></blockquote>
+     *
+     * Note that some metadata like {@linkplain CoordinateOperation#getPositionalAccuracy
+     * positional accuracy} are lost by this method. If those metadata are wanted, use the
+     * {@linkplain CoordinateOperationFactory coordinate operation factory} directly.
+     * <p>
+     * Sample use:
+     * <blockquote><code>
+     * {@linkplain MathTransform} transform = CRS.findMathTransform(
+     * CRS.{@linkplain #decode decode}("EPSG:42102"),
+     * CRS.{@linkplain #decode decode}("EPSG:4326") );
+     * </blockquote></code>
+     *
+     * @param  sourceCRS The source CRS.
+     * @param  targetCRS The target CRS.
+     * @return The math transform from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If no math transform can be created for the specified source and
+     *         target CRS.
+     */
+    public static MathTransform findMathTransform(final CoordinateReferenceSystem sourceCRS,
+                                                  final CoordinateReferenceSystem targetCRS)
+            throws FactoryException
+    {
+    	return findMathTransform(sourceCRS, targetCRS, false);
+    }
+
+    /**
+     * Grab a transform between two Coordinate Reference Systems. This method is similar to
+     * <code>{@linkplain #findMathTransform(CoordinateReferenceSystem, CoordinateReferenceSystem)
+     * findMathTransform}(sourceCRS, targetCRS)</code>, except that it can optionally tolerate
+     * <cite>lenient datum shift</cite>. If the {@code lenient} argument is {@code true},
+     * then this method will not throw a "<cite>Bursa-Wolf parameters required</cite>"
+     * exception during datum shifts if the Bursa-Wolf paramaters are not specified.
+     * Instead it will assume a no datum shift.
+     *
+     * @param  sourceCRS The source CRS.
+     * @param  targetCRS The target CRS.
+     * @param  lenient {@code true} if the math transform should be created even when there is
+     *         no information available for a datum shift. The default value is {@code false}.
+     * @return The math transform from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If no math transform can be created for the specified source and
+     *         target CRS.
+     *
+     * @see Hints#LENIENT_DATUM_SHIFT
+     */
+    public static MathTransform findMathTransform(final CoordinateReferenceSystem sourceCRS,
+                                                  final CoordinateReferenceSystem targetCRS,
+                                                  boolean lenient)
+            throws FactoryException
+    {
+        if (equalsIgnoreMetadata(sourceCRS, targetCRS)) {
+            // Slight optimization in order to avoid the overhead of loading the full referencing engine.
+            return IdentityTransform.create(sourceCRS.getCoordinateSystem().getDimension());
+        }
+        CoordinateOperationFactory operationFactory = getCoordinateOperationFactory(lenient);
+        return operationFactory.createOperation(sourceCRS, targetCRS).getMathTransform();
+    }
+
+    /**
+     * Determines the axis ordering of a specified crs object.
+     * <p>
+     * The <tt>useBaseGeoCRS</tt> parameter is used to control behaviour for 
+     * projected crs. When set to <tt>true</tt> the comparison will use the 
+     * coordinate system for the underlying geographic crs object for the 
+     * comparison. When set to false the comparison will use the coordinate 
+     * system from projected crs itself.
+     * </p>
+     * @param crs The coordinate reference system.
+     * @param useBaseGeoCRS Controls whether the base geo crs is used for 
+     *   projected crs.
+     * 
+     * @return One of {@link AxisOrder#EAST_NORTH}, {@link AxisOrder@NORTH_EAST}, 
+     * or {@link AxisOrder#INAPPLICABLE}
+     */
+    public static AxisOrder getAxisOrder(CoordinateReferenceSystem crs, boolean useBaseGeoCRS) { 
+        CoordinateSystem cs = null;
+
+        if (crs instanceof ProjectedCRS) {
+            cs = !useBaseGeoCRS ? crs.getCoordinateSystem() :  
+                ((ProjectedCRS)crs).getBaseCRS().getCoordinateSystem();
+        }
+        else if (crs instanceof GeographicCRS) {
+            cs = crs.getCoordinateSystem();
+        }
+        else {
+            return AxisOrder.INAPPLICABLE;
+        }
+
+        int dimension = cs.getDimension();
+        int longitudeDim = -1;
+        int latitudeDim = -1;
+
+        for (int i = 0; i < dimension; i++) {
+            AxisDirection dir = cs.getAxis(i).getDirection().absolute();
+
+            if (dir.equals(AxisDirection.EAST)) {
+                longitudeDim = i;
+            }
+
+            if (dir.equals(AxisDirection.NORTH)) {
+                latitudeDim = i;
+            }
+        }
+
+        if ((longitudeDim >= 0) && (latitudeDim >= 0)) {
+            if (longitudeDim < latitudeDim) {
+                return AxisOrder.EAST_NORTH;
+            } else {
+                return AxisOrder.NORTH_EAST;
+            }
+        }
+
+        return AxisOrder.INAPPLICABLE;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/DefaultAuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/DefaultAuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/DefaultAuthorityFactory.java	(revision 28000)
@@ -0,0 +1,133 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.geotools.factory.GeoTools;
+import org.geotools.factory.Hints;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.crs.DefaultGeographicCRS;
+import org.geotools.referencing.factory.AbstractAuthorityFactory;
+import org.geotools.referencing.factory.ManyAuthoritiesFactory;
+import org.geotools.referencing.factory.ThreadedAuthorityFactory;
+import org.geotools.resources.UnmodifiableArrayList;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CRSAuthorityFactory;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+
+/**
+ * The default authority factory to be used by {@link CRS#decode}.
+ * <p>
+ * This class gathers together a lot of logic in order to capture the following ideas:
+ * <ul>
+ *   <li>Uses {@link Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER} to swap ordinate order if needed.</li>
+ *   <li>Uses {@link ManyAuthoritiesFactory} to access CRSAuthorities in the environment.</li>
+ * </ul>
+ *
+ * @since 2.3
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/DefaultAuthorityFactory.java $
+ * @version $Id: DefaultAuthorityFactory.java 30641 2008-06-12 17:42:27Z acuster $
+ * @author Martin Desruisseaux
+ * @author Andrea Aime
+ */
+final class DefaultAuthorityFactory extends ThreadedAuthorityFactory implements CRSAuthorityFactory {
+    /**
+     * List of codes without authority space. We can not defines them in an ordinary
+     * authority factory.
+     */
+    private static List<String> AUTHORITY_LESS = UnmodifiableArrayList.wrap(new String[] {
+        "WGS84(DD)"  // (longitude,latitude) with decimal degrees.
+    });
+
+    /**
+     * Creates a new authority factory.
+     */
+    DefaultAuthorityFactory(final boolean longitudeFirst) {
+        super(getBackingFactory(longitudeFirst));
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private static AbstractAuthorityFactory getBackingFactory(final boolean longitudeFirst) {
+        final Hints hints = GeoTools.getDefaultHints();
+        if (longitudeFirst) {
+            hints.put(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
+        } else {
+            /*
+             * Do NOT set the hint to false. If 'longitudeFirst' is false, this means
+             * "use the system default", not "latitude first". The longitude may or may
+             * not be first depending the value of "org.geotools.referencing.forcexy"
+             * system property. This state is included in GeoTools.getDefaultHints().
+             */
+        }
+        Collection<CRSAuthorityFactory> factories =
+                ReferencingFactoryFinder.getCRSAuthorityFactories(hints);
+        if (Boolean.TRUE.equals(hints.put(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.FALSE))) {
+            /*
+             * If hints contain a requirement for "longitude first", then we may loose some
+             * authorities like "URN:OGC:...". Search again without such requirement and add
+             * any new authorities found.
+             */
+            factories = new ArrayList<CRSAuthorityFactory>(factories);
+            final Set<Citation> authorities = new LinkedHashSet<Citation>();
+            for (final CRSAuthorityFactory factory : factories) {
+                authorities.add(factory.getAuthority());
+            }
+searchNews: for (final CRSAuthorityFactory factory :
+                    ReferencingFactoryFinder.getCRSAuthorityFactories(hints))
+            {
+                final Citation authority = factory.getAuthority();
+                if (authorities.contains(authority)) {
+                    continue;
+                }
+                for (final Citation check : authorities) {
+                    if (Citations.identifierMatches(authority, check)) {
+                        continue searchNews;
+                    }
+                }
+                factories.add(factory);
+            }
+        }
+        return new ManyAuthoritiesFactory(factories);
+    }
+
+    /**
+     * Returns the coordinate reference system for the given code.
+     */
+    @Override
+    public CoordinateReferenceSystem createCoordinateReferenceSystem(String code)
+            throws FactoryException
+    {
+        if (code != null) {
+            code = code.trim();
+            if (code.equalsIgnoreCase("WGS84(DD)")) {
+                return DefaultGeographicCRS.WGS84;
+            }
+        }
+        assert !AUTHORITY_LESS.contains(code) : code;
+        return super.createCoordinateReferenceSystem(code);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/NamedIdentifier.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/NamedIdentifier.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/NamedIdentifier.java	(revision 28000)
@@ -0,0 +1,664 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.logging.LogRecord;
+
+import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.parameter.InvalidParameterValueException;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;
+import org.opengis.util.LocalName;
+import org.opengis.util.NameSpace;
+import org.opengis.util.ScopedName;
+import static org.opengis.referencing.IdentifiedObject.REMARKS_KEY;
+
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Loggings;
+import org.geotools.resources.i18n.LoggingKeys;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.util.GrowableInternationalString;
+import org.geotools.util.WeakValueHashMap;
+import org.geotools.util.logging.Logging;
+import org.geotools.util.Utilities;
+
+
+/**
+ * An identification of a CRS object. The main interface implemented by this class is
+ * {@link ReferenceIdentifier}. However, this class also implements {@link GenericName}
+ * in order to make it possible to reuse the same identifiers in the list of
+ * {@linkplain AbstractIdentifiedObject#getAlias aliases}. Casting an alias's
+ * {@linkplain GenericName generic name} to an {@linkplain ReferenceIdentifier identifier}
+ * gives access to more informations, like the URL of the authority.
+ * <P>
+ * The {@linkplain GenericName generic name} will be infered from
+ * {@linkplain ReferenceIdentifier identifier} attributes. More specifically, a
+ * {@linkplain ScopedName scoped name} will be constructed using the shortest authority's
+ * {@linkplain Citation#getAlternateTitles alternate titles} (or the
+ * {@linkplain Citation#getTitle main title} if there is no alternate titles) as the
+ * {@linkplain ScopedName#getScope scope}, and the {@linkplain #getCode code} as the
+ * {@linkplain ScopedName#asLocalName head}. This heuristic rule seems raisonable
+ * since, according ISO 19115, the {@linkplain Citation#getAlternateTitles alternate
+ * titles} often contains abreviation (for example "DCW" as an alternative title for
+ * "<cite>Digital Chart of the World</cite>").
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/NamedIdentifier.java $
+ * @version $Id: NamedIdentifier.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class NamedIdentifier implements ReferenceIdentifier, GenericName,
+                                        Serializable
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 8474731565582774497L;
+
+    /**
+     * A pool of {@link LocalName} values for given {@link InternationalString}.
+     * Will be constructed only when first needed.
+     */
+    private static Map<CharSequence,GenericName> SCOPES;
+
+    /**
+     * Identifier code or name, optionally from a controlled list or pattern
+     * defined by a code space.
+     */
+    private final String code;
+
+    /**
+     * Name or identifier of the person or organization responsible for namespace.
+     */
+    private final String codespace;
+
+    /**
+     * Organization or party responsible for definition and maintenance of the
+     * code space or code.
+     */
+    private final Citation authority;
+
+    /**
+     * Identifier of the version of the associated code space or code, as specified
+     * by the code space or code authority. This version is included only when the
+     * {@linkplain #getCode code} uses versions. When appropriate, the edition is
+     * identified by the effective date, coded using ISO 8601 date format.
+     */
+    private final String version;
+
+    /**
+     * Comments on or information about this identifier, or {@code null} if none.
+     */
+    private final InternationalString remarks;
+
+    /**
+     * The name of this identifier as a generic name. If {@code null}, will
+     * be constructed only when first needed. This field is serialized (instead
+     * of being recreated after deserialization) because it may be a user-supplied
+     * value.
+     */
+    private GenericName name;
+
+    /**
+     * Constructs an identifier from a set of properties. Keys are strings from the table below.
+     * Key are case-insensitive, and leading and trailing spaces are ignored. The map given in
+     * argument shall contains at least a <code>"code"</code> property. Other properties listed
+     * in the table below are optional.
+     * <p>
+     * <table border='1'>
+     *   <tr bgcolor="#CCCCFF" class="TableHeadingColor">
+     *     <th nowrap>Property name</th>
+     *     <th nowrap>Value type</th>
+     *     <th nowrap>Value given to</th>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@link #CODE_KEY "code"}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getCode}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@link #CODESPACE_KEY "code"}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getCodeSpace}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@link #AUTHORITY_KEY "authority"}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String} or {@link Citation}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getAuthority}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@link #VERSION_KEY "version"}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getVersion}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@link #REMARKS_KEY "remarks"}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String} or {@link InternationalString}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getRemarks}</td>
+     *   </tr>
+     * </table>
+     *
+     * <P><code>"remarks"</code> is a localizable attributes which may have a language and country
+     * code suffix. For example the <code>"remarks_fr"</code> property stands for remarks in
+     * {@linkplain Locale#FRENCH French} and the <code>"remarks_fr_CA"</code> property stands
+     * for remarks in {@linkplain Locale#CANADA_FRENCH French Canadian}.</P>
+     *
+     * @param properties The properties to be given to this identifier.
+     * @throws InvalidParameterValueException if a property has an invalid value.
+     * @throws IllegalArgumentException if a property is invalid for some other reason.
+     */
+    public NamedIdentifier(final Map<String,?> properties) throws IllegalArgumentException {
+        this(properties, true);
+    }
+
+    /**
+     * Constructs an identifier from an authority and code informations. This is a convenience
+     * constructor for commonly-used parameters. If more control are wanted (for example adding
+     * remarks), use the {@linkplain #NamedIdentifier(Map) constructor with a properties map}.
+     *
+     * @param authority The authority (e.g. {@link Citations#OGC OGC} or {@link Citations#EPSG EPSG}).
+     * @param code      The code. The {@linkplain Locale#US English name} is used
+     *                  for the code, and the international string is used for the
+     *                  {@linkplain GenericName generic name}.
+     */
+    public NamedIdentifier(final Citation authority, final InternationalString code) {
+        // The "null" locale argument is required for getting the unlocalized version.
+        this(authority, code.toString(null));
+        name = getName(authority, code);
+    }
+
+    /**
+     * Constructs an identifier from an authority and code informations. This is a convenience
+     * constructor for commonly-used parameters. If more control are wanted (for example adding
+     * remarks), use the {@linkplain #NamedIdentifier(Map) constructor with a properties map}.
+     *
+     * @param authority The authority (e.g. {@link Citations#OGC OGC} or {@link Citations#EPSG EPSG}).
+     * @param code      The code. This parameter is mandatory.
+     */
+    public NamedIdentifier(final Citation authority, final String code) {
+        this(authority, code, null);
+    }
+
+    /**
+     * Constructs an identifier from an authority and code informations. This is a convenience
+     * constructor for commonly-used parameters. If more control are wanted (for example adding
+     * remarks), use the {@linkplain #NamedIdentifier(Map) constructor with a properties map}.
+     *
+     * @param authority The authority (e.g. {@link Citations#OGC OGC} or {@link Citations#EPSG EPSG}).
+     * @param code      The code. This parameter is mandatory.
+     * @param version   The version, or {@code null} if none.
+     */
+    public NamedIdentifier(final Citation authority, final String code, final String version) {
+        this(toMap(authority, code, version));
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private static Map<String,?> toMap(final Citation authority,
+                                       final String   code,
+                                       final String   version)
+    {
+        final Map<String,Object> properties = new HashMap<String,Object>(4);
+        if (authority != null) properties.put(AUTHORITY_KEY, authority);
+        if (code      != null) properties.put(     CODE_KEY, code     );
+        if (version   != null) properties.put(  VERSION_KEY, version  );
+        return properties;
+    }
+
+    /**
+     * Implementation of the constructor. The remarks in the {@code properties} will be
+     * parsed only if the {@code standalone} argument is set to {@code true}, i.e.
+     * this identifier is being constructed as a standalone object. If {@code false}, then
+     * this identifier is assumed to be constructed from inside the {@link AbstractIdentifiedObject}
+     * constructor.
+     *
+     * @param properties The properties to parse, as described in the public constructor.
+     * @param standalone {@code true} for parsing "remarks" as well.
+     *
+     * @throws InvalidParameterValueException if a property has an invalid value.
+     * @throws IllegalArgumentException if a property is invalid for some other reason.
+     */
+    NamedIdentifier(final Map<String,?> properties, final boolean standalone)
+            throws IllegalArgumentException
+    {
+        ensureNonNull("properties", properties);
+        Object code      = null;
+        Object codespace = null;
+        Object version   = null;
+        Object authority = null;
+        Object remarks   = null;
+        GrowableInternationalString growable = null;
+        /*
+         * Iterate through each map entry. This have two purposes:
+         *
+         *   1) Ignore case (a call to properties.get("foo") can't do that)
+         *   2) Find localized remarks.
+         *
+         * This algorithm is sub-optimal if the map contains a lot of entries of no interest to
+         * this identifier. Hopefully, most users will fill a map only with usefull entries.
+         */
+        String key   = null;
+        Object value = null;
+        for (final Map.Entry<String,?> entry : properties.entrySet()) {
+            key   = entry.getKey().trim().toLowerCase();
+            value = entry.getValue();
+            /*
+             * Note: String.hashCode() is part of J2SE specification,
+             *       so it should not change across implementations.
+             */
+            switch (key.hashCode()) {
+                case 3373707: {
+                    if (!standalone && key.equals("name")) {
+                        code = value;
+                        continue;
+                    }
+                    break;
+                }
+                case 3059181: {
+                    if (key.equals(CODE_KEY)) {
+                        code = value;
+                        continue;
+                    }
+                    break;
+                }
+                case -1108676807: {
+                    if (key.equals(CODESPACE_KEY)) {
+                        codespace = value;
+                        continue;
+                    }
+                    break;
+
+                }
+                case 351608024: {
+                    if (key.equals(VERSION_KEY)) {
+                        version = value;
+                        continue;
+                    }
+                    break;
+                }
+                case 1475610435: {
+                    if (key.equals(AUTHORITY_KEY)) {
+                        if (value instanceof String) {
+                            value = Citations.fromName(value.toString());
+                        }
+                        authority = value;
+                        continue;
+                    }
+                    break;
+                }
+                case 1091415283: {
+                    if (standalone && key.equals(REMARKS_KEY)) {
+                        if (value instanceof InternationalString) {
+                            remarks = value;
+                            continue;
+                        }
+                    }
+                    break;
+                }
+            }
+            /*
+             * Search for additional locales (e.g. "remarks_fr").
+             */
+            if (standalone && value instanceof String) {
+                if (growable == null) {
+                    if (remarks instanceof GrowableInternationalString) {
+                        growable = (GrowableInternationalString) remarks;
+                    } else {
+                        growable = new GrowableInternationalString();
+                    }
+                }
+                growable.add(REMARKS_KEY, key, value.toString());
+            }
+        }
+        /*
+         * Get the localized remarks, if it was not yet set. If a user specified remarks
+         * both as InternationalString and as String for some locales (which is a weird
+         * usage...), then current implementation discart the later with a warning.
+         */
+        if (growable!=null && !growable.getLocales().isEmpty()) {
+            if (remarks == null) {
+                remarks = growable;
+            } else {
+                final Logger logger = Logging.getLogger(NamedIdentifier.class);
+                final LogRecord record = Loggings.format(Level.WARNING, LoggingKeys.LOCALES_DISCARTED);
+                record.setLoggerName(logger.getName());
+                logger.log(record);
+            }
+        }
+        /*
+         * Completes the code space if it was not explicitly set. We take the first
+         * identifier if there is any, otherwise we take the shortest title.
+         */
+        if (codespace == null && authority instanceof Citation) {
+            codespace = getCodeSpace((Citation) authority);
+        }
+        /*
+         * Stores the definitive reference to the attributes. Note that casts are performed only
+         * there (not before). This is a wanted feature, since we want to catch ClassCastExceptions
+         * are rethrown them as more informative exceptions.
+         */
+        try {
+            key=      CODE_KEY; this.code      = (String)              (value=code);
+            key=   VERSION_KEY; this.version   = (String)              (value=version);
+            key= CODESPACE_KEY; this.codespace = (String)              (value=codespace);
+            key= AUTHORITY_KEY; this.authority = (Citation)            (value=authority);
+            key=   REMARKS_KEY; this.remarks   = (InternationalString) (value=remarks);
+        } catch (ClassCastException exception) {
+            InvalidParameterValueException e = new InvalidParameterValueException(
+                    Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2, key, value), key, value);
+            e.initCause(exception);
+            throw e;
+        }
+        ensureNonNull(CODE_KEY, code);
+    }
+
+    /**
+     * Makes sure an argument is non-null. This is method duplicate
+     * {@link AbstractIdentifiedObject#ensureNonNull(String, Object)}
+     * except for the more accurate stack trace. It is duplicated
+     * there in order to avoid a dependency to {@link AbstractIdentifiedObject}.
+     *
+     * @param  name   Argument name.
+     * @param  object User argument.
+     * @throws InvalidParameterValueException if {@code object} is null.
+     */
+    private static void ensureNonNull(final String name, final Object object)
+        throws IllegalArgumentException
+    {
+        if (object == null) {
+            throw new InvalidParameterValueException(Errors.format(
+                        ErrorKeys.NULL_ARGUMENT_$1, name), name, object);
+        }
+    }
+
+    /**
+     * Identifier code or name, optionally from a controlled list or pattern.
+     *
+     * @return The code.
+     */
+    public String getCode() {
+        return code;
+    }
+
+    /**
+     * Name or identifier of the person or organization responsible for namespace.
+     *
+     * @return The codespace, or {@code null} if not available.
+     */
+    public String getCodeSpace() {
+        return codespace;
+    }
+
+    /**
+     * Organization or party responsible for definition and maintenance of the
+     * {@linkplain #getCode code}.
+     *
+     * @return The authority, or {@code null} if not available.
+     */
+    public Citation getAuthority() {
+        return authority;
+    }
+
+    /**
+     * Returns the generic name of this identifier. The name will be constructed
+     * automatically the first time it will be needed. The name's scope is infered
+     * from the shortest alternative title (if any). This heuristic rule seems raisonable
+     * since, according ISO 19115, the {@linkplain Citation#getAlternateTitles alternate
+     * titles} often contains abreviation (for example "DCW" as an alternative title for
+     * "Digital Chart of the World"). If no alternative title is found or if the main title
+     * is yet shorter, then it is used.
+     */
+    private synchronized GenericName getName() {
+        if (name == null) {
+            name = getName(authority, code);
+        }
+        return name;
+    }
+
+    /**
+     * Constructs a generic name from the specified authority and code.
+     */
+    private GenericName getName(final Citation authority, final CharSequence code) {
+        if (authority == null) {
+            return new org.geotools.util.LocalName(code);
+        }
+        final CharSequence title;
+        if (codespace != null) {
+            title = codespace;
+        } else {
+            title = getShortestTitle(authority);
+        }
+        GenericName scope;
+        synchronized (NamedIdentifier.class) {
+            if (SCOPES == null) {
+                SCOPES = new WeakValueHashMap<CharSequence,GenericName>();
+            }
+            scope = SCOPES.get(title);
+            if (scope == null) {
+                scope = new org.geotools.util.LocalName(title);
+                SCOPES.put(title, scope);
+            }
+        }
+        return new org.geotools.util.ScopedName(scope, code);
+    }
+
+    /**
+     * Returns the shortest title inferred from the specified authority.
+     */
+    private static InternationalString getShortestTitle(final Citation authority) {
+        InternationalString title = authority.getTitle();
+        int length = title.length();
+        final Collection<? extends InternationalString> alt = authority.getAlternateTitles();
+        if (alt != null) {
+            for (final InternationalString candidate : alt) {
+                final int candidateLength = candidate.length();
+                if (candidateLength>0 && candidateLength<length) {
+                    title = candidate;
+                    length = candidateLength;
+                }
+            }
+        }
+        return title;
+    }
+
+    /**
+     * Tries to get a codespace from the specified authority. This method scan first
+     * through the identifier, then through the titles if no suitable identifier were found.
+     */
+    private static String getCodeSpace(final Citation authority) {
+        final Collection<? extends Identifier> identifiers = authority.getIdentifiers();
+        if (identifiers != null) {
+            for (final Identifier id : identifiers) {
+                final String identifier = id.getCode();
+                if (isValidCodeSpace(identifier)) {
+                    return identifier;
+                }
+            }
+        }
+        // The "null" locale argument is required for getting the unlocalized version.
+        final String title = getShortestTitle(authority).toString(null);
+        if (isValidCodeSpace(title)) {
+            return title;
+        }
+        return null;
+    }
+
+    /**
+     * Returns {@code true} if the specified string looks like a valid code space.
+     * This method, together with {@link #getShortestTitle}, uses somewhat heuristic
+     * rules that may change in future Geotools versions.
+     */
+    private static boolean isValidCodeSpace(final String codespace) {
+        if (codespace == null) {
+            return false;
+        }
+        for (int i=codespace.length(); --i>=0;) {
+            if (!Character.isJavaIdentifierPart(codespace.charAt(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns the first element in the sequence of {@linkplain #getParsedNames parsed names}.
+     *
+     * @since 2.6
+     */
+    public LocalName head() {
+        return getName().head();
+    }
+
+    /**
+     * Returns the last element in the sequence of {@linkplain #getParsedNames parsed names}.
+     *
+     * @since 2.3
+     */
+    public LocalName tip() {
+        return getName().tip();
+    }
+
+    /**
+     * Returns the scope (name space) in which this name is local.
+     *
+     * @since 2.3
+     */
+    public NameSpace scope() {
+        return getName().scope();
+    }
+
+    /**
+     * Returns the depth of this name within the namespace hierarchy.
+     *
+     * @since 2.3
+     */
+    public int depth() {
+        return getName().depth();
+    }
+
+    /**
+     * Returns the sequence of {@linkplain LocalName local names} making this generic name.
+     * Each element in this list is like a directory name in a file path name.
+     * The length of this sequence is the generic name depth.
+     */
+    public List<LocalName> getParsedNames() {
+        // TODO: temporary hack to be removed after GeoAPI update.
+        return (List) getName().getParsedNames();
+    }
+
+    /**
+     * Returns this name expanded with the specified scope. One may represent this operation
+     * as a concatenation of the specified {@code name} with {@code this}.
+     *
+     * @since 2.3
+     */
+    public ScopedName push(final GenericName scope) {
+        return getName().push(scope);
+    }
+
+    /**
+     * Returns a view of this name as a fully-qualified name.
+     *
+     * @since 2.3
+     */
+    public GenericName toFullyQualifiedName() {
+        return getName().toFullyQualifiedName();
+    }
+
+    /**
+     * Returns a local-dependent string representation of this generic name. This string
+     * is similar to the one returned by {@link #toString} except that each element has
+     * been localized in the {@linkplain InternationalString#toString(Locale) specified locale}.
+     * If no international string is available, then this method returns an implementation mapping
+     * to {@link #toString} for all locales.
+     */
+    public InternationalString toInternationalString() {
+        return getName().toInternationalString();
+    }
+
+    /**
+     * Returns a string representation of this generic name. This string representation
+     * is local-independant. It contains all elements listed by {@link #getParsedNames}
+     * separated by an arbitrary character (usually {@code :} or {@code /}).
+     */
+    @Override
+    public String toString() {
+        return getName().toString();
+    }
+
+    /**
+     * Compares this name with the specified object for order. Returns a negative integer,
+     * zero, or a positive integer as this name lexicographically precedes, is equals to,
+     * or follows the specified object.
+     *
+     * @param object The object to compare with.
+     * @return -1 if this identifier precedes the given object, +1 if it follows it.
+     */
+    public int compareTo(final GenericName object) {
+        return getName().compareTo(object);
+    }
+
+    /**
+     * Compares this identifier with the specified object for equality.
+     *
+     * @param object The object to compare with this name.
+     * @return {@code true} if the given object is equals to this name.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object!=null && object.getClass().equals(getClass())) {
+            final NamedIdentifier that = (NamedIdentifier) object;
+            return Utilities.equals(this.code,      that.code     ) &&
+                   Utilities.equals(this.codespace, that.codespace) &&
+                   Utilities.equals(this.version,   that.version  ) &&
+                   Utilities.equals(this.authority, that.authority) &&
+                   Utilities.equals(this.remarks,   that.remarks  );
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this identifier.
+     */
+    @Override
+    public int hashCode() {
+        int hash = (int) serialVersionUID;
+        if (code != null) {
+            hash ^= code.hashCode();
+        }
+        if (version != null) {
+            hash = hash*37 + version.hashCode();
+        }
+        return hash;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/Properties.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/Properties.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/Properties.java	(revision 28000)
@@ -0,0 +1,170 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing;
+
+import java.util.AbstractMap;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.opengis.referencing.datum.Datum;
+import org.opengis.referencing.ReferenceSystem;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.operation.CoordinateOperation;
+
+import org.geotools.util.MapEntry;
+import org.geotools.referencing.operation.AbstractCoordinateOperation;
+
+
+/**
+ * An immutable map fetching all properties from the specified identified object. Calls
+ * to {@code get} methods are forwarded to the appropriate {@link IdentifiedObject} method.
+ *
+ * @since 2.1
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/Properties.java $
+ * @version $Id: Properties.java 30975 2008-07-09 18:04:53Z desruisseaux $
+ * @author Martin Desruisseaux (IRD)
+ */
+final class Properties extends AbstractMap<String,Object> {
+    /**
+     * The object where all properties come from.
+     */
+    private final IdentifiedObject info;
+
+    /**
+     * The entries set. Will be constructed only when first needed.
+     */
+    private transient Set<Entry<String,Object>> entries;
+
+    /**
+     * Creates new properties from the specified identified object.
+     */
+    public Properties(final IdentifiedObject info) {
+        this.info = info;
+        AbstractIdentifiedObject.ensureNonNull("info", info);
+    }
+
+    /**
+     * Returns true if this map contains a mapping for the specified key.
+     */
+    @Override
+    public boolean containsKey(final Object key) {
+        return get(key) != null;
+    }
+
+    /**
+     * Returns the value to which this map maps the specified key.
+     * Returns null if the map contains no mapping for this key.
+     */
+    @Override
+    public Object get(final Object key) {
+        if (key instanceof String) {
+            final String s = ((String) key).trim();
+            for (int i=0; i<KEYS.length; i++) {
+                if (KEYS[i].equalsIgnoreCase(s)) {
+                    return get(i);
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the value to which this map maps the specified index.
+     * Returns null if the map contains no mapping for this index.
+     */
+    private Object get(final int key) {
+        switch (key) {
+            case 0: return info.getName();
+            case 1: return info.getIdentifiers().toArray(AbstractIdentifiedObject.EMPTY_IDENTIFIER_ARRAY);
+            case 2: return info.getAlias().toArray(AbstractIdentifiedObject.EMPTY_ALIAS_ARRAY);
+            case 3: return info.getRemarks();
+            case 4: {
+                if (info instanceof ReferenceSystem) {
+                    return ((ReferenceSystem) info).getScope();
+                } else if (info instanceof Datum) {
+                    return ((Datum) info).getScope();
+                } else if (info instanceof CoordinateOperation) {
+                    return ((CoordinateOperation) info).getScope();
+                }
+                break;
+            }
+            case 5: {
+                if (info instanceof ReferenceSystem) {
+                    return ((ReferenceSystem) info).getDomainOfValidity();
+                } else if (info instanceof Datum) {
+                    return ((Datum) info).getDomainOfValidity();
+                } else if (info instanceof CoordinateOperation) {
+                    return ((CoordinateOperation) info).getDomainOfValidity();
+                }
+                break;
+            }
+            case 6: {
+                if (info instanceof CoordinateOperation) {
+                    return ((CoordinateOperation) info).getOperationVersion();
+                }
+                break;
+            }
+            case 7: {
+                if (info instanceof CoordinateOperation) {
+                    return ((CoordinateOperation) info).getCoordinateOperationAccuracy()
+                            .toArray(AbstractCoordinateOperation.EMPTY_ACCURACY_ARRAY);
+                }
+                break;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * The keys to search for. <STRONG>The index of each element in this array
+     * must matches the index searched by {@link #get(int)}.</STRONG>
+     *
+     * @todo Add properties for {@link IdentifiedObject} sub-interfaces.
+     */
+    private static final String[] KEYS = {
+        /*[0]*/IdentifiedObject    .NAME_KEY,
+        /*[1]*/IdentifiedObject    .IDENTIFIERS_KEY,
+        /*[2]*/IdentifiedObject    .ALIAS_KEY,
+        /*[3]*/IdentifiedObject    .REMARKS_KEY,
+        /*[4]*/CoordinateOperation .SCOPE_KEY,              // same in Datum and ReferenceSystem
+        /*[5]*/CoordinateOperation .DOMAIN_OF_VALIDITY_KEY, // same in Datum and ReferenceSystem
+        /*[6]*/CoordinateOperation .OPERATION_VERSION_KEY,
+        /*[7]*/CoordinateOperation .COORDINATE_OPERATION_ACCURACY_KEY
+    };
+
+    /**
+     * Returns a set view of the mappings contained in this map.
+     */
+    @Override
+    public Set<Entry<String,Object>> entrySet() {
+        if (entries == null) {
+            entries = new HashSet<Entry<String,Object>>(Math.round(KEYS.length / 0.75f) + 1, 0.75f);
+            for (int i=0; i<KEYS.length; i++) {
+                final Object value = get(i);
+                if (value != null) {
+                    entries.add(new MapEntry<String,Object>(KEYS[i], value));
+                }
+            }
+            entries = Collections.unmodifiableSet(entries);
+        }
+        return entries;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/ReferencingFactoryFinder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/ReferencingFactoryFinder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/ReferencingFactoryFinder.java	(revision 28000)
@@ -0,0 +1,336 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing;
+
+import java.util.Set;
+
+import javax.imageio.spi.ServiceRegistry;
+
+import org.geotools.factory.FactoryCreator;
+import org.geotools.factory.FactoryFinder;
+import org.geotools.factory.FactoryRegistry;
+import org.geotools.factory.FactoryRegistryException;
+import org.geotools.factory.Hints;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.resources.LazySet;
+import org.opengis.referencing.AuthorityFactory;
+import org.opengis.referencing.Factory;
+import org.opengis.referencing.crs.CRSAuthorityFactory;
+import org.opengis.referencing.crs.CRSFactory;
+import org.opengis.referencing.cs.CSAuthorityFactory;
+import org.opengis.referencing.cs.CSFactory;
+import org.opengis.referencing.datum.DatumAuthorityFactory;
+import org.opengis.referencing.datum.DatumFactory;
+import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
+import org.opengis.referencing.operation.CoordinateOperationFactory;
+import org.opengis.referencing.operation.MathTransformFactory;
+
+
+/**
+ * Defines static methods used to access the application's default {@linkplain Factory
+ * factory} implementation.
+ *
+ * <P>To declare a factory implementation, a services subdirectory is placed within the
+ * {@code META-INF} directory that is present in every JAR file. This directory
+ * contains a file for each factory interface that has one or more implementation classes
+ * present in the JAR file. For example, if the JAR file contained a class named
+ * {@code com.mycompany.DatumFactoryImpl} which implements the {@link DatumFactory}
+ * interface, the JAR file would contain a file named:</P>
+ *
+ * <blockquote><pre>META-INF/services/org.opengis.referencing.datum.DatumFactory</pre></blockquote>
+ *
+ * <P>containing the line:</P>
+ *
+ * <blockquote><pre>com.mycompany.DatumFactoryImpl</pre></blockquote>
+ *
+ * <P>If the factory classes implements {@link javax.imageio.spi.RegisterableService}, it will
+ * be notified upon registration and deregistration. Note that the factory classes should be
+ * lightweight and quick to load. Implementations of these interfaces should avoid complex
+ * dependencies on other classes and on native code. The usual pattern for more complex services
+ * is to register a lightweight proxy for the heavyweight service.</P>
+ *
+ * <H2>Note on factory ordering</H2>
+ * <P>This class is thread-safe. However, calls to any {@link #setAuthorityOrdering} or
+ * {@link #setVendorOrdering} methods have a system-wide effect. If two threads or two
+ * applications need a different ordering, they shall manage their own instance of
+ * {@link FactoryRegistry}. This {@code FactoryFinder} class is simply a convenience
+ * wrapper around a {@code FactoryRegistry} instance.</P>
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/ReferencingFactoryFinder.java $
+ * @version $Id: ReferencingFactoryFinder.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public final class ReferencingFactoryFinder extends FactoryFinder {
+    /**
+     * The service registry for this manager.
+     * Will be initialized only when first needed.
+     */
+    private static FactoryRegistry registry;
+
+    /**
+     * Do not allows any instantiation of this class.
+     */
+    private ReferencingFactoryFinder() {
+    }
+
+    /**
+     * Returns the service registry. The registry will be created the first
+     * time this method is invoked.
+     */
+    private static FactoryRegistry getServiceRegistry() {
+        assert Thread.holdsLock(ReferencingFactoryFinder.class);
+        if (registry == null) {
+            registry = new FactoryCreator(new Class<?>[] {
+                    DatumFactory.class,
+                    CSFactory.class,
+                    CRSFactory.class,
+                    DatumAuthorityFactory.class,
+                    CSAuthorityFactory.class,
+                    CRSAuthorityFactory.class,
+                    MathTransformFactory.class,
+                    CoordinateOperationFactory.class,
+                    CoordinateOperationAuthorityFactory.class});
+        }
+        return registry;
+    }
+
+    /**
+     * Returns all providers of the specified category.
+     *
+     * @param  category The factory category.
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return Set of available factory implementations.
+     */
+    private static synchronized <T extends Factory>
+            Set<T> getFactories(final Class<T> category, Hints hints)
+    {
+        hints = mergeSystemHints(hints);
+        return new LazySet<T>(getServiceRegistry().getServiceProviders(category, null, hints));
+    }
+
+    /**
+     * Returns a provider of the specified category.
+     *
+     * @param  category The factory category.
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @param  key The hint key to use for searching an implementation.
+     * @return The first factory that matches the supplied hints.
+     * @throws FactoryRegistryException if no implementation was found or can be created for the
+     *         specified interface.
+     */
+    private static synchronized <T extends Factory> T getFactory(final Class<T> category,
+            Hints hints, final Hints.Key key) throws FactoryRegistryException
+    {
+        hints = mergeSystemHints(hints);
+        return getServiceRegistry().getServiceProvider(category, null, hints, key);
+    }
+
+    /**
+     * Returns the first implementation of a factory matching the specified hints. If no
+     * implementation matches, a new one is created if possible or an exception is thrown
+     * otherwise. If more than one implementation is registered and an
+     * {@linkplain #setVendorOrdering ordering is set}, then the preferred
+     * implementation is returned. Otherwise an arbitrary one is selected.
+     *
+     * @param  category  The authority factory type.
+     * @param  authority The desired authority (e.g. "EPSG").
+     * @param  hints     An optional map of hints, or {@code null} if none.
+     * @param  key       The hint key to use for searching an implementation.
+     * @return The first authority factory that matches the supplied hints.
+     * @throws FactoryRegistryException if no implementation was found or can be created for the
+     *         specfied interface.
+     */
+    private static synchronized <T extends AuthorityFactory> T getAuthorityFactory(
+            final Class<T> category, final String authority, Hints hints, final Hints.Key key)
+            throws FactoryRegistryException
+    {
+        hints = mergeSystemHints(hints);
+        return getServiceRegistry().getServiceProvider(category, new AuthorityFilter(authority), hints, key);
+    }
+
+    /**
+     * Returns the first implementation of {@link DatumFactory} matching the specified hints.
+     * If no implementation matches, a new one is created if possible or an exception is thrown
+     * otherwise. If more than one implementation is registered and an
+     * {@linkplain #setVendorOrdering ordering is set}, then the preferred
+     * implementation is returned. Otherwise an arbitrary one is selected.
+     *
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return The first datum factory that matches the supplied hints.
+     * @throws FactoryRegistryException if no implementation was found or can be created for the
+     *         {@link DatumFactory} interface.
+     */
+    public static DatumFactory getDatumFactory(final Hints hints) throws FactoryRegistryException {
+        return getFactory(DatumFactory.class, hints, Hints.DATUM_FACTORY);
+    }
+
+    /**
+     * Returns a set of all available implementations for the {@link DatumFactory} interface.
+     *
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return Set of available datum factory implementations.
+     */
+    public static Set<DatumFactory> getDatumFactories(final Hints hints) {
+        return getFactories(DatumFactory.class, hints);
+    }
+
+    /**
+     * Returns the first implementation of {@link CSFactory} matching the specified hints.
+     * If no implementation matches, a new one is created if possible or an exception is thrown
+     * otherwise. If more than one implementation is registered and an
+     * {@linkplain #setVendorOrdering ordering is set}, then the preferred
+     * implementation is returned. Otherwise an arbitrary one is selected.
+     *
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return The first coordinate system factory that matches the supplied hints.
+     * @throws FactoryRegistryException if no implementation was found or can be created for the
+     *         {@link CSFactory} interface.
+     */
+    public static CSFactory getCSFactory(final Hints hints) throws FactoryRegistryException {
+        return getFactory(CSFactory.class, hints, Hints.CS_FACTORY);
+    }
+
+    /**
+     * Returns the first implementation of {@link CRSFactory} matching the specified hints.
+     * If no implementation matches, a new one is created if possible or an exception is thrown
+     * otherwise. If more than one implementation is registered and an
+     * {@linkplain #setVendorOrdering ordering is set}, then the preferred
+     * implementation is returned. Otherwise an arbitrary one is selected.
+     *
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return The first coordinate reference system factory that matches the supplied hints.
+     * @throws FactoryRegistryException if no implementation was found or can be created for the
+     *         {@link CRSFactory} interface.
+     */
+    public static CRSFactory getCRSFactory(final Hints hints) throws FactoryRegistryException {
+        return getFactory(CRSFactory.class, hints, Hints.CRS_FACTORY);
+    }
+
+    /**
+     * Returns the first implementation of {@link CoordinateOperationFactory} matching the specified
+     * hints. If no implementation matches, a new one is created if possible or an exception is
+     * thrown otherwise. If more than one implementation is registered and an
+     * {@linkplain #setVendorOrdering ordering is set}, then the preferred
+     * implementation is returned. Otherwise an arbitrary one is selected.
+     * <p>
+     * Hints that may be understood includes
+     * {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM_FACTORY},
+     * {@link Hints#DATUM_SHIFT_METHOD     DATUM_SHIFT_METHOD},
+     * {@link Hints#LENIENT_DATUM_SHIFT    LENIENT_DATUM_SHIFT} and
+     * {@link Hints#VERSION                VERSION}.
+     *
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return The first coordinate operation factory that matches the supplied hints.
+     * @throws FactoryRegistryException if no implementation was found or can be created for the
+     *         {@link CoordinateOperationFactory} interface.
+     */
+    public static CoordinateOperationFactory getCoordinateOperationFactory(final Hints hints)
+            throws FactoryRegistryException
+    {
+        return getFactory(CoordinateOperationFactory.class, hints,
+                Hints.COORDINATE_OPERATION_FACTORY);
+    }
+
+    /**
+     * Returns a set of all available implementations for the
+     * {@link CoordinateOperationFactory} interface.
+     *
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return Set of available coordinate operation factory implementations.
+     */
+    public static Set<CoordinateOperationFactory> getCoordinateOperationFactories(final Hints hints) {
+        return getFactories(CoordinateOperationFactory.class, hints);
+    }
+
+    /**
+     * Returns a set of all available implementations for the {@link CRSAuthorityFactory} interface.
+     * This set can be used to list the available codes known to all authorities.
+     * In the event that the same code is understood by more then one authority
+     * you will need to assume both are close enough, or make use of this set directly
+     * rather than use the {@link CRS#decode} convenience method.
+     *
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return Set of available coordinate reference system authority factory implementations.
+     */
+    public static Set<CRSAuthorityFactory> getCRSAuthorityFactories(final Hints hints) {
+        return getFactories(CRSAuthorityFactory.class, hints);
+    }
+
+    /**
+     * Returns the first implementation of {@link CoordinateOperationAuthorityFactory} matching
+     * the specified hints. If no implementation matches, a new one is created if possible or an
+     * exception is thrown otherwise. If more than one implementation is registered and an
+     * {@linkplain #setVendorOrdering ordering is set}, then the preferred
+     * implementation is returned. Otherwise an arbitrary one is selected.
+     *
+     * @param  authority The desired authority (e.g. "EPSG").
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return The first coordinate operation authority factory that matches the supplied hints.
+     * @throws FactoryRegistryException if no implementation was found or can be created for the
+     *         {@link CoordinateOperationAuthorityFactory} interface.
+     */
+    public static CoordinateOperationAuthorityFactory getCoordinateOperationAuthorityFactory(
+            final String authority, final Hints hints)
+            throws FactoryRegistryException
+    {
+        return getAuthorityFactory(CoordinateOperationAuthorityFactory.class, authority, hints,
+                Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY);
+    }
+
+    /**
+     * Returns the first implementation of {@link MathTransformFactory} matching the specified
+     * hints. If no implementation matches, a new one is created if possible or an exception is
+     * thrown otherwise. If more than one implementation is registered and an
+     * {@linkplain #setVendorOrdering ordering is set}, then the preferred
+     * implementation is returned. Otherwise an arbitrary one is selected.
+     *
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return The first math transform factory that matches the supplied hints.
+     * @throws FactoryRegistryException if no implementation was found or can be created for the
+     *         {@link MathTransformFactory} interface.
+     */
+    public static MathTransformFactory getMathTransformFactory(final Hints hints)
+            throws FactoryRegistryException
+    {
+        return getFactory(MathTransformFactory.class, hints, Hints.MATH_TRANSFORM_FACTORY);
+    }
+
+    /**
+     * A filter for factories provided for a given authority.
+     */
+    private static final class AuthorityFilter implements ServiceRegistry.Filter {
+        /** The authority to filter. */
+        private final String authority;
+
+        /** Constructs a filter for the given authority. */
+        public AuthorityFilter(final String authority) {
+            this.authority = authority;
+        }
+
+        /** Returns {@code true} if the specified provider is for the authority. */
+        public boolean filter(final Object provider) {
+            if (authority == null) {
+                // If the user didn't specified an authority name, then the factory to use must
+                // be specified explicitly through a hint (e.g. Hints.CRS_AUTHORITY_FACTORY).
+                return false;
+            }
+            return Citations.identifierMatches(((AuthorityFactory)provider).getAuthority(), authority);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/AbstractCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/AbstractCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/AbstractCRS.java	(revision 28000)
@@ -0,0 +1,130 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.crs;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.AbstractReferenceSystem;
+import org.geotools.referencing.cs.AbstractCS;
+import org.geotools.resources.i18n.Vocabulary;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * Abstract coordinate reference system, usually defined by a coordinate system and a datum.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/crs/AbstractCRS.java $
+ * @version $Id: AbstractCRS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see AbstractCS
+ * @see org.geotools.referencing.datum.AbstractDatum
+ * @tutorial http://docs.codehaus.org/display/GEOTOOLS/Coordinate+Transformation+Services+for+Geotools+2.1
+ */
+public abstract class AbstractCRS extends AbstractReferenceSystem implements CoordinateReferenceSystem {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -7433284548909530047L;
+
+    /**
+     * The coordinate system.
+     */
+    protected final CoordinateSystem coordinateSystem;
+
+    /**
+     * Constructs a coordinate reference system from a set of properties. The properties are given
+     * unchanged to the {@linkplain AbstractReferenceSystem#AbstractReferenceSystem(Map) super-class
+     * constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param cs The coordinate system.
+     */
+    public AbstractCRS(final Map<String,?> properties, final CoordinateSystem cs) {
+        super(properties);
+        ensureNonNull("cs", cs);
+        this.coordinateSystem = cs;
+    }
+
+    /**
+     * Creates a name for the predefined constants in subclasses. The name is an unlocalized String
+     * object. However, since this method is used for creation of convenience objects only (not for
+     * objects created from an "official" database), the "unlocalized" name is actually choosen
+     * according the user's locale at class initialization time. The same name is also added in
+     * a localizable form as an alias. Since the {@link #nameMatches} convenience method checks
+     * the alias, it still possible to consider two objects are equivalent even if their names
+     * were formatted in different locales.
+     */
+    static Map<String,?> name(final int key) {
+        final Map<String,Object> properties = new HashMap<String,Object>(4);
+        final InternationalString name = Vocabulary.formatInternational(key);
+        properties.put(NAME_KEY,  name.toString());
+        properties.put(ALIAS_KEY, name);
+        return properties;
+    }
+
+    /**
+     * Returns the coordinate system.
+     */
+    public CoordinateSystem getCoordinateSystem() {
+        return coordinateSystem;
+    }
+
+    /**
+     * Compare this coordinate reference system with the specified object for equality.
+     * If {@code compareMetadata} is {@code true}, then all available properties are
+     * compared including {@linkplain #getValidArea valid area} and {@linkplain #getScope scope}.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (super.equals(object, compareMetadata)) {
+            final AbstractCRS that = (AbstractCRS) object;
+            return equals(this.coordinateSystem, that.coordinateSystem, compareMetadata);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this CRS. {@linkplain #getName Name},
+     * {@linkplain #getIdentifiers identifiers} and {@linkplain #getRemarks remarks}
+     * are not taken in account. In other words, two CRS objects will return the same
+     * hash value if they are equal in the sense of
+     * <code>{@link #equals(AbstractIdentifiedObject,boolean) equals}(AbstractIdentifiedObject,
+     * <strong>false</strong>)</code>.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ coordinateSystem.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/AbstractDerivedCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/AbstractDerivedCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/AbstractDerivedCRS.java	(revision 28000)
@@ -0,0 +1,297 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.crs;
+
+import java.util.Map;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.operation.DefaultConversion;
+import org.geotools.referencing.operation.DefaultOperation;
+import org.geotools.referencing.operation.DefaultOperationMethod;
+import org.geotools.referencing.operation.DefiningConversion;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.GeneralDerivedCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.crs.SingleCRS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.datum.Datum;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.Projection;
+
+
+/**
+ * A coordinate reference system that is defined by its coordinate
+ * {@linkplain Conversion conversion} from another coordinate reference system
+ * (not by a {@linkplain Datum datum}).
+ * <p>
+ * This class is conceptually <cite>abstract</cite>, even if it is technically possible to
+ * instantiate it. Typical applications should create instances of the most specific subclass with
+ * {@code Default} prefix instead. An exception to this rule may occurs when it is not possible to
+ * identify the exact type.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/crs/AbstractDerivedCRS.java $
+ * @version $Id: AbstractDerivedCRS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class AbstractDerivedCRS extends AbstractSingleCRS implements GeneralDerivedCRS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -175151161496419854L;
+
+    /**
+     * Key for the <code>{@value}</code> property to be given to the constructor. The value should
+     * be one of <code>{@linkplain org.opengis.referencing.operation.PlanarProjection}.class</code>,
+     * <code>{@linkplain org.opengis.referencing.operation.CylindricalProjection}.class</code> or
+     * <code>{@linkplain org.opengis.referencing.operation.ConicProjection}.class</code>.
+     * <p>
+     * This is a Geotools specific property used as a hint for creating a {@linkplain Projection
+     * projection} of proper type from a {@linkplain DefiningConversion defining conversion}. In
+     * many cases, this hint is not needed since Geotools is often capable to infer it. This hint is
+     * used mostly by advanced factories like the {@linkplain org.geotools.referencing.factory.epsg
+     * EPSG backed} one.
+     *
+     * @see DefaultConversion#create
+     *
+     * @since 2.4
+     */
+    public static final String CONVERSION_TYPE_KEY = "conversionType";
+
+    /**
+     * A lock for avoiding never-ending recursivity in the {@code equals} method. This field
+     * contains a {@code boolean} flag set to {@code true} when a comparaison is in progress.
+     * This lock is necessary because {@code AbstractDerivedCRS} objects contain a
+     * {@link #conversionFromBase} field, which contains a {@link DefaultConversion#targetCRS}
+     * field set to this {@code AbstractDerivedCRS} object.
+     * <P>
+     * <STRONG>DO NOT USE THIS FIELD. It is strictly for internal use by {@link #equals} and
+     * {@link org.geotools.referencing.operation.AbstractCoordinateOperation#equals} methods.</STRONG>
+     *
+     * @todo Hide this field from the javadoc. It is not possible to make it package-privated
+     *       because {@link org.geotools.referencing.operation.AbstractCoordinateOperation}
+     *       lives in a different package.
+     */
+    public static final ThreadLocal<Boolean> _COMPARING = new ThreadLocal<Boolean>();
+
+    /**
+     * The base coordinate reference system.
+     */
+    protected final CoordinateReferenceSystem baseCRS;
+
+    /**
+     * The conversion from the {@linkplain #getBaseCRS base CRS} to this CRS.
+     */
+    protected final Conversion conversionFromBase;
+
+    /**
+     * Constructs a derived CRS from a {@linkplain DefiningConversion defining conversion}.
+     * The properties are given unchanged to the
+     * {@linkplain org.geotools.referencing.AbstractReferenceSystem#AbstractReferenceSystem(Map)
+     * super-class constructor}.
+     *
+     * @param  properties Name and other properties to give to the new derived CRS object.
+     * @param  conversionFromBase The {@linkplain DefiningConversion defining conversion}.
+     * @param  base Coordinate reference system to base the derived CRS on.
+     * @param  baseToDerived The transform from the base CRS to returned CRS.
+     * @param  derivedCS The coordinate system for the derived CRS. The number
+     *         of axes must match the target dimension of the transform
+     *         {@code baseToDerived}.
+     * @throws MismatchedDimensionException if the source and target dimension of
+     *         {@code baseToDerived} don't match the dimension of {@code base}
+     *         and {@code derivedCS} respectively.
+     */
+    protected AbstractDerivedCRS(final Map<String,?>       properties,
+                                 final Conversion  conversionFromBase,
+                                 final CoordinateReferenceSystem base,
+                                 final MathTransform    baseToDerived,
+                                 final CoordinateSystem     derivedCS)
+            throws MismatchedDimensionException
+    {
+        super(properties, getDatum(base), derivedCS);
+        ensureNonNull("conversionFromBase", conversionFromBase);
+        ensureNonNull("baseToDerived",      baseToDerived);
+        this.baseCRS = base;
+        checkDimensions(base, baseToDerived, derivedCS);
+        DefaultOperationMethod.checkDimensions(conversionFromBase.getMethod(), baseToDerived);
+        final Class<?> c = (Class<?>) properties.get(CONVERSION_TYPE_KEY);
+        Class<? extends Conversion> typeHint = getConversionType();
+        if (c != null) {
+            typeHint = c.asSubclass(typeHint);
+        }
+        this.conversionFromBase = DefaultConversion.create(
+            /* definition */ conversionFromBase,
+            /* sourceCRS  */ base,
+            /* targetCRS  */ this,
+            /* transform  */ baseToDerived,
+            /* typeHints  */ typeHint);
+    }
+
+    /**
+     * @deprecated Create explicitly a {@link DefiningConversion} instead.
+     *
+     * @todo Move the implementation in the previous constructor after we removed the deprecated
+     *       signature.
+     */
+    AbstractDerivedCRS(final Map<String,?>       properties,
+                       final OperationMethod         method,
+                       final CoordinateReferenceSystem base,
+                       final MathTransform    baseToDerived,
+                       final CoordinateSystem     derivedCS)
+            throws MismatchedDimensionException
+    {
+        super(properties, getDatum(base), derivedCS);
+        ensureNonNull("method",        method);
+        ensureNonNull("baseToDerived", baseToDerived);
+        this.baseCRS = base;
+        /*
+         * A method was explicitly specified. Make sure that the source and target
+         * dimensions match. We do not check parameters in current version of this
+         * implementation (we may add this check in a future version), since the
+         * descriptors provided in this user-supplied OperationMethod may be more
+         * accurate than the one inferred from the MathTransform.
+         */
+        checkDimensions(base, baseToDerived, derivedCS);
+        DefaultOperationMethod.checkDimensions(method, baseToDerived);
+        this.conversionFromBase = (Conversion) DefaultOperation.create(
+            /* properties */ new UnprefixedMap(properties, "conversion."),
+            /* sourceCRS  */ base,
+            /* targetCRS  */ this,
+            /* transform  */ baseToDerived,
+            /* method     */ method,
+            /* type       */ (this instanceof ProjectedCRS) ? Projection.class : Conversion.class);
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     *
+     * @todo What to do if {@code base} is not an instance of {@link SingleCRS}?
+     */
+    private static Datum getDatum(final CoordinateReferenceSystem base) {
+        ensureNonNull("base",  base);
+        return (base instanceof SingleCRS) ? ((SingleCRS) base).getDatum() : null;
+    }
+
+    /**
+     * Checks consistency between the base CRS and the "base to derived" transform.
+     */
+    private static void checkDimensions(final CoordinateReferenceSystem base,
+                                        final MathTransform    baseToDerived,
+                                        final CoordinateSystem     derivedCS)
+            throws MismatchedDimensionException
+    {
+        final int dimSource = baseToDerived.getSourceDimensions();
+        final int dimTarget = baseToDerived.getTargetDimensions();
+        int dim1, dim2;
+        if ((dim1=dimSource) != (dim2=base.getCoordinateSystem().getDimension()) ||
+            (dim1=dimTarget) != (dim2=derivedCS.getDimension()))
+        {
+            throw new MismatchedDimensionException(Errors.format(
+                    ErrorKeys.MISMATCHED_DIMENSION_$2, dim1, dim2));
+        }
+    }
+
+    /**
+     * Returns the base coordinate reference system.
+     *
+     * @return The base coordinate reference system.
+     */
+    public CoordinateReferenceSystem getBaseCRS() {
+        return baseCRS;
+    }
+
+    /**
+     * Returns the conversion from the {@linkplain #getBaseCRS base CRS} to this CRS.
+     *
+     * @return The conversion to this CRS.
+     */
+    public Conversion getConversionFromBase() {
+        return conversionFromBase;
+    }
+
+    /**
+     * Returns the expected type of conversion.
+     * {@link DefaultProjectedCRS} will override this type with {@link Projection}.
+     */
+    Class<? extends Conversion> getConversionType() {
+        return Conversion.class;
+    }
+
+    /**
+     * Compare this coordinate reference system with the specified object for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            final AbstractDerivedCRS that = (AbstractDerivedCRS) object;
+            if (equals(this.baseCRS, that.baseCRS, compareMetadata)) {
+                /*
+                 * Avoid never-ending recursivity: Conversion has a 'targetCRS' field (inherited from
+                 * the AbstractCoordinateOperation super-class) that is set to this AbstractDerivedCRS.
+                 */
+                final Boolean comparing = _COMPARING.get();
+                if (comparing!=null && comparing.booleanValue()) {
+                    return true;
+                }
+                try {
+                    _COMPARING.set(Boolean.TRUE);
+                    return equals(this.conversionFromBase,
+                                  that.conversionFromBase,
+                                  compareMetadata);
+                } finally {
+                    _COMPARING.remove();
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this derived CRS.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        /*
+         * Do not invoke 'conversionFromBase.hashCode()' in order to avoid a never-ending loop.
+         * This is because Conversion has a 'sourceCRS' field (in the AbstractCoordinateOperation
+         * super-class), which is set to this AbstractDerivedCRS. Checking the identifier should
+         * be enough.
+         */
+        return (int)serialVersionUID ^ baseCRS.hashCode() ^ conversionFromBase.getName().hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/AbstractSingleCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/AbstractSingleCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/AbstractSingleCRS.java	(revision 28000)
@@ -0,0 +1,134 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.crs;
+
+import java.util.Map;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.opengis.referencing.crs.SingleCRS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.datum.Datum;
+
+
+/**
+ * Abstract coordinate reference system, consisting of a single
+ * {@linkplain CoordinateSystem coordinate system} and a single
+ * {@linkplain Datum datum} (as opposed to {@linkplain DefaultCompoundCRS compound CRS}).
+ * <p>
+ * A coordinate reference system consists of an ordered sequence of coordinate system
+ * axes that are related to the earth through a datum. A coordinate reference system
+ * is defined by one datum and by one coordinate system. Most coordinate reference system
+ * do not move relative to the earth, except for engineering coordinate reference systems
+ * defined on moving platforms such as cars, ships, aircraft, and spacecraft.
+ * <p>
+ * Coordinate reference systems are commonly divided into sub-types. The common classification
+ * criterion for sub-typing of coordinate reference systems is the way in which they deal with
+ * earth curvature. This has a direct effect on the portion of the earth's surface that can be
+ * covered by that type of CRS with an acceptable degree of error. The exception to the rule is
+ * the subtype "Temporal" which has been added by analogy.
+ * <p>
+ * This class is conceptually <cite>abstract</cite>, even if it is technically possible to
+ * instantiate it. Typical applications should create instances of the most specific subclass with
+ * {@code Default} prefix instead. An exception to this rule may occurs when it is not possible to
+ * identify the exact type.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/crs/AbstractSingleCRS.java $
+ * @version $Id: AbstractSingleCRS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see org.geotools.referencing.cs.AbstractCS
+ * @see org.geotools.referencing.datum.AbstractDatum
+ */
+public class AbstractSingleCRS extends AbstractCRS implements SingleCRS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 1815712797774273L;
+
+    /**
+     * The datum.
+     */
+    protected final Datum datum;
+
+    /**
+     * Constructs a coordinate reference system from a set of properties.
+     * The properties are given unchanged to the
+     * {@linkplain org.geotools.referencing.AbstractReferenceSystem#AbstractReferenceSystem(Map)
+     * super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param datum The datum.
+     * @param cs The coordinate system.
+     */
+    public AbstractSingleCRS(final Map<String,?> properties,
+                             final Datum datum,
+                             final CoordinateSystem cs)
+    {
+        super(properties, cs);
+        this.datum = datum;
+        ensureNonNull("datum", datum);
+    }
+
+    /**
+     * Returns the datum.
+     *
+     * @return The datum.
+     */
+    public Datum getDatum() {
+        return datum;
+    }
+
+    /**
+     * Compare this coordinate reference system with the specified object for equality.
+     * If {@code compareMetadata} is {@code true}, then all available properties are
+     * compared including {@linkplain #getValidArea valid area} and {@linkplain #getScope scope}.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (super.equals(object, compareMetadata)) {
+            final AbstractSingleCRS that = (AbstractSingleCRS) object;
+            return equals(this.datum, that.datum, compareMetadata);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this CRS. {@linkplain #getName Name},
+     * {@linkplain #getIdentifiers identifiers} and {@linkplain #getRemarks remarks}
+     * are not taken in account. In other words, two CRS objects will return the same
+     * hash value if they are equal in the sense of
+     * <code>{@link #equals(AbstractIdentifiedObject,boolean) equals}(AbstractIdentifiedObject,
+     * <strong>false</strong>)</code>.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ datum.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultCompoundCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultCompoundCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultCompoundCRS.java	(revision 28000)
@@ -0,0 +1,249 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.crs;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.AbstractReferenceSystem;
+import org.geotools.referencing.cs.DefaultCompoundCS;
+import org.geotools.resources.UnmodifiableArrayList;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.CheckedCollection;
+import org.opengis.referencing.crs.CompoundCRS;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.SingleCRS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.datum.Datum;
+
+
+/**
+ * A coordinate reference system describing the position of points through two or more
+ * independent coordinate reference systems. Thus it is associated with two or more
+ * {@linkplain CoordinateSystem coordinate systems} and {@linkplain Datum datums} by
+ * defining the compound CRS as an ordered set of two or more instances of
+ * {@link CoordinateReferenceSystem}.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/crs/DefaultCompoundCRS.java $
+ * @version $Id: DefaultCompoundCRS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultCompoundCRS extends AbstractCRS implements CompoundCRS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -2656710314586929286L;
+
+    /**
+     * The coordinate reference systems in this compound CRS.
+     * May actually be a list of {@link SingleCRS}.
+     */
+    private final List<? extends CoordinateReferenceSystem> crs;
+
+    /**
+     * A decomposition of the CRS list into the single elements. Computed
+     * by {@link #getElements} on construction or deserialization.
+     */
+    private transient List<SingleCRS> singles;
+
+    /**
+     * Constructs a coordinate reference system from a set of properties.
+     * The properties are given unchanged to the
+     * {@linkplain AbstractReferenceSystem#AbstractReferenceSystem(Map) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param crs The array of coordinate reference system making this compound CRS.
+     */
+    public DefaultCompoundCRS(final Map<String,?> properties, CoordinateReferenceSystem[] crs) {
+        super(properties, createCoordinateSystem(crs));
+        this.crs = copy(Arrays.asList(crs));
+    }
+
+    /**
+     * Returns a compound coordinate system for the specified array of CRS objects.
+     * This method is a work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private static CoordinateSystem createCoordinateSystem(final CoordinateReferenceSystem[] crs) {
+        ensureNonNull("crs", crs);
+        if (crs.length < 2) {
+            throw new IllegalArgumentException(Errors.format(
+                        ErrorKeys.MISSING_PARAMETER_$1, "crs[" + crs.length + ']'));
+        }
+        final CoordinateSystem[] cs = new CoordinateSystem[crs.length];
+        for (int i=0; i<crs.length; i++) {
+            ensureNonNull("crs", crs, i);
+            cs[i] = crs[i].getCoordinateSystem();
+        }
+        return new DefaultCompoundCS(cs);
+    }
+
+    /**
+     * Returns an unmodifiable copy of the given list. As a side effect, this method computes the
+     * {@linkplain singles} list. If it appears that the list of {@code SingleCRS} is equals to the
+     * given list, then it is returned in other to share the same list in both {@link #crs} and
+     * {@link #singles} references.
+     * <p>
+     * <strong>WARNING:</strong> this method is invoked by constructors <em>before</em>
+     * the {@linkplain #crs} field is set. Do not use this field.
+     */
+    private List<? extends CoordinateReferenceSystem> copy(
+            List<? extends CoordinateReferenceSystem> crs)
+    {
+        if (computeSingleCRS(crs)) {
+            crs = singles; // Shares the same list.
+        } else {
+            crs = UnmodifiableArrayList.wrap(crs.toArray(new CoordinateReferenceSystem[crs.size()]));
+        }
+        return crs;
+    }
+
+    /**
+     * The ordered list of coordinate reference systems.
+     *
+     * @return The coordinate reference systems as an unmodifiable list.
+     */
+    @SuppressWarnings("unchecked") // We are safe if the list is read-only.
+    public List<CoordinateReferenceSystem> getCoordinateReferenceSystems() {
+        return (List) crs;
+    }
+
+    /**
+     * Returns the ordered list of single coordinate reference systems. If this compound CRS
+     * contains other compound CRS, all of them are expanded in an array of {@code SingleCRS}
+     * objects.
+     *
+     * @return The single coordinate reference systems as an unmodifiable list.
+     */
+    public List<SingleCRS> getSingleCRS() {
+        return singles;
+    }
+
+    /**
+     * Returns the ordered list of single coordinate reference systems for the specified CRS.
+     * The specified CRS doesn't need to be a Geotools implementation.
+     *
+     * @param  crs The coordinate reference system.
+     * @return The single coordinate reference systems.
+     * @throws ClassCastException if a CRS is neither a {@link SingleCRS} or a {@link CompoundCRS}.
+     */
+    public static List<SingleCRS> getSingleCRS(final CoordinateReferenceSystem crs) {
+        final List<SingleCRS> singles;
+        if (crs instanceof DefaultCompoundCRS) {
+            singles = ((DefaultCompoundCRS) crs).getSingleCRS();
+        } else if (crs instanceof CompoundCRS) {
+            final List<CoordinateReferenceSystem> elements =
+                ((CompoundCRS) crs).getCoordinateReferenceSystems();
+            singles = new ArrayList<SingleCRS>(elements.size());
+            getSingleCRS(elements, singles);
+        } else {
+            singles = Collections.singletonList((SingleCRS) crs);
+        }
+        return singles;
+    }
+
+    /**
+     * Recursively adds all {@link SingleCRS} in the specified list.
+     *
+     * @throws ClassCastException if a CRS is neither a {@link SingleCRS} or a {@link CompoundCRS}.
+     */
+    private static boolean getSingleCRS(
+            final List<? extends CoordinateReferenceSystem> source, final List<SingleCRS> target)
+    {
+        boolean identical = true;
+        for (final CoordinateReferenceSystem candidate : source) {
+            if (candidate instanceof CompoundCRS) {
+                getSingleCRS(((CompoundCRS) candidate).getCoordinateReferenceSystems(), target);
+                identical = false;
+            } else {
+                target.add((SingleCRS) candidate);
+            }
+        }
+        return identical;
+    }
+
+    /**
+     * Computes the {@link #singles} field from the given CRS list and returns {@code true}
+     * if it has the same content.
+     */
+    private boolean computeSingleCRS(List<? extends CoordinateReferenceSystem> crs) {
+        singles = new ArrayList<SingleCRS>(crs.size());
+        final boolean identical = getSingleCRS(crs, singles);
+        singles = UnmodifiableArrayList.wrap(singles.toArray(new SingleCRS[singles.size()]));
+        return identical;
+    }
+
+    /**
+     * Computes the single CRS on deserialization.
+     */
+    @SuppressWarnings("unchecked")
+    private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+        if (crs instanceof CheckedCollection) {
+            final Class<?> type = ((CheckedCollection) crs).getElementType();
+            if (SingleCRS.class.isAssignableFrom(type)) {
+                singles = (List) crs;
+                return;
+            }
+        }
+        computeSingleCRS(crs);
+    }
+
+    /**
+     * Compares this coordinate reference system with the specified object for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            final DefaultCompoundCRS that = (DefaultCompoundCRS) object;
+            return equals(this.crs, that.crs, compareMetadata);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this compound CRS.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        // Don't call superclass method since 'coordinateSystem' and 'datum' may be null.
+        return crs.hashCode() ^ (int)serialVersionUID;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultDerivedCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultDerivedCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultDerivedCRS.java	(revision 28000)
@@ -0,0 +1,87 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.crs;
+
+import java.util.Map;
+
+import org.geotools.referencing.operation.DefiningConversion;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.DerivedCRS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+
+
+/**
+ * A coordinate reference system that is defined by its coordinate conversion from another
+ * coordinate reference system but is not a projected coordinate reference system. This
+ * category includes coordinate reference systems derived from a projected coordinate
+ * reference system.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/crs/DefaultDerivedCRS.java $
+ * @version $Id: DefaultDerivedCRS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultDerivedCRS extends AbstractDerivedCRS implements DerivedCRS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -8149602276542469876L;
+
+    /**
+     * Constructs a derived CRS from a {@linkplain DefiningConversion defining conversion}. The
+     * properties are given unchanged to the {@linkplain AbstractDerivedCRS#AbstractDerivedCRS(Map,
+     * Conversion, CoordinateReferenceSystem, MathTransform, CoordinateSystem) super-class constructor}.
+     *
+     * @param  properties Name and other properties to give to the new derived CRS object.
+     * @param  conversionFromBase The {@linkplain DefiningConversion defining conversion}.
+     * @param  base Coordinate reference system to base the derived CRS on.
+     * @param  baseToDerived The transform from the base CRS to returned CRS.
+     * @param  derivedCS The coordinate system for the derived CRS. The number
+     *         of axes must match the target dimension of the transform
+     *         {@code baseToDerived}.
+     * @throws MismatchedDimensionException if the source and target dimension of
+     *         {@code baseToDerived} don't match the dimension of {@code base}
+     *         and {@code derivedCS} respectively.
+     */
+    public DefaultDerivedCRS(final Map<String,?>       properties,
+                             final Conversion  conversionFromBase,
+                             final CoordinateReferenceSystem base,
+                             final MathTransform    baseToDerived,
+                             final CoordinateSystem     derivedCS)
+            throws MismatchedDimensionException
+    {
+        super(properties, conversionFromBase, base, baseToDerived, derivedCS);
+    }
+
+    /**
+     * Returns a hash value for this derived CRS.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ super.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultEngineeringCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultEngineeringCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultEngineeringCRS.java	(revision 28000)
@@ -0,0 +1,166 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.crs;
+
+import java.util.Map;
+
+import javax.measure.unit.SI;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.AbstractReferenceSystem;
+import org.geotools.referencing.cs.DefaultCartesianCS;
+import org.geotools.referencing.cs.DefaultCoordinateSystemAxis;
+import org.geotools.referencing.datum.DefaultEngineeringDatum;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.geotools.util.Utilities;
+import org.opengis.referencing.crs.EngineeringCRS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.datum.EngineeringDatum;
+
+
+/**
+ * A contextually local coordinate reference system. It can be divided into two broad categories:
+ * <ul>
+ *   <li>earth-fixed systems applied to engineering activities on or near the surface of the
+ *       earth;</li>
+ *   <li>CRSs on moving platforms such as road vehicles, vessels, aircraft, or spacecraft.</li>
+ * </ul>
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.cs.CartesianCS    Cartesian},
+ *   {@link org.opengis.referencing.cs.AffineCS       Affine},
+ *   {@link org.opengis.referencing.cs.EllipsoidalCS  Ellipsoidal},
+ *   {@link org.opengis.referencing.cs.SphericalCS    Spherical},
+ *   {@link org.opengis.referencing.cs.CylindricalCS  Cylindrical},
+ *   {@link org.opengis.referencing.cs.PolarCS        Polar},
+ *   {@link org.opengis.referencing.cs.VerticalCS     Vertical},
+ *   {@link org.opengis.referencing.cs.LinearCS       Linear}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/crs/DefaultEngineeringCRS.java $
+ * @version $Id: DefaultEngineeringCRS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultEngineeringCRS extends AbstractSingleCRS implements EngineeringCRS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 6695541732063382701L;
+
+    /**
+     * A cartesian local coordinate system.
+     */
+    private static final class Cartesian extends DefaultEngineeringCRS {
+        /** Serial number for interoperability with different versions. */
+        private static final long serialVersionUID = -1773381554353809683L;
+
+        /** Constructs a coordinate system with the given name. */
+        public Cartesian(final int key, final CoordinateSystem cs) {
+            super(name(key), DefaultEngineeringDatum.UNKNOW, cs);
+        }
+
+        /**
+         * Compares the specified object to this CRS for equality. This method is overridden
+         * because, otherwise, {@code CARTESIAN_xD} and {@code GENERIC_xD} would be considered
+         * equals when metadata are ignored.
+         */
+        @Override
+        public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+            if (super.equals(object, compareMetadata)) {
+                if (compareMetadata) {
+                    // No need to performs the check below if metadata were already compared.
+                    return true;
+                }
+                final Cartesian that = (Cartesian) object;
+                return Utilities.equals(this.getName().getCode(), that.getName().getCode());
+            }
+            return false;
+        }
+    }
+
+    /**
+     * A two-dimensional wildcard coordinate system with
+     * {@linkplain DefaultCoordinateSystemAxis#X x},
+     * {@linkplain DefaultCoordinateSystemAxis#Y y}
+     * axis in {@linkplain SI#METER metres}. At the difference of {@link #CARTESIAN_2D},
+     * this coordinate system is treated specially by the default {@linkplain
+     * org.geotools.referencing.operation.DefaultCoordinateOperationFactory coordinate operation
+     * factory} with loose transformation rules: if no transformation path were found (for example
+     * through a {@linkplain DefaultDerivedCRS derived CRS}), then the transformation from this
+     * CRS to any CRS with a compatible number of dimensions is assumed to be the identity
+     * transform. This CRS is usefull as a kind of wildcard when no CRS were explicitly specified.
+     */
+    public static final DefaultEngineeringCRS GENERIC_2D =
+            new Cartesian(VocabularyKeys.GENERIC_CARTESIAN_2D, DefaultCartesianCS.GENERIC_2D);
+
+    /**
+     * A three-dimensional wildcard coordinate system with
+     * {@linkplain DefaultCoordinateSystemAxis#X x},
+     * {@linkplain DefaultCoordinateSystemAxis#Y y},
+     * {@linkplain DefaultCoordinateSystemAxis#Z z}
+     * axis in {@linkplain SI#METER metres}. At the difference of {@link #CARTESIAN_3D},
+     * this coordinate system is treated specially by the default {@linkplain
+     * org.geotools.referencing.operation.DefaultCoordinateOperationFactory coordinate operation
+     * factory} with loose transformation rules: if no transformation path were found (for example
+     * through a {@linkplain DefaultDerivedCRS derived CRS}), then the transformation from this
+     * CRS to any CRS with a compatible number of dimensions is assumed to be the identity
+     * transform. This CRS is usefull as a kind of wildcard when no CRS were explicitly specified.
+     */
+    public static final DefaultEngineeringCRS GENERIC_3D =
+            new Cartesian(VocabularyKeys.GENERIC_CARTESIAN_3D, DefaultCartesianCS.GENERIC_3D);
+
+    /**
+     * Constructs an engineering CRS from a set of properties. The properties are given unchanged to
+     * the {@linkplain AbstractReferenceSystem#AbstractReferenceSystem(Map) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param datum The datum.
+     * @param cs The coordinate system.
+     */
+    public DefaultEngineeringCRS(final Map<String,?> properties,
+                                 final EngineeringDatum   datum,
+                                 final CoordinateSystem      cs)
+    {
+        super(properties, datum, cs);
+    }
+
+    /**
+     * Returns the datum.
+     */
+    @Override
+    public EngineeringDatum getDatum() {
+        return (EngineeringDatum) super.getDatum();
+    }
+
+    /**
+     * Returns a hash value for this derived CRS.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ super.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultGeocentricCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultGeocentricCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultGeocentricCRS.java	(revision 28000)
@@ -0,0 +1,104 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.crs;
+
+import java.util.Map;
+
+import org.geotools.referencing.AbstractReferenceSystem;
+import org.opengis.referencing.crs.GeocentricCRS;
+import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.cs.SphericalCS;
+import org.opengis.referencing.datum.GeodeticDatum;
+
+
+/**
+ * A 3D coordinate reference system with the origin at the approximate centre of mass of the earth.
+ * A geocentric CRS deals with the earth's curvature by taking a 3D spatial view, which obviates
+ * the need to model the earth's curvature.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link CartesianCS Cartesian},
+ *   {@link SphericalCS Spherical}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/crs/DefaultGeocentricCRS.java $
+ * @version $Id: DefaultGeocentricCRS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultGeocentricCRS extends AbstractSingleCRS implements GeocentricCRS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 6784642848287659827L;
+
+    /**
+     * Constructs a geographic CRS from a set of properties. The properties are given unchanged to
+     * the {@linkplain AbstractReferenceSystem#AbstractReferenceSystem(Map) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param datum The datum.
+     * @param cs The coordinate system.
+     */
+    public DefaultGeocentricCRS(final Map<String,?> properties,
+                                final GeodeticDatum datum,
+                                final CartesianCS   cs)
+    {
+        super(properties, datum, cs);
+    }
+
+    /**
+     * Constructs a geographic CRS from a set of properties.
+     * The properties are given unchanged to the
+     * {@linkplain AbstractReferenceSystem#AbstractReferenceSystem(Map) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param datum The datum.
+     * @param cs The coordinate system.
+     */
+    public DefaultGeocentricCRS(final Map<String,?> properties,
+                                final GeodeticDatum datum,
+                                final SphericalCS   cs)
+    {
+        super(properties, datum, cs);
+    }
+
+    /**
+     * Returns the datum.
+     */
+    @Override
+    public GeodeticDatum getDatum() {
+        return (GeodeticDatum) super.getDatum();
+    }
+
+    /**
+     * Returns a hash value for this geocentric CRS.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ super.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultGeographicCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultGeographicCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultGeographicCRS.java	(revision 28000)
@@ -0,0 +1,121 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.crs;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.geotools.metadata.iso.extent.ExtentImpl;
+import org.geotools.referencing.AbstractReferenceSystem;
+import org.geotools.referencing.cs.DefaultEllipsoidalCS;
+import org.geotools.referencing.datum.DefaultGeodeticDatum;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.cs.EllipsoidalCS;
+import org.opengis.referencing.datum.GeodeticDatum;
+
+
+/**
+ * A coordinate reference system based on an ellipsoidal approximation of the geoid; this provides
+ * an accurate representation of the geometry of geographic features for a large portion of the
+ * earth's surface.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link EllipsoidalCS Ellipsoidal}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/crs/DefaultGeographicCRS.java $
+ * @version $Id: DefaultGeographicCRS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultGeographicCRS extends AbstractSingleCRS implements GeographicCRS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 861224913438092335L;
+
+    /**
+     * A two-dimensional geographic coordinate reference system using WGS84 datum.
+     * This CRS uses (<var>longitude</var>,<var>latitude</var>) ordinates with longitude values
+     * increasing East and latitude values increasing North. Angular units are decimal degrees and
+     * prime meridian is Greenwich.
+     */
+    public static final DefaultGeographicCRS WGS84;
+
+
+    static {
+        final Map<String,Object> properties = new HashMap<String,Object>(4);
+        properties.put(NAME_KEY, "WGS84(DD)"); // Name used in WCS 1.0.
+        final String[] alias = {
+            "WGS84",
+            "WGS 84"  // EPSG name.
+        };
+        properties.put(ALIAS_KEY, alias);
+        properties.put(DOMAIN_OF_VALIDITY_KEY, ExtentImpl.WORLD);
+        WGS84    = new DefaultGeographicCRS(properties, DefaultGeodeticDatum.WGS84,
+                                            DefaultEllipsoidalCS.GEODETIC_2D);
+        alias[1] = "WGS 84 (geographic 3D)"; // Replaces the EPSG name.
+    }
+
+    /**
+     * Constructs a geographic CRS from a set of properties. The properties are given unchanged to
+     * the {@linkplain AbstractReferenceSystem#AbstractReferenceSystem(Map) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param datum The datum.
+     * @param cs The coordinate system.
+     */
+    public DefaultGeographicCRS(final Map<String,?> properties,
+                                final GeodeticDatum datum,
+                                final EllipsoidalCS cs)
+    {
+        super(properties, datum, cs);
+    }
+
+    /**
+     * Returns the coordinate system.
+     */
+    @Override
+    public EllipsoidalCS getCoordinateSystem() {
+        return (EllipsoidalCS) super.getCoordinateSystem();
+    }
+
+    /**
+     * Returns the datum.
+     */
+    @Override
+    public GeodeticDatum getDatum() {
+        return (GeodeticDatum) super.getDatum();
+    }
+
+    /**
+     * Returns a hash value for this geographic CRS.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ super.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultImageCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultImageCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultImageCRS.java	(revision 28000)
@@ -0,0 +1,96 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.crs;
+
+import java.util.Map;
+
+import org.geotools.referencing.AbstractReferenceSystem;
+import org.opengis.referencing.crs.ImageCRS;
+import org.opengis.referencing.cs.AffineCS;
+import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.datum.ImageDatum;
+
+
+/**
+ * An engineering coordinate reference system applied to locations in images. Image coordinate
+ * reference systems are treated as a separate sub-type because a separate user community exists
+ * for images with its own terms of reference.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link CartesianCS Cartesian},
+ *   {@link AffineCS    Affine}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/crs/DefaultImageCRS.java $
+ * @version $Id: DefaultImageCRS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultImageCRS extends AbstractSingleCRS implements ImageCRS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 7312452786096397847L;
+
+    /**
+     * Constructs an image CRS from a set of properties. The properties are given unchanged to
+     * the {@linkplain AbstractReferenceSystem#AbstractReferenceSystem(Map) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param datum The datum.
+     * @param cs The coordinate system.
+     */
+    public DefaultImageCRS(final Map<String,?> properties,
+                           final ImageDatum    datum,
+                           final AffineCS      cs)
+    {
+        super(properties, datum, cs);
+    }
+
+    /**
+     * Returns the coordinate system.
+     */
+    @Override
+    public AffineCS getCoordinateSystem() {
+        return (AffineCS) super.getCoordinateSystem();
+    }
+
+    /**
+     * Returns the datum.
+     */
+    @Override
+    public ImageDatum getDatum() {
+        return (ImageDatum) super.getDatum();
+    }
+
+    /**
+     * Returns a hash value for this geographic CRS.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ super.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultProjectedCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultProjectedCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultProjectedCRS.java	(revision 28000)
@@ -0,0 +1,173 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.crs;
+
+import java.util.Map;
+
+import org.geotools.referencing.operation.DefiningConversion;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.datum.GeodeticDatum;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.Projection;
+
+
+/**
+ * A 2D coordinate reference system used to approximate the shape of the earth on a planar surface.
+ * It is done in such a way that the distortion that is inherent to the approximation is carefully
+ * controlled and known. Distortion correction is commonly applied to calculated bearings and
+ * distances to produce values that are a close match to actual field values.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link CartesianCS Cartesian}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/crs/DefaultProjectedCRS.java $
+ * @version $Id: DefaultProjectedCRS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultProjectedCRS extends AbstractDerivedCRS implements ProjectedCRS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -4502680112031773028L;
+
+    /**
+     * Constructs a projected CRS from a set of properties. The properties are given unchanged
+     * to the {@linkplain AbstractDerivedCRS#AbstractDerivedCRS(Map, OperationMethod,
+     * CoordinateReferenceSystem, MathTransform, CoordinateSystem) super-class constructor}.
+     *
+     * @param  properties Name and other properties to give to the new derived CRS object and to
+     *         the underlying {@linkplain org.geotools.referencing.operation.DefaultProjection
+     *         projection}.
+     * @param  method A description of the {@linkplain Conversion#getMethod method for the
+     *         conversion}.
+     * @param  base Coordinate reference system to base the derived CRS on.
+     * @param  baseToDerived The transform from the base CRS to returned CRS.
+     * @param  derivedCS The coordinate system for the derived CRS. The number
+     *         of axes must match the target dimension of the transform
+     *         {@code baseToDerived}.
+     * @throws MismatchedDimensionException if the source and target dimension of
+     *         {@code baseToDeviced} don't match the dimension of {@code base}
+     *         and {@code derivedCS} respectively.
+     *
+     * @deprecated Create explicitly a {@link DefiningConversion} instead.
+     */
+    public DefaultProjectedCRS(final Map<String,?>    properties,
+                               final OperationMethod      method,
+                               final GeographicCRS          base,
+                               final MathTransform baseToDerived,
+                               final CartesianCS       derivedCS)
+            throws MismatchedDimensionException
+    {
+        super(properties, method, base, baseToDerived, derivedCS);
+    }
+
+    /**
+     * Constructs a projected CRS from a {@linkplain DefiningConversion defining conversion}. The
+     * properties are given unchanged to the {@linkplain AbstractDerivedCRS#AbstractDerivedCRS(Map,
+     * Conversion, CoordinateReferenceSystem, MathTransform, CoordinateSystem) super-class constructor}.
+     *
+     * @param  properties Name and other properties to give to the new projected CRS object.
+     * @param  conversionFromBase The {@linkplain DefiningConversion defining conversion}.
+     * @param  base Coordinate reference system to base the projected CRS on.
+     * @param  baseToDerived The transform from the base CRS to returned CRS.
+     * @param  derivedCS The coordinate system for the projected CRS. The number
+     *         of axes must match the target dimension of the transform
+     *         {@code baseToDerived}.
+     * @throws MismatchedDimensionException if the source and target dimension of
+     *         {@code baseToDerived} don't match the dimension of {@code base}
+     *         and {@code derivedCS} respectively.
+     */
+    public DefaultProjectedCRS(final Map<String,?>       properties,
+                               final Conversion  conversionFromBase,
+                               final GeographicCRS             base,
+                               final MathTransform    baseToDerived,
+                               final CartesianCS          derivedCS)
+            throws MismatchedDimensionException
+    {
+        super(properties, conversionFromBase, base, baseToDerived, derivedCS);
+    }
+
+    /**
+     * Returns the coordinate system.
+     */
+    @Override
+    public CartesianCS getCoordinateSystem() {
+        return (CartesianCS) super.getCoordinateSystem();
+    }
+
+    /**
+     * Returns the datum.
+     */
+    @Override
+    public GeodeticDatum getDatum() {
+        return (GeodeticDatum) super.getDatum();
+    }
+
+    /**
+     * Returns the base coordinate reference system, which must be geographic.
+     *
+     * @return The base CRS.
+     */
+    @Override
+    public GeographicCRS getBaseCRS() {
+        return (GeographicCRS) super.getBaseCRS();
+    }
+
+    /**
+     * Returns the map projection from the {@linkplain #getBaseCRS base CRS} to this CRS.
+     *
+     * @return The map projection from base CRS to this CRS.
+     */
+    @Override
+    public Projection getConversionFromBase() {
+        return (Projection) super.getConversionFromBase();
+    }
+
+    /**
+     * Returns the expected type of conversion.
+     */
+    @Override
+    Class<? extends Projection> getConversionType() {
+        return Projection.class;
+    }
+
+    /**
+     * Returns a hash value for this projected CRS.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ super.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultTemporalCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultTemporalCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultTemporalCRS.java	(revision 28000)
@@ -0,0 +1,92 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.crs;
+
+import java.util.Map;
+
+import org.geotools.referencing.AbstractReferenceSystem;
+import org.opengis.referencing.crs.TemporalCRS;
+import org.opengis.referencing.cs.TimeCS;
+import org.opengis.referencing.datum.TemporalDatum;
+
+
+/**
+ * A 1D coordinate reference system used for the recording of time.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link TimeCS Time}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/crs/DefaultTemporalCRS.java $
+ * @version $Id: DefaultTemporalCRS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultTemporalCRS extends AbstractSingleCRS implements TemporalCRS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 3000119849197222007L;
+
+    /**
+     * Constructs a temporal CRS from a set of properties. The properties are given unchanged to
+     * the {@linkplain AbstractReferenceSystem#AbstractReferenceSystem(Map) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param cs The coordinate system.
+     * @param datum The datum.
+     */
+    public DefaultTemporalCRS(final Map<String,?> properties,
+                              final TemporalDatum datum,
+                              final TimeCS        cs)
+    {
+        super(properties, datum, cs);
+    }
+
+    /**
+     * Returns the coordinate system.
+     */
+    @Override
+    public TimeCS getCoordinateSystem() {
+        return (TimeCS) super.getCoordinateSystem();
+    }
+
+    /**
+     * Returns the datum.
+     */
+    @Override
+    public TemporalDatum getDatum() {
+        return (TemporalDatum) super.getDatum();
+    }
+
+    /**
+     * Returns a hash value for this geographic CRS.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ super.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultVerticalCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultVerticalCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/DefaultVerticalCRS.java	(revision 28000)
@@ -0,0 +1,102 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.crs;
+
+import java.util.Map;
+
+import org.geotools.referencing.AbstractReferenceSystem;
+import org.opengis.referencing.crs.VerticalCRS;
+import org.opengis.referencing.cs.VerticalCS;
+import org.opengis.referencing.datum.VerticalDatum;
+
+
+/**
+ * A 1D coordinate reference system used for recording heights or depths. Vertical CRSs make use
+ * of the direction of gravity to define the concept of height or depth, but the relationship with
+ * gravity may not be straightforward.
+ * <p>
+ * By implication, ellipsoidal heights (<var>h</var>) cannot be captured in a vertical coordinate
+ * reference system. Ellipsoidal heights cannot exist independently, but only as inseparable part
+ * of a 3D coordinate tuple defined in a geographic 3D coordinate reference system. However GeoAPI
+ * does not enforce this rule. This class defines a {@link #ELLIPSOIDAL_HEIGHT} constant in
+ * violation with ISO 19111; this is considered okay if this constant is used merely as a step
+ * toward the construction of a 3D CRS (for example in a transient state during WKT parsing),
+ * or for passing arguments in methods enforcing type-safety.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link VerticalCS Vertical}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/crs/DefaultVerticalCRS.java $
+ * @version $Id: DefaultVerticalCRS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultVerticalCRS extends AbstractSingleCRS implements VerticalCRS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 3565878468719941800L;
+
+    /**
+     * Constructs a vertical CRS from a set of properties. The properties are given unchanged to
+     * the {@linkplain AbstractReferenceSystem#AbstractReferenceSystem(Map) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param datum The datum.
+     * @param cs The coordinate system.
+     */
+    public DefaultVerticalCRS(final Map<String,?> properties,
+                              final VerticalDatum datum,
+                              final VerticalCS    cs)
+    {
+        super(properties, datum, cs);
+    }
+
+    /**
+     * Returns the coordinate system.
+     */
+    @Override
+    public VerticalCS getCoordinateSystem() {
+        return (VerticalCS) super.getCoordinateSystem();
+    }
+
+    /**
+     * Returns the datum.
+     */
+    @Override
+    public VerticalDatum getDatum() {
+        return (VerticalDatum) super.getDatum();
+    }
+
+    /**
+     * Returns a hash value for this geographic CRS.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ super.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/EPSGCRSAuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/EPSGCRSAuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/EPSGCRSAuthorityFactory.java	(revision 28000)
@@ -0,0 +1,315 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.crs;
+
+// J2SE dependencies
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+// OpenGIS dependencies
+import org.opengis.metadata.citation.Citation;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.ObjectFactory;
+import org.opengis.referencing.crs.CRSAuthorityFactory;
+import org.opengis.referencing.crs.CRSFactory;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.util.InternationalString;
+
+// Geotools dependencies
+import org.geotools.util.logging.Logging;
+import org.geotools.factory.AbstractFactory;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.ReferencingFactoryFinder;
+
+/**
+ * Default implementation for a coordinate reference system authority factory backed
+ * by the EPSG property file. This gives most of the benifits of using the EPSG 
+ * database backed authority factory, in a nice, portable property file.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/epsg-wkt/src/main/java/org/geotools/referencing/crs/EPSGCRSAuthorityFactory.java $
+ * @version $Id: EPSGCRSAuthorityFactory.java 31049 2008-07-22 20:27:03Z desruisseaux $
+ * @author Jody Garnett
+ * @author Rueben Schulz
+ *
+ * @deprecated Uses one of the other EPSG factories backed by a database instead.
+ */
+//not quite sure how I am going to create a new factory (what should the geoapi method be)
+public class EPSGCRSAuthorityFactory extends AbstractFactory implements CRSAuthorityFactory {
+	
+	private static final Logger LOGGER = Logging.getLogger("org.geotools.referencing.crs.EPSGCRSAuthorityFactory");
+	
+    public static final String AUTHORITY = "EPSG";
+    public static final String AUTHORITY_PREFIX = "EPSG:";
+    //would be nice to cache crs objects for codes that have already been requested    
+    
+    /**
+     * The default coordinate system authority factory.
+     * Will be constructed only when first requested.
+     */
+    protected static EPSGCRSAuthorityFactory DEFAULT;
+    
+    /**
+     * The properties object for our properties file. Keys are the EPSG
+     * code for a coordinate reference system and the associated value is a 
+     * WKT string for the CRS.
+     */
+    protected Properties epsg = new Properties();
+    
+    //object factory
+    protected CRSFactory crsFactory;
+
+    /** Cache of parsed CoordinateReferenceSystem WKT by EPSG_NUMBER */
+    private Hashtable cache = new Hashtable();
+    
+    /**
+     * Loads from epsg.properties if the file exists, defaults to internal defintions
+     * exported from postgis and cubeworks.
+     */
+    public EPSGCRSAuthorityFactory() {
+        this(ReferencingFactoryFinder.getCRSFactory(null));
+    }
+    
+    /**
+     * Loads from epsg.properties if the file exists, defaults to internal defintions
+     * exported from postgis and cubeworks.
+     */
+    protected EPSGCRSAuthorityFactory(final CRSFactory factory ) {
+        super(MINIMUM_PRIORITY); // Select EPSG-HSQL factory first.
+        this.crsFactory = factory;
+        try {
+            loadDefault();
+        }
+        catch( IOException oops ){
+            System.err.println("Could not load epsg.properties"+ oops );
+        }
+    }
+    
+    /** 
+     *
+     */
+    protected EPSGCRSAuthorityFactory(final CRSFactory factory,
+                       	 URL definition) throws FactoryException {
+        this( factory );
+        
+        try {
+            epsg.load( definition.openStream() );
+        }
+        catch (IOException io ){
+            // could not load properties file
+            throw new FactoryException("Could not load properties file: " + definition);  
+        }
+    }
+    
+    /**
+     * Loads from epsg.properties if the file exists, defaults to internal defintions
+     * exported from postgis and cubeworks.
+     * 
+     * @throws IOException
+     */
+    protected void loadDefault() throws IOException {
+        // Check the application directory first
+        //
+        File file = new File("epsg.properties");
+        if( file.exists() ){
+            epsg.load( new FileInputStream( file ));             
+        }        
+        // Use the built-in property defintions
+        //
+        URL url = EPSGCRSAuthorityFactory.class.getResource("epsg.properties");
+        epsg.load( url.openStream() );
+    }
+           
+    public synchronized CoordinateReferenceSystem createCoordinateReferenceSystem(String code) 
+        throws FactoryException 
+    {
+        if (code == null) {
+            return null;
+        }
+        if( !code.startsWith( AUTHORITY_PREFIX )){
+            throw new NoSuchAuthorityCodeException( "This factory only understand EPSG codes", AUTHORITY, code );
+        }
+        final String EPSG_NUMBER = code.substring( code.indexOf(':')+1 ).trim();
+        
+        if( cache.containsKey( EPSG_NUMBER ) ){ 
+            Object value = cache.get( EPSG_NUMBER );
+            if( value instanceof Throwable ){
+                throw new FactoryException( "WKT for "+code+" could not be parsed", (Throwable) value );
+            }
+            if( value instanceof CoordinateReferenceSystem){
+                return (CoordinateReferenceSystem) value;
+            }            
+        }
+        String wkt = epsg.getProperty( EPSG_NUMBER );
+        if( wkt == null ) {
+            throw new NoSuchAuthorityCodeException( "Unknown EPSG_NUMBER", AUTHORITY, code );
+        }
+        if( wkt.indexOf( EPSG_NUMBER ) == -1){
+        	wkt = wkt.trim();
+        	wkt = wkt.substring(0, wkt.length()-1 );
+        	wkt += ",AUTHORITY[\"EPSG\",\""+EPSG_NUMBER+"\"]]";
+        	LOGGER.log(Level.WARNING, "EPSG:"+EPSG_NUMBER+" lacks a proper identifying authority in its Well-Known Text. It is being added programmatically.");
+        }
+        try {
+            CoordinateReferenceSystem crs = crsFactory.createFromWKT(wkt);
+            cache.put(EPSG_NUMBER, crs);
+            return crs;
+        }
+        catch (FactoryException fex) {
+            cache.put(EPSG_NUMBER, fex);
+            throw fex;
+        }        
+    }
+    
+    public IdentifiedObject createObject(String code) throws FactoryException {
+        return createCoordinateReferenceSystem(code);
+    }
+    
+    public ProjectedCRS createProjectedCRS(String code) throws FactoryException {
+        return (ProjectedCRS) createCoordinateReferenceSystem(code);
+    }
+    
+    public GeographicCRS createGeographicCRS(String code) throws FactoryException {
+         return (GeographicCRS) createCoordinateReferenceSystem(code);
+    }    
+    
+    public Citation getAuthority() {
+        return Citations.EPSG;
+    }
+    
+    /**  
+     * Returns the set of authority codes of the given type. The type  
+     * argument specify the base class. For example if this factory is 
+     * an instance of CRSAuthorityFactory, then:
+     * <ul>
+     *  <li>CoordinateReferenceSystem.class  asks for all authority codes accepted 
+     *      by createGeographicCRS, createProjectedCRS, createVerticalCRS, createTemporalCRS and their friends.</li>
+     *  <li>ProjectedCRS.class  asks only for authority codes accepted by createProjectedCRS.</li>
+     * </ul>
+     *
+     * The following implementaiton filters the set of codes based on the
+     * "PROJCS" and "GEOGCS" at the start of the WKT strings. It is assumed
+     * that we only have GeographicCRS and ProjectedCRS's here.
+     *
+     * @param clazz The spatial reference objects type (may be Object.class). 
+     * @return The set of authority codes for spatial reference objects of the given type. 
+     * If this factory doesn't contains any object of the given type, then this method returns 
+     * an empty set. 
+     * @throws FactoryException if access to the underlying database failed.
+     */
+    public Set getAuthorityCodes(Class clazz) throws FactoryException {
+        //could cashe this info if it is time consuming to filter        
+        if (clazz.getName().equalsIgnoreCase(CoordinateReferenceSystem.class.getName())) {
+            Set all= new java.util.TreeSet();
+            for(java.util.Iterator i = epsg.keySet().iterator(); i.hasNext();) {
+                String code = (String) i.next();                
+                all.add( AUTHORITY_PREFIX+code);                
+            }  
+            return all;
+        } else if (clazz.getName().equalsIgnoreCase(GeographicCRS.class.getName())) {
+            Set all = epsg.keySet();
+            Set geoCRS = new java.util.TreeSet();
+            for(java.util.Iterator i = all.iterator(); i.hasNext();) {
+                String code = (String) i.next();
+                String wkt = epsg.getProperty( code );
+                if (wkt.startsWith("GEOGCS")) {
+                    geoCRS.add( AUTHORITY_PREFIX+code);
+                }
+            }  
+            return geoCRS;
+            
+        } else if (clazz.getName().equalsIgnoreCase(ProjectedCRS.class.getName())) {
+            Set all = epsg.keySet();
+            Set projCRS = new java.util.TreeSet();
+            for(java.util.Iterator i = all.iterator(); i.hasNext();) {
+                String code = (String) i.next();
+                String wkt = epsg.getProperty( code );
+                if (wkt.startsWith("PROJCS")) {
+                    projCRS.add( AUTHORITY_PREFIX+code);
+                }
+            }  
+            return projCRS;
+            
+        } else {
+            return new java.util.TreeSet();
+        }
+    }
+    
+    public ObjectFactory getObjectFactory() {
+        return crsFactory;        
+    }
+    
+    public Citation getVendor() {
+         return Citations.GEOTOOLS;
+    }
+    
+    public InternationalString getDescriptionText(String code) throws FactoryException { 
+        if (code == null) {
+            return null;
+        }
+        if (code.startsWith("EPSG:")) { // EPSG:26907
+            code = code.substring(5);
+        }
+        code = code.trim();
+        String wkt = epsg.getProperty( code );
+        if( wkt == null ) {
+            throw new FactoryException("Unknonwn EPSG code: '"+code+"'" );
+        }
+        wkt = wkt.trim();
+        int start = wkt.indexOf('"');
+        int end = wkt.indexOf('"',start + 1);
+        return new org.geotools.util.SimpleInternationalString(wkt.substring(start + 1, end));
+    } 
+    
+    public org.opengis.referencing.crs.CompoundCRS createCompoundCRS(String str) throws FactoryException {
+        throw new FactoryException("Not implemented");
+    }
+        
+    public org.opengis.referencing.crs.DerivedCRS createDerivedCRS(String str) throws FactoryException {
+        throw new FactoryException("Not implemented");
+    }
+    
+    public org.opengis.referencing.crs.EngineeringCRS createEngineeringCRS(String str) throws FactoryException {
+        throw new FactoryException("Not implemented");
+    }
+    
+    public org.opengis.referencing.crs.GeocentricCRS createGeocentricCRS(String str) throws FactoryException {
+        throw new FactoryException("Not implemented");
+    }
+    
+    public org.opengis.referencing.crs.ImageCRS createImageCRS(String str) throws FactoryException {
+        throw new FactoryException("Not implemented");
+    }
+    
+    public org.opengis.referencing.crs.TemporalCRS createTemporalCRS(String str) throws FactoryException {
+        throw new FactoryException("Not implemented");
+    }
+    
+    public org.opengis.referencing.crs.VerticalCRS createVerticalCRS(String str) throws FactoryException {
+        throw new FactoryException("Not implemented");
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/UnprefixedMap.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/UnprefixedMap.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/UnprefixedMap.java	(revision 28000)
@@ -0,0 +1,130 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.crs;
+
+import java.util.Map;
+import org.opengis.referencing.IdentifiedObject;
+import org.geotools.util.DerivedMap;
+
+
+/**
+ * A map without the <code>"conversion."</code> prefix in front of property keys. This
+ * implementation performs a special processing for the <code>{@linkplain #prefix}.name</code>
+ * key: if it doesn't exists, then the plain {@code name} key is used. In other words,
+ * this map inherits the {@code "name"} property from the {@linkplain #base} map.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/crs/UnprefixedMap.java $
+ * @version $Id: UnprefixedMap.java 31000 2008-07-10 21:11:13Z desruisseaux $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @since 2.0
+ */
+final class UnprefixedMap extends DerivedMap<String,String,Object> {
+    /**
+     * The prefix to remove for this map.
+     */
+    private final String prefix;
+
+    /**
+     * {@code true} if the <code>{@linkplain #prefix}.name</code> property exists
+     * in the {@linkplain #base base} map. This class will inherit the name and alias
+     * from the {@linkplain #base base} map only if this field is set to {@code false}.
+     */
+    private final boolean hasName, hasAlias;
+
+    /**
+     * Creates a new unprefixed map from the specified base map and prefix.
+     *
+     * @param base   The base map.
+     * @param prefix The prefix to remove from the keys in the base map.
+     */
+    public UnprefixedMap(final Map<String,?> base, final String prefix) {
+        super((Map) base, String.class);
+        this.prefix = prefix.trim();
+        final String  nameKey = this.prefix + IdentifiedObject. NAME_KEY;
+        final String aliasKey = this.prefix + IdentifiedObject.ALIAS_KEY;
+        boolean hasName  = false;
+        boolean hasAlias = false;
+        for (final Object value : base.keySet()) {
+            final String candidate = value.toString().trim();
+            if (keyMatches(nameKey, candidate)) {
+                hasName = true;
+                if (hasAlias) break;
+            } else
+            if (keyMatches(aliasKey, candidate)) {
+                hasAlias = true;
+                if (hasName) break;
+            }
+        }
+        this.hasName  = hasName;
+        this.hasAlias = hasAlias;
+    }
+
+    /**
+     * Remove the prefix from the specified key. If the key doesn't begins with
+     * the prefix, then this method returns {@code null}.
+     *
+     * @param  key A key from the {@linkplain #base} map.
+     * @return The key that this view should contains instead of {@code key},
+     *         or {@code null}.
+     */
+    protected String baseToDerived(final String key) {
+        final int length = prefix.length();
+        final String textualKey = key.trim();
+        if (textualKey.regionMatches(true, 0, prefix, 0, length)) {
+            return textualKey.substring(length).trim();
+        }
+        if (isPlainKey(textualKey)) {
+            return textualKey;
+        }
+        return null;
+    }
+
+    /**
+     * Add the prefix to the specified key.
+     *
+     * @param  key A key in this map.
+     * @return The key stored in the {@linkplain #base} map.
+     */
+    protected String derivedToBase(final String key) {
+        final String textualKey = key.trim();
+        if (isPlainKey(textualKey)) {
+            return textualKey;
+        }
+        return prefix + textualKey;
+    }
+
+    /**
+     * Returns {@code true} if the specified candidate is {@code "name"}
+     * or {@code "alias"} without prefix. Key starting with {@code "name_"}
+     * or {@code "alias_"} are accepted as well.
+     */
+    private boolean isPlainKey(final String key) {
+        return (!hasName  && keyMatches(IdentifiedObject.NAME_KEY,  key)) ||
+               (!hasAlias && keyMatches(IdentifiedObject.ALIAS_KEY, key));
+    }
+
+    /**
+     * Returns {@code true} if the specified candidate matched
+     * the specified key name.
+     */
+    private static boolean keyMatches(final String key, final String candidate) {
+        final int length = key.length();
+        return candidate.regionMatches(true, 0, key, 0, length) &&
+               (candidate.length()==length || candidate.charAt(length)=='_');
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/crs/package.html	(revision 28000)
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.referencing.crs</TITLE>
+  </HEAD>
+  <BODY>
+  {@linkplain org.geotools.referencing.crs.AbstractCRS Coordinate reference systems} implementation.
+  An explanation for this package is provided in the {@linkplain org.opengis.referencing.crs OpenGIS&reg; javadoc}.
+  The remaining discussion on this page is specific to the Geotools implementation.
+
+  <P ALIGN="justify">{@link org.geotools.referencing.crs.AbstractCRS} is the base class for all
+  coordinate reference systems (CRS). CRS can have an arbitrary number of dimensions. Some are two-dimensional
+  (e.g. {@link org.geotools.referencing.crs.DefaultGeographicCRS GeographicCRS} and
+  {@link org.geotools.referencing.crs.DefaultProjectedCRS ProjectedCRS}), while some others are one-dimensional
+  (e.g. {@link org.geotools.referencing.crs.DefaultVerticalCRS VerticalCRS} and
+  {@link org.geotools.referencing.crs.DefaultTemporalCRS TemporalCRS}). Those simple coordinate systems can be
+  used as building blocks for more complex coordinate reference systems. For example, it is possible to construct
+  a three-dimensional CRS with (<var>latitude</var>, <var>longitude</var>, <var>time</var>) with an aggregation
+  of {@link org.geotools.referencing.crs.DefaultGeographicCRS GeographicCRS} and
+  {@link org.geotools.referencing.crs.DefaultTemporalCRS TemporalCRS}. Such aggregations
+  are built with {@link org.geotools.referencing.crs.DefaultCompoundCRS CompoundCRS}.</P>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/AbstractCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/AbstractCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/AbstractCS.java	(revision 28000)
@@ -0,0 +1,593 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.measure.converter.ConversionException;
+import javax.measure.converter.UnitConverter;
+import javax.measure.unit.NonSI;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+import org.geotools.measure.Measure;
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.operation.matrix.GeneralMatrix;
+import org.geotools.resources.Classes;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.util.Utilities;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * The set of coordinate system axes that spans a given coordinate space. A coordinate system (CS)
+ * is derived from a set of (mathematical) rules for specifying how coordinates in a given space
+ * are to be assigned to points. The coordinate values in a coordinate tuple shall be recorded in
+ * the order in which the coordinate system axes are recorded, whenever those
+ * coordinates use a coordinate reference system that uses this coordinate system.
+ * <p>
+ * This class is conceptually <cite>abstract</cite>, even if it is technically possible to
+ * instantiate it. Typical applications should create instances of the most specific subclass with
+ * {@code Default} prefix instead. An exception to this rule may occurs when it is not possible to
+ * identify the exact type. For example it is not possible to infer the exact coordinate system from
+ * <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well
+ * Known Text</cite></A> is some cases (e.g. in a {@code LOCAL_CS} element). In such exceptional
+ * situation, a plain {@code AbstractCS} object may be instantiated.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/AbstractCS.java $
+ * @version $Id: AbstractCS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see DefaultCoordinateSystemAxis
+ * @see javax.measure.unit.Unit
+ * @see org.geotools.referencing.datum.AbstractDatum
+ * @see org.geotools.referencing.crs.AbstractCRS
+ */
+public class AbstractCS extends AbstractIdentifiedObject implements CoordinateSystem {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 6757665252533744744L;
+
+    /**
+     * Base axis to use for checking directions. This is used in order to trap
+     * inconsistency like an axis named "Northing" with South direction.
+     */
+    private static final DefaultCoordinateSystemAxis[] DIRECTION_CHECKS = {
+        DefaultCoordinateSystemAxis.NORTHING,
+        DefaultCoordinateSystemAxis.EASTING,
+        DefaultCoordinateSystemAxis.SOUTHING,
+        DefaultCoordinateSystemAxis.WESTING
+    };
+
+    /**
+     * The axis for this coordinate system at the specified dimension.
+     */
+    private final CoordinateSystemAxis[] axis;
+
+    /**
+     * The unit for measuring distance in this coordinate system, or {@code null} if none.
+     * Will be computed only when first needed.
+     */
+    private transient Unit<?> distanceUnit;
+
+    /**
+     * Constructs a coordinate system from a name.
+     *
+     * @param name  The coordinate system name.
+     * @param axis  The set of axis.
+     */
+    public AbstractCS(final String name, final CoordinateSystemAxis[] axis) {
+        this(Collections.singletonMap(NAME_KEY, name), axis);
+    }
+
+    /**
+     * Constructs a coordinate system from a set of properties. The properties map is given
+     * unchanged to the {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map)
+     * super-class constructor}.
+     *
+     * @param properties   Set of properties. Should contains at least {@code "name"}.
+     * @param axis         The set of axis.
+     */
+    public AbstractCS(final Map<String,?> properties, final CoordinateSystemAxis[] axis) {
+        super(properties);
+        ensureNonNull("axis", axis);
+        this.axis = axis.clone();
+        for (int i=0; i<axis.length; i++) {
+            ensureNonNull("axis", axis, i);
+            final AxisDirection direction = axis[i].getDirection();
+            ensureNonNull("direction", direction);
+            /*
+             * Ensures that axis direction and units are compatible with the
+             * coordinate system to be created. For example CartesianCS will
+             * accepts only linear or dimensionless units.
+             */
+            if (!isCompatibleDirection(direction)) {
+                // TOOD: localize name()
+                throw new IllegalArgumentException(Errors.format(
+                        ErrorKeys.ILLEGAL_AXIS_ORIENTATION_$2, direction.name(), getClass()));
+            }
+            final Unit<?> unit = axis[i].getUnit();
+            ensureNonNull("unit", unit);
+            if (!isCompatibleUnit(direction, unit)) {
+                throw new IllegalArgumentException(Errors.format(
+                            ErrorKeys.INCOMPATIBLE_UNIT_$1, unit));
+            }
+            /*
+             * Ensures there is no axis along the same direction
+             * (e.g. two North axis, or an East and a West axis).
+             */
+            final AxisDirection check = direction.absolute();
+            if (!check.equals(AxisDirection.OTHER)) {
+                for (int j=i; --j>=0;) {
+                    if (check.equals(axis[j].getDirection().absolute())) {
+                        // TODO: localize name()
+                        final String nameI = axis[i].getDirection().name();
+                        final String nameJ = axis[j].getDirection().name();
+                        throw new IllegalArgumentException(Errors.format(
+                                    ErrorKeys.COLINEAR_AXIS_$2, nameI, nameJ));
+                    }
+                }
+            }
+            /*
+             * Checks for some inconsistency in naming and direction. For example if the axis
+             * is named "Northing", then the direction must be North. Exceptions to this rule
+             * are the directions along a meridian from a pole. For example a "Northing" axis
+             * may have a "South along 180 deg" direction.
+             */
+            final String name = axis[i].getName().getCode();
+            for (int j=0; j<DIRECTION_CHECKS.length; j++) {
+                final DefaultCoordinateSystemAxis candidate = DIRECTION_CHECKS[j];
+                if (candidate.nameMatches(name)) {
+                    final AxisDirection expected = candidate.getDirection();
+                    if (!direction.equals(expected)) {
+                        DirectionAlongMeridian m = DirectionAlongMeridian.parse(direction);
+                        /*
+                         * Note: for the check below, maybe it would have be nice to use:
+                         *
+                         *     if (m == null || m.baseDirection.equals(expected.opposite())
+                         *
+                         * but the EPSG database contains many axis named "Northing" with
+                         * direction like "South along 180 deg", so it doesn't seem to be
+                         * considered as a contradiction...
+                         */
+                        if (m == null) {
+                            throw new IllegalArgumentException(Errors.format(
+                                    ErrorKeys.INCONSISTENT_AXIS_ORIENTATION_$2,
+                                    name, direction.name()));
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates a name for the predefined constants in subclasses. The name is an unlocalized String
+     * object. However, since this method is used for creation of convenience objects only (not for
+     * objects created from an "official" database), the "unlocalized" name is actually choosen
+     * according the user's locale at class initialization time. The same name is also added in
+     * a localizable form as an alias. Since the {@link #nameMatches} convenience method checks
+     * the alias, it still possible to consider two objects are equivalent even if their names
+     * were formatted in different locales.
+     */
+    static Map<String,Object> name(final int key) {
+        final Map<String,Object> properties = new HashMap<String,Object>(4);
+        final InternationalString name = Vocabulary.formatInternational(key);
+        properties.put(NAME_KEY,  name.toString());
+        properties.put(ALIAS_KEY, name);
+        return properties;
+    }
+
+    /**
+     * Returns {@code true} if the specified axis direction is allowed for this coordinate
+     * system. This method is invoked at construction time for checking argument validity.
+     * The default implementation returns {@code true} for all axis directions. Subclasses
+     * will overrides this method in order to put more restrictions on allowed axis directions.
+     *
+     * @param direction The direction to test for compatibility.
+     * @return {@code true} if the given direction is compatible with this coordinate system.
+     */
+    protected boolean isCompatibleDirection(final AxisDirection direction) {
+        return true;
+    }
+
+    /**
+     * Returns {@code true} is the specified unit is legal for the specified axis direction.
+     * This method is invoked at construction time for checking units compatibility. The default
+     * implementation returns {@code true} in all cases. Subclasses can override this method and
+     * check for compatibility with {@linkplain SI#METER meter} or
+     * {@linkplain NonSI#DEGREE_ANGLE degree} units.
+     *
+     * @param direction The direction of the axis having the given unit.
+     * @param unit The unit to test for compatibility.
+     * @return {@code true} if the given unit is compatible with this coordinate system.
+     *
+     * @since 2.2
+     */
+    protected boolean isCompatibleUnit(final AxisDirection direction, final Unit<?> unit) {
+        return true;
+    }
+
+    /**
+     * Returns the dimension of the coordinate system.
+     * This is the number of axis.
+     */
+    public int getDimension() {
+        return axis.length;
+    }
+
+    /**
+     * Returns the axis for this coordinate system at the specified dimension.
+     *
+     * @param  dimension The zero based index of axis.
+     * @return The axis at the specified dimension.
+     * @throws IndexOutOfBoundsException if {@code dimension} is out of bounds.
+     */
+    public CoordinateSystemAxis getAxis(final int dimension) throws IndexOutOfBoundsException {
+        return axis[dimension];
+    }
+
+    /**
+     * Returns the axis direction for the specified coordinate system.
+     *
+     * @param  cs The coordinate system.
+     * @return The axis directions for the specified coordinate system.
+     */
+    private static AxisDirection[] getAxisDirections(final CoordinateSystem cs) {
+        final AxisDirection[] axis = new AxisDirection[cs.getDimension()];
+        for (int i=0; i<axis.length; i++) {
+            axis[i] = cs.getAxis(i).getDirection();
+        }
+        return axis;
+    }
+
+    /**
+     * Returns an affine transform between two coordinate systems. Only units and
+     * axis order (e.g. transforming from
+     * ({@linkplain AxisDirection#NORTH NORTH},{@linkplain AxisDirection#WEST WEST}) to
+     * ({@linkplain AxisDirection#EAST EAST},{@linkplain AxisDirection#NORTH NORTH}
+     * are taken in account.
+     * <p>
+     * <b>Example:</b> If coordinates in {@code sourceCS} are (<var>x</var>,<var>y</var>) pairs
+     * in metres and coordinates in {@code targetCS} are (-<var>y</var>,<var>x</var>) pairs in
+     * centimetres, then the transformation can be performed as below:
+     *
+     * <pre><blockquote>
+     *          [-y(cm)]   [ 0  -100    0 ] [x(m)]
+     *          [ x(cm)] = [ 100   0    0 ] [y(m)]
+     *          [ 1    ]   [ 0     0    1 ] [1   ]
+     * </blockquote></pre>
+     *
+     * @param  sourceCS The source coordinate system.
+     * @param  targetCS The target coordinate system.
+     * @return The conversion from {@code sourceCS} to {@code targetCS} as
+     *         an affine transform. Only axis direction and units are taken in account.
+     * @throws IllegalArgumentException if axis doesn't matches, or the CS doesn't have the
+     *         same geometry.
+     * @throws ConversionException if the unit conversion is non-linear.
+     */
+    public static Matrix swapAndScaleAxis(final CoordinateSystem sourceCS,
+                                          final CoordinateSystem targetCS)
+            throws IllegalArgumentException, ConversionException
+    {
+        if (!Classes.sameInterfaces(sourceCS.getClass(), targetCS.getClass(), CoordinateSystem.class)) {
+            throw new IllegalArgumentException(Errors.format(
+                      ErrorKeys.INCOMPATIBLE_COORDINATE_SYSTEM_TYPE));
+        }
+        final AxisDirection[] sourceAxis = getAxisDirections(sourceCS);
+        final AxisDirection[] targetAxis = getAxisDirections(targetCS);
+        final GeneralMatrix matrix = new GeneralMatrix(sourceAxis, targetAxis);
+        assert Arrays.equals(sourceAxis, targetAxis) == matrix.isIdentity() : matrix;
+        /*
+         * The previous code computed a matrix for swapping axis. Usually, this
+         * matrix contains only 0 and 1 values with only one "1" value by row.
+         * For example, the matrix operation for swapping x and y axis is:
+         *
+         *          [y]   [ 0  1  0 ] [x]
+         *          [x] = [ 1  0  0 ] [y]
+         *          [1]   [ 0  0  1 ] [1]
+         *
+         * Now, take in account units conversions. Each matrix's element (j,i)
+         * is multiplied by the conversion factor from sourceCS.getUnit(i) to
+         * targetCS.getUnit(j). This is an element-by-element multiplication,
+         * not a matrix multiplication. The last column is processed in a special
+         * way, since it contains the offset values.
+         */
+        final int sourceDim = matrix.getNumCol()-1;
+        final int targetDim = matrix.getNumRow()-1;
+        assert sourceDim == sourceCS.getDimension() : sourceCS;
+        assert targetDim == targetCS.getDimension() : targetCS;
+        for (int j=0; j<targetDim; j++) {
+            final Unit<?> targetUnit = targetCS.getAxis(j).getUnit();
+            for (int i=0; i<sourceDim; i++) {
+                final double element = matrix.getElement(j,i);
+                if (element == 0) {
+                    // There is no dependency between source[i] and target[j]
+                    // (i.e. axis are orthogonal).
+                    continue;
+                }
+                final Unit<?> sourceUnit = sourceCS.getAxis(i).getUnit();
+                if (Utilities.equals(sourceUnit, targetUnit)) {
+                    // There is no units conversion to apply
+                    // between source[i] and target[j].
+                    continue;
+                }
+                final UnitConverter converter = sourceUnit.getConverterTo(targetUnit);
+                if (!converter.isLinear()) {
+                    throw new ConversionException(Errors.format(
+                              ErrorKeys.NON_LINEAR_UNIT_CONVERSION_$2, sourceUnit, targetUnit));
+                }
+                final double offset = converter.convert(0);
+// JSR-275      final double scale  = converter.derivative(0);
+                final double scale  = converter.convert(1) - offset;
+                matrix.setElement(j,i, element*scale);
+                matrix.setElement(j,sourceDim, matrix.getElement(j,sourceDim) + element*offset);
+            }
+        }
+        return matrix;
+    }
+
+    /**
+     * Returns a coordinate system with "standard" axis order and units.
+     * Most of the time, this method returns one of the predefined constants with axis in
+     * (<var>longitude</var>,<var>latitude</var>) or (<var>X</var>,<var>Y</var>) order,
+     * and units in degrees or metres. In some particular cases like
+     * {@linkplain org.opengis.referencing.cs.CartesianCS Cartesian CS}, this method may
+     * create a new instance on the fly. In every cases this method attempts to return a
+     * <A HREF="http://en.wikipedia.org/wiki/Right_hand_rule">right-handed</A> coordinate
+     * system, but this is not garanteed.
+     * <p>
+     * This method is typically used together with {@link #swapAndScaleAxis swapAndScaleAxis}
+     * for the creation of a transformation step before some
+     * {@linkplain org.opengis.referencing.operation.MathTransform math transform}.
+     * Example:
+     *
+     * <blockquote><pre>
+     * Matrix step1 = swapAndScaleAxis(sourceCS, standard(sourceCS));
+     * Matrix step2 = ... some transform operating on standard axis ...
+     * Matrix step3 = swapAndScaleAxis(standard(targetCS), targetCS);
+     * </pre></blockquote>
+     *
+     * A rational for standard axis order and units is explained in the <cite>Axis units and
+     * direction</cite> section in the {@linkplain org.geotools.referencing.operation.projection
+     * description of map projection package}.
+     *
+     * @param  cs The coordinate system.
+     * @return A constant similar to the specified {@code cs} with "standard" axis.
+     * @throws IllegalArgumentException if the specified coordinate system is unknow to this method.
+     *
+     * @since 2.2
+     */
+    public static CoordinateSystem standard(final CoordinateSystem cs)
+            throws IllegalArgumentException
+    {
+        return PredefinedCS.standard(cs);
+    }
+
+    /**
+     * Suggests an unit for measuring distances in this coordinate system. The default
+     * implementation scans all {@linkplain CoordinateSystemAxis#getUnit axis units},
+     * ignoring angular ones (this also implies ignoring {@linkplain Unit#ONE dimensionless} ones).
+     * If more than one non-angular unit is found, the default implementation returns the "largest"
+     * one (e.g. kilometers instead of meters).
+     *
+     * @return Suggested distance unit.
+     * @throws ConversionException if some non-angular units are incompatibles.
+     */
+    final Unit<?> getDistanceUnit() throws ConversionException {
+        Unit<?> unit = distanceUnit;  // Avoid the need for synchronization.
+        if (unit == null) {
+            for (int i=0; i<axis.length; i++) {
+                final Unit<?> candidate = axis[i].getUnit();
+                if (candidate!=null && !candidate.isCompatible(SI.RADIAN)) {
+                    // TODO: checks the unit scale type (keeps RATIO only).
+                    if (unit != null) {
+                        final UnitConverter converter = candidate.getConverterTo(unit);
+                        if (!converter.isLinear()) {
+                            // TODO: use the localization provided in 'swapAxis'. We could also
+                            //       do a more intelligent work by checking the unit scale type.
+                            throw new ConversionException("Unit conversion is non-linear");
+                        }
+// JSR-275              final double scale = converter.derivative(0);
+                        final double scale = converter.convert(1) - converter.convert(0);
+                        if (Math.abs(scale) <= 1) {
+                            // The candidate is a "smaller" unit than the current one
+                            // (e.g. "m" instead of "km"). Keeps the "largest" unit.
+                            continue;
+                        }
+                    }
+                    unit = candidate;
+                }
+            }
+            distanceUnit = unit;
+        }
+        return unit;
+    }
+
+    /**
+     * Convenience method for checking object dimension validity.
+     *
+     * @param  name The name of the argument to check.
+     * @param  coordinates The coordinate array to check.
+     * @throws MismatchedDimensionException if the coordinate doesn't have the expected dimension.
+     */
+    final void ensureDimensionMatch(final String name, final double[] coordinates)
+            throws MismatchedDimensionException
+    {
+        if (coordinates.length != axis.length) {
+            throw new MismatchedDimensionException(Errors.format(
+                        ErrorKeys.MISMATCHED_DIMENSION_$3, name, coordinates.length, axis.length));
+        }
+    }
+
+    /**
+     * Computes the distance between two points. This method is not available for all coordinate
+     * systems. For example, {@linkplain DefaultEllipsoidalCS ellipsoidal CS} doesn't have
+     * suffisient information.
+     *
+     * @param  coord1 Coordinates of the first point.
+     * @param  coord2 Coordinates of the second point.
+     * @return The distance between {@code coord1} and {@code coord2}.
+     * @throws UnsupportedOperationException if this coordinate system can't compute distances.
+     * @throws MismatchedDimensionException if a coordinate doesn't have the expected dimension.
+     *
+     * @todo Provides a localized message in the exception.
+     */
+    public Measure distance(final double[] coord1, final double[] coord2)
+            throws UnsupportedOperationException, MismatchedDimensionException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns every axis from the specified coordinate system as instance of
+     * {@link DefaultCoordinateSystemAxis}. This allow usage of some methods
+     * specific to that implementation.
+     */
+    private static DefaultCoordinateSystemAxis[] getDefaultAxis(final CoordinateSystem cs) {
+        final DefaultCoordinateSystemAxis[] axis = new DefaultCoordinateSystemAxis[cs.getDimension()];
+        for (int i=0; i<axis.length; i++) {
+            final CoordinateSystemAxis a = cs.getAxis(i);
+            DefaultCoordinateSystemAxis c = DefaultCoordinateSystemAxis.getPredefined(a);
+            if (c == null) {
+                if (a instanceof DefaultCoordinateSystemAxis) {
+                    c = (DefaultCoordinateSystemAxis) a;
+                } else {
+                    c = new DefaultCoordinateSystemAxis(a);
+                }
+            }
+            axis[i] = c;
+        }
+        return axis;
+    }
+
+    /**
+     * Returns {@code true} if every axis in the specified {@code userCS} are colinear with axis
+     * in this coordinate system. The comparaison is insensitive to axis order and units. What
+     * matter is axis names (because they are fixed by ISO 19111 specification) and directions.
+     * <p>
+     * If this method returns {@code true}, then there is good chances that this CS can be used
+     * together with {@code userCS} as arguments to {@link #swapAndScaleAxis swapAndScaleAxis}.
+     * <p>
+     * This method should not be public because current implementation is not fully consistent
+     * for every pair of CS. It tries to check the opposite direction in addition of the usual
+     * one, but only a few pre-defined axis declare their opposite. This method should be okay
+     * when invoked on pre-defined CS declared in this package. {@link PredefinedCS} uses this
+     * method only that way.
+     */
+    final boolean axisColinearWith(final CoordinateSystem userCS) {
+        if (userCS.getDimension() != getDimension()) {
+            return false;
+        }
+        final DefaultCoordinateSystemAxis[] axis0 = getDefaultAxis(this);
+        final DefaultCoordinateSystemAxis[] axis1 = getDefaultAxis(userCS);
+next:   for (int i=0; i<axis0.length; i++) {
+            final DefaultCoordinateSystemAxis direct   = axis0[i];
+            final DefaultCoordinateSystemAxis opposite = direct.getOpposite();
+            for (int j=0; j<axis1.length; j++) {
+                final DefaultCoordinateSystemAxis candidate = axis1[j];
+                if (candidate != null) {
+                    if (candidate.equals(direct,   false, false) || (opposite != null &&
+                        candidate.equals(opposite, false, false)))
+                    {
+                        axis1[j] = null; // Flags as already compared.
+                        continue next;
+                    }
+                }
+            }
+            return false;
+        }
+        assert directionColinearWith(userCS);
+        return true;
+    }
+
+    /**
+     * Compares directions only, without consideration for the axis name.
+     */
+    final boolean directionColinearWith(final CoordinateSystem userCS) {
+        if (userCS.getDimension() != axis.length) {
+            return false;
+        }
+        final AxisDirection[] checks = new AxisDirection[axis.length];
+        for (int i=0; i<checks.length; i++) {
+            checks[i] = userCS.getAxis(i).getDirection().absolute();
+        }
+next:   for (int i=0; i<axis.length; i++) {
+            final AxisDirection direction = axis[i].getDirection().absolute();
+            for (int j=0; j<checks.length; j++) {
+                final AxisDirection candidate = checks[j];
+                if (candidate != null && candidate.equals(direction)) {
+                    checks[j] = null;  // Flags as already compared.
+                    continue next;
+                }
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Compares the specified object with this coordinate system for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            final AbstractCS that = (AbstractCS) object;
+            return equals(this.axis, that.axis, compareMetadata);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this coordinate system.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        int code = (int)serialVersionUID;
+        for (int i=0; i<axis.length; i++) {
+            code = code*37 + axis[i].hashCode();
+        }
+        return code;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/ComparableAxisWrapper.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/ComparableAxisWrapper.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/ComparableAxisWrapper.java	(revision 28000)
@@ -0,0 +1,111 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.Arrays;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+
+
+/**
+ * Wraps a {@linkplain CoordinateSystemAxis coordinate system axis} for comparaison purpose.
+ * The sorting order tries to favor a right-handed system. Compass directions like
+ * {@linkplain AxisDirection#NORTH North} or {@linkplain AxisDirection#EAST East} are first,
+ * and vertical or temporal directions like {@linkplain AxisDirection#UP Up} are last.
+ *
+ * @version $Id: ComparableAxisWrapper.java 30641 2008-06-12 17:42:27Z acuster $
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/ComparableAxisWrapper.java $
+ * @author Martin Desruisseaux
+ */
+final class ComparableAxisWrapper implements Comparable {
+    /**
+     * The wrapped axis.
+     */
+    private final CoordinateSystemAxis axis;
+
+    /**
+     * The direction along meridian, or {@code null} if none.
+     */
+    private final DirectionAlongMeridian meridian;
+
+    /**
+     * Creates a new wrapper for the given axis.
+     */
+    private ComparableAxisWrapper(final CoordinateSystemAxis axis) {
+        this.axis = axis;
+        meridian = DirectionAlongMeridian.parse(axis.getDirection());
+    }
+
+    /**
+     * Returns {@code true} if the specified direction is a compass direction.
+     */
+    private static boolean isCompassDirection(final AxisDirection direction) {
+        int compass = DefaultCoordinateSystemAxis.getCompassAngle(direction, AxisDirection.NORTH);
+        return compass != Integer.MIN_VALUE;
+    }
+
+    /**
+     * Compares with the specified object. See class javadoc
+     * for a description of the sorting order.
+     */
+    public int compareTo(final Object other) {
+        final ComparableAxisWrapper that = (ComparableAxisWrapper) other;
+        final AxisDirection d1 = this.axis.getDirection();
+        final AxisDirection d2 = that.axis.getDirection();
+        final int compass = DefaultCoordinateSystemAxis.getCompassAngle(d2, d1);
+        if (compass != Integer.MIN_VALUE) {
+            return compass;
+        }
+        if (isCompassDirection(d1)) {
+            assert !isCompassDirection(d2) : d2;
+            return -1;
+        }
+        if (isCompassDirection(d2)) {
+            assert !isCompassDirection(d1) : d1;
+            return +1;
+        }
+        if (meridian != null) {
+            if (that.meridian != null) {
+                return meridian.compareTo(that.meridian);
+            }
+            return -1;
+        } else if (that.meridian != null) {
+            return +1;
+        }
+        return 0;
+    }
+
+    /**
+     * Sorts the specified axis in an attempt to create a right-handed system.
+     * The sorting is performed in place. This method returns {@code true} if
+     * at least one axis moved.
+     */
+    public static boolean sort(final CoordinateSystemAxis[] axis) {
+        final ComparableAxisWrapper[] wrappers = new ComparableAxisWrapper[axis.length];
+        for (int i=0; i<axis.length; i++) {
+            wrappers[i] = new ComparableAxisWrapper(axis[i]);
+        }
+        Arrays.sort(wrappers);
+        boolean changed = false;
+        for (int i=0; i<axis.length; i++) {
+            final CoordinateSystemAxis a = wrappers[i].axis;
+            changed |= (axis[i] != a);
+            axis[i] = a;
+        }
+        return changed;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultAffineCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultAffineCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultAffineCS.java	(revision 28000)
@@ -0,0 +1,138 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.Map;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+import org.opengis.referencing.cs.AffineCS;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+
+
+/**
+ * A two- or three-dimensional coordinate system with straight axes that are not necessarily
+ * orthogonal. An {@code AffineCS} shall have two or three {@linkplain #getAxis axis}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.geotools.referencing.crs.DefaultEngineeringCRS Engineering},
+ *   {@link org.geotools.referencing.crs.DefaultImageCRS       Image}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DefaultAffineCS.java $
+ * @version $Id: DefaultAffineCS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see DefaultCartesianCS
+ */
+public class DefaultAffineCS extends AbstractCS implements AffineCS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 7977674229369042440L;
+
+    /**
+     * Constructs a two-dimensional coordinate system from a set of properties.
+     * The properties map is given unchanged to the
+     * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis0 The first axis.
+     * @param axis1 The second axis.
+     */
+    public DefaultAffineCS(final Map<String,?>   properties,
+                           final CoordinateSystemAxis axis0,
+                           final CoordinateSystemAxis axis1)
+    {
+        super(properties, new CoordinateSystemAxis[] {axis0, axis1});
+    }
+
+    /**
+     * Constructs a three-dimensional coordinate system from a set of properties.
+     * The properties map is given unchanged to the superclass constructor.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis0 The first axis.
+     * @param axis1 The second axis.
+     * @param axis2 The third axis.
+     */
+    public DefaultAffineCS(final Map<String,?>   properties,
+                           final CoordinateSystemAxis axis0,
+                           final CoordinateSystemAxis axis1,
+                           final CoordinateSystemAxis axis2)
+    {
+        super(properties, new CoordinateSystemAxis[] {axis0, axis1, axis2});
+    }
+
+    /**
+     * For {@link #usingUnit} and {@link PredefinedCS#rightHanded} usage only.
+     */
+    DefaultAffineCS(final Map<String,?> properties, final CoordinateSystemAxis[] axis) {
+        super(properties, axis);
+    }
+
+    /**
+     * Returns {@code true} if the specified axis direction is allowed for this coordinate
+     * system. The default implementation accepts all directions except temporal ones (i.e.
+     * {@link AxisDirection#FUTURE FUTURE} and {@link AxisDirection#PAST PAST}).
+     */
+    @Override
+    protected boolean isCompatibleDirection(final AxisDirection direction) {
+        return !AxisDirection.FUTURE.equals(direction.absolute());
+    }
+
+    /**
+     * Returns {@code true} if the specified unit is compatible with {@linkplain SI#METER meters}.
+     * In addition, this method also accepts {@link Unit#ONE}, which is used for coordinates in a
+     * grid. This method is invoked at construction time for checking units compatibility.
+     *
+     * @since 2.2
+     */
+    @Override
+    protected boolean isCompatibleUnit(final AxisDirection direction, final Unit<?> unit) {
+        return SI.METER.isCompatible(unit) || Unit.ONE.equals(unit);
+        // Note: this condition is also coded in PredefinedCS.rightHanded(AffineCS).
+    }
+
+    // TODO: Uncomment when we will be allowed to compile for J2SE 1.5
+    /*
+     * Returns a new coordinate system with the same properties than the current one except for
+     * axis units.
+     *
+     * @param  unit The unit for the new axis.
+     * @return A coordinate system with axis using the specified units.
+     * @throws IllegalArgumentException If the specified unit is incompatible with the expected one.
+     *
+     * @since 2.5
+     *
+    public DefaultAffineCS usingUnit(final Unit unit) throws IllegalArgumentException {
+        final CoordinateSystemAxis[] axis = axisUsingUnit(unit);
+        if (axis == null) {
+            return this;
+        }
+        return new DefaultAffineCS(getProperties(this, null), axis);
+    }
+     */
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultCartesianCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultCartesianCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultCartesianCS.java	(revision 28000)
@@ -0,0 +1,228 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.Map;
+import javax.measure.unit.Unit;
+import javax.measure.converter.UnitConverter;
+
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.geometry.MismatchedDimensionException;
+
+import org.geotools.measure.Measure;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.VocabularyKeys;
+
+
+/**
+ * A 1-, 2-, or 3-dimensional coordinate system. Gives the position of points relative to
+ * orthogonal straight axes in the 2- and 3-dimensional cases. In the 1-dimensional case,
+ * it contains a single straight coordinate axis. In the multi-dimensional case, all axes
+ * shall have the same length unit of measure. A {@code CartesianCS} shall have one,
+ * two, or three {@linkplain #getAxis axis}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.geotools.referencing.crs.DefaultGeocentricCRS  Geocentric},
+ *   {@link org.geotools.referencing.crs.DefaultProjectedCRS   Projected},
+ *   {@link org.geotools.referencing.crs.DefaultEngineeringCRS Engineering},
+ *   {@link org.geotools.referencing.crs.DefaultImageCRS       Image}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DefaultCartesianCS.java $
+ * @version $Id: DefaultCartesianCS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see DefaultAffineCS
+ */
+public class DefaultCartesianCS extends DefaultAffineCS implements CartesianCS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -6182037957705712945L;
+
+    /**
+     * A two-dimensional cartesian CS with
+     * <var>{@linkplain DefaultCoordinateSystemAxis#EASTING Easting}</var>,
+     * <var>{@linkplain DefaultCoordinateSystemAxis#NORTHING Northing}</var>
+     * axis in metres.
+     */
+    public static DefaultCartesianCS PROJECTED = new DefaultCartesianCS(
+                    name(VocabularyKeys.PROJECTED),
+                    DefaultCoordinateSystemAxis.EASTING,
+                    DefaultCoordinateSystemAxis.NORTHING);
+
+    /**
+     * A three-dimensional cartesian CS with geocentric
+     * <var>{@linkplain DefaultCoordinateSystemAxis#GEOCENTRIC_X x}</var>,
+     * <var>{@linkplain DefaultCoordinateSystemAxis#GEOCENTRIC_Y y}</var>,
+     * <var>{@linkplain DefaultCoordinateSystemAxis#GEOCENTRIC_Z z}</var>
+     * axis in metres.
+     *
+     * @see DefaultSphericalCS#GEOCENTRIC
+     */
+    public static DefaultCartesianCS GEOCENTRIC = new DefaultCartesianCS(
+                    name(VocabularyKeys.GEOCENTRIC),
+                    DefaultCoordinateSystemAxis.GEOCENTRIC_X,
+                    DefaultCoordinateSystemAxis.GEOCENTRIC_Y,
+                    DefaultCoordinateSystemAxis.GEOCENTRIC_Z);
+
+    /**
+     * A two-dimensional cartesian CS with
+     * <var>{@linkplain DefaultCoordinateSystemAxis#X x}</var>,
+     * <var>{@linkplain DefaultCoordinateSystemAxis#Y y}</var>
+     * axis in metres.
+     */
+    public static DefaultCartesianCS GENERIC_2D = new DefaultCartesianCS(
+                    name(VocabularyKeys.CARTESIAN_2D),
+                    DefaultCoordinateSystemAxis.X,
+                    DefaultCoordinateSystemAxis.Y);
+
+    /**
+     * A three-dimensional cartesian CS with
+     * <var>{@linkplain DefaultCoordinateSystemAxis#X x}</var>,
+     * <var>{@linkplain DefaultCoordinateSystemAxis#Y y}</var>,
+     * <var>{@linkplain DefaultCoordinateSystemAxis#Z z}</var>
+     * axis in metres.
+     */
+    public static DefaultCartesianCS GENERIC_3D = new DefaultCartesianCS(
+                    name(VocabularyKeys.CARTESIAN_3D),
+                    DefaultCoordinateSystemAxis.X,
+                    DefaultCoordinateSystemAxis.Y,
+                    DefaultCoordinateSystemAxis.Z);
+
+    /**
+     * A two-dimensional cartesian CS with
+     * <var>{@linkplain DefaultCoordinateSystemAxis#COLUMN column}</var>,
+     * <var>{@linkplain DefaultCoordinateSystemAxis#ROW row}</var>
+     * axis.
+     */
+    public static DefaultCartesianCS GRID = new DefaultCartesianCS(
+                    name(VocabularyKeys.GRID),
+                    DefaultCoordinateSystemAxis.COLUMN,
+                    DefaultCoordinateSystemAxis.ROW);
+
+    /**
+     * Converters from {@linkplain CoordinateSystemAxis#getUnit axis units} to
+     * {@linkplain #getDistanceUnit distance unit}. Will be constructed only when
+     * first needed.
+     */
+    private transient UnitConverter[] converters;
+
+    /**
+     * Constructs a two-dimensional coordinate system from a set of properties.
+     * The properties map is given unchanged to the
+     * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis0 The first axis.
+     * @param axis1 The second axis.
+     */
+    public DefaultCartesianCS(final Map<String,?>   properties,
+                              final CoordinateSystemAxis axis0,
+                              final CoordinateSystemAxis axis1)
+    {
+        super(properties, axis0, axis1);
+        ensurePerpendicularAxis();
+    }
+
+    /**
+     * Constructs a three-dimensional coordinate system from a set of properties.
+     * The properties map is given unchanged to the
+     * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis0 The first axis.
+     * @param axis1 The second axis.
+     * @param axis2 The third axis.
+     */
+    public DefaultCartesianCS(final Map<String,?>   properties,
+                              final CoordinateSystemAxis axis0,
+                              final CoordinateSystemAxis axis1,
+                              final CoordinateSystemAxis axis2)
+    {
+        super(properties, axis0, axis1, axis2);
+        ensurePerpendicularAxis();
+    }
+
+    /**
+     * For {@link #usingUnit} and {@link PredefinedCS#rightHanded} usage only.
+     */
+    DefaultCartesianCS(final Map<String,?> properties, final CoordinateSystemAxis[] axis) {
+        super(properties, axis);
+        ensurePerpendicularAxis();
+    }
+
+    /**
+     * Ensures that all axis are perpendicular.
+     */
+    private void ensurePerpendicularAxis() throws IllegalArgumentException {
+        final int dimension = getDimension();
+        for (int i=0; i<dimension; i++) {
+            final AxisDirection axis0 = getAxis(i).getDirection();
+            for (int j=i; ++j<dimension;) {
+                final AxisDirection axis1 = getAxis(j).getDirection();
+                final double angle = DefaultCoordinateSystemAxis.getAngle(axis0, axis1);
+                if (Math.abs(Math.abs(angle) - 90) > DirectionAlongMeridian.EPS) {
+                    throw new IllegalArgumentException(Errors.format(
+                            ErrorKeys.NON_PERPENDICULAR_AXIS_$2, axis0.name(), axis1.name()));
+                }
+            }
+        }
+    }
+
+    /**
+     * Computes the distance between two points.
+     *
+     * @param  coord1 Coordinates of the first point.
+     * @param  coord2 Coordinates of the second point.
+     * @return The distance between {@code coord1} and {@code coord2}.
+     * @throws MismatchedDimensionException if a coordinate doesn't have the expected dimension.
+     */
+    @Override
+    public Measure distance(final double[] coord1, final double[] coord2)
+            throws MismatchedDimensionException
+    {
+        ensureDimensionMatch("coord1", coord1);
+        ensureDimensionMatch("coord2", coord2);
+        final Unit<?> unit = getDistanceUnit();
+        UnitConverter[] converters = this.converters; // Avoid the need for synchronization.
+        if (converters == null) {
+            converters = new UnitConverter[getDimension()];
+            for (int i=0; i<converters.length; i++) {
+                converters[i] = getAxis(i).getUnit().getConverterTo(unit);
+            }
+            this.converters = converters;
+        }
+        double sum = 0;
+        for (int i=0; i<converters.length; i++) {
+            final UnitConverter  c = converters[i];
+            final double delta = c.convert(coord1[i]) - c.convert(coord2[i]);
+            sum += delta*delta;
+        }
+        return new Measure(Math.sqrt(sum), unit);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultCompoundCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultCompoundCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultCompoundCS.java	(revision 28000)
@@ -0,0 +1,153 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.List;
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.geotools.referencing.AbstractIdentifiedObject;
+
+
+/**
+ * A coordinate system made of two or more independent coordinate systems.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.geotools.referencing.crs.DefaultCompoundCRS Compound}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DefaultCompoundCS.java $
+ * @version $Id: DefaultCompoundCS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultCompoundCS extends AbstractCS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -5726410275278843372L;
+
+    /**
+     * The coordinate systems.
+     */
+    private final CoordinateSystem[] cs;
+
+    /**
+     * An immutable view of {@link #cs} as a list. Will be created only when first needed.
+     */
+    private transient List<CoordinateSystem> asList;
+
+    /**
+     * Constructs a compound coordinate system. A name for this CS will
+     * be automatically constructed from the name of all specified CS.
+     *
+     * @param cs The set of coordinate syztem.
+     */
+    public DefaultCompoundCS(CoordinateSystem[] cs) {
+        super(getName(cs=clone(cs)), getAxis(cs));
+        this.cs = cs;
+    }
+
+    /**
+     * Returns a clone of the specified array. This method would be bundle right
+     * into the constructor if RFE #4093999 was fixed.
+     */
+    private static CoordinateSystem[] clone(CoordinateSystem[] cs) {
+        ensureNonNull("cs", cs);
+        cs = cs.clone();
+        for (int i=0; i<cs.length; i++) {
+            ensureNonNull("cs", cs, i);
+        }
+        return cs;
+    }
+
+    /**
+     * Returns the axis of all coordinate systems.
+     */
+    private static CoordinateSystemAxis[] getAxis(final CoordinateSystem[] cs) {
+        int count = 0;
+        for (int i=0; i<cs.length; i++) {
+            count += cs[i].getDimension();
+        }
+        final CoordinateSystemAxis[] axis = new CoordinateSystemAxis[count];
+        count = 0;
+        for (int i=0; i<cs.length; i++) {
+            final CoordinateSystem c = cs[i];
+            final int dim = c.getDimension();
+            for (int j=0; j<dim; j++) {
+                axis[count++] = c.getAxis(j);
+            }
+        }
+        assert count == axis.length;
+        return axis;
+    }
+
+    /**
+     * Constructs a name from a merge of the name of all coordinate systems.
+     *
+     * @param cs The coordinate systems.
+     * @param locale The locale for the name.
+     */
+    private static String getName(final CoordinateSystem[] cs) {
+        final StringBuilder buffer = new StringBuilder();
+        for (int i=0; i<cs.length; i++) {
+            if (buffer.length() != 0) {
+                buffer.append(" / ");
+            }
+            buffer.append(cs[i].getName().getCode());
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Returns all coordinate systems in this compound CS.
+     */
+    public synchronized List<CoordinateSystem> getCoordinateSystems() {
+        if (asList == null) {
+            asList = Collections.unmodifiableList(Arrays.asList(cs));
+        }
+        return asList;
+    }
+
+    /**
+     * Compares this coordinate system with the specified object for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            final DefaultCompoundCS that = (DefaultCompoundCS) object;
+            return equals(this.cs, that.cs, compareMetadata);
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultCoordinateSystemAxis.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultCoordinateSystemAxis.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultCoordinateSystemAxis.java	(revision 28000)
@@ -0,0 +1,1111 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.measure.converter.UnitConverter;
+import javax.measure.unit.NonSI;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.geotools.util.NameFactory;
+import org.geotools.util.SimpleInternationalString;
+import org.geotools.util.Utilities;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.cs.RangeMeaning;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * Definition of a coordinate system axis. This is used to label axes, and indicate the orientation.
+ * See {@linkplain org.opengis.referencing.cs#AxisNames axis name constraints}.
+ * <p>
+ * In some case, the axis name is constrained by ISO 19111 depending on the
+ * {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference system}
+ * type. These constraints are identified in the javadoc by "<cite>ISO 19111 name is...</cite>"
+ * sentences. This constraint works in two directions; for example the names
+ * "<cite>geodetic latitude</cite>" and "<cite>geodetic longitude</cite>" shall be used to
+ * designate the coordinate axis names associated with a
+ * {@linkplain org.opengis.referencing.crs.GeographicCRS geographic coordinate reference system}.
+ * Conversely, these names shall not be used in any other context.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DefaultCoordinateSystemAxis.java $
+ * @version $Id: DefaultCoordinateSystemAxis.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see AbstractCS
+ * @see Unit
+ */
+public class DefaultCoordinateSystemAxis extends AbstractIdentifiedObject
+        implements CoordinateSystemAxis
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -7883614853277827689L;
+
+    /**
+     * Number of directions from "North", "North-North-East", "North-East", etc.
+     * This is verified by {@code DefaultCoordinateSystemAxisTest.testCompass}.
+     */
+    static final int COMPASS_DIRECTION_COUNT = 16;
+
+    /**
+     * Number of items in {@link #PREDEFINED}. Should be considered
+     * as a constant after the class initialisation is completed.
+     */
+    private static int PREDEFINED_COUNT = 0;
+
+    /**
+     * The list of predefined constants declared in this class,
+     * in declaration order. This order matter.
+     */
+    private static final DefaultCoordinateSystemAxis[] PREDEFINED = new DefaultCoordinateSystemAxis[26];
+
+    /**
+     * Default axis info for geodetic longitudes in a
+     * {@linkplain org.opengis.referencing.crs.GeographicCRS geographic CRS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#EAST East}
+     * and units are {@linkplain NonSI#DEGREE_ANGLE decimal degrees}.
+     *
+     * The ISO 19111 name is "<cite>geodetic longitude</cite>" and the abbreviation is "&lambda;"
+     * (lambda).
+     *
+     * This axis is usually part of a {@link #GEODETIC_LONGITUDE}, {@link #GEODETIC_LATITUDE},
+     * {@link #ELLIPSOIDAL_HEIGHT} set.
+     *
+     * @see #LONGITUDE
+     * @see #SPHERICAL_LONGITUDE
+     * @see #GEODETIC_LATITUDE
+     */
+    public static final DefaultCoordinateSystemAxis GEODETIC_LONGITUDE = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.GEODETIC_LONGITUDE, "\u03BB", AxisDirection.EAST, NonSI.DEGREE_ANGLE);
+
+    /**
+     * Default axis info for geodetic latitudes in a
+     * {@linkplain org.opengis.referencing.crs.GeographicCRS geographic CRS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#NORTH North}
+     * and units are {@linkplain NonSI#DEGREE_ANGLE decimal degrees}.
+     *
+     * The ISO 19111 name is "<cite>geodetic latitude</cite>" and the abbreviation is "&phi;" (phi).
+     *
+     * This axis is usually part of a {@link #GEODETIC_LONGITUDE}, {@link #GEODETIC_LATITUDE},
+     * {@link #ELLIPSOIDAL_HEIGHT} set.
+     *
+     * @see #LATITUDE
+     * @see #SPHERICAL_LATITUDE
+     * @see #GEODETIC_LONGITUDE
+     */
+    public static final DefaultCoordinateSystemAxis GEODETIC_LATITUDE = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.GEODETIC_LATITUDE, "\u03C6", AxisDirection.NORTH, NonSI.DEGREE_ANGLE);
+
+    /**
+     * The default axis for height values above the ellipsoid in a
+     * {@linkplain org.opengis.referencing.crs.GeographicCRS geographic CRS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#UP up}
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The ISO 19111 name is "<cite>ellipsoidal heigt</cite>" and the abbreviation is lower case
+     * "<var>h</var>".
+     *
+     * This axis is usually part of a {@link #GEODETIC_LONGITUDE}, {@link #GEODETIC_LATITUDE},
+     * {@link #ELLIPSOIDAL_HEIGHT} set.
+     *
+     * @see #ALTITUDE
+     * @see #GEOCENTRIC_RADIUS
+     * @see #GRAVITY_RELATED_HEIGHT
+     * @see #DEPTH
+     */
+    public static final DefaultCoordinateSystemAxis ELLIPSOIDAL_HEIGHT = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.ELLIPSOIDAL_HEIGHT, "h", AxisDirection.UP, SI.METER);
+
+    /**
+     * The default axis for altitude values.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#UP up}
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The abbreviation is lower case "<var>h</var>".
+     *
+     * This axis is usually part of a {@link #LONGITUDE}, {@link #LATITUDE}, {@link #ALTITUDE} set.
+     *
+     * @see #ELLIPSOIDAL_HEIGHT
+     * @see #GEOCENTRIC_RADIUS
+     * @see #GRAVITY_RELATED_HEIGHT
+     * @see #DEPTH
+     */
+    public static final DefaultCoordinateSystemAxis ALTITUDE = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.ALTITUDE, "h", AxisDirection.UP, SI.METER);
+
+    /**
+     * The default axis for depth.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#DOWN down}
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The ISO 19111 name is "<cite>depth</cite>".
+     *
+     * @see #ALTITUDE
+     * @see #ELLIPSOIDAL_HEIGHT
+     * @see #GEOCENTRIC_RADIUS
+     * @see #GRAVITY_RELATED_HEIGHT
+     */
+    public static final DefaultCoordinateSystemAxis DEPTH = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.DEPTH, "d", AxisDirection.DOWN, SI.METER);
+    static {
+        ALTITUDE.opposite = DEPTH;
+        DEPTH.opposite = ALTITUDE;
+    }
+
+    /**
+     * Default axis info for radius in a
+     * {@linkplain org.opengis.referencing.crs.GeocentricCRS geocentric CRS} using
+     * {@linkplain org.opengis.referencing.cs.SphericalCS spherical CS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#UP up}
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The ISO 19111 name is "<cite>geocentric radius</cite>" and the abbreviation is lower case
+     * "<var>r</var>".
+     *
+     * This axis is usually part of a {@link #SPHERICAL_LONGITUDE}, {@link #SPHERICAL_LATITUDE},
+     * {@link #GEOCENTRIC_RADIUS} set.
+     *
+     * @see #ALTITUDE
+     * @see #ELLIPSOIDAL_HEIGHT
+     * @see #GRAVITY_RELATED_HEIGHT
+     * @see #DEPTH
+     */
+    public static final DefaultCoordinateSystemAxis GEOCENTRIC_RADIUS = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.GEOCENTRIC_RADIUS, "r", AxisDirection.UP, SI.METER);
+
+    /**
+     * Default axis info for longitudes in a
+     * {@linkplain org.opengis.referencing.crs.GeocentricCRS geocentric CRS} using
+     * {@linkplain org.opengis.referencing.crs.SphericalCS spherical CS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#EAST East}
+     * and units are {@linkplain NonSI#DEGREE_ANGLE decimal degrees}.
+     *
+     * The ISO 19111 name is "<cite>spherical longitude</cite>" and the abbreviation is "&Omega;"
+     * (omega).
+     *
+     * This axis is usually part of a {@link #SPHERICAL_LONGITUDE}, {@link #SPHERICAL_LATITUDE},
+     * {@link #GEOCENTRIC_RADIUS} set.
+     *
+     * @see #LONGITUDE
+     * @see #GEODETIC_LONGITUDE
+     * @see #SPHERICAL_LATITUDE
+     */
+    public static final DefaultCoordinateSystemAxis SPHERICAL_LONGITUDE = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.SPHERICAL_LONGITUDE, "\u03A9", AxisDirection.EAST, NonSI.DEGREE_ANGLE);
+
+    /**
+     * Default axis info for latitudes in a
+     * {@linkplain org.opengis.referencing.crs.GeocentricCRS geocentric CRS} using
+     * {@linkplain org.opengis.referencing.cs.SphericalCS spherical CS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#NORTH North}
+     * and units are {@linkplain NonSI#DEGREE_ANGLE decimal degrees}.
+     *
+     * The ISO 19111 name is "<cite>spherical latitude</cite>" and the abbreviation is "&Theta;"
+     * (theta).
+     *
+     * This axis is usually part of a {@link #SPHERICAL_LONGITUDE}, {@link #SPHERICAL_LATITUDE},
+     * {@link #GEOCENTRIC_RADIUS} set.
+     *
+     * @see #LATITUDE
+     * @see #GEODETIC_LATITUDE
+     * @see #SPHERICAL_LONGITUDE
+     */
+    public static final DefaultCoordinateSystemAxis SPHERICAL_LATITUDE = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.SPHERICAL_LATITUDE, "\u03B8", AxisDirection.NORTH, NonSI.DEGREE_ANGLE);
+
+    /**
+     * Default axis info for <var>x</var> values in a
+     * {@linkplain org.opengis.referencing.cs.CartesianCS cartesian CS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#EAST East}
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The abbreviation is lower case "<var>x</var>".
+     *
+     * This axis is usually part of a {@link #X}, {@link #Y}, {@link #Z} set.
+     *
+     * @see #EASTING
+     * @see #WESTING
+     * @see #GEOCENTRIC_X
+     * @see #DISPLAY_X
+     * @see #COLUMN
+     */
+    public static final DefaultCoordinateSystemAxis X = new DefaultCoordinateSystemAxis(
+            -1, "x", AxisDirection.EAST, SI.METER);
+
+    /**
+     * Default axis info for <var>y</var> values in a
+     * {@linkplain org.opengis.referencing.cs.CartesianCS cartesian CS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#NORTH North}
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The abbreviation is lower case "<var>y</var>".
+     *
+     * This axis is usually part of a {@link #X}, {@link #Y}, {@link #Z} set.
+     *
+     * @see #NORTHING
+     * @see #SOUTHING
+     * @see #GEOCENTRIC_Y
+     * @see #DISPLAY_Y
+     * @see #ROW
+     */
+    public static final DefaultCoordinateSystemAxis Y = new DefaultCoordinateSystemAxis(
+            -1, "y", AxisDirection.NORTH, SI.METER);
+
+    /**
+     * Default axis info for <var>z</var> values in a
+     * {@linkplain org.opengis.referencing.cs.CartesianCS cartesian CS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#UP up}
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The abbreviation is lower case "<var>z</var>".
+     *
+     * This axis is usually part of a {@link #X}, {@link #Y}, {@link #Z} set.
+     */
+    public static final DefaultCoordinateSystemAxis Z = new DefaultCoordinateSystemAxis(
+            -1, "z", AxisDirection.UP, SI.METER);
+
+    /**
+     * Default axis info for <var>x</var> values in a
+     * {@linkplain org.opengis.referencing.crs.GeocentricCRS geocentric CRS} using
+     * {@linkplain org.opengis.referencing.cs.CartesianCS cartesian CS}.
+     *
+     * Increasing ordinates values go toward prime meridian
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The ISO 19111 name is "<cite>geocentric X</cite>" and the abbreviation is upper case
+     * "<var>X</var>".
+     *
+     * This axis is usually part of a {@link #GEOCENTRIC_X}, {@link #GEOCENTRIC_Y},
+     * {@link #GEOCENTRIC_Z} set.
+     */
+    public static final DefaultCoordinateSystemAxis GEOCENTRIC_X = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.GEOCENTRIC_X, "X", AxisDirection.OTHER, SI.METER);
+
+    /**
+     * Default axis info for <var>y</var> values in a
+     * {@linkplain org.opengis.referencing.crs.GeocentricCRS geocentric CRS} using
+     * {@linkplain org.opengis.referencing.cs.CartesianCS cartesian CS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#EAST East}
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The ISO 19111 name is "<cite>geocentric Y</cite>" and the abbreviation is upper case
+     * "<var>Y</var>".
+     *
+     * This axis is usually part of a {@link #GEOCENTRIC_X}, {@link #GEOCENTRIC_Y},
+     * {@link #GEOCENTRIC_Z} set.
+     */
+    public static final DefaultCoordinateSystemAxis GEOCENTRIC_Y = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.GEOCENTRIC_Y, "Y", AxisDirection.EAST, SI.METER);
+
+    /**
+     * Default axis info for <var>z</var> values in a
+     * {@linkplain org.opengis.referencing.crs.GeocentricCRS geocentric CRS} using
+     * {@linkplain org.opengis.referencing.cs.CartesianCS cartesian CS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#NORTH North}
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The ISO 19111 name is "<cite>geocentric Z</cite>" and the abbreviation is upper case
+     * "<var>Z</var>".
+     *
+     * This axis is usually part of a {@link #GEOCENTRIC_X}, {@link #GEOCENTRIC_Y},
+     * {@link #GEOCENTRIC_Z} set.
+     */
+    public static final DefaultCoordinateSystemAxis GEOCENTRIC_Z = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.GEOCENTRIC_Z, "Z", AxisDirection.NORTH, SI.METER);
+
+    /**
+     * Default axis info for Easting values in a
+     * {@linkplain org.opengis.referencing.crs.ProjectedCRS projected CRS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#EAST East}
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The ISO 19111 name is "<cite>easting</cite>" and the abbreviation is upper case
+     * "<var>E</var>".
+     *
+     * This axis is usually part of a {@link #EASTING}, {@link #NORTHING} set.
+     *
+     * @see #X
+     * @see #EASTING
+     * @see #WESTING
+     */
+    public static final DefaultCoordinateSystemAxis EASTING = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.EASTING, "E", AxisDirection.EAST, SI.METER);
+
+    /**
+     * Default axis info for Westing values in a
+     * {@linkplain org.opengis.referencing.crs.ProjectedCRS projected CRS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#WEST West}
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The ISO 19111 name is "<cite>westing</cite>" and the abbreviation is upper case
+     * "<var>W</var>".
+     *
+     * @see #X
+     * @see #EASTING
+     * @see #WESTING
+     */
+    public static final DefaultCoordinateSystemAxis WESTING = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.WESTING, "W", AxisDirection.WEST, SI.METER);
+    static {
+        EASTING.opposite = WESTING;
+        WESTING.opposite = EASTING;
+    }
+
+    /**
+     * Default axis info for Northing values in a
+     * {@linkplain org.opengis.referencing.crs.ProjectedCRS projected CRS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#NORTH North}
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The ISO 19111 name is "<cite>northing</cite>" and the abbreviation is upper case
+     * "<var>N</var>".
+     *
+     * This axis is usually part of a {@link #EASTING}, {@link #NORTHING} set.
+     *
+     * @see #Y
+     * @see #NORTHING
+     * @see #SOUTHING
+     */
+    public static final DefaultCoordinateSystemAxis NORTHING = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.NORTHING, "N", AxisDirection.NORTH, SI.METER);
+
+    /**
+     * Default axis info for Southing values in a
+     * {@linkplain org.opengis.referencing.crs.ProjectedCRS projected CRS}.
+     *
+     * Increasing ordinates values go {@linkplain AxisDirection#SOUTH South}
+     * and units are {@linkplain SI#METER metres}.
+     *
+     * The ISO 19111 name is "<cite>southing</cite>" and the abbreviation is upper case
+     * "<var>S</var>".
+     *
+     * @see #Y
+     * @see #NORTHING
+     * @see #SOUTHING
+     */
+    public static final DefaultCoordinateSystemAxis SOUTHING = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.SOUTHING, "S", AxisDirection.SOUTH, SI.METER);
+    static {
+        NORTHING.opposite = SOUTHING;
+        SOUTHING.opposite = NORTHING;
+    }
+
+    /**
+     * A default axis for time values in a {@linkplain org.opengis.referencing.cs.TimeCS time CS}.
+     *
+     * Increasing time go toward {@linkplain AxisDirection#FUTURE future}
+     * and units are {@linkplain NonSI#DAY days}.
+     *
+     * The abbreviation is lower case "<var>t</var>".
+     */
+    public static final DefaultCoordinateSystemAxis TIME = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.TIME, "t", AxisDirection.FUTURE, NonSI.DAY);
+
+    /**
+     * A default axis for column indices in a {@linkplain org.opengis.coverage.grid.GridCoverage
+     * grid coverage}. Increasing values go toward {@linkplain AxisDirection#COLUMN_POSITIVE
+     * positive column number}.
+     *
+     * The abbreviation is lower case "<var>i</var>".
+     */
+    public static final DefaultCoordinateSystemAxis COLUMN = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.COLUMN, "i", AxisDirection.COLUMN_POSITIVE, Unit.ONE);
+
+    /**
+     * A default axis for row indices in a {@linkplain org.opengis.coverage.grid.GridCoverage grid
+     * coverage}. Increasing values go toward {@linkplain AxisDirection#ROW_POSITIVE positive row
+     * number}.
+     *
+     * The abbreviation is lower case "<var>j</var>".
+     */
+    public static final DefaultCoordinateSystemAxis ROW = new DefaultCoordinateSystemAxis(
+            VocabularyKeys.ROW, "j", AxisDirection.ROW_POSITIVE, Unit.ONE);
+
+    /**
+     * Some names to be treated as equivalent. This is needed because axis names are the primary
+     * way to distinguish between {@link CoordinateSystemAxis} instances. Those names are strictly
+     * defined by ISO 19111 as "Geodetic latitude" and "Geodetic longitude" among others, but the
+     * legacy WKT specifications from OGC 01-009 defined the names as "Lon" and "Lat" for the same
+     * axis.
+     * <p>
+     * Keys in this map are names <strong>in lower cases</strong>. Values are the axis that the
+     * name is for. The actual axis instance doesn't matter (the algorithm using this map should
+     * work for any axis instance); it is just a way to differentiate latitude and longitude.
+     */
+    private static final Map<String,CoordinateSystemAxis> ALIASES =
+            new HashMap<String,CoordinateSystemAxis>(12);
+    static {
+        ALIASES.put("lat",                GEODETIC_LATITUDE);
+        ALIASES.put("latitude",           GEODETIC_LATITUDE);
+        ALIASES.put("geodetic latitude",  GEODETIC_LATITUDE);
+        ALIASES.put("lon",                GEODETIC_LONGITUDE);
+        ALIASES.put("long",               GEODETIC_LONGITUDE);
+        ALIASES.put("longitude",          GEODETIC_LONGITUDE);
+        ALIASES.put("geodetic longitude", GEODETIC_LONGITUDE);
+        /*
+         * "x" and "y" are sometime used in WKT for meaning "Easting" and "Northing".
+         * We could be tempted to add them as alias in this map, but experience shows
+         * that such alias have a lot of indesirable side effet. "x" and "y" are used
+         * for too many things ("Easting", "Westing", "Geocentric X", "Display right",
+         * "Display left", etc.) and declaring them as alias introduces confusion in
+         * AbstractCS constructor (during the check of axis directions), in
+         * PredefinedCS.standard(CoordinateSystem), etc.
+         */
+    }
+
+    /**
+     * Special cases for "x" and "y" names. "x" is considered equivalent to "Easting"
+     * or "Westing", but the converse is not true. Note: by avoiding to put "x" in the
+     * {@link #ALIASES} map, we avoid undesirable side effects like considering "Easting"
+     * as equivalent to "Westing".
+     *
+     * @param  xy   The name which may be "x" or "y".
+     * @param  name The second name to compare with.
+     * @return {@code true} if the second name is equivalent to "x" or "y" (depending on
+     *         the {@code xy} value), or {@code false} otherwise.
+     */
+    private static boolean nameMatchesXY(String xy, final String name) {
+        xy = xy.trim();
+        if (xy.length() == 1) {
+            final DefaultCoordinateSystemAxis axis;
+            switch (Character.toLowerCase(xy.charAt(0))) {
+                case 'x': axis=EASTING;  break;
+                case 'y': axis=NORTHING; break;
+                default : return false;
+            }
+            return axis.nameMatches(name) || axis.getOpposite().nameMatches(name);
+        }
+        return false;
+    }
+
+    /**
+     * The abbreviation used for this coordinate system axes. This abbreviation is also
+     * used to identify the ordinates in coordinate tuple. Examples are "<var>X</var>"
+     * and "<var>Y</var>".
+     */
+    private final String abbreviation;
+
+    /**
+     * Direction of this coordinate system axis. In the case of Cartesian projected
+     * coordinates, this is the direction of this coordinate system axis locally.
+     */
+    private final AxisDirection direction;
+
+    /**
+     * The unit of measure used for this coordinate system axis.
+     */
+    private final Unit<?> unit;
+
+    /**
+     * Minimal and maximal value for this axis.
+     */
+    private final double minimum, maximum;
+
+    /**
+     * The range meaning for this axis.
+     */
+    private final RangeMeaning rangeMeaning;
+
+    /**
+     * The axis with opposite direction, or {@code null} if unknow.
+     * Not serialized because only used for the predefined constants.
+     */
+    private transient DefaultCoordinateSystemAxis opposite;
+
+    /**
+     * Constructs a new coordinate system axis with the same values than the specified one.
+     * This copy constructor provides a way to wrap an arbitrary implementation into a
+     * Geotools one or a user-defined one (as a subclass), usually in order to leverage
+     * some implementation-specific API. This constructor performs a shallow copy,
+     * i.e. the properties are not cloned.
+     *
+     * @param axis The coordinate system axis to copy.
+     *
+     * @since 2.2
+     */
+    public DefaultCoordinateSystemAxis(final CoordinateSystemAxis axis) {
+        super(axis);
+        abbreviation = axis.getAbbreviation();
+        direction    = axis.getDirection();
+        unit         = axis.getUnit();
+        minimum      = axis.getMinimumValue();
+        maximum      = axis.getMaximumValue();
+        rangeMeaning = axis.getRangeMeaning();
+    }
+
+    /**
+     * Constructs an axis from a set of properties. The properties map is given unchanged to the
+     * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
+     *
+     * @param properties   Set of properties. Should contains at least {@code "name"}.
+     * @param abbreviation The {@linkplain #getAbbreviation abbreviation} used for this
+     *                     coordinate system axes.
+     * @param direction    The {@linkplain #getDirection direction} of this coordinate system axis.
+     * @param unit         The {@linkplain #getUnit unit of measure} used for this coordinate
+     *                     system axis.
+     * @param minimum      The minimum value normally allowed for this axis.
+     * @param maximum      The maximum value normally allowed for this axis.
+     * @param rangeMeaning The meaning of axis value range specified by the minimum and
+     *                     maximum values.
+     *
+     * @since 2.3
+     */
+    public DefaultCoordinateSystemAxis(final Map<String,?> properties,
+                                       final String        abbreviation,
+                                       final AxisDirection direction,
+                                       final Unit<?>       unit,
+                                       final double        minimum,
+                                       final double        maximum,
+                                       final RangeMeaning  rangeMeaning)
+    {
+        super(properties);
+        this.abbreviation = abbreviation;
+        this.direction    = direction;
+        this.unit         = unit;
+        this.minimum      = minimum;
+        this.maximum      = maximum;
+        this.rangeMeaning = rangeMeaning;
+        ensureNonNull("abbreviation", abbreviation);
+        ensureNonNull("direction",    direction);
+        ensureNonNull("unit",         unit);
+        ensureNonNull("rangeMeaning", rangeMeaning);
+        if (!(minimum < maximum)) { // Use '!' for catching NaN
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.BAD_RANGE_$2, minimum, maximum));
+        }
+    }
+
+    /**
+     * Constructs an unbounded axis from a set of properties. The properties map is given
+     * unchanged to the {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map)
+     * super-class constructor}. The {@linkplain #getMinimumValue minimum} and
+     * {@linkplain #getMaximumValue maximum} values are inferred from the axis unit and
+     * direction.
+     *
+     * @param properties   Set of properties. Should contains at least {@code "name"}.
+     * @param abbreviation The {@linkplain #getAbbreviation abbreviation} used for this
+     *                     coordinate system axes.
+     * @param direction    The {@linkplain #getDirection direction} of this coordinate system axis.
+     * @param unit         The {@linkplain #getUnit unit of measure} used for this coordinate
+     *                     system axis.
+     */
+    public DefaultCoordinateSystemAxis(final Map<String,?> properties,
+                                       final String        abbreviation,
+                                       final AxisDirection direction,
+                                       final Unit<?>       unit)
+    {
+        // NOTE: we would invoke this(properties, abbreviation, ...) instead if Sun fixed
+        // RFE #4093999 ("Relax constraint on placement of this()/super() call in constructors").
+        super(properties);
+        this.abbreviation = abbreviation;
+        this.direction    = direction;
+        this.unit         = unit;
+        ensureNonNull("abbreviation", abbreviation);
+        ensureNonNull("direction",    direction);
+        ensureNonNull("unit",         unit);
+        if (unit.isCompatible(NonSI.DEGREE_ANGLE)) {
+            final UnitConverter fromDegrees = NonSI.DEGREE_ANGLE.getConverterTo(unit);
+            final AxisDirection dir = direction.absolute();
+            if (dir.equals(AxisDirection.NORTH)) {
+                final double range = Math.abs(fromDegrees.convert(90));
+                minimum = -range;
+                maximum = +range;
+                rangeMeaning = RangeMeaning.EXACT; // 90°N do not wraps to 90°S
+                return;
+            }
+            if (dir.equals(AxisDirection.EAST)) {
+                final double range = Math.abs(fromDegrees.convert(180));
+                minimum = -range;
+                maximum = +range;
+                rangeMeaning = RangeMeaning.WRAPAROUND; // 180°E wraps to 180°W
+                return;
+            }
+        }
+        minimum = Double.NEGATIVE_INFINITY;
+        maximum = Double.POSITIVE_INFINITY;
+        rangeMeaning = RangeMeaning.EXACT;
+    }
+
+    /**
+     * Constructs an axis with a name as an {@linkplain InternationalString international string}
+     * and an abbreviation. The {@linkplain #getName name of this identified object} is set to the
+     * unlocalized version of the {@code name} argument, as given by
+     * <code>name.{@linkplain InternationalString#toString(Locale) toString}(null)</code>. The
+     * same {@code name} argument is also stored as an {@linkplain #getAlias alias}, which
+     * allows fetching localized versions of the name.
+     *
+     * @param name         The name of this axis. Also stored as an alias for localization purpose.
+     * @param abbreviation The {@linkplain #getAbbreviation abbreviation} used for this
+     *                     coordinate system axis.
+     * @param direction    The {@linkplain #getDirection direction} of this coordinate system axis.
+     * @param unit         The {@linkplain #getUnit unit of measure} used for this coordinate
+     *                     system axis.
+     */
+    public DefaultCoordinateSystemAxis(final InternationalString name,
+                                       final String        abbreviation,
+                                       final AxisDirection direction,
+                                       final Unit<?>       unit)
+    {
+        this(toMap(name), abbreviation, direction, unit);
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private static Map<String,Object> toMap(final InternationalString name) {
+        final Map<String,Object> properties = new HashMap<String,Object>(4);
+        if (name != null) {
+            // The "null" locale argument is required for getting the unlocalized version.
+            properties.put(NAME_KEY,  name.toString(null));
+            properties.put(ALIAS_KEY, NameFactory.create(new InternationalString[] {name}));
+        }
+        return properties;
+    }
+
+    /**
+     * Constructs an axis with a name and an abbreviation as a resource bundle key.
+     * To be used for construction of pre-defined constants only.
+     *
+     * @param name         The resource bundle key for the name.
+     * @param abbreviation The {@linkplain #getAbbreviation abbreviation} used for this
+     *                     coordinate system axes.
+     * @param direction    The {@linkplain #getDirection direction} of this coordinate system axis.
+     * @param unit         The {@linkplain #getUnit unit of measure} used for this coordinate
+     *                     system axis.
+     */
+    private DefaultCoordinateSystemAxis(final int           name,
+                                        final String        abbreviation,
+                                        final AxisDirection direction,
+                                        final Unit<?>       unit)
+    {
+        this(name>=0 ? Vocabulary.formatInternational(name) :
+                new SimpleInternationalString(abbreviation), abbreviation, direction, unit);
+        PREDEFINED[PREDEFINED_COUNT++] = this;
+    }
+
+    /**
+     * Returns one of the predefined axis for the given name and direction, or {@code null} if
+     * none. This method searchs only in predefined constants like {@link #GEODETIC_LATITUDE},
+     * not in any custom axis instantiated by a public constructor. The name of those constants
+     * match ISO 19111 names or some names commonly found in <cite>Well Known Text</cite> (WKT)
+     * formats.
+     * <p>
+     * This method first checks if the specified name matches the {@linkplain #getAbbreviation
+     * abbreviation} of a predefined axis. The comparaison is case-sensitive (for example the
+     * {@link #GEOCENTRIC_X} abbreviation is uppercase {@code "X"}, while the abbreviation for
+     * the generic {@link #X} axis is lowercase {@code "x"}).
+     * <p>
+     * If the specified name doesn't match any abbreviation, then this method compares the name
+     * against predefined axis {@linkplain #getName name} in a case-insensitive manner. Examples
+     * of valid names are "<cite>Geodetic latitude</cite>" and "<cite>Northing</cite>".
+     * <p>
+     * The direction argument is optional and can be used in order to resolve ambiguity like
+     * {@link #X} and {@link #DISPLAY_X} axis. If this argument is {@code null}, then the first
+     * axis with a matching name or abbreviation will be returned.
+     *
+     * @param  name The axis name or abbreviation.
+     * @param  direction An optional direction, or {@code null}.
+     * @return One of the constants declared in this class, or {@code null}.
+     *
+     * @since 2.4
+     */
+    public static DefaultCoordinateSystemAxis getPredefined(String name, AxisDirection direction) {
+        ensureNonNull("name", name);
+        name = name.trim();
+        DefaultCoordinateSystemAxis found = null;
+        for (int i=0; i<PREDEFINED_COUNT; i++) {
+            final DefaultCoordinateSystemAxis candidate = PREDEFINED[i];
+            if (direction != null && !direction.equals(candidate.getDirection())) {
+                continue;
+            }
+            // Reminder: case matter for abbreviation, so 'equalsIgnoreCase' is not allowed.
+            if (candidate.abbreviation.equals(name)) {
+                return candidate;
+            }
+            if (found == null && candidate.nameMatches(name)) {
+                /*
+                 * We need to perform a special check for Geodetic longitude and latitude.
+                 * Because of the ALIAS map, the "Geodetic latitude" and "Latitude" names
+                 * are considered equivalent, while they are two distinct predefined axis
+                 * constants in Geotools. Because Geodetic longitude & latitude constants
+                 * are declared first, they have precedence.  So we prevent the selection
+                 * of GEODETIC_LATITUDE if the user is likely to ask for LATITUDE.
+                 */
+                if (candidate == GEODETIC_LONGITUDE || candidate == GEODETIC_LATITUDE) {
+                    if (!name.toLowerCase().startsWith("geodetic")) {
+                        continue;
+                    }
+                }
+                found = candidate;
+            }
+        }
+        return found;
+    }
+
+    /**
+     * Returns a predefined axis similar to the specified one except for units.
+     * Returns {@code null} if no predefined axis match.
+     */
+    static DefaultCoordinateSystemAxis getPredefined(final CoordinateSystemAxis axis) {
+        return getPredefined(axis.getName().getCode(), axis.getDirection());
+    }
+
+    /**
+     * Direction of this coordinate system axis. In the case of Cartesian projected
+     * coordinates, this is the direction of this coordinate system axis locally.
+     * Examples:
+     * {@linkplain AxisDirection#NORTH north} or {@linkplain AxisDirection#SOUTH south},
+     * {@linkplain AxisDirection#EAST  east}  or {@linkplain AxisDirection#WEST  west},
+     * {@linkplain AxisDirection#UP    up}    or {@linkplain AxisDirection#DOWN  down}.
+     *
+     * <P>Within any set of coordinate system axes, only one of each pair of terms
+     * can be used. For earth-fixed coordinate reference systems, this direction is often
+     * approximate and intended to provide a human interpretable meaning to the axis. When a
+     * geodetic datum is used, the precise directions of the axes may therefore vary slightly
+     * from this approximate direction.</P>
+     *
+     * <P>Note that an {@link org.geotools.referencing.crs.DefaultEngineeringCRS} often requires
+     * specific descriptions of the directions of its coordinate system axes.</P>
+     */
+    public AxisDirection getDirection() {
+        return direction;
+    }
+
+    /**
+     * The abbreviation used for this coordinate system axes. This abbreviation is also
+     * used to identify the ordinates in coordinate tuple. Examples are "<var>X</var>"
+     * and "<var>Y</var>".
+     *
+     * @return The coordinate system axis abbreviation.
+     */
+    public String getAbbreviation() {
+        return abbreviation;
+    }
+
+    /**
+     * The unit of measure used for this coordinate system axis. The value of this
+     * coordinate in a coordinate tuple shall be recorded using this unit of measure,
+     * whenever those coordinates use a coordinate reference system that uses a
+     * coordinate system that uses this axis.
+     */
+    public Unit<?> getUnit() {
+        return unit;
+    }
+
+    /**
+     * Returns the minimum value normally allowed for this axis, in the
+     * {@linkplain #getUnit unit of measure for the axis}. If there is no minimum value, then
+     * this method returns {@linkplain Double#NEGATIVE_INFINITY negative infinity}.
+     *
+     * @since 2.3
+     */
+    public double getMinimumValue() {
+        return minimum;
+    }
+
+    /**
+     * Returns the maximum value normally allowed for this axis, in the
+     * {@linkplain #getUnit unit of measure for the axis}. If there is no maximum value, then
+     * this method returns {@linkplain Double#POSITIVE_INFINITY negative infinity}.
+     *
+     * @since 2.3
+     */
+    public double getMaximumValue() {
+        return maximum;
+    }
+
+    /**
+     * Returns the meaning of axis value range specified by the {@linkplain #getMinimumValue
+     * minimum} and {@linkplain #getMaximumValue maximum} values. This element shall be omitted
+     * when both minimum and maximum values are omitted. It may be included when minimum and/or
+     * maximum values are included. If this element is omitted when minimum or maximum values are
+     * included, the meaning is unspecified.
+     *
+     * @since 2.3
+     */
+    public RangeMeaning getRangeMeaning() {
+        return rangeMeaning;
+    }
+
+    /**
+     * Returns an axis with the opposite direction of this one, or {@code null} if unknown.
+     * This method is not public because only a few predefined constants have this information.
+     */
+    final DefaultCoordinateSystemAxis getOpposite() {
+        return opposite;
+    }
+
+    /*
+     * Returns {@code true} if the specified direction is a direction along a meridian.
+     * Those directions are used in coordinate systems for polar area. Examples:
+     * "<cite>North along 90 deg East</cite>", "<cite>North along 0 deg</cite>".
+     *
+     * We do not provide such method yet. If we want this functionality, maybe we should
+     * consider making DirectionAlongMeridian a public class extending AxisDirection code
+     * list instead.
+     */
+//  public static boolean isDirectionAlongMeridian(final AxisDirection direction);
+
+    /**
+     * Returns the arithmetic (counterclockwise) angle from the first direction to the second
+     * direction, in decimal <strong>degrees</strong>. This method returns a value between
+     * -180° and +180°, or {@link Double#NaN NaN} if no angle can be computed.
+     * <p>
+     * A positive angle denotes a right-handed system, while a negative angle denotes
+     * a left-handed system. Example:
+     * <p>
+     * <ul>
+     *   <li>The angle from {@linkplain AxisDirection#EAST EAST} to
+     *       {@linkplain AxisDirection#NORTH NORTH} is 90°</li>
+     *   <li>The angle from {@linkplain AxisDirection#SOUTH SOUTH} to
+     *       {@linkplain AxisDirection#WEST WEST} is -90°</li>
+     *   <li>The angle from "<cite>North along 90 deg East</cite>" to
+     *       "<cite>North along 0 deg</cite>" is 90°.</li>
+     * </ul>
+     *
+     * @param  source The source axis direction.
+     * @param  target The target axis direction.
+     * @return The arithmetic angle (in degrees) of the rotation to apply on a line pointing toward
+     *         the source direction in order to make it point toward the target direction, or
+     *         {@link Double#NaN} if this value can't be computed.
+     *
+     * @since 2.4
+     */
+    public static double getAngle(final AxisDirection source, final AxisDirection target) {
+        ensureNonNull("source", source);
+        ensureNonNull("target", target);
+        // Tests for NORTH, SOUTH, EAST, EAST-NORTH-EAST, etc. directions.
+        final int compass = getCompassAngle(source, target);
+        if (compass != Integer.MIN_VALUE) {
+            return compass * (360.0 / COMPASS_DIRECTION_COUNT);
+        }
+        // Tests for "South along 90 deg East", etc. directions.
+        final DirectionAlongMeridian src = DirectionAlongMeridian.parse(source);
+        if (src != null) {
+            final DirectionAlongMeridian tgt = DirectionAlongMeridian.parse(target);
+            if (tgt != null) {
+                return src.getAngle(tgt);
+            }
+        }
+        return Double.NaN;
+    }
+
+    /**
+     * Tests for angle on compass only (do not tests angle between direction along meridians).
+     * Returns {@link Integer#MIN_VALUE} if the angle can't be computed.
+     */
+    static int getCompassAngle(final AxisDirection source, final AxisDirection target) {
+        final int base = AxisDirection.NORTH.ordinal();
+        final int src  = source.ordinal() - base;
+        if (src >= 0 && src < COMPASS_DIRECTION_COUNT) {
+            int tgt = target.ordinal() - base;
+            if (tgt >= 0 && tgt < COMPASS_DIRECTION_COUNT) {
+                tgt = src - tgt;
+                if (tgt < -COMPASS_DIRECTION_COUNT/2) {
+                    tgt += COMPASS_DIRECTION_COUNT;
+                } else if (tgt > COMPASS_DIRECTION_COUNT/2) {
+                    tgt -= COMPASS_DIRECTION_COUNT;
+                }
+                return tgt;
+            }
+        }
+        return Integer.MIN_VALUE;
+    }
+
+    /**
+     * Returns a new axis with the same properties than current axis except for the units.
+     *
+     * @param newUnit The unit for the new axis.
+     * @return An axis using the specified unit.
+     * @throws IllegalArgumentException If the specified unit is incompatible with the expected one.
+     */
+    final DefaultCoordinateSystemAxis usingUnit(final Unit<?> newUnit)
+            throws IllegalArgumentException
+    {
+        if (unit.equals(newUnit)) {
+            return this;
+        }
+        if (unit.isCompatible(newUnit)) {
+            return new DefaultCoordinateSystemAxis(getProperties(this, null),
+                       abbreviation, direction, newUnit, minimum, maximum, rangeMeaning);
+        }
+        throw new IllegalArgumentException(Errors.format(ErrorKeys.INCOMPATIBLE_UNIT_$1, newUnit));
+    }
+
+    /**
+     * Returns {@code true} if either the {@linkplain #getName() primary name} or at least
+     * one {@linkplain #getAlias alias} matches the specified string. This method performs
+     * all the searh done by the {@linkplain AbstractIdentifiedObject#nameMatches(String)
+     * super-class}, with the addition of special processing for latitudes and longitudes:
+     * <p>
+     * <ul>
+     *   <li>{@code "Lat"}, {@code "Latitude"} and {@code "Geodetic latitude"} are considered
+     *       equivalent.</li>
+     *   <li>{@code "Lon"}, {@code "Longitude"} and {@code "Geodetic longitude"} are considered
+     *       equivalent.</li>
+     * </ul>
+     * <p>
+     * The above special cases are needed in order to workaround a conflict in specifications:
+     * ISO 19111 explicitly state that the latitude and longitude axis names shall be
+     * "Geodetic latitude" and "Geodetic longitude", will legacy OGC 01-009 (where WKT is defined)
+     * said that the default values shall be "Lat" and "Lon".
+     *
+     * @param  name The name to compare.
+     * @return {@code true} if the primary name of at least one alias
+     *         matches the specified {@code name}.
+     */
+    @Override
+    public boolean nameMatches(final String name) {
+        if (super.nameMatches(name)) {
+            return true;
+        }
+        /*
+         * The standard comparaisons didn't worked. Check for the aliases. Note: we don't
+         * test for 'nameMatchesXY(...)' here because the "x" and "y" axis names are too
+         * generic. We test them only in the 'equals' method, which has the extra-safety
+         * of units comparaison (so less risk to treat incompatible axis as equivalent).
+         *
+         * TODO: replace Object by CoordinateSystemAxis when we will be allowed
+         * to compile for J2SE 1.5.
+         */
+        final Object type = ALIASES.get(name.trim().toLowerCase());
+        return (type != null) && (type == ALIASES.get(getName().getCode().trim().toLowerCase()));
+    }
+
+    /**
+     * Compares the specified object with this axis for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            return equals((DefaultCoordinateSystemAxis) object, compareMetadata, true);
+        }
+        return false;
+    }
+
+    /**
+     * Compares the specified object with this axis for equality, with optional comparaison
+     * of units. Units should always be compared (they are not just metadata), except in the
+     * particular case of {@link AbstractCS#axisColinearWith}, which is used as a first step
+     * toward units conversions through {@link AbstractCS#swapAndScaleAxis}.
+     */
+    final boolean equals(final DefaultCoordinateSystemAxis that,
+                         final boolean compareMetadata, final boolean compareUnit)
+    {
+        if (compareMetadata) {
+            if (!Utilities.equals(this.abbreviation, that.abbreviation) ||
+                !Utilities.equals(this.rangeMeaning, that.rangeMeaning) ||
+                Double.doubleToLongBits(minimum) != Double.doubleToLongBits(that.minimum) ||
+                Double.doubleToLongBits(maximum) != Double.doubleToLongBits(that.maximum))
+            {
+                return false;
+            }
+        } else {
+            /*
+             * Checking the abbreviation is not suffisient. For example the polar angle and the
+             * spherical latitude have the same abbreviation (theta).  Geotools extensions like
+             * "Longitude" (in addition of ISO 19111 "Geodetic longitude") bring more potential
+             * confusion. Furthermore, not all implementors will use the greek letters (even if
+             * they are part of ISO 19111).    For example most CRS in WKT format use the "Lat"
+             * abbreviation instead of the greek letter phi. For comparaisons without metadata,
+             * we ignore the unreliable abbreviation and check the axis name instead. These
+             * names are constrained by ISO 19111 specification (see class javadoc), so they
+             * should be reliable enough.
+             *
+             * Note: there is no need to execute this block if 'compareMetadata' is true,
+             *       because in this case a stricter check has already been performed by
+             *       the 'equals' method in the superclass.
+             */
+            final String thatName = that.getName().getCode();
+            if (!nameMatches(thatName)) {
+                // The above test checked for special cases ("Lat" / "Lon" aliases, etc.).
+                // The next line may not, but is tested anyway in case the user overrided
+                // the 'that.nameMatches(...)' method.
+                final String thisName = getName().getCode();
+                if (!nameMatches(that, thisName)) {
+                    // For the needs of AbstractCS.axisColinearWith(...), we must stop here.
+                    // In addition it may be safer to not test 'nameMatchesXY' when we don't
+                    // have the extra-safety of units comparaison, because "x" and "y" names
+                    // are too generic.
+                    if (!compareUnit) {
+                        return false;
+                    }
+                    // Last chance: check for the special case of "x" and "y" axis names.
+                    if (!nameMatchesXY(thatName, thisName) && !nameMatchesXY(thisName, thatName)) {
+                        return false;
+                    }
+                }
+            }
+        }
+        return Utilities.equals(this.direction, that.direction) &&
+               (!compareUnit || Utilities.equals(this.unit, that.unit));
+    }
+
+    /**
+     * Returns a hash value for this axis. This value doesn't need to be the same
+     * in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        int code = (int)serialVersionUID;
+        code = code*37 + abbreviation.hashCode();
+        code = code*37 + direction   .hashCode();
+        code = code*37 + unit        .hashCode();
+        return code;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultCylindricalCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultCylindricalCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultCylindricalCS.java	(revision 28000)
@@ -0,0 +1,81 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.Map;
+import org.opengis.referencing.cs.CylindricalCS;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+
+
+/**
+ * A three-dimensional coordinate system consisting of a
+ * {@linkplain DefaultPolarCS polar coordinate system} extended by a straight
+ * coordinate axis perpendicular to the plane spanned by the polar coordinate system.
+ * A {@code CylindricalCS} shall have three {@linkplain #getAxis axis}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.geotools.referencing.crs.DefaultEngineeringCRS Engineering}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DefaultCylindricalCS.java $
+ * @version $Id: DefaultCylindricalCS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see DefaultPolarCS
+ */
+public class DefaultCylindricalCS extends AbstractCS implements CylindricalCS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -8290402732390917907L;
+
+    /**
+     * Constructs a three-dimensional coordinate system from a set of properties.
+     * The properties map is given unchanged to the
+     * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis0 The first axis.
+     * @param axis1 The second axis.
+     * @param axis2 The third axis.
+     */
+    public DefaultCylindricalCS(final Map<String,?>   properties,
+                                final CoordinateSystemAxis axis0,
+                                final CoordinateSystemAxis axis1,
+                                final CoordinateSystemAxis axis2)
+    {
+        super(properties, new CoordinateSystemAxis[] {axis0, axis1, axis2});
+    }
+
+    /**
+     * Returns {@code true} if the specified axis direction is allowed for this coordinate
+     * system. The default implementation accepts all directions except temporal ones (i.e.
+     * {@link AxisDirection#FUTURE FUTURE} and {@link AxisDirection#PAST PAST}).
+     */
+    @Override
+    protected boolean isCompatibleDirection(final AxisDirection direction) {
+        return !AxisDirection.FUTURE.equals(direction.absolute());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultEllipsoidalCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultEllipsoidalCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultEllipsoidalCS.java	(revision 28000)
@@ -0,0 +1,152 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.Map;
+
+import javax.measure.unit.NonSI;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.cs.EllipsoidalCS;
+
+
+/**
+ * A two- or three-dimensional coordinate system in which position is specified by geodetic
+ * latitude, geodetic longitude, and (in the three-dimensional case) ellipsoidal height. An
+ * {@code EllipsoidalCS} shall have two or three {@linkplain #getAxis axis}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.geotools.referencing.crs.DefaultGeographicCRS  Geographic},
+ *   {@link org.geotools.referencing.crs.DefaultEngineeringCRS Engineering}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DefaultEllipsoidalCS.java $
+ * @version $Id: DefaultEllipsoidalCS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultEllipsoidalCS extends AbstractCS implements EllipsoidalCS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -1452492488902329211L;
+
+    /**
+     * A two-dimensional ellipsoidal CS with
+     * <var>{@linkplain DefaultCoordinateSystemAxis#GEODETIC_LONGITUDE geodetic longitude}</var>,
+     * <var>{@linkplain DefaultCoordinateSystemAxis#GEODETIC_LATITUDE geodetic latitude}</var>
+     * axis in decimal degrees.
+     */
+    public static DefaultEllipsoidalCS GEODETIC_2D = new DefaultEllipsoidalCS(
+                    name(VocabularyKeys.GEODETIC_2D),
+                    DefaultCoordinateSystemAxis.GEODETIC_LONGITUDE,
+                    DefaultCoordinateSystemAxis.GEODETIC_LATITUDE);
+
+    /**
+     * A three-dimensional ellipsoidal CS with
+     * <var>{@linkplain DefaultCoordinateSystemAxis#GEODETIC_LONGITUDE geodetic longitude}</var>,
+     * <var>{@linkplain DefaultCoordinateSystemAxis#GEODETIC_LATITUDE geodetic latitude}</var>,
+     * <var>{@linkplain DefaultCoordinateSystemAxis#ELLIPSOIDAL_HEIGHT ellipsoidal height}</var>
+     * axis.
+     */
+    public static DefaultEllipsoidalCS GEODETIC_3D = new DefaultEllipsoidalCS(
+                    name(VocabularyKeys.GEODETIC_3D),
+                    DefaultCoordinateSystemAxis.GEODETIC_LONGITUDE,
+                    DefaultCoordinateSystemAxis.GEODETIC_LATITUDE,
+                    DefaultCoordinateSystemAxis.ELLIPSOIDAL_HEIGHT);
+
+    /**
+     * Constructs a two-dimensional coordinate system from a set of properties.
+     * The properties map is given unchanged to the
+     * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis0 The first axis.
+     * @param axis1 The second axis.
+     */
+    public DefaultEllipsoidalCS(final Map<String,?>   properties,
+                                final CoordinateSystemAxis axis0,
+                                final CoordinateSystemAxis axis1)
+    {
+        super(properties, new CoordinateSystemAxis[] {axis0, axis1});
+    }
+
+    /**
+     * Constructs a three-dimensional coordinate system from a set of properties.
+     * The properties map is given unchanged to the
+     * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis0 The first axis.
+     * @param axis1 The second axis.
+     * @param axis2 The third axis.
+     */
+    public DefaultEllipsoidalCS(final Map<String,?>   properties,
+                                final CoordinateSystemAxis axis0,
+                                final CoordinateSystemAxis axis1,
+                                final CoordinateSystemAxis axis2)
+    {
+        super(properties, new CoordinateSystemAxis[] {axis0, axis1, axis2});
+    }
+
+    /**
+     * For {@link #usingUnit} usage only.
+     */
+    private DefaultEllipsoidalCS(final Map<String,?> properties, final CoordinateSystemAxis[] axis) {
+        super(properties, axis);
+    }
+
+    /**
+     * Returns {@code true} if the specified axis direction is allowed for this coordinate
+     * system. The default implementation accepts only the following directions:
+     * {@link AxisDirection#NORTH NORTH}, {@link AxisDirection#SOUTH SOUTH},
+     * {@link AxisDirection#EAST  EAST},  {@link AxisDirection#WEST  WEST},
+     * {@link AxisDirection#UP    UP} and {@link AxisDirection#DOWN  DOWN}.
+     */
+    @Override
+    protected boolean isCompatibleDirection(AxisDirection direction) {
+        direction = direction.absolute();
+        return AxisDirection.NORTH.equals(direction) ||
+               AxisDirection.EAST .equals(direction) ||
+               AxisDirection.UP   .equals(direction);
+    }
+
+    /**
+     * Returns {@code true} if the specified unit is compatible with
+     * {@linkplain NonSI#DEGREE_ANGLE decimal degrees} (or {@linkplain SI#METER meters} in the
+     * special case of height). This method is invoked at construction time for checking units
+     * compatibility.
+     *
+     * @since 2.2
+     */
+    @Override
+    protected boolean isCompatibleUnit(AxisDirection direction, final Unit<?> unit) {
+        direction = direction.absolute();
+        final Unit<?> expected = AxisDirection.UP.equals(direction) ? SI.METER : NonSI.DEGREE_ANGLE;
+        return expected.isCompatible(unit);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultLinearCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultLinearCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultLinearCS.java	(revision 28000)
@@ -0,0 +1,82 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.Map;
+import org.opengis.referencing.cs.LinearCS;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.geotools.measure.Measure;
+
+
+/**
+ * A one-dimensional coordinate system that consists of the points that lie on the single axis
+ * described. The associated ordinate is the distance from the specified origin to the point
+ * along the axis. Example: usage of the line feature representing a road to describe points
+ * on or along that road. A {@code LinearCS} shall have one
+ * {@linkplain #getAxis axis}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.geotools.referencing.crs.DefaultEngineeringCRS Engineering}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DefaultLinearCS.java $
+ * @version $Id: DefaultLinearCS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultLinearCS extends AbstractCS implements LinearCS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -6890723478287625763L;
+
+    /**
+     * Constructs a coordinate system from a set of properties.
+     * The properties map is given unchanged to the
+     * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis       The axis.
+     */
+    public DefaultLinearCS(final Map<String,?> properties, final CoordinateSystemAxis axis) {
+        super(properties, new CoordinateSystemAxis[] {axis});
+    }
+
+    /**
+     * Computes the distance between two points.
+     *
+     * @param  coord1 Coordinates of the first point.
+     * @param  coord2 Coordinates of the second point.
+     * @return The distance between {@code coord1} and {@code coord2}.
+     * @throws MismatchedDimensionException if a coordinate doesn't have the expected dimension.
+     */
+    @Override
+    public Measure distance(final double[] coord1, final double[] coord2)
+            throws MismatchedDimensionException
+    {
+        ensureDimensionMatch("coord1", coord1);
+        ensureDimensionMatch("coord2", coord2);
+        return new Measure(Math.abs(coord1[0] - coord2[0]), getDistanceUnit());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultPolarCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultPolarCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultPolarCS.java	(revision 28000)
@@ -0,0 +1,78 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.Map;
+import org.opengis.referencing.cs.PolarCS;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+
+
+/**
+ * A two-dimensional coordinate system in which position is specified by the distance from the
+ * origin and the angle between the line from the origin to a point and a reference direction.
+ * A {@code PolarCS} shall have two {@linkplain #getAxis axis}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.geotools.referencing.crs.DefaultEngineeringCRS Engineering}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DefaultPolarCS.java $
+ * @version $Id: DefaultPolarCS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see DefaultCylindricalCS
+ */
+public class DefaultPolarCS extends AbstractCS implements PolarCS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 3960197260975470951L;
+
+    /**
+     * Constructs a two-dimensional coordinate system from a set of properties.
+     * The properties map is given unchanged to the
+     * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis0 The first axis.
+     * @param axis1 The second axis.
+     */
+    public DefaultPolarCS(final Map<String,?>   properties,
+                          final CoordinateSystemAxis axis0,
+                          final CoordinateSystemAxis axis1)
+    {
+        super(properties, new CoordinateSystemAxis[] {axis0, axis1});
+    }
+
+    /**
+     * Returns {@code true} if the specified axis direction is allowed for this coordinate
+     * system. The default implementation accepts all directions except temporal ones (i.e.
+     * {@link AxisDirection#FUTURE FUTURE} and {@link AxisDirection#PAST PAST}).
+     */
+    @Override
+    protected boolean isCompatibleDirection(final AxisDirection direction) {
+        return !AxisDirection.FUTURE.equals(direction.absolute());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultSphericalCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultSphericalCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultSphericalCS.java	(revision 28000)
@@ -0,0 +1,96 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.Map;
+import org.opengis.referencing.cs.SphericalCS;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.geotools.resources.i18n.VocabularyKeys;
+
+
+/**
+ * A three-dimensional coordinate system with one distance measured from the origin and two angular
+ * coordinates. Not to be confused with an {@linkplain DefaultEllipsoidalCS ellipsoidal coordinate
+ * system} based on an ellipsoid "degenerated" into a sphere. A {@code SphericalCS} shall have
+ * three {@linkplain #getAxis axis}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.geotools.referencing.crs.DefaultGeocentricCRS  Geocentric},
+ *   {@link org.geotools.referencing.crs.DefaultEngineeringCRS Engineering}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DefaultSphericalCS.java $
+ * @version $Id: DefaultSphericalCS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultSphericalCS extends AbstractCS implements SphericalCS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 196295996465774477L;
+
+    /**
+     * A three-dimensional spherical CS with
+     * <var>{@linkplain DefaultCoordinateSystemAxis#SPHERICAL_LONGITUDE longitude}</var>,
+     * <var>{@linkplain DefaultCoordinateSystemAxis#SPHERICAL_LATITUDE latitude}</var>,
+     * <var>{@linkplain DefaultCoordinateSystemAxis#GEOCENTRIC_RADIUS radius}</var>
+     * axis.
+     *
+     * @see DefaultCartesianCS#GEOCENTRIC
+     */
+    public static DefaultSphericalCS GEOCENTRIC = new DefaultSphericalCS(
+                    name(VocabularyKeys.GEOCENTRIC),
+                    DefaultCoordinateSystemAxis.SPHERICAL_LONGITUDE,
+                    DefaultCoordinateSystemAxis.SPHERICAL_LATITUDE,
+                    DefaultCoordinateSystemAxis.GEOCENTRIC_RADIUS);
+
+    /**
+     * Constructs a three-dimensional coordinate system from a set of properties.
+     * The properties map is given unchanged to the
+     * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis0 The first axis.
+     * @param axis1 The second axis.
+     * @param axis2 The third axis.
+     */
+    public DefaultSphericalCS(final Map<String,?>   properties,
+                              final CoordinateSystemAxis axis0,
+                              final CoordinateSystemAxis axis1,
+                              final CoordinateSystemAxis axis2)
+    {
+        super(properties, new CoordinateSystemAxis[] {axis0, axis1, axis2});
+    }
+
+    /**
+     * Returns {@code true} if the specified axis direction is allowed for this coordinate
+     * system. The default implementation accepts all directions except temporal ones (i.e.
+     * {@link AxisDirection#FUTURE FUTURE} and {@link AxisDirection#PAST PAST}).
+     */
+    @Override
+    protected boolean isCompatibleDirection(final AxisDirection direction) {
+        return !AxisDirection.FUTURE.equals(direction.absolute());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultTimeCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultTimeCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultTimeCS.java	(revision 28000)
@@ -0,0 +1,133 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.Map;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+import org.opengis.referencing.cs.TimeCS;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.util.InternationalString;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.geometry.MismatchedDimensionException;
+
+import org.geotools.measure.Measure;
+import org.geotools.resources.i18n.VocabularyKeys;
+
+
+/**
+ * A one-dimensional coordinate system containing a single time axis, used to describe the
+ * temporal position of a point in the specified time units from a specified time origin.
+ * A {@code TimeCS} shall have one {@linkplain #getAxis axis}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.geotools.referencing.crs.DefaultTemporalCRS Temporal}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DefaultTimeCS.java $
+ * @version $Id: DefaultTimeCS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultTimeCS extends AbstractCS implements TimeCS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 5222911412381303989L;
+
+    /**
+     * A one-dimensional temporal CS with
+     * <var>{@linkplain DefaultCoordinateSystemAxis#TIME time}</var>,
+     * axis in {@linkplain javax.measure.unit.NonSI#DAY day} units.
+     *
+     * @see org.geotools.referencing.crs.DefaultTemporalCRS#JULIAN
+     * @see org.geotools.referencing.crs.DefaultTemporalCRS#MODIFIED_JULIAN
+     * @see org.geotools.referencing.crs.DefaultTemporalCRS#TRUNCATED_JULIAN
+     * @see org.geotools.referencing.crs.DefaultTemporalCRS#DUBLIN_JULIAN
+     */
+    public static final DefaultTimeCS DAYS;
+
+    /**
+     * Creates the constants, reusing some intermediate constructs for efficienty.
+     */
+    static {
+        final Map<String,Object> properties = name(VocabularyKeys.TEMPORAL);
+        CoordinateSystemAxis axis = DefaultCoordinateSystemAxis.TIME;
+        DAYS = new DefaultTimeCS(properties, axis);
+        final InternationalString name = axis.getAlias().iterator().next().toInternationalString();
+        axis = new DefaultCoordinateSystemAxis(name, "t", AxisDirection.FUTURE, SI.SECOND);
+        axis = new DefaultCoordinateSystemAxis(name, "t", AxisDirection.FUTURE, SI.MILLI(SI.SECOND));
+    }
+
+    /**
+     * Constructs a coordinate system from a set of properties.
+     * The properties map is given unchanged to the
+     * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis       The axis.
+     */
+    public DefaultTimeCS(final Map<String,?> properties, final CoordinateSystemAxis axis) {
+        super(properties, new CoordinateSystemAxis[] {axis});
+        ensureTimeUnit(getAxis(0).getUnit());
+    }
+
+    /**
+     * Returns {@code true} if the specified axis direction is allowed for this coordinate
+     * system. The default implementation accepts only temporal directions (i.e.
+     * {@link AxisDirection#FUTURE FUTURE} and {@link AxisDirection#PAST PAST}).
+     */
+    @Override
+    protected boolean isCompatibleDirection(final AxisDirection direction) {
+        return AxisDirection.FUTURE.equals(direction.absolute());
+    }
+
+    /**
+     * Returns {@code true} if the specified unit is compatible with {@linkplain SI#SECOND seconds}.
+     * This method is invoked at construction time for checking units compatibility.
+     *
+     * @since 2.2
+     */
+    @Override
+    protected boolean isCompatibleUnit(final AxisDirection direction, final Unit<?> unit) {
+        return SI.SECOND.isCompatible(unit);
+    }
+
+    /**
+     * Computes the time difference between two points.
+     *
+     * @param  coord1 Coordinates of the first point.
+     * @param  coord2 Coordinates of the second point.
+     * @return The time difference between {@code coord1} and {@code coord2}.
+     * @throws MismatchedDimensionException if a coordinate doesn't have the expected dimension.
+     */
+    @Override
+    public Measure distance(final double[] coord1, final double[] coord2)
+            throws MismatchedDimensionException
+    {
+        ensureDimensionMatch("coord1", coord1);
+        ensureDimensionMatch("coord2", coord2);
+        return new Measure(Math.abs(coord1[0] - coord2[0]), getDistanceUnit());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultUserDefinedCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultUserDefinedCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultUserDefinedCS.java	(revision 28000)
@@ -0,0 +1,81 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.Map;
+import org.opengis.referencing.cs.UserDefinedCS;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+
+
+/**
+ * A two- or three-dimensional coordinate system that consists of any combination of coordinate
+ * axes not covered by any other Coordinate System type. An example is a multilinear coordinate
+ * system which contains one coordinate axis that may have any 1-D shape which has no intersections
+ * with itself. This non-straight axis is supplemented by one or two straight axes to complete a 2
+ * or 3 dimensional coordinate system. The non-straight axis is typically incrementally straight or
+ * curved. A {@code UserDefinedCS} shall have two or three
+ * {@linkplain #getAxis axis}.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DefaultUserDefinedCS.java $
+ * @version $Id: DefaultUserDefinedCS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultUserDefinedCS extends AbstractCS implements UserDefinedCS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -4904091898305706316L;
+
+    /**
+     * Constructs a two-dimensional coordinate system from a set of properties.
+     * The properties map is given unchanged to the
+     * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis0 The first axis.
+     * @param axis1 The second axis.
+     */
+    public DefaultUserDefinedCS(final Map<String,?>   properties,
+                                final CoordinateSystemAxis axis0,
+                                final CoordinateSystemAxis axis1)
+    {
+        super(properties, new CoordinateSystemAxis[] {axis0, axis1});
+    }
+
+    /**
+     * Constructs a three-dimensional coordinate system from a set of properties.
+     * The properties map is given unchanged to the
+     * {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis0 The first axis.
+     * @param axis1 The second axis.
+     * @param axis2 The third axis.
+     */
+    public DefaultUserDefinedCS(final Map<String,?>   properties,
+                                final CoordinateSystemAxis axis0,
+                                final CoordinateSystemAxis axis1,
+                                final CoordinateSystemAxis axis2)
+    {
+        super(properties, new CoordinateSystemAxis[] {axis0, axis1, axis2});
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultVerticalCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultVerticalCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DefaultVerticalCS.java	(revision 28000)
@@ -0,0 +1,115 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.Map;
+
+import org.opengis.referencing.cs.VerticalCS;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.geometry.MismatchedDimensionException;
+
+import org.geotools.measure.Measure;
+
+
+/**
+ * A one-dimensional coordinate system used to record the heights (or depths) of points. Such a
+ * coordinate system is usually dependent on the Earth's gravity field, perhaps loosely as when
+ * atmospheric pressure is the basis for the vertical coordinate system axis. An exact definition
+ * is deliberately not provided as the complexities of the subject fall outside the scope of this
+ * specification. A {@code VerticalCS} shall have one {@linkplain #getAxis axis}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.geotools.referencing.crs.DefaultVerticalCRS    Vertical},
+ *   {@link org.geotools.referencing.crs.DefaultEngineeringCRS Engineering}
+ * </TD></TR></TABLE>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DefaultVerticalCS.java $
+ * @version $Id: DefaultVerticalCS.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultVerticalCS extends AbstractCS implements VerticalCS {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 1201155778896630499L;;
+
+    /**
+     * A one-dimensional vertical CS with
+     * <var>{@linkplain DefaultCoordinateSystemAxis#ELLIPSOIDAL_HEIGHT
+     * ellipsoidal height}</var> axis in metres.
+     */
+    public static DefaultVerticalCS ELLIPSOIDAL_HEIGHT = new DefaultVerticalCS(
+                    DefaultCoordinateSystemAxis.ELLIPSOIDAL_HEIGHT);
+
+    /**
+     * Constructs a coordinate system with the same properties than the specified axis.
+     * The inherited properties include the {@linkplain #getName name} and aliases.
+     *
+     * @param axis The axis.
+     *
+     * @since 2.5
+     */
+    public DefaultVerticalCS(final CoordinateSystemAxis axis) {
+        super(getProperties(axis), new CoordinateSystemAxis[] {axis});
+    }
+
+    /**
+     * Constructs a coordinate system from a set of properties. The properties map is given unchanged
+     * to the {@linkplain AbstractCS#AbstractCS(Map,CoordinateSystemAxis[]) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param axis       The axis.
+     */
+    public DefaultVerticalCS(final Map<String,?> properties, final CoordinateSystemAxis axis) {
+        super(properties, new CoordinateSystemAxis[] {axis});
+    }
+
+    /**
+     * Returns {@code true} if the specified axis direction is allowed for this coordinate
+     * system. The default implementation accepts only vertical directions (i.e.
+     * {@link AxisDirection#UP UP} and {@link AxisDirection#DOWN DOWN}).
+     */
+    @Override
+    protected boolean isCompatibleDirection(final AxisDirection direction) {
+        return AxisDirection.UP.equals(direction.absolute());
+    }
+
+    /**
+     * Computes the distance between two points.
+     *
+     * @param  coord1 Coordinates of the first point.
+     * @param  coord2 Coordinates of the second point.
+     * @return The distance between {@code coord1} and {@code coord2}.
+     * @throws MismatchedDimensionException if a coordinate doesn't have the expected dimension.
+     */
+    @Override
+    public Measure distance(final double[] coord1, final double[] coord2)
+            throws MismatchedDimensionException
+    {
+        ensureDimensionMatch("coord1", coord1);
+        ensureDimensionMatch("coord2", coord2);
+        return new Measure(Math.abs(coord1[0] - coord2[0]), getDistanceUnit());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DirectionAlongMeridian.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DirectionAlongMeridian.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/DirectionAlongMeridian.java	(revision 28000)
@@ -0,0 +1,352 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.cs;
+
+import java.io.Serializable;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.opengis.referencing.cs.AxisDirection;
+
+
+/**
+ * Parses {@linkplain AxisDirection axis direction} of the kind
+ * "<cite>South along 90 deg East</cite>". Those directions are
+ * used in the EPSG database for polar stereographic projections.
+ *
+ * @version $Id: DirectionAlongMeridian.java 37409 2011-06-11 10:01:00Z aaime $
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/DirectionAlongMeridian.java $
+ * @author Martin Desruisseaux
+ * @since 2.7.2
+ */
+public final class DirectionAlongMeridian implements Comparable, Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 1602711631943838328L;
+
+    /**
+     * For floating point comparaisons.
+     */
+    static final double EPS = 1E-10;
+
+    /**
+     * A parser for EPSG axis names. Examples:
+     *
+     * "<cite>South along 180 deg</cite>",
+     * "<cite>South along 90 deg East</cite>"
+     */
+    private static final Pattern EPSG = Pattern.compile(
+            "(\\p{Graph}+)\\s+along\\s+([\\-\\p{Digit}\\.]+)\\s*(deg|°)\\s*(\\p{Graph}+)?",
+            Pattern.CASE_INSENSITIVE);
+
+    /**
+     * The base directions we are interested in. Any direction not in
+     * this group will be rejected by our parser.
+     */
+    private static final AxisDirection[] BASE_DIRECTIONS = new AxisDirection[] {
+        AxisDirection.NORTH,
+        AxisDirection.SOUTH,
+        AxisDirection.EAST,
+        AxisDirection.WEST
+    };
+
+    /**
+     * The direction. Will be created only when first needed.
+     *
+     * @see #getDirection
+     */
+    private transient AxisDirection direction;
+
+    /**
+     * The base direction, which must be {@link AxisDirection#NORTH} or
+     * {@link AxisDirection#SOUTH}.
+     */
+    public final AxisDirection baseDirection;
+
+    /**
+     * The meridian, in degrees.
+     */
+    public final double meridian;
+
+    /**
+     * Creates a direction.
+     */
+    private DirectionAlongMeridian(final AxisDirection baseDirection, final double meridian) {
+        this.baseDirection = baseDirection;
+        this.meridian      = meridian;
+    }
+
+    /**
+     * Returns the dimension along meridian for the specified axis direction, or {@code null} if
+     * none.
+     */
+    public static DirectionAlongMeridian parse(final AxisDirection direction) {
+        final DirectionAlongMeridian candidate = parse(direction.name());
+        if (candidate != null) {
+            candidate.direction = direction;
+        }
+        return candidate;
+    }
+
+    /**
+     * If the specified name is a direction along some specific meridian,
+     * returns information about that. Otherwise returns {@code null}.
+     */
+    public static DirectionAlongMeridian parse(final String name) {
+        final Matcher m = EPSG.matcher(name);
+        if (!m.matches()) {
+            // Not the expected pattern.
+            return null;
+        }
+        String group = m.group(1);
+        final AxisDirection baseDirection = findDirection(BASE_DIRECTIONS, group);
+        if (baseDirection == null || !AxisDirection.NORTH.equals(baseDirection.absolute())) {
+            // We expected "North" or "South" direction.
+            return null;
+        }
+        group = m.group(2);
+        double meridian;
+        try {
+            meridian = Double.parseDouble(group);
+        } catch (NumberFormatException exception) {
+            // Not a legal axis direction. Just ignore the exception,
+            // since we are supposed to return 'null' in this situation.
+            return null;
+        }
+        if (!(meridian >= -180 && meridian <= 180)) {
+            // Meridian is NaN or is not in the valid range.
+            return null;
+        }
+        group = m.group(4);
+        if (group != null) {
+            final AxisDirection sign = findDirection(BASE_DIRECTIONS, group);
+            final AxisDirection abs = sign.absolute();
+            if (!AxisDirection.EAST.equals(abs)) {
+                // We expected "East" or "West" direction.
+                return null;
+            }
+            if (sign != abs) {
+                meridian = -meridian;
+            }
+        }
+        return new DirectionAlongMeridian(baseDirection, meridian);
+    }
+
+    /**
+     * Searchs for the specified name in the specified set of directions.
+     */
+    private static AxisDirection findDirection(final AxisDirection[] values, final String direction) {
+        for (int i=0; i<values.length; i++) {
+            final AxisDirection candidate = values[i];
+            final String name = candidate.name();
+            if (direction.equalsIgnoreCase(name)) {
+                return candidate;
+            } 
+            
+            // check for common abbreviations
+            if(direction.length() == 1) {
+                if(candidate == AxisDirection.NORTH && direction.equals("N"))
+                    return candidate;
+                if(candidate == AxisDirection.SOUTH && direction.equals("S"))
+                    return candidate;
+                if(candidate == AxisDirection.WEST && direction.equals("W"))
+                    return candidate;
+                if(candidate == AxisDirection.EAST && direction.equals("E"))
+                    return candidate;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Searchs for the specified name.
+     */
+    static AxisDirection findDirection(String direction) {
+        final AxisDirection[] values = AxisDirection.values();
+        AxisDirection candidate = findDirection(values, direction);
+        if (candidate == null) {
+            String modified = direction.replace('-', '_');
+            if (modified != direction) {
+                direction = modified;
+                candidate = findDirection(values, modified);
+            }
+            if (candidate == null) {
+                modified = direction.replace(' ', '_');
+                if (modified != direction) {
+                    candidate = findDirection(values, modified);
+                }
+            }
+        }
+        return candidate;
+    }
+
+    /**
+     * Returns the axis direction for this object. If a suitable axis direction already exists,
+     * it will be returned. Otherwise a new one is created and returned.
+     */
+    public AxisDirection getDirection() {
+        if (direction != null) {
+            return direction;
+        }
+        final String name = toString();
+        synchronized (AxisDirection.class) {
+            /*
+             * The calls to  'AxisDirection.values()' and 'findDirection(...)'  should be performed
+             * inside the synchronized block, since we try to avoid the creation of many directions
+             * for the same name.   Strictly speaking, this synchronization is not suffisient since
+             * it doesn't apply to the creation of axis directions from outside this class.  But it
+             * okay if this code is the only place where we create axis directions with name of the
+             * kind "South among 90°E". This assumption holds for Geotools implementation.
+             */
+            direction = findDirection(name);
+            if (direction == null) {
+                direction = AxisDirection.valueOf(name);
+            }
+        }
+        return direction;
+    }
+
+    /**
+     * Returns the arithmetic (counterclockwise) angle from this direction to the specified
+     * direction, in decimal degrees. This method returns a value between -180° and +180°, or
+     * {@link Double#NaN NaN} if the {@linkplain #baseDirection base directions} don't match.
+     * A positive angle denote a right-handed system.
+     * <p>
+     * Example: the angle from "<cite>North along 90 deg East</cite>" to
+     * "<cite>North along 0 deg</cite> is 90°.
+     */
+    public double getAngle(final DirectionAlongMeridian other) {
+        if (!baseDirection.equals(other.baseDirection)) {
+            return Double.NaN;
+        }
+        /*
+         * We want the following pair of axis:
+         * (NORTH along 90°E, NORTH along 0°)
+         * to give a positive angle of 90°
+         */
+        double angle = meridian - other.meridian;
+        /*
+         * Forces to the [-180° .. +180°] range.
+         */
+        if (angle < -180) {
+            angle += 360;
+        } else if (angle > 180) {
+            angle -= 360;
+        }
+        /*
+         * Reverses the sign for axis oriented toward SOUTH,
+         * so a positive angle is a right-handed system.
+         */
+        if (!baseDirection.equals(baseDirection.absolute())) {
+            angle = -angle;
+        }
+        return angle;
+    }
+
+    /**
+     * Compares this direction with the specified one for order. This method tries to reproduce
+     * the ordering used for the majority of coordinate systems in the EPSG database, i.e. the
+     * ordering of a right-handed coordinate system. Examples of ordered pairs that we should
+     * get (extracted from the EPSG database):
+     *
+     * <table>
+     *   <tr><td>North along 90 deg East,</td>  <td>North along 0 deg</td></tr>
+     *   <tr><td>North along 75 deg West,</td>  <td>North along 165 deg West</td></tr>
+     *   <tr><td>South along 90 deg West,</td>  <td>South along 0 deg</td></tr>
+     *   <tr><td>South along 180 deg,</td>      <td>South along 90 deg West</td></tr>
+     *   <tr><td>North along 130 deg West</td>  <td>North along 140 deg East</td></tr>
+     * </table>
+     */
+    public int compareTo(final Object object) {
+        final DirectionAlongMeridian that = (DirectionAlongMeridian) object;
+        final int c = baseDirection.compareTo(that.baseDirection);
+        if (c != 0) {
+            return c;
+        }
+        final double angle = getAngle(that);
+        if (angle < 0) return +1;  // Really the opposite sign.
+        if (angle > 0) return -1;  // Really the opposite sign.
+        return 0;
+    }
+
+    /**
+     * Tests this object for equality with the specified one.
+     * This method is used mostly for assertions.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object instanceof DirectionAlongMeridian) {
+            final DirectionAlongMeridian that = (DirectionAlongMeridian) object;
+            return baseDirection.equals(that.baseDirection) &&
+                   Double.doubleToLongBits(meridian) == Double.doubleToLongBits(that.meridian);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value, for consistency with {@link #equals}.
+     */
+    @Override
+    public int hashCode() {
+        final long code = Double.doubleToLongBits(meridian);
+        return (int)serialVersionUID ^ (int)code ^ (int)(code >> 32) + 37*baseDirection.hashCode();
+    }
+
+    /**
+     * Returns a string representation of this direction, using a syntax matching the one used
+     * by EPSG. This string representation will be used for creating a new {@link AxisDirection}.
+     * The generated name should be identical to EPSG name, but we use the generated one anyway
+     * (rather than the one provided by EPSG) in order to make sure that we create a single
+     * {@link AxisDirection} for a given direction; we avoid potential differences like lower
+     * versus upper cases, amount of white space, <cite>etc</cite>.
+     */
+    @Override
+    public String toString() {
+        final StringBuilder buffer = new StringBuilder(baseDirection.name());
+        toLowerCase(buffer, 0);
+        buffer.append(" along ");
+        final double md = Math.abs(meridian);
+        final int    mi = (int) md;
+        if (md == mi) {
+            buffer.append(mi);
+        } else {
+            buffer.append(md);
+        }
+        buffer.append(" deg");
+        if (md != 0 && mi != 180) {
+            buffer.append(' ');
+            final int base = buffer.length();
+            final AxisDirection sign = meridian < 0 ? AxisDirection.WEST : AxisDirection.EAST;
+            buffer.append(sign.name());
+            toLowerCase(buffer, base);
+        }
+        final String name = buffer.toString();
+        assert EPSG.matcher(name).matches() : name;
+        return name;
+    }
+
+    /**
+     * Changes the buffer content to lower case from {@code base+1} to
+     * the end of the buffer. For {@link #toString} internal use only.
+     */
+    private static void toLowerCase(final StringBuilder buffer, final int base) {
+        for (int i=buffer.length(); --i>base;) {
+            buffer.setCharAt(i, Character.toLowerCase(buffer.charAt(i)));
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/PredefinedCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/PredefinedCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/PredefinedCS.java	(revision 28000)
@@ -0,0 +1,213 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.cs;
+
+import java.util.List;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Map;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+import org.opengis.referencing.cs.*;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * Converts an arbitrary CS into one of the predefined constants provided in the
+ * {@link org.geotools.referencing.cs} package. The main usage for this class is
+ * to reorder the axis in some "standard" order like (<var>x</var>, <var>y</var>,
+ * <var>z</var>) or (<var>longitude</var>, <var>latitude</var>). What "standard"
+ * order means is sometime an arbitrary choice, which explain why this class is
+ * not public at this time.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/cs/PredefinedCS.java $
+ * @version $Id: PredefinedCS.java 30760 2008-06-18 14:28:24Z desruisseaux $
+ * @author Martin Desruisseaux (IRD)
+ */
+final class PredefinedCS implements Comparator<CoordinateSystem> {
+    /**
+     * An instance of {@link PredefinedCS}. Will be created only when first needed.
+     */
+    private static Comparator<CoordinateSystem> csComparator;
+
+    /**
+     * Our ordering for coordinate system objects.
+     */
+    @SuppressWarnings("unchecked")
+    private final Class<? extends CoordinateSystem>[] types = new Class[] {
+        CartesianCS  .class,
+        AffineCS     .class,
+        EllipsoidalCS.class,
+        SphericalCS  .class,
+        CylindricalCS.class,
+        PolarCS      .class,
+        VerticalCS   .class,
+        TimeCS       .class,
+        LinearCS     .class,
+        UserDefinedCS.class
+    };
+
+    /**
+     * Creates a comparator.
+     */
+    private PredefinedCS() {
+    }
+
+    /**
+     * Compares the ordering between two coordinate systems. This comparator is used for sorting
+     * the axis in an user-supplied compound CS in an order closes to some "standard" order.
+     */
+    public int compare(final CoordinateSystem object1, final CoordinateSystem object2) {
+        final Class<? extends CoordinateSystem> type1 = object1.getClass();
+        final Class<? extends CoordinateSystem> type2 = object2.getClass();
+        for (int i=0; i<types.length; i++) {
+            final Class<?> type = types[i];
+            final boolean a1 = type.isAssignableFrom(type1);
+            final boolean a2 = type.isAssignableFrom(type2);
+            if (a1) return a2 ? 0 : -1;
+            if (a2) return a1 ? 0 : +1;
+        }
+        return 0;
+    }
+
+    /**
+     * Implementation of the {@link AbstractCS#standard} method.
+     */
+    static CoordinateSystem standard(final CoordinateSystem cs) throws IllegalArgumentException {
+        final int dimension = cs.getDimension();
+        if (cs instanceof CartesianCS) {
+            switch (dimension) {
+                case 2: {
+                    if (DefaultCartesianCS.PROJECTED.axisColinearWith(cs)) {
+                        return DefaultCartesianCS.PROJECTED;
+                    }
+                    if (DefaultCartesianCS.GRID.axisColinearWith(cs)) {
+                        return DefaultCartesianCS.GRID;
+                    }
+                    if (DefaultCartesianCS.GENERIC_2D.directionColinearWith(cs)) {
+                        return DefaultCartesianCS.GENERIC_2D;
+                    }
+                    return rightHanded((CartesianCS) cs);
+                }
+                case 3: {
+                    if (DefaultCartesianCS.GEOCENTRIC.axisColinearWith(cs)) {
+                        return DefaultCartesianCS.GEOCENTRIC;
+                    }
+                    if (DefaultCartesianCS.GENERIC_3D.directionColinearWith(cs)) {
+                        return DefaultCartesianCS.GENERIC_3D;
+                    }
+                    return rightHanded((CartesianCS) cs);
+                }
+            }
+        }
+        if (cs instanceof AffineCS) {
+            return rightHanded((AffineCS) cs);
+        }
+        if (cs instanceof EllipsoidalCS) {
+            switch (dimension) {
+                case 2: return DefaultEllipsoidalCS.GEODETIC_2D;
+                case 3: return DefaultEllipsoidalCS.GEODETIC_3D;
+            }
+        }
+        if (cs instanceof SphericalCS) {
+            switch (dimension) {
+                case 3: return DefaultSphericalCS.GEOCENTRIC;
+            }
+        }
+        if (cs instanceof VerticalCS) {
+            switch (dimension) {
+                case 1: {
+                    return DefaultVerticalCS.ELLIPSOIDAL_HEIGHT;
+                }
+            }
+        }
+        if (cs instanceof TimeCS) {
+            switch (dimension) {
+                case 1: return DefaultTimeCS.DAYS;
+            }
+        }
+        if (cs instanceof DefaultCompoundCS) {
+            final List<CoordinateSystem> components = ((DefaultCompoundCS) cs).getCoordinateSystems();
+            final CoordinateSystem[] user = new CoordinateSystem[components.size()];
+            final CoordinateSystem[] std  = new CoordinateSystem[user.length];
+            for (int i=0; i<std.length; i++) {
+                std[i] = standard(user[i] = components.get(i));
+            }
+            if (csComparator == null) {
+                csComparator = new PredefinedCS();
+            }
+            Arrays.sort(std, csComparator);
+            return Arrays.equals(user, std) ? cs : new DefaultCompoundCS(std);
+        }
+        throw new IllegalArgumentException(
+                Errors.format(ErrorKeys.UNSUPPORTED_COORDINATE_SYSTEM_$1, cs.getName().getCode()));
+    }
+
+    /**
+     * Reorder the axis in the specified Affine CS in an attempt to get a right-handed system.
+     * Units are standardized to meters in the process. If no axis change is needed, then this
+     * method returns {@code cs} unchanged.
+     */
+    private static AffineCS rightHanded(final AffineCS cs) {
+        boolean changed = false;
+        final int dimension = cs.getDimension();
+        final CoordinateSystemAxis[] axis = new CoordinateSystemAxis[dimension];
+        for (int i=0; i<dimension; i++) {
+            /*
+             * Gets the axis and replaces it by one of the predefined constants declared in
+             * DefaultCoordinateSystemAxis, if possible. The predefined constants use ISO 19111
+             * names with metres or degrees units, so it is pretty close to the "standard" axis
+             * we are looking for.
+             */
+            CoordinateSystemAxis axe = axis[i] = cs.getAxis(i);
+            DefaultCoordinateSystemAxis standard = DefaultCoordinateSystemAxis.getPredefined(axe);
+            if (standard != null) {
+                axe = standard;
+            }
+            /*
+             * Changes units to meters. Every units in an affine CS should be linear or
+             * dimensionless (the later is used for grid coordinates).  The 'usingUnit'
+             * method will thrown an exception if the unit is incompatible. See
+             * DefaultAffineCS.isCompatibleUnit(Unit).
+             */
+            final Unit<?> unit = axe.getUnit();
+            if (!Unit.ONE.equals(unit) && !SI.METER.equals(unit)) {
+                if (!(axe instanceof DefaultCoordinateSystemAxis)) {
+                    axe = new DefaultCoordinateSystemAxis(axe);
+                }
+                axe = ((DefaultCoordinateSystemAxis) axe).usingUnit(SI.METER);
+            }
+            changed |= (axe != axis[i]);
+            axis[i] = axe;
+        }
+        /*
+         * Sorts the axis in an attempt to create a right-handed system
+         * and creates a new Coordinate System if at least one axis changed.
+         */
+        changed |= ComparableAxisWrapper.sort(axis);
+        if (!changed) {
+            return cs;
+        }
+        final Map<String,?> properties = DefaultAffineCS.getProperties(cs, null);
+        if (cs instanceof CartesianCS) {
+            return new DefaultCartesianCS(properties, axis);
+        }
+        return new DefaultAffineCS(properties, axis);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/cs/package.html	(revision 28000)
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.referencing.cs</TITLE>
+  </HEAD>
+  <BODY>
+  {@linkplain org.geotools.referencing.cs.AbstractCS Coordinate systems} implementation.
+  An explanation for this package is provided in the {@linkplain org.opengis.referencing.cs OpenGIS&reg; javadoc}.
+  The remaining discussion on this page is specific to the Geotools implementation.
+
+  <P align="justify">Geotools provides some convenience methods for fetching specific coordinate
+  values in standard units. For example the {@link org.geotools.referencing.cs.DefaultEllipsoidalCS}
+  class provides a {@link org.geotools.referencing.cs.DefaultEllipsoidalCS#getLongitude getLongitude}
+  method that returns the longitude value in a given set of coordinates. This convenience method free
+  the user from the task of finding which axis is for the longitude, and performing unit
+  conversion.</P>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/AbstractDatum.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/AbstractDatum.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/AbstractDatum.java	(revision 28000)
@@ -0,0 +1,260 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.datum;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.util.Utilities;
+import org.opengis.metadata.extent.Extent;
+import org.opengis.referencing.datum.Datum;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * Specifies the relationship of a coordinate system to the earth, thus creating a {@linkplain
+ * org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference system}. A datum
+ * uses a parameter or set of parameters that determine the location of the origin of the coordinate
+ * reference system. Each datum subtype can be associated with only specific types of
+ * {@linkplain org.opengis.referencing.cs.AbstractCS coordinate systems}.
+ * <p>
+ * A datum can be defined as a set of real points on the earth that have coordinates.
+ * The definition of the datum may also include the temporal behavior (such as the
+ * rate of change of the orientation of the coordinate axes).
+ * <p>
+ * This class is conceptually <cite>abstract</cite>, even if it is technically possible to
+ * instantiate it. Typical applications should create instances of the most specific subclass with
+ * {@code Default} prefix instead. An exception to this rule may occurs when it is not possible to
+ * identify the exact type.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/datum/AbstractDatum.java $
+ * @version $Id: AbstractDatum.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @since 2.1
+ *
+ * @see org.geotools.referencing.cs.AbstractCS
+ * @see org.geotools.referencing.crs.AbstractCRS
+ */
+public class AbstractDatum extends AbstractIdentifiedObject implements Datum {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -4894180465652474930L;
+
+    /**
+     * List of localizable properties. To be given to
+     * {@link AbstractIdentifiedObject} constructor.
+     */
+    private static final String[] LOCALIZABLES = {ANCHOR_POINT_KEY, SCOPE_KEY};
+
+    /**
+     * Description, possibly including coordinates, of the point or points used to anchor the datum
+     * to the Earth. Also known as the "origin", especially for Engineering and Image Datums.
+     */
+    private final InternationalString anchorPoint;
+
+    /**
+     * The time after which this datum definition is valid. This time may be precise
+     * (e.g. 1997 for IRTF97) or merely a year (e.g. 1983 for NAD83). If the time is
+     * not defined, then the value is {@link Long#MIN_VALUE}.
+     */
+    private final long realizationEpoch;
+
+    /**
+     * Area or region in which this datum object is valid.
+     */
+    private final Extent domainOfValidity;
+
+    /**
+     * Description of domain of usage, or limitations of usage, for which this
+     * datum object is valid.
+     */
+    private final InternationalString scope;
+
+    /**
+     * Constructs a datum from a set of properties. The properties given in argument follow
+     * the same rules than for the {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map)
+     * super-class constructor}. Additionally, the following properties are understood by this
+     * construtor:
+     * <br><br>
+     * <table border='1'>
+     *   <tr bgcolor="#CCCCFF" class="TableHeadingColor">
+     *     <th nowrap>Property name</th>
+     *     <th nowrap>Value type</th>
+     *     <th nowrap>Value given to</th>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@link #ANCHOR_POINT_KEY "anchorPoint"}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link InternationalString} or {@link String}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getAnchorPoint}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@link #REALIZATION_EPOCH_KEY "realizationEpoch"}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link Date}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getRealizationEpoch}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@link #DOMAIN_OF_VALIDITY_KEY "domainOfValidity"}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link Extent}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getDomainOfValidity}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@link #SCOPE_KEY "scope"}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link InternationalString} or {@link String}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getScope}</td>
+     *   </tr>
+     * </table>
+     *
+     * @param properties The properties to be given to the identified object.
+     */
+    public AbstractDatum(final Map<String,?> properties) {
+        this(properties, new HashMap<String,Object>());
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private AbstractDatum(final Map<String,?> properties, final Map<String,Object> subProperties) {
+        super(properties, subProperties, LOCALIZABLES);
+        final Date realizationEpoch;
+        anchorPoint      = (InternationalString) subProperties.get(ANCHOR_POINT_KEY      );
+        realizationEpoch = (Date)                subProperties.get(REALIZATION_EPOCH_KEY );
+        domainOfValidity = (Extent)              subProperties.get(DOMAIN_OF_VALIDITY_KEY);
+        scope            = (InternationalString) subProperties.get(SCOPE_KEY             );
+        this.realizationEpoch = (realizationEpoch != null) ?
+                                 realizationEpoch.getTime() : Long.MIN_VALUE;
+    }
+
+    /**
+     * Same convenience method than {@link org.geotools.cs.AbstractCS#name} except that we get
+     * the unlocalized name (usually in English locale), because the name is part of the elements
+     * compared by the {@link #equals} method.
+     */
+    static Map<String,Object> name(final int key) {
+        final Map<String,Object> properties = new HashMap<String,Object>(4);
+        final InternationalString name = Vocabulary.formatInternational(key);
+        properties.put(NAME_KEY,  name.toString(null)); // "null" required for unlocalized version.
+        properties.put(ALIAS_KEY, name);
+        return properties;
+    }
+
+    /**
+     * Description, possibly including coordinates, of the point or points used to anchor the datum
+     * to the Earth. Also known as the "origin", especially for Engineering and Image Datums.
+     *
+     * <ul>
+     *   <li>For a geodetic datum, this point is also known as the fundamental point, which is
+     *       traditionally the point where the relationship between geoid and ellipsoid is defined.
+     *       In some cases, the "fundamental point" may consist of a number of points. In those
+     *       cases, the parameters defining the geoid/ellipsoid relationship have then been averaged
+     *       for these points, and the averages adopted as the datum definition.</li>
+     *
+     *   <li>For an engineering datum, the anchor point may be a physical point, or it may be a
+     *       point with defined coordinates in another CRS.</li>
+     *
+     *   <li>For an image datum, the anchor point is usually either the centre of the image or the
+     *       corner of the image.</li>
+     *
+     *   <li>For a temporal datum, this attribute is not defined. Instead of the anchor point,
+     *       a temporal datum carries a separate time origin of type {@link Date}.</li>
+     * </ul>
+     */
+    public InternationalString getAnchorPoint() {
+        return anchorPoint;
+    }
+
+    /**
+     * The time after which this datum definition is valid. This time may be precise (e.g. 1997
+     * for IRTF97) or merely a year (e.g. 1983 for NAD83). In the latter case, the epoch usually
+     * refers to the year in which a major recalculation of the geodetic control network, underlying
+     * the datum, was executed or initiated. An old datum can remain valid after a new datum is
+     * defined. Alternatively, a datum may be superseded by a later datum, in which case the
+     * realization epoch for the new datum defines the upper limit for the validity of the
+     * superseded datum.
+     */
+    public Date getRealizationEpoch() {
+        return (realizationEpoch!=Long.MIN_VALUE) ? new Date(realizationEpoch) : null;
+    }
+
+    /**
+     * Area or region or timeframe in which this datum is valid.
+     *
+     * @since 2.4
+     */
+    public Extent getDomainOfValidity() {
+        return domainOfValidity;
+    }
+
+    /**
+     * Description of domain of usage, or limitations of usage, for which this
+     * datum object is valid.
+     */
+    public InternationalString getScope() {
+        return scope;
+    }
+
+    /**
+     * Gets the type of the datum as an enumerated code. Datum type was provided
+     * for all kind of datum in the legacy OGC 01-009 specification. In the new
+     * OGC 03-73 (ISO 19111) specification, datum type is provided only for
+     * vertical datum. Nevertheless, we keep this method around since it is
+     * needed for WKT formatting. Note that we returns the datum type ordinal
+     * value, not the code list object.
+     */
+    int getLegacyDatumType() {
+        return 0;
+    }
+
+    /**
+     * Compares the specified object with this datum for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (super.equals(object, compareMetadata)) {
+            if (!compareMetadata) {
+                /*
+                 * Tests for name, since datum with different name have completly
+                 * different meaning. We don't perform this comparaison if the user
+                 * asked for metadata comparaison, because in such case the names
+                 * have already been compared by the subclass.
+                 */
+                return nameMatches(object.getName().getCode()) ||
+                       object.nameMatches(getName().getCode());
+            }
+            final AbstractDatum that = (AbstractDatum) object;
+            return this.realizationEpoch == that.realizationEpoch &&
+                   Utilities.equals(this.domainOfValidity, that.domainOfValidity) &&
+                   Utilities.equals(this.anchorPoint,      that.anchorPoint) &&
+                   Utilities.equals(this.scope,            that.scope);
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/BursaWolfParameters.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/BursaWolfParameters.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/BursaWolfParameters.java	(revision 28000)
@@ -0,0 +1,255 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.datum;
+
+import static java.lang.Double.doubleToLongBits;
+
+import java.io.Serializable;
+
+import org.geotools.referencing.operation.matrix.Matrix4;
+import org.geotools.referencing.operation.matrix.XMatrix;
+import org.geotools.referencing.wkt.Formattable;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+import org.opengis.referencing.datum.GeodeticDatum;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.util.Cloneable;
+
+
+/**
+ * Parameters for a geographic transformation between two datum.
+ * The Bursa Wolf parameters should be applied to geocentric coordinates,
+ * where the <var>X</var> axis points towards the Greenwich Prime Meridian,
+ * the <var>Y</var> axis points East, and the <var>Z</var> axis points North.
+ * The "Bursa-Wolf" formula is expressed in matrix form with 7 parameters:
+ *
+ * <p align="center"><img src="../doc-files/BursaWolf.png"></p>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/datum/BursaWolfParameters.java $
+ * @version $Id: BursaWolfParameters.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class BursaWolfParameters extends Formattable implements Cloneable, Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 754825592343010900L;
+
+    /** Bursa Wolf shift in meters. */
+    public double dx;
+
+    /** Bursa Wolf shift in meters. */
+    public double dy;
+
+    /** Bursa Wolf shift in meters. */
+    public double dz;
+
+    /** Bursa Wolf rotation in arc seconds. */
+    public double ex;
+
+    /** Bursa Wolf rotation in arc seconds. */
+    public double ey;
+
+    /** Bursa Wolf rotation in arc seconds. */
+    public double ez;
+
+    /** Bursa Wolf scaling in parts per million. */
+    public double ppm;
+
+    /** The target datum for this parameters. */
+    public final GeodeticDatum targetDatum;
+
+    /**
+     * Constructs a transformation info with all parameters set to 0.
+     *
+     * @param target The target datum for this parameters.
+     */
+    public BursaWolfParameters(final GeodeticDatum target) {
+        this.targetDatum = target;
+    }
+
+    /**
+     * Returns {@code true} if this Bursa Wolf parameters performs no operation.
+     * This is true when all parameters are set to zero.
+     *
+     * @return {@code true} if the parameters describe no operation.
+     */
+    public boolean isIdentity() {
+        return dx==0 && dy==0 && dz==0 && ex==0 && ey==0 && ez==0 && ppm==0;
+    }
+
+    /**
+     * Returns {@code true} if this Bursa Wolf parameters contains only translation terms.
+     *
+     * @return {@code true} if the parameters describe to a translation only.
+     */
+    public boolean isTranslation() {
+        return ex==0 && ey==0 && ez==0 && ppm==0;
+    }
+
+    /**
+     * Returns an affine transform that can be used to define this
+     * Bursa Wolf transformation. The formula is as follows:
+     *
+     * <blockquote><pre>
+     * S = 1 + {@link #ppm}/1000000
+     *
+     * [ X ]    [     S   -{@link #ez}*S   +{@link #ey}*S   {@link #dx} ]  [ X ]
+     * [ Y ]  = [ +{@link #ez}*S       S   -{@link #ex}*S   {@link #dy} ]  [ Y }
+     * [ Z ]    [ -{@link #ey}*S   +{@link #ex}*S       S   {@link #dz} ]  [ Z ]
+     * [ 1  ]    [     0       0       0    1 ]  [ 1 ]
+     * </pre></blockquote>
+     *
+     * This affine transform can be applied on <strong>geocentric</strong> coordinates.
+     *
+     * @return An affine transform created from the parameters.
+     */
+    public XMatrix getAffineTransform() {
+        /*
+         * Note: (ex, ey, ez) is a rotation in arc seconds. We need to convert it into radians
+         *       (the R factor in RS). TODO: to be strict, are we supposed to take the sinus of
+         *       rotation angles?
+         */
+        final double  S = 1 + ppm/1E+6;
+        final double RS = (Math.PI/(180*3600)) * S;
+        return new Matrix4(
+                 S,  -ez*RS,  +ey*RS,  dx,
+            +ez*RS,       S,  -ex*RS,  dy,
+            -ey*RS,  +ex*RS,       S,  dz,
+                 0,       0,       0,   1);
+    }
+
+    /**
+     * Sets transformation info from the specified matrix, which must be affine.
+     * In addition, the matrix minus the last row and last column must be
+     * <A HREF="http://mathworld.wolfram.com/AntisymmetricMatrix.html">antisymmetric</a>.
+     *
+     * @param matrix The matrix to fit as a Bursa-Wolf construct.
+     * @param eps    The tolerance error for the antisymmetric matrix test. Should be a small
+     *               number like {@code 1E-4}.
+     * @throws IllegalArgumentException if the specified matrix doesn't meet the conditions.
+     *
+     * @since 2.2
+     */
+    public void setAffineTransform(final Matrix matrix, final double eps)
+            throws IllegalArgumentException
+    {
+        if (matrix.getNumCol()!=4 || matrix.getNumRow()!=4) {
+            // TODO: localize. Same message than Matrix4
+            throw new IllegalArgumentException("Illegal matrix size.");
+        }
+        for (int i=0; i<4; i++) {
+            if (matrix.getElement(3,i) != (i==3 ? 1 : 0)) {
+                throw new IllegalArgumentException(Errors.format(ErrorKeys.NON_AFFINE_TRANSFORM));
+            }
+        }
+        dx = matrix.getElement(0,3);
+        dy = matrix.getElement(1,3);
+        dz = matrix.getElement(2,3);
+        final double S = (matrix.getElement(0,0) +
+                          matrix.getElement(1,1) +
+                          matrix.getElement(2,2)) / 3;
+        final double RS = (Math.PI/(180*3600)) * S;
+        ppm = (S-1) * 1E+6;
+        for (int j=0; j<2; j++) {
+            final double eltS = (matrix.getElement(j,j)-1) * 1E+6;
+            if (!(Math.abs(eltS - ppm) <= eps)) {
+                // TODO: localize
+                throw new IllegalArgumentException("Scale is not uniform.");
+            }
+            for (int i=j+1; i<3; i++) {
+                final double elt1 = matrix.getElement(j,i) / RS;
+                final double elt2 = matrix.getElement(i,j) / RS;
+                // Note: compare with +, not -, because the two values should be opposite.
+                if (!(Math.abs(elt1 + elt2) <= eps)) {
+                    // TODO: localize
+                    throw new IllegalArgumentException("Matrix is not antisymmetric.");
+                }
+                final double value = 0.5*(elt1 - elt2);
+                if (j==0) switch (i) {
+                    case 1: ez = -value; continue;
+                    case 2: ey = +value; continue;
+                }
+                assert j==1 && i==2;
+                ex = -value;
+            }
+        }
+        assert getAffineTransform().equals(matrix, eps*RS);
+    }
+
+    /**
+     * Returns a hash value for this object.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        long code = serialVersionUID;
+        code = code*37 + doubleToLongBits(dx );
+        code = code*37 + doubleToLongBits(dy );
+        code = code*37 + doubleToLongBits(dz );
+        code = code*37 + doubleToLongBits(ex );
+        code = code*37 + doubleToLongBits(ey );
+        code = code*37 + doubleToLongBits(ez );
+        code = code*37 + doubleToLongBits(ppm);
+        return (int)(code >>> 32) ^ (int)code;
+    }
+
+    /**
+     * Returns a copy of this object.
+     *
+     * @return A clone of the parameters.
+     */
+    @Override
+    public BursaWolfParameters clone() {
+        try {
+            return (BursaWolfParameters) super.clone();
+        }  catch (CloneNotSupportedException exception) {
+            // Should not happen, since we are cloneable.
+            throw new AssertionError(exception);
+        }
+    }
+
+    /**
+     * Compares the specified object with this object for equality.
+     *
+     * @param object The object to compare with the parameters.
+     * @return {@code true} if the given object is equals to the parameters.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object instanceof BursaWolfParameters) {
+            final BursaWolfParameters that = (BursaWolfParameters) object;
+            return Utilities.equals(this.dx,  that.dx)  &&
+                   Utilities.equals(this.dy,  that.dy)  &&
+                   Utilities.equals(this.dz,  that.dz)  &&
+                   Utilities.equals(this.ex,  that.ex)  &&
+                   Utilities.equals(this.ey,  that.ey)  &&
+                   Utilities.equals(this.ez,  that.ez)  &&
+                   Utilities.equals(this.ppm, that.ppm) &&
+                   Utilities.equals(this.targetDatum, that.targetDatum);
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultEllipsoid.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultEllipsoid.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultEllipsoid.java	(revision 28000)
@@ -0,0 +1,336 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This class contains formulas from the public FTP area of NOAA.
+ *    NOAAS's work is fully acknowledged here.
+ */
+package org.geotools.referencing.datum;
+
+import java.util.Collections;
+import java.util.Map;
+
+import javax.measure.quantity.Length;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+import org.opengis.referencing.datum.Ellipsoid;
+
+
+/**
+ * Geometric figure that can be used to describe the approximate shape of the earth.
+ * In mathematical terms, it is a surface formed by the rotation of an ellipse about
+ * its minor axis. An ellipsoid requires two defining parameters:
+ * <ul>
+ *   <li>{@linkplain #getSemiMajorAxis semi-major axis} and
+ *       {@linkplain #getInverseFlattening inverse flattening}, or</li>
+ *   <li>{@linkplain #getSemiMajorAxis semi-major axis} and
+ *       {@linkplain #getSemiMinorAxis semi-minor axis}.</li>
+ * </ul>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/datum/DefaultEllipsoid.java $
+ * @version $Id: DefaultEllipsoid.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultEllipsoid extends AbstractIdentifiedObject implements Ellipsoid {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -1149451543954764081L;
+
+    /**
+     * WGS 1984 ellipsoid with axis in {@linkplain SI#METER metres}. This ellipsoid is used
+     * in GPS systems and is the default for most {@code org.geotools} packages.
+     */
+    public static final DefaultEllipsoid WGS84 =
+            createFlattenedSphere("WGS84", 6378137.0, 298.257223563, SI.METER);
+
+    /**
+     * GRS 80 ellipsoid with axis in {@linkplain SI#METER metres}.
+     *
+     * @since 2.2
+     */
+    public static final DefaultEllipsoid GRS80 = // NO_UCD
+            createFlattenedSphere("GRS80", 6378137.0, 298.257222101, SI.METER);
+
+    /**
+     * International 1924 ellipsoid with axis in {@linkplain SI#METER metres}.
+     */
+    public static final DefaultEllipsoid INTERNATIONAL_1924 = // NO_UCD
+            createFlattenedSphere("International 1924", 6378388.0, 297.0, SI.METER);
+
+    /**
+     * Clarke 1866 ellipsoid with axis in {@linkplain SI#METER metres}.
+     *
+     * @since 2.2
+     */
+    public static final DefaultEllipsoid CLARKE_1866 = // NO_UCD
+            createFlattenedSphere("Clarke 1866", 6378206.4, 294.9786982, SI.METER);
+
+    /**
+     * A sphere with a radius of 6371000 {@linkplain SI#METER metres}. Spheres use a simplier
+     * algorithm for {@linkplain #orthodromicDistance orthodromic distance computation}, which
+     * may be faster and more robust.
+     */
+    public static final DefaultEllipsoid SPHERE = // NO_UCD
+            createEllipsoid("SPHERE", 6371000, 6371000, SI.METER);
+
+    /**
+     * The equatorial radius.
+     * @see #getSemiMajorAxis
+     */
+    private final double semiMajorAxis;
+
+    /**
+     * The polar radius.
+     * @see #getSemiMinorAxis
+     */
+    private final double semiMinorAxis;
+
+    /**
+     * The inverse of the flattening value, or {@link Double#POSITIVE_INFINITY}
+     * if the ellipsoid is a sphere.
+     *
+     * @see #getInverseFlattening
+     */
+    private final double inverseFlattening;
+
+    /**
+     * Tells if the Inverse Flattening definitive for this ellipsoid.
+     *
+     * @see #isIvfDefinitive
+     */
+    private final boolean ivfDefinitive;
+
+    /**
+     * The units of the semi-major and semi-minor axis values.
+     */
+    private final Unit<Length> unit;
+
+    /**
+     * Constructs a new ellipsoid using the specified axis length. The properties map is
+     * given unchanged to the {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map)
+     * super-class constructor}.
+     *
+     * @param properties        Set of properties. Should contains at least {@code "name"}.
+     * @param semiMajorAxis     The equatorial radius.
+     * @param semiMinorAxis     The polar radius.
+     * @param inverseFlattening The inverse of the flattening value.
+     * @param ivfDefinitive     {@code true} if the inverse flattening is definitive.
+     * @param unit              The units of the semi-major and semi-minor axis values.
+     *
+     * @see #createEllipsoid
+     * @see #createFlattenedSphere
+     */
+    protected DefaultEllipsoid(final Map<String,?> properties,
+                               final double  semiMajorAxis,
+                               final double  semiMinorAxis,
+                               final double  inverseFlattening,
+                               final boolean ivfDefinitive,
+                               final Unit<Length> unit)
+    {
+        super(properties);
+        this.unit = unit;
+        this.semiMajorAxis     = check("semiMajorAxis",     semiMajorAxis);
+        this.semiMinorAxis     = check("semiMinorAxis",     semiMinorAxis);
+        this.inverseFlattening = check("inverseFlattening", inverseFlattening);
+        this.ivfDefinitive     = ivfDefinitive;
+        ensureNonNull("unit", unit);
+        ensureLinearUnit(unit);
+    }
+
+    /**
+     * Constructs a new ellipsoid using the specified axis length.
+     *
+     * @param name          The ellipsoid name.
+     * @param semiMajorAxis The equatorial radius.
+     * @param semiMinorAxis The polar radius.
+     * @param unit          The units of the semi-major and semi-minor axis values.
+     * @return An ellipsoid with the given axis length.
+     */
+    public static DefaultEllipsoid createEllipsoid(final String name,
+                                                   final double semiMajorAxis,
+                                                   final double semiMinorAxis,
+                                                   final Unit<Length> unit)
+    {
+        return createEllipsoid(Collections.singletonMap(NAME_KEY, name),
+                               semiMajorAxis, semiMinorAxis, unit);
+    }
+
+    /**
+     * Constructs a new ellipsoid using the specified axis length. The properties map is
+     * given unchanged to the {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map)
+     * super-class constructor}.
+     *
+     * @param properties    Set of properties. Should contains at least {@code "name"}.
+     * @param semiMajorAxis The equatorial radius.
+     * @param semiMinorAxis The polar radius.
+     * @param unit          The units of the semi-major and semi-minor axis values.
+     * @return An ellipsoid with the given axis length.
+     */
+    public static DefaultEllipsoid createEllipsoid(final Map<String,?> properties,
+                                                   final double semiMajorAxis,
+                                                   final double semiMinorAxis,
+                                                   final Unit<Length> unit)
+    {
+        if (semiMajorAxis == semiMinorAxis) {
+            return new Spheroid(properties, semiMajorAxis, false, unit);
+        } else {
+            return new DefaultEllipsoid(properties, semiMajorAxis, semiMinorAxis,
+                       semiMajorAxis/(semiMajorAxis-semiMinorAxis), false, unit);
+        }
+    }
+
+    /**
+     * Constructs a new ellipsoid using the specified axis length and inverse flattening value.
+     *
+     * @param name              The ellipsoid name.
+     * @param semiMajorAxis     The equatorial radius.
+     * @param inverseFlattening The inverse flattening value.
+     * @param unit              The units of the semi-major and semi-minor axis
+     *                          values.
+     * @return An ellipsoid with the given axis length.
+     */
+    public static DefaultEllipsoid createFlattenedSphere(final String name,
+                                                         final double semiMajorAxis,
+                                                         final double inverseFlattening,
+                                                         final Unit<Length> unit)
+    {
+        return createFlattenedSphere(Collections.singletonMap(NAME_KEY, name),
+                                     semiMajorAxis, inverseFlattening, unit);
+    }
+
+    /**
+     * Constructs a new ellipsoid using the specified axis length and
+     * inverse flattening value. The properties map is given unchanged to the
+     * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
+     *
+     * @param properties        Set of properties. Should contains at least {@code "name"}.
+     * @param semiMajorAxis     The equatorial radius.
+     * @param inverseFlattening The inverse flattening value.
+     * @param unit              The units of the semi-major and semi-minor axis
+     *                          values.
+     * @return An ellipsoid with the given axis length.
+     */
+    public static DefaultEllipsoid createFlattenedSphere(final Map<String,?> properties,
+                                                         final double semiMajorAxis,
+                                                         final double inverseFlattening,
+                                                         final Unit<Length> unit)
+    {
+        if (Double.isInfinite(inverseFlattening)) {
+            return new Spheroid(properties, semiMajorAxis, true, unit);
+        } else {
+            return new DefaultEllipsoid(properties, semiMajorAxis,
+                                        semiMajorAxis*(1-1/inverseFlattening),
+                                        inverseFlattening, true, unit);
+        }
+    }
+
+    /**
+     * Checks the argument validity. Argument {@code value} should be greater than zero.
+     *
+     * @param  name  Argument name.
+     * @param  value Argument value.
+     * @return {@code value}.
+     * @throws IllegalArgumentException if {@code value} is not greater than  0.
+     */
+    static double check(final String name, final double value) throws IllegalArgumentException {
+        if (value > 0) {
+            return value;
+        }
+        throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2, name, value));
+    }
+
+    /**
+     * Returns the linear unit of the {@linkplain #getSemiMajorAxis semi-major}
+     * and {@linkplain #getSemiMinorAxis semi-minor} axis values.
+     *
+     * @return The axis linear unit.
+     */
+    public Unit<Length> getAxisUnit() {
+        return unit;
+    }
+
+    /**
+     * Length of the semi-major axis of the ellipsoid. This is the
+     * equatorial radius in {@linkplain #getAxisUnit axis linear unit}.
+     *
+     * @return Length of semi-major axis.
+     */
+    public double getSemiMajorAxis() {
+        return semiMajorAxis;
+    }
+
+    /**
+     * Length of the semi-minor axis of the ellipsoid. This is the
+     * polar radius in {@linkplain #getAxisUnit axis linear unit}.
+     *
+     * @return Length of semi-minor axis.
+     */
+    public double getSemiMinorAxis() {
+        return semiMinorAxis;
+    }
+
+    /**
+     * Compare this ellipsoid with the specified object for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            final DefaultEllipsoid that = (DefaultEllipsoid) object;
+            return (!compareMetadata || this.ivfDefinitive == that.ivfDefinitive)   &&
+                   Utilities.equals(this.semiMajorAxis,     that.semiMajorAxis)     &&
+                   Utilities.equals(this.semiMinorAxis,     that.semiMinorAxis)     &&
+                   Utilities.equals(this.inverseFlattening, that.inverseFlattening) &&
+                   Utilities.equals(this.unit,              that.unit);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this ellipsoid. {@linkplain #getName Name},
+     * {@linkplain #getRemarks remarks} and the like are not taken in account.
+     * In other words, two ellipsoids will return the same hash value if they
+     * are equal in the sense of
+     * <code>{@link #equals equals}(AbstractIdentifiedObject, <strong>false</strong>)</code>.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        long longCode = 37*Double.doubleToLongBits(semiMajorAxis);
+        if (ivfDefinitive) {
+            longCode += inverseFlattening;
+        } else {
+            longCode += semiMinorAxis;
+        }
+        return (((int)(longCode >>> 32)) ^ (int)longCode);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultEngineeringDatum.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultEngineeringDatum.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultEngineeringDatum.java	(revision 28000)
@@ -0,0 +1,82 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.datum;
+
+import java.util.Map;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.opengis.referencing.datum.EngineeringDatum;
+
+
+/**
+ * Defines the origin of an engineering coordinate reference system. An engineering datum is used
+ * in a region around that origin. This origin can be fixed with respect to the earth (such as a
+ * defined point at a construction site), or be a defined point on a moving vehicle (such as on a
+ * ship or satellite).
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/datum/DefaultEngineeringDatum.java $
+ * @version $Id: DefaultEngineeringDatum.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultEngineeringDatum extends AbstractDatum implements EngineeringDatum {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 1498304918725248637L;
+
+    /**
+     * An engineering datum for unknow coordinate reference system. Such CRS are usually
+     * assumed cartesian, but will not have any transformation path to other CRS.
+     *
+     * @see org.geotools.referencing.crs.DefaultEngineeringCRS#CARTESIAN_2D
+     * @see org.geotools.referencing.crs.DefaultEngineeringCRS#CARTESIAN_3D
+     */
+    public static final DefaultEngineeringDatum UNKNOW =
+            new DefaultEngineeringDatum(name(VocabularyKeys.UNKNOW));
+
+    /**
+     * Constructs an engineering datum from a set of properties. The properties map is given
+     * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     */
+    public DefaultEngineeringDatum(final Map<String,?> properties) {
+        super(properties);
+    }
+
+    /**
+     * Compare this datum with the specified object for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        return super.equals(object, compareMetadata);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultGeodeticDatum.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultGeodeticDatum.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultGeodeticDatum.java	(revision 28000)
@@ -0,0 +1,384 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.datum;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.referencing.operation.matrix.XMatrix;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.referencing.datum.Datum;
+import org.opengis.referencing.datum.Ellipsoid;
+import org.opengis.referencing.datum.GeodeticDatum;
+import org.opengis.referencing.datum.PrimeMeridian;
+import org.opengis.referencing.operation.Matrix;
+
+
+/**
+ * Defines the location and precise orientation in 3-dimensional space of a defined ellipsoid
+ * (or sphere) that approximates the shape of the earth. Used also for Cartesian coordinate
+ * system centered in this ellipsoid (or sphere).
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/datum/DefaultGeodeticDatum.java $
+ * @version $Id: DefaultGeodeticDatum.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see Ellipsoid
+ * @see PrimeMeridian
+ */
+public class DefaultGeodeticDatum extends AbstractDatum implements GeodeticDatum {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 8832100095648302943L;
+
+    /**
+     * The default WGS 1984 datum.
+     */
+    public static final DefaultGeodeticDatum WGS84;
+    static {
+        final ReferenceIdentifier[] identifiers = {
+            new NamedIdentifier(Citations.OGC,    "WGS84"),
+            new NamedIdentifier(Citations.ORACLE, "WGS 84"),
+            new NamedIdentifier(null,             "WGS_84"),
+            new NamedIdentifier(null,             "WGS 1984"),
+            new NamedIdentifier(Citations.EPSG,   "WGS_1984"),
+            new NamedIdentifier(Citations.ESRI,   "D_WGS_1984"),
+            new NamedIdentifier(Citations.EPSG,   "World Geodetic System 1984")
+        };
+        final Map<String,Object> properties = new HashMap<String,Object>(4);
+        properties.put(NAME_KEY,  identifiers[0]);
+        properties.put(ALIAS_KEY, identifiers);
+        WGS84 = new DefaultGeodeticDatum(properties, DefaultEllipsoid.WGS84,
+                                         DefaultPrimeMeridian.GREENWICH);
+    }
+
+    /**
+     * The <code>{@value #BURSA_WOLF_KEY}</code> property for
+     * {@linkplain #getAffineTransform datum shifts}.
+     */
+    public static final String BURSA_WOLF_KEY = "bursaWolf";
+
+    /**
+     * The ellipsoid.
+     */
+    private final Ellipsoid ellipsoid;
+
+    /**
+     * The prime meridian.
+     */
+    private final PrimeMeridian primeMeridian;
+
+    /**
+     * Bursa Wolf parameters for datum shifts, or {@code null} if none.
+     */
+    private final BursaWolfParameters[] bursaWolf;
+
+    /**
+     * Constructs a geodetic datum from a set of properties. The properties map is given
+     * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}.
+     * Additionally, the following properties are understood by this construtor:
+     * <p>
+     * <table border='1'>
+     *   <tr bgcolor="#CCCCFF" class="TableHeadingColor">
+     *     <th nowrap>Property name</th>
+     *     <th nowrap>Value type</th>
+     *     <th nowrap>Value given to</th>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@link #BURSA_WOLF_KEY "bursaWolf"}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link BursaWolfParameters} or an array of those&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getBursaWolfParameters}</td>
+     *   </tr>
+     * </table>
+     *
+     * @param properties    Set of properties. Should contains at least {@code "name"}.
+     * @param ellipsoid     The ellipsoid.
+     * @param primeMeridian The prime meridian.
+     */
+    public DefaultGeodeticDatum(final Map<String,?> properties,
+                                final Ellipsoid     ellipsoid,
+                                final PrimeMeridian primeMeridian)
+    {
+        super(properties);
+        this.ellipsoid     = ellipsoid;
+        this.primeMeridian = primeMeridian;
+        ensureNonNull("ellipsoid",     ellipsoid);
+        ensureNonNull("primeMeridian", primeMeridian);
+        BursaWolfParameters[] bursaWolf;
+        final Object object = properties.get(BURSA_WOLF_KEY);
+        if (object instanceof BursaWolfParameters) {
+            bursaWolf = new BursaWolfParameters[] {
+                ((BursaWolfParameters) object).clone()
+            };
+        } else {
+            bursaWolf = (BursaWolfParameters[]) object;
+            if (bursaWolf != null) {
+                if (bursaWolf.length == 0) {
+                    bursaWolf = null;
+                } else {
+                    final Set<BursaWolfParameters> s = new LinkedHashSet<BursaWolfParameters>();
+                    for (int i=0; i<bursaWolf.length; i++) {
+                        s.add(bursaWolf[i].clone());
+                    }
+                    bursaWolf = s.toArray(new BursaWolfParameters[s.size()]);
+                }
+            }
+        }
+        this.bursaWolf = bursaWolf;
+    }
+
+    /**
+     * Returns the ellipsoid.
+     */
+    public Ellipsoid getEllipsoid() {
+        return ellipsoid;
+    }
+
+    /**
+     * Returns the prime meridian.
+     */
+    public PrimeMeridian getPrimeMeridian() {
+        return primeMeridian;
+    }
+
+    /**
+     * Returns all Bursa Wolf parameters specified in the {@code properties} map at
+     * construction time.
+     *
+     * @since 2.4
+     */
+    public BursaWolfParameters[] getBursaWolfParameters() { // NO_UCD
+        if (bursaWolf != null) {
+            return bursaWolf.clone();
+        }
+        return new BursaWolfParameters[0];
+    }
+
+    /**
+     * Returns Bursa Wolf parameters for a datum shift toward the specified target, or {@code null}
+     * if none. This method search only for Bursa-Wolf parameters explicitly specified in the
+     * {@code properties} map at construction time. This method doesn't try to infer a set of
+     * parameters from indirect informations. For example it doesn't try to inverse the parameters
+     * specified in the {@code target} datum if none were found in this datum. If such an elaborated
+     * search is wanted, use {@link #getAffineTransform} instead.
+     */
+    public BursaWolfParameters getBursaWolfParameters(final GeodeticDatum target) {
+        if (bursaWolf != null) {
+            for (int i=0; i<bursaWolf.length; i++) {
+                final BursaWolfParameters candidate = bursaWolf[i];
+                if (equals(target, candidate.targetDatum, false)) {
+                    return candidate.clone();
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns a matrix that can be used to define a transformation to the specified datum.
+     * If no transformation path is found, then this method returns {@code null}.
+     *
+     * @param  source The source datum.
+     * @param  target The target datum.
+     * @return An affine transform from {@code source} to {@code target}, or {@code null} if none.
+     *
+     * @see BursaWolfParameters#getAffineTransform
+     */
+    public static Matrix getAffineTransform(final GeodeticDatum source,
+                                            final GeodeticDatum target)
+    {
+        return getAffineTransform(source, target, null);
+    }
+
+    /**
+     * Returns a matrix that can be used to define a transformation to the specified datum.
+     * If no transformation path is found, then this method returns {@code null}.
+     *
+     * @param  source The source datum.
+     * @param  target The target datum.
+     * @param  exclusion The set of datum to exclude from the search, or {@code null}.
+     *         This is used in order to avoid never-ending recursivity.
+     * @return An affine transform from {@code source} to {@code target}, or {@code null} if none.
+     *
+     * @see BursaWolfParameters#getAffineTransform
+     */
+    private static XMatrix getAffineTransform(final GeodeticDatum source,
+                                              final GeodeticDatum target,
+                                              Set<GeodeticDatum> exclusion)
+    {
+        ensureNonNull("source", source);
+        ensureNonNull("target", target);
+        if (source instanceof DefaultGeodeticDatum) {
+            final BursaWolfParameters[] bursaWolf = ((DefaultGeodeticDatum) source).bursaWolf;
+            if (bursaWolf != null) {
+                for (int i=0; i<bursaWolf.length; i++) {
+                    final BursaWolfParameters transformation = bursaWolf[i];
+                    if (equals(target, transformation.targetDatum, false)) {
+                        return transformation.getAffineTransform();
+                    }
+                }
+            }
+        }
+        /*
+         * No transformation found to the specified target datum.
+         * Search if a transform exists in the opposite direction.
+         */
+        if (target instanceof DefaultGeodeticDatum) {
+            final BursaWolfParameters[] bursaWolf = ((DefaultGeodeticDatum) target).bursaWolf;
+            if (bursaWolf != null) {
+                for (int i=0; i<bursaWolf.length; i++) {
+                    final BursaWolfParameters transformation = bursaWolf[i];
+                    if (equals(source, transformation.targetDatum, false)) {
+                        final XMatrix matrix = transformation.getAffineTransform();
+                        matrix.invert();
+                        return matrix;
+                    }
+                }
+            }
+        }
+        /*
+         * No direct tranformation found. Search for a path through some intermediate datum.
+         * First, search if there is some BursaWolfParameters for the same target in both
+         * 'source' and 'target' datum. If such an intermediate is found, ask for a path
+         * as below:
+         *
+         *    source   -->   [common datum]   -->   target
+         */
+        if (source instanceof DefaultGeodeticDatum && target instanceof DefaultGeodeticDatum) {
+            final BursaWolfParameters[] sourceParam = ((DefaultGeodeticDatum) source).bursaWolf;
+            final BursaWolfParameters[] targetParam = ((DefaultGeodeticDatum) target).bursaWolf;
+            if (sourceParam!=null && targetParam!=null) {
+                GeodeticDatum sourceStep;
+                GeodeticDatum targetStep;
+                for (int i=0; i<sourceParam.length; i++) {
+                    sourceStep = sourceParam[i].targetDatum;
+                    for (int j=0; j<targetParam.length; j++) {
+                        targetStep = targetParam[j].targetDatum;
+                        if (equals(sourceStep, targetStep, false)) {
+                            final XMatrix step1, step2;
+                            if (exclusion == null) {
+                                exclusion = new HashSet<GeodeticDatum>();
+                            }
+                            if (exclusion.add(source)) {
+                                if (exclusion.add(target)) {
+                                    step1 = getAffineTransform(source, sourceStep, exclusion);
+                                    if (step1 != null) {
+                                        step2 = getAffineTransform(targetStep, target, exclusion);
+                                        if (step2 != null) {
+                                            /*
+                                             * Note: XMatrix.multiply(XMatrix) is equivalent to
+                                             *       AffineTransform.concatenate(...): First
+                                             *       transform by the supplied transform and
+                                             *       then transform the result by the original
+                                             *       transform.
+                                             */
+                                            step2.multiply(step1);
+                                            return step2;
+                                        }
+                                    }
+                                    exclusion.remove(target);
+                                }
+                                exclusion.remove(source);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns {@code true} if the specified object is equals (at least on
+     * computation purpose) to the {@link #WGS84} datum. This method may conservatively
+     * returns {@code false} if the specified datum is uncertain (for example
+     * because it come from an other implementation).
+     */
+    public static boolean isWGS84(final Datum datum) { // NO_UCD
+        if (datum instanceof AbstractIdentifiedObject) {
+            return WGS84.equals((AbstractIdentifiedObject) datum, false);
+        }
+        // Maybe the specified object has its own test...
+        return datum!=null && datum.equals(WGS84);
+    }
+
+    /**
+     * Compare this datum with the specified object for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            final DefaultGeodeticDatum that = (DefaultGeodeticDatum) object;
+            if (equals(this.ellipsoid,     that.ellipsoid,     compareMetadata) &&
+                equals(this.primeMeridian, that.primeMeridian, compareMetadata))
+            {
+                /*
+                 * HACK: We do not consider Bursa Wolf parameters as a non-metadata field.
+                 *       This is needed in order to get equalsIgnoreMetadata(...) to returns
+                 *       'true' when comparing the WGS84 constant in this class with a WKT
+                 *       DATUM element with a TOWGS84[0,0,0,0,0,0,0] element. Furthermore,
+                 *       the Bursa Wolf parameters are not part of ISO 19111 specification.
+                 *       We don't want two CRS to be considered as different because one has
+                 *       more of those transformation informations (which is nice, but doesn't
+                 *       change the CRS itself).
+                 */
+                return !compareMetadata || Arrays.equals(this.bursaWolf, that.bursaWolf);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this geodetic datum. {@linkplain #getName Name},
+     * {@linkplain #getRemarks remarks} and the like are not taken in account. In
+     * other words, two geodetic datums will return the same hash value if they
+     * are equal in the sense of
+     * <code>{@link #equals equals}(AbstractIdentifiedObject, <strong>false</strong>)</code>.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        int code = (int)serialVersionUID ^
+            37*(super        .hashCode() ^
+            37*(ellipsoid    .hashCode() ^
+            37*(primeMeridian.hashCode())));
+        return code;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultImageDatum.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultImageDatum.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultImageDatum.java	(revision 28000)
@@ -0,0 +1,100 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.datum;
+
+import java.util.Map;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.util.Utilities;
+import org.opengis.referencing.datum.ImageDatum;
+import org.opengis.referencing.datum.PixelInCell;
+
+
+/**
+ * Defines the origin of an image coordinate reference system. An image datum is used in a local
+ * context only. For an image datum, the anchor point is usually either the centre of the image
+ * or the corner of the image.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/datum/DefaultImageDatum.java $
+ * @version $Id: DefaultImageDatum.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @since 2.1
+ */
+public class DefaultImageDatum extends AbstractDatum implements ImageDatum {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -4304193511244150936L;
+
+    /**
+     * Specification of the way the image grid is associated with the image data attributes.
+     */
+    private final PixelInCell pixelInCell;
+
+    /**
+     * Constructs an image datum from a set of properties. The properties map is given
+     * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}.
+     *
+     * @param properties  Set of properties. Should contains at least {@code "name"}.
+     * @param pixelInCell the way the image grid is associated with the image data attributes.
+     */
+    public DefaultImageDatum(final Map<String,?> properties, final PixelInCell pixelInCell) {
+        super(properties);
+        this.pixelInCell = pixelInCell;
+        ensureNonNull("pixelInCell", pixelInCell);
+    }
+
+    /**
+     * Compare this datum with the specified object for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            final DefaultImageDatum that = (DefaultImageDatum) object;
+            return Utilities.equals(this.pixelInCell, that.pixelInCell);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this image datum. {@linkplain #getName Name},
+     * {@linkplain #getRemarks remarks} and the like are not taken in account. In
+     * other words, two image datums will return the same hash value if they
+     * are equal in the sense of
+     * <code>{@link #equals equals}(AbstractIdentifiedObject, <strong>false</strong>)</code>.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ pixelInCell.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultPrimeMeridian.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultPrimeMeridian.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultPrimeMeridian.java	(revision 28000)
@@ -0,0 +1,178 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.datum;
+
+import java.util.Collections;
+import java.util.Map;
+
+import javax.measure.quantity.Angle;
+import javax.measure.unit.NonSI;
+import javax.measure.unit.Unit;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.util.Utilities;
+import org.opengis.referencing.datum.PrimeMeridian;
+
+
+/**
+ * A prime meridian defines the origin from which longitude values are determined.
+ * The {@link #getName name} initial value is "Greenwich", and that value shall be
+ * used when the {@linkplain #getGreenwichLongitude greenwich longitude} value is
+ * zero.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/datum/DefaultPrimeMeridian.java $
+ * @version $Id: DefaultPrimeMeridian.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @since 2.1
+ */
+public class DefaultPrimeMeridian extends AbstractIdentifiedObject implements PrimeMeridian {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 541978454643213305L;;
+
+    /**
+     * The Greenwich meridian, with angular measurements in decimal degrees.
+     */
+    public static final DefaultPrimeMeridian GREENWICH =
+                    new DefaultPrimeMeridian("Greenwich", 0, NonSI.DEGREE_ANGLE);
+
+    /**
+     * Longitude of the prime meridian measured from the Greenwich meridian, positive eastward.
+     */
+    private final double greenwichLongitude;
+
+    /**
+     * The angular unit of the {@linkplain #getGreenwichLongitude Greenwich longitude}.
+     */
+    private final Unit<Angle> angularUnit;
+
+    /**
+     * Constructs a prime meridian from a name.
+     *
+     * @param name                The datum name.
+     * @param greenwichLongitude  The longitude value relative to the Greenwich Meridian.
+     * @param angularUnit         The angular unit of the longitude.
+     */
+    public DefaultPrimeMeridian(final String name, final double greenwichLongitude,
+                                final Unit<Angle> angularUnit)
+    {
+        this(Collections.singletonMap(NAME_KEY, name), greenwichLongitude, angularUnit);
+    }
+
+    /**
+     * Constructs a prime meridian from a set of properties. The properties map is given
+     * unchanged to the {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map)
+     * super-class constructor}.
+     *
+     * @param properties          Set of properties. Should contains at least {@code "name"}.
+     * @param greenwichLongitude  The longitude value relative to the Greenwich Meridian.
+     * @param angularUnit         The angular unit of the longitude.
+     */
+    public DefaultPrimeMeridian(final Map<String,?> properties, final double greenwichLongitude,
+                                final Unit<Angle> angularUnit)
+    {
+        super(properties);
+        this.greenwichLongitude = greenwichLongitude;
+        this.angularUnit        = angularUnit;
+        ensureAngularUnit(angularUnit);
+    }
+
+    /**
+     * Longitude of the prime meridian measured from the Greenwich meridian, positive eastward.
+     * The {@code greenwichLongitude} initial value is zero, and that value shall be used
+     * when the {@linkplain #getName meridian name} value is "Greenwich".
+     *
+     * @return The prime meridian Greenwich longitude, in {@linkplain #getAngularUnit angular unit}.
+     */
+    public double getGreenwichLongitude() {
+        return greenwichLongitude;
+    }
+
+    /**
+     * Returns the longitude value relative to the Greenwich Meridian, expressed in the specified
+     * units. This convenience method makes it easier to obtain longitude in decimal degrees
+     * ({@code getGreenwichLongitude(NonSI.DEGREE_ANGLE)}), regardless of the underlying
+     * angular units of this prime meridian.
+     *
+     * @param targetUnit The unit in which to express longitude.
+     * @return The Greenwich longitude in the given units.
+     */
+    public double getGreenwichLongitude(final Unit<Angle> targetUnit) {
+        return getAngularUnit().getConverterTo(targetUnit).convert(getGreenwichLongitude());
+    }
+
+    /**
+     * Returns the angular unit of the {@linkplain #getGreenwichLongitude Greenwich longitude}.
+     */
+    public Unit<Angle> getAngularUnit() {
+        return angularUnit;
+    }
+
+    /**
+     * Compare this prime meridian with the specified object for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            final DefaultPrimeMeridian that = (DefaultPrimeMeridian) object;
+            if (compareMetadata) {
+                return Utilities.equals(this.greenwichLongitude, that.greenwichLongitude) &&
+                       Utilities.equals(this.angularUnit, that.angularUnit);
+            } else {
+                return Utilities.equals(this.getGreenwichLongitude(NonSI.DEGREE_ANGLE), 
+                        that.getGreenwichLongitude(NonSI.DEGREE_ANGLE));
+                
+                /*
+                 * Note: if compareMetadata==false, we relax the unit check because EPSG uses
+                 *       sexagesimal degrees for the Greenwich meridian. Requirying the same
+                 *       unit prevent Geodetic.isWGS84(...) method to recognize EPSG's WGS84.
+                 */
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this prime meridian. {@linkplain #getName Name},
+     * {@linkplain #getRemarks remarks} and the like are not taken in account.
+     * In other words, two prime meridians will return the same hash value if
+     * they are equal in the sense of
+     * <code>{@link #equals equals}(AbstractIdentifiedObject, <strong>false</strong>)</code>.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        final long code = Double.doubleToLongBits(greenwichLongitude);
+        return ((int)(code >>> 32) ^ (int)code) ^ (int)serialVersionUID;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultTemporalDatum.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultTemporalDatum.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultTemporalDatum.java	(revision 28000)
@@ -0,0 +1,123 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.datum;
+
+import java.util.Date;
+import java.util.Map;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.opengis.referencing.datum.TemporalDatum;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * A temporal datum defines the origin of a temporal coordinate reference system.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/datum/DefaultTemporalDatum.java $
+ * @version $Id: DefaultTemporalDatum.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @since 2.1
+ */
+public class DefaultTemporalDatum extends AbstractDatum implements TemporalDatum {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 3357241732140076884L;
+
+    /**
+     * The date and time origin of this temporal datum.
+     */
+    private final long origin;
+
+    /**
+     * Constructs a temporal datum from a set of properties. The properties map is given
+     * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param origin The date and time origin of this temporal datum.
+     */
+    public DefaultTemporalDatum(final Map<String,?> properties, final Date origin) {
+        super(properties);
+        ensureNonNull("origin", origin);
+        this.origin = origin.getTime();
+    }
+
+    /**
+     * The date and time origin of this temporal datum.
+     *
+     * @return The date and time origin of this temporal datum.
+     */
+    public Date getOrigin() {
+        return new Date(origin);
+    }
+
+    /**
+     * Description of the point or points used to anchor the datum to the Earth.
+     */
+    @Override
+    public InternationalString getAnchorPoint() {
+        return super.getAnchorPoint();
+    }
+
+    /**
+     * The time after which this datum definition is valid.
+     */
+    @Override
+    public Date getRealizationEpoch() {
+        return super.getRealizationEpoch();
+    }
+
+    /**
+     * Compare this temporal datum with the specified object for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            final DefaultTemporalDatum that = (DefaultTemporalDatum) object;
+            return this.origin == that.origin;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this temporal datum. {@linkplain #getName Name},
+     * {@linkplain #getRemarks remarks} and the like are not taken in account. In
+     * other words, two temporal datums will return the same hash value if they
+     * are equal in the sense of
+     * <code>{@link #equals equals}(AbstractIdentifiedObject, <strong>false</strong>)</code>.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ (int)origin ^ (int)(origin >>> 32);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultVerticalDatum.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultVerticalDatum.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/DefaultVerticalDatum.java	(revision 28000)
@@ -0,0 +1,163 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.datum;
+
+import java.util.Map;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.util.Utilities;
+import org.opengis.referencing.datum.VerticalDatum;
+import org.opengis.referencing.datum.VerticalDatumType;
+
+
+/**
+ * A textual description and/or a set of parameters identifying a particular reference level
+ * surface used as a zero-height surface. The description includes its position with respect
+ * to the Earth for any of the height types recognized by this standard. There are several
+ * types of vertical datums, and each may place constraints on the
+ * {@linkplain org.opengis.referencing.cs.CoordinateSystemAxis coordinate system axis} with which
+ * it is combined to create a {@linkplain org.opengis.referencing.crs.VerticalCRS vertical CRS}.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/datum/DefaultVerticalDatum.java $
+ * @version $Id: DefaultVerticalDatum.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @since 2.1
+ */
+public class DefaultVerticalDatum extends AbstractDatum implements VerticalDatum {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 380347456670516572L;
+
+    /**
+     * A copy of the list of vertical types.
+     */
+    private static final VerticalDatumType[] TYPES = VerticalDatumType.values();
+
+    /**
+     * Mapping between {@linkplain VerticalDatumType vertical datum type} and the numeric
+     * values used in legacy specification (OGC 01-009).
+     */
+    private static final short[] LEGACY_CODES = new short[TYPES.length];
+    static {
+        LEGACY_CODES[VerticalDatumType.GEOIDAL      .ordinal()] = 2005; // CS_VD_GeoidModelDerived
+        LEGACY_CODES[VerticalDatumType.ELLIPSOIDAL  .ordinal()] = 2002; // CS_VD_Ellipsoidal
+        LEGACY_CODES[VerticalDatumType.DEPTH        .ordinal()] = 2006; // CS_VD_Depth
+        LEGACY_CODES[VerticalDatumType.BAROMETRIC   .ordinal()] = 2003; // CS_VD_AltitudeBarometric
+        LEGACY_CODES[VerticalDatumType.ORTHOMETRIC  .ordinal()] = 2001; // CS_VD_Orthometric
+        LEGACY_CODES[VerticalDatumType.OTHER_SURFACE.ordinal()] = 2000; // CS_VD_Other
+    }
+
+    /**
+     * The type of this vertical datum. Default is "geoidal".
+     */
+    private final VerticalDatumType type;
+
+    /**
+     * Constructs a vertical datum from a set of properties. The properties map is given
+     * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param type       The type of this vertical datum.
+     */
+    public DefaultVerticalDatum(final Map<String,?> properties, final VerticalDatumType type) {
+        super(properties);
+        this.type = type;
+        ensureNonNull("type", type);
+    }
+
+    /**
+     * The type of this vertical datum. Default is geoidal.
+     *
+     * @return The type of this vertical datum.
+     */
+    public VerticalDatumType getVerticalDatumType() {
+        return type;
+    }
+
+    /**
+     * Returns the legacy code for the datum type.
+     */
+    @Override
+    final int getLegacyDatumType() {
+        final int ordinal = type.ordinal();
+        if (ordinal>=0 && ordinal<LEGACY_CODES.length) {
+            assert type.equals(TYPES[ordinal]) : type;
+            return LEGACY_CODES[ordinal];
+        }
+        return 0;
+    }
+
+    /**
+     * Returns the vertical datum type from a legacy code. The legacy codes were defined in
+     * <A HREF="http://www.opengis.org/docs/01-009.pdf">Coordinate Transformation Services</A>
+     * (OGC 01-009), which also defined the
+     * <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well
+     * Known Text</cite> (WKT)</A> format. This method is used for WKT parsing.
+     *
+     * @param  code The legacy vertical datum code.
+     * @return The vertical datum type, or {@code null} if the code is unrecognized.
+     */
+    public static VerticalDatumType getVerticalDatumTypeFromLegacyCode(final int code) {
+        for (int i=0; i<LEGACY_CODES.length; i++) {
+            if (LEGACY_CODES[i] == code) {
+                return TYPES[i];
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Compare this vertical datum with the specified object for equality.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            final DefaultVerticalDatum that = (DefaultVerticalDatum) object;
+            return Utilities.equals(this.type, that.type);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash value for this vertical datum. {@linkplain #getName Name},
+     * {@linkplain #getRemarks remarks} and the like are not taken in account. In
+     * other words, two vertical datums will return the same hash value if they
+     * are equal in the sense of
+     * <code>{@link #equals equals}(AbstractIdentifiedObject, <strong>false</strong>)</code>.
+     *
+     * @return The hash code value. This value doesn't need to be the same
+     *         in past or future versions of this class.
+     */
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ type.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/Spheroid.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/Spheroid.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/datum/Spheroid.java	(revision 28000)
@@ -0,0 +1,54 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.datum;
+
+import java.util.Map;
+import javax.measure.unit.Unit;
+import javax.measure.quantity.Length;
+
+
+/**
+ * A ellipsoid which is spherical. This ellipsoid implements a faster
+ * {@link #orthodromicDistance} method.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/datum/Spheroid.java $
+ * @version $Id: Spheroid.java 31000 2008-07-10 21:11:13Z desruisseaux $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @since 2.0
+ */
+final class Spheroid extends DefaultEllipsoid {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 7867565381280669821L;
+
+    /**
+     * Constructs a new sphere using the specified radius.
+     *
+     * @param properties    Set of properties. Should contains at least {@code "name"}.
+     * @param radius        The equatorial and polar radius.
+     * @param ivfDefinitive {@code true} if the inverse flattening is definitive.
+     * @param unit          The units of the radius value.
+     */
+    protected Spheroid(Map<String,?> properties, double radius, boolean ivfDefinitive, Unit<Length> unit) {
+        super(properties, check("radius", radius), radius, Double.POSITIVE_INFINITY, ivfDefinitive, unit);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/AbstractAuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/AbstractAuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/AbstractAuthorityFactory.java	(revision 28000)
@@ -0,0 +1,953 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.factory;
+
+import java.util.Set;
+import java.util.Collections;
+import javax.measure.unit.Unit;
+
+import org.opengis.referencing.*;
+import org.opengis.referencing.cs.*;
+import org.opengis.referencing.crs.*;
+import org.opengis.referencing.datum.*;
+import org.opengis.referencing.operation.*;
+import org.opengis.util.InternationalString;
+import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.util.GenericName;
+
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.NameFactory;
+
+
+/**
+ * Base class for authority factories. An <cite>authority</cite> is an organization that maintains
+ * definitions of authority codes. An <cite>authority code</cite> is a compact string defined by
+ * an authority to reference a particular spatial reference object. For example the
+ * <A HREF="http://www.epsg.org">European Petroleum Survey Group (EPSG)</A> maintains
+ * a database of coordinate systems, and other spatial referencing objects, where each
+ * object has a code number ID. For example, the EPSG code for a WGS84 Lat/Lon coordinate
+ * system is {@code "4326"}.
+ * <p>
+ * This class defines a default implementation for most methods defined in the
+ * {@link DatumAuthorityFactory}, {@link CSAuthorityFactory} and {@link CRSAuthorityFactory}
+ * interfaces. However, those interfaces do not appear in the {@code implements} clause of
+ * this class declaration. This is up to subclasses to decide which interfaces they declare
+ * to implement.
+ * <p>
+ * The default implementation for all {@code createFoo} methods ultimately invokes
+ * {@link #createObject}, which may be the only method that a subclass need to override.
+ * However, other methods may be overridden as well for better performances.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/AbstractAuthorityFactory.java $
+ * @version $Id: AbstractAuthorityFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public abstract class AbstractAuthorityFactory extends ReferencingFactory
+        implements AuthorityFactory
+{
+    /**
+     * Constructs an instance using the specified priority level.
+     *
+     * @param priority The priority for this factory, as a number between
+     *        {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
+     *        {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
+     */
+    protected AbstractAuthorityFactory(final int priority) {
+        super(priority);
+    }
+
+    /**
+     * Returns {@code true} if this factory is available. This method may returns {@code false}
+     * for example if a connection to the EPSG database failed. This method is defined here for
+     * implementation convenience, but not yet public because not yet applicable. It will be made
+     * public in {@link DeferredAuthorityFactory} and {@link AuthorityFactoryAdapter} subclasses,
+     * which implement the {@link org.geotools.factory.OptionalFactory} interface.
+     */
+    boolean isAvailable() {
+        return true;
+    }
+
+    /**
+     * If this factory is a wrapper for the specified factory that do not add any additional
+     * {@linkplain #getAuthorityCodes authority codes}, returns {@code true}. Example of such
+     * wrappers are {@link BufferedAuthorityFactory} and {@link TransformedAuthorityFactory}.
+     * <p>
+     * This method should perform a cheap test. It is for {@link FallbackAuthorityFactory}
+     * internal use only and should not be public.
+     */
+    boolean sameAuthorityCodes(final AuthorityFactory factory) {
+        return factory == this;
+    }
+
+    /**
+     * Returns the organization or party responsible for definition and maintenance of the
+     * database.
+     */
+    public abstract Citation getAuthority();
+
+    /**
+     * Returns a description of the underlying backing store, or {@code null} if unknown.
+     * This is for example the database software used for storing the data.
+     * The default implementation returns always {@code null}.
+     *
+     * @return The description of the underlying backing store, or {@code null}.
+     * @throws FactoryException if a failure occurs while fetching the engine description.
+     */
+    public String getBackingStoreDescription() throws FactoryException {
+        return null;
+    }
+
+    /**
+     * Returns an arbitrary object from a code. The returned object will typically be an instance
+     * of {@link Datum}, {@link CoordinateSystem}, {@link CoordinateReferenceSystem} or
+     * {@link CoordinateOperation}. The default implementation always throw an exception.
+     * Subclasses should override this method if they are capable to automatically detect
+     * the object type from its code.
+     *
+     * @param  code Value allocated by authority.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createCoordinateReferenceSystem
+     * @see #createDatum
+     * @see #createEllipsoid
+     * @see #createUnit
+     */
+    public IdentifiedObject createObject(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        ensureNonNull("code", code);
+        throw noSuchAuthorityCode(IdentifiedObject.class, code);
+    }
+
+    /**
+     * Returns an arbitrary {@linkplain Datum datum} from a code.
+     * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The datum for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createGeodeticDatum
+     * @see #createVerticalDatum
+     * @see #createTemporalDatum
+     */
+    public Datum createDatum(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final IdentifiedObject object = createObject(code);
+        try {
+            return (Datum) object;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(Datum.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a {@linkplain EngineeringDatum engineering datum} from a code.
+     * The default implementation invokes <code>{@linkplain #createDatum createDatum}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The datum for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createEngineeringCRS
+     */
+    public EngineeringDatum createEngineeringDatum(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final Datum datum = createDatum(code);
+        try {
+            return (EngineeringDatum) datum;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(EngineeringDatum.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a {@linkplain ImageDatum image datum} from a code.
+     * The default implementation invokes <code>{@linkplain #createDatum createDatum}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The datum for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createImageCRS
+     */
+    public ImageDatum createImageDatum(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final Datum datum = createDatum(code);
+        try {
+            return (ImageDatum) datum;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(ImageDatum.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a {@linkplain VerticalDatum vertical datum} from a code.
+     * The default implementation invokes <code>{@linkplain #createDatum createDatum}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The datum for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createVerticalCRS
+     */
+    public VerticalDatum createVerticalDatum(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final Datum datum = createDatum(code);
+        try {
+            return (VerticalDatum) datum;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(VerticalDatum.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a {@linkplain TemporalDatum temporal datum} from a code.
+     * The default implementation invokes <code>{@linkplain #createDatum createDatum}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The datum for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createTemporalCRS
+     */
+    public TemporalDatum createTemporalDatum(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final Datum datum = createDatum(code);
+        try {
+            return (TemporalDatum) datum;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(TemporalDatum.class, code, exception);
+        }
+    }
+
+    /**
+     * Returns a {@linkplain GeodeticDatum geodetic datum} from a code.
+     * The default implementation invokes <code>{@linkplain #createDatum createDatum}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The datum for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createEllipsoid
+     * @see #createPrimeMeridian
+     * @see #createGeographicCRS
+     * @see #createProjectedCRS
+     */
+    public GeodeticDatum createGeodeticDatum(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final Datum datum = createDatum(code);
+        try {
+            return (GeodeticDatum) datum;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(GeodeticDatum.class, code, exception);
+        }
+    }
+
+    /**
+     * Returns an {@linkplain Ellipsoid ellipsoid} from a code.
+     * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The ellipsoid for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createGeodeticDatum
+     */
+    public Ellipsoid createEllipsoid(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final IdentifiedObject object = createObject(code);
+        try {
+            return (Ellipsoid) object;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(Ellipsoid.class, code, exception);
+        }
+    }
+
+    /**
+     * Returns a {@linkplain PrimeMeridian prime meridian} from a code.
+     * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The prime meridian for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createGeodeticDatum
+     */
+    public PrimeMeridian createPrimeMeridian(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final IdentifiedObject object = createObject(code);
+        try {
+            return (PrimeMeridian) object;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(PrimeMeridian.class, code, exception);
+        }
+    }
+
+    /**
+     * Returns a {@linkplain Extent extent} (usually an area of validity) from a code.
+     * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The extent for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public Extent createExtent(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final IdentifiedObject object = createObject(code);
+        try {
+            return (Extent) object;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(Extent.class, code, exception);
+        }
+    }
+
+    /**
+     * Returns an arbitrary {@linkplain CoordinateSystem coordinate system} from a code.
+     * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public CoordinateSystem createCoordinateSystem(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final IdentifiedObject object = createObject(code);
+        try {
+            return (CoordinateSystem) object;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(CoordinateSystem.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a cartesian coordinate system from a code.
+     * The default implementation invokes
+     * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public CartesianCS createCartesianCS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateSystem cs = createCoordinateSystem(code);
+        try {
+            return (CartesianCS) cs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(CartesianCS.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a polar coordinate system from a code.
+     * The default implementation invokes
+     * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public PolarCS createPolarCS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateSystem cs = createCoordinateSystem(code);
+        try {
+            return (PolarCS) cs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(PolarCS.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a cylindrical coordinate system from a code.
+     * The default implementation invokes
+     * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public CylindricalCS createCylindricalCS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateSystem cs = createCoordinateSystem(code);
+        try {
+            return (CylindricalCS) cs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(CylindricalCS.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a spherical coordinate system from a code.
+     * The default implementation invokes
+     * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public SphericalCS createSphericalCS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateSystem cs = createCoordinateSystem(code);
+        try {
+            return (SphericalCS) cs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(SphericalCS.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates an ellipsoidal coordinate system from a code.
+     * The default implementation invokes
+     * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public EllipsoidalCS createEllipsoidalCS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateSystem cs = createCoordinateSystem(code);
+        try {
+            return (EllipsoidalCS) cs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(EllipsoidalCS.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a vertical coordinate system from a code.
+     * The default implementation invokes
+     * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public VerticalCS createVerticalCS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateSystem cs = createCoordinateSystem(code);
+        try {
+            return (VerticalCS) cs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(VerticalCS.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a temporal coordinate system from a code.
+     * The default implementation invokes
+     * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public TimeCS createTimeCS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateSystem cs = createCoordinateSystem(code);
+        try {
+            return (TimeCS) cs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(TimeCS.class, code, exception);
+        }
+    }
+
+    /**
+     * Returns a {@linkplain CoordinateSystemAxis coordinate system axis} from a code.
+     * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The axis for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public CoordinateSystemAxis createCoordinateSystemAxis(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final IdentifiedObject object = createObject(code);
+        try {
+            return (CoordinateSystemAxis) object;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(CoordinateSystemAxis.class, code, exception);
+        }
+    }
+
+    /**
+     * Returns an {@linkplain Unit unit} from a code.
+     * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
+     *
+     * @param  code Value allocated by authority.
+     * @return The unit for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public Unit<?> createUnit(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final IdentifiedObject object = createObject(code);
+        try {
+            return (Unit) object;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(Unit.class, code, exception);
+        }
+    }
+
+    /**
+     * Returns an arbitrary {@linkplain CoordinateReferenceSystem coordinate reference system}
+     * from a code. If the coordinate reference system type is know at compile time, it is
+     * recommended to invoke the most precise method instead of this one (for example
+     * <code>&nbsp;{@linkplain #createGeographicCRS createGeographicCRS}(code)&nbsp;</code>
+     * instead of <code>&nbsp;createCoordinateReferenceSystem(code)&nbsp;</code> if the caller
+     * know he is asking for a {@linkplain GeographicCRS geographic coordinate reference system}).
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createGeographicCRS
+     * @see #createProjectedCRS
+     * @see #createVerticalCRS
+     * @see #createTemporalCRS
+     * @see #createCompoundCRS
+     */
+    public CoordinateReferenceSystem createCoordinateReferenceSystem(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final IdentifiedObject object = createObject(code);
+        try {
+            return (CoordinateReferenceSystem) object;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(CoordinateReferenceSystem.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a 3D coordinate reference system from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public CompoundCRS createCompoundCRS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
+        try {
+            return (CompoundCRS) crs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(CompoundCRS.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a derived coordinate reference system from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public DerivedCRS createDerivedCRS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
+        try {
+            return (DerivedCRS) crs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(DerivedCRS.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a {@linkplain EngineeringCRS engineering coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public EngineeringCRS createEngineeringCRS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
+        try {
+            return (EngineeringCRS) crs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(EngineeringCRS.class, code, exception);
+        }
+    }
+
+    /**
+     * Returns a {@linkplain GeographicCRS geographic coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createGeodeticDatum
+     */
+    public GeographicCRS createGeographicCRS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
+        try {
+            return (GeographicCRS) crs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(GeographicCRS.class, code, exception);
+        }
+    }
+
+    /**
+     * Returns a {@linkplain GeocentricCRS geocentric coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see #createGeodeticDatum
+     */
+    public GeocentricCRS createGeocentricCRS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
+        try {
+            return (GeocentricCRS) crs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(GeocentricCRS.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a {@linkplain ImageCRS image coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public ImageCRS createImageCRS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
+        try {
+            return (ImageCRS) crs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(ImageCRS.class, code, exception);
+        }
+    }
+
+    /**
+     * Returns a {@linkplain ProjectedCRS projected coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createGeodeticDatum
+     */
+    public ProjectedCRS createProjectedCRS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
+        try {
+            return (ProjectedCRS) crs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(ProjectedCRS.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a {@linkplain TemporalCRS temporal coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createTemporalDatum
+     */
+    public TemporalCRS createTemporalCRS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
+        try {
+            return (TemporalCRS) crs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(TemporalCRS.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a {@linkplain VerticalCRS vertical coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createVerticalDatum
+     */
+    public VerticalCRS createVerticalCRS(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
+        try {
+            return (VerticalCRS) crs;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(VerticalCRS.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates a parameter descriptor from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @since 2.2
+     */
+    public ParameterDescriptor createParameterDescriptor(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final IdentifiedObject operation = createObject(code);
+        try {
+            return (ParameterDescriptor) operation;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(ParameterDescriptor.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates an operation method from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The operation method for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @since 2.2
+     */
+    public OperationMethod createOperationMethod(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final IdentifiedObject operation = createObject(code);
+        try {
+            return (OperationMethod) operation;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(OperationMethod.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates an operation from a single operation code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The operation for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @since 2.2
+     */
+    public CoordinateOperation createCoordinateOperation(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final IdentifiedObject operation = createObject(code);
+        try {
+            return (CoordinateOperation) operation;
+        } catch (ClassCastException exception) {
+            throw noSuchAuthorityCode(CoordinateOperation.class, code, exception);
+        }
+    }
+
+    /**
+     * Creates an operation from coordinate reference system codes. The default implementation
+     * returns an {@linkplain Collections#EMPTY_SET empty set}. We do not delegate to some kind
+     * of {@linkplain CoordinateOperationFactory#createOperation(CoordinateReferenceSystem,
+     * CoordinateReferenceSystem) coordinate operation factory method} because the usual contract
+     * for this method is to extract the information from an authority database like
+     * <A HREF="http://www.epsg.org">EPSG</A>, not to compute operations on-the-fly.
+     * <p>
+     * <strong>Rational:</strong> Coordinate operation factory
+     * {@linkplain org.geotools.referencing.operation.AuthorityBackedFactory backed by an authority}
+     * will invoke this method. If this method invoked the coordinate operation factory in turn, the
+     * application could be trapped in infinite recursive calls.
+     *
+     * @param  sourceCRS   Coded value of source coordinate reference system.
+     * @param  targetCRS   Coded value of target coordinate reference system.
+     * @return The operations from {@code sourceCRS} to {@code targetCRS}.
+     * @throws NoSuchAuthorityCodeException if a specified code was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @since 2.2
+     */
+    public Set<CoordinateOperation> createFromCoordinateReferenceSystemCodes(String sourceCRS, String targetCRS)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        return Collections.emptySet();
+    }
+
+    /**
+     * Returns a finder which can be used for looking up unidentified objects. The finder
+     * fetchs a fully {@linkplain IdentifiedObject identified object} from an incomplete one,
+     * for example from an object without identifier or "{@code AUTHORITY[...]}" element in
+     * <cite>Well Known Text</cite> terminology.
+     *
+     * @param  type The type of objects to look for. Should be a GeoAPI interface like
+     *         {@code GeographicCRS.class}, but this method accepts also implementation
+     *         class. If the type is unknown, use {@code IdentifiedObject.class}. A more
+     *         accurate type may help to speed up the search, since it reduces the amount
+     *         of tables to scan in some implementations like the factories backed by
+     *         EPSG database.
+     * @return A finder to use for looking up unidentified objects.
+     * @throws FactoryException if the finder can not be created.
+     *
+     * @since 2.4
+     */
+    public IdentifiedObjectFinder getIdentifiedObjectFinder(Class<? extends IdentifiedObject> type)
+            throws FactoryException
+    {
+        return new IdentifiedObjectFinder(this, type);
+    }
+
+    /**
+     * Releases resources immediately instead of waiting for the garbage collector.
+     * Once a factory has been disposed, further {@code create(...)} invocations
+     * may throw a {@link FactoryException}. Disposing a previously-disposed factory,
+     * however, has no effect.
+     *
+     * @throws FactoryException if an error occured while disposing the factory.
+     */
+    public void dispose() throws FactoryException {
+        // To be overridden by subclasses.
+    }
+
+    /**
+     * Creates an exception for an unknow authority code. This convenience method is provided
+     * for implementation of {@code createXXX} methods.
+     *
+     * @param  type  The GeoAPI interface that was to be created
+     *               (e.g. {@code CoordinateReferenceSystem.class}).
+     * @param  code  The unknow authority code.
+     * @param  cause The cause of this error, or {@code null}.
+     * @return An exception initialized with an error message built
+     *         from the specified informations.
+     */
+    private NoSuchAuthorityCodeException noSuchAuthorityCode(final Class              type,
+                                                             final String             code,
+                                                             final ClassCastException cause)
+    {
+        final NoSuchAuthorityCodeException exception = noSuchAuthorityCode(type, code);
+        exception.initCause(cause);
+        return exception;
+    }
+
+    /**
+     * Trims the authority scope, if present. For example if this factory is an EPSG authority
+     * factory and the specified code start with the "EPSG:" prefix, then the prefix is removed.
+     * Otherwise, the string is returned unchanged (except for leading and trailing spaces).
+     *
+     * @param  code The code to trim.
+     * @return The code without the authority scope.
+     */
+    protected String trimAuthority(String code) {
+        /*
+         * IMPLEMENTATION NOTE: This method is overrided in PropertyAuthorityFactory. If
+         * implementation below is modified, it is probably worth to revisit the overrided
+         * method as well.
+         */
+        code = code.trim();
+        final GenericName name  = NameFactory.create(code);
+        final GenericName scope = name.scope().name();
+        if (scope == null) {
+            return code;
+        }
+        if (Citations.identifierMatches(getAuthority(), scope.toString())) {
+            return name.tip().toString().trim();
+        }
+        return code;
+    }
+
+    /**
+     * Creates an exception for an unknow authority code. This convenience method is provided
+     * for implementation of {@code createXXX} methods.
+     *
+     * @param  type  The GeoAPI interface that was to be created
+     *               (e.g. {@code CoordinateReferenceSystem.class}).
+     * @param  code  The unknow authority code.
+     * @return An exception initialized with an error message built
+     *         from the specified informations.
+     */
+    protected final NoSuchAuthorityCodeException noSuchAuthorityCode(final Class  type,
+                                                                     final String code)
+    {
+        final InternationalString authority = getAuthority().getTitle();
+        return new NoSuchAuthorityCodeException(Errors.format(ErrorKeys.NO_SUCH_AUTHORITY_CODE_$3,
+                   code, authority, type), authority.toString(), code);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/AuthorityFactoryAdapter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/AuthorityFactoryAdapter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/AuthorityFactoryAdapter.java	(revision 28000)
@@ -0,0 +1,1127 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.factory;
+
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import javax.measure.unit.Unit;
+
+import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.util.InternationalString;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.AuthorityFactory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.cs.*;
+import org.opengis.referencing.crs.*;
+import org.opengis.referencing.datum.*;
+import org.opengis.referencing.operation.*;
+
+import org.geotools.factory.Hints;
+import org.geotools.factory.AbstractFactory;
+import org.geotools.factory.OptionalFactory;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.CRS;
+import org.geotools.resources.i18n.Loggings;
+import org.geotools.resources.i18n.LoggingKeys;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+
+
+/**
+ * An authority factory which delegates {@linkplain CoordinateReferenceSystem CRS},
+ * {@linkplain CoordinateSystem CS} or {@linkplain Datum datum} objects creation to
+ * some other factory implementations.
+ * <p>
+ * All constructors are protected because this class must be subclassed in order to determine
+ * which of the {@link DatumAuthorityFactory}, {@link CSAuthorityFactory} and
+ * {@link CRSAuthorityFactory} interfaces to implement.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/AuthorityFactoryAdapter.java $
+ * @version $Id: AuthorityFactoryAdapter.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class AuthorityFactoryAdapter extends AbstractAuthorityFactory implements OptionalFactory {
+
+    /**
+     * The underlying {@linkplain Datum datum} authority factory,
+     * or {@code null} if none.
+     */
+    final DatumAuthorityFactory datumFactory;
+
+    /**
+     * The underlying {@linkplain CoordinateSystem coordinate system} authority factory,
+     * or {@code null} if none.
+     */
+    final CSAuthorityFactory csFactory;
+
+    /**
+     * The underlying {@linkplain CoordinateReferenceSystem coordinate reference system}
+     * authority factory, or {@code null} if none.
+     */
+    final CRSAuthorityFactory crsFactory;
+
+    /**
+     * The underlying {@linkplain CoordinateOperation coordinate operation} authority factory,
+     * or {@code null} if none.
+     */
+    final CoordinateOperationAuthorityFactory operationFactory;
+
+    /**
+     * Creates a wrapper around no factory. This constructor should never be used except by
+     * subclasses overriding the <code>get</code><var>Foo</var><code>AuthorityFactory</code>
+     * methods.
+     *
+     * @param priority The priority for this factory, as a number between
+     *        {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
+     *        {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
+     */
+    AuthorityFactoryAdapter(final int priority) {
+        super(priority);
+        datumFactory     = null;
+        csFactory        = null;
+        crsFactory       = null;
+        operationFactory = null;
+    }
+
+    /**
+     * Creates a wrapper around the specified factory. The {@link #priority priority} field
+     * will be set to the same value than the specified factory. Subclasses should override
+     * the {@link #getPriority() getPriority()} method if they want to set a higher or lower
+     * priority for this instance.
+     *
+     * @param factory The factory to wrap.
+     */
+    protected AuthorityFactoryAdapter(final AuthorityFactory factory) {
+        this(factory, null);
+    }
+
+    /**
+     * For {@link FallbackAuthorityFactory} constructor only.
+     */
+    AuthorityFactoryAdapter(final AuthorityFactory factory, final AuthorityFactory fallback) {
+        this((factory  instanceof   CRSAuthorityFactory) ?   (CRSAuthorityFactory) factory  :
+             (fallback instanceof   CRSAuthorityFactory) ?   (CRSAuthorityFactory) fallback : null,
+             (factory  instanceof    CSAuthorityFactory) ?    (CSAuthorityFactory) factory  :
+             (fallback instanceof    CSAuthorityFactory) ?    (CSAuthorityFactory) fallback : null,
+             (factory  instanceof DatumAuthorityFactory) ? (DatumAuthorityFactory) factory  :
+             (fallback instanceof DatumAuthorityFactory) ? (DatumAuthorityFactory) fallback : null,
+             (factory  instanceof CoordinateOperationAuthorityFactory) ?
+                    (CoordinateOperationAuthorityFactory) factory :
+             (fallback instanceof CoordinateOperationAuthorityFactory) ?
+                    (CoordinateOperationAuthorityFactory) fallback : null);
+    }
+
+    /**
+     * Creates a wrapper around the specified factories. The {@link #priority priority} field will
+     * be set to the highest priority found in the specified factories. Subclasses should override
+     * the {@link #getPriority() getPriority()} method if they want to set a higher or lower
+     * priority for this instance.
+     *
+     * @param crsFactory   The {@linkplain CoordinateReferenceSystem coordinate reference system}
+     *                     authority factory, or {@code null}.
+     * @param csFactory    The {@linkplain CoordinateSystem coordinate system} authority factory,
+     *                     or {@code null}.
+     * @param datumFactory The {@linkplain Datum datum} authority factory, or {@code null}.
+     * @param opFactory    The {@linkplain CoordinateOperation coordinate operation} authority
+     *                     factory, or {@code null}.
+     */
+    protected AuthorityFactoryAdapter(final CRSAuthorityFactory                crsFactory,
+                                      final CSAuthorityFactory                  csFactory,
+                                      final DatumAuthorityFactory            datumFactory,
+                                      final CoordinateOperationAuthorityFactory opFactory)
+    {
+        super(Math.max(getPriority(datumFactory),
+              Math.max(getPriority(   csFactory),
+              Math.max(getPriority(  crsFactory),
+                       getPriority(   opFactory)))));
+
+        if (this instanceof CRSAuthorityFactory) {
+            ensureNonNull("crsFactory", crsFactory);
+        }
+        if (this instanceof CSAuthorityFactory) {
+            ensureNonNull("csFactory", csFactory);
+        }
+        if (this instanceof DatumAuthorityFactory) {
+            ensureNonNull("datumFactory", datumFactory);
+        }
+        if (this instanceof CoordinateOperationAuthorityFactory) {
+            ensureNonNull("opFactory", opFactory);
+        }
+        store(Hints.               DATUM_AUTHORITY_FACTORY, this.    datumFactory = datumFactory);
+        store(Hints.                  CS_AUTHORITY_FACTORY, this.       csFactory =    csFactory);
+        store(Hints.                 CRS_AUTHORITY_FACTORY, this.      crsFactory =   crsFactory);
+        store(Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY, this.operationFactory =    opFactory);
+    }
+
+    /**
+     * Returns the priority of the specified factory, or {@link #NORMAL_PRIORITY} if unknown.
+     */
+    private static int getPriority(final AuthorityFactory factory) {
+        return (factory instanceof AbstractFactory) ?
+            ((AbstractFactory) factory).getPriority() : NORMAL_PRIORITY;
+    }
+
+    /**
+     * Adds the specified factory to the set of hints, if non null.
+     */
+    private void store(final Hints.Key key, final AuthorityFactory factory) {
+        if (factory != null) {
+            if (hints.put(key, factory) != null) {
+                // Should never happen since 'hints' should be initially empty.
+                throw new AssertionError(key);
+            }
+        }
+    }
+
+    /**
+     * Returns the direct dependencies. The returned list contains the backing store specified
+     * at construction time, or the exception if the backing store can't be obtained.
+     */
+    @Override
+    Collection<? super AuthorityFactory> dependencies() {
+        final List<Object> dep = new ArrayList<Object>(4);
+        Object factory;
+        try {
+            factory = getAuthorityFactory(null);
+        } catch (FactoryException e) {
+            factory = e;
+        }
+        dep.add(factory);
+        return dep;
+    }
+
+    /**
+     * If this factory is a wrapper for the specified factory that do not add any additional
+     * {@linkplain #getAuthorityCodes authority codes}, returns {@code true}. This method is
+     * for {@link FallbackAuthorityFactory} internal use only and should not be public. We
+     * expect only a simple check, so we don't invoke the {@code getFooAuthorityFactory(...)}
+     * methods.
+     */
+    @Override
+    boolean sameAuthorityCodes(final AuthorityFactory factory) {
+        if (!isCodeMethodOverriden()) {
+            /*
+             * Tests wrapped factories only if the 'toBackingFactoryCode(String)' method is not
+             * overwritten, otherwise we can't assume that the authority codes are the same. The
+             * impact on the main subclasses are usually as below:
+             *
+             *     URN_AuthorityFactory           - excluded
+             *     HTTP_AuthorityFactory          - excluded
+             *     OrderedAxisAuthorityFactory    - make the test below
+             *     FallbackAuthorityFactory       - make the test below
+             *
+             * Note: in the particular case of FallbackAuthorityFactory, we test the
+             *       primary factory only, not the fallback. This behavior matches the
+             *       FallbackAuthorityFactory.create(boolean,int,Iterator) need, which
+             *       will process this case in a special way.
+             */
+            if (sameAuthorityCodes(crsFactory,       factory) &&
+                sameAuthorityCodes(csFactory,        factory) &&
+                sameAuthorityCodes(datumFactory,     factory) &&
+                sameAuthorityCodes(operationFactory, factory))
+            {
+                return true;
+            }
+        }
+        return super.sameAuthorityCodes(factory);
+    }
+
+    /**
+     * Helper methods for {@link #sameAuthorityCodes(AuthorityFactory)} and
+     * {@link FallbackAuthorityFactory#create(boolean,int,Iterator)} implementations. If there is no
+     * backing store, returns {@code true} in order to take in account only the backing stores that
+     * are assigned. This behavior match the need of the above-cited implementations.
+     */
+    static boolean sameAuthorityCodes(final AuthorityFactory backingStore,
+                                      final AuthorityFactory factory)
+    {
+        if (backingStore instanceof AbstractAuthorityFactory) {
+            if (((AbstractAuthorityFactory) backingStore).sameAuthorityCodes(factory)) {
+                return true;
+            }
+        }
+        return (factory == backingStore) || (backingStore == null);
+    }
+
+    /**
+     * Returns {@code true} if this factory is ready for use. This default implementation
+     * checks the availability of CRS, CS, datum and operation authority factories specified
+     * at construction time.
+     *
+     * @return {@code true} if this factory is ready for use.
+     */
+    @Override
+    public boolean isAvailable() {
+        return isAvailable(      crsFactory) &&
+               isAvailable(       csFactory) &&
+               isAvailable(    datumFactory) &&
+               isAvailable(operationFactory);
+    }
+
+    /**
+     * Checks the availability of the specified factory.
+     */
+    private static boolean isAvailable(final AuthorityFactory factory) {
+        return !(factory instanceof OptionalFactory) || ((OptionalFactory) factory).isAvailable();
+    }
+
+    /**
+     * Replaces the specified unit, if applicable.
+     * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
+     */
+    Unit<?> replace(Unit<?> units) throws FactoryException {
+        return units;
+    }
+
+    /**
+     * Replaces (if needed) the specified axis by a new one.
+     * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
+     */
+    CoordinateSystemAxis replace(CoordinateSystemAxis axis) throws FactoryException {
+        return axis;
+    }
+
+    /**
+     * Replaces (if needed) the specified coordinate system by a new one.
+     * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
+     */
+    CoordinateSystem replace(CoordinateSystem cs) throws FactoryException {
+        return cs;
+    }
+
+    /**
+     * Replaces (if needed) the specified datum by a new one.
+     * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
+     */
+    Datum replace(Datum datum) throws FactoryException {
+        return datum;
+    }
+
+    /**
+     * Replaces (if needed) the specified coordinate reference system.
+     * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
+     */
+    CoordinateReferenceSystem replace(CoordinateReferenceSystem crs) throws FactoryException {
+        return crs;
+    }
+
+    /**
+     * Replaces (if needed) the specified coordinate operation.
+     * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
+     */
+    CoordinateOperation replace(CoordinateOperation operation) throws FactoryException {
+        return operation;
+    }
+
+    /**
+     * Delegates the work to an appropriate {@code replace} method for the given object.
+     */
+    private IdentifiedObject replaceObject(final IdentifiedObject object) throws FactoryException {
+        if (object instanceof CoordinateReferenceSystem) {
+            return replace((CoordinateReferenceSystem) object);
+        }
+        if (object instanceof CoordinateSystem) {
+            return replace((CoordinateSystem) object);
+        }
+        if (object instanceof CoordinateSystemAxis) {
+            return replace((CoordinateSystemAxis) object);
+        }
+        if (object instanceof Datum) {
+            return replace((Datum) object);
+        }
+        if (object instanceof CoordinateOperation) {
+            return replace((CoordinateOperation) object);
+        }
+        return object;
+    }
+
+    /**
+     * Returns one of the underlying factories as an instance of the GeoTools implementation. If
+     * there is none of them, then returns {@code null} or throws an exception if {@code caller}
+     * is not null.
+     */
+    private AbstractAuthorityFactory getGeotoolsFactory(final String caller, final String code)
+            throws FactoryException
+    {
+        final AuthorityFactory candidate = getAuthorityFactory(code);
+        if (candidate instanceof AbstractAuthorityFactory) {
+            return (AbstractAuthorityFactory) candidate;
+        }
+        if (caller == null) {
+            return null;
+        }
+        throw new FactoryException(Errors.format(
+                    ErrorKeys.GEOTOOLS_EXTENSION_REQUIRED_$1, caller));
+    }
+
+    /**
+     * Returns a description of the underlying backing store, or {@code null} if unknow.
+     *
+     * @throws FactoryException if a failure occured while fetching the engine description.
+     */
+    @Override
+    public String getBackingStoreDescription() throws FactoryException {
+        final AbstractAuthorityFactory factory = getGeotoolsFactory(null, null);
+        return (factory != null) ? factory.getBackingStoreDescription() : null;
+    }
+
+    /**
+     * Returns the vendor responsible for creating this factory implementation.
+     */
+    @Override
+    public Citation getVendor() {
+        return getAuthorityFactory().getVendor();
+    }
+
+    /**
+     * Returns the organization or party responsible for definition and maintenance of the
+     * database.
+     */
+    public Citation getAuthority() {
+        return getAuthorityFactory().getAuthority();
+    }
+
+    /**
+     * Returns the set of authority code for the specified type.
+     *
+     * @todo We should returns the union of authority codes from all underlying factories.
+     */
+    public Set<String> getAuthorityCodes(final Class<? extends IdentifiedObject> type)
+            throws FactoryException
+    {
+        return getAuthorityFactory(null).getAuthorityCodes(type);
+    }
+
+    /**
+     * Returns a description for the object identified by the specified code.
+     */
+    public InternationalString getDescriptionText(final String code) throws FactoryException {
+        return getAuthorityFactory(code).getDescriptionText(toBackingFactoryCode(code));
+    }
+
+    /**
+     * Returns an arbitrary object from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see #createCoordinateReferenceSystem
+     * @see #createDatum
+     * @see #createEllipsoid
+     * @see #createUnit
+     */
+    @Override
+    public IdentifiedObject createObject(final String code) throws FactoryException {
+        return replaceObject(getAuthorityFactory(code).createObject(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Returns an arbitrary {@linkplain Datum datum} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see #createGeodeticDatum
+     * @see #createVerticalDatum
+     * @see #createTemporalDatum
+     */
+    @Override
+    public Datum createDatum(final String code) throws FactoryException {
+        return replace(getDatumAuthorityFactory(code).createDatum(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a {@linkplain EngineeringDatum engineering datum} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see #createEngineeringCRS
+     */
+    @Override
+    public EngineeringDatum createEngineeringDatum(final String code) throws FactoryException {
+        return (EngineeringDatum) replace(getDatumAuthorityFactory(code).
+                createEngineeringDatum(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a {@linkplain ImageDatum image datum} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see #createImageCRS
+     */
+    @Override
+    public ImageDatum createImageDatum(final String code) throws FactoryException {
+        return (ImageDatum) replace(getDatumAuthorityFactory(code).
+                createImageDatum(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a {@linkplain VerticalDatum vertical datum} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see #createVerticalCRS
+     */
+    @Override
+    public VerticalDatum createVerticalDatum(final String code) throws FactoryException {
+        return (VerticalDatum) replace(getDatumAuthorityFactory(code).
+                createVerticalDatum(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a {@linkplain TemporalDatum temporal datum} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see #createTemporalCRS
+     */
+    @Override
+    public TemporalDatum createTemporalDatum(final String code) throws FactoryException {
+        return (TemporalDatum) replace(getDatumAuthorityFactory(code).
+                createTemporalDatum(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Returns a {@linkplain GeodeticDatum geodetic datum} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see #createEllipsoid
+     * @see #createPrimeMeridian
+     * @see #createGeographicCRS
+     * @see #createProjectedCRS
+     */
+    @Override
+    public GeodeticDatum createGeodeticDatum(final String code) throws FactoryException {
+        return (GeodeticDatum) replace(getDatumAuthorityFactory(code).
+                createGeodeticDatum(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Returns an {@linkplain Ellipsoid ellipsoid} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see #createGeodeticDatum
+     */
+    @Override
+    public Ellipsoid createEllipsoid(final String code) throws FactoryException {
+        return getDatumAuthorityFactory(code).createEllipsoid(toBackingFactoryCode(code));
+    }
+
+    /**
+     * Returns a {@linkplain PrimeMeridian prime meridian} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see #createGeodeticDatum
+     */
+    @Override
+    public PrimeMeridian createPrimeMeridian(final String code) throws FactoryException {
+        return getDatumAuthorityFactory(code).createPrimeMeridian(toBackingFactoryCode(code));
+    }
+
+    /**
+     * Returns a {@linkplain Extent extent} (usually an area of validity) from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public Extent createExtent(final String code) throws FactoryException {
+        return getGeotoolsFactory("createExtent", code).createExtent(toBackingFactoryCode(code));
+    }
+
+    /**
+     * Returns an arbitrary {@linkplain CoordinateSystem coordinate system} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public CoordinateSystem createCoordinateSystem(final String code) throws FactoryException {
+        return replace(getCSAuthorityFactory(code).
+                createCoordinateSystem(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a cartesian coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public CartesianCS createCartesianCS(final String code) throws FactoryException {
+        return (CartesianCS) replace(getCSAuthorityFactory(code).
+                createCartesianCS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a polar coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public PolarCS createPolarCS(final String code) throws FactoryException {
+        return (PolarCS) replace(getCSAuthorityFactory(code).
+                createPolarCS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a cylindrical coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public CylindricalCS createCylindricalCS(final String code) throws FactoryException {
+        return (CylindricalCS) replace(getCSAuthorityFactory(code).
+                createCylindricalCS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a spherical coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public SphericalCS createSphericalCS(final String code) throws FactoryException {
+        return (SphericalCS) replace(getCSAuthorityFactory(code).
+                createSphericalCS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates an ellipsoidal coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public EllipsoidalCS createEllipsoidalCS(final String code) throws FactoryException {
+        return (EllipsoidalCS) replace(getCSAuthorityFactory(code).
+                createEllipsoidalCS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a vertical coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public VerticalCS createVerticalCS(final String code) throws FactoryException {
+        return (VerticalCS) replace(getCSAuthorityFactory(code).
+                createVerticalCS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a temporal coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public TimeCS createTimeCS(final String code) throws FactoryException {
+        return (TimeCS) replace(getCSAuthorityFactory(code).
+                createTimeCS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Returns a {@linkplain CoordinateSystemAxis coordinate system axis} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public CoordinateSystemAxis createCoordinateSystemAxis(final String code)
+            throws FactoryException
+    {
+        return replace(getCSAuthorityFactory(code).
+                createCoordinateSystemAxis(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Returns an {@linkplain Unit unit} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public Unit<?> createUnit(final String code) throws FactoryException {
+        return replace(getCSAuthorityFactory(code).
+                createUnit(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Returns an arbitrary {@linkplain CoordinateReferenceSystem coordinate reference system}
+     * from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see #createGeographicCRS
+     * @see #createProjectedCRS
+     * @see #createVerticalCRS
+     * @see #createTemporalCRS
+     * @see #createCompoundCRS
+     */
+    @Override
+    public CoordinateReferenceSystem createCoordinateReferenceSystem(final String code)
+            throws FactoryException
+    {
+        return replace(getCRSAuthorityFactory(code).
+                createCoordinateReferenceSystem(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a 3D coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public CompoundCRS createCompoundCRS(final String code) throws FactoryException {
+        return (CompoundCRS) replace(getCRSAuthorityFactory(code).
+                createCompoundCRS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a derived coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public DerivedCRS createDerivedCRS(final String code) throws FactoryException {
+        return (DerivedCRS) replace(getCRSAuthorityFactory(code).
+                createDerivedCRS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a {@linkplain EngineeringCRS engineering coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public EngineeringCRS createEngineeringCRS(final String code) throws FactoryException {
+        return (EngineeringCRS) replace(getCRSAuthorityFactory(code).
+                createEngineeringCRS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Returns a {@linkplain GeographicCRS geographic coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public GeographicCRS createGeographicCRS(final String code) throws FactoryException {
+        return (GeographicCRS) replace(getCRSAuthorityFactory(code).
+                createGeographicCRS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Returns a {@linkplain GeocentricCRS geocentric coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public GeocentricCRS createGeocentricCRS(final String code) throws FactoryException {
+        return (GeocentricCRS) replace(getCRSAuthorityFactory(code).
+                createGeocentricCRS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a {@linkplain ImageCRS image coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public ImageCRS createImageCRS(final String code) throws FactoryException {
+        return (ImageCRS) replace(getCRSAuthorityFactory(code).
+                createImageCRS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Returns a {@linkplain ProjectedCRS projected coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public ProjectedCRS createProjectedCRS(final String code) throws FactoryException {
+        return (ProjectedCRS) replace(getCRSAuthorityFactory(code).
+                createProjectedCRS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a {@linkplain TemporalCRS temporal coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public TemporalCRS createTemporalCRS(final String code) throws FactoryException {
+        return (TemporalCRS) replace(getCRSAuthorityFactory(code).
+                createTemporalCRS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a {@linkplain VerticalCRS vertical coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public VerticalCRS createVerticalCRS(final String code) throws FactoryException {
+        return (VerticalCRS) replace(getCRSAuthorityFactory(code).
+                createVerticalCRS(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates a parameter descriptor from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public ParameterDescriptor createParameterDescriptor(final String code) throws FactoryException {
+        return getGeotoolsFactory("createParameterDescriptor", code).
+                createParameterDescriptor(toBackingFactoryCode(code));
+    }
+
+    /**
+     * Creates an operation method from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public OperationMethod createOperationMethod(final String code) throws FactoryException {
+        return getGeotoolsFactory("createOperationMethod", code).
+                createOperationMethod(toBackingFactoryCode(code));
+    }
+
+    /**
+     * Creates an operation from a single operation code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public CoordinateOperation createCoordinateOperation(final String code) throws FactoryException {
+        return replace(getCoordinateOperationAuthorityFactory(code).
+                createCoordinateOperation(toBackingFactoryCode(code)));
+    }
+
+    /**
+     * Creates an operation from coordinate reference system codes.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public Set<CoordinateOperation> createFromCoordinateReferenceSystemCodes(
+            final String sourceCRS, final String targetCRS) throws FactoryException
+    {
+        final CoordinateOperationAuthorityFactory factory, check;
+        factory = getCoordinateOperationAuthorityFactory(sourceCRS);
+        check   = getCoordinateOperationAuthorityFactory(targetCRS);
+        if (factory != check) {
+            /*
+             * No coordinate operation because of mismatched factories. This is not
+             * illegal - the result is an empty set - but it is worth to notify the
+             * user since this case has some chances to be an user error.
+             */
+            final LogRecord record = Loggings.format(Level.WARNING,
+                    LoggingKeys.MISMATCHED_COORDINATE_OPERATION_FACTORIES_$2, sourceCRS, targetCRS);
+            record.setSourceMethodName("createFromCoordinateReferenceSystemCodes");
+            record.setSourceClassName(AuthorityFactoryAdapter.class.getName());
+            record.setLoggerName(LOGGER.getName());
+            LOGGER.log(record);
+            return Collections.emptySet();
+        }
+        return factory.createFromCoordinateReferenceSystemCodes(
+                toBackingFactoryCode(sourceCRS), toBackingFactoryCode(targetCRS));
+    }
+
+    /**
+     * Returns a finder which can be used for looking up unidentified objects.
+     * The default implementation delegates the lookups to the underlying factory.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @since 2.4
+     */
+    @Override
+    public IdentifiedObjectFinder getIdentifiedObjectFinder(Class<? extends IdentifiedObject> type)
+            throws FactoryException
+    {
+        return new Finder(type);
+    }
+
+    /**
+     * A {@link IdentifiedObjectFinder} which tests
+     * {@linkplain AuthorityFactoryAdapter#replaceObject modified objects}
+     * in addition of original object.
+     */
+    class Finder extends IdentifiedObjectFinder.Adapter {
+        /**
+         * Creates a finder for the underlying backing store.
+         */
+        protected Finder(final Class<? extends IdentifiedObject> type) throws FactoryException {
+            super(getGeotoolsFactory("getIdentifiedObjectFinder", null).getIdentifiedObjectFinder(type));
+        }
+
+        /**
+         * Returns {@code candidate}, or an object derived from {@code candidate}, if it is
+         * {@linkplain CRS#equalsIgnoreMetadata equals ignoring metadata} to the specified
+         * model. Otherwise returns {@code null}.
+         *
+         * @throws FactoryException if an error occured while creating a derived object.
+         */
+        @Override
+        protected IdentifiedObject deriveEquivalent(final IdentifiedObject candidate,
+                                                    final IdentifiedObject model)
+                throws FactoryException
+        {
+            final IdentifiedObject modified = replaceObject(candidate);
+            if (modified != candidate) {
+                if (CRS.equalsIgnoreMetadata(modified, model)) {
+                    return modified;
+                }
+            }
+            return super.deriveEquivalent(candidate, model);
+        }
+    }
+
+    /**
+     * Creates an exception for a missing factory. We actually returns an instance of
+     * {@link NoSuchAuthorityCodeException} because this kind of exception is treated
+     * especially by {@link FallbackAuthorityFactory}.
+     */
+    private FactoryException missingFactory(final Class category, final String code) {
+        return new NoSuchAuthorityCodeException(Errors.format(ErrorKeys.FACTORY_NOT_FOUND_$1,
+                category), Citations.getIdentifier(getAuthority()), trimAuthority(code));
+    }
+
+    /**
+     * For internal use by {@link #getAuthority} and {@link #getVendor} only. Its only purpose
+     * is to catch the {@link FactoryException} for methods that don't allow it. The protected
+     * method should be used instead when this exception is allowed.
+     */
+    private AuthorityFactory getAuthorityFactory() {
+        try {
+            return getAuthorityFactory(null);
+        } catch (FactoryException cause) {
+            throw new IllegalStateException(Errors.format(ErrorKeys.UNDEFINED_PROPERTY), cause);
+        }
+    }
+
+    /**
+     * Returns an authority factory of the specified type. This method delegates to:
+     * <ul>
+     *   <li>{@link #getCRSAuthorityFactory} if {@code type} is
+     *       {@code CRSAuthorityFactory.class};</li>
+     *   <li>{@link #getCSAuthorityFactory} if {@code type} is
+     *       {@code CSAuthorityFactory.class};</li>
+     *   <li>{@link #getDatumAuthorityFactory} if {@code type} is
+     *       {@code DatumAuthorityFactory.class};</li>
+     *   <li>{@link #CoordinateOperationAuthorityFactory} if {@code type} is
+     *       {@code CoordinateOperationAuthorityFactory.class};</li>
+     * </ul>
+     *
+     * @throws IllegalArgumentException if the specified {@code type} is invalid.
+     * @throws FactoryException if no suitable factory were found.
+     */
+    @SuppressWarnings("unchecked")
+    <T extends AuthorityFactory> T getAuthorityFactory(final Class<T> type, final String code)
+            throws FactoryException
+    {
+        final AuthorityFactory f;
+        if (CRSAuthorityFactory.class.equals(type)) {
+            f = getCRSAuthorityFactory(code);
+        } else if (CSAuthorityFactory.class.equals(type)) {
+            f = getCSAuthorityFactory(code);
+        } else if (DatumAuthorityFactory.class.equals(type)) {
+            f = getDatumAuthorityFactory(code);
+        } else if (CoordinateOperationAuthorityFactory.class.equals(type)) {
+            f = getCoordinateOperationAuthorityFactory(code);
+        } else {
+            throw new IllegalArgumentException(Errors.format(
+                    ErrorKeys.ILLEGAL_ARGUMENT_$2, "type", type));
+        }
+        return type.cast(f);
+    }
+
+    /**
+     * Returns a generic object factory to use for the specified code. The default implementation
+     * returns one of the factory specified at construction time. Subclasses can override
+     * this method in order to select a different factory implementation depending on the
+     * code value.
+     * <p>
+     * <strong>Note:</strong> The value of the {@code code} argument given to this
+     * method may be {@code null} when a factory is needed for some global task,
+     * like {@link #getAuthorityCodes} method execution.
+     *
+     * @param  code The authority code given to this class. Note that the code to be given
+     *         to the returned factory {@linkplain #toBackingFactoryCode may be different}.
+     * @return A factory for the specified authority code (never {@code null}).
+     * @throws FactoryException if no suitable factory were found.
+     *
+     * @since 2.4
+     */
+    protected AuthorityFactory getAuthorityFactory(final String code) throws FactoryException {
+        if (      crsFactory != null) return       crsFactory;
+        if (       csFactory != null) return        csFactory;
+        if (    datumFactory != null) return     datumFactory;
+        if (operationFactory != null) return operationFactory;
+        throw missingFactory(AuthorityFactory.class, code);
+    }
+
+    /**
+     * Returns the datum factory to use for the specified code. The default implementation
+     * always returns the factory specified at construction time. Subclasses can override
+     * this method in order to select a different factory implementation depending on the
+     * code value.
+     *
+     * @param  code The authority code given to this class. Note that the code to be given
+     *         to the returned factory {@linkplain #toBackingFactoryCode may be different}.
+     * @return A factory for the specified authority code (never {@code null}).
+     * @throws FactoryException if no datum factory were specified at construction time.
+     *
+     * @since 2.4
+     */
+    protected DatumAuthorityFactory getDatumAuthorityFactory(final String code)
+            throws FactoryException
+    {
+        if (datumFactory == null) {
+            throw missingFactory(DatumAuthorityFactory.class, code);
+        }
+        return datumFactory;
+    }
+
+    /**
+     * Returns the coordinate system factory to use for the specified code. The default
+     * implementation always returns the factory specified at construction time. Subclasses
+     * can override this method in order to select a different factory implementation
+     * depending on the code value.
+     *
+     * @param  code The authority code given to this class. Note that the code to be given
+     *         to the returned factory {@linkplain #toBackingFactoryCode may be different}.
+     * @return A factory for the specified authority code (never {@code null}).
+     * @throws FactoryException if no coordinate system factory were specified at construction time.
+     *
+     * @since 2.4
+     */
+    protected CSAuthorityFactory getCSAuthorityFactory(final String code)
+            throws FactoryException
+    {
+        if (csFactory == null) {
+            throw missingFactory(CSAuthorityFactory.class, code);
+        }
+        return csFactory;
+    }
+
+    /**
+     * Returns the coordinate reference system factory to use for the specified code. The default
+     * implementation always returns the factory specified at construction time. Subclasses can
+     * override this method in order to select a different factory implementation depending on
+     * the code value.
+     *
+     * @param  code The authority code given to this class. Note that the code to be given
+     *         to the returned factory {@linkplain #toBackingFactoryCode may be different}.
+     * @return A factory for the specified authority code (never {@code null}).
+     * @throws FactoryException if no coordinate reference system factory were specified
+     *         at construction time.
+     *
+     * @since 2.4
+     */
+    protected CRSAuthorityFactory getCRSAuthorityFactory(final String code)
+            throws FactoryException
+    {
+        if (crsFactory == null) {
+            throw missingFactory(CRSAuthorityFactory.class, code);
+        }
+        return crsFactory;
+    }
+
+    /**
+     * Returns the coordinate operation factory to use for the specified code. The default
+     * implementation always returns the factory specified at construction time. Subclasses can
+     * override this method in order to select a different factory implementation depending on
+     * the code value.
+     *
+     * @param  code The authority code given to this class. Note that the code to be given
+     *         to the returned factory {@linkplain #toBackingFactoryCode may be different}.
+     * @return A factory for the specified authority code (never {@code null}).
+     * @throws FactoryException if no coordinate operation factory were specified
+     *         at construction time.
+     *
+     * @since 2.4
+     */
+    protected CoordinateOperationAuthorityFactory getCoordinateOperationAuthorityFactory(final String code)
+            throws FactoryException
+    {
+        if (operationFactory == null) {
+            throw missingFactory(CoordinateOperationAuthorityFactory.class, code);
+        }
+        return operationFactory;
+    }
+
+    /**
+     * Returns the code to be given to the wrapped factories. This method is automatically
+     * invoked by all {@code create} methods before to forward the code to the
+     * {@linkplain #getCRSAuthorityFactory CRS}, {@linkplain #getCSAuthorityFactory CS},
+     * {@linkplain #getDatumAuthorityFactory datum} or {@linkplain #operationFactory operation}
+     * factory. The default implementation returns the {@code code} unchanged.
+     *
+     * @param  code The code given to this factory.
+     * @return The code to give to the underlying factories.
+     * @throws FactoryException if the code can't be converted.
+     *
+     * @since 2.4
+     */
+    protected String toBackingFactoryCode(final String code) throws FactoryException {
+        return code;
+    }
+
+    /**
+     * Returns {@code true} if the {@link #toBackingFactoryCode} method is overriden.
+     */
+    final boolean isCodeMethodOverriden() {
+        final Class<?>[] arguments = new Class[] {String.class};
+        for (Class<?> type=getClass(); !AuthorityFactoryAdapter.class.equals(type); type=type.getSuperclass()) {
+            try {
+                type.getDeclaredMethod("toBackingFactoryCode", arguments);
+            } catch (NoSuchMethodException e) {
+                // The method is not overriden in this class.
+                // Checks in the super-class.
+                continue;
+            } catch (SecurityException e) {
+                // We are not allowed to get this information.
+                // Conservatively assumes that the method is overriden.
+            }
+            return true;
+        }
+        return false;
+    }
+    
+    @Override
+    public void dispose() throws FactoryException {
+        super.dispose();
+        disposeAbstractAuthorityFactory(datumFactory);
+        disposeAbstractAuthorityFactory(csFactory);
+        disposeAbstractAuthorityFactory(crsFactory);
+        disposeAbstractAuthorityFactory(operationFactory);
+    }
+    
+    private void disposeAbstractAuthorityFactory(Object factory) throws FactoryException {
+        if(factory instanceof AbstractAuthorityFactory) {
+            ((AbstractAuthorityFactory) factory).dispose();
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/AuthorityFactoryProxy.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/AuthorityFactoryProxy.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/AuthorityFactoryProxy.java	(revision 28000)
@@ -0,0 +1,384 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.factory;
+
+// J2SE dependencies
+import java.util.Set;
+import java.util.Arrays;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+// OpenGIS dependencies
+import org.opengis.referencing.*;
+import org.opengis.referencing.cs.*;
+import org.opengis.referencing.crs.*;
+import org.opengis.referencing.datum.*;
+import org.opengis.referencing.operation.*;
+import org.opengis.parameter.ParameterDescriptor;
+
+// Geotools dependencies
+import org.geotools.resources.Classes;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+/**
+ * Delegates object creations to one of the {@code create} methods in a backing
+ * {@linkplain AuthorityFactory authority factory}. It is possible to use the generic
+ * {@link AuthorityFactory#createObject createObject} method instead of this class,
+ * but some factory implementations are more efficient when we use the most specific
+ * {@code create} method. For example when using a
+ * {@linkplain org.geotools.referencing.factory.epsg.DirectEpsgFactory EPSG factory backed
+ * by a SQL database}, invoking {@link CRSAuthorityFactory#createCoordinateReferenceSystem
+ * createCoordinateReferenceSystem} instead of {@link AuthorityFactory#createObject createObject}
+ * method will reduce the amount of tables to be queried.
+ * <p>
+ * This class is useful when the same {@code create} method need to be invoked often,
+ * but is unknown at compile time. It may also be used as a workaround for authority
+ * factories that don't implement the {@code createObject} method.
+ * <p>
+ * <b>Example:</b> The following code creates a proxy which will delegates its work to the
+ * {@link CRSAuthorityFactory#createGeographicCRS createGeographicCRS} method.
+ *
+ * <blockquote><pre>
+ * AuthorityFactory factory = ...;
+ * AuthorityFactoryProxy<GeographicCRS> proxy =
+ *         AuthorityFactoryProxy.getInstance(GeographicCRS.class, factory);
+ *
+ * String code = ...;
+ * // Invokes CRSAuthorityFactory.createGeographicCRS(code);
+ * GeographicCRS crs = proxy.create(code);
+ * </pre></blockquote>
+ *
+ * @since 2.4
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/AuthorityFactoryProxy.java $
+ * @version $Id: AuthorityFactoryProxy.java 30641 2008-06-12 17:42:27Z acuster $
+ * @author Martin Desruisseaux
+ */
+abstract class AuthorityFactoryProxy {
+    /**
+     * The types that factories can be create. The most
+     * specific types must appear first in this list.
+     */
+    private static final Class/*<? extends IdentifiedObject>*/[] TYPES = {
+        CoordinateOperation      .class,
+        OperationMethod          .class,
+        ParameterDescriptor      .class,
+        ProjectedCRS             .class,
+        GeographicCRS            .class,
+        GeocentricCRS            .class,
+        ImageCRS                 .class,
+        DerivedCRS               .class,
+        VerticalCRS              .class,
+        TemporalCRS              .class,
+        EngineeringCRS           .class,
+        CompoundCRS              .class,
+        CoordinateReferenceSystem.class,
+        CoordinateSystemAxis     .class,
+        CartesianCS              .class,
+        EllipsoidalCS            .class,
+        SphericalCS              .class,
+        CylindricalCS            .class,
+        PolarCS                  .class,
+        VerticalCS               .class,
+        TimeCS                   .class,
+        CoordinateSystem         .class,
+        PrimeMeridian            .class,
+        Ellipsoid                .class,
+        GeodeticDatum            .class,
+        ImageDatum               .class,
+        VerticalDatum            .class,
+        TemporalDatum            .class,
+        EngineeringDatum         .class,
+        Datum                    .class,
+        IdentifiedObject         .class
+    };
+
+    /**
+     * Creates a new proxy.
+     */
+    AuthorityFactoryProxy() {
+    }
+
+    /**
+     * Returns a proxy instance which will create objects of the specified type using the
+     * specified factory.
+     *
+     * @param  factory The factory to use for object creations.
+     * @param  type    The type of objects to be created by the proxy.
+     */
+    public static AuthorityFactoryProxy getInstance(final AuthorityFactory factory,
+                                                    Class/*<? extends IdentifiedObject>*/ type)
+    {
+        AbstractAuthorityFactory.ensureNonNull("type",    type);
+        AbstractAuthorityFactory.ensureNonNull("factory", factory);
+        type = getType(type);
+        /*
+         * Checks for some special cases for which a fast implementation is available.
+         */
+        if (factory instanceof CRSAuthorityFactory) {
+            final CRSAuthorityFactory crsFactory = (CRSAuthorityFactory) factory;
+            if (type.equals(             ProjectedCRS.class)) return new  Projected(crsFactory);
+            if (type.equals(            GeographicCRS.class)) return new Geographic(crsFactory);
+            if (type.equals(CoordinateReferenceSystem.class)) return new        CRS(crsFactory);
+        }
+        /*
+         * Fallback on the generic case using reflection.
+         */
+        return new Default(factory, type);
+    }
+
+    /**
+     * Returns the main GeoAPI interface implemented by an object of the specified type.
+     * The {@code type} argument is often some implementation class like
+     * {@link org.geotools.referencing.crs.DefaultProjectedCRS}. This method returns
+     * the most specific GeoAPI interface implemented by {@code type}, providing that
+     * a corresponding {@code create} method exists in some {@linkplain AuthorityFactory
+     * authority factory}. For example this method may returns {@link ProjectedCRS} or
+     * {@link DerivedCRS} class, but not {@link GeneralDerivedCRS}.
+     *
+     * @param  type The implementation class.
+     * @return The most specific GeoAPI interface implemented by {@code type}.
+     * @throws IllegalArgumentException if the type doesn't implement a valid interface.
+     */
+    public static Class/*<? extends IdentifiedObject>*/ getType(
+            final Class/*<? extends IdentifiedObject>*/ type)
+            throws IllegalArgumentException
+    {
+        for (int i=0; i<TYPES.length; i++) {
+            final Class/*<? extends IdentifiedObject>*/ candidate = TYPES[i];
+            if (candidate.isAssignableFrom(type)) {
+                return candidate;
+            }
+        }
+        throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_CLASS_$2, type,
+                IdentifiedObject.class));
+    }
+
+    /**
+     * Returns the type of the objects to be created by this proxy instance.
+     */
+    public abstract Class/*<? extends IdentifiedObject>*/ getType();
+
+    /**
+     * Returns the authority factory used by the {@link #create create} method.
+     */
+    public abstract AuthorityFactory getAuthorityFactory();
+
+    /**
+     * Returns the set of authority codes.
+     *
+     * @throws FactoryException if access to the underlying database failed.
+     */
+    public final Set/*<String>*/ getAuthorityCodes() throws FactoryException {
+        return getAuthorityFactory().getAuthorityCodes(getType());
+    }
+
+    /**
+     * Creates an object for the specified code. This method will delegates to the most
+     * specific {@code create} method from the authority factory. The returned object
+     * will always be of the type returned by {@link #getType()}.
+     *
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    public abstract IdentifiedObject create(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Returns a string representation of this proxy, for debugging purpose only.
+     */
+    @Override
+    public String toString() {
+        return toString(AuthorityFactoryProxy.class);
+    }
+
+    /**
+     * Returns a string representation of the specified object, for debugging purpose only.
+     */
+    final String toString(final Class owner) {
+        final AuthorityFactory factory = getAuthorityFactory();
+        return Classes.getShortName(owner) + '[' +
+               Classes.getShortName(getType()) + " in " +
+               Classes.getShortClassName(factory) + "(\"" +
+               factory.getAuthority().getTitle() + "\")]";
+    }
+
+
+    /**
+     * A default implementation using reflections. To be used only when we don't provide
+     * a specialized, more efficient, implementation.
+     *
+     * @version $Id: AuthorityFactoryProxy.java 30641 2008-06-12 17:42:27Z acuster $
+     * @author Martin Desruisseaux
+     */
+    private static final class Default extends AuthorityFactoryProxy {
+        /**
+         * The argument types of {@code createFoo} methods.
+         */
+        private static final Class[] PARAMETERS = new Class[] {String.class};
+
+        /**
+         * The authority factory on which to delegates.
+         */
+        private final AuthorityFactory factory;
+
+        /**
+         * The type of the objects to be created.
+         */
+        private final Class/*<? extends IdentifiedObject>*/ type;
+
+        /**
+         * The {@code createFoo} method to invoke.
+         */
+        private final Method method;
+
+        /**
+         * Creates a new proxy which will delegates the object creation to the specified instance.
+         */
+        Default(final AuthorityFactory factory, final Class/*<? extends IdentifiedObject>*/ type)
+                throws IllegalArgumentException
+        {
+            this.factory = factory;
+            this.type = type;
+            final Method[] candidates = factory.getClass().getMethods();
+            for (int i=0; i<candidates.length; i++) {
+                final Method c = candidates[i];
+                if (c.getName().startsWith("create") && type.equals(c.getReturnType()) &&
+                        Arrays.equals(PARAMETERS, c.getParameterTypes()))
+                {
+                    method = c;
+                    return;
+                }
+            }
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.UNKNOW_TYPE_$1, type));
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public Class/*<? extends IdentifiedObject>*/ getType() {
+            return type;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public AuthorityFactory getAuthorityFactory() {
+            return factory;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public IdentifiedObject create(final String code) throws FactoryException {
+            try {
+                return (IdentifiedObject) method.invoke(factory, code);
+            } catch (InvocationTargetException exception) {
+                final Throwable cause = exception.getCause();
+                if (cause instanceof FactoryException) {
+                    throw (FactoryException) cause;
+                }
+                if (cause instanceof RuntimeException) {
+                    throw (RuntimeException) cause;
+                }
+                if (cause instanceof Error) {
+                    throw (Error) cause;
+                }
+                throw new FactoryException(cause.getLocalizedMessage(), cause);
+            } catch (IllegalAccessException exception) {
+                throw new FactoryException(exception.getLocalizedMessage(), exception);
+            }
+        }
+    }
+
+
+    /**
+     * An implementation for {@link CoordinateReferenceSystem} objects.
+     *
+     * @version $Id: AuthorityFactoryProxy.java 30641 2008-06-12 17:42:27Z acuster $
+     * @author Martin Desruisseaux
+     */
+    private static class CRS extends AuthorityFactoryProxy {
+        /** The authority factory on which to delegates. */
+        protected final CRSAuthorityFactory factory;
+
+        protected CRS(final CRSAuthorityFactory factory) {
+            this.factory = factory;
+        }
+
+        public Class getType() {
+            return CoordinateReferenceSystem.class;
+        }
+
+        public final AuthorityFactory getAuthorityFactory() {
+            return factory;
+        }
+
+        public IdentifiedObject create(final String code) throws FactoryException {
+            return factory.createCoordinateReferenceSystem(code);
+        }
+    }
+
+
+    /**
+     * An implementation for {@link GeographicCRS} objects.
+     *
+     * @version $Id: AuthorityFactoryProxy.java 30641 2008-06-12 17:42:27Z acuster $
+     * @author Martin Desruisseaux
+     */
+    private static final class Geographic extends CRS {
+        protected Geographic(final CRSAuthorityFactory factory) {
+            super(factory);
+        }
+
+        @Override
+        public Class getType() {
+            return GeographicCRS.class;
+        }
+
+        @Override
+        public IdentifiedObject create(final String code) throws FactoryException {
+            return factory.createGeographicCRS(code);
+        }
+    }
+
+
+    /**
+     * An implementation for {@link ProjectedCRS} objects.
+     *
+     * @version $Id: AuthorityFactoryProxy.java 30641 2008-06-12 17:42:27Z acuster $
+     * @author Martin Desruisseaux
+     */
+    private static final class Projected extends CRS {
+        protected Projected(final CRSAuthorityFactory factory) {
+            super(factory);
+        }
+
+        @Override
+        public Class getType() {
+            return ProjectedCRS.class;
+        }
+
+        @Override
+        public IdentifiedObject create(final String code) throws FactoryException {
+            return factory.createProjectedCRS(code);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/BackingStoreException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/BackingStoreException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/BackingStoreException.java	(revision 28000)
@@ -0,0 +1,46 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *   
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.factory;
+
+// J2SE direct dependencies
+import java.io.IOException;    // For javadoc
+import java.sql.SQLException;  // For javadoc
+
+
+/**
+ * Thrown to indicate that an {@link IdentifiedObjectSet} operation could not complete because of a
+ * failure in the backing store, or a failure to contact the backing store. This exception usually
+ * has an {@link IOException} or a {@link SQLException} as its {@linkplain #getCause cause}.
+ *
+ * @since 2.3
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/BackingStoreException.java $
+ * @version $Id: BackingStoreException.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class BackingStoreException extends RuntimeException {
+    /**
+     * Serial version UID allowing cross compiler use of {@code BackingStoreException}.
+     */
+    private static final long serialVersionUID = 4257200758051575441L;
+
+    /**
+     * Constructs a new exception with no detail message.
+     */
+    public BackingStoreException() {
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/BufferedAuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/BufferedAuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/BufferedAuthorityFactory.java	(revision 28000)
@@ -0,0 +1,1211 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.factory;
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.Map;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.WeakHashMap;
+import java.util.LinkedHashMap;
+import java.util.logging.LogRecord;
+import java.util.logging.Level;
+import javax.measure.unit.Unit;
+
+import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.referencing.AuthorityFactory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.cs.*;
+import org.opengis.referencing.crs.*;
+import org.opengis.referencing.datum.*;
+import org.opengis.referencing.operation.*;
+import org.opengis.util.InternationalString;
+
+import org.geotools.factory.Hints;
+import org.geotools.factory.BufferedFactory;
+import org.geotools.util.Utilities;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Loggings;
+import org.geotools.resources.i18n.LoggingKeys;
+
+
+/**
+ * An authority factory that caches all objects created by an other factory. All
+ * {@code createFoo(String)} methods first looks if a previously created object
+ * exists for the given code. If such an object exists, it is returned. Otherwise,
+ * the object creation is delegated to the {@linkplain AbstractAuthorityFactory authority factory}
+ * specified at creation time, and the result is cached in this buffered factory.
+ * <p>
+ * Objects are cached by strong references, up to the amount of objects specified at
+ * construction time. If a greater amount of objects are cached, the oldest ones will
+ * be retained through a {@linkplain WeakReference weak reference} instead of a strong
+ * one. This means that this buffered factory will continue to returns them as long as
+ * they are in use somewhere else in the Java virtual machine, but will be discarted
+ * (and recreated on the fly if needed) otherwise.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/BufferedAuthorityFactory.java $
+ * @version $Id: BufferedAuthorityFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class BufferedAuthorityFactory extends AbstractAuthorityFactory implements BufferedFactory {
+    /**
+     * The default value for {@link #maxStrongReferences}.
+     */
+    static final int DEFAULT_MAX = 20;
+
+    /**
+     * The underlying authority factory. This field may be {@code null} if this object was
+     * created by the {@linkplain #BufferedAuthorityFactory(AbstractAuthorityFactory,int)
+     * package protected constructor}. In this case, the subclass is responsible for creating
+     * the backing store when {@link DeferredAuthorityFactory#createBackingStore} is invoked.
+     *
+     * @see #getBackingStore
+     * @see DeferredAuthorityFactory#createBackingStore
+     */
+    volatile AbstractAuthorityFactory backingStore;
+
+    /**
+     * The pool of cached objects.
+     */
+    private final LinkedHashMap<Object,Object> pool =
+            new LinkedHashMap<Object,Object>(32, 0.75f, true);
+
+    /**
+     * The maximum number of objects to keep by strong reference. If a greater amount of
+     * objects are created, then the strong references for the oldest ones are replaced by
+     * weak references.
+     */
+    private final int maxStrongReferences;
+
+    /**
+     * The pool of objects identified by {@link #find}.
+     */
+    private final Map<IdentifiedObject,IdentifiedObject> findPool =
+            new WeakHashMap<IdentifiedObject,IdentifiedObject>();
+
+    /**
+     * Constructs an instance without initial backing store. This constructor is for subclass
+     * constructors only. Subclasses are responsible for creating an appropriate backing store
+     * when the {@link DeferredAuthorityFactory#createBackingStore} method is invoked.
+     *
+     * @param priority The priority for this factory, as a number between
+     *        {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
+     *        {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
+     * @param maxStrongReferences The maximum number of objects to keep by strong reference.
+     *
+     * @see DeferredAuthorityFactory#createBackingStore
+     */
+    BufferedAuthorityFactory(final int priority, final int maxStrongReferences) {
+        super(priority);
+        this.maxStrongReferences = maxStrongReferences;
+        // completeHints() will be invoked by DeferredAuthorityFactory.getBackingStore()
+    }
+
+    /**
+     * Completes the set of hints according the value currently set in this object. This method
+     * is invoked by {@code BufferedAuthorityFactory} or by {@code DeferredAuthorityFactory} at
+     * backing store creation time.
+     * <p>
+     * The backing store is of course an important dependency. This method gives a chance
+     * to {@link org.geotools.factory.FactoryRegistry} to compare the user-requested hints
+     * (especially {@link Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER}) against the backing store
+     * hints, by following the dependency declared there.
+     * <p>
+     * DON'T FORGET to set those hints to {@code null} when {@link DeferredAuthorityFactory}
+     * dispose the backing store.
+     */
+    final void completeHints() {
+        if (backingStore instanceof DatumAuthorityFactory) {
+            hints.put(Hints.DATUM_AUTHORITY_FACTORY, backingStore);
+        }
+        if (backingStore instanceof CSAuthorityFactory) {
+            hints.put(Hints.CS_AUTHORITY_FACTORY, backingStore);
+        }
+        if (backingStore instanceof CRSAuthorityFactory) {
+            hints.put(Hints.CRS_AUTHORITY_FACTORY, backingStore);
+        }
+        if (backingStore instanceof CoordinateOperationAuthorityFactory) {
+            hints.put(Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY, backingStore);
+        }
+    }
+
+    /**
+     * Returns the direct dependencies. The returned list contains the backing store
+     * specified at construction time, or the exception if it can't be obtained.
+     */
+    @Override
+    Collection<? super AuthorityFactory> dependencies() {
+        Object factory;
+        try {
+            factory = getBackingStore();
+        } catch (FactoryException e) {
+            factory = e;
+        }
+        return Collections.singleton(factory);
+    }
+
+    /**
+     * Returns the backing store authority factory.
+     *
+     * @return The backing store to uses in {@code createXXX(...)} methods.
+     * @throws FactoryException if the creation of backing store failed.
+     */
+    AbstractAuthorityFactory getBackingStore() throws FactoryException {
+        if (backingStore == null) {
+            throw new FactoryException(Errors.format(ErrorKeys.DISPOSED_FACTORY));
+        }
+        return backingStore;
+    }
+
+    /**
+     * Returns {@code true} if this factory is available. The default implementation returns
+     * {@code false} if no backing store were setup and
+     * {@link DeferredAuthorityFactory#createBackingStore} throws an exception.
+     */
+    @Override
+    boolean isAvailable() {
+        try {
+            return getBackingStore().isAvailable();
+        } catch (FactoryNotFoundException exception) {
+            /*
+             * The factory is not available. This is error may be normal; it happens
+             * for example if no gt2-epsg-hsql.jar (or similar JAR) are found in the
+             * classpath, which is the case for example in GeoServer 1.3. Do not log
+             * any stack trace,  since stack traces suggest more serious errors than
+             * what we really have here.
+             */
+        } catch (FactoryException exception) {
+            /*
+             * The factory creation failed for an other reason, which may be more
+             * serious. Now it is time to log a warning with a stack trace.
+             */
+            final Citation citation = getAuthority();
+            final Collection<? extends InternationalString> titles = citation.getAlternateTitles();
+            InternationalString title = citation.getTitle();
+            if (titles != null) {
+                for (final InternationalString candidate : titles) {
+                    /*
+                     * Uses the longuest title instead of the main one. In Geotools
+                     * implementation, the alternate title may contains usefull informations
+                     * like the EPSG database version number and the database engine.
+                     */
+                    if (candidate.length() > title.length()) {
+                        title  = candidate;
+                    }
+                }
+            }
+            final LogRecord record = Loggings.format(Level.WARNING,
+                    LoggingKeys.UNAVAILABLE_AUTHORITY_FACTORY_$1, title);
+            record.setSourceClassName(getClass().getName());
+            record.setSourceMethodName("isAvailable");
+            record.setThrown(exception);
+            record.setLoggerName(LOGGER.getName());
+            LOGGER.log(record);
+        }
+        return false;
+    }
+
+    /**
+     * If this factory is a wrapper for the specified factory that do not add any additional
+     * {@linkplain #getAuthorityCodes authority codes}, returns {@code true}. This method is
+     * for {@link FallbackAuthorityFactory} internal use only and should not be public. A
+     * cheap test without {@link #getBackingStore} invocation is suffisient for our needs.
+     */
+    @Override
+    boolean sameAuthorityCodes(final AuthorityFactory factory) {
+        final AbstractAuthorityFactory backingStore = this.backingStore; // Protect from changes.
+        if (backingStore != null && backingStore.sameAuthorityCodes(factory)) {
+            return true;
+        }
+        return super.sameAuthorityCodes(factory);
+    }
+
+    /**
+     * Returns the vendor responsible for creating the underlying factory implementation.
+     */
+    @Override
+    public Citation getVendor() {
+        return (backingStore!=null) ? backingStore.getVendor() : super.getVendor();
+    }
+
+    /**
+     * Returns the organization or party responsible for definition and maintenance of the
+     * underlying database.
+     */
+    public Citation getAuthority() {
+        return (backingStore!=null) ? backingStore.getAuthority() : null;
+    }
+
+    /**
+     * Returns a description of the underlying backing store, or {@code null} if unknow.
+     * This is for example the database software used for storing the data.
+     *
+     * @throws FactoryException if a failure occured while fetching the engine description.
+     */
+    @Override
+    public String getBackingStoreDescription() throws FactoryException {
+        return getBackingStore().getBackingStoreDescription();
+    }
+
+    /**
+     * Returns the set of authority codes of the given type. The {@code type}
+     * argument specify the base class.
+     *
+     * @param  type The spatial reference objects type.
+     * @return The set of authority codes for spatial reference objects of the given type.
+     *         If this factory doesn't contains any object of the given type, then this method
+     *         returns an {@linkplain java.util.Collections#EMPTY_SET empty set}.
+     * @throws FactoryException if access to the underlying database failed.
+     */
+    public Set<String> getAuthorityCodes(final Class<? extends IdentifiedObject> type)
+            throws FactoryException
+    {
+        return getBackingStore().getAuthorityCodes(type);
+    }
+
+    /**
+     * Gets a description of the object corresponding to a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return A description of the object, or {@code null} if the object
+     *         corresponding to the specified {@code code} has no description.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the query failed for some other reason.
+     */
+    public InternationalString getDescriptionText(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        return getBackingStore().getDescriptionText(code);
+    }
+
+    /**
+     * Returns an arbitrary object from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized IdentifiedObject createObject(final String code)
+            throws FactoryException
+    {
+        final IdentifiedObject object;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof IdentifiedObject) {
+            object = (IdentifiedObject) cached;
+        } else {
+            object = getBackingStore().createObject(code);
+        }
+        put(key, object);
+        return object;
+    }
+
+    /**
+     * Returns an arbitrary datum from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized Datum createDatum(final String code)
+            throws FactoryException
+    {
+        final Datum datum;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof Datum) {
+            datum = (Datum) cached;
+        } else {
+            datum = getBackingStore().createDatum(code);
+        }
+        put(key, datum);
+        return datum;
+    }
+
+    /**
+     * Returns an engineering datum from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized EngineeringDatum createEngineeringDatum(final String code)
+            throws FactoryException
+    {
+        final EngineeringDatum datum;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof EngineeringDatum) {
+            datum = (EngineeringDatum) cached;
+        } else {
+            datum = getBackingStore().createEngineeringDatum(code);
+        }
+        put(key, datum);
+        return datum;
+    }
+
+    /**
+     * Returns an image datum from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized ImageDatum createImageDatum(final String code)
+            throws FactoryException
+    {
+        final ImageDatum datum;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof ImageDatum) {
+            datum = (ImageDatum) cached;
+        } else {
+            datum = getBackingStore().createImageDatum(code);
+        }
+        put(key, datum);
+        return datum;
+    }
+
+    /**
+     * Returns a vertical datum from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized VerticalDatum createVerticalDatum(final String code)
+            throws FactoryException
+    {
+        final VerticalDatum datum;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof VerticalDatum) {
+            datum = (VerticalDatum) cached;
+        } else {
+            datum = getBackingStore().createVerticalDatum(code);
+        }
+        put(key, datum);
+        return datum;
+    }
+
+    /**
+     * Returns a temporal datum from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized TemporalDatum createTemporalDatum(final String code)
+            throws FactoryException
+    {
+        final TemporalDatum datum;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof TemporalDatum) {
+            datum = (TemporalDatum) cached;
+        } else {
+            datum = getBackingStore().createTemporalDatum(code);
+        }
+        put(key, datum);
+        return datum;
+    }
+
+    /**
+     * Returns a geodetic datum from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized GeodeticDatum createGeodeticDatum(final String code)
+            throws FactoryException
+    {
+        final GeodeticDatum datum;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof GeodeticDatum) {
+            datum = (GeodeticDatum) cached;
+        } else {
+            datum = getBackingStore().createGeodeticDatum(code);
+        }
+        put(key, datum);
+        return datum;
+    }
+
+    /**
+     * Returns an ellipsoid from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized Ellipsoid createEllipsoid(final String code)
+            throws FactoryException
+    {
+        final Ellipsoid ellipsoid;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof Ellipsoid) {
+            ellipsoid = (Ellipsoid) cached;
+        } else {
+            ellipsoid = getBackingStore().createEllipsoid(code);
+        }
+        put(key, ellipsoid);
+        return ellipsoid;
+    }
+
+    /**
+     * Returns a prime meridian from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized PrimeMeridian createPrimeMeridian(final String code)
+            throws FactoryException
+    {
+        final PrimeMeridian meridian;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof PrimeMeridian) {
+            meridian = (PrimeMeridian) cached;
+        } else {
+            meridian = getBackingStore().createPrimeMeridian(code);
+        }
+        put(key, meridian);
+        return meridian;
+    }
+
+    /**
+     * Returns an extent (usually an area of validity) from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized Extent createExtent(final String code)
+            throws FactoryException
+    {
+        final Extent extent;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof Extent) {
+            extent = (Extent) cached;
+        } else {
+            extent = getBackingStore().createExtent(code);
+        }
+        put(key, extent);
+        return extent;
+    }
+
+    /**
+     * Returns an arbitrary coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized CoordinateSystem createCoordinateSystem(final String code)
+            throws FactoryException
+    {
+        final CoordinateSystem cs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof CoordinateSystem) {
+            cs = (CoordinateSystem) cached;
+        } else {
+            cs = getBackingStore().createCoordinateSystem(code);
+        }
+        put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a cartesian coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized CartesianCS createCartesianCS(final String code)
+            throws FactoryException
+    {
+        final CartesianCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof CartesianCS) {
+            cs = (CartesianCS) cached;
+        } else {
+            cs = getBackingStore().createCartesianCS(code);
+        }
+        put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a polar coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized PolarCS createPolarCS(final String code)
+            throws FactoryException
+    {
+        final PolarCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof PolarCS) {
+            cs = (PolarCS) cached;
+        } else {
+            cs = getBackingStore().createPolarCS(code);
+        }
+        put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a cylindrical coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized CylindricalCS createCylindricalCS(final String code)
+            throws FactoryException
+    {
+        final CylindricalCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof CylindricalCS) {
+            cs = (CylindricalCS) cached;
+        } else {
+            cs = getBackingStore().createCylindricalCS(code);
+        }
+        put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a spherical coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized SphericalCS createSphericalCS(final String code)
+            throws FactoryException
+    {
+        final SphericalCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof SphericalCS) {
+            cs = (SphericalCS) cached;
+        } else {
+            cs = getBackingStore().createSphericalCS(code);
+        }
+        put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns an ellipsoidal coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized EllipsoidalCS createEllipsoidalCS(final String code)
+            throws FactoryException
+    {
+        final EllipsoidalCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof EllipsoidalCS) {
+            cs = (EllipsoidalCS) cached;
+        } else {
+            cs = getBackingStore().createEllipsoidalCS(code);
+        }
+        put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a vertical coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized VerticalCS createVerticalCS(final String code)
+            throws FactoryException
+    {
+        final VerticalCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof VerticalCS) {
+            cs = (VerticalCS) cached;
+        } else {
+            cs = getBackingStore().createVerticalCS(code);
+        }
+        put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a temporal coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized TimeCS createTimeCS(final String code)
+            throws FactoryException
+    {
+        final TimeCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof TimeCS) {
+            cs = (TimeCS) cached;
+        } else {
+            cs = getBackingStore().createTimeCS(code);
+        }
+        put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a coordinate system axis from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized CoordinateSystemAxis createCoordinateSystemAxis(final String code)
+            throws FactoryException
+    {
+        final CoordinateSystemAxis axis;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof CoordinateSystemAxis) {
+            axis = (CoordinateSystemAxis) cached;
+        } else {
+            axis = getBackingStore().createCoordinateSystemAxis(code);
+        }
+        put(key, axis);
+        return axis;
+    }
+
+    /**
+     * Returns an unit from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized Unit<?> createUnit(final String code)
+            throws FactoryException
+    {
+        final Unit<?> unit;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof Unit) {
+            unit = (Unit) cached;
+        } else {
+            unit = getBackingStore().createUnit(code);
+        }
+        put(key, unit);
+        return unit;
+    }
+
+    /**
+     * Returns an arbitrary coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized CoordinateReferenceSystem createCoordinateReferenceSystem(final String code)
+            throws FactoryException
+    {
+        final CoordinateReferenceSystem crs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof CoordinateReferenceSystem) {
+            crs = (CoordinateReferenceSystem) cached;
+        } else {
+            crs = getBackingStore().createCoordinateReferenceSystem(code);
+        }
+        put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a 3D coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized CompoundCRS createCompoundCRS(final String code)
+            throws FactoryException
+    {
+        final CompoundCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof CompoundCRS) {
+            crs = (CompoundCRS) cached;
+        } else {
+            crs = getBackingStore().createCompoundCRS(code);
+        }
+        put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a derived coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized DerivedCRS createDerivedCRS(final String code)
+            throws FactoryException
+    {
+        final DerivedCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof DerivedCRS) {
+            crs = (DerivedCRS) cached;
+        } else {
+            crs = getBackingStore().createDerivedCRS(code);
+        }
+        put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns an engineering coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized EngineeringCRS createEngineeringCRS(final String code)
+            throws FactoryException
+    {
+        final EngineeringCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof EngineeringCRS) {
+            crs = (EngineeringCRS) cached;
+        } else {
+            crs = getBackingStore().createEngineeringCRS(code);
+        }
+        put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a geographic coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized GeographicCRS createGeographicCRS(final String code)
+            throws FactoryException
+    {
+        final GeographicCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof GeographicCRS) {
+            crs = (GeographicCRS) cached;
+        } else {
+            crs = getBackingStore().createGeographicCRS(code);
+        }
+        put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a geocentric coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized GeocentricCRS createGeocentricCRS(final String code)
+            throws FactoryException
+    {
+        final GeocentricCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof GeocentricCRS) {
+            crs = (GeocentricCRS) cached;
+        } else {
+            crs = getBackingStore().createGeocentricCRS(code);
+        }
+        put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns an image coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized ImageCRS createImageCRS(final String code)
+            throws FactoryException
+    {
+        final ImageCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof ImageCRS) {
+            crs = (ImageCRS) cached;
+        } else {
+            crs = getBackingStore().createImageCRS(code);
+        }
+        put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a projected coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized ProjectedCRS createProjectedCRS(final String code)
+            throws FactoryException
+    {
+        final ProjectedCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof ProjectedCRS) {
+            crs = (ProjectedCRS) cached;
+        } else {
+            crs = getBackingStore().createProjectedCRS(code);
+        }
+        put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a temporal coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized TemporalCRS createTemporalCRS(final String code)
+            throws FactoryException
+    {
+        final TemporalCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof TemporalCRS) {
+            crs = (TemporalCRS) cached;
+        } else {
+            crs = getBackingStore().createTemporalCRS(code);
+        }
+        put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a vertical coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     */
+    @Override
+    public synchronized VerticalCRS createVerticalCRS(final String code)
+            throws FactoryException
+    {
+        final VerticalCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof VerticalCRS) {
+            crs = (VerticalCRS) cached;
+        } else {
+            crs = getBackingStore().createVerticalCRS(code);
+        }
+        put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a parameter descriptor from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @since 2.2
+     */
+    @Override
+    public synchronized ParameterDescriptor createParameterDescriptor(final String code)
+            throws FactoryException
+    {
+        final ParameterDescriptor parameter;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof ParameterDescriptor) {
+            parameter = (ParameterDescriptor) cached;
+        } else {
+            parameter = getBackingStore().createParameterDescriptor(code);
+        }
+        put(key, parameter);
+        return parameter;
+    }
+
+    /**
+     * Returns an operation method from a code.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @since 2.2
+     */
+    @Override
+    public synchronized OperationMethod createOperationMethod(final String code)
+            throws FactoryException
+    {
+        final OperationMethod method;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof OperationMethod) {
+            method = (OperationMethod) cached;
+        } else {
+            method = getBackingStore().createOperationMethod(code);
+        }
+        put(key, method);
+        return method;
+    }
+
+    /**
+     * Returns an operation from a single operation code.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @since 2.2
+     */
+    @Override
+    public synchronized CoordinateOperation createCoordinateOperation(final String code)
+            throws FactoryException
+    {
+        final CoordinateOperation operation;
+        final String key = trimAuthority(code);
+        final Object cached = get(key);
+        if (cached instanceof CoordinateOperation) {
+            operation = (CoordinateOperation) cached;
+        } else {
+            operation = getBackingStore().createCoordinateOperation(code);
+        }
+        put(key, operation);
+        return operation;
+    }
+
+    /**
+     * Returns an operation from coordinate reference system codes.
+     *
+     * @throws FactoryException if the object creation failed.
+     *
+     * @since 2.2
+     */
+    @Override
+    public synchronized Set<CoordinateOperation> createFromCoordinateReferenceSystemCodes(
+                        final String sourceCRS, final String targetCRS)
+            throws FactoryException
+    {
+        final Set<CoordinateOperation> operations;
+        final CodePair key = new CodePair(trimAuthority(sourceCRS), trimAuthority(targetCRS));
+        final Object cached = get(key);
+        if (cached instanceof Set) {
+            operations = (Set<CoordinateOperation>) cached;
+        } else {
+            operations = Collections.unmodifiableSet(getBackingStore()
+                         .createFromCoordinateReferenceSystemCodes(sourceCRS, targetCRS));
+        }
+        put(key, operations);
+        return operations;
+    }
+
+    /**
+     * A pair of codes for operations to cache with
+     * {@link #createFromCoordinateReferenceSystemCodes}.
+     */
+    private static final class CodePair {
+        private final String source, target;
+
+        public CodePair(final String source, final String target) {
+            this.source = source;
+            this.target = target;
+        }
+
+        @Override
+        public int hashCode() {
+            int code = 0;
+            if (source != null) code  = source.hashCode();
+            if (target != null) code += target.hashCode() * 37;
+            return code;
+        }
+
+        @Override
+        public boolean equals(final Object other) {
+            if (other instanceof CodePair) {
+                final CodePair that = (CodePair) other;
+                return Utilities.equals(this.source, that.source) &&
+                       Utilities.equals(this.target, that.target);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return source + " \u21E8 " + target;
+        }
+    }
+
+    /**
+     * Returns a finder which can be used for looking up unidentified objects.
+     * The default implementation delegates lookup to the underlying backing
+     * store and caches the result.
+     *
+     * @throws FactoryException if the finder can not be created.
+     *
+     * @since 2.4
+     */
+    @Override
+    public synchronized IdentifiedObjectFinder getIdentifiedObjectFinder(
+            final Class<? extends IdentifiedObject> type) throws FactoryException
+    {
+        return new Finder(getBackingStore().getIdentifiedObjectFinder(type));
+    }
+
+    /**
+     * An implementation of {@link IdentifiedObjectFinder} which delegates
+     * the work to the underlying backing store and caches the result.
+     * <p>
+     * <b>Implementation note:</b> we will create objects using directly the underlying backing
+     * store, not using the cache. This is because hundred of objects may be created during a
+     * scan while only one will be typically retained. We don't want to overload the cache with
+     * every false candidates that we encounter during the scan.
+     */
+    private final class Finder extends IdentifiedObjectFinder.Adapter {
+        /**
+         * Creates a finder for the underlying backing store.
+         */
+        Finder(final IdentifiedObjectFinder finder) {
+            super(finder);
+        }
+
+        /**
+         * Looks up an object from this authority factory which is equals, ignoring metadata,
+         * to the specified object. The default implementation performs the same lookup than
+         * the backing store and caches the result.
+         */
+        @Override
+        public IdentifiedObject find(final IdentifiedObject object) throws FactoryException {
+            /*
+             * Do not synchronize on 'BufferedAuthorityFactory.this'. This method may take a
+             * while to execute and we don't want to block other threads. The synchronizations
+             * in the 'create' methods and in the 'findPool' map should be suffisient.
+             *
+             * TODO: avoid to search for the same object twice. For now we consider that this
+             *       is not a big deal if the same object is searched twice; it is "just" a
+             *       waste of CPU.
+             */
+            IdentifiedObject candidate;
+            synchronized (findPool) {
+                candidate = findPool.get(object);
+            }
+            if (candidate == null) {
+                // Must delegates to 'finder' (not to 'super') in order to take
+                // advantage of the method overriden by AllAuthoritiesFactory.
+                candidate = finder.find(object);
+                if (candidate != null) {
+                    synchronized (findPool) {
+                        findPool.put(object, candidate);
+                    }
+                }
+            }
+            return candidate;
+        }
+
+        /**
+         * Returns the identifier for the specified object.
+         */
+        @Override
+        public String findIdentifier(final IdentifiedObject object) throws FactoryException {
+            IdentifiedObject candidate;
+            synchronized (findPool) {
+                candidate = findPool.get(object);
+            }
+            if (candidate != null) {
+                return getIdentifier(candidate);
+            }
+            // We don't rely on super-class implementation, because we want to
+            // take advantage of the method overriden by AllAuthoritiesFactory.
+            return finder.findIdentifier(object);
+        }
+    }
+
+    /**
+     * Releases resources immediately instead of waiting for the garbage collector.
+     *
+     * @throws FactoryException if an error occured while disposing the factory.
+     */
+    @Override
+    public synchronized void dispose() throws FactoryException {
+        if (backingStore != null) {
+            backingStore.dispose();
+            backingStore = null;
+        }
+        pool.clear();
+        findPool.clear();
+        super.dispose();
+    }
+
+    /**
+     * Returns an object from the pool for the specified code. If the object was retained as a
+     * {@linkplain Reference weak reference}, the {@link Reference#get referent} is returned.
+     *
+     * @todo Consider logging a message here to the finer or finest level.
+     */
+    private Object get(final Object key) {
+        assert Thread.holdsLock(this);
+        Object object = pool.get(key);
+        if (object instanceof Reference) {
+            object = ((Reference<?>) object).get();
+        }
+        return object;
+    }
+
+    /**
+     * Put an element in the pool. This method is invoked everytime a {@code createFoo(...)}
+     * method is invoked, even if an object was already in the pool for the given code, for
+     * the following reasons: 1) Replaces weak reference by strong reference (if applicable)
+     * and 2) Alters the linked hash set order, so that this object is declared as the last
+     * one used.
+     */
+    private void put(final Object key, final Object object) {
+        assert Thread.holdsLock(this);
+        pool.put(key, object);
+        int toReplace = pool.size() - maxStrongReferences;
+        if (toReplace > 0) {
+            for (final Iterator<Map.Entry<Object,Object>> it=pool.entrySet().iterator(); it.hasNext();) {
+                final Map.Entry<Object,Object> entry = it.next();
+                final Object value = entry.getValue();
+                if (value instanceof Reference) {
+                    if (((Reference) value).get() == null) {
+                        it.remove();
+                    }
+                    continue;
+                }
+                entry.setValue(new WeakReference<Object>(value));
+                if (--toReplace == 0) {
+                    break;
+                }
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/DatumAliases.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/DatumAliases.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/DatumAliases.java	(revision 28000)
@@ -0,0 +1,591 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.factory;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import javax.measure.unit.Unit;
+import javax.measure.quantity.Angle;
+import javax.measure.quantity.Length;
+
+import org.opengis.metadata.Identifier;
+import org.opengis.referencing.datum.*;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.FactoryException;
+import org.opengis.util.GenericName;
+import org.opengis.util.ScopedName;
+
+import org.geotools.util.LocalName;
+import org.geotools.util.NameFactory;
+import org.geotools.resources.XArray;
+import org.geotools.resources.i18n.Loggings;
+import org.geotools.resources.i18n.LoggingKeys;
+import org.geotools.referencing.ReferencingFactoryFinder;
+
+
+/**
+ * A datum factory that add {@linkplain IdentifiedObject#getAlias aliases} to a datum name before to
+ * delegates the {@linkplain org.geotools.referencing.datum.AbstractDatum#AbstractDatum(Map) datum
+ * creation} to an other factory. Aliases are especially important for {@linkplain Datum datum}
+ * since their {@linkplain IdentifiedObject#getName name} are often the only way to differentiate
+ * them. Two datum with different names are considered incompatible, unless some datum shift method
+ * are specified (e.g. {@linkplain org.geotools.referencing.datum.BursaWolfParameters Bursa-Wolf
+ * parameters}). Unfortunatly, different softwares often use different names for the same datum,
+ * which result in {@link org.opengis.referencing.operation.OperationNotFoundException} when
+ * attempting to convert coordinates from one {@linkplain CoordinateReferenceSystem coordinate
+ * reference system} to an other one. For example "<cite>Nouvelle Triangulation Française (Paris)</cite>"
+ * and "<cite>NTF (Paris meridian)</cite>" are actually the same datum. This {@code DatumAliases}
+ * class provides a way to handle that.
+ * <p>
+ * {@code DatumAliases} is a class that determines if a datum name is in our list of aliases and
+ * constructs a value for the {@linkplain IdentifiedObject#ALIAS_KEY aliases property} (as
+ * {@linkplain GenericName generic names}) for a name. The default implementation is backed by
+ * the text file "{@code DatumAliasesTable.txt}". The first line in this text file must be the
+ * authority names. All other lines are the aliases.
+ * <p>
+ * Since {@code DatumAliases} is a datum factory, any {@linkplain AuthorityFactory authority
+ * factory} or any {@linkplain org.geotools.referencing.wkt.Parser WKT parser} using this
+ * factory will takes advantage of the aliases table.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/DatumAliases.java $
+ * @version $Id: DatumAliases.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Rueben Schulz
+ * @author Martin Desruisseaux
+ *
+ * @todo Invokes {@link #freeUnused} automatically after some amount of time, in order to release
+ *       memory for unusued aliases. A timer should be set in {@code reload()} method.
+ *
+ * @see <A HREF="http://gdal.velocet.ca/~warmerda/wktproblems.html">WKT problems</A>
+ */
+public class DatumAliases extends ReferencingFactory implements DatumFactory {
+    /**
+     * The default file for alias table.
+     */
+    private static final String ALIAS_TABLE = "DatumAliasesTable.txt";
+
+    /**
+     * The column separators in the file to parse.
+     */
+    private static final String SEPARATORS = ";";
+
+    /**
+     * Array used as a marker for alias that has been discarted because never used.
+     * This array may appears in {@link #aliasMap} values.
+     *
+     * @see #freeUnused
+     */
+    private static final Object[] NEED_LOADING = new Object[0];
+
+    /**
+     * The URL of the alias table. This file is read by {@link #reload} when first needed.
+     */
+    private final URL aliasURL;
+
+    /**
+     * A map of our datum aliases. Keys are alias names in lower-case, and values are
+     * either {@code String[]} or {@code GenericName[]}. In order to reduce the amount
+     * of objects created, all values are initially {@code String[]} objects. They are
+     * converted to {@code GenericName[]} only when first needed.
+     */
+    private final Map<String,Object[]> aliasMap = new HashMap<String,Object[]>();
+
+    /**
+     * The authorities. This is the first line in the alias table.
+     * This array is constructed by {@link #reload} when first needed.
+     */
+    private LocalName[] authorities;
+
+    /**
+     * The underlying datum factory. If {@code null}, a default factory will be fetch from
+     * {@link ReferencingFactoryFinder} when first needed. A default value can't be set at
+     * construction time, since all factories may not be registered at this time.
+     */
+    private DatumFactory factory;
+
+    /**
+     * Constructs a new datum factory with the default backing factory and alias table.
+     */
+    public DatumAliases() {
+        // Uses a slightly higher priority than the default factory, in order
+        // to get WKT parser and authorities factories to use the aliases table.
+        super(NORMAL_PRIORITY + 10);
+        aliasURL = DatumAliases.class.getResource(ALIAS_TABLE);
+        if (aliasURL == null) {
+            throw new NoSuchElementException(ALIAS_TABLE);
+        }
+    }
+
+    /**
+     * Constructs a new datum factory using the specified factory and the default alias table.
+     *
+     * @param factory The factory to use for datum creation.
+     */
+    public DatumAliases(final DatumFactory factory) {
+        this();
+        this.factory = factory;
+        ensureNonNull("factory", factory);
+    }
+
+    /**
+     * Constructs a new datum factory which delegates its work to the specified factory.
+     * The aliases table is read from the specified URL. The fist line in this file most
+     * be the authority names. All other names are aliases.
+     *
+     * @param factory  The factory to use for datum creation.
+     * @param aliasURL The url to the alias table.
+     */
+    public DatumAliases(final DatumFactory factory, final URL aliasURL) {
+        super(NORMAL_PRIORITY + 10);
+        this.factory  = factory;
+        this.aliasURL = aliasURL;
+        ensureNonNull("factory",  factory );
+        ensureNonNull("aliasURL", aliasURL);
+    }
+
+    /**
+     * Returns the backing datum factory. If no factory were explicitly specified
+     * by the user, selects the first datum factory other than {@code this}.
+     * <p>
+     * <strong>Note:</strong> We can't invoke this method in the constructor, because the
+     * constructor is typically invoked during {@code FactoryFinder.scanForPlugins()} execution.
+     * {@code scanForPlugins} is looking for {@link DatumFactory} instances, it has not finished
+     * to search them, and invoking this method in the constructor would prematurely ask an other
+     * {@link DatumFactory} instance while the list is incomplete. Instead, we will invoke this
+     * method when the first {@code createXXX} method is invoked, which typically occurs after
+     * all factories have been initialized.
+     *
+     * @return The backing datum factory.
+     * @throws NoSuchElementException if there is no such factory.
+     */
+    private DatumFactory getDatumFactory() throws NoSuchElementException {
+        assert Thread.holdsLock(this);
+        if (factory == null) {
+            DatumFactory candidate;
+            final Iterator<DatumFactory> it = ReferencingFactoryFinder.getDatumFactories(null).iterator();
+            do candidate = it.next();
+            while (candidate == this);
+            factory = candidate;
+        }
+        return factory;
+    }
+
+    /**
+     * Returns a caseless version of the specified key, to be stored in the map.
+     */
+    private static String toCaseless(final String key) {
+        return key.replace('_', ' ').trim().toLowerCase();
+    }
+
+    /**
+     * Read the next line from the specified input stream, skipping all blank
+     * and comment lines. Returns {@code null} on end of stream.
+     */
+    private static String readLine(final BufferedReader in) throws IOException {
+        String line;
+        do line = in.readLine();
+        while (line!=null && ((line=line.trim()).length()==0 || line.charAt(0)=='#'));
+        return line;
+    }
+
+    /**
+     * Read again the "{@code DatumAliasesTable.txt}" file into {@link #aliasMap}.
+     * This method may be invoked more than once in order to reload entries that
+     * have been discarted by {@link #freeUnused}. This method assumes that the
+     * file content didn't change between two calls.
+     *
+     * @throws IOException if the loading failed.
+     */
+    private void reload() throws IOException {
+        assert Thread.holdsLock(this);
+        final LogRecord record = Loggings.format(Level.FINE,
+                LoggingKeys.LOADING_DATUM_ALIASES_$1, aliasURL);
+        record.setLoggerName(LOGGER.getName());
+        LOGGER.log(record);
+        final BufferedReader in = new BufferedReader(new InputStreamReader(aliasURL.openStream()));
+        /*
+         * Parses the title line. This line contains authority names as column titles.
+         * The authority names will be used as the scope for each identifiers to be
+         * created.
+         */
+        String line = readLine(in);
+        if (line != null) {
+            final List<Object> elements = new ArrayList<Object>();
+            StringTokenizer st = new StringTokenizer(line, SEPARATORS);
+            while (st.hasMoreTokens()) {
+                final String name = st.nextToken().trim();
+                elements.add(name.length()!=0 ? new LocalName(name) : null);
+            }
+            authorities = elements.toArray(new LocalName[elements.size()]);
+            final Map<String,String> canonical = new HashMap<String,String>();
+            /*
+             * Parses all aliases. They are stored as arrays of strings for now, but will be
+             * converted to array of generic names by {@link #getAliases} when first needed.
+             * If the alias belong to an authority (which should be true in most cases), a
+             * scoped name will be created at this time.
+             */
+            while ((line=readLine(in)) != null) {
+                elements .clear();
+                canonical.clear();
+                st = new StringTokenizer(line, SEPARATORS);
+                while (st.hasMoreTokens()) {
+                    String alias = st.nextToken().trim();
+                    if (alias.length() != 0) {
+                        final String previous = canonical.put(alias, alias);
+                        if (previous != null) {
+                            canonical.put(previous, previous);
+                            alias = previous;
+                        }
+                    } else {
+                        alias = null;
+                    }
+                    elements.add(alias);
+                }
+                // Trim trailing null values only (we must keep other null values).
+                for (int i=elements.size(); --i>=0;) {
+                    if (elements.get(i) != null) break;
+                    elements.remove(i);
+                }
+                if (!elements.isEmpty()) {
+                    /*
+                     * Copies the aliases array in the aliases map for all local names. If a
+                     * previous value is found as an array of GenericName objects, those generic
+                     * names are conserved in the map (instead of the string values parsed above)
+                     * in order to avoid constructing them again when they will be needed.
+                     */
+                    final String[] names = elements.toArray(new String[elements.size()]);
+                    for (int i=0; i<names.length; i++) {
+                        final String name = names[i];
+                        final String key  = toCaseless(name);
+                        final Object[] previous = aliasMap.put(key, names);
+                        if (previous!=null && previous!=NEED_LOADING) {
+                            if (previous instanceof GenericName[]) {
+                                aliasMap.put(key, previous);
+                            } else if (!Arrays.equals(previous, names)) {
+                                // TODO: localize
+                                LOGGER.warning("Inconsistent aliases for datum \""+name+"\".");
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        in.close();
+    }
+
+    /**
+     * Logs an {@link IOException}.
+     */
+    private void log(final IOException exception) {
+        LogRecord record = Loggings.format(Level.WARNING, LoggingKeys.CANT_READ_FILE_$1, aliasURL);
+        record.setSourceClassName(DatumAliases.class.getName());
+        record.setSourceMethodName("reload");
+        record.setThrown(exception);
+        record.setLoggerName(LOGGER.getName());
+        LOGGER.log(record);
+    }
+
+    /**
+     * Returns the aliases, as a set of {@link GenericName}, for the given name.
+     * This method returns an internal array; do not modify the returned value.
+     *
+     * @param name Datum alias name to lookup.
+     * @return A set of datum aliases as {@link GenericName} objects for the given name,
+     *         or {@code null} if the name is not in our list of aliases.
+     *
+     * @see #addAliases
+     * @see #reload
+     */
+    private GenericName[] getAliases(String name) {
+        assert Thread.holdsLock(this);
+        if (aliasMap.isEmpty()) try {
+            reload();
+        } catch (IOException exception) {
+            log(exception);
+            // Continue in case the requested alias has been read before the failure occured.
+        }
+        /*
+         * Gets the aliases for the specified name.  If an entry exists for this name with a null
+         * value, this means that 'freeUnused()' has been invoked previously. Reload the file and
+         * try again since the requested name may be one of the set of discarted aliases.
+         */
+        name = toCaseless(name);
+        Object[] aliases = aliasMap.get(name);
+        if (aliases == null) {
+            // Unknow name. We are done.
+            return null;
+        }
+        if (aliases == NEED_LOADING) {
+            // Known name, but the list of alias has been previously
+            // discarted because never used. Reload the file.
+            try {
+                reload();
+            } catch (IOException exception) {
+                log(exception);
+                // Continue in case the requested alias has been read before the failure occured.
+            }
+            aliases = aliasMap.get(name);
+            if (aliases == NEED_LOADING) {
+                // Should never happen, unless reloading failed or some lines have
+                // been deleted in the file since last time the file has been loaded.
+                return null;
+            }
+        }
+        if (aliases instanceof GenericName[]) {
+            return (GenericName[]) aliases;
+        }
+        /*
+         * Aliases has been found, but available as an array of strings only. This means
+         * that those aliases have never been requested before. Transforms the array of
+         * strings into an array of generic names. The new array replaces the old one for
+         * all aliases enumerated in the array (not just the requested one).
+         */
+        int count = 0;
+        GenericName[] names = new GenericName[aliases.length];
+        for (int i=0; i<aliases.length; i++) {
+            final CharSequence alias = (CharSequence) aliases[i];
+            if (alias != null) {
+                if (count < authorities.length) {
+                    final LocalName authority = authorities[count];
+                    if (authority != null) {
+                        names[count++] = new org.geotools.util.ScopedName(authority, alias);
+                        continue;
+                    }
+                }
+                names[count++] = new LocalName(alias);
+            }
+        }
+        names = XArray.resize(names, count);
+        for (int i=0; i<names.length; i++) {
+            final String alias = names[i].tip().toString();
+            final Object[] previous = aliasMap.put(toCaseless(alias), names);
+            assert previous==names || Arrays.equals(aliases, previous) : alias;
+        }
+        return names;
+    }
+
+    /**
+     * Completes the given map of properties. This method expects a map of properties to
+     * be given to {@link AbstractDatum#AbstractDatum(Map)} constructor. The name is fetch
+     * from the {@link IdentifiedObject#NAME_KEY NAME_KEY}.
+     * The {@link AbstractIdentifiedObject#ALIAS_KEY ALIAS_KEY} is
+     * completed with the aliases know to this factory.
+     *
+     * @param  properties The set of properties to complete.
+     * @return The completed properties, or {@code properties} if no change were done.
+     *
+     * @see #getAliases
+     */
+    private Map<String,?> addAliases(Map<String,?> properties) {
+        ensureNonNull("properties", properties);
+        Object value = properties.get(IdentifiedObject.NAME_KEY);
+        ensureNonNull("name", value);
+        final String name;
+        if (value instanceof Identifier) {
+            name = ((Identifier) value).getCode();
+        } else {
+            name = value.toString();
+        }
+        GenericName[] aliases = getAliases(name);
+        if (aliases != null) {
+            /*
+             * Aliases have been found. Before to add them to the properties map, overrides them
+             * with the aliases already provided by the users, if any. The 'merged' map is the
+             * union of aliases know to this factory and aliases provided by the user. User's
+             * aliases will be added first, for preserving the user's order (the LinkedHashMap
+             * acts as a FIFO queue).
+             */
+            int count = aliases.length;
+            value = properties.get(IdentifiedObject.ALIAS_KEY);
+            if (value != null) {
+                final Map<String,GenericName> merged = new LinkedHashMap<String,GenericName>();
+                putAll(NameFactory.toArray(value), merged);
+                count -= putAll(aliases, merged);
+                final Collection<GenericName> c = merged.values();
+                aliases = c.toArray(new GenericName[c.size()]);
+            }
+            /*
+             * Now set the aliases. This replacement will not be performed if
+             * all our aliases were replaced by user's aliases (count <= 0).
+             */
+            if (count > 0) {
+                final Map<String,Object> copy = new HashMap<String,Object>(properties);
+                copy.put(IdentifiedObject.ALIAS_KEY, aliases);
+                properties = copy;
+            }
+        }
+        return properties;
+    }
+
+    /**
+     * Puts all elements in the {@code names} array into the specified map. Order matter, since the
+     * first element in the array should be the first element returned by the map if the map is
+     * actually an instance of {@link LinkedHashMap}. This method returns the number of elements
+     * ignored.
+     */
+    private static final int putAll(final GenericName[] names, final Map<String,GenericName> map) {
+        int ignored = 0;
+        for (int i=0; i<names.length; i++) {
+            final GenericName   name = names[i];
+            final GenericName scoped = name.toFullyQualifiedName();
+            final String         key = toCaseless(scoped.toString());
+            final GenericName    old = map.put(key, name);
+            if (old instanceof ScopedName) {
+                map.put(key, old); // Preserves the user value, except if it was unscoped.
+                ignored++;
+            }
+        }
+        return ignored;
+    }
+
+    /**
+     * Creates an engineering datum.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @throws FactoryException if the object creation failed.
+     */
+    public synchronized EngineeringDatum createEngineeringDatum(final Map<String,?> properties)
+            throws FactoryException
+    {
+        return getDatumFactory().createEngineeringDatum(addAliases(properties));
+    }
+
+    /**
+     * Creates geodetic datum from ellipsoid and (optionaly) Bursa-Wolf parameters.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  ellipsoid Ellipsoid to use in new geodetic datum.
+     * @param  primeMeridian Prime meridian to use in new geodetic datum.
+     * @throws FactoryException if the object creation failed.
+     */
+    public synchronized GeodeticDatum createGeodeticDatum(final Map<String,?> properties,
+            final Ellipsoid ellipsoid, final PrimeMeridian primeMeridian) throws FactoryException
+    {
+        return getDatumFactory().createGeodeticDatum(addAliases(properties),
+                                                     ellipsoid, primeMeridian);
+    }
+
+    /**
+     * Creates an image datum.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  pixelInCell Specification of the way the image grid is associated
+     *         with the image data attributes.
+     * @throws FactoryException if the object creation failed.
+     */
+    public synchronized ImageDatum createImageDatum(final Map<String,?> properties,
+            final PixelInCell pixelInCell) throws FactoryException
+    {
+        return getDatumFactory().createImageDatum(addAliases(properties), pixelInCell);
+    }
+
+    /**
+     * Creates a temporal datum from an enumerated type value.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  origin The date and time origin of this temporal datum.
+     * @throws FactoryException if the object creation failed.
+     */
+    public synchronized TemporalDatum createTemporalDatum(final Map<String,?> properties,
+            final Date origin) throws FactoryException
+    {
+        return getDatumFactory().createTemporalDatum(addAliases(properties), origin);
+    }
+
+    /**
+     * Creates a vertical datum from an enumerated type value.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  type The type of this vertical datum (often geoidal).
+     * @throws FactoryException if the object creation failed.
+     */
+    public synchronized VerticalDatum createVerticalDatum(final Map<String,?> properties,
+            final VerticalDatumType type) throws FactoryException
+    {
+        return getDatumFactory().createVerticalDatum(addAliases(properties), type);
+    }
+
+    /**
+     * Creates an ellipsoid from radius values.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  semiMajorAxis Equatorial radius in supplied linear units.
+     * @param  semiMinorAxis Polar radius in supplied linear units.
+     * @param  unit Linear units of ellipsoid axes.
+     * @throws FactoryException if the object creation failed.
+     */
+    public synchronized Ellipsoid createEllipsoid(final Map<String,?> properties,
+            final double semiMajorAxis, final double semiMinorAxis, final Unit<Length> unit)
+            throws FactoryException
+    {
+        return getDatumFactory().createEllipsoid(addAliases(properties),
+                semiMajorAxis, semiMinorAxis, unit);
+    }
+
+    /**
+     * Creates an ellipsoid from an major radius, and inverse flattening.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  semiMajorAxis Equatorial radius in supplied linear units.
+     * @param  inverseFlattening Eccentricity of ellipsoid.
+     * @param  unit Linear units of major axis.
+     * @throws FactoryException if the object creation failed.
+     */
+    public synchronized Ellipsoid createFlattenedSphere(final Map<String,?> properties,
+            final double semiMajorAxis, final double inverseFlattening, final Unit<Length> unit)
+            throws FactoryException
+    {
+        return getDatumFactory().createFlattenedSphere(addAliases(properties),
+                semiMajorAxis, inverseFlattening, unit);
+    }
+
+    /**
+     * Creates a prime meridian, relative to Greenwich.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  longitude Longitude of prime meridian in supplied angular units East of Greenwich.
+     * @param  angularUnit Angular units of longitude.
+     * @throws FactoryException if the object creation failed.
+     */
+    public synchronized PrimeMeridian createPrimeMeridian(final Map<String,?> properties,
+            final double longitude, final Unit<Angle> angularUnit) throws FactoryException
+    {
+        return getDatumFactory().createPrimeMeridian(addAliases(properties),
+                longitude, angularUnit);
+    }
+
+    /**
+     * Free all aliases that have been unused up to date. If one of those alias is needed at a
+     * later time, the aliases table will be reloaded.
+     */
+    public synchronized void freeUnused() {
+        if (aliasMap != null) {
+            for (final Map.Entry<String,Object[]> entry : aliasMap.entrySet()) {
+                final Object[] value = entry.getValue();
+                if (!(value instanceof GenericName[])) {
+                    entry.setValue(NEED_LOADING);
+                }
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/DeferredAuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/DeferredAuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/DeferredAuthorityFactory.java	(revision 28000)
@@ -0,0 +1,227 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.factory;
+
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+import org.opengis.referencing.FactoryException;
+import org.geotools.factory.Hints;
+import org.geotools.factory.OptionalFactory;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Loggings;
+import org.geotools.resources.i18n.LoggingKeys;
+
+
+/**
+ * A buffered authority factory which will defer the {@linkplain #createBackingStore creation
+ * of a backing store} until when first needed. This approach allow to etablish a connection to
+ * a database (for example) only when first needed. In addition, the backing store can be
+ * automatically disposed after a timeout and recreated when needed again.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/DeferredAuthorityFactory.java $
+ * @version $Id: DeferredAuthorityFactory.java 37339 2011-05-28 10:32:42Z aaime $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @todo Extends {@link BufferedAuthorityFactory} for now in order to improve the trunk stability
+ *       during GEOT-1286 development, but we may revisit that after GEOT-1286 completion.
+ */
+public abstract class DeferredAuthorityFactory extends BufferedAuthorityFactory
+                                            implements OptionalFactory
+{
+    /**
+     * The timer for {@linkplain AbstractAuthorityFactory#dispose disposing} backing stores.
+     */
+    private static Timer TIMER = new Timer("GT authority factory disposer", true);
+
+    /**
+     * The task for disposing the backing store, or {@code null} if none.
+     * This task will be scheduled for repeated execution by {@link #setTimeout}.
+     */
+    private TimerTask disposer;
+
+    /**
+     * {@code true} if the backing store was used since the last time the timer task was run.
+     * A value of {@code true} means that the task must wait again. A value of {@code false}
+     * means that it can dispose the backing store.
+     */
+    private boolean used;
+
+    /**
+     * Constructs an instance without initial backing store. Subclasses are responsible for
+     * creating an appropriate backing store when the {@link #createBackingStore} method is
+     * invoked.
+     *
+     * @param userHints An optional set of hints, or {@code null} if none.
+     * @param priority The priority for this factory, as a number between
+     *        {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
+     *        {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
+     *
+     * @see #createBackingStore
+     *
+     * @since 2.2
+     */
+    protected DeferredAuthorityFactory(final Hints userHints, final int priority) {
+        super(priority, DEFAULT_MAX);
+    }
+
+    /**
+     * Returns {@code true} if this factory is available. The default implementation returns
+     * {@code false} if {@link #createBackingStore} throws an exception.
+     */
+    @Override
+    public boolean isAvailable() {
+        return super.isAvailable();
+    }
+
+    /**
+     * Returns the backing store authority factory.
+     *
+     * @return The backing store to uses in {@code createXXX(...)} methods.
+     * @throws FactoryException if the creation of backing store failed.
+     */
+    @Override
+    final AbstractAuthorityFactory getBackingStore() throws FactoryException {
+        if (backingStore == null) {
+            synchronized (this) {
+                if(backingStore == null) {
+                    backingStore = createBackingStore();
+                    if (backingStore == null) {
+                        throw new FactoryNotFoundException(Errors.format(ErrorKeys.NO_DATA_SOURCE));
+                    }
+                    completeHints();
+                }
+            }
+        }
+        used = true; // Tell to the disposer to wait again.
+        return backingStore;
+    }
+
+    /**
+     * Creates the backing store authority factory. This method is invoked the first time a
+     * {@code createXXX(...)} method is invoked.
+     *
+     * @return The backing store to uses in {@code createXXX(...)} methods.
+     * @throws FactoryNotFoundException if the backing store has not been found.
+     * @throws FactoryException if the creation of backing store failed for an other reason.
+     */
+    protected abstract AbstractAuthorityFactory createBackingStore() throws FactoryException;
+
+    /**
+     * Set a timer for disposing the backing store after the specified amount of milliseconds of
+     * inactivity. The {@link #createBackingStore} method will be responsible for creating a new
+     * backing store when needed. Note that the backing store disposal can be vetoed if
+     * {@link #canDisposeBackingStore} returns {@code false}.
+     *
+     * @param delay The minimal delay before to close the backing store. This delay is very
+     *        approximative. The backing store will not be closed before, but may take as
+     *        much as twice that time before to be closed.
+     */
+    public synchronized void setTimeout(final long delay) {
+        // if we have been disposed, don't do anything
+        if(TIMER == null)
+            return;
+        
+        if (disposer != null) {
+            disposer.cancel();
+        }
+        disposer = new Disposer();
+        TIMER.schedule(disposer, delay, delay);
+    }
+
+    /**
+     * Returns {@code true} if the backing store can be disposed now. This method is invoked
+     * automatically after the amount of time specified by {@link #setTimeout} if the factory
+     * were not used during that time. The default implementation always returns {@code true}.
+     * Subclasses should override this method and returns {@code false} if they want to prevent
+     * the backing store disposal under some circonstances.
+     *
+     * @param backingStore The backing store in process of being disposed.
+     */
+    protected boolean canDisposeBackingStore(final AbstractAuthorityFactory backingStore) {
+        return true;
+    }
+
+    /**
+     * Releases resources immediately instead of waiting for the garbage collector. This
+     * method disposes the backing store regardeless of {@link #canDisposeBackingStore} value.
+     */
+    @Override
+    public synchronized void dispose() throws FactoryException {
+        if (disposer != null) {
+            disposer.cancel();
+            disposer = null;
+        }
+        super.dispose();
+    }
+        
+    /**
+     * Disposes of the backing store
+     * @throws FactoryException
+     */
+    protected synchronized void disposeBackingStore() {
+        try {
+            if(backingStore != null) {
+                LOGGER.log(Level.INFO, "Disposing " + getClass() + " backing store");
+                backingStore.dispose();
+                backingStore = null;
+            }
+        } catch (FactoryException exception) {
+            backingStore = null;
+            final LogRecord record = Loggings.format(Level.WARNING,
+                    LoggingKeys.CANT_DISPOSE_BACKING_STORE);
+            record.setSourceMethodName("run");
+            record.setSourceClassName(Disposer.class.getName());
+            record.setThrown(exception);
+            record.setLoggerName(LOGGER.getName());
+            LOGGER.log(record);
+        }
+    }
+
+    /**
+     * The task for closing the backing store after the timeout.
+     */
+    private final class Disposer extends TimerTask {
+        public void run() {
+            synchronized (DeferredAuthorityFactory.this) {
+                if (used || !canDisposeBackingStore(backingStore)) {
+                    used = false;
+                    return;
+                }
+                if (cancel()) {
+                    disposer = null;
+                    if (backingStore != null) { 
+                        disposeBackingStore();
+                    }
+                    // Needed in order to lets GC do its job.
+                    hints.remove(Hints.DATUM_AUTHORITY_FACTORY);
+                    hints.remove(Hints.CS_AUTHORITY_FACTORY);
+                    hints.remove(Hints.CRS_AUTHORITY_FACTORY);
+                    hints.remove(Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY);
+                }
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/DirectAuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/DirectAuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/DirectAuthorityFactory.java	(revision 28000)
@@ -0,0 +1,110 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.factory;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.LinkedHashSet;
+import java.util.Collection;
+import java.awt.RenderingHints;
+
+import org.opengis.referencing.*;
+import org.geotools.factory.Hints;
+
+
+/**
+ * The base class for authority factories that create referencing object directly. This is
+ * in contrast with other factories like the {@linkplain AuthorityFactoryAdapter adapter}
+ * or {@linkplain BufferedAuthorityFactory buffered} ones, which delegates their work to
+ * an other factory.
+ *
+ * @since 2.3
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/DirectAuthorityFactory.java $
+ * @version $Id: DirectAuthorityFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public abstract class DirectAuthorityFactory extends AbstractAuthorityFactory {
+
+    // IMPLEMENTATION NOTE:  The reason why this class exist is that we don't want "indirect"
+    // factories like BufferedAuthorityFactory to inherit the factories field.  If this field
+    // existed in their super-class, then the super-class constructor could try to initialize
+    // it while in fact BufferedAuthorityFactory don't need it.  Experience with Geotools 2.2
+    // suggest that it can lead to tricky recursivity problems in FactoryFinder, because most
+    // factories registered in META-INF/services are some kind of BufferedAuthorityFactory.
+
+    /**
+     * The underlying factories used for objects creation.
+     */
+    protected final ReferencingFactoryContainer factories;
+
+    /**
+     * Tells if {@link ReferencingFactoryContainer#hints} has been invoked. It must be
+     * invoked exactly once, but can't be invoked in the constructor because it causes
+     * a {@link StackOverflowError} in some situations.
+     */
+    private boolean hintsInitialized;
+
+    /**
+     * Constructs an instance using the specified set of factories.
+     *
+     * @param factories The low-level factories to use.
+     * @param priority The priority for this factory, as a number between
+     *        {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
+     *        {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
+     */
+    protected DirectAuthorityFactory(final ReferencingFactoryContainer factories, final int priority) {
+        super(priority);
+        this.factories = factories;
+        ensureNonNull("factories", factories);
+    }
+
+    /**
+     * Returns the implementation hints for this factory. The returned map contains values for
+     * {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS}, {@link Hints#DATUM_FACTORY DATUM}
+     * and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM} {@code FACTORY} hints. Other values
+     * may be provided as well, at implementation choice.
+     */
+    @Override
+    public Map<RenderingHints.Key,?> getImplementationHints() {
+        synchronized (hints) { // Note: avoid lock on public object.
+            if (!hintsInitialized) {
+                hintsInitialized = true;
+                hints.putAll(factories.getImplementationHints());
+            }
+        }
+        return super.getImplementationHints();
+    }
+
+    /**
+     * Returns the direct {@linkplain Factory factory} dependencies.
+     */
+    @Override
+    Collection<? super AuthorityFactory> dependencies() {
+        if (factories != null) {
+            final Set<Object> dependencies = new LinkedHashSet<Object>(8);
+            dependencies.add(factories.getCRSFactory());
+            dependencies.add(factories.getCSFactory());
+            dependencies.add(factories.getDatumFactory());
+            return dependencies;
+        }
+        return super.dependencies();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/FactoryNotFoundException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/FactoryNotFoundException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/FactoryNotFoundException.java	(revision 28000)
@@ -0,0 +1,54 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *   
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.factory;
+
+// OpenGIS dependencies
+import org.opengis.referencing.FactoryException;
+
+
+/**
+ * Thrown when a requested factory has not been found. This exception may be thrown by
+ * {@link DeferredAuthorityFactory#createBackingStore}.
+ *
+ * @since 2.3
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/FactoryNotFoundException.java $
+ * @version $Id: FactoryNotFoundException.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class FactoryNotFoundException extends FactoryException {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -661925454228937249L;
+
+    /**
+     * Construct an exception with no detail message.
+     */
+    public FactoryNotFoundException() {
+    }
+
+    /**
+     * Construct an exception with the specified detail message.
+     *
+     * @param  message The detail message. The detail message is saved
+     *         for later retrieval by the {@link #getMessage()} method.
+     */
+    public FactoryNotFoundException(String message) {
+        super(message);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/FallbackAuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/FallbackAuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/FallbackAuthorityFactory.java	(revision 28000)
@@ -0,0 +1,1118 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.factory;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+import javax.measure.unit.Unit;
+
+import org.geotools.factory.FactoryNotFoundException;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.LoggingKeys;
+import org.geotools.resources.i18n.Loggings;
+import org.opengis.metadata.extent.Extent;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.referencing.AuthorityFactory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.crs.CRSAuthorityFactory;
+import org.opengis.referencing.crs.CompoundCRS;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.DerivedCRS;
+import org.opengis.referencing.crs.EngineeringCRS;
+import org.opengis.referencing.crs.GeocentricCRS;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.ImageCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.crs.TemporalCRS;
+import org.opengis.referencing.crs.VerticalCRS;
+import org.opengis.referencing.cs.CSAuthorityFactory;
+import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.cs.CylindricalCS;
+import org.opengis.referencing.cs.EllipsoidalCS;
+import org.opengis.referencing.cs.PolarCS;
+import org.opengis.referencing.cs.SphericalCS;
+import org.opengis.referencing.cs.TimeCS;
+import org.opengis.referencing.cs.VerticalCS;
+import org.opengis.referencing.datum.DatumAuthorityFactory;
+import org.opengis.referencing.datum.Ellipsoid;
+import org.opengis.referencing.datum.EngineeringDatum;
+import org.opengis.referencing.datum.GeodeticDatum;
+import org.opengis.referencing.datum.ImageDatum;
+import org.opengis.referencing.datum.PrimeMeridian;
+import org.opengis.referencing.datum.TemporalDatum;
+import org.opengis.referencing.datum.VerticalDatum;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * A factory which delegates all object creation to a <cite>primary</cite> factory,
+ * and fallback on an other one if the primary factory failed.
+ *
+ * @since 2.3
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/FallbackAuthorityFactory.java $
+ * @version $Id: FallbackAuthorityFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux
+ *
+ * @todo Needs a mechanism for avoiding to query the same factory twice when the fallback is the
+ *       same instance than the primary factory for some {@link AuthorityFactory} interfaces.
+ */
+public class FallbackAuthorityFactory extends AuthorityFactoryAdapter {
+    /**
+     * The factory to use as a fallback if the primary factory failed.
+     */
+    private final AbstractAuthorityFactory fallback;
+
+    /**
+     * Returns {@code true} if the two specified factories can be used in a
+     * {@code FallbackAuthorityFactory}. If this method returns {@code false},
+     * then we should not create instance of this class since it would be useless.
+     */
+    static boolean chainable(final AuthorityFactory primary, final AuthorityFactory fallback) {
+        return (interfaceMask(primary) & interfaceMask(fallback)) != 0;
+    }
+
+    /**
+     * Wraps a primary and a fallback authority factories.
+     * <p>
+     * This constructor is protected because subclasses must declare which of the
+     * {@link DatumAuthorityFactory}, {@link CSAuthorityFactory}, {@link CRSAuthorityFactory}
+     * and {@link CoordinateOperationAuthorityFactory} interfaces they choose to implement.
+     *
+     * @param primary The primary factory.
+     * @param fallback The factory to use as a fallback if the primary factory failed.
+     *
+     * @see #create
+     */
+    protected FallbackAuthorityFactory(final AuthorityFactory primary,
+                                       final AuthorityFactory fallback)
+    {
+        super(primary, fallback);
+        ensureNonNull("fallback", fallback);
+        this.fallback = (fallback instanceof AbstractAuthorityFactory) ?
+                (AbstractAuthorityFactory) fallback : new AuthorityFactoryAdapter(fallback);
+    }
+
+    /**
+     * Wraps the specified authority factories. If the specified collection contains more than
+     * one element, then a chain of {@code FallbackAuthorityFactory} instances is created. The
+     * type is inferred from the factories found in the collection.
+     * <p>
+     * Consider using <code>{@linkplain #create(Class, Collection) create}(type, factories)</code>
+     * instead when the type is known at compile time.
+     *
+     * @param  factories The factories to wrap, in iteration order.
+     * @return The given factories as a chain of fallback factories.
+     * @throws FactoryNotFoundException if the collection doesn't contains at least one element.
+     *
+     * @since 2.4
+     */
+    public static AuthorityFactory create(final Collection<? extends AuthorityFactory> factories)
+            throws FactoryNotFoundException
+    {
+        ensureNonNull("factories", factories);
+        if (factories.isEmpty()) {
+            throw new FactoryNotFoundException(Errors.format(
+                    ErrorKeys.FACTORY_NOT_FOUND_$1, AuthorityFactory.class));
+        }
+        return create(false, interfaceMask(factories), factories.iterator());
+    }
+
+    /**
+     * Wraps the specified authority factories. If the specified collection contains more than
+     * one element, then a chain of {@code FallbackAuthorityFactory} instances is created.
+     *
+     * @param automatic {@code true} if {@code interfaceMask} should automatically
+     *        be restricted to the factory types detected in the collection.
+     * @param interfaceMask The value computed by {@link #interfaceMask(Class)} that
+     *        describe the set of interfaces to be implemented by the returned factory.
+     * @param factories The factories to chain.
+     */
+    private static AuthorityFactory create(final boolean automatic, int interfaceMask,
+                                           final Iterator<? extends AuthorityFactory> factories)
+            throws FactoryNotFoundException
+    {
+        AuthorityFactory primary = factories.next();
+        if (factories.hasNext()) {
+            AuthorityFactory fallback = create(true, interfaceMask, factories);
+            while (fallback != primary) { // Paranoiac check
+                if (!sameAuthorityCodes(fallback, primary)) {
+                    /*
+                     * (Note: argument order is significant in the above method call)
+                     * Creates a "primary - fallback" chain only if the fallback is not
+                     * performing the same work than the primary factory, for example:
+                     *
+                     *   - A BufferedAuthorityFactory wrapping the primary factory. Since
+                     *     the primary factory is tested first, the second one is useless.
+                     *
+                     *   - A OrderedAxisAuthorityFactory wrapping the primary factory. If
+                     *     the primary factory failed to create a CRS, the second factory
+                     *     should fail too since it relies on the first one.
+                     */
+                    if (automatic) {
+                        // Restricts the interface to be implemented to the
+                        // same set of interfaces than the backing factories.
+                        interfaceMask &= (interfaceMask(primary) | interfaceMask(fallback));
+                    }
+                    primary = create(interfaceMask, primary, fallback);
+                } else {
+                    /*
+                     * If the fallback is redundant, we should be done (just return the primary
+                     * factory). A special case occurs if the fallback is an other instance of
+                     * FallbackAuthorityFactory. We want to discard only the redundant primary
+                     * factory (this is why we don't override sameAuthorityCodes(...) for testing
+                     * the fallback). The fallback may have value, so we test it recursively.
+                     */
+                    if (fallback instanceof FallbackAuthorityFactory) {
+                        fallback = ((FallbackAuthorityFactory) fallback).fallback;
+                        continue;
+                    }
+                }
+                break;
+            }
+        }
+        return primary;
+    }
+
+    /**
+     * Returns the direct dependencies. The returned list contains the backing store and the
+     * fallback specified at construction time, or the exception if they can't be obtained.
+     */
+    @Override
+    Collection<? super AuthorityFactory> dependencies() {
+        final Collection<? super AuthorityFactory> dep = super.dependencies();
+        dep.add(fallback);
+        return dep;
+    }
+
+    /**
+     * Returns the set of authority codes for the specified type. The default implementation
+     * returns the union of the authority codes from the <cite>primary</cite> and the
+     * <cite>fallback</cite> factories.
+     */
+    @Override
+    public Set<String> getAuthorityCodes(final Class<? extends IdentifiedObject> type)
+            throws FactoryException
+    {
+        final Set<String> codes = new LinkedHashSet<String>(super.getAuthorityCodes(type));
+        codes.addAll(fallback.getAuthorityCodes(type));
+        return codes;
+    }
+
+    /**
+     * Returns a description for the object identified by the specified code.
+     */
+    @Override
+    public InternationalString getDescriptionText(final String code) throws FactoryException {
+        try {
+            return super.getDescriptionText(code);
+        } catch (FactoryException exception) {
+            notifyFailure("getDescriptionText", exception);
+            try {
+                return fallback.getDescriptionText(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns an arbitrary object from a code.
+     */
+    @Override
+    public IdentifiedObject createObject(final String code) throws FactoryException {
+        try {
+            return super.createObject(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createObject", exception);
+            try {
+                return fallback.createObject(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns an arbitrary {@linkplain org.opengis.referencing.datum.Datum datum} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public org.opengis.referencing.datum.Datum createDatum(final String code) throws FactoryException {
+        try {
+            return super.createDatum(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createDatum", exception);
+            try {
+                return fallback.createDatum(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a {@linkplain EngineeringDatum engineering datum} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public EngineeringDatum createEngineeringDatum(final String code) throws FactoryException {
+        try {
+            return super.createEngineeringDatum(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createEngineeringDatum", exception);
+            try {
+                return fallback.createEngineeringDatum(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a {@linkplain ImageDatum image datum} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public ImageDatum createImageDatum(final String code) throws FactoryException {
+        try {
+            return super.createImageDatum(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createImageDatum", exception);
+            try {
+                return fallback.createImageDatum(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a {@linkplain VerticalDatum vertical datum} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public VerticalDatum createVerticalDatum(final String code) throws FactoryException {
+        try {
+            return super.createVerticalDatum(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createVerticalDatum", exception);
+            try {
+                return fallback.createVerticalDatum(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a {@linkplain TemporalDatum temporal datum} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public TemporalDatum createTemporalDatum(final String code) throws FactoryException {
+        try {
+            return super.createTemporalDatum(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createTemporalDatum", exception);
+            try {
+                return fallback.createTemporalDatum(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns a {@linkplain GeodeticDatum geodetic datum} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public GeodeticDatum createGeodeticDatum(final String code) throws FactoryException {
+        try {
+            return super.createGeodeticDatum(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createGeodeticDatum", exception);
+            try {
+                return fallback.createGeodeticDatum(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns an {@linkplain Ellipsoid ellipsoid} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public Ellipsoid createEllipsoid(final String code) throws FactoryException {
+        try {
+            return super.createEllipsoid(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createEllipsoid", exception);
+            try {
+                return fallback.createEllipsoid(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns a {@linkplain PrimeMeridian prime meridian} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public PrimeMeridian createPrimeMeridian(final String code) throws FactoryException {
+        try {
+            return super.createPrimeMeridian(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createPrimeMeridian", exception);
+            try {
+                return fallback.createPrimeMeridian(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns a {@linkplain Extent extent} (usually an area of validity) from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public Extent createExtent(final String code) throws FactoryException {
+        try {
+            return super.createExtent(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createExtent", exception);
+            try {
+                return fallback.createExtent(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns an arbitrary {@linkplain CoordinateSystem coordinate system} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public CoordinateSystem createCoordinateSystem(final String code) throws FactoryException {
+        try {
+            return super.createCoordinateSystem(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createCoordinateSystem", exception);
+            try {
+                return fallback.createCoordinateSystem(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a cartesian coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public CartesianCS createCartesianCS(final String code) throws FactoryException {
+        try {
+            return super.createCartesianCS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createCartesianCS", exception);
+            try {
+                return fallback.createCartesianCS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a polar coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public PolarCS createPolarCS(final String code) throws FactoryException {
+        try {
+            return super.createPolarCS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createPolarCS", exception);
+            try {
+                return fallback.createPolarCS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a cylindrical coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public CylindricalCS createCylindricalCS(final String code) throws FactoryException {
+        try {
+            return super.createCylindricalCS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createCylindricalCS", exception);
+            try {
+                return fallback.createCylindricalCS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a spherical coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public SphericalCS createSphericalCS(final String code) throws FactoryException {
+        try {
+            return super.createSphericalCS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createSphericalCS", exception);
+            try {
+                return fallback.createSphericalCS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates an ellipsoidal coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public EllipsoidalCS createEllipsoidalCS(final String code) throws FactoryException {
+        try {
+            return super.createEllipsoidalCS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createEllipsoidalCS", exception);
+            try {
+                return fallback.createEllipsoidalCS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a vertical coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public VerticalCS createVerticalCS(final String code) throws FactoryException {
+        try {
+            return super.createVerticalCS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createVerticalCS", exception);
+            try {
+                return fallback.createVerticalCS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a temporal coordinate system from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public TimeCS createTimeCS(final String code) throws FactoryException {
+        try {
+            return super.createTimeCS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createTimeCS", exception);
+            try {
+                return fallback.createTimeCS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns a {@linkplain CoordinateSystemAxis coordinate system axis} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public CoordinateSystemAxis createCoordinateSystemAxis(final String code)
+            throws FactoryException
+    {
+        try {
+            return super.createCoordinateSystemAxis(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createCoordinateSystemAxis", exception);
+            try {
+                return fallback.createCoordinateSystemAxis(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns an {@linkplain Unit unit} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public Unit<?> createUnit(final String code) throws FactoryException {
+        try {
+            return super.createUnit(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createUnit", exception);
+            try {
+                return fallback.createUnit(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns an arbitrary {@linkplain CoordinateReferenceSystem coordinate reference system}
+     * from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public CoordinateReferenceSystem createCoordinateReferenceSystem(final String code)
+            throws FactoryException
+    {
+        try {
+            return super.createCoordinateReferenceSystem(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createCoordinateReferenceSystem", exception);
+            try {
+                return fallback.createCoordinateReferenceSystem(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a 3D coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public CompoundCRS createCompoundCRS(final String code) throws FactoryException {
+        try {
+            return super.createCompoundCRS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createCompoundCRS", exception);
+            try {
+                return fallback.createCompoundCRS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a derived coordinate reference system from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public DerivedCRS createDerivedCRS(final String code) throws FactoryException {
+        try {
+            return super.createDerivedCRS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createDerivedCRS", exception);
+            try {
+                return fallback.createDerivedCRS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a {@linkplain EngineeringCRS engineering coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public EngineeringCRS createEngineeringCRS(final String code) throws FactoryException {
+        try {
+            return super.createEngineeringCRS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createEngineeringCRS", exception);
+            try {
+                return fallback.createEngineeringCRS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns a {@linkplain GeographicCRS geographic coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public GeographicCRS createGeographicCRS(final String code) throws FactoryException {
+        try {
+            return super.createGeographicCRS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createGeographicCRS", exception);
+            try {
+                return fallback.createGeographicCRS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns a {@linkplain GeocentricCRS geocentric coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public GeocentricCRS createGeocentricCRS(final String code) throws FactoryException {
+        try {
+            return super.createGeocentricCRS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createGeocentricCRS", exception);
+            try {
+                return fallback.createGeocentricCRS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a {@linkplain ImageCRS image coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public ImageCRS createImageCRS(final String code) throws FactoryException {
+        try {
+            return super.createImageCRS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createImageCRS", exception);
+            try {
+                return fallback.createImageCRS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns a {@linkplain ProjectedCRS projected coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public ProjectedCRS createProjectedCRS(final String code) throws FactoryException {
+        try {
+            return super.createProjectedCRS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createProjectedCRS", exception);
+            try {
+                return fallback.createProjectedCRS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a {@linkplain TemporalCRS temporal coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public TemporalCRS createTemporalCRS(final String code) throws FactoryException {
+        try {
+            return super.createTemporalCRS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createTemporalCRS", exception);
+            try {
+                return fallback.createTemporalCRS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a {@linkplain VerticalCRS vertical coordinate reference system} from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public VerticalCRS createVerticalCRS(final String code) throws FactoryException {
+        try {
+            return super.createVerticalCRS(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createVerticalCRS", exception);
+            try {
+                return fallback.createVerticalCRS(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates a parameter descriptor from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public ParameterDescriptor createParameterDescriptor(final String code) throws FactoryException {
+        try {
+            return super.createParameterDescriptor(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createParameterDescriptor", exception);
+            try {
+                return fallback.createParameterDescriptor(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates an operation method from a code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public OperationMethod createOperationMethod(final String code) throws FactoryException {
+        try {
+            return super.createOperationMethod(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createOperationMethod", exception);
+            try {
+                return fallback.createOperationMethod(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates an operation from a single operation code.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public CoordinateOperation createCoordinateOperation(final String code) throws FactoryException {
+        try {
+            return super.createCoordinateOperation(code);
+        } catch (FactoryException exception) {
+            notifyFailure("createCoordinateOperation", exception);
+            try {
+                return fallback.createCoordinateOperation(code);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Creates an operation from coordinate reference system codes.
+     *
+     * @throws FactoryException if the object creation failed for all factories.
+     */
+    @Override
+    public Set<CoordinateOperation> createFromCoordinateReferenceSystemCodes(
+            final String sourceCRS, final String targetCRS)
+            throws FactoryException
+    {
+        try {
+            return super.createFromCoordinateReferenceSystemCodes(sourceCRS, targetCRS);
+        } catch (FactoryException exception) {
+            notifyFailure("createFromCoordinateReferenceSystemCodes", exception);
+            try {
+                return fallback.createFromCoordinateReferenceSystemCodes(sourceCRS, targetCRS);
+            } catch (NoSuchAuthorityCodeException ignore) {
+                throw exception;
+            }
+        }
+    }
+
+    /**
+     * Returns a finder which can be used for looking up unidentified objects.
+     * The default implementation delegates the lookups to the primary factory,
+     * and fallback on the second one if the primary factory can't find a match.
+     *
+     * @since 2.4
+     */
+    @Override
+    public IdentifiedObjectFinder getIdentifiedObjectFinder(Class<? extends IdentifiedObject> type)
+            throws FactoryException
+    {
+        return new Finder(type);
+    }
+
+    /**
+     * A {@link IdentifiedObjectFinder} which fallback to the second factory
+     * if the primary one can't find a match.
+     */
+    private final class Finder extends AuthorityFactoryAdapter.Finder {
+        /**
+         * The fallback. Will be created only when first needed.
+         */
+        private transient IdentifiedObjectFinder fallback;
+
+        /**
+         * Creates a finder for the underlying backing store.
+         */
+        Finder(final Class<? extends IdentifiedObject> type) throws FactoryException {
+            super(type);
+        }
+
+        /**
+         * Makes sure that {@link #fallback} is initialized.
+         */
+        private void ensureFallback() throws FactoryException {
+            if (fallback == null) {
+                fallback = FallbackAuthorityFactory.this.fallback.getIdentifiedObjectFinder(getProxy().getType());
+            }
+            fallback.setFullScanAllowed(isFullScanAllowed());
+        }
+
+        /**
+         * Lookups for the specified object.
+         */
+        @Override
+        public IdentifiedObject find(final IdentifiedObject object) throws FactoryException {
+            IdentifiedObject candidate = finder.find(object);
+            if (candidate != null) {
+                return candidate;
+            }
+            ensureFallback();
+            candidate = fallback.find(object);
+            return candidate;
+        }
+
+        /**
+         * Returns the identifier of the specified object, or {@code null} if none.
+         */
+        @Override
+        public String findIdentifier(final IdentifiedObject object) throws FactoryException {
+            String candidate = finder.findIdentifier(object);
+            if (candidate != null) {
+                return candidate;
+            }
+            ensureFallback();
+            candidate = fallback.findIdentifier(object);
+            return candidate;
+        }
+    }
+
+    /**
+     * Invoked by <code>create</code><var>Foo</var><code>(String)</code> methods when the
+     * <cite>primary</cite> factory failed to create an object. Note that it doesn't imply
+     * anything about the success of <cite>fallback</cite> factory. The default implementation
+     * log a message to the {@link Level#FINE FINE} level.
+     *
+     * @param method The name of the invoked method.
+     * @param exception The exception that occured. It is often possible to
+     *        get the authority code from some subclasses of this exception.
+     */
+    private static void notifyFailure(final String method, final FactoryException exception) {
+        if (LOGGER.isLoggable(Level.FINE)) {
+            final LogRecord record = Loggings.format(Level.FINE,
+                    LoggingKeys.FALLBACK_FACTORY_$1, exception);
+            record.setSourceClassName(FallbackAuthorityFactory.class.getName());
+            record.setSourceMethodName(method);
+            record.setLoggerName(LOGGER.getName());
+            LOGGER.log(record);
+        }
+    }
+
+    /**
+     * Returns a mask that represent the implemented interfaces.
+     */
+    private static int interfaceMask(final Collection<? extends AuthorityFactory> factories) {
+        int mask = 0;
+        for (final AuthorityFactory factory : factories) {
+            mask |= interfaceMask(factory);
+        }
+        return mask;
+    }
+
+    /**
+     * Returns a mask that represent the implemented interface.
+     */
+    private static int interfaceMask(final AuthorityFactory factory) {
+        return interfaceMask(factory.getClass());
+    }
+
+    /**
+     * Returns a mask that represent the implemented interface.
+     */
+    private static int interfaceMask(final Class<? extends AuthorityFactory> type) {
+        int mask = 0; // Will be a set of bit flags, as set below.
+        if (CoordinateOperationAuthorityFactory.class.isAssignableFrom(type)) mask |= 1;
+        if (                 CSAuthorityFactory.class.isAssignableFrom(type)) mask |= 2;
+        if (              DatumAuthorityFactory.class.isAssignableFrom(type)) mask |= 4;
+        if (                CRSAuthorityFactory.class.isAssignableFrom(type)) mask |= 8;
+        return mask;
+    }
+
+    /**
+     * Creates a factory from a mask computed by {@link #interfaceMask}.
+     */
+    private static AuthorityFactory create(final int mask,
+            final AuthorityFactory primary, final AuthorityFactory fallback)
+    {
+        /*
+         * The following assertion fails if we try to implements some
+         * interfaces not supported by the primary or fallback factory.
+         */
+        assert (mask & ~(interfaceMask(primary) | interfaceMask(fallback))) == 0 : mask;
+        final AuthorityFactory factory;
+        /*
+         * In the 'switch' statement below, we do not implement all possible combinaisons
+         * of authority factories. Only a few common combinaisons are listed. Other
+         * combinaisons will fallback on some reasonable default. We may complete the
+         * list later if there is a need for that.
+         */
+        switch (mask) {
+            case 15: factory = new All                     (primary, fallback); break;
+            case 14: factory = new CRS_Datum_CS            (primary, fallback); break;
+            case 13: //      = new CRS_Datum_Operation     (primary, fallback); break;
+            case 12: //      = new CRS_Datum               (primary, fallback); break;
+            case 11: //      = new CRS_CS_Operation        (primary, fallback); break;
+            case 10: //      = new CRS_CS                  (primary, fallback); break;
+            case  9: //      = new CRS_Operation           (primary, fallback); break;
+            case  8: factory = new CRS                     (primary, fallback); break;
+            case  7: //      = new Datum_CS_Operation      (primary, fallback); break;
+            case  6: //      = new Datum_CS                (primary, fallback); break;
+            case  5: //      = new Datum_Operation         (primary, fallback); break;
+            case  4: factory = new Datum                   (primary, fallback); break;
+            case  3: //      = new CS_Operation            (primary, fallback); break;
+            case  2: factory = new CS                      (primary, fallback); break;
+            case  1: factory = new Operation               (primary, fallback); break;
+            case  0: factory = new FallbackAuthorityFactory(primary, fallback); break;
+            default: throw new AssertionError(mask); // Should never happen.
+        }
+        /*
+         * The following assertion fails if 'factory' implements some interfaces
+         * that wasn't requested. The opposite is allowed however: 'factory' may
+         * not implement every requested interfaces.
+         */
+        assert (interfaceMask(factory) & ~mask) == 0 : mask;
+        return factory;
+    }
+
+    /** For internal use by {@link FallbackAuthorityFactory#create} only. */
+    private static final class CRS extends FallbackAuthorityFactory
+            implements CRSAuthorityFactory
+    {
+        CRS(final AuthorityFactory primary, final AuthorityFactory fallback) {
+            super(primary, fallback);
+        }
+    }
+
+    /** For internal use by {@link FallbackAuthorityFactory#create} only. */
+    private static final class CS extends FallbackAuthorityFactory
+            implements CSAuthorityFactory
+    {
+        CS(final AuthorityFactory primary, final AuthorityFactory fallback) {
+            super(primary, fallback);
+        }
+    }
+
+    /** For internal use by {@link FallbackAuthorityFactory#create} only. */
+    private static final class Datum extends FallbackAuthorityFactory
+            implements DatumAuthorityFactory
+    {
+        Datum(final AuthorityFactory primary, final AuthorityFactory fallback) {
+            super(primary, fallback);
+        }
+    }
+
+    /** For internal use by {@link FallbackAuthorityFactory#create} only. */
+    private static final class Operation extends FallbackAuthorityFactory
+            implements CoordinateOperationAuthorityFactory
+    {
+        Operation(final AuthorityFactory primary, final AuthorityFactory fallback) {
+            super(primary, fallback);
+        }
+    }
+
+    /** For internal use by {@link FallbackAuthorityFactory#create} only. */
+    private static final class CRS_Datum_CS extends FallbackAuthorityFactory
+            implements CRSAuthorityFactory, CSAuthorityFactory, DatumAuthorityFactory
+    {
+        CRS_Datum_CS(final AuthorityFactory primary, final AuthorityFactory fallback) {
+            super(primary, fallback);
+        }
+    }
+
+    /** For internal use by {@link FallbackAuthorityFactory#create} only. */
+    private static final class All extends FallbackAuthorityFactory implements CRSAuthorityFactory,
+            CSAuthorityFactory, DatumAuthorityFactory, CoordinateOperationAuthorityFactory
+    {
+        All(final AuthorityFactory primary, final AuthorityFactory fallback) {
+            super(primary, fallback);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/IdentifiedObjectFinder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/IdentifiedObjectFinder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/IdentifiedObjectFinder.java	(revision 28000)
@@ -0,0 +1,503 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *   
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.factory;
+
+// J2SE dependencies
+import java.util.Set;
+import java.util.Iterator;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+// OpenGIS dependencies
+import org.opengis.util.GenericName;
+import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.AuthorityFactory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+
+// Geotools dependencies
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.util.logging.Logging;
+
+
+/**
+ * Looks up an object from an {@linkplain AuthorityFactory authority factory} which is
+ * {@linkplain CRS#equalsIgnoreMetadata equals, ignoring metadata}, to the specified
+ * object. The main purpose of this class is to get a fully {@linkplain IdentifiedObject
+ * identified object} from an incomplete one, for example from an object without
+ * {@linkplain IdentifiedObject#getIdentifiers identifiers} or "{@code AUTHORITY[...]}"
+ * element in <cite>Well Known Text</cite> terminology.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/IdentifiedObjectFinder.java $
+ * @version $Id: IdentifiedObjectFinder.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux
+ */
+public class IdentifiedObjectFinder {
+    public static final Logger LOGGER = Logging.getLogger("org.geotools.referencing.factory.finder");
+
+    /**
+     * The proxy for object creation.
+     */
+    private AuthorityFactoryProxy proxy;
+
+    /**
+     * {@code true} for performing full scans, or {@code false} otherwise.
+     */
+    private boolean fullScan = true;
+
+    /** Default constructor, subclass should provide an override for getProxy */
+    protected IdentifiedObjectFinder() {        
+    }
+    
+    /**
+     * Creates a finder using the same proxy than the specified finder.
+     */
+    IdentifiedObjectFinder(final IdentifiedObjectFinder finder) {
+        this.setProxy(finder.getProxy());
+    }
+
+    /**
+     * Creates a finder using the specified factory. This constructor is
+     * protected because instances of this class should not be created directly.
+     * Use {@link AbstractAuthorityFactory#getIdentifiedObjectFinder} instead.
+     *
+     * @param factory The factory to scan for the identified objects.
+     * @param type    The type of objects to lookup.
+     */
+    protected IdentifiedObjectFinder(final AuthorityFactory factory,
+                                     final Class/*<? extends IdentifiedObject>*/ type)
+    {
+        setProxy(AuthorityFactoryProxy.getInstance(factory, type));
+    }
+
+    /*
+     * Do NOT provide the following method:
+     *
+     *     public AuthorityFactory getAuthorityFactory() {
+     *         return proxy.getAuthorityFactory();
+     *     }
+     *
+     * because the returned factory may not be the one the user would expect. Some of our
+     * AbstractAuthorityFactory implementations create proxy to the underlying backing
+     * store rather than to the factory on which 'getIdentifiedObjectFinder()' was invoked.
+     */
+
+    /**
+     * @return the proxy
+     */
+    protected AuthorityFactoryProxy getProxy() {
+        return proxy;
+    }
+
+    /**
+     * If {@code true}, an exhaustive full scan against all registered objects
+     * will be performed (may be slow). Otherwise only a fast lookup based on
+     * embedded identifiers and names will be performed. The default value is
+     * {@code true}.
+     */
+    public boolean isFullScanAllowed() {
+        return fullScan;
+    }
+
+    /**
+     * Set whatever an exhaustive scan against all registered objects is allowed.
+     * The default value is {@code true}.
+     */
+    public void setFullScanAllowed(final boolean fullScan) {
+        this.fullScan = fullScan;
+    }
+
+    /**
+     * Lookups an object which is
+     * {@linkplain CRS#equalsIgnoreMetadata equals, ignoring metadata}, to the
+     * specified object. The default implementation tries to instantiate some
+     * {@linkplain IdentifiedObject identified objects} from the authority factory
+     * specified at construction time, in the following order:
+     * <p>
+     * <ul>
+     *   <li>If the specified object contains {@linkplain IdentifiedObject#getIdentifiers
+     *       identifiers} associated to the same authority than the factory, then those
+     *       identifiers are used for {@linkplain AuthorityFactory#createObject creating
+     *       objects} to be tested.</li>
+     *   <li>If the authority factory can create objects from their {@linkplain
+     *       IdentifiedObject#getName name} in addition of identifiers, then the name and
+     *       {@linkplain IdentifiedObject#getAlias aliases} are used for creating objects
+     *       to be tested.</li>
+     *   <li>If {@linkplain #isFullScanAllowed full scan is allowed}, then full
+     *       {@linkplain #getCodeCandidates set of authority codes} are used for
+     *       creating objects to be tested.</li>
+     * </ul>
+     * <p>
+     * The first of the above created objects which is equals to the specified object in the
+     * the sense of {@link CRS#equalsIgnoreMetadata equalsIgnoreMetadata} is returned.
+     *
+     * @param  object The object looked up.
+     * @return The identified object, or {@code null} if not found.
+     * @throws FactoryException if an error occured while creating an object.
+     */
+    public IdentifiedObject find(final IdentifiedObject object) throws FactoryException {
+        /*
+         * First check if one of the identifiers can be used to spot directly an
+         * identified object (and check it's actually equal to one in the factory).
+         */
+        IdentifiedObject candidate = createFromIdentifiers(object);
+        if (candidate != null) {
+            return candidate;
+        }
+        /*
+         * We are unable to find the object from its identifiers. Try a quick name lookup.
+         * Some implementations like the one backed by the EPSG database are capable to find
+         * an object from its name.
+         */
+        candidate = createFromNames(object);
+        if (candidate != null) {
+            return candidate;
+        }
+        /*
+         * Here we exhausted the quick paths. Bail out if the user does not want a full scan.
+         */
+        return fullScan ? createFromCodes(object) : null;
+    }
+
+    /**
+     * Returns the identifier of the specified object, or {@code null} if none. The default
+     * implementation invokes <code>{@linkplain #find find}(object)</code> and extracts the
+     * code from the returned {@linkplain IdentifiedObject identified object}.
+     */
+    public String findIdentifier(final IdentifiedObject object) throws FactoryException {
+        final IdentifiedObject candidate = find(object);
+        return (candidate != null) ? getIdentifier(candidate) : null;
+    }
+    
+    /**
+     * The Authority for this Finder; used during get Identifier. 
+     * @return Citation for the authority being represented.
+     */
+    protected Citation getAuthority(){
+        return getProxy().getAuthorityFactory().getAuthority();
+    }
+    /**
+     * Returns the identifier for the specified object.
+     */
+    final String getIdentifier(final IdentifiedObject object) {
+        Citation authority = getAuthority();
+        if (ReferencingFactory.ALL.equals(authority)) {
+            /*
+             * "All" is a pseudo-authority declared by AllAuthoritiesFactory. This is not a real
+             * authority, so we will not find any identifier if we search for this authority. We
+             * will rather pickup the first identifier, regardless its authority.
+             */
+            authority = null;
+        }
+        ReferenceIdentifier identifier = AbstractIdentifiedObject.getIdentifier(object, authority);
+        if (identifier == null) {
+            identifier = object.getName();
+            // Should never be null past this point, since 'name' is a mandatory attribute.
+        }
+        final String codespace = identifier.getCodeSpace();
+        final String code = identifier.getCode();
+        if (codespace != null) {
+            return codespace + org.geotools.util.GenericName.DEFAULT_SEPARATOR + code;
+        } else {
+            return code;
+        }
+    }
+
+    /**
+     * Creates an object {@linkplain CRS#equalsIgnoreMetadata equals, ignoring metadata}, to the
+     * specified object using only the {@linkplain IdentifiedObject#getIdentifiers identifiers}.
+     * If no such object is found, returns {@code null}.
+     * <p>
+     * This method may be used in order to get a fully identified object from a partially
+     * identified one.
+     * 
+     * @param object The object looked up.
+     * @return The identified object, or {@code null} if not found.
+     * @see #createFromCodes
+     * @see #createFromNames
+     * @throws FactoryException if an error occured while creating an object.
+     */
+    final IdentifiedObject createFromIdentifiers(final IdentifiedObject object) throws FactoryException {
+        final Citation authority = getProxy().getAuthorityFactory().getAuthority();
+        final boolean isAll = ReferencingFactory.ALL.equals(authority);
+        for (final Iterator it=object.getIdentifiers().iterator(); it.hasNext();) {
+            final Identifier id = (Identifier) it.next();
+            if (!isAll && !Citations.identifierMatches(authority, id.getAuthority())) {
+                // The identifier is not for this authority. Looks the other ones.
+                continue;
+            }
+            IdentifiedObject candidate;
+            try {
+                candidate = getProxy().create(id.getCode());
+            } catch (NoSuchAuthorityCodeException e) {
+                // The identifier was not recognized. No problem, let's go on.
+                continue;
+            }
+            candidate = deriveEquivalent(candidate, object);
+            if (candidate != null) {
+                return candidate;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Creates an object {@linkplain CRS#equalsIgnoreMetadata equals, ignoring metadata}, to
+     * the specified object using only the {@linkplain IdentifiedObject#getName name} and
+     * {@linkplain IdentifiedObject#getAlias aliases}. If no such object is found, returns
+     * {@code null}.
+     * <p>
+     * This method may be used with some {@linkplain AuthorityFactory authority factory}
+     * implementations like the one backed by the EPSG database, which are capable to find
+     * an object from its name when the identifier is unknown.
+     * 
+     * @param object The object looked up.
+     * @return The identified object, or {@code null} if not found.
+     * @see #createFromCodes
+     * @see #createFromIdentifiers
+     * @throws FactoryException if an error occured while creating an object.
+     */
+    final IdentifiedObject createFromNames(final IdentifiedObject object) throws FactoryException {
+        IdentifiedObject candidate;
+        try {
+            candidate = getProxy().create(object.getName().getCode());
+            candidate = deriveEquivalent(candidate, object);
+            if (candidate != null) {
+                return candidate;
+            }
+        } catch (FactoryException e) {
+            /*
+             * The identifier was not recognized. No problem, let's go on.
+             * Note: we catch a more generic exception than NoSuchAuthorityCodeException
+             *       because this attempt may fail for various reasons (character string
+             *       not supported by the underlying database for primary key, duplicated
+             *       name found, etc.).
+             */
+        }
+        for (final Iterator it=object.getAlias().iterator(); it.hasNext();) {
+            final GenericName id = (GenericName) it.next();
+            try {
+                candidate = getProxy().create(id.toString());
+            } catch (FactoryException e) {
+                // The name was not recognized. No problem, let's go on.
+                continue;
+            }
+            candidate = deriveEquivalent(candidate, object);
+            if (candidate != null) {
+                return candidate;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Creates an object {@linkplain CRS#equalsIgnoreMetadata equals, ignoring metadata}, to the
+     * specified object. This method scans the {@linkplain #getAuthorityCodes authority codes},
+     * create the objects and returns the first one which is equals to the specified object in
+     * the sense of {@link CRS#equalsIgnoreMetadata equalsIgnoreMetadata}.
+     * <p>
+     * This method may be used in order to get a fully {@linkplain IdentifiedObject identified
+     * object} from an object without {@linkplain IdentifiedObject#getIdentifiers identifiers}.
+     * <p>
+     * Scaning the whole set of authority codes may be slow. Users should try
+     * <code>{@linkplain #createFromIdentifiers createFromIdentifiers}(object)</code> and/or
+     * <code>{@linkplain #createFromNames createFromNames}(object)</code> before to fallback
+     * on this method.
+     *
+     * @param  object The object looked up.
+     * @return The identified object, or {@code null} if not found.
+     * @throws FactoryException if an error occured while scanning through authority codes.
+     *
+     * @see #createFromIdentifiers
+     * @see #createFromNames
+     */
+    final IdentifiedObject createFromCodes(final IdentifiedObject object) throws FactoryException {
+        final Set/*<String>*/ codes = getCodeCandidates(object);
+        for (final Iterator it=codes.iterator(); it.hasNext();) {
+            final String code = (String) it.next();
+            IdentifiedObject candidate;
+            try {
+                candidate = getProxy().create(code);
+            }
+            catch (FactoryException e) {
+                LOGGER.log( Level.FINEST, "Could not create '"+code+"':"+e );
+                // Some object cannot be created properly.
+                continue;
+            }
+            catch (Exception problemCode ){
+                LOGGER.log( Level.FINEST, "Could not create '"+code+"':"+problemCode, problemCode );
+                continue;
+            }
+
+            candidate = deriveEquivalent(candidate, object);
+            if (candidate != null) {
+                return candidate;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns a set of authority codes that <strong>may</strong> identify the same object than
+     * the specified one. The returned set must contains the code of every objects that are
+     * {@linkplain CRS#equalsIgnoreMetadata equals, ignoring metadata}, to the specified one.
+     * However the set is not required to contains only the codes of those objects; it may
+     * conservatively contains the code for more objects if an exact search is too expensive.
+     * <p>
+     * This method is invoked by the default {@link #find find} method implementation. The caller
+     * may iterates through every returned codes, instantiate the objects and compare them with
+     * the specified one in order to determine which codes are really applicable.
+     * <p>
+     * The default implementation returns the same set than
+     * <code>{@linkplain AuthorityFactory#getAuthorityCodes getAuthorityCodes}(type)</code>
+     * where {@code type} is the interface specified at construction type. Subclasses should
+     * override this method in order to return a smaller set, if they can.
+     *
+     * @param  object The object looked up.
+     * @return A set of code candidates.
+     * @throws FactoryException if an error occured while fetching the set of code candidates.
+     */
+    protected Set/*<String>*/ getCodeCandidates(final IdentifiedObject object) throws FactoryException {
+        return getProxy().getAuthorityCodes();
+    }
+
+    /*
+     * Do NOT define the following method in IdentifiedObjectFinder's API:
+     *
+     *     protected IdentifiedObject create(String code) throws FactoryException {
+     *         return proxy.create(code);
+     *     }
+     *
+     * We may be tempted to put such method in order to allow BufferedAuthorityFactory to
+     * override it with caching service,  but it conflicts with AuthorityFactoryAdapter's
+     * work. The later (or to be more accurate, OrderedAxisAuthorityFactory) expects axis
+     * in (latitude,longitude) order first, in order to test this CRS before to switch to
+     * (longitude,latitude) order and test again. If the BufferedAuthorityFactory's cache
+     * is in the way, we get directly (longitude,latitude) order and miss an opportunity
+     * to identify the user's CRS.
+     *
+     * We should invoke directly AuthorityFactoryProxy.create(String) instead.
+     */
+
+    /**
+     * Returns {@code candidate}, or an object derived from {@code candidate}, if it is
+     * {@linkplain CRS#equalsIgnoreMetadata equals ignoring metadata} to the specified
+     * model. Otherwise returns {@code null}.
+     * <p>
+     * This method is overriden by factories that may test many flavors of
+     * {@code candidate}, for example {@link TransformedAuthorityFactory}.
+     *
+     * @param  candidate An object created by the factory specified at construction time.
+     * @return {@code candidate}, or an object derived from {@code candidate} (for example with axis
+     *         order forced to (<var>longitude</var>, <var>latitude</var>), or {@code null} if none
+     *         of the above is {@linkplain CRS#equalsIgnoreMetadata equals ignoring metadata} to the
+     *         specified model.
+     *
+     * @throws FactoryException if an error occured while creating a derived object.
+     */
+    protected IdentifiedObject deriveEquivalent(final IdentifiedObject candidate,
+                                                final IdentifiedObject model)
+            throws FactoryException
+    {
+        return CRS.equalsIgnoreMetadata(candidate, model) ? candidate : null;
+    }
+
+    /**
+     * Returns a string representation of this finder, for debugging purpose only.
+     */
+    @Override
+    public String toString() {
+        return getProxy().toString(IdentifiedObjectFinder.class);
+    }
+
+
+
+
+    /**
+     * @param proxy the proxy to set
+     */
+    public void setProxy( AuthorityFactoryProxy proxy ) {
+        this.proxy = proxy;
+    }
+
+
+
+
+    /**
+     * A finder which delegate part of its work to an other finder. This adapter forwards
+     * some method calls to the underlying finder. This class should not be public, because
+     * not all method are overriden. The choice is tuned for {@link BufferedAuthorityFactory}
+     * and {@link AuthorityFactoryAdapter} needs and may not be appropriate in the general case.
+     *
+     * @author Martin Desruisseaux
+     */
+    static class Adapter extends IdentifiedObjectFinder {
+        /**
+         * The finder on which to delegate the work.
+         */
+        protected final IdentifiedObjectFinder finder;
+
+        /**
+         * Creates an adapter for the specified finder.
+         */
+        protected Adapter(final IdentifiedObjectFinder finder) {
+            super(finder);
+            this.finder = finder;
+        }
+
+        /**
+         * Set whatever an exhaustive scan against all registered objects is allowed.
+         */
+        @Override
+        public void setFullScanAllowed(final boolean fullScan) {
+            finder.setFullScanAllowed(fullScan);
+            super .setFullScanAllowed(fullScan);
+        }
+
+        /**
+         * Returns a set of authority codes that <strong>may</strong> identify the same object
+         * than the specified one. The default implementation delegates to the backing finder.
+         */
+        @Override
+        protected Set/*<String>*/ getCodeCandidates(final IdentifiedObject object) throws FactoryException {
+            return finder.getCodeCandidates(object);
+        }
+
+        /**
+         * Returns {@code candidate}, or an object derived from {@code candidate}, if it is
+         * {@linkplain CRS#equalsIgnoreMetadata equals ignoring metadata} to the specified
+         * model. The default implementation delegates to the backing finder.
+         */
+        @Override
+        protected IdentifiedObject deriveEquivalent(final IdentifiedObject candidate,
+                                                    final IdentifiedObject model)
+                throws FactoryException
+        {
+            return finder.deriveEquivalent(candidate, model);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ManyAuthoritiesFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ManyAuthoritiesFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ManyAuthoritiesFactory.java	(revision 28000)
@@ -0,0 +1,845 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.factory;
+
+import java.util.*;
+
+import org.opengis.referencing.*;
+import org.opengis.referencing.cs.*;
+import org.opengis.referencing.crs.*;
+import org.opengis.referencing.datum.*;
+import org.opengis.referencing.operation.*;
+import org.opengis.util.InternationalString;
+import org.opengis.metadata.citation.Citation;
+
+import org.geotools.factory.Factory;
+import org.geotools.factory.FactoryRegistryException;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.util.GenericName;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.resources.i18n.VocabularyKeys;
+
+
+/**
+ * An authority factory that delegates the object creation to an other factory determined from the
+ * authority name in the code. This factory requires that every codes given to a {@code createFoo}
+ * method are prefixed by the authority name, for example {@code "EPSG:4326"}. This is different
+ * from using a factory from a known authority, in which case the authority part was optional (for
+ * example when using the {@linkplain org.geotools.referencing.factory.epsg EPSG authority factory},
+ * the {@code "EPSG:"} part in {@code "EPSG:4326"} is optional).
+ * <p>
+ * This class parses the authority name and delegates the work the corresponding factory. For
+ * example if any {@code createFoo(...)} method in this class is invoked with a code starting
+ * by {@code "EPSG:"}, then this class delegates the object creation to one of the authority
+ * factories provided to the constructor.
+ * <p>
+ * This class is not registered in {@link ReferencingFactoryFinder}, because it is not a real
+ * authority factory. There is not a single authority name associated to this factory, but rather
+ * a set of names determined from all available authority factories.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/ManyAuthoritiesFactory.java $
+ * @version $Id: ManyAuthoritiesFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class ManyAuthoritiesFactory extends AuthorityFactoryAdapter implements CRSAuthorityFactory,
+        CSAuthorityFactory, DatumAuthorityFactory, CoordinateOperationAuthorityFactory
+{
+    /**
+     * The types to be recognized for the {@code factories} argument in
+     * constructors. Must be consistent with the types expected by the
+     * {@link AllAuthoritiesFactory#fromFactoryRegistry(String, Class)} method.
+     */
+    @SuppressWarnings("unchecked")
+    private static final Class<? extends AuthorityFactory>[] FACTORY_TYPES = new Class[] {
+        CRSAuthorityFactory.class,
+        DatumAuthorityFactory.class,
+        CSAuthorityFactory.class,
+        CoordinateOperationAuthorityFactory.class
+    };
+
+    /**
+     * The types created by {@link #FACTORY_TYPES}. For each type {@code OBJECT_TYPES[i]},
+     * the factory to be used must be {@code FACTORY_TYPES[i]}.
+     */
+    @SuppressWarnings("unchecked")
+    private static final Class<? extends IdentifiedObject>[] OBJECT_TYPES = new Class[] {
+        CoordinateReferenceSystem.class,
+        Datum.class,
+        CoordinateSystem.class,
+        CoordinateOperation.class
+    };
+
+    /**
+     * The set of user-specified factories, or {@code null} if none.
+     * This field should be modified by {@link #setFactories} only.
+     */
+    private Collection<AuthorityFactory> factories;
+
+    /**
+     * Guard against infinite recursivity in {@link #getAuthorityCodes}.
+     */
+    private final ThreadLocal<Boolean> inProgress;
+
+    /**
+     * Creates a new factory using the specified set of user factories. Any call to a
+     * {@code createFoo(code)} method will scan the supplied factories in their iteration
+     * order. The first factory implementing the appropriate interface and having the expected
+     * {@linkplain AuthorityFactory#getAuthority authority name} will be used.
+     * <p>
+     * If the {@code factories} collection contains more than one factory for the same authority
+     * and interface, then all additional factories will be {@linkplain FallbackAuthorityFactory
+     * fallbacks}, to be tried in iteration order only if the first acceptable factory failed to
+     * create the requested object.
+     *
+     * @param factories A set of user-specified factories to try before to delegate
+     *        to {@link GeometryFactoryFinder}.
+     */
+    public ManyAuthoritiesFactory(final Collection<? extends AuthorityFactory> factories) {
+        super(NORMAL_PRIORITY);
+        inProgress = new ThreadLocal<Boolean>();
+        if (factories!=null && !factories.isEmpty()) {
+            for (final AuthorityFactory factory : factories) {
+                if (factory instanceof Factory) {
+                    hints.putAll(((Factory) factory).getImplementationHints());
+                }
+            }
+            this.factories = createFallbacks(factories);
+        }
+    }
+
+    /**
+     * Returns the factories. This method should not be public since it returns directly the
+     * internal instance. This method is to be overriden by {@link AllAuthoritiesFactory} only.
+     */
+    Collection<AuthorityFactory> getFactories() {
+        return factories;
+    }
+
+    /**
+     * If more than one factory is found for the same authority and interface,
+     * then wraps them as a chain of {@link FallbackAuthorityFactory}.
+     */
+    private static Collection<AuthorityFactory> createFallbacks(
+            final Collection<? extends AuthorityFactory> factories)
+    {
+        /*
+         * 'authorities' Will contains the set of all authorities found without duplicate values
+         * in the sense of Citations.identifierMatches(...). 'factoriesByAuthority' will contains
+         * the collection of factories for each authority.
+         */
+        int authorityCount = 0;
+        final Citation[] authorities = new Citation[factories.size()];
+        @SuppressWarnings("unchecked")
+        final List<AuthorityFactory>[] factoriesByAuthority = new List[authorities.length];
+        for (final AuthorityFactory factory : factories) {
+            /*
+             * Check if the authority has already been meet previously. If the authority is found
+             * then 'authorityIndex' is set to its index. Otherwise the new authority is added to
+             * the 'authorities' list.
+             */
+            Citation authority = factory.getAuthority();
+            int authorityIndex;
+            for (authorityIndex=0; authorityIndex<authorityCount; authorityIndex++) {
+                final Citation candidate = authorities[authorityIndex];
+                if (Citations.identifierMatches(candidate, authority)) {
+                    authority = candidate;
+                    break;
+                }
+            }
+            final List<AuthorityFactory> list;
+            if (authorityIndex == authorityCount) {
+                authorities[authorityCount++] = authority;
+                factoriesByAuthority[authorityIndex] = list = new ArrayList<AuthorityFactory>(4);
+            } else {
+                list = factoriesByAuthority[authorityIndex];
+            }
+            if (!list.contains(factory)) {
+                list.add(factory);
+            }
+        }
+        /*
+         * For each authority, chains the factories into a FallbackAuthorityFactory object.
+         */
+        final ArrayList<AuthorityFactory> result = new ArrayList<AuthorityFactory>();
+        final List<AuthorityFactory> buffer = new ArrayList<AuthorityFactory>(4);
+        for (int i=0; i<authorityCount; i++) {
+            final Collection<AuthorityFactory> list = factoriesByAuthority[i];
+            while (!list.isEmpty()) {
+                AuthorityFactory primary = null;
+                boolean needOtherChains = false;
+                for (final Iterator<AuthorityFactory> it=list.iterator(); it.hasNext();) {
+                    final AuthorityFactory fallback = it.next();
+                    if (primary == null) {
+                        primary = fallback;
+                    } else if (!FallbackAuthorityFactory.chainable(primary, fallback)) {
+                        needOtherChains = true;
+                        continue;
+                    }
+                    buffer.add(fallback);
+                    if (!needOtherChains) {
+                        it.remove();
+                    }
+                }
+                result.add(FallbackAuthorityFactory.create(buffer));
+                buffer.clear();
+            }
+        }
+        result.trimToSize();
+        return result;
+    }
+
+    /**
+     * If this factory is a wrapper for the specified factory that do not add any additional
+     * {@linkplain #getAuthorityCodes authority codes}, returns {@code true}. This method is
+     * for {@link FallbackAuthorityFactory} internal use only.
+     */
+    @Override
+    boolean sameAuthorityCodes(final AuthorityFactory factory) {
+        // We don't want to inherit AuthorityFactoryAdapter implementation here.
+        return factory == this;
+    }
+
+    /**
+     * Returns the character separator for the specified code. The default implementation returns
+     * the {@linkplain GenericName#DEFAULT_SEPARATOR default name separator} {@code ':'}, except
+     * if the code looks like a URL (e.g. {@code "http://www.opengis.net/"}), in which case this
+     * method returns {@code '/'}.
+     * <p>
+     * In the current implementation, "looks like a URL" means that the first
+     * non-{@linkplain Character#isLetterOrDigit(char) aplhanumeric} characters
+     * are {@code "://"}. But this heuristic rule may change in future implementations.
+     */
+    protected char getSeparator(String code) {
+        code = code.trim();
+        final int length = code.length();
+        for (int i=0; i<length; i++) {
+            if (!Character.isLetterOrDigit(code.charAt(i))) {
+                if (code.regionMatches(i, "://", 0, 3)) {
+                    return '/';
+                }
+                break;
+            }
+        }
+        return GenericName.DEFAULT_SEPARATOR;
+    }
+
+    /**
+     * Returns {@code true} if the specified code can be splitted in a (<cite>authority</cite>,
+     * <cite>code</cite>) pair at the specified index. The default implementation returns
+     * {@code true} if the first non-whitespace character on the left and right side are
+     * valid Java identifiers.
+     * <p>
+     * The purpose of this method is to avoid considering the {@code "//"} part in
+     * {@code "http://www.opengis.net/gml/srs/epsg.xml"} as separators. In case of
+     * failure to parse the code, this restriction will produce and error message
+     * like "<cite>Unknown <code>http://www.opengis.net</code> authority</cite>"
+     * instead of "<cite>Unknown <code>http:</code> authority</cite>".
+     * <p>
+     * We may consider to turn this method into a protected one if the users need to override it.
+     */
+    private static boolean canSeparateAt(final String code, final int index) {
+        char c;
+        int i = index;
+        do {
+            if (--i < 0) {
+                return false;
+            }
+            c = code.charAt(i);
+        } while (Character.isWhitespace(c));
+        if (!Character.isJavaIdentifierPart(c)) {
+            return false;
+        }
+        final int length = code.length();
+        i = index;
+        do {
+            if (++i >= length) {
+                return false;
+            }
+            c = code.charAt(i);
+        } while (Character.isWhitespace(c));
+        return Character.isJavaIdentifierPart(c);
+    }
+
+    /**
+     * Returns the vendor responsible for creating this factory implementation.
+     * The default implementation returns {@linkplain Citations#GEOTOOLS Geotools}.
+     */
+    @Override
+    public Citation getVendor() {
+        return Citations.GEOTOOLS;
+    }
+
+    /**
+     * Returns the organization or party responsible for definition and maintenance of the
+     * database. The default implementation returns a citation with title "All".
+     */
+    @Override
+    public Citation getAuthority() {
+        return ALL;
+    }
+
+    /**
+     * Returns the authority names of every factories given at construction time.
+     */
+    public Set<String> getAuthorityNames() {
+        final Set<String> names = new HashSet<String>();
+        final Collection<AuthorityFactory> factories = getFactories();
+        if (factories != null) {
+            for (final AuthorityFactory factory : factories) {
+                names.add(Citations.getIdentifier(factory.getAuthority()));
+            }
+        }
+        return names;
+    }
+
+    /**
+     * Returns a description of the underlying backing store, or {@code null} if unknow.
+     *
+     * @throws FactoryException if a failure occured while fetching the engine description.
+     */
+    @Override
+    public String getBackingStoreDescription() throws FactoryException {
+        // We have no authority code, so we can't pick a particular factory.
+        return null;
+    }
+
+    /**
+     * Returns the direct dependencies. Current implementation returns the internal structure
+     * because we know that this package will not modifies it. But if the method become public,
+     * we will need to returns a unmodifiable view.
+     */
+    @Override
+    Collection<? super AuthorityFactory> dependencies() {
+        return getFactories();
+    }
+
+    /**
+     * Returns {@code true} if the specified factory should be excluded from the search.
+     * We exclude adapters around {@link AllAuthoritiesFactory}. This code actually aims
+     * to exclude {@link URN_AuthorityFactory} and similar adapters around all factories,
+     * since it leads to duplicated search and innacurate identifier to be returned by
+     * {@link #findIdentifier}.
+     */
+    private static boolean exclude(final AuthorityFactory factory) {
+        if (ManyAuthoritiesFactory.class.isInstance(factory)) {
+            return true;
+        }
+        if (factory instanceof AuthorityFactoryAdapter) {
+            final AuthorityFactoryAdapter adapter = (AuthorityFactoryAdapter) factory;
+            return exclude(adapter.crsFactory)   ||
+                   exclude(adapter.csFactory)    ||
+                   exclude(adapter.datumFactory) ||
+                   exclude(adapter.operationFactory);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a factory for the specified authority, or {@code null} if none.
+     * To be overriden by {@link AllAuthoritiesFactory} in order to search among
+     * factories registered on a system-wide basis.
+     *
+     * @param  authority The authority to query.
+     * @param  type The interface to be implemented.
+     * @return The factory.
+     * @throws FactoryRegistryException if there is no factory registered for the supplied
+     *         authority and hints.
+     */
+    <T extends AuthorityFactory> T fromFactoryRegistry(final String authority, final Class<T> type)
+            throws FactoryRegistryException
+    {
+        return null;
+    }
+
+    /**
+     * Searchs for a factory of the given type. This method first search in user-supplied
+     * factories. If no user factory is found, then this method request for a factory using
+     * {@link GeometryFactoryFinder}. The authority name is inferred from the specified code.
+     *
+     * @param  type The interface to be implemented.
+     * @param  code The code of the object to create.
+     * @return The factory.
+     * @throws NoSuchAuthorityCodeException if no suitable factory were found.
+     */
+    @Override
+    final <T extends AuthorityFactory> T getAuthorityFactory(final Class<T> type, final String code)
+            throws NoSuchAuthorityCodeException
+    {
+        ensureNonNull("code", code);
+        String authority = null;
+        FactoryRegistryException cause = null;
+        final Collection<AuthorityFactory> factories = getFactories();
+        final char separator = getSeparator(code);
+        for (int split = code.lastIndexOf(separator); split >= 0;
+                 split = code.lastIndexOf(separator, split-1))
+        {
+            if (!canSeparateAt(code, split)) {
+                continue;
+            }
+            /*
+             * Try all possible authority names, begining with the most specific ones.
+             * For example if the code is "urn:ogc:def:crs:EPSG:6.8:4326", then we will
+             * try "urn:ogc:def:crs:EPSG:6.8" first, "urn:ogc:def:crs:EPSG" next, etc.
+             * until a suitable factory is found (searching into user-supplied factories
+             * first).
+             */
+            authority = code.substring(0, split).trim();
+            if (factories != null) {
+                for (final AuthorityFactory factory : factories) {
+                    if (type.isAssignableFrom(factory.getClass())) {
+                        if (Citations.identifierMatches(factory.getAuthority(), authority)) {
+                            return type.cast(factory);
+                        }
+                    }
+                }
+            }
+            /*
+             * No suitable user-supplied factory. Now query FactoryFinder.
+             */
+            final AuthorityFactory factory;
+            try {
+                factory = fromFactoryRegistry(authority, type);
+            } catch (FactoryRegistryException exception) {
+                cause = exception;
+                continue;
+            }
+            if (factory != null) {
+                return type.cast(factory);
+            }
+        }
+        /*
+         * No factory found. Creates an error message from the most global authority name
+         * (for example "urn" if the code was "urn:ogc:def:crs:EPSG:6.8:4326") and the
+         * corresponding cause. Both the authority and cause may be null if the code didn't
+         * had any authority part.
+         */
+        throw noSuchAuthority(code, authority, cause);
+    }
+
+    /**
+     * Formats the exception to be throw when the user asked for a code from an unknown authority.
+     *
+     * @param  code      The code with an unknown authority.
+     * @param  authority The authority, or {@code null} if none.
+     * @param  cause     The cause for the exception to be formatted, or {@code null} if none.
+     * @return The formatted exception to be throw.
+     */
+    private NoSuchAuthorityCodeException noSuchAuthority(final String code, String authority,
+                                                         final FactoryRegistryException cause)
+    {
+        final String message;
+        if (authority == null) {
+            authority = Vocabulary.format(VocabularyKeys.UNKNOW);
+            message   = Errors.format(ErrorKeys.MISSING_AUTHORITY_$1, code);
+        } else {
+            message = Errors.format(ErrorKeys.UNKNOW_AUTHORITY_$1, authority);
+        }
+        final NoSuchAuthorityCodeException exception;
+        exception = new NoSuchAuthorityCodeException(message, authority, code);
+        exception.initCause(cause);
+        return exception;
+    }
+
+    /**
+     * Returns a generic object authority factory for the specified {@code "AUTHORITY:NUMBER"}
+     * code.
+     *
+     * @param  code The code to parse.
+     * @return The authority factory.
+     * @throws NoSuchAuthorityCodeException if no authority name has been found.
+     */
+    @Override
+    protected AuthorityFactory getAuthorityFactory(final String code)
+            throws NoSuchAuthorityCodeException
+    {
+        return getAuthorityFactory(AuthorityFactory.class, code);
+    }
+
+    /**
+     * Returns the datum authority factory for the specified {@code "AUTHORITY:NUMBER"} code.
+     *
+     * @param  code The code to parse.
+     * @return The authority factory.
+     * @throws NoSuchAuthorityCodeException if no authority name has been found.
+     */
+    @Override
+    protected DatumAuthorityFactory getDatumAuthorityFactory(final String code)
+            throws NoSuchAuthorityCodeException
+    {
+        return getAuthorityFactory(DatumAuthorityFactory.class, code);
+    }
+
+    /**
+     * Returns the CS authority factory for the specified {@code "AUTHORITY:NUMBER"} code.
+     *
+     * @param  code The code to parse.
+     * @return The authority factory.
+     * @throws NoSuchAuthorityCodeException if no authority name has been found.
+     */
+    @Override
+    protected CSAuthorityFactory getCSAuthorityFactory(final String code)
+            throws NoSuchAuthorityCodeException
+    {
+        return getAuthorityFactory(CSAuthorityFactory.class, code);
+    }
+
+    /**
+     * Returns the CRS authority factory for the specified {@code "AUTHORITY:NUMBER"} code.
+     *
+     * @param  code The code to parse.
+     * @return The authority factory.
+     * @throws NoSuchAuthorityCodeException if no authority name has been found.
+     */
+    @Override
+    protected CRSAuthorityFactory getCRSAuthorityFactory(final String code)
+            throws NoSuchAuthorityCodeException
+    {
+        return getAuthorityFactory(CRSAuthorityFactory.class, code);
+    }
+
+    /**
+     * Returns the operation authority factory for the specified {@code "AUTHORITY:NUMBER"} code.
+     *
+     * @param  code The code to parse.
+     * @return The authority factory.
+     * @throws NoSuchAuthorityCodeException if no authority name has been found.
+     */
+    @Override
+    protected CoordinateOperationAuthorityFactory getCoordinateOperationAuthorityFactory(final String code)
+            throws NoSuchAuthorityCodeException
+    {
+        return getAuthorityFactory(CoordinateOperationAuthorityFactory.class, code);
+    }
+
+    /**
+     * Returns the set of authority codes of the given type.
+     *
+     * @param  type The spatial reference objects type (may be {@code IdentifiedObject.class}).
+     * @return The set of authority codes for spatial reference objects of the given type.
+     *         If this factory doesn't contains any object of the given type, then this method
+     *         returns an {@linkplain java.util.Collections#EMPTY_SET empty set}.
+     * @throws FactoryException if access to the underlying database failed.
+     */
+    @Override
+    public Set<String> getAuthorityCodes(final Class<? extends IdentifiedObject> type)
+            throws FactoryException
+    {
+        if (Boolean.TRUE.equals(inProgress.get())) {
+            /*
+             * 'getAuthorityCodes' is invoking itself (indirectly). Returns an empty set in order
+             * to avoid infinite recursivity. Note that the end result (the output of the caller)
+             * will usually not be empty.
+             */
+            return Collections.emptySet();
+        }
+        final Set<String> codes = new LinkedHashSet<String>();
+        final Set<AuthorityFactory> done = new HashSet<AuthorityFactory>();
+        done.add(this); // Safety for avoiding recursive calls.
+        try {
+            inProgress.set(Boolean.TRUE);
+            for (String authority : getAuthorityNames()) {
+                authority = authority.trim();
+                final char separator = getSeparator(authority);
+                /*
+                 * Prepares a buffer with the "AUTHORITY:" part in "AUTHORITY:NUMBER".
+                 * We will reuse this buffer in order to prefix the authority name in
+                 * front of every codes.
+                 */
+                final StringBuilder code = new StringBuilder(authority);
+                int codeBase = code.length();
+                if (codeBase != 0 && code.charAt(codeBase - 1) != separator) {
+                    code.append(separator);
+                    codeBase = code.length();
+                }
+                code.append("all");
+                final String dummyCode = code.toString();
+                /*
+                 * Now scan over all factories. We will process a factory only if this particular
+                 * factory has not already been done in a previous iteration (some implementation
+                 * apply to more than one factory).
+                 */
+scanForType:    for (int i=0; i<FACTORY_TYPES.length; i++) {
+                    if (!OBJECT_TYPES[i].isAssignableFrom(type)) {
+                        continue;
+                    }
+                    final Class<? extends AuthorityFactory> factoryType = FACTORY_TYPES[i];
+                    final AuthorityFactory factory;
+                    try {
+                        factory = getAuthorityFactory(factoryType, dummyCode);
+                    } catch (NoSuchAuthorityCodeException e) {
+                        continue;
+                    }
+                    if (!done.add(factory)) {
+                        continue;
+                    }
+                    AuthorityFactory wrapped = factory;
+                    while (wrapped instanceof AuthorityFactoryAdapter) {
+                        final AuthorityFactoryAdapter adapter = (AuthorityFactoryAdapter) wrapped;
+                        try {
+                            wrapped = adapter.getAuthorityFactory(factoryType, dummyCode);
+                        } catch (NoSuchAuthorityCodeException exception) {
+                            /*
+                             * The factory doesn't understand our dummy code. It happen with
+                             * URN_AuthorityFactory, which expect the type ("CRS", etc.) in the URN.
+                             */
+                            continue scanForType;
+                        }
+                        if (!done.add(wrapped)) {
+                            /*
+                             * Avoid the factories that are wrapper around an other factory already
+                             * done. If we don't do that, we will duplicate the whole set of EPSG
+                             * identifiers (more than 3000 codes) for OrderedAuthorityFactory,
+                             * HTTP_AuthorityFactory, URN_AuthorityFactory, etc.
+                             */
+                            continue scanForType;
+                        }
+                    }
+                    for (String candidate : factory.getAuthorityCodes(type)) {
+                        candidate = candidate.trim();
+                        if (candidate.length() < codeBase ||
+                            Character.isLetterOrDigit (candidate.charAt(codeBase-1)) ||
+                           !authority.equalsIgnoreCase(candidate.substring(0, codeBase-1)))
+                        {
+                            // Prepend the authority code if it was not already presents.
+                            code.setLength(codeBase);
+                            code.append(candidate);
+                            candidate = code.toString();
+                        }
+                        codes.add(candidate);
+                    }
+                }
+            }
+        } finally {
+            inProgress.remove();
+        }
+        return codes;
+    }
+
+    /**
+     * Gets a description of the object corresponding to a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return A description of the object, or {@code null} if the object
+     *         corresponding to the specified {@code code} has no description.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the query failed for some other reason.
+     */
+    @Override
+    public InternationalString getDescriptionText(final String code) throws FactoryException {
+        final Set<AuthorityFactory> done = new HashSet<AuthorityFactory>();
+        done.add(this); // Safety for avoiding recursive calls.
+        FactoryException failure = null;
+        for (int type=0; type<FACTORY_TYPES.length; type++) {
+            /*
+             * Try all factories, starting with the CRS factory because it is the only one most
+             * users care about. If the CRS factory doesn't know about the specified object, then
+             * we will try the other factories (datum, CS, ...) before to rethrow the exception.
+             */
+            final AuthorityFactory factory;
+            try {
+                factory = getAuthorityFactory(FACTORY_TYPES[type], code);
+            } catch (NoSuchAuthorityCodeException exception) {
+                if (failure == null) {
+                    failure = exception;
+                }
+                continue;
+            }
+            if (done.add(factory)) try {
+                return factory.getDescriptionText(code);
+            } catch (FactoryException exception) {
+                /*
+                 * Failed to creates an object using the current factory.  We will retain only the
+                 * first exception and discart all other ones, except if the first exceptions were
+                 * due to unknown authority (we will prefer exception due to unknown code instead).
+                 * The first exception is usually thrown by the CRS factory, which is the only
+                 * factory most users care about.
+                 */
+                if (failure==null || failure.getCause() instanceof FactoryRegistryException) {
+                    failure = exception;
+                }
+            }
+        }
+        if (failure == null) {
+            failure = noSuchAuthorityCode(IdentifiedObject.class, code);
+        }
+        throw failure;
+    }
+
+    /**
+     * Returns an arbitrary object from a code.
+     *
+     * @see #createCoordinateReferenceSystem
+     * @see #createDatum
+     * @see #createEllipsoid
+     * @see #createUnit
+     */
+    @Override
+    public IdentifiedObject createObject(final String code) throws FactoryException {
+        final Set<AuthorityFactory> done = new HashSet<AuthorityFactory>();
+        done.add(this); // Safety for avoiding recursive calls.
+        FactoryException failure = null;
+        for (int type=0; type<FACTORY_TYPES.length; type++) {
+            /*
+             * Try all factories, starting with the CRS factory because it is the only one most
+             * users care about. If the CRS factory doesn't know about the specified object, then
+             * we will try the other factories (datum, CS, ...) before to rethrow the exception.
+             */
+            final AuthorityFactory factory;
+            try {
+                factory = getAuthorityFactory(FACTORY_TYPES[type], code);
+            } catch (NoSuchAuthorityCodeException exception) {
+                if (failure == null) {
+                    failure = exception;
+                }
+                continue;
+            }
+            if (done.add(factory)) try {
+                return factory.createObject(code);
+            } catch (FactoryException exception) {
+                /*
+                 * Failed to creates an object using the current factory.  We will retain only the
+                 * first exception and discart all other ones, except if the first exceptions were
+                 * due to unknown authority (we will prefer exception due to unknown code instead).
+                 * The first exception is usually thrown by the CRS factory, which is the only
+                 * factory most users care about.
+                 */
+                if (failure==null || failure.getCause() instanceof FactoryRegistryException) {
+                    failure = exception;
+                }
+            }
+        }
+        if (failure == null) {
+            failure = noSuchAuthorityCode(IdentifiedObject.class, code);
+        }
+        throw failure;
+    }
+
+    /**
+     * Returns a finder which can be used for looking up unidentified objects.
+     * The default implementation delegates the lookups to the underlying factories.
+     */
+    @Override
+    public IdentifiedObjectFinder getIdentifiedObjectFinder(Class<? extends IdentifiedObject> type)
+            throws FactoryException
+    {
+        return new Finder(this, type);
+    }
+
+    /**
+     * A {@link IdentifiedObjectFinder} which tests every factories.
+     */
+    static class Finder extends IdentifiedObjectFinder {
+        /**
+         * Creates a finder for the specified type.
+         */
+        protected Finder(final ManyAuthoritiesFactory factory,
+                         final Class<? extends IdentifiedObject> type)
+        {
+            super(factory, type);
+        }
+
+        /**
+         * Returns the user-supplied factories.
+         */
+        final Collection<AuthorityFactory> getFactories() {
+            return ((ManyAuthoritiesFactory) getProxy().getAuthorityFactory()).getFactories();
+        }
+
+        /**
+         * Returns the next finder in the specified set of factories, or {@code null} if none.
+         */
+        final IdentifiedObjectFinder next(final Iterator<AuthorityFactory> it)
+                throws FactoryException
+        {
+            while (it.hasNext()) {
+                final AuthorityFactory factory = it.next();
+                if (exclude(factory)) {
+                    continue;
+                }
+                if (factory instanceof AbstractAuthorityFactory) {
+                    final IdentifiedObjectFinder finder = ((AbstractAuthorityFactory) factory).
+                            getIdentifiedObjectFinder(getProxy().getType());
+                    if (finder != null) {
+                        finder.setFullScanAllowed(isFullScanAllowed());
+                        return finder;
+                    }
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Lookups for the specified object.
+         */
+        @Override
+        public IdentifiedObject find(final IdentifiedObject object) throws FactoryException {
+            /*
+             * Try to create from the identifier before to scan over every factories,
+             * because the identifier may contains the authority name, in which case
+             * we can pickup directly the right factory instead of trying them all.
+             */
+            IdentifiedObject candidate = createFromIdentifiers(object);
+            if (candidate != null) {
+                return candidate;
+            }
+            final Collection<AuthorityFactory> factories = getFactories();
+            if (factories != null) {
+                IdentifiedObjectFinder finder;
+                final Iterator<AuthorityFactory> it = factories.iterator();
+                while ((finder = next(it)) != null) {
+                    candidate = finder.find(object);
+                    if (candidate != null) {
+                        break;
+                    }
+                }
+            }
+            return candidate;
+        }
+
+        /**
+         * Returns the identifier of the specified object, or {@code null} if none.
+         */
+        @Override
+        public String findIdentifier(final IdentifiedObject object) throws FactoryException {
+            /*
+             * Try to create from the identifier for the same reason than find(IdentifiedObject).
+             * Note that we returns directly the primary name; we don't try to locate a name for
+             * a given authority since the "All" authority do not really exists.
+             */
+            IdentifiedObject candidate = createFromIdentifiers(object);
+            if (candidate != null) {
+                return candidate.getName().toString();
+            }
+            final Collection<AuthorityFactory> factories = getFactories();
+            if (factories != null) {
+                IdentifiedObjectFinder finder;
+                final Iterator<AuthorityFactory> it = factories.iterator();
+                while ((finder = next(it)) != null) {
+                    final String id = finder.findIdentifier(object);
+                    if (id != null) {
+                        return id;
+                    }
+                }
+            }
+            return null;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/OldReferencingObjectCache.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/OldReferencingObjectCache.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/OldReferencingObjectCache.java	(revision 28000)
@@ -0,0 +1,125 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *   
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.factory;
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+
+/**
+ * Caching implementation for ReferencingObjectCache. This instance is used when
+ * actual caching is desired. This is a temporary class.
+ * 
+ * @since 2.4
+ * @version $Id: DefaultReferencingObjectCache.java 25972 2007-06-21 13:38:35Z
+ *          desruisseaux $
+ * @source $URL:
+ *         http://svn.geotools.org/geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/DefaultReferencingObjectCache.java $
+ * @author Cory Horner (Refractions Research)
+ */
+final class OldReferencingObjectCache {
+    /**
+     * The pool of cached objects.
+     * <p>
+     * The following may be seen for a key (String key?):
+     * <ul>
+     * <li>Object (ie a strong reference) usually a referencing object like CoordinateReferenceSystem or Datum</li>
+     * <li>WeakReference used to hold a referencing object (may be cleaned up at any time</li>
+     * </ul>
+     */
+    private final LinkedHashMap pool = new LinkedHashMap(32, 0.75f, true);
+
+    /**
+     * The maximum number of objects to keep by strong reference. If a greater amount of
+     * objects are created, then the strong references for the oldest ones are replaced by
+     * weak references.
+     */
+    private final int maxStrongReferences;
+
+    /**
+     * Creates a new cache which will hold the specified amount of object by strong references.
+     * Any additional object will be help by weak references.
+     */
+    public OldReferencingObjectCache(final int maxStrongReferences) {
+        this.maxStrongReferences = maxStrongReferences;
+    }
+
+    /**
+     * Removes all entries from this map.
+     */
+    public synchronized void clear() {
+        if (pool != null) {
+            pool.clear();
+        }
+    }
+
+    /**
+     * Returns an object from the pool for the specified code. If the object was retained as a
+     * {@linkplain Reference weak reference}, the {@link Reference#get referent} is returned.
+     *
+     * @param key The authority code.
+     *
+     * @todo Consider logging a message here to the finer or finest level.
+     */
+    public Object get(final Object key) {
+        //assert Thread.holdsLock(factory);
+        Object object = pool.get(key);
+        if (object instanceof Reference) {
+            object = ((Reference) object).get();
+        }
+        return object;
+    }
+
+    /**
+     * Put an element in the pool. This method is invoked everytime a {@code createFoo(...)}
+     * method is invoked, even if an object was already in the pool for the given code, for
+     * the following reasons: 1) Replaces weak reference by strong reference (if applicable)
+     * and 2) Alters the linked hash set order, so that this object is declared as the last
+     * one used.
+     *
+     * @param key the authority code.
+     * @param object The referencing object to add in the pool.
+     */
+    public void put(final Object key, final Object object) {
+        //assert Thread.holdsLock(factory);
+        pool.put(key, object);
+        int toReplace = pool.size() - maxStrongReferences;
+        if (toReplace > 0) {
+            for (final Iterator it=pool.entrySet().iterator(); it.hasNext();) {
+                final Map.Entry entry = (Map.Entry) it.next();
+                final Object value = entry.getValue();
+                if (value instanceof Reference) {
+                    if (((Reference) value).get() == null) {
+                        it.remove();
+                    }
+                    continue;
+                }
+                entry.setValue(new WeakReference(value));
+                if (--toReplace == 0) {
+                    break;
+                }
+            }
+        }
+    }
+
+    public Object test( Object key ) {
+        return null;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/PropertyAuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/PropertyAuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/PropertyAuthorityFactory.java	(revision 28000)
@@ -0,0 +1,457 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.factory;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.text.ParseException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.Set;
+
+import org.opengis.metadata.citation.Citation;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.cs.CSAuthorityFactory;
+import org.opengis.referencing.crs.CRSAuthorityFactory;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.datum.DatumAuthorityFactory;
+import org.opengis.util.InternationalString;
+import org.opengis.util.GenericName;
+
+import org.geotools.factory.Hints;
+import org.geotools.referencing.wkt.Symbols;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.util.DerivedSet;
+import org.geotools.util.NameFactory;
+import org.geotools.util.SimpleInternationalString;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * Default implementation for a coordinate reference system authority factory
+ * backed by a property file. This gives some of the benificts of using the
+ * {@linkplain org.geotools.referencing.factory.epsg.DirectEpsgFactory EPSG database backed
+ * authority factory} (for example), in a portable property file.
+ * <p>
+ * This factory doesn't cache any result. Any call to a {@code createFoo} method will trig a new
+ * WKT parsing. For caching, this factory should be wrapped in some buffered factory like
+ * {@link BufferedAuthorityFactory}.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/PropertyAuthorityFactory.java $
+ * @version $Id: PropertyAuthorityFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Jody Garnett
+ * @author Rueben Schulz
+ * @author Martin Desruisseaux
+ */
+public class PropertyAuthorityFactory extends DirectAuthorityFactory
+        implements CRSAuthorityFactory, CSAuthorityFactory, DatumAuthorityFactory
+{
+    /**
+     * The authority for this factory.
+     */
+    private final Citation authority;
+
+    /**
+     * Same as {@link #authority}, but may contains more than one elements in some particular
+     * cases.
+     */
+    private final Citation[] authorities;
+
+    /**
+     * The properties object for our properties file. Keys are the authority
+     * code for a coordinate reference system and the associated value is a
+     * WKT string for the CRS.
+     * <p>
+     * It is technically possible to add or remove elements after they have been
+     * loaded by the constructor. However if such modification are made, then we
+     * should update {@link Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER} accordingly.
+     * It may be an issue since hints are supposed to be immutable after factory
+     * construction. For now, this class do not allow addition of elements.
+     */
+    private final Properties definitions = new Properties();
+
+    /**
+     * An unmodifiable view of the authority keys. This view is always up to date
+     * even if entries are added or removed in the {@linkplain #definitions} map.
+     */
+    @SuppressWarnings("unchecked")
+    private final Set<String> codes = Collections.unmodifiableSet((Set) definitions.keySet());
+
+    /**
+     * Views of {@link #codes} for different types. Views will be constructed only when first
+     * needed. View are always up to date even if entries are added or removed in the
+     * {@linkplain #definitions} map.
+     */
+    private transient Map<Class<? extends IdentifiedObject>, Set<String>> filteredCodes;
+
+    /**
+     * A WKT parser.
+     */
+    private transient Parser parser;
+
+    /**
+     * Creates a factory for the specified authorities from the specified file. More than
+     * one authority may be specified when the CRS to create should have more than one
+     * {@linkplain CoordinateReferenceSystem#getIdentifiers identifier}, each with the same
+     * code but different namespace. For example a
+     * {@linkplain org.geotools.referencing.factory.epsg.EsriExtension factory for CRS defined
+     * by ESRI} uses the {@code "ESRI"} namespace, but also the {@code "EPSG"} namespace
+     * because those CRS are used as extension of the EPSG database. Concequently, the same
+     * CRS can be identified as {@code "ESRI:53001"} and {@code "EPSG:53001"}, where
+     * {@code "53001"} is a unused code in the official EPSG database.
+     *
+     * @param  factories   The underlying factories used for objects creation.
+     * @param  authorities The organizations or party responsible for definition
+     *                     and maintenance of the database.
+     * @param  definitions URL to the definition file.
+     * @throws IOException if the definitions can't be read.
+     *
+     * @since 2.4
+     */
+    public PropertyAuthorityFactory(final ReferencingFactoryContainer factories,
+                                    final Citation[]                  authorities,
+                                    final URL                         definitions)
+            throws IOException
+    {
+        super(factories, MINIMUM_PRIORITY + 10);
+        // The following hints have no effect on this class behaviour,
+        // but tell to the user what this factory do about axis order.
+
+        // TODO: Following line should not be commented-out.
+        // See http://jira.codehaus.org/browse/GEOT-1699
+//      hints.put(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.FALSE);
+        hints.put(Hints.FORCE_STANDARD_AXIS_DIRECTIONS,   Boolean.FALSE);
+        hints.put(Hints.FORCE_STANDARD_AXIS_UNITS,        Boolean.FALSE);
+        ensureNonNull("authorities", authorities);
+        if (authorities.length == 0) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.EMPTY_ARRAY));
+        }
+        this.authorities = authorities.clone();
+        authority = authorities[0];
+        ensureNonNull("authority", authority);
+        final InputStream in = definitions.openStream();
+        this.definitions.load(in);
+        in.close();
+        /*
+         * If the WKT do not contains any AXIS[...] element, then every CRS will be created with
+         * the default (longitude,latitude) axis order. In such case this factory is insensitive
+         * to the FORCE_LONGITUDE_FIRST_AXIS_ORDER hint (i.e. every CRS to be created by this
+         * instance are invariant under the above-cited hint value) and we can remove it from
+         * the hint map. Removing this hint allow the CRS.decode(..., true) convenience method
+         * to find this factory (GEOT-1175).
+         */
+        final Symbols s = Symbols.DEFAULT;
+        for (final Object wkt : this.definitions.values()) {
+            if (s.containsAxis((String) wkt)) {
+                LOGGER.warning("Axis elements found in a wkt definition, the force longitude " +
+                        "first axis order hint might not be respected:\n" + wkt);
+                return;
+            }
+        }
+        hints.remove(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER);
+    }
+
+    /**
+     * Returns the organization or party responsible for definition and maintenance of the
+     * database.
+     */
+    public Citation getAuthority() {
+        return authority;
+    }
+
+    /**
+     * Returns the set of authority codes of the given type. The type
+     * argument specify the base class. For example if this factory is
+     * an instance of CRSAuthorityFactory, then:
+     * <p>
+     * <ul>
+     *  <li>{@code CoordinateReferenceSystem.class} asks for all authority codes accepted by
+     *      {@link #createGeographicCRS createGeographicCRS},
+     *      {@link #createProjectedCRS  createProjectedCRS},
+     *      {@link #createVerticalCRS   createVerticalCRS},
+     *      {@link #createTemporalCRS   createTemporalCRS}
+     *      and their friends.</li>
+     *  <li>{@code ProjectedCRS.class} asks only for authority codes accepted by
+     *      {@link #createProjectedCRS createProjectedCRS}.</li>
+     * </ul>
+     *
+     * The default implementaiton filters the set of codes based on the
+     * {@code "PROJCS"} and {@code "GEOGCS"} at the start of the WKT strings.
+     *
+     * @param  type The spatial reference objects type (may be {@code Object.class}).
+     * @return The set of authority codes for spatial reference objects of the given type.
+     *         If this factory doesn't contains any object of the given type, then this method
+     *         returns an empty set.
+     * @throws FactoryException if access to the underlying database failed.
+     */
+    public Set<String> getAuthorityCodes(final Class<? extends IdentifiedObject> type)
+            throws FactoryException
+    {
+        if (type==null || type.isAssignableFrom(IdentifiedObject.class)) {
+            return codes;
+        }
+        if (filteredCodes == null) {
+            filteredCodes = new HashMap<Class<? extends IdentifiedObject>, Set<String>>();
+        }
+        synchronized (filteredCodes) {
+            Set<String> filtered = filteredCodes.get(type);
+            if (filtered == null) {
+                @SuppressWarnings("unchecked")
+                final Map<String,String> map = (Map) definitions;
+                filtered = new Codes(map, type);
+                filteredCodes.put(type, filtered);
+            }
+            return filtered;
+        }
+    }
+
+    /**
+     * The set of codes for a specific type of CRS. This set filter the codes set in the
+     * enclosing {@link PropertyAuthorityFactory} in order to keep only the codes for the
+     * specified type. Filtering is performed on the fly. Consequently, this set is cheap
+     * if the user just want to check for the existence of a particular code.
+     */
+    private static final class Codes extends DerivedSet<String, String> {
+        /**
+         * For cross-version compatibility.
+         */
+        private static final long serialVersionUID = 2681905294171687900L;
+
+        /**
+         * The spatial reference objects type.
+         */
+        private final Class<? extends IdentifiedObject> type;
+
+        /**
+         * The reference to {@link PropertyAuthorityFactory#definitions}.
+         */
+        private final Map<String,String> definitions;
+
+        /**
+         * Constructs a set of codes for the specified type.
+         */
+        public Codes(final Map<String,String> definitions,
+                     final Class<? extends IdentifiedObject> type)
+        {
+            super(definitions.keySet(), String.class);
+            this.definitions = definitions;
+            this.type = type;
+        }
+
+        /**
+         * Returns the code if the associated key is of the expected type, or {@code null}
+         * otherwise.
+         */
+        protected String baseToDerived(final String key) {
+            final String wkt = definitions.get(key);
+            final int length = wkt.length();
+            int i=0; while (i<length && Character.isJavaIdentifierPart(wkt.charAt(i))) i++;
+            Class<?> candidate = Parser.getClassOf(wkt.substring(0,i));
+            if (candidate == null) {
+                candidate = IdentifiedObject.class;
+            }
+            return type.isAssignableFrom(candidate) ? key : null;
+        }
+
+        /**
+         * Transforms a value in this set to a value in the base set.
+         */
+        protected String derivedToBase(final String element) {
+            return element;
+        }
+    }
+
+    /**
+     * Returns the Well Know Text from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The Well Know Text (WKT) for the specified code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     */
+    public String getWKT(final String code) throws NoSuchAuthorityCodeException {
+        ensureNonNull("code", code);
+        final String wkt = definitions.getProperty(trimAuthority(code));
+        if (wkt == null) {
+            throw noSuchAuthorityCode(IdentifiedObject.class, code);
+        }
+        return wkt.trim();
+    }
+
+    /**
+     * Gets a description of the object corresponding to a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return A description of the object, or {@code null} if the object
+     *         corresponding to the specified {@code code} has no description.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the query failed for some other reason.
+     */
+    public InternationalString getDescriptionText(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final String wkt = getWKT(code);
+        int start = wkt.indexOf('"');
+        if (start >= 0) {
+            final int end = wkt.indexOf('"', ++start);
+            if (end >= 0) {
+                return new SimpleInternationalString(wkt.substring(start, end).trim());
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the parser.
+     */
+    private Parser getParser() {
+        if (parser == null) {
+            parser = new Parser();
+        }
+        return parser;
+    }
+
+    /**
+     * Returns an arbitrary object from a code. If the object type is know at compile time, it is
+     * recommended to invoke the most precise method instead of this one.
+     *
+     * @param  code Value allocated by authority.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    @Override
+    public IdentifiedObject createObject(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final String wkt = getWKT(code);
+        final Parser parser = getParser();
+        try {
+            synchronized (parser) {
+                parser.code = code;
+                return (IdentifiedObject) parser.parseObject(wkt);
+            }
+        } catch (ParseException exception) {
+            throw new FactoryException(exception);
+        }
+    }
+
+    /**
+     * Returns a coordinate reference system from a code. If the object type is know at compile
+     * time, it is recommended to invoke the most precise method instead of this one.
+     *
+     * @param  code Value allocated by authority.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    @Override
+    public CoordinateReferenceSystem createCoordinateReferenceSystem(final String code)
+            throws NoSuchAuthorityCodeException, FactoryException
+    {
+        final String wkt = getWKT(code);
+        final Parser parser = getParser();
+        try {
+            synchronized (parser) {
+                parser.code = code;
+                // parseCoordinateReferenceSystem provides a slightly faster path than parseObject.
+                return parser.parseCoordinateReferenceSystem(wkt);
+            }
+        } catch (ParseException exception) {
+            throw new FactoryException(exception);
+        }
+    }
+
+    /**
+     * Trims the authority scope, if present. If more than one authority were given at
+     * {@linkplain #PropertyAuthorityFactory(ReferencingFactoryContainer, Citation[], URL)
+     * construction time}, then any of them may appears as the scope in the supplied code.
+     *
+     * @param  code The code to trim.
+     * @return The code without the authority scope.
+     */
+    @Override
+    protected String trimAuthority(String code) {
+        code = code.trim();
+        final GenericName name  = NameFactory.create(code);
+        final GenericName scope = name.scope().name();
+        if (scope == null) {
+            return code;
+        }
+        final String candidate = scope.toString();
+        for (int i=0; i<authorities.length; i++) {
+            if (Citations.identifierMatches(authorities[i], candidate)) {
+                return name.tip().toString().trim();
+            }
+        }
+        return code;
+    }
+
+    /**
+     * The WKT parser for this authority factory. This parser add automatically the authority
+     * code if it was not explicitly specified in the WKT.
+     */
+    private final class Parser extends org.geotools.referencing.wkt.Parser {
+        /**
+         * For cross-version compatibility.
+         */
+        @SuppressWarnings("unused")
+		private static final long serialVersionUID = -5910561042299146066L;
+
+        /**
+         * The authority code for the WKT to be parsed.
+         */
+        String code;
+
+        /**
+         * Creates the parser.
+         */
+        public Parser() {
+            super(Symbols.DEFAULT, factories);
+        }
+
+        /**
+         * Add the authority code to the specified properties, if not already present.
+         */
+        @Override
+        protected Map<String,Object> alterProperties(Map<String,Object> properties) {
+            Object candidate = properties.get(IdentifiedObject.IDENTIFIERS_KEY);
+            if (candidate == null && code != null) {
+                properties = new HashMap<String,Object>(properties);
+                code = trimAuthority(code);
+                final Object identifiers;
+                if (authorities.length <= 1) {
+                    identifiers = new NamedIdentifier(authority, code);
+                } else {
+                    final NamedIdentifier[] ids = new NamedIdentifier[authorities.length];
+                    for (int i=0; i<ids.length; i++) {
+                        ids[i] = new NamedIdentifier(authorities[i], code);
+                    }
+                    identifiers = ids;
+                }
+                properties.put(IdentifiedObject.IDENTIFIERS_KEY, identifiers);
+            }
+            return super.alterProperties(properties);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ReferencingFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ReferencingFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ReferencingFactory.java	(revision 28000)
@@ -0,0 +1,140 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.logging.Logger;
+
+import org.opengis.metadata.citation.Citation;
+import org.opengis.parameter.InvalidParameterValueException;
+import org.opengis.referencing.AuthorityFactory;
+import org.opengis.referencing.Factory;
+
+import org.geotools.factory.AbstractFactory;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.metadata.iso.citation.CitationImpl;
+import org.geotools.util.logging.Logging;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.resources.i18n.VocabularyKeys;
+
+
+/**
+ * Base class for all factories in the referencing module.
+ * Factories can be grouped in two categories:
+ *
+ * <ul>
+ *   <li><p>{@linkplain org.opengis.referencing.AuthorityFactory Authority factories}
+ *       creates objects from a compact string defined by an authority.
+ *   <br><em>These classes are working as "builders": they hold the definition or recipies
+ *       used to construct an objet.</em></p></li>
+ *
+ *   <li><p>{@linkplain org.opengis.referencing.ObjectFactory Object factories}
+ *       allows applications to make objects that cannot be created by an authority factory.
+ *       This factory is very flexible, whereas the authority factory is easier to use.
+ *   <br><em>These classes are working as "Factories": they provide a series of
+ *       {@code create} methods that can be used like a constructor.</em></p></li>
+ * </ul>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/ReferencingFactory.java $
+ * @version $Id: ReferencingFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class ReferencingFactory extends AbstractFactory implements Factory {
+    /**
+     * The logger for event related to Geotools's factories.
+     */
+    public static final Logger LOGGER = Logging.getLogger("org.geotools.referencing.factory");
+
+    /**
+     * A citation which contains only the title "All" in localized language. Used
+     * as a pseudoèauthority name for {@link AllAuthoritiesFactory}. Declared here
+     * because processed specially by {@link IdentifiedObjectFinder}, since it is
+     * not a valid authority name (not declared in {@link AllAuthoritiesFactory}
+     * because we want to avoid this dependency in {@link IdentifiedObjectFinder}).
+     */
+    static final Citation ALL;
+    static {
+        final CitationImpl citation = new CitationImpl(Vocabulary.format(VocabularyKeys.ALL));
+        citation.freeze();
+        ALL = citation;
+    }
+
+    /**
+     * Constructs a factory with the default priority.
+     */
+    protected ReferencingFactory() {
+        super();
+    }
+
+    /**
+     * Constructs a factory with the specified priority.
+     *
+     * @param priority The priority for this factory, as a number between
+     *        {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
+     *        {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
+     */
+    protected ReferencingFactory(final int priority) {
+        super(priority);
+    }
+
+    /**
+     * Returns the vendor responsible for creating this factory implementation. Many implementations
+     * may be available for the same factory interface. The default implementation returns
+     * {@linkplain Citations#GEOTOOLS Geotools}.
+     *
+     * @return The vendor for this factory implementation.
+     */
+    public Citation getVendor() {
+        return Citations.GEOTOOLS;
+    }
+
+    /**
+     * Makes sure that an argument is non-null. This is a
+     * convenience method for subclass methods.
+     *
+     * @param  name   Argument name.
+     * @param  object User argument.
+     * @throws InvalidParameterValueException if {@code object} is null.
+     */
+    protected static void ensureNonNull(final String name, final Object object)
+        throws InvalidParameterValueException
+    {
+        if (object == null) {
+            throw new InvalidParameterValueException(Errors.format(
+                        ErrorKeys.NULL_ARGUMENT_$1, name), name, object);
+        }
+    }
+
+    /**
+     * Returns the direct {@linkplain Factory factory} dependencies, which may be {@code null}.
+     * This method should not returns indirect dependencies. Elements should be instance of
+     * {@link Factory} or {@link FactoryException} if a particular dependency can't be obtained.
+     * <p>
+     * The default implementation always returns an empty set.
+     */
+    Collection<? super AuthorityFactory> dependencies() {
+        return Collections.emptySet();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ReferencingFactoryContainer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ReferencingFactoryContainer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ReferencingFactoryContainer.java	(revision 28000)
@@ -0,0 +1,454 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.factory;
+
+import java.awt.RenderingHints;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.geotools.factory.Factory;
+import org.geotools.factory.FactoryCreator;
+import org.geotools.factory.FactoryRegistry;
+import org.geotools.factory.GeoTools;
+import org.geotools.factory.Hints;
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.ReferencingFactoryFinder;
+import org.geotools.referencing.crs.DefaultCompoundCRS;
+import org.geotools.referencing.cs.AbstractCS;
+import org.geotools.referencing.operation.DefiningConversion;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.crs.CRSFactory;
+import org.opengis.referencing.crs.CompoundCRS;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.crs.SingleCRS;
+import org.opengis.referencing.crs.VerticalCRS;
+import org.opengis.referencing.cs.CSFactory;
+import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.referencing.cs.EllipsoidalCS;
+import org.opengis.referencing.datum.Datum;
+import org.opengis.referencing.datum.DatumFactory;
+import org.opengis.referencing.datum.VerticalDatumType;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.referencing.operation.Matrix;
+
+
+/**
+ * A set of utilities methods working on factories. Many of those methods requires more than
+ * one factory. Consequently, they can't be a method in a single factory. Furthermore, since
+ * they are helper methods and somewhat implementation-dependent, they are not part of GeoAPI.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/ReferencingFactoryContainer.java $
+ * @version $Id: ReferencingFactoryContainer.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class ReferencingFactoryContainer extends ReferencingFactory {
+    /**
+     * A factory registry used as a cache for factory groups created up to date.
+     */
+    private static FactoryRegistry cache;
+
+    /**
+     * The {@linkplain Datum datum} factory.
+     * If null, then a default factory will be created only when first needed.
+     */
+    private DatumFactory datumFactory;
+
+    /**
+     * The {@linkplain CoordinateSystem coordinate system} factory.
+     * If null, then a default factory will be created only when first needed.
+     */
+    private CSFactory csFactory;
+
+    /**
+     * The {@linkplain CoordinateReferenceSystem coordinate reference system} factory.
+     * If null, then a default factory will be created only when first needed.
+     */
+    private CRSFactory crsFactory;
+
+    /**
+     * The {@linkplain MathTransform math transform} factory.
+     * If null, then a default factory will be created only when first needed.
+     */
+    private MathTransformFactory mtFactory;
+
+    // WARNING: Do NOT put a CoordinateOperationFactory field in this class. We tried that in
+    // Geotools 2.2, and removed it in Geotools 2.3 because it leads to very tricky recursivity
+    // problems when we try to initialize it with FactoryFinder.getCoordinateOperationFactory.
+    // The Datum, CS, CRS and MathTransform factories above are standalone, while the Geotools
+    // implementation of CoordinateOperationFactory has complex dependencies with all of those,
+    // and even with authority factories.
+
+    /**
+     * Creates an instance from the specified hints. This constructor recognizes the
+     * {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS}, {@link Hints#DATUM_FACTORY DATUM}
+     * and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM} {@code FACTORY} hints.
+     * <p>
+     * This constructor is public mainly for {@link org.geotools.factory.FactoryCreator} usage.
+     * Consider invoking <code>{@linkplain #createInstance createInstance}(userHints)</code> instead.
+     *
+     * @param userHints The hints, or {@code null} if none.
+     */
+    public ReferencingFactoryContainer(final Hints userHints) {
+        final Hints reduced = new Hints(userHints);
+        /*
+         * If hints are provided, we will fetch factory immediately (instead of storing the hints
+         * in an inner field) because most factories will retain few hints, while the Hints map
+         * may contains big objects. If no hints were provided, we will construct factories only
+         * when first needed.
+         */
+        datumFactory =         (DatumFactory) extract(reduced, Hints.DATUM_FACTORY);
+        csFactory    =            (CSFactory) extract(reduced, Hints.CS_FACTORY);
+        crsFactory   =           (CRSFactory) extract(reduced, Hints.CRS_FACTORY);
+        mtFactory    = (MathTransformFactory) extract(reduced, Hints.MATH_TRANSFORM_FACTORY);
+        /*
+         * Checks if we still have some hints that need to be taken in account. Since we can't guess
+         * which hints are relevant and which ones are not, we have to create all factories now.
+         */
+        if (!reduced.isEmpty()) {
+            setHintsInto(reduced);
+            addImplementationHints(reduced);
+            initialize();
+            hints.clear();
+        }
+    }
+
+    /**
+     * Returns the factory for the specified hint, or {@code null} if the hint is not a factory
+     * instance. It could be for example a {@link Class}.
+     */
+    private static Factory extract(final Map<?,?> reduced, final Hints.Key key) {
+        if (reduced != null) {
+            final Object candidate = reduced.get(key);
+            if (candidate instanceof Factory) {
+                reduced.remove(key);
+                return (Factory) candidate;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Creates an instance from the specified hints. This method recognizes the
+     * {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS}, {@link Hints#DATUM_FACTORY DATUM}
+     * and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM} {@code FACTORY} hints.
+     *
+     * @param  hints The hints, or {@code null} if none.
+     * @return A factory group created from the specified set of hints.
+     */
+    public static ReferencingFactoryContainer instance(final Hints hints) {
+        final Hints completed = GeoTools.getDefaultHints();
+        if (hints != null) {
+            completed.add(hints);
+        }
+        /*
+         * Use the same synchronization lock than ReferencingFactoryFinder (instead of this class)
+         * in order to reduce the risk of dead lock. This is because ReferencingFactoryContainer
+         * creation may queries ReferencingFactoryFinder, and some implementations managed by
+         * ReferencingFactoryFinder may ask for a ReferencingFactoryContainer in turn.
+         */
+        synchronized (ReferencingFactoryFinder.class) {
+            if (cache == null) {
+                cache = new FactoryCreator(Arrays.asList(new Class<?>[] {
+                        ReferencingFactoryContainer.class
+                }));
+                cache.registerServiceProvider(new ReferencingFactoryContainer(null),
+                        ReferencingFactoryContainer.class);
+            }
+            return cache.getServiceProvider(ReferencingFactoryContainer.class, null, completed, null);
+        }
+    }
+
+    /**
+     * Forces the initialisation of all factories. Implementation note: we try to create the
+     * factories in typical dependency order (CRS all because it has the greatest chances to
+     * depends on other factories).
+     */
+    private void initialize() {
+        mtFactory    = getMathTransformFactory();
+        datumFactory = getDatumFactory();
+        csFactory    = getCSFactory();
+        crsFactory   = getCRSFactory();
+    }
+
+    /**
+     * Put all factories available in this group into the specified map of hints.
+     */
+    private void setHintsInto(final Map<? super RenderingHints.Key, Object> hints) {
+        if (  crsFactory != null) hints.put(Hints.           CRS_FACTORY,   crsFactory);
+        if (   csFactory != null) hints.put(Hints.            CS_FACTORY,    csFactory);
+        if (datumFactory != null) hints.put(Hints.         DATUM_FACTORY, datumFactory);
+        if (   mtFactory != null) hints.put(Hints.MATH_TRANSFORM_FACTORY,    mtFactory);
+    }
+
+    /**
+     * Returns all factories in this group. The returned map contains values for the
+     * {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS}, {@link Hints#DATUM_FACTORY DATUM}
+     * and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM} {@code FACTORY} hints.
+     */
+    @Override
+    public Map<RenderingHints.Key, ?> getImplementationHints() {
+        synchronized (hints) {
+            if (hints.isEmpty()) {
+                initialize();
+                setHintsInto(hints);
+            }
+        }
+        return super.getImplementationHints();
+    }
+
+    /**
+     * Returns the hints to be used for lazy creation of <em>default</em> factories in various
+     * {@code getFoo} methods. This is different from {@link #getImplementationHints} because
+     * the later may returns non-default factories.
+     */
+    private Hints hints() {
+        final Hints completed = new Hints(hints);
+        setHintsInto(completed);
+        return completed;
+    }
+
+    /**
+     * Returns the {@linkplain Datum datum} factory.
+     *
+     * @return The Datum factory.
+     */
+    public DatumFactory getDatumFactory() {
+        if (datumFactory == null) {
+            synchronized (hints) {
+                datumFactory = ReferencingFactoryFinder.getDatumFactory(hints());
+            }
+        }
+        return datumFactory;
+    }
+
+    /**
+     * Returns the {@linkplain CoordinateSystem coordinate system} factory.
+     *
+     * @return The Coordinate System factory.
+     */
+    public CSFactory getCSFactory() {
+        if (csFactory == null) {
+            synchronized (hints) {
+                csFactory = ReferencingFactoryFinder.getCSFactory(hints());
+            }
+        }
+        return csFactory;
+    }
+
+    /**
+     * Returns the {@linkplain CoordinateReferenceSystem coordinate reference system} factory.
+     *
+     * @return The Coordinate Reference System factory.
+     */
+    public CRSFactory getCRSFactory() {
+        if (crsFactory == null) {
+            synchronized (hints) {
+                crsFactory = ReferencingFactoryFinder.getCRSFactory(hints());
+            }
+        }
+        return crsFactory;
+    }
+
+    /**
+     * Returns the {@linkplain MathTransform math transform} factory.
+     *
+     * @return The Math Transform factory.
+     */
+    public MathTransformFactory getMathTransformFactory() {
+        if (mtFactory == null) {
+            synchronized (hints) {
+                mtFactory = ReferencingFactoryFinder.getMathTransformFactory(hints());
+            }
+        }
+        return mtFactory;
+    }
+
+    /**
+     * Converts a 2D&nbsp;+&nbsp;1D compound CRS into a 3D CRS, if possible. More specifically,
+     * if the specified {@linkplain CompoundCRS compound CRS} is made of a
+     * {@linkplain GeographicCRS geographic} (or {@linkplain ProjectedCRS projected}) and a
+     * {@linkplain VerticalCRS vertical} CRS, and if the vertical CRS datum type is
+     * {@linkplain VerticalDatumType#ELLIPSOIDAL height above the ellipsoid}, then this method
+     * converts the compound CRS in a single 3D CRS. Otherwise, the {@code crs} argument is
+     * returned unchanged.
+     *
+     * @param  crs The compound CRS to converts in a 3D geographic or projected CRS.
+     * @return The 3D geographic or projected CRS, or {@code crs} if the change can't be applied.
+     * @throws FactoryException if the object creation failed.
+     */
+    public CoordinateReferenceSystem toGeodetic3D(final CompoundCRS crs) throws FactoryException {
+        List<SingleCRS> components = DefaultCompoundCRS.getSingleCRS(crs);
+        final int count = components.size();
+        SingleCRS   horizontal = null;
+        VerticalCRS vertical   = null;
+        int hi=0, vi=0;
+        for (int i=0; i<count; i++) {
+            final SingleCRS candidate = components.get(i);
+            if (candidate instanceof VerticalCRS) {
+                if (vertical == null) {
+                    vertical = (VerticalCRS) candidate;
+                    if (VerticalDatumType.ELLIPSOIDAL.equals(
+                            vertical.getDatum().getVerticalDatumType()))
+                    {
+                        vi = i;
+                        continue;
+                    }
+                }
+                return crs;
+            }
+            if (candidate instanceof GeographicCRS || candidate instanceof  ProjectedCRS) {
+                if (horizontal == null) {
+                    horizontal = candidate;
+                    if (horizontal.getCoordinateSystem().getDimension() == 2) {
+                        hi = i;
+                        continue;
+                    }
+                }
+                return crs;
+            }
+        }
+        if (horizontal != null && vertical != null && Math.abs(vi-hi) == 1) {
+            /*
+             * Exactly one horizontal and one vertical CRS has been found, and those two CRS are
+             * consecutives. Constructs the new 3D CS. If the two above-cited components are the
+             * only ones, the result is returned directly. Otherwise, a new compound CRS is created.
+             */
+            final boolean xyFirst = (hi < vi);
+            final SingleCRS single =
+                    toGeodetic3D(count == 2 ? crs : null, horizontal, vertical, xyFirst);
+            if (count == 2) {
+                return single;
+            }
+            final int i = xyFirst ? hi : vi;
+            components = new ArrayList<SingleCRS>(components);
+            components.remove(i);
+            components.set(i, single);
+            final SingleCRS[] c = components.toArray(new SingleCRS[components.size()]);
+            return crsFactory.createCompoundCRS(AbstractIdentifiedObject.getProperties(crs), c);
+        }
+        return crs;
+    }
+
+    /**
+     * Implementation of {@link #toGeodetic3D(CompoundCRS)} invoked after the horizontal and
+     * vertical parts have been identified. This method may invokes itself recursively if the
+     * horizontal CRS is a derived one.
+     *
+     * @param  crs        The compound CRS to converts in a 3D geographic CRS, or {@code null}.
+     *                    Used only in order to infer the name properties of objects to create.
+     * @param  horizontal The horizontal component of {@code crs}.
+     * @param  vertical   The vertical   component of {@code crs}.
+     * @param  xyFirst    {@code true} if the horizontal component appears before the vertical
+     *                    component, or {@code false} for the converse.
+     * @return The 3D geographic or projected CRS.
+     * @throws FactoryException if the object creation failed.
+     */
+    private SingleCRS toGeodetic3D(final CompoundCRS crs, final SingleCRS horizontal,
+                                   final VerticalCRS vertical, final boolean xyFirst)
+            throws FactoryException
+    {
+        /*
+         * Creates the set of axis in an order which depends of the xyFirst argument.
+         * Then creates the property maps to be given to the object to be created.
+         * They are common to whatever CRS type this method will create.
+         */
+        final CoordinateSystemAxis[] axis = new CoordinateSystemAxis[3];
+        final CoordinateSystem cs = horizontal.getCoordinateSystem();
+        axis[xyFirst ? 0 : 1] = cs.getAxis(0);
+        axis[xyFirst ? 1 : 2] = cs.getAxis(1);
+        axis[xyFirst ? 2 : 0] = vertical.getCoordinateSystem().getAxis(0);
+        final Map<String,?> csName, crsName;
+        if (crs != null) {
+            csName  = AbstractIdentifiedObject.getProperties(crs.getCoordinateSystem());
+            crsName = AbstractIdentifiedObject.getProperties(crs);
+        } else {
+            csName  = getTemporaryName(cs);
+            crsName = getTemporaryName(horizontal);
+        }
+        final  CSFactory  csFactory = getCSFactory();
+        final CRSFactory crsFactory = getCRSFactory();
+        if (horizontal instanceof GeographicCRS) {
+            /*
+             * Merges a 2D geographic CRS with the vertical CRS. This is the easiest
+             * part - we just give the 3 axis all together to a new GeographicCRS.
+             */
+            final GeographicCRS sourceCRS = (GeographicCRS) horizontal;
+            final EllipsoidalCS targetCS  = csFactory.createEllipsoidalCS(csName, axis[0], axis[1], axis[2]);
+            return crsFactory.createGeographicCRS(crsName, sourceCRS.getDatum(), targetCS);
+        }
+        if (horizontal instanceof ProjectedCRS) {
+            /*
+             * Merges a 2D projected CRS with the vertical CRS. This part is more tricky,
+             * since we need a defining conversion which does not include axis swapping or
+             * unit conversions. We revert them with concatenation of "CS to standardCS"
+             * transform. The axis swapping will be added back by createProjectedCRS(...)
+             * but not in the same place (they will be performed sooner than they would be
+             * otherwise).
+             */
+            final ProjectedCRS  sourceCRS = (ProjectedCRS) horizontal;
+            final CartesianCS   targetCS  = csFactory.createCartesianCS(csName, axis[0], axis[1], axis[2]);
+            final GeographicCRS base2D    = sourceCRS.getBaseCRS();
+            final GeographicCRS base3D    = (GeographicCRS) toGeodetic3D(null, base2D, vertical, xyFirst);
+            final Matrix        prepend   = toStandard(base2D, false);
+            final Matrix        append    = toStandard(sourceCRS, true);
+            Conversion projection = sourceCRS.getConversionFromBase();
+            if (!prepend.isIdentity() || !append.isIdentity()) {
+                final MathTransformFactory mtFactory = getMathTransformFactory();
+                MathTransform mt = projection.getMathTransform();
+                mt = mtFactory.createConcatenatedTransform(
+                     mtFactory.createConcatenatedTransform(
+                     mtFactory.createAffineTransform(prepend), mt),
+                     mtFactory.createAffineTransform(append));
+                projection = new DefiningConversion(AbstractCS.getProperties(projection),
+                                                    projection.getMethod(), mt);
+            }
+            return crsFactory.createProjectedCRS(crsName, base3D, projection, targetCS);
+        }
+        // Should never happen.
+        throw new AssertionError(horizontal);
+    }
+
+    private static Matrix toStandard(final CoordinateReferenceSystem crs, final boolean inverse) {
+        final CoordinateSystem sourceCS = crs.getCoordinateSystem();
+        final CoordinateSystem targetCS = AbstractCS.standard(sourceCS);
+        if (inverse) {
+            return AbstractCS.swapAndScaleAxis(targetCS, sourceCS);
+        } else {
+            return AbstractCS.swapAndScaleAxis(sourceCS, targetCS);
+        }
+    }
+
+    /**
+     * Returns a temporary name for object derived from the specified one.
+     */
+    private static Map<String,?> getTemporaryName(final IdentifiedObject source) {
+        return Collections.singletonMap(IdentifiedObject.NAME_KEY,
+                                        source.getName().getCode() + " (3D)");
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ReferencingObjectFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ReferencingObjectFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ReferencingObjectFactory.java	(revision 28000)
@@ -0,0 +1,747 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.factory;
+
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Map;
+import java.util.HashMap;
+import javax.measure.unit.Unit;
+import javax.measure.quantity.Angle;
+import javax.measure.quantity.Length;
+
+import org.opengis.referencing.*;
+import org.opengis.referencing.cs.*;
+import org.opengis.referencing.crs.*;
+import org.opengis.referencing.datum.*;
+import org.opengis.referencing.operation.*;
+import org.opengis.parameter.ParameterValueGroup;
+
+import org.geotools.factory.Hints;
+import org.geotools.factory.Factory;
+import org.geotools.factory.BufferedFactory;
+import org.geotools.referencing.ReferencingFactoryFinder;
+import org.geotools.referencing.wkt.Parser;
+import org.geotools.referencing.wkt.Symbols;
+import org.geotools.referencing.cs.*;
+import org.geotools.referencing.crs.*;
+import org.geotools.referencing.datum.*;
+import org.geotools.referencing.operation.MathTransformProvider;
+import org.geotools.referencing.operation.DefaultMathTransformFactory;
+import org.geotools.util.CanonicalSet;
+
+
+/**
+ * Builds Geotools implementations of {@linkplain CoordinateReferenceSystem CRS},
+ * {@linkplain CoordinateSystem CS} and {@linkplain Datum datum} objects. Most factory methods
+ * expect properties given through a {@link Map} argument. The content of this map is described
+ * in the {@link ObjectFactory} interface.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/ReferencingObjectFactory.java $
+ * @version $Id: ReferencingObjectFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class ReferencingObjectFactory extends ReferencingFactory
+        implements CSFactory, DatumFactory, CRSFactory, BufferedFactory
+{
+    /**
+     * The math transform factory. Will be created only when first needed.
+     */
+    private MathTransformFactory mtFactory;
+
+    /**
+     * The object to use for parsing <cite>Well-Known Text</cite> (WKT) strings.
+     * Will be created only when first needed.
+     */
+    private Parser parser;
+
+    /**
+     * Set of weak references to existing objects (identifiers, CRS, Datum, whatever).
+     * This set is used in order to return a pre-existing object instead of creating a
+     * new one.
+     */
+    private final CanonicalSet<IdentifiedObject> pool;
+
+    /**
+     * Constructs a default factory. This method is public in order to allows instantiations
+     * from a {@linkplain javax.imageio.spi.ServiceRegistry service registry}. Users should
+     * not instantiate this factory directly, but use one of the following lines instead:
+     *
+     * <blockquote><pre>
+     * {@linkplain DatumFactory} factory = FactoryFinder.{@linkplain ReferencingFactoryFinder#getDatumFactory getDatumFactory}null);
+     * {@linkplain CSFactory}    factory = FactoryFinder.{@linkplain ReferencingFactoryFinder#getCSFactory    getCSFactory}(null);
+     * {@linkplain CRSFactory}   factory = FactoryFinder.{@linkplain ReferencingFactoryFinder#getCRSFactory   getCRSFactory}(null);
+     * </pre></blockquote>
+     */
+    public ReferencingObjectFactory() {
+        this(null);
+    }
+
+    /**
+     * Constructs a factory with the specified hints. Users should not instantiate this
+     * factory directly, but use one of the following lines instead:
+     *
+     * <blockquote><pre>
+     * {@linkplain DatumFactory} factory = FactoryFinder.{@linkplain ReferencingFactoryFinder#getDatumFactory getDatumFactory}(hints);
+     * {@linkplain CSFactory}    factory = FactoryFinder.{@linkplain ReferencingFactoryFinder#getCSFactory    getCSFactory}(hints);
+     * {@linkplain CRSFactory}   factory = FactoryFinder.{@linkplain ReferencingFactoryFinder#getCRSFactory   getCRSFactory}(hints);
+     * </pre></blockquote>
+     *
+     * @param hints An optional set of hints, or {@code null} if none.
+     *
+     * @since 2.5
+     */
+    public ReferencingObjectFactory(final Hints hints) {
+        pool = CanonicalSet.newInstance(IdentifiedObject.class);
+        if (hints != null && !hints.isEmpty()) {
+            /*
+             * Creates the dependencies (MathTransform factory, WKT parser...) now because
+             * we need to process user's hints. Then, we will keep only the relevant hints.
+             */
+            mtFactory = ReferencingFactoryFinder.getMathTransformFactory(hints);
+            final DatumFactory datumFactory = ReferencingFactoryFinder.getDatumFactory(hints);
+            createParser(datumFactory, mtFactory);
+            addHints(datumFactory);
+            addHints(mtFactory);
+        }
+    }
+
+    /**
+     * Copies the hints from the supplied factory. Note that we do not expose the factories
+     * themself (at the contrary of what we usually do) because it is a little bit strange
+     * to declare that this factory depends on an other {@link DatumFactory}. It is only a
+     * trick for getting the WKT paser to work with aliases.
+     *
+     * @todo We should remove this trick if we can. Possible alternatives may be: make
+     *       DatumAliases to implements CRSFactory with appropriate createWKT(String)
+     *       method; move the createWKT(String) method out of CRSFactory interface.
+     */
+    private void addHints(final Object factory) {
+        if (factory instanceof Factory) {
+            hints.putAll(((Factory) factory).getImplementationHints());
+        }
+    }
+
+    /**
+     * Returns the math transform factory for internal usage only. The hints given to
+     * {@link ReferencingFactoryFinder} must be null, since the non-null case should
+     * have been handled by the constructor.
+     *
+     * @see #createParser
+     */
+    private synchronized MathTransformFactory getMathTransformFactory() {
+        if (mtFactory == null) {
+            mtFactory = ReferencingFactoryFinder.getMathTransformFactory(null);
+        }
+        return mtFactory;
+    }
+
+
+
+    /////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                         ////////
+    ////////                        D A T U M   F A C T O R Y                        ////////
+    ////////                                                                         ////////
+    /////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Creates an ellipsoid from radius values.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  semiMajorAxis Equatorial radius in supplied linear units.
+     * @param  semiMinorAxis Polar radius in supplied linear units.
+     * @param  unit Linear units of ellipsoid axes.
+     * @throws FactoryException if the object creation failed.
+     */
+    public Ellipsoid createEllipsoid(Map<String,?> properties,
+            double semiMajorAxis, double semiMinorAxis, Unit<Length> unit) throws FactoryException
+    {
+        Ellipsoid ellipsoid;
+        try {
+            ellipsoid = DefaultEllipsoid.createEllipsoid(
+                        properties, semiMajorAxis, semiMinorAxis, unit);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        ellipsoid = pool.unique(ellipsoid);
+        return ellipsoid;
+    }
+
+    /**
+     * Creates an ellipsoid from an major radius, and inverse flattening.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  semiMajorAxis Equatorial radius in supplied linear units.
+     * @param  inverseFlattening Eccentricity of ellipsoid.
+     * @param  unit Linear units of major axis.
+     * @throws FactoryException if the object creation failed.
+     */
+    public Ellipsoid createFlattenedSphere(Map<String,?> properties,
+            double semiMajorAxis, double inverseFlattening, Unit<Length> unit) throws FactoryException
+    {
+        Ellipsoid ellipsoid;
+        try {
+            ellipsoid = DefaultEllipsoid.createFlattenedSphere(
+                        properties, semiMajorAxis, inverseFlattening, unit);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        ellipsoid = pool.unique(ellipsoid);
+        return ellipsoid;
+    }
+
+    /**
+     * Creates a prime meridian, relative to Greenwich.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  longitude Longitude of prime meridian in supplied angular units East of Greenwich.
+     * @param  angularUnit Angular units of longitude.
+     * @throws FactoryException if the object creation failed.
+     */
+    public PrimeMeridian createPrimeMeridian(Map<String,?> properties,
+            double longitude, Unit<Angle> angularUnit) throws FactoryException
+    {
+        PrimeMeridian meridian;
+        try {
+            meridian = new DefaultPrimeMeridian(properties, longitude, angularUnit);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        meridian = pool.unique(meridian);
+        return meridian;
+    }
+
+    /**
+     * Creates geodetic datum from ellipsoid and (optionaly) Bursa-Wolf parameters.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  ellipsoid Ellipsoid to use in new geodetic datum.
+     * @param  primeMeridian Prime meridian to use in new geodetic datum.
+     * @throws FactoryException if the object creation failed.
+     */
+    public GeodeticDatum createGeodeticDatum(Map<String,?> properties,
+            Ellipsoid ellipsoid, PrimeMeridian primeMeridian) throws FactoryException
+    {
+        GeodeticDatum datum;
+        try {
+            datum = new DefaultGeodeticDatum(properties, ellipsoid, primeMeridian);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        datum = pool.unique(datum);
+        return datum;
+    }
+
+    /**
+     * Creates a vertical datum from an enumerated type value.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  type The type of this vertical datum (often geoidal).
+     * @throws FactoryException if the object creation failed.
+     */
+    public VerticalDatum createVerticalDatum(Map<String,?> properties, VerticalDatumType type)
+            throws FactoryException
+    {
+        VerticalDatum datum;
+        try {
+            datum = new DefaultVerticalDatum(properties, type);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        datum = pool.unique(datum);
+        return datum;
+    }
+
+    /**
+     * Creates a temporal datum from an enumerated type value.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  origin The date and time origin of this temporal datum.
+     * @throws FactoryException if the object creation failed.
+     */
+    public TemporalDatum createTemporalDatum(Map<String,?> properties, Date origin)
+            throws FactoryException
+    {
+        TemporalDatum datum;
+        try {
+            datum = new DefaultTemporalDatum(properties, origin);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        datum = pool.unique(datum);
+        return datum;
+    }
+
+    /**
+     * Creates an engineering datum.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @throws FactoryException if the object creation failed.
+     */
+    public EngineeringDatum createEngineeringDatum(Map<String,?> properties)
+            throws FactoryException
+    {
+        EngineeringDatum datum;
+        try {
+            datum = new DefaultEngineeringDatum(properties);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        datum = pool.unique(datum);
+        return datum;
+    }
+
+    /**
+     * Creates an image datum.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  pixelInCell Specification of the way the image grid is associated
+     *         with the image data attributes.
+     * @throws FactoryException if the object creation failed.
+     */
+    public ImageDatum createImageDatum(Map<String,?> properties, PixelInCell pixelInCell)
+            throws FactoryException
+    {
+        ImageDatum datum;
+        try {
+            datum = new DefaultImageDatum(properties, pixelInCell);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        datum = pool.unique(datum);
+        return datum;
+    }
+
+
+
+    /////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                         ////////
+    ////////            C O O R D I N A T E   S Y S T E M   F A C T O R Y            ////////
+    ////////                                                                         ////////
+    /////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Creates a coordinate system axis from an abbreviation and a unit.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  abbreviation The coordinate axis abbreviation.
+     * @param  direction The axis direction.
+     * @param  unit The coordinate axis unit.
+     * @throws FactoryException if the object creation failed.
+     */
+    public CoordinateSystemAxis createCoordinateSystemAxis(Map<String,?> properties,
+            String abbreviation, AxisDirection direction, Unit<?> unit) throws FactoryException
+    {
+        CoordinateSystemAxis axis;
+        try {
+            axis = new DefaultCoordinateSystemAxis(properties, abbreviation, direction, unit);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        axis = pool.unique(axis);
+        return axis;
+    }
+
+    /**
+     * Creates a two dimensional cartesian coordinate system from the given pair of axis.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  axis0 The first  axis.
+     * @param  axis1 The second axis.
+     * @throws FactoryException if the object creation failed.
+     */
+    public CartesianCS createCartesianCS(Map<String,?>   properties,
+                                         CoordinateSystemAxis axis0,
+                                         CoordinateSystemAxis axis1) throws FactoryException
+    {
+        CartesianCS cs;
+        try {
+            cs = new DefaultCartesianCS(properties, axis0, axis1);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        cs = pool.unique(cs);
+        return cs;
+    }
+
+    /**
+     * Creates a three dimensional cartesian coordinate system from the given set of axis.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  axis0 The first  axis.
+     * @param  axis1 The second axis.
+     * @param  axis2 The third  axis.
+     * @throws FactoryException if the object creation failed.
+     */
+    public CartesianCS createCartesianCS(Map<String,?>   properties,
+                                         CoordinateSystemAxis axis0,
+                                         CoordinateSystemAxis axis1,
+                                         CoordinateSystemAxis axis2) throws FactoryException
+    {
+        CartesianCS cs;
+        try {
+            cs = new DefaultCartesianCS(properties, axis0, axis1, axis2);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        cs = pool.unique(cs);
+        return cs;
+    }
+
+    /**
+     * Creates an ellipsoidal coordinate system without ellipsoidal height.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  axis0 The first  axis.
+     * @param  axis1 The second axis.
+     * @throws FactoryException if the object creation failed.
+     */
+    public EllipsoidalCS createEllipsoidalCS(Map<String,?>   properties,
+                                             CoordinateSystemAxis axis0,
+                                             CoordinateSystemAxis axis1) throws FactoryException
+    {
+        EllipsoidalCS cs;
+        try {
+            cs = new DefaultEllipsoidalCS(properties, axis0, axis1);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        cs = pool.unique(cs);
+        return cs;
+    }
+
+    /**
+     * Creates an ellipsoidal coordinate system with ellipsoidal height.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  axis0 The first  axis.
+     * @param  axis1 The second axis.
+     * @param  axis2 The third  axis.
+     * @throws FactoryException if the object creation failed.
+     */
+    public EllipsoidalCS createEllipsoidalCS(Map<String,?>   properties,
+                                             CoordinateSystemAxis axis0,
+                                             CoordinateSystemAxis axis1,
+                                             CoordinateSystemAxis axis2) throws FactoryException
+    {
+        EllipsoidalCS cs;
+        try {
+            cs = new DefaultEllipsoidalCS(properties, axis0, axis1, axis2);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        cs = pool.unique(cs);
+        return cs;
+    }
+
+    /**
+     * Creates a vertical coordinate system.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  axis The axis.
+     * @throws FactoryException if the object creation failed.
+     */
+    public VerticalCS createVerticalCS(Map<String,?>  properties,
+                                       CoordinateSystemAxis axis) throws FactoryException
+    {
+        VerticalCS cs;
+        try {
+            cs = new DefaultVerticalCS(properties, axis);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        cs = pool.unique(cs);
+        return cs;
+    }
+
+    /////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                         ////////
+    ////////  C O O R D I N A T E   R E F E R E N C E   S Y S T E M   F A C T O R Y  ////////
+    ////////                                                                         ////////
+    /////////////////////////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Creates a compound coordinate reference system from an ordered
+     * list of {@code CoordinateReferenceSystem} objects.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  elements ordered array of {@code CoordinateReferenceSystem} objects.
+     * @throws FactoryException if the object creation failed.
+     */
+    public CompoundCRS createCompoundCRS(Map<String,?> properties,
+            CoordinateReferenceSystem[] elements) throws FactoryException
+    {
+        CompoundCRS crs;
+        try {
+            crs = new DefaultCompoundCRS(properties, elements);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        crs = pool.unique(crs);
+        return crs;
+    }
+
+    /**
+     * Creates a engineering coordinate reference system.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  datum Engineering datum to use in created CRS.
+     * @param  cs The coordinate system for the created CRS.
+     * @throws FactoryException if the object creation failed.
+     */
+    public EngineeringCRS createEngineeringCRS(Map<String,?> properties,
+                                               EngineeringDatum datum,
+                                               CoordinateSystem cs) throws FactoryException
+    {
+        EngineeringCRS crs;
+        try {
+            crs = new DefaultEngineeringCRS(properties, datum, cs);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        crs = pool.unique(crs);
+        return crs;
+    }
+
+    /**
+     * Creates a vertical coordinate reference system.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  datum Vertical datum to use in created CRS.
+     * @param  cs The Vertical coordinate system for the created CRS.
+     * @throws FactoryException if the object creation failed.
+     */
+    public VerticalCRS createVerticalCRS(Map<String,?> properties,
+                                         VerticalDatum datum,
+                                         VerticalCS    cs) throws FactoryException
+    {
+        VerticalCRS crs;
+        try {
+            crs = new DefaultVerticalCRS(properties, datum, cs);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        crs = pool.unique(crs);
+        return crs;
+    }
+
+    /**
+     * Creates a geocentric coordinate reference system from a {@linkplain CartesianCS
+     * cartesian coordinate system}.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  datum Geodetic datum to use in created CRS.
+     * @param  cs The cartesian coordinate system for the created CRS.
+     * @throws FactoryException if the object creation failed.
+     */
+    public GeocentricCRS createGeocentricCRS(Map<String,?> properties,
+                                             GeodeticDatum datum,
+                                             CartesianCS   cs) throws FactoryException
+    {
+        GeocentricCRS crs;
+        try {
+            crs = new DefaultGeocentricCRS(properties, datum, cs);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        crs = pool.unique(crs);
+        return crs;
+    }
+
+    /**
+     * Creates a geographic coordinate reference system.
+     * It could be <var>Latitude</var>/<var>Longitude</var> or
+     * <var>Longitude</var>/<var>Latitude</var>.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  datum Geodetic datum to use in created CRS.
+     * @param  cs The ellipsoidal coordinate system for the created CRS.
+     * @throws FactoryException if the object creation failed.
+     */
+    public GeographicCRS createGeographicCRS(Map<String,?> properties,
+                                             GeodeticDatum datum,
+                                             EllipsoidalCS cs) throws FactoryException
+    {
+        GeographicCRS crs;
+        try {
+            crs = new DefaultGeographicCRS(properties, datum, cs);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        crs = pool.unique(crs);
+        return crs;
+    }
+
+    /**
+     * Creates a derived coordinate reference system from a conversion.
+     * It is the user's responsability to ensure that the conversion performs all required steps,
+     * including {@linkplain AbstractCS#swapAndScaleAxis unit conversions and change of axis order},
+     * if needed.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  baseCRS Coordinate reference system to base projection on.
+     * @param  conversionFromBase The {@linkplain DefiningConversion defining conversion}.
+     * @param  derivedCS The coordinate system for the derived CRS.
+     * @throws FactoryException if the object creation failed.
+     *
+     * @since 2.5
+     */
+    public DerivedCRS createDerivedCRS(Map<String,?>          properties,
+                                       CoordinateReferenceSystem baseCRS,
+                                       Conversion     conversionFromBase,
+                                       CoordinateSystem        derivedCS) throws FactoryException
+    {
+        MathTransform mt = conversionFromBase.getMathTransform();
+        if (mt == null) {
+            final ParameterValueGroup parameters = conversionFromBase.getParameterValues();
+            final MathTransformFactory mtFactory = getMathTransformFactory();
+            mt = mtFactory.createParameterizedTransform(parameters);
+        }
+        DerivedCRS crs;
+        try {
+            crs = new DefaultDerivedCRS(properties, conversionFromBase, baseCRS, mt, derivedCS);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        crs = pool.unique(crs);
+        return crs;
+    }
+
+    /**
+     * Creates a projected coordinate reference system from a conversion. The supplied
+     * conversion should <strong>not</strong> includes the operation steps for performing
+     * {@linkplain AbstractCS#swapAndScaleAxis unit conversions and change of axis order}
+     * since those operations will be inferred by this constructor
+     *
+     * @param  properties Name and other properties to give to the new object.
+     * @param  baseCRS Geographic coordinate reference system to base projection on.
+     * @param  conversionFromBase The {@linkplain DefiningConversion defining conversion}.
+     * @param  derivedCS The coordinate system for the projected CRS.
+     * @throws FactoryException if the object creation failed.
+     *
+     * @since 2.5
+     */
+    public ProjectedCRS createProjectedCRS(Map<String,?> properties,
+                                           GeographicCRS baseCRS,
+                                           Conversion    conversionFromBase,
+                                           CartesianCS   derivedCS) throws FactoryException
+    {
+        MathTransform mt;
+        final MathTransform existing = conversionFromBase.getMathTransform();
+        final MathTransformFactory mtFactory = getMathTransformFactory();
+        if (existing != null && mtFactory instanceof DefaultMathTransformFactory) {
+            /*
+             * In the particular case of GeoTools implementation, we use a shortcut which avoid
+             * the cost of creating a new parameterized transform; we use directly the existing
+             * transform instance instead. It also avoid slight rounding errors as a side-effect.
+             * This is because when a MapProjection is created, the angular parameters given to
+             * the construtor are converted from degrees to radians. When the parameters are asked
+             * back with 'conversionFromBase.getParameterValues()', they are converted back from
+             * radians to degrees resulting in values slightly different than the original ones.
+             * Those slight differences are enough for getting a math transform which is different
+             * in the sense of MapProjection.equals(Object), with the usual consequences on cached
+             * instances.
+             */
+            mt = ((DefaultMathTransformFactory) mtFactory).createBaseToDerived(baseCRS, existing, derivedCS);
+        } else {
+            /*
+             * Non-GeoTools implementation, or no existing MathTransform instance.
+             * Creates the transform from the parameters.
+             */
+            final ParameterValueGroup parameters = conversionFromBase.getParameterValues();
+            mt = mtFactory.createBaseToDerived(baseCRS, parameters, derivedCS);
+            OperationMethod method = conversionFromBase.getMethod();
+            if (!(method instanceof MathTransformProvider)) {
+                /*
+                 * Our Geotools implementation of DefaultProjectedCRS may not be able to detect
+                 * the conversion type (PlanarProjection, CylindricalProjection, etc.)  because
+                 * we rely on the Geotools-specific MathTransformProvider for that. We will try
+                 * to help it with the optional "conversionType" hint,  providing that the user
+                 * do not already provides this hint.
+                 */
+                if (!properties.containsKey(DefaultProjectedCRS.CONVERSION_TYPE_KEY)) {
+                    method = mtFactory.getLastMethodUsed();
+                    if (method instanceof MathTransformProvider) {
+                        final Map<String,Object> copy = new HashMap<String,Object>(properties);
+                        copy.put(DefaultProjectedCRS.CONVERSION_TYPE_KEY,
+                                ((MathTransformProvider) method).getOperationType());
+                        properties = copy;
+                    }
+                }
+            }
+            /*
+             * If the user gave an explicit conversion, checks if it is suitable.
+             * It may not be suitable is unit conversion, axis switch, etc. have
+             * been inserted in the operation chain by 'createBaseToDerived'.
+             */
+            if (existing != null && existing.equals(mt)) {
+                mt = existing;
+            }
+        }
+        ProjectedCRS crs;
+        try {
+            crs = new DefaultProjectedCRS(properties, conversionFromBase, baseCRS, mt, derivedCS);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        crs = pool.unique(crs);
+        return crs;
+    }
+
+    /**
+     * Creates a coordinate reference system object from a string.
+     *
+     * @param  wkt Coordinate system encoded in Well-Known Text format.
+     * @throws FactoryException if the object creation failed.
+     */
+    public synchronized CoordinateReferenceSystem createFromWKT(final String wkt)
+            throws FactoryException
+    {
+        /*
+         * Note: while this factory is thread safe, the WKT parser is not.
+         * Since we share a single instance of this parser, we must synchronize.
+         */
+        if (parser == null) {
+            createParser(ReferencingFactoryFinder.getDatumFactory(null),
+                    getMathTransformFactory());
+        }
+        try {
+            return parser.parseCoordinateReferenceSystem(wkt);
+        } catch (ParseException exception) {
+            final Throwable cause = exception.getCause();
+            if (cause instanceof FactoryException) {
+                throw (FactoryException) cause;
+            }
+            throw new FactoryException(exception);
+        }
+    }
+
+    /**
+     * Creates inconditionnaly the WKT parser. This is factored out as a single private method
+     * for making easier to spot the places in this code that need to create the parser and the
+     * datum-alias patch.
+     */
+    private void createParser(final DatumFactory datumFactory, final MathTransformFactory mtFactory) {
+        parser = new Parser(Symbols.DEFAULT, datumFactory, this, this, mtFactory);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ThreadedAuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ThreadedAuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/ThreadedAuthorityFactory.java	(revision 28000)
@@ -0,0 +1,1095 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.factory;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.WeakHashMap;
+import java.util.logging.LogRecord;
+import java.util.logging.Level;
+import javax.measure.unit.Unit;
+
+import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.referencing.AuthorityFactory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.cs.*;
+import org.opengis.referencing.crs.*;
+import org.opengis.referencing.datum.*;
+import org.opengis.referencing.operation.*;
+import org.opengis.util.InternationalString;
+
+import org.geotools.factory.Hints;
+import org.geotools.factory.BufferedFactory;
+import org.geotools.util.Utilities;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Loggings;
+import org.geotools.resources.i18n.LoggingKeys;
+
+
+/**
+ * An authority factory that caches all objects created by an other factory. All
+ * {@code createFoo(String)} methods first looks if a previously created object
+ * exists for the given code. If such an object exists, it is returned. Otherwise,
+ * the object creation is delegated to the {@linkplain AbstractAuthorityFactory authority factory}
+ * specified at creation time, and the result is cached in this buffered factory.
+ * <p>
+ * Objects are cached by strong references, up to the amount of objects specified at
+ * construction time. If a greater amount of objects are cached, the oldest ones will
+ * be retained through a {@linkplain java.lang.ref.WeakReference weak reference} instead
+ * of a strong one. This means that this buffered factory will continue to returns them
+ * as long as they are in use somewhere else in the Java virtual machine, but will be
+ * discarted (and recreated on the fly if needed) otherwise.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/ThreadedAuthorityFactory.java $
+ * @version $Id: ThreadedAuthorityFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class ThreadedAuthorityFactory extends AbstractAuthorityFactory implements BufferedFactory {
+    /**
+     * The default value for {@link #maxStrongReferences}.
+     */
+    static final int DEFAULT_MAX = 20;
+
+    /**
+     * The underlying authority factory. This field may be {@code null} if this object was
+     * created by the {@linkplain #ThreadedAuthorityFactory(AbstractAuthorityFactory,int)
+     * package protected constructor}. In this case, the subclass is responsible for creating
+     * the backing store when {@link DeferredAuthorityFactory#createBackingStore} is invoked.
+     *
+     * @see #getBackingStore
+     * @see DeferredAuthorityFactory#createBackingStore
+     */
+    AbstractAuthorityFactory backingStore;
+
+    /**
+     * The cache for referencing objects.
+     */
+    private final OldReferencingObjectCache objectCache;
+
+    /**
+     * The pool of objects identified by {@link find}.
+     */
+    private final Map<IdentifiedObject,IdentifiedObject> findPool =
+            new WeakHashMap<IdentifiedObject,IdentifiedObject>();
+
+
+    /**
+     * Constructs an instance wrapping the specified factory with a default number
+     * of entries to keep by strong reference.
+     * <p>
+     * This constructor is protected because subclasses must declare which of the
+     * {@link DatumAuthorityFactory}, {@link CSAuthorityFactory}, {@link CRSAuthorityFactory}
+     * and {@link CoordinateOperationAuthorityFactory} interfaces they choose to implement.
+     *
+     * @param factory The factory to cache. Can not be {@code null}.
+     */
+    protected ThreadedAuthorityFactory(final AbstractAuthorityFactory factory) {
+        this(factory, DEFAULT_MAX);
+    }
+
+    /**
+     * Constructs an instance wrapping the specified factory. The {@code maxStrongReferences}
+     * argument specify the maximum number of objects to keep by strong reference. If a greater
+     * amount of objects are created, then the strong references for the oldest ones are replaced
+     * by weak references.
+     * <p>
+     * This constructor is protected because subclasses must declare which of the
+     * {@link DatumAuthorityFactory}, {@link CSAuthorityFactory}, {@link CRSAuthorityFactory}
+     * and {@link CoordinateOperationAuthorityFactory} interfaces they choose to implement.
+     *
+     * @param factory The factory to cache. Can not be {@code null}.
+     * @param maxStrongReferences The maximum number of objects to keep by strong reference.
+     */
+    protected ThreadedAuthorityFactory(AbstractAuthorityFactory factory,
+                                       final int maxStrongReferences)
+    {
+        super(factory.getPriority());
+        while (factory instanceof ThreadedAuthorityFactory) {
+            factory = ((ThreadedAuthorityFactory) factory).backingStore;
+        }
+        this.backingStore = factory;
+        this.objectCache = new OldReferencingObjectCache(maxStrongReferences);
+        completeHints();
+    }
+
+    /**
+     * Completes the set of hints according the value currently set in this object. This method
+     * is invoked by {@code BufferedAuthorityFactory} or by {@code DeferredAuthorityFactory} at
+     * backing store creation time.
+     * <p>
+     * The backing store is of course an important dependency. This method gives a chance
+     * to {@link org.geotools.factory.FactoryRegistry} to compare the user-requested hints
+     * (especially {@link Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER}) against the backing store
+     * hints, by following the dependency declared there.
+     * <p>
+     * DON'T FORGET to set those hints to {@code null} when {@link DeferredAuthorityFactory}
+     * dispose the backing store.
+     */
+    final void completeHints() {
+        if (backingStore instanceof DatumAuthorityFactory) {
+            hints.put(Hints.DATUM_AUTHORITY_FACTORY, backingStore);
+        }
+        if (backingStore instanceof CSAuthorityFactory) {
+            hints.put(Hints.CS_AUTHORITY_FACTORY, backingStore);
+        }
+        if (backingStore instanceof CRSAuthorityFactory) {
+            hints.put(Hints.CRS_AUTHORITY_FACTORY, backingStore);
+        }
+        if (backingStore instanceof CoordinateOperationAuthorityFactory) {
+            hints.put(Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY, backingStore);
+        }
+    }
+
+    /**
+     * Returns the direct dependencies. The returned list contains the backing store
+     * specified at construction time, or the exception if it can't be obtained.
+     */
+    @Override
+    Collection<? super AuthorityFactory> dependencies() {
+        Object factory;
+        try {
+            factory = getBackingStore();
+        } catch (FactoryException e) {
+            factory = e;
+        }
+        return Collections.singleton(factory);
+    }
+
+    /**
+     * Returns the backing store authority factory.
+     *
+     * @return The backing store to uses in {@code createXXX(...)} methods.
+     * @throws FactoryException if the creation of backing store failed.
+     */
+    AbstractAuthorityFactory getBackingStore() throws FactoryException {
+        if (backingStore == null) {
+            throw new FactoryException(Errors.format(ErrorKeys.DISPOSED_FACTORY));
+        }
+        return backingStore;
+    }
+
+    /**
+     * Returns {@code true} if this factory is available. The default implementation returns
+     * {@code false} if no backing store were setup and
+     * {@link DeferredAuthorityFactory#createBackingStore} throws an exception.
+     */
+    @Override
+    boolean isAvailable() {
+        try {
+            return getBackingStore().isAvailable();
+        } catch (FactoryNotFoundException exception) {
+            /*
+             * The factory is not available. This is error may be normal; it happens
+             * for example if no gt2-epsg-hsql.jar (or similar JAR) are found in the
+             * classpath, which is the case for example in GeoServer 1.3. Do not log
+             * any stack trace,  since stack traces suggest more serious errors than
+             * what we really have here.
+             */
+        } catch (FactoryException exception) {
+            /*
+             * The factory creation failed for an other reason, which may be more
+             * serious. Now it is time to log a warning with a stack trace.
+             */
+            final Citation   citation = getAuthority();
+            final Collection   titles = citation.getAlternateTitles();
+            InternationalString title = citation.getTitle();
+            if (titles != null) {
+                for (final Iterator it=titles.iterator(); it.hasNext();) {
+                    /*
+                     * Uses the longuest title instead of the main one. In Geotools
+                     * implementation, the alternate title may contains usefull informations
+                     * like the EPSG database version number and the database engine.
+                     */
+                    final InternationalString candidate = (InternationalString) it.next();
+                    if (candidate.length() > title.length()) {
+                        title  = candidate;
+                    }
+                }
+            }
+            final LogRecord record = Loggings.format(Level.WARNING,
+                    LoggingKeys.UNAVAILABLE_AUTHORITY_FACTORY_$1, title);
+            record.setSourceClassName(getClass().getName());
+            record.setSourceMethodName("isAvailable");
+            record.setThrown(exception);
+            record.setLoggerName(LOGGER.getName());
+            LOGGER.log(record);
+        }
+        return false;
+    }
+
+    /**
+     * If this factory is a wrapper for the specified factory that do not add any additional
+     * {@linkplain #getAuthorityCodes authority codes}, returns {@code true}. This method is
+     * for {@link FallbackAuthorityFactory} internal use only and should not be public. A
+     * cheap test without {@link #getBackingStore} invocation is suffisient for our needs.
+     */
+    @Override
+    boolean sameAuthorityCodes(final AuthorityFactory factory) {
+        final AbstractAuthorityFactory backingStore = this.backingStore; // Protect from changes.
+        if (backingStore != null && backingStore.sameAuthorityCodes(factory)) {
+            return true;
+        }
+        return super.sameAuthorityCodes(factory);
+    }
+
+    /**
+     * Returns the vendor responsible for creating the underlying factory implementation.
+     */
+    @Override
+    public Citation getVendor() {
+        return (backingStore!=null) ? backingStore.getVendor() : super.getVendor();
+    }
+
+    /**
+     * Returns the organization or party responsible for definition and maintenance of the
+     * underlying database.
+     */
+    public Citation getAuthority() {
+        return (backingStore!=null) ? backingStore.getAuthority() : null;
+    }
+
+    /**
+     * Returns a description of the underlying backing store, or {@code null} if unknow.
+     * This is for example the database software used for storing the data.
+     *
+     * @throws FactoryException if a failure occured while fetching the engine description.
+     */
+    @Override
+    public String getBackingStoreDescription() throws FactoryException {
+        return getBackingStore().getBackingStoreDescription();
+    }
+
+    /**
+     * Returns the set of authority codes of the given type. The {@code type}
+     * argument specify the base class.
+     *
+     * @param  type The spatial reference objects type.
+     * @return The set of authority codes for spatial reference objects of the given type.
+     *         If this factory doesn't contains any object of the given type, then this method
+     *         returns an {@linkplain java.util.Collections#EMPTY_SET empty set}.
+     * @throws FactoryException if access to the underlying database failed.
+     */
+    public Set<String> getAuthorityCodes(final Class type)
+            throws FactoryException
+    {
+        return getBackingStore().getAuthorityCodes(type);
+    }
+
+    /**
+     * Gets a description of the object corresponding to a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return A description of the object, or {@code null} if the object
+     *         corresponding to the specified {@code code} has no description.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the query failed for some other reason.
+     */
+    public InternationalString getDescriptionText(final String code)
+            throws FactoryException
+    {
+        return getBackingStore().getDescriptionText(code);
+    }
+
+    /**
+     * Returns an arbitrary object from a code.
+     */
+    @Override
+    public synchronized IdentifiedObject createObject(final String code)
+            throws FactoryException
+    {
+        final IdentifiedObject object;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof IdentifiedObject) {
+            object = (IdentifiedObject) cached;
+        } else {
+            object = getBackingStore().createObject(code);
+        }
+        objectCache.put(key, object);
+        return object;
+    }
+
+    /**
+     * Returns an arbitrary datum from a code.
+     */
+    @Override
+    public synchronized Datum createDatum(final String code)
+            throws FactoryException
+    {
+        final Datum datum;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof Datum) {
+            datum = (Datum) cached;
+        } else {
+            datum = getBackingStore().createDatum(code);
+        }
+        objectCache.put(key, datum);
+        return datum;
+    }
+
+    /**
+     * Returns an engineering datum from a code.
+     */
+    @Override
+    public synchronized EngineeringDatum createEngineeringDatum(final String code)
+            throws FactoryException
+    {
+        final EngineeringDatum datum;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof EngineeringDatum) {
+            datum = (EngineeringDatum) cached;
+        } else {
+            datum = getBackingStore().createEngineeringDatum(code);
+        }
+        objectCache.put(key, datum);
+        return datum;
+    }
+
+    /**
+     * Returns an image datum from a code.
+     */
+    @Override
+    public synchronized ImageDatum createImageDatum(final String code)
+            throws FactoryException
+    {
+        final ImageDatum datum;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof ImageDatum) {
+            datum = (ImageDatum) cached;
+        } else {
+            datum = getBackingStore().createImageDatum(code);
+        }
+        objectCache.put(key, datum);
+        return datum;
+    }
+
+    /**
+     * Returns a vertical datum from a code.
+     */
+    @Override
+    public synchronized VerticalDatum createVerticalDatum(final String code)
+            throws FactoryException
+    {
+        final VerticalDatum datum;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof VerticalDatum) {
+            datum = (VerticalDatum) cached;
+        } else {
+            datum = getBackingStore().createVerticalDatum(code);
+        }
+        objectCache.put(key, datum);
+        return datum;
+    }
+
+    /**
+     * Returns a temporal datum from a code.
+     */
+    @Override
+    public synchronized TemporalDatum createTemporalDatum(final String code)
+            throws FactoryException
+    {
+        final TemporalDatum datum;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof TemporalDatum) {
+            datum = (TemporalDatum) cached;
+        } else {
+            datum = getBackingStore().createTemporalDatum(code);
+        }
+        objectCache.put(key, datum);
+        return datum;
+    }
+
+    /**
+     * Returns a geodetic datum from a code.
+     */
+    @Override
+    public synchronized GeodeticDatum createGeodeticDatum(final String code)
+            throws FactoryException
+    {
+        final GeodeticDatum datum;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof GeodeticDatum) {
+            datum = (GeodeticDatum) cached;
+        } else {
+            datum = getBackingStore().createGeodeticDatum(code);
+        }
+        objectCache.put(key, datum);
+        return datum;
+    }
+
+    /**
+     * Returns an ellipsoid from a code.
+     */
+    @Override
+    public synchronized Ellipsoid createEllipsoid(final String code)
+            throws FactoryException
+    {
+        final Ellipsoid ellipsoid;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof Ellipsoid) {
+            ellipsoid = (Ellipsoid) cached;
+        } else {
+            ellipsoid = getBackingStore().createEllipsoid(code);
+        }
+        objectCache.put(key, ellipsoid);
+        return ellipsoid;
+    }
+
+    /**
+     * Returns a prime meridian from a code.
+     */
+    @Override
+    public synchronized PrimeMeridian createPrimeMeridian(final String code)
+            throws FactoryException
+    {
+        final PrimeMeridian meridian;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof PrimeMeridian) {
+            meridian = (PrimeMeridian) cached;
+        } else {
+            meridian = getBackingStore().createPrimeMeridian(code);
+        }
+        objectCache.put(key, meridian);
+        return meridian;
+    }
+
+    /**
+     * Returns an extent (usually an area of validity) from a code.
+     */
+    @Override
+    public synchronized Extent createExtent(final String code)
+            throws FactoryException
+    {
+        final Extent extent;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof Extent) {
+            extent = (Extent) cached;
+        } else {
+            extent = getBackingStore().createExtent(code);
+        }
+        objectCache.put(key, extent);
+        return extent;
+    }
+
+    /**
+     * Returns an arbitrary coordinate system from a code.
+     */
+    @Override
+    public synchronized CoordinateSystem createCoordinateSystem(final String code)
+            throws FactoryException
+    {
+        final CoordinateSystem cs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof CoordinateSystem) {
+            cs = (CoordinateSystem) cached;
+        } else {
+            cs = getBackingStore().createCoordinateSystem(code);
+        }
+        objectCache.put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a cartesian coordinate system from a code.
+     */
+    @Override
+    public synchronized CartesianCS createCartesianCS(final String code)
+            throws FactoryException
+    {
+        final CartesianCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof CartesianCS) {
+            cs = (CartesianCS) cached;
+        } else {
+            cs = getBackingStore().createCartesianCS(code);
+        }
+        objectCache.put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a polar coordinate system from a code.
+     */
+    @Override
+    public synchronized PolarCS createPolarCS(final String code)
+            throws FactoryException
+    {
+        final PolarCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof PolarCS) {
+            cs = (PolarCS) cached;
+        } else {
+            cs = getBackingStore().createPolarCS(code);
+        }
+        objectCache.put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a cylindrical coordinate system from a code.
+     */
+    @Override
+    public synchronized CylindricalCS createCylindricalCS(final String code)
+            throws FactoryException
+    {
+        final CylindricalCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof CylindricalCS) {
+            cs = (CylindricalCS) cached;
+        } else {
+            cs = getBackingStore().createCylindricalCS(code);
+        }
+        objectCache.put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a spherical coordinate system from a code.
+     */
+    @Override
+    public synchronized SphericalCS createSphericalCS(final String code)
+            throws FactoryException
+    {
+        final SphericalCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof SphericalCS) {
+            cs = (SphericalCS) cached;
+        } else {
+            cs = getBackingStore().createSphericalCS(code);
+        }
+        objectCache.put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns an ellipsoidal coordinate system from a code.
+     */
+    @Override
+    public synchronized EllipsoidalCS createEllipsoidalCS(final String code)
+            throws FactoryException
+    {
+        final EllipsoidalCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof EllipsoidalCS) {
+            cs = (EllipsoidalCS) cached;
+        } else {
+            cs = getBackingStore().createEllipsoidalCS(code);
+        }
+        objectCache.put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a vertical coordinate system from a code.
+     */
+    @Override
+    public synchronized VerticalCS createVerticalCS(final String code)
+            throws FactoryException
+    {
+        final VerticalCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof VerticalCS) {
+            cs = (VerticalCS) cached;
+        } else {
+            cs = getBackingStore().createVerticalCS(code);
+        }
+        objectCache.put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a temporal coordinate system from a code.
+     */
+    @Override
+    public synchronized TimeCS createTimeCS(final String code)
+            throws FactoryException
+    {
+        final TimeCS cs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof TimeCS) {
+            cs = (TimeCS) cached;
+        } else {
+            cs = getBackingStore().createTimeCS(code);
+        }
+        objectCache.put(key, cs);
+        return cs;
+    }
+
+    /**
+     * Returns a coordinate system axis from a code.
+     */
+    @Override
+    public synchronized CoordinateSystemAxis createCoordinateSystemAxis(final String code)
+            throws FactoryException
+    {
+        final CoordinateSystemAxis axis;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof CoordinateSystemAxis) {
+            axis = (CoordinateSystemAxis) cached;
+        } else {
+            axis = getBackingStore().createCoordinateSystemAxis(code);
+        }
+        objectCache.put(key, axis);
+        return axis;
+    }
+
+    /**
+     * Returns an unit from a code.
+     */
+    @Override
+    public synchronized Unit<?> createUnit(final String code)
+            throws FactoryException
+    {
+        final Unit<?> unit;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof Unit) {
+            unit = (Unit) cached;
+        } else {
+            unit = getBackingStore().createUnit(code);
+        }
+        objectCache.put(key, unit);
+        return unit;
+    }
+
+    /**
+     * Returns an arbitrary coordinate reference system from a code.
+     */
+    @Override
+    public synchronized CoordinateReferenceSystem createCoordinateReferenceSystem(final String code)
+            throws FactoryException
+    {
+        final CoordinateReferenceSystem crs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof CoordinateReferenceSystem) {
+            crs = (CoordinateReferenceSystem) cached;
+        } else {
+            crs = getBackingStore().createCoordinateReferenceSystem(code);
+        }
+        objectCache.put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a 3D coordinate reference system from a code.
+     */
+    @Override
+    public synchronized CompoundCRS createCompoundCRS(final String code)
+            throws FactoryException
+    {
+        final CompoundCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof CompoundCRS) {
+            crs = (CompoundCRS) cached;
+        } else {
+            crs = getBackingStore().createCompoundCRS(code);
+        }
+        objectCache.put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a derived coordinate reference system from a code.
+     */
+    @Override
+    public synchronized DerivedCRS createDerivedCRS(final String code)
+            throws FactoryException
+    {
+        final DerivedCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof DerivedCRS) {
+            crs = (DerivedCRS) cached;
+        } else {
+            crs = getBackingStore().createDerivedCRS(code);
+        }
+        objectCache.put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns an engineering coordinate reference system from a code.
+     */
+    @Override
+    public synchronized EngineeringCRS createEngineeringCRS(final String code)
+            throws FactoryException
+    {
+        final EngineeringCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof EngineeringCRS) {
+            crs = (EngineeringCRS) cached;
+        } else {
+            crs = getBackingStore().createEngineeringCRS(code);
+        }
+        objectCache.put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a geographic coordinate reference system from a code.
+     */
+    @Override
+    public synchronized GeographicCRS createGeographicCRS(final String code)
+            throws FactoryException
+    {
+        final GeographicCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof GeographicCRS) {
+            crs = (GeographicCRS) cached;
+        } else {
+            crs = getBackingStore().createGeographicCRS(code);
+        }
+        objectCache.put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a geocentric coordinate reference system from a code.
+     */
+    @Override
+    public synchronized GeocentricCRS createGeocentricCRS(final String code)
+            throws FactoryException
+    {
+        final GeocentricCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof GeocentricCRS) {
+            crs = (GeocentricCRS) cached;
+        } else {
+            crs = getBackingStore().createGeocentricCRS(code);
+        }
+        objectCache.put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns an image coordinate reference system from a code.
+     */
+    @Override
+    public synchronized ImageCRS createImageCRS(final String code)
+            throws FactoryException
+    {
+        final ImageCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof ImageCRS) {
+            crs = (ImageCRS) cached;
+        } else {
+            crs = getBackingStore().createImageCRS(code);
+        }
+        objectCache.put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a projected coordinate reference system from a code.
+     */
+    @Override
+    public synchronized ProjectedCRS createProjectedCRS(final String code)
+            throws FactoryException
+    {
+        final ProjectedCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof ProjectedCRS) {
+            crs = (ProjectedCRS) cached;
+        } else {
+            crs = getBackingStore().createProjectedCRS(code);
+        }
+        objectCache.put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a temporal coordinate reference system from a code.
+     */
+    @Override
+    public synchronized TemporalCRS createTemporalCRS(final String code)
+            throws FactoryException
+    {
+        final TemporalCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof TemporalCRS) {
+            crs = (TemporalCRS) cached;
+        } else {
+            crs = getBackingStore().createTemporalCRS(code);
+        }
+        objectCache.put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a vertical coordinate reference system from a code.
+     */
+    @Override
+    public synchronized VerticalCRS createVerticalCRS(final String code)
+            throws FactoryException
+    {
+        final VerticalCRS crs;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof VerticalCRS) {
+            crs = (VerticalCRS) cached;
+        } else {
+            crs = getBackingStore().createVerticalCRS(code);
+        }
+        objectCache.put(key, crs);
+        return crs;
+    }
+
+    /**
+     * Returns a parameter descriptor from a code.
+     */
+    @Override
+    public synchronized ParameterDescriptor createParameterDescriptor(final String code)
+            throws FactoryException
+    {
+        final ParameterDescriptor parameter;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof ParameterDescriptor) {
+            parameter = (ParameterDescriptor) cached;
+        } else {
+            parameter = getBackingStore().createParameterDescriptor(code);
+        }
+        objectCache.put(key, parameter);
+        return parameter;
+    }
+
+    /**
+     * Returns an operation method from a code.
+     */
+    @Override
+    public synchronized OperationMethod createOperationMethod(final String code)
+            throws FactoryException
+    {
+        final OperationMethod method;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof OperationMethod) {
+            method = (OperationMethod) cached;
+        } else {
+            method = getBackingStore().createOperationMethod(code);
+        }
+        objectCache.put(key, method);
+        return method;
+    }
+
+    /**
+     * Returns an operation from a single operation code.
+     */
+    @Override
+    public synchronized CoordinateOperation createCoordinateOperation(final String code)
+            throws FactoryException
+    {
+        final CoordinateOperation operation;
+        final String key = trimAuthority(code);
+        final Object cached = objectCache.get(key);
+        if (cached instanceof CoordinateOperation) {
+            operation = (CoordinateOperation) cached;
+        } else {
+            operation = getBackingStore().createCoordinateOperation(code);
+        }
+        objectCache.put(key, operation);
+        return operation;
+    }
+
+    /**
+     * Returns an operation from coordinate reference system codes.
+     */
+    @Override
+    public synchronized Set<CoordinateOperation> createFromCoordinateReferenceSystemCodes(
+                        final String sourceCode, final String targetCode)
+            throws FactoryException
+    {
+        final Set<CoordinateOperation> operations;
+        final CodePair key = new CodePair(trimAuthority(sourceCode), trimAuthority(targetCode));
+        final Object cached = objectCache.get(key);
+        if (cached instanceof CoordinateOperation) {
+            operations = (Set<CoordinateOperation>) cached;
+        } else {
+            operations = Collections.unmodifiableSet(getBackingStore()
+                         .createFromCoordinateReferenceSystemCodes(sourceCode, targetCode));
+        }
+        objectCache.put(key, operations);
+        return operations;
+    }
+
+    /**
+     * A pair of codes for operations to cache with
+     * {@link #createFromCoordinateReferenceSystemCodes}.
+     */
+    private static final class CodePair {
+        private final String source, target;
+
+        public CodePair(final String source, final String target) {
+            this.source = source;
+            this.target = target;
+        }
+
+        @Override
+        public int hashCode() {
+            int code = 0;
+            if (source!=null) code  = source.hashCode();
+            if (target!=null) code += target.hashCode() * 37;
+            return code;
+        }
+
+        @Override
+        public boolean equals(final Object other) {
+            if (other instanceof CodePair) {
+                final CodePair that = (CodePair) other;
+                return Utilities.equals(this.source, that.source) &&
+                       Utilities.equals(this.target, that.target);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return source + " \u21E8 " + target;
+        }
+    }
+
+    /**
+     * Returns a finder which can be used for looking up unidentified objects.
+     * The default implementation delegates lookup to the underlying backing
+     * store and caches the result.
+     */
+    @Override
+    public synchronized IdentifiedObjectFinder getIdentifiedObjectFinder(
+            final Class<? extends IdentifiedObject> type) throws FactoryException
+    {
+        return new Finder(getBackingStore().getIdentifiedObjectFinder(type));
+    }
+
+    /**
+     * An implementation of {@link IdentifiedObjectFinder} which delegates
+     * the work to the underlying backing store and caches the result.
+     * <p>
+     * <b>Implementation note:</b> we will create objects using directly the underlying backing
+     * store, not using the cache. This is because hundred of objects may be created during a
+     * scan while only one will be typically retained. We don't want to overload the cache with
+     * every false candidates that we encounter during the scan.
+     */
+    private final class Finder extends IdentifiedObjectFinder.Adapter {
+        /**
+         * Creates a finder for the underlying backing store.
+         */
+        Finder(final IdentifiedObjectFinder finder) {
+            super(finder);
+        }
+
+        /**
+         * Looks up an object from this authority factory which is equals, ignoring metadata,
+         * to the specified object. The default implementation performs the same lookup than
+         * the backing store and caches the result.
+         */
+        @Override
+        public IdentifiedObject find(final IdentifiedObject object) throws FactoryException {
+            /*
+             * Do not synchronize on 'BufferedAuthorityFactory.this'. This method may take a
+             * while to execute and we don't want to block other threads. The synchronizations
+             * in the 'create' methods and in the 'findPool' map should be suffisient.
+             *
+             * TODO: avoid to search for the same object twice. For now we consider that this
+             *       is not a big deal if the same object is searched twice; it is "just" a
+             *       waste of CPU.
+             */
+            IdentifiedObject candidate;
+            synchronized (findPool) {
+                candidate = findPool.get(object);
+            }
+            if (candidate == null) {
+                // Must delegates to 'finder' (not to 'super') in order to take
+                // advantage of the method overriden by AllAuthoritiesFactory.
+                candidate = finder.find(object);
+                if (candidate != null) {
+                    synchronized (findPool) {
+                        findPool.put(object, candidate);
+                    }
+                }
+            }
+            return candidate;
+        }
+
+        /**
+         * Returns the identifier for the specified object.
+         */
+        @Override
+        public String findIdentifier(final IdentifiedObject object) throws FactoryException {
+            IdentifiedObject candidate;
+            synchronized (findPool) {
+                candidate = findPool.get(object);
+            }
+            if (candidate != null) {
+                return getIdentifier(candidate);
+            }
+            // We don't rely on super-class implementation, because we want to
+            // take advantage of the method overriden by AllAuthoritiesFactory.
+            return finder.findIdentifier(object);
+        }
+    }
+
+    /**
+     * Releases resources immediately instead of waiting for the garbage collector.
+     */
+    @Override
+    public synchronized void dispose() throws FactoryException {
+        if (backingStore != null) {
+            backingStore.dispose();
+            backingStore = null;
+        }
+        objectCache.clear();
+        super.dispose();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/EsriExtension.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/EsriExtension.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/EsriExtension.java	(revision 28000)
@@ -0,0 +1,87 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.factory.epsg;
+
+import java.net.URL;
+
+import org.geotools.factory.Hints;
+import org.geotools.metadata.iso.citation.Citations;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+
+/**
+ * Extends the EPSG database with {@linkplain CoordinateReferenceSystem Coordinate Reference Systems}
+ * defined by ESRI. Those CRS will be registered both in {@code "ESRI"} and {@code "EPSG"} name space.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/epsg-extension/src/main/java/org/geotools/referencing/factory/epsg/EsriExtension.java $
+ * @version $Id: EsriExtension.java 37305 2011-05-25 05:57:57Z mbedward $
+ * @author Martin Desruisseaux
+ */
+public class EsriExtension extends FactoryUsingWKT { // NO_UCD
+    /**
+     * The default filename to read. This file will be searched in the
+     * {@code org/geotools/referencing/factory/espg} directory in the
+     * classpath or in a JAR file.
+     *
+     * @see #getDefinitionsURL
+     */
+    public static final String FILENAME = "esri.properties";
+
+    /**
+     * Constructs an authority factory using the default set of factories.
+     */
+    public EsriExtension() {
+        this(null);
+    }
+
+    /**
+     * Constructs an authority factory using a set of factories created from the specified hints.
+     * This constructor recognizes the {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS},
+     * {@link Hints#DATUM_FACTORY DATUM} and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM}
+     * {@code FACTORY} hints.
+     */
+    public EsriExtension(final Hints hints) {
+        super(hints, DEFAULT_PRIORITY - 5);
+    }
+
+    /**
+     * Returns the set of authorities to use as identifiers for the CRS to be created.
+     * The default implementation returns {@linkplain Citations#ESRI ESRI} and
+     * {@linkplain Citations#EPSG EPSG} authorities.
+     */
+    @Override
+    protected Citation[] getAuthorities() {
+        return new Citation[] {
+            Citations.ESRI,
+            Citations.EPSG
+        };
+    }
+
+    /**
+     * Returns the URL to the property file that contains CRS definitions.
+     * The default implementation returns the URL to the {@value #FILENAME} file.
+     *
+     * @return The URL, or {@code null} if none.
+     */
+    @Override
+    protected URL getDefinitionsURL() {
+        return EsriExtension.class.getResource(FILENAME);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/FactoryUsingWKT.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/FactoryUsingWKT.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/FactoryUsingWKT.java	(revision 28000)
@@ -0,0 +1,266 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.factory.epsg;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+import org.geotools.factory.Hints;
+import org.geotools.metadata.iso.citation.CitationImpl;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.factory.AbstractAuthorityFactory;
+import org.geotools.referencing.factory.DeferredAuthorityFactory;
+import org.geotools.referencing.factory.FactoryNotFoundException;
+import org.geotools.referencing.factory.PropertyAuthorityFactory;
+import org.geotools.referencing.factory.ReferencingFactoryContainer;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.LoggingKeys;
+import org.geotools.resources.i18n.Loggings;
+import org.geotools.util.logging.Logging;
+import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CRSAuthorityFactory;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+
+/**
+ * Authority factory for {@linkplain CoordinateReferenceSystem Coordinate Reference Systems}
+ * beyong the one defined in the EPSG database. This factory is used as a fallback when a
+ * requested code is not found in the EPSG database, or when there is no connection at all
+ * to the EPSG database. The additional CRS are defined as <cite>Well Known Text</cite> in
+ * a property file located by default in the {@code org.geotools.referencing.factory.epsg}
+ * package, and whose name should be {@value #FILENAME}. If no property file is found, the
+ * factory won't be activated. The property file can also be located in a custom directory;
+ * See {@link #getDefinitionsURL()} for more details.
+ * <p>
+ * This factory can also be used to provide custom extensions or overrides to a main EPSG factory.
+ * In order to provide a custom extension file, override the {@link #getDefinitionsURL()} method.
+ * In order to make the factory be an override, change the default priority by using the
+ * two arguments constructor (this factory defaults to {@link ThreadedEpsgFactory#PRIORITY} - 10,
+ * so it's used as an extension).
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingWKT.java $
+ * @version $Id: FactoryUsingWKT.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux
+ * @author Jody Garnett
+ * @author Rueben Schulz
+ * @author Andrea Aime
+ */
+public class FactoryUsingWKT extends DeferredAuthorityFactory implements CRSAuthorityFactory {
+    /**
+     * The authority. Will be created only when first needed.
+     *
+     * @see #getAuthority
+     */
+    private Citation authority;
+
+    /**
+     * The default filename to read. The default {@code FactoryUsingWKT} implementation will
+     * search for the first occurence of this file in the following places:
+     * <p>
+     * <ul>
+     *   <li>In the directory specified by the
+     *       {@value org.geotools.factory.GeoTools#CRS_DIRECTORY_KEY} system property.</li>
+     *   <li>In every {@code org/geotools/referencing/factory/espg} directories found on the
+     *       classpath.</li>
+     * </ul>
+     * <p>
+     * The filename part before the extension ({@code "epsg"}) denotes the authority namespace
+     * where to register the content of this file. The user-directory given by the system property
+     * may contains other property files for other authorities, like {@code "esri.properties"},
+     * but those additional authorities are not handled by the default {@code FactoryUsingWKT}
+     * class.
+     *
+     * @see #getDefinitionsURL
+     */
+    public static final String FILENAME = "epsg.properties";
+
+    /**
+     * The factories to be given to the backing store.
+     */
+    private final ReferencingFactoryContainer factories;
+
+    /**
+     * Default priority for this factory.
+     *
+     * @since 2.4
+     * @deprecated We will try to replace the priority mechanism by a better
+     *             one in a future Geotools version.
+     */
+    protected static final int DEFAULT_PRIORITY = (MAXIMUM_PRIORITY - 10) - 10;
+
+    /**
+     * Directory scanned for extra definitions.
+     */
+    private final File directory;
+
+    /**
+     * Constructs an authority factory using the default set of factories.
+     */
+    public FactoryUsingWKT() {
+        this(null);
+    }
+
+    /**
+     * Constructs an authority factory using a set of factories created from the specified hints.
+     * This constructor recognizes the {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS},
+     * {@link Hints#DATUM_FACTORY DATUM} and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM}
+     * {@code FACTORY} hints.
+     */
+    public FactoryUsingWKT(final Hints userHints) {
+        this(userHints, DEFAULT_PRIORITY);
+    }
+
+    /**
+     * Constructs an authority factory using the specified hints and priority.
+     */
+    protected FactoryUsingWKT(final Hints userHints, final int priority) {
+        super(userHints, priority);
+        factories = ReferencingFactoryContainer.instance(userHints);
+        Object hint = null;
+        if (userHints != null) {
+            hint = userHints.get(Hints.CRS_AUTHORITY_EXTRA_DIRECTORY);
+        }
+        if (hint instanceof File) {
+            directory = (File) hint;
+        } else if (hint instanceof String) {
+            directory = new File((String) hint);
+        } else {
+            directory = null;
+        }
+        hints.put(Hints.CRS_AUTHORITY_EXTRA_DIRECTORY, directory);
+        // Disposes the cached property file after at least 15 minutes of inactivity.
+        setTimeout(15 * 60 * 1000L);
+    }
+
+    /**
+     * Returns the authority. The default implementation returns the first citation returned
+     * by {@link #getAuthorities()}, with the addition of identifiers from all additional
+     * authorities returned by the above method.
+     *
+     * @see #getAuthorities
+     */
+    @Override
+    public synchronized Citation getAuthority() {
+        // No need to synchronize; this is not a big deal if we create this object twice.
+        if (authority == null) {
+            final Citation[] authorities = getAuthorities();
+            switch (authorities.length) {
+                case 0: authority = Citations.EPSG; break;
+                case 1: authority = authorities[0]; break;
+                default: {
+                    final CitationImpl c = new CitationImpl(authorities[0]);
+                    final Collection<Identifier> identifiers = c.getIdentifiers();
+                    for (int i=1; i<authorities.length; i++) {
+                        identifiers.addAll(authorities[i].getIdentifiers());
+                    }
+                    c.freeze();
+                    authority = c;
+                    break;
+                }
+            }
+        }
+        return authority;
+    }
+
+    /**
+     * Returns the set of authorities to use as {@linkplain CoordinateReferenceSystem#getIdentifiers
+     * identifiers} for the CRS to be created. This set is given to the
+     * {@linkplain PropertyAuthorityFactory#PropertyAuthorityFactory(ReferencingFactoryContainer,
+     * Citation[], URL) properties-backed factory constructor}.
+     * <p>
+     * The default implementation returns a singleton containing only {@linkplain Citations#EPSG
+     * EPSG}. Subclasses should override this method in order to enumerate all relevant authorities,
+     * with {@linkplain Citations#EPSG EPSG} in last position. For example {@link EsriExtension}
+     * returns {{@linkplain Citations#ESRI ESRI}, {@linkplain Citations#EPSG EPSG}}.
+     *
+     * @since 2.4
+     */
+    protected Citation[] getAuthorities() {
+        return new Citation[] {
+            Citations.EPSG
+        };
+    }
+
+    /**
+     * Returns the URL to the property file that contains CRS definitions.
+     * The default implementation performs the following search path:
+     * <ul>
+     *   <li>If a value is set for the {@value #CRS_DIRECTORY_KEY} system property key,
+     *       then the {@value #FILENAME} file will be searched in this directory.</li>
+     *   <li>If no value is set for the above-cited system property, or if no {@value #FILENAME}
+     *       file was found in that directory, then the first {@value #FILENAME} file found in
+     *       any {@code org/geotools/referencing/factory/epsg} directory on the classpath will
+     *       be used.</li>
+     *   <li>If no file was found on the classpath neither, then this factory will be disabled.</li>
+     * </ul>
+     *
+     * @return The URL, or {@code null} if none.
+     */
+    protected URL getDefinitionsURL() {
+        try {
+            if (directory != null) {
+                final File file = new File(directory, FILENAME);
+                if (file.isFile()) {
+                    return file.toURI().toURL();
+                }
+            }
+        } catch (SecurityException exception) {
+            Logging.unexpectedException(LOGGER, exception);
+        } catch (MalformedURLException exception) {
+            Logging.unexpectedException(LOGGER, exception);
+        }
+        return FactoryUsingWKT.class.getResource(FILENAME);
+    }
+
+    /**
+     * Creates the backing store authority factory.
+     *
+     * @return The backing store to uses in {@code createXXX(...)} methods.
+     * @throws FactoryNotFoundException if the no {@code epsg.properties} file has been found.
+     * @throws FactoryException if the constructor failed to find or read the file.
+     *         This exception usually has an {@link IOException} as its cause.
+     */
+    protected AbstractAuthorityFactory createBackingStore() throws FactoryException {
+        try {
+            URL url = getDefinitionsURL();
+            if (url == null) {
+                throw new FactoryNotFoundException(Errors.format(
+                        ErrorKeys.FILE_DOES_NOT_EXIST_$1, FILENAME));
+            }
+            final Iterator<? extends Identifier> ids = getAuthority().getIdentifiers().iterator();
+            final String authority = ids.hasNext() ? ids.next().getCode() : "EPSG";
+            final LogRecord record = Loggings.format(Level.CONFIG,
+                    LoggingKeys.USING_FILE_AS_FACTORY_$2, url.getPath(), authority);
+            record.setLoggerName(LOGGER.getName());
+            LOGGER.log(record);
+            return new PropertyAuthorityFactory(factories, getAuthorities(), url);
+        } catch (IOException exception) {
+            throw new FactoryException(Errors.format(ErrorKeys.CANT_READ_$1, FILENAME), exception);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/UnnamedExtension.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/UnnamedExtension.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/UnnamedExtension.java	(revision 28000)
@@ -0,0 +1,73 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.factory.epsg;
+
+import java.net.URL;
+
+import org.geotools.factory.Hints;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+
+/**
+ * Provides common {@linkplain CoordinateReferenceSystem Coordinate Reference Systems}
+ * not found in the standard EPSG database. Those CRS will be registered in
+ * {@code "EPSG"} name space.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/epsg-extension/src/main/java/org/geotools/referencing/factory/epsg/UnnamedExtension.java $
+ * @version $Id: UnnamedExtension.java 37305 2011-05-25 05:57:57Z mbedward $
+ * @author Andrea Aime
+ */
+public class UnnamedExtension extends FactoryUsingWKT { // NO_UCD
+    /**
+     * The default filename to read. This file will be searched in the
+     * {@code org/geotools/referencing/factory/espg} directory in the
+     * classpath or in a JAR file.
+     *
+     * @see #getDefinitionsURL
+     */
+    public static final String FILENAME = "unnamed.properties";
+
+    /**
+     * Constructs an authority factory using the default set of factories.
+     */
+    public UnnamedExtension() {
+        this(null);
+    }
+
+    /**
+     * Constructs an authority factory using a set of factories created from the specified hints.
+     * This constructor recognizes the {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS},
+     * {@link Hints#DATUM_FACTORY DATUM} and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM}
+     * {@code FACTORY} hints.
+     */
+    public UnnamedExtension(final Hints hints) {
+        super(hints, DEFAULT_PRIORITY - 2);
+    }
+
+    /**
+     * Returns the URL to the property file that contains CRS definitions.
+     * The default implementation returns the URL to the {@value #FILENAME} file.
+     *
+     * @return The URL, or {@code null} if none.
+     */
+    @Override
+    protected URL getDefinitionsURL() {
+        return UnnamedExtension.class.getResource(FILENAME);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/overview.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/overview.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/overview.html	(revision 28000)
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<!-- NOTE: This file was used to be "package.html" in the factory directory.
+           However, it caused javadoc aggregation to fail with the following
+           error message: Multiple sources of package comments found for
+           package "org.geotools.referencing.factory.epsg". -->
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.referencing.factory.epsg</TITLE>
+  </HEAD>
+  <BODY>
+  Allows the EPSG database to be used with the HSQL Java database as an Authority for GeoTools
+  CRS generation. At the difference of <CODE>epsg-access</CODE> and <CODE>epsg-postgresql</CODE>,
+  the <CODE>epsg-hsql</CODE> plugin contains a copy of the EPSG database. This plugin can work
+  "out of the box" without any specifial action on the user side.
+  
+  <h3>For More Information</h3>
+  The following links will prove useful:
+  <ul>
+    <li><a href="doc-files/HSQL.html">HSQL</a> - instructions for module maintainers</li>
+    <li><a href="http://www.epsg.org/">www.epsg.org</a></li>
+  </ul>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/epsg/package.html	(revision 28000)
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.referencing.factory.epsg</TITLE>
+  </HEAD>
+  <BODY>
+  {@linkplain org.opengis.referencing.AuthorityFactory Authority factories} for
+  the <A HREF="http://www.epsg.org">EPSG</A> database.
+
+  <P ALIGN="justify">EPSG codes are numerical identifiers. For example "4326" is the EPSG
+  identifier for the "WGS 84" geographic CRS. However, the default implementation accepts
+  names as well as numeric identifiers. For example "<cite>NTF (Paris) / France I</cite>"
+  and {@code "27581"} both fetchs the same object. Note that names may be ambiguous since
+  the same name may be used for more than one object. This is the case of "WGS 84" for example.
+  If such an ambiguity is found, an exception will be thrown.</P>
+
+  <P ALIGN="justify">An EPSG authority factory is created using the following code:</P>
+  <BLOCKQUOTE><CODE>{@linkplain org.opengis.referencing.crs.CRSAuthorityFactory} factory =
+  {@linkplain org.geotools.referencing.ReferencingFactoryFinder}.getCRSAuthorityFactory("EPSG", null);</CODE></BLOCKQUOTE>
+
+  <P ALIGN="justify">This package provides the general framework for accessing an EPSG database,
+  but the actual connection to a database requires the existence of an EPSG plugin in the classpath.
+  Otherwise, a {@link org.geotools.factory.FactoryNotFoundException} will be thrown. Available plugins are:</P>
+
+  <TABLE ALIGN="center" BORDER="1" CELLPADDING="3">
+    <TR>
+      <TH>Required software</TH>
+      <TH>Data source</TH>
+      <TH>Plugin / JAR file</TH>
+      <TH>Additional notes</TH>
+    </TR>
+    <TR>
+      <TD>MS-Access ODBC driver</TD>
+      <TD>{@link org.geotools.referencing.factory.epsg.FactoryOnAccess}</TD>
+      <TD>{@code epsg-access}</TD>
+      <TD>See <A HREF="doc-files/Access.html">installation instructions</A></TD>
+    </TR>
+    <TR>
+      <TD>HSQL embedded database</TD>
+      <TD>{@link org.geotools.referencing.factory.epsg.FactoryOnHSQL}</TD>
+      <TD>{@code epsg-hsql}</TD>
+      <TD><A HREF="doc-files/HSQL.html">Note for module mainteners</A></TD>
+    </TR>
+    <TR>
+      <TD>PostgreSQL database</TD>
+      <TD>{@link org.geotools.referencing.factory.epsg.FactoryOnPostgreSQL}</TD>
+      <TD>{@code epsg-postgresql}</TD>
+      <TD><A HREF="doc-files/PostgreSQL.html">Note for module mainteners</A></TD>
+    </TR>
+  </TABLE>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/factory/package.html	(revision 28000)
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.referencing.factory</TITLE>
+  </HEAD>
+  <BODY>
+  Base classes for {@linkplain org.opengis.referencing.Factory factories} and
+  {@linkplain org.opengis.referencing.AuthorityFactory authority factories}.
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/AbstractCoordinateOperation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/AbstractCoordinateOperation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/AbstractCoordinateOperation.java	(revision 28000)
@@ -0,0 +1,421 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.crs.AbstractDerivedCRS;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.quality.PositionalAccuracy;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.ConicProjection;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.CylindricalProjection;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.Operation;
+import org.opengis.referencing.operation.PlanarProjection;
+import org.opengis.referencing.operation.Projection;
+import org.opengis.referencing.operation.Transformation;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * Establishes an association between a source and a target coordinate reference system,
+ * and provides a {@linkplain MathTransform transform} for transforming coordinates in
+ * the source CRS to coordinates in the target CRS. Many but not all coordinate operations (from
+ * {@linkplain CoordinateReferenceSystem coordinate reference system} <VAR>A</VAR> to
+ * {@linkplain CoordinateReferenceSystem coordinate reference system} <VAR>B</VAR>)
+ * also uniquely define the inverse operation (from
+ * {@linkplain CoordinateReferenceSystem coordinate reference system} <VAR>B</VAR> to
+ * {@linkplain CoordinateReferenceSystem coordinate reference system} <VAR>A</VAR>).
+ * In some cases, the operation method algorithm for the inverse operation is the same
+ * as for the forward algorithm, but the signs of some operation parameter values must
+ * be reversed. In other cases, different algorithms are required for the forward and
+ * inverse operations, but the same operation parameter values are used. If (some)
+ * entirely different parameter values are needed, a different coordinate operation
+ * shall be defined.
+ * <p>
+ * This class is conceptually <cite>abstract</cite>, even if it is technically possible to
+ * instantiate it. Typical applications should create instances of the most specific subclass with
+ * {@code Default} prefix instead. An exception to this rule may occurs when it is not possible to
+ * identify the exact type.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/AbstractCoordinateOperation.java $
+ * @version $Id: AbstractCoordinateOperation.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class AbstractCoordinateOperation extends AbstractIdentifiedObject
+        implements CoordinateOperation
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 1237358357729193885L;
+
+    /**
+     * An empty array of positional accuracy. This is usefull for fetching accuracies as an array,
+     * using the following idiom:
+     * <blockquote><pre>
+     * {@linkplain #getPositionalAccuracy()}.toArray(EMPTY_ACCURACY_ARRAY);
+     * </pre></blockquote>
+     */
+    public static final PositionalAccuracy[] EMPTY_ACCURACY_ARRAY = new PositionalAccuracy[0];
+
+    /**
+     * List of localizable properties. To be given to {@link AbstractIdentifiedObject} constructor.
+     */
+    private static final String[] LOCALIZABLES = {SCOPE_KEY};
+
+    /**
+     * The source CRS, or {@code null} if not available.
+     */
+    protected final CoordinateReferenceSystem sourceCRS;
+
+    /**
+     * The target CRS, or {@code null} if not available.
+     */
+    protected final CoordinateReferenceSystem targetCRS;
+
+    /**
+     * Version of the coordinate transformation
+     * (i.e., instantiation due to the stochastic nature of the parameters).
+     */
+    final String operationVersion;
+
+    /**
+     * Estimate(s) of the impact of this operation on point accuracy, or {@code null}
+     * if none.
+     */
+    private final Collection<PositionalAccuracy> coordinateOperationAccuracy;
+
+    /**
+     * Area in which this operation is valid, or {@code null} if not available.
+     */
+    protected final Extent domainOfValidity;
+
+    /**
+     * Description of domain of usage, or limitations of usage, for which this operation is valid.
+     */
+    private final InternationalString scope;
+
+    /**
+     * Transform from positions in the {@linkplain #getSourceCRS source coordinate reference system}
+     * to positions in the {@linkplain #getTargetCRS target coordinate reference system}.
+     */
+    protected final MathTransform transform;
+
+    /**
+     * Constructs a new coordinate operation with the same values than the specified
+     * defining conversion, together with the specified source and target CRS. This
+     * constructor is used by {@link DefaultConversion} only.
+     */
+    AbstractCoordinateOperation(final Conversion               definition,
+                                final CoordinateReferenceSystem sourceCRS,
+                                final CoordinateReferenceSystem targetCRS,
+                                final MathTransform             transform)
+    {
+        super(definition);
+        this.sourceCRS                   = sourceCRS;
+        this.targetCRS                   = targetCRS;
+        this.operationVersion            = definition.getOperationVersion();
+        this.coordinateOperationAccuracy = definition.getCoordinateOperationAccuracy();
+        this.domainOfValidity            = definition.getDomainOfValidity();
+        this.scope                       = definition.getScope();
+        this.transform                   = transform;
+    }
+
+    /**
+     * Constructs a coordinate operation from a set of properties.
+     * The properties given in argument follow the same rules than for the
+     * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
+     * Additionally, the following properties are understood by this construtor:
+     * <p>
+     * <table border='1'>
+     *   <tr bgcolor="#CCCCFF" class="TableHeadingColor">
+     *     <th nowrap>Property name</th>
+     *     <th nowrap>Value type</th>
+     *     <th nowrap>Value given to</th>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@value org.opengis.referencing.operation.CoordinateOperation#OPERATION_VERSION_KEY}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getOperationVersion}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@value org.opengis.referencing.operation.CoordinateOperation#COORDINATE_OPERATION_ACCURACY_KEY}&nbsp;</td>
+     *     <td nowrap>&nbsp;<code>{@linkplain PositionalAccuracy}[]</code>&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getCoordinateOperationAccuracy}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@value org.opengis.referencing.operation.CoordinateOperation#DOMAIN_OF_VALIDITY_KEY}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link Extent}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getDomainOfValidity}</td>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@value org.opengis.referencing.operation.CoordinateOperation#SCOPE_KEY}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String} or {@link InternationalString}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getScope}</td>
+     *   </tr>
+     * </table>
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param sourceCRS The source CRS.
+     * @param targetCRS The target CRS.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source CRS}
+     *                  to positions in the {@linkplain #getTargetCRS target CRS}.
+     */
+    public AbstractCoordinateOperation(final Map<String,?>            properties,
+                                       final CoordinateReferenceSystem sourceCRS,
+                                       final CoordinateReferenceSystem targetCRS,
+                                       final MathTransform             transform)
+    {
+        this(properties, new HashMap<String,Object>(), sourceCRS, targetCRS, transform);
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private AbstractCoordinateOperation(final Map<String,?>            properties,
+                                        final Map<String,Object>    subProperties,
+                                        final CoordinateReferenceSystem sourceCRS,
+                                        final CoordinateReferenceSystem targetCRS,
+                                        final MathTransform             transform)
+    {
+        super(properties, subProperties, LOCALIZABLES);
+        PositionalAccuracy[] positionalAccuracy;
+        domainOfValidity   = (Extent)               subProperties.get(DOMAIN_OF_VALIDITY_KEY);
+        scope              = (InternationalString)  subProperties.get(SCOPE_KEY);
+        operationVersion   = (String)               subProperties.get(OPERATION_VERSION_KEY);
+        positionalAccuracy = (PositionalAccuracy[]) subProperties.get(COORDINATE_OPERATION_ACCURACY_KEY);
+        if (positionalAccuracy==null || positionalAccuracy.length==0) {
+            positionalAccuracy = null;
+        } else {
+            positionalAccuracy = positionalAccuracy.clone();
+            for (int i=0; i<positionalAccuracy.length; i++) {
+                ensureNonNull(COORDINATE_OPERATION_ACCURACY_KEY, positionalAccuracy, i);
+            }
+        }
+        this.coordinateOperationAccuracy = asSet(positionalAccuracy);
+        this.sourceCRS = sourceCRS;
+        this.targetCRS = targetCRS;
+        this.transform = transform;
+        validate();
+    }
+
+    /**
+     * Checks the validity of this operation. This method is invoked by the constructor after
+     * every fields have been assigned. It can be overriden by subclasses if different rules
+     * should be applied.
+     * <p>
+     * {@link DefaultConversion} overrides this method in order to allow null values, providing
+     * that all of {@code transform}, {@code sourceCRS} and {@code targetCRS} are null together.
+     * Note that null values are not allowed for transformations, so {@link DefaultTransformation}
+     * does not override this method.
+     *
+     * @throws IllegalArgumentException if at least one of {@code transform}, {@code sourceCRS}
+     *         or {@code targetCRS} is invalid. We throw this kind of exception rather than
+     *         {@link IllegalStateException} because this method is invoked by the constructor
+     *         for checking argument validity.
+     */
+    void validate() throws IllegalArgumentException {
+        ensureNonNull ("sourceCRS", transform);
+        ensureNonNull ("targetCRS", transform);
+        ensureNonNull ("transform", transform);
+        checkDimension("sourceCRS", sourceCRS, transform.getSourceDimensions());
+        checkDimension("targetCRS", targetCRS, transform.getTargetDimensions());
+    }
+
+    /**
+     * Checks if a reference coordinate system has the expected number of dimensions.
+     *
+     * @param name     The argument name.
+     * @param crs      The coordinate reference system to check.
+     * @param expected The expected number of dimensions.
+     */
+    private static void checkDimension(final String name,
+                                       final CoordinateReferenceSystem crs,
+                                       final int expected)
+    {
+        final int actual = crs.getCoordinateSystem().getDimension();
+        if (actual != expected) {
+            throw new IllegalArgumentException(Errors.format(
+                    ErrorKeys.MISMATCHED_DIMENSION_$3, name, actual, expected));
+        }
+    }
+
+    /**
+     * Returns the source CRS.
+     */
+    public CoordinateReferenceSystem getSourceCRS() {
+        return sourceCRS;
+    }
+
+    /**
+     * Returns the target CRS.
+     */
+    public CoordinateReferenceSystem getTargetCRS() {
+        return targetCRS;
+    }
+
+    /**
+     * Version of the coordinate transformation (i.e., instantiation due to the stochastic
+     * nature of the parameters). Mandatory when describing a transformation, and should not
+     * be supplied for a conversion.
+     *
+     * @return The coordinate operation version, or {@code null} in none.
+     */
+    public String getOperationVersion() {
+        return operationVersion;
+    }
+
+    /**
+     * Estimate(s) of the impact of this operation on point accuracy. Gives
+     * position error estimates for target coordinates of this coordinate
+     * operation, assuming no errors in source coordinates.
+     *
+     * @return The position error estimates, or an empty collection if not available.
+     *
+     * @see #getAccuracy()
+     *
+     * @since 2.4
+     */
+    public Collection<PositionalAccuracy> getCoordinateOperationAccuracy() {
+        if (coordinateOperationAccuracy == null) {
+            return Collections.emptySet();
+        }
+        return coordinateOperationAccuracy;
+    }
+
+    /**
+     * Area or region or timeframe in which this coordinate operation is valid.
+     * Returns {@code null} if not available.
+     *
+     * @since 2.4
+     */
+    public Extent getDomainOfValidity() {
+        return domainOfValidity;
+    }
+
+    /**
+     * Description of domain of usage, or limitations of usage, for which this operation is valid.
+     */
+    public InternationalString getScope() {
+        return scope;
+    }
+
+    /**
+     * Gets the math transform. The math transform will transform positions in the
+     * {@linkplain #getSourceCRS source coordinate reference system} into positions
+     * in the {@linkplain #getTargetCRS target coordinate reference system}.
+     */
+    public MathTransform getMathTransform() {
+        return transform;
+    }
+
+    /**
+     * Returns the most specific GeoAPI interface implemented by the specified operation.
+     *
+     * @param  object A coordinate operation.
+     * @return The most specific GeoAPI interface
+     *         (e.g. <code>{@linkplain Transformation}.class</code>).
+     */
+    public static Class<? extends CoordinateOperation> getType(final CoordinateOperation object) {
+        if (object instanceof        Transformation) return        Transformation.class;
+        if (object instanceof       ConicProjection) return       ConicProjection.class;
+        if (object instanceof CylindricalProjection) return CylindricalProjection.class;
+        if (object instanceof      PlanarProjection) return      PlanarProjection.class;
+        if (object instanceof            Projection) return            Projection.class;
+        if (object instanceof            Conversion) return            Conversion.class;
+        if (object instanceof             Operation) return             Operation.class;
+        return CoordinateOperation.class;
+    }
+
+    /**
+     * Compares this coordinate operation with the specified object for equality.
+     * If {@code compareMetadata} is {@code true}, then all available properties are
+     * compared including {@linkplain #getDomainOfValidity domain of validity} and
+     * {@linkplain #getScope scope}.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            final AbstractCoordinateOperation that = (AbstractCoordinateOperation) object;
+            if (equals(this.sourceCRS, that.sourceCRS, compareMetadata) &&
+                Utilities.equals(this.transform, that.transform))
+                // See comment in DefaultOperation.equals(...) about why we compare MathTransform.
+            {
+                if (compareMetadata) {
+                    if (!Utilities.equals(this.domainOfValidity, that.domainOfValidity) ||
+                        !Utilities.equals(this.scope, that.scope) ||
+                        !Utilities.equals(this.coordinateOperationAccuracy, that.coordinateOperationAccuracy))
+                    {
+                        return false;
+                    }
+                }
+                /*
+                 * Avoid never-ending recursivity: AbstractDerivedCRS has a 'conversionFromBase'
+                 * field that is set to this AbstractCoordinateOperation.
+                 */
+                final Boolean comparing = AbstractDerivedCRS._COMPARING.get();
+                if (comparing!=null && comparing.booleanValue()) {
+                    return true;
+                }
+                try {
+                    AbstractDerivedCRS._COMPARING.set(Boolean.TRUE);
+                    return equals(this.targetCRS, that.targetCRS, compareMetadata);
+                } finally {
+                    AbstractDerivedCRS._COMPARING.set(Boolean.FALSE);
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this coordinate operation.
+     */
+    @Override
+    public int hashCode() {
+        int code = (int)serialVersionUID;
+        if (sourceCRS != null) code ^= sourceCRS.hashCode();
+        if (targetCRS != null) code ^= targetCRS.hashCode();
+        if (transform != null) code ^= transform.hashCode();
+        return code;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/AbstractCoordinateOperationFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/AbstractCoordinateOperationFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/AbstractCoordinateOperationFactory.java	(revision 28000)
@@ -0,0 +1,693 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Collections;
+import java.awt.RenderingHints;
+import javax.measure.converter.ConversionException;
+
+import org.opengis.metadata.quality.PositionalAccuracy;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.*;
+import static org.opengis.referencing.IdentifiedObject.NAME_KEY;
+
+import org.geotools.factory.Hints;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.metadata.iso.quality.PositionalAccuracyImpl;
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.referencing.factory.ReferencingFactory;
+import org.geotools.referencing.factory.ReferencingFactoryContainer;
+import org.geotools.referencing.cs.AbstractCS;
+import org.geotools.referencing.operation.transform.ProjectiveTransform;
+import org.geotools.resources.Classes;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.geotools.util.CanonicalSet;
+import org.geotools.util.Utilities;
+
+import static org.geotools.referencing.CRS.equalsIgnoreMetadata;
+
+
+/**
+ * Base class for coordinate operation factories. This class provides helper methods for the
+ * construction of building blocks. It doesn't figure out any operation path by itself. This
+ * more "intelligent" job is left to subclasses.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/AbstractCoordinateOperationFactory.java $
+ * @version $Id: AbstractCoordinateOperationFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public abstract class AbstractCoordinateOperationFactory extends ReferencingFactory
+        implements CoordinateOperationFactory
+{
+    /**
+     * The identifier for an identity operation.
+     */
+    protected static final ReferenceIdentifier IDENTITY =
+            new NamedIdentifier(Citations.GEOTOOLS,
+                Vocabulary.formatInternational(VocabularyKeys.IDENTITY));
+
+    /**
+     * The identifier for conversion using an affine transform for axis swapping and/or
+     * unit conversions.
+     */
+    protected static final ReferenceIdentifier AXIS_CHANGES =
+            new NamedIdentifier(Citations.GEOTOOLS,
+                Vocabulary.formatInternational(VocabularyKeys.AXIS_CHANGES));
+
+    /**
+     * The identifier for a transformation which is a datum shift.
+     *
+     * @see PositionalAccuracyImpl#DATUM_SHIFT_APPLIED
+     */
+    protected static final ReferenceIdentifier DATUM_SHIFT =
+            new NamedIdentifier(Citations.GEOTOOLS,
+                Vocabulary.formatInternational(VocabularyKeys.DATUM_SHIFT));
+
+    /**
+     * The identifier for a transformation which is a datum shift without
+     * {@linkplain org.geotools.referencing.datum.BursaWolfParameters Bursa Wolf parameters}.
+     * Only the changes in ellipsoid axis-length are taken in account. Such ellipsoid shifts
+     * are approximative and may have 1 kilometer error. This transformation is allowed
+     * only if the factory was created with {@link Hints#LENIENT_DATUM_SHIFT} set to
+     * {@link Boolean#TRUE}.
+     *
+     * @see PositionalAccuracyImpl#DATUM_SHIFT_OMITTED
+     */
+    protected static final ReferenceIdentifier ELLIPSOID_SHIFT =
+            new NamedIdentifier(Citations.GEOTOOLS,
+                Vocabulary.formatInternational(VocabularyKeys.ELLIPSOID_SHIFT));
+
+    /**
+     * The identifier for a geocentric conversion.
+     */
+    protected static final ReferenceIdentifier GEOCENTRIC_CONVERSION =
+            new NamedIdentifier(Citations.GEOTOOLS,
+                Vocabulary.formatInternational(VocabularyKeys.GEOCENTRIC_TRANSFORM));
+
+    /**
+     * The identifier for an inverse operation.
+     */
+    protected static final ReferenceIdentifier INVERSE_OPERATION =
+            new NamedIdentifier(Citations.GEOTOOLS,
+                Vocabulary.formatInternational(VocabularyKeys.INVERSE_OPERATION));
+
+    /**
+     * The set of helper methods on factories.
+     *
+     * @see #getFactoryGroup
+     */
+    private final ReferencingFactoryContainer factories;
+
+    /**
+     * The underlying math transform factory. This factory is used
+     * for constructing {@link MathTransform} objects for all
+     * {@linkplain CoordinateOperation coordinate operations}.
+     *
+     * @see #getMathTransformFactory
+     */
+    private final MathTransformFactory mtFactory;
+
+    /**
+     * A pool of coordinate operation. This pool is used in order
+     * to returns instance of existing operations when possible.
+     */
+    private final CanonicalSet<CoordinateOperation> pool =
+            CanonicalSet.newInstance(CoordinateOperation.class);
+
+    /**
+     * Tells if {@link FactoryGroup#hints} has been invoked. It must be invoked exactly once,
+     * but can't be invoked in the constructor because it causes a {@link StackOverflowError}
+     * in some situations.
+     */
+    private boolean hintsInitialized;
+
+    /**
+     * Constructs a coordinate operation factory using the specified hints and priority.
+     * This constructor recognizes the {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS},
+     * {@link Hints#DATUM_FACTORY DATUM} and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM}
+     * {@code FACTORY} hints.
+     *
+     * @param userHints The hints, or {@code null} if none.
+     * @param priority The priority for this factory, as a number between
+     *        {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
+     *        {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
+     *
+     * @since 2.2
+     */
+    public AbstractCoordinateOperationFactory(final Hints userHints, final int priority) {
+        super(priority);
+        factories = ReferencingFactoryContainer.instance(userHints);
+        mtFactory = factories.getMathTransformFactory();
+    }
+
+    /**
+     * If the specified factory is an instance of {@code AbstractCoordinateOperationFactory},
+     * fetch the {@link FactoryGroup} from this instance instead of from the hints. This
+     * constructor is strictly reserved for factory subclasses that are wrapper around an
+     * other factory, like {@link BufferedCoordinateOperationFactory}.
+     */
+    AbstractCoordinateOperationFactory(final CoordinateOperationFactory factory,
+                                       final Hints hints, final int priority)
+    {
+        super(priority);
+        if (factory instanceof AbstractCoordinateOperationFactory) {
+            factories = ((AbstractCoordinateOperationFactory) factory).getFactoryContainer();
+        } else {
+            factories = ReferencingFactoryContainer.instance(hints);
+        }
+        mtFactory = factories.getMathTransformFactory();
+    }
+
+    /**
+     * Returns the implementation hints for this factory. The returned map contains values for
+     * {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS}, {@link Hints#DATUM_FACTORY DATUM}
+     * and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM} {@code FACTORY} hints. Other values
+     * may be provided as well, at implementation choice.
+     */
+    @Override
+    public Map<RenderingHints.Key,?> getImplementationHints() {
+        synchronized (hints) { // Note: avoid lock on public object.
+            if (!hintsInitialized) {
+                initializeHints();
+                hintsInitialized = true; // Set only after success.
+            }
+        }
+        return super.getImplementationHints();
+    }
+
+    /**
+     * Invoked when the {@link #hints} map should be initialized. This method may
+     * be overridden by subclasses like {@link BufferedCoordinateOperationFactory}.
+     */
+    void initializeHints() {
+        assert Thread.holdsLock(hints);
+        final ReferencingFactoryContainer factories = getFactoryContainer();
+        hints.putAll(factories.getImplementationHints());
+    }
+
+    /**
+     * Returns the underlying math transform factory. This factory
+     * is used for constructing {@link MathTransform} objects for
+     * all {@linkplain CoordinateOperation coordinate operations}.
+     *
+     * @return The underlying math transform factory.
+     */
+    public final MathTransformFactory getMathTransformFactory() {
+        return mtFactory;
+    }
+
+    /**
+     * Returns the set of helper methods on factories.
+     */
+    final ReferencingFactoryContainer getFactoryContainer() {
+        return factories;
+    }
+
+    /**
+     * Returns an affine transform between two coordinate systems. Only units and
+     * axis order (e.g. transforming from (NORTH,WEST) to (EAST,NORTH)) are taken
+     * in account.
+     * <p>
+     * Example: If coordinates in {@code sourceCS} are (x,y) pairs in metres and
+     * coordinates in {@code targetCS} are (-y,x) pairs in centimetres, then the
+     * transformation can be performed as below:
+     *
+     * <pre><blockquote>
+     *          [-y(cm)]   [ 0  -100    0 ] [x(m)]
+     *          [ x(cm)] = [ 100   0    0 ] [y(m)]
+     *          [ 1    ]   [ 0     0    1 ] [1   ]
+     * </blockquote></pre>
+     *
+     * @param  sourceCS The source coordinate system.
+     * @param  targetCS The target coordinate system.
+     * @return The transformation from {@code sourceCS} to {@code targetCS} as
+     *         an affine transform. Only axis orientation and units are taken in account.
+     * @throws OperationNotFoundException If the affine transform can't be constructed.
+     *
+     * @see AbstractCS#swapAndScaleAxis
+     */
+    protected Matrix swapAndScaleAxis(final CoordinateSystem sourceCS,
+                                      final CoordinateSystem targetCS)
+            throws OperationNotFoundException
+    {
+        try {
+            return AbstractCS.swapAndScaleAxis(sourceCS,targetCS);
+        } catch (IllegalArgumentException exception) {
+            throw new OperationNotFoundException(getErrorMessage(sourceCS, targetCS), exception);
+        } catch (ConversionException exception) {
+            throw new OperationNotFoundException(getErrorMessage(sourceCS, targetCS), exception);
+        }
+        // No attempt to catch ClassCastException since such
+        // exception would indicates a programming error.
+    }
+
+    /**
+     * Returns the specified identifier in a map to be given to coordinate operation constructors.
+     * In the special case where the {@code name} identifier is {@link #DATUM_SHIFT} or
+     * {@link #ELLIPSOID_SHIFT}, the map will contains extra informations like positional
+     * accuracy.
+     *
+     * @todo In the datum shift case, an operation version is mandatory but unknow at this time.
+     *       However, we noticed that the EPSG database do not always defines a version neither.
+     *       Consequently, the Geotools implementation relax the rule requirying an operation
+     *       version and we do not try to provide this information here for now.
+     */
+    private static Map<String,Object> getProperties(final ReferenceIdentifier name) {
+        final Map<String,Object> properties;
+        if (name==DATUM_SHIFT || name==ELLIPSOID_SHIFT) {
+            properties = new HashMap<String,Object>(4);
+            properties.put(NAME_KEY, name);
+            properties.put(CoordinateOperation.COORDINATE_OPERATION_ACCURACY_KEY,
+                  new PositionalAccuracy[] {
+                      name==DATUM_SHIFT ? PositionalAccuracyImpl.DATUM_SHIFT_APPLIED
+                                        : PositionalAccuracyImpl.DATUM_SHIFT_OMITTED});
+        } else {
+            properties = Collections.singletonMap(NAME_KEY, (Object) name);
+        }
+        return properties;
+    }
+
+    /**
+     * Creates a coordinate operation from a matrix, which usually describes an affine tranform.
+     * A default {@link OperationMethod} object is given to this transform. In the special case
+     * where the {@code name} identifier is {@link #DATUM_SHIFT} or {@link #ELLIPSOID_SHIFT},
+     * the operation will be an instance of {@link Transformation} instead of the usual
+     * {@link Conversion}.
+     *
+     * @param  name      The identifier for the operation to be created.
+     * @param  sourceCRS The source coordinate reference system.
+     * @param  targetCRS The target coordinate reference system.
+     * @param  matrix    The matrix which describe an affine transform operation.
+     * @return The conversion or transformation.
+     * @throws FactoryException if the operation can't be created.
+     */
+    protected CoordinateOperation createFromAffineTransform(
+                                  final ReferenceIdentifier       name,
+                                  final CoordinateReferenceSystem sourceCRS,
+                                  final CoordinateReferenceSystem targetCRS,
+                                  final Matrix                    matrix)
+            throws FactoryException
+    {
+        final MathTransform transform = mtFactory.createAffineTransform(matrix);
+        final Map<String,?> properties = getProperties(name);
+        final Class<? extends Operation> type =
+                properties.containsKey(CoordinateOperation.COORDINATE_OPERATION_ACCURACY_KEY)
+                           ? Transformation.class : Conversion.class;
+        return createFromMathTransform(properties, sourceCRS, targetCRS, transform,
+               ProjectiveTransform.ProviderAffine.getProvider(transform.getSourceDimensions(),
+                                                              transform.getTargetDimensions()), type);
+    }
+
+    /**
+     * Creates a coordinate operation from a set of parameters.
+     * The {@linkplain OperationMethod operation method} is inferred automatically,
+     * if possible.
+     *
+     * @param  name       The identifier for the operation to be created.
+     * @param  sourceCRS  The source coordinate reference system.
+     * @param  targetCRS  The target coordinate reference system.
+     * @param  parameters The parameters.
+     * @return The conversion or transformation.
+     * @throws FactoryException if the operation can't be created.
+     */
+    protected CoordinateOperation createFromParameters(
+                                  final ReferenceIdentifier       name,
+                                  final CoordinateReferenceSystem sourceCRS,
+                                  final CoordinateReferenceSystem targetCRS,
+                                  final ParameterValueGroup       parameters)
+            throws FactoryException
+    {
+        final Map<String,?> properties = getProperties(name);
+        final MathTransform transform = mtFactory.createParameterizedTransform(parameters);
+        final OperationMethod  method = mtFactory.getLastMethodUsed();
+        return createFromMathTransform(properties, sourceCRS, targetCRS, transform,
+                                       method, Operation.class);
+    }
+
+    /**
+     * Creates a coordinate operation from a math transform.
+     *
+     * @param  name       The identifier for the operation to be created.
+     * @param  sourceCRS  The source coordinate reference system.
+     * @param  targetCRS  The destination coordinate reference system.
+     * @param  transform  The math transform.
+     * @return A coordinate operation using the specified math transform.
+     * @throws FactoryException if the operation can't be constructed.
+     */
+    protected CoordinateOperation createFromMathTransform(
+                                  final ReferenceIdentifier       name,
+                                  final CoordinateReferenceSystem sourceCRS,
+                                  final CoordinateReferenceSystem targetCRS,
+                                  final MathTransform             transform)
+            throws FactoryException
+    {
+        return createFromMathTransform(Collections.singletonMap(NAME_KEY, name),
+                                       sourceCRS, targetCRS, transform, null,
+                                       CoordinateOperation.class);
+    }
+
+    /**
+     * Creates a coordinate operation from a math transform.
+     * If the specified math transform is already a coordinate operation, and if source
+     * and target CRS match, then {@code transform} is returned with no change.
+     * Otherwise, a new coordinate operation is created.
+     *
+     * @param  properties The properties to give to the operation.
+     * @param  sourceCRS  The source coordinate reference system.
+     * @param  targetCRS  The destination coordinate reference system.
+     * @param  transform  The math transform.
+     * @param  method     The operation method, or {@code null}.
+     * @param  type       The required super-class (e.g. <code>{@linkplain Transformation}.class</code>).
+     * @return A coordinate operation using the specified math transform.
+     * @throws FactoryException if the operation can't be constructed.
+     */
+    protected CoordinateOperation createFromMathTransform(
+                                  final Map<String,?>             properties,
+                                  final CoordinateReferenceSystem sourceCRS,
+                                  final CoordinateReferenceSystem targetCRS,
+                                  final MathTransform             transform,
+                                  final OperationMethod           method,
+                                  final Class<? extends CoordinateOperation> type)
+            throws FactoryException
+    {
+        CoordinateOperation operation;
+        if (transform instanceof CoordinateOperation) {
+            operation = (CoordinateOperation) transform;
+            if (Utilities.equals(operation.getSourceCRS(),     sourceCRS) &&
+                Utilities.equals(operation.getTargetCRS(),     targetCRS) &&
+                Utilities.equals(operation.getMathTransform(), transform))
+            {
+                if (operation instanceof Operation) {
+                    if (Utilities.equals(((Operation) operation).getMethod(), method)) {
+                        return operation;
+                    }
+                } else {
+                    return operation;
+                }
+            }
+        }
+        operation = DefaultOperation.create(properties, sourceCRS, targetCRS, transform, method, type);
+        operation = pool.unique(operation);
+        return operation;
+    }
+
+    /**
+     * Creates a concatenated operation from a sequence of operations.
+     *
+     * @param  properties Set of properties. Should contains at least {@code "name"}.
+     * @param  operations The sequence of operations.
+     * @return The concatenated operation.
+     * @throws FactoryException if the object creation failed.
+     */
+    public CoordinateOperation createConcatenatedOperation(
+                        final Map<String,?> properties,
+                        final CoordinateOperation[] operations) throws FactoryException
+    {
+        CoordinateOperation operation;
+        operation = new DefaultConcatenatedOperation(properties, operations, mtFactory);
+        operation = pool.unique(operation);
+        return operation;
+    }
+
+    /**
+     * Concatenate two operation steps. If an operation is an {@link #AXIS_CHANGES},
+     * it will be included as part of the second operation instead of creating an
+     * {@link ConcatenatedOperation}. If a concatenated operation is created, it
+     * will get an automatically generated name.
+     *
+     * @param  step1 The first  step, or {@code null} for the identity operation.
+     * @param  step2 The second step, or {@code null} for the identity operation.
+     * @return A concatenated operation, or {@code null} if all arguments was nul.
+     * @throws FactoryException if the operation can't be constructed.
+     */
+    protected CoordinateOperation concatenate(final CoordinateOperation step1,
+                                              final CoordinateOperation step2)
+            throws FactoryException
+    {
+        if (step1 == null) return step2;
+        if (step2 == null) return step1;
+        if (isIdentity(step1)) return step2;
+        if (isIdentity(step2)) return step1;
+        final MathTransform mt1 = step1.getMathTransform();
+        final MathTransform mt2 = step2.getMathTransform();
+        final CoordinateReferenceSystem sourceCRS = step1.getSourceCRS();
+        final CoordinateReferenceSystem targetCRS = step2.getTargetCRS();
+        CoordinateOperation step = null;
+        if (step1.getName()==AXIS_CHANGES && mt1.getSourceDimensions()==mt1.getTargetDimensions()) step = step2;
+        if (step2.getName()==AXIS_CHANGES && mt2.getSourceDimensions()==mt2.getTargetDimensions()) step = step1;
+        if (step instanceof Operation) {
+            /*
+             * Applies only on operation in order to avoid merging with PassThroughOperation.
+             * Also applies only if the transform to hide has identical source and target
+             * dimensions in order to avoid mismatch with the method's dimensions.
+             */
+            return createFromMathTransform(AbstractIdentifiedObject.getProperties(step),
+                   sourceCRS, targetCRS, mtFactory.createConcatenatedTransform(mt1, mt2),
+                   ((Operation) step).getMethod(), CoordinateOperation.class);
+        }
+        return createConcatenatedOperation(getTemporaryName(sourceCRS, targetCRS),
+                                           new CoordinateOperation[] {step1, step2});
+    }
+
+    /**
+     * Concatenate three transformation steps. If the first and/or the last operation is an
+     * {@link #AXIS_CHANGES}, it will be included as part of the second operation instead of
+     * creating an {@link ConcatenatedOperation}. If a concatenated operation is created, it
+     * will get an automatically generated name.
+     *
+     * @param  step1 The first  step, or {@code null} for the identity operation.
+     * @param  step2 The second step, or {@code null} for the identity operation.
+     * @param  step3 The third  step, or {@code null} for the identity operation.
+     * @return A concatenated operation, or {@code null} if all arguments were null.
+     * @throws FactoryException if the operation can't be constructed.
+     */
+    protected CoordinateOperation concatenate(final CoordinateOperation step1,
+                                              final CoordinateOperation step2,
+                                              final CoordinateOperation step3)
+            throws FactoryException
+    {
+        if (step1 == null) return concatenate(step2, step3);
+        if (step2 == null) return concatenate(step1, step3);
+        if (step3 == null) return concatenate(step1, step2);
+        assert equalsIgnoreMetadata(step1.getTargetCRS(), step2.getSourceCRS()) : step1;
+        assert equalsIgnoreMetadata(step2.getTargetCRS(), step3.getSourceCRS()) : step3;
+
+        if (isIdentity(step1)) return concatenate(step2, step3);
+        if (isIdentity(step2)) return concatenate(step1, step3);
+        if (isIdentity(step3)) return concatenate(step1, step2);
+        if (step1.getName() == AXIS_CHANGES) return concatenate(concatenate(step1, step2), step3);
+        if (step3.getName() == AXIS_CHANGES) return concatenate(step1, concatenate(step2, step3));
+        final CoordinateReferenceSystem sourceCRS = step1.getSourceCRS();
+        final CoordinateReferenceSystem targetCRS = step3.getTargetCRS();
+        return createConcatenatedOperation(getTemporaryName(sourceCRS, targetCRS),
+                                           new CoordinateOperation[] {step1, step2, step3});
+    }
+
+    /**
+     * Returns {@code true} if the specified operation is an identity conversion.
+     * This method always returns {@code false} for transformations even if their
+     * associated math transform is an identity one, because such transformations
+     * are usually datum shift and must be visible.
+     */
+    private static boolean isIdentity(final CoordinateOperation operation) {
+        return (operation instanceof Conversion) && operation.getMathTransform().isIdentity();
+    }
+
+    /**
+     * Returns the inverse of the specified operation.
+     *
+     * @param  operation The operation to invert.
+     * @return The inverse of {@code operation}.
+     * @throws NoninvertibleTransformException if the operation is not invertible.
+     * @throws FactoryException if the operation creation failed for an other reason.
+     *
+     * @since 2.3
+     */
+    protected CoordinateOperation inverse(final CoordinateOperation operation)
+            throws NoninvertibleTransformException, FactoryException
+    {
+        final CoordinateReferenceSystem sourceCRS = operation.getSourceCRS();
+        final CoordinateReferenceSystem targetCRS = operation.getTargetCRS();
+        final Map<String,Object> properties = AbstractIdentifiedObject.getProperties(operation, null);
+        properties.putAll(getTemporaryName(targetCRS, sourceCRS));
+        if (operation instanceof ConcatenatedOperation) {
+            final LinkedList<CoordinateOperation> inverted = new LinkedList<CoordinateOperation>();
+            for (final CoordinateOperation op : ((ConcatenatedOperation) operation).getOperations()) {
+                inverted.addFirst(inverse(op));
+            }
+            return createConcatenatedOperation(properties,
+                    inverted.toArray(new CoordinateOperation[inverted.size()]));
+        }
+        final MathTransform transform = operation.getMathTransform().inverse();
+        final Class<? extends CoordinateOperation> type = AbstractCoordinateOperation.getType(operation);
+        final OperationMethod method = (operation instanceof Operation) ?
+                                       ((Operation) operation).getMethod() : null;
+        return createFromMathTransform(properties, targetCRS, sourceCRS, transform, method, type);
+    }
+
+
+
+
+    /////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////
+    ////////////                                                         ////////////
+    ////////////                M I S C E L L A N E O U S                ////////////
+    ////////////                                                         ////////////
+    /////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns the dimension of the specified coordinate system,
+     * or {@code 0} if the coordinate system is null.
+     */
+    static int getDimension(final CoordinateReferenceSystem crs) {
+        return (crs!=null) ? crs.getCoordinateSystem().getDimension() : 0;
+    }
+
+    /**
+     * An identifier for temporary objects. This identifier manage a count of temporary
+     * identifier. The count is appended to the identifier name (e.g. "WGS84 (step 1)").
+     */
+    private static final class TemporaryIdentifier extends NamedIdentifier {
+        /** For cross-version compatibility. */
+        private static final long serialVersionUID = -2784354058026177076L;
+
+        /** The parent identifier. */
+        private final ReferenceIdentifier parent;
+
+        /** The temporary object count. */
+        private final int count;
+
+        /** Constructs an identifier derived from the specified one. */
+        public TemporaryIdentifier(final ReferenceIdentifier parent) {
+            this(parent, ((parent instanceof TemporaryIdentifier) ?
+                         ((TemporaryIdentifier) parent).count : 0) + 1);
+        }
+
+        /** Work around for RFE #4093999 in Sun's bug database */
+        private TemporaryIdentifier(final ReferenceIdentifier parent, final int count) {
+            super(Citations.GEOTOOLS, unwrap(parent).getCode() + " (step " + count + ')');
+            this.parent = parent;
+            this.count  = count;
+        }
+
+        /** Returns the parent identifier for the specified identifier, if any. */
+        public static ReferenceIdentifier unwrap(ReferenceIdentifier identifier) {
+            while (identifier instanceof TemporaryIdentifier) {
+                identifier = ((TemporaryIdentifier) identifier).parent;
+            }
+            return identifier;
+        }
+    }
+
+    /**
+     * Returns the name of the GeoAPI interface implemented by the specified object.
+     * In addition, the name may be added between brackets.
+     */
+    private static String getClassName(final IdentifiedObject object) {
+        if (object != null) {
+            Class type = object.getClass();
+            final Class[] interfaces = type.getInterfaces();
+            for (int i=0; i<interfaces.length; i++) {
+                final Class candidate = interfaces[i];
+                if (candidate.getName().startsWith("org.opengis.referencing.")) {
+                    type = candidate;
+                    break;
+                }
+            }
+            String name = Classes.getShortName(type);
+            final ReferenceIdentifier id = object.getName();
+            if (id != null) {
+                name = name + '[' + id.getCode() + ']';
+            }
+            return name;
+        }
+        return null;
+    }
+
+    /**
+     * Returns a temporary name for object derived from the specified one.
+     *
+     * @param source The CRS to base name on, or {@code null} if none.
+     */
+    static Map<String,Object> getTemporaryName(final IdentifiedObject source) {
+        final Map<String,Object> properties = new HashMap<String,Object>(4);
+        properties.put(NAME_KEY, new TemporaryIdentifier(source.getName()));
+        properties.put(IdentifiedObject.REMARKS_KEY, Vocabulary.formatInternational(
+                       VocabularyKeys.DERIVED_FROM_$1, getClassName(source)));
+        return properties;
+    }
+
+    /**
+     * Returns a temporary name for object derived from a concatenation.
+     *
+     * @param source The CRS to base name on, or {@code null} if none.
+     */
+    static Map<String,?> getTemporaryName(final CoordinateReferenceSystem source,
+                                          final CoordinateReferenceSystem target)
+    {
+        final String name = getClassName(source) + " \u21E8 " + getClassName(target);
+        return Collections.singletonMap(NAME_KEY, name);
+    }
+
+    /**
+     * Returns an error message for "No path found from sourceCRS to targetCRS".
+     * This is used for the construction of {@link OperationNotFoundException}.
+     *
+     * @param  source The source CRS.
+     * @param  target The target CRS.
+     * @return A default error message.
+     */
+    protected static String getErrorMessage(final IdentifiedObject source,
+                                            final IdentifiedObject target)
+    {
+        return Errors.format(ErrorKeys.NO_TRANSFORMATION_PATH_$2,
+                             getClassName(source), getClassName(target));
+    }
+
+    /**
+     * Makes sure an argument is non-null.
+     *
+     * @param  name   Argument name.
+     * @param  object User argument.
+     * @throws IllegalArgumentException if {@code object} is null.
+     */
+    protected static void ensureNonNull(final String name, final Object object)
+            throws IllegalArgumentException
+    {
+        if (object == null) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1, name));
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/AuthorityBackedFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/AuthorityBackedFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/AuthorityBackedFactory.java	(revision 28000)
@@ -0,0 +1,469 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+import java.util.Iterator;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.referencing.AuthorityFactory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.*;
+
+import org.geotools.factory.Hints;
+import org.geotools.factory.OptionalFactory;
+import org.geotools.factory.FactoryRegistryException;
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.ReferencingFactoryFinder;
+import org.geotools.referencing.factory.BackingStoreException;
+import org.geotools.resources.i18n.Loggings;
+import org.geotools.resources.i18n.LoggingKeys;
+
+import static org.geotools.referencing.CRS.equalsIgnoreMetadata;
+
+
+/**
+ * A {@linkplain CoordinateOperationFactory coordinate operation factory} extended with the extra
+ * informations provided by an {@linkplain CoordinateOperationAuthorityFactory authority factory}.
+ * Such authority factory may help to find transformation paths not available otherwise (often
+ * determined from empirical parameters). Authority factories can also provide additional
+ * informations like the
+ * {@linkplain CoordinateOperation#getValidArea area of validity},
+ * {@linkplain CoordinateOperation#getScope scope} and
+ * {@linkplain CoordinateOperation#getPositionalAccuracy positional accuracy}.
+ * <p>
+ * When <code>{@linkplain #createOperation createOperation}(sourceCRS, targetCRS)</code> is invoked,
+ * {@code AuthorityBackedFactory} fetch the authority codes for source and target CRS and submits
+ * them to the {@linkplain #getAuthorityFactory underlying authority factory} through a call to its
+ * <code>{@linkplain CoordinateOperationAuthorityFactory#createFromCoordinateReferenceSystemCodes
+ * createFromCoordinateReferenceSystemCodes}(sourceCode, targetCode)</code> method. If the
+ * authority factory doesn't know about the specified CRS, then the default (standalone)
+ * process from the super-class is used as a fallback.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/AuthorityBackedFactory.java $
+ * @version $Id: AuthorityBackedFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class AuthorityBackedFactory extends DefaultCoordinateOperationFactory
+        implements OptionalFactory
+{
+    /**
+     * The priority level for this factory.
+     */
+    static final int PRIORITY = DefaultCoordinateOperationFactory.PRIORITY + 10;
+
+    /**
+     * The default authority factory to use.
+     */
+    private static final String DEFAULT_AUTHORITY = "EPSG";
+
+    /**
+     * The authority factory to use for creating new operations.
+     * If {@code null}, a default factory will be fetched when first needed.
+     */
+    private CoordinateOperationAuthorityFactory authorityFactory;
+
+    /**
+     * Used as a guard against infinite recursivity.
+     */
+    private final ThreadLocal<Boolean> processing = new ThreadLocal<Boolean>();
+
+    /**
+     * Creates a new factory backed by a default EPSG authority factory.
+     * This factory will uses a priority slightly higher than the
+     * {@linkplain DefaultCoordinateOperationFactory default (standalone) factory}.
+     */
+    public AuthorityBackedFactory() {
+        this(null);
+    }
+
+    /**
+     * Creates a new factory backed by an authority factory fetched using the specified hints.
+     * This constructor recognizes the {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS},
+     * {@link Hints#DATUM_FACTORY DATUM} and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM}
+     * {@code FACTORY} hints.
+     *
+     * @param userHints The hints, or {@code null} if none.
+     */
+    public AuthorityBackedFactory(Hints userHints) {
+        super(userHints, PRIORITY);
+        /*
+         * Removes the hint processed by the super-class. This include hints like
+         * LENIENT_DATUM_SHIFT, which usually don't apply to authority factories.
+         * An other way to see this is to said that this class "consumed" the hints.
+         * By removing them, we increase the chances to get an empty map of remaining hints,
+         * which in turn help to get the default CoordinateOperationAuthorityFactory
+         * (instead of forcing a new instance).
+         */
+        userHints = new Hints(userHints);
+        userHints.keySet().removeAll(hints.keySet());
+        userHints.remove(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER);
+        userHints.remove(Hints.FORCE_STANDARD_AXIS_DIRECTIONS);
+        userHints.remove(Hints.FORCE_STANDARD_AXIS_UNITS);
+        if (!userHints.isEmpty()) {
+            noForce(userHints);
+            authorityFactory = ReferencingFactoryFinder.getCoordinateOperationAuthorityFactory(
+                    DEFAULT_AUTHORITY, userHints);
+        }
+    }
+
+    /**
+     * Makes sure that every {@code FORCE_*} hints are set to false. We do that because we want
+     * {@link CoordinateOperationAuthorityFactory#createFromCoordinateReferenceSystemCodes} to
+     * returns coordinate operations straight from the EPSG database; we don't want an instance
+     * like {@link org.geotools.referencing.factory.OrderedAxisAuthorityFactory}. Axis swapping
+     * are performed by {@link #createFromDatabase} in this class <strong>after</strong> we invoked
+     * {@link CoordinateOperationAuthorityFactory#createFromCoordinateReferenceSystemCodes}. An
+     * {@code OrderedAxisAuthorityFactory} instance in this class would be in the way and cause
+     * an infinite recursivity.
+     *
+     * @see http://jira.codehaus.org/browse/GEOT-1161
+     */
+    private static void noForce(final Hints userHints) {
+        userHints.put(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.FALSE);
+        userHints.put(Hints.FORCE_STANDARD_AXIS_DIRECTIONS,   Boolean.FALSE);
+        userHints.put(Hints.FORCE_STANDARD_AXIS_UNITS,        Boolean.FALSE);
+    }
+
+    /**
+     * Returns the underlying coordinate operation authority factory.
+     */
+    protected CoordinateOperationAuthorityFactory getAuthorityFactory() {
+        /*
+         * No need to synchronize. This is not a big deal if ReferencingFactoryFinder is invoked
+         * twice since it is already synchronized. Actually, we should not synchronize at all.
+         * Every methods from the super-class are thread-safe without synchronized statements,
+         * and we should preserve this advantage in order to reduce the risk of contention.
+         */
+        if (authorityFactory == null) {
+            /*
+             * Factory creation at this stage will happen only if null hints were specified at
+             * construction time, which explain why it is correct to use {@link FactoryFinder}
+             * with empty hints here.
+             */
+            final Hints hints = new Hints();
+            noForce(hints);
+            authorityFactory = ReferencingFactoryFinder
+                    .getCoordinateOperationAuthorityFactory(DEFAULT_AUTHORITY, hints);
+        }
+        return authorityFactory;
+    }
+
+    /**
+     * Returns an operation for conversion or transformation between two coordinate reference
+     * systems. The default implementation extracts the authority code from the supplied
+     * {@code sourceCRS} and {@code targetCRS}, and submit them to the
+     * <code>{@linkplain CoordinateOperationAuthorityFactory#createFromCoordinateReferenceSystemCodes
+     * createFromCoordinateReferenceSystemCodes}(sourceCode, targetCode)</code> methods.
+     * If no operation is found for those codes, then this method returns {@code null}.
+     * <p>
+     * Note that this method may be invoked recursively. For example no operation may be available
+     * from the {@linkplain #getAuthorityFactory underlying authority factory} between two
+     * {@linkplain org.opengis.referencing.crs.CompoundCRS compound CRS}, but an operation
+     * may be available between two components of those compound CRS.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}, or {@code null}
+     *         if no such operation is explicitly defined in the underlying database.
+     *
+     * @since 2.3
+     */
+    @Override
+    protected CoordinateOperation createFromDatabase(final CoordinateReferenceSystem sourceCRS,
+                                                     final CoordinateReferenceSystem targetCRS)
+    {
+        /*
+         * Safety check against recursivity: returns null if the given source and target CRS
+         * are already under examination by a previous call to this method. Note: there is no
+         * need to synchronize since the Boolean is thread-local.
+         */
+        if (Boolean.TRUE.equals(processing.get())) {
+            return null;
+        }
+        /*
+         * Now performs the real work.
+         */
+        final CoordinateOperationAuthorityFactory authorityFactory = getAuthorityFactory();
+        final Citation  authority = authorityFactory.getAuthority();
+        final Identifier sourceID = AbstractIdentifiedObject.getIdentifier(sourceCRS, authority);
+        if (sourceID == null) {
+            return null;
+        }
+        final Identifier targetID = AbstractIdentifiedObject.getIdentifier(targetCRS, authority);
+        if (targetID == null) {
+            return null;
+        }
+        final String sourceCode = sourceID.getCode().trim();
+        final String targetCode = targetID.getCode().trim();
+        if (sourceCode.equals(targetCode)) {
+            /*
+             * NOTE: This check is mandatory because this method may be invoked in some situations
+             *       where (sourceCode == targetCode) but (sourceCRS != targetCRS). Such situation
+             *       should be illegal  (or at least the MathTransform from sourceCRS to targetCRS
+             *       should be the identity transform),   but unfortunatly it still happen because
+             *       EPSG defines axis order as (latitude,longitude) for geographic CRS while most
+             *       softwares expect (longitude,latitude) no matter what the EPSG authority said.
+             *       We will need to computes a transform from sourceCRS to targetCRS ignoring the
+             *       source and target codes. The superclass can do that, providing that we prevent
+             *       the authority database to (legitimately) claims that the transformation from
+             *       sourceCode to targetCode is the identity transform. See GEOT-854.
+             */
+            return null;
+        }
+        final boolean inverse;
+        Set<CoordinateOperation> operations;
+        try {
+            operations = authorityFactory.createFromCoordinateReferenceSystemCodes(sourceCode, targetCode);
+            inverse = (operations == null || operations.isEmpty());
+            if (inverse) {
+                /*
+                 * No operation from 'source' to 'target' available. But maybe there is an inverse
+                 * operation. This is typically the case when the user wants to convert from a
+                 * projected to a geographic CRS. The EPSG database usually contains transformation
+                 * paths for geographic to projected CRS only.
+                 */
+                operations = authorityFactory.createFromCoordinateReferenceSystemCodes(targetCode, sourceCode);
+            }
+        } catch (NoSuchAuthorityCodeException exception) {
+            /*
+             * sourceCode or targetCode is unknow to the underlying authority factory.
+             * Ignores the exception and fallback on the generic algorithm provided by
+             * the super-class.
+             */
+            return null;
+        } catch (FactoryException exception) {
+            /*
+             * Other kind of error. It may be more serious, but the super-class is capable
+             * to provides a raisonable default behavior. Log as a warning and lets continue.
+             */
+            log(exception, authorityFactory);
+            return null;
+        }
+        if (operations != null) {
+            for (final Iterator<CoordinateOperation> it=operations.iterator(); it.hasNext();) {
+                CoordinateOperation candidate;
+                try {
+                    // The call to it.next() must be inside the try..catch block,
+                    // which is why we don't use the Java 5 for loop syntax here.
+                    candidate = it.next();
+                    if (candidate == null) {
+                        continue;
+                    }
+                    if (inverse) {
+                        candidate = inverse(candidate);
+                    }
+                } catch (NoninvertibleTransformException e) {
+                    // The transform is non invertible. Do not log any error message, since it
+                    // may be a normal failure - the transform is not required to be invertible.
+                    continue;
+                } catch (FactoryException exception) {
+                    // Other kind of error. Log a warning and try the next coordinate operation.
+                    log(exception, authorityFactory);
+                    continue;
+                } catch (BackingStoreException exception) {
+                    log(exception, authorityFactory);
+                    continue;
+                }
+                /*
+                 * It is possible that the Identifier in user's CRS is not quite right.   For
+                 * example the user may have created his source and target CRS from WKT using
+                 * a different axis order than the official one and still call it "EPSG:xxxx"
+                 * as if it were the official CRS. Checks if the source and target CRS for the
+                 * operation just created are really the same (ignoring metadata) than the one
+                 * specified by the user.
+                 */
+                CoordinateReferenceSystem source = candidate.getSourceCRS();
+                CoordinateReferenceSystem target = candidate.getTargetCRS();
+                try {
+                    final MathTransform prepend, append;
+                    if (!equalsIgnoreMetadata(sourceCRS, source)) try {
+                        processing.set(Boolean.TRUE);
+                        prepend = createOperation(sourceCRS, source).getMathTransform();
+                        source  = sourceCRS;
+                    } finally {
+                        processing.remove();
+                    } else {
+                        prepend = null;
+                    }
+                    if (!equalsIgnoreMetadata(target, targetCRS)) try {
+                        processing.set(Boolean.TRUE);
+                        append = createOperation(target, targetCRS).getMathTransform();
+                        target = targetCRS;
+                    } finally {
+                        processing.remove();
+                    } else {
+                        append = null;
+                    }
+                    candidate = transform(source, prepend, candidate, append, target);
+                } catch (FactoryException exception) {
+                    /*
+                     * We have been unable to create a transform from the user-provided CRS to the
+                     * authority-provided CRS. In theory, the two CRS should have been the same and
+                     * the transform would have been the identity transform. In practice, it is not
+                     * always the case because of axis swapping issue (see GEOT-854). The transform
+                     * that we just tried to create in the two previous calls to the createOperation
+                     * method should have been merely an affine transform for swapping axis. If they
+                     * failed, then we are likely to fail for all other transforms provided in the
+                     * database. So stop the loop now (at the very least, do not log the same
+                     * warning for every pass of this loop!)
+                     */
+                    log(exception, authorityFactory);
+                    return null;
+                }
+                if (accept(candidate)) {
+                    return candidate;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Appends or prepends the specified math transforms to the
+     * {@linkplain CoordinateOperation#getMathTransform operation math transform}.
+     * The new coordinate operation (if any) will share the same metadata
+     * than the original operation, including the authority code.
+     * <p>
+     * This method is used in order to change axis order when the user-specified CRS
+     * disagree with the authority-supplied CRS.
+     *
+     * @param sourceCRS The source CRS to give to the new operation.
+     * @param prepend   The transform to prepend to the operation math transform.
+     * @param operation The operation in which to prepend the math transforms.
+     * @param append    The transform to append to the operation math transform.
+     * @param targetCRS The target CRS to give to the new operation.
+     * @return A new operation, or {@code operation} if {@code prepend} and {@code append} were
+     *         nulls or identity transforms.
+     * @throws FactoryException if the operation can't be constructed.
+     */
+    private CoordinateOperation transform(final CoordinateReferenceSystem sourceCRS,
+                                          final MathTransform             prepend,
+                                          final CoordinateOperation       operation,
+                                          final MathTransform             append,
+                                          final CoordinateReferenceSystem targetCRS)
+            throws FactoryException
+    {
+        if ((prepend == null || prepend.isIdentity()) && (append == null || append.isIdentity())) {
+            return operation;
+        }
+        final Map<String,?> properties = AbstractIdentifiedObject.getProperties(operation);
+        /*
+         * In the particular case of concatenated operations, we can not prepend or append a math
+         * transform to the operation as a whole (the math transform for a concatenated operation
+         * is computed automatically as the concatenation of the math transform from every single
+         * operations, and we need to stay consistent with that). Instead, we prepend to the first
+         * single operation and append to the last single operation.
+         */
+        if (operation instanceof ConcatenatedOperation) {
+            final List<SingleOperation> c = ((ConcatenatedOperation) operation).getOperations();
+            final CoordinateOperation[] op = c.toArray(new CoordinateOperation[c.size()]);
+            if (op.length != 0) {
+                final CoordinateOperation first = op[0];
+                if (op.length == 1) {
+                    op[0] = transform(sourceCRS, prepend, first, append, targetCRS);
+                } else {
+                    final CoordinateOperation last = op[op.length-1];
+                    op[0]           = transform(sourceCRS, prepend, first, null, first.getTargetCRS());
+                    op[op.length-1] = transform(last.getSourceCRS(), null, last, append, targetCRS);
+                }
+                return createConcatenatedOperation(properties, op);
+            }
+        }
+        /*
+         * Single operation case.
+         */
+        MathTransform transform = operation.getMathTransform();
+        final MathTransformFactory mtFactory = getMathTransformFactory();
+        if (prepend != null) {
+            transform = mtFactory.createConcatenatedTransform(prepend, transform);
+        }
+        if (append != null) {
+            transform = mtFactory.createConcatenatedTransform(transform, append);
+        }
+        assert !transform.equals(operation.getMathTransform()) : transform;
+        final Class<? extends CoordinateOperation> type = AbstractCoordinateOperation.getType(operation);
+        OperationMethod method = null;
+        if (operation instanceof Operation) {
+            method = ((Operation) operation).getMethod();
+            if (method != null) {
+                final int sourceDimensions = transform.getSourceDimensions();
+                final int targetDimensions = transform.getTargetDimensions();
+                if (sourceDimensions != method.getSourceDimensions() ||
+                    targetDimensions != method.getTargetDimensions())
+                {
+                    method = new DefaultOperationMethod(method, sourceDimensions, targetDimensions);
+                }
+            }
+        }
+        return createFromMathTransform(properties, sourceCRS, targetCRS, transform, method, type);
+    }
+
+    /**
+     * Logs a warning when an object can't be created from the specified factory.
+     */
+    private static void log(final Exception exception, final AuthorityFactory factory) {
+        final LogRecord record = Loggings.format(Level.WARNING,
+                                 LoggingKeys.CANT_CREATE_COORDINATE_OPERATION_$1,
+                                 factory.getAuthority().getTitle());
+        record.setSourceClassName(AuthorityBackedFactory.class.getName());
+        record.setSourceMethodName("createFromDatabase");
+        record.setThrown(exception);
+        record.setLoggerName(LOGGER.getName());
+        LOGGER.log(record);
+    }
+
+    /**
+     * Returns {@code true} if the specified operation is acceptable. This method is invoked
+     * automatically by <code>{@linkplain #createFromDatabase createFromDatabase}(...)</code>
+     * for every operation candidates found. The default implementation returns always {@code
+     * true}. Subclasses should override this method if they wish to filter the coordinate
+     * operations to be returned.
+     *
+     * @since 2.3
+     */
+    protected boolean accept(final CoordinateOperation operation) {
+        return true;
+    }
+
+    /**
+     * Returns {@code true} if this factory and its underlying
+     * {@linkplain #getAuthorityFactory authority factory} are available for use.
+     */
+    public boolean isAvailable() {
+        try {
+            final CoordinateOperationAuthorityFactory authorityFactory = getAuthorityFactory();
+            if (authorityFactory instanceof OptionalFactory) {
+                return ((OptionalFactory) authorityFactory).isAvailable();
+            }
+            return true;
+        } catch (FactoryRegistryException exception) {
+            // No factory found. Ignore the exception since it is the
+            // purpose of this method to figure out this kind of case.
+            return false;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/BufferedCoordinateOperationFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/BufferedCoordinateOperationFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/BufferedCoordinateOperationFactory.java	(revision 28000)
@@ -0,0 +1,265 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Map;
+
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.CoordinateOperationFactory;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.OperationNotFoundException;
+
+import org.geotools.factory.Hints;
+import org.geotools.factory.BufferedFactory;
+import org.geotools.util.Utilities;
+import org.geotools.util.SoftValueHashMap;
+import org.geotools.referencing.ReferencingFactoryFinder;
+
+
+/**
+ * Caches the {@linkplain CoordinateOperation coordinate operations} created by an other factory.
+ * Those coordinate operations may be expensive to create. During rendering and during data I/O,
+ * some implementations make use a lof of coordinate transformations, hence caching them might
+ * help.
+ * <p>
+ * In most cases, users should not need to create an instance of this class explicitly. An instance
+ * of {@code BufferedCoordinateOperationFactory} should be automatically registered and returned
+ * by {@link ReferencingFactoryFinder} in default Geotools configuration.
+ *
+ * @since 2.3
+ * @version $Id: BufferedCoordinateOperationFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/BufferedCoordinateOperationFactory.java $
+ * @author Simone Giannecchini
+ * @author Martin Desruisseaux
+ */
+public class BufferedCoordinateOperationFactory extends AbstractCoordinateOperationFactory
+        implements BufferedFactory
+{
+    /**
+     * The priority level for this factory.
+     */
+    static final int PRIORITY = AuthorityBackedFactory.PRIORITY + 10;
+
+    /**
+     * Helper class used in order to build an hashing for a pair of source-destination
+     * {@link CoordinateReferenceSystem} objects. This is used to cache the transformations
+     * that are pretty time-consuming to build each time.
+     */
+    private static final class CRSPair {
+        /**
+         * The hash code value, computed once for ever at construction time.
+         */
+        private final int hash;
+
+        /**
+         * The source and target CRS.
+         */
+        private final CoordinateReferenceSystem sourceCRS, targetCRS;
+
+        /**
+         * Creates a {@code CRSPair} for the specified source and target CRS.
+         */
+        public CRSPair(final CoordinateReferenceSystem sourceCRS,
+                       final CoordinateReferenceSystem targetCRS)
+        {
+            this.sourceCRS = sourceCRS;
+            this.targetCRS = targetCRS;
+            this.hash = (37 * sourceCRS.hashCode()) + targetCRS.hashCode();
+        }
+
+        /**
+         * Returns the hash code value.
+         */
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+
+        /**
+         * Compares this pair to the specified object for equality.
+         * <p>
+         * <strong>Note:</strong> we perform the CRS comparaison using strict equality, not using
+         * {@code equalsIgnoreMetadata}, because metadata matter since they are attributes of the
+         * {@link CoordinateOperation} object to be created.
+         */
+        @Override
+        public boolean equals(final Object object) {
+            if (object == this) {
+                return true;
+            }
+            if (object instanceof CRSPair) {
+                final CRSPair that = (CRSPair) object;
+                return Utilities.equals(this.sourceCRS, that.sourceCRS) &&
+                       Utilities.equals(this.targetCRS, that.targetCRS);
+            }
+            return false;
+        }
+    }
+
+    /**
+     * The wrapped factory. If {@code null}, will be fetched when first needed.
+     * We should not initialize this field using {@link ReferencingFactoryFinder} from the
+     * no-argument constructor, since this constructor is typically invoked while
+     * {@link ReferencingFactoryFinder} is still iterating over the registered implementations.
+     */
+    private CoordinateOperationFactory factory;
+
+    /**
+     * The pool of cached transformations. This map can not be static, because the values may
+     * be different for the same ({@code sourceCRS}, {@code targetCRS}) pair dependending of
+     * hint values like {@link Hints#LENIENT_DATUM_SHIFT}.
+     */
+    private final Map<CRSPair, CoordinateOperation> pool =
+            new SoftValueHashMap<CRSPair, CoordinateOperation>();
+
+    /**
+     * Creates a buffered factory wrapping the {@linkplain AuthorityBackedFactory default one}.
+     */
+    public BufferedCoordinateOperationFactory() {
+        super(null, PRIORITY);
+        /*
+         * Do not use FactoryFinder here (directly or indirectly through the call
+         * to an other constructor), because this constructor is typically invoked
+         * while FactoryFinder is iterating over registered implementations. We
+         * left the 'factory' field uninitialized and will initialize it when first
+         * needed.
+         */
+    }
+
+    /**
+     * Creates a buffered factory wrapping an other factory selected according the specified hints.
+     *
+     * @param userHints The hints to use for choosing a backing factory.
+     */
+    public BufferedCoordinateOperationFactory(final Hints userHints) {
+        this(userHints, PRIORITY);
+    }
+
+    /**
+     * Creates a buffered factory wrapping an other factory selected according the specified hints.
+     *
+     * @param userHints The hints to use for choosing a backing factory.
+     * @param priority The priority for this factory, as a number between
+     *        {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
+     *        {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
+     */
+    public BufferedCoordinateOperationFactory(final Hints userHints, final int priority) {
+        this(getBackingFactory(userHints), userHints, priority);
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private BufferedCoordinateOperationFactory(final CoordinateOperationFactory factory,
+                                               final Hints userHints, final int priority)
+    {
+        super(factory, userHints, priority);
+        this.factory = factory;
+        ensureNonNull("factory", factory);
+    }
+
+    /**
+     * Returns a backing factory from the specified hints.
+     */
+    private static CoordinateOperationFactory getBackingFactory(final Hints hints) {
+        for (final CoordinateOperationFactory candidate : ReferencingFactoryFinder.getCoordinateOperationFactories(hints)) {
+            if (!(candidate instanceof BufferedCoordinateOperationFactory)) {
+                return candidate;
+            }
+        }
+        // The following is likely to thrown a FactoryNotFoundException,
+        // which is the intended behavior.
+        return ReferencingFactoryFinder.getCoordinateOperationFactory(hints);
+    }
+
+    /**
+     * Returns the backing factory. Coordinate operation creation will be delegated to this
+     * factory when not available in the cache.
+     */
+    private final CoordinateOperationFactory getBackingFactory() {
+        assert Thread.holdsLock(hints); // Same lock than the one used by getImplementationHints().
+        if (factory == null) {
+            factory = getBackingFactory(null);
+        }
+        return factory;
+    }
+
+    /**
+     * Invoked by {@link #AbstractCoordinateOperationFactory} when the {@link #hints} map should
+     * be initialized. The {@link Hints#COORDINATE_OPERATION_FACTORY} can not always be provided
+     * at construction time, because the backing factory may be lazily created.
+     */
+    @Override
+    void initializeHints() {
+        super.initializeHints();
+        hints.put(Hints.COORDINATE_OPERATION_FACTORY, getBackingFactory());
+    }
+
+    /**
+     * Returns an operation for conversion or transformation between two coordinate reference
+     * systems. If an operation was already created and still in the cache, the cached operation
+     * is returned. Otherwise the operation creation is delegated to the
+     * {@linkplain CoordinateOperationFactory coordinate operation factory} specified at
+     * construction time and the result is cached.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS}
+     *         to {@code targetCRS}.
+     * @throws FactoryException if the operation creation failed for some other reason.
+     */
+    public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
+                                               final CoordinateReferenceSystem targetCRS)
+            throws OperationNotFoundException, FactoryException
+    {
+        ensureNonNull("sourceCRS", sourceCRS);
+        ensureNonNull("targetCRS", targetCRS);
+        final CRSPair key = new CRSPair(sourceCRS, targetCRS);
+        CoordinateOperation op;
+        synchronized (hints) { // This lock is indirectly required by getBackingFactory().
+            op = pool.get(key);
+            if (op == null) {
+                op = getBackingFactory().createOperation(sourceCRS, targetCRS);
+                pool.put(key, op);
+            }
+        }
+        return op;
+    }
+
+    /**
+     * Returns an operation for conversion or transformation between two coordinate reference
+     * systems using the specified method. The current implementation delegates to the
+     * {@linkplain CoordinateOperationFactory coordinate operation factory} specified at
+     * construction time with no caching.
+     *
+     * @deprecated Will be removed.
+     */
+    public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
+                                               final CoordinateReferenceSystem targetCRS,
+                                               final OperationMethod method)
+            throws OperationNotFoundException, FactoryException
+    {
+        synchronized (hints) { // This lock is indirectly required by getBackingFactory().
+            return getBackingFactory().createOperation(sourceCRS, targetCRS, method);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultConcatenatedOperation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultConcatenatedOperation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultConcatenatedOperation.java	(revision 28000)
@@ -0,0 +1,279 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.operation.transform.ConcatenatedTransform;
+import org.geotools.resources.Classes;
+import org.geotools.resources.UnmodifiableArrayList;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.opengis.metadata.quality.PositionalAccuracy;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.ConcatenatedOperation;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.referencing.operation.SingleOperation;
+import org.opengis.referencing.operation.Transformation;
+
+
+/**
+ * An ordered sequence of two or more single coordinate operations. The sequence of operations is
+ * constrained by the requirement that the source coordinate reference system of step
+ * (<var>n</var>+1) must be the same as the target coordinate reference system of step
+ * (<var>n</var>). The source coordinate reference system of the first step and the target
+ * coordinate reference system of the last step are the source and target coordinate reference
+ * system associated with the concatenated operation.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultConcatenatedOperation.java $
+ * @version $Id: DefaultConcatenatedOperation.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultConcatenatedOperation extends AbstractCoordinateOperation
+        implements ConcatenatedOperation
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 4199619838029045700L;
+
+    /**
+     * The sequence of operations.
+     */
+    private final List<SingleOperation> operations;
+
+    /**
+     * Constructs a concatenated operation from a set of properties and a
+     * {@linkplain MathTransformFactory math transform factory}.
+     * The properties given in argument follow the same rules than for the
+     * {@link AbstractCoordinateOperation} constructor.
+     *
+     * @param  properties Set of properties. Should contains at least {@code "name"}.
+     * @param  operations The sequence of operations.
+     * @param  factory    The math transform factory to use for math transforms concatenation.
+     * @throws FactoryException if the factory can't concatenate the math transforms.
+     */
+    public DefaultConcatenatedOperation(final Map<String,?> properties,
+                                        final CoordinateOperation[] operations,
+                                        final MathTransformFactory factory)
+            throws FactoryException
+    {
+        this(properties, new ArrayList<SingleOperation>(operations!=null ? operations.length : 4),
+             operations, factory);
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private DefaultConcatenatedOperation(final Map<String,?> properties,
+                                         final ArrayList<SingleOperation> list,
+                                         final CoordinateOperation[] operations,
+                                         final MathTransformFactory factory)
+            throws FactoryException
+    {
+        this(properties, expand(operations, list, factory, true), list);
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private DefaultConcatenatedOperation(final Map<String,?> properties,
+                                         final MathTransform transform,
+                                         final List<SingleOperation> operations)
+    {
+        super(mergeAccuracy(properties, operations),
+              operations.get(0).getSourceCRS(),
+              operations.get(operations.size() - 1).getTargetCRS(),
+              transform);
+        this.operations = UnmodifiableArrayList.wrap(
+                operations.toArray(new SingleOperation[operations.size()]));
+    }
+
+    /**
+     * Transforms the list of operations into a list of single operations. This method
+     * also check against null value and make sure that all CRS dimension matches.
+     *
+     * @param  operations The array of operations to expand.
+     * @param  target The destination list in which to add {@code SingleOperation}.
+     * @param  factory The math transform factory to use, or {@code null}
+     * @param  wantTransform {@code true} if the concatenated math transform should be computed.
+     *         This is set to {@code false} only when this method invokes itself recursively.
+     * @return The concatenated math transform.
+     * @throws FactoryException if the factory can't concatenate the math transforms.
+     */
+    private static MathTransform expand(final CoordinateOperation[] operations,
+                                        final List<SingleOperation> target,
+                                        final MathTransformFactory factory,
+                                        final boolean wantTransform)
+            throws FactoryException
+    {
+        MathTransform transform = null;
+        ensureNonNull("operations", operations);
+        for (int i=0; i<operations.length; i++) {
+            ensureNonNull("operations", operations, i);
+            final CoordinateOperation op = operations[i];
+            if (op instanceof SingleOperation) {
+                target.add((SingleOperation) op);
+            } else if (op instanceof ConcatenatedOperation) {
+                final ConcatenatedOperation cop = (ConcatenatedOperation) op;
+                final List<SingleOperation> cops = cop.getOperations();
+                expand(cops.toArray(new CoordinateOperation[cops.size()]), target, factory, false);
+            } else {
+                throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_CLASS_$2,
+                        Classes.getClass(op), SingleOperation.class));
+            }
+            /*
+             * Check the CRS dimensions.
+             */
+            if (i != 0) {
+                final CoordinateReferenceSystem previous = operations[i-1].getTargetCRS();
+                final CoordinateReferenceSystem next     = op             .getSourceCRS();
+                if (previous!=null && next!=null) {
+                    final int dim1 = previous.getCoordinateSystem().getDimension();
+                    final int dim2 =     next.getCoordinateSystem().getDimension();
+                    if (dim1 != dim2) {
+                        throw new IllegalArgumentException(Errors.format(
+                                  ErrorKeys.MISMATCHED_DIMENSION_$2, dim1, dim2));
+                    }
+                }
+            }
+            /*
+             * Concatenates the math transform.
+             */
+            if (wantTransform) {
+                final MathTransform step = op.getMathTransform();
+                if (transform == null) {
+                    transform = step;
+                } else if (factory != null) {
+                    transform = factory.createConcatenatedTransform(transform, step);
+                } else {
+                    transform = ConcatenatedTransform.create(transform, step);
+                }
+            }
+        }
+        if (wantTransform) {
+            final int size = target.size();
+            if (size <= 1) {
+                throw new IllegalArgumentException(Errors.format(
+                            ErrorKeys.MISSING_PARAMETER_$1, "operations[" + size + ']'));
+            }
+        }
+        return transform;
+    }
+
+    /**
+     * If no accuracy were specified in the given properties map, add all accuracies found in the
+     * operation to concatenate. This method considers only {@link Transformation} components and
+     * ignores all conversions. According ISO 19111, the accuracy attribute is allowed only for
+     * transformations. However, this restriction is not enforced everywhere. The EPSG database
+     * declares an accuracy of 0 meters for conversions, which is conceptually exact. Ourself we
+     * are departing from the specification, since we are adding accuracy informations to a
+     * concatenated operation. This departure should be considered as a convenience feature
+     * only; accuracies are really relevant in transformations only.
+     * <p>
+     * There is also a technical reasons for ignoring conversions. If a concatenated operation
+     * contains a datum shift (i.e. a transformation) with unknow accuracy, and a projection
+     * (i.e. a conversion) with a declared 0 meter error, we don't want to declare this 0 meter
+     * error as the concatenated operation's accuracy; it would be a false information.
+     * <p>
+     * Note that a concatenated operation typically contains an arbitrary amount of conversions,
+     * but only one transformation. So considering transformation only usually means to pickup
+     * only one operation in the given {@code operations} list.
+     *
+     * @todo We should use a Map and merge only one accuracy for each specification.
+     */
+    private static Map<String,?> mergeAccuracy(final Map<String,?> properties,
+            final List<? extends CoordinateOperation> operations)
+    {
+        if (!properties.containsKey(COORDINATE_OPERATION_ACCURACY_KEY)) {
+            Set<PositionalAccuracy> accuracy = null;
+            for (final CoordinateOperation op : operations) {
+                if (op instanceof Transformation) {
+                    // See javadoc for a rational why we take only transformations in account.
+                    Collection<PositionalAccuracy> candidates = op.getCoordinateOperationAccuracy();
+                    if (candidates!=null && !candidates.isEmpty()) {
+                        if (accuracy == null) {
+                            accuracy = new LinkedHashSet<PositionalAccuracy>();
+                        }
+                        accuracy.addAll(candidates);
+                    }
+                }
+            }
+            if (accuracy != null) {
+                final Map<String,Object> merged = new HashMap<String,Object>(properties);
+                merged.put(COORDINATE_OPERATION_ACCURACY_KEY,
+                           accuracy.toArray(new PositionalAccuracy[accuracy.size()]));
+                return merged;
+            }
+        }
+        return properties;
+    }
+
+    /**
+     * Returns the sequence of operations.
+     */
+    public List<SingleOperation> getOperations() {
+        return operations;
+    }
+
+    /**
+     * Compare this concatenated operation with the specified object for equality.
+     * If {@code compareMetadata} is {@code true}, then all available properties are
+     * compared including {@linkplain #getValidArea valid area} and {@linkplain #getScope scope}.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            final DefaultConcatenatedOperation that = (DefaultConcatenatedOperation) object;
+            return equals(this.operations, that.operations, compareMetadata);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this concatenated operation.
+     */
+    @Override
+    public int hashCode() {
+        return operations.hashCode() ^ (int)serialVersionUID;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultConicProjection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultConicProjection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultConicProjection.java	(revision 28000)
@@ -0,0 +1,89 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Map;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.ConicProjection;
+
+
+/**
+ * Base class for conical map projections.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultConicProjection.java $
+ * @version $Id: DefaultConicProjection.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @since 2.1
+ *
+ * @see org.geotools.referencing.crs.DefaultProjectedCRS
+ * @see <A HREF="http://mathworld.wolfram.com/ConicProjection.html">Conic projection on MathWorld</A>
+ */
+public class DefaultConicProjection extends DefaultProjection implements ConicProjection {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -8717453834398763963L;
+
+    /**
+     * Constructs a new projection with the same values than the specified one, together with the
+     * specified source and target CRS. While the source conversion can be an arbitrary one, it is
+     * typically a {@linkplain DefiningConversion defining conversion}.
+     *
+     * @param conversion The defining conversion.
+     * @param sourceCRS The source CRS.
+     * @param targetCRS The target CRS.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source CRS}
+     *                  to positions in the {@linkplain #getTargetCRS target CRS}.
+     */
+    public DefaultConicProjection(final Conversion               conversion,
+                                  final CoordinateReferenceSystem sourceCRS,
+                                  final CoordinateReferenceSystem targetCRS,
+                                  final MathTransform             transform)
+    {
+        super(conversion, sourceCRS, targetCRS, transform);
+    }
+
+    /**
+     * Constructs a projection from a set of properties. The properties given in argument
+     * follow the same rules than for the {@link AbstractCoordinateOperation} constructor.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param sourceCRS The source CRS, or {@code null} if not available.
+     * @param targetCRS The target CRS, or {@code null} if not available.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source coordinate
+     *                  reference system} to positions in the {@linkplain #getTargetCRS target
+     *                  coordinate reference system}.
+     * @param method    The operation method.
+     */
+    public DefaultConicProjection(final Map<String,?>             properties,
+                                  final CoordinateReferenceSystem sourceCRS,
+                                  final CoordinateReferenceSystem targetCRS,
+                                  final MathTransform             transform,
+                                  final OperationMethod           method)
+    {
+        super(properties, sourceCRS, targetCRS, transform, method);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultConversion.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultConversion.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultConversion.java	(revision 28000)
@@ -0,0 +1,157 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Map;
+
+import org.opengis.referencing.operation.*; // We use almost all of them.
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+
+/**
+ * An operation on coordinates that does not include any change of Datum. The best-known
+ * example of a coordinate conversion is a map projection. The parameters describing
+ * coordinate conversions are defined rather than empirically derived. Note that some
+ * conversions have no parameters.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultConversion.java $
+ * @version $Id: DefaultConversion.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see DefaultTransformation
+ */
+public class DefaultConversion extends DefaultOperation implements Conversion {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -2148164324805562793L;
+
+    /**
+     * Constructs a new conversion with the same values than the specified one, together with the
+     * specified source and target CRS. While the source conversion can be an arbitrary one, it is
+     * typically a {@linkplain DefiningConversion defining conversion}.
+     *
+     * @param definition The defining conversion.
+     * @param sourceCRS The source CRS.
+     * @param targetCRS The target CRS.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source CRS}
+     *                  to positions in the {@linkplain #getTargetCRS target CRS}.
+     */
+    public DefaultConversion(final Conversion               definition,
+                             final CoordinateReferenceSystem sourceCRS,
+                             final CoordinateReferenceSystem targetCRS,
+                             final MathTransform             transform)
+    {
+        super(definition, sourceCRS, targetCRS, transform);
+    }
+
+    /**
+     * Constructs a conversion from a set of properties. The properties given in argument
+     * follow the same rules than for the {@link AbstractCoordinateOperation} constructor.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param sourceCRS The source CRS.
+     * @param targetCRS The target CRS.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source CRS}
+     *                  to positions in the {@linkplain #getTargetCRS target CRS}.
+     * @param method    The operation method.
+     */
+    public DefaultConversion(final Map<String,?>             properties,
+                             final CoordinateReferenceSystem sourceCRS,
+                             final CoordinateReferenceSystem targetCRS,
+                             final MathTransform             transform,
+                             final OperationMethod           method)
+    {
+        super(properties, sourceCRS, targetCRS, transform, method);
+    }
+
+    /**
+     * Invoked by the super-class constructor for checking argument validity. At the opposite of
+     * {@link DefaultOperation}, a conversion accepts null {@code transform}, {@code sourceCRS}
+     * and {@code targetCRS} providing that all of them are null together. If only one or two of
+     * them is {@code null}, we will rely on the default validation which will throw an exception.
+     */
+    @Override
+    void validate() throws IllegalArgumentException {
+        if (transform != null || sourceCRS != null || targetCRS != null) {
+            super.validate();
+        }
+    }
+
+    /**
+     * Returns a conversion from the specified {@linkplain DefiningConversion defining conversion}.
+     * The new conversion will be a more specific type like a {@linkplain PlanarProjection planar},
+     * {@linkplain CylindricalProjection cylindrical} or {@linkplain ConicProjection conic
+     * projection}. This type is inferred from the {@code conversion} argument when possible.
+     * However the inferred type is not always the most accurate one, so an optional
+     * {@code typeHint} argument may be specified in order to get a more specific subclass.
+     * This later argument is just a hint: it may be {@code null} and will be ignored if it
+     * conflict with the automatically inferred type.
+     *
+     * @param definition The defining conversion.
+     * @param sourceCRS  The source CRS.
+     * @param targetCRS  The target CRS.
+     * @param transform  Transform from positions in the {@linkplain #getSourceCRS source CRS}
+     *                   to positions in the {@linkplain #getTargetCRS target CRS}.
+     * @param typeHint   One of <code>{@linkplain PlanarProjection}.class</code>,
+     *                   <code>{@linkplain CylindricalProjection}.class</code> or
+     *                   <code>{@linkplain ConicProjection}.class</code>, or {@code null}.
+     * @return The conversion of the given type if possible.
+     *
+     * @see DefaultOperation#create
+     *
+     * @since 2.4
+     */
+    public static Conversion create(final Conversion               definition,
+                                    final CoordinateReferenceSystem sourceCRS,
+                                    final CoordinateReferenceSystem targetCRS,
+                                    final MathTransform             transform,
+                                    final Class<? extends Conversion> typeHint)
+    {
+        Class<? extends CoordinateOperation> type = getType(definition);
+        final OperationMethod method = definition.getMethod();
+        if (method instanceof MathTransformProvider) {
+            final Class<? extends Operation> candidate = ((MathTransformProvider) method).getOperationType();
+            if (candidate != null) {
+                if (type.isAssignableFrom(candidate)) {
+                    type = candidate;
+                }
+            }
+        }
+        if (typeHint != null && type.isAssignableFrom(typeHint)) {
+            type = typeHint;
+        }
+        if (ConicProjection.class.isAssignableFrom(type)) {
+            return new DefaultConicProjection(definition, sourceCRS, targetCRS, transform);
+        }
+        if (CylindricalProjection.class.isAssignableFrom(type)) {
+            return new DefaultCylindricalProjection(definition, sourceCRS, targetCRS, transform);
+        }
+        if (PlanarProjection.class.isAssignableFrom(type)) {
+            return new DefaultPlanarProjection(definition, sourceCRS, targetCRS, transform);
+        }
+        if (Projection.class.isAssignableFrom(type)) {
+            return new DefaultProjection(definition, sourceCRS, targetCRS, transform);
+        }
+        return new DefaultConversion(definition, sourceCRS, targetCRS, transform);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultCoordinateOperationFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultCoordinateOperationFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultCoordinateOperationFactory.java	(revision 28000)
@@ -0,0 +1,1590 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Map;
+import java.util.List;
+import java.util.Collections;
+import javax.measure.unit.NonSI;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+import javax.measure.quantity.Angle;
+import javax.measure.quantity.Duration;
+import javax.vecmath.SingularMatrixException;
+
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.referencing.cs.*;
+import org.opengis.referencing.crs.*;
+import org.opengis.referencing.datum.*;
+import org.opengis.referencing.operation.*;
+
+import org.geotools.factory.Hints;
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.crs.DefaultCompoundCRS;
+import org.geotools.referencing.crs.DefaultEngineeringCRS;
+import org.geotools.referencing.cs.DefaultCartesianCS;
+import org.geotools.referencing.cs.DefaultEllipsoidalCS;
+import org.geotools.referencing.datum.BursaWolfParameters;
+import org.geotools.referencing.datum.DefaultGeodeticDatum;
+import org.geotools.referencing.datum.DefaultPrimeMeridian;
+import org.geotools.referencing.operation.matrix.XMatrix;
+import org.geotools.referencing.operation.matrix.Matrix4;
+import org.geotools.referencing.operation.matrix.MatrixFactory;
+import org.geotools.referencing.factory.ReferencingFactoryContainer;
+import org.geotools.resources.Classes;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+import static org.geotools.referencing.CRS.equalsIgnoreMetadata;
+import static org.geotools.referencing.AbstractIdentifiedObject.nameMatches;
+import static org.geotools.referencing.operation.ProjectionAnalyzer.createLinearConversion;
+
+
+/**
+ * Creates {@linkplain CoordinateOperation coordinate operations}. This factory is capable to find
+ * coordinate {@linkplain Transformation transformations} or {@linkplain Conversion conversions}
+ * between two {@linkplain CoordinateReferenceSystem coordinate reference systems}. It delegates
+ * most of its work to one or many of {@code createOperationStep} methods. Subclasses can
+ * override those methods in order to extend the factory capability to some more CRS.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultCoordinateOperationFactory.java $
+ * @version $Id: DefaultCoordinateOperationFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @tutorial http://docs.codehaus.org/display/GEOTOOLS/Coordinate+Transformation+Services+for+Geotools+2.1
+ */
+public class DefaultCoordinateOperationFactory extends AbstractCoordinateOperationFactory {
+    /**
+     * The priority level for this factory.
+     */
+    static final int PRIORITY = NORMAL_PRIORITY;
+
+    /**
+     * Small number for floating point comparaisons.
+     */
+    private static final double EPS = 1E-10;
+
+    /**
+     * A unit of one millisecond.
+     */
+    private static final Unit<Duration> MILLISECOND = SI.MILLI(SI.SECOND);
+
+    /**
+     * The operation to use by {@link #createTransformationStep(GeographicCRS,GeographicCRS)} for
+     * datum shift. This string can have one of the following values:
+     * <p>
+     * <ul>
+     *   <li><code>"Abridged_Molodenski"</code> for the abridged Molodenski transformation.</li>
+     *   <li><code>"Molodenski"</code> for the Molodenski transformation.</li>
+     *   <li>{@code null} for performing datum shifts is geocentric coordinates.</li>
+     * </ul>
+     */
+    private final String molodenskiMethod;
+
+    /**
+     * {@code true} if datum shift are allowed even if no Bursa Wolf parameters is available.
+     */
+    private final boolean lenientDatumShift;
+
+    /**
+     * Constructs a coordinate operation factory using the default factories.
+     */
+    public DefaultCoordinateOperationFactory() {
+        this(null);
+    }
+
+    /**
+     * Constructs a coordinate operation factory using the specified hints.
+     * This constructor recognizes the {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS},
+     * {@link Hints#DATUM_FACTORY DATUM} and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM}
+     * {@code FACTORY} hints.
+     *
+     * @param userHints The hints, or {@code null} if none.
+     */
+    public DefaultCoordinateOperationFactory(final Hints userHints) {
+        this(userHints, PRIORITY);
+    }
+
+    /**
+     * Constructs a coordinate operation factory using the specified hints and priority.
+     * This constructor recognizes the {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS},
+     * {@link Hints#DATUM_FACTORY DATUM} and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM}
+     * {@code FACTORY} hints.
+     *
+     * @param userHints The hints, or {@code null} if none.
+     * @param priority The priority for this factory, as a number between
+     *        {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
+     *        {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
+     *
+     * @since 2.2
+     */
+    public DefaultCoordinateOperationFactory(final Hints userHints, final int priority) {
+        super(userHints, priority);
+        //
+        // Default hints values
+        //
+        String  molodenskiMethod  = "Molodenski"; // Alternative: "Abridged_Molodenski"
+        boolean lenientDatumShift = false;
+        //
+        // Fetchs the user-supplied hints
+        //
+        if (userHints != null) {
+            Object candidate = userHints.get(Hints.DATUM_SHIFT_METHOD);
+            if (candidate instanceof String) {
+                molodenskiMethod = (String) candidate;
+                if (molodenskiMethod.trim().equalsIgnoreCase("Geocentric")) {
+                    molodenskiMethod = null;
+                }
+            }
+            candidate = userHints.get(Hints.LENIENT_DATUM_SHIFT);
+            if (candidate instanceof Boolean) {
+                lenientDatumShift = ((Boolean) candidate).booleanValue();
+            }
+        }
+        //
+        // Stores the retained hints
+        //
+        this.molodenskiMethod  = molodenskiMethod;
+        this.lenientDatumShift = lenientDatumShift;
+        this.hints.put(Hints.DATUM_SHIFT_METHOD,  molodenskiMethod);
+        this.hints.put(Hints.LENIENT_DATUM_SHIFT, Boolean.valueOf(lenientDatumShift));
+    }
+
+    /**
+     * Returns an operation for conversion or transformation between two coordinate reference
+     * systems. If an operation exists, it is returned. If more than one operation exists, the
+     * default is returned. If no operation exists, then the exception is thrown.
+     * <P>
+     * The default implementation inspects the CRS and delegates the work to one or
+     * many {@code createOperationStep(...)} methods. This method fails if no path
+     * between the CRS is found.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS}
+     *         to {@code targetCRS}.
+     * @throws FactoryException if the operation creation failed for some other reason.
+     */
+    public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
+                                               final CoordinateReferenceSystem targetCRS)
+            throws OperationNotFoundException, FactoryException
+    {
+        ensureNonNull("sourceCRS", sourceCRS);
+        ensureNonNull("targetCRS", targetCRS);
+        if (equalsIgnoreMetadata(sourceCRS, targetCRS)) {
+            final int dim  = getDimension(sourceCRS);
+            assert    dim == getDimension(targetCRS) : dim;
+            return createFromAffineTransform(IDENTITY, sourceCRS, targetCRS,
+                                             MatrixFactory.create(dim+1));
+        } else {
+            // Query the database (if any) before to try to find the operation by ourself.
+            final CoordinateOperation candidate = createFromDatabase(sourceCRS, targetCRS);
+            if (candidate != null) {
+                return candidate;
+            }
+        }
+        /*
+         * Before to process, performs a special check for CompoundCRS where the target contains
+         * every elements included in the source.  CompoundCRS are usually verified last, but in
+         * the special case described above there is only axis switch or dimension to remove. If
+         * we wait last for processing them, what would have been a simple CoordinateOperation
+         * may become interleaved with more complex operation (e.g. projection followed by the
+         * inverse projection, before they get simplified by DefaultConcatenatedOperation, etc.).
+         */
+        if (sourceCRS instanceof CompoundCRS) {
+            final List<SingleCRS> sources = DefaultCompoundCRS.getSingleCRS(sourceCRS);
+            final List<SingleCRS> targets = DefaultCompoundCRS.getSingleCRS(targetCRS);
+            if (containsIgnoreMetadata(sources, targets)) {
+                final CompoundCRS source = (CompoundCRS) sourceCRS;
+                if (targetCRS instanceof CompoundCRS) {
+                    final CompoundCRS target = (CompoundCRS) targetCRS;
+                    return createOperationStep(source, target);
+                }
+                if (targetCRS instanceof SingleCRS) {
+                    final SingleCRS target = (SingleCRS) targetCRS;
+                    return createOperationStep(source, target);
+                }
+            }
+        }
+        /////////////////////////////////////////////////////////////////////
+        ////                                                             ////
+        ////     Geographic  -->  Geographic, Projected or Geocentric    ////
+        ////                                                             ////
+        /////////////////////////////////////////////////////////////////////
+        if (sourceCRS instanceof GeographicCRS) {
+            final GeographicCRS source = (GeographicCRS) sourceCRS;
+            if (targetCRS instanceof GeographicCRS) {
+                final GeographicCRS target = (GeographicCRS) targetCRS;
+                return createOperationStep(source, target);
+            }
+            if (targetCRS instanceof ProjectedCRS) {
+                final ProjectedCRS target = (ProjectedCRS) targetCRS;
+                return createOperationStep(source, target);
+            }
+            if (targetCRS instanceof GeocentricCRS) {
+                final GeocentricCRS target = (GeocentricCRS) targetCRS;
+                return createOperationStep(source, target);
+            }
+            if (targetCRS instanceof VerticalCRS) {
+                final VerticalCRS target = (VerticalCRS) targetCRS;
+                return createOperationStep(source, target);
+            }
+        }
+        /////////////////////////////////////////////////////////
+        ////                                                 ////
+        ////     Projected  -->  Projected or Geographic     ////
+        ////                                                 ////
+        /////////////////////////////////////////////////////////
+        if (sourceCRS instanceof ProjectedCRS) {
+            final ProjectedCRS source = (ProjectedCRS) sourceCRS;
+            if (targetCRS instanceof ProjectedCRS) {
+                final ProjectedCRS target = (ProjectedCRS) targetCRS;
+                return createOperationStep(source, target);
+            }
+            if (targetCRS instanceof GeographicCRS) {
+                final GeographicCRS target = (GeographicCRS) targetCRS;
+                return createOperationStep(source, target);
+            }
+        }
+        //////////////////////////////////////////////////////////
+        ////                                                  ////
+        ////     Geocentric  -->  Geocentric or Geographic    ////
+        ////                                                  ////
+        //////////////////////////////////////////////////////////
+        if (sourceCRS instanceof GeocentricCRS) {
+            final GeocentricCRS source = (GeocentricCRS) sourceCRS;
+            if (targetCRS instanceof GeocentricCRS) {
+                final GeocentricCRS target = (GeocentricCRS) targetCRS;
+                return createOperationStep(source, target);
+            }
+            if (targetCRS instanceof GeographicCRS) {
+                final GeographicCRS target = (GeographicCRS) targetCRS;
+                return createOperationStep(source, target);
+            }
+        }
+        /////////////////////////////////////////
+        ////                                 ////
+        ////     Vertical  -->  Vertical     ////
+        ////                                 ////
+        /////////////////////////////////////////
+        if (sourceCRS instanceof VerticalCRS) {
+            final VerticalCRS source = (VerticalCRS) sourceCRS;
+            if (targetCRS instanceof VerticalCRS) {
+                final VerticalCRS target = (VerticalCRS) targetCRS;
+                return createOperationStep(source, target);
+            }
+        }
+        /////////////////////////////////////////
+        ////                                 ////
+        ////     Temporal  -->  Temporal     ////
+        ////                                 ////
+        /////////////////////////////////////////
+        if (sourceCRS instanceof TemporalCRS) {
+            final TemporalCRS source = (TemporalCRS) sourceCRS;
+            if (targetCRS instanceof TemporalCRS) {
+                final TemporalCRS target = (TemporalCRS) targetCRS;
+                return createOperationStep(source, target);
+            }
+        }
+        //////////////////////////////////////////////////////////////////
+        ////                                                          ////
+        ////     Any coordinate reference system -->  Derived CRS     ////
+        ////                                                          ////
+        //////////////////////////////////////////////////////////////////
+        if (targetCRS instanceof GeneralDerivedCRS) {
+            // Note: this code is identical to 'createOperationStep(GeographicCRS, ProjectedCRS)'
+            //       except that the later invokes directly the right method for 'step1' instead
+            //       of invoking 'createOperation' recursively.
+            final GeneralDerivedCRS  target = (GeneralDerivedCRS) targetCRS;
+            final CoordinateReferenceSystem base = target.getBaseCRS();
+            final CoordinateOperation step1 = createOperation(sourceCRS, base);
+            final CoordinateOperation step2 = target.getConversionFromBase();
+            return concatenate(step1, step2);
+        }
+        //////////////////////////////////////////////////////////////////
+        ////                                                          ////
+        ////     Derived CRS -->  Any coordinate reference system     ////
+        ////                                                          ////
+        //////////////////////////////////////////////////////////////////
+        if (sourceCRS instanceof GeneralDerivedCRS) {
+            // Note: this code is identical to 'createOperationStep(ProjectedCRS, GeographicCRS)'
+            //       except that the later invokes directly the right method for 'step2' instead
+            //       of invoking 'createOperation' recursively.
+            final GeneralDerivedCRS       source = (GeneralDerivedCRS) sourceCRS;
+            final CoordinateReferenceSystem base = source.getBaseCRS();
+            final CoordinateOperation      step2 = createOperation(base, targetCRS);
+            CoordinateOperation            step1 = source.getConversionFromBase();
+            MathTransform              transform = step1.getMathTransform();
+            try {
+                transform = transform.inverse();
+            } catch (NoninvertibleTransformException exception) {
+                throw new OperationNotFoundException(getErrorMessage(sourceCRS, base), exception);
+            }
+            step1 = createFromMathTransform(INVERSE_OPERATION, sourceCRS, base, transform);
+            return concatenate(step1, step2);
+        }
+        ////////////////////////////////////////////
+        ////                                    ////
+        ////     Compound  -->  various CRS     ////
+        ////                                    ////
+        ////////////////////////////////////////////
+        if (sourceCRS instanceof CompoundCRS) {
+            final CompoundCRS source = (CompoundCRS) sourceCRS;
+            if (targetCRS instanceof CompoundCRS) {
+                final CompoundCRS target = (CompoundCRS) targetCRS;
+                return createOperationStep(source, target);
+            }
+            if (targetCRS instanceof SingleCRS) {
+                final SingleCRS target = (SingleCRS) targetCRS;
+                return createOperationStep(source, target);
+            }
+        }
+        if (targetCRS instanceof CompoundCRS) {
+            final CompoundCRS target = (CompoundCRS) targetCRS;
+            if (sourceCRS instanceof SingleCRS) {
+                final SingleCRS source = (SingleCRS) sourceCRS;
+                return createOperationStep(source, target);
+            }
+        }
+        /////////////////////////////////////////
+        ////                                 ////
+        ////     Generic  -->  various CS    ////
+        ////     Various CS --> Generic      ////
+        ////                                 ////
+        /////////////////////////////////////////
+        if (sourceCRS == DefaultEngineeringCRS.GENERIC_2D ||
+            targetCRS == DefaultEngineeringCRS.GENERIC_2D ||
+            sourceCRS == DefaultEngineeringCRS.GENERIC_3D ||
+            targetCRS == DefaultEngineeringCRS.GENERIC_3D)
+        {
+            final int dimSource = getDimension(sourceCRS);
+            final int dimTarget = getDimension(targetCRS);
+            if (dimTarget == dimSource) {
+                final Matrix matrix = MatrixFactory.create(dimTarget+1, dimSource+1);
+                return createFromAffineTransform(IDENTITY, sourceCRS, targetCRS, matrix);
+            }
+        }
+        throw new OperationNotFoundException(getErrorMessage(sourceCRS, targetCRS));
+    }
+
+    /**
+     * Returns an operation using a particular method for conversion or transformation
+     * between two coordinate reference systems.
+     * If the operation exists on the implementation, then it is returned.
+     * If the operation does not exist on the implementation, then the implementation has the option
+     * of inferring the operation from the argument objects.
+     * If for whatever reason the specified operation will not be returned, then the exception is
+     * thrown.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @param  method the algorithmic method for conversion or transformation
+     * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS}
+     *         to {@code targetCRS}.
+     * @throws FactoryException if the operation creation failed for some other reason.
+     *
+     * @deprecated Current implementation ignore the {@code method} argument.
+     */
+    public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
+                                               final CoordinateReferenceSystem targetCRS,
+                                               final OperationMethod           method)
+            throws OperationNotFoundException, FactoryException
+    {
+        return createOperation(sourceCRS, targetCRS);
+    }
+
+
+
+
+    /////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////
+    ////////////                                                         ////////////
+    ////////////               N O R M A L I Z A T I O N S               ////////////
+    ////////////                                                         ////////////
+    /////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Makes sure that the specified geocentric CRS uses standard axis,
+     * prime meridian and the specified datum.
+     * If {@code crs} already meets all those conditions, then it is
+     * returned unchanged. Otherwise, a new normalized geocentric CRS is
+     * created and returned.
+     *
+     * @param  crs The geocentric coordinate reference system to normalize.
+     * @param  datum The expected datum.
+     * @return The normalized coordinate reference system.
+     * @throws FactoryException if the construction of a new CRS was needed but failed.
+     */
+    private GeocentricCRS normalize(final GeocentricCRS crs,
+                                    final GeodeticDatum datum)
+            throws FactoryException
+    {
+        final CartesianCS   STANDARD  = DefaultCartesianCS.GEOCENTRIC;
+        final GeodeticDatum candidate = crs.getDatum();
+        if (equalsIgnorePrimeMeridian(candidate, datum)) {
+            if (getGreenwichLongitude(candidate.getPrimeMeridian()) ==
+                getGreenwichLongitude(datum    .getPrimeMeridian()))
+            {
+                if (hasStandardAxis(crs.getCoordinateSystem(), STANDARD)) {
+                    return crs;
+                }
+            }
+        }
+        final CRSFactory crsFactory = getFactoryContainer().getCRSFactory();
+        return crsFactory.createGeocentricCRS(getTemporaryName(crs), datum, STANDARD);
+    }
+
+    /**
+     * Makes sure that the specified geographic CRS uses standard axis (longitude and latitude in
+     * decimal degrees). Optionally, this method can also make sure that the CRS use the Greenwich
+     * prime meridian. Other datum properties are left unchanged. If {@code crs} already meets all
+     * those conditions, then it is returned unchanged. Otherwise, a new normalized geographic CRS
+     * is created and returned.
+     *
+     * @param  crs The geographic coordinate reference system to normalize.
+     * @param  forceGreenwich {@code true} for forcing the Greenwich prime meridian.
+     * @return The normalized coordinate reference system.
+     * @throws FactoryException if the construction of a new CRS was needed but failed.
+     */
+    private GeographicCRS normalize(final GeographicCRS      crs,
+                                    final boolean forceGreenwich)
+            throws FactoryException
+    {
+              GeodeticDatum datum = crs.getDatum();
+        final EllipsoidalCS cs    = crs.getCoordinateSystem();
+        final EllipsoidalCS STANDARD = (cs.getDimension() <= 2) ?
+                                        DefaultEllipsoidalCS.GEODETIC_2D :
+                                        DefaultEllipsoidalCS.GEODETIC_3D;
+        if (forceGreenwich && getGreenwichLongitude(datum.getPrimeMeridian()) != 0) {
+            datum = new TemporaryDatum(datum);
+        } else if (hasStandardAxis(cs, STANDARD)) {
+            return crs;
+        }
+        /*
+         * The specified geographic coordinate system doesn't use standard axis
+         * (EAST, NORTH) or the greenwich meridian. Create a new one meeting those criterions.
+         */
+        final CRSFactory crsFactory = getFactoryContainer().getCRSFactory();
+        return crsFactory.createGeographicCRS(getTemporaryName(crs), datum, STANDARD);
+    }
+
+    /**
+     * A datum identical to the specified datum except for the prime meridian, which is replaced
+     * by Greenwich. This datum is processed in a special way by {@link #equalsIgnorePrimeMeridian}.
+     */
+    private static final class TemporaryDatum extends DefaultGeodeticDatum {
+        /** For cros-version compatibility. */
+        private static final long serialVersionUID = -8964199103509187219L;
+
+        /** The wrapped datum. */
+        private final GeodeticDatum datum;
+
+        /** Wrap the specified datum. */
+        public TemporaryDatum(final GeodeticDatum datum) {
+            super(getTemporaryName(datum), datum.getEllipsoid(), DefaultPrimeMeridian.GREENWICH);
+            this.datum = datum;
+        }
+
+        /** Unwrap the datum. */
+        public static GeodeticDatum unwrap(GeodeticDatum datum) {
+            while (datum instanceof TemporaryDatum) {
+                datum = ((TemporaryDatum) datum).datum;
+            }
+            return datum;
+        }
+
+        /** Compares this datum with the specified object for equality. */
+        @Override
+        public boolean equals(final AbstractIdentifiedObject object,
+                              final boolean compareMetadata)
+        {
+            if (super.equals(object, compareMetadata)) {
+                final GeodeticDatum other = ((TemporaryDatum) object).datum;
+                return compareMetadata ? datum.equals(other) : equalsIgnoreMetadata(datum, other);
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Returns {@code true} if the specified coordinate system
+     * use standard axis and units.
+     *
+     * @param crs  The coordinate system to test.
+     * @param standard The coordinate system that defines the standard. Usually
+     *        {@link DefaultEllipsoidalCS#GEODETIC_2D} or
+     *        {@link DefaultCartesianCS#PROJECTED}.
+     */
+    private static boolean hasStandardAxis(final CoordinateSystem cs,
+                                           final CoordinateSystem standard)
+    {
+        final int dimension = standard.getDimension();
+        if (cs.getDimension() != dimension) {
+            return false;
+        }
+        for (int i=0; i<dimension; i++) {
+            final CoordinateSystemAxis a1 =       cs.getAxis(i);
+            final CoordinateSystemAxis a2 = standard.getAxis(i);
+            if (!a1.getDirection().equals(a2.getDirection()) ||
+                !a1.getUnit()     .equals(a2.getUnit()))
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+
+
+    /////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////
+    ////////////                                                         ////////////
+    ////////////            A X I S   O R I E N T A T I O N S            ////////////
+    ////////////                                                         ////////////
+    /////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns an affine transform between two ellipsoidal coordinate systems. Only
+     * units, axis order (e.g. transforming from (NORTH,WEST) to (EAST,NORTH)) and
+     * prime meridian are taken in account. Other attributes (especially the datum)
+     * must be checked before invoking this method.
+     *
+     * @param  sourceCS The source coordinate system.
+     * @param  targetCS The target coordinate system.
+     * @param  sourcePM The source prime meridian.
+     * @param  targetPM The target prime meridian.
+     * @return The transformation from {@code sourceCS} to {@code targetCS} as
+     *         an affine transform. Only axis orientation, units and prime meridian are
+     *         taken in account.
+     * @throws OperationNotFoundException If the affine transform can't be constructed.
+     */
+    private Matrix swapAndScaleAxis(final EllipsoidalCS sourceCS,
+                                    final EllipsoidalCS targetCS,
+                                    final PrimeMeridian sourcePM,
+                                    final PrimeMeridian targetPM)
+            throws OperationNotFoundException
+    {
+        final Matrix matrix = swapAndScaleAxis(sourceCS, targetCS);
+        for (int i=targetCS.getDimension(); --i>=0;) {
+            final CoordinateSystemAxis axis = targetCS.getAxis(i);
+            final AxisDirection direction = axis.getDirection();
+            if (AxisDirection.EAST.equals(direction.absolute())) {
+                /*
+                 * A longitude ordinate has been found (i.e. the axis is oriented toward EAST or
+                 * WEST). Compute the amount of angle to add to the source longitude in order to
+                 * get the destination longitude. This amount is measured in units of the target
+                 * axis.  The affine transform is then updated in order to take this rotation in
+                 * account. Note that the resulting longitude may be outside the usual [-180..180°]
+                 * range.
+                 */
+                final Unit<Angle>       unit = axis.getUnit().asType(Angle.class);
+                final double sourceLongitude = getGreenwichLongitude(sourcePM, unit);
+                final double targetLongitude = getGreenwichLongitude(targetPM, unit);
+                final int   lastMatrixColumn = matrix.getNumCol()-1;
+                double rotate = sourceLongitude - targetLongitude;
+                if (AxisDirection.WEST.equals(direction)) {
+                    rotate = -rotate;
+                }
+                rotate += matrix.getElement(i, lastMatrixColumn);
+                matrix.setElement(i, lastMatrixColumn, rotate);
+            }
+        }
+        return matrix;
+    }
+
+    /**
+     * Returns the longitude value relative to the Greenwich Meridian,
+     * expressed in the specified units.
+     */
+    private static double getGreenwichLongitude(final PrimeMeridian pm, final Unit<Angle> unit) {
+        return pm.getAngularUnit().getConverterTo(unit).convert(pm.getGreenwichLongitude());
+    }
+
+    /**
+     * Returns the longitude value relative to the Greenwich Meridian, expressed in decimal degrees.
+     */
+    private static double getGreenwichLongitude(final PrimeMeridian pm) {
+        return getGreenwichLongitude(pm, NonSI.DEGREE_ANGLE);
+    }
+
+
+
+
+    /////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////
+    ////////////                                                         ////////////
+    ////////////        T R A N S F O R M A T I O N S   S T E P S        ////////////
+    ////////////                                                         ////////////
+    /////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Creates an operation between two temporal coordinate reference systems.
+     * The default implementation checks if both CRS use the same datum, and
+     * then adjusts for axis direction, units and epoch.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     */
+    protected CoordinateOperation createOperationStep(final TemporalCRS sourceCRS,
+                                                      final TemporalCRS targetCRS)
+            throws FactoryException
+    {
+        final TemporalDatum sourceDatum = sourceCRS.getDatum();
+        final TemporalDatum targetDatum = targetCRS.getDatum();
+        if (!equalsIgnoreMetadata(sourceDatum, targetDatum)) {
+            throw new OperationNotFoundException(getErrorMessage(sourceDatum, targetDatum));
+        }
+        /*
+         * Compute the epoch shift.  The epoch is the time "0" in a particular coordinate
+         * reference system. For example, the epoch for java.util.Date object is january 1,
+         * 1970 at 00:00 UTC.  We compute how much to add to a time in 'sourceCRS' in order
+         * to get a time in 'targetCRS'. This "epoch shift" is in units of 'targetCRS'.
+         */
+        final TimeCS sourceCS = sourceCRS.getCoordinateSystem();
+        final TimeCS targetCS = targetCRS.getCoordinateSystem();
+        final Unit targetUnit = targetCS.getAxis(0).getUnit();
+        double epochShift = sourceDatum.getOrigin().getTime() -
+                            targetDatum.getOrigin().getTime();
+        epochShift = MILLISECOND.getConverterTo(targetUnit).convert(epochShift);
+        /*
+         * Check axis orientation.  The method 'swapAndScaleAxis' should returns a matrix
+         * of size 2x2. The element at index (0,0) may be 1 if sourceCRS and targetCRS axis
+         * are in the same direction, or -1 if there are in opposite direction (e.g.
+         * "PAST" vs "FUTURE"). This number may be something else than -1 or +1 if a unit
+         * conversion was applied too,  for example 60 if time in 'sourceCRS' was in hours
+         * while time in 'targetCRS' was in minutes.
+         *
+         * The "epoch shift" previously computed is a translation.
+         * Consequently, it is added to element (0,1).
+         */
+        final Matrix matrix = swapAndScaleAxis(sourceCS, targetCS);
+        final int translationColumn = matrix.getNumCol()-1;
+        if (translationColumn >= 0) { // Paranoiac check: should always be 1.
+            final double translation = matrix.getElement(0, translationColumn);
+            matrix.setElement(0, translationColumn, translation+epochShift);
+        }
+        return createFromAffineTransform(AXIS_CHANGES, sourceCRS, targetCRS, matrix);
+    }
+
+    /**
+     * Creates an operation between two vertical coordinate reference systems.
+     * The default implementation checks if both CRS use the same datum, and
+     * then adjusts for axis direction and units.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     */
+    protected CoordinateOperation createOperationStep(final VerticalCRS sourceCRS,
+                                                      final VerticalCRS targetCRS)
+            throws FactoryException
+    {
+        final VerticalDatum sourceDatum = sourceCRS.getDatum();
+        final VerticalDatum targetDatum = targetCRS.getDatum();
+        if (!equalsIgnoreMetadata(sourceDatum, targetDatum)) {
+            throw new OperationNotFoundException(getErrorMessage(sourceDatum, targetDatum));
+        }
+        final VerticalCS sourceCS = sourceCRS.getCoordinateSystem();
+        final VerticalCS targetCS = targetCRS.getCoordinateSystem();
+        final Matrix     matrix   = swapAndScaleAxis(sourceCS, targetCS);
+        return createFromAffineTransform(AXIS_CHANGES, sourceCRS, targetCRS, matrix);
+    }
+
+    /**
+     * Creates an operation between a geographic and a vertical coordinate reference systems.
+     * The default implementation accepts the conversion only if the geographic CRS is a tri
+     * dimensional one and the vertical CRS is for {@linkplain VerticalDatumType#ELLIPSOIDAL
+     * height above the ellipsoid}. More elaborated operation, like transformation from
+     * ellipsoidal to geoidal height, should be implemented here.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     *
+     * @todo Implement GEOT-352 here.
+     */
+    protected CoordinateOperation createOperationStep(final GeographicCRS sourceCRS,
+                                                      final VerticalCRS   targetCRS)
+            throws FactoryException
+    {
+        if (VerticalDatumType.ELLIPSOIDAL.equals(targetCRS.getDatum().getVerticalDatumType())) {
+            final Matrix matrix = swapAndScaleAxis(sourceCRS.getCoordinateSystem(),
+                                                   targetCRS.getCoordinateSystem());
+            return createFromAffineTransform(AXIS_CHANGES, sourceCRS, targetCRS, matrix);
+        }
+        throw new OperationNotFoundException(getErrorMessage(sourceCRS, targetCRS));
+    }
+
+    /**
+     * Creates an operation between two geographic coordinate reference systems. The default
+     * implementation can adjust axis order and orientation (e.g. transforming from
+     * {@code (NORTH,WEST)} to {@code (EAST,NORTH)}), performs units conversion
+     * and apply datum shifts if needed.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     *
+     * @todo When rotating the prime meridian, we should ensure that
+     *       transformed longitudes stay in the range [-180..+180°].
+     */
+    protected CoordinateOperation createOperationStep(final GeographicCRS sourceCRS,
+                                                      final GeographicCRS targetCRS)
+            throws FactoryException
+    {
+        final EllipsoidalCS sourceCS    = sourceCRS.getCoordinateSystem();
+        final EllipsoidalCS targetCS    = targetCRS.getCoordinateSystem();
+        final GeodeticDatum sourceDatum = sourceCRS.getDatum();
+        final GeodeticDatum targetDatum = targetCRS.getDatum();
+        final PrimeMeridian sourcePM    = sourceDatum.getPrimeMeridian();
+        final PrimeMeridian targetPM    = targetDatum.getPrimeMeridian();
+        if (equalsIgnorePrimeMeridian(sourceDatum, targetDatum)) {
+            /*
+             * If both geographic CRS use the same datum, then there is no need for a datum shift.
+             * Just swap axis order, and rotate the longitude coordinate if prime meridians are
+             * different. Note: this special block is mandatory for avoiding never-ending loop,
+             * since it is invoked by 'createOperationStep(GeocentricCRS...)'.
+             *
+             * TODO: We should ensure that longitude is in range [-180..+180°].
+             */
+            final Matrix matrix = swapAndScaleAxis(sourceCS, targetCS, sourcePM, targetPM);
+            return createFromAffineTransform(AXIS_CHANGES, sourceCRS, targetCRS, matrix);
+        }
+        /*
+         * The two geographic CRS use different datum. If Molodenski transformations
+         * are allowed, try them first. Note that is some case if the datum shift can't
+         * be performed in a single Molodenski transformation step (i.e. if we need to
+         * go through at least one intermediate datum), then we will use the geocentric
+         * transform below instead: it allows to concatenates many Bursa Wolf parameters
+         * in a single affine transform.
+         */
+        if (molodenskiMethod != null) {
+            ReferenceIdentifier identifier = DATUM_SHIFT;
+            BursaWolfParameters bursaWolf  = null;
+            if (sourceDatum instanceof DefaultGeodeticDatum) {
+                bursaWolf = ((DefaultGeodeticDatum) sourceDatum).getBursaWolfParameters(targetDatum);
+            }
+            if (bursaWolf == null) {
+                /*
+                 * No direct path found. Try the more expensive matrix calculation, and
+                 * see if we can retrofit the result in a BursaWolfParameters object.
+                 */
+                final Matrix shift = DefaultGeodeticDatum.getAffineTransform(sourceDatum, targetDatum);
+                if (shift != null) try {
+                    bursaWolf = new BursaWolfParameters(targetDatum);
+                    bursaWolf.setAffineTransform(shift, 1E-4);
+                } catch (IllegalArgumentException ignore) {
+                    /*
+                     * A matrix exists, but we are unable to retrofit it as a set of Bursa-Wolf
+                     * parameters. Do NOT set the 'bursaWolf' variable: it must stay null, which
+                     * means to perform the datum shift using geocentric coordinates.
+                     */
+                } else if (lenientDatumShift) {
+                    /*
+                     * No BursaWolf parameters available. No affine transform to be applied in
+                     * geocentric coordinates are available neither (the "shift" matrix above),
+                     * so performing a geocentric transformation will not help. But the user wants
+                     * us to perform the datum shift anyway. We will notify the user through
+                     * positional accuracy, which is set indirectly through ELLIPSOID_SHIFT.
+                     */
+                    bursaWolf  = new BursaWolfParameters(targetDatum);
+                    identifier = ELLIPSOID_SHIFT;
+                }
+            }
+            /*
+             * Applies the Molodenski transformation now. Note: in current parameters, we can't
+             * specify a different input and output dimension. However, our Molodenski transform
+             * allows that. We should expand the parameters block for this case (TODO).
+             */
+            if (bursaWolf!=null && bursaWolf.isTranslation()) {
+                final Ellipsoid sourceEllipsoid = sourceDatum.getEllipsoid();
+                final Ellipsoid targetEllipsoid = targetDatum.getEllipsoid();
+                if (bursaWolf.isIdentity() && equalsIgnoreMetadata(sourceEllipsoid, targetEllipsoid)) {
+                    final Matrix matrix = swapAndScaleAxis(sourceCS, targetCS, sourcePM, targetPM);
+                    return createFromAffineTransform(identifier, sourceCRS, targetCRS, matrix);
+                }
+                final int sourceDim = getDimension(sourceCRS);
+                final int targetDim = getDimension(targetCRS);
+                final ParameterValueGroup parameters;
+                parameters = getMathTransformFactory().getDefaultParameters(molodenskiMethod);
+                parameters.parameter("src_semi_major").setValue(sourceEllipsoid.getSemiMajorAxis());
+                parameters.parameter("src_semi_minor").setValue(sourceEllipsoid.getSemiMinorAxis());
+                parameters.parameter("tgt_semi_major").setValue(targetEllipsoid.getSemiMajorAxis());
+                parameters.parameter("tgt_semi_minor").setValue(targetEllipsoid.getSemiMinorAxis());
+                parameters.parameter("dx")            .setValue(bursaWolf.dx);
+                parameters.parameter("dy")            .setValue(bursaWolf.dy);
+                parameters.parameter("dz")            .setValue(bursaWolf.dz);
+                parameters.parameter("dim")           .setValue(sourceDim);
+                if (sourceDim == targetDim) {
+                    final CoordinateOperation step1, step2, step3;
+                    final GeographicCRS normSourceCRS = normalize(sourceCRS, true);
+                    final GeographicCRS normTargetCRS = normalize(targetCRS, true);
+                    step1 = createOperationStep(sourceCRS, normSourceCRS);
+                    step2 = createFromParameters(identifier, normSourceCRS, normTargetCRS, parameters);
+                    step3 = createOperationStep(normTargetCRS, targetCRS);
+                    return concatenate(step1, step2, step3);
+                } else {
+                    // TODO: Need some way to pass 'targetDim' to Molodenski.
+                    //       Fallback on geocentric transformations for now.
+                }
+            }
+        }
+        /*
+         * If the two geographic CRS use different datum, transform from the
+         * source to target datum through the geocentric coordinate system.
+         * The transformation chain is:
+         *
+         *     source geographic CRS                                               -->
+         *     geocentric CRS with a preference for datum using Greenwich meridian -->
+         *     target geographic CRS
+         */
+        final CartesianCS STANDARD = DefaultCartesianCS.GEOCENTRIC;
+        final GeocentricCRS stepCRS;
+        final CRSFactory crsFactory = getFactoryContainer().getCRSFactory();
+        if (getGreenwichLongitude(targetPM) == 0) {
+            stepCRS = crsFactory.createGeocentricCRS(
+                      getTemporaryName(targetCRS), targetDatum, STANDARD);
+        } else {
+            stepCRS = crsFactory.createGeocentricCRS(
+                      getTemporaryName(sourceCRS), sourceDatum, STANDARD);
+        }
+        final CoordinateOperation step1 = createOperationStep(sourceCRS, stepCRS);
+        final CoordinateOperation step2 = createOperationStep(stepCRS, targetCRS);
+        return concatenate(step1, step2);
+    }
+
+    /**
+     * Creates an operation between two projected coordinate reference systems.
+     * The default implementation can adjust axis order and orientation. It also
+     * performs units conversion if it is the only extra change needed. Otherwise,
+     * it performs three steps:
+     *
+     * <ul>
+     *   <li>Unproject from {@code sourceCRS} to its base
+     *       {@linkplain GeographicCRS geographic CRS}.</li>
+     *   <li>Convert the source to target base geographic CRS.</li>
+     *   <li>Project from the base {@linkplain GeographicCRS geographic CRS}
+     *       to the {@code targetCRS}.</li>
+     * </ul>
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     */
+    protected CoordinateOperation createOperationStep(final ProjectedCRS sourceCRS,
+                                                      final ProjectedCRS targetCRS)
+            throws FactoryException
+    {
+        /*
+         * First, check if a linear path exists from sourceCRS to targetCRS.
+         * If both projected CRS use the same projection and the same horizontal datum,
+         * then only axis orientation and units may have been changed. We do not need
+         * to perform the tedious  ProjectedCRS --> GeographicCRS --> ProjectedCRS  chain.
+         * We can apply a much shorter conversion using only an affine transform.
+         *
+         * This shorter path is essential for proper working of
+         * createOperationStep(GeographicCRS,ProjectedCRS).
+         */
+        final Matrix linear = createLinearConversion(sourceCRS, targetCRS, EPS);
+        if (linear != null) {
+            return createFromAffineTransform(AXIS_CHANGES, sourceCRS, targetCRS, linear);
+        }
+        /*
+         * Apply the transformation in 3 steps (the 3 arrows below):
+         *
+         *     source projected CRS   --(unproject)-->
+         *     source geographic CRS  --------------->
+         *     target geographic CRS  ---(project)--->
+         *     target projected CRS
+         */
+        final GeographicCRS sourceGeo = sourceCRS.getBaseCRS();
+        final GeographicCRS targetGeo = targetCRS.getBaseCRS();
+        CoordinateOperation step1, step2, step3;
+        step1 = tryDB(sourceCRS, sourceGeo); if (step1==null) step1 = createOperationStep(sourceCRS, sourceGeo);
+        step2 = tryDB(sourceGeo, targetGeo); if (step2==null) step2 = createOperationStep(sourceGeo, targetGeo);
+        step3 = tryDB(targetGeo, targetCRS); if (step3==null) step3 = createOperationStep(targetGeo, targetCRS);
+        return concatenate(step1, step2, step3);
+    }
+
+    /**
+     * Creates an operation from a geographic to a projected coordinate reference system.
+     * The default implementation constructs the following operation chain:
+     *
+     * <blockquote><pre>
+     * sourceCRS  &rarr;  {@linkplain ProjectedCRS#getBaseCRS baseCRS}  &rarr;  targetCRS
+     * </pre></blockquote>
+     *
+     * where the conversion from {@code baseCRS} to {@code targetCRS} is obtained
+     * from <code>targetCRS.{@linkplain ProjectedCRS#getConversionFromBase
+     * getConversionFromBase()}</code>.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     */
+    protected CoordinateOperation createOperationStep(final GeographicCRS sourceCRS,
+                                                      final ProjectedCRS  targetCRS)
+            throws FactoryException
+    {
+        GeographicCRS       base  = targetCRS.getBaseCRS();
+        CoordinateOperation step2 = targetCRS.getConversionFromBase();
+        CoordinateOperation step1 = tryDB(sourceCRS, base);
+        if (step1 == null) {
+            step1 = createOperationStep(sourceCRS, base);
+        }
+        return concatenate(step1, step2);
+    }
+
+    /**
+     * Creates an operation from a projected to a geographic coordinate reference system.
+     * The default implementation constructs the following operation chain:
+     *
+     * <blockquote><pre>
+     * sourceCRS  &rarr;  {@linkplain ProjectedCRS#getBaseCRS baseCRS}  &rarr;  targetCRS
+     * </pre></blockquote>
+     *
+     * where the conversion from {@code sourceCRS} to {@code baseCRS} is obtained
+     * from the inverse of
+     * <code>sourceCRS.{@linkplain ProjectedCRS#getConversionFromBase
+     * getConversionFromBase()}</code>.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     *
+     * @todo Provides a non-null method.
+     */
+    protected CoordinateOperation createOperationStep(final ProjectedCRS  sourceCRS,
+                                                      final GeographicCRS targetCRS)
+            throws FactoryException
+    {
+        final GeographicCRS base  = sourceCRS.getBaseCRS();
+        CoordinateOperation step1 = sourceCRS.getConversionFromBase();
+        CoordinateOperation step2 = tryDB(base, targetCRS);
+        if (step2 == null) {
+            step2 = createOperationStep(base, targetCRS);
+        }
+        MathTransform transform = step1.getMathTransform();
+        try {
+            transform = transform.inverse();
+        } catch (NoninvertibleTransformException exception) {
+            throw new OperationNotFoundException(getErrorMessage(sourceCRS, base), exception);
+        }
+        step1 = createFromMathTransform(INVERSE_OPERATION, sourceCRS, base, transform);
+        return concatenate(step1, step2);
+    }
+
+    /**
+     * Creates an operation between two geocentric coordinate reference systems.
+     * The default implementation can adjust for axis order and orientation,
+     * performs units conversion and apply Bursa Wolf transformation if needed.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     *
+     * @todo Rotation of prime meridian not yet implemented.
+     * @todo Transformation version set to "(unknow)". We should search this information somewhere.
+     */
+    protected CoordinateOperation createOperationStep(final GeocentricCRS sourceCRS,
+                                                      final GeocentricCRS targetCRS)
+            throws FactoryException
+    {
+        final GeodeticDatum sourceDatum = sourceCRS.getDatum();
+        final GeodeticDatum targetDatum = targetCRS.getDatum();
+        final CoordinateSystem sourceCS = sourceCRS.getCoordinateSystem();
+        final CoordinateSystem targetCS = targetCRS.getCoordinateSystem();
+        final double sourcePM, targetPM;
+        sourcePM = getGreenwichLongitude(sourceDatum.getPrimeMeridian());
+        targetPM = getGreenwichLongitude(targetDatum.getPrimeMeridian());
+        if (equalsIgnorePrimeMeridian(sourceDatum, targetDatum)) {
+            if (sourcePM == targetPM) {
+                /*
+                 * If both CRS use the same datum and the same prime meridian,
+                 * then the transformation is probably just axis swap or unit
+                 * conversions.
+                 */
+                final Matrix matrix = swapAndScaleAxis(sourceCS, targetCS);
+                return createFromAffineTransform(AXIS_CHANGES, sourceCRS, targetCRS, matrix);
+            }
+            // Prime meridians are differents. Performs the full transformation.
+        }
+        if (sourcePM != targetPM) {
+            throw new OperationNotFoundException("Rotation of prime meridian not yet implemented");
+        }
+        /*
+         * Transform between differents ellipsoids using Bursa Wolf parameters.
+         * The Bursa Wolf parameters are used with "standard" geocentric CS, i.e.
+         * with x axis towards the prime meridian, y axis towards East and z axis
+         * toward North. The following steps are applied:
+         *
+         *     source CRS                      -->
+         *     standard CRS with source datum  -->
+         *     standard CRS with target datum  -->
+         *     target CRS
+         */
+        final CartesianCS STANDARD = DefaultCartesianCS.GEOCENTRIC;
+        final XMatrix matrix;
+        ReferenceIdentifier identifier = DATUM_SHIFT;
+        try {
+            Matrix datumShift = DefaultGeodeticDatum.getAffineTransform(
+                                    TemporaryDatum.unwrap(sourceDatum),
+                                    TemporaryDatum.unwrap(targetDatum));
+            if (datumShift == null) {
+                if (lenientDatumShift) {
+                    datumShift = new Matrix4(); // Identity transform.
+                    identifier = ELLIPSOID_SHIFT;
+                } else {
+                    throw new OperationNotFoundException(Errors.format(
+                                ErrorKeys.BURSA_WOLF_PARAMETERS_REQUIRED));
+                }
+            }
+            final Matrix normalizeSource = swapAndScaleAxis(sourceCS, STANDARD);
+            final Matrix normalizeTarget = swapAndScaleAxis(STANDARD, targetCS);
+            /*
+             * Since all steps are matrix, we can multiply them into a single matrix operation.
+             * Note: XMatrix.multiply(XMatrix) is equivalents to AffineTransform.concatenate(...):
+             *       First transform by the supplied transform and then transform the result
+             *       by the original transform.
+             *
+             * We compute: matrix = normalizeTarget * datumShift * normalizeSource
+             */
+            matrix = new Matrix4(normalizeTarget);
+            matrix.multiply(datumShift);
+            matrix.multiply(normalizeSource);
+        } catch (SingularMatrixException cause) {
+            throw new OperationNotFoundException(getErrorMessage(sourceDatum, targetDatum), cause);
+        }
+        return createFromAffineTransform(identifier, sourceCRS, targetCRS, matrix);
+    }
+
+    /**
+     * Creates an operation from a geographic to a geocentric coordinate reference systems.
+     * If the source CRS doesn't have a vertical axis, height above the ellipsoid will be
+     * assumed equals to zero everywhere. The default implementation uses the
+     * {@code "Ellipsoid_To_Geocentric"} math transform.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     */
+    protected CoordinateOperation createOperationStep(final GeographicCRS sourceCRS,
+                                                      final GeocentricCRS targetCRS)
+            throws FactoryException
+    {
+        /*
+         * This transformation is a 3 steps process:
+         *
+         *    source     geographic CRS  -->
+         *    normalized geographic CRS  -->
+         *    normalized geocentric CRS  -->
+         *    target     geocentric CRS
+         *
+         * "Normalized" means that axis point toward standards direction (East, North, etc.),
+         * units are metres or decimal degrees, prime meridian is Greenwich and height is measured
+         * above the ellipsoid. However, the horizontal datum is preserved.
+         */
+        final GeographicCRS normSourceCRS = normalize(sourceCRS, true);
+        final GeodeticDatum datum         = normSourceCRS.getDatum();
+        final GeocentricCRS normTargetCRS = normalize(targetCRS, datum);
+        final Ellipsoid         ellipsoid = datum.getEllipsoid();
+        final Unit                   unit = ellipsoid.getAxisUnit();
+        final ParameterValueGroup   param;
+        param = getMathTransformFactory().getDefaultParameters("Ellipsoid_To_Geocentric");
+        param.parameter("semi_major").setValue(ellipsoid.getSemiMajorAxis(), unit);
+        param.parameter("semi_minor").setValue(ellipsoid.getSemiMinorAxis(), unit);
+        param.parameter("dim")       .setValue(getDimension(normSourceCRS));
+
+        final CoordinateOperation step1, step2, step3;
+        step1 = createOperationStep (sourceCRS, normSourceCRS);
+        step2 = createFromParameters(GEOCENTRIC_CONVERSION, normSourceCRS, normTargetCRS, param);
+        step3 = createOperationStep (normTargetCRS, targetCRS);
+        return concatenate(step1, step2, step3);
+    }
+
+    /**
+     * Creates an operation from a geocentric to a geographic coordinate reference systems.
+     * The default implementation use the <code>"Geocentric_To_Ellipsoid"</code> math transform.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     */
+    protected CoordinateOperation createOperationStep(final GeocentricCRS sourceCRS,
+                                                      final GeographicCRS targetCRS)
+            throws FactoryException
+    {
+        final GeographicCRS normTargetCRS = normalize(targetCRS, true);
+        final GeodeticDatum datum         = normTargetCRS.getDatum();
+        final GeocentricCRS normSourceCRS = normalize(sourceCRS, datum);
+        final Ellipsoid         ellipsoid = datum.getEllipsoid();
+        final Unit                   unit = ellipsoid.getAxisUnit();
+        final ParameterValueGroup   param;
+        param = getMathTransformFactory().getDefaultParameters("Geocentric_To_Ellipsoid");
+        param.parameter("semi_major").setValue(ellipsoid.getSemiMajorAxis(), unit);
+        param.parameter("semi_minor").setValue(ellipsoid.getSemiMinorAxis(), unit);
+        param.parameter("dim")       .setValue(getDimension(normTargetCRS));
+
+        final CoordinateOperation step1, step2, step3;
+        step1 = createOperationStep (sourceCRS, normSourceCRS);
+        step2 = createFromParameters(GEOCENTRIC_CONVERSION, normSourceCRS, normTargetCRS, param);
+        step3 = createOperationStep (normTargetCRS, targetCRS);
+        return concatenate(step1, step2, step3);
+    }
+
+    /**
+     * Creates an operation from a compound to a single coordinate reference systems.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     *
+     * @todo (GEOT-401) This method work for some simple cases (e.g. no datum change), and give up
+     *       otherwise. Before to give up at the end of this method, we should try the following:
+     *       <ul>
+     *         <li>Maybe {@code sourceCRS} uses a non-ellipsoidal height. We should replace
+     *             the non-ellipsoidal height by an ellipsoidal one, create a transformation step
+     *             for that (to be concatenated), and then try again this operation step.</li>
+     *
+     *         <li>Maybe {@code sourceCRS} contains some extra axis, like a temporal CRS.
+     *             We should revisit this code in other to lets supplemental ordinates to be
+     *             pass through or removed.</li>
+     *       </ul>
+     */
+    protected CoordinateOperation createOperationStep(final CompoundCRS sourceCRS,
+                                                      final SingleCRS   targetCRS)
+            throws FactoryException
+    {
+        final List<SingleCRS> sources = DefaultCompoundCRS.getSingleCRS(sourceCRS);
+        if (sources.size() == 1) {
+            return createOperation(sources.get(0), targetCRS);
+        }
+        if (!needsGeodetic3D(sources, targetCRS)) {
+            // No need for a datum change (see 'needGeodetic3D' javadoc).
+            final List<SingleCRS> targets = Collections.singletonList(targetCRS);
+            return createOperationStep(sourceCRS, sources, targetCRS, targets);
+        }
+        /*
+         * There is a change of datum.  It may be a vertical datum change (for example from
+         * ellipsoidal to geoidal height), in which case geographic coordinates are usually
+         * needed. It may also be a geodetic datum change, in which case the height is part
+         * of computation. Try to convert the source CRS into a 3D-geodetic CRS.
+         */
+        final CoordinateReferenceSystem source3D = getFactoryContainer().toGeodetic3D(sourceCRS);
+        if (source3D != sourceCRS) {
+            return createOperation(source3D, targetCRS);
+        }
+        /*
+         * TODO: Search for non-ellipsoidal height, and lets supplemental axis (e.g. time)
+         *       pass through. See javadoc comments above.
+         */
+        throw new OperationNotFoundException(getErrorMessage(sourceCRS, targetCRS));
+    }
+
+    /**
+     * Creates an operation from a single to a compound coordinate reference system.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     */
+    protected CoordinateOperation createOperationStep(final SingleCRS   sourceCRS,
+                                                      final CompoundCRS targetCRS)
+            throws FactoryException
+    {
+        final List<SingleCRS> targets = DefaultCompoundCRS.getSingleCRS(targetCRS);
+        if (targets.size() == 1) {
+            return createOperation(sourceCRS, targets.get(0));
+        }
+        /*
+         * This method has almost no chance to succeed (we can't invent ordinate values!) unless
+         * 'sourceCRS' is a 3D-geodetic CRS and 'targetCRS' is a 2D + 1D one. Test for this case.
+         * Otherwise, the 'createOperationStep' invocation will throws the appropriate exception.
+         */
+        final CoordinateReferenceSystem target3D = getFactoryContainer().toGeodetic3D(targetCRS);
+        if (target3D != targetCRS) {
+            return createOperation(sourceCRS, target3D);
+        }
+        final List<SingleCRS> sources = Collections.singletonList(sourceCRS);
+        return createOperationStep(sourceCRS, sources, targetCRS, targets);
+    }
+
+    /**
+     * Creates an operation between two compound coordinate reference systems.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     */
+    protected CoordinateOperation createOperationStep(final CompoundCRS sourceCRS,
+                                                      final CompoundCRS targetCRS)
+            throws FactoryException
+    {
+        final List<SingleCRS> sources = DefaultCompoundCRS.getSingleCRS(sourceCRS);
+        final List<SingleCRS> targets = DefaultCompoundCRS.getSingleCRS(targetCRS);
+        if (targets.size() == 1) {
+            return createOperation(sourceCRS, targets.get(0));
+        }
+        if (sources.size() == 1) { // After 'targets' because more likely to fails to transform.
+            return createOperation(sources.get(0), targetCRS);
+        }
+        /*
+         * If the source CRS contains both a geodetic and a vertical CRS, then we can process
+         * only if there is no datum change. If at least one of those CRS appears in the target
+         * CRS with a different datum, then the datum shift must be applied on the horizontal and
+         * vertical components together.
+         */
+        for (final SingleCRS target : targets) {
+            if (needsGeodetic3D(sources, target)) {
+                final ReferencingFactoryContainer factories = getFactoryContainer();
+                final CoordinateReferenceSystem source3D = factories.toGeodetic3D(sourceCRS);
+                final CoordinateReferenceSystem target3D = factories.toGeodetic3D(targetCRS);
+                if (source3D!=sourceCRS || target3D!=targetCRS) {
+                    return createOperation(source3D, target3D);
+                }
+                /*
+                 * TODO: Search for non-ellipsoidal height, and lets supplemental axis pass through.
+                 *       See javadoc comments for createOperation(CompoundCRS, SingleCRS).
+                 */
+                throw new OperationNotFoundException(getErrorMessage(sourceCRS, targetCRS));
+            }
+        }
+        // No need for a datum change (see 'needGeodetic3D' javadoc).
+        return createOperationStep(sourceCRS, sources, targetCRS, targets);
+    }
+
+    /**
+     * Implementation of transformation step on compound CRS.
+     * <p>
+     * <strong>NOTE:</strong>
+     * If there is a horizontal (geographic or projected) CRS together with a vertical CRS,
+     * then we can't performs the transformation since the vertical value has an impact on
+     * the horizontal value, and this impact is not taken in account if the horizontal and
+     * vertical components are not together in a 3D geographic CRS.  This case occurs when
+     * the vertical CRS is not a height above the ellipsoid. It must be checked by the
+     * caller before this method is invoked.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  sources   The source CRS components.
+     * @param  targetCRS Output coordinate reference system.
+     * @param  targets   The target CRS components.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws FactoryException If the operation can't be constructed.
+     */
+    private CoordinateOperation createOperationStep(final CoordinateReferenceSystem sourceCRS,
+                                                    final List<SingleCRS>           sources,
+                                                    final CoordinateReferenceSystem targetCRS,
+                                                    final List<SingleCRS>           targets)
+            throws FactoryException
+    {
+        /*
+         * Try to find operations from source CRSs to target CRSs. All pairwise combinaisons are
+         * tried, but the preference is given to CRS in the same order (source[0] with target[0],
+         * source[1] with target[1], etc.). Operations found are stored in 'steps', but are not
+         * yet given to pass through transforms. We need to know first if some ordinate values
+         * need reordering (for matching the order of target CRS) if any ordinates reordering and
+         * source ordinates drops are required.
+         */
+        final CoordinateReferenceSystem[] ordered = new CoordinateReferenceSystem[targets.size()];
+        final CoordinateOperation[]       steps   = new CoordinateOperation      [targets.size()];
+        final boolean[]                   done    = new boolean                  [sources.size()];
+        final int[]                       indices = new int[getDimension(sourceCRS)];
+        int count=0, dimensions=0;
+search: for (int j=0; j<targets.size(); j++) {
+            int lower, upper=0;
+            final CoordinateReferenceSystem target = targets.get(j);
+            OperationNotFoundException cause = null;
+            for (int i=0; i<sources.size(); i++) {
+                final CoordinateReferenceSystem source = sources.get(i);
+                lower  = upper;
+                upper += getDimension(source);
+                if (done[i]) continue;
+                try {
+                    steps[count] = createOperation(source, target);
+                } catch (OperationNotFoundException exception) {
+                    // No operation path for this pair.
+                    // Search for an other pair.
+                    if (cause==null || i==j) {
+                        cause = exception;
+                    }
+                    continue;
+                }
+                ordered[count++] = source;
+                while (lower < upper) {
+                    indices[dimensions++] = lower++;
+                }
+                done[i] = true;
+                continue search;
+            }
+            /*
+             * No source CRS was found for current target CRS.
+             * Consequently, we can't get a transformation path.
+             */
+            throw new OperationNotFoundException(getErrorMessage(sourceCRS, targetCRS), cause);
+        }
+        /*
+         * A transformation has been found for every source and target CRS pairs.
+         * Some reordering of ordinate values may be needed. Prepare it now as an
+         * affine transform. This transform also drop source dimensions not used
+         * for any target coordinates.
+         */
+        assert count == targets.size() : count;
+        while (count!=0 && steps[--count].getMathTransform().isIdentity());
+        final ReferencingFactoryContainer factories = getFactoryContainer();
+        CoordinateOperation operation = null;
+        CoordinateReferenceSystem sourceStepCRS = sourceCRS;
+        final XMatrix select = MatrixFactory.create(dimensions+1, indices.length+1);
+        select.setZero();
+        select.setElement(dimensions, indices.length, 1);
+        for (int j=0; j<dimensions; j++) {
+            select.setElement(j, indices[j], 1);
+        }
+        if (!select.isIdentity()) {
+            if (ordered.length == 1) {
+                sourceStepCRS = ordered[0];
+            } else {
+                sourceStepCRS = factories.getCRSFactory().createCompoundCRS(
+                                    getTemporaryName(sourceCRS), ordered);
+            }
+            operation = createFromAffineTransform(AXIS_CHANGES, sourceCRS, sourceStepCRS, select);
+        }
+        /*
+         * Now creates the pass through transforms for each transformation steps found above.
+         * We get (or construct temporary) source and target CRS for this step. They will be
+         * given to the constructor of the pass through operation, after the construction of
+         * pass through transform.
+         */
+        int lower, upper=0;
+        for (int i=0; i<targets.size(); i++) {
+            CoordinateOperation step = steps[i];
+            final Map<String,?> properties = AbstractIdentifiedObject.getProperties(step);
+            final CoordinateReferenceSystem source = ordered[i];
+            final CoordinateReferenceSystem target = targets.get(i);
+            final CoordinateReferenceSystem targetStepCRS;
+            ordered[i] = target; // Used for the construction of targetStepCRS.
+            MathTransform mt = step.getMathTransform();
+            if (i >= count) {
+                targetStepCRS = targetCRS;
+            } else if (mt.isIdentity()) {
+                targetStepCRS = sourceStepCRS;
+            } else if (ordered.length == 1) {
+                targetStepCRS = ordered[0];
+            } else {
+                targetStepCRS = factories.getCRSFactory().createCompoundCRS(
+                                    getTemporaryName(target), ordered);
+            }
+            lower  = upper;
+            upper += getDimension(source);
+            if (lower!=0 || upper!=dimensions) {
+                /*
+                 * Constructs the pass through transform only if there is at least one ordinate to
+                 * pass. Actually, the code below would give an acceptable result even if this check
+                 * was not performed, except for creation of intermediate objects.
+                 */
+                if (!(step instanceof Operation)) {
+                    final MathTransform stepMT = step.getMathTransform();
+                    step = DefaultOperation.create(AbstractIdentifiedObject.getProperties(step),
+                            step.getSourceCRS(), step.getTargetCRS(), stepMT,
+                            new DefaultOperationMethod(stepMT), step.getClass());
+                }
+                mt = getMathTransformFactory().createPassThroughTransform(lower, mt, dimensions-upper);
+                step = new DefaultPassThroughOperation(properties, sourceStepCRS, targetStepCRS,
+                                                       (Operation) step, mt);
+            }
+            operation     = (operation==null) ? step : concatenate(operation, step);
+            sourceStepCRS = targetStepCRS;
+        }
+        assert upper == dimensions : upper;
+        return operation;
+    }
+
+    /**
+     * Returns {@code true} if a transformation path from {@code sourceCRS} to
+     * {@code targetCRS} is likely to requires a tri-dimensional geodetic CRS as an
+     * intermediate step. More specifically, this method returns {@code false} if at
+     * least one of the following conditions is meet:
+     *
+     * <ul>
+     *   <li>The target datum is not a vertical or geodetic one (the two datum that must work
+     *       together). Consequently, a potential datum change is not the caller's business.
+     *       It will be handled by the generic method above.</li>
+     *
+     *   <li>The target datum is vertical or geodetic, but there is no datum change. It is
+     *       better to not try to create 3D-geodetic CRS, since they are more difficult to
+     *       separate in the generic method above. An exception to this rule occurs when
+     *       the target datum is used in a three-dimensional CRS.</li>
+     *
+     *   <li>A datum change is required, but source CRS doesn't have both a geodetic
+     *       and a vertical CRS, so we can't apply a 3D datum shift anyway.</li>
+     * </ul>
+     */
+    private static boolean needsGeodetic3D(final List<SingleCRS> sourceCRS, final SingleCRS targetCRS) {
+        final boolean targetGeodetic;
+        final Datum targetDatum = targetCRS.getDatum();
+        if (targetDatum instanceof GeodeticDatum) {
+            targetGeodetic = true;
+        } else if (targetDatum instanceof VerticalDatum) {
+            targetGeodetic = false;
+        } else {
+            return false;
+        }
+        boolean horizontal = false;
+        boolean vertical   = false;
+        boolean shift      = false;
+        for (final SingleCRS crs : sourceCRS) {
+            final Datum sourceDatum = crs.getDatum();
+            final boolean sourceGeodetic;
+            if (sourceDatum instanceof GeodeticDatum) {
+                horizontal     = true;
+                sourceGeodetic = true;
+            } else if (sourceDatum instanceof VerticalDatum) {
+                vertical       = true;
+                sourceGeodetic = false;
+            } else {
+                continue;
+            }
+            if (!shift && sourceGeodetic == targetGeodetic) {
+                shift = !equalsIgnoreMetadata(sourceDatum, targetDatum);
+                assert Classes.sameInterfaces(sourceDatum.getClass(),
+                                              targetDatum.getClass(), Datum.class);
+            }
+        }
+        return horizontal && vertical &&
+               (shift || targetCRS.getCoordinateSystem().getDimension() >= 3);
+    }
+
+
+
+
+
+    /////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////
+    ////////////                                                         ////////////
+    ////////////                M I S C E L L A N E O U S                ////////////
+    ////////////                                                         ////////////
+    /////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Compares the specified datum for equality, except the prime meridian.
+     *
+     * @param  object1 The first object to compare (may be null).
+     * @param  object2 The second object to compare (may be null).
+     * @return {@code true} if both objects are equals.
+     */
+    private static boolean equalsIgnorePrimeMeridian(GeodeticDatum object1,
+                                                     GeodeticDatum object2)
+    {
+        object1 = TemporaryDatum.unwrap(object1);
+        object2 = TemporaryDatum.unwrap(object2);
+        if (equalsIgnoreMetadata(object1.getEllipsoid(), object2.getEllipsoid())) {
+            return nameMatches(object1, object2.getName().getCode()) ||
+                   nameMatches(object2, object1.getName().getCode());
+        }
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if {@code container} contains all CRS listed in {@code candidates},
+     * ignoring metadata.
+     */
+    private static boolean containsIgnoreMetadata(final List<SingleCRS> container,
+                                                  final List<SingleCRS> candidates)
+    {
+search: for (final SingleCRS crs : candidates) {
+            for (final SingleCRS c : container) {
+                if (equalsIgnoreMetadata(crs, c)) {
+                    continue search;
+                }
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Tries to get a coordinate operation from a database (typically EPSG). The exact behavior
+     * depends on the {@link AuthorityBackedFactory} implementation (the most typical subclass),
+     * but usually the database query is degelated to some instance of
+     * {@link org.opengis.referencing.operation.CoordinateOperationAuthorityFactory}.
+     * If no coordinate operation was found in the database, then this method returns {@code null}.
+     */
+    private final CoordinateOperation tryDB(final SingleCRS sourceCRS, final SingleCRS targetCRS) {
+        return (sourceCRS == targetCRS) ? null : createFromDatabase(sourceCRS, targetCRS);
+    }
+
+    /**
+     * If the coordinate operation is explicitly defined in some database (typically EPSG),
+     * returns it. Otherwise (if there is no database, or if the database doesn't contains
+     * an explicit operation from {@code sourceCRS} to {@code targetCRS}, or if this method
+     * failed to create an operation from the database), returns {@code null}.
+     * <p>
+     * The default implementation always returns {@code null}, since there is no database
+     * connected to a {@code DefaultCoordinateOperationFactory} instance. In other words,
+     * the default implementation is "standalone": it tries to figure out transformation
+     * paths by itself. Subclasses should override this method if they can fetch a more
+     * accurate operation from some database. The mean subclass doing so is
+     * {@link AuthorityBackedFactory}.
+     * <p>
+     * This method is invoked by <code>{@linkplain #createOperation createOperation}(sourceCRS,
+     * targetCRS)</code> before to try to figure out a transformation path by itself. It is also
+     * invoked by various {@code createOperationStep(...)} methods when an intermediate CRS was
+     * obtained by {@link GeneralDerivedCRS#getBaseCRS()} (this case occurs especially during
+     * {@linkplain GeographicCRS geographic} from/to {@linkplain ProjectedCRS projected} CRS
+     * operations). This method is <strong>not</strong> invoked for synthetic CRS generated by
+     * {@code createOperationStep(...)}, since those temporary CRS are not expected to exist
+     * in a database.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS} if and only if
+     *         one is explicitly defined in some underlying database, or {@code null} otherwise.
+     *
+     * @since 2.3
+     */
+    protected CoordinateOperation createFromDatabase(final CoordinateReferenceSystem sourceCRS,
+                                                     final CoordinateReferenceSystem targetCRS)
+    {
+        return null;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultCylindricalProjection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultCylindricalProjection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultCylindricalProjection.java	(revision 28000)
@@ -0,0 +1,89 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Map;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.CylindricalProjection;
+
+
+/**
+ * Base class for cylindrical map projections.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultCylindricalProjection.java $
+ * @version $Id: DefaultCylindricalProjection.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @since 2.1
+ *
+ * @see org.geotools.referencing.crs.DefaultProjectedCRS
+ * @see <A HREF="http://mathworld.wolfram.com/CylindricalProjection.html">Cylindrical projection on MathWorld</A>
+ */
+public class DefaultCylindricalProjection extends DefaultProjection implements CylindricalProjection {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -969486613826553580L;
+
+    /**
+     * Constructs a new projection with the same values than the specified one, together with the
+     * specified source and target CRS. While the source conversion can be an arbitrary one, it is
+     * typically a {@linkplain DefiningConversion defining conversion}.
+     *
+     * @param conversion The defining conversion.
+     * @param sourceCRS The source CRS.
+     * @param targetCRS The target CRS.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source CRS}
+     *                  to positions in the {@linkplain #getTargetCRS target CRS}.
+     */
+    public DefaultCylindricalProjection(final Conversion                conversion,
+                                        final CoordinateReferenceSystem sourceCRS,
+                                        final CoordinateReferenceSystem targetCRS,
+                                        final MathTransform             transform)
+    {
+        super(conversion, sourceCRS, targetCRS, transform);
+    }
+
+    /**
+     * Constructs a projection from a set of properties. The properties given in argument
+     * follow the same rules than for the {@link AbstractCoordinateOperation} constructor.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param sourceCRS The source CRS, or {@code null} if not available.
+     * @param targetCRS The target CRS, or {@code null} if not available.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source coordinate
+     *                  reference system} to positions in the {@linkplain #getTargetCRS target
+     *                  coordinate reference system}.
+     * @param method    The operation method.
+     */
+    public DefaultCylindricalProjection(final Map<String,?>             properties,
+                                        final CoordinateReferenceSystem sourceCRS,
+                                        final CoordinateReferenceSystem targetCRS,
+                                        final MathTransform             transform,
+                                        final OperationMethod           method)
+    {
+        super(properties, sourceCRS, targetCRS, transform, method);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultMathTransformFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultMathTransformFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultMathTransformFactory.java	(revision 28000)
@@ -0,0 +1,535 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.measure.converter.ConversionException;
+import javax.measure.quantity.Length;
+import javax.measure.unit.Unit;
+
+import org.geotools.factory.FactoryRegistry;
+import org.geotools.factory.Hints;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.parameter.Parameters;
+import org.geotools.referencing.cs.AbstractCS;
+import org.geotools.referencing.factory.ReferencingFactory;
+import org.geotools.referencing.operation.matrix.MatrixFactory;
+import org.geotools.referencing.operation.transform.ConcatenatedTransform;
+import org.geotools.referencing.operation.transform.PassThroughTransform;
+import org.geotools.referencing.operation.transform.ProjectiveTransform;
+import org.geotools.resources.CRSUtilities;
+import org.geotools.resources.LazySet;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.CanonicalSet;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchIdentifierException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.datum.Ellipsoid;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.Operation;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.Projection;
+
+
+/**
+ * Low level factory for creating {@linkplain MathTransform math transforms}.
+ * Many high level GIS applications will never need to use this factory directly;
+ * they can use a {@linkplain DefaultCoordinateOperationFactory coordinate operation factory}
+ * instead. However, the {@code MathTransformFactory} interface can be used directly
+ * by applications that wish to transform other types of coordinates (e.g. color coordinates,
+ * or image pixel coordinates).
+ * <P>
+ * A {@linkplain MathTransform math transform} is an object that actually does
+ * the work of applying formulae to coordinate values. The math transform does
+ * not know or care how the coordinates relate to positions in the real world.
+ * This lack of semantics makes implementing {@code MathTransformFactory}
+ * significantly easier than it would be otherwise.
+ *
+ * For example the affine transform applies a matrix to the coordinates
+ * without knowing how what it is doing relates to the real world. So if
+ * the matrix scales <var>Z</var> values by a factor of 1000, then it could
+ * be converting meters into millimeters, or it could be converting kilometers
+ * into meters.
+ * <P>
+ * Because {@linkplain MathTransform math transforms} have low semantic value
+ * (but high mathematical value), programmers who do not have much knowledge
+ * of how GIS applications use coordinate systems, or how those coordinate
+ * systems relate to the real world can implement {@code MathTransformFactory}.
+ * The low semantic content of {@linkplain MathTransform math transforms} also
+ * means that they will be useful in applications that have nothing to do with
+ * GIS coordinates. For example, a math transform could be used to map color
+ * coordinates between different color spaces, such as converting (red, green, blue)
+ * colors into (hue, light, saturation) colors.
+ * <P>
+ * Since a {@linkplain MathTransform math transform} does not know what its source
+ * and target coordinate systems mean, it is not necessary or desirable for a math
+ * transform object to keep information on its source and target coordinate systems.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultMathTransformFactory.java $
+ * @version $Id: DefaultMathTransformFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @tutorial http://docs.codehaus.org/display/GEOTOOLS/Coordinate+Transformation+Parameters
+ */
+public class DefaultMathTransformFactory extends ReferencingFactory implements MathTransformFactory {
+    /**
+     * The hints to provide to math transform providers. Null for now, but may be non-null
+     * in some future version.
+     */
+    private static final Hints HINTS = null;
+
+    /**
+     * The last value returned by {@link #getProvider}. Stored as an
+     * optimization since the same provider is often asked many times.
+     */
+    private transient MathTransformProvider lastProvider;
+
+    /**
+     * The operation method for the last transform created.
+     */
+    private static final ThreadLocal<OperationMethod> lastMethod = new ThreadLocal<OperationMethod>();
+
+    /**
+     * A pool of math transform. This pool is used in order to
+     * returns instance of existing math transforms when possible.
+     */
+    private final CanonicalSet<MathTransform> pool;
+
+    /**
+     * The service registry for finding {@link MathTransformProvider} implementations.
+     */
+    private final FactoryRegistry registry;
+
+    /**
+     * Constructs a default {@link MathTransform math transform} factory.
+     */
+    public DefaultMathTransformFactory() {
+        this(new Class<?>[] {MathTransformProvider.class});
+    }
+
+    /**
+     * Constructs a default {@link MathTransform math transform} factory using the
+     * specified {@linkplain MathTransformProvider transform providers} categories.
+     *
+     * @param categories The providers categories, as implementations
+     *                   of {@link MathTransformProvider}.
+     */
+    private DefaultMathTransformFactory(final Class<?>[] categories) {
+        registry   = new FactoryRegistry(Arrays.asList(categories));
+        pool       = CanonicalSet.newInstance(MathTransform.class);
+    }
+
+    /**
+     * Returns the vendor responsible for creating this factory implementation. Many implementations
+     * may be available for the same factory interface. The default implementation returns
+     * {@linkplain Citations#GEOTOOLS Geotools}.
+     *
+     * @return The vendor for this factory implementation.
+     */
+    @Override
+    public Citation getVendor() {
+        return Citations.GEOTOOLS;
+    }
+
+    /**
+     * Returns a set of available methods for {@linkplain MathTransform math transforms}. For
+     * each element in this set, the {@linkplain OperationMethod#getName operation method name}
+     * must be known to the {@link #getDefaultParameters} method in this factory.
+     * The set of available methods is implementation dependent.
+     *
+     * @param  type <code>{@linkplain Operation}.class</code> for fetching all operation methods,
+     *           or <code>{@linkplain Projection}.class</code> for fetching only map projection
+     *           methods.
+     * @return All {@linkplain MathTransform math transform} methods available in this factory.
+     *
+     * @see #getDefaultParameters
+     * @see #createParameterizedTransform
+     */
+    public Set<OperationMethod> getAvailableMethods(final Class<? extends Operation> type) {
+        return new LazySet<OperationMethod>(registry.getServiceProviders(MathTransformProvider.class,
+                (type!=null) ? new MethodFilter(type) : null, HINTS));
+    }
+
+    /**
+     * A filter for the set of available operations.
+     */
+    private static final class MethodFilter implements FactoryRegistry.Filter {
+        /**
+         * The expected type ({@code Projection.class}) for projections).
+         */
+        private final Class<? extends Operation> type;
+
+        /**
+         * Constructs a filter for the set of math operations methods.
+         */
+        public MethodFilter(final Class<? extends Operation> type) {
+            this.type = type;
+        }
+
+        /**
+         * Returns {@code true} if the specified element should be included. If the type is
+         * unknown, conservatively returns {@code true}.
+         */
+        public boolean filter(final Object element) {
+            if (element instanceof MathTransformProvider) {
+                final Class<? extends Operation> t = ((MathTransformProvider) element).getOperationType();
+                if (t!=null && !type.isAssignableFrom(t)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Returns the operation method used for the latest call to
+     * {@link #createParameterizedTransform createParameterizedTransform}
+     * in the currently running thread. Returns {@code null} if not applicable.
+     *
+     * @see #createParameterizedTransform
+     *
+     * @since 2.5
+     */
+    public OperationMethod getLastMethodUsed() {
+        return lastMethod.get();
+    }
+
+    /**
+     * Returns the math transform provider for the specified operation method.
+     * This provider can be used in order to query parameter for a method name
+     * (e.g. <code>getProvider("Transverse_Mercator").getParameters()</code>),
+     * or any of the alias in a given locale.
+     *
+     * @param  method The case insensitive
+     *         {@linkplain org.opengis.metadata.Identifier#getCode identifier code}
+     *         of the operation method to search for (e.g. {@code "Transverse_Mercator"}).
+     * @return The math transform provider.
+     * @throws NoSuchIdentifierException if there is no provider registered for the specified
+     *         method.
+     */
+    private MathTransformProvider getProvider(final String method) throws NoSuchIdentifierException {
+        /*
+         * Copies the 'lastProvider' reference in order to avoid synchronization. This is safe
+         * because copy of object references are atomic operations.  Note that this is not the
+         * deprecated "double check" idiom since we are not creating new objects, but checking
+         * for existing ones.
+         */
+        MathTransformProvider provider = lastProvider;
+        if (provider!=null && provider.nameMatches(method)) {
+            return provider;
+        }
+        final Iterator<MathTransformProvider> providers =
+                registry.getServiceProviders(MathTransformProvider.class, null, HINTS);
+        while (providers.hasNext()) {
+            provider = providers.next();
+            if (provider.nameMatches(method)) {
+                return lastProvider = provider;
+            }
+        }
+        throw new NoSuchIdentifierException(Errors.format(
+                  ErrorKeys.NO_TRANSFORM_FOR_CLASSIFICATION_$1, method), method);
+    }
+
+    /**
+     * Returns the default parameter values for a math transform using the given method.
+     * The method argument is the name of any operation method returned by the
+     * {@link #getAvailableMethods} method. A typical example is
+     * <code>"<A HREF="http://www.remotesensing.org/geotiff/proj_list/transverse_mercator.html">Transverse_Mercator</A>"</code>).
+     *
+     * <P>This method creates new parameter instances at every call. It is intented to be modified
+     * by the user before to be passed to <code>{@linkplain #createParameterizedTransform
+     * createParameterizedTransform}(parameters)</code>.</P>
+     *
+     * @param  method The case insensitive name of the method to search for.
+     * @return The default parameter values.
+     * @throws NoSuchIdentifierException if there is no transform registered for the specified
+     *         method.
+     *
+     * @see #getAvailableMethods
+     * @see #createParameterizedTransform
+     * @see org.geotools.referencing.operation.transform.AbstractMathTransform#getParameterValues
+     */
+    public ParameterValueGroup getDefaultParameters(final String method)
+            throws NoSuchIdentifierException
+    {
+        return getProvider(method).getParameters().createValue();
+    }
+
+    /**
+     * Creates a {@linkplain #createParameterizedTransform parameterized transform} from a base
+     * CRS to a derived CS. If the {@code "semi_major"} and {@code "semi_minor"} parameters are
+     * not explicitly specified, they will be inferred from the {@linkplain Ellipsoid ellipsoid}
+     * and added to {@code parameters}. In addition, this method performs axis switch as needed.
+     * <p>
+     * The {@linkplain OperationMethod operation method} used can be obtained by a call to
+     * {@link #getLastUsedMethod}.
+     *
+     * @param  baseCRS The source coordinate reference system.
+     * @param  parameters The parameter values for the transform.
+     * @param  derivedCS the target coordinate system.
+     * @return The parameterized transform.
+     * @throws NoSuchIdentifierException if there is no transform registered for the method.
+     * @throws FactoryException if the object creation failed. This exception is thrown
+     *         if some required parameter has not been supplied, or has illegal value.
+     */
+    public MathTransform createBaseToDerived(final CoordinateReferenceSystem baseCRS,
+                                             final ParameterValueGroup       parameters,
+                                             final CoordinateSystem          derivedCS)
+            throws NoSuchIdentifierException, FactoryException
+    {
+        /*
+         * If the user's parameter do not contains semi-major and semi-minor axis length, infers
+         * them from the ellipsoid. This is a convenience service since the user often omit those
+         * parameters (because they duplicate datum information).
+         */
+        final Ellipsoid ellipsoid = CRSUtilities.getHeadGeoEllipsoid(baseCRS);
+        if (ellipsoid != null) {
+            final Unit<Length> axisUnit = ellipsoid.getAxisUnit();
+            Parameters.ensureSet(parameters, "semi_major", ellipsoid.getSemiMajorAxis(), axisUnit, false);
+            Parameters.ensureSet(parameters, "semi_minor", ellipsoid.getSemiMinorAxis(), axisUnit, false);
+        }
+        MathTransform baseToDerived = createParameterizedTransform(parameters);
+        final OperationMethod method = lastMethod.get();
+        baseToDerived = createBaseToDerived(baseCRS, baseToDerived, derivedCS);
+        lastMethod.set(method);
+        return baseToDerived;
+    }
+
+    /**
+     * Creates a transform from a base CRS to a derived CS. This method expects a "raw"
+     * transform without unit conversion or axis switch, typically a map projection
+     * working on (<cite>longitude</cite>, <cite>latitude</cite>) axes in degrees and
+     * (<cite>x</cite>, <cite>y</cite>) axes in metres. This method inspects the coordinate
+     * systems and prepend or append the unit conversions and axis switchs automatically.
+     *
+     * @param  baseCRS The source coordinate reference system.
+     * @param  projection The "raw" <cite>base to derived</cite> transform.
+     * @param  derivedCS the target coordinate system.
+     * @return The parameterized transform.
+     * @throws FactoryException if the object creation failed. This exception is thrown
+     *         if some required parameter has not been supplied, or has illegal value.
+     *
+     * @since 2.5
+     */
+    public MathTransform createBaseToDerived(final CoordinateReferenceSystem baseCRS,
+                                             final MathTransform          projection,
+                                             final CoordinateSystem        derivedCS)
+            throws FactoryException
+    {
+        /*
+         * Computes matrix for swapping axis and performing units conversion.
+         * There is one matrix to apply before projection on (longitude,latitude)
+         * coordinates, and one matrix to apply after projection on (easting,northing)
+         * coordinates.
+         */
+        final CoordinateSystem sourceCS = baseCRS.getCoordinateSystem();
+        final Matrix swap1, swap3;
+        try {
+            swap1 = AbstractCS.swapAndScaleAxis(sourceCS, AbstractCS.standard(sourceCS));
+            swap3 = AbstractCS.swapAndScaleAxis(AbstractCS.standard(derivedCS), derivedCS);
+        } catch (IllegalArgumentException cause) {
+            // User-specified axis don't match.
+            throw new FactoryException(cause);
+        } catch (ConversionException cause) {
+            // A Unit conversion is non-linear.
+            throw new FactoryException(cause);
+        }
+        /*
+         * Prepares the concatenation of the matrix computed above and the projection.
+         * Note that at this stage, the dimensions between each step may not be compatible.
+         * For example the projection (step2) is usually two-dimensional while the source
+         * coordinate system (step1) may be three-dimensional if it has a height.
+         */
+        MathTransform step1 = createAffineTransform(swap1);
+        MathTransform step3 = createAffineTransform(swap3);
+        MathTransform step2 = projection;
+        /*
+         * If the target coordinate system has a height, instructs the projection to pass
+         * the height unchanged from the base CRS to the target CRS. After this block, the
+         * dimensions of 'step2' and 'step3' should match.
+         */
+        final int numTrailingOrdinates = step3.getSourceDimensions() - step2.getTargetDimensions();
+        if (numTrailingOrdinates > 0) {
+            step2 = createPassThroughTransform(0, step2, numTrailingOrdinates);
+        }
+        /*
+         * If the source CS has a height but the target CS doesn't, drops the extra coordinates.
+         * After this block, the dimensions of 'step1' and 'step2' should match.
+         */
+        final int sourceDim = step1.getTargetDimensions();
+        final int targetDim = step2.getSourceDimensions();
+        if (sourceDim > targetDim) {
+            final Matrix drop = MatrixFactory.create(targetDim+1, sourceDim+1);
+            drop.setElement(targetDim, sourceDim, 1);
+            step1 = createConcatenatedTransform(createAffineTransform(drop), step1);
+        }
+        return createConcatenatedTransform(createConcatenatedTransform(step1, step2), step3);
+    }
+
+    /**
+     * Creates a transform from a group of parameters. The method name is inferred from the
+     * {@linkplain org.opengis.parameter.ParameterDescriptorGroup#getName parameter group name}.
+     * Example:
+     *
+     * <blockquote><pre>
+     * ParameterValueGroup p = factory.getDefaultParameters("Transverse_Mercator");
+     * p.parameter("semi_major").setValue(6378137.000);
+     * p.parameter("semi_minor").setValue(6356752.314);
+     * MathTransform mt = factory.createParameterizedTransform(p);
+     * </pre></blockquote>
+     *
+     * @param  parameters The parameter values.
+     * @return The parameterized transform.
+     * @throws NoSuchIdentifierException if there is no transform registered for the method.
+     * @throws FactoryException if the object creation failed. This exception is thrown
+     *         if some required parameter has not been supplied, or has illegal value.
+     *
+     * @see #getDefaultParameters
+     * @see #getAvailableMethods
+     * @see #getLastUsedMethod
+     */
+    public MathTransform createParameterizedTransform(ParameterValueGroup parameters)
+            throws NoSuchIdentifierException, FactoryException
+    {
+        MathTransform transform;
+        OperationMethod method = null;
+        try {
+            final String classification = parameters.getDescriptor().getName().getCode();
+            final MathTransformProvider provider = getProvider(classification);
+            method = provider;
+            try {
+                parameters = provider.ensureValidValues(parameters);
+                transform  = provider.createMathTransform(parameters);
+            } catch (IllegalArgumentException exception) {
+                /*
+                 * Catch only exceptions which may be the result of improper parameter
+                 * usage (e.g. a value out of range). Do not catch exception caused by
+                 * programming errors (e.g. null pointer exception).
+                 */
+                throw new FactoryException(exception);
+            }
+            if (transform instanceof MathTransformProvider.Delegate) {
+                final MathTransformProvider.Delegate delegate = (MathTransformProvider.Delegate) transform;
+                method    = delegate.method;
+                transform = delegate.transform;
+            }
+            transform = pool.unique(transform);
+        } finally {
+            lastMethod.set(method); // May be null in case of failure, which is intented.
+        }
+        return transform;
+    }
+
+    /**
+     * Creates an affine transform from a matrix.
+     * If the transform's input dimension is {@code M}, and output dimension
+     * is {@code N}, then the matrix will have size {@code [N+1][M+1]}.
+     * The +1 in the matrix dimensions allows the matrix to do a shift, as well as
+     * a rotation. The {@code [M][j]} element of the matrix will be the j'th
+     * ordinate of the moved origin. The {@code [i][N]} element of the matrix
+     * will be 0 for <var>i</var> less than {@code M}, and 1 for <var>i</var>
+     * equals {@code M}.
+     *
+     * @param matrix The matrix used to define the affine transform.
+     * @return The affine transform.
+     * @throws FactoryException if the object creation failed.
+     */
+    public MathTransform createAffineTransform(final Matrix matrix)
+            throws FactoryException
+    {
+        lastMethod.remove(); // To be strict, we should set ProjectiveTransform.Provider
+        return pool.unique(ProjectiveTransform.create(matrix));
+    }
+
+    /**
+     * Creates a transform by concatenating two existing transforms.
+     * A concatenated transform acts in the same way as applying two
+     * transforms, one after the other.
+     *
+     * The dimension of the output space of the first transform must match
+     * the dimension of the input space in the second transform.
+     * If you wish to concatenate more than two transforms, then you can
+     * repeatedly use this method.
+     *
+     * @param  transform1 The first transform to apply to points.
+     * @param  transform2 The second transform to apply to points.
+     * @return The concatenated transform.
+     * @throws FactoryException if the object creation failed.
+     */
+    public MathTransform createConcatenatedTransform(final MathTransform transform1,
+                                                     final MathTransform transform2)
+            throws FactoryException
+    {
+        MathTransform tr;
+        try {
+            tr = ConcatenatedTransform.create(transform1, transform2);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        tr = pool.unique(tr);
+        return tr;
+    }
+
+    /**
+     * Creates a transform which passes through a subset of ordinates to another transform.
+     * This allows transforms to operate on a subset of ordinates. For example, if you have
+     * (<var>Lat</var>,<var>Lon</var>,<var>Height</var>) coordinates, then you may wish to
+     * convert the height values from meters to feet without affecting the
+     * (<var>Lat</var>,<var>Lon</var>) values.
+     *
+     * @param  firstAffectedOrdinate The lowest index of the affected ordinates.
+     * @param  subTransform Transform to use for affected ordinates.
+     * @param  numTrailingOrdinates Number of trailing ordinates to pass through.
+     *         Affected ordinates will range from {@code firstAffectedOrdinate}
+     *         inclusive to {@code dimTarget-numTrailingOrdinates} exclusive.
+     * @return A pass through transform with the following dimensions:<br>
+     *         <pre>
+     * Source: firstAffectedOrdinate + subTransform.getSourceDimensions() + numTrailingOrdinates
+     * Target: firstAffectedOrdinate + subTransform.getTargetDimensions() + numTrailingOrdinates</pre>
+     * @throws FactoryException if the object creation failed.
+     */
+    public MathTransform createPassThroughTransform(final int firstAffectedOrdinate,
+                                                    final MathTransform subTransform,
+                                                    final int numTrailingOrdinates)
+            throws FactoryException
+    {
+        MathTransform tr;
+        try {
+            tr = PassThroughTransform.create(firstAffectedOrdinate,
+                                             subTransform,
+                                             numTrailingOrdinates);
+        } catch (IllegalArgumentException exception) {
+            throw new FactoryException(exception);
+        }
+        tr = pool.unique(tr);
+        return tr;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultOperation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultOperation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultOperation.java	(revision 28000)
@@ -0,0 +1,296 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Map;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.operation.transform.AbstractMathTransform;
+import org.geotools.referencing.operation.transform.ConcatenatedTransform;
+import org.geotools.referencing.operation.transform.PassThroughTransform;
+import org.geotools.util.UnsupportedImplementationException;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.ConicProjection;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.CylindricalProjection;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.Operation;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.PlanarProjection;
+import org.opengis.referencing.operation.Projection;
+import org.opengis.referencing.operation.Transformation;
+
+
+/**
+ * A parameterized mathematical operation on coordinates that transforms or converts
+ * coordinates to another coordinate reference system. This coordinate operation thus
+ * uses an operation method, usually with associated parameter values.
+ * <P>
+ * In the Geotools implementation, the {@linkplain #getParameterValues parameter values}
+ * are inferred from the {@linkplain #transform transform}. Other implementations may have
+ * to overrides the {@link #getParameterValues} method.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultOperation.java $
+ * @version $Id: DefaultOperation.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see DefaultOperationMethod
+ */
+public class DefaultOperation extends DefaultSingleOperation implements Operation {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -8923365753849532179L;
+
+    /**
+     * The operation method.
+     */
+    protected final OperationMethod method;
+
+    /**
+     * Constructs a new operation with the same values than the specified defining
+     * conversion, together with the specified source and target CRS. This constructor
+     * is used by {@link DefaultConversion} only.
+     */
+    DefaultOperation(final Conversion               definition,
+                     final CoordinateReferenceSystem sourceCRS,
+                     final CoordinateReferenceSystem targetCRS,
+                     final MathTransform             transform)
+    {
+        super(definition, sourceCRS, targetCRS, transform);
+        method = definition.getMethod();
+    }
+
+    /**
+     * Constructs an operation from a set of properties. The properties given in argument
+     * follow the same rules than for the {@link AbstractCoordinateOperation} constructor.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param sourceCRS The source CRS.
+     * @param targetCRS The target CRS.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source CRS}
+     *                  to positions in the {@linkplain #getTargetCRS target CRS}.
+     * @param method    The operation method.
+     */
+    public DefaultOperation(final Map<String,?>            properties,
+                            final CoordinateReferenceSystem sourceCRS,
+                            final CoordinateReferenceSystem targetCRS,
+                            final MathTransform             transform,
+                            final OperationMethod           method)
+    {
+        super(properties, sourceCRS, targetCRS, transform);
+        ensureNonNull("method", method);
+        DefaultOperationMethod.checkDimensions(method, transform);
+        this.method = method;
+    }
+
+    /**
+     * Returns a coordinate operation of the specified class. This method may constructs instance of
+     * {@link Conversion} or {@link Transformation} among others.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param sourceCRS The source CRS.
+     * @param targetCRS The target CRS.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source CRS}
+     *                  to positions in the {@linkplain #getTargetCRS target CRS}.
+     * @param method    The operation method, or {@code null}.
+     * @param type      The minimal type as <code>{@linkplain Conversion}.class</code>,
+     *                  <code>{@linkplain Projection}.class</code>, etc. This method may
+     *                  create an instance of a subclass of {@code type}.
+     * @return A new coordinate operation of the given type.
+     *
+     * @see DefaultConversion#create
+     */
+    public static CoordinateOperation create(final Map<String,?>            properties,
+                                             final CoordinateReferenceSystem sourceCRS,
+                                             final CoordinateReferenceSystem targetCRS,
+                                             final MathTransform             transform,
+                                             final OperationMethod           method,
+                                             Class<? extends CoordinateOperation> type)
+    {
+        if (method != null) {
+            if (method instanceof MathTransformProvider) {
+                final Class<? extends Operation> candidate =
+                        ((MathTransformProvider) method).getOperationType();
+                if (candidate != null) {
+                    if (type==null || type.isAssignableFrom(candidate)) {
+                        type = candidate.asSubclass(type);
+                    }
+                }
+            }
+            if (type != null) {
+                if (Transformation.class.isAssignableFrom(type)) {
+                    return new DefaultTransformation(
+                               properties, sourceCRS, targetCRS, transform, method);
+                }
+                if (ConicProjection.class.isAssignableFrom(type)) {
+                    return new DefaultConicProjection(
+                               properties, sourceCRS, targetCRS, transform, method);
+                }
+                if (CylindricalProjection.class.isAssignableFrom(type)) {
+                    return new DefaultCylindricalProjection(
+                               properties, sourceCRS, targetCRS, transform, method);
+                }
+                if (PlanarProjection.class.isAssignableFrom(type)) {
+                    return new DefaultPlanarProjection(
+                               properties, sourceCRS, targetCRS, transform, method);
+                }
+                if (Projection.class.isAssignableFrom(type)) {
+                    return new DefaultProjection(
+                               properties, sourceCRS, targetCRS, transform, method);
+                }
+                if (Conversion.class.isAssignableFrom(type)) {
+                    return new DefaultConversion(
+                               properties, sourceCRS, targetCRS, transform, method);
+                }
+            }
+            return new DefaultOperation(
+                       properties, sourceCRS, targetCRS, transform, method);
+        }
+        return new DefaultSingleOperation(properties, sourceCRS, targetCRS, transform);
+    }
+
+    /**
+     * Returns the operation method.
+     */
+    public OperationMethod getMethod() {
+        return method;
+    }
+
+    /**
+     * Returns the parameter values. The default implementation infer the parameter
+     * values from the {@link #transform transform}, if possible.
+     *
+     * @throws UnsupportedOperationException if the parameters values can't be determined
+     *         for current math transform implementation.
+     *
+     * @see DefaultMathTransformFactory#createParameterizedTransform
+     * @see org.geotools.referencing.operation.transform.AbstractMathTransform#getParameterValues
+     */
+    public ParameterValueGroup getParameterValues() throws UnsupportedOperationException {
+        return getParameterValues(transform, method.getParameters(), true);
+    }
+
+    /**
+     * Returns the parameter values for the math transform that use the specified descriptor.
+     *
+     * @param  mt The math transform for which parameters are desired.
+     * @param  descriptor The descriptor to search for.
+     * @param  required {@code true} if an exception must be thrown if parameters are unknow.
+     * @return The parameter values, or null.
+     * @throws UnsupportedImplementationException if the math transform implementation do not
+     *         provide information about parameters.
+     */
+    private static ParameterValueGroup getParameterValues(MathTransform mt,
+            final ParameterDescriptorGroup descriptor, boolean required)
+    {
+        while (mt != null) {
+            if (mt instanceof ConcatenatedTransform) {
+                final ConcatenatedTransform ct = (ConcatenatedTransform) mt;
+                final ParameterValueGroup param1 = getParameterValues(ct.transform1, descriptor, false);
+                final ParameterValueGroup param2 = getParameterValues(ct.transform2, descriptor, false);
+                if (param1 == null && param2 != null) return param2;
+                if (param2 == null && param1 != null) return param1;
+                required = true;
+            }
+            if (mt instanceof AbstractMathTransform) {
+                final ParameterValueGroup param = ((AbstractMathTransform) mt).getParameterValues();
+                if (param != null) {
+                    return param;
+                }
+            }
+            if (mt instanceof PassThroughTransform) {
+                mt = ((PassThroughTransform) mt).getSubTransform();
+            } else {
+                break;
+            }
+        }
+        if (required) {
+            throw new UnsupportedImplementationException(mt.getClass());
+        }
+        return null;
+    }
+
+    /**
+     * Compare this operation method with the specified object for equality.
+     * If {@code compareMetadata} is {@code true}, then all available properties
+     * are compared including {@linkplain DefaultOperationMethod#getFormula formula}.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (super.equals(object, compareMetadata)) {
+            final DefaultOperation that = (DefaultOperation) object;
+            if (compareMetadata) {
+                return equals(this.method, that.method, compareMetadata);
+            }
+            /*
+             * We consider the operation method as metadata. We could argue that OperationMethod's
+             * 'sourceDimensions' and 'targetDimensions' are not metadata, but their values should
+             * be identical to the 'sourceCRS' and 'targetCRS' dimensions,  already checked by the
+             * superclass. We could also argue that 'OperationMethod.parameters' are not metadata,
+             * but their values should have been taken in account for the MathTransform creation,
+             * which was compared by the superclass.
+             *
+             * Comparing the MathTransforms instead of parameters avoid the problem of implicit
+             * parameters.  For example in a ProjectedCRS, the "semiMajor" and "semiMinor" axis
+             * lengths are sometime provided as explicit parameters, and sometime inferred from
+             * the geodetic datum.  The two cases would be different set of parameters from the
+             * OperationMethod's point of view, but still result in the creation of identical
+             * MathTransform.
+             *
+             * An other rational for treating OperationMethod as metadata is that Geotools
+             * MathTransformProvider extends DefaultOperationMethod. Consequently there is
+             * a wide range of subclasses, which make the comparaisons more difficult. For
+             * example Mercator1SP.Provider and Mercator2SP.Provider are two different ways
+             * to describe the same projection. The SQL-backed EPSG factory uses yet an
+             * other implementation.
+             *
+             * As a safety, we still compare the name. But I'm not completly sure that it is
+             * necessary.
+             * 
+             * AA: this comparison was removed to allow the common case of Conformal 1SP vs
+             * conformal 2SP equivalence to succeed a equalsIgnoreMetadata comparison. Extensive tests
+             * revealed no regressions, as it was noted above, there is no proof this is actually
+             * necessary
+             */
+            // return nameMatches(this.method, that.method);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this operation method.
+     */
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ method.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultOperationMethod.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultOperationMethod.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultOperationMethod.java	(revision 28000)
@@ -0,0 +1,392 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.geotools.parameter.Parameters;
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.operation.transform.AbstractMathTransform;
+import org.geotools.referencing.operation.transform.ConcatenatedTransform;
+import org.geotools.referencing.operation.transform.PassThroughTransform;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.geotools.util.Utilities;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.Operation;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.Projection;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * Definition of an algorithm used to perform a coordinate operation. Most operation
+ * methods use a number of operation parameters, although some coordinate conversions
+ * use none. Each coordinate operation using the method assigns values to these parameters.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultOperationMethod.java $
+ * @version $Id: DefaultOperationMethod.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see DefaultOperation
+ */
+public class DefaultOperationMethod extends AbstractIdentifiedObject implements OperationMethod {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -98032729598205972L;
+
+    /**
+     * List of localizable properties. To be given to {@link AbstractIdentifiedObject} constructor.
+     */
+    private static final String[] LOCALIZABLES = {FORMULA_KEY};
+
+    /**
+     * Formula(s) or procedure used by this operation method. This may be a reference to a
+     * publication. Note that the operation method may not be analytic, in which case this
+     * attribute references or contains the procedure, not an analytic formula.
+     */
+    private final InternationalString formula;
+
+    /**
+     * Number of dimensions in the source CRS of this operation method.
+     */
+    protected final int sourceDimensions;
+
+    /**
+     * Number of dimensions in the target CRS of this operation method.
+     */
+    protected final int targetDimensions;
+
+    /**
+     * The set of parameters, or {@code null} if none.
+     */
+    private final ParameterDescriptorGroup parameters;
+
+    /**
+     * Convenience constructor that creates an operation method from a math transform.
+     * The information provided in the newly created object are approximative, and
+     * usually acceptable only as a fallback when no other information are available.
+     *
+     * @param transform The math transform to describe.
+     */
+    public DefaultOperationMethod(final MathTransform transform) {
+        this(getProperties(transform),
+             transform.getSourceDimensions(),
+             transform.getTargetDimensions(),
+             getDescriptor(transform));
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private static Map<String,?> getProperties(final MathTransform transform) {
+        ensureNonNull("transform", transform);
+        final Map<String,?> properties;
+        if (transform instanceof AbstractMathTransform) {
+            final AbstractMathTransform mt = (AbstractMathTransform) transform;
+            properties = getProperties(mt.getParameterDescriptors(), null);
+        } else {
+            properties = Collections.singletonMap(NAME_KEY, Vocabulary.format(VocabularyKeys.UNKNOW));
+        }
+        return properties;
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     * This code should have been merged with {@code getProperties} above.
+     */
+    private static ParameterDescriptorGroup getDescriptor(final MathTransform transform) {
+        ParameterDescriptorGroup descriptor = null;
+        if (transform instanceof AbstractMathTransform) {
+            descriptor = ((AbstractMathTransform) transform).getParameterDescriptors();
+        }
+        return descriptor;
+    }
+
+    /**
+     * Constructs a new operation method with the same values than the specified one
+     * except the dimensions.
+     *
+     * @param method The operation method to copy.
+     * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
+     * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+     */
+    public DefaultOperationMethod(final OperationMethod method,
+                                  final int sourceDimensions,
+                                  final int targetDimensions)
+    {
+        super(method);
+        this.formula    = method.getFormula();
+        this.parameters = method.getParameters();
+        this.sourceDimensions = sourceDimensions;
+        this.targetDimensions = targetDimensions;
+        ensurePositive("sourceDimensions", sourceDimensions);
+        ensurePositive("targetDimensions", targetDimensions);
+    }
+
+    /**
+     * Constructs an operation method from a set of properties and a descriptor group.
+     * The properties given in argument follow the same rules than for the
+     * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
+     * Additionally, the following properties are understood by this construtor:
+     * <br><br>
+     * <table border='1'>
+     *   <tr bgcolor="#CCCCFF" class="TableHeadingColor">
+     *     <th nowrap>Property name</th>
+     *     <th nowrap>Value type</th>
+     *     <th nowrap>Value given to</th>
+     *   </tr>
+     *   <tr>
+     *     <td nowrap>&nbsp;{@link #FORMULA_KEY "formula"}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link String} or {@link InternationalString}&nbsp;</td>
+     *     <td nowrap>&nbsp;{@link #getFormula}</td>
+     *   </tr>
+     * </table>
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
+     * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+     * @param parameters The set of parameters, or {@code null} if none.
+     */
+    public DefaultOperationMethod(final Map<String,?> properties,
+                                  final int sourceDimensions,
+                                  final int targetDimensions,
+                                  final ParameterDescriptorGroup parameters)
+    {
+        this(properties, new HashMap<String,Object>(), sourceDimensions, targetDimensions, parameters);
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private DefaultOperationMethod(final Map<String,?> properties,
+                                   final Map<String,Object> subProperties,
+                                   final int sourceDimensions,
+                                   final int targetDimensions,
+                                   ParameterDescriptorGroup parameters)
+    {
+        super(properties, subProperties, LOCALIZABLES);
+        formula = (InternationalString) subProperties.get(FORMULA_KEY);
+        // 'parameters' may be null, which is okay. A null value will
+        // make serialization smaller and faster than an empty object.
+        this.parameters       = parameters;
+        this.sourceDimensions = sourceDimensions;
+        this.targetDimensions = targetDimensions;
+        ensurePositive("sourceDimensions", sourceDimensions);
+        ensurePositive("targetDimensions", targetDimensions);
+    }
+
+    /**
+     * Ensure that the specified value is positive.
+     * An {@link IllegalArgumentException} is throws if it is not.
+     *
+     * @param name  The parameter name.
+     * @param value The parameter value.
+     * @throws IllegalArgumentException if the specified value is not positive.
+     */
+    private static void ensurePositive(final String name, final int value)
+            throws IllegalArgumentException
+    {
+        if (value < 0) {
+            throw new IllegalArgumentException(Errors.format(
+                      ErrorKeys.ILLEGAL_ARGUMENT_$2, name, value));
+        }
+    }
+
+    /**
+     * Formula(s) or procedure used by this operation method. This may be a reference to a
+     * publication. Note that the operation method may not be analytic, in which case this
+     * attribute references or contains the procedure, not an analytic formula.
+     */
+    public InternationalString getFormula() {
+        return formula;
+    }
+
+    /**
+     * Number of dimensions in the source CRS of this operation method.
+     *
+     * @return The dimension of source CRS.
+     */
+    public int getSourceDimensions() {
+        return sourceDimensions;
+    }
+
+    /**
+     * Number of dimensions in the target CRS of this operation method.
+     */
+    public int getTargetDimensions() {
+        return targetDimensions;
+    }
+
+    /**
+     * Returns the set of parameters.
+     */
+    public ParameterDescriptorGroup getParameters() {
+        return (parameters!=null) ? parameters : Parameters.EMPTY_GROUP;
+    }
+
+    /**
+     * Returns the operation type. Current implementation returns {@code Projection.class} for
+     * proper WKT formatting using an unknow implementation. But the {@link MathTransformProvider}
+     * subclass (with protected access) will overrides this method with a more conservative default
+     * value.
+     *
+     * @return The GeoAPI interface implemented by this operation.
+     */
+    Class<? extends Operation> getOperationType() {
+        return Projection.class;
+    }
+
+    /**
+     * Compare this operation method with the specified object for equality.
+     * If {@code compareMetadata} is {@code true}, then all available
+     * properties are compared including {@linkplain #getFormula formula}.
+     *
+     * @param  object The object to compare to {@code this}.
+     * @param  compareMetadata {@code true} for performing a strict comparaison, or
+     *         {@code false} for comparing only properties relevant to transformations.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final AbstractIdentifiedObject object, final boolean compareMetadata) {
+        if (object == this) {
+            return true; // Slight optimization.
+        }
+        if (super.equals(object, compareMetadata)) {
+            final DefaultOperationMethod that = (DefaultOperationMethod) object;
+            if (this.sourceDimensions == that.sourceDimensions &&
+                this.targetDimensions == that.targetDimensions &&
+                equals(this.parameters,  that.parameters, compareMetadata))
+            {
+                return !compareMetadata || Utilities.equals(this.formula, that.formula);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this operation method.
+     */
+    @Override
+    public int hashCode() {
+        int code = (int)serialVersionUID + sourceDimensions + 37*targetDimensions;
+        if (parameters != null) {
+            code = code * 37 + parameters.hashCode();
+        }
+        return code;
+    }
+
+    /**
+     * Returns {@code true} if the specified transform is likely to exists only for axis switch
+     * and/or unit conversions. The heuristic rule checks if the transform is backed by a square
+     * matrix with exactly one non-null value in each row and each column. This method is used
+     * for implementation of the {@link #checkDimensions} method only.
+     */
+    private static boolean isTrivial(final MathTransform transform) {
+        if (transform instanceof LinearTransform) {
+            final Matrix matrix = ((LinearTransform) transform).getMatrix();
+            final int size = matrix.getNumRow();
+            if (matrix.getNumCol() == size) {
+                for (int j=0; j<size; j++) {
+                    int n1=0, n2=0;
+                    for (int i=0; i<size; i++) {
+                        if (matrix.getElement(j,i) != 0) n1++;
+                        if (matrix.getElement(i,j) != 0) n2++;
+                    }
+                    if (n1 != 1 || n2 != 1) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks if an operation method and a math transform have a compatible number of source
+     * and target dimensions. In the particular case of a {@linkplain PassThroughTransform pass
+     * through transform} with more dimension than the expected number, the check will rather be
+     * performed against the {@linkplain PassThroughTransform#getSubTransform sub transform}.
+     * <p>
+     * This convenience method is provided for argument checking.
+     *
+     * @param  method    The operation method to compare to the math transform, or {@code null}.
+     * @param  transform The math transform to compare to the operation method, or {@code null}.
+     * @throws MismatchedDimensionException if the number of dimensions are incompatibles.
+     *
+     * @todo The check for {@link ConcatenatedTransform} and {@link PassThroughTransform} works
+     *       only for Geotools implementation.
+     */
+    public static void checkDimensions(final OperationMethod method, MathTransform transform)
+            throws MismatchedDimensionException
+    {
+        if (method!=null && transform!=null) {
+            int actual, expected=method.getSourceDimensions();
+            while ((actual=transform.getSourceDimensions()) > expected) {
+                if (transform instanceof ConcatenatedTransform) {
+                    // Ignore axis switch and unit conversions.
+                    final ConcatenatedTransform c = (ConcatenatedTransform) transform;
+                    if (isTrivial(c.transform1)) {
+                        transform = c.transform2;
+                    } else if (isTrivial(c.transform2)) {
+                        transform = c.transform1;
+                    } else {
+                        // The transform is something more complex than an axis switch.
+                        // Stop the loop with the current illegal transform and let the
+                        // exception be thrown after the loop.
+                        break;
+                    }
+                } else if (transform instanceof PassThroughTransform) {
+                    transform = ((PassThroughTransform) transform).getSubTransform();
+                } else {
+                    break;
+                }
+            }
+            final String name;
+            if (actual != expected) {
+                name = "sourceDimensions";
+            } else {
+                actual   = transform.getTargetDimensions();
+                expected =    method.getTargetDimensions();
+                if (actual != expected) {
+                    name = "targetDimensions";
+                } else {
+                    return;
+                }
+            }
+            throw new IllegalArgumentException(Errors.format(
+                    ErrorKeys.MISMATCHED_DIMENSION_$3, name, actual, expected));
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultPassThroughOperation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultPassThroughOperation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultPassThroughOperation.java	(revision 28000)
@@ -0,0 +1,79 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Map;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.referencing.operation.Operation;
+import org.opengis.referencing.operation.PassThroughOperation;
+
+
+/**
+ * A pass-through operation specifies that a subset of a coordinate tuple is subject to a specific
+ * coordinate operation.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultPassThroughOperation.java $
+ * @version $Id: DefaultPassThroughOperation.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultPassThroughOperation extends DefaultSingleOperation implements PassThroughOperation {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 4308173919747248695L;
+
+    /**
+     * Constructs a single operation from a set of properties and the given transform.
+     * The properties given in argument follow the same rules than for the
+     * {@link AbstractCoordinateOperation} constructor.
+     *
+     * @param  properties Set of properties. Should contains at least {@code "name"}.
+     * @param  sourceCRS The source CRS.
+     * @param  targetCRS The target CRS.
+     * @param  operation The operation to apply on the subset of a coordinate tuple.
+     * @param  transform The {@linkplain MathTransformFactory#createPassThroughTransform
+     *                   pass through transform}.
+     */
+    public DefaultPassThroughOperation(final Map<String,?>            properties,
+                                       final CoordinateReferenceSystem sourceCRS,
+                                       final CoordinateReferenceSystem targetCRS,
+                                       final Operation                 operation,
+                                       final MathTransform             transform)
+    {
+        super(properties, sourceCRS, targetCRS, transform);
+        ensureNonNull("operation", operation);
+        ensureValidDimension(operation.getSourceCRS(), transform.getSourceDimensions());
+        ensureValidDimension(operation.getTargetCRS(), transform.getTargetDimensions());
+    }
+
+    /**
+     * Ensure that the dimension of the specified CRS is not greater than the specified value.
+     */
+    private static void ensureValidDimension(final CoordinateReferenceSystem crs, final int dim) {
+        if (crs.getCoordinateSystem().getDimension() > dim) {
+            throw new IllegalArgumentException(); // TODO: provides a localized message.
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultPlanarProjection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultPlanarProjection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultPlanarProjection.java	(revision 28000)
@@ -0,0 +1,89 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Map;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.PlanarProjection;
+
+
+/**
+ * Base class for for azimuthal (or planar) map projections.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultPlanarProjection.java $
+ * @version $Id: DefaultPlanarProjection.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @since 2.1
+ *
+ * @see org.geotools.referencing.crs.DefaultProjectedCRS
+ * @see <A HREF="http://mathworld.wolfram.com/AzimuthalProjection.html">Azimuthal projection on MathWorld</A>
+ */
+public class DefaultPlanarProjection extends DefaultProjection implements PlanarProjection {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 8171256287775067736L;
+
+    /**
+     * Constructs a new projection with the same values than the specified one, together with the
+     * specified source and target CRS. While the source conversion can be an arbitrary one, it is
+     * typically a {@linkplain DefiningConversion defining conversion}.
+     *
+     * @param conversion The defining conversion.
+     * @param sourceCRS The source CRS.
+     * @param targetCRS The target CRS.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source CRS}
+     *                  to positions in the {@linkplain #getTargetCRS target CRS}.
+     */
+    public DefaultPlanarProjection(final Conversion                conversion,
+                                   final CoordinateReferenceSystem sourceCRS,
+                                   final CoordinateReferenceSystem targetCRS,
+                                   final MathTransform             transform)
+    {
+        super(conversion, sourceCRS, targetCRS, transform);
+    }
+
+    /**
+     * Constructs a projection from a set of properties. The properties given in argument
+     * follow the same rules than for the {@link AbstractCoordinateOperation} constructor.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param sourceCRS The source CRS, or {@code null} if not available.
+     * @param targetCRS The target CRS, or {@code null} if not available.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source coordinate
+     *                  reference system} to positions in the {@linkplain #getTargetCRS target
+     *                  coordinate reference system}.
+     * @param method    The operation method.
+     */
+    public DefaultPlanarProjection(final Map<String,?>             properties,
+                                   final CoordinateReferenceSystem sourceCRS,
+                                   final CoordinateReferenceSystem targetCRS,
+                                   final MathTransform             transform,
+                                   final OperationMethod           method)
+    {
+        super(properties, sourceCRS, targetCRS, transform, method);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultProjection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultProjection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultProjection.java	(revision 28000)
@@ -0,0 +1,99 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Map;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.Projection;
+
+
+/**
+ * A {@linkplain DefaultConversion conversion} transforming
+ * (<var>longitude</var>,<var>latitude</var>) coordinates to cartesian coordinates
+ * (<var>x</var>,<var>y</var>).
+ *
+ * <P>An unofficial list of projections and their parameters can
+ * be found <A HREF="http://www.remotesensing.org/geotiff/proj_list/">there</A>.
+ * Most projections expect the following parameters:
+ *  <code>"central_meridian"</code> (default to 0),
+ *  <code>"latitude_of_origin"</code> (default to 0),
+ *  <code>"scale_factor"</code> (default to 1),
+ *  <code>"false_easting"</code> (default to 0) and
+ *  <code>"false_northing"</code> (default to 0).</P>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultProjection.java $
+ * @version $Id: DefaultProjection.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see org.geotools.referencing.crs.DefaultProjectedCRS
+ * @see <A HREF="http://mathworld.wolfram.com/MapProjection.html">Map projections on MathWorld</A>
+ */
+public class DefaultProjection extends DefaultConversion implements Projection {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -7176751851369816864L;
+
+    /**
+     * Constructs a new projection with the same values than the specified one, together with the
+     * specified source and target CRS. While the source conversion can be an arbitrary one, it is
+     * typically a {@linkplain DefiningConversion defining conversion}.
+     *
+     * @param conversion The defining conversion.
+     * @param sourceCRS The source CRS.
+     * @param targetCRS The target CRS.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source CRS}
+     *                  to positions in the {@linkplain #getTargetCRS target CRS}.
+     */
+    public DefaultProjection(final Conversion               conversion,
+                             final CoordinateReferenceSystem sourceCRS,
+                             final CoordinateReferenceSystem targetCRS,
+                             final MathTransform             transform)
+    {
+        super(conversion, sourceCRS, targetCRS, transform);
+    }
+
+    /**
+     * Constructs a projection from a set of properties. The properties given in argument
+     * follow the same rules than for the {@link AbstractCoordinateOperation} constructor.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param sourceCRS The source CRS, or {@code null} if not available.
+     * @param targetCRS The target CRS, or {@code null} if not available.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source coordinate
+     *                  reference system} to positions in the {@linkplain #getTargetCRS target
+     *                  coordinate reference system}.
+     * @param method    The operation method.
+     */
+    public DefaultProjection(final Map<String,?>             properties,
+                             final CoordinateReferenceSystem sourceCRS,
+                             final CoordinateReferenceSystem targetCRS,
+                             final MathTransform             transform,
+                             final OperationMethod           method)
+    {
+        super(properties, sourceCRS, targetCRS, transform, method);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultSingleOperation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultSingleOperation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultSingleOperation.java	(revision 28000)
@@ -0,0 +1,75 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Map;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.SingleOperation;
+
+
+/**
+ * A single (not {@linkplain DefaultConcatenatedOperation concatenated}) coordinate operation.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultSingleOperation.java $
+ * @version $Id: DefaultSingleOperation.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class DefaultSingleOperation extends AbstractCoordinateOperation implements SingleOperation {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 672935231344137185L;
+
+    /**
+     * Constructs a new single operation with the same values than the specified defining
+     * conversion, together with the specified source and target CRS. This constructor
+     * is used by {@link DefaultConversion} only.
+     */
+    DefaultSingleOperation(final Conversion               definition,
+                           final CoordinateReferenceSystem sourceCRS,
+                           final CoordinateReferenceSystem targetCRS,
+                           final MathTransform             transform)
+    {
+        super(definition, sourceCRS, targetCRS, transform);
+    }
+
+    /**
+     * Constructs a single operation from a set of properties. The properties given in argument
+     * follow the same rules than for the {@link AbstractCoordinateOperation} constructor.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param sourceCRS The source CRS.
+     * @param targetCRS The target CRS.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source CRS}
+     *                  to positions in the {@linkplain #getTargetCRS target CRS}.
+     */
+    public DefaultSingleOperation(final Map<String,?>            properties,
+                                  final CoordinateReferenceSystem sourceCRS,
+                                  final CoordinateReferenceSystem targetCRS,
+                                  final MathTransform             transform)
+    {
+        super(properties, sourceCRS, targetCRS, transform);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultTransformation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultTransformation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefaultTransformation.java	(revision 28000)
@@ -0,0 +1,71 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Map;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.Transformation;
+import org.opengis.referencing.operation.OperationMethod;
+
+
+/**
+ * An operation on coordinates that usually includes a change of Datum. The parameters
+ * of a coordinate transformation are empirically derived from data containing the coordinates
+ * of a series of points in both coordinate reference systems. This computational process
+ * is usually "over-determined", allowing derivation of error (or accuracy) estimates
+ * for the transformation. Also, the stochastic nature of the parameters may result
+ * in multiple (different) versions of the same coordinate transformation.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultTransformation.java $
+ * @version $Id: DefaultTransformation.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see DefaultConversion
+ */
+public class DefaultTransformation extends DefaultOperation implements Transformation {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -7486704846151648971L;
+
+    /**
+     * Constructs a transformation from a set of properties. The properties given in argument
+     * follow the same rules than for the {@link AbstractCoordinateOperation} constructor.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param sourceCRS The source CRS.
+     * @param targetCRS The target CRS.
+     * @param transform Transform from positions in the {@linkplain #getSourceCRS source CRS}
+     *                  to positions in the {@linkplain #getTargetCRS target CRS}.
+     * @param method    The operation method.
+     */
+    public DefaultTransformation(final Map<String,?>            properties,
+                                 final CoordinateReferenceSystem sourceCRS,
+                                 final CoordinateReferenceSystem targetCRS,
+                                 final MathTransform             transform,
+                                 final OperationMethod           method)
+    {
+        super(properties, sourceCRS, targetCRS, transform, method);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefiningConversion.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefiningConversion.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/DefiningConversion.java	(revision 28000)
@@ -0,0 +1,134 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.OperationMethod;
+
+
+/**
+ * A conversion used for the definition of a {@linkplain org.opengis.referencing.crs.GeneralDerivedCRS
+ * derived CRS} (including projections). This conversion has no source and target CRS, and no math
+ * transform. Those elements are created by the derived CRS itself.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefiningConversion.java $
+ * @version $Id: DefiningConversion.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Matthias Basler
+ *
+ * @see org.opengis.referencing.operation.CoordinateOperationFactory#createDefiningConversion
+ */
+public class DefiningConversion extends DefaultConversion {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 7399026512478064721L;
+
+    /**
+     * The parameter values.
+     */
+    private final ParameterValueGroup parameters;
+
+    /**
+     * Convenience constructor for creating a defining conversion with a default operation method.
+     * The operation method is assumed two-dimensional.
+     *
+     * @param name       The conversion name.
+     * @param parameters The parameter values.
+     *
+     * @since 2.2
+     */
+    public DefiningConversion(final String name, final ParameterValueGroup parameters) {
+        this(Collections.singletonMap(NAME_KEY, name), getOperationMethod(parameters), parameters);
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private static OperationMethod getOperationMethod(final ParameterValueGroup parameters) {
+        ensureNonNull("parameters", parameters);
+        final ParameterDescriptorGroup descriptor = parameters.getDescriptor();
+        return new DefaultOperationMethod(getProperties(descriptor, null), 2, 2, descriptor);
+    }
+
+    /**
+     * Constructs a conversion from a set of parameters. The properties given in argument
+     * follow the same rules than for the {@link AbstractCoordinateOperation} constructor.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param method     The operation method.
+     * @param parameters The parameter values.
+     */
+    public DefiningConversion(final Map<String,?>       properties,
+                              final OperationMethod     method,
+                              final ParameterValueGroup parameters)
+    {
+        super(properties, null, null, null, method);
+        ensureNonNull("parameters", parameters);
+        this.parameters = parameters.clone();
+    }
+
+    /**
+     * Constructs a conversion from a math transform. The properties given in argument
+     * follow the same rules than for the {@link AbstractCoordinateOperation} constructor.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param method     The operation method.
+     * @param transform  Transform from positions in the {@linkplain #getSourceCRS source CRS}
+     *                   to positions in the {@linkplain #getTargetCRS target CRS}.
+     *
+     * @since 2.5
+     */
+    public DefiningConversion(final Map<String,?>   properties,
+                              final OperationMethod method,
+                              final MathTransform   transform)
+    {
+        super(properties, null, null, transform, method);
+        parameters = null;
+    }
+
+    /**
+     * Invoked by the super-class constructor for checking argument validity. This special
+     * kind of conversion accepts non-null {@code transform} even if {@code sourceCRS} and
+     * {@code targetCRS} are non-null.
+     */
+    @Override
+    void validate() throws IllegalArgumentException {
+        if (transform == null) {
+            super.validate();
+        }
+    }
+
+    /**
+     * Returns the parameter values.
+     */
+    @Override
+    public ParameterValueGroup getParameterValues() {
+        return (parameters != null) ? parameters.clone() : super.getParameterValues();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/LinearTransform.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/LinearTransform.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/LinearTransform.java	(revision 28000)
@@ -0,0 +1,63 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.Matrix;
+import org.geotools.referencing.operation.matrix.XMatrix;
+
+
+/**
+ * Interface for linear {@link MathTransform}s.  A linear transform can be express as an affine
+ * transform using a {@linkplain #getMatrix matrix}. The {@linkplain Matrix#getNumCol number of
+ * columns} is equals to the number of {@linkplain #getSourceDimensions source dimensions} plus 1,
+ * and the {@linkplain Matrix#getNumRow number of rows} is equals to the number of
+ * {@linkplain #getTargetDimensions target dimensions} plus 1.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/LinearTransform.java $
+ * @version $Id: LinearTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public interface LinearTransform extends MathTransform {
+    /**
+     * Returns this transform as an affine transform matrix.
+     *
+     * @return A copy of the underlying matrix.
+     */
+    Matrix getMatrix();
+
+    /**
+     * Tests whether this transform does not move any points, by using the provided
+     * {@code tolerance} value. The signification of <cite>tolerance value</cite> is
+     * the same than in the following pseudo-code:
+     *
+     * <blockquote><pre>
+     * {@linkplain #getMatrix()}.{@linkplain XMatrix#isIdentity(double) isIdentity}(tolerance);
+     * </pre></blockquote>
+     *
+     * @param tolerance The tolerance factor.
+     * @return {@code true} if this transform is the identity one
+     *
+     * @since 2.4
+     */
+    boolean isIdentity(double tolerance);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/MathTransformProvider.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/MathTransformProvider.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/MathTransformProvider.java	(revision 28000)
@@ -0,0 +1,521 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.measure.unit.Unit;
+
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.parameter.DefaultParameterDescriptor;
+import org.geotools.parameter.DefaultParameterDescriptorGroup;
+import org.geotools.parameter.Parameters;
+import org.geotools.referencing.operation.transform.MathTransformProxy;
+import org.geotools.resources.XArray;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.parameter.InvalidParameterNameException;
+import org.opengis.parameter.InvalidParameterValueException;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.Operation;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.util.GenericName;
+
+
+/**
+ * An {@linkplain DefaultOperationMethod operation method} capable to creates a
+ * {@linkplain MathTransform math transform} from set of
+ * {@linkplain GeneralParameterValue parameter values}.
+ * Implementations of this class should be listed in the following file:
+ *
+ * <blockquote>
+ * <P>{@code META-INF/services/org.geotools.referencing.operation.MathTransformProvider}</P>
+ * </blockquote>
+ * <P>
+ * The {@linkplain DefaultMathTransformFactory math transform factory} will parse this file in order
+ * to gets all available providers on a system. If this file is bundle in many JAR files, the
+ * {@linkplain DefaultCoordinateOperationFactory math transform factory} will read all of them.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/MathTransformProvider.java $
+ * @version $Id: MathTransformProvider.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public abstract class MathTransformProvider extends DefaultOperationMethod {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 7530475536803158473L;
+
+    /**
+     * Constructs a math transform provider from a set of parameters. The provider
+     * {@linkplain #getIdentifiers identifiers} will be the same than the parameter
+     * ones.
+     *
+     * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
+     * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+     * @param parameters The set of parameters (never {@code null}).
+     */
+    public MathTransformProvider(final int sourceDimensions,
+                                 final int targetDimensions,
+                                 final ParameterDescriptorGroup parameters)
+    {
+        this(toMap(parameters), sourceDimensions, targetDimensions, parameters);
+    }
+
+    /**
+     * Constructs a math transform provider from a set of properties.
+     * The properties map is given unchanged to the
+     * {@linkplain DefaultOperationMethod#DefaultOperationMethod(Map,int,int,ParameterDescriptorGroup)
+     * super-class constructor}.
+     *
+     * @param properties Set of properties. Should contains at least {@code "name"}.
+     * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
+     * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+     * @param parameters The set of parameters (never {@code null}).
+     */
+    public MathTransformProvider(final Map<String,?> properties,
+                                 final int sourceDimensions,
+                                 final int targetDimensions,
+                                 final ParameterDescriptorGroup parameters)
+    {
+        super(properties, sourceDimensions, targetDimensions, parameters);
+    }
+
+    /**
+     * Work around for RFE #4093999 in Sun's bug database
+     * ("Relax constraint on placement of this()/super() call in constructors").
+     */
+    private static Map<String,Object> toMap(final IdentifiedObject parameters) {
+        ensureNonNull("parameters", parameters);
+        final Map<String,Object> properties = new HashMap<String,Object>(4);
+        properties.put(NAME_KEY,        parameters.getName());
+        properties.put(IDENTIFIERS_KEY, parameters.getIdentifiers().toArray(EMPTY_IDENTIFIER_ARRAY));
+        properties.put(ALIAS_KEY,       parameters.getAlias()      .toArray(EMPTY_ALIAS_ARRAY));
+        return properties;
+    }
+
+    /**
+     * Returns the operation type. It may be
+     * <code>{@linkplain org.opengis.referencing.operation.Operation}.class</code>,
+     * <code>{@linkplain org.opengis.referencing.operation.Conversion}.class</code>,
+     * <code>{@linkplain org.opengis.referencing.operation.Projection}.class</code>,
+     * <cite>etc</cite>.
+     * <p>
+     * The default implementation returns {@code Operation.class}.
+     * Subclass should overrides this methods and returns the appropriate
+     * OpenGIS interface type (<strong>not</strong> the implementation type).
+     *
+     * @return The GeoAPI interface implemented by this operation.
+     */
+    @Override
+    public Class<? extends Operation> getOperationType() {
+        return Operation.class;
+    }
+
+    /**
+     * Creates a math transform from the specified group of parameter values.
+     * Subclasses can implements this method as in the example below:
+     *
+     * <blockquote><pre>
+     * double semiMajor = values.parameter("semi_major").doubleValue(SI.METER);
+     * double semiMinor = values.parameter("semi_minor").doubleValue(SI.METER);
+     * // etc...
+     * return new MyTransform(semiMajor, semiMinor, ...);
+     * </pre></blockquote>
+     *
+     * @param  values The group of parameter values.
+     * @return The created math transform.
+     * @throws InvalidParameterNameException if the values contains an unknow parameter.
+     * @throws ParameterNotFoundException if a required parameter was not found.
+     * @throws InvalidParameterValueException if a parameter has an invalid value.
+     * @throws FactoryException if the math transform can't be created for some other reason
+     *         (for example a required file was not found).
+     *
+     * @see MathTransformProvider.Delegate
+     */
+    protected abstract MathTransform createMathTransform(ParameterValueGroup values)
+            throws InvalidParameterNameException,
+                   ParameterNotFoundException,
+                   InvalidParameterValueException,
+                   FactoryException;
+
+    /**
+     * Constructs a parameter descriptor from a set of alias. The parameter is
+     * identified by codes provided by one or more authorities. Common authorities are
+     * {@link Citations#OGC OGC} and {@link Citations#EPSG EPSG} for example.
+     *
+     * <P>The first entry in the {@code identifiers} array is both the
+     * {@linkplain ParameterDescriptor#getName main name} and the
+     * {@linkplain ParameterDescriptor#getIdentifiers identifiers}.
+     * All others are {@linkplain ParameterDescriptor#getAlias aliases}.</P>
+     *
+     * @param identifiers  The parameter identifiers. Most contains at least one entry.
+     * @param defaultValue The default value for the parameter, or {@link Double#NaN} if none.
+     * @param minimum The minimum parameter value, or {@link Double#NEGATIVE_INFINITY} if none.
+     * @param maximum The maximum parameter value, or {@link Double#POSITIVE_INFINITY} if none.
+     * @param unit    The unit for default, minimum and maximum values.
+     * @return The descriptor for the given identifiers.
+     */
+    protected static ParameterDescriptor<Double> createDescriptor(
+            final ReferenceIdentifier[] identifiers, final double defaultValue,
+            final double minimum, final double maximum, final Unit<?> unit)
+    {
+        return DefaultParameterDescriptor.create(toMap(identifiers), defaultValue,minimum, maximum, unit, true);
+    }
+
+    /**
+     * Constructs an optional parameter descriptor from a set of alias.
+     * The parameter is identified as with {@link #createDescriptor}.
+     *
+     * @param identifiers The parameter identifiers. Most contains at least one entry.
+     * @param minimum The minimum parameter value, or {@link Double#NEGATIVE_INFINITY} if none.
+     * @param maximum The maximum parameter value, or {@link Double#POSITIVE_INFINITY} if none.
+     * @param unit    The unit for default, minimum and maximum values.
+     * @return The descriptor for the given identifiers.
+     */
+    protected static ParameterDescriptor<Double> createOptionalDescriptor(
+            final ReferenceIdentifier[] identifiers,
+            final double minimum, final double maximum, final Unit<?> unit)
+    {
+        return DefaultParameterDescriptor.create(toMap(identifiers), Double.NaN,
+                                              minimum, maximum, unit, false);
+    }
+
+    /**
+     * Constructs a parameter group from a set of alias. The parameter group is
+     * identified by codes provided by one or more authorities. Common authorities are
+     * {@link Citations#OGC OGC} and {@link Citations#EPSG EPSG} for example.
+     * <P>
+     * Special rules:
+     * <ul>
+     *   <li>The first entry in the {@code identifiers} array is the
+     *       {@linkplain ParameterDescriptorGroup#getName primary name}.</li>
+     *   <li>If a an entry do not implements the {@link GenericName} interface, it is
+     *       an {@linkplain ParameterDescriptorGroup#getIdentifiers identifiers}.</li>
+     *   <li>All others are {@linkplain ParameterDescriptorGroup#getAlias aliases}.</li>
+     * </ul>
+     *
+     * @param identifiers  The operation identifiers. Most contains at least one entry.
+     * @param parameters   The set of parameters, or {@code null} or an empty array if none.
+     * @return The descriptor for the given identifiers.
+     */
+    protected static ParameterDescriptorGroup createDescriptorGroup(
+            final ReferenceIdentifier[] identifiers, final GeneralParameterDescriptor[] parameters)
+    {
+        return new DefaultParameterDescriptorGroup(toMap(identifiers), parameters);
+    }
+
+    /**
+     * Put the identifiers into a properties map suitable for {@link IdentifiedObject}
+     * constructor.
+     */
+    private static Map<String,Object> toMap(final ReferenceIdentifier[] identifiers) {
+        ensureNonNull("identifiers", identifiers);
+        if (identifiers.length == 0) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.EMPTY_ARRAY));
+        }
+        int idCount    = 0;
+        int aliasCount = 0;
+        ReferenceIdentifier[] id = new ReferenceIdentifier[identifiers.length];
+        GenericName[]      alias = new GenericName        [identifiers.length];
+        for (int i=0; i<identifiers.length; i++) {
+            final ReferenceIdentifier candidate = identifiers[i];
+            if (candidate instanceof GenericName) {
+                alias[aliasCount++] = (GenericName) candidate;
+            } else {
+                id[idCount++] = candidate;
+            }
+        }
+        id    = XArray.resize(id,       idCount);
+        alias = XArray.resize(alias, aliasCount);
+        final Map<String,Object> properties = new HashMap<String,Object>(4, 0.8f);
+        properties.put(NAME_KEY,        identifiers[0]);
+        properties.put(IDENTIFIERS_KEY, id);
+        properties.put(ALIAS_KEY,       alias);
+        return properties;
+    }
+
+    /**
+     * Ensures that the given set of parameters contains only valid values.
+     * This method compares all parameter names against the names declared in the
+     * {@linkplain #getParameters operation method parameter descriptor}. If an unknow
+     * parameter name is found, then an {@link InvalidParameterNameException} is thrown.
+     * This method also ensures that all values are assignable to the
+     * {@linkplain ParameterDescriptor#getValueClass expected class}, are between the
+     * {@linkplain ParameterDescriptor#getMinimumValue minimum} and
+     * {@linkplain ParameterDescriptor#getMaximumValue maximum} values and are one of the
+     * {@linkplain ParameterDescriptor#getValidValues set of valid values}.
+     * If the value fails any of those tests, then an
+     * {@link InvalidParameterValueException} is thrown.
+     *
+     * @param  values The parameters values to check.
+     * @return The parameter values to use for {@linkplain MathTransform math transform}
+     *         construction. May be different than the supplied {@code values}
+     *         argument if some missing values needed to be filled with default values.
+     * @throws InvalidParameterNameException if a parameter name is unknow.
+     * @throws InvalidParameterValueException if a parameter has an invalid value.
+     */
+    protected ParameterValueGroup ensureValidValues(final ParameterValueGroup values)
+            throws InvalidParameterNameException, InvalidParameterValueException
+    {
+        final ParameterDescriptorGroup parameters = getParameters();
+        final GeneralParameterDescriptor descriptor = values.getDescriptor();
+        if (parameters.equals(descriptor)) {
+            /*
+             * Since the "official" parameter descriptor was used, the descriptor should
+             * have already enforced argument validity. Consequently, there is no need to
+             * performs the check and we will avoid it as a performance enhancement.
+             */
+            return values;
+        }
+        /*
+         * Copy the all values from the user-supplied group to the provider-supplied group.
+         * The provider group should performs all needed checks. Furthermore, it is suppliers
+         * responsability to know about alias (e.g. OGC, EPSG, ESRI), while the user will
+         * probably use the name from only one authority. With a copy, we gives a chances to
+         * the provider-supplied parameters to uses its alias for understanding the user
+         * parameter names.
+         */
+        final ParameterValueGroup copy = parameters.createValue();
+        copy(values, copy);
+        return copy;
+    }
+
+    /**
+     * Implementation of {@code ensureValidValues}, to be invoked recursively
+     * if the specified values contains sub-groups of values. This method copy all
+     * values from the user-supplied parameter values into the provider-supplied
+     * one. The provider one should understand alias, and performs name conversion
+     * as well as argument checking on the fly.
+     *
+     * @param  values The parameters values to copy.
+     * @param  copy   The parameters values where to put the copy.
+     * @throws InvalidParameterNameException if a parameter name is unknow.
+     * @throws InvalidParameterValueException if a parameter has an invalid value.
+     */
+    private static void copy(final ParameterValueGroup values,
+                             final ParameterValueGroup copy)
+            throws InvalidParameterNameException, InvalidParameterValueException
+    {
+        for (final GeneralParameterValue value : values.values()) {
+            final String name = value.getDescriptor().getName().getCode();
+            if (value instanceof ParameterValueGroup) {
+                /*
+                 * Contains sub-group - invokes 'copy' recursively.
+                 */
+                final GeneralParameterDescriptor descriptor;
+                descriptor = copy.getDescriptor().descriptor(name);
+                if (descriptor instanceof ParameterDescriptorGroup) {
+                    final ParameterValueGroup groups = (ParameterValueGroup) descriptor.createValue();
+                    copy((ParameterValueGroup) value, groups);
+                    values.groups(name).add(groups);
+                    continue;
+                } else {
+                    throw new InvalidParameterNameException(Errors.format(
+                              ErrorKeys.UNEXPECTED_PARAMETER_$1, name), name);
+                }
+            }
+            /*
+             * Single parameter - copy the value, with special care for value with units.
+             */
+            final ParameterValue<?> source = (ParameterValue) value;
+            final ParameterValue<?> target;
+            try {
+                target = copy.parameter(name);
+            } catch (ParameterNotFoundException cause) {
+                final InvalidParameterNameException exception =
+                      new InvalidParameterNameException(Errors.format(
+                          ErrorKeys.UNEXPECTED_PARAMETER_$1, name), name);
+                exception.initCause(cause);
+                throw exception;
+            }
+            final Object  v    = source.getValue();
+            final Unit<?> unit = source.getUnit();
+            if (unit == null) {
+                target.setValue(v);
+            } else if (v instanceof Number) {
+                target.setValue(((Number) v).doubleValue(), unit);
+            } else if (v instanceof double[]) {
+                target.setValue((double[]) v, unit);
+            } else {
+                throw new InvalidParameterValueException(Errors.format(
+                          ErrorKeys.ILLEGAL_ARGUMENT_$2, name, v), name, v);
+            }
+        }
+    }
+
+    /**
+     * Returns the parameter value for the specified operation parameter.
+     * This convenience method is used by subclasses for initializing
+     * {@linkplain MathTransform math transform} from a set of parameters.
+     *
+     * @param  param The parameter to look for.
+     * @param  group The parameter value group to search into.
+     * @return The requested parameter value.
+     * @throws ParameterNotFoundException if the parameter is not found.
+     */
+    protected static <T> ParameterValue<T> getParameter(final ParameterDescriptor<T> param,
+                                                      final ParameterValueGroup    group)
+            throws ParameterNotFoundException
+    {
+        /*
+         * Search for an identifier matching the group's authority, if any.
+         * This is needed if the parameter values group was created from an
+         * EPSG database for example: we need to use the EPSG names instead
+         * of the OGC ones.
+         */
+        String name = getName(param, group.getDescriptor().getName().getAuthority());
+        if (name == null) {
+            name = param.getName().getCode();
+        }
+        if (param.getMinimumOccurs() != 0) {
+            return Parameters.cast(group.parameter(name), param.getValueClass());
+        }
+        /*
+         * The parameter is optional. We don't want to invokes 'parameter(name)', because we don't
+         * want to create a new parameter is the user didn't supplied one. Search the parameter
+         * ourself (so we don't create any), and returns null if we don't find any.
+         *
+         * TODO: A simplier solution would be to add a 'isDefined' method in GeoAPI,
+         *       or something similar.
+         */
+        final GeneralParameterDescriptor search;
+        search = group.getDescriptor().descriptor(name);
+        if (search instanceof ParameterDescriptor) {
+            for (final GeneralParameterValue candidate : group.values()) {
+                if (search.equals(candidate.getDescriptor())) {
+                    return Parameters.cast((ParameterValue) candidate, param.getValueClass());
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the parameter value for the specified operation parameter.
+     * This convenience method is used by subclasses for initializing
+     * {@linkplain MathTransform math transform} from a set of parameters.
+     *
+     * @param  param The parameter to look for.
+     * @param  group The parameter value group to search into.
+     * @return The requested parameter value, or {@code 0} if {@code param} is
+     *         {@linkplain #createOptionalDescriptor optional} and the user didn't
+     *         provided any value.
+     * @throws ParameterNotFoundException if the parameter is not found.
+     *
+     * @todo Move to the {@link org.geotools.parameter.Parameters} class.
+     */
+    protected static int intValue(final ParameterDescriptor<?> param,
+                                  final ParameterValueGroup    group)
+            throws ParameterNotFoundException
+    {
+        final ParameterValue<?> value = getParameter(param, group);
+        return (value != null) ? value.intValue() : 0;
+    }
+
+    /**
+     * Returns the parameter value for the specified operation parameter.
+     * Values are automatically converted into the standard units specified
+     * by the supplied {@code param} argument.
+     * This convenience method is used by subclasses for initializing
+     * {@linkplain MathTransform math transform} from a set of parameters.
+     *
+     * @param  param The parameter to look for.
+     * @param  group The parameter value group to search into.
+     * @return The requested parameter value, or {@code NaN} if {@code param} is
+     *         {@linkplain #createOptionalDescriptor optional} and the user didn't
+     *         provided any value.
+     * @throws ParameterNotFoundException if the parameter is not found.
+     *
+     * @todo Move to the {@link org.geotools.parameter.Parameters} class.
+     */
+    protected static double doubleValue(final ParameterDescriptor<?> param,
+                                        final ParameterValueGroup    group)
+            throws ParameterNotFoundException
+    {
+        final Unit<?> unit = param.getUnit();
+        final ParameterValue<?> value = getParameter(param, group);
+        return (value == null) ? Double.NaN :
+                (unit != null) ? value.doubleValue(unit) : value.doubleValue();
+    }
+
+    /**
+     * The result of a call to {@link MathTransformProvider#createMathTransform createMathTransform}.
+     * This class encapsulates a reference to the {@linkplain #method originating provider}
+     * as well as the {@linkplain #transform created math transform}. This information is needed
+     * when a provider delegates the work to an other provider according the parameter values.
+     * For example a generic instance of
+     * {@link org.geotools.referencing.operation.transform.ProjectiveTransform.ProviderAffine
+     * ProviderAffine} may delegates the creation of an <cite>affine transform</cite> to an other
+     * {@code ProviderAffine} instance with <cite>source</cite> and <cite>target</cite> dimensions
+     * matching the supplied parameters, because those dimensions determine the set of legal
+     * <code>"elt_<var>j</var>_<var>i</var>"</code> parameters.
+     * <p>
+     * Most {@linkplain MathTransformProvider math transform provider} do not delegate their work
+     * to an other one, and consequently do not need this class.
+     * <p>
+     * Future Geotools version may extends this class for handling more information than just the
+     * {@linkplain #transform transform} creator. This class is more convenient than adding new
+     * methods right into {@link MathTransformProvider}, because it is sometime difficult for a
+     * provider to infer all the conditions prevaling when
+     * {@link MathTransformProvider#createMathTransform createMathTransform} was executed.
+     * Furthermore, it avoid to pollute {@code MathTransformProvider} with methods unused
+     * for the vast majority of providers.
+     *
+     * @version $Id: MathTransformProvider.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     *
+     * @since 2.2
+     */
+    protected static final class Delegate extends MathTransformProxy {
+        /**
+         * For cross-version compatibility.
+         */
+        private static final long serialVersionUID = -3942740060970730790L;
+
+        /**
+         * The provider for the {@linkplain #transform transform}.
+         */
+        public final OperationMethod method;
+
+        /**
+         * Encapsulates the math transform created by the specified provider.
+         *
+         * @param transform The math transform created by provider.
+         * @param method The provider, typically as an instance of {@link MathTransformProvider}.
+         */
+        public Delegate(final MathTransform transform, final OperationMethod method) {
+            super(transform);
+            this.method = method;
+            ensureNonNull("transform", transform);
+            ensureNonNull("method",    method);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/ProjectionAnalyzer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/ProjectionAnalyzer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/ProjectionAnalyzer.java	(revision 28000)
@@ -0,0 +1,439 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation;
+
+import java.util.List;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.logging.LogRecord;
+import javax.measure.unit.Unit;
+import javax.measure.unit.SI;
+
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+
+import org.geotools.util.Utilities;
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.cs.AbstractCS;
+import org.geotools.referencing.factory.ReferencingFactory;
+import org.geotools.referencing.operation.matrix.XMatrix;
+import org.geotools.referencing.operation.matrix.MatrixFactory;
+import org.geotools.referencing.operation.transform.AbstractMathTransform;
+import org.geotools.referencing.operation.transform.ConcatenatedTransform;
+import org.geotools.referencing.operation.projection.MapProjection;   // For javadoc
+import org.geotools.resources.i18n.LoggingKeys;
+import org.geotools.resources.i18n.Loggings;
+
+import static org.geotools.referencing.AbstractIdentifiedObject.nameMatches;
+
+
+/**
+ * Returns a conversion from a source to target projected CRS, if this conversion
+ * is representable as an affine transform. More specifically, if all projection
+ * parameters are identical except the following ones:
+ * <P>
+ * <UL>
+ *   <LI>{@link MapProjection.AbstractProvider#SCALE_FACTOR   scale_factor}</LI>
+ *   <LI>{@link MapProjection.AbstractProvider#FALSE_EASTING  false_easting}</LI>
+ *   <LI>{@link MapProjection.AbstractProvider#FALSE_NORTHING false_northing}</LI>
+ * </UL>
+ * <P>
+ * Then the conversion between two projected CRS can sometime be represented as a linear
+ * conversion. For example if only false easting/northing differ, then the coordinate conversion
+ * is simply a translation.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/ProjectionAnalyzer.java $
+ * @version $Id: ProjectionAnalyzer.java 31445 2008-09-07 18:14:23Z desruisseaux $
+ * @author Martin Desruisseaux (IRD)
+ */
+final class ProjectionAnalyzer {
+    /**
+     * The map projection.
+     */
+    private final Conversion projection;
+
+    /**
+     * The affine transform applied on projected coordinates after the projection.
+     * In Geotools {@link MapProjection} implementation, this is the axis swapping
+     * and scaling needed in order to get standard (<var>x</var>,<var>y</var>) axis
+     * in metres. Can be {@code null} if none.
+     */
+    private final Matrix projectedScale;
+
+    /**
+     * The transform for the map projection alone, without the {@link #geographicScale}
+     * and {@link #projectedScale} parts. In Geotools implementation, it should be an
+     * instance of {@link MapProjection}. May be {@code null} if we can't handle the
+     * {@linkplain #projection}.
+     */
+    private final MathTransform transform;
+
+    /**
+     * The map projection parameters values, or a copy of them.
+     */
+    private List<GeneralParameterValue> parameters;
+
+    /**
+     * Constructs a {@code ProjectionAnalyzer} for the specified projected CRS. This constructor
+     * inspects the {@linkplain ProjectedCRS#getConversionFromBase conversion from base} and splits
+     * {@link ConcatenatedTransform} in their {@link #geographicScale}, {@link #projectedScale}
+     * and {@link #transform} components.
+     */
+    private ProjectionAnalyzer(final ProjectedCRS crs) {
+        Matrix geographicScale = null;
+        Matrix  projectedScale = null;
+        projection = crs.getConversionFromBase();
+        MathTransform candidate = projection.getMathTransform();
+        while (candidate instanceof ConcatenatedTransform) {
+            final ConcatenatedTransform ctr = (ConcatenatedTransform) candidate;
+            if (ctr.transform1 instanceof LinearTransform) {
+                if (geographicScale != null) {
+                    // Should never happen with ConcatenatedTransform.create(...) implementation.
+                    throw new IllegalStateException(String.valueOf(candidate));
+                }
+                geographicScale = ((LinearTransform) ctr.transform1).getMatrix();
+                candidate = ctr.transform2;
+                continue;
+            }
+            if (ctr.transform2 instanceof LinearTransform) {
+                if (projectedScale != null) {
+                    // Should never happen with ConcatenatedTransform.create(...) implementation.
+                    throw new IllegalStateException(String.valueOf(candidate));
+                }
+                projectedScale = ((LinearTransform) ctr.transform2).getMatrix();
+                candidate = ctr.transform1;
+                continue;
+            }
+            // Both transforms are non-linear. We can not handle that.
+            candidate = null;
+            break;
+        }
+        //
+        // TODO: We need to handle PassthroughTransform here in some future version
+        //       (when we will want better handling of 3D coordinates).
+        //
+        /*
+         * We should really fetch the parameters from the MathTransform as much as we can, since
+         * this is the most robust source of information (the one which is the most likely to be
+         * an accurate description of the map projection without the above geographic and projected
+         * scale components). However if we are not able to query the math transform, we will query
+         * the Conversion object as a fallback and hope that it describes only the map projection
+         * part, as in Geotools implementation.
+         */
+        ParameterValueGroup group = null;
+        if (candidate instanceof AbstractMathTransform) {
+            group = ((AbstractMathTransform) candidate).getParameterValues();
+        }
+        if (group == null) {
+            /*
+             * Fallback path only if we don't have a Geotools MapProjection implementation.
+             * NOTE: it is uncertain that we should call 'swapAndScaleAxis'. If the CS has
+             * standard axis, it will not hurt since we should get the identity transform.
+             * If the CS doesn't have standard axis, then 'projectedScale' should be non-
+             * null and 'swapAndScaleAxis' is not needed. But if none of the above hold,
+             * then some axis swapping is probably done straight into the unknown 'transform'
+             * implementation and we need to "guess" what it is. Those rules are somewhat
+             * heuristic; the previous "if" branch for Geotools MapProjection implementations
+             * should be more determinist.
+             */
+            group = projection.getParameterValues();
+            if (projectedScale == null) {
+                final CoordinateSystem cs = crs.getCoordinateSystem();
+                projectedScale = AbstractCS.swapAndScaleAxis(AbstractCS.standard(cs), cs);
+            }
+        }
+        if (group != null) {
+            parameters = group.values();
+        }
+        this.projectedScale  = projectedScale;
+        this.transform       = candidate;
+    }
+
+    /**
+     * Returns the {@linkplain #transform} parameter descriptor, or {@code null} if none.
+     */
+    private ParameterDescriptorGroup getTransformDescriptor() {
+        return (transform instanceof AbstractMathTransform) ?
+            ((AbstractMathTransform) transform).getParameterDescriptors() : null;
+    }
+
+    /**
+     * Returns the affine transform applied after the <em>normalized</em> projection in order to
+     * get the same projection than {@link #transform}. The normalized projection is a imaginary
+     * transform (we don't have a {@link MathTransform} instance for it, but we don't need) with
+     * {@code "scale factor"} == 1, {@code "false easting"} == 0 and {@code "false northing"} == 0.
+     * In other words, this method extracts the above-cited parameters in an affine transform.
+     * <p>
+     * As a side effect, this method removes from the {@linkplain #parameters} list
+     * all the above-cited ones parameters.
+     *
+     * @return The affine transform.
+     */
+    private XMatrix normalizedToProjection() {
+        parameters = new LinkedList<GeneralParameterValue>(parameters); // Keep the original list unchanged.
+        /*
+         * Creates a matrix which will conceptually stands between the normalized transform and
+         * the 'projectedScale' transform. The matrix dimensions are selected accordingly using
+         * a robust code when possible, but the result should be a 3x3 matrix most of the time.
+         */
+        final int  sourceDim = (transform != null) ? transform.getTargetDimensions() : 2;
+        final int  targetDim = (projectedScale != null) ? projectedScale.getNumCol()-1 : sourceDim;
+        final XMatrix matrix = MatrixFactory.create(targetDim + 1, sourceDim + 1);
+        /*
+         * Search for "scale factor", "false easting" and "false northing" parameters.
+         * All parameters found are removed from the list. Note: we assume that linear
+         * units in the "normalized projection" are metres, as specified in the legacy
+         * OGC 01-009 specification, and that unit conversions (if needed) are applied
+         * by 'projectedScale'. However there is no way I can see to ensure that since
+         * it is really a matter of how the map projection is implemented (for example
+         * the unit conversion factor could be merged with the "scale_factor" -- not a
+         * clean approach and I do not recommand, but some could do in order to save a
+         * few multiplications).
+         *
+         * We need "false easting" and "false northing" offsets in either user's unit or
+         * in metres, depending if the unit conversions are applied in 'transform' or in
+         * 'projectedScale' respectively. We assume the later, which stands for Geotools
+         * implementation and is closer to OGC 01-009 spirit. But we will log a warning
+         * in case of doubt.
+         */
+        Unit<?> unit = null;
+        String warning = null;
+        for (final Iterator<GeneralParameterValue> it=parameters.iterator(); it.hasNext();) {
+            final GeneralParameterValue parameter = it.next();
+            if (parameter instanceof ParameterValue) {
+                final ParameterValue<?> value = (ParameterValue) parameter;
+                final ParameterDescriptor<?> descriptor = value.getDescriptor();
+                if (Number.class.isAssignableFrom(descriptor.getValueClass())) {
+                    if (nameMatches(descriptor, "scale_factor")) {
+                        final double scale = value.doubleValue();
+                        for (int i=Math.min(sourceDim, targetDim); --i>=0;) {
+                            matrix.setElement(i,i, matrix.getElement(i,i) * scale);
+                        }
+                    } else {
+                        final int d;
+                        if (nameMatches(descriptor, "false_easting")) {
+                            d = 0;
+                        } else if (nameMatches(descriptor, "false_northing")) {
+                            d = 1;
+                        } else {
+                            continue;
+                        }
+                        final double offset = value.doubleValue(SI.METER);
+                        if (!Double.isNaN(offset) && offset != value.doubleValue()) {
+                            // See the above comment about units. The above check could have been
+                            // replaced by "if (!SI.METER.equals(unit))", but the above avoid the
+                            // warning in the very common case where 'offset == 0'.
+                            unit = value.getUnit();
+                            warning = descriptor.getName().getCode();
+                        }
+                        matrix.setElement(d, sourceDim, matrix.getElement(d, sourceDim) + offset);
+                    }
+                    it.remove();
+                }
+            }
+        }
+        if (warning != null) {
+            final LogRecord record = Loggings.format(Level.WARNING,
+                    LoggingKeys.APPLIED_UNIT_CONVERSION_$3, warning, unit, SI.METER);
+            record.setSourceClassName(getClass().getName());
+            record.setSourceMethodName("createLinearConversion"); // This is the public method.
+            final Logger logger = ReferencingFactory.LOGGER;
+            record.setLoggerName(logger.getName());
+            logger.log(record);
+        }
+        return matrix;
+    }
+
+    /**
+     * Checks if the parameter in the two specified list contains the same values.
+     * The order parameter order is irrelevant. The common parameters are removed
+     * from both lists.
+     */
+    private static boolean parameterValuesEqual(final List<GeneralParameterValue> source,
+                                                final List<GeneralParameterValue> target,
+                                                final double errorTolerance)
+    {
+search: for (final Iterator<GeneralParameterValue> targetIter=target.iterator(); targetIter.hasNext();) {
+            final GeneralParameterValue targetPrm = targetIter.next();
+            for (final Iterator<GeneralParameterValue> sourceIter=source.iterator(); sourceIter.hasNext();) {
+                final GeneralParameterValue sourcePrm = sourceIter.next();
+                if (!nameMatches(sourcePrm.getDescriptor(), targetPrm.getDescriptor())) {
+                    continue;
+                }
+                if (sourcePrm instanceof ParameterValue && targetPrm instanceof ParameterValue) {
+                    final ParameterValue<?> sourceValue = (ParameterValue) sourcePrm;
+                    final ParameterValue<?> targetValue = (ParameterValue) targetPrm;
+                    if (Number.class.isAssignableFrom(targetValue.getDescriptor().getValueClass())) {
+                        final double sourceNum, targetNum;
+                        final Unit<?> unit = targetValue.getUnit();
+                        if (unit != null) {
+                            sourceNum = sourceValue.doubleValue(unit);
+                            targetNum = targetValue.doubleValue(unit);
+                        } else {
+                            sourceNum = sourceValue.doubleValue();
+                            targetNum = targetValue.doubleValue();
+                        }
+                        double error = (targetNum - sourceNum);
+                        if (targetNum != 0) error /= targetNum;
+                        if (!(Math.abs(error) <= errorTolerance)) { // '!' for trapping NaN
+                            return false;
+                        }
+                    } else {
+                        // The parameter do not hold a numerical value. It may be a
+                        // String, etc. Use the generic Object.equals(Object) method.
+                        if (!Utilities.equals(sourceValue.getValue(), targetValue.getValue())) {
+                            return false;
+                        }
+                    }
+                } else {
+                    // The GeneralParameter is not a ParameterValue instance. It is probably a
+                    // ParameterValueGroup. Compare all child elements without processing them.
+                    if (!Utilities.equals(targetPrm, sourcePrm)) {
+                        return false;
+                    }
+                }
+                // End of processing a pair of matching parameters. The values are equal or
+                // were one of the special cases processed above. Continue with a new pair.
+                sourceIter.remove();
+                targetIter.remove();
+                continue search;
+            }
+            // End of iteration in the 'source' parameters. If we reach this point, then we
+            // have found a target parameter without matching source parameter. We consider
+            // the two projections as different kind.
+            return false;
+        }
+        // End of iteration in the 'target' parameters, which should now be empty.
+        // Check if there is any unmatched parameter left in the supplied list.
+        assert target.isEmpty();
+        return source.isEmpty();
+    }
+
+    /**
+     * Applies {@code normalizedToProjection} first, then {@link #projectedScale}.
+     */
+    private XMatrix applyProjectedScale(final XMatrix normalizedToProjection) {
+        if (projectedScale == null) {
+            return normalizedToProjection;
+        }
+        final XMatrix scale = MatrixFactory.create(projectedScale);
+        scale.multiply(normalizedToProjection);
+        return scale;
+    }
+
+    /**
+     * Returns a conversion from a source to target projected CRS, if this conversion
+     * is representable as an affine transform. If no linear conversion has been found
+     * between the two CRS, then this method returns {@code null}.
+     *
+     * @param  sourceCRS The source coordinate reference system.
+     * @param  targetCRS The target coordinate reference system.
+     * @param  errorTolerance Relative error tolerance for considering two parameter values as
+     *         equal. This is usually a small number like {@code 1E-10}.
+     * @return The conversion from {@code sourceCRS} to {@code targetCRS} as an
+     *         affine transform, or {@code null} if no linear transform has been found.
+     */
+    public static Matrix createLinearConversion(final ProjectedCRS sourceCRS,
+                                                final ProjectedCRS targetCRS,
+                                                final double errorTolerance)
+    {
+        /*
+         * Checks if the datum are the same. To be stricter, we could compare the 'baseCRS'
+         * instead. But this is not always needed. For example we don't really care if the
+         * underlying geographic CRS use different axis order or units. What matter are the
+         * axis order and units of the projected CRS.
+         *
+         * Actually, checking for 'baseCRS' causes an infinite loop (until StackOverflowError)
+         * in CoordinateOperationFactory, because it prevents this method to recognize that the
+         * transform between two projected CRS is the identity transform even if their underlying
+         * geographic CRS use different axis order.
+         */
+        if (!CRS.equalsIgnoreMetadata(sourceCRS.getDatum(), targetCRS.getDatum())) {
+            return null;
+        }
+        final ProjectionAnalyzer source = new ProjectionAnalyzer(sourceCRS);
+        final ProjectionAnalyzer target = new ProjectionAnalyzer(targetCRS);
+        if (!nameMatches(source.projection.getMethod(), target.projection.getMethod())) {
+            /*
+             * In theory, we can not find a linear conversion if the operation method is
+             * not the same. In practice, it still hapen in some occasions.  For example
+             * "Transverse Mercator" and "Transverse Mercator (South Oriented)"  are two
+             * distinct operation methods in EPSG point of view, but in Geotools the South
+             * Oriented case is implemented as a "Transverse Mercator" concatenated with
+             * an affine transform performing the axis flip, which is a linear conversion.
+             *
+             * We may be tempted to compare the 'source.transform' and 'target.transform'
+             * implementation classes, but this is not robust enough.  For example it is
+             * possible to implement the "Oblique Mercator" and "Hotine Oblique Mercator"
+             * projections with a single class. But both cases can have identical user-
+             * supplied parameters and still be different projections (they differ in the
+             * origin of their grid coordinates).
+             *
+             * As a compromise, we compare the method name declared by the math transform,
+             * in addition of the method name declared by the conversion (the check above).
+             */
+            final ParameterDescriptorGroup sourceDsc = source.getTransformDescriptor();
+            final ParameterDescriptorGroup targetDsc = source.getTransformDescriptor();
+            if (sourceDsc==null || targetDsc==null || !nameMatches(sourceDsc, targetDsc)) {
+                return null;
+            }
+        }
+        /*
+         * Extracts the "scale_factor", "false_easting" and "false_northing" parameters
+         * as affine transforms. All remaining parameters must be identical.
+         */
+        if (source.parameters == null || target.parameters == null) {
+            return null;
+        }
+        XMatrix sourceScale = source.normalizedToProjection();
+        XMatrix targetScale = target.normalizedToProjection();
+        if (!parameterValuesEqual(source.parameters, target.parameters, errorTolerance)) {
+            return null;
+        }
+        /*
+         * Creates the matrix (including axis order changes and unit conversions),
+         * and apply the scale and translation inferred from the  "false_easting"
+         * parameter and its friends. We perform the conversion in three conceptual
+         * steps (in the end, everything is bundle in a single matrix):
+         *
+         *   1) remove the old false northing/easting
+         *   2) apply the scales
+         *   3) add the new false northing/easting
+         */
+        targetScale = target.applyProjectedScale(targetScale);
+        sourceScale = source.applyProjectedScale(sourceScale);
+        sourceScale.invert();
+        targetScale.multiply(sourceScale);
+        if (targetScale.isIdentity(errorTolerance)) {
+            targetScale.setIdentity();
+        }
+        return targetScale;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/GeneralMatrix.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/GeneralMatrix.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/GeneralMatrix.java	(revision 28000)
@@ -0,0 +1,411 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.matrix;
+
+import java.awt.geom.AffineTransform;
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+
+import javax.vecmath.GMatrix;
+
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+import org.opengis.geometry.Envelope;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.operation.Matrix;
+
+
+/**
+ * A two dimensional array of numbers. Row and column numbering begins with zero.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/matrix/GeneralMatrix.java $
+ * @version $Id: GeneralMatrix.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Simone Giannecchini
+ *
+ * @see javax.vecmath.GMatrix
+ * @see java.awt.geom.AffineTransform
+ * @see javax.media.jai.PerspectiveTransform
+ * @see javax.media.j3d.Transform3D
+ * @see <A HREF="http://math.nist.gov/javanumerics/jama/">Jama matrix</A>
+ * @see <A HREF="http://jcp.org/jsr/detail/83.jsp">JSR-83 Multiarray package</A>
+ */
+public class GeneralMatrix extends GMatrix implements XMatrix {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 8447482612423035360L;
+
+    /**
+     * Constructs a square identity matrix of size {@code size}&nbsp;&times;&nbsp;{@code size}.
+     *
+     * @param size The number of rows and columns.
+     */
+    public GeneralMatrix(final int size) {
+        super(size, size);
+    }
+
+    /**
+     * Creates a matrix of size {@code numRow}&nbsp;&times;&nbsp;{@code numCol}.
+     * Elements on the diagonal <var>j==i</var> are set to 1.
+     *
+     * @param numRow Number of rows.
+     * @param numCol Number of columns.
+     */
+    public GeneralMatrix(final int numRow, final int numCol) {
+        super(numRow, numCol);
+    }
+
+    /**
+     * Constructs a {@code numRow}&nbsp;&times;&nbsp;{@code numCol} matrix
+     * initialized to the values in the {@code matrix} array. The array values
+     * are copied in one row at a time in row major fashion. The array should be
+     * exactly <code>numRow*numCol</code> in length. Note that because row and column
+     * numbering begins with zero, {@code numRow} and {@code numCol} will be
+     * one larger than the maximum possible matrix index values.
+     *
+     * @param numRow Number of rows.
+     * @param numCol Number of columns.
+     * @param matrix Initial values.
+     */
+    public GeneralMatrix(final int numRow, final int numCol, final double[] matrix) {
+        super(numRow, numCol, matrix);
+        if (numRow*numCol != matrix.length) {
+            throw new IllegalArgumentException(String.valueOf(matrix.length));
+        }
+    }
+
+    /**
+     * Constructs a new matrix and copies the initial values from the parameter matrix.
+     *
+     * @param matrix The matrix to copy.
+     */
+    public GeneralMatrix(final Matrix matrix) {
+        this(matrix.getNumRow(), matrix.getNumCol());
+        final int height = getNumRow();
+        final int width  = getNumCol();
+        for (int j=0; j<height; j++) {
+            for (int i=0; i<width; i++) {
+                setElement(j, i, matrix.getElement(j, i));
+            }
+        }
+    }
+
+    /**
+     * Constructs a transform changing axis order and/or direction.
+     * For example, the transform may converts (NORTH,WEST) coordinates
+     * into (EAST,NORTH). Axis direction can be inversed only. For example,
+     * it is illegal to transform (NORTH,WEST) coordinates into (NORTH,DOWN).
+     *
+     * <P>If the source dimension is equals to the destination dimension,
+     * then the transform is affine. However, the following special cases
+     * are also handled:</P>
+     * <BR>
+     * <UL>
+     *   <LI>If the target dimension is smaller than the source dimension,
+     *       extra axis are dropped. An exception is thrown if the target
+     *       contains some axis not found in the source.</LI>
+     * </UL>
+     *
+     * @param  srcAxis The set of axis direction for source coordinate system.
+     * @param  dstAxis The set of axis direction for destination coordinate system.
+     * @throws IllegalArgumentException If {@code dstAxis} contains some axis
+     *         not found in {@code srcAxis}, or if some colinear axis were found.
+     */
+    public GeneralMatrix(final AxisDirection[] srcAxis,
+                         final AxisDirection[] dstAxis)
+    {
+        this(null, srcAxis, null, dstAxis, false);
+    }
+
+    /**
+     * Implementation of constructors expecting envelope and/or axis directions.
+     *
+     * @param validRegions   {@code true} if source and destination regions must
+     *        be taken in account. If {@code false}, then source and destination
+     *        regions will be ignored and may be null.
+     */
+    private GeneralMatrix(final Envelope srcRegion, final AxisDirection[] srcAxis,
+                          final Envelope dstRegion, final AxisDirection[] dstAxis,
+                          final boolean validRegions)
+    {
+        super(dstAxis.length+1, srcAxis.length+1);
+        if (validRegions) {
+            ensureDimensionMatch("srcRegion", srcRegion, srcAxis.length);
+            ensureDimensionMatch("dstRegion", dstRegion, dstAxis.length);
+        }
+        /*
+         * Map source axis to destination axis.  If no axis is moved (for example if the user
+         * want to transform (NORTH,EAST) to (SOUTH,EAST)), then source and destination index
+         * will be equal.   If some axis are moved (for example if the user want to transform
+         * (NORTH,EAST) to (EAST,NORTH)),  then ordinates at index {@code srcIndex} will
+         * have to be moved at index {@code dstIndex}.
+         */
+        setZero();
+        for (int dstIndex=0; dstIndex<dstAxis.length; dstIndex++) {
+            boolean hasFound = false;
+            final AxisDirection dstAxe = dstAxis[dstIndex];
+            final AxisDirection search = dstAxe.absolute();
+            for (int srcIndex=0; srcIndex<srcAxis.length; srcIndex++) {
+                final AxisDirection srcAxe = srcAxis[srcIndex];
+                if (search.equals(srcAxe.absolute())) {
+                    if (hasFound) {
+                        // TODO: Use the localized version of 'getName' in GeoAPI 2.1
+                        throw new IllegalArgumentException(Errors.format(ErrorKeys.COLINEAR_AXIS_$2,
+                                                           srcAxe.name(), dstAxe.name()));
+                    }
+                    hasFound = true;
+                    /*
+                     * Set the matrix elements. Some matrix elements will never
+                     * be set. They will be left to zero, which is their wanted
+                     * value.
+                     */
+                    final boolean normal = srcAxe.equals(dstAxe);
+                    double scale = (normal) ? +1 : -1;
+                    double translate = 0;
+                    if (validRegions) {
+                        translate  = (normal) ? dstRegion.getMinimum(dstIndex)
+                                              : dstRegion.getMaximum(dstIndex);
+                        scale     *= dstRegion.getLength(dstIndex) /
+                                     srcRegion.getLength(srcIndex);
+                        translate -= srcRegion.getMinimum(srcIndex) * scale;
+                    }
+                    setElement(dstIndex, srcIndex,       scale);
+                    setElement(dstIndex, srcAxis.length, translate);
+                }
+            }
+            if (!hasFound) {
+                // TODO: Use the localized version of 'getName' in GeoAPI 2.1
+                throw new IllegalArgumentException(Errors.format(
+                            ErrorKeys.NO_SOURCE_AXIS_$1, dstAxis[dstIndex].name()));
+            }
+        }
+        setElement(dstAxis.length, srcAxis.length, 1);
+        assert (srcAxis.length != dstAxis.length) || isAffine() : this;
+    }
+
+    /**
+     * Convenience method for checking object dimension validity.
+     * This method is usually invoked for argument checking.
+     *
+     * @param  name      The name of the argument to check.
+     * @param  envelope  The envelope to check.
+     * @param  dimension The expected dimension for the object.
+     * @throws MismatchedDimensionException if the envelope doesn't have the expected dimension.
+     */
+    private static void ensureDimensionMatch(final String   name,
+					     final Envelope envelope,
+                                             final int      dimension)
+        throws MismatchedDimensionException
+    {
+        final int dim = envelope.getDimension();
+        if (dimension != dim) {
+            throw new MismatchedDimensionException(Errors.format(
+                        ErrorKeys.MISMATCHED_DIMENSION_$3, name, dim, dimension));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean isAffine() {
+        int dimension  = getNumRow();
+        if (dimension != getNumCol()) {
+            return false;
+        }
+        dimension--;
+        for (int i=0; i<=dimension; i++) {
+            if (getElement(dimension, i) != (i==dimension ? 1 : 0)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns {@code true} if this matrix is an identity matrix.
+     */
+    public final boolean isIdentity() {
+        final int numRow = getNumRow();
+        final int numCol = getNumCol();
+        if (numRow != numCol) {
+            return false;
+        }
+        for (int j=0; j<numRow; j++) {
+            for (int i=0; i<numCol; i++) {
+                if (getElement(j,i) != (i==j ? 1 : 0)) {
+                    return false;
+                }
+            }
+        }
+        assert isAffine() : this;
+        assert isIdentity(0) : this;
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 2.3.1
+     */
+    public final boolean isIdentity(double tolerance) {
+    	return isIdentity(this, tolerance);
+    }
+
+    /**
+     * Returns {@code true} if the matrix is an identity matrix using the provided tolerance.
+     */
+    static boolean isIdentity(final Matrix matrix, double tolerance) {
+    	tolerance = Math.abs(tolerance);
+        final int numRow = matrix.getNumRow();
+        final int numCol = matrix.getNumCol();
+        if (numRow != numCol) {
+            return false;
+        }
+        for (int j=0; j<numRow; j++) {
+            for (int i=0; i<numCol; i++) {
+                double e = matrix.getElement(j,i);
+                if (i == j) {
+                    e--;
+                }
+                if (!(Math.abs(e) <= tolerance)) {  // Uses '!' in order to catch NaN values.
+                    return false;
+                }
+            }
+        }
+        // Note: we can't assert matrix.isAffine().
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final void multiply(final Matrix matrix) {
+        final GMatrix m;
+        if (matrix instanceof GMatrix) {
+            m = (GMatrix) matrix;
+        } else {
+            m = new GeneralMatrix(matrix);
+        }
+        mul(m);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(final Matrix matrix, final double tolerance) {
+        return epsilonEquals(this, matrix, tolerance);
+    }
+
+    /**
+     * Compares the element values.
+     */
+    static boolean epsilonEquals(final Matrix m1, final Matrix m2, final double tolerance) {
+        final int numRow = m1.getNumRow();
+        if (numRow != m2.getNumRow()) {
+            return false;
+        }
+        final int numCol = m1.getNumCol();
+        if (numCol != m2.getNumCol()) {
+            return false;
+        }
+        for (int j=0; j<numRow; j++) {
+            for (int i=0; i<numCol; i++) {
+                final double v1 = m1.getElement(j, i);
+                final double v2 = m2.getElement(j, i);
+                if (!(Math.abs(v1 - v2) <= tolerance)) {
+                    if (Double.doubleToLongBits(v1) == Double.doubleToLongBits(v2)) {
+                        // Special case for NaN and infinite values.
+                        continue;
+                    }
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns an affine transform for this matrix.
+     * This is a convenience method for interoperability with Java2D.
+     *
+     * @return The affine transform for this matrix.
+     * @throws IllegalStateException if this matrix is not 3&times;3,
+     *         or if the last row is not {@code [0 0 1]}.
+     */
+    public final AffineTransform toAffineTransform2D() throws IllegalStateException {
+        int check;
+        if ((check=getNumRow())!=3 || (check=getNumCol())!=3) {
+            throw new IllegalStateException(Errors.format(
+                        ErrorKeys.NOT_TWO_DIMENSIONAL_$1, check-1));
+        }
+        if (isAffine()) {
+            return new AffineTransform(getElement(0,0), getElement(1,0),
+            getElement(0,1), getElement(1,1),
+            getElement(0,2), getElement(1,2));
+        }
+        throw new IllegalStateException(Errors.format(ErrorKeys.NOT_AN_AFFINE_TRANSFORM));
+    }
+
+    /**
+     * Returns a string representation of this matrix. The returned string is implementation
+     * dependent. It is usually provided for debugging purposes only.
+     */
+    @Override
+    public String toString() {
+        return toString(this);
+    }
+
+    /**
+     * Returns a string representation of the specified matrix. The returned string is
+     * implementation dependent. It is usually provided for debugging purposes only.
+     */
+    static String toString(final Matrix matrix) {
+        final int    numRow = matrix.getNumRow();
+        final int    numCol = matrix.getNumCol();
+        StringBuffer buffer = new StringBuffer();
+        final int      columnWidth = 12;
+        final String lineSeparator = System.getProperty("line.separator", "\n");
+        final FieldPosition  dummy = new FieldPosition(0);
+        final NumberFormat  format = NumberFormat.getNumberInstance();
+        format.setGroupingUsed(false);
+        format.setMinimumFractionDigits(6);
+        format.setMaximumFractionDigits(6);
+        for (int j=0; j<numRow; j++) {
+            for (int i=0; i<numCol; i++) {
+                final int position = buffer.length();
+                buffer = format.format(matrix.getElement(j,i), buffer, dummy);
+                final int spaces = Math.max(columnWidth - (buffer.length() - position), 1);
+                buffer.insert(position, Utilities.spaces(spaces));
+            }
+            buffer.append(lineSeparator);
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Returns a clone of this matrix.
+     */
+    @Override
+    public GeneralMatrix clone() {
+        return (GeneralMatrix) super.clone();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/Matrix1.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/Matrix1.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/Matrix1.java	(revision 28000)
@@ -0,0 +1,213 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.matrix;
+
+import java.io.Serializable;
+import javax.vecmath.SingularMatrixException;
+import org.opengis.referencing.operation.Matrix;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * A matrix of fixed {@value #SIZE}&times;{@value #SIZE} size. This trivial matrix is returned as a
+ * result of {@linkplain org.opengis.referencing.operation.MathTransform1D} derivative computation.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/matrix/Matrix1.java $
+ * @version $Id: Matrix1.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class Matrix1 implements XMatrix, Serializable {
+    /** Serial number for interoperability with different versions. */
+    private static final long serialVersionUID = -4829171016106097031L;
+
+    /** The only element in this matrix. */
+    public double m00;
+
+    /** The matrix size, which is {@value}. */
+    public static final int SIZE = 1;
+
+    /**
+     * Creates a new identity matrix.
+     */
+    public Matrix1() {
+        m00 = 1;
+    }
+
+    /**
+     * Creates a new matrix initialized to the specified value.
+     */
+    public Matrix1(final double m00) {
+        this.m00 = m00;
+    }
+
+    /**
+     * Creates a new matrix initialized to the same value than the specified one.
+     * The specified matrix size must be {@value #SIZE}&times;{@value #SIZE}.
+     */
+    public Matrix1(final Matrix matrix) {
+        if (matrix.getNumRow()!=SIZE || matrix.getNumCol()!=SIZE) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_MATRIX_SIZE));
+        }
+        m00 = matrix.getElement(0,0);
+    }
+
+    /**
+     * Returns the number of rows in this matrix, which is always {@value #SIZE}
+     * in this implementation.
+     */
+    public final int getNumRow() {
+        return SIZE;
+    }
+
+    /**
+     * Returns the number of colmuns in this matrix, which is always {@value #SIZE}
+     * in this implementation.
+     */
+    public final int getNumCol() {
+        return SIZE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final double getElement(final int row, final int col) {
+        if (row==0 && col==0) {
+            return m00;
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final void setElement(final int row, final int col, final double value) {
+        if (row==0 && col==0) {
+            m00 = value;
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final void setZero() {
+        m00 = 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final void setIdentity() {
+        m00 = 1;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean isIdentity() {
+        return m00 == 1;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean isIdentity(double tolerance) {
+    	return Math.abs(m00 - 1) <= Math.abs(tolerance);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean isAffine() {
+        return m00==1;
+    }
+
+    /**
+     * Inverts this matrix in place.
+     */
+    public final void invert() {
+        if (m00 == 0) {
+            throw new SingularMatrixException();
+        }
+        m00 = 1/m00;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final void multiply(final Matrix matrix) {
+        if (matrix.getNumRow()!=SIZE || matrix.getNumCol()!=SIZE) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_MATRIX_SIZE));
+        }
+        m00 *= matrix.getElement(0,0);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(final Matrix matrix, final double tolerance) {
+        return GeneralMatrix.epsilonEquals(this, matrix, tolerance);
+    }
+
+    /**
+     * Returns {@code true} if the specified object is of type {@code Matrix1} and
+     * all of the data members are equal to the corresponding data members in this matrix.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object!=null && object.getClass().equals(getClass())) {
+            final Matrix1 that = (Matrix1) object;
+            return Double.doubleToLongBits(this.m00) == Double.doubleToLongBits(that.m00);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value based on the data values in this object.
+     */
+    @Override
+    public int hashCode() {
+        return (int)(Double.doubleToLongBits(m00) ^ serialVersionUID);
+    }
+
+    /**
+     * Returns a string representation of this matrix. The returned string is implementation
+     * dependent. It is usually provided for debugging purposes only.
+     */
+    @Override
+    public String toString() {
+        return GeneralMatrix.toString(this);
+    }
+
+    /**
+     * Returns a clone of this matrix.
+     */
+    @Override
+    public Matrix1 clone() {
+        try {
+            return (Matrix1) super.clone();
+        } catch (CloneNotSupportedException e) {
+            // Should not happen, since we are cloneable.
+            throw new AssertionError(e);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/Matrix2.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/Matrix2.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/Matrix2.java	(revision 28000)
@@ -0,0 +1,276 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.matrix;
+
+import java.io.Serializable;
+import javax.vecmath.SingularMatrixException;
+import org.opengis.referencing.operation.Matrix;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * A matrix of fixed {@value #SIZE}&times;{@value #SIZE} size.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/matrix/Matrix2.java $
+ * @version $Id: Matrix2.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class Matrix2 implements XMatrix, Serializable {
+    /** Serial number for interoperability with different versions. */
+    private static final long serialVersionUID = 7116561372481474290L;
+
+    /** The matrix size, which is {@value}. */
+    public static final int SIZE = 2;
+
+    /** The first matrix element in the first row. */
+    public double m00;
+
+    /** The second matrix element in the first row. */
+    public double m01;
+
+    /** The first matrix element in the second row. */
+    public double m10;
+
+    /** The second matrix element in the second row. */
+    public double m11;
+
+    /**
+     * Creates a new identity matrix.
+     */
+    public Matrix2() {
+        m00 = m11 = 1;
+    }
+
+    /**
+     * Creates a new matrix initialized to the specified values.
+     */
+    public Matrix2(final double m00, final double m01,
+                   final double m10, final double m11)
+    {
+        this.m00 = m00;
+        this.m01 = m01;
+        this.m10 = m10;
+        this.m11 = m11;
+    }
+
+    /**
+     * Creates a new matrix initialized to the same value than the specified one.
+     * The specified matrix size must be {@value #SIZE}&times;{@value #SIZE}.
+     */
+    public Matrix2(final Matrix matrix) {
+        if (matrix.getNumRow()!=SIZE || matrix.getNumCol()!=SIZE) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_MATRIX_SIZE));
+        }
+        m00 = matrix.getElement(0,0);
+        m01 = matrix.getElement(0,1);
+        m10 = matrix.getElement(1,0);
+        m11 = matrix.getElement(1,1);
+    }
+
+    /**
+     * Returns the number of rows in this matrix, which is always {@value #SIZE}
+     * in this implementation.
+     */
+    public final int getNumRow() {
+        return SIZE;
+    }
+
+    /**
+     * Returns the number of colmuns in this matrix, which is always {@value #SIZE}
+     * in this implementation.
+     */
+    public final int getNumCol() {
+        return SIZE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final double getElement(final int row, final int col) {
+        switch (row) {
+            case 0: {
+                switch (col) {
+                    case 0: return m00;
+                    case 1: return m01;
+                }
+                break;
+            }
+            case 1: {
+                switch (col) {
+                    case 0: return m10;
+                    case 1: return m11;
+                }
+                break;
+            }
+        }
+        throw new IndexOutOfBoundsException();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final void setElement(final int row, final int col, final double value) {
+        switch (row) {
+            case 0: {
+                switch (col) {
+                    case 0: m00 = value; return;
+                    case 1: m01 = value; return;
+                }
+                break;
+            }
+            case 1: {
+                switch (col) {
+                    case 0: m10 = value; return;
+                    case 1: m11 = value; return;
+                }
+                break;
+            }
+        }
+        throw new IndexOutOfBoundsException();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final void setZero() {
+        m00 = m01 = m10 = m11 = 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final void setIdentity() {
+        m01 = m10 = 0;
+        m00 = m11 = 1;
+        assert isIdentity();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean isIdentity() {
+        return m01==0 && m10==0 && m00==1 && m11==1;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean isIdentity(double tolerance) {
+    	return GeneralMatrix.isIdentity(this, tolerance);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean isAffine() {
+        return m10==0 && m11==1;
+    }
+
+    /**
+     * Inverts this matrix in place.
+     */
+    public final void invert() {
+        final double det = m00*m11 - m01*m10;
+        if (det == 0) {
+            throw new SingularMatrixException();
+        }
+        final double swap = m00;
+        m00 =  m11 / det;
+        m11 = swap / det;
+        m10 = -m10 / det;
+        m01 = -m01 / det;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final void multiply(final Matrix matrix) {
+        final Matrix2 k;
+        if (matrix instanceof Matrix2) {
+            k = (Matrix2) matrix;
+        } else {
+            k = new Matrix2(matrix);
+        }
+        double m0, m1;
+        m0=m00; m1=m01;
+        m00 = m0*k.m00 + m1*k.m10;
+        m01 = m0*k.m01 + m1*k.m11;
+        m0=m10; m1=m11;
+        m10 = m0*k.m00 + m1*k.m10;
+        m11 = m0*k.m01 + m1*k.m11;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(final Matrix matrix, final double tolerance) {
+        return GeneralMatrix.epsilonEquals(this, matrix, tolerance);
+    }
+
+    /**
+     * Returns {@code true} if the specified object is of type {@code Matrix2} and
+     * all of the data members are equal to the corresponding data members in this matrix.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object!=null && object.getClass().equals(getClass())) {
+            final Matrix2 that = (Matrix2) object;
+            return Double.doubleToLongBits(this.m00) == Double.doubleToLongBits(that.m00) &&
+                   Double.doubleToLongBits(this.m01) == Double.doubleToLongBits(that.m01) &&
+                   Double.doubleToLongBits(this.m10) == Double.doubleToLongBits(that.m10) &&
+                   Double.doubleToLongBits(this.m11) == Double.doubleToLongBits(that.m11);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value based on the data values in this object.
+     */
+    @Override
+    public int hashCode() {
+        return (int)((((Double.doubleToLongBits(m00)  +
+                     37*Double.doubleToLongBits(m01)) +
+                     37*Double.doubleToLongBits(m10)) +
+                     37*Double.doubleToLongBits(m11)) ^
+                        serialVersionUID);
+    }
+
+    /**
+     * Returns a string representation of this matrix. The returned string is implementation
+     * dependent. It is usually provided for debugging purposes only.
+     */
+    @Override
+    public String toString() {
+        return GeneralMatrix.toString(this);
+    }
+
+    /**
+     * Returns a clone of this matrix.
+     */
+    @Override
+    public Matrix2 clone() {
+        try {
+            return (Matrix2) super.clone();
+        } catch (CloneNotSupportedException e) {
+            // Should not happen, since we are cloneable.
+            throw new AssertionError(e);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/Matrix3.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/Matrix3.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/Matrix3.java	(revision 28000)
@@ -0,0 +1,167 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.matrix;
+
+import javax.vecmath.Matrix3d;
+import java.awt.geom.AffineTransform;
+import org.opengis.referencing.operation.Matrix;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * A matrix of fixed {@value #SIZE}&times;{@value #SIZE} size. This specialized matrix provides
+ * better accuracy than {@link GeneralMatrix} for matrix inversion and multiplication.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/matrix/Matrix3.java $
+ * @version $Id: Matrix3.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class Matrix3 extends Matrix3d implements XMatrix {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 8902061778871586611L;
+
+    /**
+     * The matrix size, which is {@value}.
+     */
+    public static final int SIZE = 3;
+
+    /**
+     * Creates a new identity matrix.
+     */
+    public Matrix3() {
+        setIdentity();
+    }
+
+    /**
+     * Constructs a 3&times;3 matrix from the specified affine transform.
+     */
+    public Matrix3(final AffineTransform transform) {
+        setMatrix(transform);
+    }
+
+    /**
+     * Creates a new matrix initialized to the same value than the specified one.
+     * The specified matrix size must be {@value #SIZE}&times;{@value #SIZE}.
+     */
+    public Matrix3(final Matrix matrix) {
+        if (matrix.getNumRow()!=SIZE || matrix.getNumCol()!=SIZE) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_MATRIX_SIZE));
+        }
+        for (int j=0; j<SIZE; j++) {
+            for (int i=0; i<SIZE; i++) {
+                setElement(j,i, matrix.getElement(j,i));
+            }
+        }
+    }
+
+    /**
+     * Returns the number of rows in this matrix, which is always {@value #SIZE}
+     * in this implementation.
+     */
+    public final int getNumRow() {
+        return SIZE;
+    }
+
+    /**
+     * Returns the number of colmuns in this matrix, which is always {@value #SIZE}
+     * in this implementation.
+     */
+    public final int getNumCol() {
+        return SIZE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean isIdentity() {
+        for (int j=0; j<SIZE; j++) {
+            for (int i=0; i<SIZE; i++) {
+                if (getElement(j,i) != ((i==j) ? 1 : 0)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean isIdentity(double tolerance) {
+    	return GeneralMatrix.isIdentity(this, tolerance);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean isAffine() {
+        return m20==0 && m21==0 && m22==1;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final void multiply(final Matrix matrix) {
+        final Matrix3d m;
+        if (matrix instanceof Matrix3d) {
+            m = (Matrix3d) matrix;
+        } else {
+            m = new Matrix3(matrix);
+        }
+        mul(m);
+    }
+
+    /**
+     * Sets this matrix to the specified affine transform.
+     *
+     * @since 2.3
+     */
+    public void setMatrix(final AffineTransform transform) {
+        m00=transform.getScaleX(); m01=transform.getShearX(); m02=transform.getTranslateX();
+        m10=transform.getShearY(); m11=transform.getScaleY(); m12=transform.getTranslateY();
+        m20=0;                     m21=0;                     m22=1;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(final Matrix matrix, final double tolerance) {
+        return GeneralMatrix.epsilonEquals(this, matrix, tolerance);
+    }
+
+    /**
+     * Returns a string representation of this matrix. The returned string is implementation
+     * dependent. It is usually provided for debugging purposes only.
+     */
+    @Override
+    public String toString() {
+        return GeneralMatrix.toString(this);
+    }
+
+    /**
+     * Returns a clone of this matrix.
+     */
+    @Override
+    public Matrix3 clone() {
+        return (Matrix3) super.clone();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/Matrix4.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/Matrix4.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/Matrix4.java	(revision 28000)
@@ -0,0 +1,163 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.matrix;
+
+import javax.vecmath.Matrix4d;
+import org.opengis.referencing.operation.Matrix;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * A matrix of fixed {@value #SIZE}&times;{@value #SIZE} size. This specialized matrix provides
+ * better accuracy than {@link GeneralMatrix} for matrix inversion and multiplication. It is used
+ * primarily for supporting datum shifts.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/matrix/Matrix4.java $
+ * @version $Id: Matrix4.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class Matrix4 extends Matrix4d implements XMatrix {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 5685762518066856310L;
+
+    /**
+     * The matrix size, which is {@value}.
+     */
+    public static final int SIZE = 4;
+
+    /**
+     * Creates a new identity matrix.
+     */
+    public Matrix4() {
+        setIdentity();
+    }
+
+    /**
+     * Creates a new matrix initialized to the specified values.
+     */
+    public Matrix4(double m00, double m01, double m02, double m03,
+                   double m10, double m11, double m12, double m13,
+                   double m20, double m21, double m22, double m23,
+                   double m30, double m31, double m32, double m33)
+    {
+        super(m00, m01, m02, m03,
+              m10, m11, m12, m13,
+              m20, m21, m22, m23,
+              m30, m31, m32, m33);
+    }
+
+    /**
+     * Creates a new matrix initialized to the same value than the specified one.
+     * The specified matrix size must be {@value #SIZE}&times;{@value #SIZE}.
+     */
+    public Matrix4(final Matrix matrix) {
+        if (matrix.getNumRow()!=SIZE || matrix.getNumCol()!=SIZE) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_MATRIX_SIZE));
+        }
+        for (int j=0; j<SIZE; j++) {
+            for (int i=0; i<SIZE; i++) {
+                setElement(j,i, matrix.getElement(j,i));
+            }
+        }
+    }
+
+    /**
+     * Returns the number of rows in this matrix, which is always {@value #SIZE}
+     * in this implementation.
+     */
+    public final int getNumRow() {
+        return SIZE;
+    }
+
+    /**
+     * Returns the number of colmuns in this matrix, which is always {@value #SIZE}
+     * in this implementation.
+     */
+    public final int getNumCol() {
+        return SIZE;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean isIdentity() {
+        for (int j=0; j<SIZE; j++) {
+            for (int i=0; i<SIZE; i++) {
+                if (getElement(j,i) != ((i==j) ? 1 : 0)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean isIdentity(double tolerance) {
+    	return GeneralMatrix.isIdentity(this, tolerance);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean isAffine() {
+        return m30==0 && m31==0 && m32==0 && m33==1;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final void multiply(final Matrix matrix) {
+        final Matrix4d m;
+        if (matrix instanceof Matrix4d) {
+            m = (Matrix4d) matrix;
+        } else {
+            m = new Matrix4(matrix);
+        }
+        mul(m);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(final Matrix matrix, final double tolerance) {
+        return GeneralMatrix.epsilonEquals(this, matrix, tolerance);
+    }
+
+    /**
+     * Returns a string representation of this matrix. The returned string is implementation
+     * dependent. It is usually provided for debugging purposes only.
+     */
+    @Override
+    public String toString() {
+        return GeneralMatrix.toString(this);
+    }
+
+    /**
+     * Returns a clone of this matrix.
+     */
+    @Override
+    public Matrix4 clone() {
+        return (Matrix4) super.clone();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/MatrixFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/MatrixFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/MatrixFactory.java	(revision 28000)
@@ -0,0 +1,92 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.matrix;
+
+import org.opengis.referencing.operation.Matrix;
+
+
+/**
+ * Static utility methods for creating matrix. This factory selects one of the {@link Matrix1},
+ * {@link Matrix2}, {@link Matrix3}, {@link Matrix4} or {@link GeneralMatrix} implementation
+ * according the desired matrix size. Note that if the matrix size is know at compile time,
+ * it may be more efficient to invoke directly the constructor of the appropriate class instead.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/matrix/MatrixFactory.java $
+ * @version $Id: MatrixFactory.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public final class MatrixFactory {
+    /**
+     * Do not allows instantiation of this class.
+     */
+    private MatrixFactory() {
+    }
+
+    /**
+     * Creates a square identity matrix of size {@code size}&nbsp;&times;&nbsp;{@code size}.
+     *
+     * @param size For an affine transform, this is the number of source and target dimensions + 1.
+     * @return An identity matrix of the given size.
+     */
+    public static XMatrix create(final int size) {
+        switch (size) {
+            case 1:  return new Matrix1();
+            case 2:  return new Matrix2();
+            case 3:  return new Matrix3();
+            case 4:  return new Matrix4();
+            default: return new GeneralMatrix(size);
+        }
+    }
+
+    /**
+     * Creates a matrix of size {@code numRow}&nbsp;&times;&nbsp;{@code numCol}.
+     * Elements on the diagonal <var>j==i</var> are set to 1.
+     *
+     * @param numRow For an affine transform, this is the number of
+     *        {@linkplain org.opengis.referencing.operation.MathTransform#getTargetDimensions
+     *        target dimensions} + 1.
+     * @param numCol For an affine transform, this is the number of
+     *        {@linkplain org.opengis.referencing.operation.MathTransform#getSourceDimensions
+     *        source dimensions} + 1.
+     * @return An identity matrix of the given size.
+     */
+    public static XMatrix create(final int numRow, final int numCol) {
+        if (numRow == numCol) {
+            return create(numRow);
+        } else {
+            return new GeneralMatrix(numRow, numCol);
+        }
+    }
+
+    /**
+     * Creates a new matrix which is a copy of the specified matrix.
+     */
+    public static XMatrix create(final Matrix matrix) {
+        final int size = matrix.getNumRow();
+        if (size == matrix.getNumCol()) {
+            switch (size) {
+                case 1:  return new Matrix1(matrix);
+                case 2:  return new Matrix2(matrix);
+                case 3:  return new Matrix3(matrix);
+                case 4:  return new Matrix4(matrix);
+            }
+        }
+        return new GeneralMatrix(matrix);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/XAffineTransform.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/XAffineTransform.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/XAffineTransform.java	(revision 28000)
@@ -0,0 +1,385 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.matrix;
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RectangularShape;
+
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+
+
+/**
+ * Utility methods for affine transforms. This class provides two kind of services:
+ *
+ * <ul>
+ *   <li><p>A set of public static methods working on any {@link AffineTransform}.</p></li>
+ *   <li><p>An abstract base class that override all mutable {@link AffineTransform} methods
+ *       in order to check for permission before changing the transform's state.
+ *       If {@link #checkPermission} is defined to always throw an exception,
+ *       then {@code XAffineTransform} is immutable.</p></li>
+ * </ul>
+ *
+ * @since 2.3
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/matrix/XAffineTransform.java $
+ * @version $Id: XAffineTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Simone Giannecchini
+ */
+public class XAffineTransform extends AffineTransform {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 5215291166450556451L;
+
+    /**
+     * Constructs a new {@code XAffineTransform} that is a
+     * copy of the specified {@code AffineTransform} object.
+     */
+    public XAffineTransform(final AffineTransform tr) {
+        super(tr);
+    }
+
+    /**
+     * Checks if the caller is allowed to change this {@code XAffineTransform} state.
+     * If this method is defined to thrown an exception in all case, then this
+     * {@code XAffineTransform} is immutable.
+     * <p>
+     * The default implementation throws the exception in all case, thus making this
+     * instance immutable.
+     *
+     * @throws UnsupportedOperationException if this affine transform is immutable.
+     */
+    protected void checkPermission() throws UnsupportedOperationException {
+        throw new UnsupportedOperationException(
+                  Errors.format(ErrorKeys.UNMODIFIABLE_AFFINE_TRANSFORM));
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before translating this transform.
+     */
+    @Override
+    public void translate(double tx, double ty) {
+        checkPermission();
+        super.translate(tx, ty);
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before rotating this transform.
+     */
+    @Override
+    public void rotate(double theta) {
+        checkPermission();
+        super.rotate(theta);
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before rotating this transform.
+     */
+    @Override
+    public void rotate(double theta, double x, double y) {
+        checkPermission();
+        super.rotate(theta, x, y);
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before scaling this transform.
+     */
+    @Override
+    public void scale(double sx, double sy) {
+        checkPermission();
+        super.scale(sx, sy);
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before shearing this transform.
+     */
+    @Override
+    public void shear(double shx, double shy) {
+        checkPermission();
+        super.shear(shx, shy);
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before setting this transform.
+     */
+    @Override
+    public void setToIdentity() {
+        checkPermission();
+        super.setToIdentity();
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before setting this transform.
+     */
+    @Override
+    public void setToTranslation(double tx, double ty) {
+        checkPermission();
+        super.setToTranslation(tx, ty);
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before setting this transform.
+     */
+    @Override
+    public void setToRotation(double theta) {
+        checkPermission();
+        super.setToRotation(theta);
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before setting this transform.
+     */
+    @Override
+    public void setToRotation(double theta, double x, double y) {
+        checkPermission();
+        super.setToRotation(theta, x, y);
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before setting this transform.
+     */
+    @Override
+    public void setToScale(double sx, double sy) {
+        checkPermission();
+        super.setToScale(sx, sy);
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before setting this transform.
+     */
+    @Override
+    public void setToShear(double shx, double shy) {
+        checkPermission();
+        super.setToShear(shx, shy);
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before setting this transform.
+     */
+    @Override
+    public void setTransform(AffineTransform Tx) {
+        checkPermission();
+        super.setTransform(Tx);
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before setting this transform.
+     */
+    @Override
+    public void setTransform(double m00, double m10,
+                             double m01, double m11,
+                             double m02, double m12) {
+        checkPermission();
+        super.setTransform(m00, m10, m01, m11, m02, m12);
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before concatenating this transform.
+     */
+    @Override
+    public void concatenate(AffineTransform Tx) {
+        checkPermission();
+        super.concatenate(Tx);
+    }
+
+    /**
+     * Checks for {@linkplain #checkPermission permission} before concatenating this transform.
+     */
+    @Override
+    public void preConcatenate(AffineTransform Tx) {
+        checkPermission();
+        super.preConcatenate(Tx);
+    }
+
+    /**
+     * Checks whether or not this {@code XAffineTransform} is the identity by
+     * using the provided {@code tolerance}.
+     *
+     * @param tolerance The tolerance to use for this check.
+     * @return {@code true} if the transform is identity, {@code false} otherwise.
+     *
+     * @since 2.3.1
+     */
+    public boolean isIdentity(double tolerance) { // NO_UCD
+    	return isIdentity(this, tolerance);
+    }
+
+    /**
+     * Returns {@code true} if the specified affine transform is an identity transform up to the
+     * specified tolerance. This method is equivalent to computing the difference between this
+     * matrix and an identity matrix (as created by {@link AffineTransform#AffineTransform()
+     * new AffineTransform()}) and returning {@code true} if and only if all differences are
+     * smaller than or equal to {@code tolerance}.
+     * <p>
+     * This method is used for working around rounding error in affine transforms resulting
+     * from a computation, as in the example below:
+     *
+     * <blockquote><pre>
+     * [ 1.0000000000000000001  0.0                      0.0 ]
+     * [ 0.0                    0.999999999999999999999  0.0 ]
+     * [ 0.0                    0.0                      1.0 ]
+     * </pre></blockquote>
+     *
+     * @param tr The affine transform to be checked for identity.
+     * @param tolerance The tolerance value to use when checking for identity.
+     * return {@code true} if this tranformation is close enough to the
+     *        identity, {@code false} otherwise.
+     *
+     * @since 2.3.1
+     */
+    public static boolean isIdentity(final AffineTransform tr, double tolerance) {
+        if (tr.isIdentity()) {
+            return true;
+        }
+        tolerance = Math.abs(tolerance);
+        return Math.abs(tr.getScaleX() - 1) <= tolerance &&
+               Math.abs(tr.getScaleY() - 1) <= tolerance &&
+               Math.abs(tr.getShearX())     <= tolerance &&
+               Math.abs(tr.getShearY())     <= tolerance &&
+               Math.abs(tr.getTranslateX()) <= tolerance &&
+               Math.abs(tr.getTranslateY()) <= tolerance;
+    }
+
+    /**
+     * Transforms the given shape. This method is similar to
+     * {@link #createTransformedShape createTransformedShape} except that:
+     * <p>
+     * <ul>
+     *   <li>It tries to preserve the shape kind when possible. For example if the given shape
+     *       is an instance of {@link RectangularShape} and the given transform do not involve
+     *       rotation, then the returned shape may be some instance of the same class.</li>
+     *   <li>It tries to recycle the given object if {@code overwrite} is {@code true}.</li>
+     * </ul>
+     *
+     * @param transform Affine transform to use.
+     * @param shape     The shape to transform.
+     * @param overwrite If {@code true}, this method is allowed to overwrite {@code shape} with the
+     *                  transform result. If {@code false}, then {@code shape} is never modified.
+     *
+     * @return The direct transform of the given shape. May or may not be the same instance than
+     *         the given shape.
+     *
+     * @see #createTransformedShape
+     *
+     * @since 2.5
+     */
+    public static Shape transform(final AffineTransform transform, Shape shape, boolean overwrite) {
+        final int type = transform.getType();
+        if (type == TYPE_IDENTITY) {
+            return shape;
+        }
+        // If there is only scale, flip, quadrant rotation or translation,
+        // then we can optimize the transformation of rectangular shapes.
+        if ((type & (TYPE_GENERAL_ROTATION | TYPE_GENERAL_TRANSFORM)) == 0) {
+            // For a Rectangle input, the output should be a rectangle as well.
+            if (shape instanceof Rectangle2D) {
+                final Rectangle2D rect = (Rectangle2D) shape;
+                return transform(transform, rect, overwrite ? rect : null);
+            }
+            // For other rectangular shapes, we restrict to cases whithout
+            // rotation or flip because we don't know if the shape is symetric.
+            if ((type & (TYPE_FLIP & TYPE_MASK_ROTATION)) == 0) {
+                if (shape instanceof RectangularShape) {
+                    RectangularShape rect = (RectangularShape) shape;
+                    if (!overwrite) {
+                        rect = (RectangularShape) rect.clone();
+                    }
+                    final Rectangle2D frame = rect.getFrame();
+                    rect.setFrame(transform(transform, frame, frame));
+                    return rect;
+                }
+            }
+        }
+        // TODO: Check for Path2D instance instead of GeneralPath
+        //       when we will be allowed to compile for Java 6.
+        if (shape instanceof GeneralPath) {
+            final GeneralPath path = (GeneralPath) shape;
+            if (overwrite) {
+                path.transform(transform);
+            } else {
+                shape = path.createTransformedShape(transform);
+            }
+        } else if (shape instanceof Area) {
+            final Area area = (Area) shape;
+            if (overwrite) {
+                area.transform(transform);
+            } else {
+                shape = area.createTransformedArea(transform);
+            }
+        } else {
+            final GeneralPath path = new GeneralPath(shape);
+            path.transform(transform);
+            shape = path;
+            // TODO: use the line below instead of the above 3 lines when we will
+            //       be allowed to compile for Java 6:
+//          shape = new Path2D.Double(shape, transform);
+        }
+        return shape;
+    }
+
+    /**
+     * Returns a rectangle which entirely contains the direct
+     * transform of {@code bounds}. This operation is equivalent to:
+     *
+     * <blockquote><code>
+     * {@linkplain #createTransformedShape createTransformedShape}(bounds).{@linkplain
+     * Rectangle2D#getBounds2D() getBounds2D()}
+     * </code></blockquote>
+     *
+     * @param transform Affine transform to use.
+     * @param bounds    Rectangle to transform. This rectangle will not be modified except
+     *                  if {@code dest} is the same reference.
+     * @param dest      Rectangle in which to place the result.
+     *                  If null, a new rectangle will be created.
+     *
+     * @return The direct transform of the {@code bounds} rectangle.
+     *
+     * @see org.geotools.referencing.CRS#transform(
+     *      org.opengis.referencing.operation.MathTransform2D, Rectangle2D, Rectangle2D)
+     */
+    public static Rectangle2D transform(final AffineTransform transform,
+                                        final Rectangle2D     bounds,
+                                        final Rectangle2D     dest)
+    {
+        double xmin = Double.POSITIVE_INFINITY;
+        double ymin = Double.POSITIVE_INFINITY;
+        double xmax = Double.NEGATIVE_INFINITY;
+        double ymax = Double.NEGATIVE_INFINITY;
+        final Point2D.Double point = new Point2D.Double();
+        for (int i=0; i<4; i++) {
+            point.x = (i & 1) == 0 ? bounds.getMinX() : bounds.getMaxX();
+            point.y = (i & 2) == 0 ? bounds.getMinY() : bounds.getMaxY();
+            transform.transform(point, point);
+            if (point.x < xmin) xmin = point.x;
+            if (point.x > xmax) xmax = point.x;
+            if (point.y < ymin) ymin = point.y;
+            if (point.y > ymax) ymax = point.y;
+        }
+        if (dest != null) {
+            dest.setRect(xmin, ymin, xmax-xmin, ymax-ymin);
+            return dest;
+        }
+        return new Rectangle2D.Double(xmin, ymin, xmax-xmin, ymax-ymin);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/XMatrix.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/XMatrix.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/XMatrix.java	(revision 28000)
@@ -0,0 +1,130 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.matrix;
+
+import javax.vecmath.SingularMatrixException;
+import org.opengis.referencing.operation.Matrix;
+
+
+/**
+ * A matrix capables to perform some matrix operations. The basic {@link Matrix} interface
+ * is basically just a two dimensional array of numbers. The {@code XMatrix} interface add
+ * {@linkplain #invert inversion} and {@linkplain #multiply multiplication} capabilities.
+ * It is used as a bridge across various matrix implementations in Java3D
+ * ({@link javax.vecmath.Matrix3f}, {@link javax.vecmath.Matrix3d}, {@link javax.vecmath.Matrix4f},
+ * {@link javax.vecmath.Matrix4d}, {@link javax.vecmath.GMatrix}).
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/matrix/XMatrix.java $
+ * @version $Id: XMatrix.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Simone Giannecchini
+ */
+public interface XMatrix extends Matrix {
+    /**
+     * Returns the number of rows in this matrix.
+     */
+    int getNumRow();
+
+    /**
+     * Returns the number of colmuns in this matrix.
+     */
+    int getNumCol();
+
+    /**
+     * Returns the element at the specified index.
+     */
+    double getElement(int row, int column);
+
+    /**
+     * Set the element at the specified index.
+     */
+    void setElement(int row, int column, double value);
+
+    /**
+     * Sets all the values in this matrix to zero.
+     */
+    void setZero();
+
+    /**
+     * Sets this matrix to the identity matrix.
+     */
+    void setIdentity();
+
+    /**
+     * Returns {@code true} if this matrix is an identity matrix.
+     */
+    boolean isIdentity();
+
+    /**
+     * Returns {@code true} if this matrix is an identity matrix using the provided tolerance.
+     * This method is equivalent to computing the difference between this matrix and an identity
+     * matrix of identical size, and returning {@code true} if and only if all differences are
+     * smaller than or equal to {@code tolerance}.
+     *
+     * @param tolerance The tolerance value.
+     * @return {@code true} if this matrix is close enough to the identity matrix
+     *         given the tolerance value.
+     *
+     * @since 2.4
+     */
+    boolean isIdentity(double tolerance);
+
+    /**
+     * Returns {@code true} if this matrix is an affine transform.
+     * A transform is affine if the matrix is square and last row contains
+     * only zeros, except in the last column which contains 1.
+     *
+     * @return {@code true} if this matrix is affine.
+     */
+    boolean isAffine();
+
+    /**
+     * Inverts this matrix in place.
+     *
+     * @throws SingularMatrixException if this matrix is not invertible.
+     */
+    void invert() throws SingularMatrixException;
+
+    /**
+     * Sets the value of this matrix to the result of multiplying itself with the specified matrix.
+     * In other words, performs {@code this} = {@code this} &times; {@code matrix}. In the context
+     * of coordinate transformations, this is equivalent to
+     * <code>{@linkplain java.awt.geom.AffineTransform#concatenate AffineTransform.concatenate}</code>:
+     * first transforms by the supplied transform and then transform the result by the original
+     * transform.
+     *
+     * @param matrix The matrix to multiply to this matrix.
+     */
+    void multiply(Matrix matrix);
+
+    /**
+     * Compares the element values regardless the object class. This is similar to a call to
+     * <code>{@linkplain javax.vecmath.GMatrix#epsilonEquals GMatrix.epsilonEquals}(matrix,
+     * tolerance)</code>. The method name is intentionally different in order to avoid
+     * ambiguities at compile-time.
+     *
+     * @param matrix    The matrix to compare.
+     * @param tolerance The tolerance value.
+     * @return {@code true} if this matrix is close enough to the given matrix
+     *         given the tolerance value.
+     *
+     * @since 2.5
+     */
+    boolean equals(Matrix matrix, double tolerance);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/matrix/package.html	(revision 28000)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.referencing.operation.matrix</TITLE>
+  </HEAD>
+  <BODY>
+  Matrix implementations on top of the {@link javax.vecmath} package.
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/LambertConformal.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/LambertConformal.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/LambertConformal.java	(revision 28000)
@@ -0,0 +1,316 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 1999-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains formulas from the PROJ package of USGS.
+ *    USGS's work is fully acknowledged here. This derived work has
+ *    been relicensed under LGPL with Frank Warmerdam's permission.
+ */
+package org.geotools.referencing.operation.projection;
+
+import java.awt.geom.Point2D;
+import java.util.Collection;
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.geotools.measure.Latitude;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+import static java.lang.Math.*;
+
+
+/**
+ * Lambert Conical Conformal Projection.  Areas and shapes are deformed as one moves away from
+ * standard parallels.  The angles are true in a limited area.  This projection is used for the
+ * charts of North America.
+ * <p>
+ * This implementation provides transforms for three cases of the lambert conic
+ * conformal projection:
+ * <p>
+ * <ul>
+ *   <li>{@code Lambert_Conformal_Conic_1SP} (EPSG code 9801)</li>
+ *   <li>{@code Lambert_Conformal_Conic_2SP} (EPSG code 9802)</li>
+ *   <li>{@code Lambert_Conic_Conformal_2SP_Belgium} (EPSG code 9803)</li>
+ *   <li>{@code Lambert_Conformal_Conic} - An alias for the ESRI 2SP case
+ *       that includes a scale_factor parameter</li>
+ * </ul>
+ * <p>
+ * For the 1SP case the latitude of origin is used as the standard parallel (SP). To use 1SP with
+ * a latitude of origin different from the SP, use the 2SP and set the SP1 to the single SP. The
+ * {@code standard_parallel_2"} parameter is optional and will be given the same value as
+ * {@code "standard_parallel_1"} if not set (creating a 1 standard parallel projection).
+ * <p>
+ * <b>References:</b>
+ * <ul>
+ *   <li>John P. Snyder (Map Projections - A Working Manual,<br>
+ *       U.S. Geological Survey Professional Paper 1395, 1987)</li>
+ *   <li>"Coordinate Conversions and Transformations including Formulas",<br>
+ *       EPSG Guidence Note Number 7, Version 19.</li>
+ * </ul>
+ *
+ * @see <A HREF="http://mathworld.wolfram.com/LambertConformalConicProjection.html">Lambert conformal conic projection on MathWorld</A>
+ * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_1sp.html">lambert_conic_conformal_1sp</A>
+ * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_2sp.html">lambert_conic_conformal_2sp</A>
+ * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_2sp_belgium.html">lambert_conic_conformal_2sp_belgium</A>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/LambertConformal.java $
+ * @version $Id: LambertConformal.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author André Gosselin
+ * @author Martin Desruisseaux (PMO, IRD)
+ * @author Rueben Schulz
+ */
+public abstract class LambertConformal extends MapProjection {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 1275881689637308614L;
+
+    /**
+     * Maximum difference allowed when comparing real numbers.
+     */
+    private static final double EPSILON = 1E-6;
+
+    /**
+     * Constant for the belgium 2SP case. This is 29.2985 seconds, given here in radians.
+     */
+    private static final double BELGE_A = 0.00014204313635987700;
+
+    /**
+     * Standards parallel 1 in radians, for {@link #getParameterValues} implementation.
+     */
+    private final double phi1;
+
+    /**
+     * Standards parallel 2 in radians, for {@link #getParameterValues} implementation.
+     */
+    final private double phi2;
+
+    /**
+     * Internal variables for computation.
+     */
+    private final double n, F, rho0;
+
+    /**
+     * {@code true} for Belgium 2SP.
+     */
+    private final boolean belgium;
+
+    /**
+     * Constructs a new map projection from the supplied parameters.
+     *
+     * @param  parameters The parameter values in standard units.
+     * @throws ParameterNotFoundException if a mandatory parameter is missing.
+     */
+    protected LambertConformal(final ParameterValueGroup parameters)
+            throws ParameterNotFoundException
+    {
+        this(parameters, false);
+    }
+
+    /**
+     * Constructs a new map projection from the supplied parameters.
+     *
+     * @param  parameters The parameter values in standard units.
+     * @param  belgium {@code true} for the Belgium 2SP case.
+     * @throws ParameterNotFoundException if a mandatory parameter is missing.
+     */
+    LambertConformal(final ParameterValueGroup parameters, final boolean belgium)
+            throws ParameterNotFoundException
+    {
+        // Fetch parameters
+        super(parameters);
+        final Collection<GeneralParameterDescriptor> expected = getParameterDescriptors().descriptors();
+        final boolean sp2 = expected.contains(AbstractProvider.STANDARD_PARALLEL_2);
+        this.belgium = belgium;
+        if (sp2) {
+            double phi2;
+            phi1 = doubleValue(expected, AbstractProvider.STANDARD_PARALLEL_1, parameters);
+            ensureLatitudeInRange(       AbstractProvider.STANDARD_PARALLEL_1, phi1, true);
+            phi2 = doubleValue(expected, AbstractProvider.STANDARD_PARALLEL_2, parameters);
+            if (Double.isNaN(phi2)) {
+                phi2 = phi1;
+            }
+            this.phi2 = phi2;
+            ensureLatitudeInRange(AbstractProvider.STANDARD_PARALLEL_2, phi2, true);
+        } else {
+            if (belgium) {
+                throw new IllegalArgumentException();
+            }
+            // EPSG says the 1SP case uses the latitude of origin as the SP
+            phi1 = phi2 = latitudeOfOrigin;
+        }
+        // Compute constants
+        if (abs(phi1 + phi2) < EPSILON) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.ANTIPODE_LATITUDES_$2,
+                                               new Latitude(toDegrees(phi1)),
+                                               new Latitude(toDegrees(phi2))));
+        }
+        final double  cosphi1 = cos(phi1);
+        final double  sinphi1 = sin(phi1);
+        final boolean  secant = abs(phi1-phi2) > EPSILON; // Should be 'true' for 2SP case.
+        if (isSpherical) {
+            if (secant) {
+                n = log(cosphi1 / cos(phi2)) /
+                    log(tan(PI/4 + 0.5*phi2) / tan(PI/4 + 0.5*phi1));
+            } else {
+                n = sinphi1;
+            }
+            F = cosphi1 * pow(tan(PI/4 + 0.5*phi1), n) / n;
+            if (abs(abs(latitudeOfOrigin) - PI/2) >= EPSILON) {
+                rho0 = F * pow(tan(PI/4 + 0.5*latitudeOfOrigin), -n);
+            } else {
+                rho0 = 0.0;
+            }
+        } else {
+            final double m1 = msfn(sinphi1, cosphi1);
+            final double t1 = tsfn(phi1, sinphi1);
+            if (secant) {
+                final double sinphi2 = sin(phi2);
+                final double m2 = msfn(sinphi2, cos(phi2));
+                final double t2 = tsfn(phi2, sinphi2);
+                n = log(m1/m2) / log(t1/t2);
+            } else {
+                n = sinphi1;
+            }
+            F = m1 * pow(t1, -n) / n;
+            if (abs(abs(latitudeOfOrigin) - PI/2) >= EPSILON) {
+                rho0 = F * pow(tsfn(latitudeOfOrigin, sin(latitudeOfOrigin)), n);
+            } else {
+                rho0 = 0.0;
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ParameterValueGroup getParameterValues() {
+        final ParameterValueGroup values = super.getParameterValues();
+        final Collection<GeneralParameterDescriptor> expected = getParameterDescriptors().descriptors();
+        set(expected, AbstractProvider.STANDARD_PARALLEL_1, values, phi1);
+        set(expected, AbstractProvider.STANDARD_PARALLEL_2, values, phi2);
+        return values;
+    }
+
+    /**
+     * Transforms the specified (<var>&lambda;</var>,<var>&phi;</var>) coordinates
+     * (units in radians) and stores the result in {@code ptDst} (linear distance
+     * on a unit sphere).
+     */
+    protected Point2D transformNormalized(double x, double y, Point2D ptDst)
+            throws ProjectionException
+    {
+        double rho;
+        // Snyder p. 108
+        if (abs(abs(y) - PI/2) < EPSILON) {
+            if (y*n <= 0) {
+                throw new ProjectionException(y);
+            } else {
+                rho = 0;
+            }
+        } else if (isSpherical) {
+            rho = F * pow(tan(PI/4 + 0.5*y), -n);
+        } else {
+            rho = F * pow(tsfn(y, sin(y)), n);
+        }
+        x *= n;
+        if (belgium) {
+            x -= BELGE_A;
+        }
+        y = rho0 - rho * cos(x);
+        x =        rho * sin(x);
+        if (ptDst != null) {
+            ptDst.setLocation(x,y);
+            return ptDst;
+        }
+        return new Point2D.Double(x,y);
+    }
+
+    /**
+     * Transforms the specified (<var>x</var>,<var>y</var>) coordinates
+     * and stores the result in {@code ptDst}.
+     */
+    protected Point2D inverseTransformNormalized(double x, double y, Point2D ptDst)
+            throws ProjectionException
+    {
+        double theta;
+        y = rho0 - y;
+        double rho = hypot(x, y);  // Zero when the latitude is 90 degrees.
+        if (rho > EPSILON) {
+            if (n < 0) {
+                rho = -rho;
+                x = -x;
+                y = -y;
+            }
+            theta = atan2(x, y);
+            if (belgium) {
+                theta += BELGE_A;
+            }
+            x = theta/n;
+            if (isSpherical) {
+                y = 2.0 * atan(pow(F/rho, 1.0/n)) - PI/2;
+            } else {
+                y = cphi2(pow(rho/F, 1.0/n));
+            }
+        } else {
+            x = 0.0;
+            y = n < 0 ? -(PI/2) : (PI/2);
+        }
+        if (ptDst != null) {
+            ptDst.setLocation(x,y);
+            return ptDst;
+        }
+        return new Point2D.Double(x,y);
+    }
+
+    /**
+     * Returns a hash value for this projection.
+     */
+    @Override
+    public int hashCode() {
+        /*
+         * This code should be computed fast. Consequently, we do not use all fields
+         * in this object.  Two {@code LambertConformal} objects with different
+         * {@link #phi1} and {@link #phi2} should compute a F value different enough.
+         */
+        final long code = Double.doubleToLongBits(F);
+        return ((int)code ^ (int)(code >>> 32)) + 37*super.hashCode();
+    }
+
+    /**
+     * Compares the specified object with this map projection for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            // Slight optimization
+            return true;
+        }
+        if (super.equals(object)) {
+            final LambertConformal that = (LambertConformal) object;
+            return (this.belgium == that.belgium) &&
+                   equals(this.n,      that.n)    &&
+                   equals(this.F,      that.F)    &&
+                   equals(this.rho0,   that.rho0) &&
+                   equals(this.phi1,   that.phi1) &&
+                   equals(this.phi2,   that.phi2);
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/LambertConformal1SP.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/LambertConformal1SP.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/LambertConformal1SP.java	(revision 28000)
@@ -0,0 +1,142 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.projection;
+
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.ConicProjection;
+import org.opengis.referencing.operation.MathTransform;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.geotools.resources.i18n.Vocabulary;
+
+
+/**
+ * Lambert Conical Conformal 1SP Projection.
+ *
+ * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_1sp.html">lambert_conic_conformal_1sp</A>
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/LambertConformal1SP.java $
+ * @version $Id: LambertConformal1SP.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux
+ * @author Rueben Schulz
+ */
+public class LambertConformal1SP extends LambertConformal {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 149783452790829983L;
+
+    /**
+     * Constructs a new map projection from the supplied parameters.
+     *
+     * @param  parameters The parameter values in standard units.
+     * @throws ParameterNotFoundException if a mandatory parameter is missing.
+     */
+    protected LambertConformal1SP(final ParameterValueGroup parameters)
+            throws ParameterNotFoundException
+    {
+        super(parameters);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return Provider.PARAMETERS;
+    }
+
+
+
+
+    //////////////////////////////////////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                          ////////
+    ////////                                 PROVIDERS                                ////////
+    ////////                                                                          ////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * The {@linkplain org.geotools.referencing.operation.MathTransformProvider math transform
+     * provider} for a {@linkplain LambertConformal1SP Lambert Conformal 1SP} projection (EPSG
+     * code 9801).
+     *
+     * @since 2.2
+     * @version $Id: LambertConformal1SP.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux
+     * @author Rueben Schulz
+     *
+     * @see org.geotools.referencing.operation.DefaultMathTransformFactory
+     */
+    public static class Provider extends AbstractProvider {
+        /**
+         * For cross-version compatibility.
+         */
+        private static final long serialVersionUID = -4243116402872545772L;
+
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new NamedIdentifier[] {
+                new NamedIdentifier(Citations.OGC,      "Lambert_Conformal_Conic_1SP"),
+                new NamedIdentifier(Citations.EPSG,     "Lambert Conic Conformal (1SP)"),
+                new NamedIdentifier(Citations.EPSG,     "9801"),
+                new NamedIdentifier(Citations.GEOTIFF,  "CT_LambertConfConic_1SP"),
+                new NamedIdentifier(Citations.GEOTOOLS, Vocabulary.formatInternational(
+                                    VocabularyKeys.LAMBERT_CONFORMAL_PROJECTION))
+            }, new ParameterDescriptor[] {
+                SEMI_MAJOR,          SEMI_MINOR,
+                CENTRAL_MERIDIAN,    LATITUDE_OF_ORIGIN,
+                SCALE_FACTOR,
+                FALSE_EASTING,       FALSE_NORTHING
+            });
+
+        /**
+         * Constructs a new provider.
+         */
+        public Provider() {
+            super(PARAMETERS);
+        }
+
+        /**
+         * Returns the operation type for this map projection.
+         */
+        @Override
+        public Class<ConicProjection> getOperationType() {
+            return ConicProjection.class;
+        }
+
+        /**
+         * Creates a transform from the specified group of parameter values.
+         *
+         * @param  parameters The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not found.
+         */
+        protected MathTransform createMathTransform(final ParameterValueGroup parameters)
+                throws ParameterNotFoundException
+        {
+            return new LambertConformal1SP(parameters);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/LambertConformal2SP.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/LambertConformal2SP.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/LambertConformal2SP.java	(revision 28000)
@@ -0,0 +1,179 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.projection;
+
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.geotools.util.Utilities;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.ConicProjection;
+import org.opengis.referencing.operation.MathTransform;
+
+
+/**
+ * Lambert Conical Conformal 2SP Projection.
+ *
+ * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_2sp.html">lambert_conic_conformal_2sp</A>
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/LambertConformal2SP.java $
+ * @version $Id: LambertConformal2SP.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux
+ * @author Rueben Schulz
+ */
+public class LambertConformal2SP extends LambertConformal {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 7184350446186057405L;
+
+    /**
+     * Constructs a new map projection from the supplied parameters.
+     *
+     * @param  parameters The parameter values in standard units.
+     * @throws ParameterNotFoundException if a mandatory parameter is missing.
+     */
+    protected LambertConformal2SP(final ParameterValueGroup parameters)
+            throws ParameterNotFoundException
+    {
+        super(parameters);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return Provider.PARAMETERS;
+    }
+
+
+
+
+    //////////////////////////////////////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                          ////////
+    ////////                                 PROVIDERS                                ////////
+    ////////                                                                          ////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * The {@linkplain org.geotools.referencing.operation.MathTransformProvider math transform
+     * provider} for a {@linkplain LambertConformal2SP Lambert Conformal 2SP} projection (EPSG
+     * code 9802).
+     *
+     * @since 2.2
+     * @version $Id: LambertConformal2SP.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux
+     * @author Rueben Schulz
+     *
+     * @see org.geotools.referencing.operation.DefaultMathTransformFactory
+     */
+    public static class Provider extends AbstractProvider {
+        /**
+         * For cross-version compatibility.
+         */
+        private static final long serialVersionUID = 3240860802816724947L;
+
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new NamedIdentifier[] {
+                new NamedIdentifier(Citations.OGC,      "Lambert_Conformal_Conic_2SP"),
+                new NamedIdentifier(Citations.EPSG,     "Lambert Conic Conformal (2SP)"),
+                new NamedIdentifier(Citations.ESRI,     "Lambert_Conformal_Conic"),
+                new NamedIdentifier(Citations.ESRI,     "Lambert_Conformal_Conic_2SP"),
+                new NamedIdentifier(Citations.EPSG,     "9802"),
+                new NamedIdentifier(Citations.GEOTIFF,  "CT_LambertConfConic_2SP"),
+                new NamedIdentifier(Citations.GEOTIFF,  "CT_LambertConfConic"),
+                new NamedIdentifier(Citations.GEOTOOLS, Vocabulary.formatInternational(
+                                                        VocabularyKeys.LAMBERT_CONFORMAL_PROJECTION))
+            }, new ParameterDescriptor[] {
+                SEMI_MAJOR,          SEMI_MINOR,
+                CENTRAL_MERIDIAN,    LATITUDE_OF_ORIGIN,
+                STANDARD_PARALLEL_1, STANDARD_PARALLEL_2,
+                FALSE_EASTING,       FALSE_NORTHING, 
+                SCALE_FACTOR // This last parameter is for ESRI compatibility
+            });
+
+        /**
+         * Constructs a new provider.
+         */
+        public Provider() {
+            super(PARAMETERS);
+        }
+
+        /**
+         * Returns the operation type for this map projection.
+         */
+        @Override
+        public Class<ConicProjection> getOperationType() {
+            return ConicProjection.class;
+        }
+
+        /**
+         * Creates a transform from the specified group of parameter values.
+         *
+         * @param  parameters The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not found.
+         */
+        protected MathTransform createMathTransform(final ParameterValueGroup parameters)
+                throws ParameterNotFoundException
+        {
+            if(getParameter(STANDARD_PARALLEL_2, parameters) == null &&
+               getParameter(STANDARD_PARALLEL_1, parameters) == null &&
+               getParameter(LATITUDE_OF_ORIGIN, parameters) != null) {
+                // handle the ESRI 1SP case
+                return new LambertConformal1SP(parameters);
+            } else if(Utilities.equals(doubleValue(STANDARD_PARALLEL_1, parameters),
+                                doubleValue(STANDARD_PARALLEL_2, parameters)) &&
+               Utilities.equals(doubleValue(STANDARD_PARALLEL_1, parameters),
+                                doubleValue(LATITUDE_OF_ORIGIN, parameters))
+                                ) {
+                // handle the ESRI 1SP case
+                return new LambertConformal1SP(parameters);
+            } else if(getParameter(STANDARD_PARALLEL_2, parameters) == null &&
+               Utilities.equals(doubleValue(STANDARD_PARALLEL_1, parameters),
+                                doubleValue(LATITUDE_OF_ORIGIN, parameters))) {
+                // handle the ESRI 1SP case
+                return new LambertConformal1SP(parameters);
+            } else {
+                // switch sp1 and sp2 so that we get a consistent ordering, this allows to recognize
+                // tow Lamber conformal with the same standard parallels declared in opposite order
+                ParameterValue<Double> sp1 = getParameter(STANDARD_PARALLEL_1, parameters); 
+                ParameterValue<Double> sp2 = getParameter(STANDARD_PARALLEL_2, parameters);
+                if(sp1 != null && sp2 != null) {
+                    if(sp1.doubleValue() < sp2.doubleValue()) {
+                        final double temp = sp1.doubleValue();
+                        sp1.setValue(sp2.doubleValue());
+                        sp2.setValue(temp);
+                    }
+                }
+                
+                return new LambertConformal2SP(parameters);
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/LambertConformalBelgium.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/LambertConformalBelgium.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/LambertConformalBelgium.java	(revision 28000)
@@ -0,0 +1,140 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.projection;
+
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.ConicProjection;
+import org.opengis.referencing.operation.MathTransform;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.geotools.resources.i18n.Vocabulary;
+
+
+/**
+ * Lambert Conical Conformal 2SP Belgium Projection.
+ *
+ * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_2sp_belgium.html">lambert_conic_conformal_2sp_belgium</A>
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/LambertConformalBelgium.java $
+ * @version $Id: LambertConformalBelgium.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Rueben Schulz
+ * @author Martin Desruisseaux
+ */
+public class LambertConformalBelgium extends LambertConformal {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -3441696724046319189L;
+
+    /**
+     * Constructs a new map projection from the supplied parameters.
+     *
+     * @param  parameters The parameter values in standard units.
+     * @throws ParameterNotFoundException if a mandatory parameter is missing.
+     */
+    protected LambertConformalBelgium(final ParameterValueGroup parameters)
+            throws ParameterNotFoundException
+    {
+        super(parameters, true);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return Provider.PARAMETERS;
+    }
+
+
+
+
+    //////////////////////////////////////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                          ////////
+    ////////                                 PROVIDERS                                ////////
+    ////////                                                                          ////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * The {@linkplain org.geotools.referencing.operation.MathTransformProvider math transform
+     * provider} for a {@linkplain LambertConformalBelgium Lambert Conformal 2SP Belgium}
+     * projection (EPSG code 9803).
+     *
+     * @since 2.2
+     * @version $Id: LambertConformalBelgium.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Rueben Schulz
+     *
+     * @see org.geotools.referencing.operation.DefaultMathTransformFactory
+     */
+     public static final class Provider extends AbstractProvider {
+        /**
+         * For cross-version compatibility.
+         */
+        private static final long serialVersionUID = -6388030784088639876L;
+
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new NamedIdentifier[] {
+                new NamedIdentifier(Citations.OGC,      "Lambert_Conformal_Conic_2SP_Belgium"),
+                new NamedIdentifier(Citations.EPSG,     "Lambert Conic Conformal (2SP Belgium)"),
+                new NamedIdentifier(Citations.EPSG,     "9803"),
+                new NamedIdentifier(Citations.GEOTOOLS, Vocabulary.formatInternational(
+                                                        VocabularyKeys.LAMBERT_CONFORMAL_PROJECTION))
+            }, new ParameterDescriptor[] {
+                SEMI_MAJOR,          SEMI_MINOR,
+                CENTRAL_MERIDIAN,    LATITUDE_OF_ORIGIN,
+                STANDARD_PARALLEL_1, STANDARD_PARALLEL_2,
+                FALSE_EASTING,       FALSE_NORTHING
+            });
+
+        /**
+         * Constructs a new provider.
+         */
+        public Provider() {
+            super(PARAMETERS);
+        }
+
+        /**
+         * Returns the operation type for this map projection.
+         */
+        @Override
+        public Class<ConicProjection> getOperationType() {
+            return ConicProjection.class;
+        }
+
+        /**
+         * Creates a transform from the specified group of parameter values.
+         *
+         * @param  parameters The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not found.
+         */
+        protected MathTransform createMathTransform(final ParameterValueGroup parameters)
+                throws ParameterNotFoundException
+        {
+            return new LambertConformalBelgium(parameters);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/MapProjection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/MapProjection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/MapProjection.java	(revision 28000)
@@ -0,0 +1,1541 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 1999-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains formulas from the PROJ package of USGS.
+ *    USGS's work is fully acknowledged here. This derived work has
+ *    been relicensed under LGPL with Frank Warmerdam's permission.
+ */
+package org.geotools.referencing.operation.projection;
+
+import java.awt.geom.Point2D;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.logging.LogRecord;
+
+import javax.measure.unit.NonSI;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+import org.opengis.parameter.InvalidParameterValueException;
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.Projection;
+import org.opengis.referencing.operation.TransformException;
+
+import org.geotools.math.XMath;
+import org.geotools.measure.Latitude;
+import org.geotools.measure.Longitude;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.referencing.operation.MathTransformProvider;
+import org.geotools.referencing.operation.transform.AbstractMathTransform;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.util.Utilities;
+import org.geotools.util.logging.Logging;
+
+import static java.lang.Math.*;
+
+
+/**
+ * Base class for transformation services between ellipsoidal and cartographic projections.
+ * This base class provides the basic feature needed for all methods (no need to overrides
+ * methods). Subclasses must "only" implements the following methods:
+ * <ul>
+ *   <li>{@link #getParameterValues}</li>
+ *   <li>{@link #transformNormalized}</li>
+ *   <li>{@link #inverseTransformNormalized}</li>
+ * </ul>
+ * <p>
+ * <strong>NOTE:</strong>Serialization of this class is appropriate for short-term storage
+ * or RMI use, but will probably not be compatible with future version. For long term storage,
+ * WKT (Well Know Text) or XML (not yet implemented) are more appropriate.
+ *
+ * @since 2.0
+ * @version $Id: MapProjection.java 37299 2011-05-25 05:21:24Z mbedward $
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/MapProjection.java $
+ * @author André Gosselin
+ * @author Martin Desruisseaux (PMO, IRD)
+ * @author Rueben Schulz
+ *
+ * @see <A HREF="http://mathworld.wolfram.com/MapProjection.html">Map projections on MathWorld</A>
+ * @see <A HREF="http://atlas.gc.ca/site/english/learningresources/carto_corner/map_projections.html">Map projections on the atlas of Canada</A>
+ * @tutorial http://www.geotools.org/display/GEOTOOLS/How+to+add+new+projections
+ */
+public abstract class MapProjection extends AbstractMathTransform
+        implements MathTransform2D, Serializable
+{
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -406751619777246914L;
+
+    /**
+     * The projection package logger
+     */
+    protected static final Logger LOGGER = Logging.getLogger(MapProjection.class);
+
+    /**
+     * Maximum difference allowed when comparing real numbers.
+     * This field is private because subclasses may use different threshold value.
+     */
+    private static final double EPSILON = 1E-6;
+
+    /**
+     * Maximum difference allowed when comparing longitudes or latitudes in degrees.
+     * This tolerance do not apply to angle in radians. A tolerance of 1E-4 is about
+     * 10 kilometers.
+     */
+    private static final double ANGLE_TOLERANCE = 1E-4;
+
+    /**
+     * Difference allowed in iterative computations.
+     */
+    private static final double ITERATION_TOLERANCE = 1E-10;
+    
+    /**
+     * Relative iteration precision used in the <code>mlfn<code> method
+     */
+    private static final double MLFN_TOL = 1E-11;
+
+
+    /**
+     * Maximum number of iterations for iterative computations.
+     */
+    private static final int MAXIMUM_ITERATIONS = 15;
+    
+    /**
+     * Constants used to calculate {@link #en0}, {@link #en1},
+     * {@link #en2}, {@link #en3}, {@link #en4}.
+     */
+    private static final double C00= 1.0,
+                                C02= 0.25,
+                                C04= 0.046875,
+                                C06= 0.01953125,
+                                C08= 0.01068115234375,
+                                C22= 0.75,
+                                C44= 0.46875,
+                                C46= 0.01302083333333333333,
+                                C48= 0.00712076822916666666,
+                                C66= 0.36458333333333333333,
+                                C68= 0.00569661458333333333,
+                                C88= 0.3076171875;
+
+    /**
+     * Ellipsoid excentricity, equals to <code>sqrt({@link #excentricitySquared})</code>.
+     * Value 0 means that the ellipsoid is spherical.
+     *
+     * @see #excentricitySquared
+     * @see #isSpherical
+     */ 
+    protected final double excentricity;
+
+    /**
+     * The square of excentricity: e² = (a²-b²)/a² where
+     * <var>e</var> is the {@linkplain #excentricity excentricity},
+     * <var>a</var> is the {@linkplain #semiMajor semi major} axis length and
+     * <var>b</var> is the {@linkplain #semiMinor semi minor} axis length.
+     *
+     * @see #excentricity
+     * @see #semiMajor
+     * @see #semiMinor
+     * @see #isSpherical
+     */
+    protected final double excentricitySquared;
+
+    /**
+     * {@code true} if this projection is spherical. Spherical model has identical
+     * {@linkplain #semiMajor semi major} and {@linkplain #semiMinor semi minor} axis
+     * length, and an {@linkplain #excentricity excentricity} zero.
+     *
+     * @see #excentricity
+     * @see #semiMajor
+     * @see #semiMinor
+     */
+    protected final boolean isSpherical;
+
+    /**
+     * Length of semi-major axis, in metres. This is named '<var>a</var>' or '<var>R</var>'
+     * (Radius in spherical cases) in Snyder.
+     *
+     * @see #excentricity
+     * @see #semiMinor
+     */
+    protected final double semiMajor;
+
+    /**
+     * Length of semi-minor axis, in metres. This is named '<var>b</var>' in Snyder.
+     *
+     * @see #excentricity
+     * @see #semiMajor
+     */
+    protected final double semiMinor;
+
+    /**
+     * Central longitude in <u>radians</u>. Default value is 0, the Greenwich meridian.
+     * This is called '<var>lambda0</var>' in Snyder.
+     * <p>
+     * <strong>Consider this field as final</strong>. It is not final only
+     * because some classes need to modify it at construction time.
+     */
+    protected double centralMeridian;
+
+    /**
+     * Latitude of origin in <u>radians</u>. Default value is 0, the equator.
+     * This is called '<var>phi0</var>' in Snyder.
+     * <p>
+     * <strong>Consider this field as final</strong>. It is not final only
+     * because some classes need to modify it at construction time.
+     */
+    protected double latitudeOfOrigin;
+
+    /**
+     * The scale factor. Default value is 1. Named '<var>k</var>' in Snyder.
+     * <p>
+     * <strong>Consider this field as final</strong>. It is not final only
+     * because some classes need to modify it at construction time.
+     */
+    protected double scaleFactor;
+
+    /**
+     * False easting, in metres. Default value is 0.
+     */
+    protected final double falseEasting;
+
+    /**
+     * False northing, in metres. Default value is 0.
+     */
+    protected final double falseNorthing;
+
+    /**
+     * Global scale factor. Default value {@code globalScale} is equal
+     * to {@link #semiMajor}&times;{@link #scaleFactor}.
+     * <p>
+     * <strong>Consider this field as final</strong>. It is not final only
+     * because some classes need to modify it at construction time.
+     */
+    protected double globalScale;
+
+    /**
+     * The inverse of this map projection. Will be created only when needed.
+     */
+    private transient MathTransform2D inverse;
+    
+    /**
+     * Constant needed for the <code>mlfn<code> method.
+     * Setup at construction time.
+     */
+    protected double en0,en1,en2,en3,en4;
+
+    /**
+     * When different than {@link #globalRangeCheckSemaphore}, coordinate ranges will be
+     * checked and a {@code WARNING} log will be issued if they are out of their natural
+     * ranges (-180/180&deg; for longitude, -90/90&deg; for latitude).
+     *
+     * @see #verifyCoordinateRanges()
+     * @see #warningLogged()
+     */
+    private transient int rangeCheckSemaphore;
+
+    /**
+     * The value to be checked against {@link #rangeCheckSemaphore} in order to determine
+     * if coordinates ranges should be checked.
+     */
+    private static int globalRangeCheckSemaphore = 1;
+    
+    /**
+     * Marks if the projection is invertible. The vast majority is, subclasses can override.
+     */
+    protected boolean invertible = true;
+
+    /**
+     * Constructs a new map projection from the suplied parameters.
+     *
+     * @param  values The parameter values in standard units.
+     *         The following parameter are recognized:
+     *         <ul>
+     *           <li>"semi_major" (mandatory: no default)</li>
+     *           <li>"semi_minor" (mandatory: no default)</li>
+     *           <li>"central_meridian"   (default to 0°)</li>
+     *           <li>"latitude_of_origin" (default to 0°)</li>
+     *           <li>"scale_factor"       (default to 1 )</li>
+     *           <li>"false_easting"      (default to 0 )</li>
+     *           <li>"false_northing"     (default to 0 )</li>
+     *         </ul>
+     * @throws ParameterNotFoundException if a mandatory parameter is missing.
+     */
+    protected MapProjection(final ParameterValueGroup values) throws ParameterNotFoundException {
+        this(values, null);
+    }
+
+    /**
+     * Constructor invoked by sub-classes when we can't rely on {@link #getParameterDescriptors}
+     * before the construction is completed. This is the case when the later method depends on
+     * the value of some class's attribute, which has not yet been set. An example is
+     * {@link ObliqueMercator#getParameterDescriptors}.
+     * <p>
+     * This method is not public because it is not a very elegant hack, and a work around exists.
+     * For example {@code ObliqueMercator} two-points case could be implemented by as a separated
+     * classes, in which case {@link #getParameterDescriptors} returns a constant and can be safely
+     * invoked in a constructor.
+     */
+    MapProjection(final ParameterValueGroup values, Collection<GeneralParameterDescriptor> expected)
+            throws ParameterNotFoundException
+    {
+        if (expected == null) {
+            expected = getParameterDescriptors().descriptors();
+        }
+        semiMajor           = doubleValue(expected, AbstractProvider.SEMI_MAJOR,         values);
+        semiMinor           = doubleValue(expected, AbstractProvider.SEMI_MINOR,         values);
+        centralMeridian     = doubleValue(expected, AbstractProvider.CENTRAL_MERIDIAN,   values);
+        latitudeOfOrigin    = doubleValue(expected, AbstractProvider.LATITUDE_OF_ORIGIN, values);
+        scaleFactor         = doubleValue(expected, AbstractProvider.SCALE_FACTOR,       values);
+        falseEasting        = doubleValue(expected, AbstractProvider.FALSE_EASTING,      values);
+        falseNorthing       = doubleValue(expected, AbstractProvider.FALSE_NORTHING,     values);
+        isSpherical         = (semiMajor == semiMinor);
+        excentricitySquared = 1.0 - (semiMinor * semiMinor) / (semiMajor * semiMajor);
+        excentricity        = sqrt(excentricitySquared);
+        globalScale         = scaleFactor * semiMajor;
+        ensureLongitudeInRange(AbstractProvider.CENTRAL_MERIDIAN,   centralMeridian,  true);
+        ensureLatitudeInRange (AbstractProvider.LATITUDE_OF_ORIGIN, latitudeOfOrigin, true);
+        
+        //  Compute constants for the mlfn
+        double t;
+        en0 = C00 - excentricitySquared  *  (C02 + excentricitySquared  *
+             (C04 + excentricitySquared  *  (C06 + excentricitySquared  * C08)));
+        en1 =       excentricitySquared  *  (C22 - excentricitySquared  *
+             (C04 + excentricitySquared  *  (C06 + excentricitySquared  * C08)));
+        en2 =  (t = excentricitySquared  *         excentricitySquared) *
+             (C44 - excentricitySquared  *  (C46 + excentricitySquared  * C48));
+        en3 = (t *= excentricitySquared) *  (C66 - excentricitySquared  * C68);
+        en4 =   t * excentricitySquared  *  C88;
+    }
+
+    /**
+     * Returns {@code true} if the specified parameter can apply to this map projection.
+     * The set of expected parameters must be supplied. The default implementation just
+     * invokes {@code expected.contains(param)}. Some subclasses will override this method
+     * in order to handle {@link ModifiedParameterDescriptor} in a special way.
+     *
+     * @see #doubleValue
+     * @see #set
+     */
+    boolean isExpectedParameter(final Collection<GeneralParameterDescriptor> expected,
+                                final ParameterDescriptor param)
+    {
+        return expected.contains(param);
+    }
+
+    /**
+     * Returns the parameter value for the specified operation parameter. Values are
+     * automatically converted into the standard units specified by the supplied
+     * {@code param} argument, except {@link NonSI#DEGREE_ANGLE degrees} which
+     * are converted to {@link SI#RADIAN radians}.
+     *
+     * @param  expected The value returned by {@code getParameterDescriptors().descriptors()}.
+     * @param  param The parameter to look for.
+     * @param  group The parameter value group to search into.
+     * @return The requested parameter value, or {@code NaN} if {@code param} is
+     *         {@linkplain MathTransformProvider#createOptionalDescriptor optional}
+     *         and the user didn't provided any value.
+     * @throws ParameterNotFoundException if the parameter is not found.
+     *
+     * @see MathTransformProvider#doubleValue
+     */
+    final double doubleValue(final Collection<GeneralParameterDescriptor> expected,
+                             final ParameterDescriptor param,
+                             final ParameterValueGroup group)
+            throws ParameterNotFoundException
+    {
+        if (isExpectedParameter(expected, param)) {
+            /*
+             * Gets the value supplied by the user. The conversion from decimal
+             * degrees to radians (if needed) is performed by AbstractProvider.
+             */
+            return AbstractProvider.doubleValue(param, group);
+        }
+        /*
+         * The constructor asked for a parameter value that do not apply to the type of the
+         * projection to be created. Returns a default value common to all projection types,
+         * but this value should not be used in projection computations.
+         */
+        double v;
+        final Object value = param.getDefaultValue();
+        if (value instanceof Number) {
+            v = ((Number) value).doubleValue();
+            if (NonSI.DEGREE_ANGLE.equals(param.getUnit())) {
+                v = toRadians(v);
+            }
+        } else {
+            v = Double.NaN;
+        }
+        return v;
+    }
+
+    /**
+     * Ensures that this projection has equals semi-major and semi-minor axis. This method is
+     * invoked by constructors of classes implementing only spherical formulas.
+     */
+    final void ensureSpherical() throws IllegalArgumentException {
+        if (!isSpherical) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.ELLIPTICAL_NOT_SUPPORTED));
+        }
+    }
+
+    /**
+     * Ensures that the latitude is within allowed limits (&plusmn;&pi;/2).
+     * This method is useful to check the validity of projection parameters,
+     * like {@link #latitudeOfOrigin}.
+     *
+     * @param  y Latitude to check, in radians.
+     * @param  edge {@code true} to accept latitudes of &plusmn;&pi;/2.
+     * @throws IllegalArgumentException if the latitude is out of range.
+     */
+    static void ensureLatitudeInRange(final ParameterDescriptor name, double y, final boolean edge)
+            throws IllegalArgumentException
+    {
+        if (edge ? (y >= Latitude.MIN_VALUE * PI/180  &&  y <= Latitude.MAX_VALUE * PI/180) :
+                   (y >  Latitude.MIN_VALUE * PI/180  &&  y <  Latitude.MAX_VALUE * PI/180))
+        {
+            return;
+        }
+        y = toDegrees(y);
+        throw new InvalidParameterValueException(Errors.format(ErrorKeys.LATITUDE_OUT_OF_RANGE_$1,
+                                                 new Latitude(y)), name.getName().getCode(), y);
+    }
+
+    /**
+     * Ensures that the longitue is within allowed limits (&plusmn;&pi;).
+     * This method is used to check the validity of projection parameters,
+     * like {@link #centralMeridian}.
+     *
+     * @param  x Longitude to verify, in radians.
+     * @param  edge {@code true} for accepting longitudes of &plusmn;&pi;.
+     * @throws IllegalArgumentException if the longitude is out of range.
+     */
+    static void ensureLongitudeInRange(final ParameterDescriptor name, double x, final boolean edge)
+            throws IllegalArgumentException
+    {
+        if (edge ? (x >= Longitude.MIN_VALUE * PI/180  &&  x <= Longitude.MAX_VALUE * PI/180) :
+                   (x >  Longitude.MIN_VALUE * PI/180  &&  x <  Longitude.MAX_VALUE * PI/180))
+        {
+            return;
+        }
+        x = toDegrees(x);
+        throw new InvalidParameterValueException(Errors.format(ErrorKeys.LONGITUDE_OUT_OF_RANGE_$1,
+                                                 new Longitude(x)), name.getName().getCode(), x);
+    }
+
+    /**
+     * Verifies if the given coordinates are in the range of geographic coordinates. If they are
+     * not, then this method logs a warning and returns {@code true}. Otherwise this method does
+     * nothing and returns {@code false}.
+     *
+     * @param  tr The caller.
+     * @param  x The longitude in decimal degrees.
+     * @param  y The latitude in decimal degrees.
+     * @return {@code true} if the coordinates are not in the geographic range, in which case
+     *         a warning has been logged.
+     */
+    private static boolean verifyGeographicRanges(final AbstractMathTransform tr,
+                                                  final double x, final double y)
+    {
+        // Note: the following tests should not fails for NaN values.
+        final boolean xOut, yOut;
+        xOut = (x < (Longitude.MIN_VALUE - ANGLE_TOLERANCE) || x > (Longitude.MAX_VALUE + ANGLE_TOLERANCE));
+        yOut = (y < (Latitude .MIN_VALUE - ANGLE_TOLERANCE) || y > (Latitude .MAX_VALUE + ANGLE_TOLERANCE));
+        if (!xOut && !yOut) {
+            return false;
+        }
+        final String lineSeparator = System.getProperty("line.separator", "\n");
+        final StringBuilder buffer = new StringBuilder();
+        buffer.append(Errors.format(ErrorKeys.OUT_OF_PROJECTION_VALID_AREA_$1, tr.getName()));
+        if (xOut) {
+            buffer.append(lineSeparator);
+            buffer.append(Errors.format(ErrorKeys.LONGITUDE_OUT_OF_RANGE_$1, new Longitude(x)));
+        }
+        if (yOut) {
+            buffer.append(lineSeparator);
+            buffer.append(Errors.format(ErrorKeys.LATITUDE_OUT_OF_RANGE_$1, new Latitude(y)));
+        }
+        final LogRecord record = new LogRecord(Level.WARNING, buffer.toString());
+        final String classe;
+        if (tr instanceof Inverse) {
+            classe = ((Inverse) tr).inverse().getClass().getName() + ".Inverse";
+        } else {
+            classe = tr.getClass().getName();
+        }
+        record.setSourceClassName(classe);
+        record.setSourceMethodName("transform");
+        record.setLoggerName(LOGGER.getName());
+        LOGGER.log(record);
+        return true;
+    }
+
+    /**
+     * Sets the value in a parameter group. This convenience method is used
+     * by subclasses for {@link #getParameterValues} implementation. Values
+     * are automatically converted from radians to decimal degrees if needed.
+     *
+     * @param expected  The value returned by {@code getParameterDescriptors().descriptors()}.
+     * @param param     One of the {@link AbstractProvider} constants.
+     * @param group     The group in which to set the value.
+     * @param value     The value to set.
+     */
+    final void set(final Collection<GeneralParameterDescriptor> expected,
+                   final ParameterDescriptor<?> param,
+                   final ParameterValueGroup group,
+                   double value)
+    {
+        if (isExpectedParameter(expected, param)) {
+            if (NonSI.DEGREE_ANGLE.equals(param.getUnit())) {
+                /*
+                 * Converts radians to degrees and try to fix rounding error
+                 * (e.g. -61.500000000000014  -->  -61.5). This is necessary
+                 * in order to avoid a bias when formatting a transform and
+                 * parsing it again.
+                 */
+                value = toDegrees(value);
+                double old = value;
+                value = XMath.trimDecimalFractionDigits(value, 4, 12);
+                if (value == old) {
+                    /*
+                     * The attempt to fix rounding error failed. Try again with the
+                     * assumption that the true value is a multiple of 1/3 of angle
+                     * (e.g. 51.166666666666664  -->  51.166666666666666), which is
+                     * common in the EPSG database.
+                     */
+                    old *= 3;
+                    final double test = XMath.trimDecimalFractionDigits(old, 4, 12);
+                    if (test != old) {
+                        value = test/3;
+                    }
+                }
+            }
+            group.parameter(param.getName().getCode()).setValue(value);
+        }
+    }
+
+    /**
+     * Returns the parameter descriptors for this map projection.
+     * This is used for a providing a default implementation of
+     * {@link #getParameterValues}, as well as arguments checking.
+     */
+    @Override
+    public abstract ParameterDescriptorGroup getParameterDescriptors();
+
+    /**
+     * Returns the parameter values for this map projection.
+     *
+     * @return A copy of the parameter values for this map projection.
+     */
+    @Override
+    public ParameterValueGroup getParameterValues() {
+        final ParameterDescriptorGroup descriptor = getParameterDescriptors();
+        final Collection<GeneralParameterDescriptor> expected = descriptor.descriptors();
+        final ParameterValueGroup values = descriptor.createValue();
+        set(expected, AbstractProvider.SEMI_MAJOR,         values, semiMajor       );
+        set(expected, AbstractProvider.SEMI_MINOR,         values, semiMinor       );
+        set(expected, AbstractProvider.CENTRAL_MERIDIAN,   values, centralMeridian );
+        set(expected, AbstractProvider.LATITUDE_OF_ORIGIN, values, latitudeOfOrigin);
+        set(expected, AbstractProvider.SCALE_FACTOR,       values, scaleFactor     );
+        set(expected, AbstractProvider.FALSE_EASTING,      values, falseEasting    );
+        set(expected, AbstractProvider.FALSE_NORTHING,     values, falseNorthing   );
+        return values;
+    }
+
+    /**
+     * Returns the dimension of input points.
+     */
+    public final int getSourceDimensions() {
+        return 2;
+    }
+
+    /**
+     * Returns the dimension of output points.
+     */
+    public final int getTargetDimensions() {
+        return 2;
+    }
+
+
+
+
+    //////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                          ////////
+    ////////                          TRANSFORMATION METHODS                          ////////
+    ////////             Includes an inner class for inverse projections.             ////////
+    ////////                                                                          ////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns the orthodromic distance between the two specified points using a spherical
+     * approximation. This is used for assertions only.
+     */
+    private double orthodromicDistance(final Point2D source, final Point2D target) {
+        final double y1 = toRadians(source.getY());
+        final double y2 = toRadians(target.getY());
+        final double dx = toRadians(abs(target.getX() - source.getX()) % 360);
+        double rho = sin(y1)*sin(y2) + cos(y1)*cos(y2)*cos(dx);
+        if (rho > +1) {assert rho <= +(1+EPSILON) : rho; rho = +1;}
+        if (rho < -1) {assert rho >= -(1+EPSILON) : rho; rho = -1;}
+        return acos(rho) * semiMajor;
+    }
+
+    /**
+     * Check point for private use by {@link #checkReciprocal}. This class is necessary in order
+     * to avoid never-ending loop in {@code assert} statements (when an {@code assert}
+     * calls {@code transform(...)}, which calls {@code inverse.transform(...)}, which
+     * calls {@code transform(...)}, etc.).
+     */
+    @SuppressWarnings("serial")
+    private static final class CheckPoint extends Point2D.Double {
+        public CheckPoint(final Point2D point) {
+            super(point.getX(), point.getY());
+        }
+    }
+
+    /**
+     * Check if the transform of {@code point} is close enough to {@code target}.
+     * "Close enough" means that the two points are separated by a distance shorter than
+     * {@link #getToleranceForAssertions}. This method is used for assertions with J2SE 1.4.
+     *
+     * @param point   Point to transform, in decimal degrees if {@code inverse} is {@code false}.
+     * @param target  Point to compare to, in metres if {@code inverse} is {@code false}.
+     * @param inverse {@code true} for an inverse transform instead of a direct one.
+     * @return {@code true} if the two points are close enough.
+     */
+    private boolean checkReciprocal(Point2D point, final Point2D target, final boolean inverse)
+            throws ProjectionException
+    {
+        if (!(point instanceof CheckPoint)) try {
+            point = new CheckPoint(point);
+            final double longitude;
+            final double latitude;
+            final double distance;
+            if (inverse) {
+                // Computes orthodromic distance (spherical model) in metres.
+                point = inverse().transform(point, point);
+                distance  = orthodromicDistance(point, target);
+                longitude = point.getX();
+                latitude  = point.getY();
+            } else {
+                // Computes cartesian distance in metres.
+                longitude = point.getX();
+                latitude  = point.getY();
+                point     = transform(point, point);
+                distance  = point.distance(target);
+            }
+            if (distance > getToleranceForAssertions(longitude, latitude)) {
+                /*
+                 * Do not fail for NaN values. For other cases we must throw a ProjectionException,
+                 * not an AssertionError, because some code like CRS.transform(CoordinateOperation,
+                 * ...) will project points that are know to be suspicious by surrounding them in
+                 * "try ... catch" statements. Failure are normal in their case and we want to let
+                 * them handle the exception the way they are used to.
+                 */
+                throw new ProjectionException(Errors.format(ErrorKeys.PROJECTION_CHECK_FAILED_$4,
+                          distance,
+                          new Longitude(longitude - toDegrees(centralMeridian )),
+                          new Latitude (latitude  - toDegrees(latitudeOfOrigin)),
+                          getName()));
+            }
+        } catch (ProjectionException exception) {
+            throw exception;
+        } catch (TransformException exception) {
+            throw new ProjectionException(exception);
+        }
+        return true;
+    }
+
+    /**
+     * Checks if transform using spherical formulas produces the same result
+     * than ellipsoidal formulas. This method is invoked during assertions only.
+     *
+     * @param x The easting computed by spherical formulas, in metres.
+     * @param y The northing computed by spherical formulas, in metres.
+     * @param expected The (easting,northing) computed by ellipsoidal formulas.
+     * @param tolerance The tolerance (optional).
+     */
+    static boolean checkTransform(final double x, final double y,
+                                  final Point2D expected, final double tolerance)
+    {
+        compare("x", expected.getX(), x, tolerance);
+        compare("y", expected.getY(), y, tolerance);
+        return tolerance < Double.POSITIVE_INFINITY;
+    }
+
+    /**
+     * Checks if inverse transform using spherical formulas produces the same result
+     * than ellipsoidal formulas. This method is invoked during assertions only.
+     * <p>
+     * <strong>Note:</strong> this method ignores the longitude if the latitude is
+     * at a pole, because in such case the longitude is meanless.
+     *
+     * @param longitude The longitude computed by spherical formulas, in radians.
+     * @param latitude  The latitude computed by spherical formulas, in radians.
+     * @param expected  The (longitude,latitude) computed by ellipsoidal formulas.
+     * @param tolerance The tolerance (optional).
+     */
+    static boolean checkInverseTransform(final double longitude, final double latitude,
+                                         final Point2D expected, final double tolerance)
+    {
+        compare("latitude", expected.getY(), latitude, tolerance);
+        if (abs(PI/2 - abs(latitude)) > EPSILON) {
+            compare("longitude", expected.getX(), longitude, tolerance);
+        }
+        return tolerance < Double.POSITIVE_INFINITY;
+    }
+
+    /**
+     * Compares two value for equality up to some tolerance threshold. This is used during
+     * assertions only. The comparaison do not fails if at least one value to compare is
+     * {@link Double#NaN}.
+     * <p>
+     * <strong>Hack:</strong> if the {@code variable} name starts by lower-case {@code L}
+     * (as in "longitude" and "latitude"), then the value is assumed to be an angle in
+     * radians. This is used for formatting an error message, if needed.
+     */
+    private static void compare(String variable, double expected, double actual, double tolerance) {
+        if (abs(expected - actual) > tolerance) {
+            if (variable.charAt(0) == 'l') {
+                actual   = toDegrees(actual);
+                expected = toDegrees(expected);
+            }
+            throw new AssertionError(Errors.format(ErrorKeys.TEST_FAILURE_$3, variable, expected, actual));
+        }
+    }
+
+    /**
+     * Transforms the specified coordinate and stores the result in {@code ptDst}. This method
+     * returns longitude as <var>x</var> values in the range {@code [-PI..PI]} and latitude as
+     * <var>y</var> values in the range {@code [-PI/2..PI/2]}. It will be checked by the caller,
+     * so this method doesn't need to performs this check.
+     * <p>
+     * Input coordinates have the {@link #falseEasting} and {@link #falseNorthing} removed and are
+     * divided by {@link #globalScale} before this method is invoked. After this method is invoked,
+     * the {@link #centralMeridian} is added to the {@code x} results in {@code ptDst}. This means
+     * that projections that implement this method are performed on an ellipse (or sphere) with a
+     * semi-major axis of 1.
+     * <p>
+     * In <A HREF="http://www.remotesensing.org/proj/">PROJ.4</A>, the same standardization,
+     * described above, is handled by {@code pj_inv.c}. Therefore when porting projections
+     * from PROJ.4, the inverse transform equations can be used directly here with minimal
+     * change. In the equations of Snyder, {@link #falseEasting}, {@link #falseNorthing} and
+     * {@link #scaleFactor} are usually not given. When implementing these equations here, you
+     * will not need to add the {@link #centralMeridian} to the output longitude or remove the
+     * {@link #semiMajor} (<var>a</var> or <var>R</var>).
+     *
+     * @param x     The easting of the coordinate, linear distance on a unit sphere or ellipse.
+     * @param y     The northing of the coordinate, linear distance on a unit sphere or ellipse.
+     * @param ptDst the specified coordinate point that stores the result of transforming
+     *              {@code ptSrc}, or {@code null}. Ordinates will be in <strong>radians</strong>.
+     * @return      the coordinate point after transforming {@code x}, {@code y}
+     *              and storing the result in {@code ptDst}.
+     * @throws ProjectionException if the point can't be transformed.
+     */
+    protected abstract Point2D inverseTransformNormalized(double x, double y, final Point2D ptDst)
+            throws ProjectionException;
+
+    /**
+     * Transforms the specified coordinate and stores the result in {@code ptDst}. This method is
+     * usually (but <strong>not</strong> guaranteed) to be invoked with values of <var>x</var> in
+     * the range {@code [-PI..PI]} and values of <var>y</var> in the range {@code [-PI/2..PI/2]}.
+     * Values outside those ranges are accepted (sometime with a warning logged) on the assumption
+     * that most implementations use those values only in trigonometric functions like
+     * {@linkplain Math#sin sin} and {@linkplain Math#cos cos}.
+     * <p>
+     * Coordinates have the {@link #centralMeridian} removed from <var>lambda</var> before this
+     * method is invoked. After this method is invoked, the results in {@code ptDst} are multiplied
+     * by {@link #globalScale}, and the {@link #falseEasting} and {@link #falseNorthing} are added.
+     * This means that projections that implement this method are performed on an ellipse (or sphere)
+     * with a semi-major axis of 1.
+     * <p>
+     * In <A HREF="http://www.remotesensing.org/proj/">PROJ.4</A>, the same standardization,
+     * described above, is handled by {@code pj_fwd.c}. Therefore when porting projections
+     * from PROJ.4, the forward transform equations can be used directly here with minimal
+     * change. In the equations of Snyder, {@link #falseEasting}, {@link #falseNorthing} and
+     * {@link #scaleFactor} are usually not given. When implementing these equations here,
+     * you will not need to remove the {@link #centralMeridian} from <var>lambda</var> or apply
+     * the {@link #semiMajor} (<var>a</var> or <var>R</var>).
+     *
+     * @param lambda The longitude of the coordinate, in <strong>radians</strong>.
+     * @param phi    The  latitude of the coordinate, in <strong>radians</strong>.
+     * @param ptDst  the specified coordinate point that stores the result of transforming
+     *               {@code ptSrc}, or {@code null}. Ordinates will be in a
+     *               dimensionless unit, as a linear distance on a unit sphere or ellipse.
+     * @return       the coordinate point after transforming ({@code lambda}, {@code phi})
+     *               and storing the result in {@code ptDst}.
+     * @throws ProjectionException if the point can't be transformed.
+     */
+    protected abstract Point2D transformNormalized(double lambda, double phi, final Point2D ptDst)
+            throws ProjectionException;
+
+    /**
+     * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
+     * <p>
+     * This method standardizes the source {@code x} coordinate
+     * by removing the {@link #centralMeridian}, before invoking
+     * <code>{@link #transformNormalized transformNormalized}(x, y, ptDst)</code>.
+     * It also multiplies by {@link #globalScale} and adds the {@link #falseEasting} and
+     * {@link #falseNorthing} to the point returned by the {@code transformNormalized(...)} call.
+     *
+     * @param ptSrc the specified coordinate point to be transformed.
+     *              Ordinates must be in decimal degrees.
+     * @param ptDst the specified coordinate point that stores the result of transforming
+     *              {@code ptSrc}, or {@code null}. Ordinates will be in metres.
+     * @return      the coordinate point after transforming {@code ptSrc} and storing
+     *              the result in {@code ptDst}.
+     * @throws ProjectionException if the point can't be transformed.
+     */
+    @Override
+    public final Point2D transform(final Point2D ptSrc, Point2D ptDst) throws ProjectionException {
+        final double x = ptSrc.getX();
+        final double y = ptSrc.getY();
+        if (verifyCoordinateRanges()) {
+            if (verifyGeographicRanges(this, x, y)) {
+                warningLogged();
+            }
+        }
+        /*
+         * Makes sure that the longitude before conversion stay within +/- PI radians. As a
+         * special case, we do not check the range if no rotation were applied on the longitude.
+         * This is because the user may have a big area ranging from -180° to +180°. With the
+         * slight rounding errors related to map projections, the 180° longitude may be slightly
+         * over the limit. Rolling the longitude would changes its sign. For example a bounding
+         * box from 30° to +180° would become 30° to -180°, which is probably not what the user
+         * wanted.
+         */
+        ptDst = transformNormalized(centralMeridian != 0 ?
+                rollLongitude(toRadians(x) - centralMeridian) : toRadians(x), toRadians(y), ptDst);
+        ptDst.setLocation(globalScale*ptDst.getX() + falseEasting,
+                          globalScale*ptDst.getY() + falseNorthing);
+
+        if(invertible) {
+            assert checkReciprocal(ptDst, (ptSrc!=ptDst) ? ptSrc : new Point2D.Double(x,y), true);
+        }
+        return ptDst;
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values. Ordinates must be
+     * (<var>longitude</var>,<var>latitude</var>) pairs in decimal degrees.
+     *
+     * @throws ProjectionException if a point can't be transformed. This method tries to transform
+     *         every points even if some of them can't be transformed. Non-transformable points will
+     *         have value {@link Double#NaN}. If more than one point can't be transformed, then this
+     *         exception may be about an arbitrary point.
+     */
+    public final void transform(final double[] srcPts, int srcOff,
+                                final double[] dstPts, int dstOff, int numPts)
+            throws ProjectionException
+    {
+        /*
+         * Vérifie s'il faudra parcourir le tableau en sens inverse.
+         * Ce sera le cas si les tableaux source et destination se
+         * chevauchent et que la destination est après la source.
+         */
+        final boolean reverse = (srcPts == dstPts && srcOff < dstOff &&
+                                 srcOff + (2*numPts) > dstOff);
+        if (reverse) {
+            srcOff += 2*numPts;
+            dstOff += 2*numPts;
+        }
+        final Point2D.Double point = new Point2D.Double();
+        ProjectionException firstException = null;
+        while (--numPts >= 0) {
+            try {
+                point.x = srcPts[srcOff++];
+                point.y = srcPts[srcOff++];
+                transform(point, point);
+                dstPts[dstOff++] = point.x;
+                dstPts[dstOff++] = point.y;
+            } catch (ProjectionException exception) {
+                dstPts[dstOff++] = Double.NaN;
+                dstPts[dstOff++] = Double.NaN;
+                if (firstException == null) {
+                    firstException = exception;
+                }
+            }
+            if (reverse) {
+                srcOff -= 4;
+                dstOff -= 4;
+            }
+        }
+        if (firstException != null) {
+            throw firstException;
+        }
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values. Ordinates must be
+     * (<var>longitude</var>,<var>latitude</var>) pairs in decimal degrees.
+     *
+     * @throws ProjectionException if a point can't be transformed. This method tries to transform
+     *         every points even if some of them can't be transformed. Non-transformable points will
+     *         have value {@link Float#NaN}. If more than one point can't be transformed, then this
+     *         exception may be about an arbitrary point.
+     */
+    @Override
+    public final void transform(final float[] srcPts, int srcOff,
+                                final float[] dstPts, int dstOff, int numPts)
+            throws ProjectionException
+    {
+        final boolean reverse = (srcPts == dstPts && srcOff < dstOff &&
+                                 srcOff + (2*numPts) > dstOff);
+        if (reverse) {
+            srcOff += 2*numPts;
+            dstOff += 2*numPts;
+        }
+        final Point2D.Double point = new Point2D.Double();
+        ProjectionException firstException = null;
+        while (--numPts >= 0) {
+            try {
+                point.x = srcPts[srcOff++];
+                point.y = srcPts[srcOff++];
+                transform(point, point);
+                dstPts[dstOff++] = (float) point.x;
+                dstPts[dstOff++] = (float) point.y;
+            } catch (ProjectionException exception) {
+                dstPts[dstOff++] = Float.NaN;
+                dstPts[dstOff++] = Float.NaN;
+                if (firstException == null) {
+                    firstException = exception;
+                }
+            }
+            if (reverse) {
+                srcOff -= 4;
+                dstOff -= 4;
+            }
+        }
+        if (firstException != null) {
+            throw firstException;
+        }
+    }
+
+    /**
+     * Inverse of a map projection.  Will be created by {@link MapProjection#inverse()} only when
+     * first required. Implementation of {@code transform(...)} methods are mostly identical
+     * to {@code MapProjection.transform(...)}, except that they will invokes
+     * {@link MapProjection#inverseTransformNormalized} instead of
+     * {@link MapProjection#transformNormalized}.
+     *
+     * @version $Id: MapProjection.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (PMO, IRD)
+     */
+    private final class Inverse extends AbstractMathTransform.Inverse implements MathTransform2D {
+        /**
+         * For cross-version compatibility.
+         */
+        private static final long serialVersionUID = -9138242780765956870L;
+
+        /**
+         * Default constructor.
+         */
+        public Inverse() {
+            MapProjection.this.super();
+        }
+
+        /**
+         * Inverse transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
+         * <p>
+         * This method standardizes the {@code ptSrc} by removing the {@link #falseEasting}
+         * and {@link #falseNorthing} and dividing by {@link #globalScale} before invoking
+         * <code>{@link #inverseTransformNormalized inverseTransformNormalized}(x, y, ptDst)</code>.
+         * It then adds the {@link #centralMeridian} to the {@code x} of the point returned by the
+         * {@code inverseTransformNormalized} call.
+         *
+         * @param ptSrc the specified coordinate point to be transformed.
+         *              Ordinates must be in metres.
+         * @param ptDst the specified coordinate point that stores the result of transforming
+         *              {@code ptSrc}, or {@code null}. Ordinates will be in decimal degrees.
+         * @return the coordinate point after transforming {@code ptSrc}
+         *         and stroring the result in {@code ptDst}.
+         * @throws ProjectionException if the point can't be transformed.
+         */
+        @Override
+        public final Point2D transform(final Point2D ptSrc, Point2D ptDst)
+                throws ProjectionException
+        {
+            final double x0 = ptSrc.getX();
+            final double y0 = ptSrc.getY();
+            ptDst = inverseTransformNormalized((x0 - falseEasting ) / globalScale,
+                                               (y0 - falseNorthing) / globalScale, ptDst);
+            /*
+             * Makes sure that the longitude after conversion stay within +/- PI radians. As a
+             * special case, we do not check the range if no rotation were applied on the longitude.
+             * This is because the user may have a big area ranging from -180° to +180°. With the
+             * slight rounding errors related to map projections, the 180° longitude may be slightly
+             * over the limit. Rolling the longitude would changes its sign. For example a bounding
+             * box from 30° to +180° would become 30° to -180°, which is probably not what the user
+             * wanted.
+             */
+            final double x = toDegrees(centralMeridian != 0 ?
+                             rollLongitude(ptDst.getX() + centralMeridian) : ptDst.getX());
+            final double y = toDegrees(ptDst.getY());
+            ptDst.setLocation(x,y);
+            if (verifyCoordinateRanges()) {
+                if (verifyGeographicRanges(this, x, y)) {
+                    warningLogged();
+                }
+            }
+            assert checkReciprocal(ptDst, (ptSrc!=ptDst) ? ptSrc : new Point2D.Double(x0, y0), false);
+            return ptDst;
+        }
+
+        /**
+         * Inverse transforms a list of coordinate point ordinal values.
+         * Ordinates must be (<var>x</var>,<var>y</var>) pairs in metres.
+         *
+         * @throws ProjectionException if a point can't be transformed. This method tries
+         *         to transform every points even if some of them can't be transformed.
+         *         Non-transformable points will have value {@link Double#NaN}. If more
+         *         than one point can't be transformed, then this exception may be about
+         *         an arbitrary point.
+         */
+        public final void transform(final double[] src,  int srcOffset,
+                                    final double[] dest, int dstOffset, int numPts)
+                throws TransformException
+        {
+            /*
+             * Vérifie s'il faudra parcourir le tableau en sens inverse.
+             * Ce sera le cas si les tableaux source et destination se
+             * chevauchent et que la destination est après la source.
+             */
+            final boolean reverse = (src==dest && srcOffset<dstOffset &&
+                                     srcOffset+(2*numPts) > dstOffset);
+            if (reverse) {
+                srcOffset += 2*numPts;
+                dstOffset += 2*numPts;
+            }
+            final Point2D.Double point = new Point2D.Double();
+            ProjectionException firstException = null;
+            while (--numPts>=0) {
+                try {
+                    point.x = src[srcOffset++];
+                    point.y = src[srcOffset++];
+                    transform(point, point);
+                    dest[dstOffset++] = point.x;
+                    dest[dstOffset++] = point.y;
+                } catch (ProjectionException exception) {
+                    dest[dstOffset++] = Double.NaN;
+                    dest[dstOffset++] = Double.NaN;
+                    if (firstException == null) {
+                        firstException = exception;
+                    }
+                }
+                if (reverse) {
+                    srcOffset -= 4;
+                    dstOffset -= 4;
+                }
+            }
+            if (firstException != null) {
+                throw firstException;
+            }
+        }
+
+        /**
+         * Inverse transforms a list of coordinate point ordinal values.
+         * Ordinates must be (<var>x</var>,<var>y</var>) pairs in metres.
+         *
+         * @throws ProjectionException if a point can't be transformed. This method tries
+         *         to transform every points even if some of them can't be transformed.
+         *         Non-transformable points will have value {@link Float#NaN}. If more
+         *         than one point can't be transformed, then this exception may be about
+         *         an arbitrary point.
+         */
+        @Override
+        public final void transform(final float[] src,  int srcOffset,
+                                    final float[] dest, int dstOffset, int numPts)
+                throws ProjectionException
+        {
+            final boolean reverse = (src==dest && srcOffset<dstOffset &&
+                                     srcOffset+(2*numPts) > dstOffset);
+            if (reverse) {
+                srcOffset += 2*numPts;
+                dstOffset += 2*numPts;
+            }
+            final Point2D.Double point = new Point2D.Double();
+            ProjectionException firstException = null;
+            while (--numPts>=0) {
+                try {
+                    point.x = src[srcOffset++];
+                    point.y = src[srcOffset++];
+                    transform(point, point);
+                    dest[dstOffset++] = (float) point.x;
+                    dest[dstOffset++] = (float) point.y;
+                } catch (ProjectionException exception) {
+                    dest[dstOffset++] = Float.NaN;
+                    dest[dstOffset++] = Float.NaN;
+                    if (firstException == null) {
+                        firstException = exception;
+                    }
+                }
+                if (reverse) {
+                    srcOffset -= 4;
+                    dstOffset -= 4;
+                }
+            }
+            if (firstException!=null) {
+                throw firstException;
+            }
+        }
+
+        /**
+         * Returns the original map projection.
+         */
+        @Override
+        public MathTransform2D inverse() {
+            return (MathTransform2D) super.inverse();
+        }
+    }
+
+    /**
+     * Returns the inverse of this map projection.
+     */
+    @Override
+    public final MathTransform2D inverse() throws NoninvertibleTransformException {
+        if(!invertible) {
+            throw new NoninvertibleTransformException(Errors.format(ErrorKeys.NONINVERTIBLE_TRANSFORM));
+        }
+            
+        
+        // No synchronization. Not a big deal if this method is invoked in
+        // the same time by two threads resulting in two instances created.
+        if (inverse == null) {
+            inverse = new Inverse();
+        }
+        return inverse;
+    }
+
+    /**
+     * Maximal error (in metres) tolerated for assertions, if enabled. When assertions are enabled,
+     * every direct projection is followed by an inverse projection, and the result is compared to
+     * the original coordinate. If a distance greater than the tolerance level is found, then an
+     * {@link ProjectionException} will be thrown. Subclasses should override this method if they
+     * need to relax the tolerance level.
+     *
+     * @param  longitude The longitude in decimal degrees.
+     * @param  latitude The latitude in decimal degrees.
+     * @return The tolerance level for assertions, in meters.
+     */
+    protected double getToleranceForAssertions(final double longitude, final double latitude) {
+        final double delta = abs(longitude - centralMeridian)/2 +
+                             abs(latitude  - latitudeOfOrigin);
+        if (delta > 40) {
+            // When far from the valid area, use a larger tolerance.
+            return 1;
+        }
+        // Be less strict when the point is near an edge.
+        return (abs(longitude) > 179) || (abs(latitude) > 89) ? 1E-1 : 1E-5;
+    }
+
+    /**
+     * When {@code true}, coordinate ranges will be checked, and a {@link Level#WARNING WARNING}
+     * log will be issued if they are out of their natural ranges (-180/180&deg; for longitude,
+     * -90/90&deg; for latitude).
+     * <p>
+     * To avoid excessive logging, this flag will be set to {@code false} after the first
+     * coordinate failing the checks is found.
+     */
+    final boolean verifyCoordinateRanges() {
+        /*
+         * Do not synchronize - doing so would be a major bottleneck since this method will be
+         * invoked thousands of time. The consequence is that a call to {@link #resetWarnings}
+         * may not be reflected immediately in other threads, but the later is defined only on
+         * a "best effort" basis.
+         */
+        return rangeCheckSemaphore != globalRangeCheckSemaphore;
+    }
+
+    /**
+     * To be invoked after a warning in order to disable subsequent warnings.
+     */
+    final void warningLogged() {
+        synchronized (MapProjection.class) {
+            rangeCheckSemaphore = globalRangeCheckSemaphore;
+        }
+    }
+
+    //////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                          ////////
+    ////////      IMPLEMENTATION OF Object AND MathTransform2D STANDARD METHODS       ////////
+    ////////                                                                          ////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns a hash value for this map projection.
+     */
+    @Override
+    public int hashCode() {
+        long code =      Double.doubleToLongBits(semiMajor);
+        code = code*37 + Double.doubleToLongBits(semiMinor);
+        code = code*37 + Double.doubleToLongBits(centralMeridian);
+        code = code*37 + Double.doubleToLongBits(latitudeOfOrigin);
+        return (int) code ^ (int) (code >>> 32);
+    }
+
+    /**
+     * Compares the specified object with this map projection for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        // Do not check 'object==this' here, since this
+        // optimization is usually done in subclasses.
+        if (super.equals(object)) {
+            final MapProjection that = (MapProjection) object;
+            return equals(this.semiMajor,        that.semiMajor)        &&
+                   equals(this.semiMinor,        that.semiMinor)        &&
+                   equals(this.centralMeridian,  that.centralMeridian)  &&
+                   equals(this.latitudeOfOrigin, that.latitudeOfOrigin) &&
+                   equals(this.scaleFactor,      that.scaleFactor)      &&
+                   equals(this.falseEasting,     that.falseEasting)     &&
+                   equals(this.falseNorthing,    that.falseNorthing);
+        }
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if the two specified value are equals.
+     * Two {@link Double#NaN NaN} values are considered equals.
+     */
+    static boolean equals(final double value1, final double value2) {
+        return Utilities.equals(value1, value2); 
+    }
+
+
+
+
+    //////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                          ////////
+    ////////                           FORMULAS FROM SNYDER                           ////////
+    ////////                                                                          ////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Iteratively solve equation (7-9) from Snyder.
+     */
+    final double cphi2(final double ts) throws ProjectionException {
+        final double eccnth = 0.5 * excentricity;
+        double phi = (PI/2) - 2.0 * atan(ts);
+        for (int i=0; i<MAXIMUM_ITERATIONS; i++) {
+            final double con  = excentricity * sin(phi);
+            final double dphi = (PI/2) - 2.0*atan(ts * pow((1-con)/(1+con), eccnth)) - phi;
+            phi += dphi;
+            if (abs(dphi) <= ITERATION_TOLERANCE) {
+                return phi;
+            }
+        }
+        throw new ProjectionException(ErrorKeys.NO_CONVERGENCE);
+    }
+
+    /**
+     * Computes function <code>f(s,c,e²) = c/sqrt(1 - s²&times;e²)</code> needed for the true scale
+     * latitude (Snyder 14-15), where <var>s</var> and <var>c</var> are the sine and cosine of
+     * the true scale latitude, and <var>e²</var> is the {@linkplain #excentricitySquared
+     * eccentricity squared}.
+     */
+    final double msfn(final double s, final double c) {
+        return c / sqrt(1.0 - (s*s) * excentricitySquared);
+    }
+
+    /**
+     * Computes function (15-9) and (9-13) from Snyder.
+     * Equivalent to negative of function (7-7).
+     */
+    final double tsfn(final double phi, double sinphi) {
+        sinphi *= excentricity;
+        /*
+         * NOTE: change sign to get the equivalent of Snyder (7-7).
+         */
+        return tan(0.5 * (PI/2 - phi)) / pow((1 - sinphi) / (1 + sinphi), 0.5*excentricity);
+    }
+    
+    /**
+     * Calculates the meridian distance. This is the distance along the central 
+     * meridian from the equator to {@code phi}. Accurate to < 1e-5 meters 
+     * when used in conjuction with typical major axis values.
+     *
+     * @param phi latitude to calculate meridian distance for.
+     * @param sphi sin(phi).
+     * @param cphi cos(phi).
+     * @return meridian distance for the given latitude.
+     */
+    protected final double mlfn(final double phi, double sphi, double cphi) {        
+        cphi *= sphi;
+        sphi *= sphi;
+        return en0 * phi - cphi *
+              (en1 + sphi *
+              (en2 + sphi *
+              (en3 + sphi *
+              (en4))));
+    }
+    
+    /**
+     * Calculates the latitude ({@code phi}) from a meridian distance.
+     * Determines phi to TOL (1e-11) radians, about 1e-6 seconds.
+     * 
+     * @param arg meridian distance to calulate latitude for.
+     * @return the latitude of the meridian distance.
+     * @throws ProjectionException if the itteration does not converge.
+     */
+    protected final double inv_mlfn(double arg) throws ProjectionException {
+        double s, t, phi, k = 1.0/(1.0 - excentricitySquared);
+        int i;
+        phi = arg;
+        for (i=MAXIMUM_ITERATIONS; true;) { // rarely goes over 5 iterations
+            if (--i < 0) {
+                throw new ProjectionException(Errors.format(ErrorKeys.NO_CONVERGENCE));
+            }
+            s = Math.sin(phi);
+            t = 1.0 - excentricitySquared * s * s;
+            t = (mlfn(phi, s, Math.cos(phi)) - arg) * (t * Math.sqrt(t)) * k;
+            phi -= t;
+            if (Math.abs(t) < MLFN_TOL) {
+                return phi;
+            }
+        }
+    }
+    
+    //////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                          ////////
+    ////////                                 PROVIDER                                 ////////
+    ////////                                                                          ////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * The base provider for {@link MapProjection}s.
+     *
+     * @version $Id: MapProjection.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (PMO, IRD)
+     */
+    public static abstract class AbstractProvider extends MathTransformProvider {
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID = 6280666068007678702L;
+
+        /**
+         * The operation parameter descriptor for the {@linkplain #semiMajor semi major} parameter
+         * value. Valid values range is from 0 to infinity. This parameter is mandatory.
+         *
+         * @todo Would like to start range from 0 <u>exclusive</u>.
+         */
+        public static final ParameterDescriptor SEMI_MAJOR = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,  "semi_major"),
+                    new NamedIdentifier(Citations.EPSG, "semi-major axis")
+                    // EPSG does not specifically define the above parameter
+                },
+                Double.NaN, 0, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The operation parameter descriptor for the {@linkplain #semiMinor semi minor} parameter
+         * value. Valid values range is from 0 to infinity. This parameter is mandatory.
+         *
+         * @todo Would like to start range from 0 <u>exclusive</u>.
+         */
+        public static final ParameterDescriptor SEMI_MINOR = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,  "semi_minor"),
+                    new NamedIdentifier(Citations.EPSG, "semi-minor axis")
+                    // EPSG does not specifically define the above parameter
+                },
+                Double.NaN, 0, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The operation parameter descriptor for the {@linkplain #centralMeridian central meridian}
+         * parameter value. Valid values range is from -180 to 180°. Default value is 0.
+         */
+        public static final ParameterDescriptor CENTRAL_MERIDIAN = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,     "central_meridian"),
+                    new NamedIdentifier(Citations.EPSG,    "Longitude of natural origin"),
+                    new NamedIdentifier(Citations.EPSG,    "Longitude of false origin"),
+                    new NamedIdentifier(Citations.EPSG,    "Longitude of origin"),
+                    new NamedIdentifier(Citations.ESRI,    "Longitude_Of_Center"),
+                    new NamedIdentifier(Citations.ESRI,    "longitude_of_center"),
+                    new NamedIdentifier(Citations.ESRI,    "Longitude_Of_Origin"),
+                    new NamedIdentifier(Citations.ESRI,    "longitude_of_origin"),
+                    new NamedIdentifier(Citations.GEOTIFF, "NatOriginLong")
+                    // ESRI uses "Longitude_Of_Origin" in orthographic (not to
+                    // be confused with "Longitude_Of_Center" in oblique mercator).
+                },
+                0, -180, 180, NonSI.DEGREE_ANGLE);
+
+        /**
+         * The operation parameter descriptor for the {@linkplain #latitudeOfOrigin latitude of origin}
+         * parameter value. Valid values range is from -90 to 90°. Default value is 0.
+         */
+        public static final ParameterDescriptor LATITUDE_OF_ORIGIN = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,     "latitude_of_origin"),
+                    new NamedIdentifier(Citations.EPSG,    "Latitude of false origin"),
+                    new NamedIdentifier(Citations.EPSG,    "Latitude of natural origin"),
+                    new NamedIdentifier(Citations.ESRI,    "Latitude_Of_Origin"),                   
+                    new NamedIdentifier(Citations.ESRI,    "latitude_of_origin"),
+                    new NamedIdentifier(Citations.ESRI,    "Latitude_Of_Center"),
+                    new NamedIdentifier(Citations.ESRI,    "latitude_of_center"),
+                    new NamedIdentifier(Citations.GEOTIFF, "NatOriginLat")
+                    // ESRI uses "Latitude_Of_Center" in orthographic.
+                },
+                0, -90, 90, NonSI.DEGREE_ANGLE);
+
+        /**
+         * The operation parameter descriptor for the standard parallel 1 parameter value.
+         * Valid values range is from -90 to 90°. Default value is 0.
+         */
+        public static final ParameterDescriptor STANDARD_PARALLEL_1 = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,      "standard_parallel_1"),
+                    new NamedIdentifier(Citations.EPSG,     "Latitude of 1st standard parallel"),
+                    new NamedIdentifier(Citations.ESRI,     "Standard_Parallel_1"),                    
+                    new NamedIdentifier(Citations.ESRI,     "standard_parallel_1"),
+                    new NamedIdentifier(Citations.GEOTIFF,  "StdParallel1")
+                },
+                0, -90, 90, NonSI.DEGREE_ANGLE);
+
+        /**
+         * The operation parameter descriptor for the standard parallel 2 parameter value.
+         * Valid values range is from -90 to 90°. Default value is 0.
+         */
+        public static final ParameterDescriptor STANDARD_PARALLEL_2 = createOptionalDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,      "standard_parallel_2"),
+                    new NamedIdentifier(Citations.EPSG,     "Latitude of 2nd standard parallel"),
+                    new NamedIdentifier(Citations.ESRI,     "Standard_Parallel_2"),                    
+                    new NamedIdentifier(Citations.ESRI,     "standard_parallel_2"),
+                    new NamedIdentifier(Citations.GEOTIFF,  "StdParallel2")
+                },
+                -90, 90, NonSI.DEGREE_ANGLE);
+
+        /**
+         * The operation parameter descriptor for the {@link #scaleFactor scaleFactor}
+         * parameter value. Valid values range is from 0 to infinity. Default value is 1.
+         *
+         * @todo Would like to start range from 0 <u>exclusive</u>.
+         */
+        public static final ParameterDescriptor SCALE_FACTOR = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,     "scale_factor"),
+                    new NamedIdentifier(Citations.EPSG,    "Scale factor at natural origin"),
+                    new NamedIdentifier(Citations.EPSG,    "Scale factor on initial line"),
+                    new NamedIdentifier(Citations.GEOTIFF, "ScaleAtNatOrigin"),
+                    new NamedIdentifier(Citations.GEOTIFF, "ScaleAtCenter"),
+                    new NamedIdentifier(Citations.ESRI,    "Scale_Factor"),
+                    new NamedIdentifier(Citations.ESRI,    "scale_factor"),
+                },
+                1, 0, Double.POSITIVE_INFINITY, Unit.ONE);
+
+        /**
+         * The operation parameter descriptor for the {@link #falseEasting falseEasting}
+         * parameter value. Valid values range is unrestricted. Default value is 0.
+         */
+        public static final ParameterDescriptor FALSE_EASTING = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,     "false_easting"),
+                    new NamedIdentifier(Citations.EPSG,    "False easting"),
+                    new NamedIdentifier(Citations.EPSG,    "Easting at false origin"),
+                    new NamedIdentifier(Citations.EPSG,    "Easting at projection centre"),
+                    new NamedIdentifier(Citations.GEOTIFF, "FalseEasting"),
+                    new NamedIdentifier(Citations.ESRI,    "false_easting")
+                },
+                0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The operation parameter descriptor for the {@link #falseNorthing falseNorthing}
+         * parameter value. Valid values range is unrestricted. Default value is 0.
+         */
+        public static final ParameterDescriptor FALSE_NORTHING = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,     "false_northing"),
+                    new NamedIdentifier(Citations.EPSG,    "False northing"),
+                    new NamedIdentifier(Citations.EPSG,    "Northing at false origin"),
+                    new NamedIdentifier(Citations.EPSG,    "Northing at projection centre"),
+                    new NamedIdentifier(Citations.GEOTIFF, "FalseNorthing"),
+                    new NamedIdentifier(Citations.ESRI,    "False_Northing"),
+                    new NamedIdentifier(Citations.ESRI,    "false_northing")
+                },
+                0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * Constructs a math transform provider from a set of parameters. The provider
+         * {@linkplain #getIdentifiers identifiers} will be the same than the parameter
+         * ones.
+         *
+         * @param parameters The set of parameters (never {@code null}).
+         */
+        public AbstractProvider(final ParameterDescriptorGroup parameters) {
+            super(2, 2, parameters);
+        }
+
+        /**
+         * Returns the operation type for this map projection.
+         */
+        @Override
+        public Class<? extends Projection> getOperationType() {
+            return Projection.class;
+        }
+
+        /**
+         * Returns {@code true} is the parameters use a spherical datum.
+         */
+        static boolean isSpherical(final ParameterValueGroup values) {
+            try {
+                return doubleValue(SEMI_MAJOR, values) == doubleValue(SEMI_MINOR, values);
+            } catch (IllegalStateException exception) {
+                // Probably could not find the requested values -- gobble error and be forgiving.
+                // The error will probably be thrown at MapProjection construction time, which is
+                // less surprising to some users.
+                return false;
+            }
+        }
+
+        /**
+         * Returns the parameter value for the specified operation parameter in standard units.
+         * Values are automatically converted into the standard units specified by the supplied
+         * {@code param} argument, except {@link NonSI#DEGREE_ANGLE degrees} which are converted
+         * to {@link SI#RADIAN radians}. This conversion is performed because the radians units
+         * are standard for all internal computations in the map projection package. For example
+         * they are the standard units for {@link MapProjection#latitudeOfOrigin latitudeOfOrigin}
+         * and {@link MapProjection#centralMeridian centralMeridian} fields in the
+         * {@link MapProjection} class.
+         *
+         * @param  param The parameter to look for.
+         * @param  group The parameter value group to search into.
+         * @return The requested parameter value.
+         * @throws ParameterNotFoundException if the parameter is not found.
+         */
+        protected static double doubleValue(final ParameterDescriptor param,
+                                            final ParameterValueGroup group)
+                throws ParameterNotFoundException
+        {
+            double v = MathTransformProvider.doubleValue(param, group);
+            if (NonSI.DEGREE_ANGLE.equals(param.getUnit())) {
+                v = toRadians(v);
+            }
+            return v;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/ProjectionException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/ProjectionException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/ProjectionException.java	(revision 28000)
@@ -0,0 +1,79 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.projection;
+
+import org.geotools.measure.Latitude;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.opengis.referencing.operation.TransformException;
+
+
+/**
+ * Thrown by {@link MapProjection} when a map projection failed.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/ProjectionException.java $
+ * @version $Id: ProjectionException.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author André Gosselin
+ * @author Martin Desruisseaux (IRD)
+ */
+public class ProjectionException extends TransformException {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 3031350727691500915L;
+
+    /**
+     * Constructs a new exception with no detail message.
+     */
+    public ProjectionException() {
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message.
+     *
+     * @param code One of the constants suitable for {@link Errors#format(int)}.
+     */
+    ProjectionException(final int code) {
+        this(Errors.format(code));
+    }
+
+    /**
+     * Constructs a new exception with a detail message
+     * formatted for a latitude too close from a pole.
+     */
+    ProjectionException(final double latitude) {
+        this(Errors.format(ErrorKeys.POLE_PROJECTION_$1, new Latitude(Math.toDegrees(latitude))));
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message.
+     */
+    public ProjectionException(final String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause.
+     *
+     * @since 2.5
+     */
+    public ProjectionException(final Throwable cause) {
+        super(cause.getLocalizedMessage(), cause);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/TransverseMercator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/TransverseMercator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/projection/TransverseMercator.java	(revision 28000)
@@ -0,0 +1,555 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 1999-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains formulas from the PROJ package of USGS.
+ *    USGS's work is fully acknowledged here. This derived work has
+ *    been relicensed under LGPL with Frank Warmerdam's permission.
+ */
+package org.geotools.referencing.operation.projection;
+
+import static java.lang.Math.PI;
+import static java.lang.Math.abs;
+import static java.lang.Math.asin;
+import static java.lang.Math.atan2;
+import static java.lang.Math.cos;
+import static java.lang.Math.log;
+import static java.lang.Math.sin;
+import static java.lang.Math.sinh;
+import static java.lang.Math.sqrt;
+import static java.lang.Math.tan;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.referencing.operation.transform.ConcatenatedTransform;
+import org.geotools.referencing.operation.transform.ProjectiveTransform;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.ReferenceIdentifier;
+import org.opengis.referencing.operation.CylindricalProjection;
+import org.opengis.referencing.operation.MathTransform;
+
+
+/**
+ * Transverse Mercator Projection (EPSG code 9807). This
+ * is a cylindrical projection, in which the cylinder has been rotated 90°.
+ * Instead of being tangent to the equator (or to an other standard latitude),
+ * it is tangent to a central meridian. Deformation are more important as we
+ * are going futher from the central meridian. The Transverse Mercator
+ * projection is appropriate for region wich have a greater extent north-south
+ * than east-west.
+ * <p>
+ *
+ * The elliptical equations used here are series approximations, and their accuracy
+ * decreases as points move farther from the central meridian of the projection.
+ * The forward equations here are accurate to a less than a mm &plusmn;10 degrees from
+ * the central meridian, a few mm &plusmn;15 degrees from the
+ * central meridian and a few cm &plusmn;20 degrees from the central meridian.
+ * The spherical equations are not approximations and should always give the
+ * correct values.
+ * <p>
+ *
+ * There are a number of versions of the transverse mercator projection
+ * including the Universal (UTM) and Modified (MTM) Transverses Mercator
+ * projections. In these cases the earth is divided into zones. For the UTM
+ * the zones are 6 degrees wide, numbered from 1 to 60 proceeding east from
+ * 180 degrees longitude, and between lats 84 degrees North and 80
+ * degrees South. The central meridian is taken as the center of the zone
+ * and the latitude of origin is the equator. A scale factor of 0.9996 and
+ * false easting of 500000m is used for all zones and a false northing of 10000000m
+ * is used for zones in the southern hemisphere.
+ * <p>
+ *
+ * NOTE: formulas used below are not those of Snyder, but rather those
+ *       from the {@code proj4} package of the USGS survey, which
+ *       have been reproduced verbatim. USGS work is acknowledged here.
+ * <p>
+ * <b>References:</b>
+ * <ul>
+ *   <li> Proj-4.4.6 available at <A HREF="http://www.remotesensing.org/proj">www.remotesensing.org/proj</A><br>
+ *        Relevent files are: {@code PJ_tmerc.c}, {@code pj_mlfn.c}, {@code pj_fwd.c} and {@code pj_inv.c}.</li>
+ *   <li> John P. Snyder (Map Projections - A Working Manual,
+ *        U.S. Geological Survey Professional Paper 1395, 1987).</li>
+ *   <li> "Coordinate Conversions and Transformations including Formulas",
+ *        EPSG Guidence Note Number 7, Version 19.</li>
+ * </ul>
+ *
+ * @see <A HREF="http://mathworld.wolfram.com/MercatorProjection.html">Transverse Mercator projection on MathWorld</A>
+ * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/transverse_mercator.html">"Transverse_Mercator" on RemoteSensing.org</A>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/TransverseMercator.java $
+ * @version $Id: TransverseMercator.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author André Gosselin
+ * @author Martin Desruisseaux (PMO, IRD)
+ * @author Rueben Schulz
+ */
+public class TransverseMercator extends MapProjection {
+    /**
+     * Maximum difference allowed when comparing real numbers.
+     */
+    private static final double EPSILON = 1E-6;
+
+    /**
+     * Maximum difference allowed when comparing latitudes.
+     */
+    private static final double EPSILON_LATITUDE = 1E-10;
+
+    /**
+     * A derived quantity of excentricity, computed by <code>e'² = (a²-b²)/b² = es/(1-es)</code>
+     * where <var>a</var> is the semi-major axis length and <var>b</bar> is the semi-minor axis
+     * length.
+     */
+    private final double esp;
+
+    /**
+     * Meridian distance at the {@code latitudeOfOrigin}.
+     * Used for calculations for the ellipsoid.
+     */
+    private final double ml0;
+
+    /**
+     * Contants used for the forward and inverse transform for the eliptical
+     * case of the Transverse Mercator.
+     */
+    private static final double FC1= 1.00000000000000000000000,  // 1/1
+                                FC2= 0.50000000000000000000000,  // 1/2
+                                FC3= 0.16666666666666666666666,  // 1/6
+                                FC4= 0.08333333333333333333333,  // 1/12
+                                FC5= 0.05000000000000000000000,  // 1/20
+                                FC6= 0.03333333333333333333333,  // 1/30
+                                FC7= 0.02380952380952380952380,  // 1/42
+                                FC8= 0.01785714285714285714285;  // 1/56
+
+    /**
+     * Constructs a new map projection from the supplied parameters.
+     *
+     * @param  parameters The parameter values in standard units.
+     * @throws ParameterNotFoundException if a mandatory parameter is missing.
+     */
+    protected TransverseMercator(final ParameterValueGroup parameters)
+            throws ParameterNotFoundException
+    {
+        // Fetch parameters
+        super(parameters);
+
+        //  Compute constants
+        esp = excentricitySquared / (1.0 - excentricitySquared);
+        ml0 = mlfn(latitudeOfOrigin, sin(latitudeOfOrigin), cos(latitudeOfOrigin));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return Provider.PARAMETERS;
+    }
+
+    /**
+     * Transforms the specified (<var>&lambda;</var>,<var>&phi;</var>) coordinates
+     * (units in radians) and stores the result in {@code ptDst} (linear distance
+     * on a unit sphere).
+     */
+    protected Point2D transformNormalized(double x, double y, Point2D ptDst)
+            throws ProjectionException
+    {
+        double sinphi = sin(y);
+        double cosphi = cos(y);
+
+        double t = (abs(cosphi) > EPSILON) ? sinphi/cosphi : 0;
+        t *= t;
+        double al = cosphi*x;
+        double als = al*al;
+        al /= sqrt(1.0 - excentricitySquared * sinphi*sinphi);
+        double n = esp * cosphi*cosphi;
+
+        /* NOTE: meridinal distance at latitudeOfOrigin is always 0 */
+        y = (mlfn(y, sinphi, cosphi) - ml0 +
+            sinphi * al * x *
+            FC2 * ( 1.0 +
+            FC4 * als * (5.0 - t + n*(9.0 + 4.0*n) +
+            FC6 * als * (61.0 + t * (t - 58.0) + n*(270.0 - 330.0*t) +
+            FC8 * als * (1385.0 + t * ( t*(543.0 - t) - 3111.0))))));
+
+        x = al*(FC1 + FC3 * als*(1.0 - t + n +
+            FC5 * als * (5.0 + t*(t - 18.0) + n*(14.0 - 58.0*t) +
+            FC7 * als * (61.0+ t*(t*(179.0 - t) - 479.0 )))));
+
+        if (ptDst != null) {
+            ptDst.setLocation(x,y);
+            return ptDst;
+        }
+        return new Point2D.Double(x,y);
+    }
+
+    /**
+     * Transforms the specified (<var>x</var>,<var>y</var>) coordinates
+     * and stores the result in {@code ptDst}.
+     */
+    protected Point2D inverseTransformNormalized(double x, double y, Point2D ptDst)
+            throws ProjectionException
+    {
+        double phi = inv_mlfn(ml0 + y);
+
+        if (abs(phi) >= PI/2) {
+            y = y<0.0 ? -(PI/2) : (PI/2);
+            x = 0.0;
+        } else {
+            double sinphi = sin(phi);
+            double cosphi = cos(phi);
+            double t = (abs(cosphi) > EPSILON) ? sinphi/cosphi : 0.0;
+            double n = esp * cosphi*cosphi;
+            double con = 1.0 - excentricitySquared * sinphi*sinphi;
+            double d = x * sqrt(con);
+            con *= t;
+            t *= t;
+            double ds = d*d;
+
+            y = phi - (con*ds / (1.0 - excentricitySquared)) *
+                FC2 * (1.0 - ds *
+                FC4 * (5.0 + t*(3.0 - 9.0*n) + n*(1.0 - 4*n) - ds *
+                FC6 * (61.0 + t*(90.0 - 252.0*n + 45.0*t) + 46.0*n - ds *
+                FC8 * (1385.0 + t*(3633.0 + t*(4095.0 + 1574.0*t))))));
+
+            x = d*(FC1 - ds * FC3 * (1.0 + 2.0*t + n -
+                ds*FC5*(5.0 + t*(28.0 + 24* t + 8.0*n) + 6.0*n -
+                ds*FC7*(61.0 + t*(662.0 + t*(1320.0 + 720.0*t))))))/cosphi;
+        }
+
+        if (ptDst != null) {
+            ptDst.setLocation(x,y);
+            return ptDst;
+        }
+        return new Point2D.Double(x,y);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected double getToleranceForAssertions(final double longitude, final double latitude) {
+        if (abs(longitude - centralMeridian) > 0.26) {   // 15 degrees
+            // When far from the valid area, use a larger tolerance.
+            return 2.5;
+        } else if (abs(longitude - centralMeridian) > 0.22) {  // 12.5 degrees
+            return 1.0;
+        } else if (abs(longitude - centralMeridian) > 0.17) {  // 10 degrees
+            return 0.5;
+        }
+        // a normal tolerance
+        return 1E-6;
+    }
+
+
+    /**
+     * Provides the transform equations for the spherical case of the
+     * TransverseMercator projection.
+     *
+     * @version $Id: TransverseMercator.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author André Gosselin
+     * @author Martin Desruisseaux (PMO, IRD)
+     * @author Rueben Schulz
+     */
+    private static final class Spherical extends TransverseMercator {
+        /**
+         * Constructs a new map projection from the suplied parameters.
+         *
+         * @param  parameters The parameter values in standard units.
+         * @throws ParameterNotFoundException if a mandatory parameter is missing.
+         */
+        protected Spherical(final ParameterValueGroup parameters)
+                throws ParameterNotFoundException
+        {
+            super(parameters);
+            ensureSpherical();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected Point2D transformNormalized(double x, double y, Point2D ptDst)
+                throws ProjectionException
+        {
+            // Compute using ellipsoidal formulas, for comparaison later.
+            final double normalizedLongitude = x;
+            assert (ptDst = super.transformNormalized(x, y, ptDst)) != null;
+
+            double cosphi = cos(y);
+            double b = cosphi * sin(x);
+            if (abs(abs(b) - 1.0) <= EPSILON) {
+                throw new ProjectionException(ErrorKeys.VALUE_TEND_TOWARD_INFINITY);
+            }
+
+            //Using Snyder's equation for calculating y, instead of the one used in Proj4
+            //poential problems when y and x = 90 degrees, but behaves ok in tests
+            y = atan2(tan(y), cos(x)) - latitudeOfOrigin;   /* Snyder 8-3 */
+            x = 0.5 * log((1.0+b) / (1.0-b));               /* Snyder 8-1 */
+
+            assert checkTransform(x, y, ptDst, getToleranceForSphereAssertions(normalizedLongitude));
+            if (ptDst != null) {
+                ptDst.setLocation(x,y);
+                return ptDst;
+            }
+            return new Point2D.Double(x,y);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected Point2D inverseTransformNormalized(double x, double y, Point2D ptDst)
+                throws ProjectionException
+        {
+            // Compute using ellipsoidal formulas, for comparaison later.
+            assert (ptDst = super.inverseTransformNormalized(x, y, ptDst)) != null;
+
+            double sinhX = sinh(x);
+            double cosD = cos(latitudeOfOrigin + y);
+            double phi = asin(sqrt((1.0 - cosD*cosD) / (1.0 + sinhX*sinhX)));
+            // correct for the fact that we made everything positive using sqrt(x*x)
+            y = ((y + latitudeOfOrigin)<0.0) ? -phi : phi;
+            x = (abs(sinhX) <= EPSILON  &&  abs(cosD) <= EPSILON) ? 0.0 : atan2(sinhX,cosD);
+
+            assert checkInverseTransform(x, y, ptDst, getToleranceForSphereAssertions(x));
+            if (ptDst != null) {
+                ptDst.setLocation(x,y);
+                return ptDst;
+            }
+            return new Point2D.Double(x,y);
+        }
+
+        /**
+         * Maximal error tolerated for assertions in the spherical case. When assertions
+         * are enabled, every projection using spherical formulas is followed by a projection
+         * using the ellipsical formulas, and the results are compared. If a distance greater
+         * than the tolerance level is found, then an {@link AssertionError} will be thrown.
+         * Subclasses may override this method if they need to relax the tolerance level.
+         * <p>
+         * The default implementation allows a larger tolerance when comparing spherical to
+         * elliptical calculations when we are far from the central meridian (elliptical
+         * calculations are not valid here).
+         *
+         * @param  longitude The longitude standardized (in radians) with
+         *         {@linkplain #centralMeridian} already removed from it.
+         * @return The tolerance level for assertions, in meters.
+         */
+        protected double getToleranceForSphereAssertions(final double longitude) {
+            if (abs(abs(longitude)- PI/2) < EPSILON_LATITUDE) {  // 90 degrees
+                // elliptical equations are at their worst here
+                return 1E+18;
+            }
+            if (abs(longitude) > 0.26) {   // 15 degrees
+                // When far from the valid area, use a very larger tolerance.
+                return 1E+6;
+            }
+            // a normal tolerance
+            return 1E-6;
+        }
+    }
+
+    /**
+     * Returns a hash value for this projection.
+     */
+    @Override
+    public int hashCode() {
+        final long code = Double.doubleToLongBits(ml0);
+        return ((int)code ^ (int)(code >>> 32)) + 37*super.hashCode();
+    }
+
+    /**
+     * Compares the specified object with this map projection for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            // Slight optimization
+            return true;
+        }
+        // Relevant parameters are already compared in MapProjection
+        return super.equals(object);
+    }
+
+
+
+
+    //////////////////////////////////////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                          ////////
+    ////////                                 PROVIDERS                                ////////
+    ////////                                                                          ////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * The {@linkplain org.geotools.referencing.operation.MathTransformProvider math transform
+     * provider} for a {@linkplain TransverseMercator Transverse Mercator} projection (EPSG code
+     * 9807).
+     *
+     * @since 2.1
+     * @version $Id: TransverseMercator.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (PMO, IRD)
+     * @author Rueben Schulz
+     *
+     * @see org.geotools.referencing.operation.DefaultMathTransformFactory
+     */
+    public static class Provider extends AbstractProvider {
+        /**
+         * Returns a descriptor group for the specified parameters.
+         */
+        static ParameterDescriptorGroup createDescriptorGroup(final ReferenceIdentifier[] identifiers) {
+            return createDescriptorGroup(identifiers, new ParameterDescriptor[] {
+                SEMI_MAJOR,       SEMI_MINOR,
+                CENTRAL_MERIDIAN, LATITUDE_OF_ORIGIN,
+                SCALE_FACTOR,     FALSE_EASTING,
+                FALSE_NORTHING
+            });
+        }
+
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new NamedIdentifier[] {
+                new NamedIdentifier(Citations.OGC,      "Transverse_Mercator"),
+                new NamedIdentifier(Citations.EPSG,     "Transverse Mercator"),
+                new NamedIdentifier(Citations.EPSG,     "Gauss-Kruger"),
+                new NamedIdentifier(Citations.EPSG,     "9807"),
+                new NamedIdentifier(Citations.GEOTIFF,  "CT_TransverseMercator"),
+                new NamedIdentifier(Citations.ESRI,     "Transverse_Mercator"),
+                new NamedIdentifier(Citations.ESRI,     "Gauss_Kruger"),
+                new NamedIdentifier(Citations.GEOTOOLS, Vocabulary.formatInternational(
+                                    VocabularyKeys.TRANSVERSE_MERCATOR_PROJECTION))
+            });
+
+        /**
+         * Constructs a new provider.
+         */
+        public Provider() {
+            super(PARAMETERS);
+        }
+
+        /**
+         * Constructs a new provider with the specified parameters.
+         */
+        Provider(final ParameterDescriptorGroup descriptor) {
+            super(descriptor);
+        }
+
+        /**
+         * Returns the operation type for this map projection.
+         */
+        @Override
+        public Class<CylindricalProjection> getOperationType() {
+            return CylindricalProjection.class;
+        }
+
+        /**
+         * Creates a transform from the specified group of parameter values.
+         *
+         * @param  parameters The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not found.
+         */
+        protected MathTransform createMathTransform(final ParameterValueGroup parameters)
+                throws ParameterNotFoundException
+        {
+            if (isSpherical(parameters)) {
+                return new Spherical(parameters);
+            } else {
+                return new TransverseMercator(parameters);
+            }
+        }
+    }
+
+    /**
+     * The {@linkplain org.geotools.referencing.operation.MathTransformProvider math transform
+     * provider} for a South Orientated {@linkplain TransverseMercator Transverse Mercator}
+     * projection (EPSG code 9808). Note that at the contrary of what this class name suggest,
+     * the projected coordinates are still increasing toward North. This is because all
+     * {@linkplain MapProjection map projections} in Geotools must complies with standard axis
+     * orientations. The real axis flip is performed by the CRS framework outside this package.
+     * See "<cite>Axis units and orientation</cite>" in
+     * {@linkplain org.geotools.referencing.operation.projection package description} for details.
+     * <p>
+     * The usual Transverse Mercator formulas are:
+     * <p>
+     * <ul>
+     *   <li><var>easting</var> = <var>{@linkplain #falseEasting false easting}</var> + <var>px</var></li>
+     *   <li><var>northing</var> = <var>{@linkplain #falseNorthing false northing}</var> + <var>py</var></li>
+     * </ul>
+     * <p>
+     * The Transverse Mercator South Orientated Projection formulas are:
+     * <p>
+     * <ul>
+     *   <li><var>westing</var> = <var>{@linkplain #falseEasting false easting}</var> - <var>px</var></li>
+     *   <li><var>southing</var> = <var>{@linkplain #falseNorthing false northing}</var> - <var>py</var></li>
+     * </ul>
+     * <p>
+     * Where the <var>px</var> and <var>py</var> terms are the same in both cases.
+     * Transforms created by this provider actually computes
+     * (<var>easting</var>,<var>northing</var>) = (-<var>westing</var>,-<var>southing</var>).
+     * This is equivalent to a {@link TransverseMercator} projection with
+     * {@link #falseEasting falseEasting} and {@link #falseNorthing falseNorthing} sign reverted.
+     * This operation is implemented as a concatenation of a North-orientated transverse mercator
+     * projection with an affine transform for (<var>false easting</var>,<var>false northing</var>)
+     * correction.
+     *
+     * @since 2.2
+     * @version $Id: TransverseMercator.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (PMO, IRD)
+     *
+     * @see org.geotools.referencing.operation.DefaultMathTransformFactory
+     */
+    public static class Provider_SouthOrientated extends Provider { // NO_UCD
+        /**
+         * Constructs a new provider.
+         */
+        public Provider_SouthOrientated() {
+            super(createDescriptorGroup(new NamedIdentifier[] {
+                new NamedIdentifier(Citations.EPSG, "Transverse Mercator (South Orientated)"),
+                new NamedIdentifier(Citations.EPSG, "9808")
+            }));
+        }
+
+        /**
+         * Creates a transform from the specified group of parameter values.
+         *
+         * @param  parameters The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not found.
+         */
+        @Override
+        public MathTransform createMathTransform(final ParameterValueGroup parameters)
+                throws ParameterNotFoundException
+        {
+            final MapProjection projection = (MapProjection) super.createMathTransform(parameters);
+            if (projection.falseEasting==0 && projection.falseNorthing==0) {
+                return projection;
+            }
+            final AffineTransform step = AffineTransform.getTranslateInstance(
+                    -2*projection.falseEasting, -2*projection.falseNorthing);
+            return ConcatenatedTransform.create(ProjectiveTransform.create(step), projection);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/AbstractMathTransform.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/AbstractMathTransform.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/AbstractMathTransform.java	(revision 28000)
@@ -0,0 +1,896 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.IllegalPathStateException;
+import java.awt.geom.Line2D;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.QuadCurve2D;
+import java.io.Serializable;
+
+import javax.measure.unit.NonSI;
+import javax.measure.unit.SI;
+import javax.vecmath.SingularMatrixException;
+
+import org.geotools.geometry.GeneralDirectPosition;
+import org.geotools.referencing.operation.DefaultMathTransformFactory;
+import org.geotools.referencing.operation.matrix.GeneralMatrix;
+import org.geotools.referencing.operation.matrix.Matrix1;
+import org.geotools.referencing.operation.matrix.MatrixFactory;
+import org.geotools.referencing.operation.matrix.XMatrix;
+import org.geotools.referencing.wkt.Formattable;
+import org.geotools.resources.Classes;
+import org.geotools.resources.geometry.ShapeUtilities;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.geotools.util.Utilities;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.metadata.Identifier;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.Operation;
+import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.TransformException;
+
+
+/**
+ * Provides a default implementation for most methods required by the {@link MathTransform}
+ * interface. {@code AbstractMathTransform} provides a convenient base class from which other
+ * transform classes can be easily derived. In addition, {@code AbstractMathTransform} implements
+ * methods required by the {@link MathTransform2D} interface, but <strong>does not</strong>
+ * implements {@code MathTransform2D}. Subclasses must declare {@code implements MathTransform2D}
+ * themself if they know to maps two-dimensional coordinate systems.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/AbstractMathTransform.java $
+ * @version $Id: AbstractMathTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @tutorial http://docs.codehaus.org/display/GEOTOOLS/Coordinate+Transformation+Parameters
+ */
+public abstract class AbstractMathTransform extends Formattable implements MathTransform {
+    /**
+     * Constructs a math transform.
+     */
+    protected AbstractMathTransform() {
+    }
+
+    /**
+     * Returns a name for this math transform (never {@code null}). This convenience methods
+     * returns the name of the {@linkplain #getParameterDescriptors parameter descriptors} if
+     * any, or the short class name otherwise.
+     *
+     * @return A name for this math transform (never {@code null}).
+     *
+     * @since 2.5
+     */
+    public String getName() {
+        final ParameterDescriptorGroup descriptor = getParameterDescriptors();
+        if (descriptor != null) {
+            final Identifier identifier = descriptor.getName();
+            if (identifier != null) {
+                final String code = identifier.getCode();
+                if (code != null) {
+                    return code;
+                }
+            }
+        }
+        return Classes.getShortClassName(this);
+    }
+
+    /**
+     * Gets the dimension of input points.
+     */
+    public abstract int getSourceDimensions();
+
+    /**
+     * Gets the dimension of output points.
+     */
+    public abstract int getTargetDimensions();
+
+    /**
+     * Returns the parameter descriptors for this math transform, or {@code null} if unknow. This
+     * method is similar to {@link OperationMethod#getParameters}, except that {@code MathTransform}
+     * returns parameters in standard units (usually {@linkplain SI#METER meters} or
+     * {@linkplain NonSI#DEGREE_ANGLE decimal degrees}).
+     *
+     * @return The parameter descriptors for this math transform, or {@code null}.
+     *
+     * @see OperationMethod#getParameters
+     */
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return null;
+    }
+
+    /**
+     * Returns the parameter values for this math transform, or {@code null} if unknow. This method
+     * is similar to {@link Operation#getParameterValues}, except that {@code MathTransform} returns
+     * parameters in standard units (usually {@linkplain SI#METER meters} or
+     * {@linkplain NonSI#DEGREE_ANGLE decimal degrees}). Since this method returns a copy of the
+     * parameter values, any change to a value will have no effect on this math transform.
+     *
+     * @return A copy of the parameter values for this math transform, or {@code null}.
+     *
+     * @see Operation#getParameterValues
+     */
+    public ParameterValueGroup getParameterValues() {
+        return null;
+    }
+
+    /**
+     * Tests whether this transform does not move any points.
+     * The default implementation always returns {@code false}.
+     */
+    public boolean isIdentity() {
+        return false;
+    }
+
+    /**
+     * Constructs an error message for the {@link MismatchedDimensionException}.
+     *
+     * @param argument  The argument name with the wrong number of dimensions.
+     * @param dimension The wrong dimension.
+     * @param expected  The expected dimension.
+     */
+    private static String constructMessage(final String argument,
+                                           final int   dimension,
+                                           final int    expected)
+    {
+        return Errors.format(ErrorKeys.MISMATCHED_DIMENSION_$3, argument, dimension, expected);
+    }
+
+    /**
+     * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
+     * The default implementation invokes {@link #transform(double[],int,double[],int,int)}
+     * using a temporary array of doubles.
+     *
+     * @param  ptSrc The specified coordinate point to be transformed.
+     * @param  ptDst The specified coordinate point that stores the result of transforming
+     *         {@code ptSrc}, or {@code null}.
+     * @return The coordinate point after transforming {@code ptSrc} and storing the result in
+     *         {@code ptDst}.
+     * @throws MismatchedDimensionException If this transform doesn't map two-dimensional
+     *         coordinate systems.
+     * @throws TransformException If the point can't be transformed.
+     *
+     * @see MathTransform2D#transform(Point2D,Point2D)
+     */
+    public Point2D transform(final Point2D ptSrc, final Point2D ptDst) throws TransformException {
+        int dim;
+        if ((dim = getSourceDimensions()) != 2) {
+            throw new MismatchedDimensionException(constructMessage("ptSrc", 2, dim));
+        }
+        if ((dim = getTargetDimensions()) != 2) {
+            throw new MismatchedDimensionException(constructMessage("ptDst", 2, dim));
+        }
+        final double[] ord = new double[] {ptSrc.getX(), ptSrc.getY()};
+        this.transform(ord, 0, ord, 0, 1);
+        if (ptDst != null) {
+            ptDst.setLocation(ord[0], ord[1]);
+            return ptDst;
+        } else {
+            return new Point2D.Double(ord[0], ord[1]);
+        }
+    }
+
+    /**
+     * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}. The default
+     * implementation delegates to {@link #transform(double[],int,double[],int,int)}.
+     */
+    public DirectPosition transform(final DirectPosition ptSrc, DirectPosition ptDst)
+            throws TransformException
+    {
+              int  dimPoint = ptSrc.getDimension();
+        final int dimSource = getSourceDimensions();
+        final int dimTarget = getTargetDimensions();
+        if (dimPoint != dimSource) {
+            throw new MismatchedDimensionException(constructMessage("ptSrc", dimPoint, dimSource));
+        }
+        if (ptDst != null) {
+            dimPoint = ptDst.getDimension();
+            if (dimPoint != dimTarget) {
+                throw new MismatchedDimensionException(constructMessage("ptDst", dimPoint, dimTarget));
+            }
+            /*
+             * Transforms the coordinates using a temporary 'double[]' buffer,
+             * and copy the transformation result in the destination position.
+             */
+            final double[] array;
+            if (dimSource >= dimTarget) {
+                array = ptSrc.getCoordinate();
+            } else {
+                array = new double[dimTarget];
+                for (int i=dimSource; --i>=0;) {
+                    array[i] = ptSrc.getOrdinate(i);
+                }
+            }
+            transform(array, 0, array, 0, 1);
+            for (int i=dimTarget; --i>=0;) {
+                ptDst.setOrdinate(i, array[i]);
+            }
+        } else {
+            /*
+             * Destination not set.  We are going to create the destination here.  Since we know
+             * that the destination will be the Geotools implementation, write directly into the
+             * 'ordinates' array.
+             */
+            final GeneralDirectPosition destination;
+            ptDst = destination = new GeneralDirectPosition(dimTarget);
+            final double[] source;
+            if (dimSource <= dimTarget) {
+                source = destination.ordinates;
+                for (int i=dimSource; --i>=0;) {
+                    source[i] = ptSrc.getOrdinate(i);
+                }
+            } else {
+                source = ptSrc.getCoordinate();
+            }
+            transform(source, 0, destination.ordinates, 0, 1);
+        }
+        return ptDst;
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values. The default implementation
+     * invokes {@link #transform(double[],int,double[],int,int)} using a temporary array
+     * of doubles.
+     */
+    public void transform(final float[] srcPts, final int srcOff,
+                          final float[] dstPts, final int dstOff, final int numPts)
+            throws TransformException
+    {
+        final int dimSource = getSourceDimensions();
+        final int dimTarget = getTargetDimensions();
+        final double[] tmpPts = new double[numPts * Math.max(dimSource, dimTarget)];
+        for (int i=numPts*dimSource; --i>=0;) {
+            tmpPts[i] = srcPts[srcOff+i];
+        }
+        transform(tmpPts, 0, tmpPts, 0, numPts);
+        for (int i=numPts*dimTarget; --i>=0;) {
+            dstPts[dstOff+i] = (float) tmpPts[i];
+        }
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values. The default implementation
+     * invokes {@link #transform(double[],int,double[],int,int)} using a temporary array
+     * of doubles.
+     *
+     * @since 2.5
+     */
+    public void transform(final double[] srcPts, final int srcOff,
+                          final float [] dstPts, final int dstOff, final int numPts)
+            throws TransformException
+    {
+        final int dimSource = getSourceDimensions();
+        final int dimTarget = getTargetDimensions();
+        final double[] tmpPts = new double[numPts * Math.max(dimSource, dimTarget)];
+        System.arraycopy(srcPts, srcOff, tmpPts, 0, numPts * dimSource);
+        transform(tmpPts, 0, tmpPts, 0, numPts);
+        for (int i=numPts*dimTarget; --i>=0;) {
+            dstPts[dstOff+i] = (float) tmpPts[i];
+        }
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values. The default implementation
+     * delegates to {@link #transform(double[],int,double[],int,int)}.
+     *
+     * @since 2.5
+     */
+    public void transform(final float [] srcPts, final int srcOff,
+                          final double[] dstPts, final int dstOff, final int numPts)
+            throws TransformException
+    {
+        final int dimSource = getSourceDimensions();
+        final int dimTarget = getTargetDimensions();
+        if (dimSource == dimTarget) {
+            final int n = numPts * dimSource;
+            for (int i=0; i<n; i++) {
+                dstPts[dstOff + i] = srcPts[srcOff + i];
+            }
+            transform(dstPts, dstOff, dstPts, dstOff, numPts);
+        } else {
+            final double[] tmpPts = new double[numPts*dimSource];
+            for (int i=tmpPts.length; --i>=0;) {
+                tmpPts[i] = srcPts[srcOff+i];
+            }
+            transform(tmpPts, 0, dstPts, 0, numPts);
+        }
+    }
+
+    /**
+     * Transform the specified shape. The default implementation computes
+     * quadratic curves using three points for each shape segments.
+     *
+     * @param  shape Shape to transform.
+     * @return Transformed shape, or {@code shape} if this transform is the identity transform.
+     * @throws IllegalStateException if this transform doesn't map 2D coordinate systems.
+     * @throws TransformException if a transform failed.
+     *
+     * @see MathTransform2D#createTransformedShape(Shape)
+     */
+    public Shape createTransformedShape(final Shape shape) throws TransformException {
+        return isIdentity() ? shape : createTransformedShape(shape, null, null, ShapeUtilities.PARALLEL);
+    }
+
+    /**
+     * Transforms a geometric shape. This method always copy transformed coordinates in a new
+     * object. The new object is usually a {@link GeneralPath}, but may also be a {@link Line2D}
+     * or a {@link QuadCurve2D} if such simplification is possible.
+     *
+     * @param  shape         The geometric shape to transform.
+     * @param  preTransform  An optional affine transform to apply <em>before</em> the
+     *                       transformation using {@code this}, or {@code null} if none.
+     * @param  postTransform An optional affine transform to apply <em>after</em> the transformation
+     *                       using {@code this}, or {@code null} if none.
+     * @param  orientation   Base line of quadratic curves. Must be
+     *                       {@link ShapeUtilities#HORIZONTAL} or {@link ShapeUtilities#PARALLEL}).
+     *
+     * @return The transformed geometric shape.
+     * @throws MismatchedDimensionException if this transform doesn't is not two-dimensional.
+     * @throws TransformException If a transformation failed.
+     *
+     * @todo Use double precision when we will be allowed to target Java 6.
+     */
+    final Shape createTransformedShape(final Shape           shape,
+                                       final AffineTransform preTransform,
+                                       final AffineTransform postTransform,
+                                       final int             orientation)
+            throws TransformException
+    {
+        int dim;
+        if ((dim=getSourceDimensions())!=2 || (dim=getTargetDimensions())!=2) {
+            throw new MismatchedDimensionException(constructMessage("shape", 2, dim));
+        }
+        final PathIterator    it = shape.getPathIterator(preTransform);
+        final GeneralPath   path = new GeneralPath(it.getWindingRule());
+        final Point2D.Float ctrl = new Point2D.Float();
+        final double[]    buffer = new double[6];
+
+        double ax=0, ay=0;  // Coordinate of the last point before transform.
+        double px=0, py=0;  // Coordinate of the last point after  transform.
+        for (; !it.isDone(); it.next()) {
+            switch (it.currentSegment(buffer)) {
+                default: {
+                    throw new IllegalPathStateException();
+                }
+                case PathIterator.SEG_CLOSE: {
+                    /*
+                     * Closes the geometric shape and continues the loop. We use the 'continue'
+                     * instruction here instead of 'break' because we don't want to execute the
+                     * code after the switch (addition of transformed points into the path - there
+                     * is no such point in a SEG_CLOSE).
+                     */
+                    path.closePath();
+                    continue;
+                }
+                case PathIterator.SEG_MOVETO: {
+                    /*
+                     * Transforms the single point and adds it to the path. We use the 'continue'
+                     * instruction here instead of 'break' because we don't want to execute the
+                     * code after the switch (addition of a line or a curve - there is no such
+                     * curve to add here; we are just moving the cursor).
+                     */
+                    ax = buffer[0];
+                    ay = buffer[1];
+                    transform(buffer, 0, buffer, 0, 1);
+                    px = buffer[0];
+                    py = buffer[1];
+                    path.moveTo((float) px, (float) py);
+                    continue;
+                }
+                case PathIterator.SEG_LINETO: {
+                    /*
+                     * Inserts a new control point at 'buffer[0,1]'. This control point will
+                     * be initialised with coordinates in the middle of the straight line:
+                     *
+                     *  x = 0.5*(x1+x2)
+                     *  y = 0.5*(y1+y2)
+                     *
+                     * This point will be transformed after the 'switch', which is why we use
+                     * the 'break' statement here instead of 'continue' as in previous case.
+                     */
+                    buffer[0] = 0.5*(ax + (ax=buffer[0]));
+                    buffer[1] = 0.5*(ay + (ay=buffer[1]));
+                    buffer[2] = ax;
+                    buffer[3] = ay;
+                    break;
+                }
+                case PathIterator.SEG_QUADTO: {
+                    /*
+                     * Replaces the control point in 'buffer[0,1]' by a new control point lying
+                     * on the quadratic curve. Coordinates for a point in the middle of the curve
+                     * can be computed with:
+                     *
+                     *  x = 0.5*(ctrlx + 0.5*(x1+x2))
+                     *  y = 0.5*(ctrly + 0.5*(y1+y2))
+                     *
+                     * There is no need to keep the old control point because it was not lying
+                     * on the curve.
+                     */
+                    buffer[0] = 0.5*(buffer[0] + 0.5*(ax + (ax=buffer[2])));
+                    buffer[1] = 0.5*(buffer[1] + 0.5*(ay + (ay=buffer[3])));
+                    break;
+                }
+                case PathIterator.SEG_CUBICTO: {
+                    /*
+                     * Replaces the control point in 'buffer[0,1]' by a new control point lying
+                     * on the cubic curve. Coordinates for a point in the middle of the curve
+                     * can be computed with:
+                     *
+                     *  x = 0.25*(1.5*(ctrlx1+ctrlx2) + 0.5*(x1+x2));
+                     *  y = 0.25*(1.5*(ctrly1+ctrly2) + 0.5*(y1+y2));
+                     *
+                     * There is no need to keep the old control point because it was not lying
+                     * on the curve.
+                     *
+                     * NOTE: Le point calculé est bien sur la courbe, mais n'est pas
+                     *       nécessairement représentatif. Cet algorithme remplace les
+                     *       deux points de contrôles par un seul, ce qui se traduit par
+                     *       une perte de souplesse qui peut donner de mauvais résultats
+                     *       si la courbe cubique était bien tordue. Projeter une courbe
+                     *       cubique ne me semble pas être un problème simple, mais ce
+                     *       cas devrait être assez rare. Il se produira le plus souvent
+                     *       si on essaye de projeter un cercle ou une ellipse, auxquels
+                     *       cas l'algorithme actuel donnera quand même des résultats
+                     *       tolérables.
+                     */
+                    buffer[0] = 0.25*(1.5*(buffer[0]+buffer[2]) + 0.5*(ax + (ax=buffer[4])));
+                    buffer[1] = 0.25*(1.5*(buffer[1]+buffer[3]) + 0.5*(ay + (ay=buffer[5])));
+                    buffer[2] = ax;
+                    buffer[3] = ay;
+                    break;
+                }
+            }
+            /*
+             * Applies the transform on the point in the buffer, and append the transformed points
+             * to the general path. Try to add them as a quadratic line, or as a straight line if
+             * the computed control point is colinear with the starting and ending points.
+             */
+            transform(buffer, 0, buffer, 0, 2);
+            final Point2D ctrlPoint = ShapeUtilities.parabolicControlPoint(px, py,
+                                                     buffer[0], buffer[1],
+                                                     buffer[2], buffer[3],
+                                                     orientation, ctrl);
+            px = buffer[2];
+            py = buffer[3];
+            if (ctrlPoint != null) {
+                assert ctrl == ctrlPoint;
+                path.quadTo(ctrl.x, ctrl.y, (float) px, (float) py);
+            } else {
+                path.lineTo((float) px, (float) py);
+            }
+        }
+        /*
+         * La projection de la forme géométrique est terminée. Applique
+         * une transformation affine si c'était demandée, puis retourne
+         * une version si possible simplifiée de la forme géométrique.
+         */
+        if (postTransform != null) {
+            path.transform(postTransform);
+        }
+        return ShapeUtilities.toPrimitive(path);
+    }
+
+    /**
+     * Gets the derivative of this transform at a point. The default implementation always
+     * throw an exception. Subclasses that implement the {@link MathTransform2D} interface
+     * should override this method. Other subclasses should override
+     * {@link #derivative(DirectPosition)} instead.
+     *
+     * @param  point The coordinate point where to evaluate the derivative.
+     * @return The derivative at the specified point as a 2&times;2 matrix.
+     * @throws MismatchedDimensionException if the input dimension is not 2.
+     * @throws TransformException if the derivative can't be evaluated at the specified point.
+     *
+     * @see MathTransform2D#derivative(Point2D)
+     */
+    public Matrix derivative(final Point2D point) throws TransformException {
+        final int dimSource = getSourceDimensions();
+        if (dimSource != 2) {
+            throw new MismatchedDimensionException(constructMessage("point", 2, dimSource));
+        }
+        throw new TransformException(Errors.format(ErrorKeys.CANT_COMPUTE_DERIVATIVE));
+    }
+
+    /**
+     * Gets the derivative of this transform at a point. The default implementation
+     * ensure that {@code point} has a valid dimension. Next, it try to delegate
+     * the work to an other method:
+     *
+     * <ul>
+     *   <li>If the input dimension is 2, then this method delegates the work to
+     *       {@link #derivative(Point2D)}.</li>
+     *   <li>If this object is an instance of {@link MathTransform1D}, then this
+     *       method delegates the work to {@link MathTransform1D#derivative(double)
+     *       derivative(double)}.</li>
+     * </ul>
+     *
+     * Otherwise, a {@link TransformException} is thrown.
+     *
+     * @param  point The coordinate point where to evaluate the derivative.
+     * @return The derivative at the specified point (never {@code null}).
+     * @throws NullPointerException if the derivative dependents on coordinate
+     *         and {@code point} is {@code null}.
+     * @throws MismatchedDimensionException if {@code point} doesn't have
+     *         the expected dimension.
+     * @throws TransformException if the derivative can't be evaluated at the
+     *         specified point.
+     */
+    public Matrix derivative(final DirectPosition point) throws TransformException {
+        final int dimSource = getSourceDimensions();
+        if (point == null) {
+            if (dimSource == 2) {
+                return derivative((Point2D) null);
+            }
+        } else {
+            final int dimPoint = point.getDimension();
+            if (dimPoint != dimSource) {
+                throw new MismatchedDimensionException(constructMessage("point", dimPoint, dimSource));
+            }
+            if (dimSource == 2) {
+                if (point instanceof Point2D) {
+                    return derivative((Point2D) point);
+                }
+                return derivative(new Point2D.Double(point.getOrdinate(0), point.getOrdinate(1)));
+            }
+            if (this instanceof MathTransform1D) {
+                return new Matrix1(((MathTransform1D) this).derivative(point.getOrdinate(0)));
+            }
+        }
+        throw new TransformException(Errors.format(ErrorKeys.CANT_COMPUTE_DERIVATIVE));
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     * The default implementation returns {@code this} if this transform is an identity
+     * transform, and throws a {@link NoninvertibleTransformException} otherwise. Subclasses
+     * should override this method.
+     */
+    public MathTransform inverse() throws NoninvertibleTransformException {
+        if (isIdentity()) {
+            return this;
+        }
+        throw new NoninvertibleTransformException(Errors.format(ErrorKeys.NONINVERTIBLE_TRANSFORM));
+    }
+
+    /**
+     * Concatenates in an optimized way a {@link MathTransform} {@code other} to this
+     * {@code MathTransform}. A new math transform is created to perform the combined
+     * transformation. The {@code applyOtherFirst} value determine the transformation
+     * order as bellow:
+     *
+     * <ul>
+     *   <li>If {@code applyOtherFirst} is {@code true}, then transforming a point
+     *       <var>p</var> by the combined transform is equivalent to first transforming
+     *       <var>p</var> by {@code other} and then transforming the result by the
+     *       original transform {@code this}.</li>
+     *   <li>If {@code applyOtherFirst} is {@code false}, then transforming a point
+     *       <var>p</var> by the combined transform is equivalent to first transforming
+     *       <var>p</var> by the original transform {@code this} and then transforming
+     *       the result by {@code other}.</li>
+     * </ul>
+     *
+     * If no special optimization is available for the combined transform, then this method
+     * returns {@code null}.  In the later case, the concatenation will be prepared by
+     * {@link DefaultMathTransformFactory} using a generic {@link ConcatenatedTransform}.
+     *
+     * The default implementation always returns {@code null}. This method is ought to be
+     * overridden by subclasses capable of concatenating some combinaison of transforms in a
+     * special way. Examples are {@link ExponentialTransform1D} and {@link LogarithmicTransform1D}.
+     *
+     * @param  other The math transform to apply.
+     * @param  applyOtherFirst {@code true} if the transformation order is {@code other}
+     *         followed by {@code this}, or {@code false} if the transformation order is
+     *         {@code this} followed by {@code other}.
+     * @return The combined math transform, or {@code null} if no optimized combined
+     *         transform is available.
+     */
+    MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst) {
+        return null;
+    }
+
+    /**
+     * Returns a hash value for this transform.
+     */
+    @Override
+    public int hashCode() {
+        return getSourceDimensions() + 37*getTargetDimensions();
+    }
+
+    /**
+     * Compares the specified object with this math transform for equality.
+     * The default implementation checks if {@code object} is an instance
+     * of the same class than {@code this} and use the same parameter descriptor.
+     * Subclasses should override this method in order to compare internal fields.
+     *
+     * @param object The object to compare with this transform.
+     * @return {@code true} if the given object is a transform of the same class
+     *         and if, given identical source position, the
+     *         {@linkplain #transform(DirectPosition,DirectPosition) transformed}
+     *         position would be the equals.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        // Do not check 'object==this' here, since this
+        // optimization is usually done in subclasses.
+        if (object!=null && getClass().equals(object.getClass())) {
+            final AbstractMathTransform that = (AbstractMathTransform) object;
+            return Utilities.equals(this.getParameterDescriptors(),
+                                    that.getParameterDescriptors());
+        }
+        return false;
+    }
+
+    /**
+     * Checks if source coordinates need to be copied before to apply the transformation.
+     * This convenience method is provided for {@code transform(...)} method implementation.
+     * This method make the following assumptions:
+     * <P>
+     * <UL>
+     *   <LI>Coordinates will be iterated from lower index to upper index.</LI>
+     *   <LI>Coordinates are read and writen in shrunk. For example (longitude,latitude,height)
+     *       values for one coordinate are read together, and the transformed (x,y,z) values are
+     *       written together only after.</LI>
+     * </UL>
+     * <P>
+     * However, this method does not assumes that source and target dimension are the same (in the
+     * special case where source and target dimension are always the same, a simplier and more
+     * efficient check is possible). The following example prepares a transformation from 2
+     * dimensional points to three dimensional points:
+     * <P>
+     * <blockquote><pre>
+     * public void transform(double[] srcPts, int srcOff,
+     *                       double[] dstPts, int dstOff, int numPts)
+     * {
+     *     if (srcPts==dstPts && <strong>needCopy</strong>(srcOff, 2, dstOff, 3, numPts) {
+     *         final double[] old = srcPts;
+     *         srcPts = new double[numPts*2];
+     *         System.arraycopy(old, srcOff, srcPts, 0, srcPts.length);
+     *         srcOff = 0;
+     *     }
+     * }</pre><blockquote>
+     *
+     * <strong>This method is for internal usage by the referencing module only. Do not use!
+     * It will be replaced by a different mechanism in a future GeoTools version.</strong>
+     *
+     * @param srcOff The offset in the source coordinate array.
+     * @param dimSource The dimension of input points.
+     * @param dstOff The offset in the destination coordinate array.
+     * @param dimTarget The dimension of output points.
+     * @param numPts The number of points to transform.
+     * @return {@code true} if the source coordinates should be copied before to apply the
+     *         transformation in order to avoid an overlap with the destination array.
+     */
+    protected static boolean needCopy(final int srcOff, final int dimSource,
+                                      final int dstOff, final int dimTarget, final int numPts)
+    {
+        if (numPts <= 1  ||  (srcOff >= dstOff  &&  dimSource >= dimTarget)) {
+            /*
+             * Source coordinates are stored after target coordinates. If implementation
+             * read coordinates from lower index to upper index, then the destination will
+             * not overwrite the source coordinates, even if there is an overlaps.
+             */
+            return false;
+        }
+        return srcOff  <  dstOff + numPts*dimTarget &&
+               dstOff  <  srcOff + numPts*dimSource;
+    }
+
+    /**
+     * Ensures that the specified longitude stay within &plusmn;&pi; radians. This method
+     * is typically invoked after geographic coordinates are transformed. This method may add
+     * or substract some amount of 2&pi; radians to <var>x</var>.
+     *
+     * @param  x The longitude in radians.
+     * @return The longitude in the range &plusmn;&pi; radians.
+     */
+    protected static double rollLongitude(final double x) {
+        return x - (2*Math.PI) * Math.floor(x / (2*Math.PI) + 0.5);
+    }
+
+    /**
+     * Wraps the specified matrix in a Geotools implementation of {@link Matrix}. If {@code matrix}
+     * is already an instance of {@code XMatrix}, then it is returned unchanged. Otherwise, all
+     * elements are copied in a new {@code XMatrix} object.
+     */
+    static XMatrix toXMatrix(final Matrix matrix) {
+        if (matrix instanceof XMatrix) {
+            return (XMatrix) matrix;
+        }
+        return MatrixFactory.create(matrix);
+    }
+
+    /**
+     * Wraps the specified matrix in a Geotools implementation of {@link Matrix}. If {@code matrix}
+     * is already an instance of {@code GeneralMatrix}, then it is returned unchanged. Otherwise,
+     * all elements are copied in a new {@code GeneralMatrix} object.
+     * <p>
+     * Before to use this method, check if a {@link XMatrix} (to be obtained with {@link #toXMatrix})
+     * would be suffisient. Use this method only if a {@code GeneralMatrix} is really necessary.
+     */
+    static GeneralMatrix toGMatrix(final Matrix matrix) {
+        if (matrix instanceof GeneralMatrix) {
+            return (GeneralMatrix) matrix;
+        } else {
+            return new GeneralMatrix(matrix);
+        }
+    }
+
+    /**
+     * Inverts the specified matrix in place. If the matrix can't be inverted (for example
+     * because of a {@link SingularMatrixException}), then the exception is wrapped into a
+     * {@link NoninvertibleTransformException}.
+     */
+    static Matrix invert(final Matrix matrix) throws NoninvertibleTransformException {
+        try {
+            final XMatrix m = toXMatrix(matrix);
+            m.invert();
+            return m;
+        } catch (SingularMatrixException exception) {
+            NoninvertibleTransformException e = new NoninvertibleTransformException(
+                        Errors.format(ErrorKeys.NONINVERTIBLE_TRANSFORM));
+            e.initCause(exception);
+            throw e;
+        }
+    }
+
+    /**
+     * Default implementation for inverse math transform. This inner class is the inverse
+     * of the enclosing {@link MathTransform}. It is serializable only if the enclosing
+     * math transform is also serializable.
+     *
+     * @since 2.0
+     * @version $Id: AbstractMathTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     */
+    protected abstract class Inverse extends AbstractMathTransform implements Serializable {
+        /**
+         * Serial number for interoperability with different versions. This serial number is
+         * especilly important for inner classes, since the default {@code serialVersionUID}
+         * computation will not produce consistent results across implementations of different
+         * Java compiler. This is because different compilers may generate different names for
+         * synthetic members used in the implementation of inner classes. See:
+         *
+         * http://developer.java.sun.com/developer/bugParade/bugs/4211550.html
+         */
+        private static final long serialVersionUID = 3528274816628012283L;
+
+        /**
+         * Constructs an inverse math transform.
+         */
+        protected Inverse() {
+        }
+
+        /**
+         * Returns a name for this math transform (never {@code null}). The default implementation
+         * returns the direct transform name concatenated with localized flavor (when available)
+         * of "(Inverse transform)".
+         *
+         * @return A name for this math transform (never {@code null}).
+         *
+         * @since 2.5
+         */
+        @Override
+        public String getName() {
+            return AbstractMathTransform.this.getName() +
+                    " (" + Vocabulary.format(VocabularyKeys.INVERSE_TRANSFORM) + ')';
+        }
+
+        /**
+         * Gets the dimension of input points. The default
+         * implementation returns the dimension of output
+         * points of the enclosing math transform.
+         */
+        public int getSourceDimensions() {
+            return AbstractMathTransform.this.getTargetDimensions();
+        }
+
+        /**
+         * Gets the dimension of output points. The default
+         * implementation returns the dimension of input
+         * points of the enclosing math transform.
+         */
+        public int getTargetDimensions() {
+            return AbstractMathTransform.this.getSourceDimensions();
+        }
+
+        /**
+         * Gets the derivative of this transform at a point. The default
+         * implementation compute the inverse of the matrix returned by
+         * the enclosing math transform.
+         */
+        @Override
+        public Matrix derivative(final Point2D point) throws TransformException {
+            return invert(AbstractMathTransform.this.derivative(this.transform(point, null)));
+        }
+
+        /**
+         * Gets the derivative of this transform at a point. The default
+         * implementation compute the inverse of the matrix returned by
+         * the enclosing math transform.
+         */
+        @Override
+        public Matrix derivative(final DirectPosition point) throws TransformException {
+            return invert(AbstractMathTransform.this.derivative(this.transform(point, null)));
+        }
+
+        /**
+         * Returns the inverse of this math transform, which is the enclosing math transform.
+         * This behavior should not be changed since some implementation assume that the inverse
+         * of {@code this} is always {@code AbstractMathTransform.this}.
+         */
+        @Override
+        public MathTransform inverse() {
+            return AbstractMathTransform.this;
+        }
+
+        /**
+         * Tests whether this transform does not move any points.
+         * The default implementation delegate this tests to the
+         * enclosing math transform.
+         */
+        @Override
+        public boolean isIdentity() {
+            return AbstractMathTransform.this.isIdentity();
+        }
+
+        /**
+         * Returns a hash code value for this math transform.
+         */
+        @Override
+        public int hashCode() {
+            return ~AbstractMathTransform.this.hashCode();
+        }
+
+        /**
+         * Compares the specified object with this inverse math transform for equality.
+         * The default implementation tests if {@code object} in an instance of the same
+         * class than {@code this}, and then test their enclosing math transforms.
+         */
+        @Override
+        public boolean equals(final Object object) {
+            if (object == this) {
+                // Slight optimization
+                return true;
+            }
+            if (object instanceof Inverse) {
+                final Inverse that = (Inverse) object;
+                return Utilities.equals(this.inverse(), that.inverse());
+            } else {
+                return false;
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/AffineTransform2D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/AffineTransform2D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/AffineTransform2D.java	(revision 28000)
@@ -0,0 +1,196 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+
+import org.geotools.geometry.GeneralDirectPosition;
+import org.geotools.referencing.operation.LinearTransform;
+import org.geotools.referencing.operation.matrix.Matrix2;
+import org.geotools.referencing.operation.matrix.Matrix3;
+import org.geotools.referencing.operation.matrix.XAffineTransform;
+import org.geotools.resources.Formattable;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.util.Cloneable;
+
+
+/**
+ * Transforms two-dimensional coordinate points using an affine transform. This class both
+ * extends {@link AffineTransform} and implements {@link MathTransform2D}, so it can be
+ * used as a bridge between Java2D and the referencing module.
+ *
+ * @since 2.5
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/AffineTransform2D.java $
+ * @version $Id: AffineTransform2D.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class AffineTransform2D extends XAffineTransform
+        implements MathTransform2D, LinearTransform, Formattable, Cloneable
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -5299837898367149069L;
+
+    /**
+     * The inverse transform. This field will be computed only when needed.
+     */
+    private transient AffineTransform2D inverse;
+
+    /**
+     * Constructs a new affine transform with the same coefficient than the specified transform.
+     */
+    public AffineTransform2D(final AffineTransform transform) {
+        super(transform);
+    }
+
+    /**
+     * Throws an {@link UnsupportedOperationException} when a mutable method
+     * is invoked, since {@code AffineTransform2D} must be immutable.
+     */
+    @Override
+    protected final void checkPermission() throws UnsupportedOperationException {
+        super.checkPermission();
+    }
+
+    /**
+     * Gets the dimension of input points, which is fixed to 2.
+     */
+    public final int getSourceDimensions() {
+        return 2;
+    }
+
+    /**
+     * Gets the dimension of output points, which is fixed to 2.
+     */
+    public final int getTargetDimensions() {
+        return 2;
+    }
+
+    /**
+     * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
+     */
+    public DirectPosition transform(final DirectPosition ptSrc, DirectPosition ptDst) {
+        if (ptDst == null) {
+            ptDst = new GeneralDirectPosition(2);
+        } else {
+            final int dimension = ptDst.getDimension();
+            if (dimension != 2) {
+                throw new MismatchedDimensionException(Errors.format(
+                          ErrorKeys.MISMATCHED_DIMENSION_$3, "ptDst", dimension, 2));
+            }
+        }
+        final double[] array = ptSrc.getCoordinate();
+        transform(array, 0, array, 0, 1);
+        ptDst.setOrdinate(0, array[0]);
+        ptDst.setOrdinate(1, array[1]);
+        return ptDst;
+    }
+
+    /**
+     * Transforms the specified shape.
+     *
+     * @param  shape Shape to transform.
+     * @return Transformed shape, or {@code shape} if this transform is the identity transform.
+     */
+    @Override
+    public Shape createTransformedShape(final Shape shape) {
+        return transform(this, shape, false);
+    }
+
+    /**
+     * Returns this transform as an affine transform matrix.
+     */
+    public Matrix getMatrix() {
+        return new Matrix3(this);
+    }
+
+    /**
+     * Gets the derivative of this transform at a point. For an affine transform,
+     * the derivative is the same everywhere.
+     */
+    public Matrix derivative(final Point2D point) {
+        return new Matrix2(getScaleX(), getShearX(),
+                           getShearY(), getScaleY());
+    }
+
+    /**
+     * Gets the derivative of this transform at a point. For an affine transform,
+     * the derivative is the same everywhere.
+     */
+    public Matrix derivative(final DirectPosition point) {
+        return derivative((Point2D) null);
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     *
+     * @throws NoninvertibleTransformException if this transform can't be inverted.
+     */
+    public MathTransform2D inverse() throws NoninvertibleTransformException {
+        if (inverse == null) {
+            if (isIdentity()) {
+                inverse = this;
+            } else try {
+                synchronized (this) {
+                    inverse = new AffineTransform2D(createInverse());
+                    inverse.inverse = this;
+                }
+            } catch (java.awt.geom.NoninvertibleTransformException exception) {
+                throw new NoninvertibleTransformException(exception.getLocalizedMessage(), exception);
+            }
+        }
+        return inverse;
+    }
+
+    /**
+     * Returns a new affine transform which is a modifiable copy of this transform. We override
+     * this method because it is {@linkplain AffineTransform#clone defined in the super-class}.
+     * However this implementation do not returns a new {@code AffineTransform2D} instance because
+     * the later is unmodifiable, which make exact cloning useless.
+     */
+    @Override
+    public AffineTransform clone() {
+        return new AffineTransform(this);
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof AffineTransform)) {
+            return false;
+        }
+
+        AffineTransform a = (AffineTransform) obj;
+        
+        return Utilities.equals(getScaleX(), a.getScaleX()) &&
+            Utilities.equals(getScaleY(), a.getScaleY()) &&
+            Utilities.equals(getShearX(), a.getShearX()) &&
+            Utilities.equals(getShearY(), a.getShearY()) &&
+            Utilities.equals(getTranslateX(), a.getTranslateX()) &&
+            Utilities.equals(getTranslateY(), a.getTranslateY());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransform.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransform.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransform.java	(revision 28000)
@@ -0,0 +1,603 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.io.Serializable;
+
+import org.geotools.geometry.GeneralDirectPosition;
+import org.geotools.referencing.operation.LinearTransform;
+import org.geotools.referencing.operation.matrix.GeneralMatrix;
+import org.geotools.referencing.operation.matrix.Matrix3;
+import org.geotools.referencing.operation.matrix.XMatrix;
+import org.geotools.resources.Classes;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.TransformException;
+
+
+/**
+ * Base class for concatenated transform. Concatenated transforms are
+ * serializable if all their step transforms are serializables.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/ConcatenatedTransform.java $
+ * @version $Id: ConcatenatedTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class ConcatenatedTransform extends AbstractMathTransform implements Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 5772066656987558634L;
+
+    /**
+     * Small number for floating point comparaisons.
+     */
+    private static final double EPSILON = 1E-10;
+
+    /**
+     * Maximum length of temporary {@double[]} arrays to be created, used for performing
+     * transformations in batch. A value of 256 will consumes 2 kilobytes of memory. It is
+     * better to avoid too high values since allocating and initializing the array elements
+     * to zero have a cost.
+     */
+    private static final int TEMPORARY_ARRAY_LENGTH = 256;
+
+    /**
+     * The first math transform.
+     */
+    public final MathTransform transform1;
+
+    /**
+     * The second math transform.
+     */
+    public final MathTransform transform2;
+
+    /**
+     * The inverse transform. This field will be computed only when needed.
+     * But it is serialized in order to avoid rounding error if the inverse
+     * transform is serialized instead of the original one.
+     */
+    private ConcatenatedTransform inverse;
+
+    /**
+     * Constructs a concatenated transform. This constructor is for subclasses only. To
+     * create a concatenated transform, use the factory method {@link #create} instead.
+     *
+     * @param transform1 The first math transform.
+     * @param transform2 The second math transform.
+     */
+    protected ConcatenatedTransform(final MathTransform transform1,
+                                    final MathTransform transform2)
+    {
+        this.transform1 = transform1;
+        this.transform2 = transform2;
+        if (!isValid()) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.CANT_CONCATENATE_TRANSFORMS_$2,
+                      getName(transform1), getName(transform2)));
+        }
+    }
+
+    /**
+     * Returns the underlying matrix for the specified transform,
+     * or {@code null} if the matrix is unavailable.
+     */
+    private static XMatrix getMatrix(final MathTransform transform) {
+        if (transform instanceof LinearTransform) {
+            return toXMatrix(((LinearTransform) transform).getMatrix());
+        }
+        if (transform instanceof AffineTransform) {
+            return new Matrix3((AffineTransform) transform);
+        }
+        return null;
+    }
+
+    /**
+     * Tests if one math transform is the inverse of the other. This implementation
+     * can't detect every case. It just detect the case when {@code tr2} is an
+     * instance of {@link AbstractMathTransform.Inverse}.
+     *
+     * @todo We could make this test more general (just compare with tr2.inverse(),
+     *       no matter if it is an instance of AbstractMathTransform.Inverse or not,
+     *       and catch the exception if one is thrown). Would it be too expensive to
+     *       create inconditionnaly the inverse transform?
+     */
+    private static boolean areInverse(final MathTransform tr1, final MathTransform tr2) {
+        if (tr2 instanceof AbstractMathTransform.Inverse) {
+            return tr1.equals(((AbstractMathTransform.Inverse) tr2).inverse());
+        }
+        return false;
+    }
+
+    /**
+     * Constructs a concatenated transform.  This factory method checks for step transforms
+     * dimension. The returned transform will implements {@link MathTransform2D} if source and
+     * target dimensions are equal to 2.  Likewise, it will implements {@link MathTransform1D}
+     * if source and target dimensions are equal to 1.  {@link MathTransform} implementations
+     * are available in two version: direct and non-direct. The "non-direct" version use an
+     * intermediate buffer when performing transformations; they are slower and consume more
+     * memory. They are used only as a fallback when a "direct" version can't be created.
+     *
+     * @param tr1 The first math transform.
+     * @param tr2 The second math transform.
+     * @return    The concatenated transform.
+     *
+     * @todo We could add one more optimisation: if one transform is a matrix and the
+     *       other transform is a PassThroughTransform, and if the matrix as 0 elements
+     *       for all rows matching the PassThrough sub-transform, then we can get ride
+     *       of the whole PassThroughTransform object.
+     */
+    public static MathTransform create(MathTransform tr1, MathTransform tr2) {
+        final int dim1 = tr1.getTargetDimensions();
+        final int dim2 = tr2.getSourceDimensions();
+        if (dim1 != dim2) {
+            throw new IllegalArgumentException(
+                      Errors.format(ErrorKeys.CANT_CONCATENATE_TRANSFORMS_$2,
+                                    getName(tr1), getName(tr2)) + ' ' +
+                      Errors.format(ErrorKeys.MISMATCHED_DIMENSION_$2, dim1, dim2));
+        }
+        MathTransform mt = createOptimized(tr1, tr2);
+        if (mt != null) {
+            return mt;
+        }
+        /*
+         * If at least one math transform is an instance of ConcatenatedTransform and assuming
+         * that MathTransforms are associatives, tries the following arrangements and select
+         * one one with the fewest amount of steps:
+         *
+         *   Assuming :  tr1 = (A * B)
+         *               tr2 = (C * D)
+         *
+         *   Current  :  (A * B) * (C * D)     Will be the selected one if nothing better.
+         *   Try k=0  :  A * (B * (C * D))     Implies A * ((B * C) * D) through recursivity.
+         *   Try k=1  :  ((A * B) * C) * D     Implies (A * (B * C)) * D through recursivity.
+         *   Try k=2  :                        Tried only if try k=1 changed something.
+         *
+         * TODO: The same combinaison may be computed more than once (e.g. (B * C) above).
+         *       Should not be a big deal if there is not two many steps. In the even where
+         *       it would appears a performance issue, we could maintains a Map of combinaisons
+         *       already computed. The map would be local to a "create" method execution.
+         */
+        int stepCount = getStepCount(tr1) + getStepCount(tr2);
+        boolean tryAgain = true; // Really 'true' because we want at least 2 iterations.
+        for (int k=0; ; k++) {
+            MathTransform c1 = tr1;
+            MathTransform c2 = tr2;
+            final boolean first = (k & 1) == 0;
+            MathTransform candidate = first ? c1 : c2;
+            while (candidate instanceof ConcatenatedTransform) {
+                final ConcatenatedTransform ctr = (ConcatenatedTransform) candidate;
+                if (first) {
+                    c1 = candidate = ctr.transform1;
+                    c2 = create(ctr.transform2, c2);
+                } else {
+                    c1 = create(c1, ctr.transform1);
+                    c2 = candidate = ctr.transform2;
+                }
+                final int c = getStepCount(c1) + getStepCount(c2);
+                if (c < stepCount) {
+                    tr1 = c1;
+                    tr2 = c2;
+                    stepCount = c;
+                    tryAgain = true;
+                }
+            }
+            if (!tryAgain) break;
+            tryAgain = false;
+        }
+        /*
+         * Tries again the check for optimized cases (identity, etc.), because a
+         * transform may have been simplified to identity as a result of the above.
+         */
+        mt = createOptimized(tr1, tr2);
+        if (mt != null) {
+            return mt;
+        }
+        /*
+         * Can't avoid the creation of a ConcatenatedTransform object.
+         * Check for the type to create (1D, 2D, general case...)
+         */
+        return createConcatenatedTransform(tr1, tr2);
+    }
+
+    /**
+     * Tries to returns an optimized concatenation, for example by merging to affine transforms
+     * into a single one. If no optimized cases has been found, returns {@code null}. In the later
+     * case, the caller will need to create a more heavy {@link ConcatenatedTransform} instance.
+     */
+    private static MathTransform createOptimized(final MathTransform tr1, final MathTransform tr2) {
+        /*
+         * Trivial - but actually essential!! - check for the identity cases.
+         */
+        if (tr1.isIdentity()) return tr2;
+        if (tr2.isIdentity()) return tr1;
+        /*
+         * If both transforms use matrix, then we can create
+         * a single transform using the concatenated matrix.
+         */
+        final XMatrix matrix1 = getMatrix(tr1);
+        if (matrix1 != null) {
+            final XMatrix matrix2 = getMatrix(tr2);
+            if (matrix2 != null) {
+                // Compute "matrix = matrix2 * matrix1". Reuse an existing matrix object
+                // if possible, which is always the case when both matrix are square.
+                final int numRow = matrix2.getNumRow();
+                final int numCol = matrix1.getNumCol();
+                final XMatrix matrix;
+                if (numCol == matrix2.getNumCol()) {
+                    matrix = matrix2;
+                    matrix2.multiply(matrix1);
+                } else {
+                    final GeneralMatrix m = new GeneralMatrix(numRow, numCol);
+                    m.mul(toGMatrix(matrix2), toGMatrix(matrix1));
+                    matrix = m;
+                }
+                if (matrix.isIdentity(EPSILON)) {
+                    matrix.setIdentity();
+                }
+                // May not be really affine, but work anyway...
+                // This call will detect and optimize the special
+                // case where an 'AffineTransform' can be used.
+                return ProjectiveTransform.create(matrix);
+            }
+        }
+        /*
+         * If one transform is the inverse of the
+         * other, returns the identity transform.
+         */
+        if (areInverse(tr1, tr2) || areInverse(tr2, tr1)) {
+            assert tr1.getSourceDimensions() == tr2.getTargetDimensions();
+            assert tr1.getTargetDimensions() == tr2.getSourceDimensions();
+            return IdentityTransform.create(tr1.getSourceDimensions());
+        }
+        /*
+         * Gives a chance to AbstractMathTransform to returns an optimized object.
+         * The main use case is Logarithmic vs Exponential transforms.
+         */
+        if (tr1 instanceof AbstractMathTransform) {
+            final MathTransform optimized = ((AbstractMathTransform) tr1).concatenate(tr2, false);
+            if (optimized != null) {
+                return optimized;
+            }
+        }
+        if (tr2 instanceof AbstractMathTransform) {
+            final MathTransform optimized = ((AbstractMathTransform) tr2).concatenate(tr1, true);
+            if (optimized != null) {
+                return optimized;
+            }
+        }
+        // No optimized case found.
+        return null;
+    }
+
+    /**
+     * Continue the construction started by {@link #create}. The construction step is available
+     * separatly for testing purpose (in a JUnit test), and for {@link #inverse()} implementation.
+     */
+    static ConcatenatedTransform createConcatenatedTransform(final MathTransform tr1,
+                                                             final MathTransform tr2)
+    {
+        final int dimSource = tr1.getSourceDimensions();
+        final int dimTarget = tr2.getTargetDimensions();
+        /*
+         * Checks if the result need to be a MathTransform1D.
+         */
+        if (dimSource == 1 && dimTarget == 1) {
+            if (tr1 instanceof MathTransform1D && tr2 instanceof MathTransform1D) {
+                return new ConcatenatedTransformDirect1D((MathTransform1D) tr1,
+                                                         (MathTransform1D) tr2);
+            } else {
+                return new ConcatenatedTransform1D(tr1, tr2);
+            }
+        } else
+        /*
+         * Checks if the result need to be a MathTransform2D.
+         */
+        if (dimSource == 2 && dimTarget == 2) {
+            if (tr1 instanceof MathTransform2D && tr2 instanceof MathTransform2D) {
+                return new ConcatenatedTransformDirect2D((MathTransform2D) tr1,
+                                                         (MathTransform2D) tr2);
+            } else {
+                return new ConcatenatedTransform2D(tr1, tr2);
+            }
+        } else
+        /*
+         * Checks for the general case.
+         */
+        if (dimSource == tr1.getTargetDimensions() && tr2.getSourceDimensions() == dimTarget) {
+            return new ConcatenatedTransformDirect(tr1, tr2);
+        } else {
+            return new ConcatenatedTransform(tr1, tr2);
+        }
+    }
+
+    /**
+     * Returns a name for the specified math transform.
+     */
+    private static final String getName(final MathTransform transform) {
+        if (transform instanceof AbstractMathTransform) {
+            ParameterValueGroup params = ((AbstractMathTransform) transform).getParameterValues();
+            if (params != null) {
+                String name = params.getDescriptor().getName().getCode();
+                if (name!=null && (name=name.trim()).length()!=0) {
+                    return name;
+                }
+            }
+        }
+        return Classes.getShortClassName(transform);
+    }
+
+    /**
+     * Checks if transforms are compatibles. The default
+     * implementation check if transfert dimension match.
+     */
+    boolean isValid() {
+        return transform1.getTargetDimensions() == transform2.getSourceDimensions();
+    }
+
+    /**
+     * Gets the dimension of input points.
+     */
+    public final int getSourceDimensions() {
+        return transform1.getSourceDimensions();
+    }
+
+    /**
+     * Gets the dimension of output points.
+     */
+    public final int getTargetDimensions() {
+        return transform2.getTargetDimensions();
+    }
+
+    /**
+     * Returns the number of {@linkplain MathTransform math transform} steps performed by this
+     * concatenated transform.
+     *
+     * @return The number of transform steps.
+     *
+     * @since 2.5
+     */
+    public final int getStepCount() {
+        return getStepCount(transform1) + getStepCount(transform2);
+    }
+
+    /**
+     * Returns the number of {@linkplain MathTransform math transform} steps performed by the
+     * given transform. As a special case, we returns 0 for the identity transform since it
+     * should be omitted from the final chain.
+     */
+    private static int getStepCount(final MathTransform transform) {
+        if (transform.isIdentity()) {
+            return 0;
+        }
+        if (!(transform instanceof ConcatenatedTransform)) {
+            return 1;
+        }
+        return ((ConcatenatedTransform) transform).getStepCount();
+    }
+
+    /**
+     * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
+     */
+    @Override
+    public DirectPosition transform(final DirectPosition ptSrc, final DirectPosition ptDst)
+            throws TransformException
+    {
+        assert isValid();
+        //  Note: If we know that the transfert dimension is the same than source
+        //        and target dimension, then we don't need to use an intermediate
+        //        point. This optimization is done in ConcatenatedTransformDirect.
+        return transform2.transform(transform1.transform(ptSrc, null), ptDst);
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values. The source points are first
+     * transformed by {@link #transform1}, then the intermediate points are transformed
+     * by {@link #transform2}. The transformations are performed without intermediate
+     * buffer if it can be avoided.
+     */
+    public void transform(final double[] srcPts, int srcOff,
+                          final double[] dstPts, int dstOff, int numPts)
+            throws TransformException
+    {
+        assert isValid();
+        final int intermDim = transform1.getTargetDimensions();
+        final int targetDim = getTargetDimensions();
+        /*
+         * If the transfert dimension is not greater than the target dimension, then we
+         * don't need to use an intermediate buffer. Note that this optimization is done
+         * inconditionnaly in ConcatenatedTransformDirect.
+         */
+        if (intermDim <= targetDim) {
+            transform1.transform(srcPts, srcOff, dstPts, dstOff, numPts);
+            transform2.transform(dstPts, dstOff, dstPts, dstOff, numPts);
+            return;
+        }
+        if (numPts <= 0) {
+            return;
+        }
+        /*
+         * Creates a temporary array for the intermediate result. The array may be smaller than
+         * the length necessary for containing every coordinates. In such case the concatenated
+         * transform will need to be applied piecewise.
+         */
+        int numTmp = numPts;
+        int length = numTmp * intermDim;
+        if (length > TEMPORARY_ARRAY_LENGTH) {
+            numTmp = Math.max(1, TEMPORARY_ARRAY_LENGTH / intermDim);
+            length = numTmp * intermDim;
+        }
+        final double[] tmp = new double[length];
+        final int sourceDim = getSourceDimensions();
+        do {
+            if (numTmp > numPts) {
+                numTmp = numPts;
+            }
+            transform1.transform(srcPts, srcOff, tmp, 0, numTmp);
+            transform2.transform(tmp, 0, dstPts, dstOff, numTmp);
+            srcOff += numTmp * sourceDim;
+            dstOff += numTmp * targetDim;
+            numPts -= numTmp;
+        } while (numPts != 0);
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values. The source points are first copied
+     * in a temporary array of type {@code double[]}, transformed by {@link #transform1} first,
+     * then by {@link #transform2} and finally the result is casted to {@code float} primitive
+     * type and stored in the destination array. The use of {@code double} primitive type for
+     * intermediate results is necesssary for reducing rounding errors.
+     */
+    @Override
+    public void transform(final float[] srcPts, int srcOff,
+                          final float[] dstPts, int dstOff, int numPts)
+            throws TransformException
+    {
+        assert isValid();
+        if (numPts <= 0) {
+            return;
+        }
+        final int sourceDim = getSourceDimensions();
+        final int targetDim = getTargetDimensions();
+        final int intermDim = transform1.getTargetDimensions();
+        final int dimension = Math.max(Math.max(sourceDim, targetDim), intermDim);
+        int numTmp = numPts;
+        int length = numTmp * dimension;
+        if (length > TEMPORARY_ARRAY_LENGTH) {
+            numTmp = Math.max(1, TEMPORARY_ARRAY_LENGTH / dimension);
+            length = numTmp * dimension;
+        }
+        final double[] tmp = new double[length];
+        do {
+            if (numTmp > numPts) {
+                numTmp = numPts;
+            }
+            length = numTmp * sourceDim;
+            for (int i=0; i<length; i++) {
+                tmp[i] = srcPts[srcOff++];
+            }
+            transform1.transform(tmp, 0, tmp, 0, numTmp);
+            transform2.transform(tmp, 0, tmp, 0, numTmp);
+            length = numTmp * targetDim;
+            for (int i=0; i<length; i++) {
+                dstPts[dstOff++] = (float) tmp[i];
+            }
+            numPts -= numTmp;
+        } while (numPts != 0);
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public synchronized MathTransform inverse() throws NoninvertibleTransformException {
+        assert isValid();
+        if (inverse == null) {
+            inverse = createConcatenatedTransform(transform2.inverse(), transform1.inverse());
+            inverse.inverse = this;
+        }
+        return inverse;
+    }
+
+    /**
+     * Gets the derivative of this transform at a point. This method delegates to the
+     * {@link #derivative(DirectPosition)} method because the transformation steps
+     * {@link #transform1} and {@link #transform2} may not be instances of
+     * {@link MathTransform2D}.
+     *
+     * @param  point The coordinate point where to evaluate the derivative.
+     * @return The derivative at the specified point as a 2&times;2 matrix.
+     * @throws TransformException if the derivative can't be evaluated at the specified point.
+     */
+    @Override
+    public Matrix derivative(final Point2D point) throws TransformException {
+        return derivative(new GeneralDirectPosition(point));
+    }
+
+    /**
+     * Gets the derivative of this transform at a point.
+     *
+     * @param  point The coordinate point where to evaluate the derivative.
+     * @return The derivative at the specified point (never {@code null}).
+     * @throws TransformException if the derivative can't be evaluated at the specified point.
+     */
+    @Override
+    public Matrix derivative(final DirectPosition point) throws TransformException {
+        final Matrix matrix1 = transform1.derivative(point);
+        final Matrix matrix2 = transform2.derivative(transform1.transform(point, null));
+        // Compute "matrix = matrix2 * matrix1". Reuse an existing matrix object
+        // if possible, which is always the case when both matrix are square.
+        final int numRow = matrix2.getNumRow();
+        final int numCol = matrix1.getNumCol();
+        final XMatrix matrix;
+        if (numCol == matrix2.getNumCol()) {
+            matrix = toXMatrix(matrix2);
+            matrix.multiply(matrix1);
+        } else {
+            final GeneralMatrix m = new GeneralMatrix(numRow, numCol);
+            m.mul(toGMatrix(matrix2), toGMatrix(matrix1));
+            matrix = m;
+        }
+        return matrix;
+    }
+
+    /**
+     * Tests whether this transform does not move any points.
+     * Default implementation check if the two transforms are
+     * identity.
+     */
+    @Override
+    public final boolean isIdentity() {
+        return transform1.isIdentity() && transform2.isIdentity();
+    }
+
+    /**
+     * Returns a hash value for this transform.
+     */
+    @Override
+    public final int hashCode() {
+        return transform1.hashCode() + 37*transform2.hashCode();
+    }
+
+    /**
+     * Compares the specified object with this math transform for equality.
+     */
+    @Override
+    public final boolean equals(final Object object) {
+        if (object == this) {
+            // Slight optimization
+            return true;
+        }
+        if (super.equals(object)) {
+            final ConcatenatedTransform that = (ConcatenatedTransform) object;
+            return Utilities.equals(this.transform1, that.transform1) &&
+                   Utilities.equals(this.transform2, that.transform2);
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransform1D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransform1D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransform1D.java	(revision 28000)
@@ -0,0 +1,86 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import org.geotools.geometry.DirectPosition1D;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+
+
+/**
+ * Concatenated transform in which the resulting transform is one-dimensional.
+ *
+ * @since 2.0
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/ConcatenatedTransform1D.java $
+ * @version $Id: ConcatenatedTransform1D.java 30641 2008-06-12 17:42:27Z acuster $
+ * @author Martin Desruisseaux (IRD)
+ */
+final class ConcatenatedTransform1D extends ConcatenatedTransform implements MathTransform1D {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 8150427971141078395L;
+
+    /**
+     * Constructs a concatenated transform.
+     */
+    public ConcatenatedTransform1D(final MathTransform transform1,
+                                   final MathTransform transform2)
+    {
+        super(transform1, transform2);
+    }
+
+    /**
+     * Checks if transforms are compatibles with this implementation.
+     */
+    @Override
+    boolean isValid() {
+        return super.isValid() && getSourceDimensions()==1 && getTargetDimensions()==1;
+    }
+
+    /**
+     * Transforms the specified value.
+     */
+    public double transform(final double value) throws TransformException {
+        final double[] values = new double[] {value};
+        final double[] buffer = new double[] {transform1.getTargetDimensions()};
+        transform1.transform(values, 0, buffer, 0, 1);
+        transform2.transform(buffer, 0, values, 0, 1);
+        return values[0];
+    }
+
+    /**
+     * Gets the derivative of this function at a value.
+     */
+    public double derivative(final double value) throws TransformException {
+        final DirectPosition1D p = new DirectPosition1D(value);
+        final Matrix m = derivative(p);
+        assert m.getNumRow()==1 && m.getNumCol()==1;
+        return m.getElement(0,0);
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public MathTransform1D inverse() throws NoninvertibleTransformException {
+        return (MathTransform1D) super.inverse();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransform2D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransform2D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransform2D.java	(revision 28000)
@@ -0,0 +1,62 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+
+
+/**
+ * Concatenated transform in which the resulting transform is two-dimensional.
+ *
+ * @since 2.0
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/ConcatenatedTransform2D.java $
+ * @version $Id: ConcatenatedTransform2D.java 30641 2008-06-12 17:42:27Z acuster $
+ * @author Martin Desruisseaux (IRD)
+ */
+final class ConcatenatedTransform2D extends ConcatenatedTransform implements MathTransform2D {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -7307709788564866500L;
+
+    /**
+     * Constructs a concatenated transform.
+     */
+    public ConcatenatedTransform2D(final MathTransform transform1,
+                                   final MathTransform transform2)
+    {
+        super(transform1, transform2);
+    }
+
+    /**
+     * Checks if transforms are compatibles with this implementation.
+     */
+    @Override
+    boolean isValid() {
+        return super.isValid() && getSourceDimensions()==2 && getTargetDimensions()==2;
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public MathTransform2D inverse() throws NoninvertibleTransformException {
+        return (MathTransform2D) super.inverse();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransformDirect.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransformDirect.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransformDirect.java	(revision 28000)
@@ -0,0 +1,87 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.geometry.DirectPosition;
+
+
+/**
+ * Concatenated transform where the transfert dimension is the same than source and target
+ * dimension. This fact allows some optimizations, the most important one being the possibility
+ * to avoid the use of an intermediate buffer in some case.
+ *
+ * @since 2.0
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/ConcatenatedTransformDirect.java $
+ * @version $Id: ConcatenatedTransformDirect.java 30641 2008-06-12 17:42:27Z acuster $
+ * @author Martin Desruisseaux (IRD)
+ */
+class ConcatenatedTransformDirect extends ConcatenatedTransform {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -3568975979013908920L;
+
+    /**
+     * Constructs a concatenated transform.
+     */
+    public ConcatenatedTransformDirect(final MathTransform transform1,
+                                       final MathTransform transform2)
+    {
+        super(transform1, transform2);
+    }
+
+    /**
+     * Checks if transforms are compatibles with this implementation.
+     */
+    @Override
+    boolean isValid() {
+        return super.isValid() &&
+               transform1.getSourceDimensions() == transform1.getTargetDimensions() &&
+               transform2.getSourceDimensions() == transform2.getTargetDimensions();
+    }
+
+    /**
+     * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
+     */
+    @Override
+    public DirectPosition transform(final DirectPosition ptSrc, DirectPosition ptDst)
+            throws TransformException
+    {
+        assert isValid();
+        ptDst = transform1.transform(ptSrc, ptDst);
+        return  transform2.transform(ptDst, ptDst);
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    @Override
+    public void transform(final double[] srcPts, final int srcOff,
+                          final double[] dstPts, final int dstOff, final int numPts)
+            throws TransformException
+    {
+        assert isValid();
+        transform1.transform(srcPts, srcOff, dstPts, dstOff, numPts);
+        transform2.transform(dstPts, dstOff, dstPts, dstOff, numPts);
+    }
+
+    // Do NOT override the transform(float[]...) version because we really need to use an
+    // intermediate buffer of type double[] for reducing rounding error. Otherwise some map
+    // projection degrades image quality in an unacceptable way.
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransformDirect1D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransformDirect1D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransformDirect1D.java	(revision 28000)
@@ -0,0 +1,96 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+
+
+/**
+ * Concatenated transform where both transforms are one-dimensional.
+ *
+ * @since 2.0
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/ConcatenatedTransformDirect1D.java $
+ * @version $Id: ConcatenatedTransformDirect1D.java 30641 2008-06-12 17:42:27Z acuster $
+ * @author Martin Desruisseaux (IRD)
+ */
+final class ConcatenatedTransformDirect1D extends ConcatenatedTransformDirect
+                                       implements MathTransform1D
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 1064398659892864966L;
+
+    /**
+     * The first math transform. This field is identical
+     * to {@link ConcatenatedTransform#transform1}. Only
+     * the type is different.
+     */
+    private final MathTransform1D transform1;
+
+    /**
+     * The second math transform. This field is identical
+     * to {@link ConcatenatedTransform#transform1}. Only
+     * the type is different.
+     */
+    private final MathTransform1D transform2;
+
+    /**
+     * Constructs a concatenated transform.
+     */
+    public ConcatenatedTransformDirect1D(final MathTransform1D transform1,
+                                         final MathTransform1D transform2)
+    {
+        super(transform1, transform2);
+        this.transform1 = transform1;
+        this.transform2 = transform2;
+    }
+
+    /**
+     * Checks if transforms are compatibles with this implementation.
+     */
+    @Override
+    boolean isValid() {
+        return super.isValid() && getSourceDimensions()==1 && getTargetDimensions()==1;
+    }
+
+    /**
+     * Transforms the specified value.
+     */
+    public double transform(final double value) throws TransformException {
+        return transform2.transform(transform1.transform(value));
+    }
+
+    /**
+     * Gets the derivative of this function at a value.
+     */
+    public double derivative(final double value) throws TransformException {
+        final double value1 = transform1.derivative(value);
+        final double value2 = transform2.derivative(transform1.transform(value));
+        return value2 * value1;
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public MathTransform1D inverse() throws NoninvertibleTransformException {
+        return (MathTransform1D) super.inverse();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransformDirect2D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransformDirect2D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConcatenatedTransformDirect2D.java	(revision 28000)
@@ -0,0 +1,121 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.awt.Shape;
+import java.awt.geom.Point2D;
+
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+
+import org.geotools.referencing.operation.matrix.XMatrix;
+
+
+/**
+ * Concatenated transform where both transforms are two-dimensional.
+ *
+ * @since 2.0
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/ConcatenatedTransformDirect2D.java $
+ * @version $Id: ConcatenatedTransformDirect2D.java 30641 2008-06-12 17:42:27Z acuster $
+ * @author Martin Desruisseaux (IRD)
+ */
+final class ConcatenatedTransformDirect2D extends ConcatenatedTransformDirect
+                                       implements MathTransform2D
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 6009454091075588885L;
+
+    /**
+     * The first math transform. This field is identical
+     * to {@link ConcatenatedTransform#transform1}. Only
+     * the type is different.
+     */
+    private final MathTransform2D transform1;
+
+    /**
+     * The second math transform. This field is identical
+     * to {@link ConcatenatedTransform#transform1}. Only
+     * the type is different.
+     */
+    private final MathTransform2D transform2;
+
+    /**
+     * Constructs a concatenated transform.
+     */
+    public ConcatenatedTransformDirect2D(final MathTransform2D transform1,
+                                         final MathTransform2D transform2)
+    {
+        super(transform1, transform2);
+        this.transform1 = transform1;
+        this.transform2 = transform2;
+    }
+
+    /**
+     * Checks if transforms are compatibles with this implementation.
+     */
+    @Override
+    boolean isValid() {
+        return super.isValid() && getSourceDimensions()==2 && getTargetDimensions()==2;
+    }
+
+    /**
+     * Transforms the specified {@code ptSrc}
+     * and stores the result in {@code ptDst}.
+     */
+    @Override
+    public Point2D transform(final Point2D ptSrc, Point2D ptDst) throws TransformException {
+        assert isValid();
+        ptDst = transform1.transform(ptSrc, ptDst);
+        return  transform2.transform(ptDst, ptDst);
+    }
+
+    /**
+     * Transforms the specified shape.
+     */
+    @Override
+    public Shape createTransformedShape(final Shape shape) throws TransformException {
+        assert isValid();
+        return transform2.createTransformedShape(transform1.createTransformedShape(shape));
+    }
+
+    /**
+     * Gets the derivative of this transform at a point.
+     *
+     * @param  point The coordinate point where to evaluate the derivative.
+     * @return The derivative at the specified point (never {@code null}).
+     * @throws TransformException if the derivative can't be evaluated at the specified point.
+     */
+    @Override
+    public Matrix derivative(final Point2D point) throws TransformException {
+        final XMatrix matrix1 = toXMatrix(transform1.derivative(point));
+        final XMatrix matrix2 = toXMatrix(transform2.derivative(transform1.transform(point,null)));
+        matrix2.multiply(matrix1);
+        return matrix2;
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public MathTransform2D inverse() throws NoninvertibleTransformException {
+        return (MathTransform2D) super.inverse();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConstantTransform1D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConstantTransform1D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ConstantTransform1D.java	(revision 28000)
@@ -0,0 +1,75 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.util.Arrays;
+
+
+/**
+ * A one dimensional, constant transform. Output values are set to a constant value regardless
+ * of input values. This class is really a special case of {@link LinearTransform1D} in which
+ * <code>{@link #scale} = 0</code> and <code>{@link #offset} = constant</code>. However, this
+ * specialized {@code ConstantTransform1D} class is faster.
+ *
+ * @since 2.0
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/ConstantTransform1D.java $
+ * @version $Id: ConstantTransform1D.java 30641 2008-06-12 17:42:27Z acuster $
+ * @author Martin Desruisseaux (IRD)
+ */
+final class ConstantTransform1D extends LinearTransform1D {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -1583675681650985947L;
+
+    /**
+     * Constructs a new constant transform.
+     *
+     * @param offset The {@code offset} term in the linear equation.
+     */
+    protected ConstantTransform1D(final double offset) {
+        super(0, offset);
+    }
+
+    /**
+     * Transforms the specified value.
+     */
+    @Override
+    public double transform(double value) {
+        return offset;
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    @Override
+    public void transform(final float[] srcPts, int srcOff,
+                          final float[] dstPts, int dstOff, int numPts)
+    {
+        Arrays.fill(dstPts, dstOff, dstOff+numPts, (float)offset);
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    @Override
+    public void transform(final double[] srcPts, int srcOff,
+                          final double[] dstPts, int dstOff, int numPts)
+    {
+        Arrays.fill(dstPts, dstOff, dstOff+numPts, offset);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ExponentialTransform1D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ExponentialTransform1D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ExponentialTransform1D.java	(revision 28000)
@@ -0,0 +1,391 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.io.Serializable;
+import javax.measure.unit.Unit;
+
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransform1D;
+
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.parameter.DefaultParameterDescriptor;
+import org.geotools.parameter.FloatParameter;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.referencing.operation.LinearTransform;
+import org.geotools.referencing.operation.MathTransformProvider;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.geotools.resources.i18n.Vocabulary;
+
+
+/**
+ * A one dimensional exponentional transform.
+ * Input values <var>x</var> are converted into
+ * output values <var>y</var> using the following equation:
+ *
+ * <p align="center"><var>y</var> &nbsp;=&nbsp;
+ * {@linkplain #scale}&times;{@linkplain #base}<sup><var>x</var></sup></p>
+ *
+ * This equation may be written in other form:
+ *
+ * <p align="center">{@linkplain #base}<sup><var>a</var> + <var>b</var>&times;<var>x</var></sup> &nbsp;=&nbsp;
+ * {@linkplain #base}<sup><var>a</var></sup>&times;({@linkplain #base}<sup><var>b</var></sup>)<sup><var>x</var></sup></p>
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/ExponentialTransform1D.java $
+ * @version $Id: ExponentialTransform1D.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see LogarithmicTransform1D
+ * @see LinearTransform1D
+ */
+public class ExponentialTransform1D extends AbstractMathTransform
+        implements MathTransform1D, Serializable
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 5331178990358868947L;
+
+    /**
+     * The base to be raised to a power.
+     */
+    public final double base;
+
+    /**
+     * Natural logarithm of {@link #base}.
+     */
+    final double lnBase;
+
+    /**
+     * The scale value to be multiplied.
+     */
+    public final double scale;
+
+    /**
+     * The inverse of this transform. Created only when first needed.
+     * Serialized in order to avoid rounding error if this transform
+     * is actually the one which was created from the inverse.
+     */
+    private MathTransform1D inverse;
+
+    /**
+     * Constructs a new exponentional transform which is the
+     * inverse of the supplied logarithmic transform.
+     */
+    ExponentialTransform1D(final LogarithmicTransform1D inverse) {
+        this.base     = inverse.base;
+        this.lnBase   = inverse.lnBase;
+        this.scale    = Math.pow(base, -inverse.offset);
+        this.inverse  = inverse;
+    }
+
+    /**
+     * Constructs a new exponentional transform. This constructor is provided for subclasses only.
+     * Instances should be created using the {@linkplain #create factory method}, which
+     * may returns optimized implementations for some particular argument values.
+     *
+     * @param base   The base to be raised to a power.
+     * @param scale  The scale value to be multiplied.
+     */
+    protected ExponentialTransform1D(final double base, final double scale) {
+        this.base   = base;
+        this.scale  = scale;
+        this.lnBase = Math.log(base);
+    }
+
+    /**
+     * Constructs a new exponentional transform.
+     *
+     * @param base   The base to be raised to a power.
+     * @param scale  The scale value to be multiplied.
+     * @return The math transform.
+     */
+    public static MathTransform1D create(final double base, final double scale) {
+        if (base == 0 || scale == 0) {
+            return LinearTransform1D.create(0, 0);
+        }
+        if (base == 1) {
+            return LinearTransform1D.create(0, scale);
+        }
+        return new ExponentialTransform1D(base, scale);
+    }
+
+    /**
+     * Returns the parameter descriptors for this math transform.
+     */
+    @Override
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return Provider.PARAMETERS;
+    }
+
+    /**
+     * Returns the parameter values for this math transform.
+     *
+     * @return A copy of the parameter values for this math transform.
+     */
+    @Override
+    public ParameterValueGroup getParameterValues() {
+        return new org.geotools.parameter.ParameterGroup(getParameterDescriptors(),
+            new ParameterValue[] {
+            new FloatParameter(Provider.BASE,  base),
+            new FloatParameter(Provider.SCALE, scale)});
+    }
+
+    /**
+     * Gets the dimension of input points, which is 1.
+     */
+    public int getSourceDimensions() {
+        return 1;
+    }
+
+    /**
+     * Gets the dimension of output points, which is 1.
+     */
+    public int getTargetDimensions() {
+        return 1;
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public MathTransform1D inverse() {
+        if (inverse == null) {
+            inverse = LogarithmicTransform1D.create(this);
+        }
+        return inverse;
+    }
+
+    /**
+     * Gets the derivative of this function at a value.
+     */
+    public double derivative(final double value) {
+        return lnBase * transform(value);
+    }
+
+    /**
+     * Transforms the specified value.
+     */
+    public double transform(final double value) {
+        return scale * Math.pow(base, value);
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    @Override
+    public void transform(float[] srcPts, int srcOff,
+                          float[] dstPts, int dstOff, int numPts)
+    {
+        if (srcPts!=dstPts || srcOff>=dstOff) {
+            while (--numPts >= 0) {
+                dstPts[dstOff++] = (float) (scale*Math.pow(base, srcPts[srcOff++]));
+            }
+        } else {
+            srcOff += numPts;
+            dstOff += numPts;
+            while (--numPts >= 0) {
+                dstPts[--dstOff] = (float) (scale*Math.pow(base, srcPts[--srcOff]));
+            }
+        }
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    public void transform(final double[] srcPts, int srcOff,
+                          final double[] dstPts, int dstOff, int numPts)
+    {
+        if (srcPts!=dstPts || srcOff>=dstOff) {
+            while (--numPts >= 0) {
+                dstPts[dstOff++] = scale*Math.pow(base, srcPts[srcOff++]);
+            }
+        } else {
+            srcOff += numPts;
+            dstOff += numPts;
+            while (--numPts >= 0) {
+                dstPts[--dstOff] = scale*Math.pow(base, srcPts[--srcOff]);
+            }
+        }
+    }
+
+    /**
+     * Concatenates in an optimized way a {@link MathTransform} {@code other} to this
+     * {@code MathTransform}. This implementation can optimize some concatenation with
+     * {@link LinearTransform1D} and {@link LogarithmicTransform1D}.
+     *
+     * @param  other The math transform to apply.
+     * @param  applyOtherFirst {@code true} if the transformation order is {@code other}
+     *         followed by {@code this}, or {@code false} if the transformation order is
+     *         {@code this} followed by {@code other}.
+     * @return The combined math transform, or {@code null} if no optimized combined
+     *         transform is available.
+     */
+    @Override
+    MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst) {
+        if (other instanceof LinearTransform) {
+            final LinearTransform1D linear = (LinearTransform1D) other;
+            if (applyOtherFirst) {
+                final double newBase  = Math.pow(base, linear.scale);
+                final double newScale = Math.pow(base, linear.offset)*scale;
+                if (!Double.isNaN(newBase) && !Double.isNaN(newScale)) {
+                    return create(newBase, newScale);
+                }
+            } else {
+                if (linear.offset == 0) {
+                    return create(base, scale*linear.scale);
+                }
+            }
+        } else if (other instanceof LogarithmicTransform1D) {
+            return concatenateLog((LogarithmicTransform1D) other, applyOtherFirst);
+        }
+        return super.concatenate(other, applyOtherFirst);
+    }
+
+    /**
+     * Concatenates in an optimized way a {@link LogarithmicTransform1D} {@code other} to this
+     * {@code ExponentialTransform1D}.
+     *
+     * @param  other The math transform to apply.
+     * @param  applyOtherFirst {@code true} if the transformation order is {@code other}
+     *         followed by {@code this}, or {@code false} if the transformation order is
+     *         {@code this} followed by {@code other}.
+     * @return The combined math transform, or {@code null} if no optimized combined
+     *         transform is available.
+     */
+    MathTransform concatenateLog(final LogarithmicTransform1D other, final boolean applyOtherFirst) {
+        if (applyOtherFirst) {
+            final double newScale = scale*Math.pow(base, other.offset);
+            final double newPower = lnBase/other.lnBase;
+            if (!Double.isNaN(newScale)) {
+                if (newPower == 1) {
+                    return LinearTransform1D.create(newScale, 0);
+                }
+                // TODO: Needs a transform here with the following equation:
+                //
+                //       y(x)  =  newScale * Math.pow(x, newPower);
+            }
+        } else if (scale > 0) {
+            return LinearTransform1D.create(lnBase/other.lnBase,
+                                   Math.log(scale)/other.lnBase + other.offset);
+        }
+        return null;
+    }
+
+    /**
+     * Returns a hash value for this transform.
+     * This value need not remain consistent between
+     * different implementations of the same class.
+     */
+    @Override
+    public int hashCode() {
+        long code;
+        code = serialVersionUID + Double.doubleToLongBits(base);
+        code = code*37          + Double.doubleToLongBits(scale);
+        return (int)(code >>> 32) ^ (int)code;
+    }
+
+    /**
+     * Compares the specified object with this math transform for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object==this) {
+            // Slight optimization
+            return true;
+        }
+        if (super.equals(object)) {
+            final ExponentialTransform1D that = (ExponentialTransform1D) object;
+            return Double.doubleToLongBits(this.base)  == Double.doubleToLongBits(that.base) &&
+                   Double.doubleToLongBits(this.scale) == Double.doubleToLongBits(that.scale);
+        }
+        return false;
+    }
+
+    /**
+     * The provider for the {@link ExponentialTransform1D}.
+     *
+     * @version $Id: ExponentialTransform1D.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     */
+    public static class Provider extends MathTransformProvider {
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID = -5838840021166379987L;
+
+        /**
+         * The operation parameter descriptor for the {@link #base base} parameter value.
+         * Valid values range from 0 to infinity. The default value is 10.
+         */
+        public static final ParameterDescriptor BASE = LogarithmicTransform1D.Provider.BASE;
+
+        /**
+         * The operation parameter descriptor for the {@link #scale scale} parameter value.
+         * Valid values range is unrestricted. The default value is 1.
+         */
+        public static final ParameterDescriptor SCALE = DefaultParameterDescriptor.create(
+                "scale", 1, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Unit.ONE);
+
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new NamedIdentifier[] {
+                new NamedIdentifier(Citations.GEOTOOLS, Vocabulary.formatInternational(
+                                                        VocabularyKeys.EXPONENTIAL))
+            }, new ParameterDescriptor[] {
+                BASE, SCALE
+            });
+
+        /**
+         * Create a provider for logarithmic transforms.
+         */
+        public Provider() {
+            super(1, 1, PARAMETERS);
+        }
+
+        /**
+         * Returns the operation type.
+         */
+        @Override
+        public Class<Conversion> getOperationType() {
+            return Conversion.class;
+        }
+
+        /**
+         * Creates a logarithmic transform from the specified group of parameter values.
+         *
+         * @param  values The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not found.
+         */
+        protected MathTransform1D createMathTransform(final ParameterValueGroup values)
+                throws ParameterNotFoundException
+        {
+            return create(doubleValue(BASE,  values),
+                          doubleValue(SCALE, values));
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/GeocentricTransform.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/GeocentricTransform.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/GeocentricTransform.java	(revision 28000)
@@ -0,0 +1,755 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.util.Collections;
+
+import javax.measure.converter.UnitConverter;
+import javax.measure.quantity.Length;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.parameter.DefaultParameterDescriptor;
+import org.geotools.parameter.FloatParameter;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.referencing.operation.MathTransformProvider;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+
+
+/**
+ * Transforms three dimensional {@linkplain org.geotools.referencing.crs.DefaultGeographicCRS
+ * geographic} points to {@linkplain org.geotools.referencing.crs.DefaultGeocentricCRS geocentric}
+ * coordinate points. Input points must be longitudes, latitudes and heights above the ellipsoid.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/GeocentricTransform.java $
+ * @version $Id: GeocentricTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Frank Warmerdam
+ * @author Martin Desruisseaux (IRD)
+ */
+public class GeocentricTransform extends AbstractMathTransform implements Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -3352045463953828140L;
+
+    /**
+     * Maximal error tolerance in metres during assertions, in metres. If assertions
+     * are enabled (JDK 1.4 only), then every coordinates transformed with
+     * {@link #inverseTransform} will be transformed again with {@link #mathTransform}.
+     * If the distance between the resulting position and the original position
+     * is greater than {@code MAX_ERROR}, then a {@link AssertionError} is thrown.
+     */
+    private static final double MAX_ERROR = 0.01;
+
+    /**
+     * Cosine of 67.5 decimal degrees.
+     */
+    private static final double COS_67P5 = 0.38268343236508977;
+
+    /**
+     * Toms region 1 constant.
+     */
+    private static final double AD_C = 1.0026000;
+
+    /**
+     * Semi-major axis of ellipsoid in meters.
+     */
+    private final double a;
+
+    /**
+     * Semi-minor axis of ellipsoid in meters.
+     */
+    private final double b;
+
+    /**
+     * Square of semi-major axis (<var>a</var>²).
+     */
+    private final double a2;
+
+    /**
+     * Square of semi-minor axis (<var>b</var>²).
+     */
+    private final double b2;
+
+    /**
+     * Eccentricity squared.
+     */
+    private final double e2;
+
+    /**
+     * 2nd eccentricity squared.
+     */
+    private final double ep2;
+
+    /**
+     * {@code true} if geographic coordinates include an ellipsoidal
+     * height (i.e. are 3-D), or {@code false} if they are strictly 2-D.
+     */
+    private final boolean hasHeight;
+
+    /**
+     * The inverse of this transform. Will be created only when needed.
+     */
+    private transient MathTransform inverse;
+
+    /**
+     * Constructs a transform from the specified parameters.
+     *
+     * @param semiMajor The semi-major axis length.
+     * @param semiMinor The semi-minor axis length.
+     * @param units     The axis units.
+     * @param hasHeight {@code true} if geographic coordinates
+     *                  include an ellipsoidal height (i.e. are 3-D),
+     *                  or {@code false} if they are only 2-D.
+     */
+    public GeocentricTransform(final double  semiMajor,
+                               final double  semiMinor,
+                               final Unit<Length> units,
+                               final boolean hasHeight)
+    {
+        this.hasHeight = hasHeight;
+        final UnitConverter converter = units.getConverterTo(SI.METER);
+        a   = converter.convert(semiMajor);
+        b   = converter.convert(semiMinor);
+        a2  = a*a;
+        b2  = b*b;
+        e2  = (a2 - b2) / a2;
+        ep2 = (a2 - b2) / b2;
+        checkArgument("a", a, Double.MAX_VALUE);
+        checkArgument("b", b, a);
+    }
+
+    /**
+     * Checks an argument value. The argument must be greater
+     * than 0 and finite, otherwise an exception is thrown.
+     *
+     * @param name  The argument name.
+     * @param value The argument value.
+     * @param max   The maximal legal argument value.
+     */
+    private static void checkArgument(final String name,
+                                      final double value,
+                                      final double max) throws IllegalArgumentException
+    {
+        if (!(value>=0 && value<=max)) {
+            // Use '!' in order to trap NaN
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2, name, value));
+        }
+    }
+
+    /**
+     * Returns the parameter descriptors for this math transform.
+     */
+    @Override
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return Provider.PARAMETERS;
+    }
+
+    /**
+     * Returns the parameter values for this math transform.
+     *
+     * @return A copy of the parameter values for this math transform.
+     */
+    @Override
+    public ParameterValueGroup getParameterValues() {
+        return getParameterValues(getParameterDescriptors());
+    }
+
+    /**
+     * Returns the parameter values using the specified descriptor.
+     *
+     * @param  descriptor The parameter descriptor.
+     * @return A copy of the parameter values for this math transform.
+     */
+    private ParameterValueGroup getParameterValues(final ParameterDescriptorGroup descriptor) {
+        final ParameterValue[] parameters = new ParameterValue[hasHeight ? 2 : 3];
+        int index = 0;
+        if (!hasHeight) {
+            final ParameterValue p = new org.geotools.parameter.Parameter(Provider.DIM);
+            p.setValue(2);
+            parameters[index++] = p;
+        }
+        parameters[index++] = new FloatParameter(Provider.SEMI_MAJOR, a);
+        parameters[index++] = new FloatParameter(Provider.SEMI_MINOR, b);
+        return new org.geotools.parameter.ParameterGroup(descriptor, parameters);
+    }
+
+    /**
+     * Gets the dimension of input points, which is 2 or 3.
+     */
+    public int getSourceDimensions() {
+        return hasHeight ? 3 : 2;
+    }
+
+    /**
+     * Gets the dimension of output points, which is 3.
+     */
+    public final int getTargetDimensions() {
+        return 3;
+    }
+
+    /**
+     * Converts geodetic coordinates (longitude, latitude, height) to geocentric
+     * coordinates (x, y, z) according to the current ellipsoid parameters.
+     */
+    public void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) {
+        transform(srcPts, srcOff, dstPts, dstOff, numPts, false);
+    }
+
+    /**
+     * Implementation of geodetic to geocentric conversion. This implementation allows the caller
+     * to use height in computation. This is used for assertion with {@link #checkTransform}.
+     */
+    private void transform(double[] srcPts, int srcOff,
+                     final double[] dstPts, int dstOff,
+                     int numPts, boolean hasHeight)
+    {
+        final int dimSource = getSourceDimensions();
+        hasHeight |= (dimSource>=3);
+        if (srcPts==dstPts && needCopy(srcOff, dimSource, dstOff, 3, numPts)) {
+            // Source and destination arrays overlaps: copy in a temporary buffer.
+            final double[] old = srcPts;
+            srcPts = new double[numPts * (hasHeight ? 3 : 2)];
+            System.arraycopy(old, srcOff, srcPts, 0, srcPts.length);
+            srcOff = 0;
+        }
+        while (--numPts >= 0) {
+            final double L = Math.toRadians(srcPts[srcOff++]); // Longitude
+            final double P = Math.toRadians(srcPts[srcOff++]); // Latitude
+            final double h = hasHeight ? srcPts[srcOff++] : 0; // Height above the ellipsoid (m)
+
+            final double cosLat = Math.cos(P);
+            final double sinLat = Math.sin(P);
+            final double rn     = a / Math.sqrt(1 - e2 * (sinLat*sinLat));
+
+            dstPts[dstOff++] = (rn + h) * cosLat * Math.cos(L); // X: Toward prime meridian
+            dstPts[dstOff++] = (rn + h) * cosLat * Math.sin(L); // Y: Toward East
+            dstPts[dstOff++] = (rn * (1-e2) + h) * sinLat;      // Z: Toward North
+        }
+    }
+
+    /**
+     * Converts geodetic coordinates (longitude, latitude, height) to geocentric
+     * coordinates (x, y, z) according to the current ellipsoid parameters.
+     */
+    @Override
+    public void transform(float[] srcPts, int srcOff,
+                    final float[] dstPts, int dstOff, int numPts)
+    {
+        final int dimSource = getSourceDimensions();
+        final boolean hasHeight = (dimSource>=3);
+        if (srcPts==dstPts && needCopy(srcOff, dimSource, dstOff, 3, numPts)) {
+            // Source and destination arrays overlaps: copy in a temporary buffer.
+            final float[] old = srcPts;
+            srcPts = new float[numPts*dimSource];
+            System.arraycopy(old, srcOff, srcPts, 0, srcPts.length);
+            srcOff = 0;
+        }
+        while (--numPts >= 0) {
+            final double L = Math.toRadians(srcPts[srcOff++]); // Longitude
+            final double P = Math.toRadians(srcPts[srcOff++]); // Latitude
+            final double h = hasHeight ? srcPts[srcOff++] : 0; // Height above the ellipsoid (m)
+
+            final double cosLat = Math.cos(P);
+            final double sinLat = Math.sin(P);
+            final double rn     = a / Math.sqrt(1 - e2 * (sinLat*sinLat));
+
+            dstPts[dstOff++] = (float) ((rn + h) * cosLat * Math.cos(L)); // X: Toward prime meridian
+            dstPts[dstOff++] = (float) ((rn + h) * cosLat * Math.sin(L)); // Y: Toward East
+            dstPts[dstOff++] = (float) ((rn * (1-e2) + h) * sinLat);      // Z: Toward North
+        }
+    }
+
+    /**
+     * Converts geocentric coordinates (x, y, z) to geodetic coordinates
+     * (longitude, latitude, height), according to the current ellipsoid
+     * parameters. The method used here is derived from "An Improved
+     * Algorithm for Geocentric to Geodetic Coordinate Conversion", by
+     * Ralph Toms, Feb 1996.
+     *
+     * @param srcPts the array containing the source point coordinates.
+     * @param srcOff the offset to the first point to be transformed in the source array.
+     * @param dstPts the array into which the transformed point coordinates are returned.
+     *               May be the same than {@code srcPts}.
+     * @param dstOff the offset to the location of the first transformed point that is stored
+     *               in the destination array.
+     * @param numPts the number of point objects to be transformed.
+     */
+    public void inverseTransform(double[] srcPts, int srcOff,
+                           final double[] dstPts, int dstOff, final int numPts)
+    {
+        final int dimTarget = getSourceDimensions();
+        if (srcPts == dstPts && needCopy(srcOff, 3, dstOff, dimTarget, numPts)) {
+            // Source and destination arrays overlaps: copy in a temporary buffer.
+            final double[] old = srcPts;
+            srcPts = new double[numPts*3];
+            System.arraycopy(old, srcOff, srcPts, 0, srcPts.length);
+            srcOff = 0;
+        }
+        inverseTransform(null, srcPts, srcOff, null, dstPts, dstOff, numPts, dimTarget);
+    }
+
+    /**
+     * Converts geocentric coordinates (x, y, z) to geodetic coordinates
+     * (longitude, latitude, height), according to the current ellipsoid
+     * parameters. The method used here is derived from "An Improved
+     * Algorithm for Geocentric to Geodetic Coordinate Conversion", by
+     * Ralph Toms, Feb 1996.
+     *
+     * @param srcPts the array containing the source point coordinates.
+     * @param srcOff the offset to the first point to be transformed in the source array.
+     * @param dstPts the array into which the transformed point coordinates are returned.
+     *               May be the same than {@code srcPts}.
+     * @param dstOff the offset to the location of the first transformed point that is stored
+     *               in the destination array.
+     * @param numPts the number of point objects to be transformed.
+     */
+    public void inverseTransform(float[] srcPts, int srcOff,
+                           final float[] dstPts, int dstOff, final int numPts)
+    {
+        final int dimTarget = getSourceDimensions();
+        if (srcPts == dstPts && needCopy(srcOff, 3, dstOff, dimTarget, numPts)) {
+            // Source and destination arrays overlaps: copy in a temporary buffer.
+            final float[] old = srcPts;
+            srcPts = new float[numPts*3];
+            System.arraycopy(old, srcOff, srcPts, 0, srcPts.length);
+            srcOff = 0;
+        }
+        inverseTransform(srcPts, null, srcOff, dstPts, null, dstOff, numPts, dimTarget);
+    }
+
+    /**
+     * Implementation of the inverse transformation.
+     */
+    private void inverseTransform(final float[] srcPts1, final double[] srcPts2, int srcOff,
+                                  final float[] dstPts1, final double[] dstPts2, int dstOff,
+                                  int numPts, final int dimTarget)
+    {
+        final boolean hasHeight = (dimTarget>=3);
+        boolean   computeHeight = hasHeight;
+        assert (computeHeight=true)==true; // Force computeHeight to true if assertions are enabled.
+        while (--numPts >= 0) {
+            final double x, y, z;
+            if (srcPts2 != null) {
+                x = srcPts2[srcOff++]; // Toward prime meridian
+                y = srcPts2[srcOff++]; // Toward East
+                z = srcPts2[srcOff++]; // Toward North
+            } else {
+                x = srcPts1[srcOff++]; // Toward prime meridian
+                y = srcPts1[srcOff++]; // Toward East
+                z = srcPts1[srcOff++]; // Toward North
+            }
+            // Note: The Java version of 'atan2' work correctly for x==0.
+            //       No need for special handling like in the C version.
+            //       No special handling neither for latitude. Formulas
+            //       below are generic enough, considering that 'atan'
+            //       work correctly with infinities (1/0).
+
+            // Note: Variable names follow the notation used in Toms, Feb 1996
+            final double      W2 = x*x + y*y;                       // square of distance from Z axis
+            final double      W  = Math.sqrt(W2);                   // distance from Z axis
+            final double      T0 = z * AD_C;                        // initial estimate of vertical component
+            final double      S0 = Math.sqrt(T0*T0 + W2);           // initial estimate of horizontal component
+            final double  sin_B0 = T0 / S0;                         // sin(B0), B0 is estimate of Bowring aux variable
+            final double  cos_B0 = W / S0;                          // cos(B0)
+            final double sin3_B0 = sin_B0 * sin_B0 * sin_B0;        // cube of sin(B0)
+            final double      T1 = z + b * ep2 * sin3_B0;           // corrected estimate of vertical component
+            final double     sum = W - a*e2*(cos_B0*cos_B0*cos_B0); // numerator of cos(phi1)
+            final double      S1 = Math.sqrt(T1*T1 + sum * sum);    // corrected estimate of horizontal component
+            final double  sin_p1 = T1 / S1;                         // sin(phi1), phi1 is estimated latitude
+            final double  cos_p1 = sum / S1;                        // cos(phi1)
+
+            final double longitude = Math.toDegrees(Math.atan2(y      , x     ));
+            final double  latitude = Math.toDegrees(Math.atan(sin_p1 / cos_p1));
+            final double    height;
+
+            if (dstPts2 != null) {
+                dstPts2[dstOff++] = longitude;
+                dstPts2[dstOff++] = latitude;
+            } else {
+                dstPts1[dstOff++] = (float) longitude;
+                dstPts1[dstOff++] = (float) latitude;
+            }
+            if (computeHeight) {
+                final double rn = a/Math.sqrt(1-e2*(sin_p1*sin_p1)); // Earth radius at location
+                if      (cos_p1 >= +COS_67P5) height = W / +cos_p1 - rn;
+                else if (cos_p1 <= -COS_67P5) height = W / -cos_p1 - rn;
+                else                          height = z / sin_p1 + rn*(e2 - 1.0);
+                if (hasHeight) {
+                    if (dstPts2 != null) {
+                        dstPts2[dstOff++] = height;
+                    } else {
+                        dstPts1[dstOff++] = (float) height;
+                    }
+                }
+                // If assertion are enabled, then transform the
+                // result and compare it with the input array.
+                double distance;
+                assert MAX_ERROR > (distance=checkTransform(new double[]
+                        {x,y,z, longitude, latitude, height})) : distance;
+            }
+        }
+    }
+
+    /**
+     * Transform the last half if the specified array and returns
+     * the distance with the first half. Array {@code points}
+     * must have a length of 6.
+     */
+    private double checkTransform(final double[] points) {
+        transform(points, 3, points, 3, 1, true);
+        final double dx = points[0]-points[3];
+        final double dy = points[1]-points[4];
+        final double dz = points[2]-points[5];
+        return Math.sqrt(dx*dx + dy*dy + dz*dz);
+    }
+
+    /**
+     * Returns the inverse of this transform.
+     */
+    @Override
+    public synchronized MathTransform inverse() {
+        if (inverse == null) {
+            inverse = new Inverse();
+        }
+        return inverse;
+    }
+
+    /**
+     * Returns a hash value for this transform.
+     */
+    @Override
+    public int hashCode() {
+        final long code = Double.doubleToLongBits( a ) +
+                          37*(Double.doubleToLongBits( b ) +
+                          37*(Double.doubleToLongBits( a2) +
+                          37*(Double.doubleToLongBits( b2) +
+                          37*(Double.doubleToLongBits( e2) +
+                          37*(Double.doubleToLongBits(ep2))))));
+        return (int) code ^ (int) (code >>> 32) ^ (int)serialVersionUID;
+    }
+
+    /**
+     * Compares the specified object with this math transform for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            // Slight optimization
+            return true;
+        }
+        if (super.equals(object)) {
+            final GeocentricTransform that = (GeocentricTransform) object;
+            return Double.doubleToLongBits(this. a ) == Double.doubleToLongBits(that. a ) &&
+                   Double.doubleToLongBits(this. b ) == Double.doubleToLongBits(that. b ) &&
+                   Double.doubleToLongBits(this. a2) == Double.doubleToLongBits(that. a2) &&
+                   Double.doubleToLongBits(this. b2) == Double.doubleToLongBits(that. b2) &&
+                   Double.doubleToLongBits(this. e2) == Double.doubleToLongBits(that. e2) &&
+                   Double.doubleToLongBits(this.ep2) == Double.doubleToLongBits(that.ep2) &&
+                   this.hasHeight == that.hasHeight;
+        }
+        return false;
+    }
+
+    /**
+     * Inverse of a geocentric transform.
+     *
+     * @version $Id: GeocentricTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     */
+    private final class Inverse extends AbstractMathTransform.Inverse {
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID = 6942084702259211803L;
+
+        /**
+         * Default constructor.
+         */
+        public Inverse() {
+            GeocentricTransform.this.super();
+        }
+
+        /**
+         * Returns the parameter descriptors for this math transform.
+         */
+        @Override
+        public ParameterDescriptorGroup getParameterDescriptors() {
+            return ProviderInverse.PARAMETERS;
+        }
+
+        /**
+         * Returns the parameter values for this math transform.
+         *
+         * @return A copy of the parameter values for this math transform.
+         */
+        @Override
+        public ParameterValueGroup getParameterValues() {
+            return GeocentricTransform.this.getParameterValues(getParameterDescriptors());
+        }
+
+        /**
+         * Inverse transform an array of points.
+         */
+        public void transform(final double[] source, final int srcOffset,
+                              final double[] dest,   final int dstOffset, final int length)
+        {
+            GeocentricTransform.this.inverseTransform(source, srcOffset, dest, dstOffset, length);
+        }
+
+        /**
+         * Inverse transform an array of points.
+         */
+        @Override
+        public void transform(final float[] source, final int srcOffset,
+                              final float[] dest,   final int dstOffset, final int length)
+        {
+            GeocentricTransform.this.inverseTransform(source, srcOffset, dest, dstOffset, length);
+        }
+
+        /**
+         * Restore reference to this object after deserialization.
+         */
+        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+            in.defaultReadObject();
+            GeocentricTransform.this.inverse = this;
+        }
+    }
+
+    /**
+     * The provider for {@link GeocentricTransform}. This provider will constructs transforms
+     * from {@linkplain org.geotools.referencing.crs.DefaultGeographicCRS geographic} to
+     * {@linkplain org.geotools.referencing.crs.DefaultGeocentricCRS geocentric} coordinate
+     * reference systems.
+     *
+     * @version $Id: GeocentricTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     */
+    public static class Provider extends MathTransformProvider {
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID = 7043216580786030251L;
+
+        /**
+         * The operation parameter descriptor for the "semi_major" parameter value.
+         * Valid values range from 0 to infinity.
+         */
+        public static final ParameterDescriptor<Double> SEMI_MAJOR = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,  "semi_major"),
+                    new NamedIdentifier(Citations.EPSG, "semi-major axis")   //epsg does not specifically define this parameter
+                },
+                Double.NaN, 0, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The operation parameter descriptor for the "semi_minor" parameter value.
+         * Valid values range from 0 to infinity.
+         */
+        public static final ParameterDescriptor<Double> SEMI_MINOR = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,  "semi_minor"),
+                    new NamedIdentifier(Citations.EPSG, "semi-minor axis")   //epsg does not specifically define this parameter
+                },
+                Double.NaN, 0, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The number of geographic dimension (2 or 3). This is a Geotools-specific argument.
+         * The default value is 3, which is the value implied in OGC's WKT.
+         */
+        static final ParameterDescriptor<Integer> DIM = DefaultParameterDescriptor.create(
+                    Collections.singletonMap(NAME_KEY, new NamedIdentifier(Citations.GEOTOOLS, "dim")),
+                    3, 2, 3, false);
+
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(
+                        "Ellipsoid_To_Geocentric",              // OGC name
+                        "Geographic/geocentric conversions",    // EPSG name
+                        "9602",                                 // EPSG identifier
+                        VocabularyKeys.GEOCENTRIC_TRANSFORM);   // Geotools name
+
+        /**
+         * Constructs the parameters group.
+         */
+        static ParameterDescriptorGroup createDescriptorGroup(final String ogc,
+                                                              final String epsgName,
+                                                              final String epsgCode,
+                                                              final int geotools)
+        {
+            return createDescriptorGroup(new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,      ogc),
+                    new NamedIdentifier(Citations.EPSG,     epsgName),
+                    new NamedIdentifier(Citations.EPSG,     epsgCode),
+                    new NamedIdentifier(Citations.GEOTOOLS, Vocabulary.formatInternational(geotools))
+                }, new ParameterDescriptor[] {
+                    SEMI_MAJOR, SEMI_MINOR, DIM
+                });
+        }
+
+        /**
+         * The provider for the 2D case. Will be constructed when first needed.
+         */
+        transient Provider noHeight;
+
+        /**
+         * Constructs a provider with default parameters.
+         */
+        public Provider() {
+            super(3, 3, PARAMETERS);
+        }
+
+        /**
+         * Constructs a provider from a set of parameters.
+         *
+         * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
+         * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+         * @param parameters The set of parameters (never {@code null}).
+         */
+        Provider(final int sourceDimensions,
+                 final int targetDimensions,
+                 final ParameterDescriptorGroup parameters)
+        {
+            super(sourceDimensions, targetDimensions, parameters);
+        }
+
+        /**
+         * Returns the operation type.
+         */
+        @Override
+        public Class<Conversion> getOperationType() {
+            return Conversion.class;
+        }
+
+        /**
+         * Creates a transform from the specified group of parameter values.
+         *
+         * @param  values The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not found.
+         */
+        protected MathTransform createMathTransform(final ParameterValueGroup values)
+                throws ParameterNotFoundException
+        {
+            final int dimGeographic =    intValue(DIM,        values);
+            final double  semiMajor = doubleValue(SEMI_MAJOR, values);
+            final double  semiMinor = doubleValue(SEMI_MINOR, values);
+            final boolean hasHeight = (dimGeographic != 2); // Value may be 0, which default as 3.
+            MathTransform transform = new GeocentricTransform(semiMajor, semiMinor, SI.METER, hasHeight);
+            if (!hasHeight) {
+                if (noHeight == null) {
+                    noHeight = new Provider(2, 3, PARAMETERS);
+                }
+                transform = new Delegate(transform, noHeight);
+            }
+            return transform;
+        }
+    }
+
+    /**
+     * The provider for inverse of {@link GeocentricTransform}. This provider will construct
+     * transforms from {@linkplain org.geotools.referencing.crs.DefaultGeocentricCRS geocentric}
+     * to {@linkplain org.geotools.referencing.crs.DefaultGeographicCRS geographic} coordinate
+     * reference systems.
+     *
+     * @version $Id: GeocentricTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     */
+    public static class ProviderInverse extends Provider {
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID = -7356791540110076789L;
+
+        /**
+         * The parameters group.
+         *
+         * @todo The EPSG code seems to be the same than for the direct transform.
+         */
+        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(
+                        "Geocentric_To_Ellipsoid",              // OGC name
+                        "Geographic/geocentric conversions",    // EPSG name
+                        "9602",                                 // EPSG identifier
+                        VocabularyKeys.GEOCENTRIC_TRANSFORM);   // Geotools name
+
+        /**
+         * Creates a provider.
+         */
+        public ProviderInverse() {
+            super(3, 3, PARAMETERS);
+        }
+
+        /**
+         * Constructs a provider from a set of parameters.
+         *
+         * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
+         * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+         * @param parameters The set of parameters (never {@code null}).
+         */
+        ProviderInverse(final int sourceDimensions,
+                        final int targetDimensions,
+                        final ParameterDescriptorGroup parameters)
+        {
+            super(sourceDimensions, targetDimensions, parameters);
+        }
+
+        /**
+         * Creates a transform from the specified group of parameter values.
+         *
+         * @param  values The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not found.
+         */
+        @Override
+        public MathTransform createMathTransform(final ParameterValueGroup values)
+                throws ParameterNotFoundException
+        {
+            final int dimGeographic =    intValue(DIM,        values);
+            final double  semiMajor = doubleValue(SEMI_MAJOR, values);
+            final double  semiMinor = doubleValue(SEMI_MINOR, values);
+            final boolean hasHeight = (dimGeographic != 2); // Value may be 0, which default as 3.
+            MathTransform transform = new GeocentricTransform(semiMajor, semiMinor, SI.METER, hasHeight).inverse();
+            if (!hasHeight) {
+                if (noHeight == null) {
+                    noHeight = new ProviderInverse(3, 2, PARAMETERS);
+                }
+                transform = new Delegate(transform, noHeight);
+            }
+            return transform;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/GeocentricTranslation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/GeocentricTranslation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/GeocentricTranslation.java	(revision 28000)
@@ -0,0 +1,558 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.util.Collections;
+import javax.measure.unit.SI;
+import javax.measure.unit.NonSI;
+
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.Transformation;
+
+import org.geotools.util.Utilities;
+import org.geotools.measure.Units;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.parameter.DefaultParameterDescriptor;
+import org.geotools.parameter.FloatParameter;
+import org.geotools.parameter.ParameterGroup;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.referencing.datum.BursaWolfParameters;
+import org.geotools.referencing.operation.MathTransformProvider;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * An affine transform applied on {@linkplain org.opengis.referencing.crs.GeocentricCRS geocentric}
+ * coordinates. While "geocentric translation" is a little bit more restrictive name, it describes
+ * the part which is common to all instances of this class. A rotation may also be performed in
+ * addition of the translation, but the rotation sign is operation-dependent (EPSG 9606 and 9607
+ * have opposite sign). This transform is used for the following operations:
+ * <p>
+ * <table border="1">
+ *   <tr><th>EPSG name</th>                               <th>EPSG code</th></tr>
+ *   <tr><td>Geocentric translations</td>                 <td>9603</td></tr>
+ *   <tr><td>Position Vector 7-param. transformation</td> <td>9606</td></tr>
+ *   <tr><td>Coordinate Frame rotation</td>               <td>9607</td></tr>
+ * </table>
+ * <p>
+ * The conversion between geographic and geocentric coordinates is usually <strong>not</strong>
+ * part of this transform. However, the Geotools implementation of the
+ * {@linkplain GeocentricTranslation.Provider provider} accepts the following extensions:
+ * <p>
+ * <ul>
+ *   <li>If {@code "src_semi_major"} and {@code "src_semi_minor"} parameters are provided, then
+ *       a {@code "Ellipsoid_To_Geocentric"} transform is concatenated before this transform.</li>
+ *   <li>If {@code "tgt_semi_major"} and {@code "tgt_semi_minor"} parameters are provided, then
+ *       a {@code "Geocentric_To_Ellipsoid"} transform is concatenated after this transform.</li>
+ * </ul>
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/GeocentricTranslation.java $
+ * @version $Id: GeocentricTranslation.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class GeocentricTranslation extends ProjectiveTransform {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -168669443433018655L;
+
+    /**
+     * The parameter descriptor group.
+     */
+    private final ParameterDescriptorGroup descriptor;
+
+    /**
+     * Creates a new geocentric affine transform using the specified parameter descriptor.
+     */
+    GeocentricTranslation(final BursaWolfParameters      parameters,
+                          final ParameterDescriptorGroup descriptor)
+    {
+        super(parameters.getAffineTransform());
+        this.descriptor = descriptor;
+    }
+
+    /**
+     * Creates a new geocentric affine transform using the specified parameter descriptor.
+     */
+    private GeocentricTranslation(final Matrix matrix,
+                                  final ParameterDescriptorGroup descriptor)
+    {
+        super(matrix);
+        this.descriptor = descriptor;
+    }
+
+    /**
+     * Returns the parameter descriptors for this math transform.
+     */
+    @Override
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return descriptor;
+    }
+
+    /**
+     * Returns the parameters for this math transform.
+     */
+    @Override
+    public ParameterValueGroup getParameterValues() {
+        final BursaWolfParameters parameters = new BursaWolfParameters(null);
+        parameters.setAffineTransform(getMatrix(), Double.POSITIVE_INFINITY);
+        if (ProviderFrameRotation.PARAMETERS.equals(descriptor)) {
+            parameters.ex = -parameters.ex;
+            parameters.ey = -parameters.ey;
+            parameters.ez = -parameters.ez;
+        }
+        final boolean isTranslation = Provider.PARAMETERS.equals(descriptor);
+        final FloatParameter[] param = new FloatParameter[isTranslation ? 3 : 7];
+        param[0] = new FloatParameter(Provider.DX,  parameters.dx);
+        param[1] = new FloatParameter(Provider.DY,  parameters.dy);
+        param[2] = new FloatParameter(Provider.DZ,  parameters.dz);
+        if (!isTranslation) {
+            param[3] = new FloatParameter(ProviderSevenParam.EX,  parameters.ex);
+            param[4] = new FloatParameter(ProviderSevenParam.EY,  parameters.ey);
+            param[5] = new FloatParameter(ProviderSevenParam.EZ,  parameters.ez);
+            param[6] = new FloatParameter(ProviderSevenParam.PPM, parameters.ppm);
+        }
+        return new ParameterGroup(getParameterDescriptors(), param);
+    }
+
+    /**
+     * Creates an inverse transform using the specified matrix.
+     */
+    @Override
+    MathTransform createInverse(final Matrix matrix) {
+        return new GeocentricTranslation(matrix, descriptor);
+    }
+
+    /**
+     * Returns a hash value for this transform.
+     * This value need not remain consistent between
+     * different implementations of the same class.
+     */
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ descriptor.hashCode();
+    }
+
+    /**
+     * Compares the specified object with this math transform for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (super.equals(object)) {
+            final GeocentricTranslation that = (GeocentricTranslation) object;
+            return Utilities.equals(this.descriptor, that.descriptor);
+        }
+        return false;
+    }
+
+    /**
+     * Base class for {@linkplain GeocentricTranslation geocentric affine transform} providers.
+     * This base class is the provider for the "<cite>Geocentric translations</cite>" operation
+     * (EPSG code 9603). The translation terms are the same for the 2 derived operations,
+     * "<cite>Position Vector 7-param. transformation</cite>" and
+     * "<cite>Coordinate Frame rotation</cite>".
+     *
+     * @version $Id: GeocentricTranslation.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     *
+     * @since 2.2
+     */
+    public static class Provider extends MathTransformProvider {
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID = -7160250630666911608L;
+
+        /**
+         * The default value for geographic source and target dimensions, which is 2.
+         * NOTE: If this default value is modified, then the handling of the 3D cases
+         * in {@link MolodenskiTransform} must be adjusted.
+         */
+        static final int DEFAULT_DIMENSION = 2;
+
+        /**
+         * The number of source geographic dimension (2 or 3).
+         * This is a Geotools-specific argument. If presents, an {@code "Ellipsoid_To_Geocentric"}
+         * transform will be concatenated before the geocentric translation.
+         */
+        public static final ParameterDescriptor<Integer> SRC_DIM = DefaultParameterDescriptor.create(
+                    Collections.singletonMap(NAME_KEY,
+                        new NamedIdentifier(Citations.GEOTOOLS, "src_dim")),
+                    DEFAULT_DIMENSION, 2, 3, false);
+
+        /**
+         * The number of target geographic dimension (2 or 3).
+         * This is a Geotools-specific argument. If presents, a {@code "Geocentric_To_Ellipsoid"}
+         * transform will be concatenated after the geocentric translation.
+         */
+        public static final ParameterDescriptor<Integer> TGT_DIM = DefaultParameterDescriptor.create(
+                    Collections.singletonMap(NAME_KEY,
+                        new NamedIdentifier(Citations.GEOTOOLS, "tgt_dim")),
+                    DEFAULT_DIMENSION, 2, 3, false);
+
+        /**
+         * The operation parameter descriptor for the "src_semi_major" optional parameter value.
+         * This is a Geotools-specific argument. If presents, an {@code "Ellipsoid_To_Geocentric"}
+         * transform will be concatenated before the geocentric translation. Valid values range
+         * from 0 to infinity.
+         */
+        public static final ParameterDescriptor<Double> SRC_SEMI_MAJOR = createOptionalDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC, "src_semi_major")
+                },
+                0.0, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The operation parameter descriptor for the "src_semi_minor" optional parameter value.
+         * This is a Geotools-specific argument. If presents, an {@code "Ellipsoid_To_Geocentric"}
+         * transform will be concatenated before the geocentric translation. Valid values range
+         * from 0 to infinity.
+         */
+         public static final ParameterDescriptor<Double> SRC_SEMI_MINOR = createOptionalDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC, "src_semi_minor"),
+                },
+                0.0, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The operation parameter descriptor for the "tgt_semi_major" optional parameter value.
+         * This is a Geotools-specific argument. If presents, a {@code "Geocentric_To_Ellipsoid"}
+         * transform will be concatenated after the geocentric translation. Valid values range
+         * from 0 to infinity.
+         */
+        public static final ParameterDescriptor<Double> TGT_SEMI_MAJOR = createOptionalDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC, "tgt_semi_major")
+                },
+                0.0, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The operation parameter descriptor for the "tgt_semi_minor" optional parameter value.
+         * This is a Geotools-specific argument. If presents, a {@code "Geocentric_To_Ellipsoid"}
+         * transform will be concatenated after the geocentric translation. Valid values range
+         * from 0 to infinity.
+         */
+        public static final ParameterDescriptor<Double> TGT_SEMI_MINOR = createOptionalDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC, "tgt_semi_minor")
+                },
+                0.0, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The operation parameter descriptor for the <cite>X-axis translation</cite> ("dx")
+         * parameter value. Valid values range from -infinity to infinity. Units are meters.
+         */
+        public static final ParameterDescriptor<Double> DX = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,  "dx"),
+                    new NamedIdentifier(Citations.EPSG, "X-axis translation")
+                },
+                0.0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The operation parameter descriptor for the <cite>Y-axis translation</cite> ("dy")
+         * parameter value. Valid values range from -infinity to infinity. Units are meters.
+         */
+        public static final ParameterDescriptor<Double> DY = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,  "dy"),
+                    new NamedIdentifier(Citations.EPSG, "Y-axis translation")
+                },
+                0.0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The operation parameter descriptor for the <cite>Z-axis translation</cite> ("dz")
+         * parameter value. Valid values range from -infinity to infinity. Units are meters.
+         */
+        public static final ParameterDescriptor<Double> DZ = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,  "dz"),
+                    new NamedIdentifier(Citations.EPSG, "Z-axis translation")
+                },
+                0.0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new NamedIdentifier[] {
+                new NamedIdentifier(Citations.EPSG, "Geocentric translations (geog2D domain)"),
+                new NamedIdentifier(Citations.EPSG, "9603")
+            }, new ParameterDescriptor[] {
+                DX, DY, DZ,
+                SRC_SEMI_MAJOR, SRC_SEMI_MINOR,
+                TGT_SEMI_MAJOR, TGT_SEMI_MINOR,
+                SRC_DIM, TGT_DIM
+            });
+
+        /**
+         * Constructs a default provider.
+         */
+        public Provider() {
+            this(PARAMETERS);
+        }
+
+        /**
+         * Constructs a provider with the specified parameters.
+         */
+        Provider(final ParameterDescriptorGroup parameters) {
+            super(3, 3, parameters);
+        }
+
+        /**
+         * Returns the operation type.
+         */
+        @Override
+        public Class<Transformation> getOperationType() {
+            return Transformation.class;
+        }
+
+        /**
+         * Creates a math transform from the specified group of parameter values.
+         *
+         * @param  values The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not found.
+         */
+        protected MathTransform createMathTransform(final ParameterValueGroup values)
+                throws ParameterNotFoundException
+        {
+            final BursaWolfParameters parameters = new BursaWolfParameters(null);
+            fill(parameters, values);
+            return concatenate(concatenate(new GeocentricTranslation(parameters, getParameters()),
+                               values, SRC_SEMI_MAJOR, SRC_SEMI_MINOR, SRC_DIM),
+                               values, TGT_SEMI_MAJOR, TGT_SEMI_MINOR, TGT_DIM);
+        }
+
+        /**
+         * Fill the specified Bursa-Wolf parameters according the specified values.
+         * This method is invoked automatically by {@link #createMathTransform}.
+         *
+         * @param parameters The Bursa-Wold parameters to set.
+         * @param values The parameter values to read. Those parameters will not be modified.
+         */
+        protected void fill(final BursaWolfParameters parameters, final ParameterValueGroup values) {
+            parameters.dx = doubleValue(DX, values);
+            parameters.dy = doubleValue(DY, values);
+            parameters.dz = doubleValue(DZ, values);
+        }
+
+        /**
+         * Concatenates the supplied transform with an "ellipsoid to geocentric" or a
+         * "geocentric to ellipsod" step, if needed.
+         */
+        @SuppressWarnings("fallthrough")
+        private static MathTransform concatenate(final MathTransform    transform,
+                                                 final ParameterValueGroup values,
+                                                 final ParameterDescriptor major,
+                                                 final ParameterDescriptor minor,
+                                                 final ParameterDescriptor dim)
+        {
+            double semiMajor = doubleValue(major, values);
+            double semiMinor = doubleValue(minor, values);
+            int    dimension =    intValue(dim,   values);
+            switch (dimension) {
+                case 0: if (Double.isNaN(semiMajor) && Double.isNaN(semiMinor)) return transform;
+                case 2:        // Fall through for 0 and 2 cases.
+                case 3: break; // The dimension is a valid value.
+                default: throw new IllegalArgumentException(Errors.format(
+                               ErrorKeys.ILLEGAL_ARGUMENT_$2, dim.getName().getCode(), dimension));
+            }
+            ensureValid(major, semiMajor);
+            ensureValid(minor, semiMinor);
+            final GeocentricTransform step;
+            step = new GeocentricTransform(semiMajor, semiMinor, SI.METER, dimension==3);
+            // Note: dimension may be 0 if not user-provided, which is treated as 2.
+            if (dim == SRC_DIM) {
+                return ConcatenatedTransform.create(step, transform);
+            } else {
+                return ConcatenatedTransform.create(transform, step.inverse());
+            }
+        }
+
+        /**
+         * Ensures the the specified parameter is valid.
+         */
+        private static void ensureValid(final ParameterDescriptor param, double value) {
+            if (!(value > 0)) {
+                throw new IllegalStateException(Errors.format(ErrorKeys.MISSING_PARAMETER_$1,
+                                                param.getName().getCode()));
+            }
+        }
+    }
+
+    /**
+     * Base class for {@linkplain GeocentricTranslation geocentric affine transform} providers
+     * with rotation terms. This base class is the provider for the "<cite>Position Vector 7-param.
+     * transformation</cite>".
+     *
+     * @version $Id: GeocentricTranslation.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     *
+     * @since 2.2
+     */
+    public static class ProviderSevenParam extends Provider {
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID = -6398226638364450229L;
+
+        /**
+         * The maximal value for a rotation, in arc-second.
+         */
+        private static final double MAX_ROTATION = 180*60*60;
+
+        /**
+         * The operation parameter descriptor for the <cite>X-axis rotation</cite> ("ex")
+         * parameter value. Units are arc-seconds.
+         */
+        public static final ParameterDescriptor EX = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,  "ex"),
+                    new NamedIdentifier(Citations.EPSG, "X-axis rotation")
+                },
+                0.0, -MAX_ROTATION, MAX_ROTATION, NonSI.SECOND_ANGLE);
+
+        /**
+         * The operation parameter descriptor for the <cite>Y-axis rotation</cite> ("ey")
+         * parameter value. Units are arc-seconds.
+         */
+        public static final ParameterDescriptor EY = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,  "ey"),
+                    new NamedIdentifier(Citations.EPSG, "Y-axis rotation")
+                },
+                0.0, -MAX_ROTATION, MAX_ROTATION, NonSI.SECOND_ANGLE);
+
+        /**
+         * The operation parameter descriptor for the <cite>Z-axis rotation</cite> ("ez")
+         * parameter value. Units are arc-seconds.
+         */
+        public static final ParameterDescriptor EZ = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,  "ez"),
+                    new NamedIdentifier(Citations.EPSG, "Z-axis rotation")
+                },
+                0.0, -MAX_ROTATION, MAX_ROTATION, NonSI.SECOND_ANGLE);
+
+        /**
+         * The operation parameter descriptor for the <cite>Scale difference</cite> ("ppm")
+         * parameter value. Valid values range from -infinity to infinity. Units are parts
+         * per million.
+         */
+        public static final ParameterDescriptor PPM = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.OGC,  "ppm"),
+                    new NamedIdentifier(Citations.EPSG, "Scale difference")
+                },
+                0.0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Units.PPM);
+
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS =
+                        createDescriptorGroup("Position Vector transformation (geog2D domain)", "9606");
+
+        /**
+         * Creates a parameters group.
+         */
+        static ParameterDescriptorGroup createDescriptorGroup(final String name, final String code) {
+            return createDescriptorGroup(new NamedIdentifier[] {
+                new NamedIdentifier(Citations.EPSG, name),
+                new NamedIdentifier(Citations.EPSG, code)
+            }, new ParameterDescriptor[] {
+                DX, DY, DZ, EX, EY, EZ, PPM,
+                SRC_SEMI_MAJOR, SRC_SEMI_MINOR,
+                TGT_SEMI_MAJOR, TGT_SEMI_MINOR,
+                SRC_DIM, TGT_DIM
+            });
+        }
+
+        /**
+         * Constructs a default provider.
+         */
+        public ProviderSevenParam() {
+            super(PARAMETERS);
+        }
+
+        /**
+         * Constructs a provider with the specified parameters.
+         */
+        ProviderSevenParam(final ParameterDescriptorGroup parameters) {
+            super(parameters);
+        }
+
+        /**
+         * Fills the specified Bursa-Wolf parameters according the specified values.
+         */
+        @Override
+        protected void fill(final BursaWolfParameters parameters, final ParameterValueGroup values) {
+            super.fill(parameters, values);
+            parameters.ppm = doubleValue(PPM, values);
+            parameters.ex  = doubleValue(EX, values);
+            parameters.ey  = doubleValue(EY, values);
+            parameters.ez  = doubleValue(EZ, values);
+        }
+    }
+
+    /**
+     * {@linkplain GeocentricTranslation Geocentric affine transform} provider for
+     * "<cite>Coordinate Frame rotation</cite>".
+     *
+     * @version $Id: GeocentricTranslation.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     *
+     * @since 2.2
+     */
+    public static class ProviderFrameRotation extends ProviderSevenParam {
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID =  5513675854809530038L;
+
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS =
+                        createDescriptorGroup("Coordinate Frame Rotation (geog2D domain)", "9607");
+
+        /**
+         * Constructs a default provider.
+         */
+        public ProviderFrameRotation() {
+            super(PARAMETERS);
+        }
+
+        /**
+         * Fills the specified Bursa-Wolf parameters according the specified values.
+         */
+        @Override
+        protected void fill(final BursaWolfParameters parameters, final ParameterValueGroup values) {
+            super.fill(parameters, values);
+            parameters.ex = -parameters.ex;
+            parameters.ey = -parameters.ey;
+            parameters.ez = -parameters.ez;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/IdentityTransform.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/IdentityTransform.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/IdentityTransform.java	(revision 28000)
@@ -0,0 +1,240 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.awt.geom.AffineTransform;
+import java.io.Serializable;
+
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.geometry.DirectPosition;
+
+import org.geotools.geometry.GeneralDirectPosition;
+import org.geotools.referencing.operation.LinearTransform;
+import org.geotools.referencing.operation.matrix.MatrixFactory;
+
+
+/**
+ * The identity transform. The data are only copied without any transformation. This class is
+ * used for identity transform of dimension greater than 2. For 1D and 2D identity transforms,
+ * {@link LinearTransform1D} and {@link java.awt.geom.AffineTransform} already provide their
+ * own optimisations.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/IdentityTransform.java $
+ * @version $Id: IdentityTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class IdentityTransform extends AbstractMathTransform
+                            implements LinearTransform, Serializable
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -5339040282922138164L;
+
+    /**
+     * The input and output dimension.
+     */
+    private final int dimension;
+
+    /**
+     * Identity transforms for dimensions ranging from to 0 to 7.
+     * Elements in this array will be created only when first requested.
+     */
+    private static final LinearTransform[] POOL = new LinearTransform[8];
+
+    /**
+     * Constructs an identity transform of the specified dimension.
+     */
+    protected IdentityTransform(final int dimension) {
+        this.dimension = dimension;
+    }
+
+    /**
+     * Constructs an identity transform of the specified dimension.
+     */
+    public static synchronized LinearTransform create(final int dimension) {
+        LinearTransform candidate;
+        if (dimension < POOL.length) {
+            candidate = POOL[dimension];
+            if (candidate != null) {
+                return candidate;
+            }
+        }
+        switch (dimension) {
+            case 1:  candidate = LinearTransform1D.IDENTITY;                   break;
+            case 2:  candidate = new AffineTransform2D(new AffineTransform()); break;
+            default: candidate = new IdentityTransform(dimension);             break;
+        }
+        if (dimension < POOL.length) {
+            POOL[dimension] = candidate;
+        }
+        return candidate;
+    }
+
+    /**
+     * Tests whether this transform does not move any points.
+     * This implementation always returns {@code true}.
+     */
+    @Override
+    public boolean isIdentity() {
+        return true;
+    }
+
+    /**
+     * Tests whether this transform does not move any points.
+     * This implementation always returns {@code true}.
+     */
+    public boolean isIdentity(double tolerance) {
+        return true;
+    }
+
+    /**
+     * Gets the dimension of input points.
+     */
+    public int getSourceDimensions() {
+        return dimension;
+    }
+
+    /**
+     * Gets the dimension of output points.
+     */
+    public int getTargetDimensions() {
+        return dimension;
+    }
+
+    /**
+     * Returns the parameter descriptors for this math transform.
+     */
+    @Override
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return ProjectiveTransform.ProviderAffine.PARAMETERS;
+    }
+
+    /**
+     * Returns the matrix elements as a group of parameters values.
+     *
+     * @return A copy of the parameter values for this math transform.
+     */
+    @Override
+    public ParameterValueGroup getParameterValues() {
+        return ProjectiveTransform.getParameterValues(getMatrix());
+    }
+
+    /**
+     * Returns a copy of the identity matrix.
+     */
+    public Matrix getMatrix() {
+        return MatrixFactory.create(dimension+1);
+    }
+
+    /**
+     * Gets the derivative of this transform at a point. For an identity transform,
+     * the derivative is the same everywhere.
+     */
+    @Override
+    public Matrix derivative(final DirectPosition point) {
+        return MatrixFactory.create(dimension);
+    }
+
+    /**
+     * Copies the values from {@code ptSrc} to {@code ptDst}.
+     * Overrides the super-class method for performance reason.
+     *
+     * @since 2.2
+     */
+    @Override
+    public DirectPosition transform(final DirectPosition ptSrc, final DirectPosition ptDst) {
+        if (ptSrc.getDimension() == dimension) {
+            if (ptDst == null) {
+                return new GeneralDirectPosition(ptSrc);
+            }
+            if (ptDst.getDimension() == dimension) {
+                for (int i=0; i<dimension; i++) {
+                    ptDst.setOrdinate(i, ptSrc.getOrdinate(i));
+                }
+                return ptDst;
+            }
+        }
+        try {
+            // The super class will take care of throwing the MismatchedDimensionException.
+            return super.transform(ptSrc, ptDst);
+        } catch (TransformException e) {
+            throw new AssertionError(e); // Should never happen.
+        }
+    }
+
+    /**
+     * Transforms an array of floating point coordinates by this transform.
+     */
+    @Override
+    public void transform(final float[] srcPts, int srcOff,
+                          final float[] dstPts, int dstOff, int numPts)
+    {
+        System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts*dimension);
+    }
+
+    /**
+     * Transforms an array of floating point coordinates by this transform.
+     */
+    public void transform(final double[] srcPts, int srcOff,
+                          final double[] dstPts, int dstOff, int numPts)
+    {
+        System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts*dimension);
+    }
+
+    /**
+     * Returns the inverse transform of this object, which
+     * is this transform itself
+     */
+    @Override
+    public MathTransform inverse() {
+        return this;
+    }
+
+    /**
+     * Returns a hash value for this transform.
+     * This value need not remain consistent between
+     * different implementations of the same class.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID + dimension;
+    }
+
+    /**
+     * Compares the specified object with
+     * this math transform for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            // Slight optimization
+            return true;
+        }
+        if (super.equals(object)) {
+            final IdentityTransform that = (IdentityTransform) object;
+            return this.dimension == that.dimension;
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/IdentityTransform1D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/IdentityTransform1D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/IdentityTransform1D.java	(revision 28000)
@@ -0,0 +1,74 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+
+/**
+ * A one dimensional, identity transform. Output values are identical to input values.
+ * This class is really a special case of {@link LinearTransform1D} optimized for speed.
+ *
+ * @since 2.0
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/IdentityTransform1D.java $
+ * @version $Id: IdentityTransform1D.java 30641 2008-06-12 17:42:27Z acuster $
+ * @author Martin Desruisseaux (IRD)
+ */
+final class IdentityTransform1D extends LinearTransform1D {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -7378774584053573789L;
+
+    /**
+     * The shared instance of the identity transform.
+     */
+    public static final LinearTransform1D ONE = new IdentityTransform1D();
+
+    /**
+     * Constructs a new identity transform.
+     */
+    private IdentityTransform1D() {
+        super(1, 0);
+    }
+
+    /**
+     * Transforms the specified value.
+     */
+    @Override
+    public double transform(double value) {
+        return value;
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    @Override
+    public void transform(final float[] srcPts, int srcOff,
+                          final float[] dstPts, int dstOff, int numPts)
+    {
+        System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts);
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    @Override
+    public void transform(final double[] srcPts, int srcOff,
+                          final double[] dstPts, int dstOff, int numPts)
+    {
+        System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/LinearTransform1D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/LinearTransform1D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/LinearTransform1D.java	(revision 28000)
@@ -0,0 +1,293 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.io.Serializable;
+
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.geometry.DirectPosition;
+
+import org.geotools.referencing.operation.matrix.Matrix1;
+import org.geotools.referencing.operation.matrix.Matrix2;
+import org.geotools.referencing.operation.LinearTransform;
+
+
+/**
+ * A one dimensional, linear transform. Input values <var>x</var> are converted into
+ * output values <var>y</var> using the following equation:
+ *
+ * <p align="center"><var>y</var> &nbsp;=&nbsp;
+ * {@linkplain #offset} + {@linkplain #scale}&times;<var>x</var></p>
+ *
+ * This class is the same as a 2&times;2 affine transform. However, this specialized
+ * {@code LinearTransform1D} class is faster. It is defined there because extensively
+ * used by {@link org.geotools.coverage.grid.GridCoverage2D}.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/LinearTransform1D.java $
+ * @version $Id: LinearTransform1D.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see LogarithmicTransform1D
+ * @see ExponentialTransform1D
+ */
+public class LinearTransform1D extends AbstractMathTransform
+                            implements MathTransform1D, LinearTransform, Serializable
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -7595037195668813000L;
+
+    /**
+     * The identity transform.
+     */
+    public static final LinearTransform1D IDENTITY = IdentityTransform1D.ONE;
+
+    /**
+     * The value which is multiplied to input values.
+     */
+    public final double scale;
+
+    /**
+     * The value to add to input values.
+     */
+    public final double offset;
+
+    /**
+     * The inverse of this transform. Created only when first needed.
+     */
+    private transient MathTransform1D inverse;
+
+    /**
+     * Constructs a new linear transform. This constructor is provided for subclasses only.
+     * Instances should be created using the {@linkplain #create factory method}, which
+     * may returns optimized implementations for some particular argument values.
+     *
+     * @param scale  The {@code scale}  term in the linear equation.
+     * @param offset The {@code offset} term in the linear equation.
+     */
+    protected LinearTransform1D(final double scale, final double offset) {
+        this.scale   = scale;
+        this.offset  = offset;
+    }
+
+    /**
+     * Constructs a new linear transform.
+     *
+     * @param scale  The {@code scale}  term in the linear equation.
+     * @param offset The {@code offset} term in the linear equation.
+     */
+    public static LinearTransform1D create(final double scale, final double offset) {
+        if (scale == 0) {
+            return new ConstantTransform1D(offset);
+        }
+        if (scale==1 && offset==0) {
+            return IDENTITY;
+        }
+        return new LinearTransform1D(scale, offset);
+    }
+
+    /**
+     * Returns the parameter descriptors for this math transform.
+     */
+    @Override
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return ProjectiveTransform.ProviderAffine.PARAMETERS;
+    }
+
+    /**
+     * Returns the matrix elements as a group of parameters values. The number of parameters
+     * depends on the matrix size. Only matrix elements different from their default value
+     * will be included in this group.
+     *
+     * @return A copy of the parameter values for this math transform.
+     */
+    @Override
+    public ParameterValueGroup getParameterValues() {
+        return ProjectiveTransform.getParameterValues(getMatrix());
+    }
+
+    /**
+     * Gets the dimension of input points, which is 1.
+     */
+    public int getSourceDimensions() {
+        return 1;
+    }
+
+    /**
+     * Gets the dimension of output points, which is 1.
+     */
+    public int getTargetDimensions() {
+        return 1;
+    }
+
+    /**
+     * Returns this transform as an affine transform matrix.
+     */
+    public Matrix getMatrix() {
+        return new Matrix2(scale, offset, 0, 1);
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public MathTransform1D inverse() throws NoninvertibleTransformException {
+        if (inverse == null) {
+            if (isIdentity()) {
+                inverse = this;
+            } else if (scale != 0) {
+                final LinearTransform1D inverse;
+                inverse = create(1/scale, -offset/scale);
+                inverse.inverse = this;
+                this.inverse = inverse;
+            } else {
+                inverse = (MathTransform1D) super.inverse();
+            }
+        }
+        return inverse;
+    }
+
+    /**
+     * Tests whether this transform does not move any points.
+     */
+    @Override
+    public boolean isIdentity() {
+       return isIdentity(0);
+    }
+
+    /**
+     * Tests whether this transform does not move any points by using the provided tolerance.
+     * This method work in the same way than
+     * {@link org.geotools.referencing.operation.matrix.XMatrix#isIdentity(double)}.
+     *
+     * @since 2.3.1
+     */
+    public boolean isIdentity(double tolerance) {
+        tolerance = Math.abs(tolerance);
+        return Math.abs(offset) <= tolerance && Math.abs(scale-1) <= tolerance;
+    }
+
+    /**
+     * Gets the derivative of this transform at a point.  This implementation is different
+     * from the default {@link AbstractMathTransform#derivative} implementation in that no
+     * coordinate point is required and {@link Double#NaN} may be a legal output value for
+     * some users.
+     */
+    @Override
+    public Matrix derivative(final DirectPosition point) throws TransformException {
+        return new Matrix1(scale);
+    }
+
+    /**
+     * Gets the derivative of this function at a value.
+     */
+    public double derivative(final double value) {
+        return scale;
+    }
+
+    /**
+     * Transforms the specified value.
+     */
+    public double transform(double value) {
+        return offset + scale*value;
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    @Override
+    public void transform(final float[] srcPts, int srcOff,
+                          final float[] dstPts, int dstOff, int numPts)
+    {
+        if (srcPts!=dstPts || srcOff>=dstOff) {
+            while (--numPts >= 0) {
+                dstPts[dstOff++] = (float) (offset + scale*srcPts[srcOff++]);
+            }
+        } else {
+            srcOff += numPts;
+            dstOff += numPts;
+            while (--numPts >= 0) {
+                dstPts[--dstOff] = (float) (offset + scale*srcPts[--srcOff]);
+            }
+        }
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    public void transform(final double[] srcPts, int srcOff,
+                          final double[] dstPts, int dstOff, int numPts)
+    {
+        if (srcPts!=dstPts || srcOff>=dstOff) {
+            while (--numPts >= 0) {
+                dstPts[dstOff++] = offset + scale*srcPts[srcOff++];
+            }
+        } else {
+            srcOff += numPts;
+            dstOff += numPts;
+            while (--numPts >= 0) {
+                dstPts[--dstOff] = offset + scale*srcPts[--srcOff];
+            }
+        }
+    }
+
+    /**
+     * Returns a hash value for this transform.
+     * This value need not remain consistent between
+     * different implementations of the same class.
+     */
+    @Override
+    public int hashCode() {
+        long code;
+        code = (int)serialVersionUID + Double.doubleToRawLongBits(offset);
+        code =  code*37              + Double.doubleToRawLongBits(scale);
+        return (int)(code >>> 32) ^ (int)code;
+    }
+
+    /**
+     * Compares the specified object with this math transform for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            // Slight optimization
+            return true;
+        }
+        if (super.equals(object)) {
+            final LinearTransform1D that = (LinearTransform1D) object;
+            return Double.doubleToRawLongBits(this.scale)  == Double.doubleToRawLongBits(that.scale) &&
+                   Double.doubleToRawLongBits(this.offset) == Double.doubleToRawLongBits(that.offset);
+            /*
+             * NOTE: 'LinearTransform1D' and 'ConstantTransform1D' are heavily used by 'Category'
+             *       from 'org.geotools.cv' package. It is essential for Cateory to differenciate
+             *       various NaN values. Because 'equals' is used by CanonicalSet.unique(Object)
+             *       (which is used by 'DefaultMathTransformFactory'), test for equality can't use
+             *       the doubleToLongBits method because it collapse all NaN into a single canonical
+             *       value. The 'doubleToRawLongBits' instead provided the needed functionality.
+             */
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/LogarithmicTransform1D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/LogarithmicTransform1D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/LogarithmicTransform1D.java	(revision 28000)
@@ -0,0 +1,436 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.io.Serializable;
+import javax.measure.unit.Unit;
+
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransform1D;
+
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.parameter.DefaultParameterDescriptor;
+import org.geotools.parameter.FloatParameter;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.referencing.operation.LinearTransform;
+import org.geotools.referencing.operation.MathTransformProvider;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.geotools.resources.i18n.Vocabulary;
+
+
+/**
+ * A one dimensional, logarithmic transform.
+ * Input values <var>x</var> are converted into
+ * output values <var>y</var> using the following equation:
+ *
+ * <p align="center"><var>y</var> &nbsp;=&nbsp;
+ * {@linkplain #offset} + log<sub>{@linkplain #base}</sub>(<var>x</var>)
+ * &nbsp;&nbsp;=&nbsp;&nbsp;
+ * {@linkplain #offset} + ln(<var>x</var>)/ln({@linkplain #base})</p>
+ *
+ * This transform is the inverse of {@link ExponentialTransform1D}.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/LogarithmicTransform1D.java $
+ * @version $Id: LogarithmicTransform1D.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see ExponentialTransform1D
+ * @see LinearTransform1D
+ */
+public class LogarithmicTransform1D extends AbstractMathTransform
+        implements MathTransform1D, Serializable
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 1535101265352133948L;
+
+    /**
+     * Tolerance value for floating point comparaison.
+     */
+    private static final double EPS = 1E-8;
+
+    /**
+     * The base of the logarithm.
+     */
+    public final double base;
+
+    /**
+     * Natural logarithm of {@link #base}.
+     */
+    final double lnBase;
+
+    /**
+     * The offset to add to the logarithm.
+     */
+    public final double offset;
+
+    /**
+     * The inverse of this transform. Created only when first needed.
+     * Serialized in order to avoid rounding error if this transform
+     * is actually the one which was created from the inverse.
+     */
+    private MathTransform1D inverse;
+
+    /**
+     * Constructs a new logarithmic transform which is the
+     * inverse of the supplied exponentional transform.
+     */
+    private LogarithmicTransform1D(final ExponentialTransform1D inverse) {
+        this.base    = inverse.base;
+        this.lnBase  = inverse.lnBase;
+        this.offset  = -Math.log(inverse.scale) / lnBase;
+        this.inverse = inverse;
+    }
+
+    /**
+     * Constructs a new logarithmic transform. This constructor is provided for subclasses only.
+     * Instances should be created using the {@linkplain #create factory method}, which
+     * may returns optimized implementations for some particular argument values.
+     *
+     * @param base    The base of the logarithm (typically 10).
+     * @param offset  The offset to add to the logarithm.
+     */
+    protected LogarithmicTransform1D(final double base, final double offset) {
+        this.base    = base;
+        this.offset  = offset;
+        this.lnBase  = Math.log(base);
+    }
+
+    /**
+     * Constructs a new logarithmic transform which is the
+     * inverse of the supplied exponentional transform.
+     */
+    static LogarithmicTransform1D create(final ExponentialTransform1D inverse) {
+        if (Math.abs(inverse.base - 10) < EPS) {
+            return new Base10(inverse);
+        }
+        return new LogarithmicTransform1D(inverse);
+    }
+
+    /**
+     * Constructs a new logarithmic transform.
+     *
+     * @param base    The base of the logarithm (typically 10).
+     * @param offset  The offset to add to the logarithm.
+     * @return The math transform.
+     */
+    public static MathTransform1D create(final double base, final double offset) {
+        if (base == Double.POSITIVE_INFINITY || Math.abs(base) <= EPS) {
+            return LinearTransform1D.create(0, offset);
+        }
+        if (Math.abs(base - 10) < EPS) {
+            return new Base10(offset);
+        }
+        return new LogarithmicTransform1D(base, offset);
+    }
+
+    /**
+     * Returns the parameter descriptors for this math transform.
+     */
+    @Override
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return Provider.PARAMETERS;
+    }
+
+    /**
+     * Returns the parameter values for this math transform.
+     *
+     * @return A copy of the parameter values for this math transform.
+     */
+    @Override
+    public ParameterValueGroup getParameterValues() {
+        return new org.geotools.parameter.ParameterGroup(getParameterDescriptors(),
+            new ParameterValue[] {
+            new FloatParameter(Provider.BASE,   base),
+            new FloatParameter(Provider.OFFSET, offset)});
+    }
+
+    /**
+     * Gets the dimension of input points, which is 1.
+     */
+    public int getSourceDimensions() {
+        return 1;
+    }
+
+    /**
+     * Gets the dimension of output points, which is 1.
+     */
+    public int getTargetDimensions() {
+        return 1;
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public MathTransform1D inverse() {
+        if (inverse == null) {
+            inverse = new ExponentialTransform1D(this);
+        }
+        return inverse;
+    }
+
+    /**
+     * Gets the derivative of this function at a value.
+     */
+    public double derivative(final double value) {
+        return 1 / (lnBase * value);
+    }
+
+    /**
+     * Transforms the specified value.
+     */
+    public double transform(final double value) {
+        return Math.log(value)/lnBase + offset;
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    @Override
+    public void transform(final float[] srcPts, int srcOff,
+                          final float[] dstPts, int dstOff, int numPts)
+    {
+        if (srcPts!=dstPts || srcOff>=dstOff) {
+            while (--numPts >= 0) {
+                dstPts[dstOff++] = (float) (Math.log(srcPts[srcOff++])/lnBase + offset);
+            }
+        } else {
+            srcOff += numPts;
+            dstOff += numPts;
+            while (--numPts >= 0) {
+                dstPts[--dstOff] = (float) (Math.log(srcPts[srcOff++])/lnBase + offset);
+            }
+        }
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    public void transform(final double[] srcPts, int srcOff,
+                          final double[] dstPts, int dstOff, int numPts)
+    {
+        if (srcPts!=dstPts || srcOff>=dstOff) {
+            while (--numPts >= 0) {
+                dstPts[dstOff++] = Math.log(srcPts[srcOff++])/lnBase + offset;
+            }
+        } else {
+            srcOff += numPts;
+            dstOff += numPts;
+            while (--numPts >= 0) {
+                dstPts[--dstOff] = Math.log(srcPts[srcOff++])/lnBase + offset;
+            }
+        }
+    }
+
+    /**
+     * Special case for base 10 taking advantage of extra precision provided by {@link Math#log10}.
+     */
+    private static final class Base10 extends LogarithmicTransform1D {
+        /** For cross-version compatibility. */
+        private static final long serialVersionUID = -5435804027536647558L;
+
+        /** Constructs the inverse of the supplied exponentional transform. */
+        Base10(final ExponentialTransform1D inverse) {
+            super(inverse);
+        }
+
+        /** Creates a new instance with the given offset. */
+        protected Base10(final double offset) {
+            super(10, offset);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public double transform(final double value) {
+            return Math.log10(value) + offset;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void transform(final float[] srcPts, int srcOff,
+                              final float[] dstPts, int dstOff, int numPts)
+        {
+            if (srcPts!=dstPts || srcOff>=dstOff) {
+                while (--numPts >= 0) {
+                    dstPts[dstOff++] = (float) (Math.log10(srcPts[srcOff++]) + offset);
+                }
+            } else {
+                srcOff += numPts;
+                dstOff += numPts;
+                while (--numPts >= 0) {
+                    dstPts[--dstOff] = (float) (Math.log10(srcPts[srcOff++]) + offset);
+                }
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void transform(final double[] srcPts, int srcOff,
+                              final double[] dstPts, int dstOff, int numPts)
+        {
+            if (srcPts!=dstPts || srcOff>=dstOff) {
+                while (--numPts >= 0) {
+                    dstPts[dstOff++] = Math.log10(srcPts[srcOff++]) + offset;
+                }
+            } else {
+                srcOff += numPts;
+                dstOff += numPts;
+                while (--numPts >= 0) {
+                    dstPts[--dstOff] = Math.log10(srcPts[srcOff++]) + offset;
+                }
+            }
+        }
+    }
+
+    /**
+     * Concatenates in an optimized way a {@link MathTransform} {@code other} to this
+     * {@code MathTransform}. This implementation can optimize some concatenation with
+     * {@link LinearTransform1D} and {@link ExponentialTransform1D}.
+     *
+     * @param  other The math transform to apply.
+     * @param  applyOtherFirst {@code true} if the transformation order is {@code other}
+     *         followed by {@code this}, or {@code false} if the transformation order is
+     *         {@code this} followed by {@code other}.
+     * @return The combined math transform, or {@code null} if no optimized combined
+     *         transform is available.
+     */
+    @Override
+    MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst) {
+        if (other instanceof LinearTransform) {
+            final LinearTransform1D linear = (LinearTransform1D) other;
+            if (applyOtherFirst) {
+                if (linear.offset==0 && linear.scale>0) {
+                    return create(base, Math.log(linear.scale)/lnBase+offset);
+                }
+            } else {
+                final double newBase = Math.pow(base, 1/linear.scale);
+                if (!Double.isNaN(newBase)) {
+                    return create(newBase, linear.scale*offset + linear.offset);
+                }
+            }
+        } else if (other instanceof ExponentialTransform1D) {
+            return ((ExponentialTransform1D) other).concatenateLog(this, !applyOtherFirst);
+        }
+        return super.concatenate(other, applyOtherFirst);
+    }
+
+    /**
+     * Returns a hash value for this transform.
+     * This value need not remain consistent between
+     * different implementations of the same class.
+     */
+    @Override
+    public int hashCode() {
+        long code;
+        code = serialVersionUID + Double.doubleToLongBits(base);
+        code =          code*37 + Double.doubleToLongBits(offset);
+        return (int)(code >>> 32) ^ (int)code;
+    }
+
+    /**
+     * Compares the specified object with this math transform for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            // Slight optimization
+            return true;
+        }
+        if (super.equals(object)) {
+            final LogarithmicTransform1D that = (LogarithmicTransform1D) object;
+            return Double.doubleToLongBits(this.base)   == Double.doubleToLongBits(that.base) &&
+                   Double.doubleToLongBits(this.offset) == Double.doubleToLongBits(that.offset);
+        }
+        return false;
+    }
+
+    /**
+     * The provider for the {@link LogarithmicTransform1D}.
+     *
+     * @version $Id: LogarithmicTransform1D.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     */
+    public static class Provider extends MathTransformProvider {
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID = -7235097164208708484L;
+
+        /**
+         * The operation parameter descriptor for the {@link #base base} parameter value.
+         * Valid values range from 0 to infinity. The default value is 10.
+         */
+        public static final ParameterDescriptor<Double> BASE = DefaultParameterDescriptor.create(
+                "base", 10, 0, Double.POSITIVE_INFINITY, Unit.ONE);
+
+        /**
+         * The operation parameter descriptor for the {@link #offset offset} parameter value.
+         * Valid values range is unrestricted. The default value is 0.
+         */
+        public static final ParameterDescriptor<Double> OFFSET =DefaultParameterDescriptor.create(
+                "offset", 0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Unit.ONE);
+
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new NamedIdentifier[] {
+                new NamedIdentifier(Citations.GEOTOOLS, Vocabulary.formatInternational(
+                                                        VocabularyKeys.LOGARITHMIC))
+            }, new ParameterDescriptor[] {
+                BASE, OFFSET
+            });
+
+        /**
+         * Create a provider for logarithmic transforms.
+         */
+        public Provider() {
+            super(1, 1, PARAMETERS);
+        }
+
+        /**
+         * Returns the operation type.
+         */
+        @Override
+        public Class<Conversion> getOperationType() {
+            return Conversion.class;
+        }
+
+        /**
+         * Creates a logarithmic transform from the specified group of parameter values.
+         *
+         * @param  values The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not found.
+         */
+        protected MathTransform1D createMathTransform(final ParameterValueGroup values)
+                throws ParameterNotFoundException
+        {
+            return create(doubleValue(BASE,   values),
+                          doubleValue(OFFSET, values));
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/MathTransformProxy.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/MathTransformProxy.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/MathTransformProxy.java	(revision 28000)
@@ -0,0 +1,195 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.io.Serializable;
+
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.MismatchedDimensionException;
+
+import org.geotools.util.Utilities;
+
+
+/**
+ * A math transform which delegates part of its work to an other math transform. This is used
+ * as a starting point for subclass wanting to modifies only some aspect of an existing math
+ * transform, or to attach additional informations to it. The default implementation delegates
+ * all method calls to the {@linkplain #transform underlying transform}. Subclasses typically
+ * override some of those methods.
+ * <p>
+ * This class is serializable if the {@linkplain #transform underlying transform} is serializable
+ * too.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/MathTransformProxy.java $
+ * @version $Id: MathTransformProxy.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class MathTransformProxy implements MathTransform, Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 8844242705205498128L;
+
+    /**
+     * The math transform on which to delegate the work.
+     */
+    public final MathTransform transform;
+
+    /**
+     * Creates a new proxy which delegates its work to the specified math transform.
+     *
+     * @param transform The transform on which to delegate the work.
+     */
+    protected MathTransformProxy(final MathTransform transform) {
+        this.transform = transform;
+    }
+
+    /**
+     * Gets the dimension of input points.
+     */
+    public int getSourceDimensions() {
+        return transform.getTargetDimensions();
+    }
+
+    /**
+     * Gets the dimension of output points.
+     */
+    public int getTargetDimensions() {
+        return transform.getSourceDimensions();
+    }
+
+    /**
+     * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
+     *
+     * @throws MismatchedDimensionException if {@code ptSrc} or
+     *         {@code ptDst} doesn't have the expected dimension.
+     * @throws TransformException if the point can't be transformed.
+     */
+    public DirectPosition transform(final DirectPosition ptSrc, final DirectPosition ptDst)
+            throws MismatchedDimensionException, TransformException
+    {
+        return transform.transform(ptSrc, ptDst);
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    public void transform(final double[] srcPts, final int srcOff,
+                          final double[] dstPts, final int dstOff,
+                          final int numPts) throws TransformException
+    {
+        transform.transform(srcPts, srcOff, dstPts, dstOff, numPts);
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    public void transform(final float[] srcPts, final int srcOff,
+                          final float[] dstPts, final int dstOff,
+                          final int numPts) throws TransformException
+    {
+        transform.transform(srcPts, srcOff, dstPts, dstOff, numPts);
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     *
+     * @todo Remove the cast to {@link AbstractMathTransform}
+     *       when this method will be part of GeoAPI.
+     */
+    public void transform(final float [] srcPts, final int srcOff,
+                          final double[] dstPts, final int dstOff,
+                          final int numPts) throws TransformException
+    {
+        ((AbstractMathTransform) transform).transform(srcPts, srcOff, dstPts, dstOff, numPts);
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     *
+     * @todo Remove the cast to {@link AbstractMathTransform}
+     *       when this method will be part of GeoAPI.
+     */
+    public void transform(final double[] srcPts, final int srcOff,
+                          final float [] dstPts, final int dstOff,
+                          final int numPts) throws TransformException
+    {
+        ((AbstractMathTransform) transform).transform(srcPts, srcOff, dstPts, dstOff, numPts);
+    }
+
+    /**
+     * Gets the derivative of this transform at a point.
+     */
+    public Matrix derivative(final DirectPosition point) throws TransformException {
+        return transform.derivative(point);
+    }
+
+    /**
+     * Returns the inverse of this math transform.
+     */
+    public MathTransform inverse() throws NoninvertibleTransformException {
+        return transform.inverse();
+    }
+
+    /**
+     * Tests whether this transform does not move any points.
+     */
+    public boolean isIdentity() {
+        return transform.isIdentity();
+    }
+
+    /**
+     * Returns a string representation for this transform.
+     */
+    @Override
+    public String toString() {
+        return transform.toString();
+    }
+
+    /**
+     * Compares the specified object with this inverse math transform for equality.
+     *
+     * @param object The object to compare with this transform.
+     * @return {@code true} if the given object is of the same class and if the wrapped
+     *         transforms are equal.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object!=null && object.getClass().equals(getClass())) {
+            final MathTransformProxy that = (MathTransformProxy) object;
+            return Utilities.equals(this.transform, that.transform);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this math transform.
+     */
+    @Override
+    public int hashCode() {
+        return transform.hashCode() ^ (int)serialVersionUID;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/MolodenskiTransform.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/MolodenskiTransform.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/MolodenskiTransform.java	(revision 28000)
@@ -0,0 +1,821 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import javax.measure.unit.SI;
+import static java.lang.Math.*;
+
+import org.opengis.util.GenericName;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.Transformation;
+
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.parameter.DefaultParameterDescriptor;
+import org.geotools.parameter.FloatParameter;
+import org.geotools.parameter.Parameter;
+import org.geotools.parameter.ParameterGroup;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.referencing.operation.MathTransformProvider;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+
+
+/**
+ * Two- or three-dimensional datum shift using the (potentially abridged) Molodensky transformation.
+ * The Molodensky transformation (EPSG code 9604) and the abridged Molodensky transformation (EPSG
+ * code 9605) transform two or three dimensional geographic points from one geographic coordinate
+ * reference system to another (a datum shift), using three shift parameters (delta X, delta Y,
+ * delta Z) and the difference between the semi-major axis and flattenings of the two ellipsoids.
+ * <p>
+ *
+ * Unlike the Bursa-Wolf 3 parameter method (which acts on geocentric coordinates),
+ * this transformation can be performed directly on geographic coordinates.
+ * <p>
+ *
+ * <strong>References:</strong><ul>
+ *   <li> Defense Mapping Agency (DMA), Datums, Ellipsoids, Grids and Grid Reference Systems,
+ *        Technical Manual 8358.1.
+ *        Available from <a href="http://earth-info.nga.mil/GandG/pubs.html">http://earth-info.nga.mil/GandG/pubs.html</a></li>
+ *   <li> Defense Mapping Agency (DMA), The Universal Grids: Universal Transverse
+ *        Mercator (UTM) and Universal Polar Stereographic (UPS), Fairfax VA, Technical Manual 8358.2.
+ *        Available from <a href="http://earth-info.nga.mil/GandG/pubs.html">http://earth-info.nga.mil/GandG/pubs.html</a></li>
+ *   <li> National Imagery and Mapping Agency (NIMA), Department of Defense World
+ *        Geodetic System 1984, Technical Report 8350.2.
+ *        Available from <a href="http://earth-info.nga.mil/GandG/pubs.html">http://earth-info.nga.mil/GandG/pubs.html</a></li>
+ *   <li> "Coordinate Conversions and Transformations including Formulas",
+ *        EPSG Guidence Note Number 7, Version 19.</li>
+ * </ul>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/MolodenskiTransform.java $
+ * @version $Id: MolodenskiTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Rueben Schulz
+ * @author Martin Desruisseaux
+ */
+public class MolodenskiTransform extends AbstractMathTransform implements Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 7536566033885338422L;
+
+    /**
+     * The tolerance error for assertions, in decimal degrees.
+     */
+    private static final float EPS = 1E-5f;
+
+    /**
+     * {@code true} for the abridged formula, or {@code false} for the complete version.
+     */
+    private final boolean abridged;
+
+    /**
+     * {@code true} for a 3D transformation, or
+     * {@code false} for a 2D transformation.
+     */
+    private final boolean source3D, target3D;
+
+    /**
+     * X,Y,Z shift in meters.
+     */
+    private final double dx, dy, dz;
+
+    /**
+     * Semi-major (<var>a</var>) semi-minor (<var>b/<var>) radius in meters.
+     */
+    private final double a, b;
+
+    /**
+     * Difference in the semi-major ({@code da = target a - source a}) and semi-minor
+     * ({@code db = target b - source b}) axes of the target and source ellipsoids.
+     */
+    private final double da, db;
+
+    /**
+     * Difference between the flattenings ({@code df = target f - source f})
+     * of the target and source ellipsoids.
+     */
+    private final double df;
+
+    /**
+     * Ratio of the Semi-major (<var>a</var>) semi-minor (<var>b/<var>) axis
+     * values ({@code a_b = a/b} and {@code b_a = b/a}).
+     */
+    private final double b_a, a_b;
+
+    /**
+     * Some more constants (<code>daa = da*a</code> and {@code da_a = da/a}).
+     */
+    private final double daa, da_a;
+
+    /**
+     * The square of excentricity of the ellipsoid: e² = (a²-b²)/a² where
+     * <var>a</var> is the semi-major axis length and
+     * <var>b</var> is the semi-minor axis length.
+     */
+    private final double e2;
+
+    /**
+     * Defined as <code>(a*df) + (f*da)</code>.
+     */
+    private final double adf;
+
+    /**
+     * The inverse of this transform. Will be created only when first needed.
+     */
+    private transient MolodenskiTransform inverse;
+
+    /**
+     * Constructs a Molodenski transform from the specified parameters.
+     *
+     * @param abridged {@code true} for the abridged formula, or {@code false} for the complete one.
+     * @param a        The source semi-major axis length in meters.
+     * @param b        The source semi-minor axis length in meters.
+     * @param source3D {@code true} if the source has a height.
+     * @param ta       The target semi-major axis length in meters.
+     * @param tb       The target semi-minor axis length in meters.
+     * @param target3D {@code true} if the target has a height.
+     * @param dx       The <var>x</var> translation in meters.
+     * @param dy       The <var>y</var> translation in meters.
+     * @param dz       The <var>z</var> translation in meters.
+     */
+    public MolodenskiTransform(final boolean abridged,
+                               final double  a, final double  b, final boolean source3D,
+                               final double ta, final double tb, final boolean target3D,
+                               final double dx, final double dy, final double  dz)
+    {
+        this.abridged = abridged;
+        this.source3D = source3D;
+        this.target3D = target3D;
+        this.dx       = dx;
+        this.dy       = dy;
+        this.dz       = dz;
+        this.a        = a;
+        this.b        = b;
+
+        da    =  ta - a;
+        db    =  tb - b;
+        a_b   =  a / b;
+        b_a   =  b / a;
+        daa   =  da * a;
+        da_a  =  da / a;
+        df    =  (ta-tb)/ta - (a-b)/a;
+        e2    =  1 - (b*b)/(a*a);
+        adf   =  (a*df) + (a-b)*da/a;
+    }
+
+    /**
+     * Returns the parameter descriptors for this math transform.
+     */
+    @Override
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return abridged ? ProviderAbridged.PARAMETERS : Provider.PARAMETERS;
+    }
+
+    /**
+     * Returns the parameters for this math transform.
+     *
+     * @return The parameters for this math transform.
+     */
+    @Override
+    public ParameterValueGroup getParameterValues() {
+        final ParameterValue<Integer> dim = new Parameter<Integer>(Provider.DIM);
+        dim.setValue(getSourceDimensions());
+        return new ParameterGroup(getParameterDescriptors(),
+               new ParameterValue[] {
+                   dim,
+                   new FloatParameter(Provider.DX,             dx),
+                   new FloatParameter(Provider.DY,             dy),
+                   new FloatParameter(Provider.DZ,             dz),
+                   new FloatParameter(Provider.SRC_SEMI_MAJOR, a),
+                   new FloatParameter(Provider.SRC_SEMI_MINOR, b),
+                   new FloatParameter(Provider.TGT_SEMI_MAJOR, a+da),
+                   new FloatParameter(Provider.TGT_SEMI_MINOR, b+db)
+               });
+    }
+
+    /**
+     * Gets the dimension of input points.
+     */
+    public int getSourceDimensions() {
+        return source3D ? 3 : 2;
+    }
+
+    /**
+     * Gets the dimension of output points.
+     */
+    public final int getTargetDimensions() {
+        return target3D ? 3 : 2;
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     * This method is provided for efficiently transforming many points.
+     * The supplied array of ordinal values will contain packed ordinal
+     * values.  For example, if the source dimension is 3, then the ordinals
+     * will be packed in this order:
+     *
+     * (<var>x<sub>0</sub></var>,<var>y<sub>0</sub></var>,<var>z<sub>0</sub></var>,
+     *  <var>x<sub>1</sub></var>,<var>y<sub>1</sub></var>,<var>z<sub>1</sub></var> ...).
+     *
+     * @param srcPts the array containing the source point coordinates.
+     * @param srcOff the offset to the first point to be transformed
+     *               in the source array.
+     * @param dstPts the array into which the transformed point
+     *               coordinates are returned. May be the same
+     *               than {@code srcPts}.
+     * @param dstOff the offset to the location of the first
+     *               transformed point that is stored in the
+     *               destination array.
+     * @param numPts the number of point objects to be transformed.
+     */
+    public void transform(double[] srcPts, int srcOff,
+                          double[] dstPts, int dstOff, int numPts)
+    {
+        transform(null, srcPts, srcOff, null, dstPts, dstOff, numPts);
+        /*
+         * Assertions: computes the inverse transform in the 3D-case only
+         *             (otherwise the transform is too approximative).
+         *
+         * NOTE: The somewhat complicated expression below executes 'maxError' *only* if
+         * 1) assertions are enabled and 2) the conditions before 'maxError' are meet. Do
+         * not factor the call to 'maxError' outside the 'assert' statement, otherwise it
+         * would be executed everytime and would hurt performance for normal operations
+         * (instead of slowing down during debugging only).
+         */
+        assert !(target3D && srcPts!=dstPts &&
+                (maxError(null, srcPts, srcOff, null, dstPts, dstOff, numPts)) > EPS);
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     * This method is provided for efficiently transforming many points.
+     * The supplied array of ordinal values will contain packed ordinal
+     * values.  For example, if the source dimension is 3, then the ordinals
+     * will be packed in this order:
+     *
+     * (<var>x<sub>0</sub></var>,<var>y<sub>0</sub></var>,<var>z<sub>0</sub></var>,
+     *  <var>x<sub>1</sub></var>,<var>y<sub>1</sub></var>,<var>z<sub>1</sub></var> ...).
+     *
+     * @param srcPts the array containing the source point coordinates.
+     * @param srcOff the offset to the first point to be transformed
+     *               in the source array.
+     * @param dstPts the array into which the transformed point
+     *               coordinates are returned. May be the same
+     *               than {@code srcPts}.
+     * @param dstOff the offset to the location of the first
+     *               transformed point that is stored in the
+     *               destination array.
+     * @param numPts the number of point objects to be transformed.
+     */
+    @Override
+    public void transform(final float[] srcPts, int srcOff,
+                          final float[] dstPts, int dstOff, int numPts)
+    {
+        transform(srcPts, null, srcOff, dstPts, null, dstOff, numPts);
+        /*
+         * Assertions: computes the inverse transform in the 3D-case only
+         *             (otherwise the transform is too approximative).
+         *
+         * NOTE: The somewhat complicated expression below executes 'maxError' *only* if
+         * 1) assertions are enabled and 2) the conditions before 'maxError' are meet. Do
+         * not factor the call to 'maxError' outside the 'assert' statement, otherwise it
+         * would be executed everytime and would hurt performance for normal operations
+         * (instead of slowing down during debugging only).
+         */
+        assert !(target3D && srcPts!=dstPts &&
+                (maxError(srcPts, null, srcOff, dstPts, null, dstOff, numPts)) > EPS);
+    }
+
+    /**
+     * Implementation of the transformation methods for all cases.
+     */
+    private void transform(final float[] srcPts1, final double[] srcPts2, int srcOff,
+                           final float[] dstPts1, final double[] dstPts2, int dstOff, int numPts)
+    {
+        int step = 0;
+        if ((srcPts2!=null ? srcPts2==dstPts2 : srcPts1==dstPts1) &&
+            srcOff<dstOff && srcOff+numPts*getSourceDimensions()>dstOff)
+        {
+            if (source3D != target3D) {
+                // TODO: we need to figure out a general way to handle this case
+                //       (overwritting the source array  while source and target
+                //       dimensions are not the same).   This case occurs enough
+                //       in the CTS implementation...
+                throw new UnsupportedOperationException("Not yet implemented.");
+            }
+            step = getSourceDimensions();
+            srcOff += (numPts-1)*step;
+            dstOff += (numPts-1)*step;
+            step *= -2;
+        }
+        while (--numPts >= 0) {
+            double x,y,z;
+            if (srcPts2 != null) {
+                x =              srcPts2[srcOff++];
+                y =              srcPts2[srcOff++];
+                z = (source3D) ? srcPts2[srcOff++] : 0.0;
+            } else {
+                x =              srcPts1[srcOff++];
+                y =              srcPts1[srcOff++];
+                z = (source3D) ? srcPts1[srcOff++] : 0.0;
+            }
+            x = toRadians(x);
+            y = toRadians(y);
+            final double sinX = sin(x);
+            final double cosX = cos(x);
+            final double sinY = sin(y);
+            final double cosY = cos(y);
+            final double sin2Y = sinY * sinY;
+            final double Rn = a / sqrt(1 - e2*sin2Y);
+            final double Rm = Rn * (1 - e2) / (1 - e2*sin2Y);
+
+            // Note: Computation of 'x' and 'y' ommit the division by sin(1"), because
+            //       1/sin(1") / (60*60*180/PI) = 1.0000000000039174050898603898692...
+            //       (60*60 is for converting the final result from seconds to degrees,
+            //       and 180/PI is for converting degrees to radians). This is an error
+            //       of about 8E-7 arc seconds, probably close to rounding errors anyway.
+            if (abridged) {
+                y += (dz*cosY - sinY*(dy*sinX + dx*cosX) + adf*sin(2*y)) / Rm;
+                x += (dy*cosX - dx*sinX) / (Rn*cosY);
+            } else {
+                y += (dz*cosY - sinY*(dy*sinX + dx*cosX) + da_a*(Rn*e2*sinY*cosY) +
+                      df*(Rm*(a_b) + Rn*(b_a))*sinY*cosY) / (Rm + z);
+                x += (dy*cosX - dx*sinX) / ((Rn + z)*cosY);
+            }
+            // stay within latitude +-90 deg. and longitude +-180 deg.
+            if (abs(y) > PI/2.0) {
+                if (dstPts2 != null) {
+                    dstPts2[dstOff++] = 0.0;
+                    dstPts2[dstOff++] = (y > 0.0) ? 90.0 : -90.0;
+                } else {
+                    dstPts1[dstOff++] = 0.0f;
+                    dstPts1[dstOff++] = (y > 0.0f) ? 90.0f : -90.0f;
+                }
+            } else {
+                x = toDegrees(rollLongitude(x));
+                y = toDegrees(y);
+                if (dstPts2 != null) {
+                    dstPts2[dstOff++] = x;
+                    dstPts2[dstOff++] = y;
+                } else {
+                    dstPts1[dstOff++] = (float) x;
+                    dstPts1[dstOff++] = (float) y;
+                }
+            }
+            if (target3D) {
+                if (abridged) {
+                    z += dx*cosY*cosX + dy*cosY*sinX + dz*sinY + adf*sin2Y - da;
+                } else {
+                    z += dx*cosY*cosX + dy*cosY*sinX + dz*sinY + df*(b_a)*Rn*sin2Y - daa/Rn;
+                }
+                if (dstPts2 != null) {
+                    dstPts2[dstOff++] = z;
+                } else {
+                    dstPts1[dstOff++] = (float) z;
+                }
+            }
+            srcOff += step;
+            dstOff += step;
+        }
+    }
+
+    /**
+     * After a call to {@code transform}, applies the <em>inverse</em> transform on {@code dstPts}
+     * and compares the result with {@code srcPts}. The maximal difference (in absolute value) is
+     * returned. This method is used for assertions.
+     */
+    private float maxError(final float[] srcPts1, final double[] srcPts2, int srcOff,
+                           final float[] dstPts1, final double[] dstPts2, int dstOff, int numPts)
+    {
+        float max = 0f;
+        if (inverse == null) {
+            inverse();
+            if (inverse == null) {
+                return max; // Custom user's subclass; can't do the test.
+            }
+        }
+        final int sourceDim = getSourceDimensions();
+        final float[] tmp = new float[numPts * sourceDim];
+        inverse.transform(dstPts1, dstPts2, dstOff, tmp, null, 0, numPts);
+        for (int i=0; i<tmp.length; i++,srcOff++) {
+            final float expected = (srcPts2!=null) ? (float)srcPts2[srcOff] : srcPts1[srcOff];
+            float error = abs(tmp[i] - expected);
+            switch (i % sourceDim) {
+                case 0: error -= 360 * floor(error / 360); break; // Rool Longitude
+                case 2: continue; // Ignore height because inacurate.
+            }
+            if (error > max) {
+                max = error;
+            }
+        }
+        return max;
+    }
+
+    /**
+     * Returns {@code true} if this transform is the identity one.
+     * This transform is considered identity (minus rounding errors) if:
+     * <p>
+     * <ul>
+     *   <li>the X,Y,Z shift are zero</li>
+     *   <li>the source and target axis length are the same</li>
+     *   <li>the input and output dimension are the same.</li>
+     * </ul>
+     *
+     * @since 2.5
+     */
+    @Override
+    public boolean isIdentity() {
+        return dx == 0 && dy == 0 && dz == 0 && da == 0 && db == 0 && source3D == target3D;
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public MathTransform inverse() {
+        if (inverse == null) {
+            inverse = new MolodenskiTransform(abridged,
+                      a+da, b+db, target3D, a, b, source3D, -dx, -dy, -dz);
+            inverse.inverse = this;
+        }
+        return inverse;
+    }
+
+    /**
+     * Returns a hash value for this transform.
+     */
+    @Override
+    public final int hashCode() {
+        final long code = Double.doubleToLongBits(dx) +
+                      37*(Double.doubleToLongBits(dy) +
+                      37*(Double.doubleToLongBits(dz) +
+                      37*(Double.doubleToLongBits(a ) +
+                      37*(Double.doubleToLongBits(b ) +
+                      37*(Double.doubleToLongBits(da) +
+                      37*(Double.doubleToLongBits(db)))))));
+        int c = (int) code ^ (int) (code >>> 32) ^ (int)serialVersionUID;
+        if (abridged) c = ~c;
+        return c;
+    }
+
+    /**
+     * Compares the specified object with this math transform for equality.
+     */
+    @Override
+    public final boolean equals(final Object object) {
+        if (object == this) {
+            // Slight optimization
+            return true;
+        }
+        if (super.equals(object)) {
+            final MolodenskiTransform that = (MolodenskiTransform) object;
+            return this.abridged == that.abridged &&
+                   this.source3D == that.source3D &&
+                   this.target3D == that.target3D &&
+                   Double.doubleToLongBits(this.dx) == Double.doubleToLongBits(that.dx) &&
+                   Double.doubleToLongBits(this.dy) == Double.doubleToLongBits(that.dy) &&
+                   Double.doubleToLongBits(this.dz) == Double.doubleToLongBits(that.dz) &&
+                   Double.doubleToLongBits(this.a ) == Double.doubleToLongBits(that.a ) &&
+                   Double.doubleToLongBits(this.b ) == Double.doubleToLongBits(that.b ) &&
+                   Double.doubleToLongBits(this.da) == Double.doubleToLongBits(that.da) &&
+                   Double.doubleToLongBits(this.db) == Double.doubleToLongBits(that.db);
+        }
+        return false;
+    }
+
+    /**
+     * A Molodenski transforms in 2D. This implementation is identical to
+     * {@link MolodenksiTransform} except that it implements {@link MathTransform2D}.
+     */
+    private static final class As2D extends MolodenskiTransform implements MathTransform2D {
+        /** Serial number for compatibility with different versions. */
+        private static final long serialVersionUID = 8098439371246167474L;
+
+        /** Constructs a 2D transform using Molodenski formulas. */
+        public As2D(final boolean abridged,
+                    final double  a, final double  b,
+                    final double ta, final double tb,
+                    final double dx, final double dy, final double  dz)
+        {
+            super(abridged, a, b, false, ta, tb, false, dx, dy, dz);
+        }
+
+        /** Creates the inverse transform of this object. */
+        @Override
+        public MathTransform2D inverse() {
+            if (super.inverse == null) {
+                super.inverse = new As2D(super.abridged,
+                        super.a + super.da, super.b + super.db,
+                        super.a, super.b, -super.dx, -super.dy, -super.dz);
+                super.inverse.inverse = this;
+            }
+            return (MathTransform2D) super.inverse;
+        }
+    }
+
+    /**
+     * The provider for {@link MolodenskiTransform}. This provider will construct
+     * transforms from {@linkplain org.geotools.referencing.crs.DefaultGeographicCRS geographic}
+     * to {@linkplain org.geotools.referencing.crs.DefaultGeographicCRS geographic} coordinate
+     * reference systems.
+     * <p>
+     * <strong>Note:</strong>
+     * The EPSG does not use src_semi_major, etc. parameters and instead uses
+     * "Semi-major axis length difference" and "Flattening difference".
+     *
+     * @version $Id: MolodenskiTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Rueben Schulz
+     */
+    public static class Provider extends MathTransformProvider {
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID = -5332126871499059030L;
+
+        /**
+         * The default value for source and target geographic dimensions, which is 2.
+         */
+        // NOTE: If this default value is modified, then
+        // the handling of the 3D cases must be adjusted.
+        static final int DEFAULT_DIMENSION = GeocentricTranslation.Provider.DEFAULT_DIMENSION;
+
+        /**
+         * The number of geographic dimension (2 or 3). This argument applies on
+         * both the source and the target dimension. The default value is 2.
+         */
+        public static final ParameterDescriptor<Integer> DIM =DefaultParameterDescriptor.create(
+                    Collections.singletonMap(NAME_KEY,
+                        new NamedIdentifier(Citations.OGC, "dim")),
+                    DEFAULT_DIMENSION, 2, 3, false);
+
+        /**
+         * The operation parameter descriptor for the <cite>X-axis translation</cite> ("dx")
+         * parameter value. Valid values range from -infinity to infinity. Units are meters.
+         */
+        public static final ParameterDescriptor<Double> DX =
+                GeocentricTranslation.Provider.DX;
+
+        /**
+         * The operation parameter descriptor for the <cite>Y-axis translation</cite> ("dy")
+         * parameter value. Valid values range from -infinity to infinity. Units are meters.
+         */
+        public static final ParameterDescriptor<Double> DY =
+                GeocentricTranslation.Provider.DY;
+
+        /**
+         * The operation parameter descriptor for the <cite>Z-axis translation</cite> ("dz")
+         * parameter value. Valid values range from -infinity to infinity. Units are meters.
+         */
+        public static final ParameterDescriptor<Double> DZ =
+                GeocentricTranslation.Provider.DZ;
+
+        /**
+         * The operation parameter descriptor for the "src_semi_major" parameter value.
+         * Valid values range from 0 to infinity.
+         */
+        public static final ParameterDescriptor<Double> SRC_SEMI_MAJOR = createDescriptor(
+                identifiers(GeocentricTranslation.Provider.SRC_SEMI_MAJOR),
+                Double.NaN, 0.0, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The operation parameter descriptor for the "src_semi_minor" parameter value.
+         * Valid values range from 0 to infinity.
+         */
+        public static final ParameterDescriptor<Double> SRC_SEMI_MINOR = createDescriptor(
+                identifiers(GeocentricTranslation.Provider.SRC_SEMI_MINOR),
+                Double.NaN, 0.0, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The operation parameter descriptor for the "tgt_semi_major" parameter value.
+         * Valid values range from 0 to infinity.
+         */
+        public static final ParameterDescriptor<Double> TGT_SEMI_MAJOR = createDescriptor(
+                identifiers(GeocentricTranslation.Provider.TGT_SEMI_MAJOR),
+                Double.NaN, 0.0, Double.POSITIVE_INFINITY, SI.METER);
+
+        /**
+         * The operation parameter descriptor for the "tgt_semi_minor" parameter value.
+         * Valid values range from 0 to infinity.
+         */
+        public static final ParameterDescriptor<Double> TGT_SEMI_MINOR = createDescriptor(
+                identifiers(GeocentricTranslation.Provider.TGT_SEMI_MINOR),
+                Double.NaN, 0.0, Double.POSITIVE_INFINITY, SI.METER);
+
+        /** Helper method for parameter descriptor creation. */
+        private static final NamedIdentifier[] identifiers(final ParameterDescriptor parameter) {
+            final Collection<GenericName> id = parameter.getAlias();
+            return id.toArray(new NamedIdentifier[id.size()]);
+        }
+
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new NamedIdentifier[] {
+                new NamedIdentifier(Citations.OGC,      "Molodenski"),
+                new NamedIdentifier(Citations.EPSG,     "Molodenski"),
+                new NamedIdentifier(Citations.EPSG,     "9604"),
+                new NamedIdentifier(Citations.GEOTOOLS, Vocabulary.formatInternational(
+                                                        VocabularyKeys.MOLODENSKI_TRANSFORM))
+            }, new ParameterDescriptor[] {
+                DIM, DX, DY, DZ,
+                SRC_SEMI_MAJOR, SRC_SEMI_MINOR,
+                TGT_SEMI_MAJOR, TGT_SEMI_MINOR
+            });
+
+        /**
+         * The provider for the 3D case. Will be constructed
+         * by {@link #getMethod} when first needed.
+         */
+        private transient Provider withHeight;
+
+        /**
+         * Constructs a provider.
+         */
+        public Provider() {
+            super(DEFAULT_DIMENSION, DEFAULT_DIMENSION, PARAMETERS);
+        }
+
+        /**
+         * Constructs a provider from a set of parameters.
+         *
+         * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
+         * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+         * @param parameters       The set of parameters (never {@code null}).
+         */
+        Provider(final int sourceDimensions,
+                 final int targetDimensions,
+                 final ParameterDescriptorGroup parameters)
+        {
+            super(sourceDimensions, targetDimensions, parameters);
+        }
+
+        /**
+         * Returns the operation type.
+         */
+        @Override
+        public Class<Transformation> getOperationType() {
+            return Transformation.class;
+        }
+
+        /**
+         * Creates a math transform from the specified group of parameter values.
+         *
+         * @param  values The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not found.
+         */
+        protected MathTransform createMathTransform(final ParameterValueGroup values)
+                throws ParameterNotFoundException
+        {
+            final boolean hasHeight;
+            final int dim = intValue(DIM, values);
+            switch (dim) {
+                case 0: // Default value: fall through
+                case DEFAULT_DIMENSION: {
+                    hasHeight = false;
+                    break;
+                }
+                case 3: {
+                    hasHeight = true;
+                    if (withHeight == null) {
+                        withHeight = create3D();
+                    }
+                    break;
+                }
+                default: {
+                    throw new IllegalArgumentException(Errors.format(
+                            ErrorKeys.ILLEGAL_ARGUMENT_$2, "dim", dim));
+                }
+            }
+            final double  a = doubleValue(SRC_SEMI_MAJOR, values);
+            final double  b = doubleValue(SRC_SEMI_MINOR, values);
+            final double ta = doubleValue(TGT_SEMI_MAJOR, values);
+            final double tb = doubleValue(TGT_SEMI_MINOR, values);
+            final double dx = doubleValue(DX,             values);
+            final double dy = doubleValue(DY,             values);
+            final double dz = doubleValue(DZ,             values);
+            final boolean abridged = isAbridged();
+            if (!hasHeight) {
+                return new As2D(abridged, a, b, ta, tb, dx, dy, dz);
+            } else {
+                return new Delegate(new MolodenskiTransform(
+                        abridged, a, b, hasHeight, ta, tb, hasHeight, dx, dy, dz), withHeight);
+            }
+        }
+
+        /**
+         * Creates the 3D-version of this provider.
+         * This method is overridden by {@link ProviderAbridged}.
+         */
+        Provider create3D() {
+            return new Provider(3, 3, PARAMETERS);
+        }
+
+        /**
+         * Returns {@code true} for the abridged formulas.
+         * This method is overridden by {@link ProviderAbridged}.
+         */
+        boolean isAbridged() {
+            return false;
+        }
+    }
+
+    /**
+     * The provider for abridged {@link MolodenskiTransform}. This provider will construct
+     * transforms from {@linkplain org.geotools.referencing.crs.DefaultGeographicCRS geographic}
+     * to {@linkplain org.geotools.referencing.crs.DefaultGeographicCRS geographic} coordinate
+     * reference systems.
+     * <p>
+     * <strong>Note:</strong>
+     * The EPSG does not use src_semi_major, etc. parameters and instead uses
+     * "Semi-major axis length difference" and "Flattening difference".
+     *
+     * @version $Id: MolodenskiTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux
+     * @author Rueben Schulz
+     */
+    public static class ProviderAbridged extends Provider {
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID = 9148242601566635131L;
+
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new NamedIdentifier[] {
+                new NamedIdentifier(Citations.OGC,      "Abridged_Molodenski"),
+                new NamedIdentifier(Citations.EPSG,     "Abridged Molodenski"),
+                new NamedIdentifier(Citations.EPSG,     "9605"),
+                new NamedIdentifier(Citations.GEOTOOLS, Vocabulary.format(
+                                    VocabularyKeys.ABRIDGED_MOLODENSKI_TRANSFORM))
+            }, new ParameterDescriptor[] {
+                DIM, DX, DY, DZ,
+                SRC_SEMI_MAJOR, SRC_SEMI_MINOR,
+                TGT_SEMI_MAJOR, TGT_SEMI_MINOR
+            });
+
+        /**
+         * Constructs a provider.
+         */
+        public ProviderAbridged() {
+            super(DEFAULT_DIMENSION, DEFAULT_DIMENSION, PARAMETERS);
+        }
+
+        /**
+         * Constructs a provider from a set of parameters.
+         *
+         * @param sourceDimensions Number of dimensions in the source CRS of this operation method.
+         * @param targetDimensions Number of dimensions in the target CRS of this operation method.
+         * @param parameters       The set of parameters (never {@code null}).
+         */
+        private ProviderAbridged(final int sourceDimensions,
+                                 final int targetDimensions,
+                                 final ParameterDescriptorGroup parameters)
+        {
+            super(sourceDimensions, targetDimensions, parameters);
+        }
+
+        /**
+         * Creates the 3D-version of this provider.
+         */
+        @Override
+        Provider create3D() {
+            return new ProviderAbridged(3, 3, PARAMETERS);
+        }
+
+        /**
+         * Returns {@code true} for the abridged formulas.
+         */
+        @Override
+        boolean isAbridged() {
+            return true;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/PassThroughTransform.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/PassThroughTransform.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/PassThroughTransform.java	(revision 28000)
@@ -0,0 +1,387 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.io.Serializable;
+
+import org.geotools.geometry.GeneralDirectPosition;
+import org.geotools.referencing.operation.LinearTransform;
+import org.geotools.referencing.operation.matrix.GeneralMatrix;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.Utilities;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.TransformException;
+
+
+/**
+ * Transform which passes through a subset of ordinates to another transform.
+ * This allows transforms to operate on a subset of ordinates.  For example,
+ * if you have (<var>latitude</var>,<var>longitude</var>,<var>height</var>)
+ * coordinates, then you may wish to convert the height values from feet to
+ * meters without affecting the latitude and longitude values.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/PassThroughTransform.java $
+ * @version $Id: PassThroughTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see DimensionFilter
+ */
+public class PassThroughTransform extends AbstractMathTransform implements Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -1673997634240223449L;
+
+    /**
+     * Index of the first affected ordinate.
+     */
+    protected final int firstAffectedOrdinate;
+
+    /**
+     * Number of unaffected ordinates after the affected ones.
+     * Always 0 when used through the strict OpenGIS API.
+     */
+    protected final int numTrailingOrdinates;
+
+    /**
+     * The sub transform.
+     *
+     * @see #getSubTransform
+     */
+    protected final MathTransform subTransform;
+
+    /**
+     * The inverse transform. This field will be computed only when needed.
+     * But it is serialized in order to avoid rounding error.
+     */
+    private PassThroughTransform inverse;
+
+    /**
+     * Create a pass through transform.
+     *
+     * @param firstAffectedOrdinate Index of the first affected ordinate.
+     * @param subTransform The sub transform.
+     * @param numTrailingOrdinates Number of trailing ordinates to pass through.
+     *        Affected ordinates will range from {@code firstAffectedOrdinate}
+     *        inclusive to {@code dimTarget-numTrailingOrdinates} exclusive.
+     */
+    protected PassThroughTransform(final int firstAffectedOrdinate,
+                                   final MathTransform subTransform,
+                                   final int numTrailingOrdinates)
+    {
+        if (firstAffectedOrdinate < 0) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2,
+                      "firstAffectedOrdinate", firstAffectedOrdinate));
+        }
+        if (numTrailingOrdinates < 0) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2,
+                      "numTrailingOrdinates", numTrailingOrdinates));
+        }
+        if (subTransform instanceof PassThroughTransform) {
+            final PassThroughTransform passThrough = (PassThroughTransform) subTransform;
+            this.firstAffectedOrdinate = passThrough.firstAffectedOrdinate + firstAffectedOrdinate;
+            this.numTrailingOrdinates  = passThrough.numTrailingOrdinates  + numTrailingOrdinates;
+            this.subTransform          = passThrough.subTransform;
+        }  else {
+            this.firstAffectedOrdinate = firstAffectedOrdinate;
+            this.numTrailingOrdinates  = numTrailingOrdinates;
+            this.subTransform          = subTransform;
+        }
+    }
+
+    /**
+     * Creates a transform which passes through a subset of ordinates to another transform.
+     * This allows transforms to operate on a subset of ordinates. For example, if you have
+     * (<var>latitidue</var>,<var>longitude</var>,<var>height</var>) coordinates, then you
+     * may wish to convert the height values from feet to meters without affecting the
+     * latitude and longitude values.
+     *
+     * @param  firstAffectedOrdinate Index of the first affected ordinate.
+     * @param  subTransform The sub transform.
+     * @param  numTrailingOrdinates Number of trailing ordinates to pass through.
+     *         Affected ordinates will range from {@code firstAffectedOrdinate}
+     *         inclusive to {@code dimTarget-numTrailingOrdinates} exclusive.
+     * @return A pass through transform with the following dimensions:<br>
+     *         <pre>
+     * Source: firstAffectedOrdinate + subTransform.getSourceDimensions() + numTrailingOrdinates
+     * Target: firstAffectedOrdinate + subTransform.getTargetDimensions() + numTrailingOrdinates</pre>
+     */
+    public static MathTransform create(final int firstAffectedOrdinate,
+                                       final MathTransform subTransform,
+                                       final int numTrailingOrdinates)
+    {
+        if (firstAffectedOrdinate < 0) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2,
+                      "firstAffectedOrdinate", firstAffectedOrdinate));
+        }
+        if (numTrailingOrdinates < 0) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2,
+                      "numTrailingOrdinates", numTrailingOrdinates));
+        }
+        if (firstAffectedOrdinate==0 && numTrailingOrdinates==0) {
+            return subTransform;
+        }
+        /*
+         * Optimize the "Identity transform" case.
+         */
+        if (subTransform.isIdentity()) {
+            final int dimension = subTransform.getSourceDimensions();
+            if (dimension == subTransform.getTargetDimensions()) {
+                return IdentityTransform.create(firstAffectedOrdinate + dimension + numTrailingOrdinates);
+            }
+        }
+        /*
+         * Special case for transformation backed by a matrix. Is is possible to use a
+         * new matrix for such transform, instead of wrapping the sub-transform into a
+         * PassThroughTransform object. It is faster and easier to concatenate.
+         */
+        if (subTransform instanceof LinearTransform) {
+            GeneralMatrix matrix = toGMatrix(((LinearTransform)subTransform).getMatrix());
+            matrix = PassThroughTransform.expand(matrix, firstAffectedOrdinate, numTrailingOrdinates, 1);
+            return ProjectiveTransform.create(matrix);
+        }
+        /*
+         * Constructs the general PassThroughTransform object. An optimisation
+         * for the "Pass through case" is done right in the  constructor.
+         */
+        return new PassThroughTransform(firstAffectedOrdinate, subTransform, numTrailingOrdinates);
+    }
+
+    /**
+     * Returns the sub transform.
+     *
+     * @return The sub transform.
+     *
+     * @since 2.2
+     */
+    public MathTransform getSubTransform() {
+        return subTransform;
+    }
+
+    /**
+     * Gets the dimension of input points.
+     */
+    public int getSourceDimensions() {
+        return firstAffectedOrdinate + subTransform.getSourceDimensions() + numTrailingOrdinates;
+    }
+
+    /**
+     * Gets the dimension of output points.
+     */
+    public int getTargetDimensions() {
+        return firstAffectedOrdinate + subTransform.getTargetDimensions() + numTrailingOrdinates;
+    }
+
+    /**
+     * Tests whether this transform does not move any points.
+     */
+    @Override
+    public boolean isIdentity() {
+        return subTransform.isIdentity();
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    @Override
+    public void transform(final float[] srcPts, int srcOff,
+                          final float[] dstPts, int dstOff, int numPts)
+        throws TransformException
+    {
+        final int subDimSource = subTransform.getSourceDimensions();
+        final int subDimTarget = subTransform.getTargetDimensions();
+        int srcStep = numTrailingOrdinates;
+        int dstStep = numTrailingOrdinates;
+        if (srcPts==dstPts && srcOff<dstOff) {
+            final int dimSource = getSourceDimensions();
+            final int dimTarget = getTargetDimensions();
+            srcOff += numPts * dimSource;
+            dstOff += numPts * dimTarget;
+            srcStep -= 2*dimSource;
+            dstStep -= 2*dimTarget;
+        }
+        while (--numPts >= 0) {
+            System.arraycopy      (srcPts, srcOff,                        dstPts, dstOff,              firstAffectedOrdinate);
+            subTransform.transform(srcPts, srcOff+=firstAffectedOrdinate, dstPts, dstOff+=firstAffectedOrdinate,           1);
+            System.arraycopy      (srcPts, srcOff+=subDimSource,          dstPts, dstOff+=subDimTarget, numTrailingOrdinates);
+            srcOff += srcStep;
+            dstOff += dstStep;
+        }
+    }
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     */
+    public void transform(final double[] srcPts, int srcOff,
+                          final double[] dstPts, int dstOff, int numPts)
+        throws TransformException
+    {
+        final int subDimSource = subTransform.getSourceDimensions();
+        final int subDimTarget = subTransform.getTargetDimensions();
+        int srcStep = numTrailingOrdinates;
+        int dstStep = numTrailingOrdinates;
+        if (srcPts==dstPts && srcOff<dstOff) {
+            final int dimSource = getSourceDimensions();
+            final int dimTarget = getTargetDimensions();
+            srcOff += numPts * dimSource;
+            dstOff += numPts * dimTarget;
+            srcStep -= 2*dimSource;
+            dstStep -= 2*dimTarget;
+        }
+        while (--numPts >= 0) {
+            System.arraycopy      (srcPts, srcOff,                        dstPts, dstOff,              firstAffectedOrdinate);
+            subTransform.transform(srcPts, srcOff+=firstAffectedOrdinate, dstPts, dstOff+=firstAffectedOrdinate,           1);
+            System.arraycopy      (srcPts, srcOff+=subDimSource,          dstPts, dstOff+=subDimTarget, numTrailingOrdinates);
+            srcOff += srcStep;
+            dstOff += dstStep;
+        }
+    }
+
+    /**
+     * Gets the derivative of this transform at a point.
+     */
+    @Override
+    public Matrix derivative(final DirectPosition point) throws TransformException {
+        final int nSkipped = firstAffectedOrdinate + numTrailingOrdinates;
+        final int transDim = subTransform.getSourceDimensions();
+        final int pointDim = point.getDimension();
+        if (pointDim != transDim+nSkipped) {
+            throw new MismatchedDimensionException(Errors.format(
+                        ErrorKeys.MISMATCHED_DIMENSION_$3, "point", pointDim, transDim + nSkipped));
+        }
+        final GeneralDirectPosition subPoint = new GeneralDirectPosition(transDim);
+        for (int i=0; i<transDim; i++) {
+            subPoint.ordinates[i] = point.getOrdinate(i + firstAffectedOrdinate);
+        }
+        return expand(toGMatrix(subTransform.derivative(subPoint)),
+                      firstAffectedOrdinate, numTrailingOrdinates, 0);
+    }
+
+    /**
+     * Creates a pass through transform from a matrix. This method is invoked when the
+     * sub-transform can be express as a matrix. It is also invoked for computing the
+     * matrix returned by {@link #derivative}.
+     *
+     * @param subMatrix The sub-transform as a matrix.
+     * @param firstAffectedOrdinate Index of the first affected ordinate.
+     * @param numTrailingOrdinates Number of trailing ordinates to pass through.
+     * @param affine 0 if the matrix do not contains translation terms, or 1 if
+     *        the matrix is an affine transform with translation terms.
+     */
+    private static GeneralMatrix expand(final GeneralMatrix subMatrix,
+                                        final int firstAffectedOrdinate,
+                                        final int numTrailingOrdinates,
+                                        final int affine)
+    {
+        final int         nSkipped = firstAffectedOrdinate + numTrailingOrdinates;
+        final int           numRow = subMatrix.getNumRow() - affine;
+        final int           numCol = subMatrix.getNumCol() - affine;
+        final GeneralMatrix matrix = new GeneralMatrix(numRow + nSkipped + affine,
+                                                       numCol + nSkipped + affine);
+        matrix.setZero();
+
+        //  Set UL part to 1:   [ 1  0             ]
+        //                      [ 0  1             ]
+        //                      [                  ]
+        //                      [                  ]
+        //                      [                  ]
+        for (int j=0; j<firstAffectedOrdinate; j++) {
+            matrix.setElement(j, j, 1);
+        }
+        //  Set central part:   [ 1  0  0  0  0  0 ]
+        //                      [ 0  1  0  0  0  0 ]
+        //                      [ 0  0  ?  ?  ?  0 ]
+        //                      [ 0  0  ?  ?  ?  0 ]
+        //                      [                  ]
+        subMatrix.copySubMatrix(0, 0, numRow, numCol,
+                                firstAffectedOrdinate, firstAffectedOrdinate, matrix);
+
+        //  Set LR part to 1:   [ 1  0  0  0  0  0 ]
+        //                      [ 0  1  0  0  0  0 ]
+        //                      [ 0  0  ?  ?  ?  0 ]
+        //                      [ 0  0  ?  ?  ?  0 ]
+        //                      [ 0  0  0  0  0  1 ]
+        final int offset = numCol-numRow;
+        final int numRowOut = numRow + nSkipped;
+        for (int j=numRowOut-numTrailingOrdinates; j<numRowOut; j++) {
+            matrix.setElement(j, j+offset, 1);
+        }
+        if (affine != 0) {
+            // Copy the translation terms in the last column.
+            subMatrix.copySubMatrix(0, numCol, numRow, affine,
+                                    firstAffectedOrdinate, numCol+nSkipped, matrix);
+            // Copy the last row as a safety, but it should contains only 0.
+            subMatrix.copySubMatrix(numRow, 0, affine, numCol,
+                                    numRow+nSkipped, firstAffectedOrdinate, matrix);
+            // Copy the lower right corner, which should contains only 1.
+            subMatrix.copySubMatrix(numRow, numCol, affine, affine,
+                                    numRow+nSkipped, numCol+nSkipped, matrix);
+        }
+        return matrix;
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public synchronized MathTransform inverse() throws NoninvertibleTransformException {
+        if (inverse == null) {
+            inverse = new PassThroughTransform(
+                    firstAffectedOrdinate, subTransform.inverse(), numTrailingOrdinates);
+            inverse.inverse = this;
+        }
+        return inverse;
+    }
+
+    /**
+     * Returns a hash value for this transform.
+     * This value need not remain consistent between
+     * different implementations of the same class.
+     */
+    @Override
+    public int hashCode() {
+        int code = (int)serialVersionUID + firstAffectedOrdinate + 37*numTrailingOrdinates;
+        if (subTransform != null) {
+            code ^= subTransform.hashCode();
+        }
+        return code;
+    }
+
+    /**
+     * Compares the specified object with this math transform for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (super.equals(object)) {
+            final PassThroughTransform that = (PassThroughTransform) object;
+            return this.firstAffectedOrdinate == that.firstAffectedOrdinate &&
+                   this.numTrailingOrdinates  == that.numTrailingOrdinates  &&
+                   Utilities.equals(this.subTransform, that.subTransform);
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ProjectiveTransform.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ProjectiveTransform.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ProjectiveTransform.java	(revision 28000)
@@ -0,0 +1,662 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.operation.transform;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.measure.unit.NonSI;
+import javax.vecmath.MismatchedSizeException;
+import javax.vecmath.SingularMatrixException;
+
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.parameter.MatrixParameterDescriptors;
+import org.geotools.parameter.MatrixParameters;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.referencing.operation.LinearTransform;
+import org.geotools.referencing.operation.MathTransformProvider;
+import org.geotools.referencing.operation.matrix.GeneralMatrix;
+import org.geotools.referencing.operation.matrix.XMatrix;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+
+
+/**
+ * A usually affine, or otherwise a projective transform. A projective transform is capable of
+ * mapping an arbitrary quadrilateral into another arbitrary quadrilateral, while preserving the
+ * straightness of lines. In the special case where the transform is affine, the parallelism of
+ * lines in the source is preserved in the output.
+ * <p>
+ * Such a coordinate transformation can be represented by a square {@linkplain GeneralMatrix matrix}
+ * of an arbitrary size. Point coordinates must have a dimension equals to
+ * <code>{@linkplain Matrix#getNumCol}-1</code>. For example, for square matrix of size 4&times;4,
+ * coordinate points are three-dimensional. The transformed points <code>(x',y',z')</code> are
+ * computed as below (note that this computation is similar to
+ * {@link javax.media.jai.PerspectiveTransform} in <cite>Java Advanced Imaging</cite>):
+ *
+ * <blockquote><pre>
+ * [ u ]     [ m<sub>00</sub>  m<sub>01</sub>  m<sub>02</sub>  m<sub>03</sub> ] [ x ]
+ * [ v ]  =  [ m<sub>10</sub>  m<sub>11</sub>  m<sub>12</sub>  m<sub>13</sub> ] [ y ]
+ * [ w ]     [ m<sub>20</sub>  m<sub>21</sub>  m<sub>22</sub>  m<sub>23</sub> ] [ z ]
+ * [ t ]     [ m<sub>30</sub>  m<sub>31</sub>  m<sub>32</sub>  m<sub>33</sub> ] [ 1 ]
+ *
+ *   x' = u/t
+ *   y' = v/t
+ *   y' = w/t
+ * </pre></blockquote>
+ *
+ * In the special case of an affine transform, the last row contains only zero
+ * values except in the last column, which contains 1.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/ProjectiveTransform.java $
+ * @version $Id: ProjectiveTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see javax.media.jai.PerspectiveTransform
+ * @see java.awt.geom.AffineTransform
+ * @see <A HREF="http://mathworld.wolfram.com/AffineTransformation.html">Affine transformation on MathWorld</A>
+ */
+public class ProjectiveTransform extends AbstractMathTransform implements LinearTransform, Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -2104496465933824935L;
+
+    /**
+     * The number of rows.
+     */
+    private final int numRow;
+
+    /**
+     * The number of columns.
+     */
+    private final int numCol;
+
+    /**
+     * Elements of the matrix. Column indice vary fastest.
+     */
+    private final double[] elt;
+
+    /**
+     * The inverse transform. Will be created only when first needed.
+     */
+    private transient ProjectiveTransform inverse;
+
+    /**
+     * Constructs a transform from the specified matrix.
+     * The matrix should be affine, but it will not be verified.
+     *
+     * @param matrix The matrix.
+     */
+    protected ProjectiveTransform(final Matrix matrix) {
+        numRow = matrix.getNumRow();
+        numCol = matrix.getNumCol();
+        elt = new double[numRow*numCol];
+        int index = 0;
+        for (int j=0; j<numRow; j++) {
+            for (int i=0; i<numCol; i++) {
+                elt[index++] = matrix.getElement(j,i);
+            }
+        }
+    }
+
+    /**
+     * Creates a transform for the specified matrix.
+     * The matrix should be affine, but it is not be verified.
+     *
+     * @param matrix The affine transform as a matrix.
+     * @return The transform for the given matrix.
+     */
+    public static LinearTransform create(final Matrix matrix) {
+        final int dimension = matrix.getNumRow()-1;
+        if (dimension == matrix.getNumCol()-1) {
+            if (matrix.isIdentity()) {
+                return IdentityTransform.create(dimension);
+            }
+            final GeneralMatrix m = toGMatrix(matrix);
+            if (m.isAffine()) {
+                switch (dimension) {
+                    case 1: return LinearTransform1D.create(m.getElement(0,0), m.getElement(0,1));
+                    case 2: return create(m.toAffineTransform2D());
+                }
+            }
+        }
+        switch (dimension) {
+            case 2:  return new ProjectiveTransform2D(matrix);
+            default: return new ProjectiveTransform  (matrix);
+        }
+    }
+
+    /**
+     * Creates a transform for the specified matrix as a Java2D object.
+     * This method is provided for interoperability with
+     * <A HREF="http://java.sun.com/products/java-media/2D/index.jsp">Java2D</A>.
+     *
+     * @param matrix The affine transform as a matrix.
+     * @return The transform for the given matrix.
+     */
+    public static LinearTransform create(final AffineTransform matrix) {
+        if (matrix.isIdentity()) {
+            return IdentityTransform.create(2);
+        }
+        return new AffineTransform2D(matrix);
+    }
+
+    /**
+     * Returns the parameter descriptors for this math transform.
+     */
+    @Override
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return ProviderAffine.PARAMETERS;
+    }
+
+    /**
+     * Returns the matrix elements as a group of parameters values. The number of parameters
+     * depends on the matrix size. Only matrix elements different from their default value
+     * will be included in this group.
+     *
+     * @param  matrix The matrix to returns as a group of parameters.
+     * @return A copy of the parameter values for this math transform.
+     */
+    static ParameterValueGroup getParameterValues(final Matrix matrix) {
+        final MatrixParameters values;
+        values = (MatrixParameters) ProviderAffine.PARAMETERS.createValue();
+        values.setMatrix(matrix);
+        return values;
+    }
+
+    /**
+     * Returns the matrix elements as a group of parameters values. The number of parameters
+     * depends on the matrix size. Only matrix elements different from their default value
+     * will be included in this group.
+     *
+     * @return A copy of the parameter values for this math transform.
+     */
+    @Override
+    public ParameterValueGroup getParameterValues() {
+        return getParameterValues(getMatrix());
+    }
+
+    /**
+     * Transforms an array of floating point coordinates by this matrix. Point coordinates
+     * must have a dimension equals to <code>{@link Matrix#getNumCol}-1</code>. For example,
+     * for square matrix of size 4&times;4, coordinate points are three-dimensional and
+     * stored in the arrays starting at the specified offset ({@code srcOff}) in the order
+     * <code>[x<sub>0</sub>, y<sub>0</sub>, z<sub>0</sub>,
+     *        x<sub>1</sub>, y<sub>1</sub>, z<sub>1</sub>...,
+     *        x<sub>n</sub>, y<sub>n</sub>, z<sub>n</sub>]</code>.
+     *
+     * @param srcPts The array containing the source point coordinates.
+     * @param srcOff The offset to the first point to be transformed in the source array.
+     * @param dstPts The array into which the transformed point coordinates are returned.
+     * @param dstOff The offset to the location of the first transformed point that is stored
+     *               in the destination array. The source and destination array sections can
+     *               be overlaps.
+     * @param numPts The number of points to be transformed
+     */
+    @Override
+    public void transform(float[] srcPts, int srcOff,
+                          final float[] dstPts, int dstOff, int numPts)
+    {
+        final int  inputDimension = numCol-1; // The last ordinate will be assumed equals to 1.
+        final int outputDimension = numRow-1;
+        final double[]     buffer = new double[numRow];
+        if (srcPts == dstPts) {
+            // We are going to write in the source array. Checks if
+            // source and destination sections are going to clash.
+            final int upperSrc = srcOff + numPts*inputDimension;
+            if (upperSrc > dstOff) {
+                if (inputDimension >= outputDimension ? dstOff > srcOff :
+                            dstOff + numPts*outputDimension > upperSrc) {
+                    // If source overlaps destination, then the easiest workaround is
+                    // to copy source data. This is not the most efficient however...
+                    srcPts = new float[numPts*inputDimension];
+                    System.arraycopy(dstPts, srcOff, srcPts, 0, srcPts.length);
+                    srcOff = 0;
+                }
+            }
+        }
+        while (--numPts >= 0) {
+            int mix = 0;
+            for (int j=0; j<numRow; j++) {
+                double sum=elt[mix + inputDimension];
+                for (int i=0; i<inputDimension; i++) {
+                    sum += srcPts[srcOff+i]*elt[mix++];
+                }
+                buffer[j] = sum;
+                mix++;
+            }
+            final double w = buffer[outputDimension];
+            for (int j=0; j<outputDimension; j++) {
+                // 'w' is equals to 1 if the transform is affine.
+                dstPts[dstOff++] = (float) (buffer[j]/w);
+            }
+            srcOff += inputDimension;
+        }
+    }
+
+    /**
+     * Transforms an array of floating point coordinates by this matrix. Point coordinates
+     * must have a dimension equals to <code>{@link Matrix#getNumCol}-1</code>. For example,
+     * for square matrix of size 4&times;4, coordinate points are three-dimensional and
+     * stored in the arrays starting at the specified offset ({@code srcOff}) in the order
+     * <code>[x<sub>0</sub>, y<sub>0</sub>, z<sub>0</sub>,
+     *        x<sub>1</sub>, y<sub>1</sub>, z<sub>1</sub>...,
+     *        x<sub>n</sub>, y<sub>n</sub>, z<sub>n</sub>]</code>.
+     *
+     * @param srcPts The array containing the source point coordinates.
+     * @param srcOff The offset to the first point to be transformed in the source array.
+     * @param dstPts The array into which the transformed point coordinates are returned.
+     * @param dstOff The offset to the location of the first transformed point that is stored
+     *               in the destination array. The source and destination array sections can
+     *               be overlaps.
+     * @param numPts The number of points to be transformed
+     */
+    public void transform(double[] srcPts, int srcOff,
+                          final double[] dstPts, int dstOff, int numPts)
+    {
+        final int  inputDimension = numCol-1; // The last ordinate will be assumed equals to 1.
+        final int outputDimension = numRow-1;
+        final double[]     buffer = new double[numRow];
+        if (srcPts == dstPts) {
+            // We are going to write in the source array. Checks if
+            // source and destination sections are going to clash.
+            final int upperSrc = srcOff + numPts*inputDimension;
+            if (upperSrc > dstOff) {
+                if (inputDimension >= outputDimension ? dstOff > srcOff :
+                            dstOff + numPts*outputDimension > upperSrc) {
+                    // If source overlaps destination, then the easiest workaround is
+                    // to copy source data. This is not the most efficient however...
+                    srcPts = new double[numPts*inputDimension];
+                    System.arraycopy(dstPts, srcOff, srcPts, 0, srcPts.length);
+                    srcOff = 0;
+                }
+            }
+        }
+        while (--numPts >= 0) {
+            int mix = 0;
+            for (int j=0; j<numRow; j++) {
+                double sum=elt[mix + inputDimension];
+                for (int i=0; i<inputDimension; i++) {
+                    sum += srcPts[srcOff+i]*elt[mix++];
+                }
+                buffer[j] = sum;
+                mix++;
+            }
+            final double w = buffer[outputDimension];
+            for (int j=0; j<outputDimension; j++) {
+                // 'w' is equals to 1 if the transform is affine.
+                dstPts[dstOff++] = buffer[j]/w;
+            }
+            srcOff += inputDimension;
+        }
+    }
+
+    /**
+     * Gets the derivative of this transform at a point.
+     * For a matrix transform, the derivative is the
+     * same everywhere.
+     */
+    @Override
+    public Matrix derivative(final Point2D point) {
+        return derivative((DirectPosition)null);
+    }
+
+    /**
+     * Gets the derivative of this transform at a point.
+     * For a matrix transform, the derivative is the
+     * same everywhere.
+     */
+    @Override
+    public Matrix derivative(final DirectPosition point) {
+        final GeneralMatrix matrix = getGeneralMatrix();
+        matrix.setSize(numRow-1, numCol-1);
+        return matrix;
+    }
+
+    /**
+     * Returns a copy of the matrix.
+     */
+    public Matrix getMatrix() {
+        return getGeneralMatrix();
+    }
+
+    /**
+     * Returns a copy of the matrix.
+     */
+    private GeneralMatrix getGeneralMatrix() {
+        return new GeneralMatrix(numRow, numCol, elt);
+    }
+
+    /**
+     * Gets the dimension of input points.
+     */
+    public int getSourceDimensions() {
+        return numCol - 1;
+    }
+
+    /**
+     * Gets the dimension of output points.
+     */
+    public int getTargetDimensions() {
+        return numRow - 1;
+    }
+
+    /**
+     * Tests whether this transform does not move any points.
+     */
+    @Override
+    public boolean isIdentity() {
+        if (numRow != numCol) {
+            return false;
+        }
+        int index=0;
+        for (int j=0; j<numRow; j++) {
+            for (int i=0; i<numCol; i++) {
+                if (elt[index++] != (i==j ? 1 : 0)) {
+                    return false;
+                }
+            }
+        }
+        assert isIdentity(0);
+        return true;
+    }
+
+    /**
+     * Tests whether this transform does not move any points by using the provided tolerance.
+     * This method work in the same way than
+     * {@link org.geotools.referencing.operation.matrix.XMatrix#isIdentity(double)}.
+     *
+     * @since 2.4
+     */
+    public boolean isIdentity(double tolerance) {
+        tolerance = Math.abs(tolerance);
+        if (numRow != numCol) {
+            return false;
+        }
+        int index=0;
+        for (int j=0; j<numRow; j++) {
+            for (int i=0; i<numCol; i++) {
+                double e = elt[index++];
+                if (i == j) {
+                    e--;
+                }
+                // Uses '!' in order to catch NaN values.
+                if (!(Math.abs(e) <= tolerance)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public synchronized MathTransform inverse() throws NoninvertibleTransformException {
+        if (inverse == null) {
+            if (isIdentity()) {
+                inverse = this;
+            } else {
+                final XMatrix matrix = getGeneralMatrix();
+                try {
+                    matrix.invert();
+                } catch (SingularMatrixException exception) {
+                    throw new NoninvertibleTransformException(Errors.format(
+                              ErrorKeys.NONINVERTIBLE_TRANSFORM), exception);
+                } catch (MismatchedSizeException exception) {
+                    // This exception is thrown if the matrix is not square.
+                    throw new NoninvertibleTransformException(Errors.format(
+                              ErrorKeys.NONINVERTIBLE_TRANSFORM), exception);
+                }
+                inverse = new ProjectiveTransform(matrix);
+                inverse.inverse = this;
+            }
+        }
+        return inverse;
+    }
+
+    /**
+     * Creates an inverse transform using the specified matrix.
+     * To be overridden by {@link GeocentricTranslation}.
+     */
+    MathTransform createInverse(final Matrix matrix) {
+        return new ProjectiveTransform(matrix);
+    }
+
+    /**
+     * Returns a hash value for this transform.
+     * This value need not remain consistent between
+     * different implementations of the same class.
+     */
+    @Override
+    public int hashCode() {
+        long code = serialVersionUID;
+        for (int i=elt.length; --i>=0;) {
+            code = code*37 + Double.doubleToLongBits(elt[i]);
+        }
+        return (int)(code >>> 32) ^ (int)code;
+    }
+
+    /**
+     * Compares the specified object with
+     * this math transform for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            // Slight optimization
+            return true;
+        }
+        if (super.equals(object)) {
+            final ProjectiveTransform that = (ProjectiveTransform) object;
+            return this.numRow == that.numRow &&
+                   this.numCol == that.numCol &&
+                   Arrays.equals(this.elt, that.elt);
+        }
+        return false;
+    }
+
+    /**
+     * The provider for the "<cite>Affine general parametric transformation</cite>" (EPSG 9624).
+     * The OGC's name is {@code "Affine"}. The default matrix size is
+     * {@value org.geotools.parameter.MatrixParameterDescriptors#DEFAULT_MATRIX_SIZE}&times;{@value
+     * org.geotools.parameter.MatrixParameterDescriptors#DEFAULT_MATRIX_SIZE}.
+     * <p>
+     * Note that affine transform is a special case of projective transform.
+     *
+     * @version $Id: ProjectiveTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     */
+    public static final class ProviderAffine extends MathTransformProvider {
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID = 649555815622129472L;
+
+        /**
+         * The set of predefined providers.
+         */
+        private static final ProviderAffine[] methods = new ProviderAffine[8];
+
+        /**
+         * The parameters group.
+         *
+         * @todo We should register EPSG parameter identifiers (A0, A1, A2, B0, B1, B2) as well.
+         */
+        static final ParameterDescriptorGroup PARAMETERS;
+        static {
+            final NamedIdentifier name = new NamedIdentifier(Citations.OGC, "Affine");
+            final Map<String,Object> properties = new HashMap<String,Object>(4, 0.8f);
+            properties.put(NAME_KEY,        name);
+            properties.put(IDENTIFIERS_KEY, name);
+            properties.put(ALIAS_KEY, new NamedIdentifier[] {name,
+                new NamedIdentifier(Citations.EPSG, "Affine general parametric transformation"),
+                new NamedIdentifier(Citations.EPSG, "9624"),
+                new NamedIdentifier(Citations.GEOTOOLS,
+                    Vocabulary.formatInternational(VocabularyKeys.AFFINE_TRANSFORM))
+            });
+            PARAMETERS = new MatrixParameterDescriptors(properties);
+        }
+
+        /**
+         * Creates a provider for affine transform with a default matrix size.
+         */
+        public ProviderAffine() {
+            this(MatrixParameterDescriptors.DEFAULT_MATRIX_SIZE-1,
+                 MatrixParameterDescriptors.DEFAULT_MATRIX_SIZE-1);
+            methods[MatrixParameterDescriptors.DEFAULT_MATRIX_SIZE-2] = this;
+        }
+
+        /**
+         * Creates a provider for affine transform with the specified dimensions.
+         */
+        private ProviderAffine(final int sourceDimensions, final int targetDimensions) {
+            super(sourceDimensions, targetDimensions, PARAMETERS);
+        }
+
+        /**
+         * Returns the operation type.
+         */
+        @Override
+        public Class<Conversion> getOperationType() {
+            return Conversion.class;
+        }
+
+        /**
+         * Creates a projective transform from the specified group of parameter values.
+         *
+         * @param  values The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not found.
+         */
+        protected MathTransform createMathTransform(final ParameterValueGroup values)
+                throws ParameterNotFoundException
+        {
+            final MathTransform transform;
+            transform = create(((MatrixParameterDescriptors) getParameters()).getMatrix(values));
+            return new Delegate(transform, getProvider(transform.getSourceDimensions(),
+                                                       transform.getTargetDimensions()));
+        }
+
+        /**
+         * Returns the operation method for the specified source and target dimensions.
+         * This method provides different methods for different matrix sizes.
+         *
+         * @param sourceDimensions The number of source dimensions.
+         * @param targetDimensions The number of target dimensions.
+         * @return The provider for transforms of the given source and target dimensions.
+         */
+        public static ProviderAffine getProvider(final int sourceDimensions,
+                                                 final int targetDimensions)
+        {
+            if (sourceDimensions == targetDimensions) {
+                final int i = sourceDimensions - 1;
+                if (i>=0 && i<methods.length) {
+                    ProviderAffine method = methods[i];
+                    if (method == null) {
+                        methods[i] = method = new ProviderAffine(sourceDimensions, targetDimensions);
+                    }
+                    return method;
+                }
+            }
+            return new ProviderAffine(sourceDimensions, targetDimensions);
+        }
+    }
+
+    /**
+     * The provider for the "<cite>Longitude rotation</cite>" (EPSG 9601).
+     *
+     * @version $Id: ProjectiveTransform.java 37299 2011-05-25 05:21:24Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     */
+    public static final class ProviderLongitudeRotation extends MathTransformProvider { // NO_UCD
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID = -2104496465933824935L;
+
+        /**
+         * The longitude offset.
+         */
+        public static final ParameterDescriptor OFFSET = createDescriptor(
+                new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.EPSG, "Longitude offset")
+                },
+                Double.NaN, -180, +180, NonSI.DEGREE_ANGLE);
+
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new NamedIdentifier[] {
+                    new NamedIdentifier(Citations.EPSG, "Longitude rotation"),
+                    new NamedIdentifier(Citations.EPSG, "9601")
+                }, new ParameterDescriptor[] {
+                    OFFSET
+                });
+
+        /**
+         * Constructs a provider with default parameters.
+         */
+        public ProviderLongitudeRotation() {
+            super(2, 2, PARAMETERS);
+        }
+
+        /**
+         * Returns the operation type.
+         */
+        @Override
+        public Class<Conversion> getOperationType() {
+            return Conversion.class;
+        }
+
+        /**
+         * Creates a transform from the specified group of parameter values.
+         *
+         * @param  values The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not found.
+         */
+        protected MathTransform createMathTransform(final ParameterValueGroup values)
+                throws ParameterNotFoundException
+        {
+            final double offset = doubleValue(OFFSET, values);
+            return create(AffineTransform.getTranslateInstance(offset, 0));
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ProjectiveTransform2D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ProjectiveTransform2D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/ProjectiveTransform2D.java	(revision 28000)
@@ -0,0 +1,59 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.operation.transform;
+
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+
+
+/**
+ * Projective transform in 2D case.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/ProjectiveTransform2D.java $
+ * @version $Id: ProjectiveTransform2D.java 30641 2008-06-12 17:42:27Z acuster $
+ * @author Jan Jezek
+ */
+final class ProjectiveTransform2D extends ProjectiveTransform implements MathTransform2D {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -3101392684596817045L;
+
+    /**
+     * Creates projective transform from a matrix.
+     */
+    public ProjectiveTransform2D(final Matrix matrix) {
+        super(matrix);
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public MathTransform2D inverse() throws NoninvertibleTransformException {
+        return (MathTransform2D) super.inverse();
+    }
+
+    /**
+     * Creates an inverse transform using the specified matrix.
+     */
+    @Override
+    MathTransform2D createInverse(final Matrix matrix) {
+        return new ProjectiveTransform2D(matrix);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/operation/transform/package.html	(revision 28000)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.referencing.operation.transform</TITLE>
+  </HEAD>
+  <BODY>
+  Basic implementations of {@linkplain org.geotools.referencing.operation.transform.AbstractMathTransform
+  math transforms}. This package is mostly for internal purpose and should usually not be used
+  directly. Consider using {@link org.opengis.referencing.operation.MathTransformFactory} instead.
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/package.html	(revision 28000)
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.referencing</TITLE>
+  </HEAD>
+  <BODY>
+  {@linkplain org.geotools.referencing.AbstractReferenceSystem Reference systems} implementation. An
+  explanation for this package is provided in the {@linkplain org.opengis.referencing OpenGIS&reg; javadoc}.
+  The remaining discussion on this page is specific to the Geotools implementation.
+
+  <P ALIGN="justify">This package provides implementations for general positioning, coordinate
+  reference systems (CRS), and coordinate transformations. Coordinates can have any number of
+  dimensions. So this implementation can handle 2D and 3D coordinates, as well as 4D, 5D,
+  <CITE>etc.</CITE></P>
+  
+  <P ALIGN="justify">This package provides a special implementation of
+  {@linkplain org.geotools.referencing.NamedIdentifier identifier}, which is also a
+  {@linkplain org.opengis.util.GenericName generic name}. By implementing those two
+  interfaces, it is possible to use the same kind of object for specifying both the
+  {@linkplain org.geotools.referencing.AbstractIdentifiedObject#getName main identifier} and the
+  {@linkplain org.geotools.referencing.AbstractIdentifiedObject#getAlias aliases} of an
+  {@linkplain org.geotools.referencing.AbstractIdentifiedObject identified object}.</P>
+  
+  <P ALIGN="justify">All factory methods are capable to find an object using an
+  unscoped (or local) name. However, in order to avoid potential conflict, it is
+  recommanded to use scoped name when possible. For example even if both can work,
+  prefer "EPSG:9624" instead of "9624" for the affine transform in order to avoid
+  potential conflict with an other authority using the same code number.</P>
+  
+  <H3>Command-line tools</H3>
+  <P ALIGN="justify">A set of command lines tools is provided for performing queries.
+  The tools are implemented in the <CODE>main</CODE> method of some key classes. The
+  tools are:</P>
+
+  <TABLE>
+    <TR>
+      <TD>{@link org.geotools.referencing.FactoryFinder#main FactoryFinder}&nbsp;</TD>
+      <TD>Lists registered factories found in the class path (not only Geotools implementations).</TD>
+    </TR><TR>
+      <TD>{@link org.geotools.referencing.operation.DefaultMathTransformFactory#main DefaultMathTransformFactory}&nbsp;</TD>
+      <TD>Lists registered math transforms found in the class path.</TD>
+    </TR>
+    </TR><TR>
+      <TD>{@link org.geotools.referencing.CRS#main CRS}&nbsp;</TD>
+      <TD>Prints some informations about objects specified by their authority codes.</TD>
+    </TR>
+    </TR><TR>
+      <TD>{@link org.geotools.referencing.Console Console}&nbsp;</TD>
+      <TD>A command-line tool for testing transformations.</TD>
+    </TR>
+  </TABLE>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/AbstractParser.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/AbstractParser.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/AbstractParser.java	(revision 28000)
@@ -0,0 +1,144 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.wkt;
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.ParsePosition;
+
+
+/**
+ * Base class for <cite>Well Know Text</cite> (WKT) parser.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/wkt/AbstractParser.java $
+ * @version $Id: AbstractParser.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Remi Eve
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html">Well Know Text specification</A>
+ * @see <A HREF="http://gdal.velocet.ca/~warmerda/wktproblems.html">OGC WKT Coordinate System Issues</A>
+ */
+public abstract class AbstractParser {
+    /**
+     * Set to {@code true} if parsing of number in scientific notation is allowed.
+     * The way to achieve that is currently a hack, because {@link NumberFormat} has no
+     * API for managing that as of J2SE 1.5.
+     *
+     * @todo See if a future version of J2SE allows us to get ride of this ugly hack.
+     */
+    private static final boolean SCIENTIFIC_NOTATION = true;
+
+    /**
+     * The symbols to use for parsing WKT.
+     */
+    final Symbols symbols;
+
+    /**
+     * The object to use for parsing numbers.
+     */
+    private final NumberFormat numberFormat;
+
+    /**
+     * Constructs a parser using the specified set of symbols.
+     *
+     * @param symbols The set of symbols to use.
+     */
+    public AbstractParser(final Symbols symbols) {
+        this.symbols      = symbols;
+        this.numberFormat = (NumberFormat) symbols.numberFormat.clone();
+        if (SCIENTIFIC_NOTATION && numberFormat instanceof DecimalFormat) {
+            final DecimalFormat numberFormat = (DecimalFormat) this.numberFormat;
+            String pattern = numberFormat.toPattern();
+            if (pattern.indexOf("E0") < 0) {
+                final int split = pattern.indexOf(';');
+                if (split >= 0) {
+                    pattern = pattern.substring(0, split) + "E0" + pattern.substring(split);
+                }
+                pattern += "E0";
+                numberFormat.applyPattern(pattern);
+            }
+        }
+    }
+
+    /**
+     * Parses a <cite>Well Know Text</cite> (WKT).
+     *
+     * @param  text The text to be parsed.
+     * @return The object.
+     * @throws ParseException if the string can't be parsed.
+     */
+    public final Object parseObject(final String text) throws ParseException {
+        final Element element = getTree(text, new ParsePosition(0));
+        final Object object = parse(element);
+        element.close();
+        return object;
+    }
+
+    /**
+     * Parse the number at the given position.
+     */
+    final Number parseNumber(String text, final ParsePosition position) {
+        if (SCIENTIFIC_NOTATION) {
+            /*
+             * HACK: DecimalFormat.parse(...) do not understand lower case 'e' for scientific
+             *       notation. It understand upper case 'E' only. Performs the replacement...
+             */
+            final int base = position.getIndex();
+            Number number = numberFormat.parse(text, position);
+            if (number != null) {
+                int i = position.getIndex();
+                if (i<text.length() && text.charAt(i)=='e') {
+                    final StringBuilder buffer = new StringBuilder(text);
+                    buffer.setCharAt(i, 'E');
+                    text = buffer.toString();
+                    position.setIndex(base);
+                    number = numberFormat.parse(text, position);
+                }
+            }
+            return number;
+        } else {
+            return numberFormat.parse(text, position);
+        }
+    }
+
+    /**
+     * Parses the next element in the specified <cite>Well Know Text</cite> (WKT) tree.
+     *
+     * @param  element The element to be parsed.
+     * @return The object.
+     * @throws ParseException if the element can't be parsed.
+     */
+    protected abstract Object parse(final Element element) throws ParseException;
+
+    /**
+     * Returns a tree of {@link Element} for the specified text.
+     *
+     * @param  text       The text to parse.
+     * @param  position   In input, the position where to start parsing from.
+     *                    In output, the first character after the separator.
+     * @return The tree of elements to parse.
+     * @throws ParseException If an parsing error occured while creating the tree.
+     */
+    protected final Element getTree(final String text, final ParsePosition position)
+            throws ParseException
+    {
+        return new Element(new Element(this, text, position));
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/Element.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/Element.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/Element.java	(revision 28000)
@@ -0,0 +1,526 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.wkt;
+
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.geotools.resources.XArray;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.logging.LoggedFormat;
+
+
+/**
+ * An element in a <cite>Well Know Text</cite> (WKT). A {@code Element} is
+ * made of {@link String}, {@link Number} and other {@link Element}. For example:
+ *
+ * <blockquote><pre>
+ * PRIMEM["Greenwich", 0.0, AUTHORITY["some authority", "Greenwich"]]
+ * </pre></blockquote>
+ *
+ * Each {@code Element} object can contains an arbitrary amount of other elements.
+ * The result is a tree, which can be printed with {@link #print}.
+ * Elements can be pull in a <cite>first in, first out</cite> order.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/wkt/Element.java $
+ * @version $Id: Element.java 37409 2011-06-11 10:01:00Z aaime $
+ * @author Remi Eve
+ * @author Martin Desruisseaux (IRD)
+ */
+public final class Element {
+    /**
+     * The position where this element starts in the string to be parsed.
+     */
+    private final int offset;
+
+    /**
+     * Keyword of this entity. For example: "PRIMEM".
+     */
+    public final String keyword;
+
+    /**
+     * An ordered list of {@link String}s, {@link Number}s and other {@link Element}s.
+     * May be {@code null} if the keyword was not followed by a pair of brackets
+     * (e.g. "NORTH").
+     */
+    private final List<Object> list;
+
+    /**
+     * Constructs a root element.
+     *
+     * @param singleton The only children for this root.
+     */
+    Element(final Element singleton) {
+        offset  = 0;
+        keyword = null;
+        list    = new LinkedList<Object>();
+        list.add(singleton);
+    }
+
+    /**
+     * Constructs a new {@code Element}.
+     *
+     * @param  text       The text to parse.
+     * @param  position   In input, the position where to start parsing from.
+     *                    In output, the first character after the separator.
+     */
+    Element(final AbstractParser parser, final String text, final ParsePosition position)
+            throws ParseException
+    {
+        /*
+         * Find the first keyword in the specified string. If a keyword is found, then
+         * the position is set to the index of the first character after the keyword.
+         */
+        int lower = position.getIndex();
+        final int length = text.length();
+        while (lower<length && Character.isWhitespace(text.charAt(lower))) {
+            lower++;
+        }
+        offset = lower;
+        int upper = lower;
+        while (upper<length && Character.isUnicodeIdentifierPart(text.charAt(upper))) {
+            upper++;
+        }
+        if (upper <= lower) {
+            position.setErrorIndex(lower);
+            throw unparsableString(text, position);
+        }
+        keyword = text.substring(lower, upper).toUpperCase(parser.symbols.locale);
+        position.setIndex(upper);
+        /*
+         * Parse the opening bracket. According CTS's specification, two characters
+         * are acceptable: '[' and '('.  At the end of this method, we will require
+         * the matching closing bracket. For example if the opening bracket was '[',
+         * then we will require that the closing bracket is ']' and not ')'.
+         */
+        int bracketIndex = -1;
+        do {
+            if (++bracketIndex >= parser.symbols.openingBrackets.length) {
+                list = null;
+                return;
+            }
+        }
+        while (!parseOptionalSeparator(text, position, parser.symbols.openingBrackets[bracketIndex]));
+        list = new LinkedList<Object>();
+        /*
+         * Parse all elements inside the bracket. Elements are parsed sequentially
+         * and their type are selected according their first character:
+         *
+         *   - If the first character is a quote, then the element is parsed as a String.
+         *   - Otherwise, if the first character is a unicode identifier start, then the
+         *     element is parsed as a chidren Element.
+         *   - Otherwise, the element is parsed as a number.
+         */
+        do {
+            if (position.getIndex() >= length) {
+                throw missingCharacter(parser.symbols.close, length);
+            }
+            //
+            // Try to parse the next element as a quoted string. We will take
+            // it as a string if the first non-blank character is a quote.
+            //
+            if (parseOptionalSeparator(text, position, parser.symbols.quote)) {
+                lower = position.getIndex();
+                upper = text.indexOf(parser.symbols.quote, lower);
+                if (upper < lower) {
+                    position.setErrorIndex(++lower);
+                    throw missingCharacter(parser.symbols.quote, lower);
+                }
+                list.add(text.substring(lower, upper).trim());
+                position.setIndex(upper + 1);
+                continue;
+            }
+            //
+            // Try to parse the next element as a number. We will take it as a number if
+            // the first non-blank character is not the begining of an unicode identifier.
+            //
+            lower = position.getIndex();
+            if (!Character.isUnicodeIdentifierStart(text.charAt(lower))) {
+                final Number number = parser.parseNumber(text, position);
+                if (number == null) {
+                    // Do not update the error index; it is already updated by NumberFormat.
+                    throw unparsableString(text, position);
+                }
+                list.add(number);
+                continue;
+            }
+            // Otherwise, add the element as a child element.
+            list.add(new Element(parser, text, position));
+        } while (parseOptionalSeparator(text, position, parser.symbols.separator));
+        parseSeparator(text, position, parser.symbols.closingBrackets[bracketIndex]);
+    }
+
+    /**
+     * Returns {@code true} if the next non-whitespace character is the specified separator.
+     * Search is performed in string {@code text} from position {@code position}. If the
+     * separator is found, then the position is set to the first character after the separator.
+     * Otherwise, the position is set on the first non-blank character.
+     *
+     * @param  text       The text to parse.
+     * @param  position   In input, the position where to start parsing from.
+     *                    In output, the first character after the separator.
+     * @param  separator  The character to search.
+     * @return {@code true} if the next non-whitespace character is the separator,
+     *         or {@code false} otherwise.
+     */
+    private static boolean parseOptionalSeparator(final String        text,
+                                                  final ParsePosition position,
+                                                  final char          separator)
+    {
+        final int length = text.length();
+        int index = position.getIndex();
+        while (index < length) {
+            final char c = text.charAt(index);
+            if (Character.isWhitespace(c)) {
+                index++;
+                continue;
+            }
+            if (c == separator) {
+                position.setIndex(++index);
+                return true;
+            }
+            break;
+        }
+        position.setIndex(index); // MANDATORY for correct working of the constructor.
+        return false;
+    }
+
+    /**
+     * Moves to the next non-whitespace character and checks if this character is the
+     * specified separator. If the separator is found, it is skipped. Otherwise, this
+     * method thrown a {@link ParseException}.
+     *
+     * @param  text       The text to parse.
+     * @param  position   In input, the position where to start parsing from.
+     *                    In output, the first character after the separator.
+     * @param  separator  The character to search.
+     * @throws ParseException if the separator was not found.
+     */
+    private void parseSeparator(final String        text,
+                                final ParsePosition position,
+                                final char          separator)
+        throws ParseException
+    {
+        if (!parseOptionalSeparator(text, position, separator)) {
+            position.setErrorIndex(position.getIndex());
+            throw unparsableString(text, position);
+        }
+    }
+
+
+
+
+    //////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                      ////////
+    ////////    Construction of a ParseException when a string can't be parsed    ////////
+    ////////                                                                      ////////
+    //////////////////////////////////////////////////////////////////////////////////////
+    /**
+     * Returns a {@link ParseException} with the specified cause. A localized string
+     * <code>"Error in <{@link #keyword}>"</code> will be prepend to the message.
+     * The error index will be the starting index of this {@code Element}.
+     *
+     * @param  cause   The cause of the failure, or {@code null} if none.
+     * @param  message The message explaining the cause of the failure, or {@code null}
+     *                 for reusing the same message than {@code cause}.
+     * @return The exception to be thrown.
+     */
+    public ParseException parseFailed(final Exception cause, String message) {
+        if (message == null) {
+            message = cause.getLocalizedMessage();
+        }
+        ParseException exception = new ParseException(complete(message), offset);
+        exception = trim("parseFailed", exception);
+        exception.initCause(cause);
+        return exception;
+    }
+
+    /**
+     * Returns a {@link ParseException} with a "Unparsable string" message. The error message
+     * is built from the specified string starting at the specified position. Properties
+     * {@link ParsePosition#getIndex} and {@link ParsePosition#getErrorIndex} must be accurate
+     * before this method is invoked.
+     *
+     * @param  text The unparsable string.
+     * @param  position The position in the string.
+     * @return An exception with a formatted error message.
+     */
+    private ParseException unparsableString(final String text, final ParsePosition position) {
+        final int errorIndex = position.getErrorIndex();
+        String message = LoggedFormat.formatUnparsable(text, position.getIndex(), errorIndex, null);
+        message = complete(message);
+        return trim("unparsableString", new ParseException(message, errorIndex));
+    }
+
+    /**
+     * Returns an exception saying that a character is missing.
+     *
+     * @param c The missing character.
+     * @param position The error position.
+     */
+    private ParseException missingCharacter(final char c, final int position) {
+        return trim("missingCharacter", new ParseException(complete(
+                    Errors.format(ErrorKeys.MISSING_CHARACTER_$1, Character.valueOf(c))), position));
+    }
+
+    /**
+     * Returns an exception saying that a parameter is missing.
+     *
+     * @param key The name of the missing parameter.
+     */
+    private ParseException missingParameter(final String key) {
+        int error = offset;
+        if (keyword != null) {
+            error += keyword.length();
+        }
+        return trim("missingParameter", new ParseException(complete(
+                    Errors.format(ErrorKeys.MISSING_PARAMETER_$1, key)), error));
+    }
+
+    /**
+     * Append a prefix "Error in <keyword>: " before the error message.
+     *
+     * @param  message The message to complete.
+     * @return The completed message.
+     */
+    private String complete(String message) {
+        if (keyword != null) {
+            message = Errors.format(ErrorKeys.IN_$1, keyword) + ' ' + message;
+        }
+        return message;
+    }
+
+    /**
+     * Remove the exception factory method from the stack trace. The factory is
+     * not the place where the failure occurs; the error occurs in the factory's
+     * caller.
+     *
+     * @param  factory   The name of the factory method.
+     * @param  exception The exception to trim.
+     * @return {@code exception} for convenience.
+     */
+    private static ParseException trim(final String factory, final ParseException exception) {
+        StackTraceElement[] trace = exception.getStackTrace();
+        if (trace!=null && trace.length!=0) {
+            if (factory.equals(trace[0].getMethodName())) {
+                trace = XArray.remove(trace, 0, 1);
+                exception.setStackTrace(trace);
+            }
+        }
+        return exception;
+    }
+
+    /**
+     * Returns {@code true} if this element is the root element. For example in a WKT like
+     * {@code "GEOGCS["name", DATUM["name, ...]]"}, this is true for {@code "GEOGCS"} and
+     * false for all other elements inside, like {@code "DATUM"}.
+     *
+     * @return {@code true} if this element is the root element.
+     *
+     * @since 2.3
+     */
+    public boolean isRoot() {
+        return this.offset == 0;
+    }
+
+
+
+
+    //////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                      ////////
+    ////////    Pull elements from the tree                                       ////////
+    ////////                                                                      ////////
+    //////////////////////////////////////////////////////////////////////////////////////
+    /**
+     * Removes the next {@link Number} from the list and returns it.
+     *
+     * @param  key The parameter name. Used for formatting
+     *         an error message if no number are found.
+     * @return The next {@link Number} on the list as a {@code double}.
+     * @throws ParseException if no more number is available.
+     */
+    public double pullDouble(final String key) throws ParseException {
+        final Iterator iterator = list.iterator();
+        while (iterator.hasNext()) {
+            final Object object = iterator.next();
+            if (object instanceof Number) {
+                iterator.remove();
+                return ((Number)object).doubleValue();
+            }
+        }
+        throw missingParameter(key);
+    }
+
+    /**
+     * Removes the next {@link Number} from the list and returns it
+     * as an integer.
+     *
+     * @param  key The parameter name. Used for formatting
+     *         an error message if no number are found.
+     * @return The next {@link Number} on the list as an {@code int}.
+     * @throws ParseException if no more number is available, or the number
+     *         is not an integer.
+     */
+    public int pullInteger(final String key) throws ParseException {
+        final Iterator iterator = list.iterator();
+        while (iterator.hasNext()) {
+            final Object object = iterator.next();
+            if (object instanceof Number) {
+                iterator.remove();
+                final Number number = (Number) object;
+                if (number instanceof Float || number instanceof Double) {
+                    throw new ParseException(complete(Errors.format(
+                            ErrorKeys.ILLEGAL_ARGUMENT_$2, key, number)), offset);
+                }
+                return number.intValue();
+            }
+        }
+        throw missingParameter(key);
+    }
+
+    /**
+     * Removes the next {@link String} from the list and returns it.
+     *
+     * @param  key The parameter name. Used for formatting
+     *         an error message if no number are found.
+     * @return The next {@link String} on the list.
+     * @throws ParseException if no more string is available.
+     */
+    public String pullString(final String key) throws ParseException {
+    	String optionalString = pullOptionalString(key);
+    	if (optionalString != null) {
+    		return optionalString;
+    	}
+        throw missingParameter(key);
+    }
+
+    /**
+     * Removes the next {@link String} from the list and returns it.
+     * @param key The parameter name. Used for formatting
+     *         an error message if no number are found.
+     * @return The next {@link String} on the list 
+	 *         or {@code null} if no more element is available.
+     */
+    public String pullOptionalString(final String key) {
+        final Iterator iterator = list.iterator();
+        while (iterator.hasNext()) {
+            final Object object = iterator.next();
+            if (object instanceof String) {
+                iterator.remove();
+                return (String)object;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Removes the next {@link Element} from the list and returns it.
+     *
+     * @param  key The element name (e.g. <code>"PRIMEM"</code>).
+     * @return The next {@link Element} on the list.
+     * @throws ParseException if no more element is available.
+     */
+    public Element pullElement(final String key) throws ParseException {
+        final Element element = pullOptionalElement(key);
+        if (element != null) {
+            return element;
+        }
+        throw missingParameter(key);
+    }
+
+    /**
+     * Removes the next {@link Element} from the list and returns it.
+     *
+     * @param  key The element name (e.g. <code>"PRIMEM"</code>).
+     * @return The next {@link Element} on the list,
+     *         or {@code null} if no more element is available.
+     */
+    public Element pullOptionalElement(String key) {
+        key = key.toUpperCase();
+        final Iterator iterator = list.iterator();
+        while (iterator.hasNext()) {
+            final Object object = iterator.next();
+            if (object instanceof Element) {
+                final Element element = (Element) object;
+                if (element.list!=null && element.keyword.equals(key)) {
+                    iterator.remove();
+                    return element;
+                }
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * Removes and returns the next {@link Element} with no bracket, if available, or
+     * null otherwise.
+
+     * @return The next {@link Element} in the list, with no bracket, or null if none was found
+     * @throws ParseException if no more void element is available.
+     */
+    public Element pullOptionalVoidElement() throws ParseException {
+        final Iterator iterator = list.iterator();
+        while (iterator.hasNext()) {
+            final Object object = iterator.next();
+            if (object instanceof Element) {
+                final Element element = (Element) object;
+                if (element.list == null) {
+                    iterator.remove();
+                    return element;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the next element, or {@code null} if there is no more
+     * element. The element is <strong>not</strong> removed from the list.
+     *
+     * @return The next element, or {@code null} if there is no more elements.
+     */
+    public Object peek() {
+        return list.isEmpty() ? null : list.get(0);
+    }
+
+    /**
+     * Close this element.
+     *
+     * @throws ParseException If the list still contains some unprocessed elements.
+     */
+    public void close() throws ParseException {
+        if (list!=null && !list.isEmpty()) {
+            throw new ParseException(complete(Errors.format(ErrorKeys.UNEXPECTED_PARAMETER_$1,
+                                              list.get(0))), offset+keyword.length());
+        }
+    }
+
+    /**
+     * Returns the keyword. This overriding is needed for correct
+     * formatting of the error message in {@link #close}.
+     */
+    @Override
+    public String toString() {
+        return keyword;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/Formattable.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/Formattable.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/Formattable.java	(revision 28000)
@@ -0,0 +1,45 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.referencing.wkt;
+
+
+
+/**
+ * Base class for all object formattable as
+ * <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well
+ * Known Text</cite> (WKT)</A>.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/wkt/Formattable.java $
+ * @version $Id: Formattable.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html">Well Know Text specification</A>
+ * @see <A HREF="http://gdal.velocet.ca/~warmerda/wktproblems.html">OGC WKT Coordinate System Issues</A>
+ */
+public class Formattable {
+
+    /**
+     * Default constructor.
+     */
+    protected Formattable() {
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/MathTransformParser.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/MathTransformParser.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/MathTransformParser.java	(revision 28000)
@@ -0,0 +1,286 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.wkt;
+
+import java.text.ParseException;
+
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.ReferencingFactoryFinder;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchIdentifierException;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.Operation;
+import org.opengis.referencing.operation.OperationMethod;
+
+
+/**
+ * Parser for {@linkplain MathTransform math transform}
+ * <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well
+ * Known Text</cite> (WKT)</A> of math transform.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/wkt/MathTransformParser.java $
+ * @version $Id: MathTransformParser.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Remi Eve
+ * @author Martin Desruisseaux (IRD)
+ * @author Rueben Schulz
+ */
+public class MathTransformParser extends AbstractParser {
+    /**
+     * The factory to use for creating math transforms.
+     */
+    protected final MathTransformFactory mtFactory;
+
+    /**
+     * The classification of the last math transform or projection parsed,
+     * or {@code null} if none.
+     */
+    private String classification;
+
+    /**
+     * The method for the last math transform passed, or {@code null} if none.
+     *
+     * @see #getOperationMethod
+     */
+    private OperationMethod lastMethod;
+
+    /**
+     * Constructs a parser using the default set of symbols.
+     */
+    public MathTransformParser() {
+        this(Symbols.DEFAULT);
+    }
+
+    /**
+     * Constructs a parser using the specified set of symbols
+     * and the default factories.
+     *
+     * @param symbols The symbols for parsing and formatting numbers.
+     *
+     * @todo Pass hints in argument.
+     */
+    public MathTransformParser(final Symbols symbols) {
+        this(symbols, ReferencingFactoryFinder.getMathTransformFactory(null));
+    }
+
+    /**
+     * Constructs a parser for the specified set of symbols and factory.
+     *
+     * @param symbols   The symbols for parsing and formatting numbers.
+     * @param mtFactory The factory to use to create {@link MathTransform} objects.
+     */
+    public MathTransformParser(final Symbols symbols, final MathTransformFactory mtFactory) {
+        super(symbols);
+        this.mtFactory = mtFactory;
+    }
+
+    /**
+     * Parses the next element in the specified <cite>Well Know Text</cite> (WKT) tree.
+     *
+     * @param  element The element to be parsed.
+     * @return The object.
+     * @throws ParseException if the element can't be parsed.
+     */
+    protected Object parse(final Element element) throws ParseException {
+        return parseMathTransform(element, true);
+    }
+
+    /**
+     * Parses the next element (a {@link MathTransform}) in the specified
+     * <cite>Well Know Text</cite> (WKT) tree.
+     *
+     * @param  element The parent element.
+     * @param  required True if parameter is required and false in other case.
+     * @return The next element as a {@link MathTransform} object.
+     * @throws ParseException if the next element can't be parsed.
+     */
+    final MathTransform parseMathTransform(final Element element, final boolean required)
+            throws ParseException
+    {
+        lastMethod = null;
+        classification = null;
+        final Object key = element.peek();
+        if (key instanceof Element) {
+            final String keyword = ((Element) key).keyword.trim().toUpperCase(symbols.locale);
+            if ("PARAM_MT"      .equals(keyword))  return parseParamMT      (element);
+            if ("CONCAT_MT"     .equals(keyword))  return parseConcatMT     (element);
+            if ("INVERSE_MT"    .equals(keyword))  return parseInverseMT    (element);
+            if ("PASSTHROUGH_MT".equals(keyword))  return parsePassThroughMT(element);
+        }
+        if (required) {
+            throw element.parseFailed(null, Errors.format(ErrorKeys.UNKNOW_TYPE_$1, key));
+        }
+        return null;
+    }
+
+    /**
+     * Parses a "PARAM_MT" element. This element has the following pattern:
+     *
+     * <blockquote><code>
+     * PARAM_MT["<classification-name>" {,<parameter>}* ]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "PARAM_MT" element as an {@link MathTransform} object.
+     * @throws ParseException if the "PARAM_MT" element can't be parsed.
+     */
+    private MathTransform parseParamMT(final Element parent) throws ParseException {
+        final Element element = parent.pullElement("PARAM_MT");
+        classification = element.pullString("classification");
+        final ParameterValueGroup parameters;
+        try {
+            parameters = mtFactory.getDefaultParameters(classification);
+        } catch (NoSuchIdentifierException exception) {
+            throw element.parseFailed(exception, null);
+        }
+        /*
+         * Scan over all PARAMETER["name", value] elements and
+         * set the corresponding parameter in the parameter group.
+         */
+        Element param;
+        while ((param=element.pullOptionalElement("PARAMETER")) != null) {
+            final String name = param.pullString("name");
+            final ParameterValue parameter = parameters.parameter(name);
+            final Class type = parameter.getDescriptor().getValueClass();
+            if (Integer.class.equals(type)) {
+                parameter.setValue(param.pullInteger("value"));
+            } else if (Double.class.equals(type)) {
+                parameter.setValue(param.pullDouble("value"));
+            } else {
+                parameter.setValue(param.pullString("value"));
+            }
+            param.close();
+        }
+        element.close();
+        /*
+         * We now have all informations for constructing the math transform. If the factory is
+         * a Geotools implementation, we will use a special method that returns the operation
+         * method used. Otherwise, we will use the ordinary method and will performs a slower
+         * search for the operation method later if the user ask for it.
+         */
+        final MathTransform transform;
+        try {
+            transform = mtFactory.createParameterizedTransform(parameters);
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+        lastMethod = mtFactory.getLastMethodUsed();
+        return transform;
+    }
+
+    /**
+     * Parses a "INVERSE_MT" element. This element has the following pattern:
+     *
+     * <blockquote><code>
+     * INVERSE_MT[<math transform>]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "INVERSE_MT" element as an {@link MathTransform} object.
+     * @throws ParseException if the "INVERSE_MT" element can't be parsed.
+     */
+    private MathTransform parseInverseMT(final Element parent) throws ParseException {
+        final Element element = parent.pullElement("INVERSE_MT");
+        try {
+            final MathTransform transform;
+            transform = parseMathTransform(element, true).inverse();
+            element.close();
+            return transform;
+        }
+        catch (NoninvertibleTransformException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Parses a "PASSTHROUGH_MT" element. This element has the following pattern:
+     *
+     * <blockquote><code>
+     * PASSTHROUGH_MT[<integer>, <math transform>]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "PASSTHROUGH_MT" element as an {@link MathTransform} object.
+     * @throws ParseException if the "PASSTHROUGH_MT" element can't be parsed.
+     */
+    private MathTransform parsePassThroughMT(final Element parent) throws ParseException {
+        final Element           element = parent.pullElement("PASSTHROUGH_MT");
+        final int firstAffectedOrdinate = parent.pullInteger("firstAffectedOrdinate");
+        final MathTransform   transform = parseMathTransform(element, true);
+        element.close();
+        try {
+            return mtFactory.createPassThroughTransform(firstAffectedOrdinate, transform, 0);
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Parses a "CONCAT_MT" element. This element has the following pattern:
+     *
+     * <blockquote><code>
+     * CONCAT_MT[<math transform> {,<math transform>}*]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "CONCAT_MT" element as an {@link MathTransform} object.
+     * @throws ParseException if the "CONCAT_MT" element can't be parsed.
+     */
+    private MathTransform parseConcatMT(final Element parent) throws ParseException {
+        final Element element = parent.pullElement("CONCAT_MT");
+        MathTransform transform = parseMathTransform(element, true);
+        MathTransform optionalTransform;
+        while ((optionalTransform = parseMathTransform(element, false)) != null) {
+            try {
+                transform = mtFactory.createConcatenatedTransform(transform, optionalTransform);
+            } catch (FactoryException exception) {
+                throw element.parseFailed(exception, null);
+            }
+        }
+        element.close();
+        return transform;
+    }
+
+    /**
+     * Returns the operation method for the last math transform parsed. This is used by
+     * {@link Parser} in order to built {@link org.opengis.referencing.crs.DerivedCRS}.
+     */
+    final OperationMethod getOperationMethod() {
+        if (lastMethod == null) {
+            /*
+             * Safety in case come MathTransformFactory implementation do not support
+             * getLastMethod(). Performs a slower and less robust check as a fallback.
+             */
+            if (classification != null) {
+                for (final OperationMethod method : mtFactory.getAvailableMethods(Operation.class)) {
+                    if (AbstractIdentifiedObject.nameMatches(method, classification)) {
+                        lastMethod = method;
+                        break;
+                    }
+                }
+            }
+        }
+        return lastMethod;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/Parser.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/Parser.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/Parser.java	(revision 28000)
@@ -0,0 +1,1080 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.wkt;
+
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import javax.measure.unit.NonSI;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+import javax.measure.quantity.Angle;
+import javax.measure.quantity.Length;
+import javax.measure.quantity.Quantity;
+import static java.util.Collections.singletonMap;
+
+import org.opengis.metadata.citation.Citation;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.NoSuchIdentifierException;
+
+// While start import is usually a deprecated practice, we use such a large amount
+// of interfaces in those packages that it we choose to exceptionnaly use * here.
+import org.opengis.referencing.cs.*;
+import org.opengis.referencing.crs.*;
+import org.opengis.referencing.datum.*;
+import org.opengis.referencing.operation.*;
+
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.ReferencingFactoryFinder;
+import org.geotools.referencing.NamedIdentifier;
+import org.geotools.referencing.datum.BursaWolfParameters;
+import org.geotools.referencing.datum.DefaultGeodeticDatum;
+import org.geotools.referencing.datum.DefaultPrimeMeridian;
+import org.geotools.referencing.datum.DefaultVerticalDatum;
+import org.geotools.referencing.cs.AbstractCS;
+import org.geotools.referencing.cs.DefaultCoordinateSystemAxis;
+import org.geotools.referencing.cs.DirectionAlongMeridian;
+import org.geotools.referencing.factory.ReferencingFactoryContainer;
+import org.geotools.referencing.operation.DefiningConversion;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * Parser for
+ * <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well
+ * Known Text</cite> (WKT)</A>. This parser can parse {@linkplain MathTransform math transform}
+ * objects as well, which is part of the WKT's {@code FITTED_CS} element.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/wkt/Parser.java $
+ * @version $Id: Parser.java 37409 2011-06-11 10:01:00Z aaime $
+ * @author Remi Eve
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html">Well Know Text specification</A>
+ * @see <A HREF="http://gdal.velocet.ca/~warmerda/wktproblems.html">OGC WKT Coordinate System Issues</A>
+ */
+public class Parser extends MathTransformParser {
+    /**
+     * For cross-version compatibility.
+     */
+    @SuppressWarnings("unused")
+	private static final long serialVersionUID = -144097689843465085L;
+
+    /**
+     * {@code true} in order to allows the non-standard Oracle syntax. Oracle put the Bursa-Wolf
+     * parameters straight into the {@code DATUM} elements, without enclosing them in a
+     * {@code TOWGS84} element.
+     */
+    private static final boolean ALLOW_ORACLE_SYNTAX = true;
+
+    /**
+     * The mapping between WKT element name and the object class to be created.
+     * Will be created by {@link #getTypeMap} only when first needed. Keys must
+     * be upper case.
+     */
+    private static Map<String,Class<?>> TYPES;
+
+    /**
+     * The factory to use for creating {@linkplain Datum datum}.
+     */
+    protected final DatumFactory datumFactory;
+
+    /**
+     * The factory to use for creating {@linkplain CoordinateSystem coordinate systems}.
+     */
+    protected final CSFactory csFactory;
+
+    /**
+     * The factory to use for creating {@linkplain CoordinateReferenceSystem
+     * coordinate reference systems}.
+     */
+    protected final CRSFactory crsFactory;
+
+    /**
+     * The list of {@linkplain AxisDirection axis directions} from their name.
+     */
+    private final Map<String,AxisDirection> directions;
+
+    /**
+     * Constructs a parser using the default set of symbols and factories.
+     */
+    public Parser() {
+        this(Symbols.DEFAULT);
+    }
+
+    /**
+     * Constructs a parser for the specified set of symbols using default factories.
+     *
+     * @param symbols The symbols for parsing and formatting numbers.
+     *
+     * @todo Pass hints in argument.
+     */
+    public Parser(final Symbols symbols) {
+        this(symbols,
+             ReferencingFactoryFinder.getDatumFactory        (null),
+             ReferencingFactoryFinder.getCSFactory           (null),
+             ReferencingFactoryFinder.getCRSFactory          (null),
+             ReferencingFactoryFinder.getMathTransformFactory(null));
+    }
+
+    /**
+     * Constructs a parser for the specified set of symbols using the specified set of factories.
+     *
+     * @param symbols   The symbols for parsing and formatting numbers.
+     * @param factories The factories to use.
+     */
+    public Parser(final Symbols symbols, final ReferencingFactoryContainer factories) {
+        this(symbols,
+             factories.getDatumFactory(),
+             factories.getCSFactory(),
+             factories.getCRSFactory(),
+             factories.getMathTransformFactory());
+    }
+
+    /**
+     * Constructs a parser for the specified set of symbols using the specified factories.
+     *
+     * @param symbols      The symbols for parsing and formatting numbers.
+     * @param datumFactory The factory to use for creating {@linkplain Datum datum}.
+     * @param csFactory    The factory to use for creating {@linkplain CoordinateSystem
+     *                     coordinate systems}.
+     * @param crsFactory   The factory to use for creating {@linkplain CoordinateReferenceSystem
+     *                     coordinate reference systems}.
+     * @param mtFactory    The factory to use for creating {@linkplain MathTransform
+     *                     math transform} objects.
+     */
+    public Parser(final Symbols                symbols,
+                  final DatumFactory      datumFactory,
+                  final CSFactory            csFactory,
+                  final CRSFactory          crsFactory,
+                  final MathTransformFactory mtFactory)
+    {
+        super(symbols, mtFactory);
+        this.datumFactory = datumFactory;
+        this. csFactory   =    csFactory;
+        this.crsFactory   =   crsFactory;
+        final AxisDirection[] values = AxisDirection.values();
+        directions = new HashMap<String,AxisDirection>(
+                (int) Math.ceil((values.length + 1) / 0.75f), 0.75f);
+        for (int i=0; i<values.length; i++) {
+            directions.put(values[i].name().trim().toUpperCase(), values[i]);
+        }
+    }
+
+    /**
+     * Parses a coordinate reference system element.
+     *
+     * @param  text The text to be parsed.
+     * @return The coordinate reference system.
+     * @throws ParseException if the string can't be parsed.
+     */
+    public CoordinateReferenceSystem parseCoordinateReferenceSystem(final String text)
+            throws ParseException
+    {
+        final Element element = getTree(text, new ParsePosition(0));
+        final CoordinateReferenceSystem crs = parseCoordinateReferenceSystem(element);
+        element.close();
+        return crs;
+    }
+
+    /**
+     * Parses a coordinate reference system element.
+     *
+     * @param  parent The parent element.
+     * @return The next element as a {@link CoordinateReferenceSystem} object.
+     * @throws ParseException if the next element can't be parsed.
+     */
+    private CoordinateReferenceSystem parseCoordinateReferenceSystem(final Element element)
+            throws ParseException
+    {
+        final Object key = element.peek();
+        if (key instanceof Element) {
+            final String keyword = ((Element) key).keyword.trim().toUpperCase(symbols.locale);
+            CoordinateReferenceSystem r = null;
+            try {
+                if (   "GEOGCS".equals(keyword)) return r=parseGeoGCS  (element);
+                if (   "PROJCS".equals(keyword)) return r=parseProjCS  (element);
+                if (   "GEOCCS".equals(keyword)) return r=parseGeoCCS  (element);
+                if (  "VERT_CS".equals(keyword)) return r=parseVertCS  (element);
+                if ( "LOCAL_CS".equals(keyword)) return r=parseLocalCS (element);
+                if ( "COMPD_CS".equals(keyword)) return r=parseCompdCS (element);
+                if ("FITTED_CS".equals(keyword)) return r=parseFittedCS(element);
+            } finally {
+                // Work around for simulating post-conditions in Java.
+                assert isValid(r, keyword) : element;
+            }
+        }
+        throw element.parseFailed(null, Errors.format(ErrorKeys.UNKNOW_TYPE_$1, key));
+    }
+
+    /**
+     * Parses the next element in the specified <cite>Well Know Text</cite> (WKT) tree.
+     *
+     * @param  element The element to be parsed.
+     * @return The object.
+     * @throws ParseException if the element can't be parsed.
+     *
+     * @todo All sequences of <code>if ("FOO".equals(keyword))</code> in this method
+     *       and other methods of this class and subclasses, could be optimized with
+     *       a {@code switch} statement.
+     */
+    @Override
+    protected Object parse(final Element element) throws ParseException {
+        final Object key = element.peek();
+        if (key instanceof Element) {
+            final String keyword = ((Element) key).keyword.trim().toUpperCase(symbols.locale);
+            Object r = null;
+            try {
+                if (       "AXIS".equals(keyword)) return r=parseAxis      (element, SI.METER, true);
+                if (     "PRIMEM".equals(keyword)) return r=parsePrimem    (element, NonSI.DEGREE_ANGLE);
+                if (    "TOWGS84".equals(keyword)) return r=parseToWGS84   (element);
+                if (   "SPHEROID".equals(keyword)) return r=parseSpheroid  (element);
+                if ( "VERT_DATUM".equals(keyword)) return r=parseVertDatum (element);
+                if ("LOCAL_DATUM".equals(keyword)) return r=parseLocalDatum(element);
+                if (      "DATUM".equals(keyword)) return r=parseDatum     (element, DefaultPrimeMeridian.GREENWICH);
+                r = parseMathTransform(element, false);
+                if (r != null) {
+                    return r;
+                }
+            } finally {
+                // Work around for simulating post-conditions in Java.
+                assert isValid(r, keyword) : element;
+            }
+        }
+        return parseCoordinateReferenceSystem(element);
+    }
+
+    /**
+     * Checks if the parsed object is of the expected type. This is also a way to check
+     * the consistency of the {@link #TYPES} map.
+     */
+    private static boolean isValid(final Object parsed, final String keyword) {
+        if (parsed == null) {
+            // Required in order to avoid AssertionError in place of ParseException.
+            return true;
+        }
+        final Class type = getClassOf(keyword);
+        return type!=null && type.isInstance(parsed);
+    }
+
+    /**
+     * Returns the properties to be given to the parsed object. This method is invoked
+     * automatically by the parser for the {@linkplain Element#isRoot root element} only.
+     * This method expect on input the properties parsed from the {@code AUTHORITY} element,
+     * and returns on output the properties to give to the object to be created. The default
+     * implementation returns the {@code properties} map unchanged. Subclasses may override
+     * this method in order to add or change properties.
+     * <p>
+     * <strong>Example:</strong> if a subclass want to add automatically an authority code when
+     * no {@code AUTHORITY} element was explicitly set in the WKT, then it may test for the
+     * {@link IdentifiedObject#IDENTIFIERS_KEY} key and add automatically an entry if this
+     * key was missing.
+     *
+     * @param  properties The properties parsed from the WKT file. Entries can be added, removed
+     *         or modified directly in this map.
+     * @return The properties to be given to the parsed object. This is usually {@code properties}
+     *         (maybe after modifications), but could also be a new map.
+     *
+     * @since 2.3
+     */
+    protected Map<String,Object> alterProperties(final Map<String,Object> properties) {
+        return properties;
+    }
+
+    /**
+     * Parses an <strong>optional</strong> "AUTHORITY" element.
+     * This element has the following pattern:
+     *
+     * <blockquote><code>
+     * AUTHORITY["&lt;name&gt;", "&lt;code&gt;"]
+     * </code></blockquote>
+     * or even
+     * <blockquote><code>
+     * AUTHORITY["&lt;name&gt;", &lt;code&gt;]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @param  name The name of the parent object being parsed.
+     * @return A properties map with the parent name and the optional autority code.
+     * @throws ParseException if the "AUTHORITY" can't be parsed.
+     */
+    private Map<String,Object> parseAuthority(final Element parent, final String name)
+            throws ParseException
+    {
+        final boolean  isRoot = parent.isRoot();
+        final Element element = parent.pullOptionalElement("AUTHORITY");
+        Map<String,Object> properties;
+        if (element == null) {
+            if (isRoot) {
+                properties = new HashMap<String,Object>(4);
+                properties.put(IdentifiedObject.NAME_KEY, name);
+            } else {
+                properties = singletonMap(IdentifiedObject.NAME_KEY, (Object) name);
+            }
+        } else {
+            final String auth = element.pullString("name");
+            // the code can be annotation marked but could be a number to
+            String code = element.pullOptionalString("code");
+            if (code == null) {
+            	int codeNumber = element.pullInteger("code");
+            	code = String.valueOf(codeNumber);
+            }
+            element.close();
+            final Citation authority = Citations.fromName(auth);
+            properties = new HashMap<String,Object>(4);
+            properties.put(IdentifiedObject.       NAME_KEY, new NamedIdentifier(authority, name));
+            properties.put(IdentifiedObject.IDENTIFIERS_KEY, new NamedIdentifier(authority, code));
+        }
+        if (isRoot) {
+            properties = alterProperties(properties);
+        }
+        return properties;
+    }
+
+    /**
+     * Parses an "UNIT" element.
+     * This element has the following pattern:
+     *
+     * <blockquote><code>
+     * UNIT["<name>", <conversion factor> {,<authority>}]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @param  unit The contextual unit. Usually {@link SI#METRE} or {@link SI#RADIAN}.
+     * @return The "UNIT" element as an {@link Unit} object.
+     * @throws ParseException if the "UNIT" can't be parsed.
+     *
+     * @todo Authority code is currently ignored. We may consider to create a subclass of
+     *       {@link Unit} which implements {@link IdentifiedObject} in a future version.
+     */
+    private <T extends Quantity> Unit<T> parseUnit(final Element parent, final Unit<T> unit)
+            throws ParseException
+    {
+        final Element element = parent.pullElement("UNIT");
+        final String     name = element.pullString("name");
+        final double   factor = element.pullDouble("factor");
+        /*final Map<String,?> properties = */parseAuthority(element, name);
+        element.close();
+        return (factor != 1) ? unit.times(factor) : unit;
+    }
+
+    /**
+     * Parses an "AXIS" element.
+     * This element has the following pattern:
+     *
+     * <blockquote><code>
+     * AXIS["<name>", NORTH | SOUTH | EAST | WEST | UP | DOWN | OTHER]
+     * </code></blockquote>
+     *
+     * Note: there is no AUTHORITY element for AXIS element in OGC specification. However, we
+     *       accept it anyway in order to make the parser more tolerant to non-100% compliant
+     *       WKT. Note that AXIS is really the only element without such AUTHORITY clause and
+     *       the EPSG database provides authority code for all axis.
+     *
+     * @param  parent The parent element.
+     * @param  unit The contextual unit. Usually {@link NonSI#DEGREE_ANGLE} or {@link SI#METRE}.
+     * @param  required {@code true} if the axis is mandatory,
+     *         or {@code false} if it is optional.
+     * @return The "AXIS" element as a {@link CoordinateSystemAxis} object, or {@code null}
+     *         if the axis was not required and there is no axis object.
+     * @throws ParseException if the "AXIS" element can't be parsed.
+     */
+    private CoordinateSystemAxis parseAxis(final Element parent,
+                                           final Unit<?> unit,
+                                           final boolean required)
+            throws ParseException
+    {
+        final Element element;
+        if (required) {
+            element = parent.pullElement("AXIS");
+        } else {
+            element = parent.pullOptionalElement("AXIS");
+            if (element == null) {
+                return null;
+            }
+        }
+        final String  name        = element.pullString     ("name");
+        final Element orientation = element.pullOptionalVoidElement();
+        final AxisDirection direction;
+        if(orientation != null) {
+            direction = directions.get(orientation.keyword.trim().toUpperCase());
+        } else {
+            String directionName = element.pullString("orientation");
+            direction = DirectionAlongMeridian.parse(directionName).getDirection();
+        }
+        final Map<String,?> properties = parseAuthority(element, name); // See javadoc
+        element.close();
+        
+        if (direction == null) {
+            throw element.parseFailed(null, Errors.format(ErrorKeys.UNKNOW_TYPE_$1, orientation));
+        }
+        try {
+            return createAxis(properties, name, direction, unit);
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Creates an axis. If the name matches one of pre-defined axis, the pre-defined one
+     * will be returned. This replacement help to get more success when comparing a CS
+     * built from WKT against a CS built from one of Geotools's constants.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         If {@code null}, the abbreviation will be used as the axis name.
+     * @param  abbreviation The coordinate axis abbreviation.
+     * @param  direction The axis direction.
+     * @param  unit The coordinate axis unit.
+     * @throws FactoryException if the axis can't be created.
+     */
+    private CoordinateSystemAxis createAxis(Map<String,?> properties,
+                                      final String        abbreviation,
+                                      final AxisDirection direction,
+                                      final Unit<?>       unit)
+            throws FactoryException
+    {
+        final CoordinateSystemAxis candidate =
+                DefaultCoordinateSystemAxis.getPredefined(abbreviation, direction);
+        if (candidate != null && unit.equals(candidate.getUnit())) {
+            return candidate;
+        }
+        if (properties == null) {
+            properties = singletonMap(IdentifiedObject.NAME_KEY, abbreviation);
+        }
+        return csFactory.createCoordinateSystemAxis(properties, abbreviation, direction, unit);
+    }
+
+    /**
+     * Parses a "PRIMEM" element. This element has the following pattern:
+     *
+     * <blockquote><code>
+     * PRIMEM["<name>", <longitude> {,<authority>}]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @param  angularUnit The contextual unit.
+     * @return The "PRIMEM" element as a {@link PrimeMeridian} object.
+     * @throws ParseException if the "PRIMEM" element can't be parsed.
+     */
+    private PrimeMeridian parsePrimem(final Element parent, final Unit<Angle> angularUnit)
+            throws ParseException
+    {
+        final Element   element = parent.pullElement("PRIMEM");
+        final String       name = element.pullString("name");
+        final double  longitude = element.pullDouble("longitude");
+        final Map<String,?> properties = parseAuthority(element, name);
+        element.close();
+        try {
+            return datumFactory.createPrimeMeridian(properties, longitude, angularUnit);
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Parses an <strong>optional</strong> "TOWGS84" element.
+     * This element has the following pattern:
+     *
+     * <blockquote><code>
+     * TOWGS84[<dx>, <dy>, <dz>, <ex>, <ey>, <ez>, <ppm>]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "TOWGS84" element as a {@link BursaWolfParameters} object,
+     *         or {@code null} if no "TOWGS84" has been found.
+     * @throws ParseException if the "TOWGS84" can't be parsed.
+     */
+    private static BursaWolfParameters parseToWGS84(final Element parent)
+            throws ParseException
+    {
+        final Element element = parent.pullOptionalElement("TOWGS84");
+        if (element == null) {
+            return null;
+        }
+        final BursaWolfParameters info = new BursaWolfParameters(DefaultGeodeticDatum.WGS84);
+        info.dx  = element.pullDouble("dx");
+        info.dy  = element.pullDouble("dy");
+        info.dz  = element.pullDouble("dz");
+        if (element.peek() != null) {
+            info.ex  = element.pullDouble("ex");
+            info.ey  = element.pullDouble("ey");
+            info.ez  = element.pullDouble("ez");
+            info.ppm = element.pullDouble("ppm");
+        }
+        element.close();
+        return info;
+    }
+
+    /**
+     * Parses a "SPHEROID" element. This element has the following pattern:
+     *
+     * <blockquote><code>
+     * SPHEROID["<name>", <semi-major axis>, <inverse flattening> {,<authority>}]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "SPHEROID" element as an {@link Ellipsoid} object.
+     * @throws ParseException if the "SPHEROID" element can't be parsed.
+     */
+    private Ellipsoid parseSpheroid(final Element parent) throws ParseException {
+        Element          element = parent.pullElement("SPHEROID");
+        String              name = element.pullString("name");
+        double     semiMajorAxis = element.pullDouble("semiMajorAxis");
+        double inverseFlattening = element.pullDouble("inverseFlattening");
+        Map<String,?> properties = parseAuthority(element, name);
+        element.close();
+        if (inverseFlattening == 0) {
+            // Inverse flattening null is an OGC convention for a sphere.
+            inverseFlattening = Double.POSITIVE_INFINITY;
+        }
+        try {
+            return datumFactory.createFlattenedSphere(properties,
+                    semiMajorAxis, inverseFlattening, SI.METER);
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Parses a "PROJECTION" element. This element has the following pattern:
+     *
+     * <blockquote><code>
+     * PROJECTION["<name>" {,<authority>}]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @param  ellipsoid The ellipsoid, or {@code null} if none.
+     * @param  linearUnit The linear unit of the parent PROJCS element, or {@code null}.
+     * @param  angularUnit The angular unit of the parent GEOCS element, or {@code null}.
+     * @return The "PROJECTION" element as a {@link ParameterValueGroup} object.
+     * @throws ParseException if the "PROJECTION" element can't be parsed.
+     */
+    private ParameterValueGroup parseProjection(final Element      parent,
+                                                final Ellipsoid    ellipsoid,
+                                                final Unit<Length> linearUnit,
+                                                final Unit<Angle>  angularUnit)
+            throws ParseException
+    {
+        final Element          element = parent.pullElement("PROJECTION");
+        final String    classification = element.pullString("name");
+        /*final Map<String,?> properties =*/ parseAuthority(element, classification);
+        element.close();
+        /*
+         * Set the list of parameters.  NOTE: Parameters are defined in
+         * the parent Element (usually a "PROJCS" element), not in this
+         * "PROJECTION" element.
+         *
+         * We will set the semi-major and semi-minor parameters from the
+         * ellipsoid first. If those values were explicitly specified in
+         * a "PARAMETER" statement, they will overwrite the values inferred
+         * from the ellipsoid.
+         */
+        final ParameterValueGroup parameters;
+        try {
+            parameters = mtFactory.getDefaultParameters(classification);
+        } catch (NoSuchIdentifierException exception) {
+            throw element.parseFailed(exception, null);
+        }
+        Element param = parent;
+        try {
+            if (ellipsoid != null) {
+                final Unit<Length> axisUnit = ellipsoid.getAxisUnit();
+                parameters.parameter("semi_major").setValue(ellipsoid.getSemiMajorAxis(), axisUnit);
+                parameters.parameter("semi_minor").setValue(ellipsoid.getSemiMinorAxis(), axisUnit);
+            }
+            while ((param=parent.pullOptionalElement("PARAMETER")) != null) {
+                final String paramName  = param.pullString("name");
+                final double paramValue = param.pullDouble("value");
+                final ParameterValue<?> parameter = parameters.parameter(paramName);
+                final Unit<?> expected = parameter.getDescriptor().getUnit();
+                if (expected!=null && !Unit.ONE.equals(expected)) {
+                    if (linearUnit!=null && SI.METER.isCompatible(expected)) {
+                        parameter.setValue(paramValue, linearUnit);
+                        continue;
+                    }
+                    if (angularUnit!=null && SI.RADIAN.isCompatible(expected)) {
+                        parameter.setValue(paramValue, angularUnit);
+                        continue;
+                    }
+                }
+                parameter.setValue(paramValue);
+            }
+        } catch (ParameterNotFoundException exception) {
+            throw param.parseFailed(exception, Errors.format(ErrorKeys.UNEXPECTED_PARAMETER_$1,
+                                                             exception.getParameterName()));
+        }
+        return parameters;
+    }
+
+    /**
+     * Parses a "DATUM" element. This element has the following pattern:
+     *
+     * <blockquote><code>
+     * DATUM["<name>", <spheroid> {,<to wgs84>} {,<authority>}]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @param  meridian the prime meridian.
+     * @return The "DATUM" element as a {@link GeodeticDatum} object.
+     * @throws ParseException if the "DATUM" element can't be parsed.
+     */
+    private GeodeticDatum parseDatum(final Element parent,
+                                     final PrimeMeridian meridian)
+            throws ParseException
+    {
+        Element             element    = parent.pullElement("DATUM");
+        String              name       = element.pullString("name");
+        Ellipsoid           ellipsoid  = parseSpheroid(element);
+        BursaWolfParameters toWGS84    = parseToWGS84(element); // Optional; may be null.
+        Map<String,Object>  properties = parseAuthority(element, name);
+        if (ALLOW_ORACLE_SYNTAX && (toWGS84 == null) && (element.peek() instanceof Number)) {
+            toWGS84     = new BursaWolfParameters(DefaultGeodeticDatum.WGS84);
+            toWGS84.dx  = element.pullDouble("dx");
+            toWGS84.dy  = element.pullDouble("dy");
+            toWGS84.dz  = element.pullDouble("dz");
+            toWGS84.ex  = element.pullDouble("ex");
+            toWGS84.ey  = element.pullDouble("ey");
+            toWGS84.ez  = element.pullDouble("ez");
+            toWGS84.ppm = element.pullDouble("ppm");
+        }
+        element.close();
+        if (toWGS84 != null) {
+            if (!(properties instanceof HashMap)) {
+                properties = new HashMap<String,Object>(properties);
+            }
+            properties.put(DefaultGeodeticDatum.BURSA_WOLF_KEY, toWGS84);
+        }
+        try {
+            return datumFactory.createGeodeticDatum(properties, ellipsoid, meridian);
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Parses a "VERT_DATUM" element. This element has the following pattern:
+     *
+     * <blockquote><code>
+     * VERT_DATUM["<name>", <datum type> {,<authority>}]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "VERT_DATUM" element as a {@link VerticalDatum} object.
+     * @throws ParseException if the "VERT_DATUM" element can't be parsed.
+     */
+    private VerticalDatum parseVertDatum(final Element parent) throws ParseException {
+        final Element element = parent.pullElement("VERT_DATUM");
+        final String     name = element.pullString ("name");
+        final int       datum = element.pullInteger("datum");
+        final Map<String,?> properties = parseAuthority(element, name);
+        element.close();
+        final VerticalDatumType type = DefaultVerticalDatum.getVerticalDatumTypeFromLegacyCode(datum);
+        if (type == null) {
+            throw element.parseFailed(null, Errors.format(ErrorKeys.UNKNOW_TYPE_$1, datum));
+        }
+        try {
+            return datumFactory.createVerticalDatum(properties, type);
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Parses a "LOCAL_DATUM" element. This element has the following pattern:
+     *
+     * <blockquote><code>
+     * LOCAL_DATUM["<name>", <datum type> {,<authority>}]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "LOCAL_DATUM" element as an {@link EngineeringDatum} object.
+     * @throws ParseException if the "LOCAL_DATUM" element can't be parsed.
+     *
+     * @todo The vertical datum type is currently ignored.
+     */
+    private EngineeringDatum parseLocalDatum(final Element parent) throws ParseException {
+        final Element element = parent.pullElement("LOCAL_DATUM");
+        final String     name = element.pullString ("name");
+        /*final int       datum =*/ element.pullInteger("datum");
+        final Map<String,?> properties = parseAuthority(element, name);
+        element.close();
+        try {
+            return datumFactory.createEngineeringDatum(properties);
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Parses a "LOCAL_CS" element.
+     * This element has the following pattern:
+     *
+     * <blockquote><code>
+     * LOCAL_CS["<name>", <local datum>, <unit>, <axis>, {,<axis>}* {,<authority>}]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "LOCAL_CS" element as an {@link EngineeringCRS} object.
+     * @throws ParseException if the "LOCAL_CS" element can't be parsed.
+     *
+     * @todo The coordinate system used is always a Geotools implementation, since we don't
+     *       know which method to invokes in the {@link CSFactory} (is it a cartesian
+     *       coordinate system? a spherical one? etc.).
+     */
+    private EngineeringCRS parseLocalCS(final Element parent) throws ParseException {
+        Element           element = parent.pullElement("LOCAL_CS");
+        String               name = element.pullString("name");
+        EngineeringDatum    datum = parseLocalDatum(element);
+        Unit<Length>   linearUnit = parseUnit(element, SI.METER);
+        CoordinateSystemAxis axis = parseAxis(element, linearUnit, true);
+        List<CoordinateSystemAxis> list = new ArrayList<CoordinateSystemAxis>();
+        do {
+            list.add(axis);
+            axis = parseAxis(element, linearUnit, false);
+        } while (axis != null);
+        final Map<String,?> properties = parseAuthority(element, name);
+        element.close();
+        final CoordinateSystem cs;
+        cs = new AbstractCS(singletonMap("name", name),
+                list.toArray(new CoordinateSystemAxis[list.size()]));
+        try {
+            return crsFactory.createEngineeringCRS(properties, datum, cs);
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Parses a "GEOCCS" element.
+     * This element has the following pattern:
+     *
+     * <blockquote><code>
+     * GEOCCS["<name>", <datum>, <prime meridian>,  <linear unit>
+     *        {,<axis> ,<axis> ,<axis>} {,<authority>}]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "GEOCCS" element as a {@link GeocentricCRS} object.
+     * @throws ParseException if the "GEOCCS" element can't be parsed.
+     */
+    private GeocentricCRS parseGeoCCS(final Element parent) throws ParseException {
+        final Element          element = parent.pullElement("GEOCCS");
+        final String              name = element.pullString("name");
+        final Map<String,?> properties = parseAuthority(element, name);
+        final PrimeMeridian   meridian = parsePrimem   (element, NonSI.DEGREE_ANGLE);
+        final GeodeticDatum      datum = parseDatum    (element, meridian);
+        final Unit<Length>  linearUnit = parseUnit     (element, SI.METER);
+        CoordinateSystemAxis axis0, axis1, axis2;
+        axis0 = parseAxis(element, linearUnit, false);
+        try {
+            if (axis0 != null) {
+                axis1 = parseAxis(element, linearUnit, true);
+                axis2 = parseAxis(element, linearUnit, true);
+            } else {
+                // Those default values are part of WKT specification.
+                axis0 = createAxis(null, "X", AxisDirection.OTHER, linearUnit);
+                axis1 = createAxis(null, "Y", AxisDirection.EAST,  linearUnit);
+                axis2 = createAxis(null, "Z", AxisDirection.NORTH, linearUnit);
+            }
+            element.close();
+            return crsFactory.createGeocentricCRS(properties, datum,
+                    csFactory.createCartesianCS(properties, axis0, axis1, axis2));
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Parses an <strong>optional</strong> "VERT_CS" element.
+     * This element has the following pattern:
+     *
+     * <blockquote><code>
+     * VERT_CS["<name>", <vert datum>, <linear unit>, {<axis>,} {,<authority>}]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "VERT_CS" element as a {@link VerticalCRS} object.
+     * @throws ParseException if the "VERT_CS" element can't be parsed.
+     */
+    private VerticalCRS parseVertCS(final Element parent) throws ParseException {
+        final Element element = parent.pullElement("VERT_CS");
+        if (element == null) {
+            return null;
+        }
+        String               name = element.pullString("name");
+        VerticalDatum       datum = parseVertDatum(element);
+        Unit<Length>   linearUnit = parseUnit(element, SI.METER);
+        CoordinateSystemAxis axis = parseAxis(element, linearUnit, false);
+        Map<String,?>  properties = parseAuthority(element, name);
+        element.close();
+        try {
+            if (axis == null) {
+                axis = createAxis(null, "Z", AxisDirection.UP, linearUnit);
+            }
+            return crsFactory.createVerticalCRS(properties, datum,
+                    csFactory.createVerticalCS(singletonMap("name", name), axis));
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Parses a "GEOGCS" element. This element has the following pattern:
+     *
+     * <blockquote><code>
+     * GEOGCS["<name>", <datum>, <prime meridian>, <angular unit>  {,<twin axes>} {,<authority>}]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "GEOGCS" element as a {@link GeographicCRS} object.
+     * @throws ParseException if the "GEOGCS" element can't be parsed.
+     */
+    private GeographicCRS parseGeoGCS(final Element parent) throws ParseException {
+        Element            element = parent.pullElement("GEOGCS");
+        String                name = element.pullString("name");
+        Map<String,?>   properties = parseAuthority(element, name);
+        Unit<Angle>    angularUnit = parseUnit     (element, SI.RADIAN);
+        PrimeMeridian     meridian = parsePrimem   (element, angularUnit);
+        GeodeticDatum        datum = parseDatum    (element, meridian);
+        CoordinateSystemAxis axis0 = parseAxis     (element, angularUnit, false);
+        CoordinateSystemAxis axis1;
+        CoordinateSystemAxis axis2 = null;
+        try {
+            if (axis0 != null) {
+                axis1 = parseAxis(element, angularUnit, true);
+                if(axis1 != null) {
+                    axis2 = parseAxis(element, SI.METER, false);
+                } 
+            } else {
+                // Those default values are part of WKT specification.
+                axis0 = createAxis(null, "Lon", AxisDirection.EAST,  angularUnit);
+                axis1 = createAxis(null, "Lat", AxisDirection.NORTH, angularUnit);
+            }
+            element.close();
+            EllipsoidalCS ellipsoidalCS;
+            if(axis2 != null) {
+                ellipsoidalCS = csFactory.createEllipsoidalCS(properties, axis0, axis1, axis2);
+            } else {
+                ellipsoidalCS = csFactory.createEllipsoidalCS(properties, axis0, axis1);
+            }
+            return crsFactory.createGeographicCRS(properties, datum,
+                    ellipsoidalCS);
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Parses a "PROJCS" element.
+     * This element has the following pattern:
+     *
+     * <blockquote><code>
+     * PROJCS["<name>", <geographic cs>, <projection>, {<parameter>,}*,
+     *        <linear unit> {,<twin axes>}{,<authority>}]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "PROJCS" element as a {@link ProjectedCRS} object.
+     * @throws ParseException if the "GEOGCS" element can't be parsed.
+     */
+    private ProjectedCRS parseProjCS(final Element parent) throws ParseException {
+        Element                element = parent.pullElement("PROJCS");
+        String                    name = element.pullString("name");
+        Map<String,?>       properties = parseAuthority(element, name);
+        GeographicCRS           geoCRS = parseGeoGCS(element);
+        Ellipsoid            ellipsoid = geoCRS.getDatum().getEllipsoid();
+        Unit<Length>        linearUnit = parseUnit(element, SI.METER);
+        Unit<Angle>        angularUnit = geoCRS.getCoordinateSystem().getAxis(0).getUnit().asType(Angle.class);
+        ParameterValueGroup projection = parseProjection(element, ellipsoid, linearUnit, angularUnit);
+        CoordinateSystemAxis     axis0 = parseAxis(element, linearUnit, false);
+        CoordinateSystemAxis     axis1;
+        try {
+            if (axis0 != null) {
+                axis1 = parseAxis(element, linearUnit, true);
+            } else {
+                // Those default values are part of WKT specification.
+                axis0 = createAxis(null, "X", AxisDirection.EAST,  linearUnit);
+                axis1 = createAxis(null, "Y", AxisDirection.NORTH, linearUnit);
+            }
+            element.close();
+            final Conversion conversion = new DefiningConversion(name, projection);
+            return crsFactory.createProjectedCRS(properties, geoCRS, conversion,
+                    csFactory.createCartesianCS(properties, axis0, axis1));
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Parses a "COMPD_CS" element.
+     * This element has the following pattern:
+     *
+     * <blockquote><code>
+     * COMPD_CS["<name>", <head cs>, <tail cs> {,<authority>}]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "COMPD_CS" element as a {@link CompoundCRS} object.
+     * @throws ParseException if the "COMPD_CS" element can't be parsed.
+     */
+    private CompoundCRS parseCompdCS(final Element parent) throws ParseException {
+        final CoordinateReferenceSystem[] CRS = new CoordinateReferenceSystem[2];
+        Element       element    = parent.pullElement("COMPD_CS");
+        String        name       = element.pullString("name");
+        Map<String,?> properties = parseAuthority(element, name);
+        CRS[0] = parseCoordinateReferenceSystem(element);
+        CRS[1] = parseCoordinateReferenceSystem(element);
+        element.close();
+        try {
+            return crsFactory.createCompoundCRS(properties, CRS);
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Parses a "FITTED_CS" element.
+     * This element has the following pattern:
+     *
+     * <blockquote><code>
+     * FITTED_CS["<name>", <to base>, <base cs>]
+     * </code></blockquote>
+     *
+     * @param  parent The parent element.
+     * @return The "FITTED_CS" element as a {@link CompoundCRS} object.
+     * @throws ParseException if the "COMPD_CS" element can't be parsed.
+     */
+    private DerivedCRS parseFittedCS(final Element parent) throws ParseException {
+        Element       element    = parent.pullElement("FITTED_CS");
+        String        name       = element.pullString("name");
+        Map<String,?> properties = parseAuthority(element, name);
+        final MathTransform toBase = parseMathTransform(element, true);
+        final CoordinateReferenceSystem base = parseCoordinateReferenceSystem(element);
+        final OperationMethod method = getOperationMethod();
+        element.close();
+        /*
+         * WKT provides no informations about the underlying CS of a derived CRS.
+         * We have to guess some reasonable one with arbitrary units.  We try to
+         * construct the one which contains as few information as possible, in
+         * order to avoid providing wrong informations.
+         */
+        final CoordinateSystemAxis[] axis = new CoordinateSystemAxis[toBase.getSourceDimensions()];
+        final StringBuilder buffer = new StringBuilder(name);
+        buffer.append(" axis ");
+        final int start = buffer.length();
+        try {
+            for (int i=0; i<axis.length; i++) {
+                final String number = String.valueOf(i);
+                buffer.setLength(start);
+                buffer.append(number);
+                axis[i] = csFactory.createCoordinateSystemAxis(
+                    singletonMap(IdentifiedObject.NAME_KEY, buffer.toString()),
+                    number, AxisDirection.OTHER, Unit.ONE);
+            }
+            final Conversion conversion = new DefiningConversion(
+                    singletonMap(IdentifiedObject.NAME_KEY, method.getName().getCode()),
+                    method, toBase.inverse());
+            final CoordinateSystem cs = new AbstractCS(properties, axis);
+            return crsFactory.createDerivedCRS(properties, base, conversion, cs);
+        } catch (FactoryException exception) {
+            throw element.parseFailed(exception, null);
+        } catch (NoninvertibleTransformException exception) {
+            throw element.parseFailed(exception, null);
+        }
+    }
+
+    /**
+     * Returns the class of the specified WKT element. For example this method returns
+     * <code>{@linkplain ProjectedCRS}.class</code> for element "{@code PROJCS}".
+     *
+     * @param  element The WKT element name.
+     * @return The GeoAPI class of the specified element, or {@code null} if unknow.
+     */
+    public static Class<?> getClassOf(String element) {
+        if (element == null) {
+            return null;
+        }
+        element = element.trim().toUpperCase(Locale.US);
+        final Class<?> type = getTypeMap().get(element);
+        assert type == null || type.equals(MathTransform.class)
+                || element.equals(getNameOf(type)) : type;
+        return type;
+    }
+
+    /**
+     * Returns the WKT name of the specified object type. For example this method returns
+     * "{@code PROJCS}" for type <code>{@linkplain ProjectedCRS}.class</code>.
+     *
+     * @param type The GeoAPI class of the specified element.
+     * @return The WKT element name, or {@code null} if unknow.
+     *
+     * @since 2.4
+     */
+    public static String getNameOf(final Class<?> type) {
+        if (type != null) {
+            for (final Map.Entry<String,Class<?>> entry : getTypeMap().entrySet()) {
+                final Class<?> candidate = entry.getValue();
+                if (candidate.isAssignableFrom(type)) {
+                    return entry.getKey();
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the type map.
+     */
+    private static Map<String,Class<?>> getTypeMap() {
+        if (TYPES == null) {
+            final Map<String,Class<?>> map = new LinkedHashMap<String,Class<?>>(25);
+            map.put(        "GEOGCS",        GeographicCRS.class);
+            map.put(        "PROJCS",         ProjectedCRS.class);
+            map.put(        "GEOCCS",        GeocentricCRS.class);
+            map.put(       "VERT_CS",          VerticalCRS.class);
+            map.put(      "LOCAL_CS",       EngineeringCRS.class);
+            map.put(      "COMPD_CS",          CompoundCRS.class);
+            map.put(     "FITTED_CS",           DerivedCRS.class);
+            map.put(          "AXIS", CoordinateSystemAxis.class);
+            map.put(        "PRIMEM",        PrimeMeridian.class);
+            map.put(       "TOWGS84",  BursaWolfParameters.class);
+            map.put(      "SPHEROID",            Ellipsoid.class);
+            map.put(    "VERT_DATUM",        VerticalDatum.class);
+            map.put(   "LOCAL_DATUM",     EngineeringDatum.class);
+            map.put(         "DATUM",        GeodeticDatum.class);
+            map.put(      "PARAM_MT",        MathTransform.class);
+            map.put(     "CONCAT_MT",        MathTransform.class);
+            map.put(    "INVERSE_MT",        MathTransform.class);
+            map.put("PASSTHROUGH_MT",        MathTransform.class);
+            TYPES = map; // Sets the field only once completed, in order to avoid synchronisation.
+                         // It is not a big deal in current implementation if two Maps are created.
+        }
+        return TYPES;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/Symbols.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/Symbols.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/Symbols.java	(revision 28000)
@@ -0,0 +1,209 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.referencing.wkt;
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.Locale;
+
+
+/**
+ * The set of symbols to use for WKT parsing and formatting.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/referencing/wkt/Symbols.java $
+ * @version $Id: Symbols.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class Symbols {
+    /**
+     * The default set of symbols.
+     */
+    public static final Symbols DEFAULT = new Symbols(Locale.US);
+    // DONT't invoke the default constructor for this one.
+
+    /**
+     * A set of symbols with parameters between parentheses,
+     * like {@code (...)}.
+     */
+    public static final Symbols CURLY_BRACKETS = new Symbols();
+    static {
+        CURLY_BRACKETS.close = ')';
+    }
+
+    /* ----------------------------------------------------------
+     * NOTE: Consider all fields below as final.
+     *       It is not only in order to make construction easier.
+     *       If the informations provided by those fields became
+     *       needed outside of this package, then we need to make
+     *       them private and declare accessors instead.
+     * ---------------------------------------------------------- */
+
+    /**
+     * The locale for querying localizable information.
+     */
+    final Locale locale;
+
+    /**
+     * The character used for closing brace.
+     * Usually {@code ']'}, but {@code ')'} is legal as well.
+     */
+    char close = ']';
+
+    /**
+     * The character used for quote.
+     * Usually {@code '"'}.
+     */
+    final char quote = '"';
+
+    /**
+     * The character used as a separator. Usually {@code ','}, but would need
+     * to be changed if a non-English locale is used for formatting numbers.
+     */
+    char separator = ',';
+
+    /**
+     * List of caracters acceptable as opening bracket. The closing bracket must
+     * be the character in the {@code closingBrackets} array at the same index
+     * than the opening bracket.
+     */
+    final char[] openingBrackets = {'[', '('};
+
+    /**
+     * List of caracters acceptable as closing bracket.
+     */
+    final char[] closingBrackets = {']', ')'};
+
+    /**
+     * The object to use for parsing and formatting numbers.
+     *
+     * <STRONG>Note:</STRONG> {@link NumberFormat} object are usually not thread safe.
+     * Consequently, each instances of {@link Parser} or {@link Formatter} must use a
+     * clone of this object, not this object directly (unless they synchronize on it).
+     */
+    final NumberFormat numberFormat;
+
+    /**
+     * Creates a new instance initialized to the default symbols.
+     */
+    private Symbols() {
+        locale = Locale.US;
+        numberFormat = DEFAULT.numberFormat;
+    }
+
+    /**
+     * Creates a new set of symbols for the specified locale.
+     */
+    public Symbols(final Locale locale) {
+        this.locale = locale;
+        numberFormat = NumberFormat.getNumberInstance(locale);
+        numberFormat.setGroupingUsed(false);
+        numberFormat.setMinimumFractionDigits(1);
+        numberFormat.setMaximumFractionDigits(20);
+        /*
+         * The "maximum fraction digits" seems hight for the precision of floating
+         * points (even in double precision), but this is because the above format
+         * do not uses the scientific notation. For example 1E-5 is always formatted
+         * as 0.00001, and 1E-340 would actually need a maximum fraction digits of
+         * 340. For most parameters, such low values should not occurs and may be
+         * rounding error for the 0 value. For semi-major and semi-minor axis, we
+         * often want to avoid exponential notation as well.
+         */
+        if (numberFormat instanceof DecimalFormat) {
+            final char decimalSeparator = ((DecimalFormat) numberFormat)
+                       .getDecimalFormatSymbols().getDecimalSeparator();
+            if (decimalSeparator == ',') {
+                separator = ';';
+            }
+        }
+    }
+
+    /**
+     * Returns {@code true} if the specified WKT contains at least one {@code AXIS[...]} element.
+     * This method tries to make a quick checks taking in account a minimal set of WKT syntax rules.
+     *
+     * @since 2.4
+     */
+    public boolean containsAxis(final CharSequence wkt) {
+        return indexOf(wkt, "AXIS", 0) >= 0;
+    }
+
+    /**
+     * Returns the index after the specified element in the specified WKT, or -1 if not found.
+     * The element must be followed (ignoring spaces) by an opening bracket. If found, this
+     * method returns the index of the opening bracket after the element.
+     *
+     * @param  wkt The WKT to parse.
+     * @param  element The element to search. Must contains only uppercase letters.
+     * @param  index The index to start the search from.
+     */
+    private int indexOf(final CharSequence wkt, final String element, int index) {
+        assert element.equals(element.trim().toUpperCase(locale)) : element;
+        assert element.indexOf(quote) < 0 : element;
+        boolean isQuoting = false;
+        final int elementLength = element.length();
+        final int length = wkt.length();
+        if (index < length) {
+            char c = wkt.charAt(index);
+search:     while (true) {
+                // Do not parse any content between quotes.
+                if (c == quote) {
+                    isQuoting = !isQuoting;
+                }
+                if (isQuoting || !Character.isJavaIdentifierStart(c)) {
+                    if (++index == length) {
+                        break search;
+                    }
+                    c = wkt.charAt(index);
+                    continue;
+                }
+                // Checks if we have a match.
+                for (int j=0; j<elementLength; j++) {
+                    c = Character.toUpperCase(c);
+                    if (c != element.charAt(j)) {
+                        // No match. Skip all remaining letters and resume the search.
+                        while (Character.isJavaIdentifierPart(c)) {
+                            if (++index == length) {
+                                break search;
+                            }
+                            c = wkt.charAt(index);
+                        }
+                        continue search;
+                    }
+                    if (++index == length) {
+                        break search;
+                    }
+                    c = wkt.charAt(index);
+                }
+                // Checks if the next character (ignoring space) is an opening brace.
+                while (Character.isWhitespace(c)) {
+                    if (++index == length) {
+                        break search;
+                    }
+                    c = wkt.charAt(index);
+                }
+                for (int i=0; i<openingBrackets.length; i++) {
+                    if (c == openingBrackets[i]) {
+                        return index;
+                    }
+                }
+            }
+        }
+        return -1;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/referencing/wkt/package.html	(revision 28000)
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.referencing.wkt</TITLE>
+  </HEAD>
+  <BODY>
+  <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well
+  Known Text</cite> (WKT)</A> parsing and formatting.
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/BufferSoftReference.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/BufferSoftReference.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/BufferSoftReference.java	(revision 28000)
@@ -0,0 +1,60 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources;
+
+import java.lang.ref.SoftReference;
+import java.nio.ByteBuffer;
+
+import org.geotools.resources.NIOUtilities;
+import org.geotools.util.WeakCollectionCleaner;
+
+/**
+ * A soft reference that will clear the contained byte buffer before getting garbage collected 
+ * @author Andrea Aime - OpenGeo
+ *
+ */
+class BufferSoftReference extends SoftReference<ByteBuffer> {
+
+    public BufferSoftReference(ByteBuffer referent) {
+        super(referent, WeakCollectionCleaner.DEFAULT.getReferenceQueue());
+    }
+
+    @Override
+    public void clear() {
+        ByteBuffer buffer = get();
+        NIOUtilities.clean(buffer);
+        super.clear();
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if(!(other instanceof BufferSoftReference)) {
+            return false;
+        }
+        
+        ByteBuffer buffer = get();
+        if(buffer == null) {
+            return false;
+        } else {
+            ByteBuffer otherBuffer = ((BufferSoftReference) other).get();
+            if(otherBuffer == null) {
+                return false;
+            }
+            return otherBuffer == buffer;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/CRSUtilities.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/CRSUtilities.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/CRSUtilities.java	(revision 28000)
@@ -0,0 +1,92 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources;
+
+import java.util.List;
+
+import org.opengis.referencing.crs.CompoundCRS;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.SingleCRS;
+import org.opengis.referencing.datum.Datum;
+import org.opengis.referencing.datum.Ellipsoid;
+
+
+/**
+ * A set of static methods working on OpenGIS&reg;
+ * {@linkplain CoordinateReferenceSystem coordinate reference system} objects.
+ * Some of those methods are useful, but not really rigorous. This is why they
+ * do not appear in the "official" package, but instead in this private one.
+ * <strong>Do not rely on this API!</strong> It may change in incompatible way
+ * in any future release.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/resources/CRSUtilities.java $
+ * @version $Id: CRSUtilities.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public final class CRSUtilities {
+    /**
+     * Do not allow creation of instances of this class.
+     */
+    private CRSUtilities() {
+    }
+
+    /**
+     * Returns the components of the specified CRS, or {@code null} if none.
+     */
+    private static List<CoordinateReferenceSystem> getComponents(CoordinateReferenceSystem crs) {
+        if (crs instanceof CompoundCRS) {
+            final List<CoordinateReferenceSystem> components;
+            components = ((CompoundCRS) crs).getCoordinateReferenceSystems();
+            if (!components.isEmpty()) {
+                return components;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the datum of the specified CRS, or {@code null} if none.
+     *
+     * @param  crs The coordinate reference system for which to get the datum. May be {@code null}.
+     * @return The datum in the given CRS, or {@code null} if none.
+     */
+    public static Datum getDatum(final CoordinateReferenceSystem crs) {
+        return (crs instanceof SingleCRS) ? ((SingleCRS) crs).getDatum() : null;
+    }
+
+    /**
+     * Returns the ellipsoid used by the specified coordinate reference system, providing that
+     * the two first dimensions use an instance of {@link GeographicCRS}. Otherwise (i.e. if the
+     * two first dimensions are not geographic), returns {@code null}.
+     *
+     * @param  crs The coordinate reference system for which to get the ellipsoid.
+     * @return The ellipsoid in the given CRS, or {@code null} if none.
+     */
+    public static Ellipsoid getHeadGeoEllipsoid(CoordinateReferenceSystem crs) {
+        while (!(crs instanceof GeographicCRS)) {
+            final List<CoordinateReferenceSystem> c = getComponents(crs);
+            if (c == null) {
+                return null;
+            }
+            crs = c.get(0);
+        }
+        return ((GeographicCRS) crs).getDatum().getEllipsoid();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/ClassChanger.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/ClassChanger.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/ClassChanger.java	(revision 28000)
@@ -0,0 +1,157 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources;
+
+import java.util.Date;
+
+
+/**
+ * A central place to register transformations between an arbitrary class and a
+ * {@link Number}. For example, it is sometime convenient to consider {@link Date}
+ * objects as if they were {@link Long} objects for computation purpose in generic
+ * algorithms. Client can call the following method to convert an arbitrary object
+ * to a {@link Number}:
+ *
+ * <blockquote><pre>
+ * Object someArbitraryObject = new Date();
+ * Number myObjectAsANumber = {@link ClassChanger#toNumber ClassChanger.toNumber}(someArbitraryObject);
+ * </pre></blockquote>
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/ClassChanger.java $
+ * @version $Id: ClassChanger.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public abstract class ClassChanger<S extends Comparable<S>, T extends Number> {
+
+    /**
+     * A list of class objects that can be converted to numbers. This list is initialized
+     * to a few commons {@link ClassChanger} instances for some standard Java classes like
+     * {@link Date}. More objects can be added dynamically. This list must be <u>ordered</u>:
+     * subclasses must be listed before parent classes.
+     */
+    private static ClassChanger<?,?>[] changers = new ClassChanger[] {
+        new ClassChanger<Date,Long>(Date.class, Long.class) {
+            protected Long convert(final Date object) {
+                return object.getTime();
+            }
+
+            protected Date inverseConvert(final Long value) {
+                return new Date(value.longValue());
+            }
+        }
+    };
+
+    /**
+     * Parent class for {@link #convert}'s input objects.
+     */
+    private final Class<S> source;
+
+    /**
+     * Parent class for {@link #convert}'s output objects.
+     */
+    private final Class<T> target;
+
+    /**
+     * Constructs a new class changer.
+     *
+     * @param source Parent class for {@link #convert}'s input objects.
+     * @param target Parent class for {@link #convert}'s output objects.
+     */
+    protected ClassChanger(final Class<S> source, final Class<T> target) {
+        this.source = source;
+        this.target = target;
+        if (!Comparable.class.isAssignableFrom(source)) {
+            throw new IllegalArgumentException(String.valueOf(source));
+        }
+        if (!Number.class.isAssignableFrom(target)) {
+            throw new IllegalArgumentException(String.valueOf(target));
+        }
+    }
+
+    /**
+     * Returns the numerical value for an object.
+     *
+     * @param  object Object to convert (may be null).
+     * @return The object's numerical value.
+     * @throws ClassCastException if {@code object} is not of the expected class.
+     */
+    protected abstract T convert(final S object) throws ClassCastException;
+
+    /**
+     * Returns an instance of the converted classe from a numerical value.
+     *
+     * @param  value The value to wrap.
+     * @return An instance of the source classe.
+     */
+    protected abstract S inverseConvert(final T value);
+
+    /**
+     * Returns a string representation for this class changer.
+     */
+    @Override
+    public String toString() {
+        return "ClassChanger[" + source.getName() + "\u00A0\u21E8\u00A0" + target.getName() + ']';
+    }
+
+    /**
+     * Registers a new converter. All registered {@link ClassChanger} will
+     * be taken in account by the {@link #toNumber} method. The example below
+     * register a conversion for the {@link Date} class:
+     *
+     * <blockquote><pre>
+     * &nbsp;ClassChanger.register(new ClassChanger(Date.class, Long.class) {
+     * &nbsp;    protected Long convert(final Comparable o) {
+     * &nbsp;        return ((Date) o).getTime();
+     * &nbsp;    }
+     * &nbsp;
+     * &nbsp;    protected Comparable inverseConvert(final Number number) {
+     * &nbsp;        return new Date(number.longValue());
+     * &nbsp;    }
+     * &nbsp;});
+     * </pre></blockquote>
+     *
+     * @param  converter The {@link ClassChanger} to add.
+     * @throws IllegalStateException if an other {@link ClassChanger} was already
+     *         registered for the same {@code source} class. This is usually
+     *         not a concern since the registration usually take place during the
+     *         class initialization ("static" constructor).
+     */
+    public static synchronized void register(final ClassChanger<?,?> converter)
+            throws IllegalStateException
+    {
+        int i;
+        for (i=0; i<changers.length; i++) {
+            if (changers[i].source.isAssignableFrom(converter.source)) {
+                /*
+                 * We found a converter for a parent class. The new converter should be
+                 * inserted before its parent.  But before the insertion, we will check
+                 * if this converter was not already registered later in the array.
+                 */
+                for (int j=i; j<changers.length; j++) {
+                    if (changers[j].source.equals(converter.source)) {
+                        throw new IllegalStateException(changers[j].toString());
+                    }
+                }
+                break;
+            }
+        }
+        changers = XArray.insert(changers, i, 1);
+        changers[i] = converter;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/Classes.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/Classes.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/Classes.java	(revision 28000)
@@ -0,0 +1,318 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.WildcardType;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+
+
+/**
+ * A set of miscellaneous methods working on {@link Class} objects.
+ *
+ * @since 2.5
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/Classes.java $
+ * @version $Id: Classes.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+@SuppressWarnings("unused")
+public final class Classes {
+    /**
+     * Constants to be used in {@code switch} statements.
+     */
+    public static final byte DOUBLE=8, FLOAT=7, LONG=6, INTEGER=5, SHORT=4, BYTE=3,
+                            CHARACTER=2, BOOLEAN=1, OTHER=0;
+
+    /**
+     * Mapping between a primitive type and its wrapper, if any.
+     */
+    private static final Map<Class<?>,Classes> MAPPING = new HashMap<Class<?>,Classes>(16);
+    static {
+        new Classes(Double   .TYPE, Double   .class, true,  false, (byte) Double   .SIZE, DOUBLE   );
+        new Classes(Float    .TYPE, Float    .class, true,  false, (byte) Float    .SIZE, FLOAT    );
+        new Classes(Long     .TYPE, Long     .class, false, true,  (byte) Long     .SIZE, LONG     );
+        new Classes(Integer  .TYPE, Integer  .class, false, true,  (byte) Integer  .SIZE, INTEGER  );
+        new Classes(Short    .TYPE, Short    .class, false, true,  (byte) Short    .SIZE, SHORT    );
+        new Classes(Byte     .TYPE, Byte     .class, false, true,  (byte) Byte     .SIZE, BYTE     );
+        new Classes(Character.TYPE, Character.class, false, false, (byte) Character.SIZE, CHARACTER);
+        new Classes(Boolean  .TYPE, Boolean  .class, false, false, (byte) 1,              BOOLEAN  );
+        new Classes(Void     .TYPE, Void     .class, false, false, (byte) 0,              OTHER    );
+    }
+
+    /** The wrapper for the primitive type.     */ private final Class<?> wrapper;
+    /** {@code true} for integer number.        */ private final boolean  isInteger;
+
+    /**
+     * Creates a mapping between a primitive type and its wrapper.
+     */
+    private Classes(final Class<?> primitive, final Class<?> wrapper,
+                    final boolean  isFloat,   final boolean  isInteger,
+                    final byte     size,      final byte     ordinal)
+    {
+        this.wrapper   = wrapper;
+        this.isInteger = isInteger;
+        if (MAPPING.put(primitive, this) != null || MAPPING.put(wrapper, this) != null) {
+            throw new AssertionError(); // Should never happen.
+        }
+    }
+
+    /**
+     * If the given method is a getter or a setter for a parameterized attribute, returns the
+     * upper bounds of the parameterized type. Otherwise returns {@code null}. This method
+     * provides the same semantic than {@link #boundOfParameterizedAttribute(Field)}, but
+     * works on a getter or setter method rather then the field. See the javadoc of above
+     * methods for more details.
+     * <p>
+     * This method is typically used for fetching the type of elements in a collection.
+     * We do not provide a method working from a {@link Class} instance because of the
+     * way parameterized types are implemented in Java (by erasure).
+     *
+     * @param  method The getter or setter method for which to obtain the parameterized type.
+     * @return The upper bound of parameterized type, or {@code null} if the given method
+     *         do not opperate on an object of a parameterized type.
+     */
+    public static Class<?> boundOfParameterizedAttribute(final Method method) {
+        Class<?> c = getActualTypeArgument(method.getGenericReturnType());
+        if (c == null) {
+            final Type[] parameters = method.getGenericParameterTypes();
+            if (parameters != null && parameters.length == 1) {
+                c = getActualTypeArgument(parameters[0]);
+            }
+        }
+        return c;
+    }
+
+    /**
+     * Delegates to {@link ParameterizedType#getActualTypeArguments} and returns the result as a
+     * {@link Class}, provided that every objects are of the expected classes and the result was
+     * an array of length 1 (so there is no ambiguity). Otherwise returns {@code null}.
+     */
+    private static Class<?> getActualTypeArgument(Type type) {
+        if (type instanceof ParameterizedType) {
+            Type[] p = ((ParameterizedType) type).getActualTypeArguments();
+            while (p != null && p.length == 1) {
+                type = p[0];
+                if (type instanceof Class) {
+                    return (Class) type;
+                } else if (type instanceof WildcardType) {
+                    p = ((WildcardType) type).getUpperBounds();
+                } else {
+                    break; // Unknown type.
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the class of the specified object, or {@code null} if {@code object} is null.
+     * This method is also useful for fetching the class of an object known only by its bound
+     * type. As of Java 6, the usual pattern:
+     *
+     * <blockquote><pre>
+     * Number n = 0;
+     * Class<? extends Number> c = n.getClass();
+     * </pre></blockquote>
+     *
+     * doesn't seem to work if {@link Number} is replaced by a parametirez type {@code T}.
+     *
+     * @param  <T> The type of the given object.
+     * @param  object The object for which to get the class, or {@code null}.
+     * @return The class of the given object, or {@code null} if the given object was null.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> Class<? extends T> getClass(final T object) {
+        return (object != null) ? (Class<? extends T>) object.getClass() : null;
+    }
+
+    /**
+     * Returns {@code true} if the two specified objects implements exactly the same set of
+     * interfaces. Only interfaces assignable to {@code base} are compared. Declaration order
+     * doesn't matter. For example in ISO 19111, different interfaces exist for different coordinate
+     * system geometries ({@code CartesianCS}, {@code PolarCS}, etc.). We can check if two
+     * CS implementations has the same geometry with the following code:
+     *
+     * <blockquote><code>
+     * if (sameInterfaces(cs1, cs2, {@linkplain org.opengis.referencing.cs.CoordinateSystem}.class))
+     * </code></blockquote>
+     *
+     * @param <T>     A common parent for both objects.
+     * @param object1 The first object to check for interfaces.
+     * @param object2 The second object to check for interfaces.
+     * @param base    The parent of all interfaces to check.
+     * @return        {@code true} if both objects implement the same set of interfaces,
+     *                considering only sub-interfaces of {@code base}.
+     */
+    public static <T> boolean sameInterfaces(final Class<? extends T> object1,
+                                             final Class<? extends T> object2,
+                                             final Class<T> base)
+    {
+        if (object1 == object2) {
+            return true;
+        }
+        if (object1==null || object2==null) {
+            return false;
+        }
+        final Class<?>[] c1 = object1.getInterfaces();
+        final Class<?>[] c2 = object2.getInterfaces();
+        /*
+         * Trim all interfaces that are not assignable to 'base' in the 'c2' array.
+         * Doing this once will avoid to redo the same test many time in the inner
+         * loops j=[0..n].
+         */
+        int n = 0;
+        for (int i=0; i<c2.length; i++) {
+            final Class<?> c = c2[i];
+            if (base.isAssignableFrom(c)) {
+                c2[n++] = c;
+            }
+        }
+        /*
+         * For each interface assignable to 'base' in the 'c1' array, check if
+         * this interface exists also in the 'c2' array. Order doesn't matter.
+         */
+compare:for (int i=0; i<c1.length; i++) {
+            final Class<?> c = c1[i];
+            if (base.isAssignableFrom(c)) {
+                for (int j=0; j<n; j++) {
+                    if (c.equals(c2[j])) {
+                        System.arraycopy(c2, j+1, c2, j, --n-j);
+                        continue compare;
+                    }
+                }
+                return false; // Interface not found in 'c2'.
+            }
+        }
+        return n == 0; // If n>0, at least one interface was not found in 'c1'.
+    }
+
+    /**
+     * Returns {@code true} if the given {@code type} is an integer type.
+     *
+     * @param  type The type to test (may be {@code null}).
+     * @return {@code true} if {@code type} is the primitive of wrapper class of
+     *         {@link Long}, {@link Integer}, {@link Short} or {@link Byte}.
+     */
+    public static boolean isInteger(final Class<?> type) {
+        final Classes mapping = MAPPING.get(type);
+        return (mapping != null) && mapping.isInteger;
+    }
+
+    /**
+     * Changes a primitive class to its wrapper (e.g. {@code int} to {@link Integer}).
+     * If the specified class is not a primitive type, then it is returned unchanged.
+     *
+     * @param  type The primitive type (may be {@code null}).
+     * @return The type as a wrapper.
+     */
+    public static Class<?> primitiveToWrapper(final Class<?> type) {
+        final Classes mapping = MAPPING.get(type);
+        return (mapping != null) ? mapping.wrapper : type;
+    }
+
+    /**
+     * Converts the specified string into a value object. The value object can be an instance of
+     * {@link Double}, {@link Float}, {@link Long}, {@link Integer}, {@link Short}, {@link Byte},
+     * {@link Boolean}, {@link Character} or {@link String} according the specified type. This
+     * method is intentionnaly restricted to primitive types, with the addition of {@code String}
+     * which can be though as an identity operation. Other types like {@link java.io.File} are
+     * not the purpose of this method.
+     *
+     * @param  <T> The requested type.
+     * @param  type The requested type.
+     * @param  value the value to parse.
+     * @return The value object, or {@code null} if {@code value} was null.
+     * @throws IllegalArgumentException if {@code type} is not a recognized type.
+     * @throws NumberFormatException if {@code type} is a subclass of {@link Number} and the
+     *         string value is not parseable as a number of the specified type.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T valueOf(final Class<T> type, final String value)
+            throws IllegalArgumentException, NumberFormatException
+    {
+        if (value == null) {
+            return null;
+        }
+        if (Double .class.equals(type)) return (T) Double .valueOf(value);
+        if (Float  .class.equals(type)) return (T) Float  .valueOf(value);
+        if (Long   .class.equals(type)) return (T) Long   .valueOf(value);
+        if (Integer.class.equals(type)) return (T) Integer.valueOf(value);
+        if (Short  .class.equals(type)) return (T) Short  .valueOf(value);
+        if (Byte   .class.equals(type)) return (T) Byte   .valueOf(value);
+        if (Boolean.class.equals(type)) return (T) Boolean.valueOf(value);
+        if (Character.class.equals(type)) {
+            /*
+             * If the string is empty, returns 0 which means "end of string" in C/C++
+             * and NULL in Unicode standard. If non-empty, take only the first char.
+             * This is somewhat consistent with Boolean.valueOf(...) which is quite
+             * lenient about the parsing as well, and throwing a NumberFormatException
+             * for those would not be appropriate.
+             */
+            return (T) Character.valueOf(value.length() != 0 ? value.charAt(0) : 0);
+        }
+        if (String.class.equals(type)) {
+            return (T) value;
+        }
+        throw new IllegalArgumentException(Errors.format(ErrorKeys.UNKNOW_TYPE_$1, type));
+    }
+
+    /**
+     * Returns a short class name for the specified class. This method will
+     * omit the package name.  For example, it will return "String" instead
+     * of "java.lang.String" for a {@link String} object. It will also name
+     * array according Java language usage,  for example "double[]" instead
+     * of "[D".
+     *
+     * @param  classe The object class (may be {@code null}).
+     * @return A short class name for the specified object.
+     */
+    public static String getShortName(Class<?> classe) {
+        if (classe == null) {
+            return "<*>";
+        }
+        String name = classe.getSimpleName();
+        Class<?> enclosing = classe.getEnclosingClass();
+        if (enclosing != null) {
+            final StringBuilder buffer = new StringBuilder();
+            do {
+                buffer.insert(0, '.').insert(0, enclosing.getSimpleName());
+            } while ((enclosing = enclosing.getEnclosingClass()) != null);
+            name = buffer.append(name).toString();
+        }
+        return name;
+    }
+
+    /**
+     * Returns a short class name for the specified object. This method will
+     * omit the package name. For example, it will return "String" instead
+     * of "java.lang.String" for a {@link String} object.
+     *
+     * @param  object The object (may be {@code null}).
+     * @return A short class name for the specified object.
+     */
+    public static String getShortClassName(final Object object) {
+        return getShortName(getClass(object));
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/Formattable.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/Formattable.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/Formattable.java	(revision 28000)
@@ -0,0 +1,39 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources;
+
+
+
+/**
+ * Interface for object that can be formatted as
+ * <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well
+ * Known Text</cite> (WKT), but can't extends {@link org.geotools.referencing.wkt.Formattable}. This
+ * interface is especially used for {@code AffineTransform2D} implementation. This interface is not
+ * public because the {@code formatWKT(Formatter)} method usually has a protected access.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/resources/Formattable.java $
+ * @version $Id: Formattable.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @todo Consider renaming {@link org.geotools.referencing.wkt.Formattable} as
+ *       {@code AbstractFormattable} and move this interface in the wkt package.
+ */
+public interface Formattable {
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/IndexedResourceBundle.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/IndexedResourceBundle.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/IndexedResourceBundle.java	(revision 28000)
@@ -0,0 +1,560 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.MessageFormat;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.NoSuchElementException;
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.geotools.util.logging.Logging;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * {@link ResourceBundle} implementation using integers instead of strings for resource
+ * keys. Because it doesn't use strings, this implementation avoids adding all those string
+ * constants to {@code .class} files and runtime images. Developers still have meaningful labels
+ * in their code (e.g. {@code DIMENSION_MISMATCH}) through a set of constants defined in interfaces.
+ * This approach furthermore gives the benefit of compile-time safety. Because integer constants are
+ * inlined right into class files at compile time, the declarative interface is never loaded at run
+ * time. This class also provides facilities for string formatting using {@link MessageFormat}.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/IndexedResourceBundle.java $
+ * @version $Id: IndexedResourceBundle.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class IndexedResourceBundle extends ResourceBundle {
+    /**
+     * Maximum string length for text inserted into another text. This parameter is used by
+     * {@link #summarize}. Resource strings are never cut to this length. However, text replacing
+     * "{0}" in a string like "Parameter name is {0}." will be cut to this length.
+     */
+    private static final int MAX_STRING_LENGTH = 200;
+
+    /**
+     * The resource name of the binary file containing resources.
+     * It may be a file name or an entry in a JAR file.
+     */
+    private final String filename;
+
+    /**
+     * The array of resources. Keys are an array index. For example, the value for key "14" is
+     * {@code values[14]}. This array will be loaded only when first needed. We should not load
+     * it at construction time, because some {@code ResourceBundle} objects will never ask for
+     * values. This is particularly the case for ancestor classes of {@code Resources_fr_CA},
+     * {@code Resources_en}, {@code Resources_de}, etc., which will only be used if a key has
+     * not been found in the subclass.
+     */
+    private String[] values;
+
+    /**
+     * The locale for formatting objects like number, date, etc. There are two possible Locales
+     * we could use: default locale or resource bundle locale. If the default locale uses the same
+     * language as this ResourceBundle's locale, then we will use the default locale. This allows
+     * dates and numbers to be formatted according to user conventions (e.g. French Canada) even
+     * if the ResourceBundle locale is different (e.g. standard French). However, if languages
+     * don't match, then we will use ResourceBundle locale for better coherence.
+     */
+    private transient Locale locale;
+
+    /**
+     * The object to use for formatting messages. This object
+     * will be constructed only when first needed.
+     */
+    private transient MessageFormat format;
+
+    /**
+     * The key of the last resource requested. If the same resource is requested multiple times,
+     * knowing its key allows us to avoid invoking the costly {@link MessageFormat#applyPattern}
+     * method.
+     */
+    private transient int lastKey;
+
+    /**
+     * Constructs a new resource bundle. The resource filename will be inferred from
+     * the fully qualified classname of this {@code IndexedResourceBundle} subclass.
+     */
+    protected IndexedResourceBundle() {
+        filename = getClass().getSimpleName() + ".utf";
+    }
+
+    /**
+     * Returns the locale to use for formatters.
+     */
+    private Locale getFormatLocale() {
+        if (locale == null) {
+            locale = Locale.getDefault();
+            final Locale resourceLocale = getLocale();
+            if (!locale.getLanguage().equalsIgnoreCase(resourceLocale.getLanguage())) {
+                locale = resourceLocale;
+            }
+        }
+        return locale;
+    }
+
+    /**
+     * Returns the name of the package.
+     */
+    private String getPackageName() {
+        final String name = getClass().getName();
+        final int index = name.lastIndexOf('.');
+        return (index>=0) ? name.substring(0, index) : "org.geotools";
+    }
+
+    /**
+     * Ensures that resource values are loaded. If they are not, load them immediately.
+     *
+     * @param  key Key for the requested resource, or {@code null} if all resources
+     *         are requested. This key is used mostly for constructing messages.
+     * @return The resources.
+     * @throws MissingResourceException if this method failed to load resources.
+     */
+    private String[] ensureLoaded(final String key) throws MissingResourceException {
+        LogRecord record = null;
+        try {
+            String[] values;
+            synchronized (this) {
+                values = this.values;
+                if (values != null) {
+                    return values;
+                }
+                /*
+                 * Prepares a log record.  We will wait for successful loading before
+                 * posting this record.  If loading fails, the record will be changed
+                 * into an error record. Note that the message must be logged outside
+                 * the synchronized block, otherwise there is dead locks!
+                 */
+                record= new LogRecord(Level.FINER, "Loaded resources for {0} from bundle \"{1}\".");
+                record.setSourceClassName (getClass().getName());
+                record.setSourceMethodName((key != null) ? "getObject" : "getKeys");
+                /*
+                 * Loads resources from the UTF file.
+                 */
+                InputStream in;
+                String name = filename;
+                while ((in = getClass().getResourceAsStream(name)) == null) {
+                    final int ext  = name.lastIndexOf('.');
+                    final int lang = name.lastIndexOf('_', ext-1);
+                    if (lang <= 0) {
+                        throw new FileNotFoundException(filename);
+                    }
+                    name = name.substring(0, lang) + name.substring(ext);
+                }
+                final DataInputStream input = new DataInputStream(new BufferedInputStream(in));
+                this.values = values = new String[input.readInt()];
+                for (int i=0; i<values.length; i++) {
+                    values[i] = input.readUTF();
+                    if (values[i].length() == 0)
+                        values[i] = null;
+                }
+                input.close();
+                /*
+                 * Now, log the message. This message is not localized.
+                 */
+                String language = getLocale().getDisplayName(Locale.US);
+                if (language==null || language.length()==0) {
+                    language="<default>";
+                }
+                record.setParameters(new String[]{language, getPackageName()});
+            }
+            final Logger logger = Logging.getLogger(IndexedResourceBundle.class);
+            record.setLoggerName(logger.getName());
+            logger.log(record);
+            return values;
+        } catch (IOException exception) {
+            record.setLevel  (Level.WARNING);
+            record.setMessage(exception.getLocalizedMessage());
+            record.setThrown (exception);
+            final Logger logger = Logging.getLogger(IndexedResourceBundle.class);
+            record.setLoggerName(logger.getName());
+            logger.log(record);
+            final MissingResourceException error = new MissingResourceException(
+                    exception.getLocalizedMessage(), getClass().getName(), key);
+            error.initCause(exception);
+            throw error;
+        }
+    }
+
+    /**
+     * Returns an enumeration of the keys.
+     */
+    public final Enumeration<String> getKeys() {
+        // Synchronization performed by 'ensureLoaded'
+        final String[] values = ensureLoaded(null);
+        return new Enumeration<String>() {
+            private int i=0;
+
+            public boolean hasMoreElements() {
+                while (true) {
+                    if (i >= values.length) return false;
+                    if (values[i] != null)  return true;
+                    i++;
+                }
+            }
+
+            public String nextElement() {
+                while (true) {
+                    if (i >= values.length) throw new NoSuchElementException();
+                    if (values[i] != null)  return String.valueOf(i++);
+                    i++;
+                }
+            }
+        };
+    }
+
+    /**
+     * Gets an object for the given key from this resource bundle.
+     * Returns null if this resource bundle does not contain an
+     * object for the given key.
+     *
+     * @param key the key for the desired object
+     * @exception NullPointerException if {@code key} is {@code null}
+     * @return the object for the given key, or null
+     */
+    protected final Object handleGetObject(final String key) {
+        // Synchronization performed by 'ensureLoaded'
+        final String[] values = ensureLoaded(key);
+        final int keyID;
+        try {
+            keyID = Integer.parseInt(key);
+        } catch (NumberFormatException exception) {
+            return null;
+        }
+        return (keyID>=0 && keyID<values.length) ? values[keyID] : null;
+    }
+
+    /**
+     * Makes sure that the {@code text} string is not longer than {@code maxLength} characters.
+     * If {@code text} is not longer, it is returned unchanged (except for trailing blanks,
+     * which are removed). If {@code text} is longer, it will be cut somewhere in the middle.
+     * This method tries to cut between two words and replace the missing words with "(...)".
+     * For example, the following string:
+     *
+     * <blockquote>
+     *   "This sentence given as an example is way too long to be
+     *    included in a message."
+     * </blockquote>
+     *
+     * May be "summarized" by something like this:
+     *
+     * <blockquote>
+     *   "This sentence given (...) included in a message."
+     * </blockquote>
+     *
+     * @param  text The sentence to summarize if it is too long.
+     * @param  maxLength The maximum length allowed for {@code text}.
+     *         If {@code text} is longer, it will be summarized.
+     * @return A sentence not longer than {@code maxLength}.
+     */
+    private static String summarize(String text, int maxLength) {
+        text=text.trim();
+        final int length=text.length();
+        if (length<=maxLength) {
+            return text;
+        }
+        /*
+         * Computes maximum length for one half of the string. Take into
+         * account the space needed for inserting the " (...) " string.
+         */
+        maxLength = (maxLength-7) >> 1;
+        if (maxLength<=0) {
+            return text;
+        }
+        /*
+         * We will remove characters from 'break1' to 'break2', both exclusive.
+         * We try to adjust 'break1' and 'break2' in such a way that the first
+         * and last characters to be removed will be spaces or punctuation
+         * characters.
+         * Constants 'lower' and 'upper' are limit values. If we don't find
+         * values for 'break1' and 'break2' inside those limits, we will give
+         * up.
+         */
+        int break1 = maxLength;
+        int break2 = length-maxLength;
+        for (final int lower=(maxLength>>1); break1>=lower; break1--) {
+            if (!Character.isUnicodeIdentifierPart(text.charAt(break1))) {
+                while (--break1>=lower && !Character.isUnicodeIdentifierPart(text.charAt(break1)));
+                break;
+            }
+        }
+        for (final int upper=length-(maxLength>>1); break2<upper; break2++) {
+            if (!Character.isUnicodeIdentifierPart(text.charAt(break2))) {
+                while (++break2<upper && !Character.isUnicodeIdentifierPart(text.charAt(break2)));
+                break;
+            }
+        }
+        return (text.substring(0,break1+1)+" (...) "+text.substring(break2)).trim();
+    }
+
+    /**
+     * Returns {@code arguments} as an array. If {@code arguments} is already an array, this array
+     * or a copy of this array will be returned. If {@code arguments} is not an array, it will be
+     * placed in an array of length 1. In any case, all the array's elements will be checked for
+     * {@link String} objects. Any strings of length greater than {@link #MAX_STRING_LENGTH} will
+     * be reduced using the {@link #summarize} method.
+     *
+     * @param  arguments The object to check.
+     * @return {@code arguments} as an array.
+     */
+    private Object[] toArray(final Object arguments) {
+        Object[] array;
+        if (arguments instanceof Object[]) {
+            array = (Object[]) arguments;
+        } else {
+            array = new Object[] {arguments};
+        }
+        for (int i=0; i<array.length; i++) {
+            final Object element = array[i];
+            if (element instanceof CharSequence) {
+                final String s0;
+                if (element instanceof InternationalString) {
+                    s0 = ((InternationalString) element).toString(getFormatLocale());
+                } else {
+                    s0 = element.toString();
+                }
+                final String s1 = summarize(s0, MAX_STRING_LENGTH);
+                if (s0!=s1 && !s0.equals(s1)) {
+                    if (array == arguments) {
+                        array = new Object[array.length];
+                        System.arraycopy(arguments, 0, array, 0, array.length);
+                    }
+                    array[i] = s1;
+                }
+            } else if (element instanceof Throwable) {
+                String message = ((Throwable) element).getLocalizedMessage();
+                if (message == null) {
+                    message = Classes.getShortClassName(element);
+                }
+                array[i] = message;
+            } else if (element instanceof Class) {
+                array[i] = Classes.getShortName((Class<?>) element);
+            }
+        }
+        return array;
+    }
+
+    /**
+     * Gets a string for the given key from this resource bundle or one of its parents.
+     *
+     * @param  key The key for the desired string.
+     * @return The string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public final String getString(final int key) throws MissingResourceException {
+        return getString(String.valueOf(key));
+    }
+
+    /**
+     * Gets a string for the given key and formats it with the specified argument. The message is
+     * formatted using {@link MessageFormat}. Calling this method is approximately equivalent to
+     * calling:
+     *
+     * <blockquote><pre>
+     *   String pattern = getString(key);
+     *   Format f = new MessageFormat(pattern);
+     *   return f.format(arg0);
+     * </pre></blockquote>
+     *
+     * If {@code arg0} is not already an array, it will be placed into an array of length 1. Using
+     * {@link MessageFormat}, all occurrences of "{0}", "{1}", "{2}" in the resource string will be
+     * replaced by {@code arg0[0]}, {@code arg0[1]}, {@code arg0[2]}, etc.
+     *
+     * @param  key The key for the desired string.
+     * @param  arg0 A single object or an array of objects to be formatted and substituted.
+     * @return The string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     *
+     * @see #getString(String)
+     * @see #getString(int,Object,Object)
+     * @see #getString(int,Object,Object,Object)
+     * @see MessageFormat
+     */
+    public final String getString(final int key, final Object arg0) throws MissingResourceException {
+        final String pattern = getString(key);
+        final Object[] arguments = toArray(arg0);
+        synchronized (this) {
+            if (format == null) {
+                /*
+                 * Constructs a new MessageFormat for formatting the arguments.
+                 */
+                format = new MessageFormat(pattern, getFormatLocale());
+            } else if (key != lastKey) {
+                /*
+                 * Method MessageFormat.applyPattern(...) is costly! We will avoid
+                 * calling it again if the format already has the right pattern.
+                 */
+                format.applyPattern(pattern);
+                lastKey = key;
+            }
+            return format.format(arguments);
+        }
+    }
+
+    /**
+     * Gets a string for the given key and replaces all occurrences of "{0}",
+     * "{1}", with values of {@code arg0}, {@code arg1}, etc.
+     *
+     * @param  key The key for the desired string.
+     * @param  arg0 Value to substitute for "{0}".
+     * @param  arg1 Value to substitute for "{1}".
+     * @return The formatted string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public final String getString(final int    key,
+                                  final Object arg0,
+                                  final Object arg1) throws MissingResourceException
+    {
+        return getString(key, new Object[] {arg0, arg1});
+    }
+
+    /**
+     * Gets a string for the given key and replaces all occurrences of "{0}",
+     * "{1}", with values of {@code arg0}, {@code arg1}, etc.
+     *
+     * @param  key The key for the desired string.
+     * @param  arg0 Value to substitute for "{0}".
+     * @param  arg1 Value to substitute for "{1}".
+     * @param  arg2 Value to substitute for "{2}".
+     * @return The formatted string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public final String getString(final int    key,
+                                  final Object arg0,
+                                  final Object arg1,
+                                  final Object arg2) throws MissingResourceException
+    {
+        return getString(key, new Object[] {arg0, arg1, arg2});
+    }
+
+    /**
+     * Gets a string for the given key and replaces all occurrences of "{0}",
+     * "{1}", with values of {@code arg0}, {@code arg1}, etc.
+     *
+     * @param  key The key for the desired string.
+     * @param  arg0 Value to substitute for "{0}".
+     * @param  arg1 Value to substitute for "{1}".
+     * @param  arg2 Value to substitute for "{2}".
+     * @param  arg3 Value to substitute for "{3}".
+     * @return The formatted string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public final String getString(final int    key,
+                                  final Object arg0,
+                                  final Object arg1,
+                                  final Object arg2,
+                                  final Object arg3) throws MissingResourceException
+    {
+        return getString(key, new Object[] {arg0, arg1, arg2, arg3});
+    }
+
+    /**
+     * Gets a localized log record.
+     *
+     * @param  level The log record level.
+     * @param  key   The resource key.
+     * @return The log record.
+     */
+    public LogRecord getLogRecord(final Level level, final int key) {
+        return getLogRecord(level, key, null);
+    }
+
+    /**
+     * Gets a localized log record.
+     *
+     * @param  level The log record level.
+     * @param  key   The resource key.
+     * @param  arg0  The parameter for the log message, or {@code null}.
+     * @return The log record.
+     */
+    public LogRecord getLogRecord(final Level level, final int key,
+                                  final Object arg0)
+    {
+        final LogRecord record = new LogRecord(level, String.valueOf(key));
+        record.setResourceBundle(this);
+        if (arg0 != null) {
+            record.setParameters(toArray(arg0));
+        }
+        return record;
+    }
+
+    /**
+     * Gets a localized log record.
+     *
+     * @param  level The log record level.
+     * @param  key   The resource key.
+     * @param  arg0  The first parameter.
+     * @param  arg1  The second parameter.
+     * @return The log record.
+     */
+    public LogRecord getLogRecord(final Level level, final int key,
+                                  final Object arg0,
+                                  final Object arg1)
+    {
+        return getLogRecord(level, key, new Object[]{arg0, arg1});
+    }
+
+    /**
+     * Gets a localized log record.
+     *
+     * @param  level The log record level.
+     * @param  key   The resource key.
+     * @param  arg0  The first parameter.
+     * @param  arg1  The second parameter.
+     * @param  arg2  The third parameter.
+     * @return The log record.
+     */
+    public LogRecord getLogRecord(final Level level, final int key,
+                                  final Object arg0,
+                                  final Object arg1,
+                                  final Object arg2)
+    {
+        return getLogRecord(level, key, new Object[]{arg0, arg1, arg2});
+    }
+
+    /**
+     * Returns a string representation of this object.
+     * This method is for debugging purposes only.
+     */
+    @Override
+    public synchronized String toString() {
+        final StringBuilder buffer = new StringBuilder(Classes.getShortClassName(this));
+        buffer.append('[');
+        if (values != null) {
+            int count = 0;
+            for (int i=0; i<values.length; i++) {
+                if (values[i]!=null) count++;
+            }
+            buffer.append(count);
+            buffer.append(" values");
+        }
+        buffer.append(']');
+        return buffer.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/LazySet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/LazySet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/LazySet.java	(revision 28000)
@@ -0,0 +1,148 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources;
+
+import java.util.AbstractSet;
+import java.util.Iterator;
+
+
+/**
+ * An immutable set built from an iterator, which will be filled only when needed. This
+ * implementation do <strong>not</strong> check if all elements in the iterator are really
+ * unique; we assume that it was already verified by {@link javax.imageio.spi.ServiceRegistry}.
+ * This set is constructed by {@link org.geotools.referencing.FactoryFinder}.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/LazySet.java $
+ * @version $Id: LazySet.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public final class LazySet<E> extends AbstractSet<E> {
+    /**
+     * The iterator to use for filling this set.
+     */
+    private final Iterator<? extends E> iterator;
+
+    /**
+     * The elements in this set. This array will grown as needed.
+     */
+    private E[] elements;
+
+    /**
+     * The current size of this set. This size will increases as long as there is some elements
+     * remaining in the iterator. This is <strong>not</strong> the size returned by {@link #size()}.
+     */
+    private int size;
+
+    /**
+     * Construct a set to be filled using the specified iterator.
+     * Iteration in the given iterator will occurs only when needed.
+     */
+    @SuppressWarnings("unchecked")
+    public LazySet(final Iterator<? extends E> iterator) {
+        this.iterator = iterator;
+        elements = (E[]) new Object[4];
+    }
+
+    /**
+     * Add the next element from the iterator to this set. This method doesn't check
+     * if more element were available; the check must have been done before to invoke
+     * this method.
+     */
+    private void addNext() {
+        if (size >= elements.length) {
+            elements = XArray.resize(elements, size*2);
+        }
+        elements[size++] = iterator.next();
+    }
+
+    /**
+     * Returns an iterator over the elements contained in this set.
+     * This is not the same iterator than the one given to the constructor.
+     */
+    public Iterator<E> iterator() {
+        return new Iter();
+    }
+
+    /**
+     * Returns the number of elements in this set. Invoking this method
+     * force the set to immediately iterates through all remaining elements.
+     */
+    public int size() {
+        while (iterator.hasNext()) {
+            addNext();
+        }
+        return size;
+    }
+
+    /**
+     * Tests if this set has no elements.
+     */
+    @Override
+    public boolean isEmpty() {
+        return size==0 && !iterator.hasNext();
+    }
+
+    /**
+     * Returns {@code true} if an element exists at the given index.
+     * The element is not loaded immediately.
+     *
+     * <strong>NOTE: This method is for use by iterators only.</strong>
+     * It is not suited for more general usage since it doesn't check
+     * for negative index and for skipped elements.
+     */
+    final boolean exists(final int index) {
+        return index<size || iterator.hasNext();
+    }
+
+    /**
+     * Returns the element at the specified position in this set.
+     */
+    public E get(final int index) {
+        while (index >= size) {
+            if (!iterator.hasNext()) {
+                throw new IndexOutOfBoundsException(String.valueOf(index));
+            }
+            addNext();
+        }
+        return elements[index];
+    }
+
+    /**
+     * The iterator implementation for the {@linkplain LazySet lazy set}.
+     */
+    private final class Iter implements Iterator<E> {
+        /** Index of the next element to be returned. */
+        private int cursor;
+
+        /** Check if there is more elements. */
+        public boolean hasNext() {
+            return exists(cursor);
+        }
+
+        /** Returns the next element. */
+        public E next() {
+            return get(cursor++);
+        }
+
+        /** Always throws an exception, since {@link LazySet} are immutable. */
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/NIOUtilities.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/NIOUtilities.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/NIOUtilities.java	(revision 28000)
@@ -0,0 +1,269 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources;
+
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Level;
+
+import org.geotools.util.logging.Logging;
+
+
+/**
+ * Utility class for managing memory mapped buffers.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/NIOUtilities.java $
+ * @version $Id: NIOUtilities.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Andrea Aimes
+ */
+public final class NIOUtilities {
+    
+    /**
+     * The buffer cache, partitioned by buffer size and fully concurrent
+     */
+    static Map<Integer, Queue<Object>> cache = new ConcurrentHashMap<Integer, Queue<Object>>();
+    
+    static Map<Class, Method> cleanerMethodCache = new ConcurrentHashMap<Class, Method>();
+    
+    /**
+     * The maximum size of the hard reference cache (the soft one can be unbounded, the GC will
+     * regulate its size according to the memory pressure)
+     */
+    static int maxCacheSize = 2 * 1024 * 1024;
+    
+    /**
+     * The current hard cache size
+     */
+    static AtomicInteger hardCacheSize = new AtomicInteger(0);
+        
+    /**
+     * {@code true} if a warning has already been logged.
+     */
+    private static boolean warned = false;
+    
+    /**
+     * Wheter direct buffers usage is enabled, or not
+     */
+    private static boolean directBuffersEnabled = true;
+    
+    static {
+        String directBuffers = System.getProperty("geotools.nioutilities.direct", "true");
+        directBuffersEnabled = "TRUE".equalsIgnoreCase(directBuffers);
+    }
+
+    /**
+     * Do not allows instantiation of this class.
+     */
+    private NIOUtilities() {
+    }
+        
+    /**
+     * Allocates and returns a {@link ByteBuffer}. The buffer capacity will generally be greater than
+     * of two that can contain the specified limit, the buffer limit will be set at the specified
+     * value. The buffers are pooled, so remember to call {@link #clean(ByteBuffer, false)} to return
+     * the buffer to the pool.
+     * 
+     * @param limit
+     * @return
+     */
+    public static ByteBuffer allocate(int size) {
+        // look for a free cached buffer that has still not been garbage collected
+        Queue<Object> buffers = getBuffers(size);
+        Object sr = null;
+        while ((sr = buffers.poll()) != null) {
+            ByteBuffer buffer = null;
+            // what did we get, a soft or a hard reference?
+            if(sr instanceof BufferSoftReference) {
+                buffer = ((BufferSoftReference)sr).get();
+            } else {
+                // we're removing a hard reference from the cache, lower the usage figure
+                buffer = (ByteBuffer) sr;
+                hardCacheSize.addAndGet(-buffer.capacity());
+            }
+            // clean up the buffer and return it
+            if (buffer != null) {
+                buffer.clear();
+                return buffer;
+            }
+        }
+
+        // we could not find one, then allocated it
+        if(directBuffersEnabled) {
+            return ByteBuffer.allocateDirect(size);
+        } else {
+            return ByteBuffer.allocate(size);
+        }
+    }
+
+    /**
+     * Returns the buffer queue associated to the specified size
+     * @param size
+     * @return
+     */
+    private static Queue<Object> getBuffers(int size) {
+        Queue<Object> result = cache.get(size);
+        if (result == null) {
+            // this is the only synchronized bit, we don't want multiple queues
+            // to be created. result == null will be true only at the application startup
+            // for the common byte buffer sizes
+            synchronized (cache) {
+                result = cache.get(size);
+                if (result == null) {
+                    result = new ConcurrentLinkedQueue<Object>();
+                    cache.put(size, result);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Depending on the type of buffer different cleanup action will be taken:
+     * <ul><li>if the buffer is memory mapped (as per the specified parameter) the effect is the same as {@link #clean(ByteBuffer)}</li>
+     * <li>if the buffer is not memory mapped it will be returned to the buffer cache</li>
+     * </ul>
+     * @param buffer
+     * @return
+     */
+    public static boolean clean(final ByteBuffer buffer, boolean memoryMapped) {
+        if(memoryMapped) {
+            return clean(buffer);
+        } else {
+            if(returnToCache(buffer)) {
+                return true;
+            } else {
+                return clean(buffer);
+            }
+        }
+    }
+
+    /**
+     * Really closes a {@code MappedByteBuffer} without the need to wait for garbage collection. Any
+     * problems with closing a buffer on Windows (the problem child in this case) will be logged as
+     * {@code SEVERE} to the logger of the package name. To force logging of errors, set the System
+     * property "org.geotools.io.debugBuffer" to "true".
+     * 
+     * @param buffer The buffer to close.
+     * 
+     * @return true if the operation was successful, false otherwise.
+     * 
+     * @see java.nio.MappedByteBuffer
+     */
+    public static boolean clean(final ByteBuffer buffer) {
+        if(buffer == null || !buffer.isDirect()) {
+            return true;
+        }
+        
+        Boolean b = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+            public Boolean run() {
+                Boolean success = Boolean.FALSE;
+                try {
+                    Method getCleanerMethod = getCleanerMethod(buffer);
+                    if(getCleanerMethod != null) {
+                        Object cleaner = getCleanerMethod.invoke(buffer, (Object[]) null);
+                        if(cleaner != null) {
+	                        Method clean = cleaner.getClass().getMethod("clean", (Class[]) null);
+	                        clean.invoke(cleaner, (Object[]) null);
+	                        success = Boolean.TRUE;
+                        }
+                    }
+                } catch (Exception e) {
+                    // This really is a show stopper on windows
+                    if (isLoggable()) {
+                        log(e, buffer);
+                    }
+                }
+                return success;
+            }
+        });
+        return b.booleanValue();
+    }
+    
+    static Method getCleanerMethod(final ByteBuffer buffer) throws NoSuchMethodException {
+        Method result = cleanerMethodCache.get(buffer.getClass());
+        if(result == null) {
+            result = buffer.getClass().getMethod("cleaner", (Class[]) null);
+            result.setAccessible(true);
+            cleanerMethodCache.put(buffer.getClass(), result);
+        }
+        return result;
+    }
+
+    public static boolean returnToCache(final ByteBuffer buffer) {
+        // is the buffer cacheable? There are some blessed sizes we use over and over, for the
+        // rest buffer only powers of two
+        final int capacity = buffer.capacity();
+        if(capacity != 100 && capacity != 13 && capacity != 16000) {
+            int size = (int) Math.pow(2, Math.ceil(Math.log(capacity) / Math.log(2)));
+            if(size != capacity) {
+                return false;
+            }
+        }
+        
+        // clean up the buffer -> we need to zero out its contents as if it was just
+        // created or some shapefile tests will start failing
+        buffer.clear();
+        buffer.order(ByteOrder.BIG_ENDIAN);
+        
+        // set the buffer back in the cache, either as a soft reference or as
+        // a hard one depending on whether we're past the hard cache or not
+        Queue<Object> buffers = cache.get(capacity);
+        if(hardCacheSize.get() > maxCacheSize) {
+            buffers.add(new BufferSoftReference(buffer));
+        } else {
+            hardCacheSize.addAndGet(capacity);
+            buffers.add(buffer);
+        }
+        return true;
+    }
+
+    /**
+     * Checks if a warning message should be logged.
+     */
+    private static synchronized boolean isLoggable() {
+        try {
+            return !warned && (
+                    Boolean.getBoolean("org.geotools.io.debugBuffer") ||
+                    System.getProperty("os.name").indexOf("Windows") >= 0 );
+        } catch (SecurityException exception) {
+            // The utilities may be running in an Applet, in which case we
+            // can't read properties. Assumes we are not in debugging mode.
+            return false;
+        }
+    }
+
+    /**
+     * Logs a warning message.
+     */
+    private static synchronized void log(final Exception e, final ByteBuffer buffer) {
+        warned = true;
+        String message = "Error attempting to close a mapped byte buffer : " + buffer.getClass().getName()
+                       + "\n JVM : " + System.getProperty("java.version")
+                       + ' '         + System.getProperty("java.vendor");
+        Logging.getLogger("org.geotools.io").log(Level.SEVERE, message, e);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/OptionalDependencies.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/OptionalDependencies.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/OptionalDependencies.java	(revision 28000)
@@ -0,0 +1,97 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources;
+
+import java.lang.reflect.Constructor;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreeNode;
+
+
+/**
+ * Bridges to optional dependencies (especially {@code widget-swing} module).
+ *
+ * @todo Most methods of this class need to move as a {@code Trees} class in a {@code util} module.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/OptionalDependencies.java $
+ * @version $Id: OptionalDependencies.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public final class OptionalDependencies {
+    /**
+     * Constructor for {@link org.geotools.gui.swing.tree.NamedTreeNode}.
+     */
+    private static Constructor treeNodeConstructor;
+
+    /**
+     * Set to {@code true} if {@link #treeNodeConstructor} can't be obtained.
+     */
+    private static boolean noNamedTreeNode = false;
+
+    /**
+     * Interdit la création d'objets de cette classe.
+     */
+    private OptionalDependencies() {
+    }
+
+    /**
+     * Creates an initially empty tree node.
+     *
+     * @param name   The value to be returned by {@link TreeNode#toString}.
+     * @param object The user object to be returned by the tree node. May
+     *               or may not be the same than {@code name}.
+     * @param allowsChildren if children are allowed.
+     */
+    public static DefaultMutableTreeNode createTreeNode(final String name,
+                                                        final Object object,
+                                                        final boolean allowsChildren)
+    {
+        /*
+         * If the "modules/extension/swing-widgets" JAR is in the classpath,  then create an
+         * instance of NamedTreeNode (see org.geotools.swing.tree javadoc for an explanation
+         * about why the NamedTreeNode workaround is needed).  We use reflection because the
+         * swing-widgets module is optional,  so we fallback on the standard Swing object if
+         * we can't create an instance of NamedTreeNode.   We will attempt to use reflection
+         * only once in order to avoid a overhead if the swing-widgets module is not available.
+         *
+         * The swing-widgets module contains a "NamedTreeNodeTest" for making sure that the
+         * NamedTreeNode instances are properly created.
+         *
+         * Note: No need to sychronize; this is not a big deal if we make the attempt twice.
+         */
+        if (!noNamedTreeNode) try {
+            if (treeNodeConstructor == null) {
+                treeNodeConstructor = Class.forName("org.geotools.gui.swing.tree.NamedTreeNode").
+                        getConstructor(new Class[] {String.class, Object.class, Boolean.TYPE});
+            }
+            return (DefaultMutableTreeNode) treeNodeConstructor.newInstance(
+                    new Object[] {name, object, Boolean.valueOf(allowsChildren)});
+        } catch (Exception e) {
+            /*
+             * There is a large amount of checked and unchecked exceptions that the above code
+             * may thrown. We catch all of them because a reasonable fallback exists (creation
+             * of the default Swing object below).  Note that none of the unchecked exceptions
+             * (IllegalArgumentException, NullPointerException...) should occurs, except maybe
+             * SecurityException. Maybe we could let the unchecked exceptions propagate...
+             */
+            noNamedTreeNode = true;
+        }
+        return new DefaultMutableTreeNode(name, allowsChildren);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/UnmodifiableArrayList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/UnmodifiableArrayList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/UnmodifiableArrayList.java	(revision 28000)
@@ -0,0 +1,193 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources;
+
+import java.io.Serializable;
+import java.util.AbstractList;
+import org.geotools.util.CheckedCollection;
+
+
+/**
+ * An unmodifiable view of an array. Invoking
+ *
+ * <blockquote><code>
+ * UnmodifiableArrayList.wrap(array);
+ * </code></blockquote>
+ *
+ * is equivalent to
+ *
+ * <blockquote><code>
+ * {@linkplain Collections#unmodifiableList Collections.unmodifiableList}({@linkplain
+ * Arrays#asList Arrays.asList}(array)));
+ * </code></blockquote>
+ *
+ * But this class provides a very slight performance improvement since it uses one less level
+ * of indirection.
+ *
+ * @param <E> The type of elements in the list.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/UnmodifiableArrayList.java $
+ * @version $Id: UnmodifiableArrayList.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class UnmodifiableArrayList<E> extends AbstractList<E>
+        implements CheckedCollection<E>, Serializable
+{
+    /**
+     * For compatibility with different versions.
+     */
+    private static final long serialVersionUID = -3605810209653785967L;
+
+    /**
+     * The wrapped array.
+     */
+    private final E[] array;
+
+    /**
+     * Creates a new instance of an array list. A direct reference to the given array is retained
+     * (i.e. the array is <strong>not</strong> cloned). Consequently the given array should not
+     * be modified after construction if this list is intented to be immutable.
+     * <p>
+     * This constructor is for subclassing only. Users should invoke the {@link #wrap} static
+     * factory method, which provides more convenient handling of parameterized types.
+     *
+     * @param array The array to wrap.
+     */
+    protected UnmodifiableArrayList(final E[] array) {
+        this.array = array;
+    }
+
+    /**
+     * Creates a new instance of an array list. A direct reference to the given array is retained
+     * (i.e. the array is <strong>not</strong> cloned). Consequently the given array should not
+     * be modified after construction if this list is intented to be immutable.
+     *
+     * @param  <E> The type of elements in the list.
+     * @param  array The array to wrap.
+     * @return The given array wrapped in an unmodifiable list.
+     *
+     * @since 2.5
+     */
+    public static <E> UnmodifiableArrayList<E> wrap(final E[] array) {
+        return new UnmodifiableArrayList<E>(array);
+    }
+
+    /**
+     * Returns the element type of the wrapped array.
+     *
+     * @return The type of elements in the list.
+     */
+    @SuppressWarnings("unchecked") // Safe if this instance was created safely with wrap(E[]).
+    public Class<E> getElementType() {
+        return (Class) array.getClass().getComponentType();
+    }
+
+    /**
+     * Returns the list size.
+     */
+    public int size() {
+        return array.length;
+    }
+
+    /**
+     * Returns the element at the specified index.
+     */
+    public E get(final int index) {
+        return array[index];
+    }
+
+    /**
+     * Returns the index in this list of the first occurence of the specified
+     * element, or -1 if the list does not contain this element. This method
+     * is overridden only for performance reason (the default implementation
+     * would work as well).
+     *
+     * @param object The element to search for.
+     */
+    @Override
+    public int indexOf(final Object object) {
+        if (object == null) {
+            for (int i=0; i<array.length; i++) {
+                if (array[i] == null) {
+                    return i;
+                }
+            }
+        } else {
+            for (int i=0; i<array.length; i++) {
+                if (object.equals(array[i])) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Returns the index in this list of the last occurence of the specified
+     * element, or -1 if the list does not contain this element. This method
+     * is overridden only for performance reason (the default implementation
+     * would work as well).
+     *
+     * @param object The element to searcch for.
+     */
+    @Override
+    public int lastIndexOf(final Object object) {
+        int i = array.length;
+        if (object == null) {
+            while (--i >= 0) {
+                if (array[i] == null) {
+                    break;
+                }
+            }
+        } else {
+            while (--i >= 0) {
+                if (object.equals(array[i])) {
+                    break;
+                }
+            }
+        }
+        return i;
+    }
+
+    /**
+     * Returns {@code true} if this collection contains the specified element.
+     * This method is overridden only for performance reason (the default implementation
+     * would work as well).
+     *
+     * @param object The element to check for existence.
+     */
+    @Override
+    public boolean contains(final Object object) {
+        int i = array.length;
+        if (object == null) {
+            while (--i >= 0) {
+                if (array[i] == null) {
+                    return true;
+                }
+            }
+        } else {
+            while (--i >= 0) {
+                if (object.equals(array[i])) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/XArray.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/XArray.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/XArray.java	(revision 28000)
@@ -0,0 +1,197 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+
+
+/**
+ * Simple operations on arrays. This class provides a central place for
+ * inserting and deleting elements in an array, as well as resizing the array.
+ * This class may be removed if JavaSoft provide some language construct
+ * functionally equivalent to C/C++'s {@code realloc}.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/XArray.java $
+ * @version $Id: XArray.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @todo Replace all {@code resize} methods by {@code Arrays.copyOf} when we will be allowed to
+ *       compile for Java 6.
+ */
+public final class XArray {
+    /**
+     * All object constructions of this class are forbidden.
+     */
+    private XArray() {
+    }
+
+    /**
+     * Returns an array containing the same elements as the given {@code array} but with the
+     * specified {@code length}, truncating or padding with {@code null} if necessary.
+     * <ul>
+     *   <li><p>If the given {@code length} is longer than the length of the given {@code array},
+     *       then the returned array will contain all the elements of {@code array} at index
+     *       <var>i</var> &lt; {@code array.length}. Elements at index <var>i</var> &gt;=
+     *       {@code array.length} are initialized to {@code null}.</p></li>
+     *
+     *   <li><p>If the given {@code length} is shorter than the length of the given {@code array},
+     *       then the returned array will contain only the elements of {@code array} at index
+     *       <var>i</var> &lt; {@code length}. Remainding elements are not copied.</p></li>
+     *
+     *   <li><p>If the given {@code length} is equals to the length of the given {@code array},
+     *       then {@code array} is returned unchanged. <strong>No copy</strong> is performed.
+     *       This behavior is what make this method different than {@link Arrays#copyOf}.</p></li>
+     *
+     * @param  <T> The array elements.
+     * @param  array  Array to copy.
+     * @param  length Length of the desired array.
+     * @return A new array of the requested length, or {@code array} if the original
+     *         array already have the requested length.
+     *
+     * @see Arrays#copyOf(Object[],int)
+     */
+    private static <T> T doResize(final T array, final int length) {
+        final int current = array == null ? 0 : Array.getLength(array);
+        if (current != length) {
+            @SuppressWarnings("unchecked")
+            final T newArray = (T) Array.newInstance(array.getClass().getComponentType(), length);
+            System.arraycopy(array, 0, newArray, 0, Math.min(current, length));
+            return newArray;
+        } else {
+            return array;
+        }
+    }
+
+    /**
+     * Returns an array containing the same elements as the given {@code array} but with the
+     * specified {@code length}, truncating or padding with {@code null} if necessary.
+     * <ul>
+     *   <li><p>If the given {@code length} is longer than the length of the given {@code array},
+     *       then the returned array will contain all the elements of {@code array} at index
+     *       <var>i</var> &lt; {@code array.length}. Elements at index <var>i</var> &gt;=
+     *       {@code array.length} are initialized to {@code null}.</p></li>
+     *
+     *   <li><p>If the given {@code length} is shorter than the length of the given {@code array},
+     *       then the returned array will contain only the elements of {@code array} at index
+     *       <var>i</var> &lt; {@code length}. Remainding elements are not copied.</p></li>
+     *
+     *   <li><p>If the given {@code length} is equals to the length of the given {@code array},
+     *       then {@code array} is returned unchanged. <strong>No copy</strong> is performed.
+     *       This behavior is what make this method different than {@link Arrays#copyOf}.</p></li>
+     *
+     * @param  <E> The array elements.
+     * @param  array  Array to copy.
+     * @param  length Length of the desired array.
+     * @return A new array of the requested length, or {@code array} if the original
+     *         array already have the requested length.
+     *
+     * @see Arrays#copyOf(Object[],int)
+     */
+    public static <E> E[] resize(final E[] array, final int length) {
+        return doResize(array, length);
+    }
+
+    /**
+     * Returns an array containing the same elements as the given {@code array} but
+     * specified {@code length}, truncating or padding with zeros if necessary.
+     *
+     * @param  array  Array to copy.
+     * @param  length Length of the desired array.
+     * @return A new array of the requested length, or {@code array} if the original
+     *         array already have the requested length.
+     */
+    public static int[] resize(final int[] array, final int length) {
+        return doResize(array, length);
+    }
+
+    /**
+     * Removes elements from the middle of an array.
+     *
+     * @param <T>     The type of array elements.
+     * @param array   Array from which to remove elements.
+     * @param index   Index of the first element to remove from the given {@code array}.
+     * @param length  Number of elements to remove.
+     * @return        Array with the same elements than the given {@code array} except for the
+     *                removed elements, or {@code array} if {@code length} is 0.
+     */
+    private static <T> T doRemove(final T array, final int index, final int length) {
+        if (length == 0) {
+            return array;
+        }
+        int arrayLength = Array.getLength(array);
+        @SuppressWarnings("unchecked")
+        final T newArray = (T) Array.newInstance(array.getClass().getComponentType(), arrayLength -= length);
+        System.arraycopy(array, 0,            newArray, 0,                 index);
+        System.arraycopy(array, index+length, newArray, index, arrayLength-index);
+        return newArray;
+    }
+
+    /**
+     * Removes elements from the middle of an array.
+     *
+     * @param <E>     The type of array elements.
+     * @param array   Array from which to remove elements.
+     * @param index   Index of the first element to remove from the given {@code array}.
+     * @param length  Number of elements to remove.
+     * @return        Array with the same elements than the given {@code array} except for the
+     *                removed elements, or {@code array} if {@code length} is 0.
+     */
+    public static <E> E[] remove(final E[] array, final int index, final int length) {
+        return doRemove(array, index, length);
+    }
+
+    /**
+     * Inserts spaces into the middle of an array. These "spaces" will be made up of elements
+     * initialized to {@code null}.
+     *
+     * @param array   Array in which to insert spaces.
+     * @param index   Index where the first space should be inserted. All {@code array} elements
+     *                having an index equal to or higher than {@code index} will be moved forward.
+     * @param length  Number of spaces to insert.
+     * @return        Array containing the {@code array} elements with the additional space
+     *                inserted, or {@code array} if {@code length} is 0.
+     */
+    private static <T> T doInsert(final T array, final int index, final int length) {
+        if (length == 0) {
+            return array;
+        }
+        final int arrayLength = Array.getLength(array);
+        @SuppressWarnings("unchecked")
+        final T newArray = (T) Array.newInstance(array.getClass().getComponentType(), arrayLength + length);
+        System.arraycopy(array, 0,     newArray, 0,            index            );
+        System.arraycopy(array, index, newArray, index+length, arrayLength-index);
+        return newArray;
+    }
+
+    /**
+     * Inserts spaces into the middle of an array. These "spaces" will be made up of elements
+     * initialized to {@code null}.
+     *
+     * @param array   Array in which to insert spaces.
+     * @param index   Index where the first space should be inserted. All {@code array} elements
+     *                having an index equal to or higher than {@code index} will be moved forward.
+     * @param length  Number of spaces to insert.
+     * @return        Array containing the {@code array} elements with the additional space
+     *                inserted, or {@code array} if {@code length} is 0.
+     */
+    public static <E> E[] insert(final E[] array, final int index, final int length) {
+        return doInsert(array, index, length);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/XMath.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/XMath.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/XMath.java	(revision 28000)
@@ -0,0 +1,62 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources;
+
+import java.text.ChoiceFormat;
+
+
+/**
+ * Simple mathematical functions.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/XMath.java $
+ * @version $Id: XMath.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public final class XMath {
+
+    /**
+     * Do not allow instantiation of this class.
+     */
+    private XMath() {
+    }
+
+    /**
+     * Finds the least double greater than <var>f</var>.
+     * If {@code NaN}, returns same value.
+     *
+     * @see java.text.ChoiceFormat#nextDouble
+     *
+     * @todo Remove this method when we will be allowed to use Java 6.
+     */
+    public static double next(final double f) {
+        return ChoiceFormat.nextDouble(f);
+    }
+
+    /**
+     * Finds the greatest double less than <var>f</var>.
+     * If {@code NaN}, returns same value.
+     *
+     * @see java.text.ChoiceFormat#previousDouble
+     *
+     * @todo Remove this method when we will be allowed to use Java 6.
+     */
+    public static double previous(final double f) {
+        return ChoiceFormat.previousDouble(f);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/geometry/ShapeUtilities.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/geometry/ShapeUtilities.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/geometry/ShapeUtilities.java	(revision 28000)
@@ -0,0 +1,190 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources.geometry;
+
+import static java.lang.Math.abs;
+import static java.lang.Math.hypot;
+
+import java.awt.Shape;
+import java.awt.geom.CubicCurve2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.QuadCurve2D;
+
+
+/**
+ * Static utilities methods. Those methods operate on geometric
+ * shapes from the {@code java.awt.geom} package.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/referencing/src/main/java/org/geotools/resources/geometry/ShapeUtilities.java $
+ * @version $Id: ShapeUtilities.java 37299 2011-05-25 05:21:24Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public final class ShapeUtilities {
+    /**
+     * Valeur limite pour détecter si des points sont
+     * colinéaires ou si des coordonnées sont identiques.
+     */
+    private static final double EPS = 1E-6;
+
+    /**
+     * Constante pour les calculs de paraboles. Cette constante indique que l'axe des
+     * <var>x</var> de la parabole doit être parallèle à la droite joignant les points
+     * P0 et P2.
+     */
+    public static final int PARALLEL = 0;
+
+    /**
+     * Constante pour les calculs de paraboles. Cette constante indique que l'axe des
+     * <var>x</var> de la parabole doit être horizontale, quelle que soit la pente de
+     * la droite joignant les points P0 et P2.
+     */
+    public static final int HORIZONTAL = 1;
+
+    /**
+     * Interdit la création d'objets de cette classe.
+     */
+    private ShapeUtilities() {
+    }
+
+    /**
+     * Retourne le point de contrôle d'une courbe quadratique passant par les trois points spécifiés.
+     * Il peut exister une infinité de courbes quadratiques passant par trois points. On peut voir
+     * les choses en disant qu'une courbe quadratique correspond à une parabole produite par une
+     * équation de la forme <code>y=ax²+bx+c</code>, mais que l'axe des <var>x</var> de cette
+     * équation n'est pas nécessairement horizontal. La direction de cet axe des <var>x</var> dépend
+     * du paramètre {@code orientation} spécifié à cette méthode. La valeur {@link #HORIZONTAL}
+     * signifie que l'axe des <var>x</var> de la parabole sera toujours horizontal. La courbe
+     * quadratique produite ressemblera alors à une parabole classique telle qu'on en voit dans les
+     * ouvrages de mathématiques élémentaires. La valeur {@link #PARALLEL} indique plutôt que l'axe
+     * des <var>x</var> de la parabole doit être parallèle à la droite joignant les points
+     * {@code (x0,y0)} et {@code (x2,y2)}. Ce dernier type produira le même résultat que
+     * {@link #HORIZONTAL} si {@code y0==y2}.
+     *
+     * @param  x0 <var>x</var> value of the first  point.
+     * @param  y0 <var>y</var> value of the first  point.
+     * @param  x1 <var>x</var> value of the second point.
+     * @param  y1 <var>y</var> value of the second point.
+     * @param  x2 <var>x</var> value of the third  point.
+     * @param  y2 <var>y</var> value of the third  point.
+     * @param  orientation Orientation de l'axe des <var>x</var> de la parabole: {@link #PARALLEL}
+     *         ou {@link #HORIZONTAL}.
+     * @param  dest Where to store the control point.
+     * @return Le point de contrôle d'une courbe quadratique passant par les trois points spécifiés.
+     *         La courbe commencera au point {@code (x0,y0)} et se terminera au point {@code (x2,y2)}.
+     *         Si deux points ont des coordonnées presque identiques, ou si les trois points sont
+     *         colinéaires, alors cette méthode retourne {@code null}.
+     * @throws IllegalArgumentException si l'argument {@code orientation} n'est pas une des
+     *         constantes valides.
+     */
+    public static Point2D parabolicControlPoint(final double x0, final double y0,
+                                                      double x1,       double y1,
+                                                      double x2,       double y2,
+                                                final int orientation, final Point2D dest)
+        throws IllegalArgumentException
+    {
+        /*
+         * Applique une translation de façon à ce que (x0,y0)
+         * devienne l'origine du système d'axes. Il ne faudra
+         * plus utiliser (x0,y0) avant la fin de ce code.
+         */
+        x1 -= x0;
+        y1 -= y0;
+        x2 -= x0;
+        y2 -= y0;
+        switch (orientation) {
+            case PARALLEL: {
+                /*
+                 * Applique une rotation de façon à ce que (x2,y2)
+                 * tombe sur l'axe des x, c'est-à-dire que y2=0.
+                 */
+                final double rx2 = x2;
+                final double ry2 = y2;
+                x2 = hypot(x2,y2);
+                y2 = (x1*rx2 + y1*ry2) / x2; // use 'y2' as a temporary variable for 'x1'
+                y1 = (y1*rx2 - x1*ry2) / x2;
+                x1 = y2;
+                y2 = 0;
+                /*
+                 * Calcule maintenant les coordonnées du point
+                 * de contrôle selon le nouveau système d'axes.
+                 */
+                final double x = 0.5;                       // Really "x/x2"
+                final double y = (y1*x*x2) / (x1*(x2-x1));  // Really "y/y2"
+                final double check = abs(y);
+                if (!(check <= 1/EPS)) return null; // Deux points ont les mêmes coordonnées.
+                if (!(check >=   EPS)) return null; // Les trois points sont colinéaires.
+                /*
+                 * Applique une rotation inverse puis une translation pour
+                 * ramener le système d'axe dans sa position d'origine.
+                 */
+                x1 = (x*rx2 - y*ry2) + x0;
+                y1 = (y*rx2 + x*ry2) + y0;
+                break;
+            }
+            case HORIZONTAL: {
+                final double a = (y2 - y1*x2/x1) / (x2-x1); // Really "a*x2"
+                final double check = abs(a);
+                if (!(check <= 1/EPS)) return null; // Deux points ont les mêmes coordonnées.
+                if (!(check >=   EPS)) return null; // Les trois points sont colinéaires.
+                final double b = y2/x2 - a;
+                x1 = (1 + b/(2*a))*x2 - y2/(2*a);
+                y1 = y0 + b*x1;
+                x1 += x0;
+                break;
+            }
+            default: throw new IllegalArgumentException();
+        }
+        if (dest != null) {
+            dest.setLocation(x1,y1);
+            return dest;
+        } else {
+            return new Point2D.Double(x1,y1);
+        }
+    }
+
+    /**
+     * Tente de remplacer la forme géométrique {@code path} par une des formes standards
+     * de Java2D. Par exemple, si {@code path} ne contient qu'un simple segment de droite
+     * ou une courbe quadratique, alors cette méthode retournera un objet {@link Line2D} ou
+     * {@link QuadCurve2D} respectivement.
+     *
+     * @param  path Forme géométrique à simplifier (généralement un objet {@link GeneralPath}).
+     * @return Forme géométrique standard, ou {@code path} si aucun remplacement n'est proposé.
+     */
+    public static Shape toPrimitive(final Shape path) {
+        final float[] buffer = new float[6];
+        final PathIterator it = path.getPathIterator(null);
+        if (!it.isDone() && it.currentSegment(buffer) == PathIterator.SEG_MOVETO && !it.isDone()) {
+            final float x1 = buffer[0];
+            final float y1 = buffer[1];
+            final int code = it.currentSegment(buffer);
+            if (it.isDone()) {
+                switch (code) {
+                    case PathIterator.SEG_LINETO:  return new       Line2D.Float(x1,y1, buffer[0],buffer[1]);
+                    case PathIterator.SEG_QUADTO:  return new  QuadCurve2D.Float(x1,y1, buffer[0],buffer[1], buffer[2],buffer[3]);
+                    case PathIterator.SEG_CUBICTO: return new CubicCurve2D.Float(x1,y1, buffer[0],buffer[1], buffer[2],buffer[3], buffer[4],buffer[5]);
+                }
+            }
+        }
+        return path;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/geometry/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/geometry/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/geometry/package.html	(revision 28000)
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.resources.geometry</TITLE>
+  </HEAD>
+  <BODY>
+    A set of helper classes for geometry handling in the Geotools implementation;
+
+    <STRONG>Do not use!</STRONG>.
+
+    This package is for internal use only. Classes in this package may change
+    in incompatible ways in any future version.
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/ErrorKeys.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/ErrorKeys.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/ErrorKeys.java	(revision 28000)
@@ -0,0 +1,1074 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *    
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *    
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *    
+ *    THIS IS AN AUTOMATICALLY GENERATED FILE. DO NOT EDIT!
+ *    Generated with: org.geotools.resources.IndexedResourceCompiler
+ */
+package org.geotools.resources.i18n;
+
+
+/**
+ * Resource keys. This class is used when compiling sources, but
+ * no dependencies to {@code ResourceKeys} should appear in any
+ * resulting class files.  Since Java compiler inlines final integer
+ * values, using long identifiers will not bloat constant pools of
+ * classes compiled against the interface, provided that no class
+ * implements this interface.
+ *
+ * @see org.geotools.resources.IndexedResourceBundle
+ * @see org.geotools.resources.IndexedResourceCompiler
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/i18n/ErrorKeys.java $
+ */
+public final class ErrorKeys {
+    private ErrorKeys() {
+    }
+
+    /**
+     * Ambiguous axis length.
+     */
+    public static final int AMBIGIOUS_AXIS_LENGTH = 3;
+
+    /**
+     * Angle {0} is too high.
+     */
+    public static final int ANGLE_OVERFLOW_$1 = 4;
+
+    /**
+     * Latitudes {0} and {1} are opposite.
+     */
+    public static final int ANTIPODE_LATITUDES_$2 = 5;
+
+    /**
+     * Azimuth {0} is out of range (±180°).
+     */
+    public static final int AZIMUTH_OUT_OF_RANGE_$1 = 6;
+
+    /**
+     * Band number {0} is not valid.
+     */
+    public static final int BAD_BAND_NUMBER_$1 = 7;
+
+    /**
+     * Coefficient {0}={1} can't be NaN or infinity.
+     */
+    public static final int BAD_COEFFICIENT_$2 = 8;
+
+    /**
+     * Illegal coordinate: {0}
+     */
+    public static final int BAD_COORDINATE_$1 = 0;
+
+    /**
+     * Bad entry
+     */
+    public static final int BAD_ENTRY = 1;
+
+    /**
+     * Illegal grid range [{1} .. {2}] for dimension {0}.
+     */
+    public static final int BAD_GRID_RANGE_$3 = 9;
+
+    /**
+     * Illegal data at line {1} in file "{0}".
+     */
+    public static final int BAD_LINE_IN_FILE_$2 = 10;
+
+    /**
+     * Bad local: {0}
+     */
+    public static final int BAD_LOCALE_$1 = 11;
+
+    /**
+     * Parameter "{0}" can't have value "{1}".
+     */
+    public static final int BAD_PARAMETER_$2 = 12;
+
+    /**
+     * Parameter "{0}" can't be of type '{1}'.
+     */
+    public static final int BAD_PARAMETER_TYPE_$2 = 13;
+
+    /**
+     * Range [{0} .. {1}] is not valid.
+     */
+    public static final int BAD_RANGE_$2 = 14;
+
+    /**
+     * Empty or invalid rectangle: {0}
+     */
+    public static final int BAD_RECTANGLE_$1 = 2;
+
+    /**
+     * Illegal transform of type "{0}".
+     */
+    public static final int BAD_TRANSFORM_$1 = 15;
+
+    /**
+     * Multiplication or division of "{0}" by "{1}" not allowed.
+     */
+    public static final int BAD_UNIT_OPERATION_$2 = 16;
+
+    /**
+     * Unit "{1}" can't be raised to power {0}.
+     */
+    public static final int BAD_UNIT_POWER_$2 = 17;
+
+    /**
+     * Bursa wolf parameters required.
+     */
+    public static final int BURSA_WOLF_PARAMETERS_REQUIRED = 18;
+
+    /**
+     * Can't compute derivative.
+     */
+    public static final int CANT_COMPUTE_DERIVATIVE = 19;
+
+    /**
+     * Can't concatenate transforms "{0}" and "{1}".
+     */
+    public static final int CANT_CONCATENATE_TRANSFORMS_$2 = 20;
+
+    /**
+     * Failed to connect to the {0} database.
+     */
+    public static final int CANT_CONNECT_DATABASE_$1 = 21;
+
+    /**
+     * Can't convert value from type '{0}'.
+     */
+    public static final int CANT_CONVERT_FROM_TYPE_$1 = 22;
+
+    /**
+     * Can't create a factory of type "{0}".
+     */
+    public static final int CANT_CREATE_FACTORY_$1 = 23;
+
+    /**
+     * Can't create object of type '{0}' from a text.
+     */
+    public static final int CANT_CREATE_FROM_TEXT_$1 = 24;
+
+    /**
+     * An error occurred while cropping.
+     */
+    public static final int CANT_CROP = 25;
+
+    /**
+     * Can't evaluate a value for coordinate ({0}).
+     */
+    public static final int CANT_EVALUATE_$1 = 26;
+
+    /**
+     * Failed to get the data source for name "{0}".
+     */
+    public static final int CANT_GET_DATASOURCE_$1 = 27;
+
+    /**
+     * Can't read file "{0}".
+     */
+    public static final int CANT_READ_$1 = 28;
+
+    /**
+     * Can't reduce "{0}" to a two-dimensional coordinate system.
+     */
+    public static final int CANT_REDUCE_TO_TWO_DIMENSIONS_$1 = 29;
+
+    /**
+     * Can't reproject grid coverage "{0}".
+     */
+    public static final int CANT_REPROJECT_$1 = 30;
+
+    /**
+     * Can't separate CRS "{0}".
+     */
+    public static final int CANT_SEPARATE_CRS_$1 = 31;
+
+    /**
+     * Can't set a value to the parameter "{0}".
+     */
+    public static final int CANT_SET_PARAMETER_VALUE_$1 = 32;
+
+    /**
+     * Can't transform envelope.
+     */
+    public static final int CANT_TRANSFORM_ENVELOPE = 33;
+
+    /**
+     * Can't transform some points that should be valid.
+     */
+    public static final int CANT_TRANSFORM_VALID_POINTS = 34;
+
+    /**
+     * Graphic "{0}" is owned by an other canvas.
+     */
+    public static final int CANVAS_NOT_OWNER_$1 = 35;
+
+    /**
+     * Axis {0} and {1} are colinear.
+     */
+    public static final int COLINEAR_AXIS_$2 = 36;
+
+    /**
+     * Coverage returned by '{0}' is already the view of coverage "{1}".
+     */
+    public static final int COVERAGE_ALREADY_BOUND_$2 = 37;
+
+    /**
+     * Database failure while creating a '{0}' object for code "{1}".
+     */
+    public static final int DATABASE_FAILURE_$2 = 38;
+
+    /**
+     * Date {0} is outside the range of available data.
+     */
+    public static final int DATE_OUTSIDE_COVERAGE_$1 = 39;
+
+    /**
+     * The destination has not been set.
+     */
+    public static final int DESTINATION_NOT_SET = 40;
+
+    /**
+     * The direction has not been set.
+     */
+    public static final int DIRECTION_NOT_SET = 41;
+
+    /**
+     * The factory has been disposed.
+     */
+    public static final int DISPOSED_FACTORY = 42;
+
+    /**
+     * The distance {0} is out of range ({1} to {2} {3})
+     */
+    public static final int DISTANCE_OUT_OF_RANGE_$4 = 43;
+
+    /**
+     * Duplicated values for code "{0}".
+     */
+    public static final int DUPLICATED_VALUES_$1 = 44;
+
+    /**
+     * Elliptical projection not supported.
+     */
+    public static final int ELLIPTICAL_NOT_SUPPORTED = 45;
+
+    /**
+     * The array should contains at least one element.
+     */
+    public static final int EMPTY_ARRAY = 46;
+
+    /**
+     * Envelope must be at least two-dimensional and non-empty.
+     */
+    public static final int EMPTY_ENVELOPE = 47;
+
+    /**
+     * Premature end of data file
+     */
+    public static final int END_OF_DATA_FILE = 48;
+
+    /**
+     * No factory of kind "{0}" found.
+     */
+    public static final int FACTORY_NOT_FOUND_$1 = 49;
+
+    /**
+     * File does not exist or is unreadable: {0}
+     */
+    public static final int FILE_DOES_NOT_EXIST_$1 = 50;
+
+    /**
+     * File has too few data.
+     */
+    public static final int FILE_HAS_TOO_FEW_DATA = 51;
+
+    /**
+     * Geotools extension required for "{0}" operation.
+     */
+    public static final int GEOTOOLS_EXTENSION_REQUIRED_$1 = 52;
+
+    /**
+     * Latitude and Longitude grid locations are not equal
+     */
+    public static final int GRID_LOCATIONS_UNEQUAL = 53;
+
+    /**
+     * Grid header has unexpected length: {0}
+     */
+    public static final int HEADER_UNEXPECTED_LENGTH_$1 = 54;
+
+    /**
+     * Hole is not inside polygon.
+     */
+    public static final int HOLE_NOT_INSIDE_POLYGON = 55;
+
+    /**
+     * Illegal angle pattern: {0}
+     */
+    public static final int ILLEGAL_ANGLE_PATTERN_$1 = 56;
+
+    /**
+     * Illegal value for argument "{0}".
+     */
+    public static final int ILLEGAL_ARGUMENT_$1 = 57;
+
+    /**
+     * Illegal argument: "{0}={1}".
+     */
+    public static final int ILLEGAL_ARGUMENT_$2 = 58;
+
+    /**
+     * Illegal array length for {0} dimensional points.
+     */
+    public static final int ILLEGAL_ARRAY_LENGTH_FOR_DIMENSION_$1 = 59;
+
+    /**
+     * Axis can't be oriented toward {0} for coordinate system of class "{1}".
+     */
+    public static final int ILLEGAL_AXIS_ORIENTATION_$2 = 60;
+
+    /**
+     * Class '{0}' is illegal. It must be '{1}' or a derivated class.
+     */
+    public static final int ILLEGAL_CLASS_$2 = 61;
+
+    /**
+     * Illegal coordinate reference system.
+     */
+    public static final int ILLEGAL_COORDINATE_REFERENCE_SYSTEM = 62;
+
+    /**
+     * Coordinate system of type '{0}' are incompatible with CRS of type '{1}'.
+     */
+    public static final int ILLEGAL_COORDINATE_SYSTEM_FOR_CRS_$2 = 63;
+
+    /**
+     * Coordinate system can't have {0} dimensions.
+     */
+    public static final int ILLEGAL_CS_DIMENSION_$1 = 64;
+
+    /**
+     * Illegal descriptor for parameter "{0}".
+     */
+    public static final int ILLEGAL_DESCRIPTOR_FOR_PARAMETER_$1 = 65;
+
+    /**
+     * Bad ordinates at dimension {0}.
+     */
+    public static final int ILLEGAL_ENVELOPE_ORDINATE_$1 = 66;
+
+    /**
+     * "{0}" is not a valid identifier.
+     */
+    public static final int ILLEGAL_IDENTIFIER_$1 = 67;
+
+    /**
+     * Illegal instruction "{0}".
+     */
+    public static final int ILLEGAL_INSTRUCTION_$1 = 68;
+
+    /**
+     * Illegal key: {0}
+     */
+    public static final int ILLEGAL_KEY_$1 = 69;
+
+    /**
+     * Illegal matrix size.
+     */
+    public static final int ILLEGAL_MATRIX_SIZE = 70;
+
+    /**
+     * Parameter "{0}" occurs {1} time, while the expected range of occurences was [{2}..{3}].
+     */
+    public static final int ILLEGAL_OCCURS_FOR_PARAMETER_$4 = 71;
+
+    /**
+     * This operation can't be applied to values of class '{0}'.
+     */
+    public static final int ILLEGAL_OPERATION_FOR_VALUE_CLASS_$1 = 72;
+
+    /**
+     * Incompatible coordinate system type.
+     */
+    public static final int INCOMPATIBLE_COORDINATE_SYSTEM_TYPE = 73;
+
+    /**
+     * Projection parameter "{0}" is incompatible with ellipsoid "{1}".
+     */
+    public static final int INCOMPATIBLE_ELLIPSOID_$2 = 74;
+
+    /**
+     * Incompatible grid geometries.
+     */
+    public static final int INCOMPATIBLE_GRID_GEOMETRY = 75;
+
+    /**
+     * Incompatible unit: {0}
+     */
+    public static final int INCOMPATIBLE_UNIT_$1 = 76;
+
+    /**
+     * Direction "{1}" is inconsistent with axis "{0}".
+     */
+    public static final int INCONSISTENT_AXIS_ORIENTATION_$2 = 77;
+
+    /**
+     * Property "{0}" has a value inconsistent with other properties.
+     */
+    public static final int INCONSISTENT_PROPERTY_$1 = 78;
+
+    /**
+     * Index {0} is out of bounds.
+     */
+    public static final int INDEX_OUT_OF_BOUNDS_$1 = 79;
+
+    /**
+     * {0} value is infinite
+     */
+    public static final int INFINITE_VALUE_$1 = 80;
+
+    /**
+     * Inseparable transform.
+     */
+    public static final int INSEPARABLE_TRANSFORM = 81;
+
+    /**
+     * {0} points were specified, while {1} are required.
+     */
+    public static final int INSUFFICIENT_POINTS_$2 = 82;
+
+    /**
+     * This "{0}" object is too complex for WKT syntax.
+     */
+    public static final int INVALID_WKT_FORMAT_$1 = 83;
+
+    /**
+     * Error in "{0}":
+     */
+    public static final int IN_$1 = 84;
+
+    /**
+     * Latitude {0} is out of range (±90°).
+     */
+    public static final int LATITUDE_OUT_OF_RANGE_$1 = 85;
+
+    /**
+     * The line contains {0} columns while only {1} was expected. Characters "{2}" seem to be
+     * extra.
+     */
+    public static final int LINE_TOO_LONG_$3 = 86;
+
+    /**
+     * The line contains only {0} columns while {1} was expected.
+     */
+    public static final int LINE_TOO_SHORT_$2 = 87;
+
+    /**
+     * Longitude {0} is out of range (±180°).
+     */
+    public static final int LONGITUDE_OUT_OF_RANGE_$1 = 88;
+
+    /**
+     * Malformed envelope
+     */
+    public static final int MALFORMED_ENVELOPE = 89;
+
+    /**
+     * All rows doesn't have the same length.
+     */
+    public static final int MATRIX_NOT_REGULAR = 90;
+
+    /**
+     * Mismatched array length.
+     */
+    public static final int MISMATCHED_ARRAY_LENGTH = 91;
+
+    /**
+     * The coordinate reference system must be the same for all objects.
+     */
+    public static final int MISMATCHED_COORDINATE_REFERENCE_SYSTEM = 92;
+
+    /**
+     * Mismatched object dimension: {0}D and {1}D.
+     */
+    public static final int MISMATCHED_DIMENSION_$2 = 93;
+
+    /**
+     * Argument "{0}" has {1} dimensions, while {2} was expected.
+     */
+    public static final int MISMATCHED_DIMENSION_$3 = 94;
+
+    /**
+     * The envelope uses an incompatible CRS: was "{1}" while we expected "{0}".
+     */
+    public static final int MISMATCHED_ENVELOPE_CRS_$2 = 95;
+
+    /**
+     * No authority was defined for code "{0}". Did you forget "AUTHORITY:NUMBER"?
+     */
+    public static final int MISSING_AUTHORITY_$1 = 96;
+
+    /**
+     * Character '{0}' was expected.
+     */
+    public static final int MISSING_CHARACTER_$1 = 97;
+
+    /**
+     * This operation requires the "{0}" module.
+     */
+    public static final int MISSING_MODULE_$1 = 98;
+
+    /**
+     * Parameter "{0}" is missing.
+     */
+    public static final int MISSING_PARAMETER_$1 = 99;
+
+    /**
+     * Missing value for parameter "{0}".
+     */
+    public static final int MISSING_PARAMETER_VALUE_$1 = 100;
+
+    /**
+     * Missing WKT definition.
+     */
+    public static final int MISSING_WKT_DEFINITION = 101;
+
+    /**
+     * Geophysics categories mixed with non-geophysics ones.
+     */
+    public static final int MIXED_CATEGORIES = 102;
+
+    /**
+     * Column number for "{0}" ({1}) can't be negative.
+     */
+    public static final int NEGATIVE_COLUMN_$2 = 103;
+
+    /**
+     * Scaling affine transform is not invertible.
+     */
+    public static final int NONINVERTIBLE_SCALING_TRANSFORM = 104;
+
+    /**
+     * Transform is not invertible.
+     */
+    public static final int NONINVERTIBLE_TRANSFORM = 105;
+
+    /**
+     * The grid to coordinate system transform must be affine.
+     */
+    public static final int NON_AFFINE_TRANSFORM = 106;
+
+    /**
+     * Not an angular unit: "{0}".
+     */
+    public static final int NON_ANGULAR_UNIT_$1 = 107;
+
+    /**
+     * Coordinate system "{0}" is not cartesian.
+     */
+    public static final int NON_CARTESIAN_COORDINATE_SYSTEM_$1 = 108;
+
+    /**
+     * Can't convert value from units "{1}" to "{0}".
+     */
+    public static final int NON_CONVERTIBLE_UNITS_$2 = 109;
+
+    /**
+     * Unmatched parenthesis in "{0}": missing '{1}'.
+     */
+    public static final int NON_EQUILIBRATED_PARENTHESIS_$2 = 110;
+
+    /**
+     * Some categories use non-integer sample values.
+     */
+    public static final int NON_INTEGER_CATEGORY = 111;
+
+    /**
+     * Relation is not linear.
+     */
+    public static final int NON_LINEAR_RELATION = 112;
+
+    /**
+     * "{0}" is not a linear unit.
+     */
+    public static final int NON_LINEAR_UNIT_$1 = 113;
+
+    /**
+     * Unit conversion from "{0}" to "{1}" is non-linear.
+     */
+    public static final int NON_LINEAR_UNIT_CONVERSION_$2 = 114;
+
+    /**
+     * Axis directions {0} and {1} are not perpendicular.
+     */
+    public static final int NON_PERPENDICULAR_AXIS_$2 = 115;
+
+    /**
+     * "{0}" is not a scale unit.
+     */
+    public static final int NON_SCALE_UNIT_$1 = 116;
+
+    /**
+     * "{0}" is not a time unit.
+     */
+    public static final int NON_TEMPORAL_UNIT_$1 = 117;
+
+    /**
+     * Transform is not affine.
+     */
+    public static final int NOT_AN_AFFINE_TRANSFORM = 118;
+
+    /**
+     * Can't format object of class "{1}" as an angle.
+     */
+    public static final int NOT_AN_ANGLE_OBJECT_$1 = 119;
+
+    /**
+     * Value "{0}" is not a valid integer.
+     */
+    public static final int NOT_AN_INTEGER_$1 = 120;
+
+    /**
+     * Points dont seem to be distributed on a regular grid.
+     */
+    public static final int NOT_A_GRID = 121;
+
+    /**
+     * Value "{0}" is not a valid real number.
+     */
+    public static final int NOT_A_NUMBER_$1 = 122;
+
+    /**
+     * {0} is not a comparable class.
+     */
+    public static final int NOT_COMPARABLE_CLASS_$1 = 123;
+
+    /**
+     * Value {0} is not a real, non-null number.
+     */
+    public static final int NOT_DIFFERENT_THAN_ZERO_$1 = 124;
+
+    /**
+     * Number {0} is invalid. Expected a number greater than 0.
+     */
+    public static final int NOT_GREATER_THAN_ZERO_$1 = 125;
+
+    /**
+     * Not a 3D coordinate system.
+     */
+    public static final int NOT_THREE_DIMENSIONAL_CS = 126;
+
+    /**
+     * Can't wrap a {0} dimensional object into a 2 dimensional one.
+     */
+    public static final int NOT_TWO_DIMENSIONAL_$1 = 127;
+
+    /**
+     * No category for value {0}.
+     */
+    public static final int NO_CATEGORY_FOR_VALUE_$1 = 128;
+
+    /**
+     * Transformation doesn't convergence.
+     */
+    public static final int NO_CONVERGENCE = 129;
+
+    /**
+     * No convergence for points {0} and {1}.
+     */
+    public static final int NO_CONVERGENCE_$2 = 130;
+
+    /**
+     * No data source found.
+     */
+    public static final int NO_DATA_SOURCE = 131;
+
+    /**
+     * No input set.
+     */
+    public static final int NO_IMAGE_INPUT = 132;
+
+    /**
+     * No output set.
+     */
+    public static final int NO_IMAGE_OUTPUT = 133;
+
+    /**
+     * No suitable image reader for this input.
+     */
+    public static final int NO_IMAGE_READER = 134;
+
+    /**
+     * No suitable image writer for this output.
+     */
+    public static final int NO_IMAGE_WRITER = 135;
+
+    /**
+     * No source axis match {0}.
+     */
+    public static final int NO_SOURCE_AXIS_$1 = 136;
+
+    /**
+     * No object of type "{0}" has been found for code "{1}".
+     */
+    public static final int NO_SUCH_AUTHORITY_CODE_$2 = 137;
+
+    /**
+     * No code "{0}" from authority "{1}" found for object of type "{2}".
+     */
+    public static final int NO_SUCH_AUTHORITY_CODE_$3 = 138;
+
+    /**
+     * No two-dimensional transform available for this geometry.
+     */
+    public static final int NO_TRANSFORM2D_AVAILABLE = 139;
+
+    /**
+     * No transformation available from system "{0}" to "{1}".
+     */
+    public static final int NO_TRANSFORMATION_PATH_$2 = 140;
+
+    /**
+     * No transform for classification "{0}".
+     */
+    public static final int NO_TRANSFORM_FOR_CLASSIFICATION_$1 = 141;
+
+    /**
+     * Unit must be specified.
+     */
+    public static final int NO_UNIT = 142;
+
+    /**
+     * Argument "{0}" should not be null.
+     */
+    public static final int NULL_ARGUMENT_$1 = 143;
+
+    /**
+     * Attribute "{0}" should not be null.
+     */
+    public static final int NULL_ATTRIBUTE_$1 = 144;
+
+    /**
+     * Format #{0} (on {1}) is not defined.
+     */
+    public static final int NULL_FORMAT_$2 = 145;
+
+    /**
+     * "{0}" parameter should be not null and of type "{1}".
+     */
+    public static final int NULL_PARAMETER_$2 = 146;
+
+    /**
+     * Unexpected null value in record "{0}" for the column "{1}" in table "{2}".
+     */
+    public static final int NULL_VALUE_IN_TABLE_$3 = 147;
+
+    /**
+     * The number of image bands ({0}) differs from the number of supplied '{2}' objects ({1}).
+     */
+    public static final int NUMBER_OF_BANDS_MISMATCH_$3 = 148;
+
+    /**
+     * Bad array length: {0}. An even array length was expected.
+     */
+    public static final int ODD_ARRAY_LENGTH_$1 = 149;
+
+    /**
+     * Operation "{0}" is already bounds.
+     */
+    public static final int OPERATION_ALREADY_BOUNDS_$1 = 150;
+
+    /**
+     * Operation "{0}" is already binds in this grid processor.
+     */
+    public static final int OPERATION_ALREADY_BOUND_$1 = 151;
+
+    /**
+     * No such "{0}" operation for this processor.
+     */
+    public static final int OPERATION_NOT_FOUND_$1 = 152;
+
+    /**
+     * Possible use of "{0}" projection outside its valid area.
+     */
+    public static final int OUT_OF_PROJECTION_VALID_AREA_$1 = 153;
+
+    /**
+     * Name or alias for parameter "{0}" at index {1} conflict with name "{2}" at index {3}.
+     */
+    public static final int PARAMETER_NAME_CLASH_$4 = 154;
+
+    /**
+     * Unparsable string: "{0}". Please check characters "{1}".
+     */
+    public static final int PARSE_EXCEPTION_$2 = 155;
+
+    /**
+     * Coordinate ({0}) is outside coverage.
+     */
+    public static final int POINT_OUTSIDE_COVERAGE_$1 = 156;
+
+    /**
+     * Point is outside grid
+     */
+    public static final int POINT_OUTSIDE_GRID = 157;
+
+    /**
+     * Point outside hemisphere of projection.
+     */
+    public static final int POINT_OUTSIDE_HEMISPHERE = 158;
+
+    /**
+     * Latitude {0} is too close to a pole.
+     */
+    public static final int POLE_PROJECTION_$1 = 159;
+
+    /**
+     * Can't add point to a closed polygon.
+     */
+    public static final int POLYGON_CLOSED = 160;
+
+    /**
+     * The transform result may be {0} meters away from the expected position. Are you sure that
+     * the input coordinates are inside this map projection area of validity? The point is located
+     * {1} away from the central meridian and {2} away from the latitude of origin. The projection
+     * is "{3}".
+     */
+    public static final int PROJECTION_CHECK_FAILED_$4 = 161;
+
+    /**
+     * Ranges [{0}..{1}] and [{2}..{3}] overlap.
+     */
+    public static final int RANGE_OVERLAP_$4 = 162;
+
+    /**
+     * Recursive call while creating a '{0}' object.
+     */
+    public static final int RECURSIVE_CALL_$1 = 163;
+
+    /**
+     * Recursive call while creating a '{0}' object for code "{1}".
+     */
+    public static final int RECURSIVE_CALL_$2 = 164;
+
+    /**
+     * RGB value {0} is out of range.
+     */
+    public static final int RGB_OUT_OF_RANGE_$1 = 165;
+
+    /**
+     * Execution on a remote machine failed.
+     */
+    public static final int RMI_FAILURE = 166;
+
+    /**
+     * Expected {0}={1} but got {2}.
+     */
+    public static final int TEST_FAILURE_$3 = 167;
+
+    /**
+     * Tolerance error.
+     */
+    public static final int TOLERANCE_ERROR = 168;
+
+    /**
+     * Too many occurences of "{0}". There is already {1} of them.
+     */
+    public static final int TOO_MANY_OCCURENCES_$2 = 169;
+
+    /**
+     * Undefined property.
+     */
+    public static final int UNDEFINED_PROPERTY = 170;
+
+    /**
+     * Property "{0}" is not defined.
+     */
+    public static final int UNDEFINED_PROPERTY_$1 = 171;
+
+    /**
+     * Unexpected argument for operation "{0}".
+     */
+    public static final int UNEXPECTED_ARGUMENT_FOR_INSTRUCTION_$1 = 172;
+
+    /**
+     * Unexpected dimension for a "{0}" coordinate system.
+     */
+    public static final int UNEXPECTED_DIMENSION_FOR_CS_$1 = 173;
+
+    /**
+     * Unexpected end of string.
+     */
+    public static final int UNEXPECTED_END_OF_STRING = 174;
+
+    /**
+     * Image doesn't have the expected size.
+     */
+    public static final int UNEXPECTED_IMAGE_SIZE = 175;
+
+    /**
+     * Parameter "{0}" was not expected.
+     */
+    public static final int UNEXPECTED_PARAMETER_$1 = 176;
+
+    /**
+     * Matrix row {0} has a length of {1}, while {2} was expected.
+     */
+    public static final int UNEXPECTED_ROW_LENGTH_$3 = 177;
+
+    /**
+     * Transformation doesn't produce the expected values.
+     */
+    public static final int UNEXPECTED_TRANSFORM_RESULT = 178;
+
+    /**
+     * Parameter "{0}" has no unit.
+     */
+    public static final int UNITLESS_PARAMETER_$1 = 179;
+
+    /**
+     * Authority "{0}" is unknown or doesn't match the supplied hints. Maybe it is defined in an
+     * unreachable JAR file?
+     */
+    public static final int UNKNOW_AUTHORITY_$1 = 180;
+
+    /**
+     * Unknow axis direction: "{0}".
+     */
+    public static final int UNKNOW_AXIS_DIRECTION_$1 = 181;
+
+    /**
+     * Image format "{0}" is unknown.
+     */
+    public static final int UNKNOW_IMAGE_FORMAT_$1 = 182;
+
+    /**
+     * Interpolation "{0}" is unknown.
+     */
+    public static final int UNKNOW_INTERPOLATION_$1 = 183;
+
+    /**
+     * Unknow parameter: {0}
+     */
+    public static final int UNKNOW_PARAMETER_$1 = 184;
+
+    /**
+     * Unknow parameter name: {0}
+     */
+    public static final int UNKNOW_PARAMETER_NAME_$1 = 185;
+
+    /**
+     * Unknow projection type.
+     */
+    public static final int UNKNOW_PROJECTION_TYPE = 186;
+
+    /**
+     * Type "{0}" is unknow in this context.
+     */
+    public static final int UNKNOW_TYPE_$1 = 187;
+
+    /**
+     * This affine transform is unmodifiable.
+     */
+    public static final int UNMODIFIABLE_AFFINE_TRANSFORM = 188;
+
+    /**
+     * Unmodifiable geometry.
+     */
+    public static final int UNMODIFIABLE_GEOMETRY = 189;
+
+    /**
+     * Unmodifiable metadata.
+     */
+    public static final int UNMODIFIABLE_METADATA = 190;
+
+    /**
+     * Can't parse "{0}" as a number.
+     */
+    public static final int UNPARSABLE_NUMBER_$1 = 191;
+
+    /**
+     * Can't parse "{0}" because "{1}" is unrecognized.
+     */
+    public static final int UNPARSABLE_STRING_$2 = 192;
+
+    /**
+     * Coordinate reference system is unspecified.
+     */
+    public static final int UNSPECIFIED_CRS = 193;
+
+    /**
+     * Unspecified image's size.
+     */
+    public static final int UNSPECIFIED_IMAGE_SIZE = 194;
+
+    /**
+     * Unspecified coordinates transform.
+     */
+    public static final int UNSPECIFIED_TRANSFORM = 195;
+
+    /**
+     * Coordinate system "{0}" is unsupported.
+     */
+    public static final int UNSUPPORTED_COORDINATE_SYSTEM_$1 = 196;
+
+    /**
+     * Coordinate reference system "{0}" is unsupported.
+     */
+    public static final int UNSUPPORTED_CRS_$1 = 197;
+
+    /**
+     * Unsupported data type.
+     */
+    public static final int UNSUPPORTED_DATA_TYPE = 198;
+
+    /**
+     * Data type "{0}" is not supported.
+     */
+    public static final int UNSUPPORTED_DATA_TYPE_$1 = 199;
+
+    /**
+     * Unsupported file type: {0} or {1}
+     */
+    public static final int UNSUPPORTED_FILE_TYPE_$2 = 200;
+
+    /**
+     * Operation "{0}" is unsupported.
+     */
+    public static final int UNSUPPORTED_OPERATION_$1 = 205;
+
+    /**
+     * Value {0} is out of range [{1}..{2}].
+     */
+    public static final int VALUE_OUT_OF_BOUNDS_$3 = 201;
+
+    /**
+     * Numerical value tend toward infinity.
+     */
+    public static final int VALUE_TEND_TOWARD_INFINITY = 202;
+
+    /**
+     * No variable "{0}" found in file "{1}".
+     */
+    public static final int VARIABLE_NOT_FOUND_IN_FILE_$2 = 203;
+
+    /**
+     * Value {1} is outside the domain of coverage "{0}".
+     */
+    public static final int ZVALUE_OUTSIDE_COVERAGE_$2 = 204;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/Errors.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/Errors.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/Errors.java	(revision 28000)
@@ -0,0 +1,135 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources.i18n;
+
+import java.util.Locale;
+import java.util.MissingResourceException;
+import org.geotools.resources.IndexedResourceBundle;
+
+
+/**
+ * Base class for locale-dependent resources. Instances of this class should
+ * never been created directly. Use the factory method {@link #getResources}
+ * or use static convenience methods instead.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/i18n/Errors.java $
+ * @version $Id: Errors.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class Errors extends IndexedResourceBundle {
+    /**
+     * Returns resources in the given locale.
+     *
+     * @param  locale The locale, or {@code null} for the default locale.
+     * @return Resources in the given locale.
+     * @throws MissingResourceException if resources can't be found.
+     */
+    public static Errors getResources(Locale locale) throws MissingResourceException {
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+        return (Errors) getBundle(Errors.class.getName(), locale);
+        /*
+         * We rely on cache capability of ResourceBundle.
+         */
+    }
+
+    /**
+     * Gets a string for the given key from this resource bundle or one of its parents.
+     *
+     * @param  key The key for the desired string.
+     * @return The string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public static String format(final int key) throws MissingResourceException {
+        return getResources(null).getString(key);
+    }
+
+    /**
+     * Gets a string for the given key are replace all occurence of "{0}"
+     * with values of {@code arg0}.
+     *
+     * @param  key The key for the desired string.
+     * @param  arg0 Value to substitute to "{0}".
+     * @return The formatted string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public static String format(final int     key,
+                                final Object arg0) throws MissingResourceException
+    {
+        return getResources(null).getString(key, arg0);
+    }
+
+    /**
+     * Gets a string for the given key are replace all occurence of "{0}",
+     * "{1}", with values of {@code arg0}, {@code arg1}.
+     *
+     * @param  key The key for the desired string.
+     * @param  arg0 Value to substitute to "{0}".
+     * @param  arg1 Value to substitute to "{1}".
+     * @return The formatted string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public static String format(final int     key,
+                                final Object arg0,
+                                final Object arg1) throws MissingResourceException
+    {
+        return getResources(null).getString(key, arg0, arg1);
+    }
+
+    /**
+     * Gets a string for the given key are replace all occurence of "{0}",
+     * "{1}", with values of {@code arg0}, {@code arg1}, etc.
+     *
+     * @param  key The key for the desired string.
+     * @param  arg0 Value to substitute to "{0}".
+     * @param  arg1 Value to substitute to "{1}".
+     * @param  arg2 Value to substitute to "{2}".
+     * @return The formatted string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public static String format(final int     key,
+                                final Object arg0,
+                                final Object arg1,
+                                final Object arg2) throws MissingResourceException
+    {
+        return getResources(null).getString(key, arg0, arg1, arg2);
+    }
+
+    /**
+     * Gets a string for the given key are replace all occurence of "{0}",
+     * "{1}", with values of {@code arg0}, {@code arg1}, etc.
+     *
+     * @param  key The key for the desired string.
+     * @param  arg0 Value to substitute to "{0}".
+     * @param  arg1 Value to substitute to "{1}".
+     * @param  arg2 Value to substitute to "{2}".
+     * @param  arg3 Value to substitute to "{3}".
+     * @return The formatted string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public static String format(final int     key,
+                                final Object arg0,
+                                final Object arg1,
+                                final Object arg2,
+                                final Object arg3) throws MissingResourceException
+    {
+        return getResources(null).getString(key, arg0, arg1, arg2, arg3);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/LoggingKeys.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/LoggingKeys.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/LoggingKeys.java	(revision 28000)
@@ -0,0 +1,296 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *    
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *    
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *    
+ *    THIS IS AN AUTOMATICALLY GENERATED FILE. DO NOT EDIT!
+ *    Generated with: org.geotools.resources.IndexedResourceCompiler
+ */
+package org.geotools.resources.i18n;
+
+
+/**
+ * Resource keys. This class is used when compiling sources, but
+ * no dependencies to {@code ResourceKeys} should appear in any
+ * resulting class files.  Since Java compiler inlines final integer
+ * values, using long identifiers will not bloat constant pools of
+ * classes compiled against the interface, provided that no class
+ * implements this interface.
+ *
+ * @see org.geotools.resources.IndexedResourceBundle
+ * @see org.geotools.resources.IndexedResourceCompiler
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/i18n/LoggingKeys.java $
+ */
+public final class LoggingKeys {
+    private LoggingKeys() {
+    }
+
+    /**
+     * Grid geometry has been adjusted for coverage "{0}".
+     */
+    public static final int ADJUSTED_GRID_GEOMETRY_$1 = 0;
+
+    /**
+     * Ambiguity between inverse flattening and semi minor axis length. Using inverse flattening.
+     */
+    public static final int AMBIGUOUS_ELLIPSOID = 1;
+
+    /**
+     * {3,choice,0#Apply|Reuse} operation "{1}" on coverage "{0}" with interpolation "{2}".
+     */
+    public static final int APPLIED_OPERATION_$4 = 2;
+
+    /**
+     * Resampled coverage "{0}" from coordinate system "{1}" (for an image of size {2}×{3}) to
+     * coordinate system "{4}" (image size {5}×{6}). JAI operation is "{7}" with "{9}"
+     * interpolation on {8,choice,0#packed|1#geophysics} pixels values. Background value is ({10}).
+     */
+    public static final int APPLIED_RESAMPLE_$11 = 3;
+
+    /**
+     * Converted "{0}" from "{1}" to "{2}" units. We assume that this is the expected units for
+     * computation purpose.
+     */
+    public static final int APPLIED_UNIT_CONVERSION_$3 = 4;
+
+    /**
+     * Failed to bind a "{0}" entry.
+     */
+    public static final int CANT_BIND_DATASOURCE_$1 = 5;
+
+    /**
+     * Failed to create a coordinate operation from "{0}" authority factory.
+     */
+    public static final int CANT_CREATE_COORDINATE_OPERATION_$1 = 6;
+
+    /**
+     * Failed to dispose the backing store after timeout.
+     */
+    public static final int CANT_DISPOSE_BACKING_STORE = 7;
+
+    /**
+     * Can't load a service for category "{0}". Cause is "{1}".
+     */
+    public static final int CANT_LOAD_SERVICE_$2 = 8;
+
+    /**
+     * Can't read "{0}".
+     */
+    public static final int CANT_READ_FILE_$1 = 9;
+
+    /**
+     * Can't register JAI operation "{0}". Some grid coverage operations may not work.
+     */
+    public static final int CANT_REGISTER_JAI_OPERATION_$1 = 10;
+
+    /**
+     * Changed the renderer coordinate system. Cause is:
+     */
+    public static final int CHANGED_COORDINATE_REFERENCE_SYSTEM = 11;
+
+    /**
+     * Closed the EPSG database connection.
+     */
+    public static final int CLOSED_EPSG_DATABASE = 12;
+
+    /**
+     * Connected to EPSG database "{0}" on "{1}".
+     */
+    public static final int CONNECTED_EPSG_DATABASE_$2 = 13;
+
+    /**
+     * Created coordinate operation "{0}" for source CRS "{1}" and target CRS "{2}".
+     */
+    public static final int CREATED_COORDINATE_OPERATION_$3 = 14;
+
+    /**
+     * Created a "{0}" entry in the naming system.
+     */
+    public static final int CREATED_DATASOURCE_ENTRY_$1 = 15;
+
+    /**
+     * Created serializable image for coverage "{0}" using the "{1}" codec.
+     */
+    public static final int CREATED_SERIALIZABLE_IMAGE_$2 = 16;
+
+    /**
+     * Creating cached EPSG database version {0}. This operation may take a few minutes...
+     */
+    public static final int CREATING_CACHED_EPSG_DATABASE_$1 = 17;
+
+    /**
+     * Deferred painting for tile ({0},{1}).
+     */
+    public static final int DEFERRED_TILE_PAINTING_$2 = 18;
+
+    /**
+     * Excessive memory usage.
+     */
+    public static final int EXCESSIVE_MEMORY_USAGE = 19;
+
+    /**
+     * Tile cache capacity exceed maximum heap size ({0} Mb).
+     */
+    public static final int EXCESSIVE_TILE_CACHE_$1 = 20;
+
+    /**
+     * Factory implementations for category {0}:
+     */
+    public static final int FACTORY_IMPLEMENTATIONS_$1 = 21;
+
+    /**
+     * Failure in the primary factory: {0} Now trying the fallback factory...
+     */
+    public static final int FALLBACK_FACTORY_$1 = 22;
+
+    /**
+     * Found {0} reference systems in {1} elements. The most frequent appears {2} time and the less
+     * frequent appears {3} times.
+     */
+    public static final int FOUND_MISMATCHED_CRS_$4 = 23;
+
+    /**
+     * Ignored "{0}" hint.
+     */
+    public static final int HINT_IGNORED_$1 = 24;
+
+    /**
+     * Initializing transformation from {0} to {1}.
+     */
+    public static final int INITIALIZING_TRANSFORMATION_$2 = 25;
+
+    /**
+     * Loaded "{0}" JDBC driver version {1}.{2}.
+     */
+    public static final int LOADED_JDBC_DRIVER_$3 = 26;
+
+    /**
+     * Loading datum aliases from "{0}".
+     */
+    public static final int LOADING_DATUM_ALIASES_$1 = 27;
+
+    /**
+     * Text were discarted for some locales.
+     */
+    public static final int LOCALES_DISCARTED = 28;
+
+    /**
+     * No coordinate operation from "{0}" to "{1}" because of mismatched factories.
+     */
+    public static final int MISMATCHED_COORDINATE_OPERATION_FACTORIES_$2 = 29;
+
+    /**
+     * The type of the requested object doesn't match the "{0}" URN type.
+     */
+    public static final int MISMATCHED_URN_TYPE_$1 = 30;
+
+    /**
+     * Native acceleration {1,choice,0#disabled|enabled} for "{0}" operation.
+     */
+    public static final int NATIVE_ACCELERATION_STATE_$2 = 31;
+
+    /**
+     * Offscreen rendering failed for layer "{0}". Fall back on default rendering.
+     */
+    public static final int OFFSCREEN_RENDERING_FAILED_$1 = 32;
+
+    /**
+     * Renderer "{0}" painted in {1} seconds.
+     */
+    public static final int PAINTING_LAYER_$2 = 33;
+
+    /**
+     * Polygons drawn with {0,number,percent} of available points, reusing {1,number,percent} from
+     * the cache (resolution: {2} {3}).
+     */
+    public static final int POLYGON_CACHE_USE_$4 = 34;
+
+    /**
+     * Failed to allocate {0} Mb of memory. Trying a smaller memory allocation.
+     */
+    public static final int RECOVERABLE_OUT_OF_MEMORY_$1 = 35;
+
+    /**
+     * Log records are redirected to Apache commons logging.
+     */
+    public static final int REDIRECTED_TO_COMMONS_LOGGING = 36;
+
+    /**
+     * Registered Geotools extensions to JAI operations.
+     */
+    public static final int REGISTERED_JAI_OPERATIONS = 37;
+
+    /**
+     * Select an image of "{0}" decimated to level {1} of {2}.
+     */
+    public static final int RESSAMPLING_RENDERED_IMAGE_$3 = 38;
+
+    /**
+     * Creates a {1,choice,0#packed|1#geophysics|2#photographic} view of grid coverage "{0}" using
+     * operation "{2}".
+     */
+    public static final int SAMPLE_TRANSCODE_$3 = 39;
+
+    /**
+     * Layer "{0}" send a repaint event for the whole widget area.
+     */
+    public static final int SEND_REPAINT_EVENT_$1 = 40;
+
+    /**
+     * Layer "{0}" send a repaint event for pixels x=[{1}..{2}] and y=[{3}..{4}] in widget area.
+     */
+    public static final int SEND_REPAINT_EVENT_$5 = 41;
+
+    /**
+     * Unavailable authority factory: {0}
+     */
+    public static final int UNAVAILABLE_AUTHORITY_FACTORY_$1 = 42;
+
+    /**
+     * Attempt to recover from unexpected exception.
+     */
+    public static final int UNEXPECTED_EXCEPTION = 43;
+
+    /**
+     * Unexpected unit "{0}". Map scale may be inacurate.
+     */
+    public static final int UNEXPECTED_UNIT_$1 = 44;
+
+    /**
+     * Ignoring unknow parameter: "{0}" = {1} {2}.
+     */
+    public static final int UNKNOW_PARAMETER_$3 = 45;
+
+    /**
+     * Can't handle style of class {0}. Consequently, geometry "{1}" will ignore its style
+     * information.
+     */
+    public static final int UNKNOW_STYLE_$2 = 46;
+
+    /**
+     * Unrecognized scale type: "{0}". Default to linear.
+     */
+    public static final int UNRECOGNIZED_SCALE_TYPE_$1 = 47;
+
+    /**
+     * Update the cache for layer "{0}".
+     */
+    public static final int UPDATE_RENDERER_CACHE_$1 = 48;
+
+    /**
+     * Using "{0}" as {1} factory.
+     */
+    public static final int USING_FILE_AS_FACTORY_$2 = 49;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/Loggings.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/Loggings.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/Loggings.java	(revision 28000)
@@ -0,0 +1,125 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources.i18n;
+
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.logging.LogRecord;
+import java.util.logging.Level;
+import org.geotools.resources.IndexedResourceBundle;
+
+
+/**
+ * Base class for locale-dependent resources. Instances of this class should
+ * never been created directly. Use the factory method {@link #getResources}
+ * or use static convenience methods instead.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/i18n/Loggings.java $
+ * @version $Id: Loggings.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class Loggings extends IndexedResourceBundle {
+    /**
+     * Returns resources in the given locale.
+     *
+     * @param  locale The locale, or {@code null} for the default locale.
+     * @return Resources in the given locale.
+     * @throws MissingResourceException if resources can't be found.
+     */
+    public static Loggings getResources(Locale locale) throws MissingResourceException {
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+        return (Loggings) getBundle(Loggings.class.getName(), locale);
+        /*
+         * We rely on cache capability of ResourceBundle.
+         */
+    }
+
+    /**
+     * Gets a log record for the given key from this resource bundle or one of its parents.
+     *
+     * @param  level The log record level.
+     * @param  key The key for the desired string.
+     * @return The string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public static LogRecord format(final Level level,
+                                   final int key) throws MissingResourceException
+    {
+        return getResources(null).getLogRecord(level, key);
+    }
+
+    /**
+     * Gets a log record for the given key. Replaces all occurence of "{0}"
+     * with values of {@code arg0}.
+     *
+     * @param  level The log record level.
+     * @param  key The key for the desired string.
+     * @param  arg0 Value to substitute to "{0}".
+     * @return The formatted string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public static LogRecord format(final Level level,
+                                   final int     key,
+                                   final Object arg0) throws MissingResourceException
+    {
+        return getResources(null).getLogRecord(level, key, arg0);
+    }
+
+    /**
+     * Gets a log record for the given key. Replaces all occurence of "{0}",
+     * "{1}", with values of {@code arg0}, {@code arg1}.
+     *
+     * @param  level The log record level.
+     * @param  key The key for the desired string.
+     * @param  arg0 Value to substitute to "{0}".
+     * @param  arg1 Value to substitute to "{1}".
+     * @return The formatted string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public static LogRecord format(final Level level,
+                                   final int     key,
+                                   final Object arg0,
+                                   final Object arg1) throws MissingResourceException
+    {
+        return getResources(null).getLogRecord(level, key, arg0, arg1);
+    }
+
+    /**
+     * Gets a log record for the given key. Replaces all occurence of "{0}",
+     * "{1}", with values of {@code arg0}, {@code arg1}, etc.
+     *
+     * @param  level The log record level.
+     * @param  key The key for the desired string.
+     * @param  arg0 Value to substitute to "{0}".
+     * @param  arg1 Value to substitute to "{1}".
+     * @param  arg2 Value to substitute to "{2}".
+     * @return The formatted string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public static LogRecord format(final Level level,
+                                   final int     key,
+                                   final Object arg0,
+                                   final Object arg1,
+                                   final Object arg2) throws MissingResourceException
+    {
+        return getResources(null).getLogRecord(level, key, arg0, arg1, arg2);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/Vocabulary.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/Vocabulary.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/Vocabulary.java	(revision 28000)
@@ -0,0 +1,110 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.resources.i18n;
+
+import java.util.Locale;
+import java.util.MissingResourceException;
+import org.opengis.util.InternationalString;
+import org.geotools.resources.IndexedResourceBundle;
+import org.geotools.util.ResourceInternationalString;
+
+
+/**
+ * Base class for locale-dependent resources. Instances of this class should
+ * never been created directly. Use the factory method {@link #getResources}
+ * or use static convenience methods instead.
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/i18n/Vocabulary.java $
+ * @version $Id: Vocabulary.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class Vocabulary extends IndexedResourceBundle {
+    /**
+     * Returns resources in the given locale.
+     *
+     * @param  locale The locale, or {@code null} for the default locale.
+     * @return Resources in the given locale.
+     * @throws MissingResourceException if resources can't be found.
+     */
+    public static Vocabulary getResources(Locale locale) throws MissingResourceException {
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+        return (Vocabulary) getBundle(Vocabulary.class.getName(), locale);
+        /*
+         * We rely on cache capability of ResourceBundle.
+         */
+    }
+
+    /**
+     * Gets an international string for the given key. This method does not check for the key
+     * validity. If the key is invalid, then a {@link MissingResourceException} may be thrown
+     * when a {@link InternationalString#toString} method is invoked.
+     *
+     * @param  key The key for the desired string.
+     * @return An international string for the given key.
+     */
+    public static InternationalString formatInternational(final int key) {
+        return new ResourceInternationalString(Vocabulary.class.getName(), String.valueOf(key));
+    }
+
+    /**
+     * Gets an international string for the given key. This method does not check for the key
+     * validity. If the key is invalid, then a {@link MissingResourceException} may be thrown
+     * when a {@link InternationalString#toString} method is invoked.
+     *
+     * @param  key The key for the desired string.
+     * @param  arg0 Value to substitute to "{0}".
+     * @return An international string for the given key.
+     *
+     * @todo Current implementation just invokes {@link #format}. Need to format only when
+     *       {@code toString(Locale)} is invoked.
+     */
+    public static InternationalString formatInternational(final int    key,
+                                                          final Object arg0)
+    {
+        return new org.geotools.util.SimpleInternationalString(format(key, arg0));
+    }
+
+    /**
+     * Gets a string for the given key from this resource bundle or one of its parents.
+     *
+     * @param  key The key for the desired string.
+     * @return The string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public static String format(final int key) throws MissingResourceException {
+        return getResources(null).getString(key);
+    }
+
+    /**
+     * Gets a string for the given key are replace all occurence of "{0}"
+     * with values of {@code arg0}.
+     *
+     * @param  key The key for the desired string.
+     * @param  arg0 Value to substitute to "{0}".
+     * @return The formatted string for the given key.
+     * @throws MissingResourceException If no object for the given key can be found.
+     */
+    public static String format(final int     key,
+                                final Object arg0) throws MissingResourceException
+    {
+        return getResources(null).getString(key, arg0);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/VocabularyKeys.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/VocabularyKeys.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/i18n/VocabularyKeys.java	(revision 28000)
@@ -0,0 +1,1299 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *    
+ *    (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *    
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *    
+ *    THIS IS AN AUTOMATICALLY GENERATED FILE. DO NOT EDIT!
+ *    Generated with: org.geotools.resources.IndexedResourceCompiler
+ */
+package org.geotools.resources.i18n;
+
+
+/**
+ * Resource keys. This class is used when compiling sources, but
+ * no dependencies to {@code ResourceKeys} should appear in any
+ * resulting class files.  Since Java compiler inlines final integer
+ * values, using long identifiers will not bloat constant pools of
+ * classes compiled against the interface, provided that no class
+ * implements this interface.
+ *
+ * @see org.geotools.resources.IndexedResourceBundle
+ * @see org.geotools.resources.IndexedResourceCompiler
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/resources/i18n/VocabularyKeys.java $
+ */
+public final class VocabularyKeys {
+    private VocabularyKeys() {
+    }
+
+    /**
+     * About
+     */
+    public static final int ABOUT = 0;
+
+    /**
+     * Abridged Molodenski transform
+     */
+    public static final int ABRIDGED_MOLODENSKI_TRANSFORM = 1;
+
+    /**
+     * Affine transform
+     */
+    public static final int AFFINE_TRANSFORM = 2;
+
+    /**
+     * Albers Equal Area projection
+     */
+    public static final int ALBERS_EQUAL_AREA_PROJECTION = 3;
+
+    /**
+     * All
+     */
+    public static final int ALL = 4;
+
+    /**
+     * Altitude
+     */
+    public static final int ALTITUDE = 5;
+
+    /**
+     * Authority
+     */
+    public static final int AUTHORITY = 6;
+
+    /**
+     * Axis changes
+     */
+    public static final int AXIS_CHANGES = 7;
+
+    /**
+     * Azimuth
+     */
+    public static final int AZIMUTH = 8;
+
+    /**
+     * Band
+     */
+    public static final int BAND = 9;
+
+    /**
+     * Barometric altitude
+     */
+    public static final int BAROMETRIC_ALTITUDE = 10;
+
+    /**
+     * Black
+     */
+    public static final int BLACK = 11;
+
+    /**
+     * Blue
+     */
+    public static final int BLUE = 12;
+
+    /**
+     * Cancel
+     */
+    public static final int CANCEL = 13;
+
+    /**
+     * Cartesian
+     */
+    public static final int CARTESIAN = 14;
+
+    /**
+     * Cartesian 2D
+     */
+    public static final int CARTESIAN_2D = 15;
+
+    /**
+     * Cartesian 3D
+     */
+    public static final int CARTESIAN_3D = 16;
+
+    /**
+     * Cassini-Soldner projection
+     */
+    public static final int CASSINI_SOLDNER_PROJECTION = 249;
+
+    /**
+     * Category
+     */
+    public static final int CATEGORY = 17;
+
+    /**
+     * Class
+     */
+    public static final int CLASS = 18;
+
+    /**
+     * Classic
+     */
+    public static final int CLASSIC = 19;
+
+    /**
+     * Close
+     */
+    public static final int CLOSE = 20;
+
+    /**
+     * Code
+     */
+    public static final int CODE = 21;
+
+    /**
+     * Colors
+     */
+    public static final int COLORS = 22;
+
+    /**
+     * {0} colors
+     */
+    public static final int COLOR_COUNT_$1 = 23;
+
+    /**
+     * Color model
+     */
+    public static final int COLOR_MODEL = 24;
+
+    /**
+     * Column
+     */
+    public static final int COLUMN = 25;
+
+    /**
+     * Columns
+     */
+    public static final int COLUMNS = 26;
+
+    /**
+     * Compare with
+     */
+    public static final int COMPARE_WITH = 27;
+
+    /**
+     * Conversion
+     */
+    public static final int CONVERSION = 28;
+
+    /**
+     * Conversion and transformation
+     */
+    public static final int CONVERSION_AND_TRANSFORMATION = 29;
+
+    /**
+     * Coordinates selection
+     */
+    public static final int COORDINATES_SELECTION = 30;
+
+    /**
+     * Coordinate format
+     */
+    public static final int COORDINATE_FORMAT = 31;
+
+    /**
+     * Coordinate Reference System
+     */
+    public static final int COORDINATE_REFERENCE_SYSTEM = 32;
+
+    /**
+     * Cyan
+     */
+    public static final int CYAN = 33;
+
+    /**
+     * Cylindrical Mercator projection
+     */
+    public static final int CYLINDRICAL_MERCATOR_PROJECTION = 34;
+
+    /**
+     * Database engine
+     */
+    public static final int DATABASE_ENGINE = 35;
+
+    /**
+     * Database URL
+     */
+    public static final int DATABASE_URL = 36;
+
+    /**
+     * {0} data base version {1} on {2} engine.
+     */
+    public static final int DATA_BASE_$3 = 37;
+
+    /**
+     * Data type
+     */
+    public static final int DATA_TYPE = 38;
+
+    /**
+     * {1} bits {0,choice,0#unsigned integer|1#signed integer|2#real number}
+     */
+    public static final int DATA_TYPE_$2 = 39;
+
+    /**
+     * Datum shift
+     */
+    public static final int DATUM_SHIFT = 40;
+
+    /**
+     * Debug
+     */
+    public static final int DEBUG = 41;
+
+    /**
+     * Decoders
+     */
+    public static final int DECODERS = 42;
+
+    /**
+     * Default value
+     */
+    public static final int DEFAULT_VALUE = 43;
+
+    /**
+     * Depth
+     */
+    public static final int DEPTH = 44;
+
+    /**
+     * Derived from {0}
+     */
+    public static final int DERIVED_FROM_$1 = 45;
+
+    /**
+     * Description
+     */
+    public static final int DESCRIPTION = 46;
+
+    /**
+     * Discontinuous
+     */
+    public static final int DISCONTINUOUS = 47;
+
+    /**
+     * Display
+     */
+    public static final int DISPLAY = 48;
+
+    /**
+     * Distance
+     */
+    public static final int DISTANCE = 49;
+
+    /**
+     * Down
+     */
+    public static final int DOWN = 50;
+
+    /**
+     * Dublin Julian
+     */
+    public static final int DUBLIN_JULIAN = 51;
+
+    /**
+     * Duplicated value
+     */
+    public static final int DUPLICATED_VALUE = 52;
+
+    /**
+     * Earth gravitational model
+     */
+    public static final int EARTH_GRAVITATIONAL_MODEL = 53;
+
+    /**
+     * East
+     */
+    public static final int EAST = 54;
+
+    /**
+     * Easting
+     */
+    public static final int EASTING = 55;
+
+    /**
+     * Ellipsoid
+     */
+    public static final int ELLIPSOID = 56;
+
+    /**
+     * Ellipsoidal
+     */
+    public static final int ELLIPSOIDAL = 57;
+
+    /**
+     * Ellipsoidal height
+     */
+    public static final int ELLIPSOIDAL_HEIGHT = 58;
+
+    /**
+     * Ellipsoid shift
+     */
+    public static final int ELLIPSOID_SHIFT = 59;
+
+    /**
+     * Encoders
+     */
+    public static final int ENCODERS = 60;
+
+    /**
+     * End time
+     */
+    public static final int END_TIME = 61;
+
+    /**
+     * Equidistant conic projection
+     */
+    public static final int EQUIDISTANT_CONIC_PROJECTION = 250;
+
+    /**
+     * Equidistant cylindrical projection
+     */
+    public static final int EQUIDISTANT_CYLINDRICAL_PROJECTION = 62;
+
+    /**
+     * Error
+     */
+    public static final int ERROR = 63;
+
+    /**
+     * Error - {0}
+     */
+    public static final int ERROR_$1 = 64;
+
+    /**
+     * Error filters
+     */
+    public static final int ERROR_FILTERS = 65;
+
+    /**
+     * Event logger
+     */
+    public static final int EVENT_LOGGER = 66;
+
+    /**
+     * Exception
+     */
+    public static final int EXCEPTION = 67;
+
+    /**
+     * Exponential
+     */
+    public static final int EXPONENTIAL = 68;
+
+    /**
+     * Factory
+     */
+    public static final int FACTORY = 69;
+
+    /**
+     * False
+     */
+    public static final int FALSE = 70;
+
+    /**
+     * File {0}
+     */
+    public static final int FILE_$1 = 71;
+
+    /**
+     * Line {1} in file {0}
+     */
+    public static final int FILE_POSITION_$2 = 72;
+
+    /**
+     * Format
+     */
+    public static final int FORMAT = 73;
+
+    /**
+     * Future
+     */
+    public static final int FUTURE = 74;
+
+    /**
+     * Generic cartesian 2D
+     */
+    public static final int GENERIC_CARTESIAN_2D = 75;
+
+    /**
+     * Generic cartesian 3D
+     */
+    public static final int GENERIC_CARTESIAN_3D = 76;
+
+    /**
+     * Geocentric
+     */
+    public static final int GEOCENTRIC = 77;
+
+    /**
+     * Geocentric radius
+     */
+    public static final int GEOCENTRIC_RADIUS = 78;
+
+    /**
+     * Geocentric transform
+     */
+    public static final int GEOCENTRIC_TRANSFORM = 79;
+
+    /**
+     * Geocentric X
+     */
+    public static final int GEOCENTRIC_X = 80;
+
+    /**
+     * Geocentric Y
+     */
+    public static final int GEOCENTRIC_Y = 81;
+
+    /**
+     * Geocentric Z
+     */
+    public static final int GEOCENTRIC_Z = 82;
+
+    /**
+     * Geodetic 2D
+     */
+    public static final int GEODETIC_2D = 83;
+
+    /**
+     * Geodetic 3D
+     */
+    public static final int GEODETIC_3D = 84;
+
+    /**
+     * Geodetic latitude
+     */
+    public static final int GEODETIC_LATITUDE = 85;
+
+    /**
+     * Geodetic longitude
+     */
+    public static final int GEODETIC_LONGITUDE = 86;
+
+    /**
+     * Geographic coordinates
+     */
+    public static final int GEOGRAPHIC_COORDINATES = 87;
+
+    /**
+     * Geoidal
+     */
+    public static final int GEOIDAL = 88;
+
+    /**
+     * Geoid model derived
+     */
+    public static final int GEOID_MODEL_DERIVED = 89;
+
+    /**
+     * Geophysics
+     */
+    public static final int GEOPHYSICS = 90;
+
+    /**
+     * Greenwich Mean Time (GMT)
+     */
+    public static final int GMT = 91;
+
+    /**
+     * Gradient masks
+     */
+    public static final int GRADIENT_MASKS = 92;
+
+    /**
+     * Gravity-related height
+     */
+    public static final int GRAVITY_RELATED_HEIGHT = 93;
+
+    /**
+     * Gray
+     */
+    public static final int GRAY = 94;
+
+    /**
+     * Green
+     */
+    public static final int GREEN = 95;
+
+    /**
+     * Grid
+     */
+    public static final int GRID = 96;
+
+    /**
+     * Hide
+     */
+    public static final int HIDE = 97;
+
+    /**
+     * Hiden
+     */
+    public static final int HIDEN = 98;
+
+    /**
+     * Horizontal
+     */
+    public static final int HORIZONTAL = 99;
+
+    /**
+     * Horizontal component
+     */
+    public static final int HORIZONTAL_COMPONENT = 100;
+
+    /**
+     * Hue
+     */
+    public static final int HUE = 101;
+
+    /**
+     * Identity
+     */
+    public static final int IDENTITY = 102;
+
+    /**
+     * Images
+     */
+    public static final int IMAGES = 103;
+
+    /**
+     * Image of class "{0}"
+     */
+    public static final int IMAGE_CLASS_$1 = 104;
+
+    /**
+     * Image size
+     */
+    public static final int IMAGE_SIZE = 105;
+
+    /**
+     * {0} × {1} pixels × {2} bands
+     */
+    public static final int IMAGE_SIZE_$3 = 106;
+
+    /**
+     * Implementations
+     */
+    public static final int IMPLEMENTATIONS = 107;
+
+    /**
+     * Index
+     */
+    public static final int INDEX = 108;
+
+    /**
+     * Indexed
+     */
+    public static final int INDEXED = 109;
+
+    /**
+     * Informations
+     */
+    public static final int INFORMATIONS = 110;
+
+    /**
+     * Inside
+     */
+    public static final int INSIDE = 111;
+
+    /**
+     * Inverse {0}
+     */
+    public static final int INVERSE_$1 = 112;
+
+    /**
+     * Inverse operation
+     */
+    public static final int INVERSE_OPERATION = 113;
+
+    /**
+     * Inverse transform
+     */
+    public static final int INVERSE_TRANSFORM = 114;
+
+    /**
+     * {0}
+     */
+    public static final int JAVA_VENDOR_$1 = 115;
+
+    /**
+     * Java version {0}
+     */
+    public static final int JAVA_VERSION_$1 = 116;
+
+    /**
+     * Julian
+     */
+    public static final int JULIAN = 117;
+
+    /**
+     * Kernel
+     */
+    public static final int KERNEL = 118;
+
+    /**
+     * Lambert conformal conic projection
+     */
+    public static final int LAMBERT_CONFORMAL_PROJECTION = 119;
+
+    /**
+     * Latitude
+     */
+    public static final int LATITUDE = 120;
+
+    /**
+     * Left
+     */
+    public static final int LEFT = 121;
+
+    /**
+     * Level
+     */
+    public static final int LEVEL = 122;
+
+    /**
+     * Lightness
+     */
+    public static final int LIGHTNESS = 123;
+
+    /**
+     * Lines
+     */
+    public static final int LINES = 124;
+
+    /**
+     * Line {0}
+     */
+    public static final int LINE_$1 = 125;
+
+    /**
+     * Loading {0}...
+     */
+    public static final int LOADING_$1 = 126;
+
+    /**
+     * Loading images {0} and {1}
+     */
+    public static final int LOADING_IMAGES_$2 = 127;
+
+    /**
+     * Loading image {0}
+     */
+    public static final int LOADING_IMAGE_$1 = 128;
+
+    /**
+     * Local
+     */
+    public static final int LOCAL = 129;
+
+    /**
+     * Logarithmic
+     */
+    public static final int LOGARITHMIC = 130;
+
+    /**
+     * Logger
+     */
+    public static final int LOGGER = 131;
+
+    /**
+     * Longitude
+     */
+    public static final int LONGITUDE = 132;
+
+    /**
+     * Magenta
+     */
+    public static final int MAGENTA = 133;
+
+    /**
+     * Magnifier
+     */
+    public static final int MAGNIFIER = 134;
+
+    /**
+     * Math transform
+     */
+    public static final int MATH_TRANSFORM = 135;
+
+    /**
+     * Maximum
+     */
+    public static final int MAXIMUM = 136;
+
+    /**
+     * Allocated memory: {0} MB
+     */
+    public static final int MEMORY_HEAP_SIZE_$1 = 137;
+
+    /**
+     * Allocation used: {0,number,percent}
+     */
+    public static final int MEMORY_HEAP_USAGE_$1 = 138;
+
+    /**
+     * Message
+     */
+    public static final int MESSAGE = 139;
+
+    /**
+     * Method
+     */
+    public static final int METHOD = 140;
+
+    /**
+     * Minimum
+     */
+    public static final int MINIMUM = 141;
+
+    /**
+     * Modified Julian
+     */
+    public static final int MODIFIED_JULIAN = 142;
+
+    /**
+     * Molodenski transform
+     */
+    public static final int MOLODENSKI_TRANSFORM = 143;
+
+    /**
+     * ... {0} more...
+     */
+    public static final int MORE_$1 = 144;
+
+    /**
+     * NADCON transform
+     */
+    public static final int NADCON_TRANSFORM = 145;
+
+    /**
+     * Name
+     */
+    public static final int NAME = 146;
+
+    /**
+     * No data
+     */
+    public static final int NODATA = 147;
+
+    /**
+     * Normal
+     */
+    public static final int NORMAL = 148;
+
+    /**
+     * North
+     */
+    public static final int NORTH = 149;
+
+    /**
+     * Northing
+     */
+    public static final int NORTHING = 150;
+
+    /**
+     * Note
+     */
+    public static final int NOTE = 151;
+
+    /**
+     * {0} (no details)
+     */
+    public static final int NO_DETAILS_$1 = 152;
+
+    /**
+     * No duplicated value found.
+     */
+    public static final int NO_DUPLICATION_FOUND = 153;
+
+    /**
+     * Oblique Mercator projection
+     */
+    public static final int OBLIQUE_MERCATOR_PROJECTION = 154;
+
+    /**
+     * Ok
+     */
+    public static final int OK = 155;
+
+    /**
+     * Operations
+     */
+    public static final int OPERATIONS = 156;
+
+    /**
+     * "{0}" operation
+     */
+    public static final int OPERATION_$1 = 157;
+
+    /**
+     * Order
+     */
+    public static final int ORDER = 158;
+
+    /**
+     * Orthodromic distance
+     */
+    public static final int ORTHODROMIC_DISTANCE = 159;
+
+    /**
+     * Orthographic projection
+     */
+    public static final int ORTHOGRAPHIC_PROJECTION = 160;
+
+    /**
+     * Orthometric
+     */
+    public static final int ORTHOMETRIC = 161;
+
+    /**
+     * {0} system
+     */
+    public static final int OS_NAME_$1 = 162;
+
+    /**
+     * Version {0} for {1}
+     */
+    public static final int OS_VERSION_$2 = 163;
+
+    /**
+     * Other
+     */
+    public static final int OTHER = 164;
+
+    /**
+     * Others
+     */
+    public static final int OTHERS = 165;
+
+    /**
+     * Outside
+     */
+    public static final int OUTSIDE = 166;
+
+    /**
+     * Palette
+     */
+    public static final int PALETTE = 167;
+
+    /**
+     * Parameter {0}
+     */
+    public static final int PARAMETER_$1 = 168;
+
+    /**
+     * Past
+     */
+    public static final int PAST = 169;
+
+    /**
+     * Personalized
+     */
+    public static final int PERSONALIZED = 170;
+
+    /**
+     * Pixels
+     */
+    public static final int PIXELS = 171;
+
+    /**
+     * {0} points on a {1} × {2} grid.
+     */
+    public static final int POINT_COUNT_IN_GRID_$3 = 172;
+
+    /**
+     * Polyconic projection
+     */
+    public static final int POLYCONIC_PROJECTION = 251;
+
+    /**
+     * Predefined kernels
+     */
+    public static final int PREDEFINED_KERNELS = 173;
+
+    /**
+     * Preferred resolution
+     */
+    public static final int PREFERRED_RESOLUTION = 174;
+
+    /**
+     * Preview
+     */
+    public static final int PREVIEW = 175;
+
+    /**
+     * Progression
+     */
+    public static final int PROGRESSION = 176;
+
+    /**
+     * Projected
+     */
+    public static final int PROJECTED = 177;
+
+    /**
+     * Properties
+     */
+    public static final int PROPERTIES = 178;
+
+    /**
+     * {0} bits real number
+     */
+    public static final int REAL_NUMBER_$1 = 179;
+
+    /**
+     * Area: x=[{0} .. {1}], y=[{2} .. {3}]
+     */
+    public static final int RECTANGLE_$4 = 180;
+
+    /**
+     * Red
+     */
+    public static final int RED = 181;
+
+    /**
+     * Reset
+     */
+    public static final int RESET = 182;
+
+    /**
+     * Right
+     */
+    public static final int RIGHT = 183;
+
+    /**
+     * Root mean squared error.
+     */
+    public static final int ROOT_MEAN_SQUARED_ERROR = 184;
+
+    /**
+     * Rotate left
+     */
+    public static final int ROTATE_LEFT = 185;
+
+    /**
+     * Rotate right
+     */
+    public static final int ROTATE_RIGHT = 186;
+
+    /**
+     * Row
+     */
+    public static final int ROW = 187;
+
+    /**
+     * Running tasks
+     */
+    public static final int RUNNING_TASKS = 188;
+
+    /**
+     * Sample model
+     */
+    public static final int SAMPLE_MODEL = 189;
+
+    /**
+     * Saturation
+     */
+    public static final int SATURATION = 190;
+
+    /**
+     * Saving {0}...
+     */
+    public static final int SAVING_$1 = 191;
+
+    /**
+     * Scale 1:{0} (approximative)
+     */
+    public static final int SCALE_$1 = 192;
+
+    /**
+     * Search
+     */
+    public static final int SEARCH = 193;
+
+    /**
+     * Set preferred resolution
+     */
+    public static final int SET_PREFERRED_RESOLUTION = 194;
+
+    /**
+     * Show magnifier
+     */
+    public static final int SHOW_MAGNIFIER = 195;
+
+    /**
+     * {0} bits signed integer
+     */
+    public static final int SIGNED_INTEGER_$1 = 196;
+
+    /**
+     * Size
+     */
+    public static final int SIZE = 197;
+
+    /**
+     * {0} × {1}
+     */
+    public static final int SIZE_$2 = 198;
+
+    /**
+     * (in angle minutes)
+     */
+    public static final int SIZE_IN_MINUTES = 199;
+
+    /**
+     * Source CRS
+     */
+    public static final int SOURCE_CRS = 200;
+
+    /**
+     * Source point
+     */
+    public static final int SOURCE_POINT = 201;
+
+    /**
+     * South
+     */
+    public static final int SOUTH = 202;
+
+    /**
+     * Southing
+     */
+    public static final int SOUTHING = 203;
+
+    /**
+     * Spherical
+     */
+    public static final int SPHERICAL = 204;
+
+    /**
+     * Spherical latitude
+     */
+    public static final int SPHERICAL_LATITUDE = 205;
+
+    /**
+     * Spherical longitude
+     */
+    public static final int SPHERICAL_LONGITUDE = 206;
+
+    /**
+     * Start time
+     */
+    public static final int START_TIME = 207;
+
+    /**
+     * Stereographic projection
+     */
+    public static final int STEREOGRAPHIC_PROJECTION = 208;
+
+    /**
+     * System
+     */
+    public static final int SYSTEM = 209;
+
+    /**
+     * Target
+     */
+    public static final int TARGET = 210;
+
+    /**
+     * Target CRS
+     */
+    public static final int TARGET_CRS = 211;
+
+    /**
+     * Target point
+     */
+    public static final int TARGET_POINT = 212;
+
+    /**
+     * Tasks
+     */
+    public static final int TASKS = 213;
+
+    /**
+     * Temporal
+     */
+    public static final int TEMPORAL = 214;
+
+    /**
+     * Tiles size
+     */
+    public static final int TILES_SIZE = 215;
+
+    /**
+     * Tile cache capacity: {0} MB
+     */
+    public static final int TILE_CACHE_CAPACITY_$1 = 216;
+
+    /**
+     * {0}×{1} tiles of {2} × {3} pixels
+     */
+    public static final int TILE_SIZE_$4 = 217;
+
+    /**
+     * Time
+     */
+    public static final int TIME = 218;
+
+    /**
+     * Time
+     */
+    public static final int TIME_OF_DAY = 219;
+
+    /**
+     * Time range
+     */
+    public static final int TIME_RANGE = 220;
+
+    /**
+     * Time zone
+     */
+    public static final int TIME_ZONE = 221;
+
+    /**
+     * Transformation
+     */
+    public static final int TRANSFORMATION = 222;
+
+    /**
+     * Transformation accuracy
+     */
+    public static final int TRANSFORMATION_ACCURACY = 223;
+
+    /**
+     * Transparency
+     */
+    public static final int TRANSPARENCY = 224;
+
+    /**
+     * Transverse Mercator projection
+     */
+    public static final int TRANSVERSE_MERCATOR_PROJECTION = 225;
+
+    /**
+     * True
+     */
+    public static final int TRUE = 226;
+
+    /**
+     * Truncated Julian
+     */
+    public static final int TRUNCATED_JULIAN = 227;
+
+    /**
+     * Type
+     */
+    public static final int TYPE = 228;
+
+    /**
+     * Undefined
+     */
+    public static final int UNDEFINED = 229;
+
+    /**
+     * Unknow
+     */
+    public static final int UNKNOW = 230;
+
+    /**
+     * {0} bits unsigned integer ({1} bits/pixel)
+     */
+    public static final int UNSIGNED_INTEGER_$2 = 231;
+
+    /**
+     * Untitled
+     */
+    public static final int UNTITLED = 232;
+
+    /**
+     * Up
+     */
+    public static final int UP = 233;
+
+    /**
+     * Use best resolution
+     */
+    public static final int USE_BEST_RESOLUTION = 234;
+
+    /**
+     * Universal Time (UTC)
+     */
+    public static final int UTC = 235;
+
+    /**
+     * Value
+     */
+    public static final int VALUE = 236;
+
+    /**
+     * Vendor
+     */
+    public static final int VENDOR = 237;
+
+    /**
+     * Version {0}
+     */
+    public static final int VERSION_$1 = 238;
+
+    /**
+     * "{0}" version
+     */
+    public static final int VERSION_OF_$1 = 239;
+
+    /**
+     * Vertical
+     */
+    public static final int VERTICAL = 240;
+
+    /**
+     * Vertical component
+     */
+    public static final int VERTICAL_COMPONENT = 241;
+
+    /**
+     * Warning
+     */
+    public static final int WARNING = 242;
+
+    /**
+     * West
+     */
+    public static final int WEST = 243;
+
+    /**
+     * Westing
+     */
+    public static final int WESTING = 244;
+
+    /**
+     * Yellow
+     */
+    public static final int YELLOW = 245;
+
+    /**
+     * Zoom in
+     */
+    public static final int ZOOM_IN = 246;
+
+    /**
+     * Close zoom
+     */
+    public static final int ZOOM_MAX = 247;
+
+    /**
+     * Zoom out
+     */
+    public static final int ZOOM_OUT = 248;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/resources/package.html	(revision 28000)
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.resources</TITLE>
+  </HEAD>
+  <BODY>
+    A set of helper classes for Geotools implementation;
+
+    <STRONG>Do not use!</STRONG>.
+
+    This package is for internal use only. Classes in this package may change
+    in incompatible ways in any future version.
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/AbstractInternationalString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/AbstractInternationalString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/AbstractInternationalString.java	(revision 28000)
@@ -0,0 +1,175 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.util;
+
+import java.util.Locale;
+import org.opengis.util.InternationalString;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * A {@linkplain String string} that has been internationalized into several
+ * {@linkplain Locale locales}. This class is used as a replacement for the
+ * {@link String} type whenever an attribute needs to be internationalization
+ * capable. The default value (as returned by {@link #toString()} and other
+ * {@link CharSequence} methods} is the string in the current {@linkplain
+ * Locale#getDefault system default}.
+ * <P>
+ * The {@linkplain Comparable natural ordering} is defined by the string in
+ * {@linkplain Locale#getDefault default locale}, as returned by {@link #toString()}.
+ * This string also defines the {@linkplain CharSequence character sequence}.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/AbstractInternationalString.java $
+ * @version $Id: AbstractInternationalString.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public abstract class AbstractInternationalString implements InternationalString {
+    /**
+     * The string in the {@linkplain Locale#getDefault system default} locale, or {@code null}
+     * if this string has not yet been determined. This is the default string returned by
+     * {@link #toString()} and others methods from the {@link CharSequence} interface.
+     * <P>
+     * This field is not serialized because serialization is often used for data transmission
+     * between a server and a client, and the client may not use the same locale than the server.
+     * We want the locale to be examined again on the client side.
+     * <P>
+     * This field is read and write by {@link SimpleInternationalString}.
+     */
+    transient String defaultValue;
+
+    /**
+     * Constructs an international string.
+     */
+    public AbstractInternationalString() {
+    }
+
+    /**
+     * Makes sure an argument is non-null.
+     *
+     * @param  name   Argument name.
+     * @param  object User argument.
+     * @throws IllegalArgumentException if {@code object} is null.
+     */
+    static void ensureNonNull(final String name, final Object object)
+            throws IllegalArgumentException
+    {
+        if (object == null) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1, name));
+        }
+    }
+
+    /**
+     * Returns the length of the string in the {@linkplain Locale#getDefault default locale}.
+     * This is the length of the string returned by {@link #toString()}.
+     */
+    public int length() {
+        if (defaultValue == null) {
+            defaultValue = toString();
+            if (defaultValue == null) {
+                return 0;
+            }
+        }
+        return defaultValue.length();
+    }
+
+    /**
+     * Returns the character of the string in the {@linkplain Locale#getDefault default locale}
+     * at the specified index. This is the character of the string returned by {@link #toString()}.
+     *
+     * @param  index The index of the character.
+     * @return The character at the specified index.
+     * @throws IndexOutOfBoundsException if the specified index is out of bounds.
+     */
+    public char charAt(final int index) throws IndexOutOfBoundsException {
+        if (defaultValue == null) {
+            defaultValue = toString();
+            if (defaultValue == null) {
+                throw new IndexOutOfBoundsException(String.valueOf(index));
+            }
+        }
+        return defaultValue.charAt(index);
+    }
+
+    /**
+     * Returns a subsequence of the string in the {@linkplain Locale#getDefault default locale}.
+     * The subsequence is a {@link String} object starting with the character value at the specified
+     * index and ending with the character value at index {@code end - 1}.
+     *
+     * @param   start The start index, inclusive.
+     * @param   end   The end index, exclusive.
+     * @return  The specified subsequence.
+     * @throws  IndexOutOfBoundsException  if {@code start} or {@code end} is out of range.
+     */
+    public CharSequence subSequence(final int start, final int end) {
+        if (defaultValue == null) {
+            defaultValue = toString();
+            if (defaultValue == null) {
+                throw new IndexOutOfBoundsException(String.valueOf(start));
+            }
+        }
+        return defaultValue.substring(start, end);
+    }
+
+    /**
+     * Returns this string in the given locale. If no string is available in the given locale,
+     * then some default locale is used. The default locale is implementation-dependent. It
+     * may or may not be the {@linkplain Locale#getDefault() system default}).
+     *
+     * @param  locale The desired locale for the string to be returned, or {@code null}
+     *         for a string in the implementation default locale.
+     * @return The string in the given locale if available, or in the default locale otherwise.
+     */
+    public abstract String toString(final Locale locale);
+
+    /**
+     * Returns this string in the default locale. Invoking this method is equivalent to invoking
+     * <code>{@linkplain #toString(Locale) toString}({@linkplain Locale#getDefault})</code>. All
+     * methods from {@link CharSequence} operate on this string. This string is also used as the
+     * criterion for {@linkplain Comparable natural ordering}.
+     *
+     * @return The string in the default locale.
+     */
+    @Override
+    public String toString() {
+        if (defaultValue == null) {
+            defaultValue = toString(Locale.getDefault());
+            if (defaultValue == null) {
+                return "";
+            }
+        }
+        return defaultValue;
+    }
+
+    /**
+     * Compares this string with the specified object for order. This method compare
+     * the string in the {@linkplain Locale#getDefault default locale}, as returned
+     * by {@link #toString()}.
+     *
+     * @param object The string to compare with this string.
+     * @return A negative number if this string is before the given string, a positive
+     *         number if after, or 0 if equals.
+     */
+    public int compareTo(final InternationalString object) {
+        return toString().compareTo(object.toString());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/CanonicalSet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/CanonicalSet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/CanonicalSet.java	(revision 28000)
@@ -0,0 +1,108 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+
+/**
+ * A canonical set of objects, used to optimize memory use.
+ * The operation of this set is similar in spirit to the {@link String#intern} method.
+ * The following example shows a convenient way to use {@code CanonicalSet} as an
+ * internal pool of immutable objects.
+ *
+ * <blockquote><pre>
+ * public Foo create(String definition) {
+ *      Foo created = new Foo(definition);
+ *      return (Foo) canonicalSet.unique(created);
+ * }
+ * </pre></blockquote>
+ *
+ * The {@code CanonicalSet} has a {@link #get} method that is not part of the {@link java.util.Set}
+ * interface. This {@code get} method retrieves an entry from this set that is equals to
+ * the supplied object. The {@link #unique} method combines a {@code get} followed by a
+ * {@code put} operation if the specified object was not in the set.
+ * <p>
+ * The set of objects is held by weak references as explained in {@link WeakHashSet}.
+ * The {@code CanonicalSet} class is thread-safe.
+ *
+ * @param <E> The type of elements in the set.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/CanonicalSet.java $
+ * @version $Id: CanonicalSet.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ * @author Jody Garnett
+ */
+public class CanonicalSet<E> extends WeakHashSet<E> {
+    /**
+     * Constructs a {@code CanonicalSet}.
+     *
+     * @deprecated Use {@link #newInstance} instead.
+     */
+    public CanonicalSet() {
+    }
+
+    /**
+     * Constructs a {@code CanonicalSet} for elements of the specified type.
+     *
+     * @param type The type of elements in the set.
+     *
+     * @since 2.5
+     */
+    protected CanonicalSet(final Class<E> type) {
+        super(type);
+    }
+
+    /**
+     * Constructs a {@code CanonicalSet} for elements of the specified type.
+     *
+     * @param <E>  The type of elements in the set.
+     * @param type The type of elements in the set.
+     * @return An initially empty set for elements of the given type.
+     *
+     * @since 2.5
+     */
+    public static <E> CanonicalSet<E> newInstance(final Class<E> type) {
+        return new CanonicalSet<E>(type);
+    }
+
+    /**
+     * Returns an object equals to {@code object} if such an object already exist in this
+     * {@code CanonicalSet}. Otherwise, adds {@code object} to this {@code CanonicalSet}.
+     * This method is equivalents to the following code:
+     *
+     * <blockquote><pre>
+     * if (object != null) {
+     *     Object current = get(object);
+     *     if (current != null) {
+     *         return current;
+     *     } else {
+     *         add(object);
+     *     }
+     * }
+     * return object;
+     * </pre></blockquote>
+     *
+     * @param <T> The type of the element to get.
+     * @param object The element to get or to add in the set if not already presents.
+     * @return An element equals to the given one if already presents in the set,
+     *         or the given {@code object} otherwise.
+     */
+    public synchronized <T extends E> T unique(final T object) {
+        return intern(object, INTERN);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/CheckedArrayList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/CheckedArrayList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/CheckedArrayList.java	(revision 28000)
@@ -0,0 +1,488 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.opengis.util.Cloneable;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * A {@linkplain Collections#checkedList checked} and {@linkplain Collections#synchronizedList
+ * synchronized} {@link java.util.List}. Type checks are performed at run-time in addition of
+ * compile-time checks. The synchronization lock can be modified at runtime by overriding the
+ * {@link #getLock} method.
+ * <p>
+ * This class is similar to using the wrappers provided in {@link Collections}, minus the cost
+ * of indirection levels and with the addition of overrideable methods.
+ *
+ * @param <E> The type of elements in the list.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/CheckedArrayList.java $
+ * @version $Id: CheckedArrayList.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Jody Garnett (Refractions Research)
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see Collections#checkedList
+ * @see Collections#synchronizedList
+ */
+public class CheckedArrayList<E> extends ArrayList<E> implements CheckedCollection<E>, Cloneable {
+    /**
+     * Serial version UID for compatibility with different versions.
+     */
+    private static final long serialVersionUID = -587331971085094268L;
+
+    /**
+     * The element type.
+     */
+    private final Class<E> type;
+
+    /**
+     * Constructs a list of the specified type.
+     *
+     * @param type The element type (should not be null).
+     */
+    public CheckedArrayList(final Class<E> type) {
+        super();
+        this.type = type;
+        ensureNonNull();
+    }
+
+    /**
+     * Constructs a list of the specified type and initial capacity.
+     *
+     * @param type The element type (should not be null).
+     * @param capacity The initial capacity.
+     *
+     * @since 2.4
+     */
+    public CheckedArrayList(final Class<E> type, final int capacity) {
+        super(capacity);
+        this.type = type;
+        ensureNonNull();
+    }
+
+    /**
+     * Returns the element type given at construction time.
+     *
+     * @since 2.4
+     */
+    public Class<E> getElementType() {
+        return type;
+    }
+
+    /**
+     * Make sure that {@link #type} is non-null.
+     */
+    private void ensureNonNull() {
+        if (type == null) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1, "type"));
+        }
+    }
+
+    /**
+     * Checks the type of the specified object. The default implementation ensure
+     * that the object is assignable to the type specified at construction time.
+     *
+     * @param  element the object to check, or {@code null}.
+     * @throws IllegalArgumentException if the specified element is not of the expected type.
+     */
+    protected void ensureValidType(final E element) throws IllegalArgumentException {
+        if (element!=null && !type.isInstance(element)) {
+            throw new IllegalArgumentException(Errors.format(
+                    ErrorKeys.ILLEGAL_CLASS_$2, element.getClass(), type));
+        }
+    }
+
+    /**
+     * Checks the type of all elements in the specified collection.
+     *
+     * @param  collection the collection to check, or {@code null}.
+     * @throws IllegalArgumentException if at least one element is not of the expected type.
+     */
+    private void ensureValid(final Collection<? extends E> collection) throws IllegalArgumentException {
+        if (collection != null) {
+            for (final E element : collection) {
+                ensureValidType(element);
+            }
+        }
+    }
+
+    /**
+     * Checks if changes in this collection are allowed. This method is automatically invoked
+     * after this collection got the {@linkplain #getLock lock} and before any operation that
+     * may change the content. The default implementation does nothing (i.e. this collection
+     * is modifiable). Subclasses should override this method if they want to control write
+     * access.
+     *
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     *
+     * @since 2.5
+     */
+    protected void checkWritePermission() throws UnsupportedOperationException {
+    }
+
+    /**
+     * Returns the synchronization lock. The default implementation returns {@code this}.
+     * Subclasses that override this method should be careful to update the lock reference
+     * when this list is {@linkplain #clone cloned}.
+     *
+     * @return The synchronization lock.
+     *
+     * @since 2.5
+     */
+    protected Object getLock() {
+        return this;
+    }
+
+    /**
+     * Returns an iterator over the elements in this list.
+     */
+    @Override
+    public Iterator<E> iterator() {
+        final Object lock = getLock();
+        synchronized (lock) {
+            return new SynchronizedIterator<E>(super.iterator(), lock);
+        }
+    }
+
+    // Note: providing a synchronized iterator is a little bit of paranoia because the ArrayList
+    // implementation inherits the default AbstractList implementation, which delegates its work
+    // to the public List methods. And the later are synchronized. We do not override ListIterator
+    // for this reason and because it is less used.
+
+    /**
+     * Returns the number of elements in this list.
+     */
+    @Override
+    public int size() {
+	synchronized (getLock()) {
+            return super.size();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this list contains no elements.
+     */
+    @Override
+    public boolean isEmpty() {
+	synchronized (getLock()) {
+            return super.isEmpty();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this list contains the specified element.
+     */
+    @Override
+    public boolean contains(final Object o) {
+	synchronized (getLock()) {
+            return super.contains(o);
+        }
+    }
+
+    /**
+     * Returns the index of the first occurrence of the specified element in this list,
+     * or -1 if none.
+     */
+    @Override
+    public int indexOf(Object o) {
+	synchronized (getLock()) {
+            return super.indexOf(o);
+        }
+    }
+
+    /**
+     * Returns the index of the last occurrence of the specified element in this list,
+     * or -1 if none.
+     */
+    @Override
+    public int lastIndexOf(Object o) {
+	synchronized (getLock()) {
+            return super.lastIndexOf(o);
+        }
+    }
+
+    /**
+     * Returns the element at the specified position in this list.
+     */
+    @Override
+    public E get(int index) {
+        synchronized (getLock()) {
+            return super.get(index);
+        }
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element.
+     *
+     * @param  index   index of element to replace.
+     * @param  element element to be stored at the specified position.
+     * @return the element previously at the specified position.
+     * @throws IndexOutOfBoundsException if index out of range.
+     * @throws IllegalArgumentException if the specified element is not of the expected type.
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public E set(final int index, final E element)
+            throws IllegalArgumentException, UnsupportedOperationException
+    {
+        ensureValidType(element);
+        synchronized (getLock()) {
+            checkWritePermission();
+            return super.set(index, element);
+        }
+    }
+
+    /**
+     * Appends the specified element to the end of this list.
+     *
+     * @param  element element to be appended to this list.
+     * @return always {@code true}.
+     * @throws IllegalArgumentException if the specified element is not of the expected type.
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public boolean add(final E element)
+            throws IllegalArgumentException, UnsupportedOperationException
+    {
+        ensureValidType(element);
+        synchronized (getLock()) {
+            checkWritePermission();
+            return super.add(element);
+        }
+    }
+
+    /**
+     * Inserts the specified element at the specified position in this list.
+     *
+     * @param  index index at which the specified element is to be inserted.
+     * @param  element element to be inserted.
+     * @throws IndexOutOfBoundsException if index out of range.
+     * @throws IllegalArgumentException if the specified element is not of the expected type.
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public void add(final int index, final E element)
+            throws IllegalArgumentException, UnsupportedOperationException
+    {
+        ensureValidType(element);
+        synchronized (getLock()) {
+            checkWritePermission();
+            super.add(index, element);
+        }
+    }
+
+    /**
+     * Appends all of the elements in the specified collection to the end of this list,
+     * in the order that they are returned by the specified Collection's Iterator.
+     *
+     * @param collection the elements to be inserted into this list.
+     * @return {@code true} if this list changed as a result of the call.
+     * @throws IllegalArgumentException if at least one element is not of the expected type.
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public boolean addAll(final Collection<? extends E> collection)
+            throws IllegalArgumentException, UnsupportedOperationException
+    {
+        ensureValid(collection);
+        synchronized (getLock()) {
+            checkWritePermission();
+            return super.addAll(collection);
+        }
+    }
+
+    /**
+     * Inserts all of the elements in the specified collection into this list,
+     * starting at the specified position.
+     *
+     * @param index index at which to insert first element fromm the specified collection.
+     * @param collection elements to be inserted into this list.
+     * @return {@code true} if this list changed as a result of the call.
+     * @throws IllegalArgumentException if at least one element is not of the expected type.
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public boolean addAll(final int index, final Collection<? extends E> collection)
+            throws IllegalArgumentException, UnsupportedOperationException
+    {
+        ensureValid(collection);
+        synchronized (getLock()) {
+            checkWritePermission();
+            return super.addAll(index, collection);
+        }
+    }
+
+    /**
+     * Removes the element at the specified position in this list.
+     *
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public E remove(int index) throws UnsupportedOperationException {
+        synchronized (getLock()) {
+            checkWritePermission();
+            return super.remove(index);
+        }
+    }
+
+    /**
+     * Removes the first occurrence of the specified element from this list.
+     *
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public boolean remove(Object o) throws UnsupportedOperationException {
+        synchronized (getLock()) {
+            checkWritePermission();
+            return super.remove(o);
+        }
+    }
+
+    /**
+     * Removes all of this list's elements that are also contained in the specified collection.
+     *
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public boolean removeAll(Collection<?> c) throws UnsupportedOperationException {
+        synchronized (getLock()) {
+            checkWritePermission();
+            return super.removeAll(c);
+        }
+    }
+
+    /**
+     * Retains only the elements in this list that are contained in the specified collection.
+     *
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public boolean retainAll(Collection<?> c) throws UnsupportedOperationException {
+        synchronized (getLock()) {
+            checkWritePermission();
+            return super.retainAll(c);
+        }
+    }
+
+    /**
+     * Trims the capacity to the list's current size.
+     */
+    @Override
+    public void trimToSize() {
+        synchronized (getLock()) {
+            super.trimToSize();
+        }
+    }
+
+    /**
+     * Increases the capacity, if necessary, to ensure that it can hold the given number
+     * of elements.
+     */
+    @Override
+    public void ensureCapacity(final int minCapacity) {
+        synchronized (getLock()) {
+            super.ensureCapacity(minCapacity);
+        }
+    }
+
+    /**
+     * Removes all of the elements from this list.
+     *
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public void clear() throws UnsupportedOperationException {
+        synchronized (getLock()) {
+            checkWritePermission();
+            super.clear();
+        }
+    }
+
+    /**
+     * Returns an array containing all of the elements in this list.
+     */
+    @Override
+    public Object[] toArray() {
+        synchronized (getLock()) {
+            return super.toArray();
+        }
+    }
+
+    /**
+     * Returns an array containing all of the elements in this list in proper sequence.
+     *
+     * @param <T> The type of array elements.
+     */
+    @Override
+    public <T> T[] toArray(T[] a) {
+        synchronized (getLock()) {
+            return super.toArray(a);
+        }
+    }
+
+    /**
+     * Returns a string representation of this list.
+     */
+    @Override
+    public String toString() {
+        synchronized (getLock()) {
+            return super.toString();
+        }
+    }
+
+    /**
+     * Compares the specified object with this list for equality.
+     */
+    @Override
+    public boolean equals(Object o) {
+        synchronized (getLock()) {
+            return super.equals(o);
+        }
+    }
+
+    /**
+     * Returns the hash code value for this list.
+     */
+    @Override
+    public int hashCode() {
+        synchronized (getLock()) {
+            return super.hashCode();
+        }
+    }
+
+    /**
+     * Returns a shallow copy of this list.
+     *
+     * @return A shallow copy of this list.
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public CheckedArrayList<E> clone() {
+        synchronized (getLock()) {
+            return (CheckedArrayList) super.clone();
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/CheckedCollection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/CheckedCollection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/CheckedCollection.java	(revision 28000)
@@ -0,0 +1,42 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.util.Collection;
+
+
+/**
+ * Collection that ensures that all elements are assignable to a given base type.
+ * The base {@linkplain #getElement type} is usually specified at collection
+ * construction time.
+ *
+ * @param <E> The type of elements in the collection.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/CheckedCollection.java $
+ * @version $Id: CheckedCollection.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ */
+public interface CheckedCollection<E> extends Collection<E> {
+    /**
+     * Returns the element type.
+     *
+     * @return The element type.
+     */
+    Class<E> getElementType();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/CheckedHashSet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/CheckedHashSet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/CheckedHashSet.java	(revision 28000)
@@ -0,0 +1,354 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.util.Iterator;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+
+import org.opengis.util.Cloneable;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * A {@linkplain Collections#checkedSet checked} and {@linkplain Collections#synchronizedSet
+ * synchronized} {@link java.util.Set}. Type checks are performed at run-time in addition of
+ * compile-time checks. The synchronization lock can be modified at runtime by overriding the
+ * {@link #getLock} method.
+ * <p>
+ * This class is similar to using the wrappers provided in {@link Collections}, minus the cost
+ * of indirection levels and with the addition of overrideable methods.
+ *
+ * @param <E> The type of elements in the set.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/CheckedHashSet.java $
+ * @version $Id: CheckedHashSet.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Jody Garnett (Refractions Research)
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see Collections#checkedSet
+ * @see Collections#synchronizedSet
+ */
+public class CheckedHashSet<E> extends LinkedHashSet<E> implements CheckedCollection<E>, Cloneable {
+    /**
+     * Serial version UID for compatibility with different versions.
+     */
+    private static final long serialVersionUID = -9014541457174735097L;
+
+    /**
+     * The element type.
+     */
+    private final Class<E> type;
+
+    /**
+     * Constructs a set of the specified type.
+     *
+     * @param type The element type (should not be null).
+     */
+    public CheckedHashSet(final Class<E> type) {
+        super();
+        this.type = type;
+        ensureNonNull();
+    }
+
+    /**
+     * Constructs a set of the specified type and initial capacity.
+     *
+     * @param type The element type (should not be null).
+     * @param capacity The initial capacity.
+     *
+     * @since 2.4
+     */
+    public CheckedHashSet(final Class<E> type, final int capacity) {
+        super(capacity);
+        this.type = type;
+        ensureNonNull();
+    }
+
+    /**
+     * Make sure that {@link #type} is non-null.
+     */
+    private void ensureNonNull() {
+        if (type == null) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1, "type"));
+        }
+    }
+
+    /**
+     * Returns the element type given at construction time.
+     *
+     * @since 2.4
+     */
+    public Class<E> getElementType() {
+        return type;
+    }
+
+    /**
+     * Checks the type of the specified object. The default implementation ensure
+     * that the object is assignable to the type specified at construction time.
+     *
+     * @param  element the object to check, or {@code null}.
+     * @throws IllegalArgumentException if the specified element is not of the expected type.
+     */
+    protected void ensureValidType(final E element) throws IllegalArgumentException {
+        if (element!=null && !type.isInstance(element)) {
+            throw new IllegalArgumentException(Errors.format(
+                    ErrorKeys.ILLEGAL_CLASS_$2, element.getClass(), type));
+        }
+    }
+
+    /**
+     * Checks the type of all elements in the specified collection.
+     *
+     * @param  collection the collection to check, or {@code null}.
+     * @throws IllegalArgumentException if at least one element is not of the expected type.
+     */
+    private void ensureValid(final Collection<? extends E> collection) throws IllegalArgumentException {
+        if (collection != null) {
+            for (final E element : collection) {
+                ensureValidType(element);
+            }
+        }
+    }
+
+    /**
+     * Checks if changes in this collection are allowed. This method is automatically invoked
+     * after this collection got the {@linkplain #getLock lock} and before any operation that
+     * may change the content. The default implementation does nothing (i.e. this collection
+     * is modifiable). Subclasses should override this method if they want to control write
+     * access.
+     *
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     *
+     * @since 2.5
+     */
+    protected void checkWritePermission() throws UnsupportedOperationException {
+    }
+
+    /**
+     * Returns the synchronization lock. The default implementation returns {@code this}.
+     * Subclasses that override this method should be careful to update the lock reference
+     * when this set is {@linkplain #clone cloned}.
+     *
+     * @return The synchronization lock.
+     *
+     * @since 2.5
+     */
+    protected Object getLock() {
+        return this;
+    }
+
+    /**
+     * Returns an iterator over the elements in this set.
+     */
+    @Override
+    public Iterator<E> iterator() {
+        final Object lock = getLock();
+        synchronized (lock) {
+            return new SynchronizedIterator<E>(super.iterator(), lock);
+        }
+    }
+
+    /**
+     * Returns the number of elements in this set.
+     */
+    @Override
+    public int size() {
+	synchronized (getLock()) {
+            return super.size();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this set contains no elements.
+     */
+    @Override
+    public boolean isEmpty() {
+	synchronized (getLock()) {
+            return super.isEmpty();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this set contains the specified element.
+     */
+    @Override
+    public boolean contains(final Object o) {
+	synchronized (getLock()) {
+            return super.contains(o);
+        }
+    }
+
+    /**
+     * Adds the specified element to this set if it is not already present.
+     *
+     * @param  element element to be added to this set.
+     * @return {@code true} if the set did not already contain the specified element.
+     * @throws IllegalArgumentException if the specified element is not of the expected type.
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public boolean add(final E element)
+            throws IllegalArgumentException, UnsupportedOperationException
+    {
+        ensureValidType(element);
+	synchronized (getLock()) {
+            checkWritePermission();
+            return super.add(element);
+        }
+    }
+
+    /**
+     * Appends all of the elements in the specified collection to this set.
+     *
+     * @param collection the elements to be inserted into this set.
+     * @return {@code true} if this set changed as a result of the call.
+     * @throws IllegalArgumentException if at least one element is not of the expected type.
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public boolean addAll(final Collection<? extends E> collection)
+            throws IllegalArgumentException, UnsupportedOperationException
+    {
+        ensureValid(collection);
+        synchronized (getLock()) {
+            checkWritePermission();
+            return super.addAll(collection);
+        }
+    }
+
+    /**
+     * Removes the pecified element from this set.
+     *
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public boolean remove(Object o) throws UnsupportedOperationException {
+        synchronized (getLock()) {
+            checkWritePermission();
+            return super.remove(o);
+        }
+    }
+
+    /**
+     * Removes all of this set's elements that are also contained in the specified collection.
+     *
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public boolean removeAll(Collection<?> c) throws UnsupportedOperationException {
+        synchronized (getLock()) {
+            checkWritePermission();
+            return super.removeAll(c);
+        }
+    }
+
+    /**
+     * Retains only the elements in this set that are contained in the specified collection.
+     *
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public boolean retainAll(Collection<?> c) throws UnsupportedOperationException {
+        synchronized (getLock()) {
+            checkWritePermission();
+            return super.retainAll(c);
+        }
+    }
+
+    /**
+     * Removes all of the elements from this set.
+     *
+     * @throws UnsupportedOperationException if this collection is unmodifiable.
+     */
+    @Override
+    public void clear() throws UnsupportedOperationException {
+        synchronized (getLock()) {
+            checkWritePermission();
+            super.clear();
+        }
+    }
+
+    /**
+     * Returns an array containing all of the elements in this set.
+     */
+    @Override
+    public Object[] toArray() {
+        synchronized (getLock()) {
+            return super.toArray();
+        }
+    }
+
+    /**
+     * Returns an array containing all of the elements in this set.
+     *
+     * @param <T> The type of array elements.
+     */
+    @Override
+    public <T> T[] toArray(T[] a) {
+        synchronized (getLock()) {
+            return super.toArray(a);
+        }
+    }
+
+    /**
+     * Returns a string representation of this set.
+     */
+    @Override
+    public String toString() {
+        synchronized (getLock()) {
+            return super.toString();
+        }
+    }
+
+    /**
+     * Compares the specified object with this set for equality.
+     */
+    @Override
+    public boolean equals(Object o) {
+        synchronized (getLock()) {
+            return super.equals(o);
+        }
+    }
+
+    /**
+     * Returns the hash code value for this set.
+     */
+    @Override
+    public int hashCode() {
+        synchronized (getLock()) {
+            return super.hashCode();
+        }
+    }
+
+    /**
+     * Returns a shallow copy of this set.
+     *
+     * @return A shallow copy of this set.
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public CheckedHashSet<E> clone() {
+        synchronized (getLock()) {
+            return (CheckedHashSet) super.clone();
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/Converter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/Converter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/Converter.java	(revision 28000)
@@ -0,0 +1,46 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+
+/**
+ * Converts values of one type into another.
+ *
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ * @since 2.4
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/util/Converter.java $
+ */
+public interface Converter {
+    /**
+     * Converts an object to an object of another type.
+     * <p>
+     * If the converstion supplied is not supported this method can either throw an exception or
+     * return <code>null</code>.
+     * </p>
+     *
+     * @param source The original object, never <code>null</code>
+     * @param target The type of the converted object.
+     *
+     * @return An instance of target, or <code>null</code> if the conversion could not take place.
+     *
+     * @throws Exception If the conversion can not take place.
+     */
+    <T> T convert(Object source, Class<T> target) throws Exception;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/ConverterFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/ConverterFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/ConverterFactory.java	(revision 28000)
@@ -0,0 +1,53 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import org.geotools.factory.Hints;
+import org.geotools.factory.Hints.Key;
+
+
+/**
+ * Factory used to create instances of {@link Converter}.
+ *
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ * @since 2.4
+ *
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/util/ConverterFactory.java $
+ */
+public interface ConverterFactory {
+    
+    /**
+    * Hint which specifies if only safe conversions should be atttemped by 
+    * converter implementations.
+    */
+    static final Key SAFE_CONVERSION = new Key(Boolean.class);
+    
+    /**
+     * Creates a {@link Converter} instance for converting one type
+     * of object to another.
+     *
+     * @param source The type to convert from.
+     * @param target The type to convert to.
+     * @param hints Hints used to be used while creating a converter.
+     *
+     * @return The converter, or <code>null</code> if one could not be found.
+     */
+    Converter createConverter(Class<?> source, Class<?> target, Hints hints);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/Converters.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/Converters.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/Converters.java	(revision 28000)
@@ -0,0 +1,165 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.factory.FactoryCreator;
+import org.geotools.factory.FactoryRegistry;
+import org.geotools.factory.GeoTools;
+import org.geotools.factory.Hints;
+import org.geotools.resources.LazySet;
+import org.geotools.util.logging.Logging;
+
+/**
+ * Convenience class for converting an object from one type to an object of another.
+ *
+ * @author Justin Deoliveira, The Open Planning Project
+ * @since 2.4
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/api/src/main/java/org/geotools/util/Converters.java $
+ */
+public final class Converters {
+    
+    private static final Logger LOGGER = Logging.getLogger(Converters.class); 
+
+	/**
+	 * Cached list of converter factories
+	 */
+	static ConverterFactory[] factories;
+
+    /**
+     * The service registry for this manager.
+     * Will be initialized only when first needed.
+     */
+    private static FactoryRegistry registry;
+
+    /**
+     * Returns the service registry. The registry will be created the first
+     * time this method is invoked.
+     */
+    private static FactoryRegistry getServiceRegistry() {
+        assert Thread.holdsLock(Converters.class);
+        if (registry == null) {
+            registry = new FactoryCreator(Arrays.asList(new Class<?>[] {
+            		ConverterFactory.class,}));
+        }
+        return registry;
+    }
+
+    private static Hints addDefaultHints(final Hints hints) {
+        final Hints completed = GeoTools.getDefaultHints();
+        if (hints != null) {
+            completed.add(hints);
+        }
+        return completed;
+    }
+
+
+    /**
+     * Returns a set of all available implementations for the {@link ConverterFactory} interface.
+     *
+     * @param  hints An optional map of hints, or {@code null} if none.
+     * @return Set of available ConverterFactory implementations.
+     */
+    public static synchronized Set getConverterFactories(Hints hints) {
+        hints = addDefaultHints(hints);
+        return new LazySet(getServiceRegistry().getServiceProviders(
+                ConverterFactory.class, null, hints));
+    }
+
+	/**
+	 * Convenience for {@link #convert(Object, Class, Hints)}
+	 * @param source The object to convert.
+         * @param target The type of the converted value.
+	 * @return The converted value as an instance of target, or <code>null</code> if a converter
+         * could not be found
+	 * @since 2.4
+	 */
+	public static <T> T convert( Object source, Class<T> target ) {
+	    return convert( source, target, null );
+	}
+
+	/**
+	 * Converts an object of a particular type into an object of a differnt type.
+	 * <p>
+	 * This method uses the {@link ConverterFactory} extension point to find a converter capable
+	 * of performing the conversion. The first converter found is the one used. Using this class
+	 * there is no way to guarantee which converter will be used.
+	 * </p>
+	 * @param source The object to convert.
+	 * @param target The type of the converted value.
+	 * @param hints Any hints for the converter factory.
+	 *
+	 * @return The converted value as an instance of target, or <code>null</code> if a converter
+	 * could not be found.
+	 *
+	 * @since 2.4
+	 */
+	public static <T> T convert( Object source, Class<T> target, Hints hints ) {
+		//can't convert null
+        if ( source == null )
+			return null;
+        
+        // handle case of source being an instance of target up front
+        final Class sourceClass = source.getClass();
+        if (sourceClass == target ||  sourceClass.equals( target ) 
+                || target.isAssignableFrom(sourceClass) ) {
+            return (T) source;
+        }
+
+		for (ConverterFactory factory : factories()) {
+			Converter converter = factory.createConverter( sourceClass, target, hints );
+			if ( converter != null ) {
+				try {
+					T converted = converter.convert( source, target );
+					if ( converted != null ) {
+						return converted;
+					}
+				} catch (Exception e) {
+				    if(LOGGER.isLoggable(Level.FINER))
+				        LOGGER.log(Level.FINER, "Error applying the converter " + converter.getClass() + " on (" + source + "," + target + ")", e);
+				}
+			}
+		}
+
+		//a couple of final tries
+		if ( String.class.equals( target ) ) {
+			return (T) source.toString();
+		}
+		return null;
+	}
+
+	/**
+	 * Processed the {@link ConverterFactory} extension point.
+	 *
+	 * @return A collection of converter factories.
+	 * @since 2.4
+	 */
+	static ConverterFactory[] factories() {
+	    if(factories == null) {
+	        Collection factoryCollection = getConverterFactories(GeoTools.getDefaultHints());
+	        factories = (ConverterFactory[]) factoryCollection.toArray(new ConverterFactory[factoryCollection.size()]);
+	    }
+	    return factories;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/DerivedMap.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/DerivedMap.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/DerivedMap.java	(revision 28000)
@@ -0,0 +1,317 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.io.Serializable;
+import java.util.AbstractMap;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * A map whose keys are derived from an other map. The keys are derived only when
+ * requested, which make it possible to backup potentially large maps. Implementations
+ * need only to overrides {@link #baseToDerived} and {@link #derivedToBase} methods.
+ * This set do not supports {@code null} key, since {@code null} is used
+ * when no mapping from {@linkplain #base} to {@code this} exists.
+ * This class is serializable if the underlying {@linkplain #base} set is serializable
+ * too.
+ * <p>
+ * This class is <strong>not</strong> thread-safe. Synchronizations (if wanted) are user's
+ * reponsability.
+ *
+ * @param <BK> The type of keys in the backing map.
+ * @param <K>  The type of keys in this map.
+ * @param <V>  The type of values in both this map and the underlying map.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/DerivedMap.java $
+ * @version $Id: DerivedMap.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public abstract class DerivedMap<BK,K,V> extends AbstractMap<K,V> implements Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -6994867383669885934L;
+
+    /**
+     * The base map whose keys are derived from.
+     *
+     * @see #baseToDerived
+     * @see #derivedToBase
+     */
+    protected final Map<BK,V> base;
+
+    /**
+     * Key set. Will be constructed only when first needed.
+     *
+     * @see #keySet
+     */
+    private transient Set<K> keySet;
+
+    /**
+     * Entry set. Will be constructed only when first needed.
+     *
+     * @see #entrySet
+     */
+    private transient Set<Map.Entry<K,V>> entrySet;
+
+    /**
+     * The derived key type.
+     */
+    private final Class<K> keyType;
+
+    /**
+     * Creates a new derived map from the specified base map.
+     *
+     * @param base The base map.
+     * @param keyType the type of keys in the derived map.
+     *
+     * @since 2.5
+     */
+    public DerivedMap(final Map<BK,V> base, final Class<K> keyType) {
+        this.base    = base;
+        this.keyType = keyType;
+    }
+
+    /**
+     * Transforms a key from the {@linkplain #base} map to a key in this map.
+     * If there is no key in the derived map for the specified base key,
+     * then this method returns {@code null}.
+     *
+     * @param  key A ley from the {@linkplain #base} map.
+     * @return The key that this view should contains instead of {@code key},
+     *         or {@code null}.
+     */
+    protected abstract K baseToDerived(final BK key);
+
+    /**
+     * Transforms a key from this derived map to a key in the {@linkplain #base} map.
+     *
+     * @param  key A key in this map.
+     * @return The key stored in the {@linkplain #base} map.
+     */
+    protected abstract BK derivedToBase(final K key);
+
+    /**
+     * Returns the number of key-value mappings in this map.
+     *
+     * @return the number of key-value mappings in this map.
+     */
+    @Override
+    public int size() {
+	return super.size();
+    }
+
+    /**
+     * Returns {@code true} if this map contains no key-value mappings.
+     *
+     * @return {@code true} if this map contains no key-value mappings.
+     */
+    @Override
+    public boolean isEmpty() {
+	return base.isEmpty() || super.isEmpty();
+    }
+
+    /**
+     * Returns {@code true} if this map maps one or more keys to this value.
+     * The default implementation invokes
+     * <code>{@linkplain #base}.containsValue(value)</code>.
+     *
+     * @return {@code true} if this map maps one or more keys to this value.
+     */
+    @Override
+    public boolean containsValue(final Object value) {
+        return base.containsValue(value);
+    }
+
+    /**
+     * Returns {@code true} if this map contains a mapping for the specified key.
+     * The default implementation invokes
+     * <code>{@linkplain #base}.containsKey({@linkplain #derivedToBase derivedToBase}(key))</code>.
+     *
+     * @param  key key whose presence in this map is to be tested.
+     * @return {@code true} if this map contains a mapping for the specified key.
+     */
+    @Override
+    public boolean containsKey(final Object key) {
+        if (keyType.isInstance(key)) {
+            return base.containsKey(derivedToBase(keyType.cast(key)));
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns the value to which this map maps the specified key.
+     * The default implementation invokes
+     * <code>{@linkplain #base}.get({@linkplain #derivedToBase derivedToBase}(key))</code>.
+     *
+     * @param  key key whose associated value is to be returned.
+     * @return the value to which this map maps the specified key.
+     */
+    @Override
+    public V get(final Object key) {
+        if (keyType.isInstance(key)) {
+            return base.get(derivedToBase(keyType.cast(key)));
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Associates the specified value with the specified key in this map.
+     * The default implementation invokes
+     * <code>{@linkplain #base}.put({@linkplain #derivedToBase derivedToBase}(key), value)</code>.
+     *
+     * @param  key key with which the specified value is to be associated.
+     * @param  value value to be associated with the specified key.
+     * @return previous value associated with specified key, or {@code null}
+     *	       if there was no mapping for key.
+     * @throws UnsupportedOperationException if the {@linkplain #base} map doesn't
+     *         supports the {@code put} operation.
+     */
+    @Override
+    public V put(final K key, final V value) throws UnsupportedOperationException {
+        return base.put(derivedToBase(key), value);
+    }
+
+    /**
+     * Removes the mapping for this key from this map if present.
+     * The default implementation invokes
+     * <code>{@linkplain #base}.remove({@linkplain #derivedToBase derivedToBase}(key))</code>.
+     *
+     * @param  key key whose mapping is to be removed from the map.
+     * @return previous value associated with specified key, or {@code null}
+     *	       if there was no entry for key.
+     * @throws UnsupportedOperationException if the {@linkplain #base} map doesn't
+     *         supports the {@code remove} operation.
+     */
+    @Override
+    public V remove(final Object key) throws UnsupportedOperationException {
+        if (keyType.isInstance(key)) {
+            return base.remove(derivedToBase(keyType.cast(key)));
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns a set view of the keys contained in this map.
+     *
+     * @return a set view of the keys contained in this map.
+     */
+    @Override
+    public Set<K> keySet() {
+        if (keySet == null) {
+            keySet = new KeySet(base.keySet());
+        }
+        return keySet;
+    }
+
+    /**
+     * Returns a collection view of the values contained in this map.
+     *
+     * @return a collection view of the values contained in this map.
+     */
+    @Override
+    public Collection<V> values() {
+        return base.values();
+    }
+
+    /**
+     * Returns a set view of the mappings contained in this map.
+     *
+     * @return a set view of the mappings contained in this map.
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public Set<Map.Entry<K,V>> entrySet() {
+        if (entrySet == null) {
+            entrySet = (Set) new EntrySet(base.entrySet());
+        }
+        return entrySet;
+    }
+
+    /**
+     * The key set.
+     */
+    private final class KeySet extends DerivedSet<BK,K> {
+        private static final long serialVersionUID = -2931806200277420177L;
+
+        public KeySet(final Set<BK> base) {
+            super(base, keyType);
+        }
+
+        protected K baseToDerived(final BK element) {
+            return DerivedMap.this.baseToDerived(element);
+        }
+
+        protected BK derivedToBase(final K element) {
+            return DerivedMap.this.derivedToBase(element);
+        }
+    }
+
+    /**
+     * The entry set.
+     */
+    private final class EntrySet extends DerivedSet<Map.Entry<BK,V>, Entry<BK,K,V>> {
+        private static final long serialVersionUID = -2931806200277420177L;
+
+        @SuppressWarnings("unchecked")
+        public EntrySet(final Set<Map.Entry<BK,V>> base) {
+            super(base, (Class) Entry.class);
+        }
+
+        protected Entry<BK,K,V> baseToDerived(final Map.Entry<BK,V> entry) {
+            final K derived = DerivedMap.this.baseToDerived(entry.getKey());
+            return derived!=null ? new Entry<BK,K,V>(entry, derived) : null;
+        }
+
+        protected Map.Entry<BK,V> derivedToBase(final Entry<BK,K,V> element) {
+            return element.entry;
+        }
+    }
+
+    /**
+     * The entry element.
+     */
+    private static final class Entry<BK,K,V> implements Map.Entry<K,V> {
+        public final Map.Entry<BK,V> entry;
+        private final K derived;
+
+        public Entry(final Map.Entry<BK,V> entry, final K derived) {
+            this.entry   = entry;
+            this.derived = derived;
+        }
+
+        public K getKey() {
+            return derived;
+        }
+
+        public V getValue() {
+            return entry.getValue();
+        }
+
+        public V setValue(V value) {
+            return entry.setValue(value);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/DerivedSet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/DerivedSet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/DerivedSet.java	(revision 28000)
@@ -0,0 +1,250 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.io.Serializable;
+import java.util.AbstractSet;
+import java.util.Iterator;
+import java.util.Set;
+
+
+/**
+ * A set whose values are derived from an other set. The values are derived only when
+ * requested, which make it possible to backup potentially large sets. Implementations
+ * need only to overrides {@link #baseToDerived} and {@link #derivedToBase} methods.
+ * This set do not supports {@code null} value, since {@code null} is used
+ * when no mapping from {@linkplain #base} to {@code this} exists.
+ * This class is serializable if the underlying {@linkplain #base} set is serializable
+ * too.
+ * <p>
+ * This class is <strong>not</strong> thread-safe. Synchronizations (if wanted) are user's
+ * reponsability.
+ *
+ * @param <B> The type of elements in the backing set.
+ * @param <E> The type of elements in this set.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/DerivedSet.java $
+ * @version $Id: DerivedSet.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public abstract class DerivedSet<B,E> extends AbstractSet<E>
+        implements CheckedCollection<E>, Serializable
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -4662336508586424581L;
+
+    /**
+     * The base set whose values are derived from.
+     *
+     * @see #baseToDerived
+     * @see #derivedToBase
+     */
+    protected final Set<B> base;
+
+    /**
+     * The derived type.
+     */
+    private final Class<E> derivedType;
+
+    /**
+     * Creates a new derived set from the specified base set.
+     *
+     * @param base The base set.
+     * @param derivedType The type of elements in this derived set.
+     *
+     * @since 2.5
+     */
+    public DerivedSet(final Set<B> base, final Class<E> derivedType) {
+        this.base        = base;
+        this.derivedType = derivedType;
+    }
+
+    /**
+     * Returns the derived element type.
+     *
+     * @since 2.5
+     */
+    public Class<E> getElementType() {
+        return derivedType;
+    }
+
+    /**
+     * Transforms a value in the {@linkplain #base} set to a value in this set.
+     * If there is no mapping in the derived set for the specified element,
+     * then this method returns {@code null}.
+     *
+     * @param  element A value in the {@linkplain #base} set.
+     * @return The value that this view should contains instead of {@code element},
+     *         or {@code null}.
+     */
+    protected abstract E baseToDerived(final B element);
+
+    /**
+     * Transforms a value in this set to a value in the {@linkplain #base} set.
+     *
+     * @param  element A value in this set.
+     * @return The value stored in the {@linkplain #base} set.
+     */
+    protected abstract B derivedToBase(final E element);
+
+    /**
+     * Returns an iterator over the elements contained in this set.
+     * The iterator will invokes {@link #baseToDerived} for each element.
+     *
+     * @return an iterator over the elements contained in this set.
+     */
+    public Iterator<E> iterator() {
+        return new Iter(base.iterator());
+    }
+
+    /**
+     * Returns the number of elements in this set. The default implementation counts
+     * the number of elements returned by the {@link #iterator iterator}.
+     *
+     * @return the number of elements in this set.
+     */
+    public int size() {
+        int count = 0;
+        for (final Iterator it=iterator(); it.hasNext();) {
+            it.next();
+            count++;
+        }
+        return count;
+    }
+
+    /**
+     * Returns {@code true} if this set contains no elements.
+     *
+     * @return {@code true} if this set contains no elements.
+     */
+    @Override
+    public boolean isEmpty() {
+        return base.isEmpty() || super.isEmpty();
+    }
+
+    /**
+     * Returns {@code true} if this set contains the specified element.
+     * The default implementation invokes
+     * <code>{@linkplain #base}.contains({@linkplain #derivedToBase derivedToBase}(element))</code>.
+     *
+     * @param  element object to be checked for containment in this set.
+     * @return {@code true} if this set contains the specified element.
+     */
+    @Override
+    public boolean contains(final Object element) {
+        if (derivedType.isInstance(element)) {
+            return base.contains(derivedToBase(derivedType.cast(element)));
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Ensures that this set contains the specified element.
+     * The default implementation invokes
+     * <code>{@linkplain #base}.add({@linkplain #derivedToBase derivedToBase}(element))</code>.
+     *
+     * @param  element element whose presence in this set is to be ensured.
+     * @return {@code true} if the set changed as a result of the call.
+     * @throws UnsupportedOperationException if the {@linkplain #base} set doesn't
+     *         supports the {@code add} operation.
+     */
+    @Override
+    public boolean add(final E element) throws UnsupportedOperationException {
+        return base.add(derivedToBase(element));
+    }
+
+    /**
+     * Removes a single instance of the specified element from this set.
+     * The default implementation invokes
+     * <code>{@linkplain #base}.remove({@linkplain #derivedToBase derivedToBase}(element))</code>.
+     *
+     * @param  element element to be removed from this set, if present.
+     * @return {@code true} if the set contained the specified element.
+     * @throws UnsupportedOperationException if the {@linkplain #base} set doesn't
+     *         supports the {@code remove} operation.
+     */
+    @Override
+    public boolean remove(final Object element) throws UnsupportedOperationException {
+        if (derivedType.isInstance(element)) {
+            return base.remove(derivedToBase(derivedType.cast(element)));
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Iterates through the elements in the set.
+     */
+    private final class Iter implements Iterator<E> {
+        /**
+         * The iterator from the {@linkplain #base} set.
+         */
+        private final Iterator<B> iterator;
+
+        /**
+         * The next element to be returned, or {@code null}.
+         */
+        private transient E next;
+
+        /**
+         * The iterator from the {@linkplain #base} set.
+         */
+        public Iter(final Iterator<B> iterator) {
+            this.iterator = iterator;
+        }
+
+        /**
+         * Returns {@code true} if the iteration has more elements.
+         */
+        public boolean hasNext() {
+            while (next == null) {
+                if (!iterator.hasNext()) {
+                    return false;
+                }
+                next = baseToDerived(iterator.next());
+            }
+            return true;
+        }
+
+        /**
+         * Returns the next element in the iteration.
+         */
+        public E next() {
+            while (next == null) {
+                next = baseToDerived(iterator.next());
+            }
+            final E value = next;
+            next = null;
+            return value;
+        }
+
+        /**
+         * Removes from the underlying set the last element returned by the iterator.
+         *
+         * @throws UnsupportedOperationException if the {@linkplain #base} set doesn't
+         *         supports the {@code remove} operation.
+         */
+        public void remove() {
+            iterator.remove();
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/GenericName.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/GenericName.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/GenericName.java	(revision 28000)
@@ -0,0 +1,374 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.util;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
+import org.opengis.util.InternationalString;
+import org.opengis.util.LocalName;
+import org.opengis.util.NameSpace;
+import org.opengis.util.ScopedName;
+
+
+/**
+ * Base class for {@linkplain ScopedName generic scoped} and
+ * {@linkplain LocalName local name} structure for type and attribute
+ * name in the context of name spaces.
+ * <p>
+ * <b>Note:</b> this class has a natural ordering that is inconsistent with {@link #equals equals}.
+ * The natural ordering may be case-insensitive and ignores the {@linkplain #DEFAULT_SEPARATOR
+ * character separator} between name elements.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/GenericName.java $
+ * @version $Id: GenericName.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see NameFactory
+ */
+public abstract class GenericName implements org.opengis.util.GenericName, Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 8685047583179337259L;
+
+    /**
+     * The default separator character.
+     */
+    public static final char DEFAULT_SEPARATOR = ':';
+
+    /**
+     * The name space, created on the fly when needed. This is a temporary
+     * approach until we replace this class by a better implementation.
+     */
+    private transient NameSpace namespace;
+
+    /**
+     * Creates a new instance of generic name.
+     */
+    protected GenericName() {
+    }
+
+    /**
+     * Ensures that the given name is a {@link String} or an {@link InternationalString}.
+     * This is used for subclass constructors.
+     */
+    static CharSequence validate(final CharSequence name) {
+        return (name==null || name instanceof InternationalString) ? name : name.toString();
+    }
+
+    /**
+     * Returns the scope (name space) in which this name is local. The scope is set on creation
+     * and is not modifiable. The scope of a name determines where a name "starts". For instance,
+     * if a name has a {@linkplain #depth depth} of two ({@code "util.GenericName"}) and is
+     * associated with a {@linkplain NameSpace name space} having the name {@code "org.opengis"},
+     * then the fully qualified name would be {@code "org.opengis.util.GenericName"}.
+     *
+     * @return The name space.
+     *
+     * @since 2.3
+     *
+     * @todo To be strict, maybe we should returns {@code null} if there is no namespace.
+     *       Current implementation returns a namespace instance whith a null name. This
+     *       behavior is for transition from legacy API to later ISO 19103 revision and
+     *       may change in future GeoTools version.
+     */
+    public NameSpace scope() {
+        if (namespace == null) {
+            namespace = new NameSpace() {
+                public org.opengis.util.GenericName name() {
+                    return getScope();
+                }
+            };
+        }
+        return namespace;
+    }
+
+    /**
+     * Returns the scope (name space) of this generic name. If this name has no scope
+     * (e.g. is the root), then this method returns {@code null}.
+     *
+     * @return The name space of this name.
+     * @deprecated Replaced by {@link #scope}.
+     */
+    @Deprecated
+    public abstract org.opengis.util.GenericName getScope();
+
+    /**
+     * Returns the depth of this name within the namespace hierarchy.  This indicates the number
+     * of levels specified by this name.  For any {@link LocalName}, it is always one.  For a
+     * {@link ScopedName} it is some number greater than or equal to 2.
+     * <p>
+     * The depth is the length of the list returned by the {@link #getParsedNames} method.
+     * As such it is a derived parameter.
+     *
+     * @return The depth of this name.
+     *
+     * @since 2.3
+     */
+    public int depth() {
+        return getParsedNames().size();
+    }
+
+    /**
+     * Returns the sequence of {@linkplain LocalName local names} making this generic name.
+     * Each element in this list is like a directory name in a file path name.
+     * The length of this sequence is the generic name depth.
+     *
+     * @return The sequence of local names.
+     */
+    public abstract List<LocalName> getParsedNames();
+
+    /**
+     * Returns the first element in the sequence of {@linkplain #getParsedNames parsed names}.
+     * For any {@link LocalName}, this is always {@code this}.
+     *
+     * @return The first element of this name.
+     *
+     * @since 2.6
+     */
+    public LocalName head() {
+        final List<? extends LocalName> names = getParsedNames();
+        return names.get(0);
+    }
+
+    /**
+     * Returns the last element in the sequence of {@linkplain #getParsedNames parsed names}.
+     * For any {@link LocalName}, this is always {@code this}.
+     *
+     * @return The last element of this name.
+     *
+     * @since 2.6
+     */
+    public LocalName tip() {
+        final List<? extends LocalName> names = getParsedNames();
+        return names.get(names.size() - 1);
+    }
+
+    /**
+     * @deprecated Renamed as {@link #tip()}.
+     *
+     * @since 2.3
+     */
+    @Deprecated
+    public LocalName name() {
+        return tip();
+    }
+
+    /**
+     * Returns a view of this name as a fully-qualified name, or {@code null} if none.
+     * The {@linkplain #scope scope} of a fully qualified name must be
+     * {@linkplain NameSpace#isGlobal global}.
+     * <p>
+     * If this name is a {@linkplain LocalName local name} and the {@linkplain #scope scope}
+     * is already {@linkplain NameSpace#isGlobal global}, returns {@code null} since it is not
+     * possible to derive a scoped name.
+     *
+     * @return The fully-qualified name.
+     * @deprecated Replaced by {@link #toFullyQualifiedName}.
+     */
+    @Deprecated
+    public abstract ScopedName asScopedName();
+
+    /**
+     * Returns the separator character. Default to <code>':'</code>.
+     * This method is overridden by {@link org.geotools.util.ScopedName}.
+     */
+    char getSeparator() {
+        return DEFAULT_SEPARATOR;
+    }
+
+    /**
+     * Returns a string representation of this generic name. This string representation
+     * is local-independant. It contains all elements listed by {@link #getParsedNames}
+     * separated by an arbitrary character (usually {@code :} or {@code /}).
+     * This rule implies that the {@code toString()} method for a
+     * {@linkplain ScopedName scoped name} will contains the scope, while the
+     * {@code toString()} method for the {@linkplain LocalName local version} of
+     * the same name will not contains the scope.
+     *
+     * @return A string representation of this name.
+     */
+    @Override
+    public String toString() {
+        final StringBuilder buffer = new StringBuilder();
+        final List<? extends LocalName> parsedNames = getParsedNames();
+        final char separator = getSeparator();
+        for (final Iterator<? extends LocalName> it=parsedNames.iterator(); it.hasNext();) {
+            if (buffer.length() != 0) {
+                buffer.append(separator);
+            }
+            buffer.append(it.next());
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Returns a local-dependent string representation of this generic name. This string
+     * is similar to the one returned by {@link #toString} except that each element has
+     * been localized in the {@linkplain InternationalString#toString(Locale)
+     * specified locale}. If no international string is available, then this method should
+     * returns an implementation mapping to {@link #toString} for all locales.
+     *
+     * @return A localizable string representation of this name.
+     */
+    public InternationalString toInternationalString() {
+        return new International(getParsedNames(), getSeparator());
+    }
+
+    /**
+     * An international string built from a snapshot of {@link GenericName}.
+     *
+     * @version $Id: GenericName.java 37298 2011-05-25 05:16:15Z mbedward $
+     * @author Martin Desruisseaux (IRD)
+     */
+    private static final class International extends AbstractInternationalString
+                                          implements Serializable
+    {
+        /**
+         * Serial number for interoperability with different versions.
+         */
+        private static final long serialVersionUID = -4234089612436334148L;
+
+        /**
+         * The sequence of {@linkplain LocalName local names} making this generic name.
+         * This is the value returned by {@link GenericName#getParsedNames}.
+         */
+        private final List<? extends LocalName> parsedNames;
+
+        /**
+         * The separator character. This is the value returned by {@link GenericName#getSeparator}.
+         */
+        private final char separator;
+
+        /**
+         * Constructs a new international string from the specified {@link GenericName} fields.
+         *
+         * @param parsedNames The value returned by {@link GenericName#getParsedNames}.
+         * @param separator   The value returned by {@link GenericName#getSeparator}.
+         */
+        public International(final List<? extends LocalName> parsedNames, final char separator) {
+            this.parsedNames = parsedNames;
+            this.separator   = separator;
+        }
+
+        /**
+         * Returns a string representation for the specified locale.
+         */
+        public String toString(final Locale locale) {
+            final StringBuilder buffer = new StringBuilder();
+            for (final LocalName name : parsedNames) {
+                if (buffer.length() != 0) {
+                    buffer.append(separator);
+                }
+                buffer.append(name.toInternationalString().toString(locale));
+            }
+            return buffer.toString();
+        }
+
+        /**
+         * Compares this international string with the specified object for equality.
+         */
+        @Override
+        public boolean equals(final Object object) {
+            if (object!=null && object.getClass().equals(getClass())) {
+                final International that = (International) object;
+                return Utilities.equals(this.parsedNames, that.parsedNames) &&
+                                        this.separator == that.separator;
+            }
+            return false;
+        }
+
+        /**
+         * Returns a hash code value for this international text.
+         */
+        @Override
+        public int hashCode() {
+            return (int)serialVersionUID ^ parsedNames.hashCode();
+        }
+    }
+
+    /**
+     * Compares this name with the specified object for order. Returns a negative integer,
+     * zero, or a positive integer as this name lexicographically precedes, is equals to,
+     * or follows the specified object. The comparaison is performed in the following
+     * order:
+     * <ul>
+     *   <li>Compares each element in the {@linkplain #getParsedNames list of parsed names}. If an
+     *       element of this name lexicographically precedes or follows the corresponding element
+     *       of the specified name, returns a negative or a positive integer respectively.</li>
+     *   <li>If all elements in both names are lexicographically equal, then if this name has less
+     *       or more elements than the specified name, returns a negative or a positive integer
+     *       respectively.</li>
+     *   <li>Otherwise, returns 0.</li>
+     * </ul>
+     *
+     * @param that The name to compare with this name.
+     * @return -1 if this name precedes the given one, +1 if it follows, 0 if equals.
+     */
+    public int compareTo(final org.opengis.util.GenericName that) {
+        final Iterator<? extends LocalName> thisNames = this.getParsedNames().iterator();
+        final Iterator<? extends LocalName> thatNames = that.getParsedNames().iterator();
+        while (thisNames.hasNext()) {
+            if (!thatNames.hasNext()) {
+                return +1;
+            }
+            final LocalName thisNext = thisNames.next();
+            final LocalName thatNext = thatNames.next();
+            if (thisNext==this && thatNext==that) {
+                // Never-ending loop: usually an implementation error
+                throw new IllegalStateException();
+            }
+            final int compare = thisNext.compareTo(thatNext);
+            if (compare != 0) {
+                return compare;
+            }
+        }
+        return thatNames.hasNext() ? -1 : 0;
+    }
+
+    /**
+     * Compares this generic name with the specified object for equality.
+     *
+     * @param object The object to compare with this name.
+     * @return {@code true} if the given object is equals to this one.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object!=null && object.getClass().equals(getClass())) {
+            final GenericName that = (GenericName) object;
+            return Utilities.equals(this.getParsedNames(), that.getParsedNames()) &&
+                                    this.getSeparator() == that.getSeparator();
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this generic name.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ getParsedNames().hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/GrowableInternationalString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/GrowableInternationalString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/GrowableInternationalString.java	(revision 28000)
@@ -0,0 +1,377 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.opengis.util.InternationalString;
+import org.geotools.util.logging.Logging;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * An implementation of international string using a {@linkplain Map map}
+ * of strings for different {@linkplain Locale locales}. Strings for new
+ * locales can be {@linkplain #add(Locale,String) added}, but existing
+ * strings can't be removed or modified. This behavior is a compromise
+ * between making constructionss easier, and being suitable for use in
+ * immutable objects.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/GrowableInternationalString.java $
+ * @version $Id: GrowableInternationalString.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class GrowableInternationalString extends AbstractInternationalString implements Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 5760033376627376937L;
+
+    /**
+     * The set of locales created in this virtual machine through methods of this class.
+     * Used in order to get a {@linkplain #unique unique} instance of {@link Locale} objects.
+     */
+    private static final Map<Locale,Locale> LOCALES = new HashMap<Locale,Locale>();
+
+    /**
+     * The string values in different locales (never {@code null}).
+     * Keys are {@link Locale} objects and values are {@link String}s.
+     */
+    private Map<Locale,String> localMap;
+
+    /**
+     * An unmodifiable view of the entry set in {@link #localMap}. This is the set of locales
+     * defined in this international string. Will be constructed only when first requested.
+     */
+    private transient Set<Locale> localSet;
+
+    /**
+     * Constructs an initially empty international string. Localized strings can been added
+     * using one of {@link #add add(...)} methods.
+     */
+    public GrowableInternationalString() {
+        localMap = Collections.emptyMap();
+    }
+
+    /**
+     * Adds a string for the given locale.
+     *
+     * @param  locale The locale for the {@code string} value, or {@code null}.
+     * @param  string The localized string.
+     * @throws IllegalArgumentException if a different string value was already set for
+     *         the given locale.
+     */
+    public synchronized void add(final Locale locale, final String string)
+            throws IllegalArgumentException
+    {
+        if (string != null) {
+            switch (localMap.size()) {
+                case 0: {
+                    localMap = Collections.singletonMap(locale, string);
+                    defaultValue = null; // Will be recomputed when first needed.
+                    return;
+                }
+                case 1: {
+                    localMap = new HashMap<Locale,String>(localMap);
+                    break;
+                }
+            }
+            String old = localMap.get(locale);
+            if (old != null) {
+                if (string.equals(old)) {
+                    return;
+                }
+                // TODO: provide a localized message "String value already set for locale ...".
+                throw new IllegalArgumentException();
+            }
+            localMap.put(locale, string);
+            defaultValue = null; // Will be recomputed when first needed.
+        }
+    }
+
+    /**
+     * Adds a string for the given property key. This is a convenience method for constructing an
+     * {@code AbstractInternationalString} during iteration through the
+     * {@linkplain java.util.Map.Entry entries} in a {@link Map}. It infers the {@link Locale}
+     * from the property {@code key}, using the following steps:
+     * <ul>
+     *   <li>If the {@code key} do not starts with the specified {@code prefix}, then
+     *       this method do nothing and returns {@code false}.</li>
+     *   <li>Otherwise, the characters after the {@code prefix} are parsed as an ISO language
+     *       and country code, and the {@link #add(Locale,String)} method is
+     *       invoked.</li>
+     * </ul>
+     *
+     * <P>For example if the prefix is <code>"remarks"</code>, then the <code>"remarks_fr"</code>
+     * property key stands for remarks in {@linkplain Locale#FRENCH French} while the
+     * <code>"remarks_fr_CA"</code> property key stands for remarks in
+     * {@linkplain Locale#CANADA_FRENCH French Canadian}.</P>
+     *
+     * @param  prefix The prefix to skip at the begining of the {@code key}.
+     * @param  key The property key.
+     * @param  string The localized string for the specified {@code key}.
+     * @return {@code true} if the key has been recognized, or {@code false} otherwise.
+     * @throws IllegalArgumentException if the locale after the prefix is an illegal code, or a
+     *         different string value was already set for the given locale.
+     */
+    public boolean add(final String prefix, final String key, final String string)
+            throws IllegalArgumentException
+    {
+        if (!key.startsWith(prefix)) {
+            return false;
+        }
+        int position  = prefix.length();
+        final int length = key.length();
+        final String[] parts = new String[] {"", "", ""};
+        for (int i=0; /*break condition inside*/; i++) {
+            if (position == length) {
+                final Locale locale = (i==0) ? (Locale)null :
+                       unique(new Locale(parts[0] /* language */,
+                                         parts[1] /* country  */,
+                                         parts[2] /* variant  */));
+                add(locale, string);
+                return true;
+            }
+            if (key.charAt(position)!='_' || i==parts.length) {
+                // Unknow character, or two many characters
+                break;
+            }
+            int next = key.indexOf('_', ++position);
+            if (next < 0) {
+                next = length;
+            } else if (next == position) {
+                // Found two consecutive '_' characters
+                break;
+            }
+            parts[i] = key.substring(position, position=next);
+        }
+        throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2,
+                                           "locale", key.substring(prefix.length())));
+    }
+
+    /**
+     * Returns a canonical instance of the given locale.
+     *
+     * @param  locale The locale to canonicalize.
+     * @return The canonical instance of {@code locale}.
+     */
+    private static synchronized Locale unique(final Locale locale) {
+        /**
+         * Initialize the LOCALES map with the set of locales defined in the Locale class.
+         * This operation is done only once.
+         */
+        if (LOCALES.isEmpty()) try {
+            final Field[] fields = Locale.class.getFields();
+            for (int i=0; i<fields.length; i++) {
+                final Field field = fields[i];
+                if (Modifier.isStatic(field.getModifiers())) {
+                    if (Locale.class.isAssignableFrom(field.getType())) {
+                        final Locale toAdd = (Locale) field.get(null);
+                        LOCALES.put(toAdd, toAdd);
+                    }
+                }
+            }
+        } catch (Exception exception) {
+            /*
+             * Not a big deal if this operation fails (this is actually just an
+             * optimization for reducing memory usage). Log a warning and continue.
+             */
+            Logging.unexpectedException(GrowableInternationalString.class, "unique", exception);
+        }
+        /*
+         * Now canonicalize the locale.
+         */
+        final Locale candidate = LOCALES.get(locale);
+        if (candidate != null) {
+            return candidate;
+        }
+        LOCALES.put(locale, locale);
+        return locale;
+    }
+
+    /**
+     * Returns the set of locales defined in this international string.
+     *
+     * @return The set of locales.
+     */
+    public synchronized Set<Locale> getLocales() {
+        if (localSet == null) {
+            localSet = Collections.unmodifiableSet(localMap.keySet());
+        }
+        return localSet;
+    }
+
+    /**
+     * Returns a string in the specified locale. If there is no string for the specified
+     * {@code locale}, then this method search for a locale without the
+     * {@linkplain Locale#getVariant variant} part. If no string are found,
+     * then this method search for a locale without the {@linkplain Locale#getCountry country}
+     * part. For example if the <code>"fr_CA"</code> locale was requested but not found, then
+     * this method looks for the <code>"fr"</code> locale. The {@code null} locale
+     * (which stand for unlocalized message) is tried last.
+     *
+     * @param  locale The locale to look for, or {@code null}.
+     * @return The string in the specified locale, or in a default locale.
+     */
+    public synchronized String toString(Locale locale) {
+        String text;
+        while (locale != null) {
+            text = localMap.get(locale);
+            if (text != null) {
+                return text;
+            }
+            final String language = locale.getLanguage();
+            final String country  = locale.getCountry ();
+            final String variant  = locale.getVariant ();
+            if (variant.length() != 0) {
+                locale = new Locale(language, country);
+                continue;
+            }
+            if (country.length() != 0) {
+                locale = new Locale(language);
+                continue;
+            }
+            break;
+        }
+
+        // Tries the string in the 'null' locale.
+        text = localMap.get(null);
+        if (text == null) {
+            // No 'null' locale neither. Returns the first string in whatever locale.
+            final Iterator<String> it = localMap.values().iterator();
+            if (it.hasNext()) {
+                return it.next();
+            }
+        }
+        return text;
+    }
+
+    /**
+     * Returns {@code true} if all localized texts stored in this international string are
+     * contained in the specified object. More specifically:
+     *
+     * <ul>
+     *   <li><p>If {@code candidate} is an instance of {@link InternationalString}, then this method
+     *       returns {@code true} if, for all <var>{@linkplain Locale locale}</var>-<var>{@linkplain
+     *       String string}</var> pairs contained in {@code this}, <code>candidate.{@linkplain
+     *       InternationalString#toString(Locale) toString}(locale)</code> returns a string
+     *       {@linkplain String#equals equals} to {@code string}.</p></li>
+     *
+     *   <li><p>If {@code candidate} is an instance of {@link CharSequence}, then this method
+     *       returns {@code true} if {@link #toString(Locale)} returns a string {@linkplain
+     *       String#equals equals} to <code>candidate.{@linkplain CharSequence#toString()
+     *       toString()}</code> for all locales.</p></li>
+     *
+     *   <li><p>If {@code candidate} is an instance of {@link Map}, then this methods returns
+     *       {@code true} if all <var>{@linkplain Locale locale}</var>-<var>{@linkplain String
+     *       string}</var> pairs are contained into {@code candidate}.</p></li>
+     *
+     *   <li><p>Otherwise, this method returns {@code false}.</p></li>
+     * </ul>
+     *
+     * @param  candidate The object which may contains this international string.
+     * @return {@code true} if the given object contains all localized strings found in this
+     *         international string.
+     *
+     * @since 2.3
+     */
+    public boolean isSubsetOf(final Object candidate) {
+        if (candidate instanceof InternationalString) {
+            final InternationalString string = (InternationalString) candidate;
+            for (final Map.Entry<Locale,String> entry : localMap.entrySet()) {
+                final Locale locale = entry.getKey();
+                final String text   = entry.getValue();
+                if (!text.equals(string.toString(locale))) {
+                    return false;
+                }
+            }
+        } else if (candidate instanceof CharSequence) {
+            final String string = candidate.toString();
+            for (final String text : localMap.values()) {
+                if (!text.equals(string)) {
+                    return false;
+                }
+            }
+        } else if (candidate instanceof Map) {
+            final Map<?,?> map = (Map<?,?>) candidate;
+            return map.entrySet().containsAll(localMap.entrySet());
+        } else {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Compares this international string with the specified object for equality.
+     *
+     * @param object The object to compare with this international string.
+     * @return {@code true} if the given object is equals to this string.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object!=null && object.getClass().equals(getClass())) {
+            final GrowableInternationalString that = (GrowableInternationalString) object;
+            return Utilities.equals(this.localMap, that.localMap);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this international text.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ localMap.hashCode();
+    }
+
+    /**
+     * Canonicalize the locales after deserialization.
+     */
+    private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+        final int size = localMap.size();
+        if (size == 0) {
+            return;
+        }
+        @SuppressWarnings("unchecked")
+        Map.Entry<Locale,String>[] entries = new Map.Entry[size];
+        entries = localMap.entrySet().toArray(entries);
+        if (size == 1) {
+            final Map.Entry<Locale,String> entry = entries[0];
+            localMap = Collections.singletonMap(unique(entry.getKey()), entry.getValue());
+        } else {
+            localMap.clear();
+            for (int i=0; i<entries.length; i++) {
+                final Map.Entry<Locale,String> entry = entries[i];
+                localMap.put(unique(entry.getKey()), entry.getValue());
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/KVP.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/KVP.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/KVP.java	(revision 28000)
@@ -0,0 +1,65 @@
+package org.geotools.util;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+/**
+ * A linked HashMap set up for easy construction.
+ * <p>
+ * Example: <code>KVP map = new KVP("foo",1,"bar,2);</code>
+ * 
+ * @author jody
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/KVP.java $
+ */
+public class KVP extends LinkedHashMap<String, Object> {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -387821381125137128L;
+
+    /**
+     * A linked HashMap set up for easy construction.
+     * <p>
+     * Example: <code>KVP map = new KVP("foo",1,"bar,2);</code>
+     * 
+     * @param pairs
+     */
+    public KVP(Object... pairs) {
+        if ((pairs.length & 1) != 0) {
+            throw new IllegalArgumentException("Pairs was not an even number");
+        }
+        for (int i = 0; i < pairs.length; i += 2) {
+            String key = (String) pairs[i];
+            Object value = pairs[i + 1];
+            add(key, value);
+        }
+    }
+    /**
+     * An additive version of put; will add additional values resulting
+     * in a list.
+     * @param key
+     * @param value
+     */
+    @SuppressWarnings("unchecked")
+    public void add(String key, Object value) {
+        if( containsKey(key) ) {
+            Object existing = get( key );
+            if( existing instanceof List<?>){
+                List<Object> list = (List<Object>) existing;
+                list.add( value );
+            }
+            else {
+                List<Object> list = new ArrayList<Object>();
+                list.add( existing );
+                list.add( value );
+                put( key, list );
+            }
+        }
+        else {
+            put(key, value);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/LocalName.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/LocalName.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/LocalName.java	(revision 28000)
@@ -0,0 +1,305 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.util;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;
+import org.opengis.util.NameSpace;
+import org.opengis.util.ScopedName;
+
+
+/**
+ * Identifier within a name space for a local object. This could be the target object of the
+ * {@link GenericName}, or a pointer to another name space (with a new {@link GenericName})
+ * one step closer to the target of the identifier.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/LocalName.java $
+ * @version $Id: LocalName.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see NameFactory
+ */
+public class LocalName extends org.geotools.util.GenericName implements org.opengis.util.LocalName {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -5627125375582385822L;
+
+    /**
+     * The view of this object as a scoped name.
+     */
+    private final ScopedName asScopedName;
+
+    /**
+     * The name, either as a {@link String} or an {@link InternationalString}.
+     */
+    private final CharSequence name;
+
+    /**
+     * The name as a string.
+     * If not provided, will be built only when first needed.
+     */
+    private transient String asString;
+
+    /**
+     * The name as an international string.
+     * If not provided, will be built only when first needed.
+     */
+    private transient InternationalString asInternationalString;
+
+    /**
+     * The sequence of local name for this {@linkplain GenericName generic name}.
+     * Since this object is itself a locale name, this list is always a singleton
+     * containing only {@code this}. It will be built only when first needed.
+     */
+    private transient List<org.opengis.util.LocalName> parsedNames;
+
+    /**
+     * Constructs a local name from the specified string with no scope.
+     * If the specified name is an {@link InternationalString}, then the
+     * <code>{@linkplain InternationalString#toString(java.util.Locale) toString}(null)</code>
+     * method will be used in order to fetch an unlocalized name. Otherwise, the
+     * <code>{@linkplain CharSequence#toString toString}()</code> method will be used.
+     *
+     * @param name The local name (never {@code null}).
+     */
+    public LocalName(final CharSequence name) {
+        this(null, name);
+    }
+
+    /**
+     * Constructs a local name from the specified international string.
+     *
+     * This constructor is not public since it can't be used from outside
+     * of {@link org.geotools.util.ScopedName} constructor (otherwise some
+     * methods in this class may have the wrong semantic).
+     *
+     * @param asScopedName The view of this object as a scoped name.
+     * @param name         The local name (never {@code null}).
+     */
+    LocalName(final ScopedName asScopedName, final CharSequence name) {
+        this.asScopedName = asScopedName;
+        this.name         = validate(name);
+        AbstractInternationalString.ensureNonNull("name", name);
+    }
+
+    /**
+     * Returns the scope (name space) of this generic name.
+     * This method is protected from overriding by the user.
+     */
+    private GenericName getInternalScope() {
+        if (asScopedName != null) {
+            final NameSpace scope = asScopedName.scope();
+            if (scope != null) {
+                return scope.name();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the scope (name space) of this generic name.
+     *
+     * @deprecated Replaced by {@link #scope}.
+     */
+    @Deprecated
+    public GenericName getScope() {
+        return getInternalScope();
+    }
+
+    /**
+     * Returns the scope (name space) in which this name is local. The scope is set on creation
+     * and is not modifiable. The scope of a name determines where a name "starts". For instance,
+     * if a name has a {@linkplain #depth depth} of two ({@code "util.GenericName"}) and is
+     * associated with a {@linkplain NameSpace name space} having the name {@code "org.opengis"},
+     * then the fully qualified name would be {@code "org.opengis.util.GenericName"}.
+     *
+     * @since 2.3
+     *
+     * @todo To be strict, maybe we should returns {@code null} if there is no namespace.
+     *       Current implementation returns a namespace instance whith a null name. This
+     *       behavior is for transition from legacy API to later ISO 19103 revision and
+     *       may change in future GeoTools version.
+     */
+    public NameSpace scope() {
+        return (asScopedName!=null) ? asScopedName.scope() : super.scope();
+    }
+
+    /**
+     * Returns the depth, which is always 1 for a local name.
+     *
+     * @since 2.3
+     */
+    public int depth() {
+        return 1;
+    }
+
+    /**
+     * Returns the sequence of local name for this {@linkplain GenericName generic name}.
+     * Since this object is itself a locale name, this method always returns a singleton
+     * containing only {@code this}.
+     */
+    public List<org.opengis.util.LocalName> getParsedNames() {
+        // No need to sychronize: it is not a big deal if this object is built twice.
+        if (parsedNames == null) {
+            parsedNames = Collections.singletonList((org.opengis.util.LocalName) this);
+        }
+        return parsedNames;
+    }
+
+    /**
+     * Since this object is already a local name, this method always returns {@code this}.
+     */
+    @Override
+    public org.opengis.util.LocalName head() {
+        return this;
+    }
+
+    /**
+     * Since this object is already a local name, this method always returns {@code this}.
+     */
+    @Override
+    public org.opengis.util.LocalName tip() {
+        return this;
+    }
+
+    /**
+     * Returns a view of this object as a scoped name,
+     * or {@code null} if this name has no scope.
+     *
+     * @deprecated Replaced by {@link #toFullyQualifiedName}.
+     */
+    @Deprecated
+    public ScopedName asScopedName() {
+        return asScopedName;
+    }
+
+    /**
+     * Returns a view of this name as a fully-qualified name. The {@linkplain #scope scope}
+     * of a fully qualified name must be {@linkplain NameSpace#isGlobal global}. This method
+     * never returns {@code null}.
+     *
+     * @since 2.3
+     */
+    public GenericName toFullyQualifiedName() {
+        if (asScopedName == null) {
+            return this;
+        }
+        return asScopedName;
+    }
+
+    /**
+     * Returns this name expanded with the specified scope. One may represent this operation
+     * as a concatenation of the specified {@code name} with {@code this}. In pseudo-code,
+     * the following relationships must hold:
+     * <p>
+     * <ul>
+     *   <li><code>push(<var>name</var>).getParsedList() ==
+     *       <var>name</var>.getParsedList().addAll({@linkplain #getParsedNames()})</code></li>
+     *   <li><code>push(<var>name</var>).scope() == <var>name</var>.{@linkplain #scope()}</code></li>
+     * </ul>
+     * <p>
+     * <strong>Note:</strong> Those conditions can be understood in terms of the Java
+     * {@link Object#equals equals} method instead of the Java identity comparator {@code ==}.
+     *
+     * @since 2.3
+     *
+     * @todo Not yet implemented.
+     */
+    public ScopedName push(GenericName scope) {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    /**
+     * Returns a locale-independant string representation of this local name.
+     * This string do not includes the scope, which is consistent with the
+     * {@linkplain #getParsedNames parsed names} definition.
+     */
+    @Override
+    public String toString() {
+        if (asString == null) {
+            if (name instanceof InternationalString) {
+                // We really want the 'null' locale, not the system default one.
+                asString = ((InternationalString) name).toString(null);
+            } else {
+                asString = name.toString();
+            }
+        }
+        return asString;
+    }
+
+    /**
+     * Returns a local-dependent string representation of this locale name.
+     */
+    @Override
+    public InternationalString toInternationalString() {
+        if (asInternationalString == null) {
+            if (name instanceof InternationalString) {
+                asInternationalString = (InternationalString) name;
+            } else {
+                asInternationalString = new SimpleInternationalString(name.toString());
+            }
+        }
+        return asInternationalString;
+    }
+
+    /**
+     * Compares this name with the specified object for order. Returns a negative integer,
+     * zero, or a positive integer as this name lexicographically precedes, is equals to,
+     * or follows the specified object. The comparaison is case-insensitive.
+     */
+    @Override
+    public int compareTo(final GenericName object) {
+        return toString().compareToIgnoreCase(object.toString());
+    }
+
+    /**
+     * Compares this local name with the specified object for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (object!=null && object.getClass().equals(getClass())) {
+            final LocalName that = (LocalName) object;
+            // Do not use 'asScopedName' in order to avoid never-ending loop.
+            return Utilities.equals(this.getInternalScope(), that.getInternalScope()) &&
+                   Utilities.equals(this.name,               that.name);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this local name.
+     */
+    @Override
+    public int hashCode() {
+        int code = (int)serialVersionUID;
+        // Do not use 'asScopedName' in order to avoid never-ending loop.
+        if (name != null) code ^= name.hashCode();
+        return code;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/MapEntry.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/MapEntry.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/MapEntry.java	(revision 28000)
@@ -0,0 +1,124 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.geotools.resources.Classes;
+
+
+/**
+ * A default implementation of {@link java.util.Map.Entry} which map an arbitrary
+ * key-value pairs. This entry is immutable by default.
+ *
+ * @param <K> The class of key elements.
+ * @param <V> The class of value elements.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/MapEntry.java $
+ * @version $Id: MapEntry.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @todo This class will be removed when we will be allowed to compile for JSE 1.6, since a
+ *       default map entry implementation is provided there.
+ */
+public class MapEntry<K,V> implements Map.Entry<K,V>, Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 8627698052283756776L;
+
+    /**
+     * The key.
+     */
+    private final K key;
+
+    /**
+     * The value.
+     */
+    private final V value;
+
+    /**
+     * Creates a new map entry with the specified key-value pair.
+     *
+     * @param key The key.
+     * @param value The value.
+     */
+    public MapEntry(final K key, final V value) {
+        this.key   = key;
+        this.value = value;
+    }
+
+    /**
+     * Returns the key corresponding to this entry.
+     */
+    public K getKey() {
+        return key;
+    }
+
+    /**
+     * Returns the value corresponding to this entry.
+     */
+    public V getValue() {
+        return value;
+    }
+
+    /**
+     * Replaces the value corresponding to this entry with the specified
+     * value (optional operation). The default implementation throws an
+     * {@link UnsupportedOperationException}.
+     */
+    public V setValue(final V value) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Compares the specified object with this entry for equality.
+     *
+     * @param object The object to compare with this entry for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object instanceof Map.Entry) {
+            final Map.Entry that = (Map.Entry) object;
+            return Utilities.equals(this.getKey(),   that.getKey()) &&
+                   Utilities.equals(this.getValue(), that.getValue());
+        }
+        return false;
+    }
+
+    /**
+     * Returns the hash code value for this map entry
+     */
+    @Override
+    public int hashCode() {
+        int code = 0;
+        if (key   != null) code  =   key.hashCode();
+        if (value != null) code ^= value.hashCode();
+        return code;
+    }
+
+    /**
+     * Returns a string representation of this entry.
+     */
+    @Override
+    public String toString() {
+        return Classes.getShortClassName(this) + "[key=" + key + ", value=" + value + ']';
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/NameFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/NameFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/NameFactory.java	(revision 28000)
@@ -0,0 +1,173 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;  // For javadoc
+
+import org.opengis.metadata.Identifier;
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;  // For javadoc
+
+import org.geotools.resources.Classes;
+
+
+/**
+ * A factory for {@link GenericName} objects.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/NameFactory.java $
+ * @version $Id: NameFactory.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author  Martin Desruisseaux
+ */
+public final class NameFactory {
+    /**
+     * Do not allows instantiation of instance of this class.
+     */
+    private NameFactory() {
+    }
+
+    /**
+     * Constructs a generic name from a fully qualified name
+     * and the default separator character.
+     *
+     * @param name The fully qualified name.
+     */
+    public static GenericName create(final String name) {
+        return create(name, org.geotools.util.GenericName.DEFAULT_SEPARATOR);
+    }
+
+    /**
+     * Constructs a generic name from a fully qualified name
+     * and the specified separator character.
+     *
+     * @param name The fully qualified name.
+     * @param separator The separator character.
+     */
+    public static GenericName create(final String name, final char separator) {
+        final List<String> names = new ArrayList<String>();
+        int lower = 0;
+        while (true) {
+            final int upper = name.indexOf(separator, lower);
+            if (upper >= 0) {
+                names.add(name.substring(lower, upper));
+                lower = upper+1;
+            } else {
+                names.add(name.substring(lower));
+                break;
+            }
+        }
+        return create(names.toArray(new String[names.size()]), separator);
+    }
+
+    /**
+     * Constructs a generic name from an array of local names and the default separator character.
+     * If any of the specified names is an {@link InternationalString}, then the
+     * <code>{@linkplain InternationalString#toString(Locale) toString}(null)</code>
+     * method will be used in order to fetch an unlocalized name. Otherwise, the
+     * <code>{@linkplain CharSequence#toString toString}()</code> method will be used.
+     *
+     * @param names The local names as an array of strings or international strings.
+     *              This array must contains at least one element.
+     */
+    public static GenericName create(final CharSequence[] names) {
+        return create(names, org.geotools.util.GenericName.DEFAULT_SEPARATOR);
+    }
+
+    /**
+     * Constructs a generic name from an array of local names and the specified separator character.
+     * If any of the specified names is an {@link InternationalString}, then the
+     * <code>{@linkplain InternationalString#toString(Locale) toString}(null)</code>
+     * method will be used in order to fetch an unlocalized name. Otherwise, the
+     * <code>{@linkplain CharSequence#toString toString}()</code> method will be used.
+     *
+     * @param names     The local names as an array of strings.
+     *                  This array must contains at least one element.
+     * @param separator The separator character to use.
+     */
+    public static GenericName create(final CharSequence[] names, final char separator) {
+        return create(names, names.length, separator);
+    }
+
+    /**
+     * Constructs a generic name from an array of local names
+     * and the specified separator character.
+     *
+     * @param names     The local names as an array of strings.
+     * @param length    The valid length of {@code names} array.
+     * @param separator The separator character to use.
+     */
+    private static GenericName create(final CharSequence[] names,
+                                      final int  length,
+                                      final char separator)
+    {
+        if (length <= 0) {
+            throw new IllegalArgumentException(String.valueOf(length));
+        }
+        if (length == 1) {
+            return new LocalName(names[0]);
+        }
+        return new ScopedName(create(names, length-1, separator), separator, names[length-1]);
+    }
+
+    /**
+     * Returns the specified name in an array. The {@code value} may be either a {@link String},
+     * {@code String[]}, {@link GenericName} or {@code GenericName[]}. This method is used in
+     * {@link org.geotools.referencing.AbstractIdentifiedObject} constructors.
+     *
+     * @param  value The object to cast into an array of generic names.
+     * @return The generic names.
+     * @throws ClassCastException if {@code value} can't be cast.
+     */
+    public static GenericName[] toArray(final Object value) throws ClassCastException {
+        if (value instanceof GenericName[]) {
+            return (GenericName[]) value;
+        }
+        if (value instanceof GenericName) {
+            return new GenericName[] {
+                (GenericName) value
+            };
+        }
+        if (value instanceof CharSequence) {
+            return new GenericName[] {
+                create(value.toString())
+            };
+        }
+        if (value instanceof CharSequence[]) {
+            final CharSequence[] values = (CharSequence[]) value;
+            final GenericName[] names = new GenericName[values.length];
+            for (int i=0; i<values.length; i++) {
+                final CharSequence v = values[i];
+                names[i] = (v instanceof GenericName) ? (GenericName)v : create(v.toString());
+            }
+            return names;
+        }
+        if (value instanceof Identifier[]) {
+            final Identifier[] values = (Identifier[]) value;
+            final GenericName[] names = new GenericName[values.length];
+            for( int i=0; i<values.length; i++) {
+                final Identifier v = values[i];
+                names[i] = (v instanceof GenericName) ? (GenericName)v : create(v.getCode());
+            }
+            return names;
+        }
+        // TODO: localize
+        throw new ClassCastException("Cannot convert " + Classes.getShortClassName(value) + " to GenericName[]");
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/NullProgressListener.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/NullProgressListener.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/NullProgressListener.java	(revision 28000)
@@ -0,0 +1,66 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ * 
+ *    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+
+
+/**
+ * A default progress listener implementation suitable for
+ * subclassing.
+ * <p>
+ * This implementation supports cancelation and getting/setting the description.
+ * The default implementations of the other methods do nothing.
+ * </p>
+ *
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/main/src/main/java/org/geotools/util/NullProgressListener.java $
+ * @version $Id: NullProgressListener.java 37298 2011-05-25 05:16:15Z mbedward $
+ */
+public class NullProgressListener implements org.opengis.util.ProgressListener {
+
+    /**
+     * {@code true} if the action is canceled.
+     */
+    private boolean canceled = false;
+
+    /**
+     * Creates a null progress listener with no description.
+     */
+    public NullProgressListener() {
+    }
+
+    public void started() {
+        //do nothing
+    }
+
+    public void progress(float percent) {
+        //do nothing
+    }
+    
+    public void complete() {
+        //do nothing
+    }
+
+    public boolean isCanceled() {
+        return canceled;
+    }
+
+    public void exceptionOccurred(Throwable exception) {
+        //do nothing
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/ResourceInternationalString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/ResourceInternationalString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/ResourceInternationalString.java	(revision 28000)
@@ -0,0 +1,127 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.io.Serializable;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+
+/**
+ * An international string backed by a {@linkplain ResourceBundle resource bundle}. A resource
+ * bundle can be a Java class or a {@linkplain java.util.Properties properties} file, one for
+ * each language. The constructor expects the fully qualified class name of the base resource
+ * bundle (the one used when no resource was found in the client's language). The right resource
+ * bundle is loaded at runtime for the client's language by looking for a class or a
+ * {@linkplain java.util.Properties properties} file with the right suffix ("{@code _en}" for
+ * English or "{@code _fr}" for French). This mechanism is explained in J2SE's javadoc for the
+ * {@link ResourceBundle#getBundle(String,Locale,ClassLoader) getBundle} static method.
+ * <p>
+ * <b>Example:</b> If a file named "{@code MyResources.properties}" exists in the package
+ * "{@code org.geotools.mypackage}" and contains a line like "{@code MyKey = some value}",
+ * then an international string for "{@code some value}" can be created using the following
+ * code:
+ *
+ * <blockquote><code>
+ * InternationalString value = new ResourceInternationalString(
+ * "org.geotools.mypackage.MyResources", "MyKey");
+ * </code></blockquote>
+ *
+ * The "{@code some value}" string will be localized if the required properties files exist, for
+ * example "{@code MyResources_fr.properties}" for French, "{@code MyResources_it.properties}"
+ * for Italian, <cite>etc.</cite>
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/ResourceInternationalString.java $
+ * @version $Id: ResourceInternationalString.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class ResourceInternationalString extends AbstractInternationalString implements Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 6339944890723487336L;
+
+    /**
+     * The name of the resource bundle from which to fetch the string.
+     */
+    private final String resources;
+
+    /**
+     * The key for the resource to fetch.
+     */
+    private final String key;
+
+    /**
+     * Creates a new international string from the specified resource bundle and key.
+     *
+     * @param resources The name of the resource bundle, as a fully qualified class name.
+     * @param key The key for the resource to fetch.
+     */
+    public ResourceInternationalString(final String resources, final String key) {
+        this.resources = resources;
+        this.key       = key;
+        ensureNonNull("resources", resources);
+        ensureNonNull("key",       key);
+    }
+
+    /**
+     * Returns a string in the specified locale. If there is no string for the specified
+     * {@code locale}, then this method search for a string in an other locale as
+     * specified in the {@link ResourceBundle} class description.
+     *
+     * @param  locale The locale to look for, or {@code null} for an unlocalized version.
+     * @return The string in the specified locale, or in a default locale.
+     * @throws MissingResourceException is the key given to the constructor is invalid.
+     */
+    public String toString(Locale locale) throws MissingResourceException {
+        if (locale == null) {
+            // The English locale (NOT the system default) is often used
+            // as the real identifier in OGC IdentifiedObject naming. If
+            // a user wants a string in the system default locale, he
+            // should invokes the 'toString()' method instead.
+            locale = Locale.ENGLISH;
+        }
+        return ResourceBundle.getBundle(resources, locale).getString(key);
+    }
+
+    /**
+     * Compares this international string with the specified object for equality.
+     *
+     * @param object The object to compare with this international string.
+     * @return {@code true} if the given object is equals to this string.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object!=null && object.getClass().equals(getClass())) {
+            final ResourceInternationalString that = (ResourceInternationalString) object;
+            return Utilities.equals(this.key,       that.key) &&
+                   Utilities.equals(this.resources, that.resources);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this international text.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ key.hashCode() ^ resources.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/ScopedName.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/ScopedName.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/ScopedName.java	(revision 28000)
@@ -0,0 +1,241 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains documentation from OpenGIS specifications.
+ *    OpenGIS consortium's work is fully acknowledged here.
+ */
+package org.geotools.util;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale; // For javadoc
+
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString; // For javadoc
+import org.opengis.util.LocalName;
+import org.opengis.util.NameSpace;
+
+
+/**
+ * Fully qualified identifier for an object.
+ * A {@code ScopedName} contains a {@link LocalName} as
+ * {@linkplain #asLocalName head} and a {@linkplain GenericName},
+ * which may be a {@link LocalName} or an other {@link org.opengis.util.ScopedName},
+ * as {@linkplain #getScope tail}.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/ScopedName.java $
+ * @version $Id: ScopedName.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see NameFactory
+ */
+public class ScopedName extends org.geotools.util.GenericName
+                     implements org.opengis.util.ScopedName
+{
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -7664125655784137729L;
+
+    /**
+     * The scope of this variable (also know as the "tail").
+     */
+    private final GenericName scope;
+
+    /**
+     * The separator character.
+     */
+    private final char separator;
+
+    /**
+     * The head as a local name.
+     */
+    private final LocalName name;
+
+    /**
+     * The list of parsed names. Will be constructed only when first needed.
+     */
+    private transient List<LocalName> parsedNames;
+
+    /**
+     * Constructs a scoped name from the specified international string.
+     * If the specified name is an {@link InternationalString}, then the
+     * <code>{@linkplain InternationalString#toString(Locale) toString}(null)</code>
+     * method will be used in order to fetch an unlocalized name. Otherwise, the
+     * <code>{@linkplain CharSequence#toString toString}()</code> method will be used.
+     *
+     * @param scope The scope (or "tail") of the variable.
+     * @param name  The head (never {@code null}).
+     */
+    public ScopedName(final GenericName scope, final CharSequence name) {
+        this(scope, DEFAULT_SEPARATOR, name);
+    }
+
+    /**
+     * Constructs a scoped name from the specified international string.
+     * If the specified name is an {@link InternationalString}, then the
+     * <code>{@linkplain InternationalString#toString(Locale) toString}(null)</code>
+     * method will be used in order to fetch an unlocalized name. Otherwise, the
+     * <code>{@linkplain CharSequence#toString toString}()</code> method will be used.
+     *
+     * @param scope     The scope (or "tail") of the variable.
+     * @param separator The separator character (usually <code>':'</code> or <code>'/'</code>).
+     * @param name      The head (never {@code null}).
+     */
+    public ScopedName(final GenericName scope, final char separator, final CharSequence name) {
+        AbstractInternationalString.ensureNonNull("scope", scope);
+        AbstractInternationalString.ensureNonNull("name",  name);
+        this.scope     = scope;
+        this.separator = separator;
+        this.name      = new org.geotools.util.LocalName(this, name);
+    }
+
+    /**
+     * Returns the head of this scoped name. This is the first elements in the sequence of
+     * {@linkplain #getParsedNames parsed names}. The head element must exists in the same
+     * {@linkplain NameSpace name space} than this scoped name. In other words, the following
+     * relationship must holds:
+     * <p>
+     * <ul>
+     *   <li><code>head().scope() == this.{@linkplain #scope scope()}</code></li>
+     * </ul>
+     *
+     * @since 2.3
+     *
+     * @todo Not yet implemented.
+     */
+    @Override
+    public LocalName head() {
+        throw new UnsupportedOperationException("Not yet implemented.");
+    }
+
+    /**
+     * Returns the scope of this name.
+     *
+     * @deprecated Replaced by {@link #scope()}.
+     */
+    @Deprecated
+    public GenericName getScope() {
+        return scope;
+    }
+
+    /**
+     * Returns the separator character.
+     */
+    @Override
+    public char getSeparator() {
+        return separator;
+    }
+
+    /**
+     * Returns a view of this object as a scoped name. Since this object is already
+     * a scoped name, this method always returns {@code this}.
+     *
+     * @deprecated Replaced by {@link #toFullyQualifiedName}.
+     */
+    @Deprecated
+    public org.opengis.util.ScopedName asScopedName() {
+        return this;
+    }
+
+    /**
+     * Returns a view of this object as a local name. This is the last element in the
+     * sequence of {@linkplain #getParsedNames parsed names}. The local name returned
+     * by this method will still have the same {@linkplain LocalName#getScope scope}
+     * than this scoped name. Note however that the string returned by
+     * {@link LocalName#toString} will differs.
+     */
+    @Override
+    public LocalName tip() {
+        return name;
+    }
+
+    /**
+     * Returns the sequence of local name for this {@linkplain GenericName generic name}.
+     */
+    public List<LocalName> getParsedNames() {
+        if (parsedNames == null) {
+            final List<? extends LocalName> parents = scope.getParsedNames();
+            final int size = parents.size();
+            LocalName[] names = new LocalName[size + 1];
+            names = parents.toArray(names);
+            names[size] = name;
+            parsedNames = Arrays.asList(names);
+        }
+        return parsedNames;
+    }
+
+    /**
+     * Returns a view of this name as a fully-qualified name. The {@linkplain #scope scope}
+     * of a fully qualified name must be {@linkplain NameSpace#isGlobal global}. This method
+     * never returns {@code null}.
+     *
+     * @since 2.3
+     */
+    public GenericName toFullyQualifiedName() {
+        return this;
+    }
+
+    /**
+     * Returns this name expanded with the specified scope. One may represent this operation
+     * as a concatenation of the specified {@code name} with {@code this}. In pseudo-code,
+     * the following relationships must hold:
+     * <p>
+     * <ul>
+     *   <li><code>push(<var>name</var>).getParsedList() ==
+     *       <var>name</var>.getParsedList().addAll({@linkplain #getParsedNames()})</code></li>
+     *   <li><code>push(<var>name</var>).scope() == <var>name</var>.{@linkplain #scope()}</code></li>
+     *   <li><code>push({@linkplain ScopedName#head head()}).{@linkplain ScopedName#tail tail()} == this</code></li>
+     * </ul>
+     * <p>
+     * <strong>Note:</strong> Those conditions can be understood in terms of the Java
+     * {@link Object#equals equals} method instead of the Java identity comparator {@code ==}.
+     *
+     * @since 2.3
+     *
+     * @todo Not yet implemented.
+     */
+    public org.opengis.util.ScopedName push(GenericName scope) {
+        throw new UnsupportedOperationException("Not yet implemented.");
+    }
+
+    /**
+     * Compares this scoped name with the specified object for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (object!=null && object.getClass().equals(getClass())) {
+            final ScopedName that = (ScopedName) object;
+            return Utilities.equals(this.name,  that.name);
+            // No need to checks the scope, since the LocalName implementation
+            // should checks it.
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this generic name.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ name.hashCode() ^ scope.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/SimpleInternationalString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/SimpleInternationalString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/SimpleInternationalString.java	(revision 28000)
@@ -0,0 +1,98 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Locale;
+
+
+/**
+ * A simple international string consisting of a single string for all locales.
+ * For such a particular case, this implementation is the more effective than
+ * other implementations provided in this package.
+ *
+ * @since 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/SimpleInternationalString.java $
+ * @version $Id: SimpleInternationalString.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class SimpleInternationalString extends AbstractInternationalString implements Serializable {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 3543963804501667578L;
+
+    /**
+     * Creates a new instance of international string.
+     *
+     * @param message The string for all locales.
+     */
+    public SimpleInternationalString(final String message) {
+        defaultValue = message;
+        ensureNonNull("message", message);
+    }
+
+    /**
+     * Returns the same string for all locales. This is the string given to the constructor.
+     */
+    public String toString(final Locale locale) {
+        return defaultValue;
+    }
+
+    /**
+     * Compares this international string with the specified object for equality.
+     *
+     * @param object The object to compare with this international string.
+     * @return {@code true} if the given object is equals to this string.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object!=null && object.getClass().equals(getClass())) {
+            final SimpleInternationalString that = (SimpleInternationalString) object;
+            return Utilities.equals(this.defaultValue, that.defaultValue);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this international text.
+     */
+    @Override
+    public int hashCode() {
+        return (int)serialVersionUID ^ defaultValue.hashCode();
+    }
+
+    /**
+     * Write the string. This is required since {@link #defaultValue} is not serialized.
+     */
+    private void writeObject(final ObjectOutputStream out) throws IOException {
+        out.defaultWriteObject();
+        out.writeUTF(defaultValue);
+    }
+
+    /**
+     * Read the string. This is required since {@link #defaultValue} is not serialized.
+     */
+    private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+        defaultValue = in.readUTF();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/SoftValueHashMap.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/SoftValueHashMap.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/SoftValueHashMap.java	(revision 28000)
@@ -0,0 +1,688 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.lang.ref.SoftReference;
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.logging.Logging;
+
+
+/**
+ * A hash map implementation that uses {@linkplain SoftReference soft references}, leaving memory
+ * when an entry is not used anymore and memory is low.
+ * <p>
+ * This map implementation actually maintains some of the first entries as hard references.
+ * Only oldest entries are retained by soft references, in order to avoid too aggressive garbage
+ * collection. The amount of entries to retain by hard reference is specified at {@linkplain
+ * #SoftValueHashMap(int) construction time}.
+ * <p>
+ * This map is thread-safe. It accepts the null key, but doesn't accepts null values. Usage
+ * of {@linkplain #values value}, {@linkplain #keySet key} or {@linkplain #entrySet entry}
+ * collections are supported except for direct usage of their iterators, which may throw
+ * {@link java.util.ConcurrentModificationException} randomly depending on the garbage collector
+ * activity.
+ *
+ * @param <K> The type of keys in the map.
+ * @param <V> The type of values in the map.
+ *
+ * @since 2.3
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/SoftValueHashMap.java $
+ * @version $Id: SoftValueHashMap.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Simone Giannecchini
+ * @author Martin Desruisseaux
+ */
+public class SoftValueHashMap<K,V> extends AbstractMap<K,V> {
+    static final Logger LOGGER = Logging.getLogger(SoftValueHashMap.class);
+    
+    /**
+     * The default value for {@link #hardReferencesCount}.
+     */
+    private static final int DEFAULT_HARD_REFERENCE_COUNT = 20;
+
+    /**
+     * The map of hard or soft references. Values are either direct reference to the objects,
+     * or wrapped in a {@code Reference} object.
+     */
+    private final Map<K,Object> hash = new HashMap<K,Object>();
+
+    /**
+     * The FIFO list of keys to hard references. Newest elements are first, and latest elements
+     * are last. This list should never be longer than {@link #hardReferencesCount}.
+     */
+    private final LinkedList<K> hardCache = new LinkedList<K>();
+
+    /**
+     * The number of hard references to hold internally.
+     */
+    private final int hardReferencesCount;
+
+    /**
+     * The entries to be returned by {@link #entrySet()}, or {@code null} if not yet created.
+     */
+    private transient Set<Map.Entry<K,V>> entries;
+    
+    /**
+     * Creates a map with the default hard references count.
+     */
+    public SoftValueHashMap() {
+        hardReferencesCount = DEFAULT_HARD_REFERENCE_COUNT;
+    }
+
+    /**
+     * Creates a map with the specified hard references count.
+     *
+     * @param hardReferencesCount The maximal number of hard references to keep.
+     */
+    public SoftValueHashMap(final int hardReferencesCount) {
+        this.hardReferencesCount = hardReferencesCount;
+    }
+
+    /**
+     * Ensures that the specified value is non-null.
+     */
+    private static void ensureNotNull(final Object value) throws IllegalArgumentException {
+        if (value == null) {
+            throw new IllegalArgumentException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1, "value"));
+        }
+    }
+
+    /**
+     * Performs a consistency check on this map. This method is used for tests and
+     * assertions only.
+     */
+    final boolean isValid() {
+        int count=0, size=0;
+        synchronized (hash) {
+            for (final Map.Entry<K,?> entry : hash.entrySet()) {
+                if (entry.getValue() instanceof Reference) {
+                    count++;
+                } else {
+                    assert hardCache.contains(entry.getKey());
+                }
+                size++;
+            }
+            assert size == hash.size();
+            assert hardCache.size() == Math.min(size, hardReferencesCount);
+        }
+        return count == Math.max(size - hardReferencesCount, 0);
+    }
+
+    /**
+     * Returns the number of entries in this map.
+     */
+    @Override
+    public int size() {
+        synchronized (hash) {
+            return hash.size();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this map contains a mapping for the specified key.
+     */
+    @Override
+    public boolean containsKey(final Object key) {
+        synchronized (hash) {
+            return hash.containsKey(key);
+        }
+    }
+
+    /**
+     * Returns {@code true} if this map maps one or more keys to this value.
+     */
+    @Override
+    public boolean containsValue(final Object value) {
+        ensureNotNull(value);
+        synchronized (hash) {
+            /*
+             * We must rely on the super-class default implementation, not on HashMap
+             * implementation, because some references are wrapped into SoftReferences.
+             */
+            return super.containsValue(value);
+        }
+    }
+
+    /**
+     * Returns the value to which this map maps the specified key. Returns {@code null} if
+     * the map contains no mapping for this key, or the value has been garbage collected.
+     *
+     * @param key key whose associated value is to be returned.
+     * @return the value to which this map maps the specified key, or {@code null} if none.
+     */
+    @Override
+    public V get(final Object key) {
+        synchronized (hash) {
+            Object value = hash.get(key);
+            if (value instanceof Reference) {
+                /*
+                 * The value is a soft reference only if it was not used for a while and the map
+                 * contains more than 'hardReferenceCount' entries. Otherwise, it is an ordinary
+                 * reference and is returned directly. See the 'retainStrongly' method.
+                 *
+                 * If the value is a soft reference, get the referent and clear it immediately
+                 * for avoiding the reference to be enqueded. We abandon the soft reference and
+                 * reinject the referent as a strong reference in the hash map, since we try to
+                 * keep the last entries by strong references.
+                 */
+                value = ((Reference) value).getAndClear();
+                if (value != null) {
+                    /*
+                     * Transforms the soft reference into a hard one. The cast should be safe
+                     * because hash.get(key) should not have returned a non-null value if the
+                     * key wasn't valid.
+                     */
+                    @SuppressWarnings("unchecked")
+                    final K k = (K) key;
+                    hash.put(k, value);
+                    retainStrongly(k);
+                } else {
+                    // The value has already been garbage collected.
+                    hash.remove(key);
+                }
+            }
+            /*
+             * The safety of this cast depends only on this implementation, not on users.
+             * It should be safe if there is no bug in the way this class manages 'hash'.
+             */
+            @SuppressWarnings("unchecked")
+            final V v = (V) value;
+            return v;
+        }
+    }
+
+    /**
+     * Declares that the value for the specified key must be retained by hard reference.
+     * If there is already {@link #hardReferencesCount} hard references, then this method
+     * replaces the oldest hard reference by a soft one.
+     */
+    private void retainStrongly(final K key) {
+        assert Thread.holdsLock(hash);
+        assert !hardCache.contains(key) : key;
+        hardCache.addFirst(key);
+        if (hardCache.size() > hardReferencesCount) {
+            // Remove the last entry if list longer than hardReferencesCount
+            final K toRemove = hardCache.removeLast();
+            final Object value = hash.get(toRemove);
+            assert value!=null && !(value instanceof Reference) : toRemove;
+            @SuppressWarnings("unchecked")
+            final V v = (V) value;
+            hash.put(toRemove, new Reference<K,V>(hash, toRemove, v));
+            assert hardCache.size() == hardReferencesCount;
+        }
+        assert isValid();
+    }
+
+    /**
+     * Associates the specified value with the specified key in this map.
+     *
+     * @param key Key with which the specified value is to be associated.
+     * @param value Value to be associated with the specified key. The value can't be null.
+     *
+     * @return Previous value associated with specified key, or {@code null}
+     *	       if there was no mapping for key.
+     */
+    @Override
+    public V put(final K key, final V value) {
+        ensureNotNull(value);
+        synchronized (hash) {
+            Object oldValue = hash.put(key, value);
+            if (oldValue instanceof Reference) {
+                oldValue = ((Reference) oldValue).getAndClear();
+            } else if (oldValue != null) {
+                /*
+                 * The value was retained by hard reference, which implies that the key must be in
+                 * the hard-cache list. Removes the key from the list, since we want to reinsert it
+                 * at the begining of the list in order to mark the value as the most recently used.
+                 * This method performs a linear search, which may be quite ineficient. But it still
+                 * efficient enough if the key was recently used, in which case it appears near the
+                 * begining of the list. We assume that this is a common case. We may revisit later
+                 * if profiling show that this is a performance issue.
+                 */
+                if (!hardCache.remove(key)) {
+                    throw new AssertionError(key);
+                }
+            }
+            retainStrongly(key);
+            @SuppressWarnings("unchecked")
+            final V v = (V) oldValue;
+            return v;
+        }
+    }
+
+    /**
+     * Copies all of the mappings from the specified map to this map.
+     *
+     * @param map Mappings to be stored in this map.
+     */
+    @Override
+    public void putAll(final Map<? extends K, ? extends V> map) {
+        synchronized (hash) {
+            super.putAll(map);
+        }
+    }
+
+    /**
+     * Removes the mapping for this key from this map if present.
+     *
+     * @param  key Key whose mapping is to be removed from the map.
+     * @return previous value associated with specified key, or {@code null}
+     *	       if there was no entry for key.
+     */
+    @Override
+    public V remove(final Object key) {
+        synchronized (hash) {
+            Object oldValue = hash.remove(key);
+            if (oldValue instanceof Reference) {
+                oldValue = ((Reference) oldValue).getAndClear();
+            } else if (oldValue != null) {
+                /*
+                 * See the comment in the 'put' method.
+                 */
+                if (!hardCache.remove(key)) {
+                    throw new AssertionError(key);
+                }
+            }
+            @SuppressWarnings("unchecked")
+            final V v = (V) oldValue;
+            return v;
+        }
+    }
+
+    /**
+     * Removes all mappings from this map.
+     */
+    @Override
+    public void clear() {
+        synchronized (hash) {
+            for (final Iterator it=hash.values().iterator(); it.hasNext();) {
+                final Object value = it.next();
+                if (value instanceof Reference) {
+                    ((Reference) value).getAndClear();
+                }
+            }
+            hash.clear();
+            hardCache.clear();
+        }
+    }
+
+    /**
+     * Returns a set view of the mappings contained in this map.
+     */
+    @Override
+    public Set<Map.Entry<K,V>> entrySet() {
+        synchronized (hash) {
+            if (entries == null) {
+                entries = new Entries();
+            }
+            return entries;
+        }
+    }
+
+    /**
+     * Compares the specified object with this map for equality.
+     *
+     * @param object The object to compare with this map for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        synchronized (hash) {
+            return super.equals(object);
+        }
+    }
+
+    /**
+     * Returns the hash code value for this map.
+     */
+    @Override
+    public int hashCode() {
+        synchronized (hash) {
+            return super.hashCode();
+        }
+    }
+
+    /**
+     * Returns a string representation of this map.
+     */
+    @Override
+    public String toString() {
+        synchronized (hash) {
+            return super.toString();
+        }
+    }
+
+    /**
+     * Implementation of the entries set to be returned by {@link #entrySet()}.
+     */
+    private final class Entries extends AbstractSet<Map.Entry<K,V>> {
+        /**
+         * Returns an iterator over the elements contained in this collection.
+         */
+        public Iterator<Map.Entry<K,V>> iterator() {
+            synchronized (hash) {
+                return new Iter<K,V>(hash);
+            }
+        }
+
+        /**
+         * Returns the number of elements in this collection.
+         */
+        public int size() {
+            return SoftValueHashMap.this.size();
+        }
+
+        /**
+         * Returns {@code true} if this collection contains the specified element.
+         */
+        @Override
+        public boolean contains(final Object entry) {
+            synchronized (hash) {
+                return super.contains(entry);
+            }
+        }
+
+        /**
+         * Returns an array containing all of the elements in this collection.
+         */
+        @Override
+        public Object[] toArray() {
+            synchronized (hash) {
+                return super.toArray();
+            }
+        }
+
+        /**
+         * Returns an array containing all of the elements in this collection.
+         */
+        @Override
+        public <T> T[] toArray(final T[] array) {
+            synchronized (hash) {
+                return super.toArray(array);
+            }
+        }
+
+        /**
+         * Removes a single instance of the specified element from this collection,
+         * if it is present.
+         */
+        @Override
+        public boolean remove(final Object entry) {
+            synchronized (hash) {
+                return super.remove(entry);
+            }
+        }
+
+        /**
+         * Returns {@code true} if this collection contains all of the elements
+         * in the specified collection.
+         */
+        @Override
+        public boolean containsAll(final Collection<?> collection) {
+            synchronized (hash) {
+                return super.containsAll(collection);
+            }
+        }
+
+        /**
+         * Adds all of the elements in the specified collection to this collection.
+         */
+        @Override
+        public boolean addAll(final Collection<? extends Map.Entry<K,V>> collection) {
+            synchronized (hash) {
+                return super.addAll(collection);
+            }
+        }
+
+        /**
+         * Removes from this collection all of its elements that are contained in
+         * the specified collection.
+         */
+        @Override
+        public boolean removeAll(final Collection<?> collection) {
+            synchronized (hash) {
+                return super.removeAll(collection);
+            }
+        }
+
+        /**
+         * Retains only the elements in this collection that are contained in the
+         * specified collection.
+         */
+        @Override
+        public boolean retainAll(final Collection<?> collection) {
+            synchronized (hash) {
+                return super.retainAll(collection);
+            }
+        }
+
+        /**
+         * Removes all of the elements from this collection.
+         */
+        @Override
+        public void clear() {
+            SoftValueHashMap.this.clear();
+        }
+
+        /**
+         * Returns a string representation of this collection.
+         */
+        @Override
+        public String toString() {
+            synchronized (hash) {
+                return super.toString();
+            }
+        }
+    }
+
+    /**
+     * The iterator to be returned by {@link Entries}.
+     */
+    private static final class Iter<K,V> implements Iterator<Map.Entry<K,V>> {
+        /**
+         * A copy of the {@link SoftValueHashMap#hash} field.
+         */
+        private final Map<K,Object> hash;
+
+        /**
+         * The iterator over the {@link #hash} entries.
+         */
+        private final Iterator<Map.Entry<K,Object>> iterator;
+
+        /**
+         * The next entry to be returned by the {@link #next} method, or {@code null}
+         * if not yet computed of if the iteration is finished.
+         */
+        private transient Map.Entry<K,V> entry;
+
+        /**
+         * Creates an iterator for the specified {@link SoftValueHashMap#hash} field.
+         */
+        Iter(final Map<K,Object> hash) {
+            this.hash = hash;
+            this.iterator = hash.entrySet().iterator();
+        }
+
+        /**
+         * Set {@link #entry} to the next entry to iterate. Returns {@code true} if
+         * an entry has been found, or {@code false} if the iteration is finished.
+         */
+        @SuppressWarnings("unchecked")
+        private boolean findNext() {
+            assert Thread.holdsLock(hash);
+            while (iterator.hasNext()) {
+                final Map.Entry<K,Object> candidate = iterator.next();
+                Object value = candidate.getValue();
+                if (value instanceof Reference) {
+                    value = ((Reference) value).get();
+                    entry = new MapEntry<K,V>(candidate.getKey(), (V) value);
+                    return true;
+                }
+                if (value != null) {
+                    entry = (Map.Entry<K,V>) candidate;
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Returns {@code true} if this iterator can return more value.
+         */
+        public boolean hasNext() {
+            synchronized (hash) {
+                return entry!=null || findNext();
+            }
+        }
+
+        /**
+         * Returns the next value. If some value were garbage collected after the
+         * iterator was created, they will not be returned. Note however that a
+         * {@link ConcurrentModificationException} may be throw if the iteration
+         * is not synchronized on {@link #hash}.
+         */
+        public Map.Entry<K,V> next() {
+            synchronized (hash) {
+                if (entry==null && !findNext()) {
+                    throw new NoSuchElementException();
+                }
+                final Map.Entry<K,V> next = entry;
+                entry = null; // Flags that a new entry will need to be lazily fetched.
+                return next;
+            }
+        }
+
+        /**
+         * Removes the last entry.
+         */
+        public void remove() {
+            synchronized (hash) {
+                iterator.remove();
+            }
+        }
+    }
+
+    /**
+     * A soft reference to a map entry. Soft references are created only when the map contains
+     * more than {@link #hardReferencesCount}, in order to avoid to put more pressure on the
+     * garbage collector.
+     */
+    private static final class Reference<K,V> extends SoftReference<V> {
+        /**
+         * A reference to the {@link SoftValueHashMap#hash} entries. We keep this reference instead
+         * than a reference to {@link SoftValueHashMap} itself in order to avoid indirect retention
+         * of {@link SoftValueHashMap#hardCache}, which is not needed for this reference.
+         */
+        private final Map<K,Object> hash;
+
+        /**
+         * The key for the entry to be removed when the soft reference is cleared.
+         */
+        private final K key;
+        
+        /**
+         * The eventual value cleaner
+         */
+        private ValueCleaner cleaner;
+
+        /**
+         * Creates a soft reference for the specified key-value pair.
+         */
+        Reference(final Map<K,Object> hash, final K key, final V value) {
+            super(value, WeakCollectionCleaner.DEFAULT.referenceQueue);
+            this.hash = hash;
+            this.key  = key;
+        }
+
+        /**
+         * Gets and clear this reference object. This method performs no additional operation.
+         * More specifically:
+         * <ul>
+         *   <li>It does not enqueue the reference.</li>
+         *   <li>It does not remove the reference from the hash map.</li>
+         * </ul>
+         * This is because this method is invoked when the entry should have already be removed,
+         * or is about to be removed.</li>
+         */
+        final Object getAndClear() {
+            assert Thread.holdsLock(hash);
+            final Object value = get();
+            super.clear();
+            return value;
+        }
+
+        /**
+         * Removes the entries from the backing hash map. This method need to
+         * override the {@link SoftReference#clear} method because it is invoked
+         * by {@link WeakCollectionCleaner}.
+         */
+        @Override
+        public void clear() {
+            if(cleaner != null) {
+                final Object value = get();
+                if(value != null) {
+                    try {
+                        cleaner.clean(value);
+                    } catch(Throwable t) {
+                        // never let a bad implementation break soft reference cleaning
+                        LOGGER.log(Level.SEVERE, "Exception occurred while cleaning soft referenced object", t);
+                    }
+                }
+            }
+            
+            super.clear();
+            synchronized (hash) {
+                final Object old = hash.remove(key);
+                /*
+                 * If the entry was used for an other value, then put back the old value. This
+                 * case may occurs if a new value was set in the hash map before the old value
+                 * was garbage collected.
+                 */
+                if (old != this && old != null) {
+                    hash.put(key, old);
+                }
+            }
+        }
+    }
+    
+    /**
+     * A delegate that can be used to perform clean up operation, such as resource closing,
+     * before the values cached in soft part of the cache gets disposed of
+     * @author Andrea Aime - OpenGeo
+     *
+     */
+    public static interface ValueCleaner {
+        /**
+         * Cleans the specified object
+         * @param object
+         */
+        public void clean(Object object);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/SynchronizedIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/SynchronizedIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/SynchronizedIterator.java	(revision 28000)
@@ -0,0 +1,74 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.util.Iterator;
+
+
+/**
+ * An iterator synchronized on the given lock. The functionality is equivalent to the one provided
+ * by {@link java.util.Collections#synchronizedSet}'s iterator, except that the synchronization is
+ * performed on an arbitrary lock.
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/SynchronizedIterator.java $
+ * @version $Id: SynchronizedIterator.java 30792 2008-06-23 19:19:58Z desruisseaux $
+ * @author Martin Desruisseaux (IRD)
+ */
+final class SynchronizedIterator<E> implements Iterator<E> {
+    /**
+     * The wrapped iterator.
+     */
+    private final Iterator<E> iterator;
+
+    /**
+     * The lock.
+     */
+    private final Object lock;
+
+    SynchronizedIterator(final Iterator<E> iterator, final Object lock) {
+        this.iterator = iterator;
+        this.lock = lock;
+    }
+
+    /**
+     * Returns {@code true} if there is more elements to iterate over.
+     */
+    public boolean hasNext() {
+        synchronized (lock) {
+            return iterator.hasNext();
+        }
+    }
+
+    /**
+     * Returns the next element in iteratior order.
+     */
+    public E next() {
+        synchronized (lock) {
+            return iterator.next();
+        }
+    }
+
+    /**
+     * Removes the last iterated element.
+     */
+    public void remove() {
+        synchronized (lock) {
+            iterator.remove();
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/UnsupportedImplementationException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/UnsupportedImplementationException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/UnsupportedImplementationException.java	(revision 28000)
@@ -0,0 +1,49 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import org.geotools.resources.i18n.Errors;
+import org.geotools.resources.i18n.ErrorKeys;
+
+
+/**
+ * Throws when an operation can't use arbitrary implementation of an interface, and
+ * a given instance doesn't meet the requirement. For example this exception may be
+ * thrown when an operation requires a Geotools implementation of a
+ * <A HREF="http://geoapi.sourceforge.net">GeoAPI</A> interface.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/UnsupportedImplementationException.java $
+ * @version $Id: UnsupportedImplementationException.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public class UnsupportedImplementationException extends UnsupportedOperationException {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -649050339146622730L;
+
+    /**
+     * Constructs an exception with an error message formatted for the specified class.
+     *
+     * @param classe The unexpected implementation class.
+     */
+    public UnsupportedImplementationException(final Class<?> classe) {
+        super(Errors.format(ErrorKeys.UNKNOW_TYPE_$1, classe));
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/Utilities.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/Utilities.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/Utilities.java	(revision 28000)
@@ -0,0 +1,316 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.io.Serializable;
+import java.util.AbstractQueue;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Queue;
+import java.util.Set;
+
+import org.geotools.factory.Hints;
+
+
+/**
+ * Miscellaneous methods, including cnvenience methods for {@link Object#equals equals} and
+ * {@link Object#hashCode hashCode} implementations. Example use case in a class called
+ * {@code Car}:
+ *
+ * <pre>
+ * public boolean equals(Object other) {
+ *     if (this == aThat) {
+ *         return true;
+ *     }
+ *     if (other == null || !other.getClass().equals(getClass())) {
+ *         return false;
+ *     }
+ *     Car that = (Car) other;
+ *     return Utilities.equals(this.name,              that.name)       &&
+ *            Utilities.equals(this.numDoors,          that.numDoors)   &&
+ *            Utilities.equals(this.gasMileage,        that.gasMileage) &&
+ *            Utilities.equals(this.color,             that.color)      &&
+ *            Arrays   .equals(this.maintenanceChecks, that.maintenanceChecks);
+ * }
+ * </pre>
+ *
+ * Note the usage of {@link Arrays} method for comparing arrays.
+ * <p>
+ * This class also provides convenience methods for computing {@linkplain Object#hashCode hash code}
+ * values. All those methods expect a {@code seed} argument, which is the hash code value computed
+ * for previous fields in a class. For the initial seed (the one for the field for which to compute
+ * an hash code), an arbitrary value must be provided. We suggest a different number for different
+ * class in order to reduce the risk of collision between "empty" instances of different classes.
+ * {@linkplain java.io.Serializable} classes can use {@code (int) serialVersionUID} for example.
+ *
+ * @since 2.5
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/Utilities.java $
+ * @version $Id: Utilities.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public final class Utilities {
+    /**
+     * An array of strings containing only white spaces. Strings' lengths are equal to their
+     * index in the {@code spaces} array. For example, {@code spaces[4]}œcontains a string of
+     * length 4. Strings are constructed only when first needed.
+     */
+    private static final String[] spaces = new String[21];
+    static {
+        final int last = spaces.length - 1;
+        final char[] blancs = new char[last];
+        Arrays.fill(blancs, ' ');
+        spaces[last] = new String(blancs).intern();
+    }
+
+    /**
+     * The singleton instance to be returned by {@link #emptyQueue}.
+     */
+    private static final Queue<?> EMPTY_QUEUE = new EmptyQueue<Object>();
+
+    /**
+     * The class for the {@link #EMPTY_QUEUE} instance. Defined as a named class rather than
+     * anonymous in order to avoid serialization issue.
+     */
+    private static final class EmptyQueue<E> extends AbstractQueue<E> implements Serializable {
+        /** For cross-version compatibility. **/
+        private static final long serialVersionUID = -6147951199761870325L;
+
+        /** No effect on an queue which is already empty. */
+        @Override
+        public void clear() {
+        }
+
+        /** Returns {@code true} is all case. */
+        @Override
+        public boolean isEmpty() {
+            return true;
+        }
+
+        /** Returns the size, which is always 0. */
+        public int size() {
+            return 0;
+        }
+
+        /** Returns an empty iterator. */
+        public Iterator<E> iterator() {
+            final Set<E> empty = Collections.emptySet();
+            return empty.iterator();
+        }
+
+        /** Always returns {@code false} since this queue doesn't accept any element. */
+        public boolean offer(E e) {
+            return false;
+        }
+
+        /** Always returns {@code null} since this queue is always empty. */
+        public E poll() {
+            return null;
+        }
+
+        /** Always returns {@code null} since this queue is always empty. */
+        public E peek() {
+            return null;
+        }
+
+        /** Returns the singleton instance of deserialization. */
+        protected Object readResolve() {
+            return EMPTY_QUEUE;
+        }
+    }
+
+    /**
+     * Forbid object creation.
+     */
+    private Utilities() {
+    }
+
+    /**
+     * Returns {@code true} if the given doubles are equals. Positive and negative zero are
+     * considered different, while a NaN value is considered equal to other NaN values.
+     *
+     * @param o1 The first value to compare.
+     * @param o2 The second value to compare.
+     * @return {@code true} if both values are equal.
+     *
+     * @see Double#equals
+     */
+    public static boolean equals(double o1, double o2) {
+        if (Double.doubleToLongBits(o1) == Double.doubleToLongBits(o2))
+            return true;
+        
+        double tol = getTolerance();
+        final double min = o1 - Math.signum(o1) * o1 * tol; 
+        final double max = o1 + Math.signum(o1) * o1 * tol;
+        return min <= o2 && o2 <= max;
+    }
+    
+    /**
+     * Gathers the tolerance for floating point comparisons
+     * @return The tolerance set in the hints, or its default value if not set
+     */
+    private static double getTolerance() {
+        Double tol = ((Double) Hints.getSystemDefault(Hints.COMPARISON_TOLERANCE));
+        if(tol == null)
+            return Hints.COMPARISON_TOLERANCE.getDefault();
+        else
+            return tol;
+    }
+    
+    /**
+     * Convenience method for testing two objects for equality. One or both objects may be null.
+     * This method do <strong>not</strong> iterates recursively in array elements. If array needs
+     * to be compared, use one of {@link Arrays} method or {@link #deepEquals deepEquals} instead.
+     * <p>
+     * <b>Note on assertions:</b> There is no way to ensure at compile time that this method
+     * is not invoked with array arguments, while doing so would usually be a program error.
+     * Performing a systematic argument check would impose a useless overhead for correctly
+     * implemented {@link Object#equals} methods. As a compromise we perform this check at runtime
+     * only if assertions are enabled. Using assertions for argument check in a public API is
+     * usually a deprecated practice, but we make an exception for this particular method.
+     * <p>
+     * <b>Note on method overloading:</b> This method could be selected by the compiler for
+     * comparing primitive types, because the compiler could perform an auto-boxing and get
+     * a result assignable to {@code Object}. However it should not occur in practice because
+     * overloaded (and more efficient) methods are provided for every primitive types. This is
+     * true even when the two arguments are different primitive type because of widening
+     * conversions. The only exception is when a {@code boolean} argument is mixed with a
+     * different primitive type.
+     *
+     * @param object1 The first object to compare, or {@code null}.
+     * @param object2 The second object to compare, or {@code null}.
+     * @return {@code true} if both objects are equal.
+     * @throws AssertionError If assertions are enabled and at least one argument is an array.
+     */
+    public static boolean equals(final Object object1, final Object object2) throws AssertionError {
+        assert object1 == null || !object1.getClass().isArray() : object1;
+        assert object2 == null || !object2.getClass().isArray() : object2;
+        return (object1 == object2) || (object1 != null && object1.equals(object2));
+    }
+
+    /**
+     * Convenience method for testing two objects for equality. One or both objects may be null.
+     * If both are non-null and are arrays, then every array elements will be compared.
+     * <p>
+     * This method may be useful when the objects may or may not be array. If they are known
+     * to be arrays, consider using {@link Arrays#deepEquals(Object[],Object[])} or one of its
+     * primitive counter-part instead.
+     * <p>
+     * <strong>Rules for choosing an {@code equals} or {@code deepEquals} method</strong>
+     * <ul>
+     *   <li>If <em>both</em> objects are declared as {@code Object[]} (not anything else like
+     *   {@code String[]}), consider using {@link Arrays#deepEquals(Object[],Object[])} except
+     *   if it is known that the array elements can never be other arrays.</li>
+     *
+     *   <li>Otherwise if both objects are arrays (e.g. {@code Expression[]}, {@code String[]},
+     *   {@code int[]}, <cite>etc.</cite>), use {@link Arrays#equals(Object[],Object[])}. This
+     *   rule is applicable to arrays of primitive type too, since {@code Arrays.equals} is
+     *   overriden with primitive counter-parts.</li>
+     *
+     *   <li>Otherwise if at least one object is anything else than {@code Object} (e.g.
+     *   {@code String}, {@code Expression}, <cite>etc.</cite>), use {@link #equals(Object,Object)}.
+     *   Using this {@code deepEquals} method would be an overkill since there is no chance that
+     *   {@code String} or {@code Expression} could be an array.</li>
+     *
+     *   <li>Otherwise if <em>both</em> objects are declared exactly as {@code Object} type and
+     *   it is known that they could be arrays, only then invoke this {@code deepEquals} method.
+     *   In such case, make sure that the hash code is computed using {@link #deepHashCode} for
+     *   consistency.</li>
+     * </ul>
+     *
+     * @param object1 The first object to compare, or {@code null}.
+     * @param object2 The second object to compare, or {@code null}.
+     * @return {@code true} if both objects are equal.
+     */
+    public static boolean deepEquals(final Object object1, final Object object2) {
+        if (object1 == object2) {
+            return true;
+        }
+        if (object1 == null || object2 == null) {
+            return false;
+        }
+        if (object1 instanceof Object[]) {
+            return (object2 instanceof Object[]) &&
+                    Arrays.deepEquals((Object[]) object1, (Object[]) object2);
+        }
+        if (object1 instanceof double[]) {
+            return (object2 instanceof double[]) &&
+                    Arrays.equals((double[]) object1, (double[]) object2);
+        }
+        if (object1 instanceof float[]) {
+            return (object2 instanceof float[]) &&
+                    Arrays.equals((float[]) object1, (float[]) object2);
+        }
+        if (object1 instanceof long[]) {
+            return (object2 instanceof long[]) &&
+                    Arrays.equals((long[]) object1, (long[]) object2);
+        }
+        if (object1 instanceof int[]) {
+            return (object2 instanceof int[]) &&
+                    Arrays.equals((int[]) object1, (int[]) object2);
+        }
+        if (object1 instanceof short[]) {
+            return (object2 instanceof short[]) &&
+                    Arrays.equals((short[]) object1, (short[]) object2);
+        }
+        if (object1 instanceof byte[]) {
+            return (object2 instanceof byte[]) &&
+                    Arrays.equals((byte[]) object1, (byte[]) object2);
+        }
+        if (object1 instanceof char[]) {
+            return (object2 instanceof char[]) &&
+                    Arrays.equals((char[]) object1, (char[]) object2);
+        }
+        if (object1 instanceof boolean[]) {
+            return (object2 instanceof boolean[]) &&
+                    Arrays.equals((boolean[]) object1, (boolean[]) object2);
+        }
+        return object1.equals(object2);
+    }
+
+    /**
+     * Returns a string of the specified length filled with white spaces.
+     * This method tries to return a pre-allocated string if possible.
+     *
+     * @param  length The string length. Negative values are clamped to 0.
+     * @return A string of length {@code length} filled with white spaces.
+     */
+    public static String spaces(int length) {
+        /*
+         * No need to synchronize.  In the unlikely event of two threads calling this method
+         * at the same time and the two calls creating a new string, the String.intern() call
+         * will take care of canonicalizing the strings.
+         */
+        if (length < 0) {
+            length = 0;
+        }
+        String s;
+        if (length < spaces.length) {
+            s = spaces[length];
+            if (s == null) {
+                s = spaces[spaces.length - 1].substring(0, length).intern();
+                spaces[length] = s;
+            }
+        } else {
+            char[] blancs = new char[length];
+            Arrays.fill(blancs, ' ');
+            s = new String(blancs);
+        }
+        return s;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/Version.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/Version.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/Version.java	(revision 28000)
@@ -0,0 +1,253 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.io.Serializable;
+import java.util.regex.Pattern;
+
+
+/**
+ * Holds a version number. Versions are often of the form <code>{@linkplain #getMajor
+ * major}.{@linkplain #getMinor minor}.{@linkplain #getRevision revision}</code>, but
+ * are not required to. For example an EPSG database version is {@code "6.11.2"}. The
+ * separator character is the dot.
+ * <p>
+ * This class provides convenience methods for fetching the major, minor and reversion
+ * numbers, and for performing comparaisons.
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/Version.java $
+ * @version $Id: Version.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ *
+ * @see org.geotools.factory.GeoTools#getVersion
+ */
+public class Version implements CharSequence, Comparable<Version>, Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -6793384507333713770L;
+
+    /**
+     * The pattern to use for splitting version numbers.
+     */
+    private static final Pattern PATTERN = Pattern.compile("(\\.|\\-)");
+
+    /**
+     * The version in string form, with leading and trailing spaces removed.
+     */
+    private final String version;
+
+    /**
+     * The components of the version string. Will be created when first needed.
+     */
+    private transient String[] components;
+
+    /**
+     * The parsed components of the version string. Will be created when first needed.
+     */
+    private transient Comparable<?>[] parsed;
+
+    /**
+     * The hash code value. Will be computed when first needed.
+     */
+    private transient int hashCode;
+
+    /**
+     * Creates a new version object from the supplied string.
+     *
+     * @param version The version as a string.
+     */
+    public Version(final String version) {
+        this.version = version.trim();
+    }
+
+    /**
+     * Returns the specified components of this version string. For a version of the
+     * {@code major.minor.revision} form, index 0 stands for the major version number,
+     * 1 stands for the minor version number and 2 stands for the revision number.
+     * <p>
+     * The return value is an {@link Integer} if the component is parsable as an integer,
+     * or a {@link String} otherwise. If there is no component at the specified index,
+     * then this method returns {@code null}.
+     *
+     * @param  index The index of the component to fetch.
+     * @return The value at the specified index, or {@code null} if none.
+     * @throws IndexOutOfBoundsException if {@code index} is negative.
+     */
+    public synchronized Comparable<?> getComponent(final int index) {
+        if (parsed == null) {
+            if (components == null) {
+                components = PATTERN.split(version);
+            }
+            parsed = new Comparable[components.length];
+        }
+        if (index >= parsed.length) {
+            return null;
+        }
+        Comparable<?> candidate = parsed[index];
+        if (candidate == null) {
+            final String value = components[index].trim();
+            try {
+                candidate = Integer.valueOf(value);
+            } catch (NumberFormatException e) {
+                candidate = value;
+            }
+            parsed[index] = candidate;
+        }
+        return candidate;
+    }
+
+    /**
+     * Get the rank of the specified object according this type.
+     * This is for {@link #compareTo(Version, int)} internal only.
+     */
+    private static int getTypeRank(final Object value) {
+        if (value instanceof CharSequence) {
+            return 0;
+        }
+        if (value instanceof Number) {
+            return 1;
+        }
+        throw new IllegalArgumentException(String.valueOf(value));
+    }
+
+    /**
+     * Compares this version with an other version object, up to the specified limit. A limit
+     * of 1 compares only the {@linkplain #getMajor major} version number. A limit of 2 compares
+     * the major and {@linkplain #getMinor minor} version numbers, <cite>etc</cite>. The
+     * comparaisons are performed as {@link Integer} object if possible, or as {@link String}
+     * otherwise.
+     *
+     * @param  other The other version object to compare with.
+     * @param  limit The maximum number of components to compare.
+     * @return A negative value if this version is lower than the supplied version, a positive
+     *         value if it is higher, or 0 if they are equal.
+     */
+    public int compareTo(final Version other, final int limit) {
+        for (int i=0; i<limit; i++) {
+            final Comparable<?> v1 =  this.getComponent(i);
+            final Comparable<?> v2 = other.getComponent(i);
+            if (v1 == null) {
+                return (v2 == null) ? 0 : -1;
+            } else if (v2 == null) {
+                return +1;
+            }
+            final int dr = getTypeRank(v1) - getTypeRank(v2);
+            if (dr != 0) {
+                /*
+                 * One value is a text while the other value is a number.  We could be tempted to
+                 * force a comparaison by converting the number to a String and then invoking the
+                 * String.compareTo(String) method, but this strategy would violate the following
+                 * contract from Comparable.compareTo(Object):  "The implementor must also ensure
+                 * that the relation is transitive". Use case:
+                 *
+                 *    A is the integer 10
+                 *    B is the string "8Z"
+                 *    C is the integer 5.
+                 *
+                 * If mismatched types are converted to String before being compared, then we
+                 * would have A < B < C. Transitivity implies that A < C, but if we compare A
+                 * and C directly we get A > C because they are compared as numbers.  An easy
+                 * way to fix this inconsistency is to define all String as lexicographically
+                 * preceding Integer, no matter their content. This is what we do here.
+                 */
+                return dr;
+            }
+            @SuppressWarnings("unchecked")
+            final int c = ((Comparable) v1).compareTo(v2);
+            if (c != 0) {
+                return c;
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Compares this version with an other version object. This method performs the same
+     * comparaison than {@link #compareTo(Version, int)} with no limit.
+     *
+     * @param  other The other version object to compare with.
+     * @return A negative value if this version is lower than the supplied version, a positive
+     *         value if it is higher, or 0 if they are equal.
+     */
+    public int compareTo(final Version other) {
+        return compareTo(other, Integer.MAX_VALUE);
+    }
+
+    /**
+     * Compare this version string with the specified object for equality. Two version are
+     * considered equal if <code>{@linkplain #compareTo(Object) compareTo}(other) == 0</code>.
+     *
+     * @param other The object to compare with this version for equality.
+     */
+    @Override
+    public boolean equals(final Object other) {
+        if (other != null && getClass().equals(other.getClass())) {
+            return compareTo((Version) other) == 0;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the length of the version string.
+     */
+    public int length() {
+        return version.length();
+    }
+
+    /**
+     * Returns the {@code char} value at the specified index.
+     */
+    public char charAt(final int index) {
+        return version.charAt(index);
+    }
+
+    /**
+     * Returns a new version string that is a subsequence of this sequence.
+     */
+    public CharSequence subSequence(final int start, final int end) {
+        return version.subSequence(start, end);
+    }
+
+    /**
+     * Returns the version string. This is the string specified at construction time.
+     */
+    @Override
+    public String toString() {
+        return version;
+    }
+
+    /**
+     * Returns a hash code value for this version.
+     */
+    @Override
+    public int hashCode() {
+        if (hashCode == 0) {
+            int code = (int) serialVersionUID;
+            int index = 0;
+            Comparable<?> component;
+            while ((component = getComponent(index)) != null) {
+                code = code * 37 + component.hashCode();
+                index++;
+            }
+            hashCode = code;
+        }
+        return hashCode;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/WeakCollectionCleaner.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/WeakCollectionCleaner.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/WeakCollectionCleaner.java	(revision 28000)
@@ -0,0 +1,105 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+
+import org.geotools.util.logging.Logging;
+
+
+/**
+ * A thread invoking {@link Reference#clear} on each enqueded reference.
+ * This is usefull only if {@code Reference} subclasses has overridden
+ * their {@code clear()} method in order to perform some cleaning.
+ * This thread is used by {@link WeakHashSet} and {@link WeakValueHashMap},
+ * which remove their entry from the collection when {@link Reference#clear}
+ * is invoked.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/WeakCollectionCleaner.java $
+ * @version $Id: WeakCollectionCleaner.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ */
+public final class WeakCollectionCleaner extends Thread {
+    /**
+     * The default thread.
+     */
+    public static final WeakCollectionCleaner DEFAULT = new WeakCollectionCleaner();
+
+    /**
+     * List of reference collected by the garbage collector.
+     * Those elements must be removed from {@link #table}.
+     */
+    ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();
+    
+    /**
+     * Constructs and starts a new thread as a daemon. This thread will be sleeping
+     * most of the time.  It will run only some few nanoseconds each time a new
+     * {@link Reference} is enqueded.
+     */
+    private WeakCollectionCleaner() {
+        super("WeakCollectionCleaner");
+        setPriority(MAX_PRIORITY - 2);
+        setDaemon(true);
+        start();
+    }
+    
+    public synchronized ReferenceQueue<Object> getReferenceQueue() {
+        return referenceQueue;
+    }
+
+    /**
+     * Loop to be run during the virtual machine lifetime.
+     */
+    @Override
+    public void run() {
+        ReferenceQueue<Object> rq;
+        while ((rq = getReferenceQueue ()) != null) {
+            try {
+                // Block until a reference is enqueded.
+                final Reference ref = rq.remove();
+                if (ref == null) {
+                    /*
+                     * Should never happen according Sun's Javadoc ("Removes the next reference
+                     * object in this queue, blocking until one becomes available."). However a
+                     * null reference seems to be returned during JVM shutdown on Linux. Wait a
+                     * few seconds in order to give the JVM a chance to kill this daemon thread
+                     * before the logging at the sever level, and stop the loop.  We do not try
+                     * to resume the loop since something is apparently going wrong and we want
+                     * the user to be notified. See GEOT-1138.
+                     */
+                    sleep(15 * 1000L);
+                    break;
+                }
+                ref.clear();
+                // Note: To be usefull, the clear() method must have been overridden in Reference
+                //       subclasses. This is what WeakHashSet.Entry and WeakHashMap.Entry do.
+            } catch (InterruptedException exception) {
+                // Somebody doesn't want to lets us sleep... Go back to work.
+            } catch (Exception exception) {
+                Logging.unexpectedException(WeakCollectionCleaner.class, "remove", exception);
+            } catch (AssertionError exception) {
+                Logging.unexpectedException(WeakCollectionCleaner.class, "remove", exception);
+                // Do not kill the thread on assertion failure, in order to
+                // keep the same behaviour as if assertions were turned off.
+            }
+        }
+        Logging.getLogger(WeakCollectionCleaner.class).info("Weak collection cleaner stopped");
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/WeakHashSet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/WeakHashSet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/WeakHashSet.java	(revision 28000)
@@ -0,0 +1,446 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Array;
+import java.util.AbstractSet;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.geotools.resources.XArray;
+import org.geotools.util.logging.Logging;
+
+
+/**
+ * A set of objects hold by weak references. An entry in a {@code WeakHashSet}
+ * will automatically be removed when it is no longer in ordinary use. More precisely,
+ * the presence of an entry will not prevent the entry from being discarded by the
+ * garbage collector, that is, made finalizable, finalized, and then reclaimed.
+ * When an entry has been discarded it is effectively removed from the set, so
+ * this class behaves somewhat differently than other {@link java.util.Set} implementations.
+ * <p>
+ * If you would like to use {@code WeakHashSet} as inside a factory to prevent creating
+ * duplicate immutable objects, please look at the {@link CanonicalSet} subclass.
+ * <p>
+ * The {@code WeakHashSet} class is thread-safe.
+ *
+ * @param <E> The type of elements in the set.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/WeakHashSet.java $
+ * @version $Id: WeakHashSet.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see java.util.WeakHashMap
+ */
+public class WeakHashSet<E> extends AbstractSet<E> implements CheckedCollection<E> {
+    /**
+     * Minimal capacity for {@link #table}.
+     */
+    private static final int MIN_CAPACITY = 7;
+
+    /**
+     * Load factor. Control the moment
+     * where {@link #table} must be rebuild.
+     */
+    private static final float LOAD_FACTOR = 0.75f;
+
+    /**
+     * A weak reference to an element.
+     */
+    private final class Entry extends WeakReference<E> {
+        /**
+         * The next entry, or {@code null} if there is none.
+         */
+        Entry next;
+
+        /**
+         * Index for this element in {@link #table}. This index
+         * must be updated at every {@link #rehash} call.
+         */
+        int index;
+
+        /**
+         * Constructs a new weak reference.
+         */
+        Entry(final E obj, final Entry next, final int index) {
+            super(obj, WeakCollectionCleaner.DEFAULT.referenceQueue);
+            this.next  = next;
+            this.index = index;
+        }
+
+        /**
+         * Clear the reference.
+         */
+        @Override
+        public void clear() {
+            super.clear();
+            removeEntry(this);
+        }
+    }
+
+    /**
+     * Table of weak references.
+     */
+    private Entry[] table;
+
+    /**
+     * The type of the elements in this set.
+     */
+    private final Class<E> type;
+
+    /**
+     * Number of non-nul elements in {@link #table}.
+     */
+    private int count;
+
+    /**
+     * The next size value at which to resize. This value should
+     * be <code>{@link #table}.length*{@link #loadFactor}</code>.
+     */
+    private int threshold;
+
+    /**
+     * The timestamp when {@link #table} was last rehashed. This information
+     * is used to avoid too early table reduction. When the garbage collector
+     * collected a lot of elements, we will wait at least 20 seconds before
+     * rehashing {@link #table}. Too early table reduction leads to many cycles
+     * like "reduce", "expand", "reduce", "expand", etc.
+     */
+    private long lastRehashTime;
+
+    /**
+     * Number of millisecond to wait before to rehash
+     * the table for reducing its size.
+     */
+    private static final long HOLD_TIME = 20*1000L;
+
+    /**
+     * Constructs a {@code WeakHashSet}.
+     *
+     * @deprecated Use {@link WeakHashSet(Class)}.
+     */
+    @SuppressWarnings("unchecked")
+    public WeakHashSet() {
+        this((Class) Object.class);
+    }
+
+    /**
+     * Constructs a {@code WeakHashSet}.
+     *
+     * @param type The type of the element to be included in this set.
+     *
+     * @since 2.5
+     */
+    public WeakHashSet(final Class<E> type) {
+        this.type = type;
+        newEntryTable(MIN_CAPACITY);
+        threshold = Math.round(table.length*LOAD_FACTOR);
+        lastRehashTime = System.currentTimeMillis();
+    }
+
+    /**
+     * Sets the {@link #table} array to the specified size. The content of the old array is lost.
+     *
+     * @todo Use the commented line instead if a future Java version supports generic arrays.
+     */
+    private void newEntryTable(final int size) {
+//      table = new Entry[size];
+        table = (Entry[]) Array.newInstance(Entry.class, size);
+    }
+
+    /**
+     * Returns the element type.
+     *
+     * @since 2.5
+     */
+    public Class<E> getElementType() {
+        return type;
+    }
+
+    /**
+     * Invoked by {@link Entry} when an element has been collected by the garbage
+     * collector. This method will remove the weak reference from {@link #table}.
+     */
+    private synchronized void removeEntry(final Entry toRemove) {
+        assert valid() : count;
+        final int i = toRemove.index;
+        // Index 'i' may not be valid if the reference 'toRemove'
+        // has been already removed in a previous rehash.
+        if (i < table.length) {
+            Entry prev = null;
+            Entry e = table[i];
+            while (e != null) {
+                if (e == toRemove) {
+                    if (prev != null) {
+                        prev.next = e.next;
+                    } else {
+                        table[i] = e.next;
+                    }
+                    count--;
+                    assert valid();
+
+                    // If the number of elements has dimunished
+                    // significatively, rehash the table.
+                    if (count <= threshold/4) {
+                        rehash(false);
+                    }
+                    // We must not continue the loop, since
+                    // variable 'e' is no longer valid.
+                    return;
+                }
+                prev = e;
+                e = e.next;
+            }
+        }
+        assert valid();
+        /*
+         * If we reach this point, its mean that reference 'toRemove' has not
+         * been found. This situation may occurs if 'toRemove' has already been
+         * removed in a previous run of {@link #rehash}.
+         */
+    }
+
+    /**
+     * Rehash {@link #table}.
+     *
+     * @param augmentation
+     *          {@code true} if this method is invoked for augmenting {@link #table},
+     *          or {@code false} if it is invoked for making the table smaller.
+     */
+    private void rehash(final boolean augmentation) {
+        assert Thread.holdsLock(this);
+        assert valid();
+        final long currentTime = System.currentTimeMillis();
+        final int capacity = Math.max(Math.round(count/(LOAD_FACTOR/2)), count+MIN_CAPACITY);
+        if (augmentation ? (capacity<=table.length) :
+                           (capacity>=table.length || currentTime-lastRehashTime<HOLD_TIME))
+        {
+            return;
+        }
+        lastRehashTime = currentTime;
+        final Entry[] oldTable = table;
+        newEntryTable(capacity);
+        threshold = Math.round(capacity*LOAD_FACTOR);
+        for (int i=0; i<oldTable.length; i++) {
+            for (Entry old=oldTable[i]; old!=null;) {
+                final Entry e=old;
+                old = old.next; // We keep 'next' right now because its value will change.
+                final E obj_e = e.get();
+                if (obj_e != null) {
+                    final int index = (obj_e.hashCode() & 0x7FFFFFFF) % table.length;
+                    e.index = index;
+                    e.next  = table[index];
+                    table[index]=e;
+                } else {
+                    count--;
+                }
+            }
+        }
+        final Logger logger = Logging.getLogger("org.geotools.util");
+        final Level   level = Level.FINEST;
+        if (logger.isLoggable(level)) {
+            final LogRecord record = new LogRecord(level,
+                    "Rehash from " + oldTable.length + " to " + table.length);
+            record.setSourceMethodName(augmentation ? "unique" : "remove");
+            record.setSourceClassName(WeakHashSet.class.getName());
+            record.setLoggerName(logger.getName());
+            logger.log(record);
+        }
+        assert valid();
+    }
+
+    /**
+     * Checks if this {@code WeakHashSet} is valid. This method counts the
+     * number of elements and compare it to {@link #count}. If the check fails,
+     * the number of elements is corrected (if we didn't, an {@link AssertionError}
+     * would be thrown for every operations after the first error,  which make
+     * debugging more difficult). The set is otherwise unchanged, which should
+     * help to get similar behaviour as if assertions hasn't been turned on.
+     */
+    private boolean valid() {
+        int n = 0;
+        for (int i=0; i<table.length; i++) {
+            for (Entry e=table[i]; e!=null; e=e.next) {
+                n++;
+            }
+        }
+        if (n!=count) {
+            count = n;
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Returns the count of element in this set.
+     */
+    public synchronized int size() {
+        assert valid();
+        return count;
+    }
+
+    /**
+     * Returns {@code true} if this set contains the specified element.
+     *
+     * @param  obj Object to be checked for containment in this set.
+     * @return {@code true} if this set contains the specified element.
+     */
+    @Override
+    public synchronized boolean contains(final Object obj) {
+        return obj != null && intern(type.cast(obj), GET) != null;
+    }
+
+    /**
+     * Removes a single instance of the specified element from this set, if it is present
+     *
+     * @param  obj element to be removed from this set, if present.
+     * @return {@code true} if the set contained the specified element.
+     */
+    @Override
+    public synchronized boolean remove(final Object obj) {
+        return intern(type.cast(obj), REMOVE) != null;
+    }
+
+    /**
+     * Adds the specified element to this set if it is not already present.
+     * If this set already contains the specified element, the call leaves
+     * this set unchanged and returns {@code false}.
+     *
+     * @param  obj Element to be added to this set.
+     * @return {@code true} if this set did not already contain the specified element.
+     */
+    @Override
+    public synchronized boolean add(final E obj) {
+        return intern(obj, ADD) == null;
+    }
+
+    // Arguments for the {@link #intern} method.
+    /** The "remove" operation.  */  static final int REMOVE = -1;
+    /** The "get"    operation.  */  static final int GET    =  0;
+    /** The "add"    operation.  */  static final int ADD    = +1;
+    /** The "intern" operation.  */  static final int INTERN = +2;
+
+    /**
+     * Returns an object equals to {@code obj} if such an object already
+     * exist in this {@code WeakHashSet}. Otherwise, add {@code obj}
+     * to this {@code WeakHashSet}. This method is equivalents to the
+     * following code:
+     *
+     * <blockquote><pre>
+     * &nbsp;  if (object!=null) {
+     * &nbsp;      final Object current = get(object);
+     * &nbsp;      if (current != null) {
+     * &nbsp;          return current;
+     * &nbsp;      } else {
+     * &nbsp;          add(object);
+     * &nbsp;      }
+     * &nbsp;  }
+     * &nbsp;  return object;
+     * </pre></blockquote>
+     */
+    final <T extends E> T intern(final T obj, final int operation) {
+        assert Thread.holdsLock(this);
+        assert WeakCollectionCleaner.DEFAULT.isAlive();
+        assert valid() : count;
+        if (obj != null) {
+            assert obj.equals(obj) : obj;
+            /*
+             * Check if {@code obj} is already contained in this
+             * {@code WeakHashSet}. If yes, returns the element.
+             */
+            final int hash = obj.hashCode() & 0x7FFFFFFF;
+            int index = hash % table.length;
+            for (Entry e=table[index]; e!=null; e=e.next) {
+                final E candidate = e.get();
+                if (candidate != null) {
+                    if (candidate.equals(obj)) {
+                        if (operation == REMOVE) {
+                            e.clear();
+                        }
+                        assert candidate.getClass().equals(obj.getClass()) : candidate;
+                        @SuppressWarnings("unchecked")
+                        final T result = (T) candidate;
+                        return result;
+                    }
+                }
+                // Do not remove the null element; lets ReferenceQueue do its job
+                // (it was a bug to remove element here as an "optimization")
+            }
+            if (operation >= ADD) {
+                /*
+                 * Check if the table need to be rehashed,
+                 * and add {@code obj} to the table.
+                 */
+                if (count >= threshold) {
+                    rehash(true);
+                    index = hash % table.length;
+                }
+                table[index] = new Entry(obj, table[index], index);
+                count++;
+            }
+        }
+        assert valid();
+        return (operation == INTERN) ? obj : null;
+    }
+
+    /**
+     * Removes all of the elements from this set.
+     */
+    @Override
+    public synchronized void clear() {
+        Arrays.fill(table, null);
+        count = 0;
+    }
+
+    /**
+     * Returns a view of this set as an array. Elements will be in an arbitrary
+     * order. Note that this array contains strong reference.  Consequently, no
+     * object reclamation will occurs as long as a reference to this array is hold.
+     */
+    @Override
+    public synchronized E[] toArray() {
+        assert valid();
+        @SuppressWarnings("unchecked")
+        final E[] elements = (E[]) Array.newInstance(type, count);
+        int index = 0;
+        for (int i=0; i<table.length; i++) {
+            for (Entry el=table[i]; el!=null; el=el.next) {
+                if ((elements[index]=el.get()) != null) {
+                    index++;
+                }
+            }
+        }
+        return XArray.resize(elements, index);
+    }
+
+    /**
+     * Returns an iterator over the elements contained in this collection.
+     * No element from this set will be garbage collected as long as a
+     * reference to the iterator is hold.
+     */
+    @Override
+    public Iterator<E> iterator() {
+        return Arrays.asList(toArray()).iterator();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/WeakValueHashMap.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/WeakValueHashMap.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/WeakValueHashMap.java	(revision 28000)
@@ -0,0 +1,468 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Array;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.geotools.util.logging.Logging;
+
+
+/**
+ * A hashtable-based {@link Map} implementation with <em>weak values</em>. An entry in a
+ * {@code WeakValueHashMap} will automatically be removed when its value is no longer
+ * in ordinary use. This class is similar to the standard {@link java.util.WeakHashMap}
+ * class provided in J2SE, except that weak references are hold on values instead of keys.
+ * <p>
+ * The {@code WeakValueHashMap} class is thread-safe.
+ *
+ * @param <K> The class of key elements.
+ * @param <V> The class of value elements.
+ *
+ * @since 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/WeakValueHashMap.java $
+ * @version $Id: WeakValueHashMap.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux (IRD)
+ *
+ * @see java.util.WeakHashMap
+ * @see WeakHashSet
+ */
+public class WeakValueHashMap<K,V> extends AbstractMap<K,V> {
+    /**
+     * Minimal capacity for {@link #table}.
+     */
+    private static final int MIN_CAPACITY = 7;
+
+    /**
+     * Load factor. Control the moment
+     * where {@link #table} must be rebuild.
+     */
+    private static final float LOAD_FACTOR = 0.75f;
+
+    /**
+     * An entry in the {@link WeakValueHashMap}. This is a weak reference
+     * to a value together with a strong reference to a key.
+     */
+    private final class Entry extends WeakReference<V> implements Map.Entry<K,V> {
+        /**
+         * The key.
+         */
+        K key;
+
+        /**
+         * The next entry, or {@code null} if there is none.
+         */
+        Entry next;
+
+        /**
+         * Index for this element in {@link #table}. This index
+         * must be updated at every {@link #rehash} call.
+         */
+        int index;
+
+        /**
+         * Constructs a new weak reference.
+         */
+        Entry(final K key, final V value, final Entry next, final int index) {
+            super(value, WeakCollectionCleaner.DEFAULT.referenceQueue);
+            this.key   = key;
+            this.next  = next;
+            this.index = index;
+        }
+
+        /**
+         * Returns the key corresponding to this entry.
+         */
+        public K getKey() {
+            return key;
+        }
+
+        /**
+         * Returns the value corresponding to this entry.
+         */
+        public V getValue() {
+            return get();
+        }
+
+        /**
+         * Replaces the value corresponding to this entry with the specified value.
+         */
+        public V setValue(final V value) {
+            if (value != null) {
+                throw new UnsupportedOperationException();
+            }
+            V old = get();
+            clear();
+            return old;
+        }
+
+        /**
+         * Clear the reference. The {@link WeakCollectionCleaner} requires that this method is
+         * overridden in order to remove this entry from the enclosing hash map.
+         */
+        @Override
+        public void clear() {
+            super.clear();
+            removeEntry(this);
+            key = null;
+        }
+
+        /**
+         * Compares the specified object with this entry for equality.
+         */
+        @Override
+        public boolean equals(final Object other) {
+            if (other instanceof Map.Entry) {
+                final Map.Entry that = (Map.Entry) other;
+                return Utilities.equals(this.getKey(),   that.getKey()) &&
+                       Utilities.equals(this.getValue(), that.getValue());
+            }
+            return false;
+        }
+
+        /**
+         * Returns the hash code value for this map entry.
+         */
+        @Override
+        public int hashCode() {
+            final Object val = get();
+            return (key==null ? 0 : key.hashCode()) ^
+                   (val==null ? 0 : val.hashCode());
+        }
+    }
+
+    /**
+     * Table of weak references.
+     */
+    private Entry[] table;
+
+    /**
+     * Number of non-nul elements in {@link #table}.
+     */
+    private int count;
+
+    /**
+     * The next size value at which to resize. This value should
+     * be <code>{@link #table}.length*{@link #loadFactor}</code>.
+     */
+    private int threshold;
+
+    /**
+     * The timestamp when {@link #table} was last rehashed. This information
+     * is used to avoid too early table reduction. When the garbage collector
+     * collected a lot of elements, we will wait at least 20 seconds before
+     * rehashing {@link #table}. Too early table reduction leads to many cycles
+     * like "reduce", "expand", "reduce", "expand", etc.
+     */
+    private long lastRehashTime;
+
+    /**
+     * Number of millisecond to wait before to rehash
+     * the table for reducing its size.
+     */
+    private static final long HOLD_TIME = 20*1000L;
+
+    /**
+     * Creates a {@code WeakValueHashMap}.
+     */
+    public WeakValueHashMap() {
+        this(MIN_CAPACITY);
+    }
+
+    /**
+     * Creates a {@code WeakValueHashMap} of the requested size and default load factor.
+     *
+     * @param initialSize The initial size.
+     */
+    public WeakValueHashMap(final int initialSize) {
+        newEntryTable(initialSize);
+        threshold = Math.round(table.length * LOAD_FACTOR);
+        lastRehashTime = System.currentTimeMillis();
+    }
+
+    /**
+     * Sets the {@link #table} array to the specified size. The content of the old array is lost.
+     *
+     * @todo Use the commented line instead if a future Java version supports generic arrays.
+     */
+    private void newEntryTable(final int size) {
+//      table = new Entry[size];
+        table = (Entry[]) Array.newInstance(Entry.class, size);
+    }
+
+    /**
+     * Invoked by {@link Entry} when an element has been collected
+     * by the garbage collector. This method will remove the weak reference
+     * from {@link #table}.
+     */
+    private synchronized void removeEntry(final Entry toRemove) {
+        assert valid() : count;
+        final int i = toRemove.index;
+        // Index 'i' may not be valid if the reference 'toRemove'
+        // has been already removed in a previous rehash.
+        if (i < table.length) {
+            Entry prev = null;
+            Entry e = table[i];
+            while (e != null) {
+                if (e == toRemove) {
+                    if (prev != null) {
+                        prev.next = e.next;
+                    } else {
+                        table[i] = e.next;
+                    }
+                    count--;
+                    assert valid();
+
+                    // If the number of elements has dimunished
+                    // significatively, rehash the table.
+                    if (count <= threshold/4) {
+                        rehash(false);
+                    }
+                    // We must not continue the loop, since
+                    // variable 'e' is no longer valid.
+                    return;
+                }
+                prev = e;
+                e = e.next;
+            }
+        }
+        assert valid();
+        /*
+         * If we reach this point, its mean that reference 'toRemove' has not
+         * been found. This situation may occurs if 'toRemove' has already been
+         * removed in a previous run of {@link #rehash}.
+         */
+    }
+
+    /**
+     * Rehashs {@link #table}.
+     *
+     * @param augmentation {@code true} if this method is invoked
+     *        for augmenting {@link #table}, or {@code false} if
+     *        it is invoked for making the table smaller.
+     */
+    private void rehash(final boolean augmentation) {
+        assert Thread.holdsLock(this);
+        assert valid();
+        final long currentTime = System.currentTimeMillis();
+        final int capacity = Math.max(Math.round(count/(LOAD_FACTOR/2)), count+MIN_CAPACITY);
+        if (augmentation ? (capacity<=table.length) :
+                           (capacity>=table.length || currentTime-lastRehashTime<HOLD_TIME))
+        {
+            return;
+        }
+        lastRehashTime = currentTime;
+        final Entry[] oldTable = table;
+        newEntryTable(capacity);
+        threshold = Math.round(capacity*LOAD_FACTOR);
+        for (int i=0; i<oldTable.length; i++) {
+            for (Entry old=oldTable[i]; old!=null;) {
+                final Entry e=old;
+                old = old.next; // On retient 'next' tout de suite car sa valeur va changer...
+                final Object key = e.key;
+                if (key != null) {
+                    final int index=(key.hashCode() & 0x7FFFFFFF) % table.length;
+                    e.index = index;
+                    e.next  = table[index];
+                    table[index] = e;
+                } else {
+                    count--;
+                }
+            }
+        }
+        final Logger logger = Logging.getLogger("org.geotools.util");
+        final Level   level = Level.FINEST;
+        if (logger.isLoggable(level)) {
+            final LogRecord record = new LogRecord(level,
+                    "Rehash from " + oldTable.length + " to " + table.length);
+            record.setSourceMethodName(augmentation ? "unique" : "remove");
+            record.setSourceClassName(WeakValueHashMap.class.getName());
+            record.setLoggerName(logger.getName());
+            logger.log(record);
+        }
+        assert valid();
+    }
+
+    /**
+     * Checks if this {@code WeakValueHashMap} is valid. This method counts the
+     * number of elements and compare it to {@link #count}. If the check fails,
+     * the number of elements is corrected (if we didn't, an {@link AssertionError}
+     * would be thrown for every operations after the first error,  which make
+     * debugging more difficult). The set is otherwise unchanged, which should
+     * help to get similar behaviour as if assertions hasn't been turned on.
+     */
+    private boolean valid() {
+        int n=0;
+        for (int i=0; i<table.length; i++) {
+            for (Entry e=table[i]; e!=null; e=e.next) {
+                n++;
+            }
+        }
+        if (n!=count) {
+            count = n;
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Returns the number of key-value mappings in this map.
+     */
+    @Override
+    public synchronized int size() {
+        assert valid();
+        return count;
+    }
+
+    /**
+     * Returns {@code true} if this map maps one or more keys to this value.
+     *
+     * @param value value whose presence in this map is to be tested.
+     * @return {@code true} if this map maps one or more keys to this value.
+     */
+    @Override
+    public synchronized boolean containsValue(final Object value) {
+        return super.containsValue(value);
+    }
+
+    /**
+     * Returns {@code true} if this map contains a mapping for the specified key.
+     *
+     * @param key key whose presence in this map is to be tested.
+     * @return {@code true} if this map contains a mapping for the specified key.
+     * @throws NullPointerException If key is {@code null}.
+     */
+    @Override
+    public boolean containsKey(final Object key) {
+        return get(key) != null;
+    }
+
+    /**
+     * Returns the value to which this map maps the specified key. Returns
+     * {@code null} if the map contains no mapping for this key.
+     *
+     * @param  key Key whose associated value is to be returned.
+     * @return The value to which this map maps the specified key.
+     * @throws NullPointerException if the key is {@code null}.
+     */
+    @Override
+    public synchronized V get(final Object key) {
+        assert WeakCollectionCleaner.DEFAULT.isAlive();
+        assert valid() : count;
+        final int index = (key.hashCode() & 0x7FFFFFFF) % table.length;
+        for (Entry e=table[index]; e!=null; e=e.next) {
+            if (key.equals(e.key)) {
+                return e.get();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Implementation of {@link #put} and {@link #remove} operations.
+     */
+    private synchronized V intern(final K key, final V value) {
+        assert WeakCollectionCleaner.DEFAULT.isAlive();
+        assert valid() : count;
+        /*
+         * Check if {@code obj} is already contained in this
+         * {@code WeakValueHashMap}. If yes, clear it.
+         */
+        V oldValue = null;
+        final int hash = key.hashCode() & 0x7FFFFFFF;
+        int index = hash % table.length;
+        for (Entry e=table[index]; e!=null; e=e.next) {
+            if (key.equals(e.key)) {
+                oldValue = e.get();
+                e.clear();
+            }
+        }
+        if (value != null) {
+            if (count >= threshold) {
+                rehash(true);
+                index = hash % table.length;
+            }
+            table[index] = new Entry(key, value, table[index], index);
+            count++;
+        }
+        assert valid();
+        return oldValue;
+    }
+
+    /**
+     * Associates the specified value with the specified key in this map.
+     * The value is associated using a {@link WeakReference}.
+     *
+     * @param  key key with which the specified value is to be associated.
+     * @param  value value to be associated with the specified key.
+     * @return previous value associated with specified key, or {@code null}
+     *	       if there was no mapping for key.
+     *
+     * @throws NullPointerException if the key or the value is {@code null}.
+     */
+    @Override
+    public V put(final K key, final V value) {
+        if (value == null) {
+            throw new NullPointerException("Null value not allowed");
+            // TODO: localize this message.
+        }
+        return intern(key, value);
+    }
+
+    /**
+     * Removes the mapping for this key from this map if present.
+     *
+     * @param key key whose mapping is to be removed from the map.
+     * @return previous value associated with specified key, or {@code null}
+     *	       if there was no entry for key.
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public V remove(final Object key) {
+        return intern((K) key, null);
+    }
+
+    /**
+     * Removes all of the elements from this map.
+     */
+    @Override
+    public synchronized void clear() {
+        Arrays.fill(table, null);
+        count = 0;
+    }
+
+    /**
+     * Returns a set view of the mappings contained in this map.
+     * Each element in this set is a {@link java.util.Map.Entry}.
+     * The current implementation thrown {@link UnsupportedOperationException}.
+     *
+     * @return a set view of the mappings contained in this map.
+     */
+    @Override
+    public Set<Map.Entry<K,V>> entrySet() {
+        throw new UnsupportedOperationException();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/logging/LoggedFormat.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/logging/LoggedFormat.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/logging/LoggedFormat.java	(revision 28000)
@@ -0,0 +1,105 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2007-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util.logging;
+
+import java.text.Format;
+import java.text.ParsePosition;
+import java.util.Locale;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+
+
+/**
+ * Wraps a {@link Format} object in order to either parse fully a string, or log a warning.
+ * This class provides a {@link #parse} method which performs the following tasks:
+ * <p>
+ * <ul>
+ *   <li>Checks if the string was fully parsed and log a warning if it was not. This is
+ *       different than the default {@link #parseObject(String)} behavior which check only
+ *       if the <em>begining</em> of the string was parsed and ignore any remaining characters.</li>
+ *   <li>Ensures that the parsed object is of some specific class specified at construction time.</li>
+ *   <li>If the string can't be fully parsed or is not of the expected class, logs a warning.</li>
+ * </ul>
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/logging/LoggedFormat.java $
+ * @version $Id: LoggedFormat.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ */
+public class LoggedFormat {
+
+    /**
+     * Formats an error message for an unparsable string. This method performs the same work that
+     * {@link #formatUnparsable(String, int, int, Locale, Level) formatUnparsable(..., Level)},
+     * except that the result is returned as a {@link String} rather than a {@link LogRecord}.
+     * This is provided as a convenience method for creating the message to give to an
+     * {@linkplain Exception#Exception(String) exception constructor}.
+     *
+     * @param  text The unparsable string.
+     * @param  index The parse position. This is usually {@link ParsePosition#getIndex}.
+     * @param  errorIndex The index where the error occured. This is usually
+     *         {@link ParsePosition#getErrorIndex}.
+     * @param  locale The locale for the message, or {@code null} for the default one.
+     * @return A formatted error message.
+     *
+     * @since 2.5
+     */
+    public static String formatUnparsable(final String text, final int index,
+            final int errorIndex, final Locale locale)
+    {
+        return (String) doFormatUnparsable(text, index, errorIndex, locale, null);
+    }
+
+    /**
+     * Implementation of {@code formatUnparsable} methods. Returns a {@link LogRecord}
+     * if {@code level} is non-null, or a {@link String} otherwise.
+     */
+    private static Object doFormatUnparsable(String text, final int index, int errorIndex,
+                                             final Locale locale, final Level level)
+    {
+        final Errors resources = Errors.getResources(locale);
+        final int length = text.length();
+        if (errorIndex < index) {
+            errorIndex = index;
+        }
+        if (errorIndex == length) {
+            if (level != null) {
+                return resources.getLogRecord(level, ErrorKeys.UNEXPECTED_END_OF_STRING);
+            }
+            return resources.getString(ErrorKeys.UNEXPECTED_END_OF_STRING);
+        }
+        int upper = errorIndex;
+        if (upper < length) {
+            final int type = Character.getType(text.charAt(upper));
+            while (++upper < length) {
+                if (Character.getType(text.charAt(upper)) != type) {
+                    break;
+                }
+            }
+        }
+        final String error = text.substring(errorIndex, upper);
+        text = text.substring(index);
+        if (level != null) {
+            return resources.getLogRecord(level, ErrorKeys.UNPARSABLE_STRING_$2, text, error);
+        }
+        return resources.getString(ErrorKeys.UNPARSABLE_STRING_$2, text, error);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/logging/Logging.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/logging/Logging.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/logging/Logging.java	(revision 28000)
@@ -0,0 +1,346 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2006-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.geotools.util.logging;
+
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.geotools.resources.Classes;
+
+
+/**
+ * A set of utilities method for configuring loggings in GeoTools. <strong>All GeoTools
+ * code should fetch their logger through a call to {@link #getLogger(String)}</strong>,
+ * not {@link Logger#getLogger(String)}. This is necessary in order to give GeoTools a
+ * chance to redirect log events to an other logging framework, for example
+ * <A HREF="http://jakarta.apache.org/commons/logging/">commons-logging</A>.
+ * <p>
+ * <b>Example:</b> In order to redirect every GeoTools log events to Commons-logging,
+ * invoke the following once at application startup:
+ *
+ * <blockquote><code>
+ * Logging.{@linkplain #GEOTOOLS}.{@linkplain #setLoggerFactory
+ * setLoggerFactory}("org.geotools.util.logging.CommonsLoggerFactory");
+ * </code></blockquote>
+ *
+ * @since 2.4
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/metadata/src/main/java/org/geotools/util/logging/Logging.java $
+ * @version $Id: Logging.java 37298 2011-05-25 05:16:15Z mbedward $
+ * @author Martin Desruisseaux
+ */
+public final class Logging {
+
+    /**
+     * The name of the base package.
+     */
+    final String name;
+
+    /**
+     * Creates an instance for the root logger. This constructor should not be used
+     * for anything else than {@link #ALL} construction; use {@link #getLogging} instead.
+     */
+    private Logging() {
+        name = "";
+    }
+
+    /**
+     * Creates an instance for the specified base logger. This constructor
+     * should not be public; use {@link #getLogging} instead.
+     *
+     * @param parent The parent {@code Logging} instance.
+     * @param name   The logger name for the new instance.
+     */
+    private Logging(final Logging parent, final String name) {
+        this.name = name;
+        assert name.startsWith(parent.name) : name;
+    }
+
+    /**
+     * Returns a logger for the specified class. This convenience method invokes
+     * {@link #getLogger(String)} with the package name as the logger name.
+     *
+     * @param  classe The class for which to obtain a logger.
+     * @return A logger for the specified class.
+     *
+     * @since 2.5
+     */
+    public static Logger getLogger(final Class<?> classe) {
+        String name = classe.getName();
+        final int separator = name.lastIndexOf('.');
+        name = (separator >= 1) ? name.substring(0, separator) : "";
+        return getLogger(name);
+    }
+
+    /**
+     * Returns a logger for the specified name. If a {@linkplain LoggerFactory logger factory} has
+     * been set, then this method first {@linkplain LoggerFactory#getLogger ask to the factory}.
+     * It gives GeoTools a chance to redirect logging events to
+     * <A HREF="http://jakarta.apache.org/commons/logging/">commons-logging</A>
+     * or some equivalent framework.
+     * <p>
+     * If no factory was found or if the factory choose to not redirect the loggings, then this
+     * method returns the usual <code>{@linkplain Logger#getLogger Logger.getLogger}(name)</code>.
+     *
+     * @param  name The logger name.
+     * @return A logger for the specified name.
+     */
+    public static Logger getLogger(final String name) {
+        return Logger.getLogger(name);
+    }
+
+    /**
+     * Invoked when an unexpected error occurs. This method logs a message at the
+     * {@link Level#WARNING WARNING} level to the specified logger. The originating
+     * class name and method name are inferred from the error stack trace, using the
+     * first {@linkplain StackTraceElement stack trace element} for which the class
+     * name is inside a package or sub-package of the logger name. For example if
+     * the logger name is {@code "org.geotools.image"}, then this method will uses
+     * the first stack trace element where the fully qualified class name starts with
+     * {@code "org.geotools.image"} or {@code "org.geotools.image.io"}, but not
+     * {@code "org.geotools.imageio"}.
+     *
+     * @param  logger Where to log the error.
+     * @param  error  The error that occured.
+     * @return {@code true} if the error has been logged, or {@code false} if the logger
+     *         doesn't log anything at the {@link Level#WARNING WARNING} level.
+     */
+    public static boolean unexpectedException(final Logger logger, final Throwable error) {
+        return unexpectedException(logger, null, null, error, Level.WARNING);
+    }
+
+    /**
+     * Invoked when an unexpected error occurs. This method logs a message at the
+     * {@link Level#WARNING WARNING} level to the specified logger. The originating
+     * class name and method name can optionnaly be specified. If any of them is
+     * {@code null}, then it will be inferred from the error stack trace as in
+     * {@link #unexpectedException(Logger, Throwable)}.
+     * <p>
+     * Explicit value for class and method names are sometime preferred to automatic
+     * inference for the following reasons:
+     *
+     * <ul>
+     *   <li><p>Automatic inference is not 100% reliable, since the Java Virtual Machine
+     *       is free to omit stack frame in optimized code.</p></li>
+     *   <li><p>When an exception occured in a private method used internally by a public
+     *       method, we sometime want to log the warning for the public method instead,
+     *       since the user is not expected to know anything about the existence of the
+     *       private method. If a developper really want to know about the private method,
+     *       the stack trace is still available anyway.</p></li>
+     * </ul>
+     *
+     * @param logger  Where to log the error.
+     * @param classe  The class where the error occurred, or {@code null}.
+     * @param method  The method where the error occurred, or {@code null}.
+     * @param error   The error.
+     * @return {@code true} if the error has been logged, or {@code false} if the logger
+     *         doesn't log anything at the {@link Level#WARNING WARNING} level.
+     */
+    public static boolean unexpectedException(final Logger logger, final Class<?> classe,
+                                              final String method, final Throwable error)
+    {
+        final String classname = (classe != null) ? classe.getName() : null;
+        return unexpectedException(logger, classname, method, error, Level.WARNING);
+    }
+
+    /**
+     * Invoked when an unexpected error occurs. This method logs a message at the
+     * {@link Level#WARNING WARNING} level to the logger for the specified package
+     * name. The originating class name and method name can optionnaly be specified.
+     * If any of them is {@code null}, then it will be inferred from the error stack
+     * trace as in {@link #unexpectedException(Logger, Throwable)}.
+     *
+     * @param paquet  The package where the error occurred, or {@code null}. This
+     *                information is used for fetching an appropriate {@link Logger}
+     *                for logging the error.
+     * @param classe  The class where the error occurred, or {@code null}.
+     * @param method  The method where the error occurred, or {@code null}.
+     * @param error   The error.
+     * @return {@code true} if the error has been logged, or {@code false} if the logger
+     *         doesn't log anything at the {@link Level#WARNING WARNING} level.
+     *
+     * @deprecated Use one of the other {@code unexpectedException} methods instead.
+     */
+    public static boolean unexpectedException(final String paquet, final Class<?> classe,
+                                              final String method, final Throwable error)
+    {
+        final Logger logger = (paquet != null) ? getLogger(paquet) : null;
+        return unexpectedException(logger, classe, method, error);
+    }
+
+    /**
+     * Invoked when an unexpected error occurs. This method logs a message at the
+     * {@link Level#WARNING WARNING} level to a logger inferred from the given class.
+     *
+     * @param classe  The class where the error occurred.
+     * @param method  The method where the error occurred, or {@code null}.
+     * @param error   The error.
+     * @return {@code true} if the error has been logged, or {@code false} if the logger
+     *         doesn't log anything at the {@link Level#WARNING WARNING} level.
+     *
+     * @since 2.5
+     */
+    public static boolean unexpectedException(Class<?> classe, String method, Throwable error) {
+        return unexpectedException((Logger) null, classe, method, error);
+    }
+
+    /**
+     * Implementation of {@link #unexpectedException(Logger, Class, String, Throwable)}.
+     *
+     * @param logger  Where to log the error, or {@code null}.
+     * @param classe  The fully qualified class name where the error occurred, or {@code null}.
+     * @param method  The method where the error occurred, or {@code null}.
+     * @param error   The error.
+     * @param level   The logging level.
+     * @return {@code true} if the error has been logged, or {@code false} if the logger
+     *         doesn't log anything at the specified level.
+     */
+    private static boolean unexpectedException(Logger logger, String classe, String method,
+                                               final Throwable error, final Level level)
+    {
+        /*
+         * Checks if loggable, inferring the logger from the classe name if needed.
+         */
+        if (error == null) {
+            return false;
+        }
+        if (logger == null && classe != null) {
+            final int separator = classe.lastIndexOf('.');
+            final String paquet = (separator >= 1) ? classe.substring(0, separator-1) : "";
+            logger = getLogger(paquet);
+        }
+        if (logger != null && !logger.isLoggable(level)) {
+            return false;
+        }
+        /*
+         * Loggeable, so complete the null argument from the stack trace if we can.
+         */
+        if (logger==null || classe==null || method==null) {
+            String paquet = (logger != null) ? logger.getName() : null;
+            final StackTraceElement[] elements = error.getStackTrace();
+            for (int i=0; i<elements.length; i++) {
+                /*
+                 * Searchs for the first stack trace element with a classname matching the
+                 * expected one. We compare preferably against the name of the class given
+                 * in argument, or against the logger name (taken as the package name) otherwise.
+                 */
+                final StackTraceElement element = elements[i];
+                final String classname = element.getClassName();
+                if (classe != null) {
+                    if (!classname.equals(classe)) {
+                        continue;
+                    }
+                } else if (paquet != null) {
+                    if (!classname.startsWith(paquet)) {
+                        continue;
+                    }
+                    final int length = paquet.length();
+                    if (classname.length() > length) {
+                        // We expect '.' but we accept also '$' or end of string.
+                        final char separator = classname.charAt(length);
+                        if (Character.isJavaIdentifierPart(separator)) {
+                            continue;
+                        }
+                    }
+                }
+                /*
+                 * Now that we have a stack trace element from the expected class (or any
+                 * element if we don't know the class), make sure that we have the right method.
+                 */
+                final String methodName = element.getMethodName();
+                if (method != null && !methodName.equals(method)) {
+                    continue;
+                }
+                /*
+                 * Now computes every values that are null, and stop the loop.
+                 */
+                if (paquet == null) {
+                    final int separator = classname.lastIndexOf('.');
+                    paquet = (separator >= 1) ? classname.substring(0, separator-1) : "";
+                    logger = getLogger(paquet);
+                    if (!logger.isLoggable(level)) {
+                        return false;
+                    }
+                }
+                if (classe == null) {
+                    classe = classname;
+                }
+                if (method == null) {
+                    method = methodName;
+                }
+                break;
+            }
+            /*
+             * The logger may stay null if we have been unable to find a suitable
+             * stack trace. Fallback on the global logger.
+             *
+             * TODO: Use GLOBAL_LOGGER_NAME constant when we will be allowed to target Java 6.
+             */
+            if (logger == null) {
+                logger = getLogger("global");
+                if (!logger.isLoggable(level)) {
+                    return false;
+                }
+            }
+        }
+        /*
+         * Now prepare the log message. If we have been unable to figure out a source class and
+         * method name, we will fallback on Java logging default mechanism, which may returns a
+         * less relevant name than our attempt to use the logger name as the package name.
+         */
+        final StringBuilder buffer = new StringBuilder(Classes.getShortClassName(error));
+        final String message = error.getLocalizedMessage();
+        if (message != null) {
+            buffer.append(": ").append(message);
+        }
+        final LogRecord record = new LogRecord(level, buffer.toString());
+        if (classe != null) {
+            record.setSourceClassName(classe);
+        }
+        if (method != null) {
+            record.setSourceMethodName(method);
+        }
+        if (level.intValue() > 500) {
+            record.setThrown(error);
+        }
+        record.setLoggerName(logger.getName());
+        logger.log(record);
+        return true;
+    }
+
+    /**
+     * Invoked when a recoverable error occurs. This method is similar to
+     * {@link #unexpectedException(Logger,Class,String,Throwable) unexpectedException}
+     * except that it doesn't log the stack trace and uses a lower logging level.
+     *
+     * @param logger  Where to log the error.
+     * @param classe  The class where the error occurred.
+     * @param method  The method name where the error occurred.
+     * @param error   The error.
+     * @return {@code true} if the error has been logged, or {@code false} if the logger
+     *         doesn't log anything at the specified level.
+     *
+     * @since 2.5
+     */
+    public static boolean recoverableException(final Logger logger, final Class<?> classe,
+                                               final String method, final Throwable error)
+    {
+        final String classname = (classe != null) ? classe.getName() : null;
+        return unexpectedException(logger, classname, method, error, Level.FINE);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/geotools/util/logging/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/geotools/util/logging/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/geotools/util/logging/package.html	(revision 28000)
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.geotools.util.logging</TITLE>
+  </HEAD>
+  <BODY>
+    Extensions to the {@linkplain java.util.logging Java logging} framework. The GeoTools
+    project uses the standard {@link java.util.logging.Logger} API for its logging, but this
+    package allows redirection of logs to some other frameworks like
+    <a href="http://logging.apache.org/log4j/">Log4J</a>.
+    <p>
+    <strong>All GeoTools code should fetch their logger through a call to
+    {@link org.geotools.util.logging.Logging#getLogger(String)}</strong>, not
+    {@link java.util.logging.Logger#getLogger(String)}. This is necessary in
+    order to give GeoTools a chance to redirect log events to an other logging
+    framework.
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/Attribute.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/Attribute.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/Attribute.java	(revision 28000)
@@ -0,0 +1,535 @@
+/*--
+
+ $Id: Attribute.java,v 1.56 2007/11/10 05:28:58 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+/**
+ * An XML attribute. Methods allow the user to obtain the value of the attribute
+ * as well as namespace and type information.
+ *
+ * @version $Revision: 1.56 $, $Date: 2007/11/10 05:28:58 $
+ * @author  Brett McLaughlin
+ * @author  Jason Hunter
+ * @author  Elliotte Rusty Harold
+ * @author  Wesley Biggs
+ * @author  Victor Toni
+ */
+public class Attribute implements Serializable, Cloneable {
+
+    /**
+     * Attribute type: the attribute has not been declared or type
+     * is unknown.
+     *
+     * @see #getAttributeType
+     */
+    public final static int UNDECLARED_TYPE = 0;
+
+    /**
+     * Attribute type: the attribute value is a string.
+     *
+     * @see #getAttributeType
+     */
+    public final static int CDATA_TYPE = 1;
+
+    /**
+     * Attribute type: the attribute value is a unique identifier.
+     *
+     * @see #getAttributeType
+     */
+    public final static int ID_TYPE = 2;
+
+    /**
+     * Attribute type: the attribute value is a reference to a
+     * unique identifier.
+     *
+     * @see #getAttributeType
+     */
+    public final static int IDREF_TYPE = 3;
+
+    /**
+     * Attribute type: the attribute value is a list of references to
+     * unique identifiers.
+     *
+     * @see #getAttributeType
+     */
+    public final static int IDREFS_TYPE = 4;
+
+    /**
+     * Attribute type: the attribute value is the name of an entity.
+     *
+     * @see #getAttributeType
+     */
+    public final static int ENTITY_TYPE = 5;
+
+    /**
+     * <p>
+     * Attribute type: the attribute value is a list of entity names.
+     * </p>
+     *
+     * @see #getAttributeType
+     */
+    public final static int ENTITIES_TYPE = 6;
+
+    /**
+     * Attribute type: the attribute value is a name token.
+     * <p>
+     * According to SAX 2.0 specification, attributes of enumerated
+     * types should be reported as "NMTOKEN" by SAX parsers.  But the
+     * major parsers (Xerces and Crimson) provide specific values
+     * that permit to recognize them as {@link #ENUMERATED_TYPE}.
+     *
+     * @see #getAttributeType
+     */
+    public final static int NMTOKEN_TYPE = 7;
+
+    /**
+     * Attribute type: the attribute value is a list of name tokens.
+     *
+     * @see #getAttributeType
+     */
+    public final static int NMTOKENS_TYPE = 8;
+
+    /**
+     * Attribute type: the attribute value is the name of a notation.
+     *
+     * @see #getAttributeType
+     */
+    public final static int NOTATION_TYPE = 9;
+
+    /**
+     * Attribute type: the attribute value is a name token from an
+     * enumeration.
+     *
+     * @see #getAttributeType
+     */
+    public final static int ENUMERATED_TYPE = 10;
+
+    // Keep the old constant names for one beta cycle to help migration
+
+
+
+    /** The local name of the <code>Attribute</code> */
+    protected String name;
+
+    /** The <code>{@link Namespace}</code> of the <code>Attribute</code> */
+    protected transient Namespace namespace;
+
+    /** The value of the <code>Attribute</code> */
+    protected String value;
+
+    /** Parent element, or null if none */
+    protected Element parent;
+
+    /**
+     * Default, no-args constructor for implementations to use if needed.
+     */
+    protected Attribute() {}
+
+    /**
+     * This will create a new <code>Attribute</code> with the
+     * specified (local) name and value, and in the provided
+     * <code>{@link Namespace}</code>.
+     *
+     * @param name <code>String</code> name of <code>Attribute</code>.
+     * @param value <code>String</code> value for new attribute.
+     * @param namespace <code>Namespace</code> namespace for new attribute.
+     * @throws IllegalNameException if the given name is illegal as an
+     *         attribute name or if if the new namespace is the default
+     *         namespace. Attributes cannot be in a default namespace.
+     * @throws IllegalDataException if the given attribute value is
+     *         illegal character data (as determined by
+     *         {@link org.jdom.Verifier#checkCharacterData}).
+     */
+    public Attribute(final String name, final String value, final Namespace namespace) {
+        this(name, value, UNDECLARED_TYPE, namespace);
+    }
+
+    /**
+     * This will create a new <code>Attribute</code> with the
+     * specified (local) name, value, and type, and in the provided
+     * <code>{@link Namespace}</code>.
+     *
+     * @param name <code>String</code> name of <code>Attribute</code>.
+     * @param value <code>String</code> value for new attribute.
+     * @param type <code>int</code> type for new attribute.
+     * @param namespace <code>Namespace</code> namespace for new attribute.
+     * @throws IllegalNameException if the given name is illegal as an
+     *         attribute name or if if the new namespace is the default
+     *         namespace. Attributes cannot be in a default namespace.
+     * @throws IllegalDataException if the given attribute value is
+     *         illegal character data (as determined by
+     *         {@link org.jdom.Verifier#checkCharacterData}) or
+     *         if the given attribute type is not one of the
+     *         supported types.
+     */
+    public Attribute(final String name, final String value, final int type, final Namespace namespace) {
+        setName(name);
+        setValue(value);
+        setAttributeType(type);
+        setNamespace(namespace);
+    }
+
+    /**
+     * This will return the parent of this <code>Attribute</code>.
+     * If there is no parent, then this returns <code>null</code>.
+     *
+     * @return parent of this <code>Attribute</code>
+     */
+    public Element getParent() {
+        return parent;
+    }
+
+    /**
+     * This will set the parent of this <code>Attribute</code>.
+     *
+     * @param parent <code>Element</code> to be new parent.
+     * @return this <code>Attribute</code> modified.
+     */
+    protected Attribute setParent(final Element parent) {
+        this.parent = parent;
+        return this;
+    }
+
+    /**
+     * This detaches the <code>Attribute</code> from its parent, or does
+     * nothing if the <code>Attribute</code> has no parent.
+     *
+     * @return <code>Attribute</code> - this <code>Attribute</code> modified.
+     */
+    public Attribute detach() {
+        final Element parentElement = getParent();
+        if (parentElement != null) {
+            parentElement.removeAttribute(getName(),getNamespace());
+        }
+
+        return this;
+    }
+
+    /**
+     * This will retrieve the local name of the
+     * <code>Attribute</code>. For any XML attribute
+     * which appears as
+     * <code>[namespacePrefix]:[attributeName]</code>,
+     * the local name of the attribute would be
+     * <code>[attributeName]</code>. When the attribute
+     * has no namespace, the local name is simply the attribute
+     * name.
+     * <p>
+     * To obtain the namespace prefix for this
+     * attribute, the
+     * <code>{@link #getNamespacePrefix()}</code>
+     * method should be used.
+     *
+     * @return <code>String</code> - name of this attribute,
+     *                               without any namespace prefix.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * This sets the local name of the <code>Attribute</code>.
+     *
+     * @param name the new local name to set
+     * @return <code>Attribute</code> - the attribute modified.
+     * @throws IllegalNameException if the given name is illegal as an
+     *         attribute name.
+     */
+    public Attribute setName(final String name) {
+        final String reason  = Verifier.checkAttributeName(name);
+        if (reason != null) {
+            throw new IllegalNameException(name, "attribute", reason);
+        }
+        this.name = name;
+        return this;
+    }
+
+    /**
+     * This will retrieve the qualified name of the <code>Attribute</code>.
+     * For any XML attribute whose name is
+     * <code>[namespacePrefix]:[elementName]</code>,
+     * the qualified name of the attribute would be
+     * everything (both namespace prefix and
+     * element name). When the attribute has no
+     * namespace, the qualified name is simply the attribute's
+     * local name.
+     * <p>
+     * To obtain the local name of the attribute, the
+     * <code>{@link #getName()}</code> method should be used.
+     * <p>
+     * To obtain the namespace prefix for this attribute,
+     * the <code>{@link #getNamespacePrefix()}</code>
+     * method should be used.
+     *
+     * @return <code>String</code> - full name for this element.
+     */
+    public String getQualifiedName() {
+        // Note: Any changes here should be reflected in
+        // XMLOutputter.printQualifiedName()
+        final String prefix = namespace.getPrefix();
+        
+        // no prefix found
+        if ((prefix == null) || ("".equals(prefix))) {
+            return getName();
+        } else {
+            return new StringBuffer(prefix)
+                .append(':')
+                .append(getName())
+                .toString();
+        }
+    }
+
+    /**
+     * This will retrieve the namespace prefix of the
+     * <code>Attribute</code>. For any XML attribute
+     * which appears as
+     * <code>[namespacePrefix]:[attributeName]</code>,
+     * the namespace prefix of the attribute would be
+     * <code>[namespacePrefix]</code>. When the attribute
+     * has no namespace, an empty <code>String</code> is returned.
+     *
+     * @return <code>String</code> - namespace prefix of this
+     *                               attribute.
+     */
+    public String getNamespacePrefix() {
+        return namespace.getPrefix();
+    }
+
+    /**
+     * This returns the URI mapped to this <code>Attribute</code>'s
+     * prefix. If no mapping is found, an empty <code>String</code> is
+     * returned.
+     *
+     * @return <code>String</code> - namespace URI for this <code>Attribute</code>.
+     */
+    public String getNamespaceURI() {
+        return namespace.getURI();
+    }
+
+    /**
+     * This will return this <code>Attribute</code>'s
+     * <code>{@link Namespace}</code>.
+     *
+     * @return <code>Namespace</code> - Namespace object for this <code>Attribute</code>
+     */
+    public Namespace getNamespace() {
+        return namespace;
+    }
+
+    /**
+     * This sets this <code>Attribute</code>'s <code>{@link Namespace}</code>.
+     * If the provided namespace is null, the attribute will have no namespace.
+     * The namespace must have a prefix.
+     *
+     * @param namespace the new namespace
+     * @return <code>Element</code> - the element modified.
+     * @throws IllegalNameException if the new namespace is the default
+     *         namespace. Attributes cannot be in a default namespace.
+     */
+    public Attribute setNamespace(Namespace namespace) {
+        if (namespace == null) {
+            namespace = Namespace.NO_NAMESPACE;
+        }
+
+        // Verify the attribute isn't trying to be in a default namespace
+        // Attributes can't be in a default namespace
+        if (namespace != Namespace.NO_NAMESPACE &&
+            "".equals(namespace.getPrefix())) {
+            throw new IllegalNameException("", "attribute namespace",
+                "An attribute namespace without a prefix can only be the " +
+                "NO_NAMESPACE namespace");
+        }
+        this.namespace = namespace;
+        return this;
+    }
+
+    /**
+     * This will return the actual textual value of this
+     * <code>Attribute</code>.  This will include all text
+     * within the quotation marks.
+     *
+     * @return <code>String</code> - value for this attribute.
+     */
+    public String getValue() {
+        return value;
+    }
+
+    /**
+     * This will set the value of the <code>Attribute</code>.
+     *
+     * @param value <code>String</code> value for the attribute.
+     * @return <code>Attribute</code> - this Attribute modified.
+     * @throws IllegalDataException if the given attribute value is
+     *         illegal character data (as determined by
+     *         {@link org.jdom.Verifier#checkCharacterData}).
+     */
+    public Attribute setValue(final String value) {
+        final String reason = Verifier.checkCharacterData(value);
+        if (reason != null) {
+            throw new IllegalDataException(value, "attribute", reason);
+        }
+        this.value = value;
+        return this;
+    }
+
+    /**
+     * This will set the type of the <code>Attribute</code>.
+     *
+     * @param type <code>int</code> type for the attribute.
+     * @return <code>Attribute</code> - this Attribute modified.
+     * @throws IllegalDataException if the given attribute type is
+     *         not one of the supported types.
+     */
+    public Attribute setAttributeType(final int type) {
+        if ((type < UNDECLARED_TYPE) || (type > ENUMERATED_TYPE)) {
+            throw new IllegalDataException(String.valueOf(type),
+                                        "attribute", "Illegal attribute type");
+        }
+        return this;
+    }
+
+    /**
+     * This returns a <code>String</code> representation of the
+     * <code>Attribute</code>, suitable for debugging.
+     *
+     * @return <code>String</code> - information about the
+     *         <code>Attribute</code>
+     */
+    public String toString() {
+        return new StringBuffer()
+            .append("[Attribute: ")
+            .append(getQualifiedName())
+            .append("=\"")
+            .append(value)
+            .append("\"")
+            .append("]")
+            .toString();
+    }
+
+    /**
+     * This tests for equality of this <code>Attribute</code> to the supplied
+     * <code>Object</code>.
+     *
+     * @param ob <code>Object</code> to compare to.
+     * @return <code>boolean</code> - whether the <code>Attribute</code> is
+     *         equal to the supplied <code>Object</code>.
+     */
+    public final boolean equals(final Object ob) {
+        return (ob == this);
+    }
+
+    /**
+     * This returns the hash code for this <code>Attribute</code>.
+     *
+     * @return <code>int</code> - hash code.
+     */
+    public final int hashCode() {
+        return super.hashCode();
+    }
+
+    /**
+     * This will return a clone of this <code>Attribute</code>.
+     *
+     * @return <code>Object</code> - clone of this <code>Attribute</code>.
+     */
+    public Object clone() {
+        Attribute attribute = null;
+        try {
+            attribute = (Attribute) super.clone();
+        }
+        catch (final CloneNotSupportedException ignore) {
+            // Won't happen
+        }
+
+        // Name, namespace, and value are references to imutable objects
+        // and are copied by super.clone() (aka Object.clone())
+
+        // super.clone() copies reference to set parent to null
+        attribute.parent = null;
+        return attribute;
+    }
+
+    /////////////////////////////////////////////////////////////////
+    // Convenience Methods below here
+    /////////////////////////////////////////////////////////////////
+
+
+    // Support a custom Namespace serialization so no two namespace
+    // object instances may exist for the same prefix/uri pair
+    private void writeObject(final ObjectOutputStream out) throws IOException {
+
+        out.defaultWriteObject();
+
+        // We use writeObject() and not writeUTF() to minimize space
+        // This allows for writing pointers to already written strings
+        out.writeObject(namespace.getPrefix());
+        out.writeObject(namespace.getURI());
+    }
+
+    private void readObject(final ObjectInputStream in)
+        throws IOException, ClassNotFoundException {
+
+        in.defaultReadObject();
+
+        namespace = Namespace.getNamespace(
+            (String) in.readObject(), (String) in.readObject());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/AttributeList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/AttributeList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/AttributeList.java	(revision 28000)
@@ -0,0 +1,468 @@
+/*--
+
+ $Id: AttributeList.java,v 1.24 2007/11/10 05:28:58 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+import java.util.*;
+
+/**
+ * <code>AttributeList</code> represents legal JDOM <code>Attribute</code>
+ * content.  This class is NOT PUBLIC; users should see it as a simple List
+ * implementation.
+ *
+ * @author Alex Rosen
+ * @author Philippe Riand
+ * @author Bradley S. Huffman
+ * @version $Revision: 1.24 $, $Date: 2007/11/10 05:28:58 $
+ * @see CDATA
+ * @see Comment
+ * @see Element
+ * @see EntityRef
+ * @see ProcessingInstruction
+ * @see Text
+ */
+class AttributeList extends AbstractList
+                    implements java.io.Serializable {
+
+    private static final int INITIAL_ARRAY_SIZE = 5;
+
+    /** The backing list */
+    private Attribute elementData[];
+    private int size;
+
+    /** The parent Element */
+    private Element parent;
+
+    /** Force an Element parent */
+    @SuppressWarnings("unused")
+	private AttributeList() {}
+
+    /**
+     * Create a new instance of the AttributeList representing
+     * Element content
+     *
+     * @param parent element whose attributes are to be held
+     */
+    AttributeList(Element parent) {
+        this.parent = parent;
+    }
+
+    /**
+     * Add a attribute to the end of the list or replace a existing
+     * attribute with the same name and <code>Namespace</code>.
+     *
+     * @param obj The object to insert into the list.
+     * @return true (as per the general contract of Collection.add).
+     * @throws IndexOutOfBoundsException if index < 0 || index > size()
+     */
+    public boolean add(Object obj) {
+        if (obj instanceof Attribute) {
+            Attribute attribute = (Attribute) obj;
+            int duplicate = indexOfDuplicate(attribute);
+            if (duplicate < 0) {
+                add(size(), attribute);
+            }
+            else {
+                set(duplicate, attribute);
+            }
+        }
+        else if (obj == null) {
+            throw new IllegalAddException("Cannot add null attribute");
+        }
+        else {
+            throw new IllegalAddException("Class " +
+                                          obj.getClass().getName() +
+                                          " is not an attribute");
+        }
+        return true;
+    }
+
+    /**
+     * Inserts the specified attribute at the specified position in this list.
+     * Shifts the attribute currently at that position (if any) and any
+     * subsequent attributes to the right (adds one to their indices).
+     *
+     * @param index The location to set the value to.
+     * @param obj The object to insert into the list.
+     * throws IndexOutOfBoundsException if index < 0 || index > size()
+     */
+    public void add(int index, Object obj) {
+        if (obj instanceof Attribute) {
+            Attribute attribute = (Attribute) obj;
+            int duplicate = indexOfDuplicate(attribute);
+            if (duplicate >= 0) {
+                throw new IllegalAddException("Cannot add duplicate attribute");
+            }
+            add(index, attribute);
+        }
+        else if (obj == null) {
+            throw new IllegalAddException("Cannot add null attribute");
+        }
+        else {
+            throw new IllegalAddException("Class " +
+                                          obj.getClass().getName() +
+                                          " is not an attribute");
+        }
+        modCount++;
+    }
+
+    /**
+     * Check and add the <code>Attribute</code> to this list at
+     * the given index. Note: does not check for duplicate
+     * attributes.
+     *
+     * @param index index where to add <code>Attribute</code>
+     * @param attribute <code>Attribute</code> to add
+     */
+    void add(int index, Attribute attribute) {
+        if (attribute.getParent() != null) {
+            throw new IllegalAddException(
+                          "The attribute already has an existing parent \"" +
+                          attribute.getParent().getQualifiedName() + "\"");
+        }
+
+        String reason = Verifier.checkNamespaceCollision(attribute, parent);
+        if (reason != null) {
+            throw new IllegalAddException(parent, attribute, reason);
+        }
+
+        if (index<0 || index>size) {
+            throw new IndexOutOfBoundsException("Index: " + index +
+                                                " Size: " + size());
+        }
+
+        attribute.setParent(parent);
+
+        ensureCapacity(size+1);
+        if( index==size ) {
+            elementData[size++] = attribute;
+        } else {
+            System.arraycopy(elementData, index, elementData, index + 1, size - index);
+            elementData[index] = attribute;
+            size++;
+        }
+        modCount++;
+    }
+
+    /**
+     * Add all the objects in the specified collection.
+     *
+     * @param collection The collection containing all the objects to add.
+     * @return <code>true</code> if the list was modified as a result of
+     * the add.
+     */
+    public boolean addAll(Collection collection) {
+        return addAll(size(), collection);
+    }
+
+    /**
+     * Inserts the specified collecton at the specified position in this list.
+     * Shifts the attribute currently at that position (if any) and any
+     * subsequent attributes to the right (adds one to their indices).
+     *
+     * @param index The offset to start adding the data in the collection
+     * @param collection The collection to insert into the list.
+     * @return <code>true</code> if the list was modified as a result of
+     *                           the add.
+     * throws IndexOutOfBoundsException if index < 0 || index > size()
+     */
+    public boolean addAll(int index, Collection collection) {
+        if (index<0 || index>size) {
+            throw new IndexOutOfBoundsException("Index: " + index +
+                                                " Size: " + size());
+        }
+
+        if ((collection == null) || (collection.size() == 0)) {
+            return false;
+        }
+        ensureCapacity(size() + collection.size());
+
+        int count = 0;
+
+        try {
+            Iterator i = collection.iterator();
+            while (i.hasNext()) {
+                Object obj = i.next();
+                add(index + count, obj);
+                count++;
+            }
+        }
+        catch (RuntimeException exception) {
+            for (int i = 0; i < count; i++) {
+                remove(index);
+            }
+            throw exception;
+        }
+
+        return true;
+    }
+
+    /**
+     * Clear the current list.
+     */
+    public void clear() {
+        if (elementData != null) {
+            for (int i = 0; i < size; i++) {
+                Attribute attribute = elementData[i];
+                attribute.setParent(null);
+            }
+            elementData = null;
+            size = 0;
+        }
+        modCount++;
+    }
+
+    /**
+     * Increases the capacity of this <code>AttributeList</code> instance,
+     * if necessary, to ensure that it can hold at least the number of
+     * items specified by the minimum capacity argument.
+     *
+     * @param minCapacity the desired minimum capacity.
+     */
+    private void ensureCapacity(int minCapacity) {
+        if (elementData == null) {
+            elementData = new Attribute[Math.max(minCapacity, INITIAL_ARRAY_SIZE)];
+        }
+        else {
+            int oldCapacity = elementData.length;
+            if (minCapacity > oldCapacity) {
+                Attribute oldData[] = elementData;
+                int newCapacity = (oldCapacity * 3)/2 + 1;
+                if (newCapacity < minCapacity)
+                    newCapacity = minCapacity;
+                elementData = new Attribute[newCapacity];
+                System.arraycopy(oldData, 0, elementData, 0, size);
+            }
+        }
+    }
+
+    /**
+     * Return the object at the specified offset.
+     *
+     * @param index The offset of the object.
+     * @return The Object which was returned.
+     */
+    public Object get(int index) {
+        if (index<0 || index>=size) {
+            throw new IndexOutOfBoundsException("Index: " + index +
+                                                " Size: " + size());
+        }
+
+        return elementData[index];
+    }
+
+    /**
+     * Return the <code>Attribute</code> with the
+     * given name and <code>Namespace</code>.
+     *
+     * @param name name of attribute to return
+     * @param namespace <code>Namespace</code> to match
+     * @return the <code>Attribute</code>, or null if one doesn't exist.
+     */
+    Object get(String name, Namespace namespace) {
+        int index = indexOf(name, namespace);
+        if (index < 0) {
+            return null;
+        }
+        return elementData[index];
+    }
+
+    /**
+     * Return index of the <code>Attribute</code> with the
+     * given name and uri.
+     */
+    int indexOf(String name, Namespace namespace) {
+        String uri = namespace.getURI();
+        if (elementData != null) {
+            for (int i = 0; i < size; i++) {
+                Attribute old = elementData[i];
+                String oldURI = old.getNamespaceURI();
+                String oldName = old.getName();
+                if (oldURI.equals(uri) && oldName.equals(name)) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Remove the object at the specified offset.
+     *
+     * @param index The offset of the object.
+     * @return The Object which was removed.
+     */
+    public Object remove(int index) {
+        if (index<0 || index>=size)
+            throw new IndexOutOfBoundsException("Index: " + index +
+                                                " Size: " + size());
+
+        Attribute old = elementData[index];
+        old.setParent(null);
+        int numMoved = size - index - 1;
+        if (numMoved > 0)
+            System.arraycopy(elementData, index+1, elementData, index,numMoved);
+        elementData[--size] = null; // Let gc do its work
+        modCount++;
+        return old;
+    }
+
+    /**
+     * Remove the <code>Attribute</code> with the
+     * given name and <code>Namespace</code>.
+     *
+     * @param namespace <code>Namespace</code> to match
+     * @return the <code>true</code> if attribute was removed,
+     *             <code>false</code> otherwise
+     */
+    boolean remove(String name, Namespace namespace) {
+        int index = indexOf(name, namespace);
+        if (index < 0) {
+            return false;
+        }
+        remove(index);
+        return true;
+    }
+
+    /**
+     * Set the object at the specified location to the supplied
+     * object.
+     *
+     * @param index The location to set the value to.
+     * @param obj The location to set the value to.
+     * @return The object which was replaced.
+     * throws IndexOutOfBoundsException if index < 0 || index >= size()
+     */
+    public Object set(int index, Object obj) {
+        if (obj instanceof Attribute) {
+            Attribute attribute = (Attribute) obj;
+            int duplicate = indexOfDuplicate(attribute);
+            if ((duplicate >= 0) && (duplicate != index)) {
+                throw new IllegalAddException("Cannot set duplicate attribute");
+            }
+            return set(index, attribute);
+        }
+        else if (obj == null) {
+            throw new IllegalAddException("Cannot add null attribute");
+        }
+        else {
+            throw new IllegalAddException("Class " +
+                                          obj.getClass().getName() +
+                                          " is not an attribute");
+        }
+    }
+
+    /**
+     * Set the object at the specified location to the supplied
+     * object. Note: does not check for duplicate attributes.
+     *
+     * @param index The location to set the value to.
+     * @param attribute The attribute to set.
+     * @return The object which was replaced.
+     * throws IndexOutOfBoundsException if index < 0 || index >= size()
+     */
+    Object set(int index, Attribute attribute) {
+        if (index < 0 || index >= size)
+            throw new IndexOutOfBoundsException("Index: " + index +
+                                                " Size: " + size());
+
+        if (attribute.getParent() != null) {
+            throw new IllegalAddException(
+                          "The attribute already has an existing parent \"" +
+                          attribute.getParent().getQualifiedName() + "\"");
+        }
+
+        String reason = Verifier.checkNamespaceCollision(attribute, parent);
+        if (reason != null) {
+            throw new IllegalAddException(parent, attribute, reason);
+        }
+
+        Attribute old = elementData[index];
+        old.setParent(null);
+
+        elementData[index] = attribute;
+        attribute.setParent(parent);
+        return old;
+    }
+
+    /**
+     * Return index of attribute with same name and Namespace, or
+     * -1 if one doesn't exist
+     */
+    private int indexOfDuplicate(Attribute attribute) {
+        int duplicate = -1;
+        String name = attribute.getName();
+        Namespace namespace = attribute.getNamespace();
+        duplicate = indexOf(name, namespace);
+        return duplicate;
+    }
+
+    /**
+     * Return the number of items in this list
+     *
+     * @return The number of items in this list.
+     */
+    public int size() {
+        return size;
+    }
+
+    /**
+     * Return this list as a <code>String</code>
+     */
+    public String toString() {
+        return super.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/CDATA.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/CDATA.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/CDATA.java	(revision 28000)
@@ -0,0 +1,202 @@
+/*--
+
+ $Id: CDATA.java,v 1.32 2007/11/10 05:28:58 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+/**
+ * An XML CDATA section. Represents character-based content within an XML
+ * document that should be output within special CDATA tags. Semantically it's
+ * identical to a simple {@link Text} object, but output behavior is different.
+ * CDATA makes no guarantees about the underlying textual representation of
+ * character data, but does expose that data as a Java String.
+ *
+ * @version $Revision: 1.32 $, $Date: 2007/11/10 05:28:58 $
+ * @author  Dan Schaffer
+ * @author  Brett McLaughlin
+ * @author  Jason Hunter
+ * @author  Bradley S. Huffman
+ * @author  Victor Toni
+ */
+public class CDATA extends Text {
+
+    /**
+     * This is the protected, no-args constructor standard in all JDOM
+     * classes. It allows subclassers to get a raw instance with no
+     * initialization.
+     */
+    protected CDATA() { }
+
+    /**
+     * This constructor creates a new <code>CDATA</code> node, with the
+     * supplied string value as it's character content.
+     *
+     * @param string the node's character content.
+     * @throws IllegalDataException if <code>str</code> contains an 
+     *         illegal character such as a vertical tab (as determined
+     *          by {@link org.jdom.Verifier#checkCharacterData})
+     *         or the CDATA end delimiter <code>]]&gt;</code>.
+     */
+    public CDATA(final String string) {
+        setText(string);
+    }
+
+    /**
+     * This will set the value of this <code>CDATA</code> node.
+     *
+     * @param str value for node's content.
+     * @return the object on which the method was invoked
+     * @throws IllegalDataException if <code>str</code> contains an 
+     *         illegal character such as a vertical tab (as determined
+     *          by {@link org.jdom.Verifier#checkCharacterData})
+     *         or the CDATA end delimiter <code>]]&gt;</code>.
+     */
+    public Text setText(final String str) {
+        // Overrides Text.setText() because this needs to check that CDATA rules
+        // are enforced. We could have a separate Verifier check for CDATA
+        // beyond Text and call that alone before super.setText().
+
+        if (str == null || "".equals(str)) {
+            value = EMPTY_STRING;
+            return this;
+        }
+
+        final String reason = Verifier.checkCDATASection(str);
+        if (reason != null) {
+            throw new IllegalDataException(str, "CDATA section", reason);
+        }
+
+        value = str;
+
+        return this;
+    }
+
+    /**
+     * This will append character content to whatever content already
+     * exists within this <code>CDATA</code> node.
+     *
+     * @param str character content to append.
+     * @throws IllegalDataException if <code>str</code> contains an 
+     *         illegal character such as a vertical tab (as determined
+     *          by {@link org.jdom.Verifier#checkCharacterData})
+     *         or the CDATA end delimiter <code>]]&gt;</code>.
+     */
+    public void append(final String str) {
+        // Overrides Text.append(String) because this needs to check that CDATA
+        // rules are enforced. We could have a separate Verifier check for CDATA
+        // beyond Text and call that alone before super.setText().
+    
+        if (str == null || "".equals(str)) {
+            return;
+        }
+    
+        // we need a temp value to ensure that the value is changed _after_
+        // validation
+        final String tmpValue;
+        if (value == EMPTY_STRING) {
+            tmpValue = str;
+        } else {
+            tmpValue = value + str;
+        }
+    
+        // we have to do late checking since the end of a CDATA section could 
+        // have been created by concating both strings:
+        // "]" + "]>" 
+        // or 
+        // "]]" + ">"
+        // TODO: maybe this could be optimized for this two cases
+        final String reason = Verifier.checkCDATASection(tmpValue);
+        if (reason != null) {
+            throw new IllegalDataException(str, "CDATA section", reason);
+        }
+    
+        value = tmpValue;
+    }
+    
+    /**
+     * This will append the content of another <code>Text</code> node
+     * to this node.
+     *
+     * @param text Text node to append.
+     */
+    public void append(final Text text) {
+        // Overrides Text.append(Text) because this needs to check that CDATA
+        // rules are enforced. We could have a separate Verifier check for CDATA
+        // beyond Text and call that alone before super.setText().
+    
+        if (text == null) {
+            return;
+        }
+        append(text.getText());
+    }
+
+    /**
+     * This returns a <code>String</code> representation of the
+     * <code>CDATA</code> node, suitable for debugging. If the XML
+     * representation of the <code>CDATA</code> node is desired,
+     * either <code>{@link #getText}</code> or
+     * {@link org.jdom.output.XMLOutputter#output(CDATA, java.io.Writer)}</code>
+     * should be used.
+     *
+     * @return <code>String</code> - information about this node.
+     */
+    public String toString() {
+        return new StringBuffer(64)
+            .append("[CDATA: ")
+            .append(getText())
+            .append("]")
+            .toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/Comment.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/Comment.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/Comment.java	(revision 28000)
@@ -0,0 +1,114 @@
+/*--
+
+ $Id: Comment.java,v 1.33 2007/11/10 05:28:58 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+/**
+ * An XML comment. Methods allow the user to get and set the text of the
+ * comment.
+ *
+ * @version $Revision: 1.33 $, $Date: 2007/11/10 05:28:58 $
+ * @author  Brett McLaughlin
+ * @author  Jason Hunter
+ */
+public class Comment extends Content {
+
+    /** Text of the <code>Comment</code> */
+    protected String text;
+
+    /**
+     * Default, no-args constructor for implementations to use if needed.
+     */
+    protected Comment() {}
+
+    /**
+     * This creates the comment with the supplied text.
+     *
+     * @param text <code>String</code> content of comment.
+     */
+    public Comment(String text) {
+        setText(text);
+    }
+
+
+    /**
+     * Returns the XPath 1.0 string value of this element, which is the
+     * text of this comment.
+     *
+     * @return the text of this comment
+     */
+    public String getValue() {
+        return text;
+    }
+
+    /**
+     * This will set the value of the <code>Comment</code>.
+     *
+     * @param text <code>String</code> text for comment.
+     * @return <code>Comment</code> - this Comment modified.
+     * @throws IllegalDataException if the given text is illegal for a
+     *         Comment.
+     */
+    public Comment setText(String text) {
+        String reason;
+        if ((reason = Verifier.checkCommentData(text)) != null) {
+            throw new IllegalDataException(text, "comment", reason);
+        }
+
+        this.text = text;
+        return this;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/Content.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/Content.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/Content.java	(revision 28000)
@@ -0,0 +1,192 @@
+/*--
+
+ $Id: Content.java,v 1.6 2007/11/10 05:28:58 jhunter Exp $
+
+ Copyright (C) 2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+import java.io.*;
+
+/**
+ * Superclass for JDOM objects which can be legal child content
+ * of {@link org.jdom.Parent} nodes.
+ *
+ * @see org.jdom.Comment
+ * @see org.jdom.DocType
+ * @see org.jdom.Element
+ * @see org.jdom.EntityRef
+ * @see org.jdom.Parent
+ * @see org.jdom.ProcessingInstruction
+ * @see org.jdom.Text
+ *
+ * @author Bradley S. Huffman
+ * @author Jason Hunter
+ * @version $Revision: 1.6 $, $Date: 2007/11/10 05:28:58 $
+ */
+public abstract class Content implements Cloneable, Serializable {
+
+    protected Parent parent = null;
+
+    protected Content() {}
+
+    /**
+     * Detaches this child from its parent or does nothing if the child
+     * has no parent.
+     *
+     * @return this child detached
+     */
+    public Content detach() {
+        if (parent != null) {
+            parent.removeContent(this);
+        }
+        return this;
+    }
+
+    /**
+     * Return this child's parent, or null if this child is currently
+     * not attached. The parent can be either an {@link Element}
+     * or a {@link Document}.
+     *
+     * @return this child's parent or null if none
+     */
+    public Parent getParent() {
+        return parent;
+    }
+
+    /**
+     * A convenience method that returns any parent element for this element,
+     * or null if the element is unattached or is a root element.  This was the
+     * original behavior of getParent() in JDOM Beta 9 which began returning
+     * Parent in Beta 10.  This method provides a convenient upgrade path for
+     * JDOM Beta 10 and 1.0 users.
+     *
+     * @return the containing Element or null if unattached or a root element
+     */
+    public Element getParentElement() {
+        Parent parent = getParent();
+        return (Element) ((parent instanceof Element) ? parent : null);
+    }
+
+    /**
+     * Sets the parent of this Content. The caller is responsible for removing
+     * any pre-existing parentage.
+     *
+     * @param  parent              new parent element
+     * @return                     the target element
+     */
+    protected Content setParent(Parent parent) {
+        this.parent = parent;
+        return this;
+    }
+
+    /**
+     * Return this child's owning document or null if the branch containing
+     * this child is currently not attached to a document.
+     *
+     * @return this child's owning document or null if none
+     */
+    public Document getDocument() {
+        if (parent == null) return null;
+        return parent.getDocument();
+    }
+
+
+    /**
+     * Returns the XPath 1.0 string value of this child.
+     *
+     * @return xpath string value of this child.
+     */
+    public abstract String getValue();
+
+    /**
+     * Returns a deep, unattached copy of this child and its descendants
+     * detached from any parent or document.
+     *
+     * @return a detached deep copy of this child and descendants
+     */
+    public Object clone() {
+        try {
+            Content c = (Content)super.clone();
+            c.parent = null;
+            return c;
+        } catch (CloneNotSupportedException e) {
+            //Can not happen ....
+            //e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * This tests for equality of this Content object to the supplied object.
+     * Content items are considered equal only if they are referentially equal
+     * (i&#46;e&#46; the same object).  User code may choose to compare objects
+     * based on their properties instead.
+     *
+     * @param ob <code>Object</code> to compare to.
+     * @return <code>boolean</code> - whether the <code>Content</code> is
+     *         equal to the supplied <code>Object</code>.
+     */
+    public final boolean equals(Object ob) {
+        return (ob == this);
+    }
+
+    /**
+     * This returns the hash code for this <code>Content</code> item.
+     *
+     * @return <code>int</code> - hash code.
+     */
+    public final int hashCode() {
+        return super.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/ContentList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/ContentList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/ContentList.java	(revision 28000)
@@ -0,0 +1,921 @@
+/*--
+
+ $Id: ContentList.java,v 1.42 2007/11/10 05:28:58 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org).
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+import java.util.AbstractList;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+import org.jdom.filter.Filter;
+
+/**
+ * A non-public list implementation holding only legal JDOM content, including
+ * content for Document or Element nodes. Users see this class as a simple List
+ * implementation.
+ *
+ * @see     CDATA
+ * @see     Comment
+ * @see     Element
+ * @see     EntityRef
+ * @see     ProcessingInstruction
+ * @see     Text
+ *
+ * @version $Revision: 1.42 $, $Date: 2007/11/10 05:28:58 $
+ * @author  Alex Rosen
+ * @author  Philippe Riand
+ * @author  Bradley S. Huffman
+ */
+final class ContentList extends AbstractList implements java.io.Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	private static final int INITIAL_ARRAY_SIZE = 5;
+
+    /** Our backing list */
+    private Content elementData[];
+    private int size;
+
+    /** Document or Element this list belongs to */
+    private Parent parent;
+
+    /** Force either a Document or Element parent */
+    ContentList(Parent parent) {
+        this.parent = parent;
+    }
+
+    /**
+     * Inserts the specified object at the specified position in this list.
+     * Shifts the object currently at that position (if any) and any
+     * subsequent objects to the right (adds one to their indices).
+     *
+     * @param index The location to set the value to.
+     * @param obj The object to insert into the list.
+     * throws IndexOutOfBoundsException if index < 0 || index > size()
+     */
+    public void add(int index, Object obj) {
+        if (obj == null) {
+            throw new IllegalAddException("Cannot add null object");
+        }
+        if (obj instanceof String) {  // String is OK to add as special case
+            obj = new Text(obj.toString());  // wrap it as a Content
+        }
+        if ((obj instanceof Content)) {
+            add(index, (Content) obj);
+        } else {
+            throw new IllegalAddException("Class " +
+                         obj.getClass().getName() +
+                         " is of unrecognized type and cannot be added");
+        }
+    }
+
+    /**
+     * @see org.jdom.ContentList#add(int, org.jdom.Content)
+     */
+    private void documentCanContain(int index, Content child) throws IllegalAddException {
+        if (child instanceof Element) {
+            if (indexOfFirstElement() >= 0) {
+                throw new IllegalAddException(
+                        "Cannot add a second root element, only one is allowed");
+            }
+            if (indexOfDocType() >= index) {
+                throw new IllegalAddException(
+                        "A root element cannot be added before the DocType");
+            }
+        }
+        if (child instanceof DocType) {
+            if (indexOfDocType() >= 0) {
+                throw new IllegalAddException(
+                        "Cannot add a second doctype, only one is allowed");
+            }
+            int firstElt = indexOfFirstElement();
+            if (firstElt != -1 && firstElt < index) {
+                throw new IllegalAddException(
+                        "A DocType cannot be added after the root element");
+            }
+        }
+        if (child instanceof CDATA) {
+            throw new IllegalAddException("A CDATA is not allowed at the document root");
+        }
+
+        if (child instanceof Text) {
+            throw new IllegalAddException("A Text is not allowed at the document root");
+        }
+
+        if (child instanceof EntityRef) {
+            throw new IllegalAddException("An EntityRef is not allowed at the document root");
+        }
+    }
+
+    private static void elementCanContain(int index, Content child) throws IllegalAddException {
+        if (child instanceof DocType) {
+            throw new IllegalAddException(
+                    "A DocType is not allowed except at the document level");
+        }
+    }
+
+    /**
+     * Check and add the <code>Element</code> to this list at
+     * the given index.
+     *
+     * @param index index where to add <code>Element</code>
+     * @param child <code>Element</code> to add
+     */
+    void add(int index, Content child) {
+        if (child == null) {
+            throw new IllegalAddException("Cannot add null object");
+        }
+        if (parent instanceof Document) {
+          documentCanContain(index, child);
+        }
+        else {
+          elementCanContain(index, child);
+        }
+
+        if (child.getParent() != null) {
+            Parent p = child.getParent();
+            if (p instanceof Document) {
+                throw new IllegalAddException((Element)child,
+                   "The Content already has an existing parent document");
+            }
+            else {
+                throw new IllegalAddException(
+                     "The Content already has an existing parent \"" +
+                     ((Element)p).getQualifiedName() + "\"");
+            }
+        }
+
+        if (child == parent) {
+            throw new IllegalAddException(
+                "The Element cannot be added to itself");
+        }
+
+        // Detect if we have <a><b><c/></b></a> and c.add(a)
+        if ((parent instanceof Element && child instanceof Element) &&
+                ((Element) child).isAncestor((Element)parent)) {
+            throw new IllegalAddException(
+                "The Element cannot be added as a descendent of itself");
+        }
+
+        if (index<0 || index>size) {
+            throw new IndexOutOfBoundsException("Index: " + index +
+                                                " Size: " + size());
+        }
+
+        child.setParent(parent);
+
+        ensureCapacity(size+1);
+        if( index==size ) {
+            elementData[size++] = child;
+        } else {
+            System.arraycopy(elementData, index, elementData, index + 1, size - index);
+            elementData[index] = child;
+            size++;
+        }
+        modCount++;
+    }
+
+    /**
+     * Add the specified collecton to the end of this list.
+     *
+     * @param collection The collection to add to the list.
+     * @return <code>true</code> if the list was modified as a result of
+     *                           the add.
+     */
+    public boolean addAll(Collection collection) {
+        return addAll(size(), collection);
+    }
+
+    /**
+     * Inserts the specified collecton at the specified position in this list.
+     * Shifts the object currently at that position (if any) and any
+     * subsequent objects to the right (adds one to their indices).
+     *
+     * @param index The offset to start adding the data in the collection
+     * @param collection The collection to insert into the list.
+     * @return <code>true</code> if the list was modified as a result of
+     *                           the add.
+     * throws IndexOutOfBoundsException if index < 0 || index > size()
+     */
+    public boolean addAll(int index, Collection collection) {
+        if (index<0 || index>size) {
+            throw new IndexOutOfBoundsException("Index: " + index +
+                                                " Size: " + size());
+        }
+
+        if ((collection == null) || (collection.size() == 0)) {
+            return false;
+        }
+        ensureCapacity(size() + collection.size());
+
+        int count = 0;
+        try {
+            Iterator i = collection.iterator();
+            while (i.hasNext()) {
+                Object obj = i.next();
+                add(index + count, obj);
+                count++;
+            }
+        }
+        catch (RuntimeException exception) {
+            for (int i = 0; i < count; i++) {
+                remove(index);
+            }
+            throw exception;
+        }
+
+        return true;
+    }
+
+    /**
+     * Clear the current list.
+     */
+    public void clear() {
+        if (elementData != null) {
+            for (int i = 0; i < size; i++) {
+                Content obj = elementData[i];
+                removeParent(obj);
+            }
+            elementData = null;
+            size = 0;
+        }
+        modCount++;
+    }
+
+    /**
+     * Increases the capacity of this <code>ContentList</code> instance,
+     * if necessary, to ensure that it can hold at least the number of
+     * items specified by the minimum capacity argument.
+     *
+     * @param minCapacity the desired minimum capacity.
+     */
+    void ensureCapacity(int minCapacity) {
+        if( elementData==null ) {
+            elementData = new Content[Math.max(minCapacity, INITIAL_ARRAY_SIZE)];
+        } else {
+            int oldCapacity = elementData.length;
+            if (minCapacity > oldCapacity) {
+                Object oldData[] = elementData;
+                int newCapacity = (oldCapacity * 3)/2 + 1;
+                if (newCapacity < minCapacity)
+                    newCapacity = minCapacity;
+                elementData = new Content[newCapacity];
+                System.arraycopy(oldData, 0, elementData, 0, size);
+            }
+        }
+    }
+
+    /**
+     * Return the object at the specified offset.
+     *
+     * @param index The offset of the object.
+     * @return The Object which was returned.
+     */
+    public Object get(int index) {
+        if (index<0 || index>=size) {
+            throw new IndexOutOfBoundsException("Index: " + index +
+                                                " Size: " + size());
+        }
+        return elementData[index];
+    }
+
+    /**
+     * Return a view of this list based on the given filter.
+     *
+     * @param filter <code>Filter</code> for this view.
+     * @return a list representing the rules of the <code>Filter</code>.
+     */
+    List getView(Filter filter) {
+        return new FilterList(filter);
+    }
+
+    /**
+     * Return the index of the first Element in the list.  If the parent
+     * is a <code>Document</code> then the element is the root element.
+     * If the list contains no Elements, it returns -1.
+     *
+     * @return index of first element, or -1 if one doesn't exist
+     */
+    int indexOfFirstElement() {
+        if( elementData!=null ) {
+            for (int i = 0; i < size; i++) {
+                if (elementData[i] instanceof Element) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Return the index of the DocType element in the list. If the list contains
+     * no DocType, it returns -1.
+     *
+     * @return                     index of the DocType, or -1 if it doesn't
+     *                             exist
+     */
+    int indexOfDocType() {
+        if (elementData != null) {
+            for (int i = 0; i < size; i++) {
+                if (elementData[i] instanceof DocType) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Remove the object at the specified offset.
+     *
+     * @param index The offset of the object.
+     * @return The Object which was removed.
+     */
+    public Object remove(int index) {
+        if (index<0 || index>=size)
+            throw new IndexOutOfBoundsException("Index: " + index +
+                                                 " Size: " + size());
+
+        Content old = elementData[index];
+        removeParent(old);
+        int numMoved = size - index - 1;
+        if (numMoved > 0)
+            System.arraycopy(elementData, index+1, elementData, index,numMoved);
+        elementData[--size] = null; // Let gc do its work
+        modCount++;
+        return old;
+    }
+
+
+    /** Remove the parent of a Object */
+    private static void removeParent(Content c) {
+        c.setParent(null);
+    }
+
+    /**
+     * Set the object at the specified location to the supplied
+     * object.
+     *
+     * @param index The location to set the value to.
+     * @param obj The location to set the value to.
+     * @return The object which was replaced.
+     * throws IndexOutOfBoundsException if index < 0 || index >= size()
+     */
+    public Object set(int index, Object obj) {
+        if (index<0 || index>=size)
+            throw new IndexOutOfBoundsException("Index: " + index +
+                                                 " Size: " + size());
+
+        if ((obj instanceof Element) && (parent instanceof Document)) {
+            int root = indexOfFirstElement();
+            if ((root >= 0) && (root != index)) {
+                throw new IllegalAddException(
+                  "Cannot add a second root element, only one is allowed");
+            }
+        }
+
+        if ((obj instanceof DocType) && (parent instanceof Document)) {
+            int docTypeIndex = indexOfDocType();
+            if ((docTypeIndex >= 0) && (docTypeIndex != index)) {
+                throw new IllegalAddException(
+                        "Cannot add a second doctype, only one is allowed");
+            }
+        }
+
+        Object old = remove(index);
+        try {
+            add(index, obj);
+        }
+        catch (RuntimeException exception) {
+            add(index, old);
+            throw exception;
+        }
+        return old;
+    }
+
+    /**
+     * Return the number of items in this list
+     *
+     * @return The number of items in this list.
+     */
+    public int size() {
+        return size;
+    }
+
+    /**
+     * Return this list as a <code>String</code>
+     *
+     * @return The number of items in this list.
+     */
+    public String toString() {
+        return super.toString();
+    }
+
+    /** Give access of ContentList.modCount to FilterList */
+    private int getModCount() {
+        return modCount;
+    }
+
+    /* * * * * * * * * * * * * FilterList * * * * * * * * * * * * * * * */
+    /* * * * * * * * * * * * * FilterList * * * * * * * * * * * * * * * */
+
+    /**
+     * <code>FilterList</code> represents legal JDOM content, including content
+     * for <code>Document</code>s or <code>Element</code>s.
+     */
+
+    class FilterList extends AbstractList implements java.io.Serializable {
+
+        /** The Filter */
+        Filter filter;
+
+        /** Current number of items in this view */
+        int count = 0;
+
+        /** Expected modCount in our backing list */
+        int expected = -1;
+
+        // Implementation Note: Directly after size() is called, expected
+        //       is sync'd with ContentList.modCount and count provides
+        //       the true size of this view.  Before the first call to
+        //       size() or if the backing list is modified outside this
+        //       FilterList, both might contain bogus values and should
+        //       not be used without first calling size();
+
+        /**
+         * Create a new instance of the FilterList with the specified Filter.
+         */
+        FilterList(Filter filter) {
+            this.filter = filter;
+        }
+
+        /**
+         * Inserts the specified object at the specified position in this list.
+         * Shifts the object currently at that position (if any) and any
+         * subsequent objects to the right (adds one to their indices).
+         *
+         * @param index The location to set the value to.
+         * @param obj The object to insert into the list.
+         * throws IndexOutOfBoundsException if index < 0 || index > size()
+         */
+        public void add(int index, Object obj) {
+            if (filter.matches(obj)) {
+                int adjusted = getAdjustedIndex(index);
+                ContentList.this.add(adjusted, obj);
+                expected++;
+                count++;
+            }
+            else throw new IllegalAddException("Filter won't allow the " +
+                                obj.getClass().getName() +
+                                " '" + obj + "' to be added to the list");
+        }
+
+        /**
+         * Return the object at the specified offset.
+         *
+         * @param index The offset of the object.
+         * @return The Object which was returned.
+         */
+        public Object get(int index) {
+            int adjusted = getAdjustedIndex(index);
+            return ContentList.this.get(adjusted);
+        }
+
+        public Iterator iterator() {
+            return new FilterListIterator(filter, 0);
+        }
+
+        public ListIterator listIterator() {
+            return new FilterListIterator(filter, 0);
+        }
+
+        public ListIterator listIterator(int index) {
+            return new FilterListIterator(filter,  index);
+        }
+
+        /**
+         * Remove the object at the specified offset.
+         *
+         * @param index The offset of the object.
+         * @return The Object which was removed.
+         */
+        public Object remove(int index) {
+            int adjusted = getAdjustedIndex(index);
+            Object old = ContentList.this.get(adjusted);
+            if (filter.matches(old)) {
+                old = ContentList.this.remove(adjusted);
+                expected++;
+                count--;
+            }
+            else {
+                throw new IllegalAddException("Filter won't allow the " +
+                                             (old.getClass()).getName() +
+                                             " '" + old + "' (index " + index +
+                                             ") to be removed");
+            }
+            return old;
+        }
+
+        /**
+         * Set the object at the specified location to the supplied
+         * object.
+         *
+         * @param index The location to set the value to.
+         * @param obj The location to set the value to.
+         * @return The object which was replaced.
+         * throws IndexOutOfBoundsException if index < 0 || index >= size()
+         */
+        public Object set(int index, Object obj) {
+            Object old = null;
+            if (filter.matches(obj)) {
+                int adjusted = getAdjustedIndex(index);
+                old = ContentList.this.get(adjusted);
+                if (!filter.matches(old)) {
+                    throw new IllegalAddException("Filter won't allow the " +
+                                             (old.getClass()).getName() +
+                                             " '" + old + "' (index " + index +
+                                             ") to be removed");
+                }
+                old = ContentList.this.set(adjusted, obj);
+                expected += 2;
+            }
+            else {
+                throw new IllegalAddException("Filter won't allow index " +
+                                              index + " to be set to " +
+                                              (obj.getClass()).getName());
+            }
+            return old;
+        }
+
+        /**
+         * Return the number of items in this list
+         *
+         * @return The number of items in this list.
+         */
+        public int size() {
+            // Implementation Note: Directly after size() is called, expected
+            //       is sync'd with ContentList.modCount and count provides
+            //       the true size of this view.  Before the first call to
+            //       size() or if the backing list is modified outside this
+            //       FilterList, both might contain bogus values and should
+            //       not be used without first calling size();
+
+            if (expected == ContentList.this.getModCount()) {
+                return count;
+            }
+
+            count = 0;
+            for (int i = 0; i < ContentList.this.size(); i++) {
+                Object obj = ContentList.this.elementData[i];
+                if (filter.matches(obj)) {
+                    count++;
+                }
+            }
+            expected = ContentList.this.getModCount();
+            return count;
+        }
+
+        /**
+         * Return the adjusted index
+         *
+         * @param index Index of in this view.
+         * @return True index in backing list
+         */
+        final private int getAdjustedIndex(int index) {
+            int adjusted = 0;
+            for (int i = 0; i < ContentList.this.size; i++) {
+                Object obj = ContentList.this.elementData[i];
+                if (filter.matches(obj)) {
+                    if (index == adjusted) {
+                        return i;
+                    }
+                    adjusted++;
+                }
+            }
+
+            if (index == adjusted) {
+                return ContentList.this.size;
+            }
+
+            return ContentList.this.size + 1;
+        }
+    }
+
+    /* * * * * * * * * * * * * FilterListIterator * * * * * * * * * * * */
+    /* * * * * * * * * * * * * FilterListIterator * * * * * * * * * * * */
+
+    class FilterListIterator implements ListIterator {
+
+        /** The Filter that applies */
+        Filter filter;
+
+        /** Whether this iterator is in forward or reverse. */
+        private boolean forward = false;
+        /** Whether a call to remove() is valid */
+        private boolean canremove = false;
+        /** Whether a call to set() is valid */
+        private boolean canset = false;
+
+        /** Index in backing list of next object */
+        private int cursor = -1;
+        /** the backing index to use if we actually DO move */
+        private int tmpcursor = -1;
+        /** Index in ListIterator */
+        private int index = -1;
+
+        /** Expected modCount in our backing list */
+        private int expected = -1;
+
+        /** Number of elements matching the filter. */
+        private int fsize = 0;
+         
+        /**
+         * Default constructor
+         */
+        FilterListIterator(Filter filter, int start) {
+			this.filter = filter;
+			expected = ContentList.this.getModCount();
+			// always start list iterators in backward mode ....
+			// it makes sense... really.
+			forward = false;
+
+			if (start < 0) {
+				throw new IndexOutOfBoundsException("Index: " + start);
+			}
+
+			// the number of matching elements....
+			fsize = 0;
+
+			// go through the list, count the matching elements...
+			for (int i = 0; i < ContentList.this.size(); i++) {
+				if (filter.matches(ContentList.this.get(i))) {
+					if (start == fsize) {
+						// set the back-end cursor to the matching element....
+						cursor = i;
+						// set the front-end cursor too.
+						index = fsize;
+					}
+					fsize++;
+				}
+			}
+
+			if (start > fsize) {
+				throw new IndexOutOfBoundsException("Index: " + start + " Size: " + fsize);
+			}
+			if (cursor == -1) {
+				// implies that start == fsize (i.e. after the last element
+				// put the insertion point at the end of the Underlying
+				// content list ....
+				// i.e. an add() at this point may potentially end up with
+				// filtered content between previous() and next()
+				// the alternative is to put the cursor on the Content after
+				// the last Content that the filter passed
+				// The implications are ambiguous.
+				cursor = ContentList.this.size();
+				index = fsize;
+			}
+
+		}
+
+        /**
+		 * Returns <code>true</code> if this list iterator has a next element.
+		 */
+        public boolean hasNext() {
+        	return nextIndex() < fsize;
+        }
+
+        /**
+         * Returns the next element in the list.
+         */
+        public Object next() {
+        	if (!hasNext())
+				throw new NoSuchElementException("next() is beyond the end of the Iterator");
+			index = nextIndex();
+			cursor = tmpcursor;
+			forward = true;
+			canremove = true;
+			canset = true;
+			return ContentList.this.get(cursor);
+        }
+
+        /**
+		 * Returns <code>true</code> if this list iterator has more elements
+		 * when traversing the list in the reverse direction.
+		 */
+        public boolean hasPrevious() {
+        	return previousIndex() >= 0;
+        }
+
+        /**
+         * Returns the previous element in the list.
+         */
+        public Object previous() {
+			if (!hasPrevious())
+				throw new NoSuchElementException("previous() is before the start of the Iterator");
+			index = previousIndex();
+			cursor = tmpcursor;
+			forward = false;
+			canremove = true;
+			canset = true;
+			return ContentList.this.get(cursor);
+		}
+
+        /**
+		 * Returns the index of the element that would be returned by a
+		 * subsequent call to <code>next</code>.
+		 */
+        public int nextIndex() {
+            checkConcurrentModification();
+        	if (forward) {
+        		// Starting with next possibility ....
+        		for (int i = cursor + 1; i < ContentList.this.size(); i++) {
+        			if (filter.matches(ContentList.this.get(i))) {
+        				tmpcursor = i;
+        				return index + 1;
+        			}
+        		}
+    			// Never found another match.... put the insertion point at
+    			// the end of the list....
+    			tmpcursor = ContentList.this.size();
+    			return index + 1;
+    		}
+
+    		// We've been going back... so nextIndex() returns the same
+			// element.
+    		tmpcursor = cursor;
+    		return index;
+        }
+
+        /**
+         * Returns the index of the element that would be returned by a
+         * subsequent call to <code>previous</code>. (Returns -1 if the
+         * list iterator is at the beginning of the list.)
+         */
+        public int previousIndex() {
+			checkConcurrentModification();
+			if (!forward) {
+				// starting with next possibility ....
+				for (int i = cursor - 1; i >= 0; i--) {
+					if (filter.matches(ContentList.this.get(i))) {
+						tmpcursor = i;
+						return index - 1;
+					}
+				}
+				// Never found another match.... put the insertion point at
+				// the start of the list....
+				tmpcursor = -1;
+				return index - 1;
+			}
+
+			// We've been going forwards... so previousIndex() returns same
+			// element.
+			tmpcursor = cursor;
+			return index;
+		}
+
+        /**
+		 * Inserts the specified element into the list.
+		 */
+        public void add(Object obj) {
+            if (!filter.matches(obj)) {
+                throw new IllegalAddException("Filter won't allow the " +
+                        obj.getClass().getName() +
+                        " '" + obj + "' to be added to the list");
+            }
+
+			// Call to nextIndex() will check concurrent.
+			nextIndex();
+			// tmpcursor is the backing cursor of the next element
+			// Remember that List.add(index,obj) is really an insert....
+			ContentList.this.add(tmpcursor, obj);
+			expected = ContentList.this.getModCount();
+			canremove = canset = false;
+
+			if (forward) {
+			  index++;
+			} else {
+			  forward = true;
+			}
+			fsize++;
+			cursor = tmpcursor;
+		}
+
+        /**
+		 * Removes from the list the last element that was returned by
+		 * the last call to <code>next</code> or <code>previous</code>.
+		 */
+        public void remove() {
+			if (!canremove)
+				throw new IllegalStateException("Can not remove an "
+						+ "element unless either next() or previous() has been called "
+						+ "since the last remove()");
+			// we are removing the last entry reuned by either next() or previous().
+			// the idea is to remove it, and pretend that we used to be at the
+			// entry that happened *after* the removed entry.
+			// so, get what would be the next entry (set at tmpcursor).
+			// so call nextIndex to set tmpcursor to what would come after.
+			boolean dir = forward;
+			forward = true;
+			try {
+				nextIndex();
+				ContentList.this.remove(cursor);
+			} finally {
+				forward = dir;
+			}
+			cursor = tmpcursor - 1;
+			expected = ContentList.this.getModCount();
+
+			forward = false;
+			canremove = false;
+			canset = false;
+			fsize--;
+		}
+
+        /**
+		 * Replaces the last element returned by <code>next</code> or
+		 * <code>previous</code> with the specified element.
+		 */
+        public void set(Object obj) {
+			if (!canset)
+				throw new IllegalStateException("Can not set an element "
+						+ "unless either next() or previous() has been called since the " 
+						+ "last remove() or set()");
+			checkConcurrentModification();
+
+			if (!filter.matches(obj)) {
+				throw new IllegalAddException("Filter won't allow index " + index + " to be set to "
+						+ (obj.getClass()).getName());
+			}
+			
+			ContentList.this.set(cursor, obj);
+			expected = ContentList.this.getModCount();
+			
+		}
+
+        /**
+         * Check if are backing list is being modified by someone else.
+         */
+        private void checkConcurrentModification() {
+            if (expected != ContentList.this.getModCount()) {
+                throw new ConcurrentModificationException();
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/DefaultJDOMFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/DefaultJDOMFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/DefaultJDOMFactory.java	(revision 28000)
@@ -0,0 +1,134 @@
+/*--
+
+ $Id: DefaultJDOMFactory.java,v 1.7 2007/11/10 05:28:58 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+
+/**
+ * Creates the standard top-level JDOM classes (Element, Document, Comment,
+ * etc). A subclass of this factory might construct custom classes.
+ *
+ * @version $Revision: 1.7 $, $Date: 2007/11/10 05:28:58 $
+ * @author  Ken Rune Holland
+ * @author  Phil Nelson
+ * @author  Bradley S. Huffman
+ */
+public class DefaultJDOMFactory implements JDOMFactory {
+
+    public DefaultJDOMFactory() { }
+
+    // Allow Javadocs to inherit from JDOMFactory
+
+    public Attribute attribute(String name, String value,
+                                            int type, Namespace namespace) {
+        return new Attribute(name, value, type, namespace);
+    }
+
+    public CDATA cdata(String text) {
+        return new CDATA(text);
+    }
+
+    public Text text(String text) {
+        return new Text(text);
+    }
+
+    public Comment comment(String text) {
+        return new Comment(text);
+    }
+
+    public DocType docType(String elementName,
+                           String publicID, String systemID) {
+        return new DocType(elementName, publicID, systemID);
+    }
+
+    public Document document(Element rootElement) {
+        return new Document(rootElement);
+    }
+
+    public Element element(String name, Namespace namespace) {
+        return new Element(name, namespace);
+    }
+
+    public ProcessingInstruction processingInstruction(String target,
+                                                       String data) {
+        return new ProcessingInstruction(target, data);
+    }
+
+    public EntityRef entityRef(String name) {
+        return new EntityRef(name);
+    }
+
+    public EntityRef entityRef(String name, String publicID, String systemID) {
+        return new EntityRef(name, publicID, systemID);
+    }
+
+    // =====================================================================
+    // List manipulation
+    // =====================================================================
+
+    public void addContent(Parent parent, Content child) {
+        if (parent instanceof Document) {
+            ((Document) parent).addContent(child);
+        }
+        else {
+            ((Element) parent).addContent(child);
+        }
+    }
+
+    public void setAttribute(Element parent, Attribute a) {
+        parent.setAttribute(a);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/DescendantIterator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/DescendantIterator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/DescendantIterator.java	(revision 28000)
@@ -0,0 +1,170 @@
+/*--
+
+ $Id: DescendantIterator.java,v 1.6 2007/11/10 05:28:58 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+import java.util.*;
+import org.jdom.Content;
+import org.jdom.Element;
+import org.jdom.Parent;
+
+/**
+ * Traverse all a parent's descendants (all children at any level below
+ * the parent).
+ *
+ * @author Bradley S. Huffman
+ * @author Jason Hunter
+ * @version $Revision: 1.6 $, $Date: 2007/11/10 05:28:58 $
+ */
+class DescendantIterator implements Iterator {
+
+    private Iterator iterator;
+    private Iterator nextIterator;
+    private List stack = new ArrayList();
+
+    /**
+     * Iterator for the descendants of the supplied object.
+     *
+     * @param parent document or element whose descendants will be iterated
+     */
+    DescendantIterator(Parent parent) {
+        if (parent == null) {
+            throw new IllegalArgumentException("parent parameter was null");
+        }
+        this.iterator = parent.getContent().iterator();
+    }
+
+    /**
+     * Returns true> if the iteration has more {@link Content} descendants.
+     *
+     * @return true is the iterator has more descendants
+     */
+    public boolean hasNext() {
+        if (iterator != null && iterator.hasNext()) return true;
+        if (nextIterator != null && nextIterator.hasNext()) return true;
+        if (stackHasAnyNext()) return true;
+        return false;
+    }
+
+    /**
+     * Returns the next {@link Content} descendant.
+     *
+     * @return the next descendant
+     */
+    public Object next() {
+        if (!hasNext()) {
+            throw new NoSuchElementException();
+        }
+
+        // If we need to descend, go for it and record where we are.
+        // We do the shuffle here on the next next() call so remove() is easy
+        // to code up.
+        if (nextIterator != null) {
+            push(iterator);
+            iterator = nextIterator;
+            nextIterator = null;
+        }
+
+        // If this iterator is finished, try moving up the stack
+        while (!iterator.hasNext()) {
+            if (stack.size() > 0) {
+                iterator = pop();
+            }
+            else {
+              throw new NoSuchElementException("Somehow we lost our iterator");
+            }
+        }
+
+        Content child = (Content) iterator.next();
+        if (child instanceof Element) {
+            nextIterator = ((Element)child).getContent().iterator();
+        }
+        return child;
+    }
+
+    /**
+     * Detaches the last {@link org.jdom.Content} returned by the last call to
+     * next from it's parent.  <b>Note</b>: this <b>does not</b> affect
+     * iteration and all children, siblings, and any node following the
+     * removed node (in document order) will be visited.
+     */
+    public void remove() {
+        iterator.remove();
+    }
+
+    private Iterator pop() {
+        int stackSize = stack.size();
+        if (stackSize == 0) {
+            throw new NoSuchElementException("empty stack");
+        }
+        return (Iterator) stack.remove(stackSize - 1);
+    }
+
+    private void push(Iterator itr) {
+        stack.add(itr);
+    }
+
+    private boolean stackHasAnyNext() {
+        int size = stack.size();
+        for (int i = 0; i < size; i++) {
+            Iterator itr = (Iterator) stack.get(i);
+            if (itr.hasNext()) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/DocType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/DocType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/DocType.java	(revision 28000)
@@ -0,0 +1,175 @@
+/*--
+
+ $Id: DocType.java,v 1.32 2007/11/10 05:28:58 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+/**
+ * An XML DOCTYPE declaration.  Method allow the user to get and set the
+ * root element name, public id, and system id.
+ *
+ * @author Brett McLaughlin
+ * @author Jason Hunter
+ * @version $Revision: 1.32 $, $Date: 2007/11/10 05:28:58 $
+ */
+public class DocType extends Content {
+
+    /**
+     * Default, no-args constructor for implementations to use if needed.
+     */
+    protected DocType() {}
+
+    /*
+     * XXX:
+     *   We need to take care of entities and notations here.
+     */
+
+    /**
+     * This will create the <code>DocType</code> with
+     * the specified element name and a reference to an
+     * external DTD.
+     *
+     * @param elementName <code>String</code> name of
+     *        element being constrained.
+     * @param publicID <code>String</code> public ID of
+     *        referenced DTD
+     * @param systemID <code>String</code> system ID of
+     *        referenced DTD
+     * @throws IllegalDataException if the given system ID is not a legal
+     *         system literal or the public ID is not a legal public ID.
+     * @throws IllegalNameException if the given root element name is not a
+     *         legal XML element name.
+     */
+    public DocType(String elementName, String publicID, String systemID) {
+        setElementName(elementName);
+        setPublicID(publicID);
+        setSystemID(systemID);
+    }
+
+    /**
+     * This will set the root element name declared by this
+     * DOCTYPE declaration.
+     *
+     * @return DocType <code>DocType</code> this DocType object
+     * @param elementName <code>String</code> name of
+     *        root element being constrained.
+     * @throws IllegalNameException if the given root element name is not a
+     *         legal XML element name.
+     */
+    public DocType setElementName(String elementName) {
+        // This can contain a colon so we use checkXMLName()
+        // instead of checkElementName()
+        String reason = Verifier.checkXMLName(elementName);
+        if (reason != null) {
+            throw new IllegalNameException(elementName, "DocType", reason);
+        }
+        return this;
+    }
+
+    /**
+     * This will set the public ID of an externally
+     * referenced DTD.
+     *
+     * @param publicID id to set
+     * @return DocType <code>DocType</code> this DocType object
+     * @throws IllegalDataException if the given public ID is not a legal
+     *         public ID.
+     */
+    public DocType setPublicID(String publicID) {
+        String reason = Verifier.checkPublicID(publicID);
+        if (reason != null) {
+            throw new IllegalDataException(publicID, "DocType", reason);
+        }
+
+        return this;
+    }
+
+    /**
+     * This will set the system ID of an externally
+     * referenced DTD.
+     *
+     * @param systemID id to set
+     * @return systemID <code>String</code> system ID of
+     *                  referenced DTD.
+     * @throws IllegalDataException if the given system ID is not a legal
+     *         system literal.
+     */
+    public DocType setSystemID(String systemID) {
+        String reason = Verifier.checkSystemLiteral(systemID);
+        if (reason != null) {
+            throw new IllegalDataException(systemID, "DocType", reason);
+        }
+
+        return this;
+    }
+
+    /**
+     * Returns the empty string since doctypes don't have an XPath
+     * 1.0 string value.
+     * @return the empty string
+     */
+    public String getValue() {
+        return "";  // doctypes don't have an XPath string value
+    }
+
+    /**
+     * This sets the data for the internal subset.
+     *
+     * @param newData data for the internal subset, as a
+     *        <code>String</code>.
+     */
+    public void setInternalSubset(String newData) {
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/Document.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/Document.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/Document.java	(revision 28000)
@@ -0,0 +1,420 @@
+/*--
+
+ $Id: Document.java,v 1.85 2007/11/10 05:28:58 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * An XML document. Methods allow access to the root element as well as the
+ * {@link DocType} and other document-level information.
+ *
+ * @version $Revision: 1.85 $, $Date: 2007/11/10 05:28:58 $
+ * @author  Brett McLaughlin
+ * @author  Jason Hunter
+ * @author  Jools Enticknap
+ * @author  Bradley S. Huffman
+ */
+public class Document implements Parent {
+
+    /**
+     * This document's content including comments, PIs, a possible
+     * DocType, and a root element.
+     * Subclassers have to track content using their own
+     * mechanism.
+     */
+    ContentList content = new ContentList(this);
+
+    /**
+     * Creates a new empty document.  A document must have a root element,
+     * so this document will not be well-formed and accessor methods will
+     * throw an IllegalStateException if this document is accessed before a
+     * root element is added.  This method is most useful for build tools.
+     */
+    public Document() {}
+
+    /**
+     * This will create a new <code>Document</code>,
+     * with the supplied <code>{@link Element}</code>
+     * as the root element, the supplied
+     * <code>{@link DocType}</code> declaration, and the specified
+     * base URI.
+     *
+     * @param rootElement <code>Element</code> for document root.
+     * @param docType <code>DocType</code> declaration.
+     * @param baseURI the URI from which this doucment was loaded.
+     * @throws IllegalAddException if the given docType object
+     *         is already attached to a document or the given
+     *         rootElement already has a parent
+     */
+    public Document(Element rootElement, DocType docType, String baseURI) {
+        if (rootElement != null) {
+            setRootElement(rootElement);
+        }
+        if (docType != null) {
+            setDocType(docType);
+        }
+        if (baseURI != null) {
+            setBaseURI(baseURI);
+        }
+    }
+
+    /**
+     * This will create a new <code>Document</code>,
+     * with the supplied <code>{@link Element}</code>
+     * as the root element, and no <code>{@link DocType}</code>
+     * declaration.
+     *
+     * @param rootElement <code>Element</code> for document root
+     * @throws IllegalAddException if the given rootElement already has
+     *         a parent.
+     */
+    public Document(Element rootElement) {
+        this(rootElement, null, null);
+    }
+
+//    /**
+//     * Starting at the given index (inclusive), return the index of
+//     * the first child matching the supplied filter, or -1
+//     * if none is found.
+//     *
+//     * @return index of child, or -1 if none found.
+//     */
+//    private int indexOf(int start, Filter filter) {
+//        int size = getContentSize();
+//        for (int i = start; i < size; i++) {
+//            if (filter.matches(getContent(i))) {
+//                return i;
+//            }
+//        }
+//        return -1;
+//    }
+
+    /**
+     * This will return <code>true</code> if this document has a
+     * root element, <code>false</code> otherwise.
+     *
+     * @return <code>true</code> if this document has a root element,
+     *         <code>false</code> otherwise.
+     */
+    public boolean hasRootElement() {
+        return (content.indexOfFirstElement() < 0) ? false : true;
+    }
+
+    /**
+     * This will return the root <code>Element</code>
+     * for this <code>Document</code>
+     *
+     * @return <code>Element</code> - the document's root element
+     * @throws IllegalStateException if the root element hasn't been set
+     */
+    public Element getRootElement() {
+        int index = content.indexOfFirstElement();
+        if (index < 0) {
+            throw new IllegalStateException("Root element not set");
+        }
+        return (Element) content.get(index);
+    }
+
+    /**
+     * This sets the root <code>{@link Element}</code> for the
+     * <code>Document</code>. If the document already has a root
+     * element, it is replaced.
+     *
+     * @param rootElement <code>Element</code> to be new root.
+     * @return <code>Document</code> - modified Document.
+     * @throws IllegalAddException if the given rootElement already has
+     *         a parent.
+     */
+    public Document setRootElement(Element rootElement) {
+        int index = content.indexOfFirstElement();
+        if (index < 0) {
+            content.add(rootElement);
+        }
+        else {
+            content.set(index, rootElement);
+        }
+        return this;
+    }
+
+    /**
+     * This will return the <code>{@link DocType}</code>
+     * declaration for this <code>Document</code>, or
+     * <code>null</code> if none exists.
+     *
+     * @return <code>DocType</code> - the DOCTYPE declaration.
+     */
+    public DocType getDocType() {
+        int index = content.indexOfDocType();
+        if (index < 0) {
+            return null;
+        }
+        else {
+            return (DocType) content.get(index);
+        }
+    }
+
+    /**
+     * This will set the <code>{@link DocType}</code>
+     * declaration for this <code>Document</code>. Note
+     * that a DocType can only be attached to one Document.
+     * Attempting to set the DocType to a DocType object
+     * that already belongs to a Document will result in an
+     * IllegalAddException being thrown.
+     *
+     * @param docType <code>DocType</code> declaration.
+     * @return object on which the method was invoked
+     * @throws IllegalAddException if the given docType is
+     *   already attached to a Document.
+     */
+    public Document setDocType(DocType docType) {
+        if (docType == null) {
+            // Remove any existing doctype
+            int docTypeIndex = content.indexOfDocType();
+            if (docTypeIndex >= 0) content.remove(docTypeIndex);
+            return this;
+        }
+
+        if (docType.getParent() != null) {
+            throw new IllegalAddException(docType,
+                              "The DocType already is attached to a document");
+        }
+
+        // Add DocType to head if new, replace old otherwise
+        int docTypeIndex = content.indexOfDocType();
+        if (docTypeIndex < 0) {
+            content.add(0, docType);
+        }
+        else {
+            content.set(docTypeIndex, docType);
+        }
+
+        return this;
+    }
+
+    /**
+     * Appends the child to the end of the content list.
+     *
+     * @param child   child to append to end of content list
+     * @return        the document on which the method was called
+     * @throws IllegalAddException if the given child already has a parent.
+     */
+    public Document addContent(Content child) {
+        content.add(child);
+        return this;
+    }
+
+//    public Content getChild(Filter filter) {
+//        int i = indexOf(0, filter);
+//        return (i < 0) ? null : getContent(i);
+//    }
+
+    /**
+     * This will return all content for the <code>Document</code>.
+     * The returned list is "live" in document order and changes to it
+     * affect the document's actual content.
+     *
+     * <p>
+     * Sequential traversal through the List is best done with a Iterator
+     * since the underlying implement of List.size() may require walking the
+     * entire list.
+     * </p>
+     *
+     * @return <code>List</code> - all Document content
+     * @throws IllegalStateException if the root element hasn't been set
+     */
+    public List getContent() {
+        if (!hasRootElement())
+            throw new IllegalStateException("Root element not set");
+        return content;
+    }
+
+    /**
+     *
+     * <p>
+     * Sets the effective URI from which this document was loaded,
+     * and against which relative URLs in this document will be resolved.
+     * </p>
+     *
+     * @param uri the base URI of this document
+     */
+    public final void setBaseURI(String uri) {
+    }
+
+    public boolean removeContent(Content child) {
+        return content.remove(child);
+    }
+
+    /**
+     * This returns a <code>String</code> representation of the
+     * <code>Document</code>, suitable for debugging. If the XML
+     * representation of the <code>Document</code> is desired,
+     * {@link org.jdom.output.XMLOutputter#outputString(Document)}
+     * should be used.
+     *
+     * @return <code>String</code> - information about the
+     *         <code>Document</code>
+     */
+    public String toString() {
+        StringBuffer stringForm = new StringBuffer()
+            .append("[Document: ");
+
+        DocType docType = getDocType();
+        if (docType != null) {
+            stringForm.append(docType.toString())
+                      .append(", ");
+        } else {
+            stringForm.append(" No DOCTYPE declaration, ");
+        }
+
+		if (hasRootElement()) {
+            stringForm.append("Root is ")
+                      .append(getRootElement().toString());
+        } else {
+            stringForm.append(" No root element"); // shouldn't happen
+        }
+
+        stringForm.append("]");
+
+        return stringForm.toString();
+    }
+
+    /**
+     * This tests for equality of this <code>Document</code> to the supplied
+     * <code>Object</code>.
+     *
+     * @param ob <code>Object</code> to compare to
+     * @return <code>boolean</code> whether the <code>Document</code> is
+     *         equal to the supplied <code>Object</code>
+     */
+    public final boolean equals(Object ob) {
+        return (ob == this);
+    }
+
+    /**
+     * This returns the hash code for this <code>Document</code>.
+     *
+     * @return <code>int</code> hash code
+     */
+    public final int hashCode() {
+        return super.hashCode();
+    }
+
+    /**
+     * This will return a deep clone of this <code>Document</code>.
+     *
+     * @return <code>Object</code> clone of this <code>Document</code>
+     */
+    public Object clone() {
+        Document doc = null;
+
+        try {
+            doc = (Document) super.clone();
+        } catch (CloneNotSupportedException ce) {
+            // Can't happen
+        }
+
+        // The clone has a reference to this object's content list, so
+        // owerwrite with a empty list
+        doc.content = new ContentList(doc);
+
+        // Add the cloned content to clone
+
+        for (int i = 0; i < content.size(); i++) {
+            Object obj = content.get(i);
+            if (obj instanceof Element) {
+                Element element = (Element)((Element)obj).clone();
+                doc.content.add(element);
+            }
+            else if (obj instanceof Comment) {
+                Comment comment = (Comment)((Comment)obj).clone();
+                doc.content.add(comment);
+            }
+            else if (obj instanceof ProcessingInstruction) {
+                ProcessingInstruction pi = (ProcessingInstruction)
+                           ((ProcessingInstruction)obj).clone();
+                doc.content.add(pi);
+            }
+            else if (obj instanceof DocType) {
+                DocType dt = (DocType) ((DocType)obj).clone();
+                doc.content.add(dt);
+            }
+        }
+
+        return doc;
+    }
+
+    /**
+     * Returns an iterator that walks over all descendants in document order.
+     *
+     * @return an iterator to walk descendants
+     */
+    public Iterator getDescendants() {
+        return new DescendantIterator(this);
+    }
+
+    public Parent getParent() {
+        return null;  // documents never have parents
+    }
+
+    /**
+     * @see org.jdom.Parent#getDocument()
+     */
+    public Document getDocument() {
+        return this;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/Element.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/Element.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/Element.java	(revision 28000)
@@ -0,0 +1,913 @@
+/*--
+
+ $Id: Element.java,v 1.159 2007/11/14 05:02:08 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jdom.filter.ElementFilter;
+
+/**
+ * An XML element. Methods allow the user to get and manipulate its child
+ * elements and content, directly access the element's textual content,
+ * manipulate its attributes, and manage namespaces.
+ *
+ * @version $Revision: 1.159 $, $Date: 2007/11/14 05:02:08 $
+ * @author  Brett McLaughlin
+ * @author  Jason Hunter
+ * @author  Lucas Gonze
+ * @author  Kevin Regan
+ * @author  Dan Schaffer
+ * @author  Yusuf Goolamabbas
+ * @author  Kent C. Johnson
+ * @author  Jools Enticknap
+ * @author  Alex Rosen
+ * @author  Bradley S. Huffman
+ * @author  Victor Toni
+ */
+public class Element extends Content implements Parent {
+
+    private static final int INITIAL_ARRAY_SIZE = 5;
+
+    /** The local name of the element */
+    protected String name;
+
+    /** The namespace of the element */
+    protected transient Namespace namespace;
+
+    /** Additional namespace declarations to store on this element; useful
+     * during output */
+    protected transient List additionalNamespaces;
+
+    // See http://lists.denveronline.net/lists/jdom-interest/2000-September/003030.html
+    // for a possible memory optimization here (using a RootElement subclass)
+
+    /**
+     *  The attributes of the element.  Subclassers have to
+     * track attributes using their own mechanism.
+     */
+    AttributeList attributes = new AttributeList(this);
+
+    /**
+     * The content of the element.  Subclassers have to
+     * track content using their own mechanism.
+     */
+    ContentList content = new ContentList(this);
+
+    /**
+     * This protected constructor is provided in order to support an Element
+     * subclass that wants full control over variable initialization. It
+     * intentionally leaves all instance variables null, allowing a lightweight
+     * subclass implementation. The subclass is responsible for ensuring all the
+     * get and set methods on Element behave as documented.
+     * <p>
+     * When implementing an Element subclass which doesn't require full control
+     * over variable initialization, be aware that simply calling super() (or
+     * letting the compiler add the implicit super() call) will not initialize
+     * the instance variables which will cause many of the methods to throw a
+     * NullPointerException. Therefore, the constructor for these subclasses
+     * should call one of the public constructors so variable initialization is
+     * handled automatically.
+     */
+    protected Element() { }
+
+    /**
+     * Creates a new element with the supplied (local) name and namespace. If
+     * the provided namespace is null, the element will have no namespace.
+     *
+     * @param  name                 local name of the element
+     * @param  namespace            namespace for the element
+     * @throws IllegalNameException if the given name is illegal as an element
+     *                              name
+     */
+    public Element(final String name, final Namespace namespace) {
+        setName(name);
+        setNamespace(namespace);
+    }
+
+    /**
+     * Returns the (local) name of the element (without any namespace prefix).
+     *
+     * @return                     local element name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets the (local) name of the element.
+     *
+     * @param  name                 the new (local) name of the element
+     * @return                      the target element
+     * @throws IllegalNameException if the given name is illegal as an Element
+     *                              name
+     */
+    public Element setName(final String name) {
+        final String reason = Verifier.checkElementName(name);
+        if (reason != null) {
+            throw new IllegalNameException(name, "element", reason);
+        }
+        this.name = name;
+        return this;
+    }
+
+    /**
+     * Returns the element's {@link Namespace}.
+     *
+     * @return                     the element's namespace
+     */
+    public Namespace getNamespace() {
+        return namespace;
+    }
+
+    /**
+     * Sets the element's {@link Namespace}. If the provided namespace is null,
+     * the element will have no namespace.
+     *
+     * @param  namespace           the new namespace
+     * @return                     the target element
+     */
+    public Element setNamespace(Namespace namespace) {
+        if (namespace == null) {
+            namespace = Namespace.NO_NAMESPACE;
+        }
+		String reason = Verifier.checkNamespaceCollision(namespace, 
+				getAdditionalNamespaces());
+		if (reason != null) {
+			throw new IllegalAddException(this, namespace, reason);
+		}
+		for (Iterator it = getAttributes().iterator(); it.hasNext();) {
+			Attribute a = (Attribute)it.next();
+			reason = Verifier.checkNamespaceCollision(namespace, a);
+			if (reason != null) {
+				throw new IllegalAddException(this, namespace, reason);
+			}
+		}
+
+        this.namespace = namespace;
+        return this;
+    }
+
+    /**
+     * Returns the namespace prefix of the element or an empty string if none
+     * exists.
+     *
+     * @return                     the namespace prefix
+     */
+    public String getNamespacePrefix() {
+        return namespace.getPrefix();
+    }
+
+    /**
+     * Returns the namespace URI mapped to this element's prefix (or the
+     * in-scope default namespace URI if no prefix). If no mapping is found, an
+     * empty string is returned.
+     *
+     * @return                     the namespace URI for this element
+     */
+    public String getNamespaceURI() {
+        return namespace.getURI();
+    }
+
+    /**
+     * Returns the {@link Namespace} corresponding to the given prefix in scope
+     * for this element. This involves searching up the tree, so the results
+     * depend on the current location of the element. Returns null if there is
+     * no namespace in scope with the given prefix at this point in the
+     * document.
+     *
+     * @param  prefix              namespace prefix to look up
+     * @return                     the Namespace for this prefix at this
+     *                             location, or null if none
+     */
+    public Namespace getNamespace(final String prefix) {
+        if (prefix == null) {
+            return null;
+        }
+
+        if ("xml".equals(prefix)) {
+            // Namespace "xml" is always bound.
+            return Namespace.XML_NAMESPACE;
+        }
+
+        // Check if the prefix is the prefix for this element
+        if (prefix.equals(getNamespacePrefix())) {
+            return getNamespace();
+        }
+
+        // Scan the additional namespaces
+        if (additionalNamespaces != null) {
+            for (int i = 0; i < additionalNamespaces.size(); i++) {
+                final Namespace ns = (Namespace) additionalNamespaces.get(i);
+                if (prefix.equals(ns.getPrefix())) {
+                    return ns;
+                }
+            }
+        }
+        
+        if (attributes != null) {
+        	for (Iterator it = attributes.iterator(); it.hasNext();) {
+        		Attribute a = (Attribute)it.next();
+        		if (prefix.equals(a.getNamespacePrefix())) {
+        			return a.getNamespace();
+        		}
+        	}
+        }
+
+        // If we still don't have a match, ask the parent
+        if (parent instanceof Element) {
+            return ((Element)parent).getNamespace(prefix);
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the full name of the element, in the form
+     * [namespacePrefix]:[localName]. If the element does not have a namespace
+     * prefix, then the local name is returned.
+     *
+     * @return                     qualified name of the element (including
+     *                             namespace prefix)
+     */
+    public String getQualifiedName() {
+        // Note: Any changes here should be reflected in
+        // XMLOutputter.printQualifiedName()
+        if ("".equals(namespace.getPrefix())) {
+            return getName();
+        }
+
+        return new StringBuffer(namespace.getPrefix())
+            .append(':')
+            .append(name)
+            .toString();
+    }
+
+    /**
+     * Adds a namespace declarations to this element. This should <i>not</i> be
+     * used to add the declaration for this element itself; that should be
+     * assigned in the construction of the element. Instead, this is for adding
+     * namespace declarations on the element not relating directly to itself.
+     * It's used during output to for stylistic reasons move namespace
+     * declarations higher in the tree than they would have to be.
+     *
+     * @param  additionalNamespace namespace to add
+     * @throws IllegalAddException if the namespace prefix collides with another
+     *                             namespace prefix on the element
+     */
+    public void addNamespaceDeclaration(final Namespace additionalNamespace) {
+
+        // Verify the new namespace prefix doesn't collide with another
+        // declared namespace, an attribute prefix, or this element's prefix
+        final String reason = Verifier.checkNamespaceCollision(additionalNamespace, this);
+        if (reason != null) {
+            throw new IllegalAddException(this, additionalNamespace, reason);
+        }
+
+        if (additionalNamespaces == null) {
+            additionalNamespaces = new ArrayList(INITIAL_ARRAY_SIZE);
+        }
+
+        additionalNamespaces.add(additionalNamespace);
+    }
+
+    /**
+     * Returns a list of the additional namespace declarations on this element.
+     * This includes only additional namespace, not the namespace of the element
+     * itself, which can be obtained through {@link #getNamespace()}. If there
+     * are no additional declarations, this returns an empty list. Note, the
+     * returned list is unmodifiable.
+     *
+     * @return                     a List of the additional namespace
+     *                             declarations
+     */
+    public List getAdditionalNamespaces() {
+        // Not having the returned list be live allows us to avoid creating a
+        // new list object when XMLOutputter calls this method on an element
+        // with an empty list.
+        if (additionalNamespaces == null) {
+            return Collections.EMPTY_LIST;
+        }
+        return Collections.unmodifiableList(additionalNamespaces);
+    }
+
+    /**
+     * Returns the XPath 1.0 string value of this element, which is the
+     * complete, ordered content of all text node descendants of this element
+     * (i&#46;e&#46; the text that's left after all references are resolved
+     * and all other markup is stripped out.)
+     *
+     * @return a concatentation of all text node descendants
+     */
+    public String getValue() {
+        final StringBuffer buffer = new StringBuffer();
+
+        final Iterator iter = getContent().iterator();
+        while (iter.hasNext()) {
+            final Content child = (Content) iter.next();
+            if (child instanceof Element || child instanceof Text) {
+                buffer.append(child.getValue());
+            }
+        }
+        return buffer.toString();
+    }
+
+//    private int indexOf(int start, Filter filter) {
+//        int size = getContentSize();
+//        for (int i = start; i < size; i++) {
+//            if (filter.matches(getContent(i))) {
+//                return i;
+//            }
+//        }
+//        return -1;
+//    }
+
+
+    /**
+     * Returns the textual content directly held under this element as a string.
+     * This includes all text within this single element, including whitespace
+     * and CDATA sections if they exist. It's essentially the concatenation of
+     * all {@link Text} and {@link CDATA} nodes returned by {@link #getContent}.
+     * The call does not recurse into child elements. If no textual value exists
+     * for the element, an empty string is returned.
+     *
+     * @return                     text content for this element, or empty
+     *                             string if none
+     */
+    public String getText() {
+        if (content.size() == 0) {
+            return "";
+        }
+
+        // If we hold only a Text or CDATA, return it directly
+        if (content.size() == 1) {
+            final Object obj = content.get(0);
+            if (obj instanceof Text) {
+                return ((Text) obj).getText();
+            }
+            else {
+                return "";
+            }
+        }
+
+        // Else build String up
+        final StringBuffer textContent = new StringBuffer();
+        boolean hasText = false;
+
+        for (int i = 0; i < content.size(); i++) {
+            final Object obj = content.get(i);
+            if (obj instanceof Text) {
+                textContent.append(((Text) obj).getText());
+                hasText = true;
+            }
+        }
+
+        if (!hasText) {
+            return "";
+        }
+        else {
+            return textContent.toString();
+        }
+    }
+
+    /**
+     * Returns the textual content of this element with all surrounding
+     * whitespace removed. If no textual value exists for the element, or if
+     * only whitespace exists, the empty string is returned.
+     *
+     * @return                     trimmed text content for this element, or
+     *                             empty string if none
+     */
+    public String getTextTrim() {
+        return getText().trim();
+    }
+
+    /**
+     * Returns the textual content of the named child element, or null if
+     * there's no such child. This method is a convenience because calling
+     * <code>getChild().getText()</code> can throw a NullPointerException.
+     *
+     * @param  name                the name of the child
+     * @return                     text content for the named child, or null if
+     *                             no such child
+     */
+    public String getChildText(final String name) {
+        final Element child = getChild(name);
+        if (child == null) {
+            return null;
+        }
+        return child.getText();
+    }
+
+    /**
+     * Sets the content of the element to be the text given. All existing text
+     * content and non-text context is removed. If this element should have both
+     * textual content and nested elements, use <code>{@link #setContent}</code>
+     * instead. Setting a null text value is equivalent to setting an empty
+     * string value.
+     *
+     * @param  text                 new text content for the element
+     * @return                      the target element
+     * @throws IllegalDataException if the assigned text contains an illegal
+     *                              character such as a vertical tab (as
+     *                              determined by {@link
+     *                              org.jdom.Verifier#checkCharacterData})
+     */
+    public Element setText(final String text) {
+        content.clear();
+
+        if (text != null) {
+            addContent(new Text(text));
+        }
+
+        return this;
+    }
+
+    /**
+     * This returns the full content of the element as a List which
+     * may contain objects of type <code>Text</code>, <code>Element</code>,
+     * <code>Comment</code>, <code>ProcessingInstruction</code>,
+     * <code>CDATA</code>, and <code>EntityRef</code>.
+     * The List returned is "live" in document order and modifications
+     * to it affect the element's actual contents.  Whitespace content is
+     * returned in its entirety.
+     *
+     * <p>
+     * Sequential traversal through the List is best done with an Iterator
+     * since the underlying implement of List.size() may require walking the
+     * entire list.
+     * </p>
+     *
+     * @return a <code>List</code> containing the mixed content of the
+     *         element: may contain <code>Text</code>,
+     *         <code>{@link Element}</code>, <code>{@link Comment}</code>,
+     *         <code>{@link ProcessingInstruction}</code>,
+     *         <code>{@link CDATA}</code>, and
+     *         <code>{@link EntityRef}</code> objects.
+     */
+    public List getContent() {
+        return content;
+    }
+
+    /**
+     * Appends the child to the end of the element's content list.
+     *
+     * @param child   child to append to end of content list
+     * @return        the element on which the method was called
+     * @throws IllegalAddException if the given child already has a parent.     */
+    public Element addContent(final Content child) {
+        content.add(child);
+        return this;
+    }
+
+//    public Content getChild(Filter filter) {
+//        int i = indexOf(0, filter);
+//        return (i < 0) ? null : getContent(i);
+//    }
+
+    public boolean removeContent(final Content child) {
+        return content.remove(child);
+    }
+
+    /**
+     * Determines if this element is the ancestor of another element.
+     *
+     * @param element <code>Element</code> to check against
+     * @return <code>true</code> if this element is the ancestor of the
+     *         supplied element
+     */
+    public boolean isAncestor(final Element element) {
+        Parent p = element.getParent();
+        while (p instanceof Element) {
+            if (p == this) {
+                return true;
+            }
+            p = p.getParent();
+        }
+        return false;
+    }
+
+    /**
+     * <p>
+     * This returns the complete set of attributes for this element, as a
+     * <code>List</code> of <code>Attribute</code> objects in no particular
+     * order, or an empty list if there are none.
+     * The returned list is "live" and changes to it affect the
+     * element's actual attributes.
+     * </p>
+     *
+     * @return attributes for the element
+     */
+    public List getAttributes() {
+        return attributes;
+    }
+
+    /**
+     * <p>
+     * This returns the attribute for this element with the given name
+     * and within the given Namespace, or null if no such attribute exists.
+     * </p>
+     *
+     * @param name name of the attribute to return
+     * @param ns <code>Namespace</code> to search within
+     * @return attribute for the element
+     */
+    public Attribute getAttribute(final String name, final Namespace ns) {
+        return (Attribute) attributes.get(name, ns);
+    }
+
+    /**
+     * <p>
+     * This returns the attribute value for the attribute with the given name
+     * and within the given Namespace, null if there is no such attribute, and
+     * the empty string if the attribute value is empty.
+     * </p>
+     *
+     * @param name name of the attribute whose valud is to be returned
+     * @param ns <code>Namespace</code> to search within
+     * @return the named attribute's value, or null if no such attribute
+     */
+    public String getAttributeValue(final String name, final Namespace ns) {
+        return getAttributeValue(name, ns, null);
+    }
+
+    /**
+     * <p>
+     * This returns the attribute value for the attribute with the given name
+     * and within the given Namespace, or the passed-in default if there is no
+     * such attribute.
+     * </p>
+     *
+     * @param name name of the attribute whose valud is to be returned
+     * @param ns <code>Namespace</code> to search within
+     * @param def a default value to return if the attribute does not exist
+     * @return the named attribute's value, or the default if no such attribute
+     */
+    public String getAttributeValue(final String name, final Namespace ns, final String def) {
+        final Attribute attribute = (Attribute) attributes.get(name, ns);
+        if (attribute == null) {
+            return def;
+        }
+
+        return attribute.getValue();
+    }
+
+    /**
+     * <p>
+     * This sets an attribute value for this element.  Any existing attribute
+     * with the same name and namespace URI is removed.
+     * </p>
+     *
+     * @param name name of the attribute to set
+     * @param value value of the attribute to set
+     * @param ns namespace of the attribute to set
+     * @return this element modified
+     * @throws IllegalNameException if the given name is illegal as an
+     *         attribute name, or if the namespace is an unprefixed default
+     *         namespace
+     * @throws IllegalDataException if the given attribute value is
+     *         illegal character data (as determined by
+     *         {@link org.jdom.Verifier#checkCharacterData}).
+     * @throws IllegalAddException if the attribute namespace prefix
+     *         collides with another namespace prefix on the element.
+     */
+    public Element setAttribute(final String name, final String value, final Namespace ns) {
+        final Attribute attribute = getAttribute(name, ns);
+        if (attribute == null) {
+            final Attribute newAttribute = new Attribute(name, value, ns);
+            setAttribute(newAttribute);
+        } else {
+            attribute.setValue(value);
+        }
+
+        return this;
+    }
+
+    /**
+     * <p>
+     * This sets an attribute value for this element.  Any existing attribute
+     * with the same name and namespace URI is removed.
+     * </p>
+     *
+     * @param attribute <code>Attribute</code> to set
+     * @return this element modified
+     * @throws IllegalAddException if the attribute being added already has a
+     *   parent or if the attribute namespace prefix collides with another
+     *   namespace prefix on the element.
+     */
+    public Element setAttribute(final Attribute attribute) {
+        attributes.add(attribute);
+        return this;
+    }
+
+    /**
+     * <p>
+     * This removes the attribute with the given name and within the
+     * given Namespace.  If no such attribute exists, this method does
+     * nothing.
+     * </p>
+     *
+     * @param name name of attribute to remove
+     * @param ns namespace URI of attribute to remove
+     * @return whether the attribute was removed
+     */
+    public boolean removeAttribute(final String name, final Namespace ns) {
+        return attributes.remove(name, ns);
+    }
+
+    /**
+     * <p>
+     * This removes the supplied Attribute should it exist.
+     * </p>
+     *
+     * @param attribute Reference to the attribute to be removed.
+     * @return whether the attribute was removed
+     */
+    public boolean removeAttribute(final Attribute attribute) {
+        return attributes.remove(attribute);
+    }
+
+    /**
+     * <p>
+     *  This returns a <code>String</code> representation of the
+     *    <code>Element</code>, suitable for debugging. If the XML
+     *    representation of the <code>Element</code> is desired,
+     *    {@link org.jdom.output.XMLOutputter#outputString(Element)}
+     *    should be used.
+     * </p>
+     *
+     * @return <code>String</code> - information about the
+     *         <code>Element</code>
+     */
+    public String toString() {
+        final StringBuffer stringForm = new StringBuffer(64)
+            .append("[Element: <")
+            .append(getQualifiedName());
+
+        final String nsuri = getNamespaceURI();
+        if (!"".equals(nsuri)) {
+            stringForm
+            .append(" [Namespace: ")
+            .append(nsuri)
+            .append("]");
+        }
+        stringForm.append("/>]");
+
+        return stringForm.toString();
+    }
+
+    /**
+     * <p>
+     *  This returns a deep clone of this element.
+     *  The new element is detached from its parent, and getParent()
+     *  on the clone will return null.
+     * </p>
+     *
+     * @return the clone of this element
+     */
+   public Object clone() {
+
+       // Ken Rune Helland <kenh@csc.no> is our local clone() guru
+
+       final Element element = (Element) super.clone();
+
+       // name and namespace are references to immutable objects
+       // so super.clone() handles them ok
+
+       // Reference to parent is copied by super.clone()
+       // (Object.clone()) so we have to remove it
+       // Actually, super is a Content, which has already detached in the
+       // clone().
+       // element.parent = null;
+
+       // Reference to content list and attribute lists are copyed by
+       // super.clone() so we set it new lists if the original had lists
+       element.content = new ContentList(element);
+       element.attributes = new AttributeList(element);
+
+       // Cloning attributes
+       if (attributes != null) {
+           for(int i = 0; i < attributes.size(); i++) {
+               final Attribute attribute = (Attribute) attributes.get(i);
+               element.attributes.add(attribute.clone());
+           }
+       }
+
+       // Cloning additional namespaces
+       if (additionalNamespaces != null) {
+           element.additionalNamespaces = new ArrayList(additionalNamespaces);
+       }
+
+       // Cloning content
+       if (content != null) {
+           for(int i = 0; i < content.size(); i++) {
+               final Content c = (Content) content.get(i);
+               element.content.add(c.clone());
+           }
+       }
+
+       return element;
+   }
+
+
+    // Support a custom Namespace serialization so no two namespace
+    // object instances may exist for the same prefix/uri pair
+    private void writeObject(final ObjectOutputStream out) throws IOException {
+
+        out.defaultWriteObject();
+
+        // We use writeObject() and not writeUTF() to minimize space
+        // This allows for writing pointers to already written strings
+        out.writeObject(namespace.getPrefix());
+        out.writeObject(namespace.getURI());
+
+        if (additionalNamespaces == null) {
+            out.write(0);
+        }
+        else {
+            final int size = additionalNamespaces.size();
+            out.write(size);
+            for (int i = 0; i < size; i++) {
+                final Namespace additional = (Namespace) additionalNamespaces.get(i);
+                out.writeObject(additional.getPrefix());
+                out.writeObject(additional.getURI());
+            }
+        }
+    }
+
+    private void readObject(final ObjectInputStream in)
+        throws IOException, ClassNotFoundException {
+
+        in.defaultReadObject();
+
+        namespace = Namespace.getNamespace(
+            (String)in.readObject(), (String)in.readObject());
+
+        final int size = in.read();
+
+        if (size != 0) {
+            additionalNamespaces = new ArrayList(size);
+            for (int i = 0; i < size; i++) {
+                final Namespace additional = Namespace.getNamespace(
+                    (String)in.readObject(), (String)in.readObject());
+                additionalNamespaces.add(additional);
+            }
+        }
+    }
+
+    /**
+     * Returns an iterator that walks over all descendants in document order.
+     *
+     * @return an iterator to walk descendants
+     */
+    public Iterator getDescendants() {
+        return new DescendantIterator(this);
+    }
+
+    /**
+     * This returns a <code>List</code> of all the child elements
+     * nested directly (one level deep) within this element, as
+     * <code>Element</code> objects.  If this target element has no nested
+     * elements, an empty List is returned.  The returned list is "live"
+     * in document order and changes to it affect the element's actual
+     * contents.
+     *
+     * <p>
+     * Sequential traversal through the List is best done with a Iterator
+     * since the underlying implement of List.size() may not be the most
+     * efficient.
+     * </p>
+     *
+     * <p>
+     * No recursion is performed, so elements nested two levels deep
+     * would have to be obtained with:
+     * <pre>
+     * <code>
+     *   Iterator itr = (currentElement.getChildren()).iterator();
+     *   while(itr.hasNext()) {
+     *     Element oneLevelDeep = (Element)itr.next();
+     *     List twoLevelsDeep = oneLevelDeep.getChildren();
+     *     // Do something with these children
+     *   }
+     * </code>
+     * </pre>
+     * </p>
+     *
+     * @return list of child <code>Element</code> objects for this element
+     */
+    public List getChildren() {
+        return content.getView(new ElementFilter());
+    }
+
+    /**
+     * This returns a <code>List</code> of all the child elements
+     * nested directly (one level deep) within this element with the given
+     * local name and belonging to the given Namespace, returned as
+     * <code>Element</code> objects.  If this target element has no nested
+     * elements with the given name in the given Namespace, an empty List
+     * is returned.  The returned list is "live" in document order
+     * and changes to it affect the element's actual contents.
+     * <p>
+     * Please see the notes for <code>{@link #getChildren}</code>
+     * for a code example.
+     * </p>
+     *
+     * @param name local name for the children to match
+     * @param ns <code>Namespace</code> to search within
+     * @return all matching child elements
+     */
+    public List getChildren(final String name, final Namespace ns) {
+        return content.getView(new ElementFilter(name, ns));
+    }
+
+    /**
+     * This returns the first child element within this element with the
+     * given local name and belonging to the given namespace.
+     * If no elements exist for the specified name and namespace, null is
+     * returned.
+     *
+     * @param name local name of child element to match
+     * @param ns <code>Namespace</code> to search within
+     * @return the first matching child element, or null if not found
+     */
+    public Element getChild(final String name, final Namespace ns) {
+        final List elements = content.getView(new ElementFilter(name, ns));
+        final Iterator iter = elements.iterator();
+        if (iter.hasNext()) {
+            return (Element) iter.next();
+        }
+        return null;
+    }
+
+    /**
+     * This returns the first child element within this element with the
+     * given local name and belonging to no namespace.
+     * If no elements exist for the specified name and namespace, null is
+     * returned.
+     *
+     * @param name local name of child element to match
+     * @return the first matching child element, or null if not found
+     */
+    public Element getChild(final String name) {
+        return getChild(name, Namespace.NO_NAMESPACE);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/EntityRef.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/EntityRef.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/EntityRef.java	(revision 28000)
@@ -0,0 +1,185 @@
+/*--
+
+ $Id: EntityRef.java,v 1.22 2007/11/10 05:28:59 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+/**
+ * An XML entity reference. Methods allow the user to manage its name, public
+ * id, and system id.
+ *
+ * @version $Revision: 1.22 $, $Date: 2007/11/10 05:28:59 $
+ * @author  Brett McLaughlin
+ * @author  Jason Hunter
+ * @author  Philip Nelson
+ */
+public class EntityRef extends Content {
+
+    /** The name of the <code>EntityRef</code> */
+    protected String name;
+
+
+    /**
+     * Default, no-args constructor for implementations to use if needed.
+     */
+    protected EntityRef() {}
+
+    /**
+     * This will create a new <code>EntityRef</code> with the supplied name.
+     *
+     * @param name <code>String</code> name of element.
+     * @throws IllegalNameException if the given name is not a legal
+     *         XML name.
+     */
+    public EntityRef(String name) {
+        this(name, null, null);
+    }
+
+    /**
+     * This will create a new <code>EntityRef</code>
+     * with the supplied name, public id, and system id.
+     *
+     * @param name <code>String</code> name of element.
+     * @param publicID public id of the entity reference being constructed
+     * @param systemID system id of the entity reference being constructed
+     * @throws IllegalDataException if the given system ID is not a legal
+     *         system literal or the the given public ID is not a
+     *         legal public ID
+     * @throws IllegalNameException if the given name is not a legal
+     *         XML name.
+     */
+    public EntityRef(String name, String publicID, String systemID) {
+        setName(name);
+        setPublicID(publicID);
+        setSystemID(systemID);
+    }
+
+    /**
+     * Returns the empty string since entity references don't have an XPath
+     * 1.0 string value.
+     * @return the empty string
+     */
+    public String getValue() {
+        return "";  // entity references don't have XPath string values
+    }
+
+    /**
+     * This will set the name of this <code>EntityRef</code>.
+     *
+     * @param name new name of the entity
+     * @return this <code>EntityRef</code> modified.
+     * @throws IllegalNameException if the given name is not a legal
+     *         XML name.
+     */
+    public EntityRef setName(String name) {
+        // This can contain a colon so we use checkXMLName()
+        // instead of checkElementName()
+        String reason = Verifier.checkXMLName(name);
+        if (reason != null) {
+            throw new IllegalNameException(name, "EntityRef", reason);
+        }
+        this.name = name;
+        return this;
+    }
+
+    /**
+     * This will set the public ID of this <code>EntityRef</code>.
+     *
+     * @param publicID new public id
+     * @return this <code>EntityRef</code> modified.
+     * @throws IllegalDataException if the given public ID is not a legal
+     *         public ID.
+     */
+    public EntityRef setPublicID(String publicID) {
+        String reason = Verifier.checkPublicID(publicID);
+        if (reason != null) {
+            throw new IllegalDataException(publicID, "EntityRef", reason);
+        }
+        return this;
+    }
+
+    /**
+     * This will set the system ID of this <code>EntityRef</code>.
+     *
+     * @param systemID new system id
+     * @throws IllegalDataException if the given system ID is not a legal
+     *         system literal.
+     * @return this <code>EntityRef</code> modified.
+     */
+    public EntityRef setSystemID(String systemID) {
+        String reason = Verifier.checkSystemLiteral(systemID);
+        if (reason != null) {
+            throw new IllegalDataException(systemID, "EntityRef", reason);
+        }
+        return this;
+    }
+
+    /**
+     * This returns a <code>String</code> representation of the
+     * <code>EntityRef</code>, suitable for debugging.
+     *
+     * @return <code>String</code> - information about the
+     *         <code>EntityRef</code>
+     */
+    public String toString() {
+        return new StringBuffer()
+            .append("[EntityRef: ")
+            .append("&")
+            .append(name)
+            .append(";")
+            .append("]")
+            .toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/IllegalAddException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/IllegalAddException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/IllegalAddException.java	(revision 28000)
@@ -0,0 +1,157 @@
+/*-- 
+
+ $Id: IllegalAddException.java,v 1.26 2007/11/10 05:28:59 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows 
+    these conditions in the documentation and/or other materials 
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+ 
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+ 
+ In addition, we request (but do not require) that you include in the 
+ end-user documentation provided with the redistribution and/or in the 
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos 
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many 
+ individuals on behalf of the JDOM Project and was originally 
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+ 
+ */
+
+package org.jdom;
+
+/**
+ * Thrown when trying to add a illegal object to a JDOM construct.
+ *
+ * @version $Revision: 1.26 $, $Date: 2007/11/10 05:28:59 $
+ * @author  Brett McLaughlin
+ * @author  Jason Hunter
+ */
+public class IllegalAddException extends IllegalArgumentException {
+
+    /**
+     * This will create an <code>Exception</code> indicating
+     * that the addition of the <code>{@link Attribute}</code>
+     * to the <code>{@link Element}</code> is illegal.
+     *
+     * @param base <code>Element</code> that <code>Attribute</code>
+     *        couldn't be added to
+     * @param added <code>Attribute</code> that could not be added
+     * @param reason cause of the problem
+     */
+    IllegalAddException(Element base, Attribute added, String reason) {
+        super(new StringBuffer()
+              .append("The attribute \"")
+              .append(added.getQualifiedName())
+              .append("\" could not be added to the element \"")
+              .append(base.getQualifiedName())
+              .append("\": ")
+              .append(reason)
+              .toString());
+    }
+
+    /**
+     * This will create an <code>Exception</code> indicating
+     * that the addition of the <code>{@link Element}</code>
+     * to the <code>{@link Document}</code> is illegal.
+     *
+     * @param added <code>Element</code> that could not be added
+     * @param reason cause of the problem
+     */
+    IllegalAddException(Element added, String reason) {
+        super(new StringBuffer()
+              .append("The element \"")
+              .append(added.getQualifiedName())
+              .append("\" could not be added as the root of the document: ")
+              .append(reason)
+              .toString());
+    }
+
+    /**
+     * This will create an <code>Exception</code> indicating
+     * that the addition of the <code>{@link Namespace}</code>
+     * to the <code>{@link Element}</code> is illegal.
+     *
+     * @param base <code>Element</code> that the <code>Namespace</code>
+     *             couldn't be added to
+     * @param added <code>Namespace</code> that could not be added
+     * @param reason cause of the problem
+     */
+    IllegalAddException(Element base, Namespace added, String reason) {
+        super(new StringBuffer()
+              .append("The namespace xmlns")
+              .append((added.getPrefix() == null ||
+                       added.getPrefix().equals("")) ? "=" 
+                                   : ":" + added.getPrefix() + "=")
+              .append("\"")
+              .append(added.getURI())
+              .append("\" could not be added as a namespace to \"")
+              .append(base.getQualifiedName())
+              .append("\": ")
+              .append(reason)
+              .toString());
+    }
+
+    /**
+     * This will create an <code>Exception</code> indicating
+     * that the addition of the <code>{@link DocType}</code>
+     * to the <code>{@link Document}</code> is illegal.
+     *
+     * @param added <code>DocType</code> that could not be added
+     * @param reason cause of the problem
+     */
+    IllegalAddException(DocType added, String reason) {
+        super(new StringBuffer()
+              .append("The DOCTYPE ")
+              .append(added.toString())
+              .append(" could not be added to the document: ")
+              .append(reason)
+              .toString());
+    }
+
+    /**
+     * This will create an <code>Exception</code> with the specified
+     * error message.
+     *
+     * @param reason cause of the problem
+     */
+    public IllegalAddException(String reason) {
+        super(reason);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/IllegalDataException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/IllegalDataException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/IllegalDataException.java	(revision 28000)
@@ -0,0 +1,106 @@
+/*-- 
+
+ $Id: IllegalDataException.java,v 1.14 2007/11/10 05:28:59 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows 
+    these conditions in the documentation and/or other materials 
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+ 
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+ 
+ In addition, we request (but do not require) that you include in the 
+ end-user documentation provided with the redistribution and/or in the 
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos 
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many 
+ individuals on behalf of the JDOM Project and was originally 
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+ 
+ */
+
+package org.jdom;
+
+/**
+ * Thrown when illegal text is supplied to a JDOM construct.
+ *
+ * @version $Revision: 1.14 $, $Date: 2007/11/10 05:28:59 $
+ * @author  Brett McLaughlin
+ * @author  Elliotte Rusty Harold
+ */
+public class IllegalDataException extends IllegalArgumentException {
+
+    /**
+     * This will create an <code>Exception</code> indicating
+     * that the specified data is illegal for the construct
+     * it was supplied to.
+     *
+     * @param data <code>String</code> data that breaks rules.
+     * @param construct <code>String</code> construct that data is illegal for.
+     * @param reason <code>String</code> message or reason data is illegal.
+     */
+    IllegalDataException(String data, String construct, String reason) {
+        super(new StringBuffer()
+              .append("The data \"")
+              .append(data)
+              .append("\" is not legal for a JDOM ")
+              .append(construct)
+              .append(": ")
+              .append(reason)
+              .append(".")
+              .toString());
+    }
+
+    /**
+     * This will create an <code>Exception</code> indicating
+     * that the specified data is illegal for the construct
+     * it was supplied to.
+     *
+     * @param data <code>String</code> data that breaks rules.
+     * @param construct <code>String</code> construct that data is illegal for.
+     */
+    IllegalDataException(String data, String construct) {
+        super(new StringBuffer()
+              .append("The data \"")
+              .append(data)
+              .append("\" is not legal for a JDOM ")
+              .append(construct)
+              .append(".")
+              .toString());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/IllegalNameException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/IllegalNameException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/IllegalNameException.java	(revision 28000)
@@ -0,0 +1,90 @@
+/*-- 
+
+ $Id: IllegalNameException.java,v 1.14 2007/11/10 05:28:59 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows 
+    these conditions in the documentation and/or other materials 
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+ 
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+ 
+ In addition, we request (but do not require) that you include in the 
+ end-user documentation provided with the redistribution and/or in the 
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos 
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many 
+ individuals on behalf of the JDOM Project and was originally 
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+ 
+ */
+
+package org.jdom;
+
+/**
+ * Thrown when a name is supplied in construction of a JDOM construct whose
+ * where the name breaks XML naming conventions.
+ * 
+ * @version $Revision: 1.14 $, $Date: 2007/11/10 05:28:59 $
+ * @author  Brett McLaughlin
+ * @author  Elliotte Rusty Harold
+ */
+public class IllegalNameException extends IllegalArgumentException {
+
+    /**
+     * This will create an <code>Exception</code> indicating
+     * that the specified name is illegal for the construct
+     * it was supplied to.
+     *
+     * @param name <code>String</code> name that breaks rules.
+     * @param construct <code>String</code> name of JDOM construct
+     *        that <code>name</code> was supplied to.
+     * @param reason <code>String</code> message or reason name is illegal.
+     */
+    IllegalNameException(String name, String construct, String reason) {
+        super(new StringBuffer()
+              .append("The name \"")
+              .append(name)
+              .append("\" is not legal for JDOM/XML ")
+              .append(construct)
+              .append("s: ")
+              .append(reason)
+              .append(".")
+              .toString());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/IllegalTargetException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/IllegalTargetException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/IllegalTargetException.java	(revision 28000)
@@ -0,0 +1,86 @@
+/*-- 
+
+ $Id: IllegalTargetException.java,v 1.15 2007/11/10 05:28:59 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows 
+    these conditions in the documentation and/or other materials 
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+ 
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+ 
+ In addition, we request (but do not require) that you include in the 
+ end-user documentation provided with the redistribution and/or in the 
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos 
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many 
+ individuals on behalf of the JDOM Project and was originally 
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+ 
+ */
+
+package org.jdom;
+
+/**
+ * Thrown when a target is supplied in construction of a JDOM {@link
+ * ProcessingInstruction}, and that name breaks XML naming conventions.
+ * 
+ * @version $Revision: 1.15 $, $Date: 2007/11/10 05:28:59 $
+ * @author  Brett McLaughlin
+ */
+public class IllegalTargetException extends IllegalArgumentException {
+
+	/**
+     * This will create an <code>Exception</code> indicating
+     * that the specified target is illegal for the
+     * <code>{@link ProcessingInstruction}</code> it was supplied to.
+     *
+     * @param target <code>String</code> target that breaks rules.
+     * @param reason <code>String</code> message or reason target is illegal.
+     */
+    IllegalTargetException(String target, String reason) {
+        super(new StringBuffer()
+              .append("The target \"")
+              .append(target)
+              .append("\" is not legal for JDOM/XML Processing Instructions: ")
+              .append(reason)
+              .append(".")
+              .toString());
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/JDOMException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/JDOMException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/JDOMException.java	(revision 28000)
@@ -0,0 +1,363 @@
+/*-- 
+
+ $Id: JDOMException.java,v 1.26 2008/12/10 00:59:51 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows 
+    these conditions in the documentation and/or other materials 
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+ 
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+ 
+ In addition, we request (but do not require) that you include in the 
+ end-user documentation provided with the redistribution and/or in the 
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos 
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many 
+ individuals on behalf of the JDOM Project and was originally 
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+ 
+ */
+
+package org.jdom;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.sql.*;
+
+import org.xml.sax.*;
+
+/**
+ * The top level exception that JDOM classes can throw. Its subclasses add
+ * specificity to the problems that can occur using JDOM. This single exception
+ * can be caught to handle all JDOM specific problems (some methods may throw
+ * {@link java.io.IOException} and such).
+ *
+ * @version $Revision: 1.26 $, $Date: 2008/12/10 00:59:51 $
+ * @author  Brett McLaughlin
+ * @author  Jason Hunter
+ */
+public class JDOMException extends Exception {
+
+    /** A wrapped <code>Throwable</code> */
+    private Throwable cause;
+
+    /**
+     * This will create an <code>Exception</code>.
+     */
+    public JDOMException() {
+        super("Error occurred in JDOM application.");
+    }
+
+    /**
+     * This will create an <code>Exception</code> with the given message.
+     *
+     * @param message <code>String</code> message indicating
+     *                the problem that occurred.
+     */    
+    public JDOMException(String message)  {
+        super(message);
+    }
+
+    /**
+     * This will create an <code>Exception</code> with the given message
+     * and wrap another <code>Exception</code>.  This is useful when
+     * the originating <code>Exception</code> should be held on to.
+     *
+     * @param message <code>String</code> message indicating
+     *                the problem that occurred.
+     * @param cause <code>Throwable</code> that caused this
+     *                  to be thrown.
+     */    
+    public JDOMException(String message, Throwable cause)  {
+        super(message);    
+        this.cause = cause;
+    }    
+
+    /** 
+     * Intializes the cause of this exception to be the specified value.
+     *
+     * @param cause <code>Throwable</code> that caused this
+     *                  to be thrown.
+     * @return a pointer to this throwable
+     */
+    // Created to match the JDK 1.4 Throwable method.
+    public Throwable initCause(Throwable cause)  {
+        this.cause = cause;
+        return this;
+    }    
+
+    /**
+     * This returns the message for the <code>Exception</code>. If
+     * there are one or more nested exceptions, their messages
+     * are appended.
+     *
+     * @return <code>String</code> - message for <code>Exception</code>.
+     */
+    public String getMessage() {
+        // Get this exception's message.
+        String msg = super.getMessage();
+
+        Throwable parent = this;
+        Throwable child;
+        
+        // Look for nested exceptions.
+        while((child = getNestedException(parent)) != null) {
+            // Get the child's message.
+            String msg2 = child.getMessage();
+            
+            // Special case: If a SAXException has no message of its own, but has a 
+            // nested exception, then it returns the nested exception's message as its
+            // message. We don't want to add that message twice.
+            if (child instanceof SAXException) {
+                Throwable grandchild = ((SAXException)child).getException();
+                // If the SAXException tells us that it's message is identical to 
+                // its nested exception's message, then we skip it, so we don't
+                // add it twice.
+                if (grandchild != null && msg2 != null && msg2.equals(grandchild.getMessage())) {
+                    msg2 = null;
+                }
+            }
+
+            // If we found a message for the child exception, we append it.
+            if (msg2 != null) {
+                if (msg != null) {
+                    msg += ": " + msg2;
+                } else {
+                    msg = msg2;
+                }
+            }
+
+            // Any nested JDOMException will append its own children,
+            // so we need to break out of here.
+            if (child instanceof JDOMException) {
+                break;
+            }
+            parent = child;
+        }
+
+        // Return the completed message.
+        return msg;
+    }
+
+    /**
+     * This prints the stack trace of the <code>Exception</code>. If
+     * there is a root cause, the stack trace of the root
+     * <code>Exception</code> is printed right after.
+     */
+    public void printStackTrace() {
+        // Print the stack trace for this exception.
+        super.printStackTrace();
+
+        Throwable parent = this;
+        Throwable child;
+
+        // Print the stack trace for each nested exception.
+        while((child = getNestedException(parent)) != null) {
+            System.err.print("Caused by: ");
+            child.printStackTrace();
+            // Any nested JDOMException will print its own children,
+            // so we need to break out of here.
+            if (child instanceof JDOMException) {
+                break;
+            }
+            parent = child;
+        }
+    }
+
+    /**
+     * Prints the stack trace of the <code>Exception</code> to the given
+     * PrintStream. If there is a root cause, the stack trace of the root
+     * <code>Exception</code> is printed right after.
+     *
+     * @param s PrintStream to print to
+     */
+    public void printStackTrace(PrintStream s) {
+        // Print the stack trace for this exception.
+        super.printStackTrace(s);
+
+        Throwable parent = this;
+        Throwable child;
+
+        // Print the stack trace for each nested exception.
+        while((child = getNestedException(parent)) != null) {
+            s.print("Caused by: ");
+            child.printStackTrace(s);
+            // Any nested JDOMException will print its own children,
+            // so we need to break out of here.
+            if (child instanceof JDOMException) {
+                break;
+            }
+            parent = child;
+        }
+    }
+
+    /**
+     * Prints the stack trace of the <code>Exception</code> to the given
+     * PrintWriter. If there is a root cause, the stack trace of the root
+     * <code>Exception</code> is printed right after.
+     *
+     * @param w PrintWriter to print to
+     */
+    public void printStackTrace(PrintWriter w) {
+        // Print the stack trace for this exception.
+        super.printStackTrace(w);
+
+        Throwable parent = this;
+        Throwable child;
+
+        // Print the stack trace for each nested exception.
+        while((child = getNestedException(parent)) != null) {
+            w.print("Caused by: ");
+            child.printStackTrace(w);
+            // Any nested JDOMException will print its own children,
+            // so we need to break out of here.
+            if (child instanceof JDOMException) {
+                break;
+            }
+            parent = child;
+        }
+    }
+
+    /**
+     * This will return the root cause <code>Throwable</code>, or null
+     * if one does not exist.
+     * 
+     * @return <code>Throwable</code> - the wrapped <code>Throwable</code>.
+     */
+    public Throwable getCause()  {
+        return cause;             
+    }
+
+    // If this Throwable has a nested (child) exception, then we return it.
+    // Otherwise we return null.
+    private static Throwable getNestedException(Throwable parent) {
+        if (parent instanceof JDOMException) {
+            return ((JDOMException)parent).getCause();
+        }
+        
+        if (parent instanceof SAXException) {
+            return ((SAXException)parent).getException();
+        }
+        
+        if (parent instanceof SQLException) {
+            return ((SQLException)parent).getNextException();
+        }
+        
+        if (parent instanceof InvocationTargetException) {
+            return ((InvocationTargetException)parent).getTargetException();
+        }
+        
+        if (parent instanceof ExceptionInInitializerError) {
+            return ((ExceptionInInitializerError)parent).getException();
+        }
+        
+        // The RMI classes are not present in Android's Dalvik VM, so we use reflection to access them.
+
+        Throwable nestedException = getNestedExceptionFromField(parent, "java.rmi.RemoteException", "detail");
+        if (nestedException != null) {
+            return nestedException;
+        }
+        
+        // These classes are not part of standard JDK 1.1 or 1.2, so again we use reflection to access them.
+
+        nestedException = getNestedException(parent, "javax.naming.NamingException", "getRootCause");
+        if (nestedException != null) {
+            return nestedException;
+        }
+        
+        nestedException = getNestedException(parent, "javax.servlet.ServletException", "getRootCause");
+        if (nestedException != null) {
+            return nestedException;
+        }
+
+        return null;
+    }
+
+    // This method uses reflection to obtain the nest exception of a Throwable. We use reflection
+    // because the desired class may not exist in the currently-running VM.
+    private static Throwable getNestedException(
+                                 Throwable parent, String className, String methodName) {
+        try {
+            // See if this Throwable is of the desired type, by using isAssignableFrom().
+            Class testClass = Class.forName(className);
+            Class objectClass = parent.getClass();
+            if (testClass.isAssignableFrom(objectClass)) {
+                // Use reflection to call the specified method.
+                Class[] argClasses = new Class[0];
+                Method method = testClass.getMethod(methodName, argClasses);
+                Object[] args = new Object[0];
+                return (Throwable)method.invoke(parent, args);
+            }
+        }
+        catch(Exception ex) {
+            // Most likely, the desired class is not available in this VM. That's fine.
+            // Even if it's caused by something else, we don't want to display an error
+            // here, since we're already in the process of trying to display the original
+            // error - another error here will just confuse things.
+        }
+
+        return null;
+    }
+
+    // This method is similar to getNestedException() except it looks for a field instead
+    // of a method.
+    private static Throwable getNestedExceptionFromField(
+                                 Throwable parent, String className, String fieldName) {
+        try {
+            // See if this Throwable is of the desired type, by using isAssignableFrom().
+            Class testClass = Class.forName(className);
+            Class objectClass = parent.getClass();
+            if (testClass.isAssignableFrom(objectClass)) {
+                // Use reflection to call the specified method.
+                Field field = testClass.getField(fieldName);
+                return (Throwable)field.get(parent);
+            }
+        }
+        catch(Exception ex) {
+            // Most likely, the desired class is not available in this VM. That's fine.
+            // Could be that the named field isn't of type Throwable, but that should happen
+            // with proper call usage.
+            // Even if it's caused by something else, we don't want to display an error
+            // here, since we're already in the process of trying to display the original
+            // error - another error here will just confuse things.
+        }
+
+        return null;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/JDOMFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/JDOMFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/JDOMFactory.java	(revision 28000)
@@ -0,0 +1,192 @@
+/*--
+
+ $Id: JDOMFactory.java,v 1.9 2007/11/10 05:28:59 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+
+/**
+ * An interface to be used by builders when constructing JDOM objects. The
+ * <code>DefaultJDOMFactory</code> creates the standard top-level JDOM classes
+ * (Element, Document, Comment, etc). Another implementation of this factory
+ * could be used to create custom classes.
+ *
+ * @version $Revision: 1.9 $, $Date: 2007/11/10 05:28:59 $
+ * @author  Ken Rune Holland
+ * @author  Phil Nelson
+ * @author  Bradley S. Huffman
+ */
+public interface JDOMFactory {
+
+    // **** constructing Attributes ****
+
+    /**
+     * This will create a new <code>Attribute</code> with the
+     * specified (local) name, value, and type, and in the provided
+     * <code>{@link org.jdom.Namespace}</code>.
+     *
+     * @param name <code>String</code> name of <code>Attribute</code>.
+     * @param value <code>String</code> value for new attribute.
+     * @param type <code>int</code> type for new attribute.
+     * @param namespace <code>Namespace</code> namespace for new attribute.
+     */
+    public Attribute attribute(String name, String value,
+                                            int type, Namespace namespace);
+
+    // **** constructing CDATA ****
+
+    /**
+     * This creates the CDATA with the supplied text.
+     *
+     * @param str <code>String</code> content of CDATA.
+     */
+    public CDATA cdata(String str);
+
+    // **** constructing Text ****
+
+    /**
+     * This creates the Text with the supplied text.
+     *
+     * @param str <code>String</code> content of Text.
+     */
+    public Text text(String str);
+
+    // **** constructing Comment ****
+
+    /**
+     * This creates the comment with the supplied text.
+     *
+     * @param text <code>String</code> content of comment.
+     */
+    public Comment comment(String text);
+
+    // **** constructing DocType
+
+    /**
+     * This will create the <code>DocType</code> with
+     * the specified element name and a reference to an
+     * external DTD.
+     *
+     * @param elementName <code>String</code> name of
+     *        element being constrained.
+     * @param publicID <code>String</code> public ID of
+     *        referenced DTD
+     * @param systemID <code>String</code> system ID of
+     *        referenced DTD
+     */
+    public DocType docType(String elementName,
+                           String publicID, String systemID);
+
+    /**
+     * This will create a new <code>Document</code>,
+     * with the supplied <code>{@link org.jdom.Element}</code>
+     * as the root element, and no <code>{@link org.jdom.DocType}</code>
+     * declaration.
+     *
+     * @param rootElement <code>Element</code> for document root
+     */
+    public Document document(Element rootElement);
+
+    // **** constructing Elements ****
+
+    /**
+     * This will create a new <code>Element</code>
+     * with the supplied (local) name, and define
+     * the <code>{@link org.jdom.Namespace}</code> to be used.
+     *
+     * @param name <code>String</code> name of element.
+     * @param namespace <code>Namespace</code> to put element in.
+         */
+    public Element element(String name, Namespace namespace);
+
+    /**
+     * This will create a new <code>ProcessingInstruction</code>
+     * with the specified target and data.
+     *
+     * @param target <code>String</code> target of PI.
+     * @param data <code>String</code> data for PI.
+     */
+    public ProcessingInstruction processingInstruction(String target,
+                                                       String data);
+
+    // **** constructing EntityRef ****
+
+    /**
+     * This will create a new <code>EntityRef</code>
+     * with the supplied name.
+     *
+     * @param name <code>String</code> name of element.
+     */
+    public EntityRef entityRef(String name);
+
+    /**
+     * This will create a new <code>EntityRef</code>
+     * with the supplied name, public ID, and system ID.
+     *
+     * @param name <code>String</code> name of element.
+     * @param publicID <code>String</code> public ID of element.
+     * @param systemID <code>String</code> system ID of element.
+     */
+    public EntityRef entityRef(String name, String publicID, String systemID);
+
+    // =====================================================================
+    // List manipulation
+    // =====================================================================
+
+    public void addContent(Parent parent, Content content);
+
+    public void setAttribute(Element element, Attribute a);
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/Namespace.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/Namespace.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/Namespace.java	(revision 28000)
@@ -0,0 +1,261 @@
+/*-- 
+
+ $Id: Namespace.java,v 1.44 2008/12/17 23:22:48 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows 
+    these conditions in the documentation and/or other materials 
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+ 
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+ 
+ In addition, we request (but do not require) that you include in the 
+ end-user documentation provided with the redistribution and/or in the 
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos 
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many 
+ individuals on behalf of the JDOM Project and was originally 
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+ 
+ */
+
+package org.jdom;
+
+import java.util.*;
+
+/**
+ * An XML namespace representation, as well as a factory for creating XML
+ * namespace objects. Namespaces are not Serializable, however objects that use
+ * namespaces have special logic to handle serialization manually. These classes
+ * call the getNamespace() method on deserialization to ensure there is one
+ * unique Namespace object for any unique prefix/uri pair.
+ *
+ * @version $Revision: 1.44 $, $Date: 2008/12/17 23:22:48 $
+ * @author  Brett McLaughlin
+ * @author  Elliotte Rusty Harold
+ * @author  Jason Hunter
+ * @author  Wesley Biggs
+ */
+public final class Namespace {
+
+    // XXX May want to use weak references to keep the maps from growing 
+    // large with extended use
+
+    /** 
+     * Factory list of namespaces. 
+     * Keys are <i>prefix</i>&amp;<i>URI</i>. 
+     * Values are Namespace objects 
+     */
+    private static HashMap namespaces;
+
+    /** Define a <code>Namespace</code> for when <i>not</i> in a namespace */
+    public static final Namespace NO_NAMESPACE = new Namespace("", "");
+
+    /** Define a <code>Namespace</code> for the standard xml prefix. */
+    public static final Namespace XML_NAMESPACE =
+        new Namespace("xml", "http://www.w3.org/XML/1998/namespace");
+
+    /** The prefix mapped to this namespace */
+    private String prefix;
+
+    /** The URI for this namespace */
+    private String uri;
+
+    /**
+     * This static initializer acts as a factory contructor.
+     * It sets up storage and required initial values.
+     */
+    static {
+        namespaces = new HashMap(16);
+
+        // Add the "empty" namespace
+        namespaces.put(new NamespaceKey(NO_NAMESPACE), NO_NAMESPACE);
+        namespaces.put(new NamespaceKey(XML_NAMESPACE), XML_NAMESPACE);
+    }
+
+    /**
+     * This will retrieve (if in existence) or create (if not) a 
+     * <code>Namespace</code> for the supplied prefix and URI.
+     *
+     * @param prefix <code>String</code> prefix to map to 
+     *               <code>Namespace</code>.
+     * @param uri <code>String</code> URI of new <code>Namespace</code>.
+     * @return <code>Namespace</code> - ready to use namespace.
+     * @throws IllegalNameException if the given prefix and uri make up
+     *         an illegal namespace name.
+     */
+    public static Namespace getNamespace(String prefix, String uri) {
+        // Sanity checking
+        if ((prefix == null) || (prefix.trim().equals(""))) {
+            // Short-cut out for common case of no namespace
+            if ((uri == null) || (uri.trim().equals(""))) {
+                return NO_NAMESPACE;
+            }
+            prefix = "";
+        }
+        else if ((uri == null) || (uri.trim().equals(""))) {
+            uri = "";
+        }
+
+        // Return existing namespace if found. The preexisting namespaces
+        // should all be legal. In other words, an illegal namespace won't
+        // have been placed in this.  Thus we can do this test before
+        // verifying the URI and prefix.
+        NamespaceKey lookup = new NamespaceKey(prefix, uri);
+        Namespace preexisting;
+        synchronized (namespaces) {
+            preexisting = (Namespace) namespaces.get(lookup);
+        }
+        if (preexisting != null) {
+            return preexisting;
+        }
+
+        // Ensure proper naming
+        String reason;
+        if ((reason = Verifier.checkNamespacePrefix(prefix)) != null) {
+            throw new IllegalNameException(prefix, "Namespace prefix", reason);
+        }
+        if ((reason = Verifier.checkNamespaceURI(uri)) != null) {
+            throw new IllegalNameException(uri, "Namespace URI", reason);
+        }
+
+        // Unless the "empty" Namespace (no prefix and no URI), require a URI
+        if ((!prefix.equals("")) && (uri.equals(""))) {
+            throw new IllegalNameException("", "namespace",
+                "Namespace URIs must be non-null and non-empty Strings");
+        }
+
+        // Handle XML namespace mislabels. If the user requested the correct
+        // namespace and prefix -- xml, http://www.w3.org/XML/1998/namespace
+        // -- then it was already returned from the preexisting namespaces.
+        // Thus any use of the xml prefix or the
+        // http://www.w3.org/XML/1998/namespace URI at this point must be
+        // incorrect. 
+        if (prefix.equals("xml")) {
+            throw new IllegalNameException(prefix, "Namespace prefix",
+             "The xml prefix can only be bound to " +
+             "http://www.w3.org/XML/1998/namespace");        
+        }
+
+        // The erratum to Namespaces in XML 1.0 that suggests this 
+        // next check is controversial. Not everyone accepts it. 
+        if (uri.equals("http://www.w3.org/XML/1998/namespace")) {
+            throw new IllegalNameException(uri, "Namespace URI",
+             "The http://www.w3.org/XML/1998/namespace must be bound to " +
+             "the xml prefix.");        
+        }
+
+        // Finally, store and return
+        Namespace ns = new Namespace(prefix, uri);
+        synchronized (namespaces) {
+            namespaces.put(lookup, ns);
+        }
+        return ns;
+    }
+
+    /**
+     * This constructor handles creation of a <code>Namespace</code> object
+     * with a prefix and URI; it is intentionally left <code>private</code>
+     * so that it cannot be invoked by external programs/code.
+     *
+     * @param prefix <code>String</code> prefix to map to this namespace.
+     * @param uri <code>String</code> URI for namespace.
+     */
+    private Namespace(String prefix, String uri) {
+        this.prefix = prefix;
+        this.uri = uri;
+    }
+
+    /**
+     * This returns the prefix mapped to this <code>Namespace</code>.
+     *
+     * @return <code>String</code> - prefix for this <code>Namespace</code>.
+     */
+    public String getPrefix() {
+        return prefix;
+    }
+
+    /**
+     * This returns the namespace URI for this <code>Namespace</code>.
+     *
+     * @return <code>String</code> - URI for this <code>Namespace</code>.
+     */
+    public String getURI() {
+        return uri;
+    }
+
+    /**
+     * This tests for equality - Two <code>Namespaces</code>
+     * are equal if and only if their URIs are byte-for-byte equals.
+     *
+     * @param ob <code>Object</code> to compare to this <code>Namespace</code>.
+     * @return <code>boolean</code> - whether the supplied object is equal to
+     *         this <code>Namespace</code>.
+     */
+    public boolean equals(Object ob) {
+        if (this == ob) {
+            return true;
+        }
+        if (ob instanceof Namespace) {  // instanceof returns false if null
+            return uri.equals(((Namespace)ob).uri);
+        }
+        return false;
+    }
+
+    /**
+     * This returns a <code>String</code> representation of this 
+     * <code>Namespace</code>, suitable for use in debugging.
+     *
+     * @return <code>String</code> - information about this instance.
+     */
+    public String toString() {
+        return "[Namespace: prefix \"" + prefix + "\" is mapped to URI \"" + 
+               uri + "\"]";
+    }
+
+    /**
+     * This returns a probably unique hash code for the <code>Namespace</code>.
+     * If two namespaces have the same URI, they are equal and have the same
+     * hash code, even if they have different prefixes.
+     *
+     * @return <code>int</code> - hash code for this <code>Namespace</code>.
+     */
+    public int hashCode() {
+        return uri.hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/NamespaceKey.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/NamespaceKey.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/NamespaceKey.java	(revision 28000)
@@ -0,0 +1,104 @@
+/*-- 
+
+ $Id: NamespaceKey.java,v 1.2 2007/11/10 05:28:59 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows 
+    these conditions in the documentation and/or other materials 
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+ 
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+ 
+ In addition, we request (but do not require) that you include in the 
+ end-user documentation provided with the redistribution and/or in the 
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos 
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many 
+ individuals on behalf of the JDOM Project and was originally 
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+ 
+ */
+
+package org.jdom;
+
+
+/**
+ * Key for storing a namespace representation in a map.
+ *
+ * @version $Revision: 1.2 $, $Date: 2007/11/10 05:28:59 $
+ * @author  Tatu Saloranta
+ * @author  Bradley S. Huffman
+ */
+final class NamespaceKey {
+
+    private String prefix;
+    private String uri;
+    private int hash;
+
+    public NamespaceKey(String prefix, String uri) {
+        this.prefix = prefix;
+        this.uri = uri;
+        this.hash = prefix.hashCode();
+    }
+
+    public NamespaceKey(Namespace namespace) {
+        this(namespace.getPrefix(), namespace.getURI());
+    }
+
+    public boolean equals(Object ob) {
+        if (this == ob) {
+            return true;
+        }
+        else if (ob instanceof NamespaceKey) {
+            NamespaceKey other = (NamespaceKey) ob;
+            return prefix.equals(other.prefix) && uri.equals(other.uri);
+        }
+        else {
+            return false;
+        }
+    }
+
+    public int hashCode() {
+        return hash;
+    }
+    
+    public String toString() {
+        return "[NamespaceKey: prefix \"" + prefix +
+               "\" is mapped to URI \"" + uri + "\"]";
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/Parent.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/Parent.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/Parent.java	(revision 28000)
@@ -0,0 +1,135 @@
+/*--
+
+ $Id: Parent.java,v 1.13 2007/11/10 05:28:59 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Superclass for JDOM objects which are allowed to contain
+ * {@link Content} content.
+ *
+ * @see org.jdom.Content
+ * @see org.jdom.Document
+ * @see org.jdom.Element
+ *
+ * @author Bradley S. Huffman
+ * @author Jason Hunter
+ * @version $Revision: 1.13 $, $Date: 2007/11/10 05:28:59 $
+ */
+public interface Parent extends Cloneable, Serializable {
+
+    /**
+     * Returns the full content of this parent as a {@link java.util.List}
+     * which contains objects of type {@link Content}. The returned list is
+     * <b>"live"</b> and in document order. Any modifications
+     * to it affect the element's actual contents. Modifications are checked
+     * for conformance to XML 1.0 rules.
+     * <p>
+     * Sequential traversal through the List is best done with an Iterator
+     * since the underlying implement of {@link java.util.List#size} may
+     * require walking the entire list and indexed lookups may require
+     * starting at the beginning each time.
+     *
+     * @return a list of the content of the parent
+     * @throws IllegalStateException if parent is a Document
+     *         and the root element is not set
+     */
+    List getContent();
+
+    /**
+     * Removes a single child node from the content list.
+     *
+     * @param  child  child to remove
+     * @return whether the removal occurred
+     */
+    boolean removeContent(Content child);
+
+    /**
+     * Obtain a deep, unattached copy of this parent and it's children.
+     *
+     * @return a deep copy of this parent and it's children.
+     */
+    Object clone();
+
+    /**
+     * Returns an {@link java.util.Iterator} that walks over all descendants
+     * in document order.
+     *
+     * @return an iterator to walk descendants
+     */
+    Iterator getDescendants();
+
+    /**
+     * Return this parent's parent, or null if this parent is currently
+     * not attached to another parent. This is the same method as in Content but
+     * also added to Parent to allow more easy up-the-tree walking.
+     *
+     * @return this parent's parent or null if none
+     */
+    Parent getParent();
+
+    /**
+     * Return this parent's owning document or null if the branch containing
+     * this parent is currently not attached to a document.
+     *
+     * @return this child's owning document or null if none
+     */
+    Document getDocument();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/ProcessingInstruction.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/ProcessingInstruction.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/ProcessingInstruction.java	(revision 28000)
@@ -0,0 +1,294 @@
+/*--
+
+ $Id: ProcessingInstruction.java,v 1.47 2007/11/10 05:28:59 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * An XML processing instruction. Methods allow the user to obtain the target of
+ * the PI as well as its data. The data can always be accessed as a String or,
+ * if the data appears akin to an attribute list, can be retrieved as name/value
+ * pairs.
+ *
+ * @version $Revision: 1.47 $, $Date: 2007/11/10 05:28:59 $
+ * @author  Brett McLaughlin
+ * @author  Jason Hunter
+ * @author  Steven Gould
+ */
+
+public class ProcessingInstruction extends Content {
+
+    /** The data for the PI as a String */
+    protected String rawData;
+
+    /** The data for the PI in name/value pairs */
+    protected Map mapData;
+
+    /**
+     * Default, no-args constructor for implementations
+     * to use if needed.
+     */
+    protected ProcessingInstruction() { }
+
+    /**
+     * This will create a new <code>ProcessingInstruction</code>
+     * with the specified target and data.
+     *
+     * @param target <code>String</code> target of PI.
+     * @param data <code>String</code> data for PI.
+     * @throws IllegalTargetException if the given target is illegal
+     *         as a processing instruction name.
+     */
+    public ProcessingInstruction(String target, String data) {
+        setTarget(target);
+        setData(data);
+    }
+
+    /**
+     * This will set the target for the PI.
+     *
+     * @param newTarget <code>String</code> new target of PI.
+     * @return <code>ProcessingInstruction</code> - this PI modified.
+     */
+    public ProcessingInstruction setTarget(String newTarget) {
+        String reason;
+        if ((reason = Verifier.checkProcessingInstructionTarget(newTarget))
+                                    != null) {
+            throw new IllegalTargetException(newTarget, reason);
+        }
+
+        return this;
+    }
+
+    /**
+     * Returns the XPath 1.0 string value of this element, which is the
+     * data of this PI.
+     *
+     * @return the data of this PI
+     */
+    public String getValue() {
+        return rawData;
+    }
+
+
+    /**
+     * This will set the raw data for the PI.
+     *
+     * @param data <code>String</code> data of PI.
+     * @return <code>ProcessingInstruction</code> - this PI modified.
+     */
+    public ProcessingInstruction setData(String data) {
+        String reason = Verifier.checkProcessingInstructionData(data);
+        if (reason != null) {
+            throw new IllegalDataException(data, reason);
+        }
+
+        this.rawData = data;
+        this.mapData = parseData(data);
+        return this;
+    }
+
+    /**
+     * This will parse and load the instructions for the PI.
+     * This is separated to allow it to occur once and then be reused.
+     */
+    private Map parseData(String rawData) {
+        // The parsing here is done largely "by hand" which means the code
+        // gets a little tricky/messy.  The following conditions should
+        // now be handled correctly:
+        //   <?pi href="http://hi/a=b"?>        Reads OK
+        //   <?pi href = 'http://hi/a=b' ?>     Reads OK
+        //   <?pi href\t = \t'http://hi/a=b'?>  Reads OK
+        //   <?pi href  =  "http://hi/a=b"?>    Reads OK
+        //   <?pi?>                             Empty Map
+        //   <?pi id=22?>                       Empty Map
+        //   <?pi id='22?>                      Empty Map
+
+        Map data = new HashMap();
+
+        // System.out.println("rawData: " + rawData);
+
+        // The inputData variable holds the part of rawData left to parse
+        String inputData = rawData.trim();
+
+        // Iterate through the remaining inputData string
+        while (!inputData.trim().equals("")) {
+            //System.out.println("parseData() looking at: " + inputData);
+
+            // Search for "name =", "name=" or "name1 name2..."
+            String name = "";
+            String value = "";
+            int startName = 0;
+            char previousChar = inputData.charAt(startName);
+            int pos = 1;
+            for (; pos<inputData.length(); pos++) {
+                char currentChar = inputData.charAt(pos);
+                if (currentChar == '=') {
+                    name = inputData.substring(startName, pos).trim();
+                    // Get the boundaries on the quoted string
+                    // We use boundaries so we know where to start next
+                    int[] bounds = extractQuotedString(
+                                     inputData.substring(pos+1));
+                    // A null value means a parse error and we return empty!
+                    if (bounds == null) {
+                        return new HashMap();
+                    }
+                    value = inputData.substring(bounds[0]+pos+1,
+                                                bounds[1]+pos+1);
+                    pos += bounds[1] + 1;  // skip past value
+                    break;
+                }
+                else if (Character.isWhitespace(previousChar)
+                          && !Character.isWhitespace(currentChar)) {
+                    startName = pos;
+                }
+
+                previousChar = currentChar;
+            }
+
+            // Remove the first pos characters; they have been processed
+            inputData = inputData.substring(pos);
+
+            // System.out.println("Extracted (name, value) pair: ("
+            //                          + name + ", '" + value+"')");
+
+            // If both a name and a value have been found, then add
+            // them to the data Map
+            if (name.length() > 0 && value != null) {
+                //if (data.containsKey(name)) {
+                    // A repeat, that's a parse error, so return a null map
+                    //return new HashMap();
+                //}
+                //else {
+                    data.put(name, value);
+                //}
+            }
+        }
+
+        return data;
+    }
+
+    /**
+     * This is a helper routine, only used by parseData, to extract a
+     * quoted String from the input parameter, rawData. A quoted string
+     * can use either single or double quotes, but they must match up.
+     * A singly quoted string can contain an unbalanced amount of double
+     * quotes, or vice versa. For example, the String "JDOM's the best"
+     * is legal as is 'JDOM"s the best'.
+     *
+     * @param rawData the input string from which a quoted string is to
+     *                be extracted.
+     * @return the first quoted string encountered in the input data. If
+     *         no quoted string is found, then the empty string, "", is
+     *         returned.
+     * @see #parseData
+     */
+    private static int[] extractQuotedString(String rawData) {
+        // Remembers whether we're actually in a quoted string yet
+        boolean inQuotes = false;
+
+        // Remembers which type of quoted string we're in
+        char quoteChar = '"';
+
+        // Stores the position of the first character inside
+        //  the quoted string (i.e. the start of the return string)
+        int start = 0;
+
+        // Iterate through the input string looking for the start
+        // and end of the quoted string
+        for (int pos=0; pos < rawData.length(); pos++) {
+            char currentChar = rawData.charAt(pos);
+            if (currentChar=='"' || currentChar=='\'') {
+                if (!inQuotes) {
+                    // We're entering a quoted string
+                    quoteChar = currentChar;
+                    inQuotes = true;
+                    start = pos+1;
+                }
+                else if (quoteChar == currentChar) {
+                    // We're leaving a quoted string
+                    inQuotes = false;
+                    return new int[] { start, pos };
+                }
+                // Otherwise we've encountered a quote
+                // inside a quote, so just continue
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * This will return a clone of this <code>ProcessingInstruction</code>.
+     *
+     * @return <code>Object</code> - clone of this
+     * <code>ProcessingInstruction</code>.
+     */
+    public Object clone() {
+        ProcessingInstruction pi = (ProcessingInstruction) super.clone();
+
+        // target and rawdata are immutable and references copied by
+        // Object.clone()
+
+        // Create a new Map object for the clone (since Map isn't Cloneable)
+        if (mapData != null) {
+            pi.mapData = parseData(rawData);
+        }
+        return pi;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/Text.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/Text.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/Text.java	(revision 28000)
@@ -0,0 +1,210 @@
+/*--
+
+ $Id: Text.java,v 1.25 2007/11/10 05:28:59 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom;
+
+/**
+ * Character-based XML content. Provides a modular, parentable method of
+ * representing text. Text makes no guarantees about the underlying textual
+ * representation of character data, but does expose that data as a Java String.
+ *
+ * @version $Revision: 1.25 $, $Date: 2007/11/10 05:28:59 $
+ * @author  Brett McLaughlin
+ * @author  Jason Hunter
+ * @author  Bradley S. Huffman
+ */
+public class Text extends Content {
+
+    static final String EMPTY_STRING = "";
+
+    /** The actual character content */
+    // XXX See http://www.servlets.com/archive/servlet/ReadMsg?msgId=8612
+    // from elharo for a description of why Java characters may not suffice
+    // long term
+    protected String value;
+
+    /**
+     * This is the protected, no-args constructor standard in all JDOM
+     * classes. It allows subclassers to get a raw instance with no
+     * initialization.
+     */
+    protected Text() { }
+
+    /**
+     * This constructor creates a new <code>Text</code> node, with the
+     * supplied string value as it's character content.
+     *
+     * @param str the node's character content.
+     * @throws IllegalDataException if <code>str</code> contains an
+     *         illegal character such as a vertical tab (as determined
+     *         by {@link org.jdom.Verifier#checkCharacterData})
+     */
+    public Text(String str) {
+        setText(str);
+    }
+
+    /**
+     * This returns the value of this <code>Text</code> node as a Java
+     * <code>String</code>.
+     *
+     * @return <code>String</code> - character content of this node.
+     */
+    public String getText() {
+        return value;
+    }
+
+    /**
+     * This will set the value of this <code>Text</code> node.
+     *
+     * @param str value for node's content.
+     * @return the object on which the method was invoked
+     * @throws IllegalDataException if <code>str</code> contains an
+     *         illegal character such as a vertical tab (as determined
+     *         by {@link org.jdom.Verifier#checkCharacterData})
+     */
+    public Text setText(String str) {
+        String reason;
+
+        if (str == null) {
+            value = EMPTY_STRING;
+            return this;
+        }
+
+        if ((reason = Verifier.checkCharacterData(str)) != null) {
+            throw new IllegalDataException(str, "character content", reason);
+        }
+        value = str;
+        return this;
+    }
+
+    /**
+     * This will append character content to whatever content already
+     * exists within this <code>Text</code> node.
+     *
+     * @param str character content to append.
+     * @throws IllegalDataException if <code>str</code> contains an
+     *         illegal character such as a vertical tab (as determined
+     *         by {@link org.jdom.Verifier#checkCharacterData})
+     */
+    public void append(String str) {
+        String reason;
+
+        if (str == null) {
+            return;
+        }
+        if ((reason = Verifier.checkCharacterData(str)) != null) {
+            throw new IllegalDataException(str, "character content", reason);
+        }
+
+        if (str.length() > 0) {
+             value += str;
+        }
+    }
+
+    /**
+     * This will append the content of another <code>Text</code> node
+     * to this node.
+     *
+     * @param text Text node to append.
+     */
+    public void append(Text text) {
+        if (text == null) {
+            return;
+        }
+        value += text.getText();
+    }
+
+    /**
+     * Returns the XPath 1.0 string value of this element, which is the
+     * text itself.
+     *
+     * @return the text
+     */
+    public String getValue() {
+        return value;
+    }
+
+    /**
+     * This returns a <code>String</code> representation of the
+     * <code>Text</code> node, suitable for debugging. If the XML
+     * representation of the <code>Text</code> node is desired,
+     * either <code>{@link #getText}</code> or
+     * {@link org.jdom.output.XMLOutputter#outputString(Text)}</code>
+     * should be used.
+     *
+     * @return <code>String</code> - information about this node.
+     */
+    public String toString() {
+        return new StringBuffer(64)
+            .append("[Text: ")
+            .append(getText())
+            .append("]")
+            .toString();
+    }
+
+    /**
+     * This will return a clone of this <code>Text</code> node, with the
+     * same character content, but no parent.
+     *
+     * @return <code>Text</code> - cloned node.
+     */
+    public Object clone() {
+        Text text = (Text)super.clone();
+        text.value = value;
+        return text;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/Verifier.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/Verifier.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/Verifier.java	(revision 28000)
@@ -0,0 +1,1147 @@
+/*-- 
+
+ $Id: Verifier.java,v 1.57 2009/07/23 05:54:23 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows 
+    these conditions in the documentation and/or other materials 
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+ 
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+ 
+ In addition, we request (but do not require) that you include in the 
+ end-user documentation provided with the redistribution and/or in the 
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos 
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many 
+ individuals on behalf of the JDOM Project and was originally 
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+ 
+ */
+
+package org.jdom;
+
+import java.util.*;
+
+/**
+ * A utility class to handle well-formedness checks on names, data, and other
+ * verification tasks for JDOM. The class is final and may not be subclassed.
+ *
+ * @version $Revision: 1.57 $, $Date: 2009/07/23 05:54:23 $
+ * @author  Brett McLaughlin
+ * @author  Elliotte Rusty Harold
+ * @author  Jason Hunter
+ * @author  Bradley S. Huffman
+ */
+final public class Verifier {
+
+    /**
+     * Ensure instantation cannot occur.
+     */
+    private Verifier() { }
+
+    /**
+     * This will check the supplied name to see if it is legal for use as
+     * a JDOM <code>{@link Element}</code> name.
+     *
+     * @param name <code>String</code> name to check.
+     * @return <code>String</code> reason name is illegal, or
+     *         <code>null</code> if name is OK.
+     */
+    public static String checkElementName(String name) {
+        // Check basic XML name rules first
+        String reason;
+        if ((reason = checkXMLName(name)) != null) {
+            return reason;
+        }
+
+        // No colons allowed, since elements handle this internally
+        if (name.indexOf(":") != -1) {
+            return "Element names cannot contain colons";
+        }
+
+        // If we got here, everything is OK
+        return null;
+    }
+
+    /**
+     * This will check the supplied name to see if it is legal for use as
+     * a JDOM <code>{@link Attribute}</code> name.
+     *
+     * @param name <code>String</code> name to check.
+     * @return <code>String</code> reason name is illegal, or
+     *         <code>null</code> if name is OK.
+     */
+    public static String checkAttributeName(String name) {
+        // Check basic XML name rules first
+        String reason;
+        if ((reason = checkXMLName(name)) != null) {
+            return reason;
+        }
+
+        // No colons are allowed, since attributes handle this internally
+        if (name.indexOf(":") != -1) {
+            return "Attribute names cannot contain colons";
+        }
+
+        // Attribute names may not be xmlns since we do this internally too
+        if (name.equals("xmlns")) {
+            return "An Attribute name may not be \"xmlns\"; " +
+                   "use the Namespace class to manage namespaces";
+        }
+
+        // If we got here, everything is OK
+        return null;
+    }
+    
+    /**
+     * This will check the supplied string to see if it only contains
+     * characters allowed by the XML 1.0 specification. The C0 controls
+     * (e.g. null, vertical tab, formfeed, etc.) are specifically excluded
+     * except for carriage return, linefeed, and the horizontal tab.
+     * Surrogates are also excluded. 
+     * <p>
+     * This method is useful for checking element content and attribute
+     * values. Note that characters 
+     * like " and &lt; are allowed in attribute values and element content. 
+     * They will simply be escaped as &quot; or &lt; 
+     * when the value is serialized. 
+     * </p>
+     *
+     * @param text <code>String</code> value to check.
+     * @return <code>String</code> reason name is illegal, or
+     *         <code>null</code> if name is OK.
+     */
+    public static String checkCharacterData(String text) {
+        if (text == null) {
+            return "A null is not a legal XML value";
+        }
+
+        // Do check
+        for (int i = 0, len = text.length(); i<len; i++) {
+
+            int ch = text.charAt(i);
+            
+            // Check if high part of a surrogate pair
+            if (isHighSurrogate((char) ch)) {
+                // Check if next char is the low-surrogate
+                i++;
+                if (i < len) {
+                    char low = text.charAt(i);
+                    if (!isLowSurrogate(low)) {
+                        return "Illegal Surrogate Pair";
+                    }
+                    // It's a good pair, calculate the true value of
+                    // the character to then fall thru to isXMLCharacter
+                    ch = decodeSurrogatePair((char) ch, low);
+                }
+                else {
+                    return "Surrogate Pair Truncated";
+                }
+            }
+
+            if (!isXMLCharacter(ch)) {
+                // Likely this character can't be easily displayed
+                // because it's a control so we use it'd hexadecimal 
+                // representation in the reason.
+                return ("0x" + Integer.toHexString(ch) +
+                        " is not a legal XML character");
+            }
+        }
+
+        // If we got here, everything is OK
+        return null;
+    }
+
+    /**
+     * This will check the supplied data to see if it is legal for use as
+     * JDOM <code>{@link CDATA}</code>.
+     *
+     * @param data <code>String</code> data to check.
+     * @return <code>String</code> reason data is illegal, or
+     *         <code>null</code> is name is OK.
+     */
+    public static String checkCDATASection(String data) {
+        String reason = null;
+        if ((reason = checkCharacterData(data)) != null) {
+            return reason;
+        }
+
+        if (data.indexOf("]]>") != -1) {
+            return "CDATA cannot internally contain a CDATA ending " +
+                   "delimiter (]]>)";
+        }
+
+        // If we got here, everything is OK
+        return null;
+    }
+
+    /**
+     * This will check the supplied name to see if it is legal for use as
+     * a JDOM <code>{@link Namespace}</code> prefix.
+     *
+     * @param prefix <code>String</code> prefix to check.
+     * @return <code>String</code> reason name is illegal, or
+     *         <code>null</code> if name is OK.
+     */
+    public static String checkNamespacePrefix(String prefix) {
+        // Manually do rules, since URIs can be null or empty
+        if ((prefix == null) || (prefix.equals(""))) {
+            return null;
+        }
+
+        // Cannot start with a number
+        char first = prefix.charAt(0);
+        if (isXMLDigit(first)) {
+            return "Namespace prefixes cannot begin with a number";
+        }
+        // Cannot start with a $
+        if (first == '$') {
+            return "Namespace prefixes cannot begin with a dollar sign ($)";
+        }
+        // Cannot start with a -
+        if (first == '-') {
+            return "Namespace prefixes cannot begin with a hyphen (-)";
+        }
+        // Cannot start with a .
+        if (first == '.') {
+            return "Namespace prefixes cannot begin with a period (.)";
+        }
+        // Cannot start with "xml" in any character case
+        if (prefix.toLowerCase().startsWith("xml")) {
+            return "Namespace prefixes cannot begin with " +
+                   "\"xml\" in any combination of case";
+        }
+
+        // Ensure legal content
+        for (int i=0, len = prefix.length(); i<len; i++) {
+            char c = prefix.charAt(i);
+            if (!isXMLNameCharacter(c)) {
+                return "Namespace prefixes cannot contain the character \"" +
+                        c + "\"";
+            }
+        }
+
+        // No colons allowed
+        if (prefix.indexOf(":") != -1) {
+            return "Namespace prefixes cannot contain colons";
+        }
+
+        // If we got here, everything is OK
+        return null;
+    }
+
+    /**
+     * This will check the supplied name to see if it is legal for use as
+     * a JDOM <code>{@link Namespace}</code> URI.
+     *
+     * @param uri <code>String</code> URI to check.
+     * @return <code>String</code> reason name is illegal, or
+     *         <code>null</code> if name is OK.
+     */
+    public static String checkNamespaceURI(String uri) {
+        // Manually do rules, since URIs can be null or empty
+        if ((uri == null) || (uri.equals(""))) {
+            return null;
+        }
+
+        // Cannot start with a number
+        char first = uri.charAt(0);
+        if (Character.isDigit(first)) {
+            return "Namespace URIs cannot begin with a number";
+        }
+        // Cannot start with a $
+        if (first == '$') {
+            return "Namespace URIs cannot begin with a dollar sign ($)";
+        }
+        // Cannot start with a -
+        if (first == '-') {
+            return "Namespace URIs cannot begin with a hyphen (-)";
+        }
+
+        // If we got here, everything is OK
+        return null;
+    }
+
+    /**
+     * Check if two namespaces collide.
+     *
+     * @param namespace <code>Namespace</code> to check.
+     * @param other <code>Namespace</code> to check against.
+     * @return <code>String</code> reason for collision, or
+     *         <code>null</code> if no collision.
+     */
+    public static String checkNamespaceCollision(Namespace namespace,
+                                                 Namespace other) {
+        String p1,p2,u1,u2,reason;
+
+        reason = null;
+        p1 = namespace.getPrefix();
+        u1 = namespace.getURI();
+        p2 = other.getPrefix();
+        u2 = other.getURI();
+        if (p1.equals(p2) && !u1.equals(u2)) {
+            reason = "The namespace prefix \"" + p1 + "\" collides";
+        }
+        return reason;
+    }
+
+    /**
+     * Check if <code>{@link Attribute}</code>'s namespace collides with a 
+     * <code>{@link Element}</code>'s namespace.
+     *
+     * @param attribute <code>Attribute</code> to check.
+     * @param element <code>Element</code> to check against.
+     * @return <code>String</code> reason for collision, or
+     *         <code>null</code> if no collision.
+     */
+    public static String checkNamespaceCollision(Attribute attribute,
+                                                 Element element) {
+        Namespace namespace = attribute.getNamespace();
+        String prefix = namespace.getPrefix();
+        if ("".equals(prefix)) {
+            return null;
+        }
+
+        return checkNamespaceCollision(namespace, element);
+    }
+
+    /**
+     * Check if a <code>{@link Namespace}</code> collides with a
+     * <code>{@link Element}</code>'s namespace.
+     *
+     * @param namespace <code>Namespace</code> to check.
+     * @param element <code>Element</code> to check against.
+     * @return <code>String</code> reason for collision, or
+     *         <code>null</code> if no collision.
+     */
+    public static String checkNamespaceCollision(Namespace namespace,
+                                                 Element element) {
+        String reason = checkNamespaceCollision(namespace,
+                                                element.getNamespace());
+        if (reason != null) {
+            return reason + " with the element namespace prefix";
+        }
+
+        reason = checkNamespaceCollision(namespace,
+                                         element.getAdditionalNamespaces());
+        if (reason != null) {
+            return reason;
+        }
+
+        reason = checkNamespaceCollision(namespace, element.getAttributes());
+        if (reason != null) {
+            return reason;
+        }
+
+        return null;
+    }
+
+    /**
+     * Check if a <code>{@link Namespace}</code> collides with a
+     * <code>{@link Attribute}</code>'s namespace.
+     *
+     * @param namespace <code>Namespace</code> to check.
+     * @param attribute <code>Attribute</code> to check against.
+     * @return <code>String</code> reason for collision, or
+     *         <code>null</code> if no collision.
+     */
+    public static String checkNamespaceCollision(Namespace namespace,
+                                                 Attribute attribute) {
+        String reason = null;
+        if (!attribute.getNamespace().equals(Namespace.NO_NAMESPACE)) {
+            reason = checkNamespaceCollision(namespace,
+                                                attribute.getNamespace());
+            if (reason != null) {
+                reason += " with an attribute namespace prefix on the element";
+            }
+        }
+        return reason;
+    }
+
+    /**
+     * Check if a <code>{@link Namespace}</code> collides with any namespace
+     * from a list of objects.
+     *
+     * @param namespace <code>Namespace</code> to check.
+     * @param list <code>List</code> to check against.
+     * @return <code>String</code> reason for collision, or
+     *         <code>null</code> if no collision.
+     */
+    public static String checkNamespaceCollision(Namespace namespace,
+                                                 List list) {
+        if (list == null) {
+            return null;
+        }
+
+        String reason = null;
+        Iterator i = list.iterator();
+        while ((reason == null) && i.hasNext()) {
+            Object obj = i.next();
+            if (obj instanceof Attribute) {
+                reason = checkNamespaceCollision(namespace, (Attribute) obj);
+            }
+            else if (obj instanceof Element) {
+                reason = checkNamespaceCollision(namespace, (Element) obj);
+            }
+            else if (obj instanceof Namespace) {
+                reason = checkNamespaceCollision(namespace, (Namespace) obj);
+                if (reason != null) {
+                    reason += " with an additional namespace declared" +
+                              " by the element";
+                }
+            }
+        }
+        return reason;
+    }
+
+    /**
+     * This will check the supplied data to see if it is legal for use as
+     * a JDOM <code>{@link ProcessingInstruction}</code> target.
+     *
+     * @param target <code>String</code> target to check.
+     * @return <code>String</code> reason target is illegal, or
+     *         <code>null</code> if target is OK.
+     */
+    public static String checkProcessingInstructionTarget(String target) {
+        // Check basic XML name rules first
+        String reason;
+        if ((reason = checkXMLName(target)) != null) {
+            return reason;
+        }
+
+        // No colons allowed, per Namespace Specification Section 6
+        if (target.indexOf(":") != -1) {
+            return "Processing instruction targets cannot contain colons";
+        }
+
+        // Cannot begin with 'xml' in any case
+        if (target.equalsIgnoreCase("xml")) {
+            return "Processing instructions cannot have a target of " +
+                   "\"xml\" in any combination of case. (Note that the " +
+                   "\"<?xml ... ?>\" declaration at the beginning of a " +
+                   "document is not a processing instruction and should not " + 
+                   "be added as one; it is written automatically during " +
+                   "output, e.g. by XMLOutputter.)";
+        }
+
+        // If we got here, everything is OK
+        return null;
+    }
+
+   /**
+     * This will check the supplied data to see if it is legal for use as
+     * <code>{@link ProcessingInstruction}</code> data. Besides checking that
+     * all the characters are allowed in XML, this also checks
+     * that the data does not contain the PI end-string "?&gt;".
+     *
+     * @param data <code>String</code> data to check.
+     * @return <code>String</code> reason data is illegal, or
+     *         <code>null</code> if data is OK.
+     */
+    public static String checkProcessingInstructionData(String data) {
+        // Check basic XML name rules first
+        String reason = checkCharacterData(data);
+
+        if (reason == null) {
+            if (data.indexOf("?>") >= 0) {
+                return "Processing instructions cannot contain " +
+                       "the string \"?>\"";
+            }
+        }
+
+        return reason;
+    }
+
+    /**
+     * This will check the supplied data to see if it is legal for use as
+     * JDOM <code>{@link Comment}</code> data.
+     *
+     * @param data <code>String</code> data to check.
+     * @return <code>String</code> reason data is illegal, or
+     *         <code>null</code> if data is OK.
+     */
+    public static String checkCommentData(String data) {
+        String reason = null;
+        if ((reason = checkCharacterData(data)) != null) {
+            return reason;
+        }
+
+        if (data.indexOf("--") != -1) {
+            return "Comments cannot contain double hyphens (--)";
+        }
+        if (data.endsWith("-")) {
+            return "Comment data cannot end with a hyphen.";
+        }
+
+        // If we got here, everything is OK
+        return null;
+    }
+    /**
+     * This is a utility function to decode a non-BMP 
+     * UTF-16 surrogate pair.
+     * @param high high 16 bits
+     * @param low low 16 bits
+     * @return decoded character
+     */
+    public static int decodeSurrogatePair(char high, char low) {
+    	return 0x10000 + (high - 0xD800) * 0x400 + (low - 0xDC00);
+    }
+
+    // [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] |
+    // [-'()+,./:=?;*#@$_%]
+    public static boolean isXMLPublicIDCharacter(char c) {
+
+        if (c >= 'a' && c <= 'z') return true;
+        if (c >= '?' && c <= 'Z') return true;
+        if (c >= '\'' && c <= ';') return true;
+
+        if (c == ' ') return true;
+        if (c == '!') return true;
+        if (c == '=') return true;
+        if (c == '#') return true;
+        if (c == '$') return true;
+        if (c == '_') return true;
+        if (c == '%') return true;
+        if (c == '\n') return true;
+        if (c == '\r') return true;
+        if (c == '\t') return true;
+
+        return false;
+    }
+
+    /**
+     * This will ensure that the data for a public identifier
+     * is legal.
+     *
+     * @param publicID <code>String</code> public ID to check.
+     * @return <code>String</code> reason public ID is illegal, or
+     *         <code>null</code> if public ID is OK.
+     */
+    public static String checkPublicID(String publicID) {
+        String reason = null;
+
+        if (publicID == null) return null;
+        // This indicates there is no public ID
+
+        for (int i = 0; i < publicID.length(); i++) {
+          char c = publicID.charAt(i);
+          if (!isXMLPublicIDCharacter(c)) {
+            reason = c + " is not a legal character in public IDs";
+            break;
+          }
+        }
+
+        return reason;
+    }
+
+
+    /**
+     * This will ensure that the data for a system literal
+     * is legal.
+     *
+     * @param systemLiteral <code>String</code> system literal to check.
+     * @return <code>String</code> reason system literal is illegal, or
+     *         <code>null</code> if system literal is OK.
+     */
+    public static String checkSystemLiteral(String systemLiteral) {
+        String reason = null;
+
+        if (systemLiteral == null) return null;
+        // This indicates there is no system ID
+
+        if (systemLiteral.indexOf('\'') != -1
+          && systemLiteral.indexOf('"') != -1) {
+            reason =
+             "System literals cannot simultaneously contain both single and double quotes.";
+        }
+        else {
+          reason = checkCharacterData(systemLiteral);
+        }
+
+        return reason;
+    }
+
+    /**
+     * This is a utility function for sharing the base process of checking
+     * any XML name.
+     *
+     * @param name <code>String</code> to check for XML name compliance.
+     * @return <code>String</code> reason the name is illegal, or
+     *         <code>null</code> if OK.
+     */
+    public static String checkXMLName(String name) {
+        // Cannot be empty or null
+        if ((name == null) || (name.length() == 0) 
+                           || (name.trim().equals(""))) {
+            return "XML names cannot be null or empty";
+        }
+
+      
+        // Cannot start with a number
+        char first = name.charAt(0);
+        if (!isXMLNameStartCharacter(first)) {
+            return "XML names cannot begin with the character \"" + 
+                   first + "\"";
+        }
+        // Ensure legal content for non-first chars
+        for (int i=1, len = name.length(); i<len; i++) {
+            char c = name.charAt(i);
+            if (!isXMLNameCharacter(c)) {
+                return "XML names cannot contain the character \"" + c + "\"";
+            }
+        }
+
+        // We got here, so everything is OK
+        return null;
+    }
+    
+    /**
+     * This is a function for determining whether the
+     * specified character is the high 16 bits in a 
+     * UTF-16 surrogate pair.
+     * @param ch character to check
+     * @return true if the character is a high surrogate, false otherwise
+     */
+    public static boolean isHighSurrogate(char ch) {
+    	return (ch >= 0xD800 && ch <= 0xDBFF);
+    }
+    
+    /**
+     * This is a function for determining whether the 
+     * specified character is the low 16 bits in a 
+     * UTF-16 surrogate pair.
+     * @param ch character to check
+     * @return true if the character is a low surrogate, false otherwise.
+     */
+    public static boolean isLowSurrogate(char ch) {
+    	return (ch >= 0xDC00 && ch <= 0xDFFF);
+    }
+    
+    /**
+     * This is a utility function for determining whether a specified 
+     * character is a character according to production 2 of the 
+     * XML 1.0 specification.
+     *
+     * @param c <code>char</code> to check for XML compliance
+     * @return <code>boolean</code> true if it's a character, 
+     *                                false otherwise
+     */
+    public static boolean isXMLCharacter(int c) {
+    
+        if (c == '\n') return true;
+        if (c == '\r') return true;
+        if (c == '\t') return true;
+        
+        if (c < 0x20) return false;  if (c <= 0xD7FF) return true;
+        if (c < 0xE000) return false;  if (c <= 0xFFFD) return true;
+        if (c < 0x10000) return false;  if (c <= 0x10FFFF) return true;
+        
+        return false;
+    }
+
+
+    /**
+     * This is a utility function for determining whether a specified 
+     * character is a name character according to production 4 of the 
+     * XML 1.0 specification.
+     *
+     * @param c <code>char</code> to check for XML name compliance.
+     * @return <code>boolean</code> true if it's a name character, 
+     *                                false otherwise.
+     */
+    public static boolean isXMLNameCharacter(char c) {
+    
+      return (isXMLLetter(c) || isXMLDigit(c) || c == '.' || c == '-' 
+                             || c == '_' || c == ':' || isXMLCombiningChar(c) 
+                             || isXMLExtender(c));
+    }
+
+    /**
+     * This is a utility function for determining whether a specified 
+     * character is a legal name start character according to production 5
+     * of the XML 1.0 specification. This production does allow names
+     * to begin with colons which the Namespaces in XML Recommendation
+     * disallows. 
+     *
+     * @param c <code>char</code> to check for XML name start compliance.
+     * @return <code>boolean</code> true if it's a name start character, 
+     *                                false otherwise.
+     */
+    public static boolean isXMLNameStartCharacter(char c) {
+    
+      return (isXMLLetter(c) || c == '_' || c ==':');
+    
+    }
+
+    /**
+     * This is a utility function for determining whether a specified character
+     * is a letter according to production 84 of the XML 1.0 specification.
+     *
+     * @param c <code>char</code> to check for XML name compliance.
+     * @return <code>String</code> true if it's a letter, false otherwise.
+     */
+    public static boolean isXMLLetter(char c) {
+        // Note that order is very important here.  The search proceeds 
+        // from lowest to highest values, so that no searching occurs 
+        // above the character's value.  BTW, the first line is equivalent to:
+        // if (c >= 0x0041 && c <= 0x005A) return true;
+
+        if (c < 0x0041) return false;  if (c <= 0x005a) return true;
+        if (c < 0x0061) return false;  if (c <= 0x007A) return true;
+        if (c < 0x00C0) return false;  if (c <= 0x00D6) return true;
+        if (c < 0x00D8) return false;  if (c <= 0x00F6) return true;
+        if (c < 0x00F8) return false;  if (c <= 0x00FF) return true;
+        if (c < 0x0100) return false;  if (c <= 0x0131) return true;
+        if (c < 0x0134) return false;  if (c <= 0x013E) return true;
+        if (c < 0x0141) return false;  if (c <= 0x0148) return true;
+        if (c < 0x014A) return false;  if (c <= 0x017E) return true;
+        if (c < 0x0180) return false;  if (c <= 0x01C3) return true;
+        if (c < 0x01CD) return false;  if (c <= 0x01F0) return true;
+        if (c < 0x01F4) return false;  if (c <= 0x01F5) return true;
+        if (c < 0x01FA) return false;  if (c <= 0x0217) return true;
+        if (c < 0x0250) return false;  if (c <= 0x02A8) return true;
+        if (c < 0x02BB) return false;  if (c <= 0x02C1) return true;
+        if (c == 0x0386) return true;
+        if (c < 0x0388) return false;  if (c <= 0x038A) return true;
+        if (c == 0x038C) return true;
+        if (c < 0x038E) return false;  if (c <= 0x03A1) return true;
+        if (c < 0x03A3) return false;  if (c <= 0x03CE) return true;
+        if (c < 0x03D0) return false;  if (c <= 0x03D6) return true;
+        if (c == 0x03DA) return true;
+        if (c == 0x03DC) return true;
+        if (c == 0x03DE) return true;
+        if (c == 0x03E0) return true;
+        if (c < 0x03E2) return false;  if (c <= 0x03F3) return true;
+        if (c < 0x0401) return false;  if (c <= 0x040C) return true;
+        if (c < 0x040E) return false;  if (c <= 0x044F) return true;
+        if (c < 0x0451) return false;  if (c <= 0x045C) return true;
+        if (c < 0x045E) return false;  if (c <= 0x0481) return true;
+        if (c < 0x0490) return false;  if (c <= 0x04C4) return true;
+        if (c < 0x04C7) return false;  if (c <= 0x04C8) return true;
+        if (c < 0x04CB) return false;  if (c <= 0x04CC) return true;
+        if (c < 0x04D0) return false;  if (c <= 0x04EB) return true;
+        if (c < 0x04EE) return false;  if (c <= 0x04F5) return true;
+        if (c < 0x04F8) return false;  if (c <= 0x04F9) return true;
+        if (c < 0x0531) return false;  if (c <= 0x0556) return true;
+        if (c == 0x0559) return true;
+        if (c < 0x0561) return false;  if (c <= 0x0586) return true;
+        if (c < 0x05D0) return false;  if (c <= 0x05EA) return true;
+        if (c < 0x05F0) return false;  if (c <= 0x05F2) return true;
+        if (c < 0x0621) return false;  if (c <= 0x063A) return true;
+        if (c < 0x0641) return false;  if (c <= 0x064A) return true;
+        if (c < 0x0671) return false;  if (c <= 0x06B7) return true;
+        if (c < 0x06BA) return false;  if (c <= 0x06BE) return true;
+        if (c < 0x06C0) return false;  if (c <= 0x06CE) return true;
+        if (c < 0x06D0) return false;  if (c <= 0x06D3) return true;
+        if (c == 0x06D5) return true;
+        if (c < 0x06E5) return false;  if (c <= 0x06E6) return true;
+        if (c < 0x0905) return false;  if (c <= 0x0939) return true;
+        if (c == 0x093D) return true;
+        if (c < 0x0958) return false;  if (c <= 0x0961) return true;
+        if (c < 0x0985) return false;  if (c <= 0x098C) return true;
+        if (c < 0x098F) return false;  if (c <= 0x0990) return true;
+        if (c < 0x0993) return false;  if (c <= 0x09A8) return true;
+        if (c < 0x09AA) return false;  if (c <= 0x09B0) return true;
+        if (c == 0x09B2) return true;
+        if (c < 0x09B6) return false;  if (c <= 0x09B9) return true;
+        if (c < 0x09DC) return false;  if (c <= 0x09DD) return true;
+        if (c < 0x09DF) return false;  if (c <= 0x09E1) return true;
+        if (c < 0x09F0) return false;  if (c <= 0x09F1) return true;
+        if (c < 0x0A05) return false;  if (c <= 0x0A0A) return true;
+        if (c < 0x0A0F) return false;  if (c <= 0x0A10) return true;
+        if (c < 0x0A13) return false;  if (c <= 0x0A28) return true;
+        if (c < 0x0A2A) return false;  if (c <= 0x0A30) return true;
+        if (c < 0x0A32) return false;  if (c <= 0x0A33) return true;
+        if (c < 0x0A35) return false;  if (c <= 0x0A36) return true;
+        if (c < 0x0A38) return false;  if (c <= 0x0A39) return true;
+        if (c < 0x0A59) return false;  if (c <= 0x0A5C) return true;
+        if (c == 0x0A5E) return true;
+        if (c < 0x0A72) return false;  if (c <= 0x0A74) return true;
+        if (c < 0x0A85) return false;  if (c <= 0x0A8B) return true;
+        if (c == 0x0A8D) return true;
+        if (c < 0x0A8F) return false;  if (c <= 0x0A91) return true;
+        if (c < 0x0A93) return false;  if (c <= 0x0AA8) return true;
+        if (c < 0x0AAA) return false;  if (c <= 0x0AB0) return true;
+        if (c < 0x0AB2) return false;  if (c <= 0x0AB3) return true;
+        if (c < 0x0AB5) return false;  if (c <= 0x0AB9) return true;
+        if (c == 0x0ABD) return true;
+        if (c == 0x0AE0) return true;
+        if (c < 0x0B05) return false;  if (c <= 0x0B0C) return true;
+        if (c < 0x0B0F) return false;  if (c <= 0x0B10) return true;
+        if (c < 0x0B13) return false;  if (c <= 0x0B28) return true;
+        if (c < 0x0B2A) return false;  if (c <= 0x0B30) return true;
+        if (c < 0x0B32) return false;  if (c <= 0x0B33) return true;
+        if (c < 0x0B36) return false;  if (c <= 0x0B39) return true;
+        if (c == 0x0B3D) return true;
+        if (c < 0x0B5C) return false;  if (c <= 0x0B5D) return true;
+        if (c < 0x0B5F) return false;  if (c <= 0x0B61) return true;
+        if (c < 0x0B85) return false;  if (c <= 0x0B8A) return true;
+        if (c < 0x0B8E) return false;  if (c <= 0x0B90) return true;
+        if (c < 0x0B92) return false;  if (c <= 0x0B95) return true;
+        if (c < 0x0B99) return false;  if (c <= 0x0B9A) return true;
+        if (c == 0x0B9C) return true;
+        if (c < 0x0B9E) return false;  if (c <= 0x0B9F) return true;
+        if (c < 0x0BA3) return false;  if (c <= 0x0BA4) return true;
+        if (c < 0x0BA8) return false;  if (c <= 0x0BAA) return true;
+        if (c < 0x0BAE) return false;  if (c <= 0x0BB5) return true;
+        if (c < 0x0BB7) return false;  if (c <= 0x0BB9) return true;
+        if (c < 0x0C05) return false;  if (c <= 0x0C0C) return true;
+        if (c < 0x0C0E) return false;  if (c <= 0x0C10) return true;
+        if (c < 0x0C12) return false;  if (c <= 0x0C28) return true;
+        if (c < 0x0C2A) return false;  if (c <= 0x0C33) return true;
+        if (c < 0x0C35) return false;  if (c <= 0x0C39) return true;
+        if (c < 0x0C60) return false;  if (c <= 0x0C61) return true;
+        if (c < 0x0C85) return false;  if (c <= 0x0C8C) return true;
+        if (c < 0x0C8E) return false;  if (c <= 0x0C90) return true;
+        if (c < 0x0C92) return false;  if (c <= 0x0CA8) return true;
+        if (c < 0x0CAA) return false;  if (c <= 0x0CB3) return true;
+        if (c < 0x0CB5) return false;  if (c <= 0x0CB9) return true;
+        if (c == 0x0CDE) return true;
+        if (c < 0x0CE0) return false;  if (c <= 0x0CE1) return true;
+        if (c < 0x0D05) return false;  if (c <= 0x0D0C) return true;
+        if (c < 0x0D0E) return false;  if (c <= 0x0D10) return true;
+        if (c < 0x0D12) return false;  if (c <= 0x0D28) return true;
+        if (c < 0x0D2A) return false;  if (c <= 0x0D39) return true;
+        if (c < 0x0D60) return false;  if (c <= 0x0D61) return true;
+        if (c < 0x0E01) return false;  if (c <= 0x0E2E) return true;
+        if (c == 0x0E30) return true;
+        if (c < 0x0E32) return false;  if (c <= 0x0E33) return true;
+        if (c < 0x0E40) return false;  if (c <= 0x0E45) return true;
+        if (c < 0x0E81) return false;  if (c <= 0x0E82) return true;
+        if (c == 0x0E84) return true;
+        if (c < 0x0E87) return false;  if (c <= 0x0E88) return true;
+        if (c == 0x0E8A) return true;
+        if (c == 0x0E8D) return true;
+        if (c < 0x0E94) return false;  if (c <= 0x0E97) return true;
+        if (c < 0x0E99) return false;  if (c <= 0x0E9F) return true;
+        if (c < 0x0EA1) return false;  if (c <= 0x0EA3) return true;
+        if (c == 0x0EA5) return true;
+        if (c == 0x0EA7) return true;
+        if (c < 0x0EAA) return false;  if (c <= 0x0EAB) return true;
+        if (c < 0x0EAD) return false;  if (c <= 0x0EAE) return true;
+        if (c == 0x0EB0) return true;
+        if (c < 0x0EB2) return false;  if (c <= 0x0EB3) return true;
+        if (c == 0x0EBD) return true;
+        if (c < 0x0EC0) return false;  if (c <= 0x0EC4) return true;
+        if (c < 0x0F40) return false;  if (c <= 0x0F47) return true;
+        if (c < 0x0F49) return false;  if (c <= 0x0F69) return true;
+        if (c < 0x10A0) return false;  if (c <= 0x10C5) return true;
+        if (c < 0x10D0) return false;  if (c <= 0x10F6) return true;
+        if (c == 0x1100) return true;
+        if (c < 0x1102) return false;  if (c <= 0x1103) return true;
+        if (c < 0x1105) return false;  if (c <= 0x1107) return true;
+        if (c == 0x1109) return true;
+        if (c < 0x110B) return false;  if (c <= 0x110C) return true;
+        if (c < 0x110E) return false;  if (c <= 0x1112) return true;
+        if (c == 0x113C) return true;
+        if (c == 0x113E) return true;
+        if (c == 0x1140) return true;
+        if (c == 0x114C) return true;
+        if (c == 0x114E) return true;
+        if (c == 0x1150) return true;
+        if (c < 0x1154) return false;  if (c <= 0x1155) return true;
+        if (c == 0x1159) return true;
+        if (c < 0x115F) return false;  if (c <= 0x1161) return true;
+        if (c == 0x1163) return true;
+        if (c == 0x1165) return true;
+        if (c == 0x1167) return true;
+        if (c == 0x1169) return true;
+        if (c < 0x116D) return false;  if (c <= 0x116E) return true;
+        if (c < 0x1172) return false;  if (c <= 0x1173) return true;
+        if (c == 0x1175) return true;
+        if (c == 0x119E) return true;
+        if (c == 0x11A8) return true;
+        if (c == 0x11AB) return true;
+        if (c < 0x11AE) return false;  if (c <= 0x11AF) return true;
+        if (c < 0x11B7) return false;  if (c <= 0x11B8) return true;
+        if (c == 0x11BA) return true;
+        if (c < 0x11BC) return false;  if (c <= 0x11C2) return true;
+        if (c == 0x11EB) return true;
+        if (c == 0x11F0) return true;
+        if (c == 0x11F9) return true;
+        if (c < 0x1E00) return false;  if (c <= 0x1E9B) return true;
+        if (c < 0x1EA0) return false;  if (c <= 0x1EF9) return true;
+        if (c < 0x1F00) return false;  if (c <= 0x1F15) return true;
+        if (c < 0x1F18) return false;  if (c <= 0x1F1D) return true;
+        if (c < 0x1F20) return false;  if (c <= 0x1F45) return true;
+        if (c < 0x1F48) return false;  if (c <= 0x1F4D) return true;
+        if (c < 0x1F50) return false;  if (c <= 0x1F57) return true;
+        if (c == 0x1F59) return true;
+        if (c == 0x1F5B) return true;
+        if (c == 0x1F5D) return true;
+        if (c < 0x1F5F) return false;  if (c <= 0x1F7D) return true;
+        if (c < 0x1F80) return false;  if (c <= 0x1FB4) return true;
+        if (c < 0x1FB6) return false;  if (c <= 0x1FBC) return true;
+        if (c == 0x1FBE) return true;
+        if (c < 0x1FC2) return false;  if (c <= 0x1FC4) return true;
+        if (c < 0x1FC6) return false;  if (c <= 0x1FCC) return true;
+        if (c < 0x1FD0) return false;  if (c <= 0x1FD3) return true;
+        if (c < 0x1FD6) return false;  if (c <= 0x1FDB) return true;
+        if (c < 0x1FE0) return false;  if (c <= 0x1FEC) return true;
+        if (c < 0x1FF2) return false;  if (c <= 0x1FF4) return true;
+        if (c < 0x1FF6) return false;  if (c <= 0x1FFC) return true;
+        if (c == 0x2126) return true;
+        if (c < 0x212A) return false;  if (c <= 0x212B) return true;
+        if (c == 0x212E) return true;
+        if (c < 0x2180) return false;  if (c <= 0x2182) return true;
+        if (c == 0x3007) return true;                          // ideographic
+        if (c < 0x3021) return false;  if (c <= 0x3029) return true;  // ideo
+        if (c < 0x3041) return false;  if (c <= 0x3094) return true;
+        if (c < 0x30A1) return false;  if (c <= 0x30FA) return true;
+        if (c < 0x3105) return false;  if (c <= 0x312C) return true;
+        if (c < 0x4E00) return false;  if (c <= 0x9FA5) return true;  // ideo
+        if (c < 0xAC00) return false;  if (c <= 0xD7A3) return true;
+      
+        return false;
+        
+    }
+
+    /**
+     * This is a utility function for determining whether a specified character
+     * is a combining character according to production 87
+     * of the XML 1.0 specification.
+     *
+     * @param c <code>char</code> to check.
+     * @return <code>boolean</code> true if it's a combining character,
+     *         false otherwise.
+     */
+    public static boolean isXMLCombiningChar(char c) {
+        // CombiningChar
+        if (c < 0x0300) return false;  if (c <= 0x0345) return true;
+        if (c < 0x0360) return false;  if (c <= 0x0361) return true;
+        if (c < 0x0483) return false;  if (c <= 0x0486) return true;
+        if (c < 0x0591) return false;  if (c <= 0x05A1) return true;
+                                       
+        if (c < 0x05A3) return false;  if (c <= 0x05B9) return true;
+        if (c < 0x05BB) return false;  if (c <= 0x05BD) return true;
+        if (c == 0x05BF) return true;
+        if (c < 0x05C1) return false;  if (c <= 0x05C2) return true;
+                                       
+        if (c == 0x05C4) return true;
+        if (c < 0x064B) return false;  if (c <= 0x0652) return true;
+        if (c == 0x0670) return true;
+        if (c < 0x06D6) return false;  if (c <= 0x06DC) return true;
+                                       
+        if (c < 0x06DD) return false;  if (c <= 0x06DF) return true;
+        if (c < 0x06E0) return false;  if (c <= 0x06E4) return true;
+        if (c < 0x06E7) return false;  if (c <= 0x06E8) return true;
+                                       
+        if (c < 0x06EA) return false;  if (c <= 0x06ED) return true;
+        if (c < 0x0901) return false;  if (c <= 0x0903) return true;
+        if (c == 0x093C) return true;
+        if (c < 0x093E) return false;  if (c <= 0x094C) return true;
+                                       
+        if (c == 0x094D) return true;
+        if (c < 0x0951) return false;  if (c <= 0x0954) return true;
+        if (c < 0x0962) return false;  if (c <= 0x0963) return true;
+        if (c < 0x0981) return false;  if (c <= 0x0983) return true;
+                                       
+        if (c == 0x09BC) return true;
+        if (c == 0x09BE) return true;
+        if (c == 0x09BF) return true;
+        if (c < 0x09C0) return false;  if (c <= 0x09C4) return true;
+        if (c < 0x09C7) return false;  if (c <= 0x09C8) return true;
+                                       
+        if (c < 0x09CB) return false;  if (c <= 0x09CD) return true;
+        if (c == 0x09D7) return true;
+        if (c < 0x09E2) return false;  if (c <= 0x09E3) return true;
+        if (c == 0x0A02) return true;
+        if (c == 0x0A3C) return true;
+                                       
+        if (c == 0x0A3E) return true;
+        if (c == 0x0A3F) return true;
+        if (c < 0x0A40) return false;  if (c <= 0x0A42) return true;
+        if (c < 0x0A47) return false;  if (c <= 0x0A48) return true;
+                                       
+        if (c < 0x0A4B) return false;  if (c <= 0x0A4D) return true;
+        if (c < 0x0A70) return false;  if (c <= 0x0A71) return true;
+        if (c < 0x0A81) return false;  if (c <= 0x0A83) return true;
+        if (c == 0x0ABC) return true;
+                                       
+        if (c < 0x0ABE) return false;  if (c <= 0x0AC5) return true;
+        if (c < 0x0AC7) return false;  if (c <= 0x0AC9) return true;
+        if (c < 0x0ACB) return false;  if (c <= 0x0ACD) return true;
+                                       
+        if (c < 0x0B01) return false;  if (c <= 0x0B03) return true;
+        if (c == 0x0B3C) return true;
+        if (c < 0x0B3E) return false;  if (c <= 0x0B43) return true;
+        if (c < 0x0B47) return false;  if (c <= 0x0B48) return true;
+                                       
+        if (c < 0x0B4B) return false;  if (c <= 0x0B4D) return true;
+        if (c < 0x0B56) return false;  if (c <= 0x0B57) return true;
+        if (c < 0x0B82) return false;  if (c <= 0x0B83) return true;
+                                       
+        if (c < 0x0BBE) return false;  if (c <= 0x0BC2) return true;
+        if (c < 0x0BC6) return false;  if (c <= 0x0BC8) return true;
+        if (c < 0x0BCA) return false;  if (c <= 0x0BCD) return true;
+        if (c == 0x0BD7) return true;
+                                       
+        if (c < 0x0C01) return false;  if (c <= 0x0C03) return true;
+        if (c < 0x0C3E) return false;  if (c <= 0x0C44) return true;
+        if (c < 0x0C46) return false;  if (c <= 0x0C48) return true;
+                                       
+        if (c < 0x0C4A) return false;  if (c <= 0x0C4D) return true;
+        if (c < 0x0C55) return false;  if (c <= 0x0C56) return true;
+        if (c < 0x0C82) return false;  if (c <= 0x0C83) return true;
+                                       
+        if (c < 0x0CBE) return false;  if (c <= 0x0CC4) return true;
+        if (c < 0x0CC6) return false;  if (c <= 0x0CC8) return true;
+        if (c < 0x0CCA) return false;  if (c <= 0x0CCD) return true;
+                                       
+        if (c < 0x0CD5) return false;  if (c <= 0x0CD6) return true;
+        if (c < 0x0D02) return false;  if (c <= 0x0D03) return true;
+        if (c < 0x0D3E) return false;  if (c <= 0x0D43) return true;
+                                       
+        if (c < 0x0D46) return false;  if (c <= 0x0D48) return true;
+        if (c < 0x0D4A) return false;  if (c <= 0x0D4D) return true;
+        if (c == 0x0D57) return true;
+        if (c == 0x0E31) return true;
+                                       
+        if (c < 0x0E34) return false;  if (c <= 0x0E3A) return true;
+        if (c < 0x0E47) return false;  if (c <= 0x0E4E) return true;
+        if (c == 0x0EB1) return true;
+        if (c < 0x0EB4) return false;  if (c <= 0x0EB9) return true;
+                                       
+        if (c < 0x0EBB) return false;  if (c <= 0x0EBC) return true;
+        if (c < 0x0EC8) return false;  if (c <= 0x0ECD) return true;
+        if (c < 0x0F18) return false;  if (c <= 0x0F19) return true;
+        if (c == 0x0F35) return true;
+                                       
+        if (c == 0x0F37) return true;
+        if (c == 0x0F39) return true;
+        if (c == 0x0F3E) return true;
+        if (c == 0x0F3F) return true;
+        if (c < 0x0F71) return false;  if (c <= 0x0F84) return true;
+                                       
+        if (c < 0x0F86) return false;  if (c <= 0x0F8B) return true;
+        if (c < 0x0F90) return false;  if (c <= 0x0F95) return true;
+        if (c == 0x0F97) return true;
+        if (c < 0x0F99) return false;  if (c <= 0x0FAD) return true;
+                                       
+        if (c < 0x0FB1) return false;  if (c <= 0x0FB7) return true;
+        if (c == 0x0FB9) return true;
+        if (c < 0x20D0) return false;  if (c <= 0x20DC) return true;
+        if (c == 0x20E1) return true;
+                                       
+        if (c < 0x302A) return false;  if (c <= 0x302F) return true;
+        if (c == 0x3099) return true;
+        if (c == 0x309A) return true; 
+        
+        return false;
+        
+    }
+    
+    /**
+     * This is a utility function for determining whether a specified 
+     * character is an extender according to production 88 of the XML 1.0
+     * specification.
+     *
+     * @param c <code>char</code> to check.
+     * @return <code>String</code> true if it's an extender, false otherwise.
+     */
+    public static boolean isXMLExtender(char c) {
+
+        if (c < 0x00B6) return false;  // quick short circuit
+
+        // Extenders                               
+        if (c == 0x00B7) return true;
+        if (c == 0x02D0) return true;
+        if (c == 0x02D1) return true;
+        if (c == 0x0387) return true;
+        if (c == 0x0640) return true;
+        if (c == 0x0E46) return true;
+        if (c == 0x0EC6) return true;
+        if (c == 0x3005) return true;
+                                       
+        if (c < 0x3031) return false;  if (c <= 0x3035) return true;
+        if (c < 0x309D) return false;  if (c <= 0x309E) return true;
+        if (c < 0x30FC) return false;  if (c <= 0x30FE) return true;
+        
+        return false;
+        
+    }
+      
+    /**
+     * This is a utility function for determining whether a specified 
+     * Unicode character
+     * is a digit according to production 88 of the XML 1.0 specification.
+     *
+     * @param c <code>char</code> to check for XML digit compliance
+     * @return <code>boolean</code> true if it's a digit, false otherwise
+     */
+    public static boolean isXMLDigit(char c) {
+      
+        if (c < 0x0030) return false;  if (c <= 0x0039) return true;
+        if (c < 0x0660) return false;  if (c <= 0x0669) return true;
+        if (c < 0x06F0) return false;  if (c <= 0x06F9) return true;
+        if (c < 0x0966) return false;  if (c <= 0x096F) return true;
+                                       
+        if (c < 0x09E6) return false;  if (c <= 0x09EF) return true;
+        if (c < 0x0A66) return false;  if (c <= 0x0A6F) return true;
+        if (c < 0x0AE6) return false;  if (c <= 0x0AEF) return true;
+                                       
+        if (c < 0x0B66) return false;  if (c <= 0x0B6F) return true;
+        if (c < 0x0BE7) return false;  if (c <= 0x0BEF) return true;
+        if (c < 0x0C66) return false;  if (c <= 0x0C6F) return true;
+                                       
+        if (c < 0x0CE6) return false;  if (c <= 0x0CEF) return true;
+        if (c < 0x0D66) return false;  if (c <= 0x0D6F) return true;
+        if (c < 0x0E50) return false;  if (c <= 0x0E59) return true;
+                                       
+        if (c < 0x0ED0) return false;  if (c <= 0x0ED9) return true;
+        if (c < 0x0F20) return false;  if (c <= 0x0F29) return true; 
+      
+        return false;
+    }  
+    
+    /**
+     * This is a utility function for determining whether a specified 
+     * Unicode character is a whitespace character according to production 3
+     * of the XML 1.0 specification.
+     *
+     * @param c <code>char</code> to check for XML whitespace compliance
+     * @return <code>boolean</code> true if it's a whitespace, false otherwise
+     */
+    public static boolean isXMLWhitespace(char c) {
+        if (c==' ' || c=='\n' || c=='\t' || c=='\r' ){
+            return true;
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/AbstractFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/AbstractFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/AbstractFilter.java	(revision 28000)
@@ -0,0 +1,70 @@
+/*--
+
+ $Id: AbstractFilter.java,v 1.6 2007/11/10 05:29:00 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom.filter;
+
+/**
+ * Partial implementation of {@link Filter}.
+ *
+ * @author Bradley S. Huffman
+ * @version $Revision: 1.6 $, $Date: 2007/11/10 05:29:00 $
+ */
+public abstract class AbstractFilter implements Filter {
+
+    public Filter negate() {
+        return new NegateFilter(this);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/ElementFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/ElementFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/ElementFilter.java	(revision 28000)
@@ -0,0 +1,168 @@
+/*--
+
+ $Id: ElementFilter.java,v 1.20 2007/11/10 05:29:00 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom.filter;
+
+import java.io.*;
+import org.jdom.*;
+
+/**
+ * A Filter that only matches {@link org.jdom.Element} objects.
+ *
+ * @version $Revision: 1.20 $, $Date: 2007/11/10 05:29:00 $
+ * @author  Jools Enticknap
+ * @author  Bradley S. Huffman
+ */
+public class ElementFilter extends AbstractFilter {
+
+    /** The element name */
+    private String name;
+
+    /** The element namespace */
+    private transient Namespace namespace;
+
+    /**
+     * Select only the Elements.
+     */
+    public ElementFilter() {}
+
+    /**
+     * Select only the Elements with the supplied name and Namespace.
+     *
+     * @param name   The name of the Element.
+     * @param namespace The namespace the Element lives in.
+     */
+    public ElementFilter(String name, Namespace namespace) {
+        this.name   = name;
+        this.namespace = namespace;
+    }
+
+    /**
+     * Check to see if the object matches a predefined set of rules.
+     *
+     * @param obj The object to verify.
+     * @return <code>true</code> if the objected matched a predfined
+     *           set of rules.
+     */
+    public boolean matches(Object obj) {
+        if (obj instanceof Element) {
+            Element el = (Element) obj;
+            return
+              (this.name == null || this.name.equals(el.getName())) &&
+              (this.namespace == null || this.namespace.equals(el.getNamespace()));
+        }
+        return false;
+    }
+
+    /**
+     * Returns whether the two filters are equivalent (i&#46;e&#46; the
+     * matching names and namespace are equivalent).
+     *
+     * @param  obj                   the object to compare against
+     * @return                     whether the two filters are equal
+     */
+    public boolean equals(Object obj) {
+        // Generated by IntelliJ
+        if (this == obj) return true;
+        if (!(obj instanceof ElementFilter)) return false;
+
+        final ElementFilter filter = (ElementFilter) obj;
+
+        if (name != null ? !name.equals(filter.name) : filter.name != null) return false;
+        if (namespace != null ? !namespace.equals(filter.namespace) : filter.namespace != null) return false;
+
+        return true;
+    }
+
+    public int hashCode() {
+        // Generated by IntelliJ
+        int result;
+        result = (name != null ? name.hashCode() : 0);
+        result = 29 * result + (namespace != null ? namespace.hashCode() : 0);
+        return result;
+    }
+
+    // Support a custom Namespace serialization so no two namespace
+    // object instances may exist for the same prefix/uri pair
+    private void writeObject(ObjectOutputStream out) throws IOException {
+
+        out.defaultWriteObject();
+
+        // We use writeObject() and not writeUTF() to minimize space
+        // This allows for writing pointers to already written strings
+        if (namespace != null) {
+            out.writeObject(namespace.getPrefix());
+            out.writeObject(namespace.getURI());
+        }
+        else {
+            out.writeObject(null);
+            out.writeObject(null);
+        }
+    }
+
+    private void readObject(ObjectInputStream in)
+            throws IOException, ClassNotFoundException {
+
+        in.defaultReadObject();
+
+        Object prefix = in.readObject();
+        Object uri = in.readObject();
+
+        if (prefix != null) {  // else leave namespace null here
+            namespace = Namespace.getNamespace((String) prefix, (String) uri);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/Filter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/Filter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/Filter.java	(revision 28000)
@@ -0,0 +1,76 @@
+/*-- 
+
+ $Id: Filter.java,v 1.10 2007/11/10 05:29:00 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows 
+    these conditions in the documentation and/or other materials 
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+ 
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+ 
+ In addition, we request (but do not require) that you include in the 
+ end-user documentation provided with the redistribution and/or in the 
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos 
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many 
+ individuals on behalf of the JDOM Project and was originally 
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+ 
+ */
+
+package org.jdom.filter;
+
+
+/**
+ * A generalized filter to restrict visibility or mutability on a list.
+ *
+ * @version $Revision: 1.10 $, $Date: 2007/11/10 05:29:00 $
+ * @author  Jools Enticknap
+ * @author  Bradley S. Huffman
+ */
+public interface Filter extends java.io.Serializable {
+    /**
+     * Check to see if the object matches a predefined set of rules.
+     *
+     * @param obj The object to verify.
+     * @return <code>true</code> if the object matches a predfined 
+     *           set of rules.
+     */
+    public boolean matches(Object obj);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/NegateFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/NegateFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/NegateFilter.java	(revision 28000)
@@ -0,0 +1,110 @@
+/*--
+
+ $Id: NegateFilter.java,v 1.4 2007/11/10 05:29:00 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom.filter;
+
+/**
+ * Filter that is the logical <b>negation</b> operation of another filter.
+ *
+ *
+ * @author Bradley S. Huffman
+ * @version $Revision: 1.4 $, $Date: 2007/11/10 05:29:00 $
+ */
+final class NegateFilter extends AbstractFilter {
+
+    // Underlying filter.
+    private Filter filter;
+
+    /**
+     * Match if the supplied filter <b>does not</b> match.
+     *
+     * @param filter filter to use.
+     */
+    public NegateFilter(Filter filter) {
+        this.filter = filter;
+    }
+
+    public boolean matches(Object obj) {
+        return !filter.matches(obj);
+    }
+
+    public Filter negate() {
+        return filter;
+    }
+
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof NegateFilter) {
+            return filter.equals(((NegateFilter) obj).filter);
+        }
+        return false;
+    }
+
+    public int hashCode() {
+        return ~filter.hashCode();
+    }
+
+    public String toString() {
+        return new StringBuffer(64)
+                   .append("[NegateFilter: ")
+                   .append(filter.toString())
+                   .append("]")
+                   .toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/filter/package.html	(revision 28000)
@@ -0,0 +1,9 @@
+<body>
+
+Classes to programmatically filter nodes of a document based on type, name,
+value, or other aspects and to boolean and/or/negate these rules.  Filters can
+be used in methods like getContent(Filter) and getDescendants(Filter).  A
+sampling of generally useful filters are provided here.  Alternate filters can
+be user defined.
+
+</body>
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/input/BuilderErrorHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/input/BuilderErrorHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/input/BuilderErrorHandler.java	(revision 28000)
@@ -0,0 +1,108 @@
+/*-- 
+
+ $Id: BuilderErrorHandler.java,v 1.13 2007/11/10 05:29:00 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows 
+    these conditions in the documentation and/or other materials 
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+ 
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+ 
+ In addition, we request (but do not require) that you include in the 
+ end-user documentation provided with the redistribution and/or in the 
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos 
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many 
+ individuals on behalf of the JDOM Project and was originally 
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+ 
+ */
+
+package org.jdom.input;
+
+import org.xml.sax.*;
+
+/**
+ * The standard JDOM error handler implementation.
+ * 
+ * @author  Jason Hunter
+ * @version $Revision: 1.13 $, $Date: 2007/11/10 05:29:00 $
+ */
+
+public class BuilderErrorHandler implements ErrorHandler {
+
+    /**
+     * This method is called when a warning has occurred; this indicates
+     * that while no XML rules were broken, something appears to be
+     * incorrect or missing.
+     * The implementation of this method here is a "no op".
+     *
+     * @param exception <code>SAXParseException</code> that occurred.
+     * @throws SAXException when things go wrong
+     */
+    public void warning(SAXParseException exception) throws SAXException {
+        // nothing
+    }
+
+    /**
+     * This method is called in response to an error that has occurred; 
+     * this indicates that a rule was broken, typically in validation, but 
+     * that parsing could reasonably continue.
+     * The implementation of this method here is to rethrow the exception.
+     *
+     * @param exception <code>SAXParseException</code> that occurred.
+     * @throws SAXException when things go wrong
+     */
+    public void error(SAXParseException exception) throws SAXException {
+        throw exception;
+    }
+
+    /**
+     * This method is called in response to a fatal error; this indicates that
+     * a rule has been broken that makes continued parsing either impossible
+     * or an almost certain waste of time.
+     * The implementation of this method here is to rethrow the exception.
+     *
+     * @param exception <code>SAXParseException</code> that occurred.
+     * @throws SAXException when things go wrong
+     */
+    public void fatalError(SAXParseException exception) throws SAXException {
+        throw exception;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/input/JDOMParseException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/input/JDOMParseException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/input/JDOMParseException.java	(revision 28000)
@@ -0,0 +1,89 @@
+/*--
+
+ $Id: JDOMParseException.java,v 1.8 2007/11/10 05:29:00 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom.input;
+
+import org.jdom.Document;
+import org.jdom.JDOMException;
+
+/**
+ * Thrown during parse errors, with information about where the parse error
+ * occurred as well as access to the partially built document.
+ *
+ * @version $Revision: 1.8 $, $Date: 2007/11/10 05:29:00 $
+ * @author  Laurent Bihanic
+ */
+public class JDOMParseException extends JDOMException {
+
+    /**
+     * This will create a parse <code>Exception</code> with the given
+     * message and the partial document and wrap the
+     * <code>Exception</code> that cause a document parse to fail.
+     *
+     * @param message <code>String</code> message indicating
+     *                the problem that occurred.
+     * @param cause <code>Throwable</code> that caused this
+     *              to be thrown.
+     * @param partialDocument <code>Document</code> the portion of
+     *                        the input XML document that was
+     *                        successfully built.
+     */
+    public JDOMParseException(String message, Throwable cause,
+                              Document partialDocument)  {
+        super(message, cause);
+    }
+}
+
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/input/SAXBuilder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/input/SAXBuilder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/input/SAXBuilder.java	(revision 28000)
@@ -0,0 +1,612 @@
+/*--
+
+ $Id: SAXBuilder.java,v 1.93 2009/07/23 06:26:26 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom.input;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.jdom.DefaultJDOMFactory;
+import org.jdom.DocType;
+import org.jdom.Document;
+import org.jdom.EntityRef;
+import org.jdom.JDOMException;
+import org.jdom.JDOMFactory;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLFilter;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * Builds a JDOM document from files, streams, readers, URLs, or a SAX {@link
+ * org.xml.sax.InputSource} instance using a SAX parser. The builder uses a
+ * third-party SAX parser (chosen by JAXP by default, or you can choose
+ * manually) to handle the parsing duties and simply listens to the SAX events
+ * to construct a document. Details which SAX does not provide, such as
+ * whitespace outside the root element, are not represented in the JDOM
+ * document. Information about SAX can be found at <a
+ * href="http://www.saxproject.org">http://www.saxproject.org</a>.
+ * <p>
+ * Known issues: Relative paths for a {@link DocType} or {@link EntityRef} may
+ * be converted by the SAX parser into absolute paths.
+ *
+ * @version $Revision: 1.93 $, $Date: 2009/07/23 06:26:26 $
+ * @author  Jason Hunter
+ * @author  Brett McLaughlin
+ * @author  Dan Schaffer
+ * @author  Philip Nelson
+ * @author  Alex Rosen
+ */
+public class SAXBuilder {
+
+    /**
+     * Default parser class to use. This is used when no other parser
+     * is given and JAXP isn't available.
+     */
+    private static final String DEFAULT_SAX_DRIVER =
+        "org.apache.xerces.parsers.SAXParser";
+
+    /** Whether validation should occur */
+    private boolean validate;
+
+    /** Whether expansion of entities should occur */
+    private boolean expand = true;
+
+    /** Adapter class to use */
+    private String saxDriverClass;
+
+    /** ErrorHandler class to use */
+    private ErrorHandler saxErrorHandler = null;
+
+    /** EntityResolver class to use */
+    private EntityResolver saxEntityResolver = null;
+
+    /** DTDHandler class to use */
+    private DTDHandler saxDTDHandler = null;
+
+    /** XMLFilter instance to use */
+    private XMLFilter saxXMLFilter = null;
+
+    /** The factory for creating new JDOM objects */
+    private JDOMFactory factory = new DefaultJDOMFactory();
+
+    /** Whether to ignore ignorable whitespace */
+    private boolean ignoringWhite = false;
+
+    /** Whether to ignore all whitespace content */
+    private boolean ignoringBoundaryWhite = false;
+
+    /** User-specified features to be set on the SAX parser */
+    private HashMap features = new HashMap(5);
+
+    /** User-specified properties to be set on the SAX parser */
+    private HashMap properties = new HashMap(5);
+
+    /** Whether to use fast parser reconfiguration */
+    private boolean fastReconfigure = false;
+
+    /** Whether to try lexical reporting in fast parser reconfiguration */
+    private boolean skipNextLexicalReportingConfig = false;
+
+    /** Whether to to try entity expansion in fast parser reconfiguration */
+    private boolean skipNextEntityExpandConfig = false;
+
+    /**
+     * Whether parser reuse is allowed.
+     * <p>Default: <code>true</code></p>
+     */
+    private boolean reuseParser = true;
+
+    /** The current SAX parser, if parser reuse has been activated. */
+    private XMLReader saxParser = null;
+
+    /**
+     * Creates a new SAXBuilder which will attempt to first locate
+     * a parser via JAXP, then will try to use a set of default
+     * SAX Drivers. The underlying parser will not validate.
+     */
+    public SAXBuilder() {
+        this(false);
+    }
+
+    /**
+     * Creates a new SAXBuilder which will attempt to first locate
+     * a parser via JAXP, then will try to use a set of default
+     * SAX Drivers. The underlying parser will validate or not
+     * according to the given parameter.
+     *
+     * @param validate <code>boolean</code> indicating if
+     *                 validation should occur.
+     */
+    public SAXBuilder(boolean validate) {
+        this.validate = validate;
+    }
+
+    /**
+     * This builds a document from the supplied
+     * input source.
+     *
+     * @param in <code>InputSource</code> to read from
+     * @return <code>Document</code> resultant Document object
+     * @throws JDOMException when errors occur in parsing
+     * @throws IOException when an I/O error prevents a document
+     *         from being fully parsed
+     */
+    public Document build(InputSource in)
+     throws JDOMException, IOException {
+        SAXHandler contentHandler = null;
+
+        try {
+            // Create and configure the content handler.
+            contentHandler = createContentHandler();
+            configureContentHandler(contentHandler);
+
+            XMLReader parser = this.saxParser;
+            if (parser == null) {
+                // Create and configure the parser.
+                parser = createParser();
+
+                // Install optional filter
+                if (saxXMLFilter != null) {
+                    // Connect filter chain to parser
+                    XMLFilter root = saxXMLFilter;
+                    while (root.getParent() instanceof XMLFilter) {
+                        root = (XMLFilter)root.getParent();
+                    }
+                    root.setParent(parser);
+
+                    // Read from filter
+                    parser = saxXMLFilter;
+                }
+
+                // Configure parser
+                configureParser(parser, contentHandler);
+
+                if (reuseParser) {
+                    this.saxParser = parser;
+                }
+            }
+            else {
+                // Reset content handler as SAXHandler instances cannot
+                // be reused
+                configureParser(parser, contentHandler);
+            }
+
+            // Parse the document.
+            parser.parse(in);
+
+            return contentHandler.getDocument();
+        }
+        catch (SAXParseException e) {
+            Document doc = contentHandler.getDocument();
+            if (doc.hasRootElement() == false) {
+                doc = null;
+            }
+
+            String systemId = e.getSystemId();
+            if (systemId != null) {
+                throw new JDOMParseException("Error on line " +
+                    e.getLineNumber() + " of document " + systemId, e, doc);
+            } else {
+                throw new JDOMParseException("Error on line " +
+                    e.getLineNumber(), e, doc);
+            }
+        }
+        catch (SAXException e) {
+            throw new JDOMParseException("Error in building: " +
+                e.getMessage(), e, contentHandler.getDocument());
+        }
+        finally {
+            // Explicitly nullify the handler to encourage GC
+            // It's a stack var so this shouldn't be necessary, but it
+            // seems to help on some JVMs
+            contentHandler = null;
+        }
+    }
+
+    /**
+     * This creates the SAXHandler that will be used to build the Document.
+     *
+     * @return <code>SAXHandler</code> - resultant SAXHandler object.
+     */
+    protected SAXHandler createContentHandler() {
+        SAXHandler contentHandler = new SAXHandler(factory);
+        return contentHandler;
+    }
+
+    /**
+     * This configures the SAXHandler that will be used to build the Document.
+     * <p>
+     * The default implementation simply passes through some configuration
+     * settings that were set on the SAXBuilder: setExpandEntities() and
+     * setIgnoringElementContentWhitespace().
+     * </p>
+     * @param contentHandler The SAXHandler to configure
+     */
+    protected void configureContentHandler(SAXHandler contentHandler) {
+        // Setup pass through behavior
+        contentHandler.setExpandEntities(expand);
+        contentHandler.setIgnoringElementContentWhitespace(ignoringWhite);
+        contentHandler.setIgnoringBoundaryWhitespace(ignoringBoundaryWhite);
+    }
+
+    /**
+     * This creates the XMLReader to be used for reading the XML document.
+     * <p>
+     * The default behavior is to (1) use the saxDriverClass, if it has been
+     * set, (2) try to obtain a parser from JAXP, if it is available, and
+     * (3) if all else fails, use a hard-coded default parser (currently
+     * the Xerces parser). Subclasses may override this method to determine
+     * the parser to use in a different way.
+     * </p>
+     *
+     * @return <code>XMLReader</code> - resultant XMLReader object.
+     * @throws org.jdom.JDOMException
+     */
+    protected XMLReader createParser() throws JDOMException {
+        XMLReader parser = null;
+        if (saxDriverClass != null) {
+            // The user knows that they want to use a particular class
+            try {
+                parser = XMLReaderFactory.createXMLReader(saxDriverClass);
+
+                // Configure parser
+                setFeaturesAndProperties(parser, true);
+            }
+            catch (SAXException e) {
+              throw new JDOMException("Could not load " + saxDriverClass, e);
+            }
+        } else {
+            // Try using JAXP...
+            // Note we need JAXP 1.1, and if JAXP 1.0 is all that's
+            // available then the getXMLReader call fails and we skip
+            // to the hard coded default parser
+            try {
+                // Get factory class and method.
+                Class factoryClass =
+                    Class.forName("org.jdom.input.JAXPParserFactory");
+
+                Method createParser =
+                    factoryClass.getMethod("createParser",
+                        new Class[] { boolean.class, Map.class, Map.class });
+
+                // Create SAX parser.
+                parser = (XMLReader)createParser.invoke(null,
+                                new Object[] { validate ? Boolean.TRUE : Boolean.FALSE,
+                                               features, properties });
+
+                // Configure parser
+                setFeaturesAndProperties(parser, false);
+            }
+            catch (JDOMException e) {
+                throw e;
+            }
+            catch (NoClassDefFoundError e) {
+                // The class loader failed to resolve the dependencies
+                // of org.jdom.input.JAXPParserFactory. This probably means
+                // that no JAXP parser is present in its class path.
+                // => Ignore and try allocating default SAX parser instance.
+            }
+            catch (Exception e) {
+                // Ignore and try allocating default SAX parser instance.
+            }
+        }
+
+        // Check to see if we got a parser yet, if not, try to use a
+        // hard coded default
+        if (parser == null) {
+            try {
+                parser = XMLReaderFactory.createXMLReader(DEFAULT_SAX_DRIVER);
+                // System.out.println("using default " + DEFAULT_SAX_DRIVER);
+                saxDriverClass = parser.getClass().getName();
+
+                // Configure parser
+                setFeaturesAndProperties(parser, true);
+            }
+            catch (SAXException e) {
+                throw new JDOMException("Could not load default SAX parser: "
+                  + DEFAULT_SAX_DRIVER, e);
+            }
+        }
+
+        return parser;
+    }
+
+    /**
+     * This configures the XMLReader to be used for reading the XML document.
+     * <p>
+     * The default implementation sets various options on the given XMLReader,
+     *  such as validation, DTD resolution, entity handlers, etc., according
+     *  to the options that were set (e.g. via <code>setEntityResolver</code>)
+     *  and set various SAX properties and features that are required for JDOM
+     *  internals. These features may change in future releases, so change this
+     *  behavior at your own risk.
+     * </p>
+     * @param parser
+     * @param contentHandler
+     * @throws org.jdom.JDOMException
+     */
+    protected void configureParser(XMLReader parser, SAXHandler contentHandler)
+        throws JDOMException {
+
+        // Setup SAX handlers.
+
+        parser.setContentHandler(contentHandler);
+
+        if (saxEntityResolver != null) {
+            parser.setEntityResolver(saxEntityResolver);
+        }
+
+        if (saxDTDHandler != null) {
+            parser.setDTDHandler(saxDTDHandler);
+        } else {
+            parser.setDTDHandler(contentHandler);
+        }
+
+        if (saxErrorHandler != null) {
+             parser.setErrorHandler(saxErrorHandler);
+        } else {
+             parser.setErrorHandler(new BuilderErrorHandler());
+        }
+
+        // If fastReconfigure is enabled and we failed in the previous attempt
+        // in configuring lexical reporting, then we skip this step.  This
+        // saves the work of repeated exception handling on each parse.
+        if (!skipNextLexicalReportingConfig) {
+            boolean success = false;
+
+            try {
+                parser.setProperty("http://xml.org/sax/handlers/LexicalHandler",
+                                   contentHandler);
+                success = true;
+            } catch (SAXNotSupportedException e) {
+                // No lexical reporting available
+            } catch (SAXNotRecognizedException e) {
+                // No lexical reporting available
+            }
+
+            // Some parsers use alternate property for lexical handling (grr...)
+            if (!success) {
+                try {
+                    parser.setProperty("http://xml.org/sax/properties/lexical-handler",
+                                       contentHandler);
+                    success = true;
+                } catch (SAXNotSupportedException e) {
+                    // No lexical reporting available
+                } catch (SAXNotRecognizedException e) {
+                    // No lexical reporting available
+                }
+            }
+
+            // If unable to configure this property and fastReconfigure is
+            // enabled, then setup to avoid this code path entirely next time.
+            if (!success && fastReconfigure) {
+                skipNextLexicalReportingConfig = true;
+            }
+        }
+
+        // If fastReconfigure is enabled and we failed in the previous attempt
+        // in configuring entity expansion, then skip this step.  This
+        // saves the work of repeated exception handling on each parse.
+        if (!skipNextEntityExpandConfig) {
+            boolean success = false;
+
+            // Try setting the DeclHandler if entity expansion is off
+            if (!expand) {
+                try {
+                    parser.setProperty("http://xml.org/sax/properties/declaration-handler",
+                                       contentHandler);
+                    success = true;
+                } catch (SAXNotSupportedException e) {
+                    // No lexical reporting available
+                } catch (SAXNotRecognizedException e) {
+                    // No lexical reporting available
+                }
+            }
+
+            /* If unable to configure this property and fastReconfigure is
+             * enabled, then setup to avoid this code path entirely next time.
+             */
+            if (!success && fastReconfigure) {
+                skipNextEntityExpandConfig = true;
+            }
+        }
+    }
+
+    private void setFeaturesAndProperties(XMLReader parser,
+                                          boolean coreFeatures)
+                                                        throws JDOMException {
+        // Set any user-specified features on the parser.
+        Iterator iter = features.keySet().iterator();
+        while (iter.hasNext()) {
+            String  name  = (String)iter.next();
+            Boolean value = (Boolean)features.get(name);
+            internalSetFeature(parser, name, value.booleanValue(), name);
+        }
+
+        // Set any user-specified properties on the parser.
+        iter = properties.keySet().iterator();
+        while (iter.hasNext()) {
+            String name = (String)iter.next();
+            internalSetProperty(parser, name, properties.get(name), name);
+        }
+
+        if (coreFeatures) {
+            // Set validation.
+            try {
+                internalSetFeature(parser,
+                        "http://xml.org/sax/features/validation",
+                        validate, "Validation");
+            } catch (JDOMException e) {
+                // If validation is not supported, and the user is requesting
+                // that we don't validate, that's fine - don't throw an
+                // exception.
+                if (validate)
+                    throw e;
+            }
+
+            // Setup some namespace features.
+            internalSetFeature(parser,
+                        "http://xml.org/sax/features/namespaces",
+                        true, "Namespaces");
+            internalSetFeature(parser,
+                        "http://xml.org/sax/features/namespace-prefixes",
+                        true, "Namespace prefixes");
+        }
+
+        // Set entity expansion
+        // Note SAXHandler can work regardless of how this is set, but when
+        // entity expansion it's worth it to try to tell the parser not to
+        // even bother with external general entities.
+        // Apparently no parsers yet support this feature.
+        // XXX It might make sense to setEntityResolver() with a resolver
+        // that simply ignores external general entities
+        try {
+            if (parser.getFeature("http://xml.org/sax/features/external-general-entities") != expand) {
+                parser.setFeature("http://xml.org/sax/features/external-general-entities", expand);
+            }
+        }
+        catch (SAXNotRecognizedException e) { /* Ignore... */ }
+        catch (SAXNotSupportedException  e) { /* Ignore... */ }
+    }
+
+    /**
+     * Tries to set a feature on the parser. If the feature cannot be set,
+     * throws a JDOMException describing the problem.
+     */
+    private void internalSetFeature(XMLReader parser, String feature,
+                    boolean value, String displayName) throws JDOMException {
+        try {
+            parser.setFeature(feature, value);
+        } catch (SAXNotSupportedException e) {
+            throw new JDOMException(
+                displayName + " feature not supported for SAX driver " + parser.getClass().getName());
+        } catch (SAXNotRecognizedException e) {
+            throw new JDOMException(
+                displayName + " feature not recognized for SAX driver " + parser.getClass().getName());
+        }
+    }
+
+    /**
+     * <p>
+     * Tries to set a property on the parser. If the property cannot be set,
+     * throws a JDOMException describing the problem.
+     * </p>
+     */
+    private void internalSetProperty(XMLReader parser, String property,
+                    Object value, String displayName) throws JDOMException {
+        try {
+            parser.setProperty(property, value);
+        } catch (SAXNotSupportedException e) {
+            throw new JDOMException(
+                displayName + " property not supported for SAX driver " + parser.getClass().getName());
+        } catch (SAXNotRecognizedException e) {
+            throw new JDOMException(
+                displayName + " property not recognized for SAX driver " + parser.getClass().getName());
+        }
+    }
+
+    /**
+     * <p>
+     * This builds a document from the supplied
+     *   input stream.
+     * </p>
+     *
+     * @param in <code>InputStream</code> to read from
+     * @return <code>Document</code> resultant Document object
+     * @throws JDOMException when errors occur in parsing
+     * @throws IOException when an I/O error prevents a document
+     *         from being fully parsed.
+     */
+    public Document build(InputStream in)
+     throws JDOMException, IOException {
+        return build(new InputSource(in));
+    }
+
+//    /**
+//     * Imitation of File.toURL(), a JDK 1.2 method, reimplemented
+//     * here to work with JDK 1.1.
+//     *
+//     * @see java.io.File
+//     *
+//     * @param f the file to convert
+//     * @return the file path converted to a file: URL
+//     */
+//    protected URL fileToURL(File f) throws MalformedURLException {
+//        String path = f.getAbsolutePath();
+//        if (File.separatorChar != '/') {
+//            path = path.replace(File.separatorChar, '/');
+//        }
+//        if (!path.startsWith("/")) {
+//            path = "/" + path;
+//        }
+//        if (!path.endsWith("/") && f.isDirectory()) {
+//            path = path + "/";
+//        }
+//        return new URL("file", "", path);
+//    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/input/SAXHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/input/SAXHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/input/SAXHandler.java	(revision 28000)
@@ -0,0 +1,1043 @@
+/*--
+
+ $Id: SAXHandler.java,v 1.73 2007/11/10 05:29:00 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom.input;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.jdom.Attribute;
+import org.jdom.DefaultJDOMFactory;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.EntityRef;
+import org.jdom.JDOMFactory;
+import org.jdom.Namespace;
+import org.jdom.Parent;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.DeclHandler;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * A support class for {@link SAXBuilder}.
+ *
+ * @version $Revision: 1.73 $, $Date: 2007/11/10 05:29:00 $
+ * @author  Brett McLaughlin
+ * @author  Jason Hunter
+ * @author  Philip Nelson
+ * @author  Bradley S. Huffman
+ * @author  phil@triloggroup.com
+ */
+public class SAXHandler extends DefaultHandler implements LexicalHandler,
+                                                          DeclHandler {
+
+    /** Hash table to map SAX attribute type names to JDOM attribute types. */
+    private static final Map attrNameToTypeMap = new HashMap(13);
+
+    /** <code>Document</code> object being built */
+    private Document document;
+
+    /** <code>Element</code> object being built */
+    private Element currentElement;
+
+    /** Indicator of where in the document we are */
+    private boolean atRoot;
+
+    /** Indicator of whether we are in the DocType. Note that the DTD consists
+     * of both the internal subset (inside the <!DOCTYPE> tag) and the
+      * external subset (in a separate .dtd file). */
+    private boolean inDTD = false;
+
+    /** Indicator of whether we are in the internal subset */
+    private boolean inInternalSubset = false;
+
+    /** Indicator of whether we previously were in a CDATA */
+    private boolean previousCDATA = false;
+
+    /** Indicator of whether we are in a CDATA */
+    private boolean inCDATA = false;
+
+    /** Indicator of whether we should expand entities */
+    private boolean expand = true;
+
+    /** Indicator of whether we are actively suppressing (non-expanding) a
+        current entity */
+    private boolean suppress = false;
+
+    /** How many nested entities we're currently within */
+    private int entityDepth = 0;  // XXX may not be necessary anymore?
+
+    /** Temporary holder for namespaces that have been declared with
+      * startPrefixMapping, but are not yet available on the element */
+    private List declaredNamespaces;
+
+    /** Temporary holder for the internal subset */
+    private StringBuffer internalSubset = new StringBuffer();
+
+    /** Temporary holder for Text and CDATA */
+    private TextBuffer textBuffer = new TextBuffer();
+
+    /** The external entities defined in this document */
+    private Map externalEntities;
+
+    /** The JDOMFactory used for JDOM object creation */
+    private JDOMFactory factory;
+
+    /** Whether to ignore ignorable whitespace */
+    private boolean ignoringWhite = false;
+
+    /** Whether to ignore text containing all whitespace */
+    private boolean ignoringBoundaryWhite = false;
+
+    /** The SAX Locator object provided by the parser */
+    private Locator locator;
+
+    /**
+     * Class initializer: Populate a table to translate SAX attribute
+     * type names into JDOM attribute type value (integer).
+     * <p>
+     * <b>Note that all the mappings defined below are compliant with
+     * the SAX 2.0 specification exception for "ENUMERATION" with is
+     * specific to Crimson 1.1.X and Xerces 2.0.0-betaX which report
+     * attributes of enumerated types with a type "ENUMERATION"
+     * instead of the expected "NMTOKEN".
+     * </p>
+     * <p>
+     * Note also that Xerces 1.4.X is not SAX 2.0 compliant either
+     * but handling its case requires
+     * {@link #getAttributeType specific code}.
+     * </p>
+     */
+    static {
+        attrNameToTypeMap.put("CDATA",
+                              new Integer(Attribute.CDATA_TYPE));
+        attrNameToTypeMap.put("ID",
+                              new Integer(Attribute.ID_TYPE));
+        attrNameToTypeMap.put("IDREF",
+                              new Integer(Attribute.IDREF_TYPE));
+        attrNameToTypeMap.put("IDREFS",
+                              new Integer(Attribute.IDREFS_TYPE));
+        attrNameToTypeMap.put("ENTITY",
+                              new Integer(Attribute.ENTITY_TYPE));
+        attrNameToTypeMap.put("ENTITIES",
+                              new Integer(Attribute.ENTITIES_TYPE));
+        attrNameToTypeMap.put("NMTOKEN",
+                              new Integer(Attribute.NMTOKEN_TYPE));
+        attrNameToTypeMap.put("NMTOKENS",
+                              new Integer(Attribute.NMTOKENS_TYPE));
+        attrNameToTypeMap.put("NOTATION",
+                              new Integer(Attribute.NOTATION_TYPE));
+        attrNameToTypeMap.put("ENUMERATION",
+                              new Integer(Attribute.ENUMERATED_TYPE));
+    }
+
+    /**
+     * This will create a new <code>SAXHandler</code> that listens to SAX
+     * events and creates a JDOM Document.  The objects will be constructed
+     * using the default factory.
+     */
+    public SAXHandler() {
+        this(null);
+    }
+
+    /**
+     * This will create a new <code>SAXHandler</code> that listens to SAX
+     * events and creates a JDOM Document.  The objects will be constructed
+     * using the provided factory.
+     *
+     * @param factory <code>JDOMFactory</code> to be used for constructing
+     * objects
+     */
+    public SAXHandler(JDOMFactory factory) {
+        if (factory != null) {
+            this.factory = factory;
+        } else {
+            this.factory = new DefaultJDOMFactory();
+        }
+
+        atRoot = true;
+        declaredNamespaces = new ArrayList();
+        externalEntities = new HashMap();
+
+        document = this.factory.document(null);
+    }
+
+    /**
+     * Returns the document.  Should be called after parsing is complete.
+     *
+     * @return <code>Document</code> - Document that was built
+     */
+    public Document getDocument() {
+        return document;
+    }
+
+    /**
+     * This sets whether or not to expand entities during the build.
+     * A true means to expand entities as normal content.  A false means to
+     * leave entities unexpanded as <code>EntityRef</code> objects.  The
+     * default is true.
+     *
+     * @param expand <code>boolean</code> indicating whether entity expansion
+     * should occur.
+     */
+    public void setExpandEntities(boolean expand) {
+        this.expand = expand;
+    }
+
+    /**
+     * Specifies whether or not the parser should elminate whitespace in
+     * element content (sometimes known as "ignorable whitespace") when
+     * building the document.  Only whitespace which is contained within
+     * element content that has an element only content model will be
+     * eliminated (see XML Rec 3.2.1).  For this setting to take effect
+     * requires that validation be turned on.  The default value of this
+     * setting is <code>false</code>.
+     *
+     * @param ignoringWhite Whether to ignore ignorable whitespace
+     */
+    public void setIgnoringElementContentWhitespace(boolean ignoringWhite) {
+        this.ignoringWhite = ignoringWhite;
+    }
+
+    /**
+     * Specifies whether or not the parser should elminate text() nodes
+     * containing only whitespace when building the document.  See
+     * {@link SAXBuilder#setIgnoringBoundaryWhitespace(boolean)}.
+     *
+     * @param ignoringBoundaryWhite Whether to ignore only whitespace content
+     */
+    public void setIgnoringBoundaryWhitespace(boolean ignoringBoundaryWhite) {
+        this.ignoringBoundaryWhite = ignoringBoundaryWhite;
+    }
+
+    public void startDocument() {
+        if (locator != null) {
+            document.setBaseURI(locator.getSystemId());
+        }
+    }
+
+    /**
+     * This is called when the parser encounters an external entity
+     * declaration.
+     *
+     * @param name entity name
+     * @param publicID public id
+     * @param systemID system id
+     * @throws SAXException when things go wrong
+     */
+    public void externalEntityDecl(String name,
+                                   String publicID, String systemID)
+                                   throws SAXException {
+        // Store the public and system ids for the name
+        externalEntities.put(name, new String[]{publicID, systemID});
+
+        if (!inInternalSubset) return;
+
+        internalSubset.append("  <!ENTITY ")
+              .append(name);
+        appendExternalId(publicID, systemID);
+        internalSubset.append(">\n");
+    }
+
+    /**
+     * This handles an attribute declaration in the internal subset.
+     *
+     * @param eName <code>String</code> element name of attribute
+     * @param aName <code>String</code> attribute name
+     * @param type <code>String</code> attribute type
+     * @param valueDefault <code>String</code> default value of attribute
+     * @param value <code>String</code> value of attribute
+     * @throws SAXException
+     */
+    public void attributeDecl(String eName, String aName, String type,
+                              String valueDefault, String value)
+        throws SAXException {
+
+        if (!inInternalSubset) return;
+
+        internalSubset.append("  <!ATTLIST ")
+              .append(eName)
+              .append(' ')
+              .append(aName)
+              .append(' ')
+              .append(type)
+              .append(' ');
+        if (valueDefault != null) {
+              internalSubset.append(valueDefault);
+        } else {
+            internalSubset.append('\"')
+                  .append(value)
+                  .append('\"');
+        }
+        if ((valueDefault != null) && (valueDefault.equals("#FIXED"))) {
+            internalSubset.append(" \"")
+                  .append(value)
+                  .append('\"');
+        }
+        internalSubset.append(">\n");
+    }
+
+    /**
+     * Handle an element declaration in a DTD.
+     *
+     * @param name <code>String</code> name of element
+     * @param model <code>String</code> model of the element in DTD syntax
+     * @throws SAXException
+     */
+    public void elementDecl(String name, String model) throws SAXException {
+        // Skip elements that come from the external subset
+        if (!inInternalSubset) return;
+
+        internalSubset.append("  <!ELEMENT ")
+              .append(name)
+              .append(' ')
+              .append(model)
+              .append(">\n");
+    }
+
+    /**
+     * Handle an internal entity declaration in a DTD.
+     *
+     * @param name <code>String</code> name of entity
+     * @param value <code>String</code> value of the entity
+     * @throws SAXException
+     */
+    public void internalEntityDecl(String name, String value)
+        throws SAXException {
+
+        // Skip entities that come from the external subset
+        if (!inInternalSubset) return;
+
+        internalSubset.append("  <!ENTITY ");
+        if (name.startsWith("%")) {
+           internalSubset.append("% ").append(name.substring(1));
+        } else {
+           internalSubset.append(name);
+        }
+        internalSubset.append(" \"")
+              .append(value)
+              .append("\">\n");
+    }
+
+    /**
+     * This will indicate that a processing instruction has been encountered.
+     * (The XML declaration is not a processing instruction and will not
+     * be reported.)
+     *
+     * @param target <code>String</code> target of PI
+     * @param data <code>String</code> containing all data sent to the PI.
+     *             This typically looks like one or more attribute value
+     *             pairs.
+     * @throws SAXException when things go wrong
+     */
+    public void processingInstruction(String target, String data)
+        throws SAXException {
+
+        if (suppress) return;
+
+        flushCharacters();
+
+        if (atRoot) {
+            factory.addContent(document, factory.processingInstruction(target, data));
+        } else {
+            factory.addContent(getCurrentElement(),
+                factory.processingInstruction(target, data));
+        }
+    }
+
+    /**
+     * This indicates that an unresolvable entity reference has been
+     * encountered, normally because the external DTD subset has not been
+     * read.
+     *
+     * @param name <code>String</code> name of entity
+     * @throws SAXException when things go wrong
+     */
+    public void skippedEntity(String name)
+        throws SAXException {
+
+        // We don't handle parameter entity references.
+        if (name.startsWith("%")) return;
+
+        flushCharacters();
+
+        factory.addContent(getCurrentElement(), factory.entityRef(name));
+    }
+
+    /**
+     * This will add the prefix mapping to the JDOM
+     * <code>Document</code> object.
+     *
+     * @param prefix <code>String</code> namespace prefix.
+     * @param uri <code>String</code> namespace URI.
+     */
+    public void startPrefixMapping(String prefix, String uri)
+        throws SAXException {
+
+        if (suppress) return;
+
+        Namespace ns = Namespace.getNamespace(prefix, uri);
+        declaredNamespaces.add(ns);
+    }
+
+    /**
+     * This reports the occurrence of an actual element.  It will include
+     * the element's attributes, with the exception of XML vocabulary
+     * specific attributes, such as
+     * <code>xmlns:[namespace prefix]</code> and
+     * <code>xsi:schemaLocation</code>.
+     *
+     * @param namespaceURI <code>String</code> namespace URI this element
+     *                     is associated with, or an empty
+     *                     <code>String</code>
+     * @param localName <code>String</code> name of element (with no
+     *                  namespace prefix, if one is present)
+     * @param qName <code>String</code> XML 1.0 version of element name:
+     *                [namespace prefix]:[localName]
+     * @param atts <code>Attributes</code> list for this element
+     * @throws SAXException when things go wrong
+     */
+    public void startElement(String namespaceURI, String localName,
+                             String qName, Attributes atts)
+                             throws SAXException {
+        if (suppress) return;
+        String prefix = "";
+        
+        // If QName is set, then set prefix and local name as necessary
+        if (!"".equals(qName)) {
+        	int colon = qName.indexOf(':');
+
+        	if (colon > 0) {
+        		prefix = qName.substring(0, colon);
+        	}
+
+        	// If local name is not set, try to get it from the QName
+        	if ((localName == null) || (localName.equals(""))) {
+        		localName = qName.substring(colon + 1);
+        	}
+        }
+        // At this point either prefix and localName are set correctly or
+        // there is an error in the parser.
+
+        Namespace namespace = Namespace.getNamespace(prefix, namespaceURI);
+        Element element = factory.element(localName, namespace);
+
+		// Take leftover declared namespaces and add them to this element's
+		// map of namespaces
+		if (declaredNamespaces.size() > 0) {
+			transferNamespaces(element);
+		}
+
+		flushCharacters();
+
+		if (atRoot) {
+			document.setRootElement(element);  // XXX should we use a factory call?
+			atRoot = false;
+		} else {
+			factory.addContent(getCurrentElement(), element);
+		}
+		currentElement = element;
+
+		// Handle attributes
+		for (int i=0, len=atts.getLength(); i<len; i++) {
+
+			String attPrefix = "";
+			String attLocalName = atts.getLocalName(i);
+			String attQName = atts.getQName(i);
+
+			// If attribute QName is set, then set attribute prefix and
+			// attribute local name as necessary
+			if (!attQName.equals("")) {
+				// Bypass any xmlns attributes which might appear, as we got
+				// them already in startPrefixMapping(). This is sometimes
+				// necessary when SAXHandler is used with another source than
+				// SAXBuilder, as with JDOMResult.
+				if (attQName.startsWith("xmlns:") || attQName.equals("xmlns")) {
+					continue;
+				}
+
+				int attColon = attQName.indexOf(':');
+
+				if (attColon > 0) {
+					attPrefix = attQName.substring(0, attColon);
+				}
+
+				// If localName is not set, try to get it from the QName
+				if ("".equals(attLocalName)) {
+					attLocalName = attQName.substring(attColon + 1);
+				}
+			}
+			// At this point either attPrefix and attLocalName are set
+			// correctly or there is an error in the parser.
+
+			int attType = getAttributeType(atts.getType(i));
+			String attValue = atts.getValue(i);
+			String attURI = atts.getURI(i);
+			
+			if ("xmlns".equals(attLocalName) || 
+					"xmlns".equals(attPrefix) || 
+					"http://www.w3.org/2000/xmlns/".equals(attURI)) {
+				// use the actual Namespace to check too, because, in theory, a
+				// namespace-aware parser does not need to set the qName unless
+				// the namespace-prefixes feature is set as well.
+				continue;
+			}
+
+			// just one thing to sort out....
+			// the prefix for the namespace.
+			if (!"".equals(attURI) && "".equals(attPrefix)) {
+                // the localname and qName are the same, but there is a
+                // Namspace URI. We need to figure out the namespace prefix.
+                // this is an unusual condition. Currently the only known trigger
+                // is when there is a fixed/defaulted attribute from a validating
+                // XMLSchema, and the attribute is in a different namespace
+                // than the rest of the document, this happens whenever there
+                // is an attribute definition that has form="qualified".
+                //  <xs:attribute name="attname" form="qualified" ... />
+                // or the schema sets attributeFormDefault="qualified"
+                Element p = element;
+                // We need to ensure that a particular prefix has not been
+                // overridden at a lower level than what we are expecting.
+                // track all prefixes to ensure they are not changed lower
+                // down.
+                HashSet overrides = new HashSet();
+                uploop: do {
+                    // Search up the Element tree looking for a prefixed namespace
+                    // matching our attURI
+                    if (p.getNamespace().getURI().equals(attURI)
+                            && !overrides.contains(p.getNamespacePrefix())
+                            && !"".equals(element.getNamespace().getPrefix())) {
+                        // we need a prefix. It's impossible to have a namespaced
+                        // attribute if there is no prefix for that attribute.
+                        attPrefix = p.getNamespacePrefix();
+                        break uploop;
+                    }
+                    overrides.add(p.getNamespacePrefix());
+                    for (Iterator it = p.getAdditionalNamespaces().iterator();
+                            it.hasNext(); ) {
+                        Namespace ns = (Namespace)it.next();
+                        if (!overrides.contains(ns.getPrefix())
+                                 && attURI.equals(ns.getURI())) {
+                            attPrefix = ns.getPrefix();
+                            break uploop;
+                        }
+                        overrides.add(ns.getPrefix());
+                    }
+                    for (Iterator it = p.getAttributes().iterator();
+                            it.hasNext(); ) {
+                        Namespace ns = ((Attribute)it.next()).getNamespace();
+                        if (!overrides.contains(ns.getPrefix())
+                                 && attURI.equals(ns.getURI())) {
+                            attPrefix = ns.getPrefix();
+                            break uploop;
+                        }
+                        overrides.add(ns.getPrefix());
+                    }
+                    p = p.getParentElement();
+                } while (p != null);
+                if ("".equals(attPrefix)) {
+                    // we cannot find a 'prevailing' namespace that has a prefix
+                    // that is for this namespace.
+                    // This basically means that there's an XMLSchema, for the
+                    // DEFAULT namespace, and there's a defaulted/fixed
+                    // attribute definition in the XMLSchema that's targeted
+                    // for this namespace,... but, the user has either not
+                    // declared a prefixed version of the namespace, or has
+                    // re-declared the same prefix at a lower level with a
+                    // different namespace.
+                    // All of these things are possible.
+                    // Create some sort of default prefix.
+                    int cnt = 0;
+                    String base = "attns";
+                    String pfx = base + cnt;
+                    while (overrides.contains(pfx)) {
+                        cnt++;
+                        pfx = base + cnt;
+                    }
+                    attPrefix = pfx;
+                }
+			}
+			Namespace attNs = Namespace.getNamespace(attPrefix, attURI);
+				
+            Attribute attribute = factory.attribute(attLocalName, attValue,
+				                                                    attType, attNs);
+			factory.setAttribute(element, attribute);
+		}
+    }
+
+    /**
+     * This will take the supplied <code>{@link Element}</code> and
+     * transfer its namespaces to the global namespace storage.
+     *
+     * @param element <code>Element</code> to read namespaces from.
+     */
+    private void transferNamespaces(Element element) {
+        Iterator i = declaredNamespaces.iterator();
+        while (i.hasNext()) {
+            Namespace ns = (Namespace)i.next();
+            if (ns != element.getNamespace()) {
+                element.addNamespaceDeclaration(ns);
+            }
+        }
+        declaredNamespaces.clear();
+    }
+
+    /**
+     * This will report character data (within an element).
+     *
+     * @param ch <code>char[]</code> character array with character data
+     * @param start <code>int</code> index in array where data starts.
+     * @param length <code>int</code> length of data.
+     * @throws SAXException
+     */
+    public void characters(char[] ch, int start, int length)
+                    throws SAXException {
+
+        if (suppress || (length == 0))
+            return;
+
+        if (previousCDATA != inCDATA) {
+            flushCharacters();
+        }
+
+        textBuffer.append(ch, start, length);
+    }
+
+    /**
+     * Capture ignorable whitespace as text.  If
+     * setIgnoringElementContentWhitespace(true) has been called then this
+     * method does nothing.
+     *
+     * @param ch <code>[]</code> - char array of ignorable whitespace
+     * @param start <code>int</code> - starting position within array
+     * @param length <code>int</code> - length of whitespace after start
+     * @throws SAXException when things go wrong
+     */
+    public void ignorableWhitespace(char[] ch, int start, int length)
+                                                     throws SAXException {
+        if (!ignoringWhite) {
+            characters(ch, start, length);
+        }
+    }
+
+    /**
+     * This will flush any characters from SAX character calls we've
+     * been buffering.
+     *
+     * @throws SAXException when things go wrong
+     */
+    protected void flushCharacters() throws SAXException {
+        if (ignoringBoundaryWhite) {
+            if (!textBuffer.isAllWhitespace()) {
+                flushCharacters(textBuffer.toString());
+            }
+        }
+        else {
+            flushCharacters(textBuffer.toString());
+        }
+        textBuffer.clear();
+    }
+
+    /**
+     * Flush the given string into the document.  This is a protected method
+     * so subclassers can control text handling without knowledge of the
+     * internals of this class.
+     *
+     * @param data string to flush
+     */
+    protected void flushCharacters(String data) throws SAXException {
+        if (data.length() == 0) {
+            previousCDATA = inCDATA;
+            return;
+        }
+
+/**
+ * This is commented out because of some problems with
+ * the inline DTDs that Xerces seems to have.
+if (!inDTD) {
+  if (inEntity) {
+    getCurrentElement().setContent(factory.text(data));
+  } else {
+    getCurrentElement().addContent(factory.text(data));
+}
+*/
+
+        if (previousCDATA) {
+            factory.addContent(getCurrentElement(), factory.cdata(data));
+        }
+        else {
+            factory.addContent(getCurrentElement(), factory.text(data));
+        }
+
+        previousCDATA = inCDATA;
+    }
+
+    /**
+     * Indicates the end of an element
+     * (<code>&lt;/[element name]&gt;</code>) is reached.  Note that
+     * the parser does not distinguish between empty
+     * elements and non-empty elements, so this will occur uniformly.
+     *
+     * @param namespaceURI <code>String</code> URI of namespace this
+     *                     element is associated with
+     * @param localName <code>String</code> name of element without prefix
+     * @param qName <code>String</code> name of element in XML 1.0 form
+     * @throws SAXException when things go wrong
+     */
+    public void endElement(String namespaceURI, String localName,
+                           String qName) throws SAXException {
+
+        if (suppress) return;
+
+        flushCharacters();
+
+        if (!atRoot) {
+            Parent p = currentElement.getParent();
+            if (p instanceof Document) {
+               atRoot = true;
+            }
+            else {
+                currentElement = (Element) p;
+            }
+        }
+        else {
+            throw new SAXException(
+                "Ill-formed XML document (missing opening tag for " +
+                localName + ")");
+        }
+    }
+
+    /**
+     * This will signify that a DTD is being parsed, and can be
+     * used to ensure that comments and other lexical structures
+     * in the DTD are not added to the JDOM <code>Document</code>
+     * object.
+     *
+     * @param name <code>String</code> name of element listed in DTD
+     * @param publicID <code>String</code> public ID of DTD
+     * @param systemID <code>String</code> system ID of DTD
+     */
+    public void startDTD(String name, String publicID, String systemID)
+        throws SAXException {
+
+        flushCharacters(); // Is this needed here?
+
+        factory.addContent(document, factory.docType(name, publicID, systemID));
+        inDTD = true;
+        inInternalSubset = true;
+    }
+
+    /**
+     * This signifies that the reading of the DTD is complete.
+     *
+     * @throws SAXException
+     */
+    public void endDTD() throws SAXException {
+
+        document.getDocType().setInternalSubset(internalSubset.toString());
+        inDTD = false;
+        inInternalSubset = false;
+    }
+
+    public void startEntity(String name) throws SAXException {
+        entityDepth++;
+
+        if (expand || entityDepth > 1) {
+            // Short cut out if we're expanding or if we're nested
+            return;
+        }
+
+        // A "[dtd]" entity indicates the beginning of the external subset
+        if (name.equals("[dtd]")) {
+            inInternalSubset = false;
+            return;
+        }
+
+        // Ignore DTD references, and translate the standard 5
+        if ((!inDTD) &&
+            (!name.equals("amp")) &&
+            (!name.equals("lt")) &&
+            (!name.equals("gt")) &&
+            (!name.equals("apos")) &&
+            (!name.equals("quot"))) {
+
+            if (!expand) {
+                String pub = null;
+                String sys = null;
+                String[] ids = (String[]) externalEntities.get(name);
+                if (ids != null) {
+                  pub = ids[0];  // may be null, that's OK
+                  sys = ids[1];  // may be null, that's OK
+                }
+                /**
+                 * if no current element, this entity belongs to an attribute
+                 * in these cases, it is an error on the part of the parser
+                 * to call startEntity but this will help in some cases.
+                 * See org/xml/sax/ext/LexicalHandler.html#startEntity(java.lang.String)
+                 * for more information
+                 */
+                if (!atRoot) {
+                    flushCharacters();
+                    EntityRef entity = factory.entityRef(name, pub, sys);
+
+                    // no way to tell if the entity was from an attribute or element so just assume element
+                    factory.addContent(getCurrentElement(), entity);
+                }
+                suppress = true;
+            }
+        }
+    }
+
+    public void endEntity(String name) throws SAXException {
+        entityDepth--;
+        if (entityDepth == 0) {
+            // No way are we suppressing if not in an entity,
+            // regardless of the "expand" value
+            suppress = false;
+        }
+        if (name.equals("[dtd]")) {
+            inInternalSubset = true;
+        }
+    }
+
+    /**
+     * Report a CDATA section
+     *
+     * @throws SAXException
+     */
+    public void startCDATA() throws SAXException {
+        if (suppress) return;
+
+        inCDATA = true;
+    }
+
+    /**
+     * Report a CDATA section
+     */
+    public void endCDATA() throws SAXException {
+        if (suppress) return;
+
+        previousCDATA = true;
+        inCDATA = false;
+    }
+
+    /**
+     * This reports that a comments is parsed.  If not in the
+     * DTD, this comment is added to the current JDOM
+     * <code>Element</code>, or the <code>Document</code> itself
+     * if at that level.
+     *
+     * @param ch <code>ch[]</code> array of comment characters.
+     * @param start <code>int</code> index to start reading from.
+     * @param length <code>int</code> length of data.
+     * @throws SAXException
+     */
+    public void comment(char[] ch, int start, int length)
+        throws SAXException {
+
+        if (suppress) return;
+
+        flushCharacters();
+
+        String commentText = new String(ch, start, length);
+        if (inDTD && inInternalSubset && (expand == false)) {
+            internalSubset.append("  <!--")
+                  .append(commentText)
+                  .append("-->\n");
+            return;
+        }
+        if ((!inDTD) && (!commentText.equals(""))) {
+            if (atRoot) {
+                factory.addContent(document, factory.comment(commentText));
+            } else {
+                factory.addContent(getCurrentElement(), factory.comment(commentText));
+            }
+        }
+    }
+
+    /**
+     * Handle the declaration of a Notation in a DTD
+     *
+     * @param name name of the notation
+     * @param publicID the public ID of the notation
+     * @param systemID the system ID of the notation
+     */
+    public void notationDecl(String name, String publicID, String systemID)
+        throws SAXException {
+
+        if (!inInternalSubset) return;
+
+        internalSubset.append("  <!NOTATION ")
+              .append(name);
+        appendExternalId(publicID, systemID);
+        internalSubset.append(">\n");
+    }
+
+    /**
+     * Handler for unparsed entity declarations in the DTD
+     *
+     * @param name <code>String</code> of the unparsed entity decl
+     * @param publicID <code>String</code> of the unparsed entity decl
+     * @param systemID <code>String</code> of the unparsed entity decl
+     * @param notationName <code>String</code> of the unparsed entity decl
+     */
+    public void unparsedEntityDecl(String name, String publicID,
+                                   String systemID, String notationName)
+        throws SAXException {
+
+        if (!inInternalSubset) return;
+
+        internalSubset.append("  <!ENTITY ")
+              .append(name);
+        appendExternalId(publicID, systemID);
+        internalSubset.append(" NDATA ")
+              .append(notationName);
+        internalSubset.append(">\n");
+    }
+
+    /**
+     * Appends an external ID to the internal subset buffer. Either publicID
+     * or systemID may be null, but not both.
+     *
+     * @param publicID the public ID
+     * @param systemID the system ID
+     */
+    private void appendExternalId(String publicID, String systemID) {
+        if (publicID != null) {
+            internalSubset.append(" PUBLIC \"")
+                  .append(publicID)
+                  .append('\"');
+        }
+        if (systemID != null) {
+            if (publicID == null) {
+                internalSubset.append(" SYSTEM ");
+            }
+            else {
+                internalSubset.append(' ');
+            }
+            internalSubset.append('\"')
+                  .append(systemID)
+                  .append('\"');
+        }
+    }
+
+    /**
+     * Returns the being-parsed element.
+     *
+     * @return <code>Element</code> - element being built.
+     * @throws SAXException
+     */
+    public Element getCurrentElement() throws SAXException {
+        if (currentElement == null) {
+            throw new SAXException(
+                "Ill-formed XML document (multiple root elements detected)");
+        }
+        return currentElement;
+    }
+
+    /**
+     * Returns the the JDOM Attribute type value from the SAX 2.0
+     * attribute type string provided by the parser.
+     *
+     * @param typeName <code>String</code> the SAX 2.0 attribute
+     * type string.
+     *
+     * @return <code>int</code> the JDOM attribute type.
+     *
+     * @see Attribute#setAttributeType
+     * @see Attributes#getType
+     */
+    private static int getAttributeType(String typeName) {
+        Integer type = (Integer)(attrNameToTypeMap.get(typeName));
+        if (type == null) {
+            if (typeName != null && typeName.length() > 0 &&
+                typeName.charAt(0) == '(') {
+                // Xerces 1.4.X reports attributes of enumerated type with
+                // a type string equals to the enumeration definition, i.e.
+                // starting with a parenthesis.
+                return Attribute.ENUMERATED_TYPE;
+            }
+            else {
+                return Attribute.UNDECLARED_TYPE;
+            }
+        } else {
+            return type.intValue();
+        }
+    }
+
+    /**
+     * Receives an object for locating the origin of SAX document
+     * events.  This method is invoked by the SAX parser.
+     * <p>
+     * {@link org.jdom.JDOMFactory} implementations can use the
+     * {@link #getDocumentLocator} method to get access to the
+     * {@link Locator} during parse.
+     * </p>
+     *
+     * @param locator <code>Locator</code> an object that can return
+     * the location of any SAX document event.
+     */
+    public void setDocumentLocator(Locator locator) {
+        this.locator = locator;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/input/TextBuffer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/input/TextBuffer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/input/TextBuffer.java	(revision 28000)
@@ -0,0 +1,173 @@
+/*--
+
+ $Id: TextBuffer.java,v 1.10 2007/11/10 05:29:00 jhunter Exp $
+
+ Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows
+    these conditions in the documentation and/or other materials
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom.input;
+
+import org.jdom.*;
+
+/**
+ * A non-public utility class similar to StringBuffer but optimized for XML
+ * parsing where the common case is that you get only one chunk of characters
+ * per text section. TextBuffer stores the first chunk of characters in a
+ * String, which can just be returned directly if no second chunk is received.
+ * Subsequent chunks are stored in a supplemental char array (like StringBuffer
+ * uses). In this case, the returned text will be the first String chunk,
+ * concatenated with the subsequent chunks stored in the char array. This
+ * provides optimal performance in the common case, while still providing very
+ * good performance in the uncommon case. Furthermore, avoiding StringBuffer
+ * means that no extra unused char array space will be kept around after parsing
+ * is through.
+ *
+ * @version $Revision: 1.10 $, $Date: 2007/11/10 05:29:00 $
+ * @author  Bradley S. Huffman
+ * @author  Alex Rosen
+ */
+class TextBuffer {
+
+    /** The first part of the text value (the "prefix"). If null, the
+      * text value is the empty string. */
+    private String prefixString;
+
+    /** The rest of the text value (the "suffix"). Only the first 
+      * code>arraySize</code> characters are valid. */
+    private char[] array;
+
+    /** The size of the rest of the text value. If zero, then only 
+      * code>prefixString</code> contains the text value. */
+    private int arraySize;
+
+    /** Constructor */
+    TextBuffer() {
+        array = new char[4096]; // initial capacity
+        arraySize = 0;
+    }
+
+    /** Append the specified text to the text value of this buffer. */
+    void append(char[] source, int start, int count) {
+        if (prefixString == null) {
+            // This is the first chunk, so we'll store it in the prefix string
+            prefixString = new String(source, start, count);
+        }
+        else {
+            // This is a subsequent chunk, so we'll add it to the char array
+            ensureCapacity(arraySize + count);
+            System.arraycopy(source, start, array, arraySize, count);
+            arraySize += count;
+        }
+    }
+
+    /** Clears the text value and prepares the TextBuffer for reuse. */
+    void clear() {
+        arraySize = 0;
+        prefixString = null;
+    }
+
+    boolean isAllWhitespace() {
+        if ((prefixString == null) || (prefixString.length() == 0)) {
+            return true;
+        }
+
+        int size = prefixString.length();
+        for(int i = 0; i < size; i++) {
+            if ( !Verifier.isXMLWhitespace(prefixString.charAt(i))) {
+                return false;
+            }
+        }
+
+        for(int i = 0; i < arraySize; i++) {
+            if ( !Verifier.isXMLWhitespace(array[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /** Returns the text value stored in the buffer. */
+    public String toString() {
+        if (prefixString == null) {
+            return "";
+        }
+
+        String str = "";
+        if (arraySize == 0) {
+            // Char array is empty, so the text value is just prefixString.
+            str = prefixString;
+        }
+        else {
+            // Char array is not empty, so the text value is prefixString
+            // plus the char array.
+            str = new StringBuffer(prefixString.length() + arraySize)
+                    .append(prefixString)
+                    .append(array, 0, arraySize)
+                    .toString();
+        }
+        return str;
+    }
+
+    // Ensure that the char array has room for at least "csize" characters.
+    private void ensureCapacity(int csize) {
+        int capacity = array.length;
+        if (csize > capacity) {
+            char[] old = array;
+            int nsize = capacity;
+            while (csize > nsize) {
+                nsize += (capacity/2);
+            }
+            array = new char[nsize];
+            System.arraycopy(old, 0, array, 0, arraySize);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/input/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/input/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/input/package.html	(revision 28000)
@@ -0,0 +1,10 @@
+<body>
+
+Classes to build JDOM documents from various sources.  The most common builder
+class is SAXBuilder which constructs a JDOM document using a SAX parser and
+can pull content from files, streams, sockets, readers, and so on.  It can use
+any underlying SAX parser to handle the parsing chores.  SAXHandler provides
+support for SAXBuilder.  DOMBuilder lets you build from a pre-existing DOM
+tree.
+
+</body>
Index: /applications/editors/josm/plugins/opendata/includes/org/jdom/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jdom/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jdom/package.html	(revision 28000)
@@ -0,0 +1,13 @@
+<body>
+
+Classes to represent the components of an XML document.  The Verifier is a
+special class useful in ensuring well-formedness of documents.  The Parent
+interface is implemented by Document and Element exposing their commonality.
+The Content abstract class is extended by all the node types of a document
+except Document itself.
+
+The JDOMFactory interface and DefaultJDOMFactory standard implementation
+provide advanced users with the ability to create subtypes of the org.jdom
+classes.
+
+</body>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ChildCreator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ChildCreator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ChildCreator.java	(revision 28000)
@@ -0,0 +1,122 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+/**
+ * A helper to create children in the schema order.
+ * 
+ * @author Sylvain CUAZ
+ */
+public class ChildCreator {
+
+    private final Element content;
+    private final List<Element> elemsOrder;
+
+    protected ChildCreator(final Element content, final List<Element> children) {
+        if (content == null)
+            throw new NullPointerException("null content");
+        this.content = content;
+        this.elemsOrder = new ArrayList<Element>(children);
+    }
+
+    public final Element getElement() {
+        return this.content;
+    }
+
+    // *** children
+
+    public final Element getChild(Namespace childNS, String childName) {
+        return this.getChild(childNS, childName, false);
+    }
+
+    private final int indexOf(Namespace childNS, String childName) {
+        for (int i = 0; i < this.elemsOrder.size(); i++) {
+            final Element elem = this.elemsOrder.get(i);
+            if (elem.getNamespace().equals(childNS) && elem.getName().equals(childName))
+                return i;
+        }
+        return -1;
+    }
+
+    private final int indexOf(final Element elem) {
+        return this.indexOf(elem.getNamespace(), elem.getName());
+    }
+
+    /**
+     * Trouve l'index ou il faut insérer le fils dans ce document.
+     * 
+     * @param childName le nom du fils que l'on veut insérer.
+     * @return l'index ou il faut l'insérer (s'il est déjà présent son index actuel +1).
+     * @throws IllegalArgumentException if childName is not in {@link #getChildren()}.
+     */
+    @SuppressWarnings("unchecked")
+    private final int findInsertIndex(Namespace childNS, String childName) {
+        // eg 6, for "master-styles"
+        final int idealIndex = indexOf(childNS, childName);
+        if (idealIndex == -1)
+            throw new IllegalArgumentException(childName + " is unknown.");
+        final Element existingChild = this.getChild(childNS, childName);
+        if (existingChild != null)
+            return this.getElement().getChildren().indexOf(existingChild) + 1;
+        // eg [scripts, font-decls, styles, font-face-decls, automatic-styles, body]
+        final List<Element> children = this.getElement().getChildren();
+        final ListIterator<Element> iter = children.listIterator();
+        while (iter.hasNext()) {
+            final Element elem = iter.next();
+            if (indexOf(elem) > idealIndex)
+                // eg indexOf("body") == 7 > 6
+                // eg return 5
+                return iter.previousIndex();
+        }
+        return children.size();
+    }
+
+    /**
+     * Insère cet élément à la bonne place. The child should not be already present.
+     * 
+     * @param child l'élément à insérer, doit être dans TOP_ELEMENTS.
+     */
+    @SuppressWarnings("unchecked")
+    private final void insertChild(Element child) {
+        // on ajoute au bon endroit
+        this.getElement().getChildren().add(this.findInsertIndex(child.getNamespace(), child.getName()), child);
+    }
+
+    /**
+     * Return the asked child, optionally creating it.
+     * 
+     * @param childNS the namespace of the child.
+     * @param childName the name of the child.
+     * @param create whether it should be created in case it doesn't exist.
+     * @return the asked child or <code>null</code> if it doesn't exist and create is
+     *         <code>false</code>
+     */
+    public final Element getChild(Namespace childNS, String childName, boolean create) {
+        Element child = this.getElement().getChild(childName, childNS);
+        if (create && child == null) {
+            child = new Element(childName, childNS);
+            this.insertChild(child);
+        }
+        return child;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ImmutableDocStyledNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ImmutableDocStyledNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ImmutableDocStyledNode.java	(revision 28000)
@@ -0,0 +1,56 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jdom.Document;
+import org.jdom.Element;
+
+public class ImmutableDocStyledNode<S extends StyleStyle, D extends ODDocument> extends StyledNode<S, D> {
+
+    private static final Set<Document> getDocuments(final ODPackage pkg) {
+        final Set<Document> res = new HashSet<Document>();
+        for (final String entry : pkg.getEntries()) {
+            final ODPackageEntry e = pkg.getEntry(entry);
+            if (e.getData() instanceof ODXMLDocument)
+                res.add(pkg.getDocument(entry));
+        }
+        return res;
+    }
+
+    private final D parent;
+
+    /**
+     * Create a new instance. We used to find the {@link StyleStyle} class with reflection but this
+     * was slow.
+     * 
+     * @param parent the parent document.
+     * @param local our XML model.
+     * @param styleClass our class of style, cannot be <code>null</code>.
+     */
+    public ImmutableDocStyledNode(D parent, Element local, final Class<S> styleClass) {
+        super(local, styleClass);
+        this.parent = parent;
+        assert getDocuments(this.parent.getPackage()).contains(local.getDocument()) : "Local not in parent: " + parent;
+    }
+
+    @Override
+    public final D getODDocument() {
+        return this.parent;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODDocument.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODDocument.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODDocument.java	(revision 28000)
@@ -0,0 +1,27 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+/**
+ * An ODF document, like a spreadsheet or a text file.
+ * 
+ * @author Sylvain
+ */
+public interface ODDocument {
+    public XMLVersion getVersion();
+
+    public ODPackage getPackage();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODMeta.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODMeta.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODMeta.java	(revision 28000)
@@ -0,0 +1,162 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+/**
+ * OpenDocument metadata, obtained through {@link ODPackage#getMeta()}.
+ * 
+ * @author Sylvain
+ * @see "section 3 of OpenDocument v1.1"
+ */
+public class ODMeta extends ODNode {
+
+    static ODMeta create(ODXMLDocument parent) {
+        final Element meta = parent.getChild("meta");
+        return meta == null ? null : new ODMeta(meta, parent);
+    }
+
+    private static final Map<XMLVersion, List<Element>> ELEMS_ORDER;
+    static {
+        ELEMS_ORDER = new HashMap<XMLVersion, List<Element>>(2);
+        ELEMS_ORDER.put(XMLVersion.getOOo(), createChildren(XMLVersion.getOOo()));
+        ELEMS_ORDER.put(XMLVersion.getOD(), createChildren(XMLVersion.getOD()));
+    }
+
+    private static final List<Element> createChildren(XMLVersion ins) {
+        final Namespace meta = ins.getMETA();
+        final Namespace dc = ins.getNS("dc");
+        final List<Element> res = new ArrayList<Element>(8);
+        res.add(new Element("generator", meta));
+        res.add(new Element("title", dc));
+        res.add(new Element("description", dc));
+        res.add(new Element("subject", dc));
+        res.add(new Element("keyword", meta));
+        res.add(new Element("initial-creator", meta));
+        res.add(new Element("creator", dc));
+        res.add(new Element("printed-by", meta));
+        res.add(new Element("creation-date", meta));
+        res.add(new Element("date", dc));
+        res.add(new Element("print-date", meta));
+        res.add(new Element("template", meta));
+        res.add(new Element("auto-reload", meta));
+        res.add(new Element("hyperlink-behaviour", meta));
+        res.add(new Element("language", dc));
+        res.add(new Element("editing-cycles", meta));
+        res.add(new Element("editing-duration", meta));
+        res.add(new Element("document-statistic", meta));
+        res.add(new Element("user-defined", meta));
+        return res;
+    }
+
+    // *** instance
+
+    private final ODXMLDocument parent;
+    private final ChildCreator childCreator;
+
+    private ODMeta(final Element elem, ODXMLDocument parent) {
+        super(elem);
+        this.parent = parent;
+        this.childCreator = new ChildCreator(this.getElement(), ELEMS_ORDER.get(this.getNS()));
+    }
+
+    protected final ODXMLDocument getParent() {
+        return this.parent;
+    }
+
+    private final XMLVersion getNS() {
+        return this.getParent().getVersion();
+    }
+
+    public final String getInitialCreator() { // NO_UCD
+        return this.getMetaChild("initial-creator").getTextTrim();
+    }
+
+    public final String getCreator() { // NO_UCD
+        return this.getDCChild("creator").getTextTrim();
+    }
+
+    public final Calendar getCreationDate() { // NO_UCD
+        return this.getDateChild("creation-date", this.getNS().getMETA());
+    }
+
+    public final Calendar getModifDate() { // NO_UCD
+        return this.getDateChild("date", this.getNS().getNS("dc"));
+    }
+
+    public final String getLanguage() { // NO_UCD
+        return this.getDCChild("language").getTextTrim();
+    }
+
+    /**
+     * Return the metadata with the passed name, optionnaly creating it.
+     * 
+     * @param name the name of user metadata.
+     * @param create <code>true</code> if it should be created.
+     * @return the requested metadata, or <code>null</code> if none is found and <code>create</code>
+     *         is <code>false</code>.
+     */
+    public final ODUserDefinedMeta getUserMeta(String name, boolean create) {
+        final Element userElem = ODUserDefinedMeta.getElement(this.getElement(), name, this.getNS());
+        if (userElem != null)
+            return new ODUserDefinedMeta(userElem, this.getParent());
+        else if (create) {
+            final ODUserDefinedMeta res = ODUserDefinedMeta.create(name, this.getParent());
+            this.getElement().addContent(res.getElement());
+            return res;
+        } else
+            return null;
+    }
+
+    // * getChild
+
+    public final Element getMetaChild(final String name) {
+        return this.getChild(name, this.getNS().getMETA());
+    }
+
+    public final Element getDCChild(final String name) {
+        return this.getChild(name, this.getNS().getNS("dc"));
+    }
+
+    private final Element getChild(final String name, final Namespace ns) {
+        return this.childCreator.getChild(ns, name, true);
+    }
+
+    private final Calendar getDateChild(final String name, final Namespace ns) {
+        final String date = this.getChild(name, ns).getTextTrim();
+        if (date.length() == 0)
+            return null;
+        else {
+            final Calendar cal = Calendar.getInstance();
+            try {
+                cal.setTime((Date) OOUtils.DATE_FORMAT.parseObject(date));
+            } catch (ParseException e) {
+                throw new IllegalStateException("wrong date: " + date, e);
+            }
+            return cal;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODNode.java	(revision 28000)
@@ -0,0 +1,39 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+import org.jdom.Element;
+
+/**
+ * A node in an XML document.
+ * 
+ * @author Sylvain
+ */
+public abstract class ODNode {
+
+    private final Element localElement;
+
+    public ODNode(final Element elem) {
+        if (elem == null)
+            throw new NullPointerException();
+        this.localElement = elem;
+    }
+
+    public final Element getElement() {
+        return this.localElement;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODPackage.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODPackage.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODPackage.java	(revision 28000)
@@ -0,0 +1,176 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.jdom.Document;
+import org.jdom.JDOMException;
+import org.jopendocument.util.CopyUtils;
+import org.jopendocument.util.FileUtils;
+
+/**
+ * An OpenDocument package, ie a zip containing XML documents and their associated files.
+ * 
+ * @author ILM Informatique 2 août 2004
+ */
+public class ODPackage {
+
+    private static final Set<String> subdocNames;
+    static {
+        subdocNames = new HashSet<String>();
+        // section 2.1 of OpenDocument-v1.1-os.odt
+        subdocNames.add("content.xml");
+        subdocNames.add("styles.xml");
+        subdocNames.add("meta.xml");
+        subdocNames.add("settings.xml");
+    }
+
+    private final Map<String, ODPackageEntry> files;
+    private File file;
+
+    public ODPackage() {
+        this.files = new HashMap<String, ODPackageEntry>();
+        this.file = null;
+    }
+
+    public ODPackage(ODPackage o) {
+        this();
+        // ATTN this works because, all files are read upfront
+        for (final String name : o.getEntries()) {
+            final ODPackageEntry entry = o.getEntry(name);
+            final Object data = entry.getData();
+            final Object myData;
+            if (data instanceof byte[])
+                // assume byte[] are immutable
+                myData = data;
+            else if (data instanceof ODSingleXMLDocument) {
+                myData = new ODSingleXMLDocument((ODSingleXMLDocument) data, this);
+            } else {
+                myData = CopyUtils.copy(data);
+            }
+            this.putFile(name, myData, entry.getType(), entry.isCompressed());
+        }
+        this.file = o.file;
+    }
+
+    /**
+     * The version of this package, <code>null</code> if it cannot be found (eg this package is
+     * empty, or contains no xml).
+     * 
+     * @return the version of this package, can be <code>null</code>.
+     */
+    public final XMLVersion getVersion() {
+        final ODXMLDocument content = this.getContent();
+        if (content == null)
+            return null;
+        else
+            return content.getVersion();
+    }
+
+
+    // *** getter on files
+
+    public final Set<String> getEntries() {
+        return this.files.keySet();
+    }
+
+    public final ODPackageEntry getEntry(String entry) {
+        return this.files.get(entry);
+    }
+
+    protected final Object getData(String entry) {
+        final ODPackageEntry e = this.getEntry(entry);
+        return e == null ? null : e.getData();
+    }
+
+    public final ODXMLDocument getXMLFile(String xmlEntry) {
+        return (ODXMLDocument) this.getData(xmlEntry);
+    }
+
+    public final ODXMLDocument getXMLFile(final Document doc) {
+        for (final String s : subdocNames) {
+            final ODXMLDocument xmlFile = getXMLFile(s);
+            if (xmlFile != null && xmlFile.getDocument() == doc) {
+                return xmlFile;
+            }
+        }
+        return null;
+    }
+
+    public final ODXMLDocument getContent() {
+        return this.getXMLFile("content.xml");
+    }
+
+    public final ODMeta getMeta() { // NO_UCD
+        final ODMeta meta;
+        if (this.getEntries().contains("meta.xml"))
+            meta = ODMeta.create(this.getXMLFile("meta.xml"));
+        else
+            meta = ODMeta.create(this.getContent());
+        return meta;
+    }
+
+    /** 
+     * Return an XML document.
+     * 
+     * @param xmlEntry the filename, eg "styles.xml".
+     * @return the matching document, or <code>null</code> if there's none.
+     * @throws JDOMException if error about the XML.
+     * @throws IOException if an error occurs while reading the file.
+     */
+    public Document getDocument(String xmlEntry) {
+        final ODXMLDocument xml = this.getXMLFile(xmlEntry);
+        return xml == null ? null : xml.getDocument();
+    }
+
+    // *** setter
+
+    public void putFile(String entry, Object data) {
+        this.putFile(entry, data, null);
+    }
+
+    public void putFile(final String entry, final Object data, final String mediaType) {
+        this.putFile(entry, data, mediaType, true);
+    }
+
+    public void putFile(final String entry, final Object data, final String mediaType, final boolean compress) {
+        if (entry == null)
+            throw new NullPointerException("null name");
+        final Object myData;
+        if (subdocNames.contains(entry)) {
+            final ODXMLDocument oodoc;
+            if (data instanceof Document)
+                oodoc = new ODXMLDocument((Document) data);
+            else
+                oodoc = (ODXMLDocument) data;
+            // si le package est vide n'importe quelle version convient
+            if (this.getVersion() != null && !oodoc.getVersion().equals(this.getVersion()))
+                throw new IllegalArgumentException("version mismatch " + this.getVersion() + " != " + oodoc);
+            myData = oodoc;
+        } else if (data != null && !(data instanceof byte[]))
+            throw new IllegalArgumentException("should be byte[] for " + entry + ": " + data);
+        else
+            myData = data;
+        final String inferredType = mediaType != null ? mediaType : FileUtils.findMimeType(entry);
+        this.files.put(entry, new ODPackageEntry(entry, inferredType, myData, compress));
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODPackageEntry.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODPackageEntry.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODPackageEntry.java	(revision 28000)
@@ -0,0 +1,58 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+/**
+ * An OpenDocument package entry, ie a file or folder inside a zip.
+ */
+public class ODPackageEntry {
+
+    private final String name;
+    private String type;
+    // either byte[] or OOXMLDocument
+    private final Object data;
+    private boolean compressed;
+
+    public ODPackageEntry(String name, String type, Object data, final boolean compressed) {
+        super();
+        this.name = name;
+        this.type = type;
+        this.data = data;
+        this.compressed = compressed;
+    }
+
+    public final String getName() {
+        return this.name;
+    }
+
+    public final String getType() {
+        return this.type;
+    }
+
+    public final Object getData() {
+        return this.data;
+    }
+
+    public final boolean isCompressed() {
+        return this.compressed;
+    }
+
+    @Override
+    public String toString() {
+        return this.getClass().getSimpleName() + " " + getName() + "[" + this.getType() + "]" + getData();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODSingleXMLDocument.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODSingleXMLDocument.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODSingleXMLDocument.java	(revision 28000)
@@ -0,0 +1,81 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * An XML document containing all of an office document, see section 2.1 of OpenDocument 1.1.
+ * 
+ * @author Sylvain CUAZ 24 nov. 2004
+ */
+public class ODSingleXMLDocument extends ODXMLDocument implements Cloneable, ODDocument {
+
+    final static Set<String> DONT_PREFIX;
+    static {
+        DONT_PREFIX = new HashSet<String>();
+        // don't touch to user fields and variables
+        // we want them to be the same across the document
+        DONT_PREFIX.add("user-field-decl");
+        DONT_PREFIX.add("user-field-get");
+        DONT_PREFIX.add("variable-get");
+        DONT_PREFIX.add("variable-decl");
+        DONT_PREFIX.add("variable-set");
+    }
+
+    /**
+     * fix bug when a SingleXMLDoc is used to create a document (for example with P2 and 1_P2), and
+     * then create another instance s2 with the previous document and add a second file (also with
+     * P2 and 1_P2) => s2 will contain P2, 1_P2, 1_P2, 1_1_P2.
+     */
+    private static final String COUNT = "SingleXMLDocument_count";
+
+    /** Le nombre de fichiers concat */
+    private int numero;
+    /** Les styles présent dans ce document */
+    private final Set<String> stylesNames;
+    /** Les styles de liste présent dans ce document */
+    private final Set<String> listStylesNames;
+    /** Les fichiers référencés par ce document */
+    private final ODPackage pkg;
+    private final ODMeta meta;
+
+    ODSingleXMLDocument(ODSingleXMLDocument doc, ODPackage p) {
+        super(doc);
+        this.stylesNames = new HashSet<String>(doc.stylesNames);
+        this.listStylesNames = new HashSet<String>(doc.listStylesNames);
+        this.pkg = p;
+        this.meta = ODMeta.create(this);
+        this.setNumero(doc.numero);
+    }
+
+    @Override
+    public ODSingleXMLDocument clone() {
+        final ODPackage copy = new ODPackage(this.pkg);
+        return (ODSingleXMLDocument) copy.getContent();
+    }
+
+    private void setNumero(int numero) {
+        this.numero = numero;
+        this.meta.getUserMeta(COUNT, true).setValue(this.numero);
+    }
+
+    @Override
+    public ODPackage getPackage() {
+        return this.pkg;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODUserDefinedMeta.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODUserDefinedMeta.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODUserDefinedMeta.java	(revision 28000)
@@ -0,0 +1,101 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+import java.util.EnumSet;
+import java.util.List;
+
+import org.jdom.Attribute;
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+// eg <meta:user-defined meta:name="countOfSomething">5.2</meta:user-defined>
+public class ODUserDefinedMeta extends ODNode {
+
+    private static final String ELEM_NAME = "user-defined";
+
+    static ODUserDefinedMeta create(String name, ODXMLDocument parent) {
+        final Element elem = new Element(ELEM_NAME, parent.getVersion().getMETA());
+        elem.setAttribute("name", name, parent.getVersion().getMETA());
+        final ODUserDefinedMeta res = new ODUserDefinedMeta(elem, parent);
+        res.setValue("");
+        return res;
+    }
+
+    @SuppressWarnings("unchecked")
+    static private List<Element> getChildren(final Element metaElem, final Namespace metaNS) {
+        return metaElem.getChildren(ELEM_NAME, metaNS);
+    }
+
+    static Element getElement(final Element metaElem, String name, final XMLVersion ns) {
+        final Namespace metaNS = ns.getMETA();
+        for (final Element elem : getChildren(metaElem, metaNS)) {
+            if (name.equals(elem.getAttributeValue("name", metaNS)))
+                return elem;
+        }
+        return null;
+    }
+
+    private static final EnumSet<ODValueType> allowedTypes = EnumSet.of(ODValueType.FLOAT, ODValueType.DATE, ODValueType.TIME, ODValueType.BOOLEAN, ODValueType.STRING);
+
+    private final ODXMLDocument parent;
+
+    ODUserDefinedMeta(final Element elem, ODXMLDocument parent) {
+        super(elem);
+        this.parent = parent;
+    }
+
+    protected final ODXMLDocument getParent() {
+        return this.parent;
+    }
+
+    private final XMLVersion getNS() {
+        return this.getParent().getVersion();
+    }
+
+    private final Attribute getValueTypeAttr() {
+        return getValueTypeAttr(true);
+    }
+
+    private final Attribute getValueTypeAttr(boolean create) {
+        Attribute res = this.getElement().getAttribute("value-type", this.getNS().getMETA());
+        // oo don't put value-type for strings (eg File/Properties/User)
+        if (res == null && create) {
+            res = new Attribute("value-type", ODValueType.STRING.getName(), this.getNS().getMETA());
+            this.getElement().setAttribute(res);
+        }
+        return res;
+    }
+
+    public final void setValue(Object o) {
+        this.setValue(o, ODValueType.forObject(o));
+    }
+
+    public final void setValue(Object o, final ODValueType vt) {
+        if (!allowedTypes.contains(vt))
+            throw new IllegalArgumentException(vt + " is not allowed: " + allowedTypes);
+        if (vt != ODValueType.STRING)
+            this.getValueTypeAttr().setValue(vt.getName());
+        else {
+            // OOo doesn't support value types
+            final Attribute attr = this.getValueTypeAttr(false);
+            if (attr != null)
+                attr.detach();
+        }
+        this.getElement().setText(vt.format(o));
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODValueType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODValueType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODValueType.java	(revision 28000)
@@ -0,0 +1,224 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+import java.math.BigDecimal;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * A type of value, as per 16.1 "Data Types" and 6.7.1 "Variable Value Types and Values"
+ */
+public enum ODValueType {
+
+    /**
+     * Parses to {@link BigDecimal} to return the exact number.
+     */
+    FLOAT("value", Number.class) {
+
+        @Override
+        public String format(Object o) {
+            // avoid 1.23E+3
+            if (o instanceof BigDecimal)
+                return ((BigDecimal) o).toPlainString();
+            else
+                return ((Number) o).toString();
+        }
+
+        @Override
+        public BigDecimal parse(String s) {
+            return new BigDecimal(s);
+        }
+
+    },
+    PERCENTAGE("value", Number.class) {
+
+        @Override
+        public String format(Object o) {
+            return FLOAT.format(o);
+        }
+
+        @Override
+        public Object parse(String s) {
+            return FLOAT.parse(s);
+        }
+
+    },
+    CURRENCY("value", Number.class) {
+
+        @Override
+        public String format(Object o) {
+            return FLOAT.format(o);
+        }
+
+        @Override
+        public Object parse(String s) {
+            return FLOAT.parse(s);
+        }
+    },
+    DATE("date-value", Date.class, Calendar.class) {
+
+        @Override
+        public String format(Object o) {
+            final Date d = o instanceof Calendar ? ((Calendar) o).getTime() : (Date) o;
+            return OOUtils.DATE_FORMAT.format(d);
+        }
+
+        @Override
+        public Date parse(String date) {
+            if (date.length() == 0)
+                return null;
+            else {
+                try {
+                    return (Date) OOUtils.DATE_FORMAT.parseObject(date);
+                } catch (ParseException e) {
+                    throw new IllegalStateException("wrong date: " + date, e);
+                }
+            }
+        }
+
+    },
+    TIME("time-value", Calendar.class) {
+        // FIXME
+        @Override
+        public String format(Object o) {
+            final Calendar cal = (Calendar) o;
+            // adjust the format TZ to the calendar's
+            // that way even you pass a non default Calendar, if you did
+            // myCal.set(HOUR_OF_DAY, 22), the string will have "22H"
+            final SimpleDateFormat fmt = (SimpleDateFormat) OOUtils.TIME_FORMAT.clone();
+            fmt.setTimeZone(cal.getTimeZone());
+            return fmt.format(cal.getTime());
+        }
+
+        @Override
+        public Calendar parse(String date) {
+            if (date.length() == 0)
+                return null;
+            else {
+                // take the calendar from the format, that way if date contains "22H"
+                // returnedCal.get(HOUR_OF_DAY) will return 22 (even if TIME_FORMAT wasn't set to
+                // the default TZ)
+                final Calendar cal = (Calendar) OOUtils.TIME_FORMAT.getCalendar().clone();
+                try {
+                    cal.setTime((Date) OOUtils.TIME_FORMAT.parseObject(date));
+                } catch (ParseException e) {
+                    throw new IllegalStateException("wrong date: " + date, e);
+                }
+                return cal;
+            }
+        }
+
+    },
+    BOOLEAN("boolean-value", Boolean.class) {
+
+        @Override
+        public String format(Object o) {
+            return ((Boolean) o).toString().toLowerCase();
+        }
+
+        @Override
+        public Boolean parse(String s) {
+            return Boolean.valueOf(s);
+        }
+
+    },
+    STRING("string-value", String.class) {
+
+        @Override
+        public String format(Object o) {
+            return o.toString();
+        }
+
+        @Override
+        public String parse(String s) {
+            return s;
+        }
+    };
+
+    private final String attr;
+    private final List<Class<?>> acceptedClasses;
+
+    private ODValueType(String attr, Class<?>... classes) {
+        this.attr = attr;
+        this.acceptedClasses = Arrays.asList(classes);
+    }
+
+    /**
+     * The name of the value attribute for this value type.
+     * 
+     * @return the value attribute, eg "boolean-value".
+     */
+    public final String getValueAttribute() {
+        return this.attr;
+    }
+
+    public boolean canFormat(Class<?> toFormat) {
+        for (final Class<?> c : this.acceptedClasses)
+            if (c.isAssignableFrom(toFormat))
+                return true;
+        return false;
+    }
+
+    public abstract String format(Object o);
+
+    public abstract Object parse(String s);
+
+    /**
+     * The value for the value-type attribute.
+     * 
+     * @return the value for the value-type attribute, eg "float".
+     */
+    public final String getName() {
+        return this.name().toLowerCase();
+    }
+
+    /**
+     * The instance for the passed value type.
+     * 
+     * @param name the value of the value-type attribute, eg "date".
+     * @return the corresponding instance, eg {@link #DATE}.
+     */
+    public static ODValueType get(String name) {
+        return ODValueType.valueOf(name.toUpperCase());
+    }
+
+    /**
+     * Try to guess the value type for the passed object.
+     * 
+     * @param o the object.
+     * @return a value type capable of formatting <code>o</code> or <code>null</code>.
+     */
+    public static ODValueType forObject(Object o) {
+        if (o instanceof Number)
+            return FLOAT;
+        else if (o instanceof Boolean)
+            return BOOLEAN;
+        else if (o instanceof String)
+            return STRING;
+        else if (o instanceof Calendar && !((Calendar) o).isSet(Calendar.DATE))
+            return TIME;
+        else if (DATE.canFormat(o.getClass()))
+            return DATE;
+        else
+            return null;
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODXMLDocument.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODXMLDocument.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/ODXMLDocument.java	(revision 28000)
@@ -0,0 +1,120 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+/*
+ * Créé le 28 oct. 2004
+ */
+package org.jopendocument.dom;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+/**
+ * An OpenDocument XML document, like content.xml ou styles.xml.
+ * 
+ * @author Sylvain CUAZ
+ */
+public class ODXMLDocument {
+
+    /**
+     * All top-level elements that an office document may contain. Note that only the single xml
+     * representation (office:document) contains all of them.
+     */
+    private static final Map<XMLVersion, List<Element>> ELEMS_ORDER;
+    static {
+        ELEMS_ORDER = new HashMap<XMLVersion, List<Element>>(2);
+        ELEMS_ORDER.put(XMLVersion.getOOo(), createChildren(XMLVersion.getOOo()));
+        ELEMS_ORDER.put(XMLVersion.getOD(), createChildren(XMLVersion.getOD()));
+    }
+
+    private static final List<Element> createChildren(XMLVersion ins) {
+        final Namespace ns = ins.getOFFICE();
+        final List<Element> res = new ArrayList<Element>(8);
+        res.add(new Element("meta", ns));
+        res.add(new Element("settings", ns));
+        res.add(new Element("script", ns));
+        res.add(new Element("font-decls", ns));
+        res.add(new Element("styles", ns));
+        res.add(new Element("automatic-styles", ns));
+        res.add(new Element("master-styles", ns));
+        res.add(new Element("body", ns));
+        return res;
+    }
+
+    // namespaces for the name attributes
+    static private final Map<String, String> namePrefixes;
+    static {
+        namePrefixes = new HashMap<String, String>();
+        namePrefixes.put("table:table", "table");
+        namePrefixes.put("text:a", "office");
+        namePrefixes.put("draw:text-box", "draw");
+        namePrefixes.put("draw:image", "draw");
+        namePrefixes.put("draw:frame", "draw");
+    }
+
+    private final Document content;
+    private final XMLVersion version;
+    private final ChildCreator childCreator;
+
+    // before making it public, assure that content is really of version "version"
+    // eg by checking some namespace
+    protected ODXMLDocument(final Document content, final XMLVersion version) {
+        if (content == null)
+            throw new NullPointerException("null document");
+        this.content = content;
+        this.version = version;
+        this.childCreator = new ChildCreator(this.content.getRootElement(), ELEMS_ORDER.get(this.getVersion()));
+    }
+
+    public ODXMLDocument(Document content) {
+        this(content, XMLVersion.getVersion(content.getRootElement()));
+    }
+
+    public ODXMLDocument(ODXMLDocument doc) {
+        this((Document) doc.content.clone(), doc.version);
+    }
+
+    public Document getDocument() {
+        return this.content;
+    }
+
+    public final XMLVersion getVersion() {
+        return this.version;
+    }
+
+    // *** children
+    
+    public final Element getChild(String childName) {
+        return this.getChild(childName, false);
+    }
+
+    /**
+     * Return the asked child, optionally creating it.
+     * 
+     * @param childName the name of the child.
+     * @param create whether it should be created in case it doesn't exist.
+     * @return the asked child or <code>null</code> if it doesn't exist and create is
+     *         <code>false</code>
+     */
+    public Element getChild(String childName, boolean create) {
+        return this.childCreator.getChild(this.getVersion().getOFFICE(), childName, create);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/OOUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/OOUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/OOUtils.java	(revision 28000)
@@ -0,0 +1,36 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+import java.text.Format;
+import java.text.SimpleDateFormat;
+
+import org.jopendocument.util.FormatGroup;
+import org.jopendocument.util.XMLDateFormat;
+
+public class OOUtils {
+    // as per 16.1 "Data Types" and 6.7.1 "Variable Value Types and Values"
+    // see http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#isoformats
+
+    // time means Duration for OpenDocument (see 6.7.1)
+    public static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("'PT'HH'H'mm'M'ss'S'");
+    static public final Format DATE_FORMAT;
+    static {
+        // first date and time so we don't loose time information on format() or parse()
+        // MAYBE add HH':'mm':'ss,SSS for OOo 1
+        DATE_FORMAT = new FormatGroup(new XMLDateFormat(), new SimpleDateFormat("yyyy-MM-dd'T'HH':'mm':'ss"), new SimpleDateFormat("yyyy-MM-dd"));
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/StyleDesc.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/StyleDesc.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/StyleDesc.java	(revision 28000)
@@ -0,0 +1,111 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.jdom.Element;
+import org.jopendocument.util.CollectionMap;
+
+/**
+ * Describe a family of style.
+ * 
+ * @author Sylvain CUAZ
+ * 
+ * @param <S> type of style
+ */
+public abstract class StyleDesc<S extends StyleStyle> {
+
+    public static <C extends StyleStyle> StyleDesc<C> copy(final StyleDesc<C> toClone, final XMLVersion version) {
+        final StyleDesc<C> res = new StyleDesc<C>(toClone.getStyleClass(), version, toClone.getFamily(), toClone.getBaseName()) {
+            @Override
+            public C create(ODPackage pkg, Element e) {
+                return toClone.create(pkg, e);
+            }
+        };
+        res.getRefElementsMap().putAll(toClone.getRefElementsMap());
+        res.getMultiRefElementsMap().putAll(toClone.getMultiRefElementsMap());
+        return res;
+    }
+
+    private final Class<S> clazz;
+    // need version since each one might have different attributes and elements (plus we need it
+    // anyway for the XPath, otherwise it fails when searching for an inexistant namespace)
+    private final XMLVersion version;
+    private final String family, baseName;
+    // { attribute -> element }
+    private final CollectionMap<String, String> refElements;
+    private final CollectionMap<String, String> multiRefElements;
+
+    protected StyleDesc(final Class<S> clazz, final XMLVersion version, String family, String baseName, String ns) {
+        this(clazz, version, family, baseName, ns, Collections.singletonList(ns + ":" + family));
+    }
+
+    protected StyleDesc(final Class<S> clazz, final XMLVersion version, String family, String baseName, String ns, final List<String> refQNames) {
+        this(clazz, version, family, baseName);
+        this.getRefElementsMap().putAll(ns + ":style-name", refQNames);
+    }
+
+    protected StyleDesc(final Class<S> clazz, final XMLVersion version, String family, String baseName) {
+        super();
+        this.clazz = clazz;
+        this.version = version;
+        this.family = family;
+        this.baseName = baseName;
+        this.refElements = new CollectionMap<String, String>();
+        // 4 since they are not common
+        this.multiRefElements = new CollectionMap<String, String>(4);
+    }
+
+    public abstract S create(ODPackage pkg, Element e);
+
+    final Class<S> getStyleClass() {
+        return this.clazz;
+    }
+
+    public final XMLVersion getVersion() {
+        return this.version;
+    }
+
+    public final String getFamily() {
+        return this.family;
+    }
+
+    public final String getBaseName() {
+        return this.baseName;
+    }
+
+    /**
+     * The list of elements that can point to this family of style.
+     * 
+     * @return a list of qualified names, e.g. ["text:h", "text:p"].
+     */
+    protected final Collection<String> getRefElements() {
+        return this.getRefElementsMap().values();
+    }
+
+    // e.g. { "text:style-name" -> ["text:h", "text:p"] }
+    protected final CollectionMap<String, String> getRefElementsMap() {
+        return this.refElements;
+    }
+
+    // e.g. { "table:default-cell-style-name" -> ["table:table-column", "table:table-row"] }
+    protected final CollectionMap<String, String> getMultiRefElementsMap() {
+        return this.multiRefElements;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/StyleStyle.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/StyleStyle.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/StyleStyle.java	(revision 28000)
@@ -0,0 +1,139 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+import org.jopendocument.dom.spreadsheet.CellStyle;
+import org.jopendocument.dom.spreadsheet.ColumnStyle;
+import org.jopendocument.dom.spreadsheet.RowStyle;
+import org.jopendocument.dom.spreadsheet.TableStyle;
+
+/**
+ * A style:style, see section 14.1. Maintains a map of family to classes.
+ * 
+ * @author Sylvain
+ */
+public class StyleStyle extends ODNode {
+
+    private static final Map<XMLVersion, Map<String, StyleDesc<?>>> family2Desc;
+    private static final Map<XMLVersion, Map<Class<? extends StyleStyle>, StyleDesc<?>>> class2Desc;
+    private static boolean descsLoaded = false;
+    static {
+        family2Desc = new HashMap<XMLVersion, Map<String, StyleDesc<?>>>();
+        class2Desc = new HashMap<XMLVersion, Map<Class<? extends StyleStyle>, StyleDesc<?>>>();
+        for (final XMLVersion v : XMLVersion.values()) {
+            family2Desc.put(v, new HashMap<String, StyleDesc<?>>());
+            class2Desc.put(v, new HashMap<Class<? extends StyleStyle>, StyleDesc<?>>());
+        }
+    }
+
+    // lazy initialization to avoid circular dependency (i.e. ClassLoader loads PStyle.DESC which
+    // loads StyleStyle which needs PStyle.DESC)
+    private static void loadDescs() {
+        if (!descsLoaded) {
+            registerAllVersions(CellStyle.DESC);
+            registerAllVersions(RowStyle.DESC);
+            registerAllVersions(ColumnStyle.DESC);
+            registerAllVersions(TableStyle.DESC);
+            descsLoaded = true;
+        }
+    }
+
+    // until now styles have remained constant through versions
+    private static void registerAllVersions(StyleDesc<? extends StyleStyle> desc) {
+        for (final XMLVersion v : XMLVersion.values()) {
+            if (v == desc.getVersion())
+                register(desc);
+            else
+                register(StyleDesc.copy(desc, v));
+        }
+    }
+
+    public static void register(StyleDesc<? extends StyleStyle> desc) {
+        if (family2Desc.get(desc.getVersion()).put(desc.getFamily(), desc) != null)
+            throw new IllegalStateException(desc.getFamily() + " duplicate");
+        if (class2Desc.get(desc.getVersion()).put(desc.getStyleClass(), desc) != null)
+            throw new IllegalStateException(desc.getStyleClass() + " duplicate");
+    }
+
+    static <S extends StyleStyle> StyleDesc<S> getStyleDesc(Class<S> clazz, final XMLVersion version) {
+        return getStyleDesc(clazz, version, true);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <S extends StyleStyle> StyleDesc<S> getStyleDesc(Class<S> clazz, final XMLVersion version, final boolean mustExist) {
+        loadDescs();
+        final Map<Class<? extends StyleStyle>, StyleDesc<?>> map = class2Desc.get(version);
+        if (map.containsKey(clazz))
+            return (StyleDesc<S>) map.get(clazz);
+        else if (mustExist)
+            throw new IllegalArgumentException("unregistered " + clazz + " for version " + version);
+        else
+            return null;
+    }
+
+    private final StyleDesc<?> desc;
+    private final ODPackage pkg;
+    private final String name, family;
+    private final XMLVersion ns;
+
+    public StyleStyle(final ODPackage pkg, final Element styleElem) {
+        super(styleElem);
+        this.pkg = pkg;
+        this.name = this.getElement().getAttributeValue("name", this.getSTYLE());
+        this.family = this.getElement().getAttributeValue("family", this.getSTYLE());
+        this.ns = this.pkg.getVersion();
+        this.desc = getStyleDesc(this.getClass(), this.ns, false);
+        if (this.desc != null && !this.desc.getFamily().equals(this.getFamily()))
+            throw new IllegalArgumentException("expected " + this.desc.getFamily() + " but got " + this.getFamily() + " for " + styleElem);
+        // assert that styleElem is in pkg (and thus have the same version)
+        assert this.pkg.getXMLFile(getElement().getDocument()) != null;
+        assert this.pkg.getVersion() == XMLVersion.getVersion(getElement());
+    }
+
+    protected final Namespace getSTYLE() {
+        return this.getElement().getNamespace("style");
+    }
+
+    public final XMLVersion getNS() { // NO_UCD
+        return this.ns;
+    }
+
+    public final String getName() {
+        return this.name;
+    }
+
+    public final String getFamily() {
+        return this.family;
+    }
+
+    @Override
+    public final boolean equals(Object obj) {
+        if (!(obj instanceof StyleStyle))
+            return false;
+        final StyleStyle o = (StyleStyle) obj;
+        return this.getName().equals(o.getName()) && this.getFamily().equals(o.getFamily());
+    }
+
+    @Override
+    public int hashCode() {
+        return this.getName().hashCode() + this.getFamily().hashCode();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/StyledNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/StyledNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/StyledNode.java	(revision 28000)
@@ -0,0 +1,54 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+import org.jdom.Element;
+
+/**
+ * A node with a style.
+ * 
+ * @author Sylvain CUAZ
+ * 
+ * @param <S> type of style.
+ * @param <D> type of document.
+ */
+public abstract class StyledNode<S extends StyleStyle, D extends ODDocument> extends ODNode {
+
+    private final StyleDesc<S> styleClass;
+
+    /**
+     * Create a new instance. We used to find the {@link StyleStyle} class with reflection but this
+     * was slow.
+     * 
+     * @param local our XML model.
+     * @param styleClass our class of style, cannot be <code>null</code>.
+     */
+    public StyledNode(Element local, final Class<S> styleClass) {
+        super(local);
+        if (styleClass == null)
+            throw new NullPointerException("null style class");
+        this.styleClass = StyleStyle.getStyleDesc(styleClass, XMLVersion.getVersion(getElement()));
+        assert this.styleClass.getRefElements().contains(this.getElement().getQualifiedName()) : this.getElement().getQualifiedName() + " not in " + this.styleClass;
+    }
+
+    // can be null if this node wasn't created from a document (eg new Paragraph())
+    public abstract D getODDocument();
+
+    // some nodes have more complicated ways of finding their style (eg Cell)
+    protected String getStyleName() {
+        return this.getElement().getAttributeValue("style-name", this.getElement().getNamespace());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/XMLVersion.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/XMLVersion.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/XMLVersion.java	(revision 28000)
@@ -0,0 +1,170 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+/**
+ * Encapsulate all namespaces for a particular version of xml.
+ * 
+ * @author ILM Informatique 26 juil. 2004
+ */
+public enum XMLVersion {
+
+    // OpenOffice.org 1.x.
+    OOo("OpenOffice.org", Namespace.getNamespace("manifest", "http://openoffice.org/2001/manifest")) {
+        {
+            this.putMandatory(OFFICE_1, STYLE_1, TEXT_1, TABLE_1);
+            this.put("number", NUMBER_1);
+            this.put("draw", DRAW_1);
+            this.put("number", NUMBER_1);
+            this.put("fo", FO_1);
+            this.put("form", "http://openoffice.org/2000/form");
+            this.put("xlink", "http://www.w3.org/1999/xlink");
+            this.put("script", "http://openoffice.org/2000/script");
+            this.put("svg", "http://www.w3.org/2000/svg");
+            this.put("meta", "http://openoffice.org/2000/meta");
+            this.put("dc", "http://purl.org/dc/elements/1.1/");
+        }
+    },
+    // OpenDocument 1.x/OpenOffice.org 2.x.
+    OD("OpenDocument", Namespace.getNamespace("manifest", "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0")) {
+        {
+            this.putMandatory(OFFICE_2, STYLE_2, TEXT_2, TABLE_2);
+            this.put("number", NUMBER_2);
+            this.put("draw", DRAW_2);
+            this.put("number", NUMBER_2);
+            this.put("fo", FO_2);
+            this.put("form", "urn:oasis:names:tc:opendocument:xmlns:form:1.0");
+            this.put("xlink", "http://www.w3.org/1999/xlink");
+            this.put("script", "urn:oasis:names:tc:opendocument:xmlns:script:1.0");
+            this.put("svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0");
+            this.put("meta", "urn:oasis:names:tc:opendocument:xmlns:meta:1.0");
+            this.put("dc", "http://purl.org/dc/elements/1.1/");
+        }
+    };
+
+    private static final String OFFICE_1 = "http://openoffice.org/2000/office";
+    private static final String STYLE_1 = "http://openoffice.org/2000/style";
+    private static final String TEXT_1 = "http://openoffice.org/2000/text";
+    private static final String NUMBER_1 = "http://openoffice.org/2000/datastyle";
+    private static final String TABLE_1 = "http://openoffice.org/2000/table";
+    private static final String DRAW_1 = "http://openoffice.org/2000/drawing";
+    private static final String FO_1 = "http://www.w3.org/1999/XSL/Format";
+
+    private static final String OFFICE_2 = "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
+    private static final String STYLE_2 = "urn:oasis:names:tc:opendocument:xmlns:style:1.0";
+    private static final String TEXT_2 = "urn:oasis:names:tc:opendocument:xmlns:text:1.0";
+    private static final String NUMBER_2 = "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0";
+    private static final String TABLE_2 = "urn:oasis:names:tc:opendocument:xmlns:table:1.0";
+    private static final String DRAW_2 = "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0";
+    private static final String FO_2 = "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0";
+
+    private final Map<String, Namespace> nss;
+
+    private XMLVersion(String name, Namespace manifest) {
+        this.nss = new HashMap<String, Namespace>(16);
+    }
+
+    protected final void putMandatory(String office, String style, String text, String table) {
+        this.put("office", office);
+        this.put("style", style);
+        this.put("text", text);
+        this.put("table", table);
+    }
+
+    protected final void put(String prefix, String uri) {
+        this.nss.put(prefix, Namespace.getNamespace(prefix, uri));
+    }
+
+    public final Namespace getNS(String prefix) {
+        if (!this.nss.containsKey(prefix))
+            throw new IllegalStateException("unknown " + prefix + " : " + this.nss.keySet());
+        return this.nss.get(prefix);
+    }
+
+    public Namespace getOFFICE() {
+        return this.getNS("office");
+    }
+
+    public Namespace getSTYLE() { // NO_UCD
+        return this.getNS("style");
+    }
+
+    public Namespace getTEXT() { // NO_UCD
+        return this.getNS("text");
+    }
+
+    public Namespace getTABLE() {
+        return this.getNS("table");
+    }
+
+    public Namespace getMETA() {
+        return this.getNS("meta");
+    }
+
+    // *** static public
+
+    /**
+     * Namespaces for OpenOffice.org 1.x.
+     * 
+     * @return namespaces for OO.o 1.
+     */
+    public static final XMLVersion getOOo() {
+        return OOo;
+    }
+
+    /**
+     * Namespaces for OpenDocument/OpenOffice.org 2.x.
+     * 
+     * @return namespaces for OpenDocument.
+     */
+    public static final XMLVersion getOD() {
+        return OD;
+    }
+
+    /**
+     * Find the NS to which belongs the passed namespace.
+     * 
+     * @param ns the namespace, eg office=http://openoffice.org/2000/office.
+     * @return the matching NS, eg NS.getOOo(), or <code>null</code> if none is found.
+     */
+    public static final XMLVersion getParent(Namespace ns) {
+        for (XMLVersion v : values()) {
+            if (v.getNS(ns.getPrefix()).equals(ns))
+                return v;
+        }
+        return null;
+    }
+
+    /**
+     * Infer the version of an XML element from its namespace.
+     * 
+     * @param elem the element to be tested, eg &lt;text:line-break/&gt;.
+     * @return the version.
+     * @throws IllegalArgumentException if the namespace is unknown.
+     */
+    public static final XMLVersion getVersion(Element elem) {
+        final XMLVersion parent = getParent(elem.getNamespace());
+        if (parent == null)
+            throw new IllegalArgumentException(elem + " is not an OpenOffice element.");
+        return parent;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/classDiag.violet
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/classDiag.violet	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/classDiag.violet	(revision 28000)
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?> 
+<java version="1.6.0_15" class="java.beans.XMLDecoder"> 
+ <object class="com.horstmann.violet.ClassDiagramGraph"> 
+  <void method="addNode"> 
+   <object id="ClassNode0" class="com.horstmann.violet.ClassNode"> 
+    <void property="attributes"> 
+     <void property="text"> 
+      <string>file</string> 
+     </void> 
+    </void> 
+    <void property="methods"> 
+     <void property="text"> 
+      <string>getVersion
+getContentType
+getMimeType
+getBinaryFile
+getXMLFile
+getDocument
+putFile
+toSingle
+save
+</string> 
+     </void> 
+    </void> 
+    <void property="name"> 
+     <void property="text"> 
+      <string>ODPackage</string> 
+     </void> 
+    </void> 
+   </object> 
+   <object class="java.awt.geom.Point2D$Double"> 
+    <void method="setLocation"> 
+     <double>33.0</double> 
+     <double>27.0</double> 
+    </void> 
+   </object> 
+  </void> 
+  <void method="addNode"> 
+   <object id="ClassNode1" class="com.horstmann.violet.ClassNode"> 
+    <void property="methods"> 
+     <void property="text"> 
+      <string>add
+saveAs</string> 
+     </void> 
+    </void> 
+    <void property="name"> 
+     <void property="text"> 
+      <string>OOSingleXMLDocument</string> 
+     </void> 
+    </void> 
+   </object> 
+   <object class="java.awt.geom.Point2D$Double"> 
+    <void method="setLocation"> 
+     <double>283.0</double> 
+     <double>294.0</double> 
+    </void> 
+   </object> 
+  </void> 
+  <void method="addNode"> 
+   <object id="ClassNode2" class="com.horstmann.violet.ClassNode"> 
+    <void property="methods"> 
+     <void property="text"> 
+      <string>getDocument
+getVersion
+getChild
+setChild</string> 
+     </void> 
+    </void> 
+    <void property="name"> 
+     <void property="text"> 
+      <string>OOXMLDocument</string> 
+     </void> 
+    </void> 
+   </object> 
+   <object class="java.awt.geom.Point2D$Double"> 
+    <void method="setLocation"> 
+     <double>308.0</double> 
+     <double>63.0</double> 
+    </void> 
+   </object> 
+  </void> 
+  <void method="connect"> 
+   <object class="com.horstmann.violet.ClassRelationshipEdge"> 
+    <void property="bentStyle"> 
+     <object class="com.horstmann.violet.BentStyle" field="VHV"/> 
+    </void> 
+    <void property="endArrowHead"> 
+     <object class="com.horstmann.violet.ArrowHead" field="TRIANGLE"/> 
+    </void> 
+   </object> 
+   <object idref="ClassNode1"/> 
+   <object idref="ClassNode2"/> 
+  </void> 
+  <void method="connect"> 
+   <object class="com.horstmann.violet.ClassRelationshipEdge"> 
+    <void property="bentStyle"> 
+     <object class="com.horstmann.violet.BentStyle" field="HVH"/> 
+    </void> 
+    <void property="endArrowHead"> 
+     <object class="com.horstmann.violet.ArrowHead" field="V"/> 
+    </void> 
+    <void property="endLabel"> 
+     <string>getXMLFile()</string> 
+    </void> 
+    <void property="lineStyle"> 
+     <object class="com.horstmann.violet.LineStyle" field="DOTTED"/> 
+    </void> 
+   </object> 
+   <object idref="ClassNode0"/> 
+   <object idref="ClassNode2"/> 
+  </void> 
+  <void method="connect"> 
+   <object class="com.horstmann.violet.ClassRelationshipEdge"> 
+    <void property="bentStyle"> 
+     <object class="com.horstmann.violet.BentStyle" field="HVH"/> 
+    </void> 
+    <void property="endArrowHead"> 
+     <object class="com.horstmann.violet.ArrowHead" field="V"/> 
+    </void> 
+    <void property="endLabel"> 
+     <string>toSingle()</string> 
+    </void> 
+    <void property="lineStyle"> 
+     <object class="com.horstmann.violet.LineStyle" field="DOTTED"/> 
+    </void> 
+   </object> 
+   <object idref="ClassNode0"/> 
+   <object idref="ClassNode1"/> 
+  </void> 
+ </object> 
+</java> 
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/Manifest.dtd
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/Manifest.dtd	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/Manifest.dtd	(revision 28000)
@@ -0,0 +1,86 @@
+<!--
+	$Id: Manifest.dtd,v 1.8 2001/09/05 19:54:54 mtg Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): Martin Gallwey (gallwey@Sun.COM)
+
+-->
+<!ELEMENT manifest:manifest (manifest:file-entry+)>
+<!ATTLIST manifest:manifest xmlns:manifest CDATA #FIXED "http://openoffice.org/2001/manifest"> 
+
+<!ELEMENT manifest:file-entry (manifest:encryption-data?)>
+<!-- manifest:size is usually only specified for encrypted entries -->
+<!ATTLIST manifest:file-entry
+	manifest:full-path CDATA #REQUIRED
+	manifest:size CDATA #IMPLIED
+	manifest:media-type CDATA #REQUIRED
+>
+
+<!ELEMENT manifest:encryption-data (manifest:algorithm,manifest:key-derivation)>
+<!ATTLIST manifest:encryption-data
+	manifest:checksum-type CDATA #REQUIRED
+	manifest:checksum CDATA #REQUIRED >
+<!-- algorithm-name specifies the name of the algorithm used to encrypt
+	 the stream, for example Blowfish 
+	 manifest:initialisation-vector is stored encoded in Base64 -->
+<!ELEMENT manifest:algorithm EMPTY>
+<!ATTLIST manifest:algorithm
+	manifest:algorithm-name CDATA #REQUIRED
+	manifest:initialisation-vector CDATA #REQUIRED>
+
+<!ELEMENT manifest:key-derivation EMPTY>
+<!-- manifest:key-derivation-name specifies the name of the algorithm used to derive
+	 the key, for example PBKDF2 (see rfc 2898 ) 
+	 manifest:salt is stored encoded in Base64 -->
+<!ATTLIST manifest:key-derivation
+	manifest:key-derivation-name CDATA #REQUIRED
+	manifest:salt CDATA #REQUIRED
+	manifest:iteration-count CDATA #REQUIRED>
+
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/OpenDocument-schema-v1.1.rng
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/OpenDocument-schema-v1.1.rng	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/OpenDocument-schema-v1.1.rng	(revision 28000)
@@ -0,0 +1,17891 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    OASIS OpenDocument v1.1
+    OASIS Standard, 1 Feb 2007
+    Relax-NG Schema
+
+    $Id$
+
+    © 2002-2007 OASIS Open
+    © 1999-2007 Sun Microsystems, Inc.
+-->
+
+<grammar
+    xmlns="http://relaxng.org/ns/structure/1.0"
+    xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+
+    datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
+
+    xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
+    xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
+    xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
+    xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
+    xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
+    xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
+    xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0"
+    xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
+    xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
+    xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
+    xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
+    xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
+    xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
+    xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0"
+
+    xmlns:dc="http://purl.org/dc/elements/1.1/"
+    xmlns:xlink="http://www.w3.org/1999/xlink"
+    xmlns:math="http://www.w3.org/1998/Math/MathML"
+    xmlns:xforms="http://www.w3.org/2002/xforms"
+
+    xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
+    xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
+    xmlns:smil="urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0"
+>
+<define name="office-process-content">
+    <optional>
+        <attribute name="office:process-content" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<start>
+    <choice>
+        <ref name="office-document"/>
+        <ref name="office-document-content"/>
+        <ref name="office-document-styles"/>
+        <ref name="office-document-meta"/>
+        <ref name="office-document-settings"/>
+    </choice>
+</start>
+<define name="office-document">
+    <element name="office:document">
+        <ref name="office-document-attrs"/>
+        <ref name="office-document-common-attrs"/>
+        <ref name="office-meta"/>
+        <ref name="office-settings"/>
+        <ref name="office-scripts"/>
+        <ref name="office-font-face-decls"/>
+        <ref name="office-styles"/>
+        <ref name="office-automatic-styles"/>
+        <ref name="office-master-styles"/>
+        <ref name="office-body"/>
+    </element>
+</define>
+<define name="office-document-content">
+    <element name="office:document-content">
+        <ref name="office-document-common-attrs"/>
+        <ref name="office-scripts"/>
+        <ref name="office-font-face-decls"/>
+        <ref name="office-automatic-styles"/>
+        <ref name="office-body"/>
+    </element>
+</define>
+<define name="office-document-styles">
+    <element name="office:document-styles">
+        <ref name="office-document-common-attrs"/>
+        <ref name="office-font-face-decls"/>
+        <ref name="office-styles"/>
+        <ref name="office-automatic-styles"/>
+        <ref name="office-master-styles"/>
+    </element>
+</define>
+<define name="office-document-meta">
+    <element name="office:document-meta">
+        <ref name="office-document-common-attrs"/>
+        <ref name="office-meta"/>
+    </element>
+</define>
+<define name="office-document-settings">
+    <element name="office:document-settings">
+        <ref name="office-document-common-attrs"/>
+        <ref name="office-settings"/>
+    </element>
+</define>
+<define name="office-document-common-attrs" combine="interleave">
+    <optional>
+        <attribute name="office:version">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="office-document-attrs" combine="interleave">
+    <attribute name="office:mimetype">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="office-meta">
+    <optional>
+        <element name="office:meta">
+            <ref name="office-meta-content"/>
+        </element>
+    </optional>
+</define>
+
+<define name="office-meta-content">
+    <ref name="anyElements"/>
+</define>
+
+<define name="office-meta-content-strict">
+    <zeroOrMore>
+        <ref name="office-meta-data"/>
+    </zeroOrMore>
+</define>
+<define name="office-body">
+    <element name="office:body">
+        <ref name="office-body-content"/>
+    </element>
+</define>
+<define name="office-body-content" combine="choice">
+    <element name="office:text">
+        <ref name="office-text-attlist"/>
+        <ref name="office-text-content-prelude"/>
+        <zeroOrMore>
+            <ref name="office-text-content-main"/>
+        </zeroOrMore>
+        <ref name="office-text-content-epilogue"/>
+    </element>
+</define>
+<define name="office-text-content-prelude">
+    <ref name="office-forms"/>
+    <ref name="text-tracked-changes"/>
+    <ref name="text-decls"/>
+    <ref name="table-decls"/>
+</define>
+<define name="office-text-content-main">
+    <choice>
+        <zeroOrMore>
+            <ref name="text-content"/>
+        </zeroOrMore>
+        <group>
+            <ref name="text-page-sequence"/>
+            <zeroOrMore>
+                <choice>
+                    <ref name="draw-a"/>
+                    <ref name="shape"/>
+                </choice>
+            </zeroOrMore>
+        </group>
+    </choice>
+</define>
+
+<define name="text-content">
+    <choice>
+        <ref name="text-h"/>
+        <ref name="text-p"/>
+        <ref name="text-list"/>
+        <ref name="text-numbered-paragraph"/>
+        <ref name="table-table"/>
+        <ref name="draw-a"/>
+        <ref name="text-section"/>
+        <ref name="text-soft-page-break"/> 
+        <ref name="text-table-of-content"/>
+        <ref name="text-illustration-index"/>
+        <ref name="text-table-index"/>
+        <ref name="text-object-index"/>
+        <ref name="text-user-index"/>
+        <ref name="text-alphabetical-index"/>
+        <ref name="text-bibliography"/>
+        <ref name="shape"/>
+        <ref name="change-marks"/>
+    </choice>
+</define>
+<define name="office-text-content-epilogue">
+    <ref name="table-functions"/>
+</define>
+<define name="office-text-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:global" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="office-text-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:use-soft-page-breaks" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="office-body-content" combine="choice">
+    <element name="office:drawing">
+        <ref name="office-drawing-attlist"/>
+        <ref name="office-drawing-content-prelude"/>
+        <ref name="office-drawing-content-main"/>
+        <ref name="office-drawing-content-epilogue"/>
+    </element>
+</define>
+
+<define name="office-drawing-attlist">
+    <empty/>
+</define>
+<define name="office-drawing-content-prelude">
+    <ref name="text-decls"/>
+    <ref name="table-decls"/>
+</define>
+<define name="office-drawing-content-main">
+    <zeroOrMore>
+        <ref name="draw-page"/>
+    </zeroOrMore>
+</define>
+<define name="office-drawing-content-epilogue">
+    <ref name="table-functions"/>
+</define>
+<define name="office-body-content" combine="choice">
+    <element name="office:presentation">
+        <ref name="office-presentation-attlist"/>
+        <ref name="office-presentation-content-prelude"/>
+        <ref name="office-presentation-content-main"/>
+        <ref name="office-presentation-content-epilogue"/>
+    </element>
+</define>
+
+<define name="office-presentation-attlist">
+    <empty/>
+</define>
+<define name="office-presentation-content-prelude">
+    <ref name="text-decls"/>
+    <ref name="table-decls"/>
+    <ref name="presentation-decls"/>
+</define>
+<define name="office-presentation-content-main">
+    <zeroOrMore>
+        <ref name="draw-page"/>
+    </zeroOrMore>
+</define>
+<define name="office-presentation-content-epilogue">
+    <ref name="presentation-settings"/>
+    <ref name="table-functions"/>
+</define>
+<define name="office-body-content" combine="choice">
+    <element name="office:spreadsheet">
+        <ref name="office-spreadsheet-attlist"/>
+        <ref name="office-spreadsheet-content-prelude"/>
+        <ref name="office-spreadsheet-content-main"/>
+        <ref name="office-spreadsheet-content-epilogue"/>
+    </element>
+</define>
+<define name="office-spreadsheet-content-prelude">
+    <optional>
+        <ref name="table-tracked-changes"/>    
+    </optional>
+    <ref name="text-decls"/>
+    <ref name="table-decls"/>
+</define>
+
+<define name="table-decls">
+    <optional>
+        <ref name="table-calculation-settings"/>    
+    </optional>
+    <optional>
+        <ref name="table-content-validations"/>    
+    </optional>
+    <optional>
+        <ref name="table-label-ranges"/>    
+    </optional>
+</define>
+<define name="office-spreadsheet-content-main">
+    <zeroOrMore>
+        <ref name="table-table"/>
+    </zeroOrMore>
+</define>
+<define name="office-spreadsheet-content-epilogue">
+    <ref name="table-functions"/>    
+</define>
+
+<define name="table-functions">
+    <optional>
+        <ref name="table-named-expressions"/>    
+    </optional>
+    <optional>
+        <ref name="table-database-ranges"/>    
+    </optional>
+    <optional>
+        <ref name="table-data-pilot-tables"/>    
+    </optional>
+    <optional>
+        <ref name="table-consolidation"/>    
+    </optional>
+    <optional>
+        <ref name="table-dde-links"/>    
+    </optional>
+</define>
+<define name="office-body-content" combine="choice">
+    <element name="office:chart">
+        <ref name="office-chart-attlist"/>
+        <ref name="office-chart-content-prelude"/>
+        <ref name="office-chart-content-main"/>
+        <ref name="office-chart-content-epilogue"/>
+    </element>
+</define>
+
+<define name="office-chart-attlist">
+    <empty/>
+</define>
+<define name="office-chart-content-prelude">
+    <ref name="text-decls"/>
+    <ref name="table-decls"/>
+</define>
+<define name="office-chart-content-main">
+    <ref name="chart-chart"/>
+</define>
+<define name="office-chart-content-epilogue">
+    <ref name="table-functions"/>    
+</define>
+<define name="office-body-content" combine="choice">
+    <element name="office:image">
+        <ref name="office-image-attlist"/>
+        <ref name="office-image-content-prelude"/>
+        <ref name="office-image-content-main"/>
+        <ref name="office-image-content-epilogue"/>
+    </element>
+</define>
+
+<define name="office-image-attlist">
+    <empty/>
+</define>
+<define name="office-image-content-prelude">
+    <empty/>
+</define>
+<define name="office-image-content-main">
+    <ref name="draw-frame"/>
+</define>
+<define name="office-image-content-epilogue">
+    <empty/>
+</define>
+<define name="office-settings">
+    <optional>
+        <element name="office:settings">
+            <oneOrMore>
+                <ref name="config-config-item-set"/>
+            </oneOrMore>
+        </element>
+    </optional>
+</define>
+<define name="config-config-item-set">
+    <element name="config:config-item-set">
+        <ref name="config-config-item-set-attlist"/>
+        <ref name="config-items"/>
+    </element>
+</define>
+
+<define name="config-items">
+    <oneOrMore>
+        <choice>
+            <ref name="config-config-item"/>
+            <ref name="config-config-item-set"/>
+            <ref name="config-config-item-map-named"/>
+            <ref name="config-config-item-map-indexed"/>
+        </choice>
+    </oneOrMore>
+</define>
+<define name="config-config-item-set-attlist" combine="interleave">
+    <attribute name="config:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="config-config-item">
+    <element name="config:config-item">
+        <ref name="config-config-item-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="config-config-item-attlist" combine="interleave">
+    <attribute name="config:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="config-config-item-attlist" combine="interleave">
+    <attribute name="config:type">
+        <choice>
+            <value>boolean</value>
+            <value>short</value>
+            <value>int</value>
+            <value>long</value>
+            <value>double</value>
+            <value>string</value>
+            <value>datetime</value>
+            <value>base64Binary</value>
+        </choice>
+    </attribute>
+</define>
+<define name="config-config-item-map-indexed">
+    <element name="config:config-item-map-indexed">
+        <ref name="config-config-item-map-indexed-attlist"/>
+        <oneOrMore>
+            <ref name="config-config-item-map-entry"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="config-config-item-map-indexed-attlist" combine="interleave">
+    <attribute name="config:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="config-config-item-map-entry">
+    <element name="config:config-item-map-entry">
+        <ref name="config-config-item-map-entry-attlist"/>
+        <ref name="config-items"/>
+    </element>
+</define>
+<define name="config-config-item-map-entry-attlist" combine="interleave">
+    <optional>
+        <attribute name="config:name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="config-config-item-map-named">
+    <element name="config:config-item-map-named">
+        <ref name="config-config-item-map-named-attlist"/>
+        <oneOrMore>
+            <ref name="config-config-item-map-entry"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="config-config-item-map-named-attlist" combine="interleave">
+    <attribute name="config:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="office-scripts">
+    <optional>
+        <element name="office:scripts">
+            <zeroOrMore>
+                <ref name="office-script"/>
+            </zeroOrMore>
+            <optional>
+                <ref name="office-event-listeners"/>
+            </optional>
+        </element>
+    </optional>
+</define>
+<define name="office-script">
+    <element name="office:script">
+        <ref name="office-script-attlist"/>
+        <mixed>
+            <ref name="anyElements"/>
+        </mixed>
+    </element>
+</define>
+<define name="office-script-attlist">
+    <attribute name="script:language">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="office-font-face-decls">
+    <optional>
+        <element name="office:font-face-decls">
+            <zeroOrMore>
+                <ref name="style-font-face"/>
+            </zeroOrMore>
+        </element>
+    </optional>
+</define>
+<define name="office-styles">
+    <optional>
+        <element name="office:styles">
+            <interleave>
+                <ref name="styles"/>
+                <zeroOrMore>
+                    <ref name="style-default-style"/>
+                </zeroOrMore>
+                <optional>
+                    <ref name="text-outline-style"/>
+                </optional>
+                <zeroOrMore>
+                    <ref name="text-notes-configuration"/>
+                </zeroOrMore>
+                <optional>
+                    <ref name="text-bibliography-configuration"/>
+                </optional>
+                <optional>
+                    <ref name="text-linenumbering-configuration"/>
+                </optional>
+                <zeroOrMore>
+                    <ref name="draw-gradient"/>
+                </zeroOrMore>
+                <zeroOrMore>
+                    <ref name="svg-linearGradient"/>
+                </zeroOrMore>
+                <zeroOrMore>
+                    <ref name="svg-radialGradient"/>
+                </zeroOrMore>
+                <zeroOrMore>
+                    <ref name="draw-hatch"/>
+                </zeroOrMore>
+                <zeroOrMore>
+                    <ref name="draw-fill-image"/>
+                </zeroOrMore>
+                <zeroOrMore>
+                    <ref name="draw-marker"/>
+                </zeroOrMore>
+                <zeroOrMore>
+                    <ref name="draw-stroke-dash"/>
+                </zeroOrMore>
+                <zeroOrMore>
+                    <ref name="draw-opacity"/>
+                </zeroOrMore>
+                <zeroOrMore>
+                    <ref name="style-presentation-page-layout"/>
+                </zeroOrMore>
+            </interleave>
+        </element>
+    </optional>
+</define>
+<define name="office-automatic-styles">
+    <optional>
+        <element name="office:automatic-styles">
+            <interleave>
+                <ref name="styles"/>
+                <zeroOrMore>
+                    <ref name="style-page-layout"/>
+                </zeroOrMore>
+            </interleave>
+        </element>
+    </optional>
+</define>
+<define name="office-master-styles">
+    <optional>
+        <element name="office:master-styles">
+            <interleave>
+                <zeroOrMore>
+                    <ref name="style-master-page"/>
+                </zeroOrMore>
+                <optional>
+                    <ref name="style-handout-master"/>
+                </optional>
+                <optional>
+                    <ref name="draw-layer-set"/>
+                </optional>
+            </interleave>
+        </element>
+    </optional>
+</define>
+
+<define name="styles">
+    <interleave>
+        <zeroOrMore>
+            <ref name="style-style"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="text-list-style"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="number-number-style"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="number-currency-style"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="number-percentage-style"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="number-date-style"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="number-time-style"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="number-boolean-style"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="number-text-style"/>
+        </zeroOrMore>
+    </interleave>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="meta:generator">
+        <ref name="string"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="dc:title">
+        <ref name="string"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="dc:description">
+        <ref name="string"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="dc:subject">
+        <ref name="string"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="meta:keyword">
+        <ref name="string"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="meta:initial-creator">
+        <ref name="string"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <ref name="dc-creator"/>
+</define>
+<define name="dc-creator">
+    <element name="dc:creator">
+        <ref name="string"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="meta:printed-by">
+        <ref name="string"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="meta:creation-date">
+        <ref name="dateTime"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <ref name="dc-date"/>
+</define>
+<define name="dc-date">
+    <element name="dc:date">
+        <ref name="dateTime"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="meta:print-date">
+        <ref name="dateTime"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="meta:template">
+        <attribute name="xlink:href">
+            <ref name="anyURI"/>
+        </attribute>
+        <optional>
+            <attribute name="xlink:type" a:defaultValue="simple">
+                <value>simple</value>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:actuate" a:defaultValue="onRequest">
+                <value>onRequest</value>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:title">
+                <ref name="string"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="meta:date">
+                <ref name="dateTime"/>
+            </attribute>
+        </optional>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="meta:auto-reload">
+        <optional>
+            <attribute name="xlink:type" a:defaultValue="simple">
+                <value>simple</value>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:show" a:defaultValue="replace">
+                <value>replace</value>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:actuate" a:defaultValue="onLoad">
+                <value>onLoad</value>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:href">
+                <ref name="anyURI"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="meta:delay">
+                <ref name="duration"/>
+            </attribute>
+        </optional>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="meta:hyperlink-behaviour">
+        <optional>
+            <attribute name="office:target-frame-name">
+                <ref name="targetFrameName"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:show">
+                <choice>
+                    <value>new</value>
+                    <value>replace</value>
+                </choice>
+            </attribute>
+        </optional>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="dc:language">
+        <ref name="language"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="meta:editing-cycles">
+        <ref name="nonNegativeInteger"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="meta:editing-duration">
+        <ref name="duration"/>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="meta:document-statistic">
+        <optional>
+            <attribute name="meta:page-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="meta:table-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="meta:draw-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="meta:image-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="meta:ole-object-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="meta:object-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="meta:paragraph-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="meta:word-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="meta:character-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="frame-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="sentence-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="syllable-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="non-whitespace-character-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="meta:row-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="meta:cell-count">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+    </element>
+</define>
+<define name="office-meta-data" combine="choice">
+    <element name="meta:user-defined">
+        <attribute name="meta:name">
+            <ref name="string"/>
+        </attribute>
+        <choice>
+            <group>
+                <attribute name="meta:value-type">
+                    <value>float</value>
+                </attribute>
+                <ref name="double"/>
+            </group>
+            <group>
+                <attribute name="meta:value-type">
+                    <value>date</value>
+                </attribute>
+                <ref name="dateOrDateTime"/>
+            </group>
+            <group>
+                <attribute name="meta:value-type">
+                    <value>time</value>
+                </attribute>
+                <ref name="duration"/>
+            </group>
+            <group>
+                <attribute name="meta:value-type">
+                    <value>boolean</value>
+                </attribute>
+                <ref name="boolean"/>
+            </group>
+            <group>
+                <attribute name="meta:value-type">
+                    <value>string</value>
+                </attribute>
+                <ref name="string"/>
+            </group>
+            <text/>
+        </choice>
+    </element>
+</define>
+<define name="text-h">
+    <element name="text:h">
+        <ref name="heading-attrs"/>
+        <ref name="paragraph-attrs"/>
+        <optional>
+            <ref name="text-number"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="paragraph-content"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="heading-attrs" combine="interleave">
+    <attribute name="text:outline-level">
+        <ref name="positiveInteger"/>
+    </attribute>
+</define>
+<define name="heading-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:restart-numbering" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="heading-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:start-value">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="heading-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:is-list-header" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-number">
+    <element name="text:number">
+        <ref name="string"/>
+    </element>
+</define>
+<define name="text-p">
+    <element name="text:p">
+        <ref name="paragraph-attrs"/>
+        <zeroOrMore>
+            <ref name="paragraph-content"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="paragraph-attrs">
+    <optional>
+        <attribute name="text:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:class-names">
+            <ref name="styleNameRefs"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:cond-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-attrs" combine="interleave">
+    <optional>
+        <ref name="text-id"/>
+    </optional>
+</define>
+<define name="text-page-sequence">
+    <element name="text:page-sequence">
+        <oneOrMore>
+            <ref name="text-page"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="text-page">
+    <element name="text:page">
+        <ref name="text-page-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="text-page-attlist">
+    <attribute name="text:master-page-name">
+        <ref name="styleNameRef"/>
+    </attribute>
+</define>
+<define name="text-list">
+    <element name="text:list">
+        <ref name="text-list-attr"/>
+        <optional>
+            <ref name="text-list-header"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="text-list-item"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-list-attr" combine="interleave">
+    <optional>
+        <attribute name="text:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-list-attr" combine="interleave">
+    <optional>
+        <attribute name="text:continue-numbering">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-list-item">
+    <element name="text:list-item">
+        <ref name="text-list-item-attr"/>
+        <ref name="text-list-item-content"/>
+    </element>
+</define>
+<define name="text-list-item-content">
+    <optional>
+        <ref name="text-number"/>
+    </optional>
+    <zeroOrMore>
+        <choice>
+            <ref name="text-p"/>
+            <ref name="text-h"/>
+            <ref name="text-list"/>
+            <ref name="text-soft-page-break"/>
+        </choice>
+    </zeroOrMore>
+</define>
+<define name="text-list-item-attr" combine="interleave">
+    <optional>
+        <attribute name="text:start-value">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-list-header">
+    <element name="text:list-header">
+        <ref name="text-list-item-content"/>
+    </element>
+</define>
+<define name="text-numbered-paragraph">
+    <element name="text:numbered-paragraph">
+        <ref name="text-numbered-paragraph-attr"/>
+        <optional>
+            <ref name="text-number"/>
+        </optional>
+        <choice>
+            <ref name="text-p"/>
+            <ref name="text-h"/>
+        </choice>
+    </element>
+</define>
+<define name="text-numbered-paragraph-attr" combine="interleave">
+    <optional>
+        <attribute name="text:level" a:defaultValue="1">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-numbered-paragraph-attr" combine="interleave">
+    <ref name="text-list-attr"/>
+</define>
+<define name="text-numbered-paragraph-attr" combine="interleave">
+    <ref name="text-list-item-attr"/>
+</define>
+<define name="text-section">
+    <element name="text:section">
+        <ref name="text-section-attr"/>
+        <choice>
+            <ref name="text-section-source"/>
+            <ref name="text-section-source-dde"/>
+            <empty/>
+        </choice>
+        <zeroOrMore>
+            <ref name="text-content"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-section-attr" combine="interleave">
+    <ref name="sectionAttr"/>
+</define>
+<define name="sectionAttr" combine="interleave">
+    <optional>
+        <attribute name="text:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="sectionAttr" combine="interleave">
+    <attribute name="text:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="sectionAttr" combine="interleave">
+    <optional>
+        <attribute name="text:protected">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="sectionAttr" combine="interleave">
+    <optional>
+        <attribute name="text:protection-key">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-section-attr" combine="interleave">
+    <choice>
+        <attribute name="text:display">
+            <choice>
+                <value>true</value>
+                <value>none</value>
+            </choice>
+        </attribute>
+        <group>
+            <attribute name="text:display">
+                <value>condition</value>
+            </attribute>
+            <attribute name="text:condition">
+                <ref name="string"/>
+            </attribute>
+        </group>
+        <empty/>
+    </choice>
+</define>
+<define name="text-section-source">
+    <element name="text:section-source">
+        <ref name="text-section-source-attr"/>
+    </element>
+</define>
+<define name="text-section-source-attr" combine="interleave">
+    <optional>
+        <attribute name="xlink:href">
+            <ref name="anyURI"/>
+        </attribute>
+        <optional>
+            <attribute name="xlink:type" a:defaultValue="simple">
+                <value>simple</value>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:show" a:defaultValue="embed">
+                <value>embed</value>
+            </attribute>
+        </optional>
+    </optional>
+</define>
+<define name="text-section-source-attr" combine="interleave">
+    <optional>
+        <attribute name="text:section-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-section-source-attr" combine="interleave">
+    <optional>
+        <attribute name="text:filter-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-section-source-dde">
+    <ref name="office-dde-source"/>
+</define>
+<define name="text-tracked-changes">
+    <optional>
+        <element name="text:tracked-changes">
+            <ref name="text-tracked-changes-attr"/>
+            <zeroOrMore>
+                <ref name="text-changed-region"/>
+            </zeroOrMore>
+        </element>
+    </optional>
+</define>
+<define name="text-tracked-changes-attr" combine="interleave">
+    <optional>
+        <attribute name="text:track-changes" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-changed-region">
+    <element name="text:changed-region">
+        <ref name="text-changed-region-attr"/>
+        <ref name="text-changed-region-content"/>
+    </element>
+</define>
+<define name="text-changed-region-attr" combine="interleave">
+    <attribute name="text:id">
+        <ref name="ID"/>
+    </attribute>
+</define>
+<define name="text-changed-region-content" combine="choice">
+    <element name="text:insertion">
+        <ref name="office-change-info"/>
+    </element>
+</define>
+<define name="text-changed-region-content" combine="choice">
+    <element name="text:deletion">
+        <ref name="office-change-info"/>
+        <zeroOrMore>
+            <ref name="text-content"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-changed-region-content" combine="choice">
+    <element name="text:format-change">
+        <ref name="office-change-info"/>
+    </element>
+</define>
+<define name="change-marks">
+    <choice>
+        <element name="text:change">
+            <ref name="change-mark-attr"/>
+        </element>
+        <element name="text:change-start">
+            <ref name="change-mark-attr"/>
+        </element>
+        <element name="text:change-end">
+            <ref name="change-mark-attr"/>
+        </element>
+    </choice>
+</define>
+<define name="change-mark-attr">
+    <attribute name="text:change-id">
+        <ref name="IDREF"/>
+    </attribute>
+</define>
+<define name="text-soft-page-break">
+    <element name="text:soft-page-break">
+        <empty/>
+    </element>
+</define>
+<define name="text-decls">
+    <optional>
+        <element name="text:variable-decls">
+            <zeroOrMore>
+                <ref name="text-variable-decl"/>
+            </zeroOrMore>
+        </element>
+    </optional>
+    <optional>
+        <element name="text:sequence-decls">
+            <zeroOrMore>
+                <ref name="text-sequence-decl"/>
+            </zeroOrMore>
+        </element>
+    </optional>
+    <optional>
+        <element name="text:user-field-decls">
+            <zeroOrMore>
+                <ref name="text-user-field-decl"/>
+            </zeroOrMore>
+        </element>
+    </optional>
+    <optional>
+        <element name="text:dde-connection-decls">
+            <zeroOrMore>
+                <ref name="text-dde-connection-decl"/>
+            </zeroOrMore>
+        </element>
+    </optional>
+    <optional>
+        <ref name="text-alphabetical-index-auto-mark-file"/>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <text/>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:s">
+        <optional>
+            <attribute name="text:c">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:tab">
+        <ref name="text-tab-attr"/>
+    </element>
+</define>
+<define name="text-tab-attr">
+    <optional>
+        <attribute name="text:tab-ref">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:line-break">
+        <empty/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <ref name="text-soft-page-break"/>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:span">
+        <optional>
+            <attribute name="text:style-name">
+                <ref name="styleNameRef"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="text:class-names">
+                <ref name="styleNameRefs"/>
+            </attribute>
+        </optional>
+        <zeroOrMore>
+            <ref name="paragraph-content"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:a">
+        <ref name="text-a-attlist"/>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="paragraph-content"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-a-attlist" combine="interleave">
+    <optional>
+        <attribute name="office:name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-a-attlist" combine="interleave">
+    <optional>
+        <attribute name="office:title">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-a-attlist" combine="interleave">
+    <attribute name="xlink:href">
+        <ref name="anyURI"/>
+    </attribute>
+    <optional>
+        <attribute name="xlink:type" a:defaultValue="simple">
+            <value>simple</value>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="xlink:actuate" a:defaultValue="onRequest">
+            <value>onRequest</value>
+        </attribute>
+    </optional>
+</define>
+<define name="text-a-attlist" combine="interleave">
+    <optional>
+        <attribute name="office:target-frame-name">
+            <ref name="targetFrameName"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="xlink:show">
+            <choice>
+                <value>new</value>
+                <value>replace</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="text-a-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:visited-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <choice>
+        <element name="text:bookmark">
+            <attribute name="text:name">
+                <ref name="string"/>
+            </attribute>
+        </element>
+        <element name="text:bookmark-start">
+            <attribute name="text:name">
+                <ref name="string"/>
+            </attribute>
+        </element>
+        <element name="text:bookmark-end">
+            <attribute name="text:name">
+                <ref name="string"/>
+            </attribute>
+        </element>
+    </choice>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:reference-mark">
+        <attribute name="text:name">
+            <ref name="string"/>
+        </attribute>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <choice>
+        <element name="text:reference-mark-start">
+            <attribute name="text:name">
+                <ref name="string"/>
+            </attribute>
+        </element>
+        <element name="text:reference-mark-end">
+            <attribute name="text:name">
+                <ref name="string"/>
+            </attribute>
+        </element>
+    </choice>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:note">
+        <ref name="text-note-class"/>
+        <optional>
+            <attribute name="text:id">
+                <ref name="string"/>
+            </attribute>
+        </optional>
+        <element name="text:note-citation">
+            <optional>
+                <attribute name="text:label">
+                    <ref name="string"/>
+                </attribute>
+            </optional>
+            <text/>
+        </element>
+        <element name="text:note-body">
+            <zeroOrMore>
+                <ref name="text-content"/>
+            </zeroOrMore>
+        </element>
+    </element>
+</define>
+<define name="text-note-class">
+    <attribute name="text:note-class">
+        <choice>
+            <value>footnote</value>
+            <value>endnote</value>
+        </choice>
+    </attribute>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:ruby">
+        <optional>
+            <attribute name="text:style-name">
+                <ref name="styleNameRef"/>
+            </attribute>
+        </optional>
+        <element name="text:ruby-base">
+            <ref name="paragraph-content"/>
+        </element>
+        <element name="text:ruby-text">
+            <optional>
+                <attribute name="text:style-name">
+                    <ref name="styleNameRef"/>
+                </attribute>
+            </optional>
+            <text/>
+        </element>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <ref name="office-annotation"/>
+</define>
+<define name="paragraph-content" combine="choice">
+    <ref name="change-marks"/>
+</define>
+<define name="paragraph-content" combine="choice">
+    <choice>
+        <ref name="shape"/>
+        <ref name="draw-a"/>
+    </choice>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:date">
+        <ref name="text-date-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-date-attlist" combine="interleave">
+    <interleave>
+        <ref name="common-field-fixed-attlist"/>
+        <ref name="common-field-data-style-name-attlist"/>
+    </interleave>
+</define>
+<define name="text-date-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:date-value">
+            <ref name="dateOrDateTime"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-date-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:date-adjust">
+            <ref name="duration"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:time">
+        <ref name="text-time-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-time-attlist" combine="interleave">
+    <interleave>
+        <ref name="common-field-fixed-attlist"/>
+        <ref name="common-field-data-style-name-attlist"/>
+    </interleave>
+</define>
+<define name="text-time-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:time-value">
+            <ref name="timeOrDateTime"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-time-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:time-adjust">
+            <ref name="duration"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:page-number">
+        <ref name="text-page-number-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-page-number-attlist" combine="interleave">
+    <interleave>
+        <ref name="common-field-num-format-attlist"/>
+        <ref name="common-field-fixed-attlist"/>
+    </interleave>
+</define>
+<define name="text-page-number-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:page-adjust">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-page-number-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:select-page">
+            <choice>
+                <value>previous</value>
+                <value>current</value>
+                <value>next</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:page-continuation">
+        <ref name="text-page-continuation-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-page-continuation-attlist" combine="interleave">
+    <attribute name="text:select-page">
+        <choice>
+            <value>previous</value>
+            <value>next</value>
+        </choice>
+    </attribute>
+</define>
+<define name="text-page-continuation-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:string-value">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-firstname">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-lastname">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-initials">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-title">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-position">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-email">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-phone-private">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-fax">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-company">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-phone-work">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-street">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-city">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-postal-code">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-country">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sender-state-or-province">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:author-name">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:author-initials">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:chapter">
+        <ref name="text-chapter-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-chapter-attlist" combine="interleave">
+    <attribute name="text:display">
+        <choice>
+            <value>name</value>
+            <value>number</value>
+            <value>number-and-name</value>
+            <value>plain-number-and-name</value>
+            <value>plain-number</value>
+        </choice>
+    </attribute>
+</define>
+<define name="text-chapter-attlist" combine="interleave">
+    <attribute name="text:outline-level">
+        <ref name="nonNegativeInteger"/>
+    </attribute>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:file-name">
+        <ref name="text-file-name-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-file-name-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:display">
+            <choice>
+                <value>full</value>
+                <value>path</value>
+                <value>name</value>
+                <value>name-and-extension</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="text-file-name-attlist" combine="interleave">
+    <ref name="common-field-fixed-attlist"/>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:template-name">
+        <ref name="text-template-name-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-template-name-attlist">
+    <optional>
+        <attribute name="text:display">
+            <choice>
+                <value>full</value>
+                <value>path</value>
+                <value>name</value>
+                <value>name-and-extension</value>
+                <value>area</value>
+                <value>title</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sheet-name">
+        <text/>
+    </element>
+</define>
+<define name="text-variable-decl">
+    <element name="text:variable-decl">
+        <ref name="common-field-name-attlist"/>
+        <ref name="common-value-type-attlist"/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:variable-set">
+        <interleave>
+            <ref name="common-field-name-attlist"/>
+            <ref name="common-field-formula-attlist"/>
+            <ref name="common-value-and-type-attlist"/>
+            <ref name="common-field-display-value-none-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:variable-get">
+        <interleave>
+            <ref name="common-field-name-attlist"/>
+            <ref name="common-field-display-value-formula-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:variable-input">
+        <interleave>
+            <ref name="common-field-name-attlist"/>
+            <ref name="common-field-description-attlist"/>
+            <ref name="common-value-type-attlist"/>
+            <ref name="common-field-display-value-none-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="text-user-field-decl">
+    <element name="text:user-field-decl">
+        <ref name="common-field-name-attlist"/>
+        <optional>
+            <ref name="common-field-formula-attlist"/>
+        </optional>
+        <ref name="common-value-and-type-attlist"/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:user-field-get">
+        <interleave>
+            <ref name="common-field-name-attlist"/>
+            <ref name="common-field-display-value-formula-none-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:user-field-input">
+        <interleave>
+            <ref name="common-field-name-attlist"/>
+            <ref name="common-field-description-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="text-sequence-decl">
+    <element name="text:sequence-decl">
+        <ref name="text-sequence-decl-attlist"/>
+    </element>
+</define>
+<define name="text-sequence-decl-attlist" combine="interleave">
+    <ref name="common-field-name-attlist"/>
+</define>
+<define name="text-sequence-decl-attlist" combine="interleave">
+    <attribute name="text:display-outline-level">
+        <ref name="nonNegativeInteger"/>
+    </attribute>
+</define>
+<define name="text-sequence-decl-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:separation-character">
+            <ref name="character"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sequence">
+        <interleave>
+            <ref name="common-field-name-attlist"/>
+            <ref name="common-field-formula-attlist"/>
+            <ref name="common-field-num-format-attlist"/>
+            <ref name="text-sequence-ref-name"/>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="text-sequence-ref-name">
+    <optional>
+        <attribute name="text:ref-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:expression">
+        <interleave>
+            <ref name="common-field-formula-attlist"/>
+            <optional>
+                <ref name="common-value-and-type-attlist"/>
+            </optional>
+            <ref name="common-field-display-value-formula-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:text-input">
+        <ref name="common-field-description-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:initial-creator">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:creation-date">
+        <interleave>
+            <ref name="common-field-fixed-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+            <optional>
+                <attribute name="text:date-value">
+                    <ref name="dateOrDateTime"/>
+                </attribute>
+            </optional>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:creation-time">
+        <interleave>
+            <ref name="common-field-fixed-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+            <optional>
+                <attribute name="text:time-value">
+                    <ref name="timeOrDateTime"/>
+                </attribute>
+            </optional>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:description">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:user-defined">
+        <interleave>
+            <ref name="common-field-fixed-attlist"/>
+            <attribute name="text:name">
+                <ref name="string"/>
+            </attribute>
+            <ref name="common-field-data-style-name-attlist"/>
+            <optional>
+                <attribute name="office:value">
+                    <ref name="double"/>
+                </attribute>
+            </optional>
+            <optional>
+                <attribute name="office:date-value">
+                    <ref name="dateOrDateTime"/>
+                </attribute>
+            </optional>
+            <optional>
+                <attribute name="office:time-value">
+                    <ref name="duration"/>
+                </attribute>
+            </optional>
+            <optional>
+                <attribute name="office:boolean-value">
+                    <ref name="boolean"/>
+                </attribute>
+            </optional>
+            <optional>
+                <attribute name="office:string-value">
+                    <ref name="string"/>
+                </attribute>
+            </optional>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:print-time">
+        <interleave>
+            <ref name="common-field-fixed-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+            <optional>
+                <attribute name="text:time-value">
+                    <ref name="time"/>
+                </attribute>
+            </optional>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:print-date">
+        <interleave>
+            <ref name="common-field-fixed-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+            <optional>
+                <attribute name="text:date-value">
+                    <ref name="date"/>
+                </attribute>
+            </optional>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:printed-by">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:title">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:subject">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:keywords">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:editing-cycles">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:editing-duration">
+        <interleave>
+            <ref name="common-field-fixed-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+            <optional>
+                <attribute name="text:duration">
+                    <ref name="duration"/>
+                </attribute>
+            </optional>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:modification-time">
+        <interleave>
+            <ref name="common-field-fixed-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+            <optional>
+                <attribute name="text:time-value">
+                    <ref name="time"/>
+                </attribute>
+            </optional>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:modification-date">
+        <interleave>
+            <ref name="common-field-fixed-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+            <optional>
+                <attribute name="text:date-value">
+                    <ref name="date"/>
+                </attribute>
+            </optional>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:creator">
+        <ref name="common-field-fixed-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element>
+        <choice>
+            <name>text:page-count</name>
+            <name>text:paragraph-count</name>
+            <name>text:word-count</name>
+            <name>text:character-count</name>
+            <name>text:table-count</name>
+            <name>text:image-count</name>
+            <name>text:object-count</name>
+        </choice>
+        <ref name="common-field-num-format-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="common-field-database-table">
+    <ref name="common-field-database-table-attlist"/>
+    <ref name="common-field-database-name"/>
+</define>
+<define name="common-field-database-name" combine="choice">
+    <optional>
+        <attribute name="text:database-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-field-database-name" combine="choice">
+    <ref name="form-connection-resource"/>
+</define>
+<define name="common-field-database-table-attlist" combine="interleave">
+    <attribute name="text:table-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="common-field-database-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:table-type">
+            <choice>
+                <value>table</value>
+                <value>query</value>
+                <value>command</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:database-display">
+        <ref name="text-database-display-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-database-display-attlist" combine="interleave">
+    <ref name="common-field-database-table"/>
+</define>
+<define name="text-database-display-attlist" combine="interleave">
+    <ref name="common-field-data-style-name-attlist"/>
+</define>
+<define name="text-database-display-attlist" combine="interleave">
+    <attribute name="text:column-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:database-next">
+        <ref name="text-database-next-attlist"/>
+    </element>
+</define>
+<define name="text-database-next-attlist" combine="interleave">
+    <ref name="common-field-database-table"/>
+</define>
+<define name="text-database-next-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:condition">
+            <ref name="formula"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:database-row-select">
+        <ref name="text-database-row-select-attlist"/>
+    </element>
+</define>
+<define name="text-database-row-select-attlist" combine="interleave">
+    <ref name="common-field-database-table"/>
+</define>
+<define name="text-database-row-select-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:condition">
+            <ref name="formula"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-database-row-select-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:row-number">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:database-row-number">
+        <interleave>
+            <ref name="common-field-database-table"/>
+            <ref name="common-field-num-format-attlist"/>
+            <optional>
+                <attribute name="text:value">
+                    <ref name="nonNegativeInteger"/>
+                </attribute>
+            </optional>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:database-name">
+        <ref name="common-field-database-table"/>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:page-variable-set">
+        <ref name="text-set-page-variable-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-set-page-variable-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:active">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-set-page-variable-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:page-adjust">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:page-variable-get">
+        <ref name="text-get-page-variable-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-get-page-variable-attlist" combine="interleave">
+    <ref name="common-field-num-format-attlist"/>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:placeholder">
+        <ref name="text-placeholder-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-placeholder-attlist" combine="interleave">
+    <attribute name="text:placeholder-type">
+        <choice>
+            <value>text</value>
+            <value>table</value>
+            <value>text-box</value>
+            <value>image</value>
+            <value>object</value>
+        </choice>
+    </attribute>
+</define>
+<define name="text-placeholder-attlist" combine="interleave">
+    <ref name="common-field-description-attlist"/>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:conditional-text">
+        <ref name="text-conditional-text-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-conditional-text-attlist" combine="interleave">
+    <attribute name="text:condition">
+        <ref name="formula"/>
+    </attribute>
+</define>
+<define name="text-conditional-text-attlist" combine="interleave">
+    <attribute name="text:string-value-if-true">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="text-conditional-text-attlist" combine="interleave">
+    <attribute name="text:string-value-if-false">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="text-conditional-text-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:current-value">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:hidden-text">
+        <ref name="text-hidden-text-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-hidden-text-attlist" combine="interleave">
+    <attribute name="text:condition">
+        <ref name="formula"/>
+    </attribute>
+</define>
+<define name="text-hidden-text-attlist" combine="interleave">
+    <attribute name="text:string-value">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="text-hidden-text-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:is-hidden">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element>
+        <choice>
+            <name>text:reference-ref</name>
+            <name>text:bookmark-ref</name>
+        </choice>
+        <interleave>
+            <ref name="text-common-ref-content"/>
+            <ref name="text-ref-content"/>
+        </interleave>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:note-ref">
+        <interleave>
+            <ref name="text-common-ref-content"/>
+            <ref name="text-note-ref-content"/>
+            <ref name="text-ref-content"/>
+        </interleave>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:sequence-ref">
+        <interleave>
+            <ref name="text-common-ref-content"/>
+            <ref name="text-sequence-ref-content"/>
+        </interleave>
+    </element>
+</define>
+<define name="text-common-ref-content" combine="interleave">
+    <text/>
+</define>
+<define name="text-common-ref-content" combine="interleave">
+    <optional>
+        <attribute name="text:ref-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-note-ref-content" combine="interleave">
+    <ref name="text-note-class"/>
+</define>
+<define name="text-ref-content" combine="interleave">
+    <optional>
+        <attribute name="text:reference-format">
+            <choice>
+                <value>page</value>
+                <value>chapter</value>
+                <value>direction</value>
+                <value>text</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="text-sequence-ref-content" combine="interleave">
+    <optional>
+        <attribute name="text:reference-format">
+            <choice>
+                <value>page</value>
+                <value>chapter</value>
+                <value>direction</value>
+                <value>text</value>
+                <value>category-and-value</value>
+                <value>caption</value>
+                <value>value</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:script">
+        <interleave>
+            <choice>
+                <group>
+                    <attribute name="xlink:href">
+                        <ref name="anyURI"/>
+                    </attribute>
+                    <optional>
+                        <attribute name="xlink:type" a:defaultValue="simple">
+                            <value>simple</value>
+                        </attribute>
+                    </optional>
+                </group>    
+                <text/>
+            </choice>
+            <optional>
+                <attribute name="script:language">
+                    <ref name="string"/>
+                </attribute>
+            </optional>
+        </interleave>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:execute-macro">
+        <optional>
+            <attribute name="text:name">
+                <ref name="string"/>
+            </attribute>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:hidden-paragraph">
+        <ref name="text-hidden-paragraph-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="text-hidden-paragraph-attlist" combine="interleave">
+    <attribute name="text:condition">
+        <ref name="formula"/>
+    </attribute>
+</define>
+<define name="text-hidden-paragraph-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:is-hidden">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:dde-connection">
+        <attribute name="text:connection-name">
+            <ref name="string"/>
+        </attribute>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:measure">
+        <attribute name="text:kind">
+            <choice>
+                <value>value</value>
+                <value>unit</value>
+                <value>gap</value>
+            </choice>
+        </attribute>
+        <text/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:table-formula">
+        <interleave>
+            <ref name="common-field-formula-attlist"/>
+            <ref name="common-field-display-value-formula-attlist"/>
+            <ref name="common-field-data-style-name-attlist"/>
+        </interleave>
+        <text/>
+    </element>
+</define>
+<define name="common-value-type-attlist">
+    <attribute name="office:value-type">
+        <ref name="valueType"/>
+    </attribute>
+</define>
+<define name="common-value-and-type-attlist">
+    <choice>
+        <group>
+            <attribute name="office:value-type">
+                <value>float</value>
+            </attribute>
+            <attribute name="office:value">
+                <ref name="double"/>
+            </attribute>
+        </group>
+        <group>
+            <attribute name="office:value-type">
+                <value>percentage</value>
+            </attribute>
+            <attribute name="office:value">
+                <ref name="double"/>
+            </attribute>
+        </group>
+        <group>
+            <attribute name="office:value-type">
+                <value>currency</value>
+            </attribute>
+            <attribute name="office:value">
+                <ref name="double"/>
+            </attribute>
+            <optional>
+                <attribute name="office:currency">
+                    <ref name="string"/>
+                </attribute>
+            </optional>
+        </group>
+        <group>
+            <attribute name="office:value-type">
+                <value>date</value>
+            </attribute>
+            <attribute name="office:date-value">
+                <ref name="dateOrDateTime"/>
+            </attribute>
+        </group>
+        <group>
+            <attribute name="office:value-type">
+                <value>time</value>
+            </attribute>
+            <attribute name="office:time-value">
+                <ref name="duration"/>
+            </attribute>
+        </group>
+        <group>
+            <attribute name="office:value-type">
+                <value>boolean</value>
+            </attribute>
+            <attribute name="office:boolean-value">
+                <ref name="boolean"/>
+            </attribute>
+        </group>
+        <group>
+            <attribute name="office:value-type">
+                <value>string</value>
+            </attribute>
+            <optional>
+                <attribute name="office:string-value">
+                    <ref name="string"/>
+                </attribute>
+            </optional>
+        </group>
+    </choice>
+</define>
+<define name="common-field-fixed-attlist">
+    <optional>
+        <attribute name="text:fixed">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-field-name-attlist">
+    <attribute name="text:name">
+        <ref name="variableName"/>
+    </attribute>
+</define>
+<define name="common-field-description-attlist">
+    <optional>
+        <attribute name="text:description">
+            <text/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-field-display-value-none-attlist">
+    <optional>
+        <attribute name="text:display">
+            <choice>
+                <value>value</value>
+                <value>none</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-field-display-value-formula-none-attlist">
+    <optional>
+        <attribute name="text:display">
+            <choice>
+                <value>value</value>
+                <value>formula</value>
+                <value>none</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-field-display-value-formula-attlist">
+    <optional>
+        <attribute name="text:display">
+            <choice>
+                <value>value</value>
+                <value>formula</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-field-formula-attlist">
+    <optional>
+        <attribute name="text:formula">
+            <ref name="formula"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-field-data-style-name-attlist">
+    <optional>
+        <attribute name="style:data-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-field-num-format-attlist">
+    <optional>
+        <ref name="common-num-format-attlist"/>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:toc-mark-start">
+        <ref name="text-toc-mark-start-attrs"/>
+    </element>
+</define>
+<define name="text-toc-mark-start-attrs">
+    <ref name="text-id"/>
+    <ref name="text-outline-level"/>
+</define>
+<define name="text-outline-level">
+    <optional>
+        <attribute name="text:outline-level">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-id">
+    <attribute name="text:id">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:toc-mark-end">
+        <ref name="text-id"/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:toc-mark">
+        <attribute name="text:string-value">
+            <ref name="string"/>
+        </attribute>
+        <ref name="text-outline-level"/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:user-index-mark-start">
+        <ref name="text-id"/>
+        <ref name="text-outline-level"/>
+        <ref name="text-index-name"/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:user-index-mark-end">
+        <ref name="text-id"/>
+        <ref name="text-outline-level"/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:user-index-mark">
+        <attribute name="text:string-value">
+            <ref name="string"/>
+        </attribute>
+        <ref name="text-outline-level"/>
+        <ref name="text-index-name"/>
+    </element>
+</define>
+<define name="text-index-name">
+    <attribute name="text:index-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:alphabetical-index-mark-start">
+        <ref name="text-id"/>
+        <ref name="text-alphabetical-index-mark-attrs"/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:alphabetical-index-mark-end">
+        <ref name="text-id"/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:alphabetical-index-mark">
+        <attribute name="text:string-value">
+            <ref name="string"/>
+        </attribute>
+        <ref name="text-alphabetical-index-mark-attrs"/>
+    </element>
+</define>
+<define name="text-alphabetical-index-mark-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:key1">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:key2">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-alphabetical-index-mark-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:string-value-phonetic">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:key1-phonetic">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:key2-phonetic">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-alphabetical-index-mark-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:main-entry" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="text:bibliography-mark">
+        <attribute name="text:bibliography-type">
+            <ref name="text-bibliography-types"/>
+        </attribute>
+        <zeroOrMore>
+            <attribute>
+                <choice>
+                    <name>text:identifier</name>
+                    <name>text:address</name>
+                    <name>text:annote</name>
+                    <name>text:author</name>
+                    <name>text:booktitle</name>
+                    <name>text:chapter</name>
+                    <name>text:edition</name>
+                    <name>text:editor</name>
+                    <name>text:howpublished</name>
+                    <name>text:institution</name>
+                    <name>text:journal</name>
+                    <name>text:month</name>
+                    <name>text:note</name>
+                    <name>text:number</name>
+                    <name>text:organizations</name>
+                    <name>text:pages</name>
+                    <name>text:publisher</name>
+                    <name>text:school</name>
+                    <name>text:series</name>
+                    <name>text:title</name>
+                    <name>text:report-type</name>
+                    <name>text:volume</name>
+                    <name>text:year</name>
+                    <name>text:url</name>
+                    <name>text:custom1</name>
+                    <name>text:custom2</name>
+                    <name>text:custom3</name>
+                    <name>text:custom4</name>
+                    <name>text:custom5</name>
+                    <name>text:isbn</name>
+                    <name>text:issn</name>
+                </choice>
+                <ref name="string"/>
+            </attribute>
+        </zeroOrMore>
+        <text/>
+    </element>
+</define>
+<define name="text-bibliography-types">
+    <choice>
+        <value>article</value>
+        <value>book</value>
+        <value>booklet</value>
+        <value>conference</value>
+        <value>custom1</value>
+        <value>custom2</value>
+        <value>custom3</value>
+        <value>custom4</value>
+        <value>custom5</value>
+        <value>email</value>
+        <value>inbook</value>
+        <value>incollection</value>
+        <value>inproceedings</value>
+        <value>journal</value>
+        <value>manual</value>
+        <value>mastersthesis</value>
+        <value>misc</value>
+        <value>phdthesis</value>
+        <value>proceedings</value>
+        <value>techreport</value>
+        <value>unpublished</value>
+        <value>www</value>
+    </choice>
+</define>
+<define name="text-index-body">
+    <element name="text:index-body">
+        <zeroOrMore>
+            <ref name="index-content-main"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="index-content-main">
+    <choice>
+        <ref name="text-content"/>
+        <ref name="text-index-title"/>
+    </choice>
+</define>
+<define name="text-index-title">
+    <element name="text:index-title">
+        <ref name="sectionAttr"/>
+        <zeroOrMore>
+            <ref name="index-content-main"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-table-of-content">
+    <element name="text:table-of-content">
+        <ref name="sectionAttr"/>
+        <ref name="text-table-of-content-source"/>
+        <ref name="text-index-body"/>
+    </element>
+</define>
+<define name="text-table-of-content-source">
+    <element name="text:table-of-content-source">
+        <ref name="text-table-of-content-source-attlist"/>
+        <optional>
+            <ref name="text-index-title-template"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="text-table-of-content-entry-template"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="text-index-source-styles"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-table-of-content-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:outline-level">
+            <choice>
+                <ref name="positiveInteger"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="text-table-of-content-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:use-outline-level" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-table-of-content-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:use-index-marks">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-table-of-content-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:use-index-source-styles">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-table-of-content-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:index-scope">
+            <choice>
+                <value>document</value>
+                <value>chapter</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="text-table-of-content-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:relative-tab-stop-position">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-table-of-content-entry-template">
+    <element name="text:table-of-content-entry-template">
+        <ref name="text-table-of-content-entry-template-attlist"/>
+        <zeroOrMore>
+            <ref name="text-table-of-content-children"/>
+
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-table-of-content-children">
+    <choice>
+        <ref name="text-index-entry-chapter"/>
+        <ref name="text-index-entry-page-number"/>
+        <ref name="text-index-entry-text"/>
+        <ref name="text-index-entry-span"/>
+        <ref name="text-index-entry-tab-stop"/>
+        <ref name="text-index-entry-link-start"/>
+        <ref name="text-index-entry-link-end"/>
+    </choice>
+</define>
+<define name="text-table-of-content-entry-template-attlist"
+        combine="interleave">
+    <attribute name="text:outline-level">
+        <ref name="positiveInteger"/>
+    </attribute>
+</define>
+<define name="text-table-of-content-entry-template-attlist"
+        combine="interleave">
+    <attribute name="text:style-name">
+        <ref name="styleNameRef"/>
+    </attribute>
+</define>
+<define name="text-illustration-index">
+    <element name="text:illustration-index">
+        <ref name="sectionAttr"/>
+        <ref name="text-illustration-index-source"/>
+        <ref name="text-index-body"/>
+    </element>
+</define>
+<define name="text-illustration-index-source">
+    <element name="text:illustration-index-source">
+        <ref name="text-illustration-index-source-attrs"/>
+        <optional>
+            <ref name="text-index-title-template"/>
+        </optional>
+        <optional>
+            <ref name="text-illustration-index-entry-template"/>
+        </optional>
+    </element>
+</define>
+<define name="text-illustration-index-source-attrs" combine="interleave">
+    <ref name="text-index-scope-attr"/>
+</define>
+<define name="text-index-scope-attr">
+    <optional>
+        <attribute name="text:index-scope" a:defaultValue="document">
+            <choice>
+                <value>document</value>
+                <value>chapter</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="text-illustration-index-source-attrs" combine="interleave">
+    <ref name="text-relative-tab-stop-position-attr"/>
+</define>
+<define name="text-relative-tab-stop-position-attr">
+    <optional>
+        <attribute name="text:relative-tab-stop-position"
+                   a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-illustration-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:use-caption" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-illustration-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:caption-sequence-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-illustration-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:caption-sequence-format">
+            <choice>
+                <value>text</value>
+                <value>category-and-value</value>
+                <value>caption</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="text-illustration-index-entry-template">
+    <element name="text:illustration-index-entry-template">
+        <ref name="text-illustration-index-entry-content"/>
+    </element>
+</define>
+<define name="text-illustration-index-entry-content">
+    <ref name="text-illustration-index-entry-template-attrs"/>
+    <zeroOrMore>
+        <choice>
+            <ref name="text-index-entry-page-number"/>
+            <ref name="text-index-entry-text"/>
+            <ref name="text-index-entry-span"/>
+            <ref name="text-index-entry-tab-stop"/>
+        </choice>
+    </zeroOrMore>
+</define>
+<define name="text-illustration-index-entry-template-attrs">
+    <attribute name="text:style-name">
+        <ref name="styleNameRef"/>
+    </attribute>
+</define>
+<define name="text-table-index">
+    <element name="text:table-index">
+        <ref name="sectionAttr"/>
+        <ref name="text-table-index-source"/>
+        <ref name="text-index-body"/>
+    </element>
+</define>
+<define name="text-table-index-source">
+    <element name="text:table-index-source">
+        <ref name="text-illustration-index-source-attrs"/>
+        <optional>
+            <ref name="text-index-title-template"/>
+        </optional>
+        <optional>
+            <ref name="text-table-index-entry-template"/>
+        </optional>
+    </element>
+</define>
+<define name="text-table-index-entry-template">
+    <element name="text:table-index-entry-template">
+        <ref name="text-illustration-index-entry-content"/>
+    </element>
+</define>
+<define name="text-object-index">
+    <element name="text:object-index">
+        <ref name="sectionAttr"/>
+        <ref name="text-object-index-source"/>
+        <ref name="text-index-body"/>
+    </element>
+</define>
+<define name="text-object-index-source">
+    <element name="text:object-index-source">
+        <ref name="text-object-index-source-attrs"/>
+        <optional>
+            <ref name="text-index-title-template"/>
+        </optional>
+        <optional>
+            <ref name="text-object-index-entry-template"/>
+        </optional>
+    </element>
+</define>
+<define name="text-object-index-source-attrs" combine="interleave">
+    <ref name="text-index-scope-attr"/>
+</define>
+<define name="text-object-index-source-attrs" combine="interleave">
+    <ref name="text-relative-tab-stop-position-attr"/>
+</define>
+<define name="text-object-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:use-spreadsheet-objects" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-object-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:use-math-objects" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-object-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:use-draw-objects" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-object-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:use-chart-objects" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-object-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:use-other-objects" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-object-index-entry-template">
+    <element name="text:object-index-entry-template">
+        <ref name="text-illustration-index-entry-content"/>
+    </element>
+</define>
+<define name="text-user-index">
+    <element name="text:user-index">
+        <ref name="sectionAttr"/>
+        <ref name="text-user-index-source"/>
+        <ref name="text-index-body"/>
+    </element>
+</define>
+<define name="text-user-index-source">
+    <element name="text:user-index-source">
+        <ref name="text-user-index-source-attr"/>
+        <optional>
+            <ref name="text-index-title-template"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="text-user-index-entry-template"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="text-index-source-styles"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-user-index-source-attr" combine="interleave">
+    <ref name="text-index-scope-attr"/>
+    <ref name="text-relative-tab-stop-position-attr"/>
+    <attribute name="text:index-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="text-user-index-source-attr" combine="interleave">
+    <optional>
+        <attribute name="text:use-index-marks" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:use-graphics" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:use-tables" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:use-floating-frames"
+                     a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:use-objects" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-user-index-source-attr" combine="interleave">
+    <optional>
+        <attribute name="text:copy-outline-levels"
+                     a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-user-index-entry-template">
+    <element name="text:user-index-entry-template">
+        <ref name="text-user-index-entry-template-attrs"/>
+        <zeroOrMore>
+            <choice>
+                <ref name="text-index-entry-chapter"/>
+                <ref name="text-index-entry-page-number"/>
+                <ref name="text-index-entry-text"/>
+                <ref name="text-index-entry-span"/>
+                <ref name="text-index-entry-tab-stop"/>
+            </choice>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-user-index-entry-template-attrs" combine="interleave">
+    <attribute name="text:outline-level">
+        <ref name="positiveInteger"/>
+    </attribute>
+</define>
+<define name="text-user-index-entry-template-attrs" combine="interleave">
+    <attribute name="text:style-name">
+        <ref name="styleNameRef"/>
+    </attribute>
+</define>
+<define name="text-alphabetical-index">
+    <element name="text:alphabetical-index">
+        <ref name="sectionAttr"/>
+        <ref name="text-alphabetical-index-source"/>
+        <ref name="text-index-body"/>
+    </element>
+</define>
+<define name="text-alphabetical-index-source">
+    <element name="text:alphabetical-index-source">
+        <ref name="text-alphabetical-index-source-attrs"/>
+        <optional>
+            <ref name="text-index-title-template"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="text-alphabetical-index-entry-template"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-alphabetical-index-source-attrs" combine="interleave">
+    <ref name="text-index-scope-attr"/>
+    <ref name="text-relative-tab-stop-position-attr"/>
+</define>
+<define name="text-alphabetical-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:ignore-case" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-alphabetical-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:main-entry-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-alphabetical-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:alphabetical-separators" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-alphabetical-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:combine-entries" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:combine-entries-with-dash"
+                   a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:combine-entries-with-pp" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-alphabetical-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:use-keys-as-entries" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-alphabetical-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:capitalize-entries" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-alphabetical-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:comma-separated" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-alphabetical-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="fo:language">
+            <ref name="languageCode"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-alphabetical-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="fo:country">
+            <ref name="countryCode"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-alphabetical-index-source-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:sort-algorithm">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-alphabetical-index-auto-mark-file">
+    <element name="text:alphabetical-index-auto-mark-file">
+        <attribute name="xlink:href">
+            <ref name="anyURI"/>
+        </attribute>
+        <optional>
+            <attribute name="xlink:type" a:defaultValue="simple">
+                <value>simple</value>
+            </attribute>
+        </optional>
+    </element>
+</define>
+<define name="text-alphabetical-index-entry-template">
+    <element name="text:alphabetical-index-entry-template">
+        <ref name="text-alphabetical-index-entry-template-attrs"/>
+        <zeroOrMore>
+            <choice>
+                <ref name="text-index-entry-chapter"/>
+                <ref name="text-index-entry-page-number"/>
+                <ref name="text-index-entry-text"/>
+                <ref name="text-index-entry-span"/>
+                <ref name="text-index-entry-tab-stop"/>
+            </choice>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-alphabetical-index-entry-template-attrs"
+        combine="interleave">
+    <attribute name="text:outline-level">
+        <choice>
+            <value>1</value>
+            <value>2</value>
+            <value>3</value>
+            <value>separator</value>
+        </choice>
+    </attribute>
+</define>
+<define name="text-alphabetical-index-entry-template-attrs"
+        combine="interleave">
+    <attribute name="text:style-name">
+        <ref name="styleNameRef"/>
+    </attribute>
+</define>
+<define name="text-bibliography">
+    <element name="text:bibliography">
+        <ref name="sectionAttr"/>
+        <ref name="text-bibliography-source"/>
+        <ref name="text-index-body"/>
+    </element>
+</define>
+<define name="text-bibliography-source">
+    <element name="text:bibliography-source">
+        <optional>
+            <ref name="text-index-title-template"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="text-bibliography-entry-template"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-bibliography-entry-template">
+    <element name="text:bibliography-entry-template">
+        <ref name="text-bibliography-entry-template-attrs"/>
+        <zeroOrMore>
+            <choice>
+                <ref name="text-index-entry-span"/>
+                <ref name="text-index-entry-tab-stop"/>
+                <ref name="text-index-entry-bibliography"/>
+            </choice>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-bibliography-entry-template-attrs" combine="interleave">
+    <attribute name="text:bibliography-type">
+        <ref name="text-bibliography-types"/>
+    </attribute>
+</define>
+<define name="text-bibliography-entry-template-attrs" combine="interleave">
+    <attribute name="text:style-name">
+        <ref name="styleNameRef"/>
+    </attribute>
+</define>
+<define name="text-index-source-styles">
+    <element name="text:index-source-styles">
+        <attribute name="text:outline-level">
+            <ref name="positiveInteger"/>
+        </attribute>
+        <zeroOrMore>
+            <ref name="text-index-source-style"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-index-source-style">
+    <element name="text:index-source-style">
+        <attribute name="text:style-name">
+            <ref name="styleName"/>
+        </attribute>
+        <empty/>
+    </element>
+</define>
+<define name="text-index-title-template">
+    <element name="text:index-title-template">
+        <optional>
+            <attribute name="text:style-name">
+                <ref name="styleNameRef"/>
+            </attribute>
+        </optional>
+        <text/>
+    </element>
+</define>
+<define name="text-index-entry-chapter">
+    <element name="text:index-entry-chapter">
+        <optional>
+            <attribute name="text:style-name">
+                <ref name="styleNameRef"/>
+            </attribute>
+        </optional>
+        <ref name="text-index-entry-chapter-attrs"/>
+    </element>
+</define>
+<define name="text-index-entry-chapter-attrs">
+    <optional>
+        <attribute name="text:display" a:defaultValue="number">
+            <choice>
+                <value>name</value>
+                <value>number</value>
+                <value>number-and-name</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="text-index-entry-text">
+    <element name="text:index-entry-text">
+        <optional>
+            <attribute name="text:style-name">
+                <ref name="styleNameRef"/>
+            </attribute>
+        </optional>
+    </element>
+</define>
+<define name="text-index-entry-page-number">
+    <element name="text:index-entry-page-number">
+        <optional>
+            <attribute name="text:style-name">
+                <ref name="styleNameRef"/>
+            </attribute>
+        </optional>
+    </element>
+</define>
+<define name="text-index-entry-span">
+    <element name="text:index-entry-span">
+        <optional>
+            <attribute name="text:style-name">
+                <ref name="styleNameRef"/>
+            </attribute>
+        </optional>
+        <text/>
+    </element>
+</define>
+<define name="text-index-entry-bibliography">
+    <element name="text:index-entry-bibliography">
+        <ref name="text-index-entry-bibliography-attrs"/>
+    </element>
+</define>
+<define name="text-index-entry-bibliography-attrs" combine="interleave">
+    <optional>
+        <attribute name="text:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-index-entry-bibliography-attrs" combine="interleave">
+    <attribute name="text:bibliography-data-field">
+        <choice>
+            <value>address</value>
+            <value>annote</value>
+            <value>author</value>
+            <value>bibliography-type</value>
+            <value>booktitle</value>
+            <value>chapter</value>
+            <value>custom1</value>
+            <value>custom2</value>
+            <value>custom3</value>
+            <value>custom4</value>
+            <value>custom5</value>
+            <value>edition</value>
+            <value>editor</value>
+            <value>howpublished</value>
+            <value>identifier</value>
+            <value>institution</value>
+            <value>isbn</value>
+            <value>issn</value>
+            <value>journal</value>
+            <value>month</value>
+            <value>note</value>
+            <value>number</value>
+            <value>organizations</value>
+            <value>pages</value>
+            <value>publisher</value>
+            <value>report-type</value>
+            <value>school</value>
+            <value>series</value>
+            <value>title</value>
+            <value>url</value>
+            <value>volume</value>
+            <value>year</value>
+        </choice>
+    </attribute>
+</define>
+<define name="text-index-entry-tab-stop">
+    <element name="text:index-entry-tab-stop">
+        <optional>
+            <attribute name="text:style-name">
+                <ref name="styleNameRef"/>
+            </attribute>
+        </optional>
+        <ref name="text-index-entry-tab-stop-attrs"/>
+    </element>
+</define>
+<define name="text-index-entry-tab-stop-attrs" combine="interleave">
+    <optional>
+        <attribute name="style:leader-char">
+            <ref name="character"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-index-entry-tab-stop-attrs" combine="interleave">
+    <choice>
+        <attribute name="style:type">
+            <value>right</value>
+        </attribute>
+        <group>
+            <attribute name="style:type">
+                <value>left</value>
+            </attribute>
+            <attribute name="style:position">
+                <ref name="length"/>
+            </attribute>
+        </group>
+    </choice>
+</define>
+<define name="text-index-entry-link-start">
+    <element name="text:index-entry-link-start">
+        <optional>
+            <attribute name="text:style-name">
+                <ref name="styleNameRef"/>
+            </attribute>
+        </optional>
+    </element>
+</define>
+<define name="text-index-entry-link-end">
+    <element name="text:index-entry-link-end">
+        <optional>
+            <attribute name="text:style-name">
+                <ref name="styleNameRef"/>
+            </attribute>
+        </optional>
+    </element>
+</define>
+<define name="table-table">
+    <element name="table:table">
+        <ref name="table-table-attlist"/>
+        <optional>
+            <ref name="table-table-source"/>
+        </optional>
+        <optional>
+            <ref name="office-dde-source"/>
+        </optional>
+        <optional>
+            <ref name="table-scenario"/>
+        </optional>
+        <optional>
+            <ref name="office-forms"/>
+        </optional>
+        <optional>
+            <ref name="table-shapes"/>
+        </optional>
+        <ref name="table-columns-and-groups"/>
+        <ref name="table-rows-and-groups"/>
+    </element>
+</define>
+<define name="table-columns-and-groups">
+    <oneOrMore>
+        <choice>
+            <ref name="table-table-column-group"/>
+            <ref name="table-columns-no-group"/>
+        </choice>
+    </oneOrMore>
+</define>
+
+<define name="table-columns-no-group">
+    <choice>
+        <group>
+            <ref name="table-columns"/>
+            <optional>
+                <ref name="table-table-header-columns"/>
+                <optional>
+                    <ref name="table-columns"/>
+                </optional>
+            </optional>
+        </group>
+        <group>
+            <ref name="table-table-header-columns"/>
+            <optional>
+                <ref name="table-columns"/>
+            </optional>
+        </group>
+    </choice>
+</define>
+
+<define name="table-columns">
+    <choice>
+        <ref name="table-table-columns"/>
+        <oneOrMore>
+                <ref name="table-table-column"/>
+        </oneOrMore>
+    </choice>
+</define>
+
+<define name="table-rows-and-groups">
+    <oneOrMore>
+        <choice>
+            <ref name="table-table-row-group"/>
+            <ref name="table-rows-no-group"/>
+        </choice>
+    </oneOrMore>
+</define>
+
+<define name="table-rows-no-group">
+    <choice>
+        <group>
+            <ref name="table-rows"/>
+            <optional>
+                <ref name="table-table-header-rows"/>
+                <optional>
+                    <ref name="table-rows"/>
+                </optional>
+            </optional>
+        </group>
+        <group>
+            <ref name="table-table-header-rows"/>
+            <optional>
+                <ref name="table-rows"/>
+            </optional>
+        </group>
+    </choice>
+</define>
+
+<define name="table-rows">
+    <choice>
+        <ref name="table-table-rows"/>
+        <oneOrMore>
+            <optional>
+                <ref name="text-soft-page-break"/>
+            </optional>
+            <ref name="table-table-row"/>
+        </oneOrMore>
+    </choice>
+</define>
+<define name="table-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:protected" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="table:protection-key">
+            <text/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:print" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:print-ranges">
+            <ref name="cellRangeAddressList"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-row">
+    <element name="table:table-row">
+        <ref name="table-table-row-attlist"/>
+        <oneOrMore>
+            <choice>
+                <ref name="table-table-cell"/>
+                <ref name="table-covered-table-cell"/>
+            </choice>
+        </oneOrMore>
+    </element>
+</define>
+<define name="table-table-row-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:number-rows-repeated" a:defaultValue="1">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-row-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-row-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:default-cell-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-row-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:visibility" a:defaultValue="visible">
+            <ref name="table-visibility-value"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="table-visibility-value">
+    <choice>
+        <value>visible</value>
+        <value>collapse</value>
+        <value>filter</value>
+    </choice>
+</define>
+<define name="table-table-cell">
+    <element name="table:table-cell">
+        <ref name="table-table-cell-attlist"/>
+        <ref name="table-table-cell-attlist-extra"/>
+        <ref name="table-table-cell-content"/>
+    </element>
+</define>
+
+<define name="table-covered-table-cell">
+    <element name="table:covered-table-cell">
+        <ref name="table-table-cell-attlist"/>
+        <ref name="table-table-cell-content"/>
+    </element>
+</define>
+
+<define name="table-table-cell-content">
+    <optional>
+        <ref name="table-cell-range-source"/>
+    </optional>
+    <optional>
+        <ref name="office-annotation"/>
+    </optional>
+    <optional>
+        <ref name="table-detective"/>
+    </optional>
+    <zeroOrMore>
+        <ref name="text-content"/>
+    </zeroOrMore>
+</define>
+<define name="table-table-cell-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:number-columns-repeated" a:defaultValue="1">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-cell-attlist-extra" combine="interleave">
+    <optional>
+        <attribute name="table:number-columns-spanned" a:defaultValue="1">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="table:number-rows-spanned" a:defaultValue="1">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-cell-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-cell-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:content-validation-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-cell-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:formula">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-cell-attlist-extra" combine="interleave">
+    <optional>
+        <attribute name="table:number-matrix-columns-spanned">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="table:number-matrix-rows-spanned">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-cell-attlist" combine="interleave">
+    <optional>
+        <ref name="common-value-and-type-attlist"/>
+    </optional>
+</define>
+<define name="table-table-cell-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:protect" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-column">
+    <element name="table:table-column">
+        <ref name="table-table-column-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-table-column-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:number-columns-repeated" a:defaultValue="1">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-column-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-column-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:visibility" a:defaultValue="visible">
+            <ref name="table-visibility-value"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-column-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:default-cell-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-header-columns">
+    <element name="table:table-header-columns">
+        <oneOrMore>
+            <ref name="table-table-column"/>
+        </oneOrMore>
+    </element>
+</define>
+
+<define name="table-table-columns">
+    <element name="table:table-columns">
+        <oneOrMore>
+            <ref name="table-table-column"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="table-table-column-group">
+    <element name="table:table-column-group">
+        <ref name="table-table-column-group-attlist"/>
+        <ref name="table-columns-and-groups"/>
+    </element>
+</define>
+<define name="table-table-column-group-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:display" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-header-rows">
+    <element name="table:table-header-rows">
+        <oneOrMore>
+            <optional>
+                <ref name="text-soft-page-break"/>
+            </optional>
+            <ref name="table-table-row"/>
+        </oneOrMore>
+    </element>
+</define>
+
+<define name="table-table-rows">
+    <element name="table:table-rows">
+        <oneOrMore>
+            <optional>
+                <ref name="text-soft-page-break"/>
+            </optional>
+            <ref name="table-table-row"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="table-table-row-group">
+    <element name="table:table-row-group">
+        <ref name="table-table-row-group-attlist"/>
+        <ref name="table-rows-and-groups"/>
+    </element>
+</define>
+<define name="table-table-row-group-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:display" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:is-sub-table" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="cellAddress">
+    <data type="string">
+        <param name="pattern">($?([^\. ']+|'([^']|'')+'))?\.$?[A-Z]+$?[0-9]+</param>
+
+    </data>
+</define>
+<define name="cellRangeAddress">
+    <data type="string">
+        <param name="pattern">($?([^\. ']+|'([^']|'')+'))?\.$?[A-Z]+$?[0-9]+(:($?([^\. ']+|'([^']|'')+'))?\.$?[A-Z]+$?[0-9]+)?</param>
+
+    </data>
+</define>
+<define name="cellRangeAddressList">
+    <!-- Value is a space separated list of "cellRangeAddress" patterns -->
+    <data type="string"/> 
+</define>
+<define name="table-table-source">
+    <element name="table:table-source">
+        <ref name="table-table-source-attlist"/>
+        <ref name="table-linked-source-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-table-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:mode" a:defaultValue="copy-all">
+            <choice>
+                <value>copy-all</value>
+                <value>copy-results-only</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:table-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-linked-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="xlink:type" a:defaultValue="simple">
+            <value>simple</value>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="xlink:actuate" a:defaultValue="onRequest">
+            <value>onRequest</value>
+        </attribute>
+    </optional>
+    <attribute name="xlink:href">
+        <ref name="anyURI"/>
+    </attribute>
+</define>
+<define name="table-linked-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:filter-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-linked-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:filter-options">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-linked-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:refresh-delay">
+            <ref name="duration"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-scenario">
+    <element name="table:scenario">
+        <ref name="table-scenario-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-scenario-attlist" combine="interleave">
+    <attribute name="table:scenario-ranges">
+        <ref name="cellRangeAddressList"/>
+    </attribute>
+</define>
+<define name="table-scenario-attlist" combine="interleave">
+    <attribute name="table:is-active">
+        <ref name="boolean"/>
+    </attribute>
+</define>
+<define name="table-scenario-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:display-border" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-scenario-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:border-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-scenario-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:copy-back" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-scenario-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:copy-styles" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-scenario-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:copy-formulas" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-scenario-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:comment">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-scenario-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:protected">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-shapes">
+    <element name="table:shapes">
+        <oneOrMore>
+            <ref name="shape"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="table-cell-range-source">
+    <element name="table:cell-range-source">
+        <ref name="table-table-cell-range-source-attlist"/>
+        <ref name="table-linked-source-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-table-cell-range-source-attlist" combine="interleave">
+    <attribute name="table:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-table-cell-range-source-attlist" combine="interleave">
+    <attribute name="table:last-column-spanned">
+        <ref name="positiveInteger"/>
+    </attribute>
+    <attribute name="table:last-row-spanned">
+        <ref name="positiveInteger"/>
+    </attribute>
+</define>
+<define name="table-detective">
+    <element name="table:detective">
+        <zeroOrMore>
+            <ref name="table-highlighted-range"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="table-operation"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="table-operation">
+    <element name="table:operation">
+        <ref name="table-operation-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-operation-attlist" combine="interleave">
+    <attribute name="table:name">
+        <choice>
+            <value>trace-dependents</value>
+            <value>remove-dependents</value>
+            <value>trace-precedents</value>
+            <value>remove-precedents</value>
+            <value>trace-errors</value>
+        </choice>
+    </attribute>
+</define>
+<define name="table-operation-attlist" combine="interleave">
+    <attribute name="table:index">
+        <ref name="nonNegativeInteger"/>
+    </attribute>
+</define>
+<define name="table-highlighted-range">
+    <element name="table:highlighted-range">
+        <choice>
+            <group>
+                <ref name="table-highlighted-range-attlist"/>
+            </group>
+            <group>
+                <ref name="table-highlighted-range-attlist-invalid"/>
+            </group>
+        </choice>
+        <empty/>
+    </element>
+</define>
+<define name="table-highlighted-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:cell-range-address">
+            <ref name="cellRangeAddress"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-highlighted-range-attlist" combine="interleave">
+    <attribute name="table:direction">
+        <choice>
+            <value>from-another-table</value>
+            <value>to-another-table</value>
+            <value>from-same-table</value>
+        </choice>
+    </attribute>
+</define>
+<define name="table-highlighted-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:contains-error" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-highlighted-range-attlist-invalid" combine="interleave">
+    <attribute name="table:marked-invalid">
+        <ref name="boolean"/>
+    </attribute>
+</define>
+<define name="office-spreadsheet-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:structure-protected" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="table:protection-key">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-calculation-settings">
+    <element name="table:calculation-settings">
+        <ref name="table-calculation-setting-attlist"/>
+        <optional>
+            <ref name="table-null-date"/>
+        </optional>
+        <optional>
+            <ref name="table-iteration"/>
+        </optional>
+    </element>
+</define>
+<define name="table-calculation-setting-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:case-sensitive" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-calculation-setting-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:precision-as-shown" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-calculation-setting-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:search-criteria-must-apply-to-whole-cell"
+                     a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-calculation-setting-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:automatic-find-labels" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-calculation-setting-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:use-regular-expressions"
+                     a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-calculation-setting-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:null-year" a:defaultValue="1930">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-null-date">
+    <element name="table:null-date">
+        <optional>
+            <attribute name="table:value-type" a:defaultValue="date">
+                <ref name="valueType"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="table:date-value"
+                         a:defaultValue="1899-12-30">
+                <ref name="date"/>
+            </attribute>
+        </optional>
+        <empty/>
+    </element>
+</define>
+<define name="table-iteration">
+    <element name="table:iteration">
+        <optional>
+            <attribute name="table:status" a:defaultValue="disable">
+                <choice>
+                    <value>enable</value>
+                    <value>disable</value>
+                </choice>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="table:steps" a:defaultValue="100">
+                <ref name="positiveInteger"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="table:maximum-difference"
+                         a:defaultValue="0.001">
+                <ref name="double"/>
+            </attribute>
+        </optional>
+        <empty/>
+    </element>
+</define>
+<define name="table-content-validations">
+    <element name="table:content-validations">
+        <oneOrMore>
+            <ref name="table-content-validation"/>
+        </oneOrMore>
+    </element>
+</define>
+
+<define name="table-content-validation">
+    <element name="table:content-validation">
+        <ref name="table-validation-attlist"/>
+        <optional>
+            <ref name="table-help-message"/>
+        </optional>
+        <optional>
+            <choice>
+                <ref name="table-error-message"/>
+                <group>
+                    <ref name="table-error-macro"/>
+                    <optional>
+                        <ref name="office-event-listeners"/>
+                    </optional>
+                </group>
+            </choice>
+        </optional>
+    </element>
+</define>
+<define name="table-validation-attlist" combine="interleave">
+    <attribute name="table:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-validation-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:condition">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-validation-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:base-cell-address">
+            <ref name="cellAddress"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-validation-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:allow-empty-cell" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-validation-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:display-list" a:defaultValue="unsorted">
+            <choice>
+                <value>none</value>
+                <value>unsorted</value>
+                <value>sort-ascending</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="table-help-message">
+    <element name="table:help-message">
+        <optional>
+            <attribute name="table:title">
+                <ref name="string"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="table:display" a:defaultValue="false">
+                <ref name="boolean"/>
+            </attribute>
+        </optional>
+        <zeroOrMore>
+            <ref name="text-p"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="table-error-message">
+    <element name="table:error-message">
+        <optional>
+            <attribute name="table:title">
+                <ref name="string"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="table:display" a:defaultValue="false">
+                <ref name="boolean"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="table:message-type" a:defaultValue="stop">
+                <choice>
+                    <value>stop</value>
+                    <value>warning</value>
+                    <value>information</value>
+                </choice>
+            </attribute>
+        </optional>
+        <zeroOrMore>
+            <ref name="text-p"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="table-error-macro">
+    <element name="table:error-macro">
+        <optional>
+            <attribute name="table:execute" a:defaultValue="true">
+                <ref name="boolean"/>
+            </attribute>
+        </optional>
+    </element>
+</define>
+<define name="table-label-ranges">
+    <element name="table:label-ranges">
+        <zeroOrMore>
+            <ref name="table-label-range"/>
+        </zeroOrMore>
+    </element>
+</define>
+
+<define name="table-label-range">
+    <element name="table:label-range">
+        <ref name="table-label-range-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-label-range-attlist" combine="interleave">
+    <attribute name="table:label-cell-range-address">
+        <ref name="cellRangeAddress"/>
+    </attribute>
+</define>
+<define name="table-label-range-attlist" combine="interleave">
+    <attribute name="table:data-cell-range-address">
+        <ref name="cellRangeAddress"/>
+    </attribute>
+</define>
+<define name="table-label-range-attlist" combine="interleave">
+    <attribute name="table:orientation">
+        <choice>
+            <value>column</value>
+            <value>row</value>
+        </choice>
+    </attribute>
+</define>
+<define name="table-named-expressions">
+    <element name="table:named-expressions">
+        <zeroOrMore>
+            <choice>
+                <ref name="table-named-range"/>
+                <ref name="table-named-expression"/>
+            </choice>
+        </zeroOrMore>
+    </element>
+</define>
+
+<define name="table-named-range">
+    <element name="table:named-range">
+        <ref name="table-named-range-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="table-named-range-attlist" combine="interleave">
+    <attribute name="table:name">
+        <ref name="string"/>
+    </attribute>
+    <attribute name="table:cell-range-address">
+        <ref name="cellRangeAddress"/>
+    </attribute>
+    <optional>
+        <attribute name="table:base-cell-address">
+            <ref name="cellAddress"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="table:range-usable-as" a:defaultValue="none">
+            <choice>
+                <value>none</value>
+                <list>
+                    <oneOrMore>
+                        <choice>
+                            <value>print-range</value>
+                            <value>filter</value>
+                            <value>repeat-row</value>
+                            <value>repeat-column</value>
+                        </choice>
+                    </oneOrMore>
+                </list>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="table-named-expression">
+    <element name="table:named-expression">
+        <ref name="table-named-expression-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="table-named-expression-attlist" combine="interleave">
+    <attribute name="table:name">
+        <ref name="string"/>
+    </attribute>
+    <attribute name="table:expression">
+        <ref name="string"/>
+    </attribute>
+    <optional>
+        <attribute name="table:base-cell-address">
+            <ref name="cellAddress"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-database-ranges">
+    <element name="table:database-ranges">
+        <zeroOrMore>
+            <ref name="table-database-range"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="table-database-range">
+    <element name="table:database-range">
+        <ref name="table-database-range-attlist"/>
+        <optional>
+            <choice>
+                <ref name="table-database-source-sql"/>
+                <ref name="table-database-source-table"/>
+                <ref name="table-database-source-query"/>
+            </choice>
+        </optional>
+        <optional>
+            <ref name="table-filter"/>
+        </optional>
+        <optional>
+            <ref name="table-sort"/>
+        </optional>
+        <optional>
+            <ref name="table-subtotal-rules"/>
+        </optional>
+    </element>
+</define>
+<define name="table-database-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-database-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:is-selection" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-database-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:on-update-keep-styles" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-database-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:on-update-keep-size" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-database-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:has-persistent-data" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-database-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:orientation" a:defaultValue="row">
+            <choice>
+                <value>column</value>
+                <value>row</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="table-database-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:contains-header" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-database-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:display-filter-buttons"
+                   a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-database-range-attlist" combine="interleave">
+    <attribute name="table:target-range-address">
+        <ref name="cellRangeAddress"/>
+    </attribute>
+</define>
+<define name="table-database-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:refresh-delay">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-database-source-sql">
+    <element name="table:database-source-sql">
+        <ref name="table-database-source-sql-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-database-source-sql-attlist" combine="interleave">
+    <attribute name="table:database-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-database-source-sql-attlist" combine="interleave">
+    <attribute name="table:sql-statement">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-database-source-sql-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:parse-sql-statement" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-database-source-query">
+    <element name="table:database-source-table">
+        <ref name="table-database-source-table-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-database-source-table-attlist" combine="interleave">
+    <attribute name="table:database-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-database-source-table-attlist" combine="interleave">
+    <attribute name="table:database-table-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-database-source-table">
+    <element name="table:database-source-query">
+        <ref name="table-database-source-query-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-database-source-query-attlist" combine="interleave">
+    <attribute name="table:database-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-database-source-query-attlist" combine="interleave">
+    <attribute name="table:query-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-sort">
+    <element name="table:sort">
+        <ref name="table-sort-attlist"/>
+        <oneOrMore>
+            <ref name="table-sort-by"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="table-sort-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:bind-styles-to-content" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-sort-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:target-range-address">
+            <ref name="cellRangeAddress"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-sort-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:case-sensitive" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-sort-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:language">
+            <ref name="languageCode"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-sort-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:country">
+            <ref name="countryCode"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-sort-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:algorithm">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-sort-by">
+    <element name="table:sort-by">
+        <ref name="table-sort-by-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-sort-by-attlist" combine="interleave">
+    <attribute name="table:field-number">
+        <ref name="nonNegativeInteger"/>
+    </attribute>
+</define>
+<define name="table-sort-by-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:data-type" a:defaultValue="automatic">
+            <choice>
+                <value>text</value>
+                <value>number</value>
+                <value>automatic</value>
+                <ref name="string"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="table-sort-by-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:order" a:defaultValue="ascending">
+            <choice>
+                <value>ascending</value>
+                <value>descending</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="table-subtotal-rules">
+    <element name="table:subtotal-rules">
+        <ref name="table-subtotal-rules-attlist"/>
+        <optional>
+            <ref name="table-sort-groups"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="table-subtotal-rule"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="table-subtotal-rules-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:bind-styles-to-content" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-subtotal-rules-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:case-sensitive" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-subtotal-rules-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:page-breaks-on-group-change"
+                   a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-sort-groups">
+    <element name="table:sort-groups">
+        <ref name="table-sort-groups-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-sort-groups-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:data-type" a:defaultValue="automatic">
+            <choice>
+                <value>text</value>
+                <value>number</value>
+                <value>automatic</value>
+                <ref name="string"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="table-sort-groups-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:order" a:defaultValue="ascending">
+            <choice>
+                <value>ascending</value>
+                <value>descending</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="table-subtotal-rule">
+    <element name="table:subtotal-rule">
+        <ref name="table-subtotal-rule-attlist"/>
+        <zeroOrMore>
+            <ref name="table-subtotal-field"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="table-subtotal-rule-attlist" combine="interleave">
+    <attribute name="table:group-by-field-number">
+        <ref name="nonNegativeInteger"/>
+    </attribute>
+</define>
+<define name="table-subtotal-field">
+    <element name="table:subtotal-field">
+        <ref name="table-subtotal-field-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-subtotal-field-attlist" combine="interleave">
+    <attribute name="table:field-number">
+        <ref name="nonNegativeInteger"/>
+    </attribute>
+</define>
+<define name="table-subtotal-field-attlist" combine="interleave">
+    <attribute name="table:function">
+        <choice>
+            <value>auto</value>
+            <value>average</value>
+            <value>count</value>
+            <value>countnums</value>
+            <value>max</value>
+            <value>min</value>
+            <value>product</value>
+            <value>stdev</value>
+            <value>stdevp</value>
+            <value>sum</value>
+            <value>var</value>
+            <value>varp</value>
+            <ref name="string"/>
+        </choice>
+    </attribute>
+</define>
+<define name="table-filter">
+    <element name="table:filter">
+        <ref name="table-filter-attlist"/>
+        <choice>
+            <ref name="table-filter-condition"/>
+            <ref name="table-filter-and"/>
+            <ref name="table-filter-or"/>
+        </choice>
+    </element>
+</define>
+<define name="table-filter-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:target-range-address">
+            <ref name="cellRangeAddress"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-filter-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:condition-source" a:defaultValue="self">
+            <choice>
+                <value>self</value>
+                <value>cell-range</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="table-filter-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:condition-source-range-address">
+            <ref name="cellRangeAddress"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-filter-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:display-duplicates" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-filter-and">
+    <element name="table:filter-and">
+        <oneOrMore>
+            <choice>
+                <ref name="table-filter-or"/>
+                <ref name="table-filter-condition"/>
+            </choice>
+        </oneOrMore>
+    </element>
+</define>
+<define name="table-filter-or">
+    <element name="table:filter-or">
+        <oneOrMore>
+            <choice>
+                <ref name="table-filter-and"/>
+                <ref name="table-filter-condition"/>
+            </choice>
+        </oneOrMore>
+    </element>
+</define>
+<define name="table-filter-condition">
+    <element name="table:filter-condition">
+        <ref name="table-filter-condition-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-filter-condition-attlist" combine="interleave">
+    <attribute name="table:field-number">    
+        <ref name="nonNegativeInteger"/>
+    </attribute>
+</define>
+<define name="table-filter-condition-attlist" combine="interleave">
+    <attribute name="table:value">    
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-filter-condition-attlist" combine="interleave">
+    <attribute name="table:operator">    
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-filter-condition-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:case-sensitive" a:defaultValue="false">    
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-filter-condition-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:data-type" a:defaultValue="text">
+            <choice>
+                <value>text</value>
+                <value>number</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-tables">
+    <element name="table:data-pilot-tables">
+        <zeroOrMore>
+            <ref name="table-data-pilot-table"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="table-data-pilot-table">
+    <element name="table:data-pilot-table">
+        <ref name="table-data-pilot-table-attlist"/>
+        <optional>
+            <choice>
+                <ref name="table-database-source-sql"/>
+                <ref name="table-database-source-table"/>
+                <ref name="table-database-source-query"/>
+                <ref name="table-source-service"/>
+                <ref name="table-source-cell-range"/>
+            </choice>
+        </optional>
+        <oneOrMore>
+            <ref name="table-data-pilot-field"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="table-data-pilot-table-attlist" combine="interleave">
+    <attribute name="table:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-data-pilot-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:application-data">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:grand-total" a:defaultValue="both">
+            <choice>
+                <value>none</value>
+                <value>row</value>
+                <value>column</value>
+                <value>both</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:ignore-empty-rows" a:defaultValue="false">    
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:identify-categories" a:defaultValue="false">    
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-table-attlist" combine="interleave">
+    <attribute name="table:target-range-address">    
+        <ref name="cellRangeAddress"/>
+    </attribute>
+</define>
+<define name="table-data-pilot-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:buttons">    
+            <ref name="cellRangeAddressList"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:show-filter-button" a:defaultValue="true">    
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-table-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:drill-down-on-double-click"
+                   a:defaultValue="true">    
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-source-cell-range">
+    <element name="table:source-cell-range">
+        <ref name="table-source-cell-range-attlist"/>
+        <optional>
+            <ref name="table-filter"/>
+        </optional>
+    </element>
+</define>
+<define name="table-source-cell-range-attlist" combine="interleave">
+    <attribute name="table:cell-range-address">    
+        <ref name="cellRangeAddress"/>
+    </attribute>
+</define>
+<define name="table-source-service">
+    <element name="table:source-service">
+        <ref name="table-source-service-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-source-service-attlist" combine="interleave">
+    <attribute name="table:name">    
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-source-service-attlist" combine="interleave">
+    <attribute name="table:source-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-source-service-attlist" combine="interleave">
+    <attribute name="table:object-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-source-service-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:user-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-source-service-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:password">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-field">
+    <element name="table:data-pilot-field">
+        <ref name="table-data-pilot-field-attlist"/>
+        <optional>
+            <ref name="table-data-pilot-level"/>
+        </optional>
+        <optional>
+            <ref name="table-data-pilot-field-reference"/>
+        </optional>
+        <optional>
+            <ref name="table-data-pilot-groups"/>
+        </optional>
+    </element>
+</define>
+<define name="table-data-pilot-field-attlist" combine="interleave">
+    <attribute name="table:source-field-name">    
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-data-pilot-field-attlist" combine="interleave">
+    <choice>
+        <attribute name="table:orientation">    
+            <choice>
+                <value>row</value>
+                <value>column</value>
+                <value>data</value>
+                <value>hidden</value>
+            </choice>
+        </attribute>
+        <group>
+            <attribute name="table:orientation">
+                <value>page</value>
+            </attribute>
+            <attribute name="table:selected-page">
+                <ref name="string"/>
+            </attribute>
+        </group>
+    </choice>
+</define>
+<define name="table-data-pilot-field-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:is-data-layout-field" a:defaultValue="false">    
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-field-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:function">
+            <choice>
+                <value>auto</value>
+                <value>average</value>
+                <value>count</value>
+                <value>countnums</value>
+                <value>max</value>
+                <value>min</value>
+                <value>product</value>
+                <value>stdev</value>
+                <value>stdevp</value>
+                <value>sum</value>
+                <value>var</value>
+                <value>varp</value>
+                <ref name="string"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-field-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:used-hierarchy" a:defaultValue="-1">    
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-level">
+    <element name="table:data-pilot-level">
+        <ref name="table-data-pilot-level-attlist"/>
+        <optional>
+            <ref name="table-data-pilot-subtotals"/>
+        </optional>
+        <optional>
+            <ref name="table-data-pilot-members"/>
+        </optional>
+        <optional>
+            <ref name="table-data-pilot-display-info"/>
+        </optional>
+        <optional>
+            <ref name="table-data-pilot-sort-info"/>
+        </optional>
+        <optional>
+            <ref name="table-data-pilot-layout-info"/>
+        </optional>
+    </element>
+</define>
+<define name="table-data-pilot-level-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:show-empty">    
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-subtotals">
+    <element name="table:data-pilot-subtotals">
+        <zeroOrMore>
+            <ref name="table-data-pilot-subtotal"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="table-data-pilot-subtotal">
+    <element name="table:data-pilot-subtotal">
+        <ref name="table-data-pilot-subtotal-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-data-pilot-subtotal-attlist" combine="interleave">
+    <attribute name="table:function">
+        <choice>
+            <value>auto</value>
+            <value>average</value>
+            <value>count</value>
+            <value>countnums</value>
+            <value>max</value>
+            <value>min</value>
+            <value>product</value>
+            <value>stdev</value>
+            <value>stdevp</value>
+            <value>sum</value>
+            <value>var</value>
+            <value>varp</value>
+            <ref name="string"/>
+        </choice>
+    </attribute>
+</define>
+<define name="table-data-pilot-members">
+    <element name="table:data-pilot-members">
+        <zeroOrMore>
+            <ref name="table-data-pilot-member"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="table-data-pilot-member">
+    <element name="table:data-pilot-member">
+        <ref name="table-data-pilot-member-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-data-pilot-member-attlist" combine="interleave">
+    <attribute name="table:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-data-pilot-member-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:display">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-member-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:show-details">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-data-pilot-display-info">
+    <element name="table:data-pilot-display-info">
+        <ref name="table-data-pilot-display-info-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-data-pilot-display-info-attlist" combine="interleave">
+    <attribute name="table:enabled">
+        <ref name="boolean"/>
+    </attribute>
+</define>
+<define name="table-data-pilot-display-info-attlist" combine="interleave">
+    <attribute name="table:data-field">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-data-pilot-display-info-attlist" combine="interleave">
+    <attribute name="table:member-count">
+        <ref name="nonNegativeInteger"/>
+    </attribute>
+</define>
+<define name="table-data-pilot-display-info-attlist" combine="interleave">
+    <attribute name="table:display-member-mode">
+        <choice>
+            <value>from-top</value>
+            <value>from-bottom</value>
+        </choice>
+    </attribute>
+</define>
+<define name="table-data-pilot-sort-info">
+    <element name="table:data-pilot-sort-info">
+        <ref name="table-data-pilot-sort-info-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-data-pilot-sort-info-attlist" combine="interleave">
+    <choice>
+        <group>
+            <attribute name="table:sort-mode">
+                <value>data</value>
+            </attribute>
+            <attribute name="table:data-field">
+                <ref name="string"/>
+            </attribute>
+        </group>
+        <attribute name="table:sort-mode">
+            <choice>
+                <value>none</value>
+                <value>manual</value>
+                <value>name</value>
+            </choice>
+        </attribute>
+    </choice>
+</define>
+<define name="table-data-pilot-sort-info-attlist" combine="interleave">
+    <attribute name="table:order">
+        <choice>
+            <value>ascending</value>
+            <value>descending</value>
+        </choice>
+    </attribute>
+</define>
+<define name="table-data-pilot-layout-info">
+    <element name="table:data-pilot-layout-info">
+        <ref name="table-data-pilot-layout-info-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-data-pilot-layout-info-attlist" combine="interleave">
+    <attribute name="table:layout-mode">
+        <choice>
+            <value>tabular-layout</value>
+            <value>outline-subtotals-top</value>
+            <value>outline-subtotals-bottom</value>
+        </choice>
+    </attribute>
+</define>
+<define name="table-data-pilot-layout-info-attlist" combine="interleave">
+    <attribute name="table:add-empty-lines">
+        <ref name="boolean"/>
+    </attribute>
+</define>
+<define name="table-data-pilot-field-reference">
+    <element name="table:data-pilot-field-reference">
+        <ref name="table-data-pilot-field-reference-attlist"/>
+    </element>
+</define>
+<define name="table-data-pilot-field-reference-attlist" combine="interleave">
+    <attribute name="table:field-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-data-pilot-field-reference-attlist" combine="interleave">
+    <choice>
+        <group>
+            <attribute name="table:member-type">
+                <value>named</value>
+            </attribute>
+            <attribute name="table:member-name">
+                <ref name="string"/>
+            </attribute>
+        </group>
+        <attribute name="table:member-type">
+            <choice>
+                <value>previous</value>
+                <value>next</value>
+            </choice>
+        </attribute>
+    </choice>
+</define>
+<define name="table-data-pilot-field-reference-attlist" combine="interleave">
+    <attribute name="table:type">
+        <choice>
+            <value>none</value>
+            <value>member-difference</value>
+            <value>member-percentage</value>
+            <value>member-percentage-difference</value>
+            <value>running-total</value>
+            <value>row-percentage</value>
+            <value>column-percentage</value>
+            <value>total-percentage</value>
+            <value>index</value>
+        </choice>
+    </attribute>
+</define>
+<define name="table-data-pilot-groups">
+    <element name="table:data-pilot-groups">
+        <ref name="table-data-pilot-groups-attlist"/>
+        <oneOrMore>
+            <ref name="table-data-pilot-group"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="table-data-pilot-groups-attlist" combine="interleave">
+    <attribute name="table:source-field-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-data-pilot-groups-attlist" combine="interleave">
+    <choice>
+        <attribute name="table:date-start">
+            <choice>
+                <ref name="dateOrDateTime"/>
+                <value>auto</value>
+            </choice>
+        </attribute>
+        <attribute name="table:start">
+            <choice>
+                <ref name="double"/>
+                <value>auto</value>
+            </choice>
+        </attribute>
+    </choice>
+</define>
+<define name="table-data-pilot-groups-attlist" combine="interleave">
+    <choice>
+        <attribute name="table:date-end">
+            <choice>
+                <ref name="dateOrDateTime"/>
+                <value>auto</value>
+            </choice>
+        </attribute>
+        <attribute name="table:end">
+            <choice>
+                <ref name="double"/>
+                <value>auto</value>
+            </choice>
+        </attribute>
+    </choice>
+</define>
+<define name="table-data-pilot-groups-attlist" combine="interleave">
+    <attribute name="table:step">
+        <ref name="double"/>
+    </attribute>
+</define>
+<define name="table-data-pilot-groups-attlist" combine="interleave">
+    <attribute name="table:grouped-by">
+        <choice>
+            <value>seconds</value>
+            <value>minutes</value>
+            <value>hours</value>
+            <value>days</value>
+            <value>months</value>
+            <value>quarters</value>
+            <value>years</value>
+        </choice>
+    </attribute>
+</define>
+<define name="table-data-pilot-group">
+    <element name="table:data-pilot-group">
+        <ref name="table-data-pilot-group-attlist"/>
+        <oneOrMore>
+            <ref name="table-data-pilot-group-member"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="table-data-pilot-group-attlist" combine="interleave">
+    <attribute name="table:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-data-pilot-group-member">
+    <element name="table:data-pilot-group-member">
+        <ref name="table-data-pilot-group-member-attlist"/>
+    </element>
+</define>
+<define name="table-data-pilot-group-member-attlist" combine="interleave">
+    <attribute name="table:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-consolidation">
+    <element name="table:consolidation">
+        <ref name="table-consolidation-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-consolidation-attlist" combine="interleave">
+    <attribute name="table:function">    
+        <choice>
+            <value>auto</value>
+            <value>average</value>
+            <value>count</value>
+            <value>countnums</value>
+            <value>max</value>
+            <value>min</value>
+            <value>product</value>
+            <value>stdev</value>
+            <value>stdevp</value>
+            <value>sum</value>
+            <value>var</value>
+            <value>varp</value>
+            <ref name="string"/>
+        </choice>
+    </attribute>
+</define>
+<define name="table-consolidation-attlist" combine="interleave">
+    <attribute name="table:source-cell-range-addresses">    
+        <ref name="cellRangeAddressList"/>
+    </attribute>
+</define>
+<define name="table-consolidation-attlist" combine="interleave">
+    <attribute name="table:target-cell-address">    
+        <ref name="cellAddress"/>
+    </attribute>
+</define>
+<define name="table-consolidation-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:use-labels" a:defaultValue="none">
+            <choice>
+                <value>none</value>
+                <value>row</value>
+                <value>column</value>
+                <value>both</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="table-consolidation-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:link-to-source-data" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-dde-links">
+    <element name="table:dde-links">
+        <oneOrMore>
+            <ref name="table-dde-link"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="table-tracked-changes">
+    <element name="table:tracked-changes">
+        <ref name="table-tracked-changes-attlist"/>
+        <zeroOrMore>
+            <choice>
+                <ref name="table-cell-content-change"/>
+                <ref name="table-insertion"/>
+                <ref name="table-deletion"/>
+                <ref name="table-movement"/>
+            </choice>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="table-tracked-changes-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:track-changes" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-insertion">
+    <element name="table:insertion">
+        <ref name="table-insertion-attlist"/>
+        <ref name="common-table-change-attlist"/>
+        <ref name="office-change-info"/>
+        <optional>
+            <ref name="table-dependencies"/>
+        </optional>
+        <optional>
+            <ref name="table-deletions"/>
+        </optional>
+    </element>
+</define>
+<define name="table-insertion-attlist" combine="interleave">
+    <attribute name="table:type">
+        <choice>
+            <value>row</value>
+            <value>column</value>
+            <value>table</value>
+        </choice>
+    </attribute>
+</define>
+<define name="table-insertion-attlist" combine="interleave">
+    <attribute name="table:position">
+        <ref name="integer"/>
+    </attribute>
+</define>
+<define name="table-insertion-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:count" a:defaultValue="1">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-insertion-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:table">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-dependencies">
+    <element name="table:dependencies">
+        <oneOrMore>
+            <ref name="table-dependency"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="table-dependency">
+    <element name="table:dependency">
+        <attribute name="table:id">
+            <ref name="string"/>
+        </attribute>
+        <empty/>
+    </element>
+</define>
+<define name="table-deletions">
+    <element name="table:deletions">
+        <oneOrMore>
+            <choice>
+                <ref name="table-cell-content-deletion"/>
+                <ref name="table-change-deletion"/>
+            </choice>
+        </oneOrMore>
+    </element>
+</define>
+<define name="table-cell-content-deletion">
+    <element name="table:cell-content-deletion">
+        <optional>
+            <attribute name="table:id">
+                <ref name="string"/>
+            </attribute>
+        </optional>
+        <optional>
+            <ref name="table-cell-address"/>
+        </optional>
+        <optional>
+            <ref name="table-change-track-table-cell"/>
+        </optional>
+    </element>
+</define>
+<define name="table-change-deletion">
+    <element name="table:change-deletion">
+        <optional>
+            <attribute name="table:id">
+                <ref name="string"/>
+            </attribute>
+        </optional>
+        <empty/>
+    </element>
+</define>
+<define name="table-deletion">
+    <element name="table:deletion">
+        <ref name="table-deletion-attlist"/>
+        <ref name="common-table-change-attlist"/>
+        <ref name="office-change-info"/>
+        <optional>
+            <ref name="table-dependencies"/>
+        </optional>
+        <optional>
+            <ref name="table-deletions"/>
+        </optional>
+        <optional>
+            <ref name="table-cut-offs"/>
+        </optional>
+    </element>
+</define>
+<define name="table-deletion-attlist" combine="interleave">
+    <attribute name="table:type">
+        <choice>
+            <value>row</value>
+            <value>column</value>
+            <value>table</value>
+        </choice>
+    </attribute>
+</define>
+<define name="table-deletion-attlist" combine="interleave">
+    <attribute name="table:position">
+        <ref name="integer"/>
+    </attribute>
+</define>
+<define name="table-deletion-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:table">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-deletion-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:multi-deletion-spanned">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-cut-offs">
+    <element name="table:cut-offs">
+        <choice>
+            <oneOrMore>
+                <ref name="table-movement-cut-off"/>
+            </oneOrMore>
+            <group>
+                <ref name="table-insertion-cut-off"/>
+                <zeroOrMore>
+                    <ref name="table-movement-cut-off"/>
+                </zeroOrMore>
+            </group>
+        </choice>
+    </element>
+</define>
+<define name="table-insertion-cut-off">
+    <element name="table:insertion-cut-off">
+        <ref name="table-insertion-cut-off-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-insertion-cut-off-attlist" combine="interleave">
+    <attribute name="table:id">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-insertion-cut-off-attlist" combine="interleave">
+    <attribute name="table:position">
+        <ref name="integer"/>
+    </attribute>
+</define>
+<define name="table-movement-cut-off">
+    <element name="table:movement-cut-off">
+        <ref name="table-movement-cut-off-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-movement-cut-off-attlist" combine="interleave">
+    <choice>
+        <attribute name="table:position">
+            <ref name="integer"/>
+        </attribute>
+        <group>
+            <attribute name="table:start-position">
+                <ref name="integer"/>
+            </attribute>
+            <attribute name="table:end-position">
+                <ref name="integer"/>
+            </attribute>
+        </group>
+    </choice>
+</define>
+<define name="table-movement">
+    <element name="table:movement">
+        <ref name="common-table-change-attlist"/>
+        <ref name="table-source-range-address"/>
+        <ref name="table-target-range-address"/>
+        <ref name="office-change-info"/>
+        <optional>
+            <ref name="table-dependencies"/>
+        </optional>
+        <optional>
+            <ref name="table-deletions"/>
+        </optional>
+    </element>
+</define>
+<define name="table-source-range-address">
+    <element name="table:source-range-address">
+        <ref name="common-table-range-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="table-target-range-address">
+    <element name="table:target-range-address">
+        <ref name="common-table-range-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+
+<define name="common-table-range-attlist" combine="interleave">
+    <choice>
+        <group>
+            <ref name="common-table-cell-address-attlist"/>
+        </group>
+        <group>
+            <ref name="common-table-cell-range-address-attlist"/>
+        </group>
+    </choice>
+</define>
+<define name="common-table-cell-address-attlist" combine="interleave">
+    <attribute name="table:column">
+        <ref name="integer"/>
+    </attribute>
+    <attribute name="table:row">
+        <ref name="integer"/>
+    </attribute>
+    <attribute name="table:table">
+        <ref name="integer"/>
+    </attribute>
+</define>
+<define name="common-table-cell-range-address-attlist" combine="interleave">
+    <attribute name="table:start-column">
+        <ref name="integer"/>
+    </attribute>
+    <attribute name="table:start-row">
+        <ref name="integer"/>
+    </attribute>
+    <attribute name="table:start-table">
+        <ref name="integer"/>
+    </attribute>
+    <attribute name="table:end-column">
+        <ref name="integer"/>
+    </attribute>
+    <attribute name="table:end-row">
+        <ref name="integer"/>
+    </attribute>
+    <attribute name="table:end-table">
+        <ref name="integer"/>
+    </attribute>
+</define>
+<define name="table-change-track-table-cell" combine="interleave">
+    <element name="table:change-track-table-cell">
+        <ref name="table-change-track-table-cell-attlist"/>
+        <zeroOrMore>
+            <ref name="text-p"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="table-change-track-table-cell-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:cell-address">
+            <ref name="cellAddress"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-change-track-table-cell-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:matrix-covered" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-change-track-table-cell-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:formula">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="table:number-matrix-columns-spanned">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="table:number-matrix-rows-spanned">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+    <optional>
+        <ref name="common-value-and-type-attlist"/>
+    </optional>
+</define>
+<define name="table-cell-content-change">
+    <element name="table:cell-content-change">
+        <ref name="common-table-change-attlist"/>
+        <ref name="table-cell-address"/>
+        <ref name="office-change-info"/>
+        <optional>
+            <ref name="table-dependencies"/>
+        </optional>
+        <optional>
+            <ref name="table-deletions"/>
+        </optional>
+        <ref name="table-previous"/>
+    </element>
+</define>
+<define name="table-cell-address">
+    <element name="table:cell-address">
+        <ref name="common-table-cell-address-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="table-previous">
+    <element name="table:previous">
+        <optional>
+            <attribute name="table:id">
+                <ref name="string"/>
+            </attribute>
+        </optional>
+        <ref name="table-change-track-table-cell"/>
+    </element>
+</define>
+<define name="common-table-change-attlist" combine="interleave">
+    <attribute name="table:id">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="common-table-change-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:acceptance-state" a:defaultValue="pending">
+            <choice>
+                <value>accepted</value>
+                <value>rejected</value>
+                <value>pending</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-table-change-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:rejecting-change-id">
+            <ref name="string"/> 
+        </attribute>
+    </optional>
+</define>
+<define name="style-handout-master">
+    <element name="style:handout-master">
+        <ref name="common-presentation-header-footer-attlist"/>
+        <ref name="style-handout-master-attlist"/>
+        <zeroOrMore>
+            <ref name="shape"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="style-handout-master-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:presentation-page-layout-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-handout-master-attlist" combine="interleave">
+    <attribute name="style:page-layout-name">
+        <ref name="styleNameRef"/>
+    </attribute>
+</define>
+<define name="style-handout-master-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-layer-set">
+    <element name="draw:layer-set">
+        <zeroOrMore>
+            <ref name="draw-layer"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="draw-layer">
+    <element name="draw:layer">
+        <ref name="draw-layer-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+    </element>
+</define>
+<define name="draw-layer-attlist" combine="interleave">
+    <attribute name="draw:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="draw-layer-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:protected" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-layer-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:display" a:defaultValue="always">
+            <choice>
+                <value>always</value>
+                <value>screen</value>
+                <value>printer</value>
+                <value>none</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-page">
+    <element name="draw:page">
+        <ref name="common-presentation-header-footer-attlist"/>
+        <ref name="draw-page-attlist"/>
+        <optional>
+            <ref name="office-forms"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="shape"/>
+        </zeroOrMore>
+        <optional>
+            <choice>
+                <ref name="presentation-animations"/>
+                <ref name="animation-element"/>
+            </choice>
+        </optional>
+        <optional>
+            <ref name="presentation-notes"/>
+        </optional>
+    </element>
+</define>
+<define name="draw-page-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-page-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-page-attlist" combine="interleave">
+    <attribute name="draw:master-page-name">
+        <ref name="styleNameRef"/>
+    </attribute>
+</define>
+<define name="draw-page-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:presentation-page-layout-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-presentation-header-footer-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:use-header-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-presentation-header-footer-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:use-footer-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-presentation-header-footer-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:use-date-time-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-page-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:id">
+            <ref name="ID"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-page-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:nav-order">
+            <ref name="IDREFS"/>
+        </attribute>
+    </optional>
+</define>
+<define name="shape">
+    <choice>
+        <ref name="draw-rect"/>
+        <ref name="draw-line"/>
+        <ref name="draw-polyline"/>
+        <ref name="draw-polygon"/>
+        <ref name="draw-regular-polygon"/>
+        <ref name="draw-path"/>
+        <ref name="draw-circle"/>
+        <ref name="draw-ellipse"/>
+        <ref name="draw-g"/>
+        <ref name="draw-page-thumbnail"/>
+        <ref name="draw-frame"/>
+        <ref name="draw-measure"/>
+        <ref name="draw-caption"/>
+        <ref name="draw-connector"/>
+        <ref name="draw-control"/>
+        <ref name="dr3d-scene"/>
+        <ref name="draw-custom-shape"/>
+    </choice>
+</define>
+<define name="draw-rect">
+    <element name="draw:rect">
+        <ref name="draw-rect-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <ref name="draw-text"/>
+    </element>
+</define>
+<define name="draw-rect-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:corner-radius">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-line">
+    <element name="draw:line">
+        <ref name="draw-line-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <ref name="draw-text"/>
+    </element>
+</define>
+<define name="draw-line-attlist" combine="interleave">
+    <attribute name="svg:x1">
+        <ref name="coordinate"/>
+    </attribute>
+    <attribute name="svg:y1">
+        <ref name="coordinate"/>
+    </attribute>
+</define>
+<define name="draw-line-attlist" combine="interleave">
+    <attribute name="svg:x2">
+        <ref name="coordinate"/>
+    </attribute>
+    <attribute name="svg:y2">
+        <ref name="coordinate"/>
+    </attribute>
+</define>
+<define name="draw-polyline">
+    <element name="draw:polyline">
+        <ref name="common-draw-points-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-viewbox-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <ref name="draw-text"/>
+    </element>
+</define>
+<define name="common-draw-points-attlist">
+    <attribute name="draw:points">
+        <ref name="points"/>
+    </attribute>
+</define>
+<define name="draw-polygon">
+    <element name="draw:polygon">
+        <ref name="common-draw-points-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-viewbox-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <ref name="draw-text"/>
+    </element>
+</define>
+<define name="draw-regular-polygon">
+    <element name="draw:regular-polygon">
+        <ref name="draw-regular-polygon-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <ref name="draw-text"/>
+    </element>
+</define>
+<define name="draw-regular-polygon-attlist" combine="interleave">
+    <choice>
+        <attribute name="draw:concave">
+            <value>false</value>
+        </attribute>
+        <group>
+            <attribute name="draw:concave">
+                <value>true</value>
+            </attribute>
+            <ref name="draw-regular-polygon-sharpness-attlist"/>
+        </group>
+    </choice>
+</define>
+<define name="draw-regular-polygon-attlist" combine="interleave">
+    <attribute name="draw:corners">
+        <ref name="positiveInteger"/>
+    </attribute>
+</define>
+<define name="draw-regular-polygon-sharpness-attlist">
+    <attribute name="draw:sharpness">
+        <ref name="percent"/>
+    </attribute>
+</define>
+<define name="draw-path">
+    <element name="draw:path">
+        <ref name="common-draw-path-data-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-viewbox-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <ref name="draw-text"/>
+    </element>
+</define>
+<define name="common-draw-path-data-attlist">
+    <attribute name="svg:d">
+        <ref name="pathData"/>
+    </attribute>
+</define>
+<define name="draw-circle">
+    <element name="draw:circle">
+        <ref name="draw-circle-attlist"/>
+        <ref name="common-draw-circle-ellipse-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <ref name="draw-text"/>
+    </element>
+</define>
+<define name="common-draw-circle-ellipse-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:cx">
+            <ref name="coordinate"/>
+        </attribute>
+        <attribute name="svg:cy">
+            <ref name="coordinate"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-circle-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:r">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-circle-ellipse-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:kind" a:defaultValue="full">
+            <choice>
+                <value>full</value>
+                <value>section</value>
+                <value>cut</value>
+                <value>arc</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-circle-ellipse-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:start-angle">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-circle-ellipse-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:end-angle">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-ellipse">
+    <element name="draw:ellipse">
+        <ref name="common-draw-circle-ellipse-attlist"/>
+        <ref name="draw-ellipse-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <ref name="draw-text"/>
+    </element>
+</define>
+<define name="draw-ellipse-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:rx">
+            <ref name="length"/>
+        </attribute>
+        <attribute name="svg:ry">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-connector">
+    <element name="draw:connector">
+        <ref name="draw-connector-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <ref name="draw-text"/>
+    </element>
+</define>
+<define name="draw-connector-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:type" a:defaultValue="standard">
+            <choice>
+                <value>standard</value>
+                <value>lines</value>
+                <value>line</value>
+                <value>curve</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-connector-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:x1">
+            <ref name="coordinate"/>
+        </attribute>
+        <attribute name="svg:y1">
+            <ref name="coordinate"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-connector-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:start-shape">
+            <ref name="IDREF"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-connector-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:start-glue-point">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-connector-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:x2">
+            <ref name="coordinate"/>
+        </attribute>
+        <attribute name="svg:y2">
+            <ref name="coordinate"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-connector-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:end-shape">
+            <ref name="IDREF"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-connector-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:end-glue-point">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-connector-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:line-skew">
+            <list>
+                <ref name="length"/>
+                <optional>
+                    <ref name="length"/>
+                    <optional>
+                        <ref name="length"/>
+                    </optional>
+                </optional>
+            </list>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-caption">
+    <element name="draw:caption">
+        <ref name="draw-caption-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <ref name="draw-text"/>
+    </element>
+</define>
+<define name="draw-caption-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:caption-point-x">
+            <ref name="coordinate"/>
+        </attribute>
+        <attribute name="draw:caption-point-y">
+            <ref name="coordinate"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-caption-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:corner-radius">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-measure">
+    <element name="draw:measure">
+        <ref name="draw-measure-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <ref name="draw-text"/>
+    </element>
+</define>
+<define name="draw-measure-attlist" combine="interleave">
+    <attribute name="svg:x1">
+        <ref name="coordinate"/>
+    </attribute>
+    <attribute name="svg:y1">
+        <ref name="coordinate"/>
+    </attribute>
+</define>
+<define name="draw-measure-attlist" combine="interleave">
+    <attribute name="svg:x2">
+        <ref name="coordinate"/>
+    </attribute>
+    <attribute name="svg:y2">
+        <ref name="coordinate"/>
+    </attribute>
+</define>
+<define name="draw-control">
+    <element name="draw:control">
+        <ref name="draw-control-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>    
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="draw-control-attlist" combine="interleave">
+    <attribute name="draw:control">
+        <ref name="IDREF"/>
+    </attribute>
+</define>
+<define name="draw-page-thumbnail">
+    <element name="draw:page-thumbnail">
+        <ref name="draw-page-thumbnail-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="presentation-shape-attlist"/>
+        <ref name="common-draw-shape-with-styles-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+    </element>
+</define>
+<define name="draw-page-thumbnail-attlist">
+    <optional>
+        <attribute name="draw:page-number">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-g">
+    <element name="draw:g">
+        <ref name="draw-g-attlist"/>
+        <ref name="common-draw-z-index-attlist"/>
+        <ref name="common-draw-name-attlist"/>
+        <ref name="common-draw-id-attlist"/>
+        <ref name="common-draw-style-name-attlist"/>
+        <ref name="common-text-spreadsheet-shape-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="shape"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="draw-g-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:y">
+            <ref name="coordinate"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-name-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-caption-id-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:caption-id">
+            <ref name="IDREF"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-position-attlist">
+    <optional>
+        <attribute name="svg:x">
+            <ref name="coordinate"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:y">
+            <ref name="coordinate"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-size-attlist">
+    <optional>
+        <attribute name="svg:width">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:height">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-transform-attlist">
+    <optional>
+        <attribute name="draw:transform">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-viewbox-attlist">
+    <attribute name="svg:viewBox">
+        <list>
+            <ref name="integer"/>
+            <ref name="integer"/>
+            <ref name="integer"/>
+            <ref name="integer"/>
+        </list>
+    </attribute>
+</define>
+<define name="common-draw-style-name-attlist">
+    <choice>
+        <group>
+            <optional>
+                <attribute name="draw:style-name">
+                    <ref name="styleNameRef"/>
+                </attribute>
+            </optional>
+            <optional>
+                <attribute name="draw:class-names">
+                    <ref name="styleNameRefs"/>
+                </attribute>
+            </optional>
+        </group>
+        <group>
+            <optional>
+                <attribute name="presentation:style-name">
+                    <ref name="styleNameRef"/>
+                </attribute>
+            </optional>
+            <optional>
+                <attribute name="presentation:class-names">
+                    <ref name="styleNameRefs"/>
+                </attribute>
+            </optional>
+        </group>
+    </choice>
+</define>
+<define name="common-draw-text-style-name-attlist">
+    <optional>
+        <attribute name="draw:text-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-layer-name-attlist">
+    <optional>
+        <attribute name="draw:layer">
+            <data type="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-id-attlist">
+    <optional>
+        <attribute name="draw:id">
+            <ref name="ID"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-z-index-attlist">
+    <optional>
+        <attribute name="draw:z-index">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-text-spreadsheet-shape-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:end-cell-address">
+            <ref name="cellAddress"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="table:end-x">
+            <ref name="coordinate"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="table:end-y">
+            <ref name="coordinate"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-text-spreadsheet-shape-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:table-background">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-text-spreadsheet-shape-attlist" combine="interleave">
+    <ref name="common-text-anchor-attlist"/>
+</define>
+
+<define name="common-text-anchor-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:anchor-type">
+            <choice>
+                <value>page</value>
+                <value>frame</value>
+                <value>paragraph</value>
+                <value>char</value>
+                <value>as-char</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-text-anchor-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:anchor-page-number">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-text">
+    <zeroOrMore>
+        <choice>
+            <ref name="text-p"/>
+            <ref name="text-list"/>
+        </choice>
+    </zeroOrMore>
+</define>
+<define name="common-draw-shape-with-styles-attlist">
+    <ref name="common-draw-z-index-attlist"/>
+    <ref name="common-draw-id-attlist"/>
+    <ref name="common-draw-layer-name-attlist"/>
+    <ref name="common-draw-style-name-attlist"/>
+    <ref name="common-draw-transform-attlist"/>
+    <ref name="common-draw-name-attlist"/>
+    <ref name="common-text-spreadsheet-shape-attlist"/>
+</define>
+<define name="common-draw-shape-with-text-and-styles-attlist">
+    <ref name="common-draw-shape-with-styles-attlist"/>
+    <ref name="common-draw-text-style-name-attlist"/>
+</define>
+<define name="draw-glue-point">
+    <element name="draw:glue-point">
+        <ref name="draw-glue-point-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="draw-glue-point-attlist" combine="interleave">
+    <attribute name="draw:id">
+        <ref name="nonNegativeInteger"/>
+    </attribute>
+</define>
+<define name="draw-glue-point-attlist" combine="interleave">
+    <attribute name="svg:x">
+        <choice>
+            <ref name="distance"/> 
+            <ref name="percent"/>
+        </choice>
+    </attribute>
+    <attribute name="svg:y">
+        <choice>
+            <ref name="distance"/> 
+            <ref name="percent"/>
+        </choice>
+    </attribute>
+</define>
+<define name="draw-glue-point-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:align">
+            <choice>
+                <value>top-left</value>
+                <value>top</value>
+                <value>top-right</value>
+                <value>left</value>
+                <value>center</value>
+                <value>right</value>
+                <value>bottom-left</value>
+                <value>bottom-right</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-glue-points-attlist" combine="interleave">
+    <attribute name="draw:escape-direction">
+        <choice>
+            <value>auto</value>
+            <value>left</value>
+            <value>right</value>
+            <value>up</value>
+            <value>down</value>
+            <value>horizontal</value>
+            <value>vertical</value>
+        </choice>
+    </attribute>
+</define>
+<define name="svg-title">
+    <element name="svg:title">
+        <text/>
+    </element>
+</define>
+<define name="svg-desc">
+    <element name="svg:desc">
+        <text/>
+    </element>
+</define>
+<define name="draw-frame">
+    <element name="draw:frame">
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-rel-size-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <ref name="presentation-shape-attlist"/>
+        <ref name="draw-frame-attlist"/>
+        <zeroOrMore>
+            <choice>
+                <ref name="draw-text-box"/>
+                <ref name="draw-image"/>
+                <ref name="draw-object"/>
+                <ref name="draw-object-ole"/>
+                <ref name="draw-applet"/>
+                <ref name="draw-floating-frame"/>
+                <ref name="draw-plugin"/>
+            </choice>
+        </zeroOrMore>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <optional>
+            <ref name="draw-image-map"/>
+        </optional>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <choice>
+                <ref name="draw-contour-polygon"/>
+                <ref name="draw-contour-path"/>
+            </choice>
+        </optional>
+    </element>
+</define>
+<define name="common-draw-rel-size-attlist">
+    <ref name="common-draw-size-attlist"/>
+    <optional>
+        <attribute name="style:rel-width">
+            <choice>
+                <ref name="percent"/>
+                <value>scale</value>
+                <value>scale-min</value>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:rel-height">
+            <choice>
+                <ref name="percent"/>
+                <value>scale</value>
+                <value>scale-min</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-frame-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:copy-of">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-text-box">
+    <element name="draw:text-box">
+        <ref name="draw-text-box-attlist"/>
+        <zeroOrMore>
+            <ref name="text-content"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="draw-text-box-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:chain-next-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-text-box-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:corner-radius">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-text-box-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:min-height">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:min-width">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-text-box-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:max-height">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:max-width">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-text-box-attlist" combine="interleave">
+    <optional>
+        <ref name="text-id"/>
+    </optional>
+</define>
+<define name="draw-image">
+    <element name="draw:image">
+        <ref name="draw-image-attlist"/>
+        <choice>
+            <ref name="common-draw-data-attlist"/>
+            <ref name="office-binary-data"/>
+        </choice>
+        <ref name="draw-text"/>
+    </element>
+</define>
+<define name="common-draw-data-attlist" combine="interleave">
+    <group>
+        <attribute name="xlink:href">
+            <ref name="anyURI"/>
+        </attribute>
+        <optional>
+            <attribute name="xlink:type" a:defaultValue="simple">
+                <choice>
+                    <value>simple</value>
+                </choice>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:show" a:defaultValue="embed">
+                <choice>
+                    <value>embed</value>
+                </choice>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:actuate" a:defaultValue="onLoad">
+                <choice>
+                    <value>onLoad</value>
+                </choice>
+            </attribute>
+        </optional>
+    </group>
+</define>
+
+<define name="office-binary-data">
+    <element name="office:binary-data">
+        <ref name="base64Binary"/>
+    </element>
+</define>
+<define name="draw-image-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:filter-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-object">
+    <element name="draw:object">
+        <ref name="draw-object-attlist"/>
+        <choice>
+            <ref name="common-draw-data-attlist"/>
+            <ref name="office-document"/>
+            <ref name="math-math"/>
+        </choice>
+    </element>
+</define>
+
+<define name="draw-object-ole">
+    <element name="draw:object-ole">
+        <ref name="draw-object-ole-attlist"/>
+        <choice>
+            <ref name="common-draw-data-attlist"/>
+            <ref name="office-binary-data"/>
+        </choice>
+    </element>
+</define>
+<define name="draw-object-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:notify-on-update-of-ranges">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-object-ole-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:class-id"/>
+    </optional>
+</define>
+<define name="draw-applet">
+    <element name="draw:applet">
+        <ref name="draw-applet-attlist"/>
+        <optional>
+            <ref name="common-draw-data-attlist"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-param"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="draw-applet-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:code"/>
+    </optional>
+</define>
+<define name="draw-applet-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:object"/>
+    </optional>
+</define>
+<define name="draw-applet-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:archive"/>
+    </optional>
+</define>
+<define name="draw-applet-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:may-script" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-plugin">
+    <element name="draw:plugin">
+        <ref name="draw-plugin-attlist"/>
+        <ref name="common-draw-data-attlist"/>
+        <zeroOrMore>
+            <ref name="draw-param"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="draw-plugin-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:mime-type"/>
+    </optional>
+</define>
+<define name="draw-param">
+    <element name="draw:param">
+        <ref name="draw-param-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="draw-param-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:name"/>
+    </optional>
+</define>
+<define name="draw-param-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:value"/>
+    </optional>
+</define>
+<define name="draw-floating-frame">
+    <element name="draw:floating-frame">
+        <ref name="draw-floating-frame-attlist"/>
+        <ref name="common-draw-data-attlist"/>
+    </element>
+</define>
+<define name="draw-floating-frame-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:frame-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-contour-polygon">
+    <element name="draw:contour-polygon">
+        <ref name="common-contour-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-viewbox-attlist"/>
+        <ref name="common-draw-points-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="draw-contour-path">
+    <element name="draw:contour-path">
+        <ref name="common-contour-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-viewbox-attlist"/>
+        <ref name="common-draw-path-data-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="common-contour-attlist" combine="interleave">
+    <attribute name="draw:recreate-on-edit">
+        <ref name="boolean"/>
+    </attribute>
+</define>
+<define name="draw-a">
+    <element name="draw:a">
+        <ref name="draw-a-attlist"/>
+        <ref name="draw-frame"/>
+    </element>
+</define>
+<define name="draw-a-attlist" combine="interleave">
+    <attribute name="xlink:href">
+        <ref name="anyURI"/>
+    </attribute>
+    <optional>
+        <attribute name="xlink:type" a:defaultValue="simple">
+            <value>simple</value>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="xlink:actuate" a:defaultValue="onRequest">
+            <choice>
+                <value>onRequest</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-a-attlist" combine="interleave">
+    <optional>
+        <attribute name="office:target-frame-name">
+            <ref name="targetFrameName"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="xlink:show">
+            <choice>
+                <value>new</value>
+                <value>replace</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-a-attlist" combine="interleave">
+    <optional>
+        <attribute name="office:name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-a-attlist" combine="interleave">
+    <optional>
+        <attribute name="office:title">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-a-attlist" combine="interleave">
+    <optional>
+        <attribute name="office:server-map" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-image-map">
+    <element name="draw:image-map">
+        <zeroOrMore>
+            <choice>
+                <ref name="draw-area-rectangle"/>
+                <ref name="draw-area-circle"/>
+                <ref name="draw-area-polygon"/>
+            </choice>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="draw-area-rectangle">
+    <element name="draw:area-rectangle">
+        <ref name="common-draw-area-attlist"/>
+        <attribute name="svg:x">
+            <ref name="coordinate"/>
+        </attribute>
+        <attribute name="svg:y">
+            <ref name="coordinate"/>
+        </attribute>
+        <attribute name="svg:width">
+            <ref name="length"/>
+        </attribute>
+        <attribute name="svg:height">
+            <ref name="length"/>
+        </attribute>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+    </element>
+</define>
+<define name="draw-area-circle">
+    <element name="draw:area-circle">
+        <ref name="common-draw-area-attlist"/>
+        <attribute name="svg:cx">
+            <ref name="coordinate"/>
+        </attribute>
+        <attribute name="svg:cy">
+            <ref name="coordinate"/>
+        </attribute>
+        <attribute name="svg:r">
+            <ref name="length"/>
+        </attribute>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+    </element>
+</define>
+<define name="draw-area-polygon">
+    <element name="draw:area-polygon">
+        <ref name="common-draw-area-attlist"/>
+        <attribute name="svg:x">
+            <ref name="coordinate"/>
+        </attribute>
+        <attribute name="svg:y">
+            <ref name="coordinate"/>
+        </attribute>
+        <attribute name="svg:width">
+            <ref name="length"/>
+        </attribute>
+        <attribute name="svg:height">
+            <ref name="length"/>
+        </attribute>
+        <ref name="common-draw-viewbox-attlist"/>
+        <ref name="common-draw-points-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+    </element>
+</define>
+<define name="common-draw-area-attlist" combine="interleave">
+    <optional>
+        <attribute name="xlink:href">
+            <ref name="anyURI"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="xlink:type" a:defaultValue="simple">
+            <choice>
+                <value>simple</value>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="office:target-frame-name">
+            <ref name="targetFrameName"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="xlink:show">
+            <choice>
+                <value>new</value>
+                <value>replace</value>
+            </choice>
+            </attribute>
+    </optional>
+</define>
+<define name="common-draw-area-attlist" combine="interleave">
+    <optional>
+        <attribute name="office:name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-area-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:nohref">
+            <choice>
+                <value>nohref</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-scene">
+    <element name="dr3d:scene">
+        <ref name="dr3d-scene-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-style-name-attlist"/>
+        <ref name="common-draw-z-index-attlist"/>
+        <ref name="common-draw-id-attlist"/>
+        <ref name="common-draw-layer-name-attlist"/>
+        <ref name="common-text-spreadsheet-shape-attlist"/>
+        <ref name="common-dr3d-transform-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="dr3d-light"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="shapes3d"/>
+        </zeroOrMore>
+    </element>
+</define>
+
+<define name="shapes3d">
+    <choice>
+        <ref name="dr3d-scene"/>
+        <ref name="dr3d-extrude"/>
+        <ref name="dr3d-sphere"/>
+        <ref name="dr3d-rotate"/>
+        <ref name="dr3d-cube"/>
+    </choice>
+</define>
+<define name="dr3d-scene-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:vrp">
+            <ref name="vector3D"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="dr3d:vpn">
+            <ref name="vector3D"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="dr3d:vup">
+            <ref name="vector3D"/>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-scene-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:projection">
+            <choice>
+                <value>parallel</value>
+                <value>perspective</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-scene-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:distance">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-scene-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:focal-length">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-scene-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:shadow-slant">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-scene-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:shade-mode">
+            <choice>
+                <value>flat</value>
+                <value>phong</value>
+                <value>gouraud</value>
+                <value>draft</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-scene-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:ambient-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-scene-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:lighting-mode">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-dr3d-transform-attlist">
+    <optional>
+        <attribute name="dr3d:transform"/>
+    </optional>
+</define>
+<define name="dr3d-light">
+    <element name="dr3d:light">
+        <ref name="dr3d-light-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="dr3d-light-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:diffuse-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-light-attlist" combine="interleave">
+    <attribute name="dr3d:direction">
+        <ref name="vector3D"/>
+    </attribute>
+</define>
+<define name="dr3d-light-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:enabled">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-light-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:specular">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-cube">
+    <element name="dr3d:cube">
+        <ref name="dr3d-cube-attlist"/>
+        <ref name="common-draw-z-index-attlist"/>
+        <ref name="common-draw-id-attlist"/>
+        <ref name="common-draw-layer-name-attlist"/>
+        <ref name="common-draw-style-name-attlist"/>
+        <ref name="common-dr3d-transform-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="dr3d-cube-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:min-edge">
+            <ref name="vector3D"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="dr3d:max-edge">
+            <ref name="vector3D"/>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-sphere">
+    <element name="dr3d:sphere">
+        <ref name="dr3d-sphere-attlist"/>
+        <ref name="common-draw-z-index-attlist"/>
+        <ref name="common-draw-id-attlist"/>
+        <ref name="common-draw-layer-name-attlist"/>
+        <ref name="common-draw-style-name-attlist"/>
+        <ref name="common-dr3d-transform-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="dr3d-sphere-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:center">
+            <ref name="vector3D"/>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-sphere-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:size">
+            <ref name="vector3D"/>
+        </attribute>
+    </optional>
+</define>
+<define name="dr3d-extrude">
+    <element name="dr3d:extrude">
+        <ref name="common-draw-path-data-attlist"/>
+        <ref name="common-draw-viewbox-attlist"/>
+        <ref name="common-draw-id-attlist"/>
+        <ref name="common-draw-z-index-attlist"/>
+        <ref name="common-draw-layer-name-attlist"/>
+        <ref name="common-draw-style-name-attlist"/>
+        <ref name="common-dr3d-transform-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="dr3d-rotate">
+    <element name="dr3d:rotate">
+        <ref name="common-draw-viewbox-attlist"/>
+        <ref name="common-draw-path-data-attlist"/>
+        <ref name="common-draw-z-index-attlist"/>
+        <ref name="common-draw-id-attlist"/>
+        <ref name="common-draw-layer-name-attlist"/>
+        <ref name="common-draw-style-name-attlist"/>
+        <ref name="common-dr3d-transform-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="draw-custom-shape">
+    <element name="draw:custom-shape">
+        <ref name="draw-custom-shape-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <ref name="common-draw-caption-id-attlist"/>
+        <optional>
+            <ref name="svg-title"/>
+        </optional>
+        <optional>
+            <ref name="svg-desc"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="draw-glue-point"/>
+        </zeroOrMore>
+        <ref name="draw-text"/>
+        <optional>
+            <ref name="draw-enhanced-geometry"/>
+        </optional>
+    </element>
+</define>
+<define name="draw-custom-shape-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:engine">
+            <ref name="namespacedToken"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-custom-shape-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:data">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry">
+    <element name="draw:enhanced-geometry">
+        <ref name="draw-enhanced-geometry-attlist"/>
+        <zeroOrMore>
+            <ref name="draw-equation"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="draw-handle"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:type" a:defaultValue="non-primitive">
+            <ref name="custom-shape-type"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="custom-shape-type">
+    <choice>
+        <value>non-primitive</value>
+        <ref name="string"/>
+    </choice>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:viewBox">
+            <list>
+                <ref name="integer"/>
+                <ref name="integer"/>
+                <ref name="integer"/>
+                <ref name="integer"/>
+            </list>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:mirror-vertical" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:mirror-horizontal" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:text-rotate-angle" a:defaultValue="0">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-allowed" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:text-path-allowed" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:concentric-gradient-fill-allowed"
+                    a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-brightness" a:defaultValue="33%">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-depth" a:defaultValue="36pt 0">
+            <list>
+                <ref name="length"/>
+                <ref name="double"/>
+            </list>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-diffusion" a:defaultValue="0%">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-number-of-line-segments"
+                   a:defaultValue="30">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-light-face" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-first-light-harsh"
+                   a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-second-light-harsh"
+                   a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-first-light-level"
+                   a:defaultValue="66%">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-second-light-level"
+                   a:defaultValue="66%">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-first-light-direction"
+                   a:defaultValue="(5 0 1)">
+            <ref name="vector3D"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-second-light-direction"
+                   a:defaultValue="(-5 0 1)">
+            <ref name="vector3D"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-metal" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:shade-mode" a:defaultValue="flat">
+            <choice>
+                <value>flat</value>
+                <value>phong</value>
+                <value>gouraud</value>
+                <value>draft</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-rotation-angle" a:defaultValue="0 0">
+            <list>
+                <ref name="double"/>
+                <ref name="double"/>
+            </list>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-rotation-center">
+            <ref name="vector3D"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-shininess" a:defaultValue="50%">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-skew" a:defaultValue="50 45">
+            <list>
+                <ref name="double"/>
+                <ref name="double"/>
+            </list>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-specularity" a:defaultValue="0%">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:projection" a:defaultValue="parallel">
+            <choice>
+                <value>parallel</value>
+                <value>perspective</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-viewpoint" 
+                   a:defaultValue="3.5cm -3.5cm 25cm">
+            <ref name="point3D"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="point3D">
+    <data type="string"/>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-origin" a:defaultValue="0.5 -0.5">
+            <list>
+                <ref name="double"/>
+                <ref name="double"/>
+            </list>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:extrusion-color" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:enhanced-path">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:path-stretchpoint-x" a:defaultValue="0">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:path-stretchpoint-y" a:defaultValue="0">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:text-areas">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:glue-points">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:glue-point-type" a:defaultValue="none">
+            <choice>
+                <value>none</value>
+                <value>segments</value>
+                <value>rectangle</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:glue-point-leaving-directions"/>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:text-path" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:text-path-mode" a:defaultValue="normal">
+            <choice>
+                <value>normal</value>
+                <value>path</value>
+                <value>shape</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:text-path-scale" a:defaultValue="path">
+            <choice>
+                <value>path</value>
+                <value>shape</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:text-path-same-letter-heights"
+                   a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:modifiers">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-equation">
+    <element name="draw:equation">
+        <ref name="draw-equation-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="draw-equation-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-equation-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:formula">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-handle">
+    <element name="draw:handle">
+        <ref name="draw-handle-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="draw-handle-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:handle-mirror-vertical" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-handle-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:handle-mirror-horizontal" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-handle-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:handle-switched" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-handle-attlist" combine="interleave">
+    <attribute name="draw:handle-position">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="draw-handle-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:handle-range-x-minimum">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-handle-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:handle-range-x-maximum">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-handle-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:handle-range-y-minimum">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-handle-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:handle-range-y-maximum">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-handle-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:handle-polar">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-handle-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:handle-radius-range-minimum">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-handle-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:handle-radius-range-maximum">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-shape-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:class">
+            <ref name="presentation-classes"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-classes">
+    <choice>
+        <value>title</value>
+        <value>outline</value>
+        <value>subtitle</value>
+        <value>text</value>
+        <value>graphic</value>
+        <value>object</value>
+        <value>chart</value>
+        <value>table</value>
+        <value>orgchart</value>
+        <value>page</value>
+        <value>notes</value>
+        <value>handout</value>
+        <value>header</value>
+        <value>footer</value>
+        <value>date-time</value>
+        <value>page-number</value>
+    </choice>
+</define>
+<define name="presentation-shape-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:placeholder">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-shape-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:user-transformed">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-animations">
+    <element name="presentation:animations">
+        <zeroOrMore>
+            <choice>
+                <ref name="presentation-animation-elements"/>
+                <ref name="presentation-animation-group"/>
+            </choice>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="presentation-animation-elements">
+    <choice>
+        <ref name="presentation-show-shape"/>
+        <ref name="presentation-show-text"/>
+        <ref name="presentation-hide-shape"/>
+        <ref name="presentation-hide-text"/>
+        <ref name="presentation-dim"/>
+        <ref name="presentation-play"/>
+    </choice>
+</define>
+<define name="presentation-sound">
+    <element name="presentation:sound">
+        <ref name="presentation-sound-attlist"/>
+        <attribute name="xlink:href">
+            <ref name="anyURI"/>
+        </attribute>
+        <optional>
+            <attribute name="xlink:type" a:defaultValue="simple">
+                <choice>
+                    <value>simple</value>
+                </choice>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:actuate" a:defaultValue="onRequest">
+                <choice>
+                    <value>onRequest</value>
+                </choice>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:show">
+                <choice>
+                    <value>new</value>
+                    <value>replace</value>
+                </choice>
+            </attribute>
+        </optional>
+        <empty/>
+    </element>
+</define>
+<define name="presentation-sound-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:play-full">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-show-shape">
+    <element name="presentation:show-shape">
+        <ref name="common-presentation-effect-attlist"/>
+        <optional>
+            <ref name="presentation-sound"/>
+        </optional>
+    </element>
+</define>
+<define name="common-presentation-effect-attlist" combine="interleave">
+    <attribute name="draw:shape-id">
+        <ref name="IDREF"/>
+    </attribute>
+</define>
+<define name="common-presentation-effect-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:effect" a:defaultValue="none">
+            <ref name="presentationEffects"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentationEffects">
+    <choice>
+        <value>none</value>
+        <value>fade</value>
+        <value>move</value>
+        <value>stripes</value>
+        <value>open</value>
+        <value>close</value>
+        <value>dissolve</value>
+        <value>wavyline</value>
+        <value>random</value>
+        <value>lines</value>
+        <value>laser</value>
+        <value>appear</value>
+        <value>hide</value>
+        <value>move-short</value>
+        <value>checkerboard</value>
+        <value>rotate</value>
+        <value>stretch</value>
+    </choice>
+</define>
+<define name="common-presentation-effect-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:direction" a:defaultValue="none">
+            <ref name="presentationEffectDirections"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentationEffectDirections">
+    <choice>
+        <value>none</value>
+        <value>from-left</value>
+        <value>from-top</value>
+        <value>from-right</value>
+        <value>from-bottom</value>
+        <value>from-center</value>
+        <value>from-upper-left</value>
+        <value>from-upper-right</value>
+        <value>from-lower-left</value>
+        <value>from-lower-right</value>
+        <value>to-left</value>
+        <value>to-top</value>
+        <value>to-right</value>
+        <value>to-bottom</value>
+        <value>to-upper-left</value>
+        <value>to-upper-right</value>
+        <value>to-lower-right</value>
+        <value>to-lower-left</value>
+        <value>path</value>
+        <value>spiral-inward-left</value>
+        <value>spiral-inward-right</value>
+        <value>spiral-outward-left</value>
+        <value>spiral-outward-right</value>
+        <value>vertical</value>
+        <value>horizontal</value>
+        <value>to-center</value>
+        <value>clockwise</value>
+        <value>counter-clockwise</value>
+    </choice>
+</define>
+<define name="common-presentation-effect-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:speed" a:defaultValue="medium">
+            <ref name="presentationSpeeds"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentationSpeeds">
+    <choice>
+        <value>slow</value>
+        <value>medium</value>
+        <value>fast</value>
+    </choice>
+</define>
+<define name="common-presentation-effect-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:delay">
+            <ref name="duration"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-presentation-effect-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:start-scale" a:defaultValue="100%">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-presentation-effect-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:path-id"/>
+    </optional>
+</define>
+<define name="presentation-show-text">
+    <element name="presentation:show-text">
+        <ref name="common-presentation-effect-attlist"/>
+        <optional>
+            <ref name="presentation-sound"/>
+        </optional>
+    </element>
+</define>
+<define name="presentation-hide-shape">
+    <element name="presentation:hide-shape">
+        <ref name="common-presentation-effect-attlist"/>
+        <optional>
+            <ref name="presentation-sound"/>
+        </optional>
+    </element>
+</define>
+<define name="presentation-hide-text">
+    <element name="presentation:hide-text">
+        <ref name="common-presentation-effect-attlist"/>
+        <optional>
+            <ref name="presentation-sound"/>
+        </optional>
+    </element>
+</define>
+<define name="presentation-dim">
+    <element name="presentation:dim">
+        <ref name="presentation-dim-attlist"/>
+        <optional>
+            <ref name="presentation-sound"/>
+        </optional>
+    </element>
+</define>
+<define name="presentation-dim-attlist" combine="interleave">
+    <attribute name="draw:shape-id">
+        <ref name="IDREF"/>
+    </attribute>
+</define>
+<define name="presentation-dim-attlist" combine="interleave">
+    <attribute name="draw:color">
+        <ref name="color"/>
+    </attribute>
+</define>
+<define name="presentation-play">
+    <element name="presentation:play">
+        <ref name="presentation-play-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="presentation-play-attlist" combine="interleave">
+    <attribute name="draw:shape-id">
+        <ref name="IDREF"/>
+    </attribute>
+    <optional>
+        <attribute name="presentation:speed" a:defaultValue="medium">
+            <ref name="presentationSpeeds"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-animation-group">
+    <element name="presentation:animation-group">
+        <zeroOrMore>
+            <ref name="presentation-animation-elements"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="common-anim-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:node-type" a:defaultValue="default">
+            <choice>
+                <value>default</value>
+                <value>on-click</value>
+                <value>with-previous</value>
+                <value>after-previous</value>
+                <value>timing-root</value>
+                <value>main-sequence</value>
+                <value>interactive-sequence</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:preset-id">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:preset-sub-type">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:preset-class" a:defaultValue="custom">
+            <choice>
+                <value>custom</value>
+                <value>entrance</value>
+                <value>exit</value>
+                <value>emphasis</value>
+                <value>motion-path</value>
+                <value>ole-action</value>
+                <value>media-call</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:master-element">
+            <ref name="IDREF"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:group-id">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-event-listener">
+    <element name="presentation:event-listener">
+        <ref name="presentation-event-listener-attlist"/>
+        <optional>
+            <ref name="presentation-sound"/>
+        </optional>
+    </element>
+</define>
+<define name="presentation-event-listener-attlist" combine="interleave">
+    <attribute name="script:event-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="presentation-event-listener-attlist" combine="interleave">
+    <attribute name="presentation:action">
+        <choice>
+            <value>none</value>
+            <value>previous-page</value>
+            <value>next-page</value>
+            <value>first-page</value>
+            <value>last-page</value>
+            <value>hide</value>
+            <value>stop</value>
+            <value>execute</value>
+            <value>show</value>
+            <value>verb</value>
+            <value>fade-out</value>
+            <value>sound</value>
+        </choice>
+    </attribute>
+</define>
+<define name="presentation-event-listener-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:effect" a:defaultValue="none">
+            <ref name="presentationEffects"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-event-listener-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:direction" a:defaultValue="none">
+            <ref name="presentationEffectDirections"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-event-listener-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:speed" a:defaultValue="medium">
+            <ref name="presentationSpeeds"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-event-listener-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:start-scale" a:defaultValue="100%">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-event-listener-attlist" combine="interleave">
+    <optional>
+        <attribute name="xlink:href">
+            <ref name="anyURI"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="xlink:type" a:defaultValue="simple">
+            <choice>
+                <value>simple</value>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="xlink:show" a:defaultValue="embed">
+            <choice>
+                <value>embed</value>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="xlink:actuate" a:defaultValue="onRequest">
+            <choice>
+                <value>onRequest</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-event-listener-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:verb">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="presentation:header">
+        <empty/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="presentation:footer">
+        <empty/>
+    </element>
+</define>
+<define name="paragraph-content" combine="choice">
+    <element name="presentation:date-time">
+        <empty/>
+    </element>
+</define>
+<define name="presentation-decls">
+    <zeroOrMore>
+        <ref name="presentation-decl"/>
+    </zeroOrMore>
+</define>
+<define name="presentation-decl" combine="choice">
+    <element name="presentation:header-decl">
+        <ref name="presentation-header-decl-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="presentation-header-decl-attlist" combine="interleave">
+    <attribute name="presentation:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="presentation-decl" combine="choice">
+    <element name="presentation:footer-decl">
+        <ref name="presentation-footer-decl-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="presentation-footer-decl-attlist" combine="interleave">
+    <attribute name="presentation:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="presentation-decl" combine="choice">
+    <element name="presentation:date-time-decl">
+        <ref name="presentation-date-time-decl-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="presentation-date-time-decl-attlist" combine="interleave">
+    <attribute name="presentation:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="presentation-date-time-decl-attlist" combine="interleave">
+    <attribute name="presentation:source">
+        <choice>
+            <value>fixed</value>
+            <value>current-date</value>
+        </choice>
+    </attribute>
+</define>
+<define name="presentation-date-time-decl-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:data-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings">
+    <optional>
+        <element name="presentation:settings">
+            <ref name="presentation-settings-attlist"/>
+            <zeroOrMore>
+                <ref name="presentation-show"/>
+            </zeroOrMore>
+        </element>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:start-page">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:show">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:full-screen" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:endless" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:pause">
+            <ref name="duration"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:show-logo" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:force-manual" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:mouse-visible" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:mouse-as-pen" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:start-with-navigator"
+                   a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:animations" a:defaultValue="enabled">
+            <choice>
+                <value>enabled</value>
+                <value>disabled</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:transition-on-click"
+                   a:defaultValue="enabled">
+            <choice>
+                <value>enabled</value>
+                <value>disabled</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:stay-on-top" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-settings-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:show-end-of-presentation-slide"
+                   a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-show">
+    <element name="presentation:show">
+        <ref name="presentation-show-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="presentation-show-attlist" combine="interleave">
+    <attribute name="presentation:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="presentation-show-attlist" combine="interleave">
+    <attribute name="presentation:pages"/>
+</define>
+<define name="chart-chart">
+    <element name="chart:chart">
+        <ref name="chart-chart-attlist"/>
+        <optional>
+            <ref name="chart-title"/>
+        </optional>
+        <optional>
+            <ref name="chart-subtitle"/>
+        </optional>
+        <optional>
+            <ref name="chart-footer"/>
+        </optional>
+        <optional>
+            <ref name="chart-legend"/>
+        </optional>
+        <ref name="chart-plot-area"/>
+        <optional>
+            <ref name="table-table"/>
+        </optional>
+    </element>
+</define>
+<define name="chart-chart-attlist" combine="interleave">
+    <attribute name="chart:class">
+        <ref name="namespacedToken"/>
+    </attribute>
+</define>
+<define name="chart-chart-attlist" combine="interleave">
+    <ref name="common-draw-size-attlist"/>
+</define>
+<define name="chart-chart-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:column-mapping">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-chart-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:row-mapping">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-chart-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-title">
+    <element name="chart:title">
+        <ref name="chart-title-attlist"/>
+        <optional>
+            <ref name="text-p"/>
+        </optional>
+    </element>
+</define>
+<define name="chart-title-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:cell-range">
+            <ref name="cellAddress"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-title-attlist" combine="interleave">
+    <ref name="common-draw-position-attlist"/>
+</define>
+<define name="chart-title-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-subtitle">
+    <element name="chart:subtitle">
+        <ref name="chart-title-attlist"/>
+        <optional>
+            <ref name="text-p"/>
+        </optional>
+    </element>
+</define>
+<define name="chart-footer">
+    <element name="chart:footer">
+        <ref name="chart-title-attlist"/>
+        <optional>
+            <ref name="text-p"/>
+        </optional>
+    </element>
+</define>
+<define name="chart-legend">
+    <element name="chart:legend">
+        <ref name="chart-legend-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="chart-legend-attlist" combine="interleave">
+    <choice>
+        <group>
+            <attribute name="chart:legend-position">
+                <choice>
+                    <value>start</value>
+                    <value>end</value>
+                    <value>top</value>
+                    <value>bottom</value>
+                </choice>
+            </attribute>
+            <optional>
+                <attribute name="chart:legend-align">
+                    <choice>
+                        <value>start</value>
+                        <value>center</value>
+                        <value>end</value>
+                    </choice>
+                </attribute>
+            </optional>
+        </group>
+        <attribute name="chart:legend-position">
+            <choice>
+                <value>top-start</value>
+                <value>bottom-start</value>
+                <value>top-end</value>
+                <value>bottom-end</value>
+            </choice>
+        </attribute>
+        <empty/>
+    </choice>
+</define>
+<define name="chart-legend-attlist" combine="interleave">
+    <ref name="common-draw-position-attlist"/>
+</define>
+<define name="chart-legend-attlist" combine="interleave">
+    <choice>
+        <attribute name="style:legend-expansion">
+            <choice>
+                <value>wide</value>
+                <value>high</value>
+                <value>balanced</value>
+            </choice>
+        </attribute>
+        <group>
+            <attribute name="style:legend-expansion">
+                <value>custom</value>
+            </attribute>
+            <attribute name="style:legend-expansion-aspect-ratio">
+                <ref name="double"/>
+            </attribute>
+        </group>
+        <empty/>
+    </choice>
+</define>
+<define name="chart-legend-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-plot-area">
+    <element name="chart:plot-area">
+        <ref name="chart-plot-area-attlist"/>
+        <zeroOrMore>
+            <ref name="dr3d-light"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="chart-axis"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="chart-series"/>
+        </zeroOrMore>
+        <optional>
+            <ref name="chart-stock-gain-marker"/>
+        </optional>
+        <optional>
+            <ref name="chart-stock-loss-marker"/>
+        </optional>
+        <optional>
+            <ref name="chart-stock-range-line"/>
+        </optional>
+        <optional>
+            <ref name="chart-wall"/>
+        </optional>
+        <optional>
+            <ref name="chart-floor"/>
+        </optional>
+    </element>
+</define>
+<define name="chart-plot-area-attlist" combine="interleave">
+    <ref name="common-draw-position-attlist"/>
+    <ref name="common-draw-size-attlist"/>
+</define>
+<define name="chart-plot-area-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-plot-area-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:cell-range-address">
+            <ref name="cellRangeAddress"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-plot-area-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:data-source-has-labels" a:defaultValue="none">
+            <choice>
+                <value>none</value>
+                <value>row</value>
+                <value>column</value>
+                <value>both</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-plot-area-attlist" combine="interleave">
+    <ref name="dr3d-scene-attlist"/>
+    <ref name="common-dr3d-transform-attlist"/>
+</define>
+<define name="chart-wall">
+    <element name="chart:wall">
+        <ref name="chart-wall-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="chart-wall-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:width">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-wall-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-floor">
+    <element name="chart:floor">
+        <ref name="chart-floor-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="chart-floor-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:width">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-floor-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-axis">
+    <element name="chart:axis">
+        <ref name="chart-axis-attlist"/>
+        <optional>
+            <ref name="chart-title"/>
+        </optional>
+        <optional>
+            <ref name="chart-categories"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="chart-grid"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="chart-axis-attlist" combine="interleave">
+    <attribute name="chart:dimension">
+        <choice>
+            <value>x</value>
+            <value>y</value>
+            <value>z</value>
+        </choice>
+    </attribute>
+</define>
+<define name="chart-axis-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-axis-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-grid">
+    <element name="chart:grid">
+        <ref name="chart-grid-attlist"/>
+    </element>
+</define>
+<define name="chart-grid-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:class" a:defaultValue="major">
+            <choice>
+                <value>major</value>
+                <value>minor</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-grid-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-series">
+    <element name="chart:series">
+        <ref name="chart-series-attlist"/>
+        <zeroOrMore>
+            <ref name="chart-domain"/>
+        </zeroOrMore>
+        <optional>
+            <ref name="chart-mean-value"/>
+        </optional>
+        <optional>
+            <ref name="chart-regression-curve"/>
+        </optional>
+        <optional>
+            <ref name="chart-error-indicator"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="chart-data-point"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="chart-series-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:values-cell-range-address">
+            <ref name="cellRangeAddress"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-series-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:label-cell-address">
+            <ref name="cellAddress"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-series-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:class">
+            <ref name="namespacedToken"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-series-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:attached-axis">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-series-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-domain">
+    <element name="chart:domain">
+    <optional>
+        <attribute name="table:cell-range-address">
+            <ref name="cellRangeAddress"/>
+        </attribute>
+    </optional>
+    </element>
+</define>
+<define name="chart-categories">
+    <element name="chart:categories">
+    <optional>
+        <attribute name="table:cell-range-address">
+            <ref name="cellRangeAddress"/>
+        </attribute>
+    </optional>
+    </element>
+</define>
+<define name="chart-data-point">
+    <element name="chart:data-point">
+        <ref name="chart-data-point-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="chart-data-point-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:repeated">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-data-point-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="chart-mean-value">
+    <element name="chart:mean-value">
+        <ref name="chart-mean-value-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="chart-mean-value-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-error-indicator">
+    <element name="chart:error-indicator">
+        <ref name="chart-error-indicator-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="chart-error-indicator-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-regression-curve">
+    <element name="chart:regression-curve">
+        <ref name="chart-regression-curve-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="chart-regression-curve-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="chart-stock-gain-marker">
+    <element name="chart:stock-gain-marker">
+        <ref name="common-stock-marker-attlist"/>
+    </element>
+</define>
+<define name="chart-stock-loss-marker">
+    <element name="chart:stock-loss-marker">
+        <ref name="common-stock-marker-attlist"/>
+    </element>
+</define>
+<define name="chart-stock-range-line">
+    <element name="chart:stock-range-line">
+        <ref name="common-stock-marker-attlist"/>
+    </element>
+</define>
+<define name="common-stock-marker-attlist">
+    <optional>
+        <attribute name="chart:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="office-forms">
+    <optional>
+        <element name="office:forms">
+            <ref name="office-forms-attlist"/>
+            <zeroOrMore>
+                <choice>
+                    <ref name="form-form"/>
+                    <ref name="xforms-model"/>
+                </choice>
+            </zeroOrMore>
+        </element>
+    </optional>
+</define>
+<define name="office-forms-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:automatic-focus" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="office-forms-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:apply-design-mode" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form">
+    <element name="form:form">
+        <ref name="common-form-control-attlist"/>
+        <ref name="form-form-attlist"/>
+        <optional>
+            <ref name="form-properties"/>
+        </optional>
+        <optional>
+            <ref name="office-event-listeners"/>
+        </optional>
+        <zeroOrMore>
+            <choice>
+                <ref name="controls"/>
+                <ref name="form-form"/>
+            </choice>
+        </zeroOrMore>
+        <optional>
+            <ref name="form-connection-resource"/>
+        </optional>
+    </element>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="xlink:href">
+            <ref name="anyURI"/>
+        </attribute>
+        <optional>
+            <attribute name="xlink:type" a:defaultValue="simple">
+                <value>simple</value>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:actuate" a:defaultValue="onRequest">
+                <value>onRequest</value>
+            </attribute>
+        </optional>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="office:target-frame" a:defaultValue="_blank">
+            <ref name="targetFrameName"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:method" a:defaultValue="get">
+            <choice>
+                <value>get</value>
+                <value>post</value>
+                <ref name="string"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:enctype" 
+                    a:defaultValue="application/x-www-form-urlencoded">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:allow-deletes" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:allow-inserts" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:allow-updates" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:apply-filter" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:command-type" a:defaultValue="command">
+            <choice>
+                <value>table</value>
+                <value>query</value>
+                <value>command</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:command"/>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:datasource">
+            <choice>
+                <ref name="anyURI"/>
+                <ref name="string"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:master-fields">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:detail-fields">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:escape-processing" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:filter">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:ignore-result" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:navigation-mode">
+            <ref name="navigation"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="navigation">
+    <choice>
+        <value>none</value>
+        <value>current</value>
+        <value>parent</value>
+    </choice>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:order">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-form-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:tab-cycle">
+            <ref name="tab-cycles"/>
+        </attribute>
+    </optional>
+</define>
+<define name="tab-cycles">
+    <choice>
+        <value>records</value>
+        <value>current</value>
+        <value>page</value>
+    </choice>
+</define>
+<define name="form-connection-resource">
+    <element name="form:connection-resource">
+        <attribute name="xlink:href">
+            <ref name="anyURI"/>
+        </attribute>
+        <empty/>
+    </element>
+</define>
+<define name="xforms-model">
+    <element name="xforms:model">
+        <ref name="anyAttListOrElements"/>
+    </element>
+</define>
+<define name="column-controls" combine="choice">
+    <element name="form:text">
+        <ref name="form-text-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="controls" combine="choice">
+    <ref name="column-controls"/>
+</define>
+<define name="form-text-attlist">
+    <ref name="form-control-attlist"/>
+    <ref name="common-current-value-attlist"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="common-maxlength-attlist"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-readonly-attlist"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="common-title-attlist"/>
+    <ref name="common-value-attlist"/>
+    <ref name="common-convert-empty-attlist"/>
+    <ref name="common-data-field-attlist"/>
+</define>
+<define name="form-control-attlist">
+    <ref name="common-form-control-attlist"/>
+    <ref name="common-control-id-attlist"/>
+    <ref name="xforms-bind-attlist"/>
+</define>
+<define name="common-form-control-content">
+    <optional>
+        <ref name="form-properties"/>
+    </optional>
+    <optional>
+        <ref name="office-event-listeners"/>
+    </optional>
+</define>
+<define name="column-controls" combine="choice">
+    <element name="form:textarea">
+        <ref name="form-textarea-attlist"/>
+        <ref name="common-form-control-content"/>
+        <zeroOrMore>
+            <ref name="text-p"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="form-textarea-attlist">
+    <ref name="form-control-attlist"/>
+    <ref name="common-current-value-attlist"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="common-maxlength-attlist"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-readonly-attlist"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="common-title-attlist"/>
+    <ref name="common-value-attlist"/>
+    <ref name="common-convert-empty-attlist"/>
+    <ref name="common-data-field-attlist"/>
+</define>
+<define name="controls" combine="choice">
+    <element name="form:password">
+        <ref name="form-password-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-password-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="common-maxlength-attlist"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="common-title-attlist"/>
+    <ref name="common-value-attlist"/>
+    <ref name="common-convert-empty-attlist"/>
+</define>
+<define name="form-password-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:echo-char" a:defaultValue="*">
+            <ref name="character"/>
+        </attribute>
+    </optional>
+</define>
+<define name="controls" combine="choice">
+    <element name="form:file">
+        <ref name="form-file-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-file-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="common-current-value-attlist"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="common-maxlength-attlist"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-readonly-attlist"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="common-title-attlist"/>
+    <ref name="common-value-attlist"/>
+</define>
+<define name="column-controls" combine="choice">
+    <element name="form:formatted-text">
+        <ref name="form-formatted-text-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-formatted-text-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="common-current-value-attlist"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="common-maxlength-attlist"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-readonly-attlist"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="common-title-attlist"/>
+    <ref name="common-value-attlist"/>
+    <ref name="common-convert-empty-attlist"/>
+    <ref name="common-data-field-attlist"/>
+</define>
+<define name="form-formatted-text-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:max-value">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-formatted-text-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:min-value">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-formatted-text-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:validation" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="column-controls" combine="choice">
+    <element name="form:number">
+        <ref name="form-number-attlist"/>
+        <ref name="common-numeric-control-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="common-numeric-control-attlist">
+    <ref name="form-control-attlist"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="common-maxlength-attlist"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-readonly-attlist"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="common-title-attlist"/>
+    <ref name="common-convert-empty-attlist"/>
+    <ref name="common-data-field-attlist"/>
+</define>
+<define name="form-number-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:value">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-number-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:current-value">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-number-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:min-value">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-number-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:max-value">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="column-controls" combine="choice">
+    <element name="form:date">
+        <ref name="form-date-attlist"/>
+        <ref name="common-numeric-control-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="controls" combine="choice">
+    <element name="form:time">
+        <ref name="form-time-attlist"/>
+        <ref name="common-numeric-control-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-date-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:value">
+            <ref name="date"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-time-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:value">
+            <ref name="time"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-date-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:current-value">
+            <ref name="date"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-time-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:current-value">
+            <ref name="time"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-date-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:min-value">
+            <ref name="date"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-time-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:min-value">
+            <ref name="time"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-date-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:max-value">
+            <ref name="date"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-time-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:max-value">
+            <ref name="time"/>
+        </attribute>
+    </optional>
+</define>
+<define name="controls" combine="choice">
+    <element name="form:fixed-text">
+        <ref name="form-fixed-text-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-fixed-text-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="for"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="label"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-title-attlist"/>
+</define>
+<define name="form-fixed-text-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:multi-line" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="column-controls" combine="choice">
+    <element name="form:combobox">
+        <ref name="form-combobox-attlist"/>
+        <ref name="common-form-control-content"/>
+        <zeroOrMore>
+            <ref name="form-item"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="form-combobox-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="common-current-value-attlist"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="dropdown"/>
+    <ref name="common-maxlength-attlist"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-readonly-attlist"/>
+    <ref name="size"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="common-title-attlist"/>
+    <ref name="common-value-attlist"/>
+    <ref name="common-convert-empty-attlist"/>
+    <ref name="common-data-field-attlist"/>
+    <ref name="list-source"/>
+    <ref name="list-source-type"/>
+</define>
+<define name="form-combobox-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:auto-complete">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-item">
+    <element name="form:item">
+        <ref name="form-item-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="form-item-attlist" combine="interleave">
+    <ref name="label"/>
+</define>
+<define name="column-controls" combine="choice">
+    <element name="form:listbox">
+        <ref name="form-listbox-attlist"/>
+        <ref name="common-form-control-content"/>
+        <zeroOrMore>
+            <ref name="form-option"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="form-listbox-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="dropdown"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="size"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="common-title-attlist"/>
+    <ref name="bound-column"/>
+    <ref name="common-data-field-attlist"/>
+    <ref name="list-source"/>
+    <ref name="list-source-type"/>
+</define>
+<define name="form-listbox-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:multiple" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-listbox-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:xforms-list-source">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-option">
+    <element name="form:option">
+        <ref name="form-option-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="form-option-attlist" combine="interleave">
+    <ref name="current-selected"/>
+    <ref name="selected"/>
+    <ref name="label"/>
+    <ref name="common-value-attlist"/>
+</define>
+<define name="controls" combine="choice">
+    <element name="form:button">
+        <ref name="form-button-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-button-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="button-type"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="label"/>
+    <ref name="image-data"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="target-frame"/>
+    <ref name="target-location"/>
+    <ref name="common-title-attlist"/>
+    <ref name="common-value-attlist"/>
+    <ref name="common-form-relative-image-position-attlist"/>
+</define>
+<define name="form-button-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:default-button" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-button-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:toggle" a:default-value="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-button-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:focus-on-click">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-button-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:xforms-submission">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="controls" combine="choice">
+    <element name="form:image">
+        <ref name="form-image-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-image-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="button-type"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="image-data"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="target-frame"/>
+    <ref name="target-location"/>
+    <ref name="common-title-attlist"/>
+    <ref name="common-value-attlist"/>
+</define>
+<define name="column-controls" combine="choice">
+    <element name="form:checkbox">
+        <ref name="form-checkbox-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-checkbox-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="label"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="common-title-attlist"/>
+    <ref name="common-value-attlist"/>
+    <ref name="common-data-field-attlist"/>
+    <ref name="common-form-visual-effect-attlist"/>
+    <ref name="common-form-relative-image-position-attlist"/>
+</define>
+<define name="states">
+    <choice>
+        <value>unchecked</value>
+        <value>checked</value>
+        <value>unknown</value>
+    </choice>
+</define>
+<define name="form-checkbox-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:current-state">
+            <ref name="states"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-checkbox-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:is-tristate" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-checkbox-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:state" a:defaultValue="unchecked">
+            <ref name="states"/>
+        </attribute>
+    </optional>
+</define>
+<define name="controls" combine="choice">
+    <element name="form:radio">
+        <ref name="form-radio-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-radio-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="current-selected"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="label"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="selected"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="common-title-attlist"/>
+    <ref name="common-value-attlist"/>
+    <ref name="common-data-field-attlist"/>
+    <ref name="common-form-visual-effect-attlist"/>
+    <ref name="common-form-relative-image-position-attlist"/>
+</define>
+<define name="controls" combine="choice">
+    <element name="form:frame">
+        <ref name="form-frame-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-frame-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="for"/>
+    <ref name="label"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-title-attlist"/>
+</define>
+<define name="controls" combine="choice">
+    <element name="form:image-frame">
+        <ref name="form-image-frame-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-image-frame-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="image-data"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-readonly-attlist"/>
+    <ref name="common-title-attlist"/>
+    <ref name="common-data-field-attlist"/>
+</define>
+<define name="controls" combine="choice">
+    <element name="form:hidden">
+        <ref name="form-hidden-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-hidden-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="common-value-attlist"/>
+</define>
+<define name="controls" combine="choice">
+    <element name="form:grid">
+        <ref name="form-grid-attlist"/>
+        <ref name="common-form-control-content"/>
+        <zeroOrMore>
+            <ref name="form-column"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="form-grid-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="common-title-attlist"/>
+</define>
+<define name="form-column">
+    <element name="form:column">
+        <ref name="form-column-attlist"/>
+        <oneOrMore>
+            <ref name="column-controls"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="form-column-attlist" combine="interleave">
+    <ref name="common-form-control-attlist"/>
+    <ref name="label"/>
+    <ref name="text-style-name"/>
+</define>
+<define name="text-style-name">
+    <optional>
+        <attribute name="form:text-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="controls" combine="choice">
+    <element name="form:value-range">
+        <ref name="form-value-range-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-value-range-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+    <ref name="common-disabled-attlist"/>
+    <ref name="common-printable-attlist"/>
+    <ref name="common-tab-attlist"/>
+    <ref name="common-title-attlist"/>
+    <ref name="common-value-attlist"/>
+</define>
+<define name="form-value-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:max-value">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-value-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:min-value">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-value-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:step-size" a:defaultName="1">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-value-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:page-step-size">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-value-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:delay-for-repeat">
+            <ref name="duration"/>
+        </attribute>
+    </optional>
+</define>
+<define name="form-value-range-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:orientation">
+            <choice>
+                <value>horizontal</value>
+                <value>vertical</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="controls" combine="choice">
+    <element name="form:generic-control">
+        <ref name="form-generic-control-attlist"/>
+        <ref name="common-form-control-content"/>
+    </element>
+</define>
+<define name="form-generic-control-attlist" combine="interleave">
+    <ref name="form-control-attlist"/>
+</define>
+<define name="common-form-control-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-form-control-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:control-implementation">
+            <ref name="namespacedToken"/>
+        </attribute>
+    </optional>
+</define>
+<define name="xforms-bind-attlist">
+    <optional>
+        <attribute name="xforms:bind">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="types">
+    <choice>
+        <value>submit</value>
+        <value>reset</value>
+        <value>push</value>
+        <value>url</value>
+    </choice>
+</define>
+<define name="button-type">
+    <optional>
+        <attribute name="form:button-type" a:defaultValue="push">
+            <ref name="types"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-control-id-attlist">
+    <attribute name="form:id">
+        <ref name="ID"/>
+    </attribute>
+</define>
+<define name="current-selected">
+    <optional>
+        <attribute name="form:current-selected" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-value-attlist">
+    <optional>
+        <attribute name="form:value">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-current-value-attlist">
+    <optional>
+        <attribute name="form:current-value">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-disabled-attlist">
+    <optional>
+        <attribute name="form:disabled" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="dropdown">
+    <optional>
+        <attribute name="form:dropdown" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="for">
+    <optional>
+        <attribute name="form:for">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="image-data">
+    <optional>
+        <attribute name="form:image-data">
+            <ref name="anyURI"/>
+        </attribute>
+    </optional>
+</define>
+<define name="label">
+    <optional>
+        <attribute name="form:label">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-maxlength-attlist">
+    <optional>
+        <attribute name="form:max-length">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-printable-attlist">
+    <optional>
+        <attribute name="form:printable" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-readonly-attlist">
+    <optional>
+        <attribute name="form:readonly" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="selected">
+    <optional>
+        <attribute name="form:selected" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="size">
+    <optional>
+        <attribute name="form:size">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-tab-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:tab-index" a:defaultValue="0">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-tab-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:tab-stop" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="target-frame">
+    <optional>
+        <attribute name="office:target-frame" a:defaultValue="_blank">
+            <ref name="targetFrameName"/>
+        </attribute>
+    </optional>
+</define>
+<define name="target-location">
+    <optional>
+        <attribute name="xlink:href">
+            <ref name="anyURI"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-title-attlist">
+    <optional>
+        <attribute name="form:title"/>
+    </optional>
+</define>
+<define name="common-form-visual-effect-attlist" combine="interleave">
+    <optional>
+        <attribute name="form:visual-effect">
+            <choice>
+                <value>flat</value>
+                <value>3d</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-form-relative-image-position-attlist"
+        combine="interleave">
+    <choice>
+        <optional>
+            <attribute name="form:image-position" a:defaultValue="center">
+                <value>center</value>
+            </attribute>
+        </optional>
+        <group>
+            <attribute name="form:image-position">
+                <choice>
+                    <value>start</value>
+                    <value>end</value>
+                    <value>top</value>
+                    <value>bottom</value>
+                </choice>
+            </attribute>
+            <optional>
+                <attribute name="form:image-align" a:defaultValue="center">
+                    <choice>
+                        <value>start</value>
+                        <value>center</value>
+                        <value>end</value>
+                    </choice>
+                </attribute>
+            </optional>
+        </group>
+    </choice>
+</define>
+<define name="bound-column">
+    <optional>
+        <attribute name="form:bound-column">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-convert-empty-attlist">
+    <optional>
+        <attribute name="form:convert-empty-to-null" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-data-field-attlist">
+    <optional>
+        <attribute name="form:data-field">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="list-source">
+    <optional>
+        <attribute name="form:list-source">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="list-source-type">
+    <optional>
+        <attribute name="form:list-source-type">
+            <choice>
+                <value>table</value>
+                <value>query</value>
+                <value>sql</value>
+                <value>sql-pass-through</value>
+                <value>value-list</value>
+                <value>table-fields</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="form-properties">
+    <element name="form:properties">
+        <oneOrMore>
+            <ref name="form-property"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="form-property" combine="choice">
+    <element name="form:property">
+        <ref name="form-property-name"/>
+        <ref name="form-property-value-and-type-attlist"/>
+    </element>
+</define>
+<define name="form-property-name" combine="interleave">
+    <attribute name="form:property-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="form-property-value-and-type-attlist" combine="interleave">
+    <choice>
+        <ref name="common-value-and-type-attlist"/>
+        <attribute name="office:value-type">
+            <value>void</value>
+        </attribute>
+    </choice>
+</define>
+<define name="form-property" combine="choice">
+    <element name="form:list-property">
+        <ref name="form-property-name"/>
+        <ref name="form-property-type-and-value-list"/>
+    </element>
+</define>
+<define name="form-property-type-and-value-list">
+    <choice>
+        <group>
+            <attribute name="office:value-type">
+                <value>float</value>
+            </attribute>
+            <zeroOrMore>
+                <element name="form:list-value">
+                    <attribute name="office:value">
+                        <ref name="double"/>
+                    </attribute>
+                </element>
+            </zeroOrMore>
+        </group>
+        <group>
+            <attribute name="office:value-type">
+                <value>percentage</value>
+            </attribute>
+            <zeroOrMore>
+                <element name="form:list-value">
+                    <attribute name="office:value">
+                        <ref name="double"/>
+                    </attribute>
+                </element>
+            </zeroOrMore>
+        </group>
+        <group>
+            <attribute name="office:value-type">
+                <value>currency</value>
+            </attribute>
+            <zeroOrMore>
+                <element name="form:list-value">
+                    <attribute name="office:value">
+                        <ref name="double"/>
+                    </attribute>
+                    <optional>
+                        <attribute name="office:currency">
+                            <ref name="string"/>
+                        </attribute>
+                    </optional>
+                </element>
+            </zeroOrMore>
+        </group>
+        <group>
+            <attribute name="office:value-type">
+                <value>date</value>
+            </attribute>
+            <zeroOrMore>
+                <element name="form:list-value">
+                    <attribute name="office:date-value">
+                        <ref name="dateOrDateTime"/>
+                    </attribute>
+                </element>
+            </zeroOrMore>
+        </group>
+        <group>
+            <attribute name="office:value-type">
+                <value>time</value>
+            </attribute>
+            <zeroOrMore>
+                <element name="form:list-value">
+                    <attribute name="office:time-value">
+                        <ref name="duration"/>
+                    </attribute>
+                </element>
+            </zeroOrMore>
+        </group>
+        <group>
+            <attribute name="office:value-type">
+                <value>boolean</value>
+            </attribute>
+            <zeroOrMore>
+                <element name="form:list-value">
+                    <attribute name="office:boolean-value">
+                        <ref name="boolean"/>
+                    </attribute>
+                </element>
+            </zeroOrMore>
+        </group>
+        <group>
+            <attribute name="office:value-type">
+                <value>string</value>
+            </attribute>
+            <zeroOrMore>
+                <element name="form:list-value">
+                    <attribute name="office:string-value">
+                        <ref name="string"/>
+                    </attribute>
+                </element>
+            </zeroOrMore>
+        </group>
+        <attribute name="office:value-type">
+            <value>void</value>
+        </attribute>
+    </choice>
+</define>
+<define name="office-annotation">
+    <element name="office:annotation">
+        <ref name="office-annotation-attlist"/>
+        <ref name="draw-caption-attlist"/>
+        <ref name="common-draw-position-attlist"/>
+        <ref name="common-draw-size-attlist"/>
+        <ref name="common-draw-shape-with-text-and-styles-attlist"/>
+        <optional>
+            <ref name="dc-creator"/>
+        </optional>
+        <optional>
+            <ref name="dc-date"/>
+        </optional>
+        <optional>
+            <ref name="meta-date-string"/>
+        </optional>
+        <zeroOrMore>
+            <choice>
+                <ref name="text-p"/>
+                <ref name="text-list"/>
+            </choice>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="office-annotation-attlist" combine="interleave">
+    <optional>
+        <attribute name="office:display">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="meta-date-string">
+    <element name="meta:date-string">
+        <ref name="string"/>
+    </element>
+</define>
+<define name="common-num-format-prefix-suffix-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:num-prefix">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:num-suffix">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-num-format-attlist" combine="interleave">
+    <choice>
+        <attribute name="style:num-format">
+            <choice>
+                <value>1</value>
+                <value>i</value>
+                <value>I</value>
+                <ref name="string"/>
+                <empty/>
+            </choice>
+        </attribute>
+        <group>
+            <attribute name="style:num-format">
+                <choice>
+                    <value>a</value>
+                    <value>A</value>
+                </choice>
+            </attribute>
+            <ref name="style-num-letter-sync-attlist"/>
+        </group>
+        <empty/>
+    </choice>
+</define>
+<define name="style-num-letter-sync-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:num-letter-sync">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="office-change-info">
+    <element name="office:change-info">
+        <ref name="dc-creator"/>
+        <ref name="dc-date"/>
+        <zeroOrMore>
+            <ref name="text-p"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="office-event-listeners">
+    <element name="office:event-listeners">
+        <zeroOrMore>
+            <choice>
+                <ref name="script-event-listener"/>
+                <ref name="presentation-event-listener"/>
+            </choice>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="script-event-listener" combine="interleave">
+    <element name="script:event-listener">
+        <ref name="script-event-listener-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="script-event-listener-attlist" combine="interleave">
+    <attribute name="script:event-name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="script-event-listener-attlist" combine="interleave">
+    <attribute name="script:language">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="script-event-listener-attlist" combine="interleave">
+    <choice>
+        <attribute name="script:macro-name">
+            <ref name="string"/>
+        </attribute>
+        <group>
+            <attribute name="xlink:href">
+                <ref name="anyURI"/>
+            </attribute>
+            <optional>
+                <attribute name="xlink:type" a:defaultValue="simple">
+                    <value>simple</value>
+                </attribute>
+            </optional>
+            <optional>
+                <attribute name="xlink:actuate" a:defaultValue="onRequest">
+                    <value>onRequest</value>
+                </attribute>
+            </optional>
+        </group>
+    </choice>
+</define>
+<define name="math-math">
+    <element name="math:math">
+        <ref name="mathMarkup"/>
+    </element>
+</define>
+
+<!-- To avoid inclusion of the complete MathML schema, anything -->
+<!-- is allowed within a math:math top-level element            -->
+<define name="mathMarkup">
+    <zeroOrMore>
+        <choice>
+            <attribute>
+                <anyName/>
+            </attribute>
+            <text/>
+            <element>
+                <anyName/>
+                <ref name="mathMarkup"/>
+            </element>
+        </choice>
+    </zeroOrMore>
+</define>
+<define name="text-dde-connection-decl">
+    <element name="text:dde-connection-decl">
+        <ref name="text-dde-connection-decl-attlist"/>
+        <ref name="common-dde-connection-decl-attlist"/>
+    </element>
+</define>
+<define name="text-dde-connection-decl-attlist" combine="interleave">
+    <attribute name="office:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="common-dde-connection-decl-attlist" combine="interleave">
+    <attribute name="office:dde-application">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="common-dde-connection-decl-attlist" combine="interleave">
+    <attribute name="office:dde-topic">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="common-dde-connection-decl-attlist" combine="interleave">
+    <attribute name="office:dde-item">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="common-dde-connection-decl-attlist" combine="interleave">
+    <optional>
+        <attribute name="office:automatic-update" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-dde-link">
+    <element name="table:dde-link">
+        <ref name="office-dde-source"/>
+        <ref name="table-table"/>
+    </element>
+</define>
+<define name="office-dde-source">
+    <element name="office:dde-source">
+        <ref name="office-dde-source-attlist"/>
+        <ref name="common-dde-connection-decl-attlist"/>
+    </element>
+</define>
+<define name="office-dde-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="office:name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="office-dde-source-attlist" combine="interleave">
+    <optional>
+        <attribute name="office:conversion-mode" 
+                    a:defaultValue="into-default-style-data-style">
+            <choice>
+                <value>into-default-style-data-style</value>
+                <value>into-english-number</value>
+                <value>keep-text</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="animation-element" combine="choice">
+    <element name="anim:animate">
+        <ref name="common-anim-target-attlist"/>
+        <ref name="common-anim-named-target-attlist"/>
+        <ref name="common-anim-values-attlist"/>
+        <ref name="common-anim-spline-mode-attlist"/>
+        <ref name="common-spline-anim-value-attlist"/>
+        <ref name="common-timing-attlist"/>
+        <ref name="common-anim-add-accum-attlist"/>
+    </element>
+</define>
+<define name="animation-element" combine="choice">
+    <element name="anim:set">
+        <ref name="common-anim-target-attlist"/>
+        <ref name="common-anim-named-target-attlist"/>
+        <ref name="common-anim-set-values-attlist"/>
+        <ref name="common-timing-attlist"/>
+        <ref name="common-anim-add-accum-attlist"/>
+    </element>
+</define>
+<define name="animation-element" combine="choice">
+    <element name="anim:animateMotion">
+        <ref name="anim-animate-motion-attlist"/>
+        <ref name="common-anim-target-attlist"/>
+        <ref name="common-anim-named-target-attlist"/>
+        <ref name="common-anim-add-accum-attlist"/>
+        <ref name="common-anim-values-attlist"/>
+        <ref name="common-timing-attlist"/>
+        <ref name="common-spline-anim-value-attlist"/>
+    </element>
+</define>
+<define name="anim-animate-motion-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:path">
+            <ref name="pathData"/>
+        </attribute>
+    </optional>
+</define>
+<define name="anim-animate-motion-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:origin">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="anim-animate-motion-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:calcMode" a:defaultValue="paced">   
+            <choice>
+                <value>discrete</value>
+                <value>linear</value>
+                <value>paced</value>
+                <value>spline</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="animation-element" combine="choice">
+    <element name="anim:animateColor">
+        <ref name="common-anim-target-attlist"/>
+        <ref name="common-anim-named-target-attlist"/>
+        <ref name="common-anim-add-accum-attlist"/>
+        <ref name="common-anim-values-attlist"/>
+        <ref name="common-anim-spline-mode-attlist"/>
+        <ref name="common-spline-anim-value-attlist"/>
+        <ref name="anim-animate-color-attlist"/>
+        <ref name="common-timing-attlist"/>
+    </element>
+</define>
+<define name="anim-animate-color-attlist" combine="interleave">
+    <optional>
+        <attribute name="anim:color-interpolation" a:defaultValue="rgb">
+            <choice>
+                <value>rgb</value>
+                <value>hsl</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="anim-animate-color-attlist" combine="interleave">
+    <optional>
+        <attribute name="anim:color-interpolation-direction"     
+                                   a:defaultValue="clockwise">
+            <choice>
+                <value>clockwise</value>
+                <value>counter-clockwise</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="animation-element" combine="choice">
+    <element name="anim:animateTransform">
+        <ref name="common-anim-target-attlist"/>
+        <ref name="common-anim-named-target-attlist"/>
+        <ref name="common-anim-add-accum-attlist"/>
+        <ref name="common-anim-values-attlist"/>
+        <ref name="anim-animate-transform-attlist"/>
+        <ref name="common-timing-attlist"/>
+    </element>
+</define>
+<define name="anim-animate-transform-attlist" combine="interleave">
+    <attribute name="svg:type">
+        <choice>
+            <value>translate</value>
+            <value>scale</value>
+            <value>rotate</value>
+            <value>skewX</value>
+            <value>skewY</value> 
+        </choice>
+    </attribute>
+</define>
+<define name="animation-element" combine="choice">
+    <element name="anim:transitionFilter">
+        <ref name="common-anim-target-attlist"/>
+        <ref name="common-anim-add-accum-attlist"/>
+        <ref name="common-anim-values-attlist"/>
+        <ref name="common-anim-spline-mode-attlist "/>
+        <ref name="anim-transition-filter-attlist"/>
+        <ref name="common-timing-attlist"/>
+    </element>
+</define>
+<define name="anim-transition-filter-attlist" combine="interleave">
+    <attribute name="smil:type">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="anim-transition-filter-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:subtype">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="anim-transition-filter-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:direction" a:defaultValue="forward">
+            <choice>
+                <value>forward</value>
+                <value>reverse</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="anim-transition-filter-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:fadeColor">
+            <choice>
+                <value>forward</value>
+                <value>reverse</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="anim-transition-filter-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:mode" a:defaultValue="in">
+            <choice>
+                <value>in</value>
+                <value>out</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-attlist" combine="interleave">
+    <optional>
+        <attribute name="anim:id">
+            <ref name="ID"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-target-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:targetElement">
+            <ref name="IDREF"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-named-target-attlist" combine="interleave">
+    <attribute name="smil:attributeName">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="common-anim-target-attlist" combine="interleave">
+    <optional>
+        <attribute name="anim:sub-item">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-values-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:values">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-spline-mode-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:calcMode" a:defaultValue="discrete">   
+            <choice>
+                <value>discrete</value>
+                <value>linear</value>
+                <value>paced</value>
+                <value>spline</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-spline-anim-value-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:keyTimes">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-spline-anim-value-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:keySplines">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-add-accum-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:accumulate">
+            <choice>
+                <value>none</value>
+                <value>sum</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-add-accum-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:additive">
+            <choice>
+                <value>replace</value>
+                <value>sum</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-values-attlist" combine="interleave">
+    <optional>
+        <attribute name="anim:formula">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-anim-set-values-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:to">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="common-anim-values-attlist" combine="interleave">
+    <ref name="common-anim-set-values-attlist"/>
+    <optional>
+        <attribute name="smil:from">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="smil:by">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-begin-end-timing-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:begin">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-begin-end-timing-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:end">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-dur-timing-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:dur">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-endsync-timing-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:endsync">
+            <choice>
+                <value>first</value>
+                <value>last</value>
+                <value>all</value>
+                <value>media</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-repeat-timing-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:repeatDur">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="smil:repeatCount">
+            <choice>
+                <ref name="nonNegativeInteger"/>
+                <value>indefinite</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-fill-timing-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:fill">
+            <choice>
+                <value>remove</value>
+                <value>freeze</value>
+                <value>hold</value>
+                <value>auto</value>
+                <value>default</value>
+                <value>transition</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-fill-default-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:fillDefault">
+            <choice>
+                <value>remove</value>
+                <value>freeze</value>
+                <value>hold</value>
+                <value>transition</value>
+                <value>auto</value>
+                <value>inherit</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-restart-timing-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:restart" a:defaultValue="default">
+            <choice>
+                <value>never</value>
+                <value>always</value>
+                <value>whenNotActive</value>
+                <value>default</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-restart-default-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:restartDefault" a:defaultValue="inherit">
+            <choice>
+                <value>never</value>
+                <value>always</value>
+                <value>whenNotActive</value>
+                <value>inherit</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-time-manip-attlist" combine="interleave">
+    <optional>    
+        <attribute name="smil:accelerate" a:defaultValue="0.0">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-time-manip-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:decelerate" a:defaultValue="0.0">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-time-manip-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:autoReverse" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="animation-element" combine="choice">
+    <element name="anim:par">
+        <ref name="common-anim-attlist"/>
+        <ref name="common-timing-attlist"/>
+        <ref name="common-endsync-timing-attlist"/>
+        <zeroOrMore>
+            <ref name="animation-element"/>
+        </zeroOrMore>
+    </element>
+</define>
+
+<define name="common-basic-timing-attlist" combine="interleave">
+   <ref name="common-begin-end-timing-attlist"/>
+   <ref name="common-dur-timing-attlist"/>
+   <ref name="common-repeat-timing-attlist"/>
+</define>
+
+<define name="common-timing-attlist" combine="interleave">
+   <ref name="common-basic-timing-attlist"/>
+   <ref name="common-restart-timing-attlist"/>
+   <ref name="common-restart-default-attlist"/>
+   <ref name="common-fill-timing-attlist"/>
+   <ref name="common-fill-default-attlist"/>
+   <ref name="common-time-manip-attlist"/>
+</define>
+<define name="animation-element" combine="choice">
+    <element name="anim:seq">
+        <ref name="common-anim-attlist"/>
+        <ref name="common-endsync-timing-attlist"/>
+        <ref name="common-timing-attlist"/>
+        <zeroOrMore>
+            <ref name="animation-element"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="animation-element" combine="choice">
+    <element name="anim:iterate">
+        <ref name="common-anim-attlist"/>
+        <ref name="anim-iterate-attlist"/>
+        <ref name="common-timing-attlist"/>
+        <ref name="common-endsync-timing-attlist"/>
+        <zeroOrMore>
+            <ref name="animation-element"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="anim-iterate-attlist" combine="interleave">
+    <ref name="common-anim-target-attlist"/>
+</define>
+<define name="anim-iterate-attlist" combine="interleave">
+    <optional>
+        <attribute name="anim:iterate-type">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="anim-iterate-attlist" combine="interleave">
+    <optional>
+        <attribute name="anim:iterate-interval">
+            <ref name="duration"/>
+        </attribute>
+    </optional>
+</define>
+<define name="animation-element" combine="choice">
+    <element name="anim:audio">
+        <ref name="common-anim-attlist"/>
+        <ref name="anim-audio-attlist"/>
+        <ref name="common-basic-timing-attlist"/>
+    </element>
+</define>
+<define name="anim-audio-attlist" combine="interleave">
+    <optional>
+        <attribute name="xlink:href">
+            <ref name="anyURI"/>
+        </attribute>
+    </optional>
+</define>
+<define name="anim-audio-attlist" combine="interleave">
+    <optional>
+        <attribute name="anim:audio-level">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="animation-element" combine="choice">
+    <element name="anim:command">
+        <ref name="common-anim-attlist"/>
+        <ref name="anim-command-attlist"/>
+        <ref name="common-begin-end-timing-attlist"/>
+        <ref name="common-anim-target-attlist"/>
+        <zeroOrMore>
+            <element name="anim:param">
+                <attribute name="anim:name"/>
+                <attribute name="anim:value"/>
+            </element>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="anim-command-attlist" combine="interleave">
+    <attribute name="anim:command">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="style-style">
+    <element name="style:style">
+        <ref name="style-style-attlist"/>
+        <ref name="style-style-content"/>
+        <zeroOrMore>
+            <ref name="style-map"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="style-style-attlist" combine="interleave">
+    <attribute name="style:name">
+        <ref name="styleName"/>
+    </attribute>
+</define>
+<define name="style-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:display-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:parent-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:next-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:list-style-name">
+            <choice>
+                <ref name="styleName"/>
+                <empty/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:master-page-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:auto-update" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:data-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:class">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:default-outline-level">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-map">
+    <element name="style:map">
+        <ref name="style-map-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="style-map-attlist" combine="interleave">
+    <attribute name="style:condition">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="style-map-attlist" combine="interleave">
+    <attribute name="style:apply-style-name">
+        <ref name="styleNameRef"/>
+    </attribute>
+</define>
+<define name="style-map-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:base-cell-address">
+            <ref name="cellAddress"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-default-style">
+    <element name="style:default-style">
+        <ref name="style-style-content"/>
+    </element>
+</define>
+<define name="style-page-layout">
+    <element name="style:page-layout">
+        <ref name="style-page-layout-attlist"/>
+        <optional>
+            <ref name="style-page-layout-properties"/>
+        </optional>
+        <optional>
+            <ref name="style-header-style"/>
+        </optional>
+        <optional>
+            <ref name="style-footer-style"/>
+        </optional>
+    </element>
+</define>
+<define name="style-page-layout-attlist" combine="interleave">
+    <attribute name="style:name">
+        <ref name="styleName"/>
+    </attribute>
+</define>
+<define name="style-page-layout-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:page-usage" a:defaultValue="all">
+            <choice>
+                <value>all</value>
+                <value>left</value>
+                <value>right</value>
+                <value>mirrored</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-header-style">
+    <element name="style:header-style">
+        <optional>
+            <ref name="style-header-footer-properties"/>
+        </optional>
+    </element>
+</define>
+<define name="style-footer-style">
+    <element name="style:footer-style">
+        <optional>
+            <ref name="style-header-footer-properties"/>
+        </optional>
+    </element>
+</define>
+<define name="style-master-page">
+    <element name="style:master-page">
+        <ref name="style-master-page-attlist"/>
+        <optional>
+            <ref name="style-header"/>
+            <optional>
+                <ref name="style-header-left"/>
+            </optional>
+        </optional>
+        <optional>
+            <ref name="style-footer"/>
+            <optional>
+                <ref name="style-footer-left"/>
+            </optional>
+        </optional>
+        <optional>
+            <ref name="office-forms"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="style-style"/>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="shape"/>
+        </zeroOrMore>
+        <optional>
+            <ref name="presentation-notes"/>
+        </optional>
+    </element>
+</define>
+<define name="style-master-page-attlist" combine="interleave">
+    <attribute name="style:name">
+        <ref name="styleName"/>
+    </attribute>
+</define>
+<define name="style-master-page-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:display-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-master-page-attlist" combine="interleave">
+    <attribute name="style:page-layout-name">
+        <ref name="styleNameRef"/>
+    </attribute>
+</define>
+<define name="style-master-page-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-master-page-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:next-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-header">
+    <element name="style:header">
+        <ref name="common-style-header-footer-attlist"/>
+        <ref name="header-footer-content"/>
+    </element>
+</define>
+<define name="style-footer">
+    <element name="style:footer">
+        <ref name="common-style-header-footer-attlist"/>
+        <ref name="header-footer-content"/>
+    </element>
+</define>
+<define name="style-header-left">
+    <element name="style:header-left">
+        <ref name="common-style-header-footer-attlist"/>
+        <ref name="header-footer-content"/>
+    </element>
+</define>
+<define name="style-footer-left">
+    <element name="style:footer-left">
+        <ref name="common-style-header-footer-attlist"/>
+        <ref name="header-footer-content"/>
+    </element>
+</define>
+<define name="header-footer-content">
+    <choice>
+        <group>
+            <ref name="text-tracked-changes"/>
+            <ref name="text-decls"/>
+            <zeroOrMore>
+                <choice>
+                    <ref name="text-h"/>
+                    <ref name="text-p"/>
+                    <ref name="text-list"/>
+                    <ref name="table-table"/>
+                    <ref name="text-section"/>
+                    <ref name="text-table-of-content"/>
+                    <ref name="text-illustration-index"/>
+                    <ref name="text-table-index"/>
+                    <ref name="text-object-index"/>
+                    <ref name="text-user-index"/>
+                    <ref name="text-alphabetical-index"/>
+                    <ref name="text-bibliography"/>
+                    <ref name="text-index-title"/>
+                    <ref name="change-marks"/>
+                </choice>
+            </zeroOrMore>
+        </group>
+        <group>
+            <optional>
+                <ref name="style-region-left"/>
+            </optional>
+            <optional>
+                <ref name="style-region-center"/>
+            </optional>
+            <optional>
+                <ref name="style-region-right"/>
+            </optional>
+        </group>
+    </choice>
+</define>
+<define name="common-style-header-footer-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:display" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-region-left">
+    <element name="style:region-left">
+        <ref name="region-content"/>
+    </element>
+</define>
+<define name="style-region-center">
+    <element name="style:region-center">
+        <ref name="region-content"/>
+    </element>
+</define>
+<define name="style-region-right">
+    <element name="style:region-right">
+        <ref name="region-content"/>
+    </element>
+</define>
+
+<define name="region-content">
+    <zeroOrMore>
+        <ref name="text-p"/>
+    </zeroOrMore>
+</define>
+<define name="presentation-notes">
+    <element name="presentation:notes">
+        <ref name="common-presentation-header-footer-attlist"/>
+        <ref name="presentation-notes-attlist"/>
+        <ref name="office-forms"/>
+        <zeroOrMore>
+            <ref name="shape"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="presentation-notes-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:page-layout-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="presentation-notes-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="table-table-template">
+    <element name="table:table-template">
+        <ref name="table-table-template-attlist"/>
+        <optional>
+            <ref name="table-first-row"/>
+        </optional>
+        <optional>
+            <ref name="table-last-row"/>
+        </optional>
+        <optional>
+            <ref name="table-first-column"/>
+        </optional>
+        <optional>
+            <ref name="table-last-column"/>
+        </optional>
+        <choice>
+            <ref name="table-body"/>
+            <group>
+                <ref name="table-even-rows"/>
+                <ref name="table-odd-rows"/>
+            </group>
+            <group>
+                <ref name="table-even-columns"/>
+                <ref name="table-odd-columns"/>
+            </group>
+        </choice>
+    </element>
+</define>
+<define name="table-table-template-attlist" combine="interleave">
+    <attribute name="text:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="table-table-template-attlist" combine="interleave">
+    <attribute name="text:first-row-start-column">
+        <ref name="rowOrCol"/>
+    </attribute>
+</define>
+
+<define name="table-table-template-attlist" combine="interleave">
+    <attribute name="text:first-row-end-column">
+        <ref name="rowOrCol"/>
+    </attribute>
+</define>
+
+<define name="table-table-template-attlist" combine="interleave">
+    <attribute name="text:last-row-start-column">
+        <ref name="rowOrCol"/>
+    </attribute>
+</define>
+
+<define name="table-table-template-attlist" combine="interleave">
+    <attribute name="text:last-row-end-column">
+        <ref name="rowOrCol"/>
+    </attribute>
+</define>
+
+<define name="rowOrCol">
+    <choice>
+        <value>row</value>
+        <value>column</value>
+    </choice>
+</define>
+<define name="table-first-row">
+    <element name="table:first-row">
+        <ref name="common-table-template-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="table-last-row">
+    <element name="table:last-row">
+        <ref name="common-table-template-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="table-first-column">
+    <element name="table:first-column">
+        <ref name="common-table-template-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="table-last-column">
+    <element name="table:last-column">
+        <ref name="common-table-template-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="table-body">
+    <element name="table:body">
+        <ref name="common-table-template-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="table-even-rows">
+    <element name="table:even-rows">
+        <ref name="common-table-template-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="table-odd-rows">
+    <element name="table:odd-rows">
+        <ref name="common-table-template-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="table-even-columns">
+    <element name="table:even-columns">
+        <ref name="common-table-template-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="table-odd-columns">
+    <element name="table:odd-columns">
+        <ref name="common-table-template-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="common-table-template-attlist" combine="interleave">
+    <attribute name="text:style-name">
+        <ref name="styleNameRef"/>
+    </attribute>
+    <attribute name="text:paragraph-style-name">
+        <optional>
+            <ref name="styleNameRef"/>
+        </optional>
+    </attribute>
+</define>
+<define name="style-font-face">
+    <element name="style:font-face">
+        <ref name="style-font-face-attlist"/>
+        <optional>
+            <ref name="svg-font-face-src"/>
+        </optional>
+        <optional>
+            <ref name="svg-definition-src"/>
+        </optional>
+    </element>
+</define>
+<define name="style-font-face-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:font-family">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:font-style">
+            <ref name="fontStyle"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:font-variant">
+            <ref name="fontVariant"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:font-weight">
+            <ref name="fontWeight"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:font-stretch">
+            <choice>
+                <value>normal</value>
+                <value>ultra-condensed</value>
+                <value>extra-condensed</value>
+                <value>condensed</value>
+                <value>semi-condensed</value>
+                <value>semi-expanded</value>
+                <value>expanded</value>
+                <value>extra-expanded</value>
+                <value>ultra-expanded</value>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:font-size">
+            <ref name="positiveLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:unicode-range"/>
+    </optional>
+    <optional>
+        <attribute name="svg:units-per-em">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:panose-1"/>
+    </optional>
+    <optional>
+        <attribute name="svg:stemv">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:stemh">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:slope">
+            <ref name="integer"/>
+        </attribute>
+        </optional>
+    <optional>
+        <attribute name="svg:cap-height">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:x-height">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:accent-height">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:ascent">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:descent">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:widths"/>
+    </optional>
+    <optional>
+        <attribute name="svg:bbox"/>
+    </optional>
+    <optional>
+        <attribute name="svg:ideographic">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:alphabetic">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:mathematical">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:hanging">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:v-ideographic">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:v-alphabetic">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:v-mathematical">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:v-hanging">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:underline-position">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:underline-thickness">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:strikethrough-position">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:strikethrough-thickness">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:overline-position">
+            <ref name="integer"/>
+        </attribute>
+        </optional>
+    <optional>
+        <attribute name="svg:overline-thickness">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="svg-font-face-src">
+    <element name="svg:font-face-src">
+        <oneOrMore>
+            <choice>
+                <ref name="svg-font-face-uri"/>
+                <ref name="svg-font-face-name"/>
+            </choice>
+        </oneOrMore>
+    </element>
+</define>
+
+<define name="svg-font-face-uri">
+    <element name="svg:font-face-uri">
+        <ref name="common-svg-font-face-xlink-attlist"/>
+        <zeroOrMore>
+            <ref name="svg-font-face-format"/>
+        </zeroOrMore>
+    </element>
+</define>
+
+<define name="svg-font-face-format">
+    <element name="svg:font-face-format">
+        <optional>
+            <attribute name="svg:string"/>
+        </optional>
+        <empty/>
+    </element>
+</define>
+<define name="svg-font-face-name">
+    <element name="svg:font-face-name">
+        <optional>
+            <attribute name="svg:name"/>
+        </optional>
+        <empty/>
+    </element>
+</define>
+
+<define name="svg-definition-src">
+    <element name="svg:definition-src">
+        <ref name="common-svg-font-face-xlink-attlist"/>
+    <empty/>
+    </element>
+</define>
+
+<define name="common-svg-font-face-xlink-attlist" combine="interleave">
+    <attribute name="xlink:href">
+        <ref name="anyURI"/>
+    </attribute>
+    <optional>
+        <attribute name="xlink:type" a:defaultValue="simple">
+            <value>simple</value>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="xlink:actuate" a:defaultValue="onRequest">
+            <value>onRequest</value>
+        </attribute>
+    </optional>
+</define>
+<define name="style-font-face-attlist" combine="interleave">
+    <attribute name="style:name">
+        <ref name="string"/>
+    </attribute>
+</define>
+<define name="style-font-face-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:font-adornments">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-font-face-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:font-family-generic">
+            <ref name="fontFamilyGeneric"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-font-face-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:font-pitch">
+            <ref name="fontPitch"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="style-font-face-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:font-charset">
+            <ref name="textEncoding"/>
+        </attribute>
+    </optional>
+</define>
+<define name="number-number-style">
+    <element name="number:number-style">
+        <ref name="common-data-style-attlist"/>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+        <optional>
+            <ref name="number-text"/>
+        </optional>
+        <optional>
+            <ref name="any-number"/>
+            <optional>
+                <ref name="number-text"/>
+            </optional>
+        </optional>
+        <zeroOrMore>
+            <ref name="style-map"/>
+        </zeroOrMore>
+    </element>
+</define>
+
+<define name="any-number">
+    <choice>
+        <ref name="number-number"/>
+        <ref name="number-scientific-number"/>
+        <ref name="number-fraction"/>
+    </choice>
+</define>
+<define name="number-number">
+    <element name="number:number">
+        <ref name="number-number-attlist"/>
+        <ref name="common-decimal-places-attlist"/>
+        <ref name="common-number-attlist"/>
+        <zeroOrMore>
+            <ref name="number-embedded-text"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="number-number-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:decimal-replacement"/>
+    </optional>
+</define>
+<define name="number-number-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:display-factor" a:defaultValue="1">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="number-embedded-text">
+    <element name="number:embedded-text">
+        <ref name="number-embedded-text-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="number-embedded-text-attlist" combine="interleave">
+    <attribute name="number:position">
+        <ref name="integer"/>
+    </attribute>
+</define>
+<define name="number-scientific-number">
+    <element name="number:scientific-number">
+        <ref name="number-scientific-number-attlist"/>
+        <ref name="common-decimal-places-attlist"/>
+        <ref name="common-number-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="number-scientific-number-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:min-exponent-digits">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="number-fraction">
+    <element name="number:fraction">
+        <ref name="number-fraction-attlist"/>
+        <ref name="common-number-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="number-fraction-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:min-numerator-digits">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="number-fraction-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:min-denominator-digits">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="number-fraction-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:denominator-value">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="number-currency-style">
+    <element name="number:currency-style">
+        <ref name="common-data-style-attlist"/>
+        <ref name="common-auto-reorder-attlist"/>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+        <optional>
+            <ref name="number-text"/>
+        </optional>
+        <optional>
+            <choice>
+                <group>
+                    <ref name="number-and-text"/>
+                    <optional>
+                        <ref name="currency-symbol-and-text"/>
+                    </optional>
+                </group>
+                <group>
+                    <ref name="currency-symbol-and-text"/>
+                    <optional>
+                        <ref name="number-and-text"/>
+                    </optional>
+                </group>
+            </choice>
+        </optional>
+        <zeroOrMore>
+            <ref name="style-map"/>
+        </zeroOrMore>
+    </element>
+</define>
+
+<define name="currency-symbol-and-text">
+    <ref name="number-currency-symbol"/>
+    <optional>
+        <ref name="number-text"/>
+    </optional>
+</define>
+<define name="number-and-text">
+    <ref name="number-number"/>
+    <optional>
+        <ref name="number-text"/>
+    </optional>
+</define>
+<define name="number-currency-symbol">
+    <element name="number:currency-symbol">
+        <ref name="number-currency-symbol-attlist"/>
+        <text/>
+    </element>
+</define>
+<define name="number-currency-symbol-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:language">
+            <ref name="languageCode"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="number:country">
+            <ref name="countryCode"/>
+        </attribute>
+    </optional>
+</define>
+<define name="number-percentage-style">
+    <element name="number:percentage-style">
+        <ref name="common-data-style-attlist"/>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+        <optional>
+            <ref name="number-text"/>
+        </optional>
+        <optional>
+            <ref name="number-and-text"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="style-map"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="number-date-style">
+    <element name="number:date-style">
+        <ref name="common-data-style-attlist"/>
+        <ref name="common-auto-reorder-attlist"/>
+        <ref name="common-format-source-attlist"/>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+        <!-- This DTD does not reflect the fact that some elements must not -->
+        <!-- occur more than once. -->
+        <optional>
+            <ref name="number-text"/>
+        </optional>
+        <oneOrMore>
+            <ref name="any-date"/>
+            <optional>
+                <ref name="number-text"/>
+            </optional>
+        </oneOrMore>
+        <zeroOrMore>
+            <ref name="style-map"/>
+        </zeroOrMore>
+    </element>
+</define>
+
+<define name="any-date">
+    <choice>
+        <ref name="number-day"/>
+        <ref name="number-month"/>
+        <ref name="number-year"/>
+        <ref name="number-era"/>
+        <ref name="number-day-of-week"/>
+        <ref name="number-week-of-year"/>
+        <ref name="number-quarter"/>
+        <ref name="number-hours"/>
+        <ref name="number-am-pm"/>
+        <ref name="number-minutes"/>
+        <ref name="number-seconds"/>
+    </choice>
+</define>
+<define name="number-day">
+    <element name="number:day">
+        <ref name="number-day-attlist"/>
+        <ref name="common-calendar-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="number-day-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:style" a:defaultValue="short">
+            <choice>
+                <value>short</value>
+                <value>long</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="number-month">
+    <element name="number:month">
+        <ref name="number-month-attlist"/>
+        <ref name="common-calendar-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="number-month-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:textual" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="number-month-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:possessive-form" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="number-month-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:style" a:defaultValue="short">
+            <choice>
+                <value>short</value>
+                <value>long</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="number-year">
+    <element name="number:year">
+        <ref name="number-year-attlist"/>
+        <ref name="common-calendar-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="number-year-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:style" a:defaultValue="short">
+            <choice>
+                <value>short</value>
+                <value>long</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="number-era">
+    <element name="number:era">
+        <ref name="number-era-attlist"/>
+        <ref name="common-calendar-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="number-era-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:style" a:defaultValue="short">
+            <choice>
+                <value>short</value>
+                <value>long</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="number-day-of-week">
+    <element name="number:day-of-week">
+        <ref name="number-day-of-week-attlist"/>
+        <ref name="common-calendar-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="number-day-of-week-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:style" a:defaultValue="short">
+            <choice>
+                <value>short</value>
+                <value>long</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="number-week-of-year">
+    <element name="number:week-of-year">
+        <ref name="common-calendar-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="number-quarter">
+    <element name="number:quarter">
+        <ref name="number-quarter-attlist"/>
+        <ref name="common-calendar-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="number-quarter-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:style" a:defaultValue="short">
+            <choice>
+                <value>short</value>
+                <value>long</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="number-time-style">
+    <element name="number:time-style">
+        <ref name="number-time-style-attlist"/>
+        <ref name="common-data-style-attlist"/>
+        <ref name="common-format-source-attlist"/>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+        <!-- This DTD does not reflect the fact that some elements must not -->
+        <!-- occur more than once. -->
+        <optional>
+            <ref name="number-text"/>
+        </optional>
+        <oneOrMore>
+            <ref name="any-time"/>
+            <optional>
+                <ref name="number-text"/>
+            </optional>
+        </oneOrMore>
+        <zeroOrMore>
+            <ref name="style-map"/>
+        </zeroOrMore>
+    </element>
+</define>
+
+<define name="any-time">
+    <choice>
+        <ref name="number-hours"/>
+        <ref name="number-am-pm"/>
+        <ref name="number-minutes"/>
+        <ref name="number-seconds"/>
+    </choice>
+</define>
+<define name="number-time-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:truncate-on-overflow" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="number-hours">
+    <element name="number:hours">
+        <ref name="number-hours-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="number-hours-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:style" a:defaultValue="short">
+            <choice>
+                <value>short</value>
+                <value>long</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="number-minutes">
+    <element name="number:minutes">
+        <ref name="number-minutes-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="number-minutes-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:style" a:defaultValue="short">
+            <choice>
+                <value>short</value>
+                <value>long</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="number-seconds">
+    <element name="number:seconds">
+        <ref name="number-seconds-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="number-seconds-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:style" a:defaultValue="short">
+            <choice>
+                <value>short</value>
+                <value>long</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="number-seconds-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:decimal-places" a:defaultValue="0">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="number-am-pm">
+    <element name="number:am-pm">
+        <empty/>
+    </element>
+</define>
+<define name="number-boolean-style">
+    <element name="number:boolean-style">
+        <ref name="common-data-style-attlist"/>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+        <optional>
+            <ref name="number-text"/>
+        </optional>
+        <optional>
+            <ref name="number-boolean"/>
+            <optional>
+                <ref name="number-text"/>
+            </optional>
+        </optional>
+        <zeroOrMore>
+            <ref name="style-map"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="number-boolean">
+    <element name="number:boolean">
+        <empty/>
+    </element>
+</define>
+<define name="number-text-style">
+    <element name="number:text-style">
+        <ref name="common-data-style-attlist"/>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+        <optional>
+            <ref name="number-text"/>
+        </optional>
+        <zeroOrMore>
+            <ref name="number-text-content"/>
+            <optional>
+                <ref name="number-text"/>
+            </optional>
+        </zeroOrMore>
+        <zeroOrMore>
+            <ref name="style-map"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="number-text">
+    <element name="number:text">
+        <text/>
+    </element>
+</define>
+<define name="number-text-content">
+    <element name="number:text-content">
+        <empty/>
+    </element>
+</define>
+<define name="common-data-style-attlist" combine="interleave">
+    <attribute name="style:name">
+        <ref name="styleName"/>
+    </attribute>
+</define>
+<define name="style-data-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:display-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-data-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:language">
+            <ref name="languageCode"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-data-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:country">
+            <ref name="countryCode"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-data-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:title"/>
+    </optional>
+</define>
+<define name="common-data-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:volatile">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-auto-reorder-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:automatic-order" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-format-source-attlist">
+    <optional>
+        <attribute name="number:format-source" a:defaultValue="fixed">
+            <choice>
+                <value>fixed</value>
+                <value>language</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-data-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:transliteration-format" a:defaultValue="1">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-data-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:transliteration-language">
+            <ref name="countryCode"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-data-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:transliteration-country">
+            <ref name="countryCode"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-data-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:transliteration-style" a:defaultValue="short">
+            <choice>
+                <value>short</value>
+                <value>medium</value>
+                <value>long</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-decimal-places-attlist">
+    <optional>
+        <attribute name="number:decimal-places">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-number-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:min-integer-digits">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-number-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:grouping" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-calendar-attlist" combine="interleave">
+    <optional>
+        <attribute name="number:calendar">
+            <choice>
+                <value>gregorian</value>
+                <value>gengou</value>
+                <value>ROC</value>
+                <value>hanja_yoil</value>
+                <value>hanja</value>
+                <value>hijri</value>
+                <value>jewish</value>
+                <value>buddhist</value>
+                <ref name="string"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-style-content" combine="choice">
+    <group>
+        <attribute name="style:family">
+            <value>text</value>
+        </attribute>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+    </group>
+</define>
+<define name="style-style-content" combine="choice">
+    <group>
+        <attribute name="style:family">
+            <value>paragraph</value>
+        </attribute>
+        <optional>
+            <ref name="style-paragraph-properties"/>
+        </optional>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+    </group>
+</define>
+<define name="style-style-content" combine="choice">
+    <group>
+        <attribute name="style:family">
+            <value>section</value>
+        </attribute>
+        <optional>
+            <ref name="style-section-properties"/>
+        </optional>
+    </group>
+</define>
+<define name="style-style-content" combine="choice">
+    <group>
+        <attribute name="style:family">
+            <value>ruby</value>
+        </attribute>
+        <optional>
+            <ref name="style-ruby-properties"/>
+        </optional>
+    </group>
+</define>
+<define name="text-linenumbering-configuration">
+    <element name="text:linenumbering-configuration">
+        <ref name="text-linenumbering-configuration-attlist"/>
+        <optional>
+            <ref name="text-linenumbering-separator"/>
+        </optional>
+    </element>
+</define>
+<define name="text-linenumbering-configuration-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:number-lines" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-linenumbering-configuration-attlist" combine="interleave">
+    <optional>
+        <ref name="common-num-format-attlist"/>
+    </optional>
+</define>
+<define name="text-linenumbering-configuration-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-linenumbering-configuration-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:increment">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-linenumbering-configuration-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:number-position" a:defaultValue="left">
+            <choice>
+                <value>left</value>
+                <value>right</value>
+                <value>inner</value>
+                <value>outer</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="text-linenumbering-configuration-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:offset">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-linenumbering-configuration-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:count-empty-lines" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-linenumbering-configuration-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:count-in-text-boxes" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-linenumbering-configuration-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:restart-on-page" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-linenumbering-separator">
+    <element name="text:linenumbering-separator">
+        <optional>
+            <attribute name="text:increment">
+                <ref name="nonNegativeInteger"/>
+            </attribute>
+        </optional>
+        <text/>
+    </element>
+</define>
+<define name="text-notes-configuration">
+    <element name="text:notes-configuration">
+        <ref name="text-notes-configuration-content"/>
+    </element>
+</define>
+<define name="text-notes-configuration-content" combine="interleave">
+    <ref name="text-note-class"/>
+</define>
+<define name="text-notes-configuration-content" combine="interleave">
+    <optional>
+        <attribute name="text:citation-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-notes-configuration-content" combine="interleave">
+    <optional>
+        <attribute name="text:citation-body-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-notes-configuration-content" combine="interleave">
+    <optional>
+        <attribute name="text:default-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-notes-configuration-content" combine="interleave">
+    <optional>
+        <attribute name="text:master-page-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-notes-configuration-content" combine="interleave">
+    <optional>
+        <attribute name="text:start-value">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-notes-configuration-content" combine="interleave">
+    <ref name="common-num-format-prefix-suffix-attlist"/>
+    <optional>
+        <ref name="common-num-format-attlist"/>
+    </optional>
+</define>
+<define name="text-notes-configuration-content" combine="interleave">
+    <optional>
+        <attribute name="text:start-numbering-at">
+            <choice>
+                <value>document</value>
+                <value>chapter</value>
+                <value>page</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="text-notes-configuration-content" combine="interleave">
+    <optional>
+        <attribute name="text:footnotes-position">
+            <choice>
+                <value>text</value>
+                <value>page</value>
+                <value>section</value>
+                <value>document</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="text-notes-configuration-content" combine="interleave">
+    <optional>
+        <element name="text:note-continuation-notice-forward">
+            <text/>
+        </element>
+    </optional>
+</define>
+<define name="text-notes-configuration-content" combine="interleave">
+    <optional>
+        <element name="text:note-continuation-notice-backward">
+            <text/>
+        </element>
+    </optional>
+</define>
+<define name="text-bibliography-configuration">
+    <element name="text:bibliography-configuration">
+        <ref name="text-bibliography-configuration-attlist"/>
+        <zeroOrMore>
+            <ref name="text-sort-key"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-bibliography-configuration-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:prefix">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:suffix">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-bibliography-configuration-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:numbered-entries" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-bibliography-configuration-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:sort-by-position" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:language">
+            <ref name="languageCode"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:country">
+            <ref name="countryCode"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:sort-algorithm">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-sort-key">
+    <element name="text:sort-key">
+        <ref name="text-sort-key-attlist"/>
+        <empty/>
+    </element>
+</define>
+
+<define name="text-sort-key-attlist" combine="interleave">
+    <attribute name="text:key">
+        <choice>
+            <value>address</value>
+            <value>annote</value>
+            <value>author</value>
+            <value>bibliography-type</value>
+            <value>booktitle</value>
+            <value>chapter</value>
+            <value>custom1</value>
+            <value>custom2</value>
+            <value>custom3</value>
+            <value>custom4</value>
+            <value>custom5</value>
+            <value>edition</value>
+            <value>editor</value>
+            <value>howpublished</value>
+            <value>identifier</value>
+            <value>institution</value>
+            <value>isbn</value>
+            <value>issn</value>
+            <value>journal</value>
+            <value>month</value>
+            <value>note</value>
+            <value>number</value>
+            <value>organizations</value>
+            <value>pages</value>
+            <value>publisher</value>
+            <value>report-type</value>
+            <value>school</value>
+            <value>series</value>
+            <value>title</value>
+            <value>url</value>
+            <value>volume</value>
+            <value>year</value>
+        </choice>
+    </attribute>
+    <optional>
+        <attribute name="text:sort-ascending" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-list-style">
+    <element name="text:list-style">
+        <ref name="text-list-style-attr"/>
+        <zeroOrMore>
+            <ref name="text-list-style-content"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="text-list-style-attr" combine="interleave">
+    <attribute name="style:name">
+        <ref name="styleName"/>
+    </attribute>
+</define>
+<define name="text-list-style-attr" combine="interleave">
+    <optional>
+        <attribute name="style:display-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-list-style-attr" combine="interleave">
+    <optional>
+        <attribute name="text:consecutive-numbering" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-list-level-style-attr">
+    <attribute name="text:level">
+        <ref name="positiveInteger"/>
+    </attribute>
+</define>
+<define name="text-list-style-content" combine="choice">
+    <element name="text:list-level-style-number">
+        <ref name="text-list-level-style-attr"/>
+        <ref name="text-list-level-style-number-attr"/>
+        <optional>
+            <ref name="style-list-level-properties"/>
+        </optional>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+    </element>
+</define>
+<define name="text-list-level-style-number-attr" combine="interleave">
+    <optional>
+        <attribute name="text:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-list-level-style-number-attr" combine="interleave">
+    <ref name="common-num-format-attlist"/>
+    <ref name="common-num-format-prefix-suffix-attlist"/>
+</define>
+<define name="text-list-level-style-number-attr" combine="interleave">
+    <optional>
+        <attribute name="text:display-levels" a:defaultValue="1">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-list-level-style-number-attr" combine="interleave">
+    <optional>
+        <attribute name="text:start-value" a:defaultValue="1">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-list-style-content" combine="choice">
+    <element name="text:list-level-style-bullet">
+        <ref name="text-list-level-style-attr"/>
+        <ref name="text-list-level-style-bullet-attr"/>
+        <optional>
+            <ref name="style-list-level-properties"/>
+        </optional>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+    </element>
+</define>
+<define name="text-list-level-style-bullet-attr" combine="interleave">
+    <optional>
+        <attribute name="text:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-list-level-style-bullet-attr" combine="interleave">
+    <attribute name="text:bullet-char">
+        <ref name="character"/>
+    </attribute>
+</define>
+<define name="text-list-level-style-bullet-attr" combine="interleave">
+    <ref name="common-num-format-prefix-suffix-attlist"/>
+</define>
+<define name="text-list-level-style-bullet-attr" combine="interleave">
+    <optional>
+        <attribute name="text:bullet-relative-size">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-list-style-content" combine="choice">
+    <element name="text:list-level-style-image">
+        <ref name="text-list-level-style-attr"/>
+        <ref name="text-list-level-style-image-attr"/>
+        <optional>
+            <ref name="style-list-level-properties"/>
+        </optional>
+    </element>
+</define>
+<define name="text-list-level-style-image-attr" combine="interleave">
+    <choice>
+        <ref name="common-draw-data-attlist"/>
+        <ref name="office-binary-data"/>
+    </choice>
+</define>
+<define name="text-outline-style">
+    <element name="text:outline-style">
+        <oneOrMore>
+            <ref name="text-outline-level-style"/>
+        </oneOrMore>
+    </element>
+</define>
+<define name="text-outline-level-style">
+    <element name="text:outline-level-style">
+        <ref name="text-outline-level-style-attlist"/>
+        <optional>
+            <ref name="style-list-level-properties"/>
+        </optional>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+    </element>
+</define>
+<define name="text-outline-level-style-attlist" combine="interleave">
+    <attribute name="text:level">
+        <ref name="positiveInteger"/>
+    </attribute>
+</define>
+<define name="text-outline-level-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-outline-level-style-attlist" combine="interleave">
+    <ref name="common-num-format-attlist"/>
+    <ref name="common-num-format-prefix-suffix-attlist"/>
+</define>
+<define name="text-outline-level-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:display-levels" a:defaultValue="1">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="text-outline-level-style-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:start-value" a:defaultValue="1">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-style-content" combine="choice">
+    <group>
+        <attribute name="style:family">
+            <value>table</value>
+        </attribute>
+        <optional>
+            <ref name="style-table-properties"/>
+        </optional>
+    </group>
+</define>
+<define name="style-style-content" combine="choice">
+    <group>
+        <attribute name="style:family">
+            <value>table-column</value>
+        </attribute>
+        <optional>
+            <ref name="style-table-column-properties"/>
+        </optional>
+    </group>
+</define>
+<define name="style-style-content" combine="choice">
+    <group>
+        <attribute name="style:family">
+            <value>table-row</value>
+        </attribute>
+        <optional>
+            <ref name="style-table-row-properties"/>
+        </optional>
+    </group>
+</define>
+<define name="style-style-content" combine="choice">
+    <group>
+        <attribute name="style:family">
+            <value>table-cell</value>
+        </attribute>
+        <optional>
+            <ref name="style-table-cell-properties"/>
+        </optional>
+        <optional>
+            <ref name="style-paragraph-properties"/>
+        </optional>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+    </group>
+</define>
+<define name="style-style-content" combine="choice">
+    <group>
+        <attribute name="style:family">
+            <choice>
+                <value>graphic</value>
+                <value>presentation</value>
+            </choice>
+        </attribute>
+        <optional>
+            <ref name="style-graphic-properties"/>
+        </optional>
+        <optional>
+            <ref name="style-paragraph-properties"/>
+        </optional>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+    </group>
+</define>
+
+<define name="style-graphic-properties">
+    <element name="style:graphic-properties">
+        <ref name="style-graphic-properties-content"/>
+    </element>
+</define>
+
+<define name="style-graphic-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-graphic-properties-content-strict">
+    <ref name="style-graphic-properties-attlist"/>
+    <ref name="style-graphic-fill-properties-attlist"/>
+    <ref name="style-graphic-properties-elements"/>
+</define>
+
+<define name=" style-graphic-properties-elements">
+    <empty/>
+</define>
+<define name="style-style-content" combine="choice">
+    <group>
+        <attribute name="style:family">
+            <value>drawing-page</value>
+        </attribute>
+        <optional>
+            <ref name="style-drawing-page-properties"/>
+        </optional>
+    </group>
+</define>
+
+<define name="style-drawing-page-properties">
+    <element name="style:drawing-page-properties">
+        <ref name="style-drawing-page-properties-content"/>
+    </element>
+</define>
+
+<define name="style-drawing-page-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-drawing-page-properties-content-strict">
+    <ref name="style-graphic-fill-properties-attlist"/>
+    <ref name="style-drawing-page-properties-attlist"/>
+    <ref name="style-drawing-page-properties-elements"/>
+</define>
+<define name="draw-gradient">
+    <element name="draw:gradient">
+        <ref name="common-draw-gradient-attlist"/>
+        <ref name="draw-gradient-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="common-draw-gradient-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:name">
+            <ref name="styleName"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-gradient-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:display-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-gradient-attlist" combine="interleave">
+    <attribute name="draw:style">
+        <ref name="gradient-style"/>
+    </attribute>
+</define>
+<define name="gradient-style">
+    <choice>
+        <value>linear</value>
+        <value>axial</value>
+        <value>radial</value>
+        <value>ellipsoid</value>
+        <value>square</value>
+        <value>rectangular</value>
+    </choice>
+</define>
+<define name="common-draw-gradient-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:cx">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:cy">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-gradient-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:start-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:end-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-gradient-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:start-intensity">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:end-intensity">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-gradient-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:angle">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="common-draw-gradient-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:border">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="svg-linearGradient">
+    <element name="svg:linearGradient">
+        <ref name="common-svg-gradient-attlist"/>
+        <optional>
+            <attribute name="svg:x1" a:defaultValue="0%">
+                <choice>
+                    <ref name="coordinate"/>
+                    <ref name="percent"/>
+                </choice>                
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="svg:y1" a:defaultValue="0%">
+                <choice>
+                    <ref name="coordinate"/>
+                    <ref name="percent"/>
+                </choice>                
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="svg:x2" a:defaultValue="100%">
+                <choice>
+                    <ref name="coordinate"/>
+                    <ref name="percent"/>
+                </choice>                
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="svg:y2" a:defaultValue="100%">
+                <choice>
+                    <ref name="coordinate"/>
+                    <ref name="percent"/>
+                </choice>                
+            </attribute>
+        </optional>
+        <zeroOrMore>
+            <ref name="svg-stop"/>
+        </zeroOrMore>
+    </element>
+</define>
+
+<define name="svg-radialGradient">
+    <element name="svg:radialGradient">
+        <ref name="common-svg-gradient-attlist"/>
+        <optional>
+            <attribute name="svg:cx" a:defaultValue="50%">
+                <choice>
+                    <ref name="coordinate"/>
+                    <ref name="percent"/>
+                </choice>                
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="svg:cy" a:defaultValue="50%">
+                <choice>
+                    <ref name="coordinate"/>
+                    <ref name="percent"/>
+                </choice>                
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="svg:r" a:defaultValue="50%">
+                <choice>
+                    <ref name="coordinate"/>
+                    <ref name="percent"/>
+                </choice>                
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="svg:fx">
+                <choice>
+                    <ref name="coordinate"/>
+                    <ref name="percent"/>
+                </choice>                
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="svg:fy">
+                <choice>
+                    <ref name="coordinate"/>
+                    <ref name="percent"/>
+                </choice>                
+            </attribute>
+        </optional>
+        <zeroOrMore>
+            <ref name="svg-stop"/>
+        </zeroOrMore>
+    </element>
+</define>
+
+<define name="svg-stop">
+    <element name="svg:stop">
+        <attribute name="svg:offset">
+            <choice>
+                <ref name="double"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+        <optional>
+            <attribute name="svg:stop-color">
+                <ref name="color"/>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="svg:stop-opacity">
+                <ref name="double"/>
+            </attribute>
+        </optional>
+    </element>
+</define>
+
+<define name="common-svg-gradient-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:gradientUnits" a:defaultValue="objectBoundingBox">
+            <value>objectBoundingBox</value>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:gradientTransform">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:spreadMethod" a:defaultValue="pad">
+            <choice>
+                <value>pad</value>
+                <value>reflect</value>
+                <value>repeat</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="common-svg-gradient-attlist" combine="interleave">
+    <attribute name="draw:name">
+        <ref name="styleName"/>
+    </attribute>
+</define>
+<define name="common-svg-gradient-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:display-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-hatch">
+    <element name="draw:hatch">
+        <ref name="draw-hatch-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="draw-hatch-attlist" combine="interleave">
+    <attribute name="draw:name">
+        <ref name="styleName"/>
+    </attribute>
+</define>
+<define name="draw-hatch-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:display-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-hatch-attlist" combine="interleave">
+    <attribute name="draw:style">
+        <choice>
+            <value>single</value>
+            <value>double</value>
+            <value>triple</value>
+        </choice>
+    </attribute>
+</define>
+<define name="draw-hatch-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-hatch-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:distance">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-hatch-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:rotation">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-fill-image">
+    <element name="draw:fill-image">
+        <ref name="draw-fill-image-attlist"/>
+        <attribute name="xlink:href">
+            <ref name="anyURI"/>
+        </attribute>
+        <optional>
+            <attribute name="xlink:type" a:defaultValue="simple">
+                <choice>
+                    <value>simple</value>
+                </choice>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:show" a:defaultValue="embed">
+                <choice>
+                    <value>embed</value>
+                </choice>
+            </attribute>
+        </optional>
+        <optional>
+            <attribute name="xlink:actuate" a:defaultValue="onLoad">
+                <choice>
+                    <value>onLoad</value>
+                </choice>
+            </attribute>
+        </optional>
+        <empty/>
+    </element>
+</define>
+<define name="draw-fill-image-attlist" combine="interleave">
+    <attribute name="draw:name">
+        <ref name="styleName"/>
+    </attribute>
+</define>
+<define name="draw-fill-image-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:display-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-fill-image-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:width">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:height">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-opacity">
+    <element name="draw:opacity">
+        <ref name="common-draw-gradient-attlist"/>
+        <ref name="draw-opacity-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="draw-opacity-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:start">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:end">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-marker">
+    <element name="draw:marker">
+        <ref name="draw-marker-attlist"/>
+        <ref name="common-draw-viewbox-attlist"/>
+        <ref name="common-draw-path-data-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="draw-marker-attlist" combine="interleave">
+    <attribute name="draw:name">
+        <ref name="styleName"/>
+    </attribute>
+</define>
+<define name="draw-marker-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:display-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-stroke-dash">
+    <element name="draw:stroke-dash">
+        <ref name="draw-stroke-dash-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="draw-stroke-dash-attlist" combine="interleave">
+    <attribute name="draw:name">
+        <ref name="styleName"/>
+    </attribute>
+</define>
+<define name="draw-stroke-dash-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:display-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-stroke-dash-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:style">
+            <choice>
+                <value>rect</value>
+                <value>round</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-stroke-dash-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:dots1">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:dots1-length">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:dots2">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:dots2-length">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="draw-stroke-dash-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:distance">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-presentation-page-layout">
+    <element name="style:presentation-page-layout">
+        <attribute name="style:name">
+            <ref name="styleName"/>
+        </attribute>
+        <optional>
+            <attribute name="style:display-name">
+                <ref name="string"/>
+            </attribute>
+        </optional>
+        <zeroOrMore>
+            <ref name="presentation-placeholder"/>
+        </zeroOrMore>
+    </element>
+</define>
+<define name="presentation-placeholder">
+    <element name="presentation:placeholder">
+        <attribute name="presentation:object">
+            <ref name="presentation-classes"/>
+        </attribute>
+        <attribute name="svg:x">
+            <choice>
+                <ref name="coordinate"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+        <attribute name="svg:y">
+            <choice>
+                <ref name="coordinate"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+        <attribute name="svg:width">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+        <attribute name="svg:height">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+        <empty/>
+    </element>
+</define>
+<define name="style-style-content" combine="choice">
+    <group>
+        <attribute name="style:family">
+            <value>chart</value>
+        </attribute>
+        <optional>
+            <ref name="style-chart-properties"/>
+        </optional>
+        <optional>
+            <ref name="style-graphic-properties"/>
+        </optional>
+        <optional>
+            <ref name="style-paragraph-properties"/>
+        </optional>
+        <optional>
+            <ref name="style-text-properties"/>
+        </optional>
+    </group>
+</define>
+<define name="style-properties-content">
+    <ref name="anyAttListOrElements"/>
+</define>
+<define name="style-page-layout-properties">
+    <element name="style:page-layout-properties">
+        <ref name="style-page-layout-properties-content"/>
+    </element>
+</define>
+
+<define name="style-page-layout-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-page-layout-properties-content-strict">
+    <ref name="style-page-layout-properties-attlist"/>
+    <ref name="style-page-layout-properties-elements"/>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:page-width">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:page-height">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <ref name="common-num-format-attlist"/>
+    </optional>
+    <ref name="common-num-format-prefix-suffix-attlist"/>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:paper-tray-name">
+            <choice>
+                <value>default</value>
+                <ref name="string"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:print-orientation">
+            <choice>
+                <value>portrait</value>
+                <value>landscape</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <ref name="common-horizontal-margin-attlist"/>
+    <ref name="common-vertical-margin-attlist"/>
+    <ref name="common-margin-attlist"/>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <ref name="common-border-attlist"/>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <ref name="common-border-line-width-attlist"/>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <ref name="common-padding-attlist"/>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <ref name="common-shadow-attlist"/>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <ref name="common-background-color-attlist"/>
+</define>
+<define name="style-page-layout-properties-elements" combine="interleave">
+    <ref name="style-background-image"/>
+</define>
+<define name="style-page-layout-properties-elements" combine="interleave">
+    <ref name="style-columns"/>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:register-truth-ref-style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:print">
+            <list>
+                <zeroOrMore>
+                    <choice>
+                        <value>headers</value>
+                        <value>grid</value>
+                        <value>annotations</value>
+                        <value>objects</value>
+                        <value>charts</value>
+                        <value>drawings</value>
+                        <value>formulas</value>
+                        <value>zero-values</value>
+                    </choice>
+                </zeroOrMore>
+            </list>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:print-page-order">
+            <choice>
+                <value>ttb</value>
+                <value>ltr</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:first-page-number">
+            <choice>
+                <ref name="positiveInteger"/>
+                <value>continue</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:scale-to">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:scale-to-pages">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:table-centering">
+            <choice>
+                <value>horizontal</value>
+                <value>vertical</value>
+                <value>both</value>
+                <value>none</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:footnote-max-height">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <ref name="common-writing-mode-attlist"/>
+</define>
+<define name="style-page-layout-properties-elements" combine="interleave">
+    <ref name="style-footnote-sep"/>
+</define>
+
+<define name="style-footnote-sep">
+    <optional>
+        <element name="style:footnote-sep">
+            <ref name="style-footnote-sep-attlist"/>
+            <empty/>
+        </element>
+    </optional>
+</define>
+<define name="style-footnote-sep-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:width">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:rel-width">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:line-style">
+            <ref name="lineStyle"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:adjustment" a:defaultValue="left">
+            <choice>
+                <value>left</value>
+                <value>center</value>
+                <value>right</value>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:distance-before-sep">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:distance-after-sep">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:layout-grid-mode">
+            <choice>
+                <value>none</value>
+                <value>line</value>
+                <value>both</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:layout-grid-base-height">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:layout-grid-ruby-height">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:layout-grid-lines">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:layout-grid-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:layout-grid-ruby-below">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:layout-grid-print">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-page-layout-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:layout-grid-display">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-header-footer-properties">
+    <element name="style:header-footer-properties">
+        <ref name="style-header-footer-properties-content"/>
+    </element>
+</define>
+
+<define name="style-header-footer-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-header-footer-properties-content-strict">
+        <ref name="style-header-footer-properties-attlist"/>
+        <ref name="style-header-footer-properties-elements"/>
+</define>
+<define name="style-header-footer-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:height">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:min-height">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-header-footer-properties-attlist" combine="interleave">
+    <ref name="common-horizontal-margin-attlist"/>
+    <ref name="common-vertical-margin-attlist"/>
+    <ref name="common-margin-attlist"/>
+</define>
+<define name="style-header-footer-properties-attlist" combine="interleave">
+    <ref name="common-border-attlist"/>
+</define>
+<define name="style-header-footer-properties-attlist" combine="interleave">
+    <ref name="common-border-line-width-attlist"/>
+</define>
+<define name="style-header-footer-properties-attlist" combine="interleave">
+    <ref name="common-padding-attlist"/>
+</define>
+<define name="style-header-footer-properties-attlist" combine="interleave">
+    <ref name="common-background-color-attlist"/>
+</define>
+<define name="style-header-footer-properties-elements" combine="interleave">
+    <ref name="style-background-image"/>
+</define>
+<define name="style-header-footer-properties-attlist" combine="interleave">
+    <ref name="common-shadow-attlist"/>
+</define>
+<define name="style-header-footer-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:dynamic-spacing">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties">
+    <element name="style:text-properties">
+        <ref name="style-text-properties-content"/>
+    </element>
+</define>
+
+<define name="style-text-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-text-properties-content-strict">
+    <ref name="style-text-properties-attlist"/>
+    <ref name="style-text-properties-elements"/>
+</define>
+
+<define name="style-text-properties-elements">
+    <empty/>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:font-variant">
+            <ref name="fontVariant"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="fontVariant">
+    <choice>
+        <value>normal</value>
+        <value>small-caps</value>
+    </choice>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:text-transform">
+            <choice>
+                <value>none</value>
+                <value>lowercase</value>
+                <value>uppercase</value>
+                <value>capitalize</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+            <attribute name="fo:color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:use-window-font-color">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-outline">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-line-through-type">
+            <ref name="lineType"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-line-through-style">
+            <ref name="lineStyle"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-line-through-width">
+            <ref name="lineWidth"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-line-through-color">
+            <choice>
+                <value>font-color</value>
+                <ref name="color"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-line-through-text">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-line-through-text-style">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-position">
+            <list>
+                <choice>
+                    <ref name="percent"/>
+                    <value>super</value>
+                    <value>sub</value>
+                </choice>
+                <optional>
+                    <ref name="percent"/>
+                </optional>
+            </list>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:font-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-name-asian">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-name-complex">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:font-family">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-family-asian">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-family-complex">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:font-family-generic">
+            <ref name="fontFamilyGeneric"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-family-generic-asian">
+            <ref name="fontFamilyGeneric"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-family-generic-complex">
+            <ref name="fontFamilyGeneric"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="fontFamilyGeneric">
+    <choice>
+        <value>roman</value>
+        <value>swiss</value>
+        <value>modern</value>
+        <value>decorative</value>
+        <value>script</value>
+        <value>system</value>
+    </choice>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:font-style-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-style-name-asian">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-style-name-complex">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:font-pitch">
+            <ref name="fontPitch"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-pitch-asian">
+            <ref name="fontPitch"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-pitch-complex">
+            <ref name="fontPitch"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="fontPitch">
+    <choice>
+        <value>fixed</value>
+        <value>variable</value>
+    </choice>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:font-charset">
+            <ref name="textEncoding"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-charset-asian">
+            <ref name="textEncoding"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-charset-complex">
+            <ref name="textEncoding"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="textEncoding">
+    <data type="string">
+        <param name="pattern">[A-Za-z][A-Za-z0-9._\-]*</param>
+    </data>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:font-size">
+            <choice>
+                <ref name="positiveLength"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-size-asian">
+            <choice>
+                <ref name="positiveLength"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-size-complex">
+            <choice>
+                <ref name="positiveLength"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:font-size-rel">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-size-rel-asian">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-size-rel-complex">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:script-type">
+            <choice>
+                <value>latin</value>
+                <value>asian</value>
+                <value>complex</value>
+                <value>ignore</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:letter-spacing">
+            <choice>
+                <ref name="length"/>
+                <value>normal</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:language">
+            <ref name="languageCode"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:language-asian">
+            <ref name="languageCode"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:language-complex">
+            <ref name="languageCode"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:country">
+            <ref name="countryCode"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:country-asian">
+            <ref name="countryCode"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:country-complex">
+            <ref name="countryCode"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:font-style">
+            <ref name="fontStyle"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-style-asian">
+            <ref name="fontStyle"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-style-complex">
+            <ref name="fontStyle"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="fontStyle">
+    <choice>
+        <value>normal</value>
+        <value>italic</value>
+        <value>oblique</value>
+    </choice>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:font-relief">
+            <choice>
+            <value>none</value>
+                <value>embossed</value>
+                <value>engraved</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:text-shadow">
+            <ref name="shadowType"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="shadowType">
+    <choice>
+        <value>none</value>
+        <!-- The following string must match an XSL shadow decl -->
+        <ref name="string"/>
+    </choice>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-underline-type">
+            <ref name="lineType"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="lineType">
+    <choice>
+        <value>none</value>
+        <value>single</value>
+        <value>double</value>
+    </choice>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-underline-style">
+            <ref name="lineStyle"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="lineStyle">
+    <choice>
+        <value>none</value>
+        <value>solid</value>
+        <value>dotted</value>
+        <value>dash</value>
+        <value>long-dash</value>
+        <value>dot-dash</value>
+        <value>dot-dot-dash</value>
+        <value>wave</value>
+    </choice>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-underline-width">
+            <ref name="lineWidth"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="lineWidth">
+    <choice>
+        <value>auto</value>
+        <value>normal</value>
+        <value>bold</value>
+        <value>thin</value>
+        <value>dash</value>
+        <value>medium</value>
+        <value>thick</value>
+        <ref name="positiveInteger"/>
+        <ref name="percent"/>
+        <ref name="positiveLength"/>
+    </choice>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-underline-color">
+            <choice>
+                <value>font-color</value>
+                <ref name="color"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:font-weight">
+            <ref name="fontWeight"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-weight-asian">
+            <ref name="fontWeight"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:font-weight-complex">
+            <ref name="fontWeight"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="fontWeight">
+    <choice>
+        <value>normal</value>
+        <value>bold</value>
+        <value>100</value>
+        <value>200</value>
+        <value>300</value>
+        <value>400</value>
+        <value>500</value>
+        <value>600</value>
+        <value>700</value>
+        <value>800</value>
+        <value>900</value>
+    </choice>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-underline-mode">
+            <ref name="lineMode"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="lineMode">
+    <choice>
+        <value>continuous</value>
+        <value>skip-white-space</value>
+    </choice>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-line-through-mode">
+            <ref name="lineMode"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:letter-kerning">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-blinking">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <ref name="common-background-color-attlist"/>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-combine">
+            <choice>
+                <value>none</value>
+                <value>letters</value>
+                <value>lines</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-combine-start-char">
+            <ref name="character"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:text-combine-end-char">
+            <ref name="character"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-emphasize">
+            <choice>
+                <value>none</value>
+                <list>
+                    <choice>
+                        <value>none</value>
+                        <value>accent</value>
+                        <value>dot</value>
+                        <value>circle</value>
+                        <value>disc</value>
+                    </choice>
+                    <choice>
+                        <value>above</value>
+                        <value>below</value>
+                    </choice>
+                </list>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-scale">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-rotation-angle">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-rotation-scale">
+            <choice>
+                <value>fixed</value>
+                <value>line-height</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:hyphenate">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:hyphenation-remain-char-count">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:hyphenation-push-char-count">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-text-properties-attlist" combine="interleave">
+    <choice>
+        <attribute name="text:display">
+            <value>true</value>
+        </attribute>
+        <attribute name="text:display">
+            <value>none</value>
+        </attribute>
+        <group>
+            <attribute name="text:display">
+                <value>condition</value>
+            </attribute>
+            <attribute name="text:condition">
+                <value>none</value>
+            </attribute>
+        </group>
+        <empty/>
+    </choice>
+</define>
+<define name="style-paragraph-properties">
+    <element name="style:paragraph-properties">
+        <ref name="style-paragraph-properties-content"/>
+    </element>
+</define>
+
+<define name="style-paragraph-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-paragraph-properties-content-strict">
+    <ref name="style-paragraph-properties-attlist"/>
+    <ref name="style-paragraph-properties-elements"/>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:line-height">
+            <choice>
+                <value>normal</value>
+                <ref name="nonNegativeLength"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:line-height-at-least">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:line-spacing">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:font-independent-line-spacing">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <ref name="common-text-align"/>
+</define>
+
+<define name="common-text-align">
+    <optional>
+        <attribute name="fo:text-align">
+            <choice>
+                <value>start</value>
+                <value>end</value>
+                <value>left</value>
+                <value>right</value>
+                <value>center</value>
+                <value>justify</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:text-align-last">
+            <choice>
+                <value>start</value>
+                <value>center</value>
+                <value>justify</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:justify-single-word">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:keep-together">
+            <choice>
+                <value>auto</value>
+                <value>always</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:widows">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:orphans">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-elements" combine="interleave">
+    <ref name="style-tab-stops"/>
+</define>
+
+<define name="style-tab-stops">
+    <optional>
+        <element name="style:tab-stops">
+            <zeroOrMore>
+                <ref name="style-tab-stop"/>
+            </zeroOrMore>
+        </element>
+    </optional>
+</define>
+
+<define name="style-tab-stop">
+    <element name="style:tab-stop">
+        <ref name="style-tab-stop-attlist"/>
+        <empty/>
+    </element>
+</define>
+<define name="style-tab-stop-attlist" combine="interleave">
+    <attribute name="style:position">
+        <ref name="nonNegativeLength"/>
+    </attribute>
+</define>
+<define name="style-tab-stop-attlist" combine="interleave">
+    <choice>
+        <optional>
+            <attribute name="style:type" a:defaultValue="left">
+                <choice>
+                    <value>left</value>
+                    <value>center</value>
+                    <value>right</value>
+                </choice>
+            </attribute>
+        </optional>
+        <group>
+            <attribute name="style:type">
+                <value>char</value>
+            </attribute>
+            <ref name="style-tab-stop-char-attlist"/>
+        </group>
+    </choice>
+</define>
+<define name="style-tab-stop-char-attlist" combine="interleave">
+    <attribute name="style:char">
+        <ref name="character"/>
+    </attribute>
+</define>
+<define name="style-tab-stop-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:leader-type">
+            <ref name="lineType"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-tab-stop-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:leader-style">
+            <ref name="lineStyle"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-tab-stop-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:leader-width">
+            <ref name="lineWidth"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-tab-stop-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:leader-color">
+            <choice>
+                <value>font-color</value>
+                <ref name="color"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-tab-stop-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:leader-text" a:defaultValue=" ">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-tab-stop-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:leader-text-style">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:tab-stop-distance">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:hyphenation-keep">
+            <choice>
+                <value>auto</value>
+                <value>page</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:hyphenation-ladder-count">
+            <choice>
+                <value>no-limit</value>
+                <ref name="positiveInteger"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-elements" combine="interleave">
+    <ref name="style-drop-cap"/>
+</define>
+
+<define name="style-drop-cap">
+    <optional>
+        <element name="style:drop-cap">
+            <ref name="style-drop-cap-attlist"/>
+            <empty/>
+        </element>
+    </optional>
+</define>
+<define name="style-drop-cap-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:length" a:defaultValue="1">
+            <choice>
+                <value>word</value>
+                <ref name="positiveInteger"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drop-cap-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:lines" a:defaultValue="1">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drop-cap-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:distance" a:defaultValue="0cm">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drop-cap-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:style-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+        <optional>
+            <attribute name="style:register-true">
+                <ref name="boolean"/>
+            </attribute>
+        </optional>
+    </define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <ref name="common-horizontal-margin-attlist"/>
+</define>
+
+<define name="common-horizontal-margin-attlist">
+    <optional>
+        <attribute name="fo:margin-left">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:margin-right">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:text-indent">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:auto-text-indent">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <ref name="common-vertical-margin-attlist"/>
+</define>
+
+<define name="common-vertical-margin-attlist">
+    <optional>
+        <attribute name="fo:margin-top">
+            <choice>
+                <ref name="nonNegativeLength"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:margin-bottom">
+            <choice>
+                <ref name="nonNegativeLength"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <ref name="common-margin-attlist"/>
+</define>
+
+<define name="common-margin-attlist">
+    <optional>
+        <attribute name="fo:margin">
+            <choice>
+                <ref name="nonNegativeLength"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <ref name="common-break-attlist"/>
+</define>
+
+<define name="common-break-attlist">
+    <optional>
+        <attribute name="fo:break-before">
+            <choice>
+                <value>auto</value>
+                <value>column</value>
+                <value>page</value>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:break-after">
+            <choice>
+                <value>auto</value>
+                <value>column</value>
+                <value>page</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <ref name="common-background-color-attlist"/>
+</define>
+
+<define name="common-background-color-attlist">
+    <optional>
+        <attribute name="fo:background-color">
+            <choice>
+                <value>transparent</value>
+                <ref name="color"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-elements" combine="interleave">
+    <ref name="style-background-image"/>
+</define>
+
+<define name="style-background-image">
+    <optional>
+        <element name="style:background-image">
+            <ref name="style-background-image-attlist"/>
+            <choice>
+                <ref name="common-draw-data-attlist"/>
+                <ref name="office-binary-data"/>
+                <empty/>
+            </choice>
+        </element>
+    </optional>
+</define>
+<define name="style-background-image-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:repeat" a:defaultValue="repeat">
+            <choice>
+                <value>no-repeat</value>
+                <value>repeat</value>
+                <value>stretch</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-background-image-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:position" a:defaultValue="center">
+            <choice>
+                <value>left</value>
+                <value>center</value>
+                <value>right</value>
+                <value>top</value>
+                <value>bottom</value>
+                <list>
+                    <ref name="horiBackPos"/>
+                    <ref name="vertBackPos"/>
+                </list>
+                <list>
+                    <ref name="vertBackPos"/>
+                    <ref name="horiBackPos"/>
+                </list>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+
+<define name="horiBackPos">
+    <choice>
+        <value>left</value>
+        <value>center</value>
+        <value>right</value>
+    </choice>
+</define>
+<define name="vertBackPos">
+    <choice>
+        <value>top</value>
+        <value>center</value>
+        <value>bottom</value>
+    </choice>
+</define>
+<define name="style-background-image-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:filter-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-background-image-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:opacity">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <ref name="common-border-attlist"/>
+</define>
+
+<define name="common-border-attlist">
+    <optional>
+        <attribute name="fo:border">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:border-top">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:border-bottom">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:border-left">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:border-right">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <ref name="common-border-line-width-attlist"/>
+</define>
+
+<define name="common-border-line-width-attlist">
+    <optional>
+        <attribute name="style:border-line-width">
+            <ref name="borderWidths"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:border-line-width-top">
+            <ref name="borderWidths"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:border-line-width-bottom">
+            <ref name="borderWidths"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:border-line-width-left">
+            <ref name="borderWidths"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:border-line-width-right">
+            <ref name="borderWidths"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="borderWidths">
+    <list>
+        <ref name="positiveLength"/>
+        <ref name="positiveLength"/>
+        <ref name="positiveLength"/>
+    </list>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <ref name="common-padding-attlist"/>
+</define>
+
+<define name="common-padding-attlist">
+    <optional>
+        <attribute name="fo:padding">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:padding-top">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:padding-bottom">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:padding-left">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:padding-right">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <ref name="common-shadow-attlist"/>
+</define>
+
+<define name="common-shadow-attlist">
+    <optional>
+        <attribute name="style:shadow">
+            <ref name="shadowType"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <ref name="common-keep-with-next-attlist"/>
+</define>
+
+<define name="common-keep-with-next-attlist">
+    <optional>
+        <attribute name="fo:keep-with-next">
+            <choice>
+                <value>auto</value>
+                <value>always</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:number-lines" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:line-number">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-autospace">
+            <choice>
+                <value>none</value>
+                <value>ideograph-alpha</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:punctuation-wrap">
+            <choice>
+                <value>simple</value>
+                <value>hanging</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:line-break">
+            <choice>
+                <value>normal</value>
+                <value>strict</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:vertical-align" a:defaultValue="auto">
+            <choice>
+                <value>top</value>
+                <value>middle</value>
+                <value>bottom</value>
+                <value>auto</value>
+                <value>baseline</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <ref name="common-writing-mode-attlist"/>
+</define>
+
+<define name="common-writing-mode-attlist">
+    <optional>
+        <attribute name="style:writing-mode">
+            <choice>
+                <value>lr-tb</value>
+                <value>rl-tb</value>
+                <value>tb-rl</value>
+                <value>tb-lr</value>
+                <value>lr</value>
+                <value>rl</value>
+                <value>tb</value>
+                <value>page</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:writing-mode-automatic">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:snap-to-layout-grid">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <ref name="common-page-number-attlist"/>
+</define>
+
+<define name="common-page-number-attlist">
+    <optional>
+        <attribute name="style:page-number">
+            <choice>                <ref name="positiveInteger"/>                <value>auto</value>            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-paragraph-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:background-transparency">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-ruby-properties">
+    <element name="style:ruby-properties">
+        <ref name="style-ruby-properties-content"/>
+    </element>
+</define>
+
+<define name="style-ruby-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-ruby-properties-content-strict">
+    <ref name="style-ruby-properties-attlist"/>
+    <ref name="style-ruby-properties-elements"/>
+</define>
+
+<define name="style-ruby-properties-elements">
+    <empty/>
+</define>
+<define name="style-ruby-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:ruby-position">
+            <choice>
+                <value>above</value>
+                <value>below</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-ruby-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:ruby-align">
+            <choice>
+                <value>left</value>
+                <value>center</value>
+                <value>right</value>
+                <value>distribute-letter</value>
+                <value>distribute-space</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-section-properties">
+    <element name="style:section-properties">
+        <ref name="style-section-properties-content"/>
+    </element>
+</define>
+
+<define name="style-section-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-section-properties-content-strict">
+    <ref name="style-section-properties-attlist"/>
+    <ref name="style-section-properties-elements"/>
+</define>
+<define name="style-section-properties-attlist" combine="interleave">
+    <ref name="common-background-color-attlist"/>
+</define>
+<define name="style-section-properties-elements" combine="interleave">
+    <ref name="style-background-image"/>
+</define>
+<define name="style-section-properties-attlist" combine="interleave">
+    <ref name="common-horizontal-margin-attlist"/>
+</define>
+<define name="style-section-properties-elements" combine="interleave">
+    <ref name="style-columns"/>
+</define>
+
+<define name="style-columns">
+    <optional>
+        <element name="style:columns">
+            <ref name="style-columns-attlist"/>
+            <optional>
+                <ref name="style-column-sep"/>
+            </optional>
+            <zeroOrMore>
+                <ref name="style-column"/>
+            </zeroOrMore>
+        </element>
+    </optional>
+</define>
+<define name="style-columns-attlist" combine="interleave">
+    <attribute name="fo:column-count">
+        <ref name="positiveInteger"/>
+    </attribute>
+</define>
+<define name="style-columns-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:column-gap">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-column">
+    <element name="style:column">
+        <ref name="style-column-attlist"/>
+    </element>
+</define>
+<define name="style-column-attlist" combine="interleave">
+    <attribute name="style:rel-width">
+        <ref name="relativeLength"/>
+    </attribute>
+</define>
+<define name="style-column-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:start-indent" a:defaultValue="0cm">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-column-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:end-indent" a:defaultValue="0cm">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-column-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:space-before" a:defaultValue="0cm">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-column-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:space-after" a:defaultValue="0cm">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-column-sep">
+    <element name="style:column-sep">
+        <ref name="style-column-sep-attlist"/>
+    </element>
+</define>
+<define name="style-column-sep-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:style" a:defaultValue="solid">
+            <choice>
+                <value>none</value>
+                <value>solid</value>
+                <value>dotted</value>
+                <value>dashed</value>
+                <value>dot-dashed</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-column-sep-attlist" combine="interleave">
+    <attribute name="style:width">
+        <ref name="length"/>
+    </attribute>
+</define>
+<define name="style-column-sep-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:height" a:defaultValue="100%">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-column-sep-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:vertical-align" a:defaultValue="top">
+            <choice>
+                <value>top</value>
+                <value>middle</value>
+                <value>bottom</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-column-sep-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:color" a:defaultValue="#000000">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-section-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:protect" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-section-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:dont-balance-text-columns">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-section-properties-attlist" combine="interleave">
+    <ref name="common-writing-mode-attlist"/>
+</define>
+<define name="style-section-properties-elements" combine="interleave">
+    <zeroOrMore>
+        <ref name="text-notes-configuration"/>
+    </zeroOrMore>
+</define>
+<define name="style-table-properties">
+    <element name="style:table-properties">
+        <ref name="style-table-properties-content"/>
+    </element>
+</define>
+
+<define name="style-table-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-table-properties-content-strict">
+    <ref name="style-table-properties-attlist"/>
+    <ref name="style-table-properties-elements"/>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:width">
+            <ref name="positiveLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:rel-width">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:align">
+            <choice>
+                <value>left</value>
+                <value>center</value>
+                <value>right</value>
+                <value>margins</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <ref name="common-horizontal-margin-attlist"/>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <ref name="common-vertical-margin-attlist"/>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <ref name="common-margin-attlist"/>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <ref name="common-page-number-attlist"/>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <ref name="common-break-attlist"/>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <ref name="common-background-color-attlist"/>
+</define>
+<define name="style-table-properties-elements" combine="interleave">
+    <ref name="style-background-image"/>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <ref name="common-shadow-attlist"/>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <ref name="common-keep-with-next-attlist"/>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:may-break-between-rows">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:border-model">
+            <choice>
+                <value>collapsing</value>
+                <value>separating</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <ref name="common-writing-mode-attlist"/>
+</define>
+<define name="style-table-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="table:display">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-column-properties">
+    <element name="style:table-column-properties">
+        <ref name="style-table-column-properties-content"/>
+    </element>
+</define>
+
+<define name="style-table-column-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-table-column-properties-content-strict">
+    <ref name="style-table-column-properties-attlist"/>
+    <ref name="style-table-column-properties-elements"/>
+</define>
+
+<define name="style-table-column-properties-elements">
+    <empty/>
+</define>
+<define name="style-table-column-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:column-width">
+            <ref name="positiveLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:rel-column-width">
+            <ref name="relativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-column-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:use-optimal-column-width">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-column-properties-attlist" combine="interleave">
+    <ref name="common-break-attlist"/>
+</define>
+<define name="style-table-row-properties">
+    <element name="style:table-row-properties">
+        <ref name="style-table-row-properties-content"/>
+    </element>
+</define>
+
+<define name="style-table-row-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-table-row-properties-content-strict">
+    <ref name="style-table-row-properties-attlist"/>
+    <ref name="style-table-row-properties-elements"/>
+</define>
+<define name="style-table-row-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:row-height">
+            <ref name="positiveLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:min-row-height">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-row-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:use-optimal-row-height">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-row-properties-attlist" combine="interleave">
+    <ref name="common-background-color-attlist"/>
+</define>
+<define name="style-table-row-properties-elements" combine="interleave">
+    <ref name="style-background-image"/>
+</define>
+<define name="style-table-row-properties-attlist" combine="interleave">
+    <ref name="common-break-attlist"/>
+</define>
+<define name="style-table-row-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:keep-together">
+            <choice>
+                <value>auto</value>
+                <value>always</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-cell-properties">
+    <element name="style:table-cell-properties">
+        <ref name="style-table-cell-properties-content"/>
+    </element>
+</define>
+
+<define name="style-table-cell-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-table-cell-properties-content-strict">
+    <ref name="style-table-cell-properties-attlist"/>
+    <ref name="style-table-cell-properties-elements"/>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:vertical-align">
+            <choice>
+                <value>top</value>
+                <value>middle</value>
+                <value>bottom</value>
+                <value>automatic</value>
+            </choice>
+            </attribute>
+    </optional>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:text-align-source">
+            <choice>
+                <value>fix</value>
+                <value>value-type</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <ref name="common-style-direction-attlist"/>
+</define>
+
+<define name="common-style-direction-attlist">
+    <optional>
+        <attribute name="style:direction">
+            <choice>
+                <value>ltr</value>
+                <value>ttb</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:glyph-orientation-vertical">
+            <choice>
+                <value>auto</value>
+                <value>0</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <ref name="common-shadow-attlist"/>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <ref name="common-background-color-attlist"/>
+</define>
+<define name="style-table-cell-properties-elements" combine="interleave">
+    <ref name="style-background-image"/>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <ref name="common-border-attlist"/>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:diagonal-tl-br">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:diagonal-tl-br-widths">
+            <ref name="borderWidths"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:diagonal-bl-tr">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="style:diagonal-bl-tr-widths">
+            <ref name="borderWidths"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <ref name="common-border-line-width-attlist"/>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <ref name="common-padding-attlist"/>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:wrap-option">
+            <choice>
+                <value>no-wrap</value>
+                <value>wrap</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <ref name="common-rotation-angle-attlist"/>
+</define>
+
+<define name="common-rotation-angle-attlist">
+    <optional>
+        <attribute name="style:rotation-angle">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:rotation-align">
+            <choice>
+                <value>none</value>
+                <value>bottom</value>
+                <value>top</value>
+                <value>center</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:cell-protect">
+            <choice>
+                <value>none</value>
+                <value>hidden-and-protected</value>
+                <list>
+                    <oneOrMore>
+                        <choice>
+                            <value>protected</value>
+                            <value>formula-hidden</value>
+                        </choice>
+                    </oneOrMore>
+                </list>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:print-content">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:decimal-places">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:repeat-content">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-table-cell-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:shrink-to-fit">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-list-level-properties">
+    <element name="style:list-level-properties">
+        <ref name="style-list-level-properties-content"/>
+    </element>
+</define>
+
+<define name="style-list-level-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-list-level-properties-content-strict">
+    <ref name="style-list-level-properties-attlist"/>
+    <ref name="style-list-level-properties-elements"/>
+</define>
+
+<define name="style-list-level-properties-elements">
+    <empty/>
+</define>
+<define name="style-list-level-properties-attlist" combine="interleave">
+    <ref name="common-text-align"/>
+</define>
+<define name="style-list-level-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:space-before">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-list-level-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:min-label-width">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-list-level-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:min-label-distance">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-list-level-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:font-name">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-list-level-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:width">
+            <ref name="positiveLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:height">
+            <ref name="positiveLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-list-level-properties-attlist" combine="interleave">
+    <ref name="common-vertical-rel-attlist"/>
+    <ref name="common-vertical-pos-attlist"/>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:stroke">
+            <choice>
+                <value>none</value>
+                <value>dash</value>
+                <value>solid</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:stroke-dash">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:stroke-dash-names">
+            <ref name="styleNameRefs"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:stroke-width">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:stroke-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:marker-start">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:marker-end">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:marker-start-width">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:marker-end-width">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:marker-start-center">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:marker-end-center">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:stroke-opacity">
+            <choice>
+                <data type="double">
+                    <param name="minInclusive">0</param>
+                    <param name="maxInclusive">1</param>
+                </data>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:stroke-linejoin">
+            <choice>
+                <value>miter</value>
+                <value>round</value>
+                <value>bevel</value>
+                <value>middle</value>
+                <value>none</value>
+                <value>inherit</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:fill">
+            <choice>
+                <value>none</value>
+                <value>solid</value>
+                <value>bitmap</value>
+                <value>gradient</value>
+                <value>hatch</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:fill-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:secondary-fill-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:fill-gradient-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:gradient-step-count">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:fill-hatch-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:fill-hatch-solid">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:fill-image-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:repeat">
+            <choice>
+                <value>no-repeat</value>
+                <value>repeat</value>
+                <value>stretch</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:fill-image-width">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:fill-image-height">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:fill-image-ref-point-x">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:fill-image-ref-point-y">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:fill-image-ref-point">
+            <choice>
+                <value>top-left</value>
+                <value>top</value>
+                <value>top-right</value>
+                <value>left</value>
+                <value>center</value>
+                <value>right</value>
+                <value>bottom-left</value>
+                <value>bottom</value>
+                <value>bottom-right</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:tile-repeat-offset"/>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:opacity">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:opacity-name">
+            <ref name="styleNameRef"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-fill-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="svg:fill-rule">
+            <choice>
+                <value>nonzero</value>
+                <value>evenodd</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:symbol-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:animation">
+            <choice>
+                <value>none</value>
+                <value>scroll</value>
+                <value>alternate</value>
+                <value>slide</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:animation-direction">
+            <choice>
+                <value>left</value>
+                <value>right</value>
+                <value>up</value>
+                <value>down</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:animation-start-inside">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:animation-stop-inside">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:animation-repeat">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:animation-delay">
+            <ref name="duration"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="text:animation-steps">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:auto-grow-width">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:auto-grow-height">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:fit-to-size">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:fit-to-contour">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:textarea-vertical-align">
+            <choice>
+                <value>top</value>
+                <value>middle</value>
+                <value>bottom</value>
+                <value>justify</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:textarea-horizontal-align">
+            <choice>
+                <value>left</value>
+                <value>center</value>
+                <value>right</value>
+                <value>justify</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:wrap-option">
+            <choice>
+                <value>no-wrap</value>
+                <value>wrap</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-elements" combine="interleave">
+    <optional>
+        <ref name="text-list-style"/>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:color-mode">
+            <choice>
+                <value>greyscale</value>
+                <value>mono</value>
+                <value>watermark</value>
+                <value>standard</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:color-inversion">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:luminance">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:contrast">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:gamma">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:red">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:green">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:blue">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:image-opacity">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:shadow">
+            <choice>
+                <value>visible</value>
+                <value>hidden</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:shadow-offset-x">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:shadow-offset-y">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:shadow-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:shadow-opacity">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:start-line-spacing-horizontal">
+            <ref name="distance"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:start-line-spacing-vertical">
+            <ref name="distance"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:end-line-spacing-horizontal">
+            <ref name="distance"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:end-line-spacing-vertical">
+            <ref name="distance"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:line-distance">
+            <ref name="distance"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:guide-overhang">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:guide-distance">
+            <ref name="distance"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:start-guide">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:end-guide">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:placing">
+            <choice>
+                <value>below</value>
+                <value>above</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:parallel">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:measure-align">
+            <choice>
+                <value>automatic</value>
+                <value>left-outside</value>
+                <value>inside</value>
+                <value>right-outside</value>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:measure-vertical-align">
+            <choice>
+                <value>automatic</value>
+                <value>above</value>
+                <value>below</value>
+                <value>center</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:unit">
+            <choice>
+                <value>automatic</value>
+                <value>mm</value>
+                <value>cm</value>
+                <value>m</value>
+                <value>km</value>
+                <value>pt</value>
+                <value>pc</value>
+                <value>inch</value>
+                <value>ft</value>
+                <value>mi</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:show-unit">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:decimal-places">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:caption-type">
+            <choice>
+                <value>straight-line</value>
+                <value>angled-line</value>
+                <value>angled-connector-line</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:caption-angle-type">
+            <choice>
+                <value>fixed</value>
+                <value>free</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:caption-angle">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:caption-gap">
+            <ref name="distance"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:caption-escape-direction">
+            <choice>
+                <value>horizontal</value>
+                <value>vertical</value>
+                <value>auto</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:caption-escape">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:caption-line-length">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:caption-fit-line-length">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:horizontal-segments">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:vertical-segments">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:edge-rounding">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:edge-rounding-mode">
+            <choice>
+                <value>correct</value>
+                <value>attractive</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:back-scale">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:depth">
+            <ref name="length"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:backface-culling">
+            <choice>
+                <value>enabled</value>
+                <value>disabled</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:end-angle">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:close-front">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:close-back">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:lighting-mode">
+            <choice>
+                <value>standard</value>
+                <value>double-sided</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:normals-kind">
+            <choice>
+                <value>object</value>
+                <value>flat</value>
+                <value>sphere</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:normals-direction">
+            <choice>
+                <value>normal</value>
+                <value>inverse</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:texture-generation-mode-x">
+            <choice>
+                <value>object</value>
+                <value>parallel</value>
+                <value>sphere</value>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="dr3d:texture-generation-mode-y">
+            <choice>
+                <value>object</value>
+                <value>parallel</value>
+                <value>sphere</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:texture-kind">
+            <choice>
+                <value>luminance</value>
+                <value>intensity</value>
+                <value>color</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:texture-filter">
+            <choice>
+                <value>enabled</value>
+                <value>disabled</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:texture-mode">
+            <choice>
+                <value>replace</value>
+                <value>modulate</value>
+                <value>blend</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:ambient-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="dr3d:emissive-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="dr3d:specular-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="dr3d:diffuse-color">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:shininess">
+            <ref name="percent"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="dr3d:shadow">
+            <choice>
+                <value>visible</value>
+                <value>hidden</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <ref name="common-draw-rel-size-attlist"/>
+    <optional>
+        <attribute name="fo:min-width">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:min-height">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:max-height">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="fo:max-width">
+            <choice>
+                <ref name="length"/>
+                <ref name="percent"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <ref name="common-horizontal-margin-attlist"/>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <ref name="common-vertical-margin-attlist"/>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <ref name="common-margin-attlist"/>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:print-content">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:protect">
+            <choice>
+                <value>none</value>
+                <list>
+                    <oneOrMore>
+                        <choice>
+                            <value>content</value>
+                            <value>position</value>
+                            <value>size</value>
+                        </choice>
+                    </oneOrMore>
+                </list>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:horizontal-pos">
+            <choice>
+                <value>left</value>
+                <value>center</value>
+                <value>right</value>
+                <value>from-left</value>
+                <value>inside</value>
+                <value>outside</value>
+                <value>from-inside</value>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:x">
+            <ref name="coordinate"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:horizontal-rel">
+            <choice>
+                    <value>page</value>
+                <value>page-content</value>
+                <value>page-start-margin</value>
+                <value>page-end-margin</value>
+                <value>frame</value>
+                <value>frame-content</value>
+                <value>frame-start-margin</value>
+                <value>frame-end-margin</value>
+                <value>paragraph</value>
+                <value>paragraph-content</value>
+                <value>paragraph-start-margin</value>
+                <value>paragraph-end-margin</value>
+                <value>char</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <ref name="common-vertical-pos-attlist"/>
+</define>
+
+<define name="common-vertical-pos-attlist">
+    <optional>
+        <attribute name="style:vertical-pos">
+            <choice>
+                <value>top</value>
+                <value>middle</value>
+                <value>bottom</value>
+                <value>from-top</value>
+                <value>below</value>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="svg:y">
+            <ref name="coordinate"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <ref name="common-vertical-rel-attlist"/>
+</define>
+
+<define name="common-vertical-rel-attlist">
+    <optional>
+        <attribute name="style:vertical-rel">
+            <choice>
+                <value>page</value>
+                <value>page-content</value>
+                <value>frame</value>
+                <value>frame-content</value>
+                <value>paragraph</value>
+                <value>paragraph-content</value>
+                <value>char</value>
+                <value>line</value>
+                <value>baseline</value>
+                <value>text</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <ref name="common-text-anchor-attlist"/>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <ref name="common-border-attlist"/>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <ref name="common-border-line-width-attlist"/>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <ref name="common-padding-attlist"/>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <ref name="common-shadow-attlist"/>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <ref name="common-background-color-attlist"/>
+</define>
+<define name="style-graphic-properties-elements" combine="interleave">
+    <ref name="style-background-image"/>
+</define>
+<define name="style-graphic-properties-elements" combine="interleave">
+    <ref name="style-columns"/>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:editable">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:wrap">
+            <choice>
+                <value>none</value>
+                <value>left</value>
+                <value>right</value>
+                <value>parallel</value>
+                <value>dynamic</value>
+                <value>run-through</value>
+                <value>biggest</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:wrap-dynamic-threshold">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:number-wrapped-paragraphs">
+            <choice>
+                <value>no-limit</value>
+                <ref name="positiveInteger"/>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:wrap-contour">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:wrap-contour-mode">
+            <choice>
+                <value>full</value>
+                <value>outside</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:run-through">
+            <choice>
+                <value>foreground</value>
+                <value>background</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:flow-with-text">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:overflow-behavior">
+            <choice>
+                <value>clip</value>
+                <value>auto-create-new-frame</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="style:mirror">
+            <choice>
+                <value>none</value>
+                <value>vertical</value>
+                <ref name="horizontal-mirror"/>
+                <list>
+                    <value>vertical</value>
+                    <ref name="horizontal-mirror"/>
+                </list>
+                <list>
+                    <ref name="horizontal-mirror"/>
+                    <value>vertical</value>
+                </list>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+
+<define name="horizontal-mirror">
+    <choice>
+        <value>horizontal</value>
+        <value>horizontal-on-odd</value>
+        <value>horizontal-on-even</value>
+    </choice>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="fo:clip">
+            <!-- The attribute value must match the one XSL's clip -->
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:wrap-influence-on-position"
+                    a:defaultValue="iterative">
+            <choice>
+                <value>iterative</value>
+                <value>once-concurrent</value>
+                <value>once-successive</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <ref name="common-writing-mode-attlist"/>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:frame-display-scrollbar">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:frame-display-border">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:frame-margin-horizontal">
+            <ref name="nonNegativePixelLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:frame-margin-vertical">
+            <ref name="nonNegativePixelLength"/>
+        </attribute>
+    </optional>
+</define>
+
+<define name="nonNegativePixelLength">
+    <data type="string">
+        <param name="pattern">([0-9]+(\.[0-9]*)?|\.[0-9]+)(px)</param>
+    </data>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:visible-area-left">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:visible-area-top">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:visible-area-width">
+            <ref name="positiveLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="draw:visible-area-height">
+            <ref name="positiveLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-graphic-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="draw:ole-draw-aspect">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties">
+    <element name="style:chart-properties">
+        <ref name="style-chart-properties-content"/>
+    </element>
+</define>
+
+<define name="style-chart-properties-content">
+    <ref name="style-properties-content"/>
+</define>
+
+<define name="style-chart-properties-content-strict">
+    <ref name="style-chart-properties-attlist"/>
+    <ref name="style-chart-properties-elements"/>
+</define>
+
+<define name="style-chart-properties-elements">
+    <empty/>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:scale-text" a:defaultValue="true">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:three-dimensional">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:deep">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <choice>
+        <attribute name="chart:symbol-type">
+            <value>none</value>
+        </attribute>
+        <attribute name="chart:symbol-type">
+            <value>automatic</value>
+        </attribute>
+        <group>
+            <attribute name="chart:symbol-type">
+                <value>named-symbol</value>
+            </attribute>
+            <attribute name="chart:symbol-name">
+                <choice>
+                    <value>square</value>
+                    <value>diamond</value>
+                    <value>arrow-down</value>
+                    <value>arrow-up</value>
+                    <value>arrow-right</value>
+                    <value>arrow-left</value>
+                    <value>bow-tie</value>
+                    <value>hourglass</value>
+                    <value>circle</value>
+                    <value>star</value>
+                    <value>x</value>
+                    <value>plus</value>
+                    <value>asterisk</value>
+                    <value>horizontal-bar</value>
+                    <value>vertical-bar</value>
+                </choice>
+            </attribute>
+        </group>
+        <group>
+            <attribute name="chart:symbol-type">
+                <value>image</value>
+            </attribute>
+            <element name="chart:symbol-image">
+                <attribute name="xlink:href">
+                    <ref name="anyURI"/>
+                </attribute>
+            </element>
+        </group>
+        <empty/>
+    </choice>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:symbol-width">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:symbol-height">
+            <ref name="nonNegativeLength"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:vertical" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:connect-bars" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:gap-width">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:overlap">
+            <ref name="integer"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:japanese-candle-stick"
+                    a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:interpolation" a:defaultValue="none">
+            <choice>
+                <value>none</value>
+                <value>cubic-spline</value>
+                <value>b-spline</value>
+            </choice>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:spline-order" a:defaultValue="2">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:spline-resolution" a:defaultValue="20">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:pie-offset" a:defaultValue="0">
+            <ref name="nonNegativeInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:lines" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:solid-type" a:defaultValue="cuboid">
+            <choice>
+                <value>cuboid</value>
+                <value>cylinder</value>
+                <value>cone</value>
+                <value>pyramid</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:stacked" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:percentage" a:defaultValue="false">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:link-data-style-to-source">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:visible">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:logarithmic">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:maximum">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:minimum">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:origin">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:interval-major">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:interval-minor-divisor">
+            <ref name="positiveInteger"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:tick-marks-major-inner">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:tick-marks-major-outer">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:tick-marks-minor-inner">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:tick-marks-minor-outer">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:display-label">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:text-overlap">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="text:line-break">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:label-arrangement"
+                   a:defaultValue="side-by-side">
+            <choice>
+                <value>side-by-side</value>
+                <value>stagger-even</value>
+                <value>stagger-odd</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <ref name="common-style-direction-attlist"/>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <ref name="common-rotation-angle-attlist"/>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:data-label-number">
+            <choice>
+                <value>none</value>
+                <value>value</value>
+                <value>percentage</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:data-label-text">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:data-label-symbol">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:mean-value">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:error-category" a:defaultValue="none">
+            <choice>
+                <value>none</value>
+                <value>variance</value>
+                <value>standard-deviation</value>
+                <value>percentage</value>
+                <value>error-margin</value>
+                <value>constant</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:error-percentage">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:error-margin">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:error-lower-limit">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:error-upper-limit">
+            <ref name="double"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:error-upper-indicator">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+    <optional>
+        <attribute name="chart:error-lower-indicator">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:series-source" a:defaultValue="columns">
+            <choice>
+                <value>columns</value>
+                <value>rows</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-chart-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="chart:regression-type" a:defaultValue="none">
+            <choice>
+                <value>none</value>
+                <value>linear</value>
+                <value>logarithmic</value>
+                <value>exponential</value>
+                <value>power</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist"
+        combine="interleave">
+    <optional>
+        <attribute name="presentation:transition-type">
+            <choice>
+                <value>manual</value>
+                <value>automatic</value>
+                <value>semi-automatic</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist"
+         combine="interleave">
+    <optional>
+        <attribute name="presentation:transition-style">
+            <choice>
+                <value>none</value>
+                <value>fade-from-left</value>
+                <value>fade-from-top</value>
+                <value>fade-from-right</value>
+                <value>fade-from-bottom</value>
+                <value>fade-from-upperleft</value>
+                <value>fade-from-upperright</value>
+                <value>fade-from-lowerleft</value>
+                <value>fade-from-lowerright</value>
+                <value>move-from-left</value>
+                <value>move-from-top</value>
+                <value>move-from-right</value>
+                <value>move-from-bottom</value>
+                <value>move-from-upperleft</value>
+                <value>move-from-upperright</value>
+                <value>move-from-lowerleft</value>
+                <value>move-from-lowerright</value>
+                <value>uncover-to-left</value>
+                <value>uncover-to-top</value>
+                <value>uncover-to-right</value>    
+                <value>uncover-to-bottom</value>
+                <value>uncover-to-upperleft</value>
+                <value>uncover-to-upperright</value>
+                <value>uncover-to-lowerleft</value>
+                <value>uncover-to-lowerright</value>
+                <value>fade-to-center</value>
+                <value>fade-from-center</value>
+                <value>vertical-stripes</value>
+                <value>horizontal-stripes</value>
+                <value>clockwise</value>
+                <value>counterclockwise</value>
+                <value>open-vertical</value>
+                <value>open-horizontal</value>
+                <value>close-vertical</value>
+                <value>close-horizontal</value>
+                <value>wavyline-from-left</value>
+                <value>wavyline-from-top</value>
+                <value>wavyline-from-right</value>
+                <value>wavyline-from-bottom</value>
+                <value>spiralin-left</value>
+                <value>spiralin-right</value>
+                <value>spiralout-left</value>
+                <value>spiralout-right</value>
+                <value>roll-from-top</value>
+                <value>roll-from-left</value>
+                <value>roll-from-right</value>
+                <value>roll-from-bottom</value>
+                <value>stretch-from-left</value>
+                <value>stretch-from-top</value>
+                <value>stretch-from-right</value>
+                <value>stretch-from-bottom</value>
+
+                <value>vertical-lines</value>
+                <value>horizontal-lines</value>
+                <value>dissolve</value>
+                <value>random</value>
+                <value>vertical-checkerboard</value>
+                <value>horizontal-checkerboard</value>
+                <value>interlocking-horizontal-left</value>
+                <value>interlocking-horizontal-right</value>
+                <value>interlocking-vertical-top</value>
+                <value>interlocking-vertical-bottom</value>
+                <value>fly-away</value>
+                <value>open</value>
+                <value>close</value>
+                <value>melt</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist"
+        combine="interleave">
+    <optional>
+        <attribute name="presentation:transition-speed">
+            <ref name="presentationSpeeds"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist " combine="interleave">
+    <optional>
+        <attribute name="smil:type">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:subtype">
+            <ref name="string"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:direction" a:defaultValue="forward">
+            <choice>
+                <value>forward</value>
+                <value>reverse</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="smil:fadeColor">
+            <ref name="color"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist"
+        combine="interleave">
+    <optional>
+        <attribute name="presentation:duration">
+            <ref name="duration"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist"
+         combine="interleave">
+    <optional>
+        <attribute name="presentation:visibility">
+            <choice>
+                <value>visible</value>
+                <value>hidden</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-elements"
+         combine="interleave">
+    <optional>
+        <ref name="presentation-sound"/>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist"
+         combine="interleave">
+    <optional>
+        <attribute name="draw:background-size">
+            <choice>
+                <value>full</value>
+                <value>border</value>
+            </choice>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist"
+         combine="interleave">
+    <optional>
+        <attribute name="presentation:background-objects-visible">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist"
+         combine="interleave">
+    <optional>
+        <attribute name="presentation:background-visible">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:display-header">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:display-footer">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:display-page-number">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="style-drawing-page-properties-attlist" combine="interleave">
+    <optional>
+        <attribute name="presentation:display-date-time">
+            <ref name="boolean"/>
+        </attribute>
+    </optional>
+</define>
+<define name="string">
+    <data type="string"/>
+</define>
+<define name="date">
+    <data type="date"/>
+</define>
+<define name="time">
+    <data type="time"/>
+</define>
+<define name="dateTime">
+    <data type="dateTime"/>
+</define>
+<define name="duration">
+    <data type="duration"/>
+</define>
+<define name="integer">
+    <data type="integer"/>
+</define>
+<define name="nonNegativeInteger">
+    <data type="nonNegativeInteger"/>
+</define>
+<define name="positiveInteger">
+    <data type="positiveInteger"/>
+</define>
+<define name="double">
+    <data type="double"/>
+</define>
+<define name="anyURI">
+    <data type="anyURI"/>
+</define>
+<define name="base64Binary">
+    <data type="base64Binary"/>
+</define>
+<define name="ID">
+    <data type="ID"/>
+</define>
+<define name="IDREF">
+    <data type="IDREF"/>
+</define>
+<define name="IDREFS">
+    <data type="IDREFS"/>
+</define>
+<define name="boolean">
+    <choice>
+        <value>true</value>
+        <value>false</value>
+    </choice>
+</define>
+<define name="dateOrDateTime">
+    <choice>
+        <data type="date"/>
+        <data type="dateTime"/>
+    </choice>
+</define>
+<define name="timeOrDateTime">
+    <choice>
+        <data type="time"/>
+        <data type="dateTime"/>
+    </choice>
+</define>
+<define name="language">
+    <data type="language"/>
+</define>
+<define name="countryCode">
+    <data type="token">
+        <param name="pattern">[A-Za-z0-9]{1,8}</param>
+    </data>
+</define>
+<define name="languageCode">
+    <data type="token">
+        <param name="pattern">[A-Za-z]{1,8}</param>
+    </data>
+</define>
+<define name="character">
+    <data type="string">
+        <param name="length">1</param>
+    </data>
+</define>
+<define name="length">
+    <data type="string">
+        <param name="pattern">-?([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc)|(px))</param>
+
+    </data>
+</define>
+<define name="nonNegativeLength">
+    <data type="string">
+        <param name="pattern">([0-9]+(\.[0-9]*)?|\.[0-9]+)((cm)|(mm)|(in)|(pt)|(pc)|(px))</param>
+
+    </data>
+</define>
+<define name="positiveLength">
+    <data type="string">
+        <param name="pattern">([0-9]*[1-9][0-9]*(\.[0-9]*)?|0+\.[0-9]*[1-9][0-9]*|\.[0-9]*[1-9][0-9]*)((cm)|(mm)|(in)|(pt)|(pc)|(px))</param>
+
+    </data>
+</define>
+<define name="percent">
+    <data type="string">
+        <param name="pattern">-?([0-9]+(\.[0-9]*)?|\.[0-9]+)%</param>
+    </data>
+</define>
+<define name="relativeLength">
+    <data type="string">
+        <param name="pattern">[0-9]+\*</param>
+    </data>
+</define>
+<define name="coordinate">
+    <ref name="length"/>
+</define>
+<define name="distance">
+    <ref name="length"/>
+</define>
+<define name="color">
+    <data type="string">
+        <param name="pattern">#[0-9a-fA-F]{6}</param>
+    </data>
+</define>
+<define name="styleName">
+    <data type="NCName"/>
+</define>
+<define name="styleNameRef">
+    <choice>
+        <data type="NCName"/>
+        <empty/>
+    </choice>
+</define>
+<define name="styleNameRefs">
+    <list>
+        <zeroOrMore>
+            <data type="NCName"/>
+        </zeroOrMore>
+    </list>
+</define>
+<define name="variableName">
+    <data type="string"/>
+</define>
+<define name="formula">
+    <!-- A formula should start with a namespace prefix, -->
+    <!-- but has no restrictions-->
+    <data type="string"/>
+</define>
+
+<define name="targetFrameName">
+    <choice>
+        <value>_self</value>
+        <value>_blank</value>
+        <value>_parent</value>
+        <value>_top</value>
+        <ref name="string"/>
+    </choice>
+</define>
+
+<define name="valueType">
+    <choice>
+        <value>float</value>
+        <value>time</value>
+        <value>date</value>
+        <value>percentage</value>
+        <value>currency</value>
+        <value>boolean</value>
+        <value>string</value>
+    </choice>
+</define>
+
+<define name="points">
+    <data type="string">
+        <param name="pattern">-?[0-9]+,-?[0-9]+([ ]+-?[0-9]+,-?[0-9]+)*</param>
+    </data>
+</define>
+<define name="pathData">
+    <data type="string"/>
+</define>
+
+<define name="vector3D">
+    <data type="string">
+        <param name="pattern">\([ ]*-?([0-9]+(\.[0-9]*)?|\.[0-9]+)([ ]+-?([0-9]+(\.[0-9]*)?|\.[0-9]+)){2}[ ]*\)</param>
+
+    </data>
+</define>
+
+<define name="namespacedToken">
+    <data type="string">
+        <param name="pattern">[0-9a-zA-Z_]+:[0-9a-zA-Z._\-]+</param>
+    </data>
+</define>
+<define name="anyAttListOrElements">
+    <zeroOrMore>
+        <attribute>
+            <anyName/>
+            <text/>
+        </attribute>
+    </zeroOrMore>
+    <ref name="anyElements"/>
+</define>
+<define name="anyElements">
+    <zeroOrMore>
+        <element>
+            <anyName/>
+            <mixed>
+                <ref name="anyAttListOrElements"/>
+            </mixed>
+        </element>
+    </zeroOrMore>
+</define>
+</grammar>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/OpenDocument-strict-schema-v1.1.rng
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/OpenDocument-strict-schema-v1.1.rng	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/OpenDocument-strict-schema-v1.1.rng	(revision 28000)
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    OASIS OpenDocument v1.1
+    OASIS Standard, 1 Feb 2007
+    Strict Relax-NG Schema
+
+    $Id$
+
+    © 2002-2007 OASIS Open
+    © 1999-2007 Sun Microsystems, Inc.
+-->
+
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+    <include href="OpenDocument-schema-v1.1.rng">
+        <define name="office-meta-content">
+            <ref name="office-meta-content-strict"/>
+        </define>
+        <define name="style-page-layout-properties-content">
+            <ref name="style-page-layout-properties-content-strict"/>
+        </define>
+        <define name="style-header-footer-properties-content">
+            <ref name="style-header-footer-properties-content-strict"/>
+        </define>
+        <define name="style-drawing-page-properties-content">
+            <ref name="style-drawing-page-properties-content-strict"/>
+        </define>
+        <define name="style-text-properties-content">
+            <ref name="style-text-properties-content-strict"/>
+        </define>
+        <define name="style-paragraph-properties-content">
+            <ref name="style-paragraph-properties-content-strict"/>
+        </define>
+        <define name="style-ruby-properties-content">
+            <ref name="style-ruby-properties-content-strict"/>
+        </define>
+        <define name="style-section-properties-content">
+            <ref name="style-section-properties-content-strict"/>
+        </define>
+        <define name="style-list-level-properties-content">
+            <ref name="style-list-level-properties-content-strict"/>
+        </define>
+        <define name="style-table-properties-content">
+            <ref name="style-table-properties-content-strict"/>
+        </define>
+        <define name="style-table-column-properties-content">
+            <ref name="style-table-column-properties-content-strict"/>
+        </define>
+        <define name="style-table-row-properties-content">
+            <ref name="style-table-row-properties-content-strict"/>
+        </define>
+        <define name="style-table-cell-properties-content">
+            <ref name="style-table-cell-properties-content-strict"/>
+        </define>
+        <define name="style-graphic-properties-content">
+            <ref name="style-graphic-properties-content-strict"/>
+        </define>
+        <define name="style-chart-properties-content">
+            <ref name="style-chart-properties-content-strict"/>
+        </define>
+    </include>
+</grammar>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/accelerator.dtd
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/accelerator.dtd	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/accelerator.dtd	(revision 28000)
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	$Id: accelerator.dtd,v 1.2 2001/10/16 15:44:43 cd Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+-->
+
+<!ENTITY % boolean		"(true|false)">
+
+<!ELEMENT accel:acceleratorlist (accel:item*)>
+<!ATTLIST accel:acceleratorlist
+	xmlns:accel CDATA #FIXED "http://openoffice.org/2001/accel"
+	xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink"
+>
+
+<!ELEMENT accel:item EMPTY>
+<!ATTLIST accel:item
+	accel:code CDATA #REQUIRED
+	accel:shift %boolean; "false"
+	accel:mod1 %boolean; "false"
+	accel:mod2 %boolean; "false"
+	xlink:href CDATA #REQUIRED
+>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/chart.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/chart.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/chart.mod	(revision 28000)
@@ -0,0 +1,290 @@
+<!--
+	$Id: chart.mod,v 1.33 2003/03/27 18:19:53 hr Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+
+<!ENTITY % chart-class "(line|area|circle|ring|scatter|radar|bar|stock|add-in)">
+<!ENTITY % chart-solid-type "(cuboid|cylinder|cone|pyramid)">
+
+<!-- Chart element -->
+<!ELEMENT chart:chart ( chart:title?, chart:subtitle?, chart:legend?,
+					    chart:plot-area,
+						table:table? )>
+<!ATTLIST chart:chart
+		  chart:class %chart-class; #REQUIRED
+		  chart:add-in-name %string; #IMPLIED
+		  chart:table-number-list %string; #IMPLIED
+		  draw:name %string; #IMPLIED
+		  %draw-position;
+		  %draw-size;
+		  %draw-style-name;
+		  chart:column-mapping %string; #IMPLIED
+		  chart:row-mapping %string; #IMPLIED
+		  chart:style-name %styleName; #IMPLIED>
+
+<!ATTLIST chart:chart %presentation-class; >
+<!ATTLIST chart:chart %zindex;>
+<!ATTLIST chart:chart %draw-end-position; >
+<!ATTLIST chart:chart draw:id %draw-shape-id; >
+<!ATTLIST chart:chart draw:layer %layerName; #IMPLIED>
+
+<!ATTLIST style:properties
+		  chart:scale-text %boolean; "true"
+		  chart:stock-updown-bars %boolean; "false"
+		  chart:stock-with-volume %boolean; "false"
+		  chart:three-dimensional %boolean; "false"
+		  chart:deep %boolean; "false"
+		  chart:lines %boolean; "false"
+		  chart:percentage %boolean; "false"
+		  chart:solid-type %chart-solid-type; "cuboid"
+		  chart:splines %nonNegativeInteger; "0"
+		  chart:stacked %boolean; "false"
+		  chart:symbol %integer; "-1"
+		  chart:vertical %boolean; "false"
+		  chart:lines-used %nonNegativeInteger; "0"
+		  chart:connect-bars %boolean; "false"
+		  chart:spline-order %nonNegativeInteger; "2"
+		  chart:spline-resolution %nonNegativeInteger; "20"
+          chart:pie-offset %nonNegativeInteger; "0">
+
+<!-- Main/Sub Title -->
+<!-- the cell-address attribute is currently not supported for titles -->
+<!ELEMENT chart:title (text:p)?>
+<!ATTLIST chart:title
+		  table:cell-range %cell-address; #IMPLIED
+		  svg:x %coordinate; #IMPLIED
+		  svg:y %coordinate; #IMPLIED
+		  chart:style-name %styleName; #IMPLIED >
+
+<!ELEMENT chart:subtitle (text:p)?>
+<!ATTLIST chart:subtitle
+		  table:cell-range %cell-address; #IMPLIED
+		  svg:x %coordinate; #IMPLIED
+		  svg:y %coordinate; #IMPLIED
+		  chart:style-name %styleName; #IMPLIED >
+
+<!-- you must specify either a legend-position or both, x and y coordinates -->
+<!ELEMENT chart:legend EMPTY>
+<!ATTLIST chart:legend
+		  chart:legend-position (top|left|bottom|right) "right"
+		  svg:x %coordinate; #IMPLIED
+		  svg:y %coordinate; #IMPLIED
+		  chart:style-name %styleName; #IMPLIED >
+
+<!-- Plot-Area specification -->
+
+<!ELEMENT chart:plot-area (dr3d:light*,
+						   chart:axis*,
+						   chart:categories?,
+						   chart:series*,
+						   chart:stock-gain-marker?,
+						   chart:stock-loss-marker?,
+						   chart:stock-range-line?,
+						   chart:wall?,
+						   chart:floor?) >
+
+<!ATTLIST chart:plot-area
+		  svg:x %coordinate; #IMPLIED
+		  svg:y %coordinate; #IMPLIED
+		  svg:width %length; #IMPLIED
+		  svg:height %length; #IMPLIED
+		  chart:style-name %styleName; #IMPLIED
+		  table:cell-range-address %cell-range-address; #IMPLIED
+		  chart:table-number-list %string; #IMPLIED
+		  chart:data-source-has-labels (none|row|column|both) "none" >
+
+<!-- 3d scene attributes on plot-area -->
+<!ATTLIST chart:plot-area
+		  dr3d:vrp %vector3D; #IMPLIED
+		  dr3d:vpn %vector3D; #IMPLIED
+		  dr3d:vup %vector3D; #IMPLIED
+		  dr3d:projection (parallel|perspective) #IMPLIED
+		  dr3d:transform CDATA #IMPLIED
+		  dr3d:distance %length; #IMPLIED
+		  dr3d:focal-length %length; #IMPLIED
+		  dr3d:shadow-slant %nonNegativeInteger; #IMPLIED
+		  dr3d:shade-mode (flat|phong|gouraud|draft) #IMPLIED
+		  dr3d:ambient-color %color; #IMPLIED
+		  dr3d:lighting-mode %boolean; #IMPLIED >
+
+<!ATTLIST style:properties
+		  chart:series-source (columns|rows) "columns" >
+
+<!ELEMENT chart:wall EMPTY>
+<!ATTLIST chart:wall
+		  svg:width %length; #IMPLIED
+		  chart:style-name %styleName; #IMPLIED >
+
+<!ELEMENT chart:floor EMPTY>
+<!ATTLIST chart:floor
+		  svg:width %length; #IMPLIED
+		  chart:style-name %styleName; #IMPLIED >
+
+<!-- Stock chart elements -->
+
+<!ELEMENT chart:stock-gain-marker EMPTY>
+<!ATTLIST chart:stock-gain-marker
+		  chart:style-name %styleName; #IMPLIED >
+
+<!ELEMENT chart:stock-loss-marker EMPTY>
+<!ATTLIST chart:stock-loss-marker
+		  chart:style-name %styleName; #IMPLIED >
+
+<!ELEMENT chart:stock-range-line EMPTY>
+<!ATTLIST chart:stock-range-line
+		  chart:style-name %styleName; #IMPLIED >
+
+<!-- Axis -->
+
+<!ELEMENT chart:axis (chart:title?, chart:grid*)>
+<!ATTLIST chart:axis
+		  chart:class (category|value|series|domain) #REQUIRED
+		  chart:name %string; #IMPLIED
+		  chart:style-name %styleName; #IMPLIED >
+
+<!ATTLIST style:properties
+		  chart:tick-marks-major-inner %boolean; "false"
+		  chart:tick-marks-major-outer %boolean; "true"
+		  chart:tick-marks-minor-inner %boolean; "false"
+		  chart:tick-marks-minor-outer %boolean; "false"
+		  chart:logarithmic %boolean; "false"
+		  chart:maximum %float; #IMPLIED
+		  chart:minimum %float; #IMPLIED
+		  chart:origin %float; #IMPLIED
+		  chart:interval-major %float; #IMPLIED
+		  chart:interval-minor %float; #IMPLIED
+		  chart:gap-width %integer; #IMPLIED
+		  chart:overlap %integer; #IMPLIED
+		  text:line-break %boolean; "true"
+		  chart:display-label %boolean; "true"
+		  chart:label-arrangement (side-by-side|stagger-even|stagger-odd) "side-by-side"
+		  chart:text-overlap %boolean; "false"
+		  chart:visible %boolean; "true" 
+		  chart:link-data-style-to-source %boolean; "true" >
+
+<!ELEMENT chart:grid EMPTY>
+<!ATTLIST chart:grid
+		  chart:class (major|minor) "major"
+		  chart:style-name %styleName; #IMPLIED >
+
+
+<!ELEMENT chart:categories EMPTY>
+<!ATTLIST chart:categories
+		  table:cell-range-address %cell-range-address; #IMPLIED >
+
+<!--
+	each series element must have an cell-range-address element that points
+	to the underlying table data.
+	Impl. Note: Internally all href elements are merged to one table range
+	that represents the data for the whole chart
+-->
+<!ELEMENT chart:series ( chart:domain*,
+                         chart:mean-value?,
+						 chart:regression-curve?,
+						 chart:error-indicator?,
+						 chart:data-point* )>
+<!ATTLIST chart:series
+		  chart:values-cell-range-address %cell-range-address; #IMPLIED
+		  chart:label-cell-address %cell-address; #IMPLIED
+		  chart:class %chart-class; #IMPLIED
+		  chart:attached-axis %string; #IMPLIED
+		  chart:style-name %styleName; #IMPLIED >
+
+<!ELEMENT chart:domain EMPTY>
+<!ATTLIST chart:domain
+		  table:cell-range-address %cell-range-address; #IMPLIED >
+
+<!ELEMENT chart:data-point EMPTY>
+<!ATTLIST chart:data-point
+		  chart:repeated %nonNegativeInteger; #IMPLIED
+		  chart:style-name %styleName; #IMPLIED >
+
+<!-- statistical properties -->
+
+<!ELEMENT chart:mean-value EMPTY>
+<!ELEMENT chart:regression-curve EMPTY >
+<!ELEMENT chart:error-indicator EMPTY >
+<!ATTLIST chart:mean-value chart:style-name %styleName; #IMPLIED >
+<!ATTLIST chart:regression-curve chart:style-name %styleName; #IMPLIED >
+<!ATTLIST chart:error-indicator chart:style-name %styleName; #IMPLIED >
+
+<!ATTLIST style:properties
+		  chart:mean-value %boolean; #IMPLIED
+		  chart:error-category (none|variance|standard-deviation|percentage|error-margin|constant) "none"
+		  chart:error-percentage %float; #IMPLIED
+		  chart:error-margin %float; #IMPLIED
+		  chart:error-lower-limit %float; #IMPLIED
+		  chart:error-upper-limit %float; #IMPLIED
+		  chart:error-upper-indicator %boolean; #IMPLIED
+		  chart:error-lower-indicator %boolean; #IMPLIED
+		  chart:regression-type (none|linear|logarithmic|exponential|power) "none" >
+
+<!-- data label properties -->
+
+<!ATTLIST style:properties
+		  chart:data-label-number (none|value|percentage) "none"
+		  chart:data-label-text %boolean; "false"
+		  chart:data-label-symbol %boolean; "false" >
+
+<!-- general text properties -->
+
+<!ATTLIST style:properties 
+		  text:rotation-angle %integer; "0" >
+
+<!-- symbol properties -->
+
+<!ATTLIST style:properties
+		  chart:symbol-width %nonNegativeLength; #IMPLIED
+		  chart:symbol-height %nonNegativeLength; #IMPLIED
+		  chart:symbol-image-name %string; #IMPLIED >
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/datastyl.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/datastyl.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/datastyl.mod	(revision 28000)
@@ -0,0 +1,234 @@
+<!--
+
+   $Id: datastyl.mod,v 1.11 2002/06/26 16:52:37 er Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!-- data styles -->
+<!ENTITY % any-number "( number:number | number:scientific-number | number:fraction )">
+<!ENTITY % number-style-content "( (number:text,(%any-number;,number:text?)?) | (%any-number;,number:text?) )">
+<!ELEMENT number:number-style ( style:properties?, %number-style-content;, style:map* )>
+<!ELEMENT number:number ( number:embedded-text* )>
+<!ELEMENT number:scientific-number EMPTY>
+<!ELEMENT number:fraction EMPTY>
+
+<!ELEMENT number:embedded-text (#PCDATA)>
+<!ATTLIST number:embedded-text number:position %integer; #REQUIRED>
+
+<!ENTITY % currency-symbol-and-text "number:currency-symbol,number:text?">
+<!ENTITY % number-and-text "number:number,number:text?">
+<!ENTITY % currency-symbol-and-number "((%number-and-text;),(%currency-symbol-and-text;)?) | ((%currency-symbol-and-text;),(%number-and-text;)?)">
+<!ENTITY % currency-style-content "number:text?, (%currency-symbol-and-number;)?">
+
+<!ELEMENT number:currency-style ( style:properties?, (%currency-style-content;), style:map* )>
+<!ELEMENT number:currency-symbol (#PCDATA)>
+<!ATTLIST number:currency-symbol number:language CDATA #IMPLIED>
+<!ATTLIST number:currency-symbol number:country CDATA #IMPLIED>
+
+<!ENTITY % percentage-style-content "( (number:text,(%number-and-text;)?) | (%number-and-text;) )">
+<!ELEMENT number:percentage-style ( style:properties?, %percentage-style-content;, style:map* )>
+
+<!ENTITY % any-date "( number:day | number:month | number:year | number:era | number:day-of-week | number:week-of-year | number:quarter| number:hours | number:am-pm | number:minutes | number:seconds )">
+<!ENTITY % date-style-content "( (number:text,(%any-date;,number:text?)+) | (%any-date;,number:text?)+ )">
+<!ELEMENT number:date-style ( style:properties?, %date-style-content;, style:map* )>
+<!ELEMENT number:day EMPTY>
+<!ATTLIST number:day number:style (short|long) "short">
+<!ATTLIST number:day number:calendar CDATA #IMPLIED>
+<!ELEMENT number:month EMPTY>
+<!ATTLIST number:month number:textual %boolean; "false">
+<!ATTLIST number:month number:style (short|long) "short">
+<!ATTLIST number:month number:calendar CDATA #IMPLIED>
+<!ELEMENT number:year EMPTY>
+<!ATTLIST number:year number:style (short|long) "short">
+<!ATTLIST number:year number:calendar CDATA #IMPLIED>
+<!ELEMENT number:era EMPTY>
+<!ATTLIST number:era number:style (short|long) "short">
+<!ATTLIST number:era number:calendar CDATA #IMPLIED>
+<!ELEMENT number:day-of-week EMPTY>
+<!ATTLIST number:day-of-week number:style (short|long) "short">
+<!ATTLIST number:day-of-week number:calendar CDATA #IMPLIED>
+<!ELEMENT number:week-of-year EMPTY>
+<!ATTLIST number:week-of-year number:calendar CDATA #IMPLIED>
+<!ELEMENT number:quarter EMPTY>
+<!ATTLIST number:quarter number:style (short|long) "short">
+<!ATTLIST number:quarter number:calendar CDATA #IMPLIED>
+
+<!ENTITY % any-time "( number:hours | number:am-pm | number:minutes | number:seconds )">
+<!ENTITY % time-style-content "( (number:text,(%any-time;,number:text?)+) | (%any-time;,number:text?)+)">
+<!ELEMENT number:time-style ( style:properties?, %time-style-content;, style:map* )>
+<!ELEMENT number:hours EMPTY>
+<!ATTLIST number:hours number:style (short|long) "short">
+<!ELEMENT number:minutes EMPTY>
+<!ATTLIST number:minutes number:style (short|long) "short">
+<!ELEMENT number:seconds EMPTY>
+<!ATTLIST number:seconds number:style (short|long) "short">
+<!ATTLIST number:seconds number:decimal-places %integer; "0">
+<!ELEMENT number:am-pm EMPTY>
+
+<!ENTITY % boolean-style-content "( (number:text,(number:boolean,number:text?)?) | (number:boolean,number:text?) )">
+<!ELEMENT number:boolean-style ( style:properties?,%boolean-style-content;, style:map* )>
+<!ELEMENT number:boolean EMPTY>
+
+<!ENTITY % text-style-content "( (number:text,(number:text-content,number:text?)?) | (number:text-content,number:text?) )">
+<!ELEMENT number:text-style ( style:properties?,%text-style-content;, style:map* )>
+<!ELEMENT number:text (#PCDATA)>
+<!ELEMENT number:text-content EMPTY>
+
+<!ATTLIST number:number-style style:name %styleName; #REQUIRED>
+<!ATTLIST number:currency-style style:name %styleName; #REQUIRED>
+<!ATTLIST number:percentage-style style:name %styleName; #REQUIRED>
+<!ATTLIST number:date-style style:name %styleName; #REQUIRED>
+<!ATTLIST number:time-style style:name %styleName; #REQUIRED>
+<!ATTLIST number:boolean-style style:name %styleName; #REQUIRED>
+<!ATTLIST number:text-style style:name %styleName; #REQUIRED>
+
+<!ATTLIST number:number-style style:family CDATA #REQUIRED>
+<!ATTLIST number:currency-style style:family CDATA #REQUIRED>
+<!ATTLIST number:percentage-style style:family CDATA #REQUIRED>
+<!ATTLIST number:date-style style:family CDATA #REQUIRED>
+<!ATTLIST number:time-style style:family CDATA #REQUIRED>
+<!ATTLIST number:boolean-style style:family CDATA #REQUIRED>
+<!ATTLIST number:text-style style:family CDATA #REQUIRED>
+
+<!ATTLIST number:number-style number:language CDATA #IMPLIED>
+<!ATTLIST number:currency-style number:language CDATA #IMPLIED>
+<!ATTLIST number:percentage-style number:language CDATA #IMPLIED>
+<!ATTLIST number:date-style number:language CDATA #IMPLIED>
+<!ATTLIST number:time-style number:language CDATA #IMPLIED>
+<!ATTLIST number:boolean-style number:language CDATA #IMPLIED>
+<!ATTLIST number:text-style number:language CDATA #IMPLIED>
+
+<!ATTLIST number:number-style number:country CDATA #IMPLIED>
+<!ATTLIST number:currency-style number:country CDATA #IMPLIED>
+<!ATTLIST number:percentage-style number:country CDATA #IMPLIED>
+<!ATTLIST number:date-style number:country CDATA #IMPLIED>
+<!ATTLIST number:time-style number:country CDATA #IMPLIED>
+<!ATTLIST number:boolean-style number:country CDATA #IMPLIED>
+<!ATTLIST number:text-style number:country CDATA #IMPLIED>
+
+<!ATTLIST number:number-style number:title CDATA #IMPLIED>
+<!ATTLIST number:currency-style number:title CDATA #IMPLIED>
+<!ATTLIST number:percentage-style number:title CDATA #IMPLIED>
+<!ATTLIST number:date-style number:title CDATA #IMPLIED>
+<!ATTLIST number:time-style number:title CDATA #IMPLIED>
+<!ATTLIST number:boolean-style number:title CDATA #IMPLIED>
+<!ATTLIST number:text-style number:title CDATA #IMPLIED>
+
+<!ATTLIST number:number-style style:volatile %boolean; #IMPLIED>
+<!ATTLIST number:currency-style style:volatile %boolean; #IMPLIED>
+<!ATTLIST number:percentage-style style:volatile %boolean; #IMPLIED>
+<!ATTLIST number:date-style style:volatile %boolean; #IMPLIED>
+<!ATTLIST number:time-style style:volatile %boolean; #IMPLIED>
+<!ATTLIST number:boolean-style style:volatile %boolean; #IMPLIED>
+<!ATTLIST number:text-style style:volatile %boolean; #IMPLIED>
+
+<!ATTLIST number:number-style number:transliteration-format CDATA "1">
+<!ATTLIST number:currency-style number:transliteration-format CDATA "1">
+<!ATTLIST number:percentage-style number:transliteration-format CDATA "1">
+<!ATTLIST number:date-style number:transliteration-format CDATA "1">
+<!ATTLIST number:time-style number:transliteration-format CDATA "1">
+<!ATTLIST number:boolean-style number:transliteration-format CDATA "1">
+<!ATTLIST number:text-style number:transliteration-format CDATA "1">
+
+<!ATTLIST number:number-style number:transliteration-language CDATA #IMPLIED>
+<!ATTLIST number:currency-style number:transliteration-language CDATA #IMPLIED>
+<!ATTLIST number:percentage-style number:transliteration-language CDATA #IMPLIED>
+<!ATTLIST number:date-style number:transliteration-language CDATA #IMPLIED>
+<!ATTLIST number:time-style number:transliteration-language CDATA #IMPLIED>
+<!ATTLIST number:boolean-style number:transliteration-language CDATA #IMPLIED>
+<!ATTLIST number:text-style number:transliteration-language CDATA #IMPLIED>
+
+<!ATTLIST number:number-style number:transliteration-country CDATA #IMPLIED>
+<!ATTLIST number:currency-style number:transliteration-country CDATA #IMPLIED>
+<!ATTLIST number:percentage-style number:transliteration-country CDATA #IMPLIED>
+<!ATTLIST number:date-style number:transliteration-country CDATA #IMPLIED>
+<!ATTLIST number:time-style number:transliteration-country CDATA #IMPLIED>
+<!ATTLIST number:boolean-style number:transliteration-country CDATA #IMPLIED>
+<!ATTLIST number:text-style number:transliteration-country CDATA #IMPLIED>
+
+<!ATTLIST number:number-style number:transliteration-style (short|medium|long) "short">
+<!ATTLIST number:currency-style number:transliteration-style (short|medium|long) "short">
+<!ATTLIST number:percentage-style number:transliteration-style (short|medium|long) "short">
+<!ATTLIST number:date-style number:transliteration-style (short|medium|long) "short">
+<!ATTLIST number:time-style number:transliteration-style (short|medium|long) "short">
+<!ATTLIST number:boolean-style number:transliteration-style (short|medium|long) "short">
+<!ATTLIST number:text-style number:transliteration-style (short|medium|long) "short">
+
+<!ATTLIST number:currency-style number:automatic-order %boolean; "false">
+<!ATTLIST number:date-style number:automatic-order %boolean; "false">
+
+<!ATTLIST number:date-style number:format-source (fixed|language) "fixed">
+<!ATTLIST number:time-style number:format-source (fixed|language) "fixed">
+
+<!ATTLIST number:time-style number:truncate-on-overflow %boolean; "true">
+
+<!ATTLIST number:number number:decimal-places %integer; #IMPLIED>
+<!ATTLIST number:scientific-number number:decimal-places %integer; #IMPLIED>
+
+<!ATTLIST number:number number:min-integer-digits %integer; #IMPLIED>
+<!ATTLIST number:scientific-number number:min-integer-digits %integer; #IMPLIED>
+<!ATTLIST number:fraction number:min-integer-digits %integer; #IMPLIED>
+
+<!ATTLIST number:number number:grouping %boolean; "false">
+<!ATTLIST number:scientific-number number:grouping %boolean; "false">
+<!ATTLIST number:fraction number:grouping %boolean; "false">
+
+<!ATTLIST number:number number:decimal-replacement CDATA #IMPLIED>
+
+<!ATTLIST number:number number:display-factor %float; "1">
+
+<!ATTLIST number:scientific-number number:min-exponent-digits %integer; #IMPLIED>
+
+<!ATTLIST number:fraction number:min-numerator-digits %integer; #IMPLIED>
+
+<!ATTLIST number:fraction number:min-denominator-digits %integer; #IMPLIED>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/defs.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/defs.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/defs.mod	(revision 28000)
@@ -0,0 +1,84 @@
+<!--
+	$Id: defs.mod,v 1.2 2002/11/01 10:22:59 dvo Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+ 
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+ 
+   Sun Microsystems Inc., October, 2000
+ 
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+ 
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+ 
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+ 
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+ 
+ 
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+ 
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+ 
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ 
+   Copyright: 2000 by Sun Microsystems, Inc.
+ 
+   All Rights Reserved.
+ 
+   Contributor(s): _______________________________________
+
+-->
+
+<!-- This module should contain entities intended for content definitions
+     in several other modules. Putting all of them here should remove
+     (some) order dependencies of the other module files
+-->
+
+
+<!-- text marks for tracking changes; usually used inside of paragraphs -->
+<!ENTITY % change-marks "text:change | text:change-start | text:change-end">
+
+<!-- (optional) text declarations; used before the first paragraph -->
+<!ENTITY % text-decls "text:variable-decls?, text:sequence-decls?,
+					   text:user-field-decls?, text:dde-connection-decls?, 
+					   text:alphabetical-index-auto-mark-file?" >
+
+<!-- define the types of text which may occur inside of sections -->
+<!ENTITY % sectionText "(text:h|text:p|text:ordered-list|
+						text:unordered-list|table:table|text:section|
+						text:table-of-content|text:illustration-index|
+						text:table-index|text:object-index|text:user-index|
+						text:alphabetical-index|text:bibliography|
+						text:index-title|%change-marks;)*">
+
+<!ENTITY % headerText "(%text-decls;, (text:h|text:p|text:ordered-list|
+						text:unordered-list|table:table|text:section|
+						text:table-of-content|text:illustration-index|
+						text:table-index|text:object-index|text:user-index|
+						text:alphabetical-index|text:bibliography|
+						text:index-title|%change-marks;)* )">
+
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/dialog.dtd
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/dialog.dtd	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/dialog.dtd	(revision 28000)
@@ -0,0 +1,369 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+        $Id: dialog.dtd,v 1.23 2002/03/25 12:03:20 dbo Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!ENTITY % boolean "(true|false)">
+<!ENTITY % numeric "CDATA">
+
+<!ENTITY % default-attributes "dlg:id CDATA #REQUIRED
+                               dlg:left %numeric; #REQUIRED
+                               dlg:top %numeric; #REQUIRED
+                               dlg:width %numeric; #REQUIRED
+                               dlg:height %numeric; #REQUIRED
+                               dlg:style-id CDATA #IMPLIED
+                               dlg:tab-index %numeric; #IMPLIED
+                               dlg:disabled %boolean; #IMPLIED
+                               dlg:printable %boolean; #IMPLIED
+                               dlg:page %numeric; #IMPLIED
+                               dlg:tag CDATA #IMPLIED
+                               dlg:help-text CDATA #IMPLIED
+                               dlg:help-url CDATA #IMPLIED
+                               ">
+
+<!ENTITY % event "(script:event|
+                   script:listener-event|
+                   dlg:event
+                  )">
+
+<!ENTITY % control "(dlg:bulletinboard|
+                     dlg:button|
+                     dlg:checkbox|
+                     dlg:combobox|
+                     dlg:menulist|
+                     dlg:radiogroup|
+                     dlg:titledbox|
+                     dlg:textfield|
+                     dlg:text|
+                     dlg:filecontrol|
+                     dlg:img|
+                     dlg:timefield|
+                     dlg:datefield|
+                     dlg:numericfield|
+                     dlg:currencyfield|
+                     dlg:patternfield|
+                     dlg:formattedfield|
+                     dlg:fixedline|
+                     dlg:progressmeter|
+                     dlg:scrollbar
+                    )">
+
+<!ELEMENT dlg:window (dlg:styles*, (%event;)*, dlg:bulletinboard*)>
+<!ATTLIST dlg:window %default-attributes;
+		     dlg:closeable %boolean; #IMPLIED
+		     dlg:moveable %boolean; #IMPLIED
+		     dlg:resizeable %boolean; #IMPLIED
+                     dlg:title CDATA #IMPLIED
+                     xmlns:dlg CDATA #FIXED "http://openoffice.org/2000/dialog"
+                     xmlns:script CDATA #FIXED "http://openoffice.org/2000/script"
+                     >
+
+<!ELEMENT dlg:styles (dlg:style+)>
+
+<!ELEMENT dlg:style EMPTY>
+<!ATTLIST dlg:style dlg:style-id CDATA #REQUIRED
+                    dlg:background-color %numeric; #IMPLIED
+                    dlg:text-color %numeric; #IMPLIED
+                    dlg:textline-color %numeric; #IMPLIED
+                    dlg:fill-color %numeric; #IMPLIED
+                    dlg:border (none|3d|simple) #IMPLIED
+                    dlg:font-name CDATA #IMPLIED
+                    dlg:font-height %numeric; #IMPLIED
+                    dlg:font-width %numeric; #IMPLIED
+                    dlg:font-stylename CDATA #IMPLIED
+                    dlg:font-family (decorative|modern|roman|script|swiss|system) #IMPLIED
+                    dlg:font-charset (ansi|mac|ibmpc_437|ibmpc_850|ibmpc_860|ibmpc_861|ibmpc_863|ibmpc_865|system|symbol) #IMPLIED
+                    dlg:font-pitch (fixed|variable) #IMPLIED
+                    dlg:font-charwidth %numeric; #IMPLIED
+                    dlg:font-weight %numeric; #IMPLIED
+                    dlg:font-slant (oblique|italic|reverse_oblique|reverse_italic) #IMPLIED
+                    dlg:font-underline (single|double|dotted|dash|longdash|dashdot|dashdotdot|smallwave|wave|doublewave|bold|bolddotted|bolddash|boldlongdash|bolddashdot|bolddashdotdot|boldwave) #IMPLIED
+                    dlg:font-strikeout (single|double|bold|slash|x) #IMPLIED
+                    dlg:font-orientation CDATA #IMPLIED
+                    dlg:font-kerning %boolean; #IMPLIED
+                    dlg:font-wordlinemode %boolean; #IMPLIED
+                    dlg:font-type (raster|device|scalable) #IMPLIED
+		    dialog:font-relief (none|embossed|engraved) #IMPLIED
+		    dialog:font-emphasismark (none|dot|circle|disc|accent|above|below) #IMPLIED
+                    >
+
+<!ELEMENT script:event EMPTY>
+<!ATTLIST script:event script:location CDATA #IMPLIED
+                       script:language CDATA #REQUIRED
+                       script:macro-name CDATA #REQUIRED
+                       script:event-name CDATA #REQUIRED
+                       >
+<!ELEMENT script:listener-event EMPTY>
+<!ATTLIST script:listener-event script:location CDATA #IMPLIED
+                                script:language CDATA #REQUIRED
+                                script:macro-name CDATA #REQUIRED
+                                script:listener-type CDATA #REQUIRED
+                                script:listener-method CDATA #REQUIRED
+                                script:listener-param CDATA #IMPLIED
+                                >
+<!-- deprecated -->
+<!ELEMENT dlg:event EMPTY>
+<!ATTLIST dlg:event dlg:listener-type CDATA #REQUIRED
+                    dlg:event-method CDATA #REQUIRED
+                    dlg:script-type CDATA #IMPLIED
+                    dlg:script-code CDATA #IMPLIED
+                    dlg:param CDATA #IMPLIED
+                    >
+<!-- /deprecated -->
+                        
+<!ELEMENT dlg:bulletinboard ((%control;)*)>
+<!ATTLIST dlg:bulletinboard dlg:left %numeric; #IMPLIED
+                            dlg:top %numeric; #IMPLIED
+                            >
+
+<!ELEMENT dlg:button ((%event;)*)>
+<!ATTLIST dlg:button %default-attributes;
+                     dlg:value CDATA #IMPLIED
+                     dlg:default %boolean; #IMPLIED
+                     dlg:tabstop %boolean; #IMPLIED
+                     dlg:image-src CDATA #IMPLIED
+                     dlg:image-align (top|left|right|bottom) #IMPLIED
+		     dlg:button-type (standard|ok|cancel|help) #IMPLIED
+                     >
+
+<!ELEMENT dlg:checkbox ((%event;)*)>
+<!ATTLIST dlg:checkbox %default-attributes;
+                       dlg:value CDATA #IMPLIED
+                       dlg:checked %boolean; #IMPLIED
+                       dlg:tristate %boolean; #IMPLIED
+                       dlg:tabstop %boolean; #IMPLIED
+                       >
+
+<!ELEMENT dlg:combobox (dlg:menupopup?, (%event;)*)>
+<!ATTLIST dlg:combobox %default-attributes;
+                       dlg:tabstop %boolean; #IMPLIED
+                       dlg:readonly %boolean; #IMPLIED
+                       dlg:autocomplete %boolean; #IMPLIED
+                       dlg:spin %boolean; #IMPLIED
+                       dlg:maxlength %numeric; #IMPLIED
+                       dlg:linecount %numeric; #IMPLIED
+                       dlg:value CDATA #IMPLIED
+                       >
+
+<!ELEMENT dlg:menulist (dlg:menupopup?, (%event;)*)>
+<!ATTLIST dlg:menulist %default-attributes;
+                       dlg:tabstop %boolean; #IMPLIED
+                       dlg:spin %boolean; #IMPLIED
+                       dlg:multiselection %boolean; #IMPLIED
+                       dlg:readonly %boolean; #IMPLIED
+                       dlg:linecount %numeric; #IMPLIED
+                       >
+
+<!ELEMENT dlg:menupopup (dlg:menuitem+)>
+<!ELEMENT dlg:menuitem EMPTY>
+<!ATTLIST dlg:menuitem dlg:value CDATA #REQUIRED
+                       dlg:selected %boolean; #IMPLIED
+                       >
+
+<!ELEMENT dlg:radiogroup (dlg:radio+)>
+<!ELEMENT dlg:radio ((%event;)*)>
+<!ATTLIST dlg:radio %default-attributes;
+                    dlg:value CDATA #IMPLIED
+                    dlg:checked %boolean; #IMPLIED
+                    dlg:tabstop %boolean; #IMPLIED
+                    >
+
+<!ELEMENT dlg:titledbox (dlg:title?, dlg:radio*, (%control;)*, (%event;)*)>
+<!ATTLIST dlg:titledbox %default-attributes;
+                        >
+<!ELEMENT dlg:title EMPTY>
+<!ATTLIST dlg:title dlg:value CDATA #IMPLIED
+                    >
+
+<!ELEMENT dlg:text ((%event;)*)>
+<!ATTLIST dlg:text %default-attributes;
+                   dlg:align (left|center|right) #IMPLIED
+                   dlg:multiline %boolean; #IMPLIED
+                   dlg:tabstop %boolean; #IMPLIED
+                   dlg:value CDATA #IMPLIED
+                   >
+
+<!ELEMENT dlg:textfield ((%event;)*)>
+<!ATTLIST dlg:textfield %default-attributes;
+                        dlg:tabstop %boolean; #IMPLIED
+                        dlg:align (left|center|right) #IMPLIED
+                        dlg:readonly %boolean; #IMPLIED
+                        dlg:echochar CDATA #IMPLIED
+                        dlg:hard-linebreaks %boolean; #IMPLIED
+                        dlg:hscroll %boolean; #IMPLIED
+                        dlg:vscroll %boolean; #IMPLIED
+                        dlg:maxlength %numeric; #IMPLIED
+                        dlg:multiline %boolean; #IMPLIED
+                        dlg:value CDATA #IMPLIED
+                        >
+
+<!ELEMENT dlg:img ((%event;)*)>
+<!ATTLIST dlg:img %default-attributes;
+                  dlg:src CDATA #IMPLIED
+                  dlg:scale-image %boolean; #IMPLIED
+                  >
+
+<!ELEMENT dlg:filecontrol ((%event;)*)>
+<!ATTLIST dlg:filecontrol %default-attributes;
+                          dlg:tabstop %boolean; #IMPLIED
+                          dlg:value CDATA #IMPLIED
+                          >
+
+<!ELEMENT dlg:currencyfield ((%event;)*)>
+<!ATTLIST dlg:currencyfield %default-attributes;
+                            dlg:tabstop %boolean; #IMPLIED
+                            dlg:readonly %boolean; #IMPLIED
+                            dlg:currency-symbol CDATA #IMPLIED
+                            dlg:strict-format %boolean; #IMPLIED
+                            dlg:decimal-accuracy %numeric; #IMPLIED
+                            dlg:thousands-separator %boolean; #IMPLIED
+                            dlg:value %numeric; #IMPLIED
+                            dlg:value-min %numeric; #IMPLIED
+                            dlg:value-max %numeric; #IMPLIED
+                            dlg:value-step %numeric; #IMPLIED
+                            dlg:spin %boolean; #IMPLIED
+                            dlg:prepend-symbol %boolean; #IMPLIED
+                            >
+
+<!ELEMENT dlg:datefield ((%event;)*)>
+<!ATTLIST dlg:datefield %default-attributes;
+                        dlg:tabstop %boolean; #IMPLIED
+                        dlg:readonly %boolean; #IMPLIED
+                        dlg:strict-format %boolean; #IMPLIED
+                        dlg:date-format (system_short|system_short_YY|system_short_YYYY|system_long|short_DDMMYY|short_MMDDYY|short_YYMMDD|short_DDMMYYYY|short_MMDDYYYY|short_YYYYMMDD|short_YYMMDD_DIN5008|short_YYYYMMDD_DIN5008) #IMPLIED
+                        dlg:show-century %boolean; #IMPLIED
+                        dlg:value CDATA #IMPLIED
+                        dlg:value-min CDATA #IMPLIED
+                        dlg:value-max CDATA #IMPLIED
+                        dlg:spin %boolean; #IMPLIED
+                        dlg:dropdown %boolean; #IMPLIED
+                        >
+
+<!ELEMENT dlg:numericfield ((%event;)*)>
+<!ATTLIST dlg:numericfield %default-attributes;
+                           dlg:tabstop %boolean; #IMPLIED
+                           dlg:readonly %boolean; #IMPLIED
+                           dlg:strict-format %boolean; #IMPLIED
+                           dlg:decimal-accuracy %numeric; #IMPLIED
+                           dlg:thousands-separator %boolean; #IMPLIED
+                           dlg:value %numeric; #IMPLIED
+                           dlg:value-min %numeric; #IMPLIED
+                           dlg:value-max %numeric; #IMPLIED
+                           dlg:value-step %numeric; #IMPLIED
+                           dlg:spin %boolean; #IMPLIED
+                           >
+
+<!ELEMENT dlg:timefield ((%event;)*)>
+<!ATTLIST dlg:timefield %default-attributes;
+                        dlg:tabstop %boolean; #IMPLIED
+                        dlg:readonly %boolean; #IMPLIED
+                        dlg:strict-format %boolean; #IMPLIED
+                        dlg:time-format (24h_short|24h_long|12h_short|12h_long|Duration_short|Duration_long) #IMPLIED
+                        dlg:value CDATA #IMPLIED
+                        dlg:value-min CDATA #IMPLIED
+                        dlg:value-max CDATA #IMPLIED
+                        dlg:spin %boolean; #IMPLIED
+                        >
+
+<!ELEMENT dlg:patternfield ((%event;)*)>
+<!ATTLIST dlg:patternfield %default-attributes;
+                           dlg:tabstop %boolean; #IMPLIED
+                           dlg:readonly %boolean; #IMPLIED
+                           dlg:strict-format %boolean; #IMPLIED
+                           dlg:value CDATA #IMPLIED
+                           dlg:maxlength %numeric; #IMPLIED
+                           dlg:edit-mask CDATA #IMPLIED
+                           dlg:literal-mask CDATA #IMPLIED
+                           >
+
+<!ELEMENT dlg:formattedfield ((%event;)*)>
+<!ATTLIST dlg:formattedfield %default-attributes;
+			     dlg:tabstop %boolean; #IMPLIED
+			     dlg:readonly %boolean; #IMPLIED
+			     dlg:align (left|center|right) #IMPLIED
+			     dlg:format-code CDATA #IMPLIED
+			     dlg:format-locale CDATA #IMPLIED
+			     dlg:treat-as-number %boolean; #IMPLIED
+			     dlg:strict-format %boolean; #IMPLIED
+			     dlg:value-default CDATA #IMPLIED
+			     dlg:value-max %numeric; #IMPLIED
+			     dlg:value-min %numeric; #IMPLIED
+			     dlg:value %numeric; #IMPLIED
+			     dlg:maxlength %numeric; #IMPLIED
+			     dlg:spin %boolean; #IMPLIED
+			     dlg:text CDATA #IMPLIED
+			     >
+
+<!ELEMENT dlg:fixedline ((%event;)*)>
+<!ATTLIST dlg:fixedline %default-attributes;
+                        dlg:align (horizontal|vertical) #IMPLIED
+                        dlg:value CDATA #IMPLIED
+                        >
+
+<!ELEMENT dlg:scrollbar ((%event;)*)>
+<!ATTLIST dlg:scrollbar %default-attributes;
+                        dlg:align (horizontal|vertical) #IMPLIED
+                        dlg:curpos %numeric; #IMPLIED
+                        dlg:maxpos %numeric; #IMPLIED
+                        dlg:increment %numeric; #IMPLIED
+                        dlg:pageincrement %numeric; #IMPLIED
+                        dlg:visible-size %numeric; #IMPLIED
+                        >
+
+<!ELEMENT dlg:progressmeter ((%event;)*)>
+<!ATTLIST dlg:progressmeter %default-attributes;
+                            dlg:value %numeric; #IMPLIED
+                            dlg:value-min %numeric; #IMPLIED
+                            dlg:value-max %numeric; #IMPLIED
+                            >
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/drawing.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/drawing.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/drawing.mod	(revision 28000)
@@ -0,0 +1,886 @@
+<!--
+	$Id: drawing.mod,v 1.83 2003/03/27 18:19:53 hr Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!ENTITY % points "CDATA" >
+<!ENTITY % pathData "CDATA" >
+<!ENTITY % gradient-style "(linear|axial|radial|ellipsoid|square|rectangular)" >
+<!ENTITY % draw-position "svg:x %coordinate; #IMPLIED svg:y %coordinate; #IMPLIED">
+<!ENTITY % draw-end-position "table:end-cell-address %cell-address; #IMPLIED table:end-x %coordinate; #IMPLIED table:end-y %coordinate; #IMPLIED">
+<!ENTITY % draw-size "svg:width %coordinate; #IMPLIED svg:height %coordinate; #IMPLIED">
+<!ENTITY % draw-transform "draw:transform CDATA #IMPLIED">
+<!ENTITY % draw-viewbox "svg:viewBox CDATA #REQUIRED">
+<!ENTITY % draw-style-name "draw:style-name %styleName; #IMPLIED presentation:style-name %styleName; #IMPLIED draw:text-style-name %styleName; #IMPLIED">
+<!ENTITY % draw-shape-id "CDATA #IMPLIED" >
+<!ENTITY % draw-text "(text:p|text:unordered-list|text:ordered-list)*">
+<!ENTITY % zindex "draw:z-index %nonNegativeInteger; #IMPLIED">
+<!ENTITY % distance "CDATA">
+<!ENTITY % rectanglePoint "(top-left|top|top-right|left|center|right|bottom-left|bottom|bottom-right)">
+<!ENTITY % vector3D "CDATA">
+<!ENTITY % text-anchor "text:anchor-type %anchorType; #IMPLIED text:anchor-page-number %positiveInteger; #IMPLIED">
+<!ENTITY % layerName "CDATA">
+<!ENTITY % table-background "table:table-background (true | false) #IMPLIED">
+
+<!-- commont presentation shape attributes -->
+<!ENTITY % presentation-style-name "presentation:style-name %styleName; #IMPLIED">
+<!ENTITY % presentation-classes "(title|outline|subtitle|text|graphic|object|chart|table|orgchart|page|notes)" >
+<!-- ENTITY % presentation-class "presentation:class %presentation-classes; #IMPLIED" -->
+<!ENTITY % presentation-class "presentation:class %presentation-classes; #IMPLIED presentation:placeholder (true|false) #IMPLIED presentation:user-transformed (true|false) #IMPLIED">
+<!ENTITY % presentationEffects "(none|fade|move|stripes|open|close|dissolve|wavyline|random|lines|laser|appear|hide|move-short|checkerboard|rotate|stretch)" >
+<!ENTITY % presentationEffectDirections "(none|from-left|from-top|from-right|from-bottom|from-center|from-upper-left|from-upper-right|from-lower-left|from-lower-right|to-left|to-top|to-right|to-bottom|to-upper-left|to-upper-right|to-lower-right|to-lower-left|path|spiral-inward-left|spiral-inward-right|spiral-outward-left|spiral-outward-right|vertical|horizontal|to-center|clockwise|counter-clockwise)" >
+<!ENTITY % presentationSpeeds "(slow|medium|fast)" >
+
+<!-- Drawing shapes -->
+<!ELEMENT draw:rect ( office:events?, %draw-text; )>
+<!ATTLIST draw:rect %draw-position; >
+<!ATTLIST draw:rect %draw-end-position; >
+<!ATTLIST draw:rect %table-background; >
+<!ATTLIST draw:rect %draw-size; >
+<!ATTLIST draw:rect %draw-style-name; >
+<!ATTLIST draw:rect %draw-transform; >
+<!ATTLIST draw:rect draw:corner-radius %nonNegativeLength; #IMPLIED>
+<!ATTLIST draw:rect %zindex;>
+<!ATTLIST draw:rect draw:id %draw-shape-id;>
+<!ATTLIST draw:rect %text-anchor;>
+<!ATTLIST draw:rect draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT draw:line ( office:events?, %draw-text; )>
+<!ATTLIST draw:line svg:x1 %length; #IMPLIED>
+<!ATTLIST draw:line svg:y1 %length; #IMPLIED>
+<!ATTLIST draw:line svg:x2 %length; #REQUIRED>
+<!ATTLIST draw:line svg:y2 %length; #REQUIRED>
+<!ATTLIST draw:line svg:y %coordinate; #IMPLIED>
+<!ATTLIST draw:line %draw-style-name; >
+<!ATTLIST draw:line %draw-transform; >
+<!ATTLIST draw:line %zindex;>
+<!ATTLIST draw:line %draw-end-position; >
+<!ATTLIST draw:line %table-background; >
+<!ATTLIST draw:line draw:id %draw-shape-id;>
+<!ATTLIST draw:line %text-anchor;>
+<!ATTLIST draw:line draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT draw:polyline ( office:events?, %draw-text; )>
+<!ATTLIST draw:polyline %draw-position; >
+<!ATTLIST draw:polyline %draw-size; >
+<!ATTLIST draw:polyline %draw-viewbox; >
+<!ATTLIST draw:polyline draw:points %points; #REQUIRED>
+<!ATTLIST draw:polyline %draw-style-name; >
+<!ATTLIST draw:polyline %draw-transform; >
+<!ATTLIST draw:polyline %zindex;>
+<!ATTLIST draw:polyline %draw-end-position; >
+<!ATTLIST draw:polyline %table-background; >
+<!ATTLIST draw:polyline draw:id %draw-shape-id;>
+<!ATTLIST draw:polyline %text-anchor;>
+<!ATTLIST draw:polyline draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT draw:polygon ( office:events?, %draw-text; )>
+<!ATTLIST draw:polygon %draw-position; >
+<!ATTLIST draw:polygon %draw-end-position; >
+<!ATTLIST draw:polygon %table-background; >
+<!ATTLIST draw:polygon %draw-size; >
+<!ATTLIST draw:polygon %draw-viewbox; >
+<!ATTLIST draw:polygon draw:points %points; #REQUIRED >
+<!ATTLIST draw:polygon %draw-style-name; >
+<!ATTLIST draw:polygon %draw-transform; >
+<!ATTLIST draw:polygon %zindex;>
+<!ATTLIST draw:polygon draw:id %draw-shape-id;>
+<!ATTLIST draw:polygon %text-anchor;>
+<!ATTLIST draw:polygon draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT draw:path ( office:events?, %draw-text; )>
+<!ATTLIST draw:path %draw-position;>
+<!ATTLIST draw:path %draw-end-position; >
+<!ATTLIST draw:path %table-background; >
+<!ATTLIST draw:path %draw-size; >
+<!ATTLIST draw:path %draw-viewbox; >
+<!ATTLIST draw:path svg:d %pathData; #REQUIRED >
+<!ATTLIST draw:path %draw-style-name; >
+<!ATTLIST draw:path %draw-transform; >
+<!ATTLIST draw:path %zindex;>
+<!ATTLIST draw:path draw:id %draw-shape-id;>
+<!ATTLIST draw:path %text-anchor;>
+<!ATTLIST draw:path draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT draw:circle ( office:events?, %draw-text; )>
+<!ATTLIST draw:circle %draw-position; >
+<!ATTLIST draw:circle %draw-size; >
+<!ATTLIST draw:circle %draw-style-name; >
+<!ATTLIST draw:circle %draw-transform; >
+<!ATTLIST draw:circle %zindex;>
+<!ATTLIST draw:circle %draw-end-position; >
+<!ATTLIST draw:circle %table-background; >
+<!ATTLIST draw:circle draw:id %draw-shape-id;>
+<!ATTLIST draw:circle draw:kind (full|section|cut|arc) "full">
+<!ATTLIST draw:circle draw:start-angle %nonNegativeInteger; #IMPLIED>
+<!ATTLIST draw:circle draw:end-angle %nonNegativeInteger; #IMPLIED>
+<!ATTLIST draw:circle %text-anchor;>
+<!ATTLIST draw:circle draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT draw:ellipse ( office:events?, %draw-text; )>
+<!ATTLIST draw:ellipse %draw-position; >
+<!ATTLIST draw:ellipse %draw-size; >
+<!ATTLIST draw:ellipse %draw-style-name; >
+<!ATTLIST draw:ellipse %draw-transform; >
+<!ATTLIST draw:ellipse %zindex;>
+<!ATTLIST draw:ellipse %draw-end-position; >
+<!ATTLIST draw:ellipse %table-background; >
+<!ATTLIST draw:ellipse draw:id %draw-shape-id;>
+<!ATTLIST draw:ellipse draw:kind (full|section|cut|arc) "full">
+<!ATTLIST draw:ellipse draw:start-angle %nonNegativeInteger; #IMPLIED>
+<!ATTLIST draw:ellipse draw:end-angle %nonNegativeInteger; #IMPLIED>
+<!ATTLIST draw:ellipse  %text-anchor;>
+<!ATTLIST draw:ellipse draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT draw:connector ( office:events?, %draw-text;)>
+<!ATTLIST draw:connector draw:type (standard|lines|line|curve) "standard">
+<!ATTLIST draw:connector draw:line-skew CDATA #IMPLIED>
+<!ATTLIST draw:connector %draw-style-name;>
+<!ATTLIST draw:connector svg:x1 %coordinate; #REQUIRED>
+<!ATTLIST draw:connector svg:y1 %coordinate; #REQUIRED>
+<!ATTLIST draw:connector svg:x2 %coordinate; #REQUIRED>
+<!ATTLIST draw:connector svg:y2 %coordinate; #REQUIRED>
+<!ATTLIST draw:connector draw:start-shape %draw-shape-id;>
+<!ATTLIST draw:connector draw:start-glue-point %integer; #IMPLIED>
+<!ATTLIST draw:connector draw:end-shape %draw-shape-id;>
+<!ATTLIST draw:connector draw:end-glue-point %integer; #IMPLIED>
+<!ATTLIST draw:connector %zindex;>
+<!ATTLIST draw:connector %draw-end-position; >
+<!ATTLIST draw:connector %table-background; >
+<!ATTLIST draw:connector draw:id %draw-shape-id;>
+<!ATTLIST draw:connector %text-anchor;>
+<!ATTLIST draw:connector draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT draw:control EMPTY>
+<!ATTLIST draw:control %draw-style-name;>
+<!ATTLIST draw:control %draw-position; >
+<!ATTLIST draw:control %draw-size; >
+<!ATTLIST draw:control %control-id; >
+<!ATTLIST draw:control %zindex;>
+<!ATTLIST draw:control %draw-end-position; >
+<!ATTLIST draw:control %table-background; >
+<!ATTLIST draw:control draw:id %draw-shape-id;>
+<!ATTLIST draw:control %text-anchor;>
+<!ATTLIST draw:control draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT draw:g ( office:events?, (%shapes;)* ) >
+<!ATTLIST draw:g svg:y %coordinate; #IMPLIED>
+<!ATTLIST draw:g %draw-transform; >
+<!ATTLIST draw:g draw:name %string; #IMPLIED>
+<!ATTLIST draw:g %draw-style-name; >
+<!ATTLIST draw:g %zindex;>
+<!ATTLIST draw:g %draw-end-position; >
+<!ATTLIST draw:g %table-background; >
+<!ATTLIST draw:g draw:id %draw-shape-id;>
+<!ATTLIST draw:g %text-anchor;>
+<!ATTLIST draw:g draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT draw:page-thumbnail EMPTY>
+<!ATTLIST draw:page-thumbnail draw:page-number %positiveInteger; #IMPLIED>
+<!ATTLIST draw:page-thumbnail %draw-position; >
+<!ATTLIST draw:page-thumbnail %draw-size; >
+<!ATTLIST draw:page-thumbnail %draw-style-name; >
+<!ATTLIST draw:page-thumbnail %presentation-class; >
+<!ATTLIST draw:page-thumbnail %zindex;>
+<!ATTLIST draw:page-thumbnail %draw-end-position; >
+<!ATTLIST draw:page-thumbnail %table-background; >
+<!ATTLIST draw:page-thumbnail draw:id %draw-shape-id;>
+<!ATTLIST draw:page-thumbnail %text-anchor;>
+<!ATTLIST draw:page-thumbnail draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT draw:caption ( office:events?, %draw-text;)>
+<!ATTLIST draw:caption %draw-position; >
+<!ATTLIST draw:caption %draw-end-position; >
+<!ATTLIST draw:caption %table-background; >
+<!ATTLIST draw:caption %draw-size; >
+<!ATTLIST draw:caption %draw-style-name; >
+<!ATTLIST draw:caption %draw-transform; >
+<!ATTLIST draw:caption draw:caption-point-x %coordinate; #IMPLIED>
+<!ATTLIST draw:caption draw:caption-point-y %coordinate; #IMPLIED>
+<!ATTLIST draw:caption %zindex;>
+<!ATTLIST draw:caption draw:id %draw-shape-id;>
+<!ATTLIST draw:caption  %text-anchor;>
+<!ATTLIST draw:caption draw:layer %layerName; #IMPLIED>
+<!ATTLIST draw:caption draw:corner-radius %nonNegativeLength; #IMPLIED>
+
+<!ELEMENT draw:measure ( office:events?, %draw-text;)>
+<!ATTLIST draw:measure svg:x1 %coordinate; #REQUIRED>
+<!ATTLIST draw:measure svg:y1 %coordinate; #REQUIRED>
+<!ATTLIST draw:measure svg:x2 %coordinate; #REQUIRED>
+<!ATTLIST draw:measure svg:y2 %coordinate; #REQUIRED>
+<!ATTLIST draw:measure %draw-end-position; >
+<!ATTLIST draw:measure %table-background; >
+<!ATTLIST draw:measure %draw-style-name; >
+<!ATTLIST draw:measure %draw-transform; >
+<!ATTLIST draw:measure %zindex;>
+<!ATTLIST draw:measure draw:id %draw-shape-id;>
+<!ATTLIST draw:measure %text-anchor;>
+<!ATTLIST draw:measure draw:layer %layerName; #IMPLIED>
+
+<!-- graphic style elements -->
+<!ELEMENT draw:gradient EMPTY >
+<!ATTLIST draw:gradient draw:name %styleName; #REQUIRED>
+<!ATTLIST draw:gradient draw:style %gradient-style; #REQUIRED>
+<!ATTLIST draw:gradient draw:cx %coordinate; #IMPLIED>
+<!ATTLIST draw:gradient draw:cy %coordinate; #IMPLIED>
+<!ATTLIST draw:gradient draw:start-color %color; #IMPLIED>
+<!ATTLIST draw:gradient draw:end-color %color; #IMPLIED>
+<!ATTLIST draw:gradient draw:start-intensity %percentage; #IMPLIED>
+<!ATTLIST draw:gradient draw:end-intensity %percentage; #IMPLIED>
+<!ATTLIST draw:gradient draw:angle %integer; #IMPLIED>
+<!ATTLIST draw:gradient draw:border %percentage; #IMPLIED>
+
+<!ELEMENT draw:hatch EMPTY >
+<!ATTLIST draw:hatch draw:name %styleName; #REQUIRED>
+<!ATTLIST draw:hatch draw:style (single|double|triple) #REQUIRED >
+<!ATTLIST draw:hatch draw:color %color; #IMPLIED>
+<!ATTLIST draw:hatch draw:distance %length; #IMPLIED>
+<!ATTLIST draw:hatch draw:rotation %integer; #IMPLIED>
+
+
+<!ELEMENT draw:fill-image EMPTY >
+<!ATTLIST draw:fill-image draw:name %styleName; #REQUIRED>
+<!ATTLIST draw:fill-image xlink:href %uriReference; #REQUIRED>
+<!ATTLIST draw:fill-image xlink:type (simple) #IMPLIED>
+<!ATTLIST draw:fill-image xlink:show (embed) #IMPLIED>
+<!ATTLIST draw:fill-image xlink:actuate (onLoad) #IMPLIED>
+<!ATTLIST draw:fill-image svg:width %length; #IMPLIED>
+<!ATTLIST draw:fill-image svg:height %length; #IMPLIED>
+
+<!ELEMENT draw:transparency EMPTY>
+<!ATTLIST draw:transparency draw:name %styleName; #REQUIRED>
+<!ATTLIST draw:transparency draw:style %gradient-style; #REQUIRED>
+<!ATTLIST draw:transparency draw:cx %coordinate; #IMPLIED>
+<!ATTLIST draw:transparency draw:cy %coordinate; #IMPLIED>
+<!ATTLIST draw:transparency draw:start %percentage; #IMPLIED>
+<!ATTLIST draw:transparency draw:end %percentage; #IMPLIED>
+<!ATTLIST draw:transparency draw:angle %integer; #IMPLIED>
+<!ATTLIST draw:transparency draw:border %percentage; #IMPLIED>
+
+<!ELEMENT draw:marker EMPTY>
+<!ATTLIST draw:marker draw:name %styleName; #REQUIRED>
+<!ATTLIST draw:marker %draw-viewbox; >
+<!ATTLIST draw:marker svg:d %pathData; #REQUIRED>
+
+<!ELEMENT draw:stroke-dash EMPTY>
+<!ATTLIST draw:stroke-dash draw:name %styleName; #REQUIRED>
+<!ATTLIST draw:stroke-dash draw:style (rect|round) #IMPLIED>
+<!ATTLIST draw:stroke-dash draw:dots1 %integer; #IMPLIED>
+<!ATTLIST draw:stroke-dash draw:dots1-length %length; #IMPLIED>
+<!ATTLIST draw:stroke-dash draw:dots2 %integer; #IMPLIED>
+<!ATTLIST draw:stroke-dash draw:dots2-length %length; #IMPLIED>
+<!ATTLIST draw:stroke-dash draw:distance %length; #IMPLIED>
+
+<!-- stroke attributes -->
+<!ATTLIST style:properties draw:stroke (none|dash|solid) #IMPLIED>
+<!ATTLIST style:properties draw:stroke-dash CDATA #IMPLIED>
+<!ATTLIST style:properties svg:stroke-width %length; #IMPLIED>
+<!ATTLIST style:properties svg:stroke-color %color; #IMPLIED>
+<!ATTLIST style:properties draw:marker-start %styleName; #IMPLIED>
+<!ATTLIST style:properties draw:marker-end %styleName; #IMPLIED>
+<!ATTLIST style:properties draw:marker-start-width %length; #IMPLIED>
+<!ATTLIST style:properties draw:marker-end-width %length; #IMPLIED>
+<!ATTLIST style:properties draw:marker-start-center %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:marker-end-center %boolean; #IMPLIED>
+<!ATTLIST style:properties svg:stroke-opacity %floatOrPercentage; #IMPLIED>
+<!ATTLIST style:properties svg:stroke-linejoin (miter|round|bevel|middle|none|inherit) #IMPLIED>
+
+<!-- text attributes -->
+<!ATTLIST style:properties draw:auto-grow-width %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:auto-grow-height %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:fit-to-size %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:fit-to-contour %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:textarea-horizontal-align ( left | center | right | justify ) #IMPLIED>
+<!ATTLIST style:properties draw:textarea-vertical-align ( top | middle | bottom | justify ) #IMPLIED>
+<!ATTLIST style:properties draw:writing-mode (lr-tb|tb-rl) "lr-tb">
+
+<!-- fill attributes -->
+<!ATTLIST style:properties draw:fill (none|solid|bitmap|gradient|hatch) #IMPLIED>
+<!ATTLIST style:properties draw:fill-color %color; #IMPLIED>
+<!ATTLIST style:properties draw:fill-gradient-name %styleName; #IMPLIED>
+<!ATTLIST style:properties draw:gradient-step-count CDATA #IMPLIED>
+<!ATTLIST style:properties draw:fill-hatch-name %styleName; #IMPLIED>
+<!ATTLIST style:properties draw:fill-hatch-solid %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:fill-image-name %styleName; #IMPLIED>
+<!ATTLIST style:properties style:repeat (no-repeat|repeat|stretch) #IMPLIED>
+<!ATTLIST style:properties draw:fill-image-width %lengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties draw:fill-image-height %lengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties draw:fill-image-ref-point-x %percentage; #IMPLIED>
+<!ATTLIST style:properties draw:fill-image-ref-point-y %percentage; #IMPLIED>
+<!ATTLIST style:properties draw:fill-image-ref-point %rectanglePoint; #IMPLIED>
+<!ATTLIST style:properties draw:tile-repeat-offset CDATA #IMPLIED>
+<!ATTLIST style:properties draw:transparency %percentage; #IMPLIED>
+<!ATTLIST style:properties draw:transparency-name %styleName; #IMPLIED>
+
+<!-- graphic attributes -->
+<!ATTLIST style:properties draw:color-mode (greyscale|mono|watermark|standard) #IMPLIED>
+<!ATTLIST style:properties draw:luminance %percentage; #IMPLIED>
+<!ATTLIST style:properties draw:contrast %percentage; #IMPLIED>
+<!ATTLIST style:properties draw:gamma %percentage; #IMPLIED>
+<!ATTLIST style:properties draw:red %percentage; #IMPLIED>
+<!ATTLIST style:properties draw:green %percentage; #IMPLIED>
+<!ATTLIST style:properties draw:blue %percentage; #IMPLIED>
+<!ATTLIST style:properties draw:color-inversion %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:mirror %boolean; #IMPLIED>
+
+<!-- shadow attributes -->
+<!ATTLIST style:properties draw:shadow (visible|hidden) #IMPLIED>
+<!ATTLIST style:properties draw:shadow-offset-x %length; #IMPLIED>
+<!ATTLIST style:properties draw:shadow-offset-y %length; #IMPLIED>
+<!ATTLIST style:properties draw:shadow-color %color; #IMPLIED>
+<!ATTLIST style:properties draw:shadow-transparency CDATA #IMPLIED>
+
+<!-- connector attributes -->
+<!ATTLIST style:properties draw:start-line-spacing-horizontal %distance; #IMPLIED>
+<!ATTLIST style:properties draw:start-line-spacing-vertical %distance; #IMPLIED>
+<!ATTLIST style:properties draw:end-line-spacing-horizontal %distance; #IMPLIED>
+<!ATTLIST style:properties draw:end-line-spacing-vertical %distance; #IMPLIED>
+
+<!-- measure attributes -->
+<!ATTLIST style:properties draw:line-distance %distance; #IMPLIED>
+<!ATTLIST style:properties draw:guide-overhang %distance; #IMPLIED>
+<!ATTLIST style:properties draw:guide-distance %distance; #IMPLIED>
+<!ATTLIST style:properties draw:start-guide %distance; #IMPLIED>
+<!ATTLIST style:properties draw:end-guide %distance; #IMPLIED>
+<!ATTLIST style:properties draw:measure-align (automatic|left-outside|inside|right-outside) #IMPLIED>
+<!ATTLIST style:properties draw:measure-vertical-align (automatic|above|below|center) #IMPLIED>
+<!ATTLIST style:properties draw:unit (automatic|mm|cm|m|km|pt|pc|inch|ft|mi) #IMPLIED>
+<!ATTLIST style:properties draw:show-unit %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:placing (below|above) #IMPLIED>
+<!ATTLIST style:properties draw:parallel %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:decimal-places %nonNegativeLength; #IMPLIED>
+
+<!-- frame attributes -->
+<!ATTLIST style:properties draw:frame-display-scrollbar %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:frame-display-border %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:frame-margin-horizontal %nonNegativePixelLength; #IMPLIED>
+<!ATTLIST style:properties draw:frame-margin-vertical %nonNegativePixelLength; #IMPLIED>
+<!ATTLIST style:properties draw:size-protect %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:move-protect %boolean; #IMPLIED>
+
+<!-- ole object attributes -->
+<!ATTLIST style:properties draw:visible-area-left %nonNegativeLength; #IMPLIED>
+<!ATTLIST style:properties draw:visible-area-top %nonNegativeLength; #IMPLIED>
+<!ATTLIST style:properties draw:visible-area-width %positiveLength; #IMPLIED>
+<!ATTLIST style:properties draw:visible-area-height %positiveLength; #IMPLIED>
+
+<!-- fontwork attributes -->
+<!ATTLIST style:properties draw:fontwork-style (rotate|upright|slant-x|slant-y|none) #IMPLIED>
+<!ATTLIST style:properties draw:fontwork-adjust (left|right|autosize|center) #IMPLIED>
+<!ATTLIST style:properties draw:fontwork-distance %distance; #IMPLIED>
+<!ATTLIST style:properties draw:fontwork-start %distance; #IMPLIED>
+<!ATTLIST style:properties draw:fontwork-mirror %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:fontwork-outline %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:fontwork-shadow (normal|slant|none) #IMPLIED>
+<!ATTLIST style:properties draw:fontwork-shadow-color %color; #IMPLIED>
+<!ATTLIST style:properties draw:fontwork-shadow-offset-x %distance; #IMPLIED>
+<!ATTLIST style:properties draw:fontwork-shadow-offset-y %distance; #IMPLIED>
+<!ATTLIST style:properties draw:fontwork-form (none|top-circle|bottom-circle|left-circle|right-circle|top-arc|bottom-arc|left-arc|right-arc|button1|button2|button3|button4) #IMPLIED>
+<!ATTLIST style:properties draw:fontwork-hide-form %boolean; #IMPLIED>
+<!ATTLIST style:properties draw:fontwork-shadow-transparence %percentage; #IMPLIED>
+
+<!-- caption attributes -->
+<!ATTLIST style:properties draw:caption-type (straight-line|angled-line|angled-connector-line) #IMPLIED>
+<!ATTLIST style:properties draw:caption-angle-type (fixed|free) #IMPLIED>
+<!ATTLIST style:properties draw:caption-angle %nonNegativeInteger; #IMPLIED>
+<!ATTLIST style:properties draw:caption-gap %distance; #IMPLIED>
+<!ATTLIST style:properties draw:caption-escape-direction (horizontal|vertical|auto) #IMPLIED>
+<!ATTLIST style:properties draw:caption-escape %lengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties draw:caption-line-length %distance; #IMPLIED>
+<!ATTLIST style:properties draw:caption-fit-line-length %boolean; #IMPLIED>
+
+<!-- Animations -->
+<!ELEMENT presentation:sound EMPTY>
+<!ATTLIST presentation:sound xlink:href %uriReference; #REQUIRED>
+<!ATTLIST presentation:sound xlink:type (simple) #FIXED "simple">
+<!ATTLIST presentation:sound xlink:show (new|replace) #IMPLIED>
+<!ATTLIST presentation:sound xlink:actuate (onRequest) "onRequest">
+<!ATTLIST presentation:sound presentation:play-full %boolean; #IMPLIED>
+
+<!ELEMENT presentation:show-shape (presentation:sound)?>
+<!ATTLIST presentation:show-shape draw:shape-id CDATA #REQUIRED>
+<!ATTLIST presentation:show-shape presentation:effect %presentationEffects; "none">
+<!ATTLIST presentation:show-shape presentation:direction %presentationEffectDirections; "none">
+<!ATTLIST presentation:show-shape presentation:speed %presentationSpeeds; "medium">
+<!ATTLIST presentation:show-shape presentation:start-scale %percentage; "100%">
+<!ATTLIST presentation:show-shape presentation:path-id CDATA #IMPLIED >
+
+<!ELEMENT presentation:show-text (presentation:sound)?>
+<!ATTLIST presentation:show-text draw:shape-id CDATA #REQUIRED>
+<!ATTLIST presentation:show-text presentation:effect %presentationEffects; "none">
+<!ATTLIST presentation:show-text presentation:direction %presentationEffectDirections; "none">
+<!ATTLIST presentation:show-text presentation:speed %presentationSpeeds; "medium">
+<!ATTLIST presentation:show-text presentation:start-scale %percentage; "100%">
+<!ATTLIST presentation:show-text presentation:path-id CDATA #IMPLIED >
+
+<!ELEMENT presentation:hide-shape (presentation:sound)?>
+<!ATTLIST presentation:hide-shape draw:shape-id CDATA #REQUIRED>
+<!ATTLIST presentation:hide-shape presentation:effect %presentationEffects; "none">
+<!ATTLIST presentation:hide-shape presentation:direction %presentationEffectDirections; "none">
+<!ATTLIST presentation:hide-shape presentation:speed %presentationSpeeds; "medium">
+<!ATTLIST presentation:hide-shape presentation:start-scale %percentage; "100%">
+<!ATTLIST presentation:hide-shape presentation:path-id CDATA #IMPLIED >
+
+<!ELEMENT presentation:hide-text (presentation:sound)?>
+<!ATTLIST presentation:hide-text draw:shape-id CDATA #REQUIRED>
+<!ATTLIST presentation:hide-text presentation:effect %presentationEffects; "none">
+<!ATTLIST presentation:hide-text presentation:direction %presentationEffectDirections; "none">
+<!ATTLIST presentation:hide-text presentation:speed %presentationSpeeds; "medium">
+<!ATTLIST presentation:hide-text presentation:start-scale %percentage; "100%">
+<!ATTLIST presentation:hide-text presentation:path-id CDATA #IMPLIED >
+
+<!ELEMENT presentation:dim (presentation:sound)?>
+<!ATTLIST presentation:dim draw:shape-id CDATA #REQUIRED>
+<!ATTLIST presentation:dim draw:color %color; #REQUIRED>
+
+<!ELEMENT presentation:play EMPTY>
+<!ATTLIST presentation:play draw:shape-id CDATA #REQUIRED>
+<!ATTLIST presentation:play presentation:speed %presentationSpeeds; "medium">
+
+<!ELEMENT presentation:animations (presentation:show-shape|presentation:show-text|presentation:hide-shape|presentation:hide-text|presentation:dim|presentation:play)*>
+
+<!ELEMENT presentation:show EMPTY>
+<!ATTLIST presentation:show presentation:name %styleName; #REQUIRED>
+<!ATTLIST presentation:show presentation:pages CDATA #REQUIRED>
+
+<!ELEMENT presentation:settings (presentation:show)*>
+<!ATTLIST presentation:settings presentation:start-page %styleName; #IMPLIED>
+<!ATTLIST presentation:settings presentation:show %styleName; #IMPLIED>
+<!ATTLIST presentation:settings presentation:full-screen %boolean; "true">
+<!ATTLIST presentation:settings presentation:endless %boolean; "false">
+<!ATTLIST presentation:settings presentation:pause %timeDuration; #IMPLIED>
+<!ATTLIST presentation:settings presentation:show-logo %boolean; "false">
+<!ATTLIST presentation:settings presentation:force-manual %boolean; "false">
+<!ATTLIST presentation:settings presentation:mouse-visible %boolean; "true">
+<!ATTLIST presentation:settings presentation:mouse-as-pen %boolean; "false">
+<!ATTLIST presentation:settings presentation:start-with-navigator %boolean; "false">
+<!ATTLIST presentation:settings presentation:animations (enabled|disabled) "enabled">
+<!ATTLIST presentation:settings presentation:stay-on-top %boolean; "false">
+<!ATTLIST presentation:settings presentation:transition-on-click (enabled|disabled) "enabled">
+
+<!-- Drawing page -->
+<!ELEMENT draw:page (office:forms?,(%shapes;)*,presentation:animations?,presentation:notes?)>
+<!ATTLIST draw:page draw:name %string; #IMPLIED>
+<!ATTLIST draw:page draw:style-name %styleName; #IMPLIED>
+<!ATTLIST draw:page draw:master-page-name %styleName; #REQUIRED>
+<!ATTLIST draw:page presentation:presentation-page-layout-name %styleName; #IMPLIED>
+<!ATTLIST draw:page draw:id %nonNegativeInteger; #IMPLIED>
+<!ATTLIST draw:page xlink:href %uriReference; #IMPLIED>
+<!ATTLIST draw:page xlink:type (simple) #IMPLIED>
+<!ATTLIST draw:page xlink:show (replace) #IMPLIED>
+<!ATTLIST draw:page xlink:actuate (onRequest) #IMPLIED>
+
+<!-- Presentation notes -->
+<!ELEMENT presentation:notes (%shapes;)*>
+<!ATTLIST presentation:notes style:page-master-name %styleName; #IMPLIED>
+
+<!-- presentation page layouts -->
+<!ELEMENT style:presentation-page-layout (presentation:placeholder)* >
+<!ATTLIST style:presentation-page-layout style:name %styleName; #REQUIRED>
+<!ELEMENT presentation:placeholder EMPTY >
+<!ATTLIST presentation:placeholder presentation:object (title|outline|subtitle|text|graphic|object|chart|orgchart|page|notes|handout) #REQUIRED>
+<!ATTLIST presentation:placeholder svg:x %coordinateOrPercentage; #REQUIRED>
+<!ATTLIST presentation:placeholder svg:y %coordinateOrPercentage; #REQUIRED>
+<!ATTLIST presentation:placeholder svg:width %lengthOrPercentage; #REQUIRED>
+<!ATTLIST presentation:placeholder svg:height %lengthOrPercentage; #REQUIRED>
+
+<!-- presentation page attributes -->
+<!ATTLIST style:properties presentation:transition-type (manual|automatic|semi-automatic) #IMPLIED >
+<!ATTLIST style:properties presentation:transition-style (none|fade-from-left|fade-from-top|fade-from-right|fade-from-bottom|fade-to-center|fade-from-center|move-from-left|move-from-top|move-from-right|move-from-bottom|roll-from-top|roll-from-left|roll-from-right|roll-from-bottom|vertical-stripes|horizontal-stripes|clockwise|counterclockwise|fade-from-upperleft|fade-from-upperright|fade-from-lowerleft|fade-from-lowerright|close-vertical|close-horizontal|open-vertical|open-horizontal|spiralin-left|spiralin-right|spiralout-left|spiralout-right|dissolve|wavyline-from-left|wavyline-from-top|wavyline-from-right|wavyline-from-bottom|random|stretch-from-left|stretch-from-top|stretch-from-right|stretch-from-bottom|vertical-lines|horizontal-lines) #IMPLIED >
+<!ATTLIST style:properties presentation:transition-speed %presentationSpeeds; #IMPLIED >
+<!ATTLIST style:properties presentation:duration %timeDuration; #IMPLIED>
+<!ATTLIST style:properties presentation:visibility (visible|hidden) #IMPLIED>
+<!ATTLIST style:properties draw:background-size (full|border) #IMPLIED>
+<!ATTLIST style:properties presentation:background-objects-visible %boolean; #IMPLIED>
+<!ATTLIST style:properties presentation:background-visible %boolean; #IMPLIED>
+
+
+<!-- text boxes -->
+<!ELEMENT draw:text-box (office:events?,draw:image-map?,
+		%sectionText;)>
+<!ATTLIST draw:text-box %draw-style-name;>
+<!ATTLIST draw:text-box %draw-transform; >
+<!ATTLIST draw:text-box draw:name %string; #IMPLIED>
+<!ATTLIST draw:text-box draw:chain-next-name %string; #IMPLIED>
+
+<!ATTLIST draw:text-box %text-anchor;>
+<!ATTLIST draw:text-box %draw-position;>
+<!ATTLIST draw:text-box %draw-end-position; >
+<!ATTLIST draw:text-box %table-background; >
+<!ATTLIST draw:text-box svg:width %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:text-box svg:height %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:text-box style:rel-width %percentage; #IMPLIED>
+<!ATTLIST draw:text-box style:rel-height %percentage; #IMPLIED>
+<!ATTLIST draw:text-box fo:min-height %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:text-box %zindex;>
+<!ATTLIST draw:text-box %presentation-class; >
+<!ATTLIST draw:text-box draw:id %draw-shape-id;>
+<!ATTLIST draw:text-box draw:layer %layerName; #IMPLIED>
+<!ATTLIST draw:text-box draw:corner-radius %nonNegativeLength; #IMPLIED>
+
+<!-- image -->
+<!ELEMENT draw:image (office:binary-data?,office:events?,draw:image-map?,svg:desc?,(draw:contour-polygon|draw:contour-path)?)>
+<!ATTLIST draw:image %draw-transform; >
+<!ATTLIST draw:image %draw-style-name;>
+<!ATTLIST draw:image draw:name %string; #IMPLIED>
+<!ATTLIST draw:image xlink:href %uriReference; #IMPLIED>
+<!ATTLIST draw:image xlink:type (simple) #IMPLIED>
+<!ATTLIST draw:image xlink:show (embed) #IMPLIED>
+<!ATTLIST draw:image xlink:actuate (onLoad) #IMPLIED>
+<!ATTLIST draw:image draw:filter-name %string; #IMPLIED>
+<!ATTLIST draw:image %text-anchor;>
+<!ATTLIST draw:image %draw-position;>
+<!ATTLIST draw:image %draw-end-position; >
+<!ATTLIST draw:image %table-background; >
+<!ATTLIST draw:image svg:width %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:image svg:height %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:image %presentation-class; >
+<!ATTLIST draw:image %zindex;>
+<!ATTLIST draw:image draw:id %draw-shape-id;>
+<!ATTLIST draw:image draw:layer %layerName; #IMPLIED>
+<!ATTLIST draw:image style:rel-width %percentage; #IMPLIED>
+<!ATTLIST draw:image style:rel-height %percentage; #IMPLIED>
+
+<!-- objects -->
+<!ELEMENT draw:thumbnail EMPTY>
+<!ATTLIST draw:thumbnail xlink:href %uriReference; #REQUIRED>
+<!ATTLIST draw:thumbnail xlink:type (simple) #IMPLIED>
+<!ATTLIST draw:thumbnail xlink:show (embed) #IMPLIED>
+<!ATTLIST draw:thumbnail xlink:actuate (onLoad) #IMPLIED>
+
+<!ELEMENT math:math ANY> <!-- dummy (we have no MathML DTD currently)-->
+<!ELEMENT draw:object (draw:thumbnail?,(office:document|math:math)?,office:events?, draw:image-map?, svg:desc?,(draw:contour-polygon|draw:contour-path)?)>
+<!ATTLIST draw:object %draw-style-name;>
+<!ATTLIST draw:object draw:name %string; #IMPLIED>
+<!ATTLIST draw:object xlink:href %uriReference; #IMPLIED>
+<!ATTLIST draw:object xlink:type (simple) #IMPLIED>
+<!ATTLIST draw:object xlink:show (embed) #IMPLIED>
+<!ATTLIST draw:object xlink:actuate (onLoad) #IMPLIED>
+<!ATTLIST draw:object %text-anchor;>
+<!ATTLIST draw:object %draw-position;>
+<!ATTLIST draw:object %draw-end-position; >
+<!ATTLIST draw:object %table-background; >
+<!ATTLIST draw:object svg:width %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:object svg:height %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:object %presentation-class; >
+<!ATTLIST draw:object %zindex;>
+<!ATTLIST draw:object draw:id %draw-shape-id;>
+<!ATTLIST draw:object draw:layer %layerName; #IMPLIED>
+<!ATTLIST draw:object draw:notify-on-update-of-ranges %string; #IMPLIED>
+<!ATTLIST draw:object style:rel-width %percentage; #IMPLIED>
+<!ATTLIST draw:object style:rel-height %percentage; #IMPLIED>
+
+<!ELEMENT draw:object-ole (office:binary-data?|office:events?|draw:image-map?|svg:desc?|draw:contour-polygon?|draw:contour-path?|draw:thumbnail?)>
+<!ATTLIST draw:object-ole draw:class-id CDATA #IMPLIED>
+<!ATTLIST draw:object-ole %draw-style-name;>
+<!ATTLIST draw:object-ole draw:name %string; #IMPLIED>
+<!ATTLIST draw:object-ole xlink:href %uriReference; #IMPLIED>
+<!ATTLIST draw:object-ole xlink:type (simple) #IMPLIED>
+<!ATTLIST draw:object-ole xlink:show (embed) #IMPLIED>
+<!ATTLIST draw:object-ole xlink:actuate (onLoad) #IMPLIED>
+<!ATTLIST draw:object-ole %text-anchor;>
+<!ATTLIST draw:object-ole %draw-position;>
+<!ATTLIST draw:object-ole %draw-end-position; >
+<!ATTLIST draw:object-ole %table-background; >
+<!ATTLIST draw:object-ole svg:width %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:object-ole svg:height %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:object-ole %presentation-class; >
+<!ATTLIST draw:object-ole %zindex;>
+<!ATTLIST draw:object-ole draw:id %draw-shape-id;>
+<!ATTLIST draw:object-ole draw:layer %layerName; #IMPLIED>
+<!ATTLIST draw:object-ole style:rel-width %percentage; #IMPLIED>
+<!ATTLIST draw:object-ole style:rel-height %percentage; #IMPLIED>
+
+<!ELEMENT svg:desc (#PCDATA)>
+
+<!ELEMENT draw:contour-polygon EMPTY>
+<!ATTLIST draw:contour-polygon svg:width %coordinate; #REQUIRED>
+<!ATTLIST draw:contour-polygon svg:height %coordinate; #REQUIRED>
+<!ATTLIST draw:contour-polygon %draw-viewbox;>
+<!ATTLIST draw:contour-polygon draw:points %points; #REQUIRED>
+<!ATTLIST draw:contour-polygon draw:recreate-on-edit %boolean; #IMPLIED>
+
+<!ELEMENT draw:contour-path EMPTY>
+<!ATTLIST draw:contour-path svg:width %coordinate; #REQUIRED>
+<!ATTLIST draw:contour-path svg:height %coordinate; #REQUIRED>
+<!ATTLIST draw:contour-path %draw-viewbox;>
+<!ATTLIST draw:contour-path svg:d %pathData; #REQUIRED>
+<!ATTLIST draw:contour-path draw:recreate-on-edit %boolean; #IMPLIED>
+
+<!-- hyperlink -->
+<!ELEMENT draw:a (draw:image|draw:text-box)>
+<!ATTLIST draw:a xlink:href %uriReference; #REQUIRED>
+<!ATTLIST draw:a xlink:type (simple) #FIXED "simple">
+<!ATTLIST draw:a xlink:show (new|replace) #IMPLIED>
+<!ATTLIST draw:a xlink:actuate (onRequest) "onRequest">
+<!ATTLIST draw:a office:name %string; #IMPLIED>
+<!ATTLIST draw:a office:target-frame-name %string; #IMPLIED>
+<!ATTLIST draw:a office:server-map %boolean; "false">
+
+<!-- 3d properties -->
+<!ATTLIST style:properties dr3d:horizontal-segments %nonNegativeInteger; #IMPLIED>
+<!ATTLIST style:properties dr3d:vertical-segments %nonNegativeInteger; #IMPLIED>
+<!ATTLIST style:properties dr3d:edge-rounding %percentage; #IMPLIED>
+<!ATTLIST style:properties dr3d:edge-rounding-mode (correct|attractive) #IMPLIED>
+<!ATTLIST style:properties dr3d:back-scale %percentage; #IMPLIED>
+<!ATTLIST style:properties dr3d:end-angle %nonNegativeInteger; #IMPLIED>
+<!ATTLIST style:properties dr3d:depth %length; #IMPLIED>
+<!ATTLIST style:properties dr3d:backface-culling (enabled|disabled) #IMPLIED>
+<!ATTLIST style:properties dr3d:lighting-mode (standard|double-sided) #IMPLIED>
+<!ATTLIST style:properties dr3d:normals-kind (object|flat|sphere) #IMPLIED>
+<!ATTLIST style:properties dr3d:normals-direction (normal|inverse) #IMPLIED>
+<!ATTLIST style:properties dr3d:texture-generation-mode-x (object|parallel|sphere) #IMPLIED>
+<!ATTLIST style:properties dr3d:texture-generation-mode-y (object|parallel|sphere) #IMPLIED>
+<!ATTLIST style:properties dr3d:texture-kind (luminance|intesity|color) #IMPLIED>
+<!ATTLIST style:properties dr3d:texture-filter (enabled|disabled) #IMPLIED>
+<!ATTLIST style:properties dr3d:texture-mode (replace|modulate|blend) #IMPLIED>
+<!ATTLIST style:properties dr3d:ambient-color %color; #IMPLIED>
+<!ATTLIST style:properties dr3d:emissive-color %color; #IMPLIED>
+<!ATTLIST style:properties dr3d:specular-color %color; #IMPLIED>
+<!ATTLIST style:properties dr3d:diffuse-color %color; #IMPLIED>
+<!ATTLIST style:properties dr3d:shininess %percentage; #IMPLIED>
+<!ATTLIST style:properties dr3d:shadow (visible|hidden) #IMPLIED>
+<!ATTLIST style:properties dr3d:close-front %boolean; #IMPLIED>
+<!ATTLIST style:properties dr3d:close-back %boolean; #IMPLIED>
+
+<!ELEMENT dr3d:light EMPTY>
+<!ATTLIST dr3d:light dr3d:diffuse-color %color; #IMPLIED>
+<!ATTLIST dr3d:light dr3d:direction %vector3D; #REQUIRED>
+<!ATTLIST dr3d:light dr3d:enabled %boolean; #IMPLIED>
+<!ATTLIST dr3d:light dr3d:specular %boolean; #IMPLIED>
+
+<!ENTITY % shapes3d "(dr3d:scene|dr3d:extrude|dr3d:sphere|dr3d:rotate|dr3d:cube)">
+
+<!ELEMENT dr3d:cube EMPTY>
+<!ATTLIST dr3d:cube dr3d:transform CDATA #IMPLIED>
+<!ATTLIST dr3d:cube dr3d:min-edge %vector3D; #IMPLIED>
+<!ATTLIST dr3d:cube dr3d:max-edge %vector3D; #IMPLIED>
+<!ATTLIST dr3d:cube %zindex;>
+<!ATTLIST dr3d:cube draw:id %draw-shape-id;>
+<!ATTLIST dr3d:cube %draw-end-position; >
+<!ATTLIST dr3d:cube %table-background; >
+<!ATTLIST dr3d:cube %draw-style-name; >
+<!ATTLIST dr3d:cube draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT dr3d:sphere EMPTY>
+<!ATTLIST dr3d:sphere dr3d:transform CDATA #IMPLIED>
+<!ATTLIST dr3d:sphere dr3d:center %vector3D; #IMPLIED>
+<!ATTLIST dr3d:sphere dr3d:size %vector3D; #IMPLIED>
+<!ATTLIST dr3d:sphere %zindex;>
+<!ATTLIST dr3d:sphere draw:id %draw-shape-id;>
+<!ATTLIST dr3d:sphere %draw-end-position; >
+<!ATTLIST dr3d:sphere %table-background; >
+<!ATTLIST dr3d:sphere %draw-style-name; >
+<!ATTLIST dr3d:sphere draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT dr3d:extrude EMPTY>
+<!ATTLIST dr3d:extrude dr3d:transform CDATA #IMPLIED>
+<!ATTLIST dr3d:extrude %draw-viewbox;>
+<!ATTLIST dr3d:extrude svg:d %pathData; #REQUIRED >
+<!ATTLIST dr3d:extrude %zindex;>
+<!ATTLIST dr3d:extrude draw:id %draw-shape-id;>
+<!ATTLIST dr3d:extrude %draw-end-position; >
+<!ATTLIST dr3d:extrude %table-background; >
+<!ATTLIST dr3d:extrude %draw-style-name; >
+<!ATTLIST dr3d:extrude draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT dr3d:rotate EMPTY>
+<!ATTLIST dr3d:rotate dr3d:transform CDATA #IMPLIED>
+<!ATTLIST dr3d:rotate %draw-viewbox;>
+<!ATTLIST dr3d:rotate svg:d %pathData; #REQUIRED >
+<!ATTLIST dr3d:rotate %zindex;>
+<!ATTLIST dr3d:rotate draw:id %draw-shape-id;>
+<!ATTLIST dr3d:rotate %draw-end-position; >
+<!ATTLIST dr3d:rotate %table-background; >
+<!ATTLIST dr3d:rotate %draw-style-name; >
+<!ATTLIST dr3d:rotate draw:layer %layerName; #IMPLIED>
+
+<!ELEMENT dr3d:scene (dr3d:light*,(%shapes3d;)*)>
+<!ATTLIST dr3d:scene %draw-style-name; >
+<!ATTLIST dr3d:scene svg:x %coordinate; #IMPLIED>
+<!ATTLIST dr3d:scene svg:y %coordinate; #IMPLIED>
+<!ATTLIST dr3d:scene svg:width %length; #IMPLIED>
+<!ATTLIST dr3d:scene svg:height %length; #IMPLIED>
+<!ATTLIST dr3d:scene dr3d:vrp %vector3D; #IMPLIED>
+<!ATTLIST dr3d:scene dr3d:vpn %vector3D; #IMPLIED>
+<!ATTLIST dr3d:scene dr3d:vup %vector3D; #IMPLIED>
+<!ATTLIST dr3d:scene dr3d:projection (parallel|perspective) #IMPLIED>
+<!ATTLIST dr3d:scene dr3d:transform CDATA #IMPLIED>
+<!ATTLIST dr3d:scene dr3d:distance %length; #IMPLIED>
+<!ATTLIST dr3d:scene dr3d:focal-length %length; #IMPLIED>
+<!ATTLIST dr3d:scene dr3d:shadow-slant %nonNegativeInteger; #IMPLIED>
+<!ATTLIST dr3d:scene dr3d:shade-mode (flat|phong|gouraud|draft) #IMPLIED>
+<!ATTLIST dr3d:scene dr3d:ambient-color %color; #IMPLIED>
+<!ATTLIST dr3d:scene dr3d:lighting-mode %boolean; #IMPLIED>
+<!ATTLIST dr3d:scene %zindex;>
+<!ATTLIST dr3d:scene draw:id %draw-shape-id;>
+<!ATTLIST dr3d:scene %draw-end-position; >
+<!ATTLIST dr3d:scene %table-background; >
+
+<!-- layer -->
+
+<!ELEMENT draw:layer-set (draw:layer*)>
+
+<!ELEMENT draw:layer EMPTY>
+<!ATTLIST draw:layer draw:name %layerName; #REQUIRED>
+
+<!-- events -->
+<!ELEMENT presentation:event (presentation:sound)?>
+<!ATTLIST presentation:event %event-name;>
+<!ATTLIST presentation:event presentation:action (none|previous-page|next-page|first-page|last-page|hide|stop|execute|show|verb|fade-out|sound) #REQUIRED>
+<!ATTLIST presentation:event presentation:effect %presentationEffects; "none">
+<!ATTLIST presentation:event presentation:direction %presentationEffectDirections; "none">
+<!ATTLIST presentation:event presentation:speed %presentationSpeeds; "medium">
+<!ATTLIST presentation:event presentation:start-scale %percentage; "100%">
+<!ATTLIST presentation:event xlink:href %uriReference; #IMPLIED>
+<!ATTLIST presentation:event xlink:type (simple) #IMPLIED>
+<!ATTLIST presentation:event xlink:show (embed) #IMPLIED>
+<!ATTLIST presentation:event xlink:actuate (onRequest) #IMPLIED>
+<!ATTLIST presentation:event presentation:verb %nonNegativeInteger; #IMPLIED>
+
+<!-- applets -->
+<!ELEMENT draw:applet (draw:thumbnail?, draw:param*, svg:desc?)>
+<!ATTLIST draw:applet xlink:href %uriReference; #IMPLIED>
+<!ATTLIST draw:applet xlink:type (simple) #IMPLIED>
+<!ATTLIST draw:applet xlink:show (embed) #IMPLIED>
+<!ATTLIST draw:applet xlink:actuate (onLoad) #IMPLIED>
+<!ATTLIST draw:applet draw:code CDATA #REQUIRED>
+<!ATTLIST draw:applet draw:object CDATA #IMPLIED>
+<!ATTLIST draw:applet draw:archive CDATA #IMPLIED>
+<!ATTLIST draw:applet draw:may-script %boolean; "false">
+<!ATTLIST draw:applet draw:name CDATA #IMPLIED>
+<!ATTLIST draw:applet %draw-style-name;>
+<!ATTLIST draw:applet svg:width %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:applet svg:height %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:applet %zindex;>
+<!ATTLIST draw:applet draw:layer %layerName; #IMPLIED>
+<!ATTLIST draw:applet %draw-position;>
+<!ATTLIST draw:applet %draw-end-position; >
+
+<!-- plugins -->
+<!ELEMENT draw:plugin (draw:thumbnail?, draw:param*, svg:desc?)>
+<!ATTLIST draw:plugin xlink:href %uriReference; #IMPLIED>
+<!ATTLIST draw:plugin xlink:type (simple) #IMPLIED>
+<!ATTLIST draw:plugin xlink:show (embed) #IMPLIED>
+<!ATTLIST draw:plugin xlink:actuate (onLoad) #IMPLIED>
+<!ATTLIST draw:plugin draw:mime-type CDATA #IMPLIED>
+<!ATTLIST draw:plugin draw:name CDATA #IMPLIED>
+<!ATTLIST draw:plugin %draw-style-name;>
+<!ATTLIST draw:plugin svg:width %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:plugin svg:height %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:plugin %zindex;>
+<!ATTLIST draw:plugin draw:layer %layerName; #IMPLIED>
+<!ATTLIST draw:plugin %draw-position;>
+<!ATTLIST draw:plugin %draw-end-position; >
+
+<!-- Paramaters -->
+<!ELEMENT draw:param EMPTY>
+<!ATTLIST draw:param draw:name CDATA #IMPLIED>
+<!ATTLIST draw:param draw:value CDATA #IMPLIED>
+
+<!-- Floating Frames -->
+<!ELEMENT draw:floating-frame (draw:thumbnail?, svg:desc?)>
+<!ATTLIST draw:floating-frame xlink:href %uriReference; #IMPLIED>
+<!ATTLIST draw:floating-frame xlink:type (simple) #IMPLIED>
+<!ATTLIST draw:floating-frame xlink:show (embed) #IMPLIED>
+<!ATTLIST draw:floating-frame xlink:actuate (onLoad) #IMPLIED>
+<!ATTLIST draw:floating-frame draw:name CDATA #IMPLIED>
+<!ATTLIST draw:floating-frame draw:frame-name CDATA #IMPLIED>
+<!ATTLIST draw:floating-frame %draw-style-name;>
+<!ATTLIST draw:floating-frame svg:width %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:floating-frame svg:height %lengthOrPercentage; #IMPLIED>
+<!ATTLIST draw:floating-frame %zindex;>
+<!ATTLIST draw:floating-frame draw:layer %layerName; #IMPLIED>
+<!ATTLIST draw:floating-frame %draw-position;>
+<!ATTLIST draw:floating-frame %draw-end-position; >
+
+<!-- Image Maps -->
+<!ELEMENT draw:image-map
+	(draw:area-rectangle|draw:area-circle|draw:area-polygon)*>
+
+<!ELEMENT draw:area-rectangle (svg:desc?,office:events?)>
+<!ATTLIST draw:area-rectangle xlink:href %uriReference; #IMPLIED>
+<!ATTLIST draw:area-rectangle xlink:type (simple) #IMPLIED>
+<!ATTLIST draw:area-rectangle office:target-frame-name CDATA #IMPLIED>
+<!ATTLIST draw:area-rectangle xlink:show (new|replace) #IMPLIED>
+<!ATTLIST draw:area-rectangle office:name CDATA #IMPLIED>
+<!ATTLIST draw:area-rectangle draw:nohref (nohref) #IMPLIED>
+<!ATTLIST draw:area-rectangle svg:x %coordinate; #REQUIRED>
+<!ATTLIST draw:area-rectangle svg:y %coordinate; #REQUIRED>
+<!ATTLIST draw:area-rectangle svg:width %coordinate; #REQUIRED>
+<!ATTLIST draw:area-rectangle svg:height %coordinate; #REQUIRED>
+
+<!ELEMENT draw:area-circle (svg:desc?,office:events?)>
+<!ATTLIST draw:area-circle xlink:href %uriReference; #IMPLIED>
+<!ATTLIST draw:area-circle xlink:type (simple) #IMPLIED>
+<!ATTLIST draw:area-circle office:target-frame-name CDATA #IMPLIED>
+<!ATTLIST draw:area-circle xlink:show (new|replace) #IMPLIED>
+<!ATTLIST draw:area-circle office:name CDATA #IMPLIED>
+<!ATTLIST draw:area-circle draw:nohref (nohref) #IMPLIED>
+<!ATTLIST draw:area-circle svg:cx %coordinate; #REQUIRED>
+<!ATTLIST draw:area-circle svg:cy %coordinate; #REQUIRED>
+<!ATTLIST draw:area-circle svg:r %coordinate; #REQUIRED>
+
+<!ELEMENT draw:area-polygon (svg:desc?,office:events?)>
+<!ATTLIST draw:area-polygon xlink:href %uriReference; #IMPLIED>
+<!ATTLIST draw:area-polygon xlink:type (simple) #IMPLIED>
+<!ATTLIST draw:area-polygon office:target-frame-name CDATA #IMPLIED>
+<!ATTLIST draw:area-polygon xlink:show (new|replace) #IMPLIED>
+<!ATTLIST draw:area-polygon office:name CDATA #IMPLIED>
+<!ATTLIST draw:area-polygon draw:nohref (nohref) #IMPLIED>
+<!ATTLIST draw:area-polygon svg:x %coordinate; #REQUIRED>
+<!ATTLIST draw:area-polygon svg:y %coordinate; #REQUIRED>
+<!ATTLIST draw:area-polygon svg:width %coordinate; #REQUIRED>
+<!ATTLIST draw:area-polygon svg:height %coordinate; #REQUIRED>
+<!ATTLIST draw:area-polygon svg:points %points; #REQUIRED>
+<!ATTLIST draw:area-polygon svg:viewBox CDATA #REQUIRED>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/dtypes.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/dtypes.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/dtypes.mod	(revision 28000)
@@ -0,0 +1,171 @@
+<!--
+	$Id: dtypes.mod,v 1.15 2001/07/24 11:23:13 cl Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!-- datatypes corresponding to XML Schema Part 2 W3C Working draft of	-->
+<!-- 07 April 2000														-->
+
+<!-- string -->
+<!ENTITY % string				"CDATA">
+<!ENTITY % cString				"#PCDATA">
+
+<!-- boolean (values are "true" and "false" -->
+<!ENTITY % boolean				"CDATA">
+
+<!-- integer ( ..., -2, -1, 0, 1, 2, ...) -->
+<!ENTITY % integer				"CDATA">
+
+<!-- non negative integer ( 0, 1, 2, ...) -->
+<!ENTITY % nonNegativeInteger	"CDATA">
+
+<!-- positive integer ( 1, 2, ...) -->
+<!ENTITY % positiveInteger		"CDATA">
+<!ENTITY % cPositiveInteger		"#PCDATA">
+
+<!ENTITY % positiveNumberOrDefault "CDATA">
+
+<!-- time duration as specified by ISO8601, section 5.5.3.2 -->
+<!ENTITY % timeDuration			"CDATA">
+<!ENTITY % cTimeDuration		"#PCDATA">
+
+<!-- time instance as specified by ISO8601, section 5.4 -->
+<!ENTITY % timeInstance			"CDATA">
+<!ENTITY % cTimeInstance		"#PCDATA">
+
+<!-- date instance as specified by ISO8601, section 5.2.1.1, extended format-->
+<!ENTITY % date					"CDATA">
+<!ENTITY % cDate				"#PCDATA">
+
+<!-- date duration, like timDuration but truncated to full dates -->
+<!ENTITY % dateDuration			"CDATA">
+<!ENTITY % cDateDuration		"#PCDATA">
+
+<!-- URI reference -->
+<!ENTITY % uriReference			"CDATA">
+
+<!-- language code as specified by RFC1766 -->
+<!ENTITY % language				"CDATA">
+<!ENTITY % cLanguage			"#PCDATA">
+
+<!-- float -->
+<!ENTITY % float "CDATA">
+
+<!-- Some other common used data types -->
+
+<!-- a single UNICODE character -->
+<!ENTITY % character			"CDATA">
+
+<!-- a style name -->
+<!ENTITY % styleName			"CDATA">
+
+<!-- a target frame mame -->
+<!ENTITY % targetFrameName			"CDATA">
+
+<!-- a language without a country as specified by ISO639 -->
+<!ENTITY % languageOnly			"CDATA">
+
+<!-- a country as specified by ISO3166 -->
+<!ENTITY % country				"CDATA">
+
+<!-- a color value having the format #rrggbb -->
+<!ENTITY % color				"CDATA">
+<!-- a color value having the format #rrggbb or "transparent" -->
+<!ENTITY % transparentOrColor			"CDATA">
+
+<!-- a percentage -->
+<!ENTITY % percentage 			"CDATA">
+
+<!-- a length (i.e. 1cm or .6inch) -->
+<!ENTITY % length				"CDATA">
+<!ENTITY % positiveLength		"CDATA">
+<!ENTITY % nonNegativeLength	"CDATA">
+<!ENTITY % lengthOrNoLimit "CDATA">
+
+<!-- a length or a percentage -->
+<!ENTITY % lengthOrPercentage	"CDATA">
+<!ENTITY % positiveLengthOrPercentage	"CDATA">
+
+<!-- a pixel length (i.e. 2px) -->
+<!ENTITY % nonNegativePixelLength	"CDATA">
+
+<!-- a float or a percentage -->
+<!ENTITY % floatOrPercentage	"CDATA">
+
+<!-- a text encoding -->
+<!ENTITY % textEncoding	"CDATA">
+
+<!-- cell address and cell range address -->
+<!ENTITY % cell-address "CDATA">
+<!ENTITY % cell-range-address "CDATA">
+<!ENTITY % cell-range-address-list "CDATA">
+
+<!-- value types -->
+<!ENTITY % valueType "(float|time|date|percentage|currency|boolean|string)">
+
+<!-- an svg coordinate in different distance formats -->
+<!ENTITY % coordinate "CDATA">
+
+<!ENTITY % coordinateOrPercentage	"CDATA">
+
+<!ENTITY % shape "draw:rect|draw:line|draw:polyline|draw:polygon|draw:path|
+				   draw:circle|draw:ellipse|draw:g|draw:page-thumbnail|
+				   draw:text-box|draw:image|draw:object|draw:object-ole|
+				   draw:applet|draw:floating-frame|draw:plugin|
+				   draw:measure|draw:caption|draw:connector|chart:chart|
+				   dr3d:scene|draw:control" >
+<!ENTITY % shapes "(%shape;)" >
+
+<!ENTITY % anchorType "(page|frame|paragraph|char|as-char)">
+
+<!ENTITY % control-id "form:id CDATA #REQUIRED">
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/event.dtd
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/event.dtd	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/event.dtd	(revision 28000)
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	$Id: event.dtd,v 1.3 2003/03/25 18:19:27 hr Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+-->
+
+<!-- xlink:type -->
+<!ENTITY % xlinkType "CDATA">
+
+<!ELEMENT event:event EMPTY>
+<!ATTLIST event:event
+	event:name CDATA #REQUIRED
+	event:language CDATA #REQUIRED
+	event:library CDATA #IMPLIED
+	event:macro-name CDATA #IMPLIED
+	xlink:type %xlinkType; "simple"
+	xlink:href CDATA #IMPLIED
+>
+<!ELEMENT event:events (event:event*)>
+<!ATTLIST event:events
+	xmlns:event CDATA #FIXED "http://openoffice.org/2001/event"
+	xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink"
+>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/form.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/form.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/form.mod	(revision 28000)
@@ -0,0 +1,340 @@
+<!--
+	$Id: form.mod,v 1.13 2002/11/01 12:30:41 fs Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!ENTITY % controls	"form:text|form:textarea|form:fixed-text|form:file|
+					 form:password|form:formatted-text|form:button|form:image|
+					 form:checkbox|form:radio|form:listbox|form:combobox|form:frame|
+					 form:hidden|form:image-frame|form:grid|form:generic-control">
+
+<!ENTITY % name "form:name CDATA #IMPLIED">
+<!ENTITY % service-name "form:service-name CDATA #IMPLIED">
+
+<!ENTITY % navigation "(none|current|parent)">
+<!ENTITY % cycles "(records|current|page)">
+<!ENTITY % url "CDATA">
+
+
+<!ENTITY % types "(submit|reset|push|url)">
+<!ENTITY % button-type "form:button-type %types; 'push'">
+<!ENTITY % current-selected "form:current-selected %boolean; 'false'">
+<!ENTITY % current-value "form:current-value CDATA #IMPLIED">
+<!ENTITY % value "form:value CDATA #IMPLIED">
+<!ENTITY % disabled "form:disabled %boolean; 'false'">
+<!ENTITY % dropdown "form:dropdown %boolean; 'false'">
+<!ENTITY % for "form:for CDATA #IMPLIED">
+<!ENTITY % image-data "form:image-data %url; #IMPLIED">
+<!ENTITY % label "form:label CDATA #IMPLIED">
+<!ENTITY % max-length "form:max-length CDATA #IMPLIED">
+<!ENTITY % printable "form:printable %boolean; 'true'">
+<!ENTITY % readonly "form:readonly %boolean; 'false'">
+<!ENTITY % size "form:size CDATA #IMPLIED">
+<!ENTITY % selected "form:selected %boolean; 'false'">
+<!ENTITY % size "form:size CDATA #IMPLIED">
+<!ENTITY % tab-index "form:tab-index CDATA #IMPLIED">
+<!ENTITY % target-frame "office:target-frame CDATA '_blank'">
+<!ENTITY % target-location "xlink:href %url; #IMPLIED">
+<!ENTITY % tab-stop "form:tab-stop %boolean; 'true'">
+<!ENTITY % title "form:title CDATA #IMPLIED">
+<!ENTITY % default-value "form:default-value CDATA #IMPLIED">
+<!ENTITY % bound-column "form:bound-column CDATA #IMPLIED">
+<!ENTITY % convert-empty "form:convert-empty-to-null  %boolean; 'false'">
+<!ENTITY % data-field "form:data-field CDATA #IMPLIED">
+<!ENTITY % list-source "form:list-source CDATA #IMPLIED">
+<!ENTITY % list-source-types "(table|query|sql|sql-pass-through|value-list|table-fields)">
+<!ENTITY % list-source-type "form:list-source-type %list-source-types; #IMPLIED">
+<!ENTITY % column-style-name "form:column-style-name %styleName; #IMPLIED">
+
+
+<!ELEMENT form:control (%controls;)+>
+<!ATTLIST form:control %name;
+                       %service-name;
+                       %control-id;>
+
+<!ELEMENT form:form (form:properties?, office:events?, (form:control|form:form)*)>
+<!ATTLIST form:form %name; %service-name;>
+<!ATTLIST form:form xlink:href %url; #IMPLIED>
+<!ATTLIST form:form form:enctype CDATA "application/x-www-form-urlencoded">
+<!ATTLIST form:form form:method CDATA "get">
+<!ATTLIST form:form office:target-frame CDATA "_blank">
+<!ATTLIST form:form form:allow-deletes %boolean; "true">
+<!ATTLIST form:form form:allow-inserts %boolean; "true">
+<!ATTLIST form:form form:allow-updates %boolean; "true">
+<!ATTLIST form:form form:apply-filter %boolean; "false">
+<!ATTLIST form:form form:command CDATA #IMPLIED>
+<!ATTLIST form:form form:command-type (table|query|command) "command">
+<!ATTLIST form:form form:datasource CDATA #IMPLIED>
+<!ATTLIST form:form form:detail-fields CDATA #IMPLIED>
+<!ATTLIST form:form form:escape-processing %boolean; "true">
+<!ATTLIST form:form form:filter CDATA #IMPLIED>
+<!ATTLIST form:form form:ignore-result %boolean; "false">
+<!ATTLIST form:form form:master-fields CDATA #IMPLIED>
+<!ATTLIST form:form form:navigation-mode %navigation; #IMPLIED>
+<!ATTLIST form:form form:order CDATA #IMPLIED>
+<!ATTLIST form:form form:tab-cycle %cycles; #IMPLIED>
+
+<!ELEMENT office:forms (form:form*)>
+<!ATTLIST office:forms form:automatic-focus %boolean; "false">
+<!ATTLIST office:forms form:apply-design-mode %boolean; "true">
+
+<!ELEMENT form:text (form:properties?, office:events?)>
+<!ATTLIST form:text %current-value;
+                    %disabled;
+                    %max-length;
+                    %printable;
+                    %readonly;
+                    %tab-index;
+                    %tab-stop;
+                    %title;
+                    %value;
+                    %convert-empty;
+                    %data-field;>
+
+<!ELEMENT form:textarea (form:properties?, office:events?)>
+<!ATTLIST form:textarea %current-value;
+                        %disabled;
+                        %max-length;
+                        %printable;
+                        %readonly;
+                        %tab-index;
+                        %tab-stop;
+                        %title;
+                        %value;
+                        %convert-empty;
+                        %data-field;>
+
+<!ELEMENT form:password (form:properties?, office:events?)>
+<!ATTLIST form:password %disabled;
+                        %max-length;
+                        %printable;
+                        %tab-index;
+                        %tab-stop;
+                        %title;
+                        %value;
+						%convert-empty;>
+
+<!ATTLIST form:password form:echo-char CDATA "*">
+
+<!ELEMENT form:file (form:properties?, office:events?)>
+<!ATTLIST form:file %current-value;
+                    %disabled;
+                    %max-length;
+                    %printable;
+                    %readonly;
+                    %tab-index;
+                    %tab-stop;
+                    %title;
+                    %value;>
+
+<!ELEMENT form:formatted-text (form:properties?, office:events?)>
+<!ATTLIST form:formatted-text %current-value;
+                              %disabled;
+                              %max-length;
+                              %printable;
+                              %readonly;
+                              %tab-index;
+                              %tab-stop;
+                              %title;
+                              %value;
+                              %convert-empty;
+                              %data-field;>
+<!ATTLIST form:formatted-text form:max-value CDATA #IMPLIED>
+<!ATTLIST form:formatted-text form:min-value CDATA #IMPLIED>
+<!ATTLIST form:formatted-text form:validation %boolean; "false">
+
+<!ELEMENT form:fixed-text (form:properties?, office:events?)>
+<!ATTLIST form:fixed-text %for;
+                          %disabled;
+                          %label;
+                          %printable;
+                          %title;>
+<!ATTLIST form:fixed-text form:multi-line %boolean; "false">
+
+<!ELEMENT form:combobox (form:properties?, office:events?, form:item*)>
+<!ATTLIST form:combobox %current-value;
+                        %disabled;
+                        %dropdown;
+                        %max-length;
+                        %printable;
+                        %readonly;
+                        %size;
+                        %tab-index;
+                        %tab-stop;
+                        %title;
+                        %value;
+                        %convert-empty;
+                        %data-field;
+                        %list-source;
+                        %list-source-type;>
+<!ATTLIST form:combobox form:auto-complete %boolean; #IMPLIED>
+
+<!ELEMENT form:item (#PCDATA)>
+<!ATTLIST form:item %label;>
+
+<!ELEMENT form:listbox (form:properties?, office:events?, form:option*)>
+<!ATTLIST form:listbox %disabled;
+                       %dropdown;
+                       %printable;
+                       %size;
+                       %tab-index;
+                       %tab-stop;
+                       %title;
+                       %bound-column;
+                       %data-field;
+                       %list-source;
+                       %list-source-type;>
+<!ATTLIST form:listbox form:multiple %boolean; "false">
+
+<!ELEMENT form:option (#PCDATA)>
+<!ATTLIST form:option %current-selected;
+                      %selected;
+                      %label;
+                      %value;>
+
+<!ELEMENT form:button (form:properties?, office:events?)>
+<!ATTLIST form:button %button-type;
+                      %disabled;
+                      %label;
+                      %image-data;
+                      %printable;
+                      %tab-index;
+                      %tab-stop;
+                      %target-frame;
+                      %target-location;
+                      %title;
+                      %value;>
+<!ATTLIST form:button form:default-button %boolean; "false">
+
+<!ELEMENT form:image (form:properties?, office:events?)>
+<!ATTLIST form:image %button-type;
+                     %disabled;
+                     %image-data;
+                     %printable;
+                     %tab-index;
+                     %tab-stop;
+                     %target-frame;
+                     %target-location;
+                     %title;
+                     %value;>
+
+<!ELEMENT form:checkbox (form:properties?, office:events?)>
+<!ATTLIST form:checkbox %disabled;
+                        %label;
+                        %printable;
+                        %tab-index;
+                        %tab-stop;
+                        %title;
+                        %value;
+                        %data-field;>
+<!ENTITY % states "(unchecked|checked|unknown)">
+<!ATTLIST form:checkbox form:current-state %states; #IMPLIED>
+<!ATTLIST form:checkbox form:is-tristate %boolean; "false">
+<!ATTLIST form:checkbox form:state %states; "unchecked">
+
+<!ELEMENT form:radio (form:properties?, office:events?)>
+<!ATTLIST form:radio %current-selected;
+                     %disabled;
+                     %label;
+                     %printable;
+                     %selected;
+                     %tab-index;
+                     %tab-stop;
+                     %title;
+                     %value;
+                     %data-field;>
+
+<!ELEMENT form:frame (form:properties?, office:events?)>
+<!ATTLIST form:frame %disabled;
+                     %for;
+                     %label;
+                     %printable;
+                     %title;>
+
+<!ELEMENT form:image-frame (form:properties?, office:events?)>
+<!ATTLIST form:image-frame %disabled;
+                           %image-data;
+                           %printable;
+                           %readonly;
+                           %title;
+                           %data-field;>
+
+<!ELEMENT form:hidden (form:properties?, office:events?)>
+<!ATTLIST form:hidden %name;
+                      %service-name;
+                      %value;>
+
+<!ELEMENT form:grid (form:properties?, office:events?, form:column*)>
+<!ATTLIST form:grid %disabled;
+                    %printable;
+                    %tab-index;
+                    %tab-stop;
+                    %title;>
+
+<!ENTITY % column-type "form:text| form:textarea| form:formatted-text|form:checkbox| form:listbox| form:combobox">
+<!ELEMENT form:column (%column-type;)+>
+<!ATTLIST form:column %name;
+                      %service-name;
+                      %label;
+					  %column-style-name;>
+
+<!ELEMENT form:generic-control (form:properties?, office:events?)>
+
+
+<!ELEMENT form:properties (form:property+)>
+<!ELEMENT form:property (form:property-value*)>
+<!ATTLIST form:property form:property-is-list %boolean; #IMPLIED>
+<!ATTLIST form:property form:property-name CDATA #REQUIRED>
+<!ATTLIST form:property form:property-type (boolean|short|int|long|double|string)  #REQUIRED>
+<!ELEMENT form:property-value (#PCDATA)>
+<!ATTLIST form:property-value form:property-is-void %boolean; #IMPLIED>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/image.dtd
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/image.dtd	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/image.dtd	(revision 28000)
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	$Id: image.dtd,v 1.3 2001/11/28 10:53:08 mba Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+-->
+
+<!ENTITY % url "CDATA">
+
+<!-- URI reference -->
+<!ENTITY % uriReference "CDATA">
+
+<!-- a color value having the format #rrggbb -->
+<!ENTITY % color				"CDATA">
+
+<!-- determine the mask mode of the image bitmap -->
+<!ENTITY % maskMode "(maskcolor|maskbitmap)">
+
+<!ELEMENT image:entry EMPTY>
+<!ATTLIST image:entry
+	image:command %url; #REQUIRED
+	image:bitmap-index CDATA #REQUIRED
+>
+
+<!ELEMENT image:externalentry EMPTY>
+<!ATTLIST image:externalentry
+	image:command %url; #REQUIRED
+	xlink:href %uriReference; #REQUIRED
+	xlink:type CDATA #FIXED "simple"
+>
+
+<!ELEMENT image:externalimages (image:externalentry*)>
+<!ELEMENT image:images (image:entry*)>
+<!ATTLIST image:images
+	xlink:href %uriReference; #REQUIRED
+	xlink:type CDATA #FIXED "simple"
+	image:maskmode %maskMode; "maskcolor"
+	image:maskcolor %color; "#000000"
+	image:maskurl %url; #IMPLIED
+>
+
+<!ELEMENT image:imagescontainer (image:images*, image:externalimages?)>
+<!ATTLIST image:imagescontainer
+	xmlns:image CDATA #FIXED "http://openoffice.org/2001/image"
+	xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink"
+>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/libraries.dtd
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/libraries.dtd	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/libraries.dtd	(revision 28000)
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	$Id: libraries.dtd,v 1.3 2001/12/04 11:44:14 ab Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!ENTITY % boolean "(true|false)">
+
+<!ELEMENT library:libraries (library:library)*>
+<!ATTLIST library:libraries 
+	xmlns:library CDATA #FIXED "http://openoffice.org/2000/library" 
+	xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink"
+>
+
+<!ELEMENT library:library EMPTY>
+<!ATTLIST library:library 
+	library:name CDATA #REQUIRED
+	xlink:href CDATA #IMPLIED
+	xlink:type CDATA #IMPLIED
+	library:link %boolean; #REQUIRED
+	library:readonly %boolean; #IMPLIED
+>
+
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/library.dtd
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/library.dtd	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/library.dtd	(revision 28000)
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	$Id: library.dtd,v 1.1 2001/12/04 11:45:28 ab Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!ENTITY % boolean "(true|false)">
+
+<!ELEMENT library:library (library:element)*>
+<!ATTLIST library:library 
+	xmlns:library CDATA #FIXED "http://openoffice.org/2000/library" 
+	library:name CDATA #REQUIRED
+	library:readonly %boolean; #REQUIRED
+	library:passwordprotected %boolean; #REQUIRED
+>
+
+<!ELEMENT library:element EMPTY>
+<!ATTLIST library:element 
+	library:name CDATA #REQUIRED
+>
+
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/menubar.dtd
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/menubar.dtd	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/menubar.dtd	(revision 28000)
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	$Id: menubar.dtd,v 1.1 2001/05/21 11:07:49 cd Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+-->
+
+<!ELEMENT menu:menubar (menu:menu+)>
+<!ELEMENT menu:menu (menu:menupopup)>
+<!ELEMENT menu:menupopup (menu:menuitem | menu:menuseparator | menu:menu)+>
+<!ELEMENT menu:menuseparator EMPTY>
+<!ELEMENT menu:menuitem EMPTY>
+<!ATTLIST menu:menubar
+	menu:id CDATA #REQUIRED
+	xmlns:menu CDATA #FIXED "http://openoffice.org/2001/menu"
+>
+<!ATTLIST menu:menu
+	menu:id CDATA #REQUIRED
+	menu:label CDATA #IMPLIED
+>
+<!ATTLIST menu:menuitem
+	menu:id CDATA #REQUIRED
+	menu:helpid CDATA #IMPLIED
+	menu:label CDATA #IMPLIED
+>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/meta.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/meta.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/meta.mod	(revision 28000)
@@ -0,0 +1,118 @@
+<!--
+	$Id: meta.mod,v 1.4 2000/12/15 13:55:41 mib Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+
+<!ELEMENT meta:generator (%cString;)>
+
+<!ELEMENT dc:title (%cString;)>
+
+<!ELEMENT dc:description (%cString;)>
+
+<!ELEMENT dc:subject (%cString;)>
+
+<!ELEMENT meta:keywords (meta:keyword)*>
+<!ELEMENT meta:keyword (%cString;)>
+
+<!ELEMENT meta:initial-creator (%cString;)>
+
+<!ELEMENT dc:creator (%cString;)>
+
+<!ELEMENT meta:printed-by (%cString;)>
+
+<!ELEMENT meta:creation-date (%cTimeInstance;)>
+
+<!ELEMENT dc:date (%cTimeInstance;)>
+
+<!ELEMENT meta:print-date (%cTimeInstance;)>
+
+<!ELEMENT meta:template EMPTY>
+<!ATTLIST meta:template xlink:type (simple) #FIXED "simple">
+<!ATTLIST meta:template xlink:actuate (onRequest) "onRequest">
+<!ATTLIST meta:template xlink:href %uriReference; #REQUIRED>
+<!ATTLIST meta:template xlink:title %string; #IMPLIED>
+<!ATTLIST meta:template meta:date %timeInstance; #IMPLIED>
+
+<!ELEMENT meta:auto-reload EMPTY>
+<!ATTLIST meta:auto-reload xlink:type (simple) #IMPLIED>
+<!ATTLIST meta:auto-reload xlink:show (replace) #IMPLIED>
+<!ATTLIST meta:auto-reload xlink:actuate (onLoad) #IMPLIED>
+<!ATTLIST meta:auto-reload xlink:href %uriReference; #IMPLIED>
+<!ATTLIST meta:auto-reload meta:delay %timeDuration; "P0S">
+
+<!ELEMENT meta:hyperlink-behaviour EMPTY>
+<!ATTLIST meta:hyperlink-behaviour office:target-frame-name %targetFrameName; #IMPLIED>
+<!ATTLIST meta:hyperlink-behaviour xlink:show (new|replace) #IMPLIED>
+
+<!ELEMENT dc:language (%cLanguage;)>
+
+<!ELEMENT meta:editing-cycles (%cPositiveInteger;)>
+
+<!ELEMENT meta:editing-duration (%cTimeDuration;)>
+
+<!ELEMENT meta:user-defined (%cString;)>
+<!ATTLIST meta:user-defined meta:name %string; #REQUIRED>
+
+<!ELEMENT meta:document-statistic EMPTY>
+<!ATTLIST meta:document-statistic meta:page-count %positiveInteger; #IMPLIED
+	meta:table-count %nonNegativeInteger; #IMPLIED
+	meta:draw-count %nonNegativeInteger; #IMPLIED
+	meta:image-count %nonNegativeInteger; #IMPLIED
+	meta:ole-object-count %nonNegativeInteger; #IMPLIED
+	meta:paragraph-count %nonNegativeInteger; #IMPLIED
+	meta:word-count %nonNegativeInteger; #IMPLIED
+	meta:character-count %nonNegativeInteger; #IMPLIED
+	meta:row-count %nonNegativeInteger; #IMPLIED
+	meta:cell-count %nonNegativeInteger; #IMPLIED
+	meta:object-count %positiveInteger; #IMPLIED>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/module.dtd
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/module.dtd	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/module.dtd	(revision 28000)
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	$Id: module.dtd,v 1.1 2001/05/22 13:42:01 ab Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!ELEMENT script:module (#PCDATA)>
+<!ATTLIST script:module
+	xmlns:script CDATA #FIXED "http://openoffice.org/2000/script"
+	script:name CDATA #REQUIRED
+	script:language CDATA #REQUIRED
+>
+
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/nmspace.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/nmspace.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/nmspace.mod	(revision 28000)
@@ -0,0 +1,80 @@
+<!--
+	$Id: nmspace.mod,v 1.5 2002/05/06 09:34:55 bm Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!ENTITY nFO "http://www.w3.org/1999/XSL/Format">
+<!ENTITY nXLink "http://www.w3.org/1999/xlink">
+<!ENTITY nSVG "http://www.w3.org/2000/svg">
+<!ENTITY nMath "http://www.w3.org/1998/Math/MathML">
+
+<!-- StarOffice namespace names and prefixes -->
+
+<!ENTITY nOpenOffice "http://openoffice.org/2000">
+<!ENTITY nOpenOffice2001 "http://openoffice.org/2001">
+
+<!ENTITY nOffice "&nOpenOffice;/office">
+<!ENTITY nStyle "&nOpenOffice;/style">
+<!ENTITY nText "&nOpenOffice;/text">
+<!ENTITY nTable "&nOpenOffice;/table">
+<!ENTITY nMeta "&nOpenOffice;/meta">
+<!ENTITY nScript "&nOpenOffice;/script">
+<!ENTITY nDraw "&nOpenOffice;/drawing">
+<!ENTITY nChart "&nOpenOffice;/chart">
+<!ENTITY nNumber "&nOpenOffice;/datastyle">
+<!ENTITY nDr3D "&nOpenOffice;/dr3d">
+<!ENTITY nForm "&nOpenOffice;/form">
+<!ENTITY nConfig "&nOpenOffice2001;/config">
+
+<!-- dublin core namespace name and prefic -->
+<!ENTITY nDC "http://purl.org/dc/elements/1.1/">
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/office.dtd
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/office.dtd	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/office.dtd	(revision 28000)
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	$Id: office.dtd,v 1.7 2002/02/28 14:42:15 dvo Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!ENTITY % dtypes-mod SYSTEM "dtypes.mod">
+%dtypes-mod;
+<!ENTITY % nmspace-mod SYSTEM "nmspace.mod">
+%nmspace-mod;
+<!ENTITY % defs-mod SYSTEM "defs.mod">
+%defs-mod;
+<!ENTITY % office-mod SYSTEM "office.mod">
+%office-mod;
+<!ENTITY % style-mod SYSTEM "style.mod">
+%style-mod;
+<!ENTITY % meta-mod SYSTEM "meta.mod">
+%meta-mod;
+<!ENTITY % script-mod SYSTEM "script.mod">
+%script-mod;
+<!ENTITY % drawing-mod SYSTEM "drawing.mod">
+%drawing-mod;
+<!ENTITY % text-mod SYSTEM "text.mod">
+%text-mod;
+<!ENTITY % table-mod SYSTEM "table.mod">
+%table-mod;
+<!ENTITY % chart-mod SYSTEM "chart.mod">
+%chart-mod;
+<!ENTITY % datastyl-mod SYSTEM "datastyl.mod">
+%datastyl-mod;
+<!ENTITY % form-mod SYSTEM "form.mod">
+%form-mod;
+<!ENTITY % settings-mod SYSTEM "settings.mod">
+%settings-mod;
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/office.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/office.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/office.mod	(revision 28000)
@@ -0,0 +1,270 @@
+<!--
+	$Id: office.mod,v 1.47 2003/04/17 15:59:01 vg Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!ELEMENT office:document ( office:meta?,
+							office:settings?,
+							office:script?,
+							office:font-decls?,
+							office:styles?,
+							office:automatic-styles?,
+							office:master-styles?,
+							office:body ) >
+
+<!ATTLIST office:document xmlns:office	CDATA #FIXED "&nOffice;">
+<!ATTLIST office:document xmlns:meta	CDATA #FIXED "&nMeta;">
+<!ATTLIST office:document xmlns:script	CDATA #FIXED "&nScript;">
+<!ATTLIST office:document xmlns:style	CDATA #FIXED "&nStyle;">
+<!ATTLIST office:document xmlns:text	CDATA #FIXED "&nText;">
+<!ATTLIST office:document xmlns:table	CDATA #FIXED "&nTable;">
+<!ATTLIST office:document xmlns:draw	CDATA #FIXED "&nDraw;">
+<!ATTLIST office:document xmlns:chart	CDATA #FIXED "&nChart;">
+<!ATTLIST office:document xmlns:number	CDATA #FIXED "&nNumber;">
+<!ATTLIST office:document xmlns:fo		CDATA #FIXED "&nFO;">
+<!ATTLIST office:document xmlns:xlink	CDATA #FIXED "&nXLink;">
+<!ATTLIST office:document xmlns:svg		CDATA #FIXED "&nSVG;">
+<!ATTLIST office:document xmlns:dc		CDATA #FIXED "&nDC;">
+<!ATTLIST office:document xmlns:dr3d	CDATA #FIXED "&nDr3D;">
+<!ATTLIST office:document xmlns:math	CDATA #FIXED "&nMath;">
+<!ATTLIST office:document xmlns:form	CDATA #FIXED "&nForm;">
+<!ATTLIST office:document xmlns:config	CDATA #FIXED "&nConfig;">
+
+<!ATTLIST office:document office:class
+						  (text|text-global|
+						   drawing|presentation|
+						   spreadsheet|chart) #REQUIRED>
+
+<!ATTLIST office:document office:version	%string; #IMPLIED>
+
+<!-- document-styles -->
+<!ELEMENT office:document-styles (
+							office:font-decls?,
+							office:styles?,
+							office:automatic-styles?,
+							office:master-styles? ) >
+
+<!ATTLIST office:document-styles xmlns:office	CDATA #FIXED "&nOffice;">
+<!ATTLIST office:document-styles xmlns:meta	CDATA #FIXED "&nMeta;">
+<!ATTLIST office:document-styles xmlns:script	CDATA #FIXED "&nScript;">
+<!ATTLIST office:document-styles xmlns:style	CDATA #FIXED "&nStyle;">
+<!ATTLIST office:document-styles xmlns:text	CDATA #FIXED "&nText;">
+<!ATTLIST office:document-styles xmlns:table	CDATA #FIXED "&nTable;">
+<!ATTLIST office:document-styles xmlns:draw	CDATA #FIXED "&nDraw;">
+<!ATTLIST office:document-styles xmlns:chart	CDATA #FIXED "&nChart;">
+<!ATTLIST office:document-styles xmlns:number	CDATA #FIXED "&nNumber;">
+<!ATTLIST office:document-styles xmlns:fo		CDATA #FIXED "&nFO;">
+<!ATTLIST office:document-styles xmlns:xlink	CDATA #FIXED "&nXLink;">
+<!ATTLIST office:document-styles xmlns:svg		CDATA #FIXED "&nSVG;">
+<!ATTLIST office:document-styles xmlns:dc		CDATA #FIXED "&nDC;">
+<!ATTLIST office:document-styles xmlns:dr3d		CDATA #FIXED "&nDr3D;">
+<!ATTLIST office:document-styles xmlns:math		CDATA #FIXED "&nMath;">
+<!ATTLIST office:document-styles xmlns:form		CDATA #FIXED "&nForm;">
+
+<!ATTLIST office:document-styles office:version	%string; #IMPLIED>
+
+<!-- document-content -->
+
+<!ELEMENT office:document-content (
+							office:script?,
+							office:font-decls?,
+							office:automatic-styles?,
+							office:body ) >
+
+<!ATTLIST office:document-content xmlns:office	CDATA #FIXED "&nOffice;">
+<!ATTLIST office:document-content xmlns:meta	CDATA #FIXED "&nMeta;">
+<!ATTLIST office:document-content xmlns:script	CDATA #FIXED "&nScript;">
+<!ATTLIST office:document-content xmlns:style	CDATA #FIXED "&nStyle;">
+<!ATTLIST office:document-content xmlns:text	CDATA #FIXED "&nText;">
+<!ATTLIST office:document-content xmlns:table	CDATA #FIXED "&nTable;">
+<!ATTLIST office:document-content xmlns:draw	CDATA #FIXED "&nDraw;">
+<!ATTLIST office:document-content xmlns:chart	CDATA #FIXED "&nChart;">
+<!ATTLIST office:document-content xmlns:number	CDATA #FIXED "&nNumber;">
+<!ATTLIST office:document-content xmlns:fo		CDATA #FIXED "&nFO;">
+<!ATTLIST office:document-content xmlns:xlink	CDATA #FIXED "&nXLink;">
+<!ATTLIST office:document-content xmlns:svg		CDATA #FIXED "&nSVG;">
+<!ATTLIST office:document-content xmlns:dc		CDATA #FIXED "&nDC;">
+<!ATTLIST office:document-content xmlns:dr3d	CDATA #FIXED "&nDr3D;">
+<!ATTLIST office:document-content xmlns:math	CDATA #FIXED "&nMath;">
+<!ATTLIST office:document-content xmlns:form	CDATA #FIXED "&nForm;">
+
+<!ATTLIST office:document-content office:class
+						  (text|text-global|
+						   drawing|presentation|
+						   spreadsheet|chart) #REQUIRED>
+
+<!ATTLIST office:document-content office:version	%string; #IMPLIED>
+
+<!-- document-content -->
+
+<!ELEMENT office:document-meta ( office:meta? ) >
+
+<!ATTLIST office:document-meta xmlns:office	CDATA #FIXED "&nOffice;">
+<!ATTLIST office:document-meta xmlns:meta	CDATA #FIXED "&nMeta;">
+<!ATTLIST office:document-meta xmlns:script	CDATA #FIXED "&nScript;">
+<!ATTLIST office:document-meta xmlns:style	CDATA #FIXED "&nStyle;">
+<!ATTLIST office:document-meta xmlns:text	CDATA #FIXED "&nText;">
+<!ATTLIST office:document-meta xmlns:table	CDATA #FIXED "&nTable;">
+<!ATTLIST office:document-meta xmlns:draw	CDATA #FIXED "&nDraw;">
+<!ATTLIST office:document-meta xmlns:chart	CDATA #FIXED "&nChart;">
+<!ATTLIST office:document-meta xmlns:number	CDATA #FIXED "&nNumber;">
+<!ATTLIST office:document-meta xmlns:fo		CDATA #FIXED "&nFO;">
+<!ATTLIST office:document-meta xmlns:xlink	CDATA #FIXED "&nXLink;">
+<!ATTLIST office:document-meta xmlns:svg		CDATA #FIXED "&nSVG;">
+<!ATTLIST office:document-meta xmlns:dc		CDATA #FIXED "&nDC;">
+<!ATTLIST office:document-meta xmlns:dr3d	CDATA #FIXED "&nDr3D;">
+<!ATTLIST office:document-meta xmlns:math	CDATA #FIXED "&nMath;">
+<!ATTLIST office:document-meta xmlns:form	CDATA #FIXED "&nForm;">
+
+<!ATTLIST office:document-meta office:version	%string; #IMPLIED>
+
+<!ELEMENT office:document-settings (office:settings) >
+<!ATTLIST office:document-settings xmlns:office	CDATA #FIXED "&nOffice;">
+<!ATTLIST office:document-settings xmlns:xlink	CDATA #FIXED "&nXLink;">
+<!ATTLIST office:document-settings xmlns:config	CDATA #FIXED "&nConfig;">
+
+<!ATTLIST office:document-settings office:version	%string; #IMPLIED>
+
+<!ENTITY % meta "(meta:generator?,
+				  dc:title?,
+				  dc:description?,
+				  dc:subject?,
+				  meta:initial-creator?,
+				  meta:creation-date?,
+				  dc:creator?,
+				  dc:date?,
+				  meta:printed-by?,
+				  meta:print-date?,
+				  meta:keywords?,
+				  dc:language?,
+				  meta:editing-cycles?,
+				  meta:editing-duration?,
+				  meta:hyperlink-behaviour?,
+				  meta:auto-reload?,
+				  meta:template?,
+				  meta:user-defined*,
+				  meta:document-statistic?)">
+<!ELEMENT office:meta %meta;>
+
+<!ENTITY % script	"(script:library-embedded |
+					  script:library-linked)*,office:events?">
+<!ELEMENT office:script (%script;)>
+
+<!ELEMENT office:font-decls (style:font-decl)*>
+
+<!ENTITY % styles "(style:default-style|style:style|text:list-style|
+		number:number-style|number:currency-style|number:percentage-style|
+		number:date-style|number:time-style|number:boolean-style|
+		number:text-style|
+		draw:gradient|draw:hatch|draw:fill-image|draw:marker|draw:stroke-dash|
+		style:presentation-page-layout|draw:transparency)">
+
+<!-- Validity constraint: The elements
+		text:outline-style,
+		text:footnotes-configuration,
+		text:endnotes-configuration,
+		text:bibliography-configuration and
+		text:linenumbering-configuration
+	may appear only once!
+	Unfortunatetly, this constraint cannot be easily specified in the DTD.
+-->
+<!ELEMENT office:styles (%styles;|text:outline-style|
+		text:footnotes-configuration|text:endnotes-configuration|
+		text:bibliography-configuration|text:linenumbering-configuration)*>
+
+<!ELEMENT office:automatic-styles (%styles;|style:page-master)*>
+
+<!ELEMENT office:master-styles (draw:layer-set?,style:handout-master?,style:master-page*) >
+
+
+<!ENTITY % body "(office:forms?,(text:tracked-changes|table:tracked-changes)?,%text-decls;,table:calculation-settings?,table:content-validations?,table:label-ranges?,
+		(text:h|text:p|text:ordered-list|
+		text:unordered-list|table:table|draw:page|
+		draw:a|%shape;|text:section|text:table-of-content|
+		text:illustration-index|text:table-index|text:object-index|
+		text:user-index|text:alphabetical-index|text:bibliography|
+		%change-marks;)*,
+		table:named-expressions?,
+		table:database-ranges?,table:data-pilot-tables?,
+		table:consolidation?,
+		table:dde-links?,
+		presentation:settings?)">
+<!ELEMENT office:body %body;>
+<!ATTLIST office:body table:structure-protected %boolean; "false"
+			table:protection-key CDATA #IMPLIED>
+
+<!ELEMENT office:events (script:event|presentation:event)*>
+
+<!-- DDE source: for text sections and tables -->
+<!ELEMENT office:dde-source EMPTY>
+<!ATTLIST office:dde-source office:dde-application CDATA #IMPLIED>
+<!ATTLIST office:dde-source office:dde-topic CDATA #IMPLIED>
+<!ATTLIST office:dde-source office:dde-item CDATA #IMPLIED>
+<!ATTLIST office:dde-source office:automatic-update %boolean; "false">
+<!ATTLIST office:dde-source office:name CDATA #IMPLIED>
+<!ATTLIST office:dde-source table:conversion-mode (into-default-style-data-style|into-english-number|let-text) "into-default-style-data-style" >
+
+<!-- annotations -->
+<!-- limitation: in the current implementation, only plain text inside of
+     paragraphs is supported -->
+<!ELEMENT office:annotation (text:p)*>
+<!ATTLIST office:annotation office:author %string; #IMPLIED>
+<!ATTLIST office:annotation office:create-date %date; #IMPLIED>
+<!ATTLIST office:annotation office:create-date-string %string; #IMPLIED>
+<!ATTLIST office:annotation office:display %boolean; "false">
+
+<!ELEMENT office:change-info (text:p)*>
+<!ATTLIST office:change-info office:chg-author %string; #REQUIRED>
+<!ATTLIST office:change-info office:chg-date-time %timeInstance; #REQUIRED>
+
+<!ELEMENT office:binary-data (#PCDATA)>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/script.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/script.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/script.mod	(revision 28000)
@@ -0,0 +1,79 @@
+<!--
+	$Id: script.mod,v 1.7 2001/08/09 13:22:49 dvo Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!ELEMENT script:library-embedded (script:module*)>
+<!ATTLIST script:library-embedded script:name %string; #REQUIRED>
+<!ATTLIST script:library-embedded script:password %string; #IMPLIED>
+
+<!ELEMENT script:library-linked EMPTY>
+<!ATTLIST script:library-linked script:name %string; #REQUIRED>
+<!ATTLIST script:library-linked xlink:href %string; #REQUIRED>
+<!ATTLIST script:library-linked xlink:type (simple) #FIXED "simple">
+
+<!ELEMENT script:module (#PCDATA)>
+<!ATTLIST script:module script:name %string; #REQUIRED>
+<!ATTLIST script:module script:language %string; #IMPLIED>
+
+
+<!ENTITY % script-language "script:language %string; #REQUIRED">
+<!ENTITY % event-name "script:event-name %string; #REQUIRED">
+<!ENTITY % location "script:location (document|application) #REQUIRED">
+<!ENTITY % macro-name "script:macro-name %string; #REQUIRED">
+
+<!ELEMENT script:event (#PCDATA)>
+<!ATTLIST script:event %script-language;
+                       %event-name;
+                       %location;
+					   %macro-name;>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/settings.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/settings.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/settings.mod	(revision 28000)
@@ -0,0 +1,77 @@
+<!--
+	$Id: settings.mod,v 1.2 2001/05/04 13:03:16 sab Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!ELEMENT office:settings (config:config-item-set+)>
+
+<!ENTITY % items	"(config:config-item |
+			config:config-item-set |
+			config:config-item-map-named |
+			config:config-item-map-indexed)+">
+
+<!ELEMENT config:config-item-set %items;>
+<!ATTLIST config:config-item-set config:name CDATA #REQUIRED>
+
+<!ELEMENT config:config-item (#PCDATA)>
+<!ATTLIST config:config-item config:name CDATA #REQUIRED
+			config:type (boolean | short | int | long | double | string | datetime | base64Binary) #REQUIRED>
+
+<!ELEMENT config:config-item-map-named (config:config-item-map-entry)+>
+<!ATTLIST config:config-item-map-named config:name CDATA #REQUIRED>
+
+<!ELEMENT config:config-item-map-indexed (config:config-item-map-entry)+>
+<!ATTLIST config:config-item-map-indexed config:name CDATA #REQUIRED>
+
+<!ELEMENT config:config-item-map-entry %items;>
+<!ATTLIST config:config-item-map-entry config:name CDATA #IMPLIED>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/statusbar.dtd
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/statusbar.dtd	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/statusbar.dtd	(revision 28000)
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	$Id: statusbar.dtd,v 1.2 2001/10/16 15:44:43 cd Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+-->
+
+<!ENTITY % boolean		"(true|false)">
+<!ENTITY % numeric		"CDATA">
+<!ENTITY % alignment	"(left|center|right)">
+<!ENTITY % style		"(in|out|flat)">
+
+<!ELEMENT statusbar:statusbar (statusbar:statusbaritem*)>
+<!ATTLIST statusbar:statusbar
+	xmlns:statusbar CDATA #FIXED "http://openoffice.org/2001/statusbar"
+	xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink"
+>
+<!ELEMENT statusbar:statusbaritem EMPTY>
+<!ATTLIST statusbar:statusbaritem
+	xlink:href CDATA #REQUIRED
+	statusbar:align %alignment; "center"
+	statusbar:style %style; "in"
+	statusbar:autosize %boolean; "false"
+	statusbar:ownerdraw %boolean; "false"
+	statusbar:width %numeric; "0"
+	statusbar:offset %numeric; "5"
+>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/style.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/style.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/style.mod	(revision 28000)
@@ -0,0 +1,449 @@
+<!--
+	$Id: style.mod,v 1.58 2003/05/27 16:06:15 rt Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!ELEMENT style:font-decl EMPTY>
+<!ATTLIST style:font-decl style:name %string; #REQUIRED>
+<!ATTLIST style:font-decl fo:font-family %string; #REQUIRED>
+<!ATTLIST style:font-decl style:font-style-name %string; #IMPLIED>
+<!ENTITY % fontFamilyGeneric "(roman|swiss|modern|decorative|script|system)">
+<!ATTLIST style:font-decl style:font-family-generic %fontFamilyGeneric;
+						   #IMPLIED>
+<!ENTITY % fontPitch "(fixed|variable)">
+<!ATTLIST style:font-decl style:font-pitch %fontPitch; #IMPLIED>
+<!ATTLIST style:font-decl style:font-charset %textEncoding; #IMPLIED>
+
+<!ELEMENT style:style ( style:properties?,office:events?,style:map*)>
+
+<!ATTLIST style:style style:name %styleName; #REQUIRED>
+
+<!ENTITY % styleFamily "(paragraph|text|section|
+						 table|table-column|table-row|table-cell|table-page|chart|graphics|default|drawing-page|presentation|control|ruby)">
+<!ATTLIST style:style style:family %styleFamily; #REQUIRED>
+
+<!ATTLIST style:style style:parent-style-name %styleName; #IMPLIED>
+<!ATTLIST style:style style:master-page-name %styleName; #IMPLIED>
+<!ATTLIST style:style style:next-style-name %styleName; #IMPLIED>
+<!ATTLIST style:style style:list-style-name %styleName; #IMPLIED>
+<!ATTLIST style:style style:data-style-name %styleName; #IMPLIED>
+
+<!ATTLIST style:style style:auto-update %boolean; "false">
+
+<!ATTLIST style:style style:class %string; #IMPLIED>
+
+<!ELEMENT style:default-style (style:properties?)>
+<!ATTLIST style:default-style style:family %styleFamily; #REQUIRED>
+
+<!ELEMENT style:map EMPTY>
+
+<!ATTLIST style:map style:condition %string; #REQUIRED>
+<!ATTLIST style:map style:apply-style-name %styleName; #REQUIRED>
+<!ATTLIST style:map style:base-cell-address %cell-address; #IMPLIED>
+
+<!ELEMENT style:properties ANY>
+
+<!-- number format properties -->
+<!ATTLIST style:properties style:num-prefix %string; #IMPLIED>
+<!ATTLIST style:properties style:num-suffix %string; #IMPLIED>
+<!ATTLIST style:properties style:num-format %string; #IMPLIED>
+<!ATTLIST style:properties style:num-letter-sync %boolean; #IMPLIED>
+
+<!-- frame properties -->
+<!ATTLIST style:properties fo:width %positiveLength; #IMPLIED>
+<!ATTLIST style:properties fo:height %positiveLength; #IMPLIED>
+<!ATTLIST style:properties style:vertical-pos (top|middle|bottom|from-top|below) #IMPLIED>
+<!ATTLIST style:properties style:vertical-rel (page|page-content|
+											   frame|frame-content|
+											   paragraph|paragraph-content|char|
+											   line|baseline|text) #IMPLIED>
+<!ATTLIST style:properties style:horizontal-pos (left|center|right|from-left|inside|outside|from-inside) #IMPLIED>
+<!ATTLIST style:properties style:horizontal-rel (page|page-content|
+								 page-start-margin|page-end-margin|
+								 frame|frame-content|
+								 frame-start-margin|frame-end-margin|
+								 paragraph|paragraph-content|
+								 paragraph-start-margin|paragraph-end-margin|
+								 char) #IMPLIED>
+<!ATTLIST style:properties svg:width %lengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties svg:height %lengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties fo:min-height %lengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties fo:min-width %lengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties fo:max-height %lengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties fo:max-width %lengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties text:anchor-type %anchorType; #IMPLIED>
+<!ATTLIST style:properties text:anchor-page-number %positiveInteger; #IMPLIED>
+<!ATTLIST style:properties svg:x %coordinate; #IMPLIED>
+<!ATTLIST style:properties svg:y %coordinate; #IMPLIED>
+<!ATTLIST style:properties style:print-content %boolean; #IMPLIED>
+<!ATTLIST style:properties style:protect %boolean; #IMPLIED>
+<!ATTLIST style:properties style:wrap (none|left|right|parallel|dynamic|run-through) #IMPLIED>
+<!ENTITY % noLimitOrPositiveInteger "CDATA">
+<!ATTLIST style:properties style:number-wrapped-paragraphs %noLimitOrPositiveInteger; #IMPLIED>
+<!ATTLIST style:properties style:wrap-contour %boolean; #IMPLIED>
+<!ATTLIST style:properties style:wrap-contour-mode (full|outside) #IMPLIED>
+<!ATTLIST style:properties style:run-through (foreground|background) #IMPLIED>
+<!ATTLIST style:properties style:editable %boolean; #IMPLIED>
+<!ATTLIST style:properties style:mirror CDATA #IMPLIED>
+<!ATTLIST style:properties fo:clip CDATA #IMPLIED>
+<!ATTLIST style:properties text:animation (none|scroll|alternate|slide) #IMPLIED>
+<!ATTLIST style:properties text:animation-direction (left|right|up|down) #IMPLIED>
+<!ATTLIST style:properties text:animation-start-inside %boolean; #IMPLIED>
+<!ATTLIST style:properties text:animation-stop-inside %boolean; #IMPLIED>
+<!ATTLIST style:properties text:animation-repeat %integer; #IMPLIED>
+<!ATTLIST style:properties text:animation-delay %timeDuration; #IMPLIED>
+<!ATTLIST style:properties text:animation-steps %length; #IMPLIED>
+
+<!-- text properties -->
+<!ATTLIST style:properties fo:font-variant (normal|small-caps) #IMPLIED>
+<!ATTLIST style:properties fo:text-transform (none|lowercase|
+											  uppercase|capitalize) #IMPLIED>
+<!ATTLIST style:properties fo:color %color; #IMPLIED>
+<!ATTLIST style:properties style:use-window-font-color %boolean; #IMPLIED>
+<!ATTLIST style:properties style:text-outline %boolean; #IMPLIED>
+<!ATTLIST style:properties style:text-crossing-out
+						   (none|single-line|double-line|thick-line|slash|X)
+						   #IMPLIED>
+<!ATTLIST style:properties style:text-position CDATA #IMPLIED>
+<!ATTLIST style:properties style:text-align (left|right|start|center|end|justify|justified) #IMPLIED>
+
+<!ATTLIST style:properties style:font-name %string; #IMPLIED>
+<!ATTLIST style:properties fo:font-family %string; #IMPLIED>
+<!ATTLIST style:properties style:font-family-generic %fontFamilyGeneric;
+						   #IMPLIED>
+<!ATTLIST style:properties style:font-style-name %string; #IMPLIED>
+<!ATTLIST style:properties style:font-pitch %fontPitch; #IMPLIED>
+<!ATTLIST style:properties style:font-charset %textEncoding; #IMPLIED>
+<!ATTLIST style:properties style:font-name-asian %string; #IMPLIED>
+<!ATTLIST style:properties style:font-family-asian %string; #IMPLIED>
+<!ATTLIST style:properties style:font-family-generic-asian %fontFamilyGeneric;
+						   #IMPLIED>
+<!ATTLIST style:properties style:font-style-name-asian %string; #IMPLIED>
+<!ATTLIST style:properties style:font-pitch-asian %fontPitch; #IMPLIED>
+<!ATTLIST style:properties style:font-charset-asian %textEncoding; #IMPLIED>
+<!ATTLIST style:properties style:font-name-complex %string; #IMPLIED>
+<!ATTLIST style:properties style:font-family-complex %string; #IMPLIED>
+<!ATTLIST style:properties style:font-family-generic-complex %fontFamilyGeneric;
+						   #IMPLIED>
+<!ATTLIST style:properties style:font-style-name-complex %string; #IMPLIED>
+<!ATTLIST style:properties style:font-pitch-complex %fontPitch; #IMPLIED>
+<!ATTLIST style:properties style:font-charset-complex %textEncoding; #IMPLIED>
+
+<!ATTLIST style:properties fo:font-size %positiveLengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties style:font-size-rel %length; #IMPLIED>
+<!ATTLIST style:properties style:font-size-asian %positiveLengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties style:font-size-rel-asian %length; #IMPLIED>
+<!ATTLIST style:properties style:font-size-complex %positiveLengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties style:font-size-rel-complex %length; #IMPLIED>
+<!ENTITY % normalOrLength "CDATA">
+<!ATTLIST style:properties fo:letter-spacing %normalOrLength; #IMPLIED>
+<!ATTLIST style:properties fo:language %languageOnly; #IMPLIED>
+<!ATTLIST style:properties style:language-asian %languageOnly; #IMPLIED>
+<!ATTLIST style:properties style:language-complex %languageOnly; #IMPLIED>
+<!ATTLIST style:properties fo:country %country; #IMPLIED>
+<!ATTLIST style:properties style:country-asian %country; #IMPLIED>
+<!ATTLIST style:properties style:country-complex %country; #IMPLIED>
+<!ENTITY % fontStyle "(normal|italic|oblique)">
+<!ATTLIST style:properties fo:font-style %fontStyle; #IMPLIED>
+<!ATTLIST style:properties style:font-style-asian %fontStyle; #IMPLIED>
+<!ATTLIST style:properties style:font-style-complex %fontStyle; #IMPLIED>
+<!ENTITY % fontRelief "(none|embossed|engraved)">
+<!ATTLIST style:properties style:font-relief %fontRelief; #IMPLIED>
+<!ATTLIST style:properties fo:text-shadow CDATA #IMPLIED>
+<!ATTLIST style:properties style:text-underline
+						   (none|single|double|dotted|dash|long-dash|dot-dash|
+							dot-dot-dash|wave|bold|bold-dotted|bold-dash|
+							bold-long-dash|bold-dot-dash|bold-dot-dot-dash|
+							bold-wave|double-wave|small-wave) #IMPLIED>
+<!ATTLIST style:properties style:text-autospace (none | ideograph-alpha) #IMPLIED>
+<!ATTLIST style:properties style:punctuation-wrap (simple | hanging) #IMPLIED>
+<!ATTLIST style:properties style:line-break (normal | strict) #IMPLIED>
+<!ENTITY % fontColorOrColor "CDATA">
+<!ATTLIST style:properties style:text-underline-color %fontColorOrColor;
+						   #IMPLIED>
+<!ATTLIST style:properties fo:font-weight CDATA #IMPLIED>
+<!ATTLIST style:properties style:font-weight-asian CDATA #IMPLIED>
+<!ATTLIST style:properties style:font-weight-complex CDATA #IMPLIED>
+<!ATTLIST style:properties fo:score-spaces %boolean; #IMPLIED>
+<!ATTLIST style:properties style:letter-kerning %boolean; #IMPLIED>
+<!ATTLIST style:properties style:text-blinking %boolean; #IMPLIED>
+<!ATTLIST style:properties style:text-background-color %transparentOrColor;
+						   #IMPLIED>
+
+<!ATTLIST style:properties style:text-combine (none|letters|lines) #IMPLIED>
+<!ATTLIST style:properties style:text-combine-start-char %character; #IMPLIED>
+<!ATTLIST style:properties style:text-combine-end-char %character; #IMPLIED>
+<!ATTLIST style:properties style:text-emphasize CDATA #IMPLIED>
+<!ATTLIST style:properties style:text-scale %percentage; #IMPLIED>
+<!ATTLIST style:properties style:text-rotation-angle %integer; #IMPLIED>
+<!ATTLIST style:properties style:text-rotation-scale (fixed|line-height) #IMPLIED>
+
+<!-- paragraph properties -->
+<!ENTITY % nonNegativeLengthOrPercentageOrNormal "CDATA">
+<!ATTLIST style:properties fo:line-height
+						   %nonNegativeLengthOrPercentageOrNormal; #IMPLIED>
+<!ATTLIST style:properties style:line-height-at-least %nonNegativeLength;
+						   #IMPLIED>
+<!ATTLIST style:properties style:line-spacing %length; #IMPLIED>
+<!ATTLIST style:properties fo:text-align (start|end|center|justify) #IMPLIED>
+<!ATTLIST style:properties fo:text-align-last (start|center|justify) #IMPLIED>
+<!ATTLIST style:properties style:text-align-source (fix|value-type) #IMPLIED>
+<!ATTLIST style:properties style:justify-single-word %boolean; #IMPLIED>
+<!ATTLIST style:properties style:break-inside (auto|avoid) #IMPLIED>
+<!ATTLIST style:properties fo:widows %nonNegativeInteger; #IMPLIED>
+<!ATTLIST style:properties fo:orphans %nonNegativeInteger; #IMPLIED>
+
+<!ATTLIST style:properties fo:hyphenate %boolean; #IMPLIED>
+<!ATTLIST style:properties fo:hyphenate-keep (none|page) #IMPLIED>
+<!ATTLIST style:properties fo:hyphenation-remain-char-count %positiveInteger;
+						   #IMPLIED>
+<!ATTLIST style:properties fo:hyphenation-push-char-count %positiveInteger;
+						   #IMPLIED>
+<!ATTLIST style:properties fo:hyphenation-ladder-count
+						   %noLimitOrPositiveInteger;  #IMPLIED>
+<!ATTLIST style:properties style:page-number %positiveInteger; #IMPLIED>
+
+<!ELEMENT style:tab-stops (style:tab-stop)*>
+<!ELEMENT style:tab-stop EMPTY>
+<!ATTLIST style:tab-stop style:position %nonNegativeLength; #REQUIRED>
+<!ATTLIST style:tab-stop style:type (left|center|right|char|default) "left">
+<!ATTLIST style:tab-stop style:char %character; #IMPLIED>
+<!ATTLIST style:tab-stop style:leader-char %character; " ">
+
+<!ELEMENT style:drop-cap EMPTY>
+<!ENTITY % wordOrPositiveInteger "CDATA">
+<!ATTLIST style:drop-cap style:length %wordOrPositiveInteger; "1">
+<!ATTLIST style:drop-cap style:lines %positiveInteger; "1">
+<!ATTLIST style:drop-cap style:distance %length; "0cm">
+<!ATTLIST style:drop-cap style:style-name %styleName; #IMPLIED>
+
+<!ATTLIST style:properties style:register-true %boolean; #IMPLIED>
+<!ATTLIST style:properties style:register-truth-ref-style-name %styleName; #IMPLIED>
+<!ATTLIST style:properties fo:margin-left %positiveLengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties fo:margin-right %positiveLengthOrPercentage;
+						   #IMPLIED>
+<!ATTLIST style:properties fo:text-indent %lengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties style:auto-text-indent %boolean; #IMPLIED>
+<!ATTLIST style:properties fo:margin-top %positiveLengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties fo:margin-bottom %positiveLengthOrPercentage; #IMPLIED>
+<!ATTLIST style:properties fo:break-before (auto|column|page) #IMPLIED>
+<!ATTLIST style:properties fo:break-after (auto|column|page) #IMPLIED>
+<!ATTLIST style:properties fo:background-color %transparentOrColor; #IMPLIED>
+<!ATTLIST style:properties style:background-transparency %percentage; #IMPLIED>
+<!ATTLIST style:properties style:dynamic-spacing %boolean; #IMPLIED>
+
+<!ELEMENT style:background-image (office:binary-data?)>
+<!ATTLIST style:background-image xlink:type (simple) #IMPLIED>
+<!ATTLIST style:background-image xlink:href %uriReference; #IMPLIED>
+<!ATTLIST style:background-image xlink:show (embed) #IMPLIED>
+<!ATTLIST style:background-image xlink:actuate (onLoad) #IMPLIED>
+<!ATTLIST style:background-image style:repeat (no-repeat|repeat|stretch)
+								 "repeat">
+<!ATTLIST style:background-image style:position CDATA "center">
+<!ATTLIST style:background-image style:filter-name %string; #IMPLIED>
+<!ATTLIST style:background-image draw:transparency %percentage; #IMPLIED>
+
+<!ELEMENT style:symbol-image (office:binary-data?)>
+<!ATTLIST style:symbol-image xlink:type (simple) #IMPLIED>
+<!ATTLIST style:symbol-image xlink:href %uriReference; #IMPLIED>
+<!ATTLIST style:symbol-image xlink:show (embed) #IMPLIED>
+<!ATTLIST style:symbol-image xlink:actuate (onLoad) #IMPLIED>
+
+<!ATTLIST style:properties fo:border CDATA #IMPLIED>
+<!ATTLIST style:properties fo:border-top CDATA #IMPLIED>
+<!ATTLIST style:properties fo:border-bottom CDATA #IMPLIED>
+<!ATTLIST style:properties fo:border-left CDATA #IMPLIED>
+<!ATTLIST style:properties fo:border-right CDATA #IMPLIED>
+<!ATTLIST style:properties style:border-line-width CDATA #IMPLIED>
+<!ATTLIST style:properties style:border-line-width-top CDATA #IMPLIED>
+<!ATTLIST style:properties style:border-line-width-bottom CDATA #IMPLIED>
+<!ATTLIST style:properties style:border-line-width-left CDATA #IMPLIED>
+<!ATTLIST style:properties style:border-line-width-right CDATA #IMPLIED>
+<!ATTLIST style:properties fo:padding %nonNegativeLength; #IMPLIED>
+<!ATTLIST style:properties fo:padding-top %nonNegativeLength; #IMPLIED>
+<!ATTLIST style:properties fo:padding-bottom %nonNegativeLength; #IMPLIED>
+<!ATTLIST style:properties fo:padding-left %nonNegativeLength; #IMPLIED>
+<!ATTLIST style:properties fo:padding-right %nonNegativeLength; #IMPLIED>
+<!ATTLIST style:properties style:shadow CDATA #IMPLIED>
+<!ATTLIST style:properties fo:keep-with-next %boolean; #IMPLIED>
+<!ATTLIST style:properties style:join-border %boolean; #IMPLIED>
+
+<!ATTLIST style:properties text:number-lines %boolean; "false">
+<!ATTLIST style:properties text:line-number %nonNegativeInteger; #IMPLIED>
+
+<!ATTLIST style:properties style:decimal-places %nonNegativeInteger; #IMPLIED>
+<!ATTLIST style:properties style:tab-stop-distance %nonNegativeLength; #IMPLIED>
+
+<!-- section properties -->
+<!ATTLIST style:properties text:dont-balance-text-columns %boolean; #IMPLIED>
+
+<!-- ruby properties -->
+<!ATTLIST style:properties style:ruby-align (left|center|right|distribute-letter|distribute-space) #IMPLIED>
+<!ATTLIST style:properties style:ruby-position (above|below) #IMPLIED>
+
+
+<!-- table properties -->
+<!ATTLIST style:properties style:width %positiveLength; #IMPLIED>
+<!ATTLIST style:properties style:rel-width %percentage; #IMPLIED>
+<!ATTLIST style:properties style:may-break-between-rows %boolean; #IMPLIED>
+<!ATTLIST style:properties table:page-style-name %styleName; #IMPLIED>
+<!ATTLIST style:properties table:display %boolean; #IMPLIED>
+
+<!-- table column properties -->
+<!ATTLIST style:properties style:column-width %positiveLength; #IMPLIED>
+<!ENTITY % relWidth "CDATA">
+<!ATTLIST style:properties style:rel-column-width %relWidth; #IMPLIED>
+<!ATTLIST style:properties style:use-optimal-column-width %boolean; #IMPLIED>
+
+<!-- table row properties -->
+<!ATTLIST style:properties style:row-height %positiveLength; #IMPLIED>
+<!ATTLIST style:properties style:min-row-height %nonNegativeLength; #IMPLIED>
+<!ATTLIST style:properties style:use-optimal-row-height %boolean; #IMPLIED>
+
+<!-- table cell properties -->
+<!ATTLIST style:properties
+	table:align (left | center | right | margins) #IMPLIED
+	table:border-model (collapsing | separating) #IMPLIED
+	fo:vertical-align (top | middle | bottom | automatic) #IMPLIED
+	fo:direction (ltr | ttb) #IMPLIED
+	style:glyph-orientation-vertical (auto | 0) #IMPLIED
+	style:rotation-angle %nonNegativeInteger; #IMPLIED
+	style:rotation-align (none | bottom | top | center) #IMPLIED
+	style:cell-protect CDATA #IMPLIED
+	fo:wrap-option (no-wrap | wrap) #IMPLIED
+>
+<!ELEMENT style:columns (style:column-sep?,style:column*)>
+<!ATTLIST style:columns fo:column-count %nonNegativeInteger; #IMPLIED>
+<!ATTLIST style:columns fo:column-gap %positiveLength; #IMPLIED>
+
+<!ELEMENT style:column EMPTY>
+<!ATTLIST style:column style:rel-width CDATA #IMPLIED>
+<!ATTLIST style:column fo:margin-left %positiveLength; #IMPLIED>
+<!ATTLIST style:column fo:margin-right %positiveLength; #IMPLIED>
+
+<!ELEMENT style:column-sep EMPTY>
+<!ATTLIST style:column-sep style:style (none|solid|dotted|dashed|dot-dashed)
+																	"solid">
+<!ATTLIST style:column-sep style:width %length; #REQUIRED>
+<!ATTLIST style:column-sep style:height %percentage; "100%">
+<!ATTLIST style:column-sep style:vertical-align (top|middle|bottom) "top">
+<!ATTLIST style:column-sep style:color %color; "#000000">
+
+<!-- page master properties -->
+<!ELEMENT style:page-master (style:properties?, style:header-style?, style:footer-style?)>
+<!ATTLIST style:page-master style:name %styleName; #REQUIRED>
+<!ATTLIST style:page-master style:page-usage (all|left|right|mirrored) "all">
+
+<!ELEMENT style:header-style (style:properties?)>
+<!ELEMENT style:footer-style (style:properties?)>
+
+<!ATTLIST style:properties fo:page-width %length; #IMPLIED>
+<!ATTLIST style:properties fo:page-height %length; #IMPLIED>
+<!ATTLIST style:properties style:paper-tray-name %string; #IMPLIED>
+<!ATTLIST style:properties style:print-orientation (portrait|landscape) #IMPLIED>
+<!ATTLIST style:properties style:print CDATA #IMPLIED>
+<!ATTLIST style:properties style:print-page-order (ttb|ltr) #IMPLIED>
+<!ATTLIST style:properties style:first-page-number %positiveInteger; #IMPLIED>
+<!ATTLIST style:properties style:scale-to %percentage; #IMPLIED>
+<!ATTLIST style:properties style:scale-to-pages %positiveInteger; #IMPLIED>
+<!ATTLIST style:properties style:table-centering (horizontal | vertical | both | none) #IMPLIED>
+
+<!ATTLIST style:properties style:footnote-max-height %lengthOrNoLimit; #IMPLIED>
+<!ATTLIST style:properties style:vertical-align (top|bottom|middle|basline|auto) #IMPLIED>
+<!ATTLIST style:properties style:writing-mode (lr-tb|rl-tb|tb-rl|tb-lr|lr|rl|tb|page) "lr-tb">
+<!ATTLIST style:properties style:layout-grid-mode (none|line|both) #IMPLIED>
+<!ATTLIST style:properties style:layout-grid-base-height %length; #IMPLIED>
+<!ATTLIST style:properties style:layout-grid-ruby-height %length; #IMPLIED>
+<!ATTLIST style:properties style:layout-grid-lines %positiveInteger; #IMPLIED>
+<!ATTLIST style:properties style:layout-grid-color %color; #IMPLIED>
+<!ATTLIST style:properties style:layout-grid-ruby-below %boolean; #IMPLIED>
+<!ATTLIST style:properties style:layout-grid-print %boolean; #IMPLIED>
+<!ATTLIST style:properties style:layout-grid-display %boolean; #IMPLIED>
+<!ATTLIST style:properties style:snap-to-layout-grid %boolean; #IMPLIED>
+
+<!ELEMENT style:footnote-sep EMPTY>
+<!ATTLIST style:footnote-sep style:width %length; #IMPLIED>
+<!ATTLIST style:footnote-sep style:rel-width %percentage; #IMPLIED>
+<!ATTLIST style:footnote-sep style:color %color; #IMPLIED>
+<!ATTLIST style:footnote-sep style:adjustment (left|center|right) "left">
+<!ATTLIST style:footnote-sep style:distance-before-sep %length; #IMPLIED>
+<!ATTLIST style:footnote-sep style:distance-after-sep %length; #IMPLIED>
+
+<!-- master page -->
+<!ELEMENT style:master-page ( (style:header, style:header-left?)?, (style:footer, style:footer-left?)?,
+								office:forms?,style:style*, (%shapes;)*, presentation:notes? )>
+<!ATTLIST style:master-page style:name %styleName; #REQUIRED>
+<!ATTLIST style:master-page style:page-master-name %styleName; #REQUIRED>
+<!ATTLIST style:master-page style:next-style-name %styleName; #IMPLIED>
+<!ATTLIST style:master-page draw:style-name %styleName; #IMPLIED>
+
+<!-- handout master -->
+<!ELEMENT style:handout-master (%shapes;)*>
+<!ATTLIST style:handout-master presentation:presentation-page-layout-name %styleName; #IMPLIED>
+<!ATTLIST style:handout-master style:page-master-name %styleName; #IMPLIED>
+
+
+<!ENTITY % hd-ft-content "( %headerText; | (style:region-left?, style:region-center?, style:region-right?) )">
+<!ELEMENT style:header %hd-ft-content;>
+<!ATTLIST style:header style:display %boolean; "true">
+<!ELEMENT style:footer %hd-ft-content;>
+<!ATTLIST style:footer style:display %boolean; "true">
+<!ELEMENT style:header-left %hd-ft-content;>
+<!ATTLIST style:header-left style:display %boolean; "true">
+<!ELEMENT style:footer-left %hd-ft-content;>
+<!ATTLIST style:footer-left style:display %boolean; "true">
+
+<!ENTITY % region-content "(text:p*)">
+<!ELEMENT style:region-left %region-content;>
+<!ELEMENT style:region-center %region-content;>
+<!ELEMENT style:region-right %region-content;>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/table.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/table.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/table.mod	(revision 28000)
@@ -0,0 +1,522 @@
+<!--
+	$Id: table.mod,v 1.42 2002/11/08 08:40:55 sab Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+
+-->
+
+<!ELEMENT table:calculation-settings (table:null-date?, table:iteration?)>
+<!ATTLIST table:calculation-settings
+	table:case-sensitive %boolean; "true"
+	table:precision-as-shown %boolean; "false"
+	table:search-criteria-must-apply-to-whole-cell %boolean; "true"
+	table:automatic-find-labels %boolean; "true"
+	table:use-regular-expressions %boolean; "true"
+	table:null-year %positiveInteger; "1930"
+>
+<!ELEMENT table:null-date EMPTY>
+<!ATTLIST table:null-date
+	table:value-type %valueType; #FIXED "date"
+	table:date-value %date; "1899-12-30"
+>
+<!ELEMENT table:iteration EMPTY>
+<!ATTLIST table:iteration
+	table:status (enable | disable) "disable"
+	table:steps %positiveInteger; "100"
+	table:maximum-difference %float; "0.001"
+>
+
+<!ELEMENT table:tracked-changes (table:cell-content-change | table:insertion | table:deletion | table:movement | table:rejection)*>
+<!ATTLIST table:tracked-changes table:track-changes %boolean; "true"
+				table:protected %boolean; "false"
+				table:protection-key CDATA #IMPLIED
+>
+
+<!ELEMENT table:dependences (table:dependence)+>
+<!ELEMENT table:dependence EMPTY>
+<!ATTLIST table:dependence
+	table:id CDATA #REQUIRED
+>
+<!ELEMENT table:deletions (table:cell-content-deletion | table:change-deletion)+>
+<!ELEMENT table:cell-content-deletion (table:cell-address?, table:change-track-table-cell?)>
+<!ATTLIST table:cell-content-deletion
+	table:id CDATA #IMPLIED
+>
+<!ELEMENT table:change-deletion EMPTY>
+<!ATTLIST table:change-deletion
+	table:id CDATA #IMPLIED
+>
+<!ELEMENT table:insertion (office:change-info, table:dependences?, table:deletions?)>
+<!ATTLIST table:insertion
+	table:id CDATA #REQUIRED
+	table:acceptance-state (accepted | rejected | pending) "pending"
+	table:rejecting-change-id %positiveInteger; #IMPLIED
+	table:type (row | column | table) #REQUIRED
+	table:position %integer; #REQUIRED
+	table:count %positiveInteger; "1"
+	table:table %integer; #IMPLIED
+>
+<!ELEMENT table:deletion (office:change-info, table:dependences?, table:deletions?, table:cut-offs?)>
+<!ATTLIST table:deletion
+	table:id CDATA #REQUIRED
+	table:acceptance-state (accepted | rejected | pending) "pending"
+	table:rejecting-change-id %positiveInteger; #IMPLIED
+	table:type (row | column | table) #REQUIRED
+	table:position %integer; #REQUIRED
+	table:count %positiveInteger; "1"
+	table:table %integer; #IMPLIED
+	table:multi-deletion-spanned %integer; #IMPLIED
+>
+<!ELEMENT table:cut-offs (table:movement-cut-off+ | (table:insertion-cut-off, table:movement-cut-off*))>
+<!ELEMENT table:insertion-cut-off EMPTY>
+<!ATTLIST table:insertion-cut-off
+	table:id CDATA #REQUIRED
+	table:position %integer; #REQUIRED
+>
+<!ELEMENT table:movement-cut-off EMPTY>
+<!ATTLIST table:movement-cut-off
+	table:id CDATA #REQUIRED
+	table:start-position %integer; #IMPLIED
+	table:end-position %integer; #IMPLIED
+	table:position %integer; #IMPLIED
+>
+<!ELEMENT table:movement (table:source-range-address, table:target-range-address, office:change-info, table:dependences?, table:deletions?)>
+<!ATTLIST table:movement
+	table:id CDATA #REQUIRED
+	table:acceptance-state (accepted | rejected | pending) "pending"
+	table:rejecting-change-id %positiveInteger; #IMPLIED
+>
+<!ELEMENT table:target-range-address EMPTY>
+<!ATTLIST table:target-range-address
+	table:column %integer; #IMPLIED
+	table:row %integer; #IMPLIED
+	table:table %integer; #IMPLIED
+	table:start-column %integer; #IMPLIED
+	table:start-row %integer; #IMPLIED
+	table:start-table %integer; #IMPLIED
+	table:end-column %integer; #IMPLIED
+	table:end-row %integer; #IMPLIED
+	table:end-table %integer; #IMPLIED
+>
+<!ELEMENT table:source-range-address EMPTY>
+<!ATTLIST table:source-range-address
+	table:column %integer; #IMPLIED
+	table:row %integer; #IMPLIED
+	table:table %integer; #IMPLIED
+	table:start-column %integer; #IMPLIED
+	table:start-row %integer; #IMPLIED
+	table:start-table %integer; #IMPLIED
+	table:end-column %integer; #IMPLIED
+	table:end-row %integer; #IMPLIED
+	table:end-table %integer; #IMPLIED
+>
+<!ELEMENT table:change-track-table-cell (text:p*)>
+<!ATTLIST table:change-track-table-cell
+	table:cell-address %cell-address; #IMPLIED
+	table:matrix-covered (true | false) "false"
+	table:formula %string; #IMPLIED
+	table:number-matrix-rows-spanned %positiveInteger; #IMPLIED
+	table:number-matrix-columns-spanned %positiveInteger; #IMPLIED
+	table:value-type %valueType; "string"
+	table:value %float; #IMPLIED
+	table:date-value %date; #IMPLIED
+	table:time-value %timeInstance; #IMPLIED
+	table:string-value %string; #IMPLIED
+>
+<!ELEMENT table:cell-content-change (table:cell-address, office:change-info, table:dependences?, table:deletions?, table:previous)>
+<!ATTLIST table:cell-content-change
+	table:id CDATA #REQUIRED
+	table:acceptance-state (accepted | rejected | pending) "pending"
+	table:rejecting-change-id %positiveInteger; #IMPLIED
+>
+<!ELEMENT table:cell-address EMPTY>
+<!ATTLIST table:cell-address
+	table:column %integer; #IMPLIED
+	table:row %integer; #IMPLIED
+	table:table %integer; #IMPLIED
+>
+<!ELEMENT table:previous (table:change-track-table-cell)>
+<!ATTLIST table:previous
+	table:id CDATA #IMPLIED
+>
+<!ELEMENT table:rejection (office:change-info, table:dependences?, table:deletions?)>
+<!ATTLIST table:rejection
+	table:id CDATA #REQUIRED
+	table:acceptance-state (accepted | rejected | pending) "pending"
+	table:rejecting-change-id %positiveInteger; #IMPLIED
+>
+
+<!ENTITY % table-columns "table:table-columns | ( table:table-column | table:table-column-group )+">
+<!ENTITY % table-header-columns "table:table-header-columns">
+<!ENTITY % table-rows "table:table-rows | ( table:table-row | table:table-row-group )+">
+<!ENTITY % table-header-rows "table:table-header-rows">
+<!ENTITY % table-column-groups "((%table-columns;),(%table-header-columns;,(%table-columns;)?)?) | (%table-header-columns;,(%table-columns;)?)">
+<!ENTITY % table-row-groups "((%table-rows;),(%table-header-rows;,(%table-rows;)?)?) | (%table-header-rows;,(%table-rows;)?)">
+<!ELEMENT table:table (table:table-source?, table:scenario?, office:forms?, table:shapes?, (%table-column-groups;), (%table-row-groups;))>
+<!ATTLIST table:table
+	table:name %string; #IMPLIED
+	table:style-name %styleName; #IMPLIED
+	table:protected %boolean; "false"
+	table:protection-key CDATA #IMPLIED
+	table:print-ranges %cell-range-address-list; #IMPLIED
+>
+<!ELEMENT table:table-source EMPTY>
+<!ATTLIST table:table-source
+	table:mode (copy-all | copy-results-only) "copy-all"
+	xlink:type (simple) #FIXED "simple"
+	xlink:actuate (onRequest) "onRequest"
+	xlink:href %uriReference; #REQUIRED
+	table:filter-name CDATA #IMPLIED
+	table:table-name CDATA #IMPLIED
+	table:filter-options CDATA #IMPLIED
+	table:refresh-delay %timeDuration; #IMPLIED
+>
+<!ELEMENT table:scenario EMPTY>
+<!ATTLIST table:scenario
+	table:display-border %boolean; "true"
+	table:border-color %color; #IMPLIED
+	table:copy-back %boolean; "true"
+	table:copy-styles %boolean; "true"
+	table:copy-formulas %boolean; "true"
+	table:is-active %boolean; #REQUIRED
+	table:scenario-ranges %cell-range-address-list; #REQUIRED
+	table:comment CDATA #IMPLIED
+>
+<!ELEMENT table:shapes %shapes;>
+<!ELEMENT table:table-column-group (table:table-header-columns | table:table-column | table:table-column-group)+>
+<!ATTLIST table:table-column-group
+	table:display %boolean; "true"
+>
+<!ELEMENT table:table-header-columns (table:table-column | table:table-column-group)+>
+<!ELEMENT table:table-columns (table:table-column | table:table-column-group)+>
+<!ELEMENT table:table-column EMPTY>
+<!ATTLIST table:table-column
+	table:number-columns-repeated %positiveInteger; "1"
+	table:style-name %styleName; #IMPLIED
+	table:visibility (visible | collapse | filter) "visible"
+	table:default-cell-style-name %styleName; #IMPLIED
+>
+<!ELEMENT table:table-row-group (table:table-header-rows | table:table-row | table:table-row-group)+>
+<!ATTLIST table:table-row-group
+	table:display %boolean; "true"
+>
+<!ELEMENT table:table-header-rows (table:table-row | table:table-row-group)+>
+<!ELEMENT table:table-rows (table:table-row | table:table-row-group)+>
+<!ENTITY % table-cells "(table:table-cell|table:covered-table-cell)+">
+<!ELEMENT table:table-row %table-cells;>
+<!ATTLIST table:table-row
+	table:number-rows-repeated %positiveInteger; "1"
+	table:style-name %styleName; #IMPLIED
+	table:visibility (visible | collapse | filter) "visible"
+	table:default-cell-style-name %styleName; #IMPLIED
+>
+
+<!ENTITY % text-wo-table "(text:h|text:p|text:ordered-list|text:unordered-list|%shapes;)*">
+<!ENTITY % cell-content "(table:cell-range-source?,office:annotation?,table:detective?,(table:sub-table|%text-wo-table;))">
+<!ELEMENT table:table-cell %cell-content;>
+<!ELEMENT table:covered-table-cell %cell-content;>
+<!ATTLIST table:table-cell
+	table:number-columns-repeated %positiveInteger; "1"
+	table:number-rows-spanned %positiveInteger; "1"
+	table:number-columns-spanned %positiveInteger; "1"
+	table:style-name %styleName; #IMPLIED
+	table:validation-name CDATA #IMPLIED
+	table:formula %string; #IMPLIED
+	table:number-matrix-rows-spanned %positiveInteger; #IMPLIED
+	table:number-matrix-columns-spanned %positiveInteger; #IMPLIED
+	table:value-type %valueType; "string"
+	table:value %float; #IMPLIED
+	table:date-value %date; #IMPLIED
+	table:time-value %timeInstance; #IMPLIED
+	table:boolean-value %boolean; #IMPLIED
+	table:string-value %string; #IMPLIED
+	table:currency %string; #IMPLIED
+>
+<!ATTLIST table:covered-table-cell
+	table:number-columns-repeated %positiveInteger; "1"
+	table:style-name %styleName; #IMPLIED
+	table:validation-name CDATA #IMPLIED
+	table:formula %string; #IMPLIED
+	table:number-matrix-rows-spanned %positiveInteger; #IMPLIED
+	table:number-matrix-columns-spanned %positiveInteger; #IMPLIED
+	table:value-type %valueType; "string"
+	table:value %float; #IMPLIED
+	table:date-value %date; #IMPLIED
+	table:time-value %timeInstance; #IMPLIED
+	table:boolean-value %boolean; #IMPLIED
+	table:string-value %string; #IMPLIED
+	table:currency %string; #IMPLIED
+>
+<!-- cell protection in writer: cell attribute; calc uses format -->
+<!ATTLIST table:table-cell table:protected %boolean; "false">
+
+<!ELEMENT table:cell-range-source EMPTY>
+<!ATTLIST table:cell-range-source
+	table:name %string; #REQUIRED
+	xlink:type (simple) #FIXED "simple"
+	xlink:actuate (onRequest) #FIXED "onRequest"
+	xlink:href %uriReference; #REQUIRED
+	table:filter-name %string; #REQUIRED
+	table:filter-options %string; #IMPLIED
+	table:last-column-spanned %positiveInteger; #REQUIRED
+	table:last-row-spanned %positiveInteger; #REQUIRED
+	table:refresh-delay %timeDuration; #IMPLIED
+>
+
+<!ELEMENT table:detective (table:highlighted-range*, table:operation*)>
+<!ELEMENT table:highlighted-range EMPTY>
+<!ATTLIST table:highlighted-range
+	table:cell-range-address %cell-range-address; #IMPLIED
+	table:direction (from-another-table | to-another-table | from-same-table | to-same-table) #IMPLIED
+	table:contains-error %boolean; #IMPLIED
+	table:marked-invalid %boolean; #IMPLIED
+>
+<!ELEMENT table:operation EMPTY>
+<!ATTLIST table:operation
+	table:name (trace-dependents | remove-dependents | trace-precedents | remove-precedents | trace-errors) #REQUIRED
+	table:index %nonNegativeInteger; #REQUIRED
+>
+
+<!ELEMENT table:content-validations (table:content-validation)+>
+<!ELEMENT table:content-validation (table:help-message?, (table:error-message | (table:error-macro, office:events?))?)>
+<!ATTLIST table:content-validation
+	table:name CDATA #REQUIRED
+	table:condition CDATA #IMPLIED
+	table:base-cell-address %cell-address; #IMPLIED
+	table:allow-empty-cell %boolean; #IMPLIED
+>
+<!ELEMENT table:help-message (text:p*)>
+<!ATTLIST table:help-message
+	table:title CDATA #IMPLIED
+	table:display %boolean; #IMPLIED
+>
+<!ELEMENT table:error-message (text:p*)>
+<!ATTLIST table:error-message
+	table:title CDATA #IMPLIED
+	table:message-type (stop | warning | information) #IMPLIED
+	table:display %boolean; #IMPLIED
+>
+<!ELEMENT table:error-macro EMPTY>
+<!ATTLIST table:error-macro
+	table:name CDATA #IMPLIED
+	table:execute %boolean; #IMPLIED
+>
+
+<!ELEMENT table:sub-table ((%table-column-groups;) , (%table-row-groups;))>
+
+<!ELEMENT table:label-ranges (table:label-range)*>
+<!ELEMENT table:label-range EMPTY>
+<!ATTLIST table:label-range
+	table:label-cell-range-address %cell-range-address; #REQUIRED
+	table:data-cell-range-address %cell-range-address; #REQUIRED
+	table:orientation (column | row) #REQUIRED
+>
+
+<!ELEMENT table:named-expressions (table:named-range | table:named-expression)*>
+<!ELEMENT table:named-range EMPTY>
+<!ATTLIST table:named-range
+	table:name CDATA #REQUIRED
+	table:cell-range-address %cell-range-address; #REQUIRED
+	table:base-cell-address %cell-address; #IMPLIED
+	table:range-usable-as CDATA "none"
+>
+<!ELEMENT table:named-expression EMPTY>
+<!ATTLIST table:named-expression
+	table:name CDATA #REQUIRED
+	table:expression CDATA #REQUIRED
+	table:base-cell-address %cell-address; #IMPLIED
+>
+
+<!ELEMENT table:filter (table:filter-condition | table:filter-and | table:filter-or)>
+<!ATTLIST table:filter
+	table:target-range-address %cell-range-address; #IMPLIED
+	table:condition-source-range-address %cell-range-address; #IMPLIED
+	table:condition-source (self | cell-range) "self"
+	table:display-duplicates %boolean; "true"
+>
+<!ELEMENT table:filter-and (table:filter-or | table:filter-condition)+>
+<!ELEMENT table:filter-or (table:filter-and | table:filter-condition)+>
+<!ELEMENT table:filter-condition EMPTY>
+<!ATTLIST table:filter-condition
+	table:field-number %nonNegativeInteger; #REQUIRED
+	table:case-sensitive %boolean; "false"
+	table:data-type (text | number) "text"
+	table:value CDATA #REQUIRED
+	table:operator CDATA #REQUIRED
+>
+
+<!ELEMENT table:database-ranges (table:database-range)*>
+<!ELEMENT table:database-range ((table:database-source-sql | table:database-source-table | table:database-source-query)?, table:filter?, table:sort?, table:subtotal-rules?)>
+<!ATTLIST table:database-range
+	table:name CDATA #IMPLIED
+	table:is-selection %boolean; "false"
+	table:on-update-keep-styles %boolean; "false"
+	table:on-update-keep-size %boolean; "true"
+	table:has-persistant-data %boolean; "true"
+	table:orientation (row | column) "row"
+	table:contains-header %boolean; "true"
+	table:display-filter-buttons %boolean; "false"
+	table:target-range-address %cell-range-address; #REQUIRED
+	table:refresh-delay %timeDuration; #IMPLIED
+>
+<!ELEMENT table:database-source-sql EMPTY>
+<!ATTLIST table:database-source-sql
+	table:database-name CDATA #REQUIRED
+	table:sql-statement CDATA #REQUIRED
+	table:parse-sql-statements %boolean; "false"
+>
+<!ELEMENT table:database-source-table EMPTY>
+<!ATTLIST table:database-source-table
+	table:database-name CDATA #REQUIRED
+	table:table-name CDATA #REQUIRED
+>
+<!ELEMENT table:database-source-query EMPTY>
+<!ATTLIST table:database-source-query
+	table:database-name CDATA #REQUIRED
+	table:query-name CDATA #REQUIRED
+>
+
+<!ELEMENT table:sort (table:sort-by)+>
+<!ATTLIST table:sort
+	table:bind-styles-to-content %boolean; "true"
+	table:target-range-address %cell-range-address; #IMPLIED
+	table:case-sensitive %boolean; "false"
+	table:language CDATA #IMPLIED
+	table:country CDATA #IMPLIED
+	table:algorithm CDATA #IMPLIED
+>
+<!ELEMENT table:sort-by EMPTY>
+<!ATTLIST table:sort-by
+	table:field-number %nonNegativeInteger; #REQUIRED
+	table:data-type CDATA "automatic"
+	table:order (ascending | descending) "ascending"
+>
+
+<!ELEMENT table:subtotal-rules (table:sort-groups? | table:subtotal-rule*)?>
+<!ATTLIST table:subtotal-rules
+	table:bind-styles-to-content %boolean; "true"
+	table:case-sensitive %boolean; "false"
+	table:page-breaks-on-group-change %boolean; "false"
+>
+<!ELEMENT table:sort-groups EMPTY>
+<!ATTLIST table:sort-groups
+	table:data-type CDATA "automatic"
+	table:order (ascending | descending) "ascending"
+>
+<!ELEMENT table:subtotal-rule (table:subtotal-field)*>
+<!ATTLIST table:subtotal-rule
+	table:group-by-field-number %nonNegativeInteger; #REQUIRED
+>
+<!ELEMENT table:subtotal-field EMPTY>
+<!ATTLIST table:subtotal-field
+	table:field-number %nonNegativeInteger; #REQUIRED
+	table:function CDATA #REQUIRED
+>
+
+<!ELEMENT table:data-pilot-tables (table:data-pilot-table)*>
+<!ELEMENT table:data-pilot-table ((table:database-source-sql | table:database-source-table | table:database-source-query | table:source-service | table:source-cell-range)?, table:data-pilot-field+)>
+<!ATTLIST table:data-pilot-table
+	table:name CDATA #REQUIRED
+	table:application-data CDATA #IMPLIED
+	table:grand-total (none | row | column | both) "both"
+	table:ignore-empty-rows %boolean; "false"
+	table:identify-categories %boolean; "false"
+	table:target-range-address %cell-range-address; #REQUIRED
+	table:buttons %cell-range-address-list; #REQUIRED
+>
+<!ELEMENT table:source-service EMPTY>
+<!ATTLIST table:source-service
+	table:name CDATA #REQUIRED
+	table:source-name CDATA #REQUIRED
+	table:object-name CDATA #REQUIRED
+	table:username CDATA #IMPLIED
+	table:password CDATA #IMPLIED
+>
+<!ELEMENT table:source-cell-range (table:filter)?>
+<!ATTLIST table:source-cell-range
+	table:cell-range-address %cell-range-address; #REQUIRED
+>
+<!ELEMENT table:data-pilot-field (table:data-pilot-level)?>
+<!ATTLIST table:data-pilot-field
+	table:source-field-name CDATA #REQUIRED
+	table:is-data-layout-field %boolean; "false"
+	table:function CDATA #REQUIRED
+	table:orientation (row | column | data | page | hidden) #REQUIRED
+	table:used-hierarchy %positiveInteger; "1"
+>
+<!ELEMENT table:data-pilot-level (table:data-pilot-subtotals?, table:data-pilot-members?)>
+<!ATTLIST table:data-pilot-level
+	table:display-empty %boolean; #IMPLIED
+>
+<!ELEMENT table:data-pilot-subtotals (table:data-pilot-subtotal)*>
+<!ELEMENT table:data-pilot-subtotal EMPTY>
+<!ATTLIST table:data-pilot-subtotal
+	table:function CDATA #REQUIRED
+>
+<!ELEMENT table:data-pilot-members (table:data-pilot-member)*>
+<!ELEMENT table:data-pilot-member EMPTY>
+<!ATTLIST table:data-pilot-member
+	table:name CDATA #REQUIRED
+	table:display %boolean; #IMPLIED
+	table:display-details %boolean; #IMPLIED
+>
+
+<!ELEMENT table:consolidation EMPTY>
+<!ATTLIST table:consolidation
+	table:function CDATA #REQUIRED
+	table:source-cell-range-addresses %cell-range-address-list; #REQUIRED
+	table:target-cell-address %cell-address; #REQUIRED
+	table:use-label (none | column | row | both) "none"
+	table:link-to-source-data %boolean; "false"
+>
+
+<!ELEMENT table:dde-links (table:dde-link)+>
+<!ELEMENT table:dde-link (office:dde-source, table:table)>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/text.mod
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/text.mod	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/text.mod	(revision 28000)
@@ -0,0 +1,1126 @@
+<!--
+	$Id: text.mod,v 1.54 2003/04/17 13:16:02 vg Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+ 
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+ 
+   Sun Microsystems Inc., October, 2000
+ 
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+ 
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+ 
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+ 
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+ 
+ 
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+ 
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+ 
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ 
+   Copyright: 2000 by Sun Microsystems, Inc.
+ 
+   All Rights Reserved.
+ 
+   Contributor(s): _______________________________________
+
+-->
+
+<!ENTITY % fields "text:date |
+				   text:time |
+				   text:page-number |
+				   text:page-continuation |
+				   text:sender-firstname |
+				   text:sender-lastname |
+				   text:sender-initials | 
+				   text:sender-title |
+				   text:sender-position |
+				   text:sender-email | 
+				   text:sender-phone-private |
+				   text:sender-fax | 
+				   text:sender-company |
+				   text:sender-phone-work |
+				   text:sender-street |
+				   text:sender-city |
+				   text:sender-postal-code |
+				   text:sender-country |
+				   text:sender-state-or-province |
+				   text:author-name |
+				   text:author-initials |
+				   text:placeholder |
+				   text:variable-set | 
+				   text:variable-get | 
+				   text:variable-input | 
+				   text:user-field-get | 
+				   text:user-field-input | 
+				   text:sequence | 
+				   text:expression | 
+				   text:text-input |
+				   text:database-display |
+				   text:database-next |
+				   text:database-select |
+				   text:database-row-number |
+				   text:database-name |
+				   text:initial-creator |
+				   text:creation-date |
+				   text:creation-time |
+				   text:description |
+				   text:user-defined |
+				   text:print-time |
+				   text:print-date |
+				   text:printed-by |
+				   text:title |
+				   text:subject |
+				   text:keywords |
+				   text:editing-cycles |
+				   text:editing-duration |
+				   text:modification-time |
+				   text:modification-date |
+				   text:creator |
+				   text:conditional-text |
+				   text:hidden-text |
+				   text:hidden-paragraph |
+				   text:chapter |
+				   text:file-name |
+				   text:template-name |
+				   text:page-variable-set |
+				   text:page-variable-get |
+				   text:execute-macro |
+				   text:dde-connection |
+				   text:reference-ref |
+				   text:sequence-ref |
+				   text:bookmark-ref |
+				   text:footnote-ref |
+				   text:endnote-ref |
+				   text:sheet-name |
+				   text:bibliography-mark |
+				   text:page-count |
+				   text:paragraph-count |
+				   text:word-count |
+				   text:character-count |
+				   text:table-count |
+				   text:image-count |
+				   text:object-count |
+				   office:annotation |
+				   text:script |
+				   text:measure" >
+
+<!ENTITY % inline-text-elements "
+				 text:span|text:tab-stop|text:s|text:line-break|
+				 text:footnote|text:endnote|text:a|
+				 text:bookmark|text:bookmark-start|text:bookmark-end|
+				 text:reference-mark|text:reference-mark-start|
+				 text:reference-mark-end|%fields;|%shape;|
+				 text:toc-mark-start | text:toc-mark-end | 
+				 text:toc-mark | text:user-index-mark-start |
+				 text:user-index-mark-end | text:user-index-mark |
+				 text:alphabetical-index-mark-start |
+				 text:alphabetical-index-mark-end |
+				 text:alphabetical-index-mark |
+				 %change-marks; | draw:a | text:ruby">
+
+<!ENTITY % inline-text "( #PCDATA | %inline-text-elements; )*">
+
+<!ELEMENT text:p %inline-text;>
+<!ELEMENT text:h %inline-text;>
+
+<!ATTLIST text:p text:style-name %styleName; #IMPLIED>
+<!ATTLIST text:p text:cond-style-name %styleName; #IMPLIED>
+
+<!ATTLIST text:h text:style-name %styleName; #IMPLIED>
+<!ATTLIST text:h text:cond-style-name %styleName; #IMPLIED>
+<!ATTLIST text:h text:level %positiveInteger; "1">
+
+<!ELEMENT text:span %inline-text;>
+<!ATTLIST text:span text:style-name %styleName; #REQUIRED>
+
+<!ELEMENT text:a (#PCDATA | office:events | %inline-text-elements;)*>
+<!ATTLIST text:a xlink:href %uriReference; #REQUIRED>
+<!ATTLIST text:a xlink:type (simple) #FIXED "simple">
+<!ATTLIST text:a xlink:actuate (onRequest) "onRequest">
+<!ATTLIST text:a xlink:show (new|replace) "replace">
+<!ATTLIST text:a office:name %string; #IMPLIED>
+<!ATTLIST text:a office:target-frame-name %string; #IMPLIED>
+<!ATTLIST text:a text:style-name %styleName; #IMPLIED>
+<!ATTLIST text:a text:visited-style-name %styleName; #IMPLIED>
+
+
+<!ELEMENT text:s EMPTY>
+<!ATTLIST text:s text:c %positiveInteger; "1">
+
+<!ELEMENT text:tab-stop EMPTY>
+
+<!ELEMENT text:line-break EMPTY>
+
+
+<!ENTITY % list-items "((text:list-header,text:list-item*)|text:list-item+)">
+<!ELEMENT text:ordered-list %list-items;>
+<!ELEMENT text:unordered-list %list-items;>
+
+
+<!ATTLIST text:ordered-list text:style-name %styleName; #IMPLIED>
+<!ATTLIST text:unordered-list text:style-name %styleName; #IMPLIED>
+
+<!ATTLIST text:ordered-list text:continue-numbering %boolean; "false">
+
+<!ELEMENT text:list-header (text:p|text:h)+>
+<!ELEMENT text:list-item (text:p|text:h|text:ordered-list|text:unordered-list)+>
+
+<!ATTLIST text:list-item text:restart-numbering %boolean; "false">
+<!ATTLIST text:list-item text:start-value %positiveInteger; #IMPLIED>
+
+<!ELEMENT text:list-style (text:list-level-style-number|
+     					   text:list-level-style-bullet|
+     					   text:list-level-style-image)+>
+
+<!ATTLIST text:list-style style:name %styleName; #IMPLIED>
+
+<!ATTLIST text:list-style text:consecutive-numbering %boolean; "false">
+
+
+<!ELEMENT text:list-level-style-number (style:properties?)>
+
+<!ATTLIST text:list-level-style-number text:level %positiveInteger;
+									     		 #REQUIRED>
+<!ATTLIST text:list-level-style-number text:style-name %styleName; #IMPLIED>
+
+<!ATTLIST text:list-level-style-number style:num-format %string; #REQUIRED>
+<!ATTLIST text:list-level-style-number style:num-prefix %string; #IMPLIED>
+<!ATTLIST text:list-level-style-number style:num-suffix %string; #IMPLIED>
+<!ATTLIST text:list-level-style-number style:num-letter-sync %boolean;
+									     					"false">
+<!ATTLIST text:list-level-style-number text:display-levels %positiveInteger;
+									     				  "1">
+<!ATTLIST text:list-level-style-number text:start-value %positiveInteger;
+														   "1">
+<!ELEMENT text:list-level-style-bullet (style:properties?)>
+
+<!ATTLIST text:list-level-style-bullet text:level %positiveInteger; #REQUIRED>
+<!ATTLIST text:list-level-style-bullet text:style-name %styleName; #IMPLIED>
+<!ATTLIST text:list-level-style-bullet text:bullet-char %character; #REQUIRED>
+<!ATTLIST text:list-level-style-bullet style:num-prefix %string; #IMPLIED>
+<!ATTLIST text:list-level-style-bullet style:num-suffix %string; #IMPLIED>
+
+<!ELEMENT text:list-level-style-image (style:properties?,office:binary-data?)>
+
+<!ATTLIST text:list-level-style-image text:level %positiveInteger; #REQUIRED>
+<!ATTLIST text:list-level-style-image xlink:type (simple) #IMPLIED>
+<!ATTLIST text:list-level-style-image xlink:href %uriReference; #IMPLIED>
+<!ATTLIST text:list-level-style-image xlink:actuate (onLoad) #IMPLIED>
+<!ATTLIST text:list-level-style-image xlink:show (embed) #IMPLIED>
+
+
+<!-- list properties -->
+<!ATTLIST style:properties text:space-before %nonNegativeLength; #IMPLIED>
+<!ATTLIST style:properties text:min-label-width %nonNegativeLength; #IMPLIED>
+<!ATTLIST style:properties text:min-label-distance %nonNegativeLength; #IMPLIED>
+<!ATTLIST style:properties text:enable-numbering %boolean; #IMPLIED>
+<!ATTLIST style:properties style:list-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:outline-style (text:outline-level-style)+>
+
+<!ELEMENT text:outline-level-style (style:properties?)>
+
+<!ATTLIST text:outline-level-style text:level %positiveInteger;
+													 #REQUIRED>
+<!ATTLIST text:outline-level-style text:style-name %styleName; #IMPLIED>
+
+<!ATTLIST text:outline-level-style style:num-format %string; #REQUIRED>
+<!ATTLIST text:outline-level-style style:num-prefix %string; #IMPLIED>
+<!ATTLIST text:outline-level-style style:num-suffix %string; #IMPLIED>
+<!ATTLIST text:outline-level-style style:num-letter-sync %boolean;
+																"false">
+<!ATTLIST text:outline-level-style text:display-levels %positiveInteger;
+															  "1">
+<!ATTLIST text:outline-level-style text:start-value %positiveInteger;
+														   "1">
+
+<!ENTITY % field-declarations "text:variable-decls?, 
+							   text:user-field-decls?, 
+							   text:sequence-decls?">
+
+<!ENTITY % variableName "CDATA">
+
+<!ENTITY % formula "CDATA">
+
+<!ENTITY % valueAttr "text:value-type %valueType; #IMPLIED
+							 text:currency CDATA #IMPLIED" >
+
+<!ENTITY % valueAndTypeAttr "%valueAttr;
+		 					 text:value %float; #IMPLIED
+							 text:date-value %date; #IMPLIED
+							 text:time-value %timeInstance; #IMPLIED
+							 text:boolean-value %boolean; #IMPLIED
+							 text:string-value %string; #IMPLIED" >
+
+<!ENTITY % numFormat 'style:num-format CDATA #IMPLIED 
+					   style:num-letter-sync %boolean; "false"'>
+
+
+<!ELEMENT text:date (#PCDATA)>
+<!ATTLIST text:date text:date-value %timeInstance; #IMPLIED>
+<!ATTLIST text:date text:date-adjust %dateDuration; #IMPLIED>
+<!ATTLIST text:date text:fixed %boolean; "false">
+<!ATTLIST text:date style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:time (#PCDATA)>
+<!ATTLIST text:time text:time-value %timeInstance; #IMPLIED>
+<!ATTLIST text:time text:time-adjust %timeDuration; #IMPLIED>
+<!ATTLIST text:time text:fixed %boolean; "false">
+<!ATTLIST text:time style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:page-number (#PCDATA)>
+<!ATTLIST text:page-number text:page-adjust %positiveInteger; #IMPLIED>
+<!ATTLIST text:page-number text:select-page (previous|current|next) "current">
+<!ATTLIST text:page-number %numFormat;>
+
+<!ELEMENT text:page-continuation (#PCDATA)>
+<!ATTLIST text:page-continuation text:select-page (previous|next) #REQUIRED>
+<!ATTLIST text:page-continuation text:string-value %string; #IMPLIED>
+
+<!ELEMENT text:sender-firstname (#PCDATA)>
+<!ATTLIST text:sender-firstname text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-lastname (#PCDATA)>
+<!ATTLIST text:sender-lastname text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-initials (#PCDATA)>
+<!ATTLIST text:sender-initials text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-title (#PCDATA)>
+<!ATTLIST text:sender-title text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-position (#PCDATA)>
+<!ATTLIST text:sender-position text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-email (#PCDATA)>
+<!ATTLIST text:sender-email text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-phone-private (#PCDATA)>
+<!ATTLIST text:sender-phone-private text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-fax (#PCDATA)>
+<!ATTLIST text:sender-fax text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-company (#PCDATA)>
+<!ATTLIST text:sender-company text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-phone-work (#PCDATA)>
+<!ATTLIST text:sender-phone-work text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-street (#PCDATA)>
+<!ATTLIST text:sender-street text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-city (#PCDATA)>
+<!ATTLIST text:sender-city text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-postal-code (#PCDATA)>
+<!ATTLIST text:sender-postal-code text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-country (#PCDATA)>
+<!ATTLIST text:sender-country text:fixed %boolean; "true">
+
+<!ELEMENT text:sender-state-or-province (#PCDATA)>
+<!ATTLIST text:sender-state-or-province text:fixed %boolean; "true">
+
+<!ELEMENT text:author-name (#PCDATA)>
+<!ATTLIST text:author-name text:fixed %boolean; "true">
+
+<!ELEMENT text:author-initials (#PCDATA)>
+<!ATTLIST text:author-initials text:fixed %boolean; "true">
+
+<!ELEMENT text:placeholder (#PCDATA)>
+<!ATTLIST text:placeholder text:placeholder-type (text|table|text-box|image|object) #REQUIRED>
+<!ATTLIST text:placeholder text:description %string; #IMPLIED>
+
+<!ELEMENT text:variable-decls (text:variable-decl)*>
+
+<!ELEMENT text:variable-decl EMPTY>
+<!ATTLIST text:variable-decl text:name %variableName; #REQUIRED>
+<!ATTLIST text:variable-decl %valueAndTypeAttr;>
+
+<!ELEMENT text:variable-set (#PCDATA)>
+<!ATTLIST text:variable-set text:name %variableName; #REQUIRED>
+<!ATTLIST text:variable-set text:formula %formula; #IMPLIED>
+<!ATTLIST text:variable-set %valueAndTypeAttr;>
+<!ATTLIST text:variable-set text:display (value|none) "value">
+<!ATTLIST text:variable-set style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:variable-get (#PCDATA)>
+<!ATTLIST text:variable-get text:name %variableName; #REQUIRED>
+<!ATTLIST text:variable-get text:display (value|formula) "value">
+<!ATTLIST text:variable-get style:data-style-name %styleName; #IMPLIED>
+<!ATTLIST text:variable-get %valueAttr;>
+
+<!ELEMENT text:variable-input (#PCDATA)>
+<!ATTLIST text:variable-input text:name %variableName; #REQUIRED>
+<!ATTLIST text:variable-input text:description %string; #IMPLIED>
+<!ATTLIST text:variable-input %valueAndTypeAttr;>
+<!ATTLIST text:variable-input text:display (value|none) "value">
+<!ATTLIST text:variable-input style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:user-field-decls (text:user-field-decl)*>
+
+<!ELEMENT text:user-field-decl EMPTY>
+<!ATTLIST text:user-field-decl text:name %variableName; #REQUIRED>
+<!ATTLIST text:user-field-decl text:formula %formula; #IMPLIED>
+<!ATTLIST text:user-field-decl %valueAndTypeAttr;>
+
+<!ELEMENT text:user-field-get (#PCDATA)>
+<!ATTLIST text:user-field-get text:name %variableName; #REQUIRED>
+<!ATTLIST text:user-field-get text:display (value|formula|none) "value">
+<!ATTLIST text:user-field-get style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:user-field-input (#PCDATA)>
+<!ATTLIST text:user-field-input text:name %variableName; #REQUIRED>
+<!ATTLIST text:user-field-input text:description %string; #IMPLIED>
+<!ATTLIST text:user-field-input style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:sequence-decls (text:sequence-decl)*>
+
+<!ELEMENT text:sequence-decl EMPTY>
+<!ATTLIST text:sequence-decl text:name %variableName; #REQUIRED>
+<!ATTLIST text:sequence-decl text:display-outline-level %positiveInteger; "0">
+<!ATTLIST text:sequence-decl text:separation-character %character; ".">
+
+<!ELEMENT text:sequence (#PCDATA)>
+<!ATTLIST text:sequence text:name %variableName; #REQUIRED>
+<!ATTLIST text:sequence text:formula %formula; #IMPLIED>
+<!ATTLIST text:sequence %numFormat;>
+<!ATTLIST text:sequence text:ref-name ID #IMPLIED>
+
+<!ELEMENT text:expression (#PCDATA)>
+<!ATTLIST text:expression text:formula %formula; #IMPLIED>
+<!ATTLIST text:expression text:display (value|formula ) "value">
+<!ATTLIST text:expression %valueAndTypeAttr;>
+<!ATTLIST text:expression style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:text-input (#PCDATA)>
+<!ATTLIST text:text-input text:description %string; #IMPLIED>
+
+<!ENTITY % database-table "text:database-name CDATA #REQUIRED 
+						   text:table-name CDATA #REQUIRED
+						   text:table-type (table|query|command) #IMPLIED">
+
+<!ELEMENT text:database-display (#PCDATA)>
+<!ATTLIST text:database-display %database-table;>
+<!ATTLIST text:database-display text:column-name %string; #REQUIRED>
+<!ATTLIST text:database-display style:data-style-name %styleName; #IMPLIED>
+<!ATTLIST text:database-display text:display (none|value) #IMPLIED>
+
+<!ELEMENT text:database-next (#PCDATA)>
+<!ATTLIST text:database-next %database-table;>
+<!ATTLIST text:database-next text:condition %formula; #IMPLIED>
+
+<!ELEMENT text:database-select (#PCDATA)>
+<!ATTLIST text:database-select %database-table;>
+<!ATTLIST text:database-select text:condition %formula; #IMPLIED>
+<!ATTLIST text:database-select text:row-number %integer; #REQUIRED>
+
+<!ELEMENT text:database-row-number (#PCDATA)>
+<!ATTLIST text:database-row-number %database-table;>
+<!ATTLIST text:database-row-number %numFormat;>
+<!ATTLIST text:database-row-number text:value %integer; #IMPLIED>
+<!ATTLIST text:database-row-number text:display (none|value) #IMPLIED>
+
+<!ELEMENT text:database-name (#PCDATA)>
+<!ATTLIST text:database-name %database-table;>
+<!ATTLIST text:database-name text:display (none|value) #IMPLIED>
+
+<!ELEMENT text:initial-creator (#PCDATA)>
+<!ATTLIST text:initial-creator text:fixed %boolean; "false">
+
+<!ELEMENT text:creation-date (#PCDATA)>
+<!ATTLIST text:creation-date text:fixed %boolean; "false">
+<!ATTLIST text:creation-date text:date-value %date; #IMPLIED>
+<!ATTLIST text:creation-date style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:creation-time (#PCDATA)>
+<!ATTLIST text:creation-time text:fixed %boolean; "false">
+<!ATTLIST text:creation-time text:time-value %timeInstance; #IMPLIED>
+<!ATTLIST text:creation-time style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:description (#PCDATA)>
+<!ATTLIST text:description text:fixed %boolean; "false">
+
+<!ELEMENT text:user-defined (#PCDATA)>
+<!ATTLIST text:user-defined text:fixed %boolean; "false">
+<!ATTLIST text:user-defined text:name %string; #REQUIRED>
+
+<!ELEMENT text:print-time (#PCDATA)>
+<!ATTLIST text:print-time text:fixed %boolean; "false">
+<!ATTLIST text:print-time text:time-value %timeInstance; #IMPLIED>
+<!ATTLIST text:print-time style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:print-date (#PCDATA)>
+<!ATTLIST text:print-date text:fixed %boolean; "false">
+<!ATTLIST text:print-date text:date-value %date; #IMPLIED>
+<!ATTLIST text:print-date style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:printed-by (#PCDATA)>
+<!ATTLIST text:printed-by text:fixed %boolean; "false">
+
+<!ELEMENT text:title (#PCDATA)>
+<!ATTLIST text:title text:fixed %boolean; "false">
+
+<!ELEMENT text:subject (#PCDATA)>
+<!ATTLIST text:subject text:fixed %boolean; "false">
+
+<!ELEMENT text:keywords (#PCDATA)>
+<!ATTLIST text:keywords text:fixed %boolean; "false">
+
+<!ELEMENT text:editing-cycles (#PCDATA)>
+<!ATTLIST text:editing-cycles text:fixed %boolean; "false">
+
+<!ELEMENT text:editing-duration (#PCDATA)>
+<!ATTLIST text:editing-duration text:fixed %boolean; "false">
+<!ATTLIST text:editing-duration text:duration %timeDuration; #IMPLIED>
+<!ATTLIST text:editing-duration style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:modification-time (#PCDATA)>
+<!ATTLIST text:modification-time text:fixed %boolean; "false">
+<!ATTLIST text:modification-time text:time-value %timeInstance; #IMPLIED>
+<!ATTLIST text:modification-time style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:modification-date (#PCDATA)>
+<!ATTLIST text:modification-date text:fixed %boolean; "false">
+<!ATTLIST text:modification-date text:date-value %date; #IMPLIED>
+<!ATTLIST text:modification-date style:data-style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:creator (#PCDATA)>
+<!ATTLIST text:creator text:fixed %boolean; "false">
+
+<!ELEMENT text:conditional-text (#PCDATA)>
+<!ATTLIST text:conditional-text text:condition %formula; #REQUIRED>
+<!ATTLIST text:conditional-text text:string-value-if-false %string; #REQUIRED>
+<!ATTLIST text:conditional-text text:string-value-if-true %string; #REQUIRED>
+<!ATTLIST text:conditional-text text:current-value %boolean; "false">
+
+<!ELEMENT text:hidden-text (#PCDATA)>
+<!ATTLIST text:hidden-text text:condition %formula; #REQUIRED>
+<!ATTLIST text:hidden-text text:string-value %string; #REQUIRED>
+<!ATTLIST text:hidden-text text:is-hidden %boolean; "false">
+
+<!ELEMENT text:hidden-paragraph EMPTY>
+<!ATTLIST text:hidden-paragraph text:condition %formula; #REQUIRED>
+<!ATTLIST text:hidden-paragraph text:is-hidden %boolean; "false">
+
+<!ELEMENT text:chapter (#PCDATA)>
+<!ATTLIST text:chapter text:display (name|number|number-and-name|
+									 plain-number-and-name|plain-number) 
+									 "number-and-name">
+<!ATTLIST text:chapter text:outline-level %integer; "1">
+
+<!ELEMENT text:file-name (#PCDATA)>
+<!ATTLIST text:file-name text:display (full|path|name|name-and-extension) 	
+									  "full">
+<!ATTLIST text:file-name text:fixed %boolean; "false">
+
+<!ELEMENT text:template-name (#PCDATA)>
+<!ATTLIST text:template-name text:display (full|path|name|name-and-extension|
+										  area|title) "full">
+
+<!ELEMENT text:page-variable-set EMPTY>
+<!ATTLIST text:page-variable-set text:active %boolean; "true">
+<!ATTLIST text:page-variable-set text:page-adjust %integer; "0">
+
+<!ELEMENT text:page-variable-get (#PCDATA)>
+<!ATTLIST text:page-variable-get %numFormat;>
+
+<!ELEMENT text:execute-macro (#PCDATA|office:events)* >
+<!ATTLIST text:execute-macro text:description %string; #IMPLIED>
+
+
+<!ELEMENT text:dde-connection-decls (text:dde-connection-decl)*>
+
+<!ELEMENT text:dde-connection-decl EMPTY>
+<!ATTLIST text:dde-connection-decl text:name %string; #REQUIRED>
+<!ATTLIST text:dde-connection-decl office:dde-application %string; #REQUIRED>
+<!ATTLIST text:dde-connection-decl office:dde-topic %string; #REQUIRED>
+<!ATTLIST text:dde-connection-decl office:dde-item %string; #REQUIRED>
+<!ATTLIST text:dde-connection-decl office:automatic-update %boolean; "false">
+
+<!ELEMENT text:dde-connection (#PCDATA)>
+<!ATTLIST text:dde-connection text:connection-name %string; #REQUIRED>
+
+<!ELEMENT text:reference-ref (#PCDATA)>
+<!ATTLIST text:reference-ref text:ref-name %string; #REQUIRED>
+<!ATTLIST text:reference-ref text:reference-format (page|chapter|text|direction) #IMPLIED>
+
+<!ELEMENT text:sequence-ref (#PCDATA)>
+<!ATTLIST text:sequence-ref text:ref-name %string; #REQUIRED>
+<!ATTLIST text:sequence-ref text:reference-format (page|chapter|text|direction|category-and-value|caption|value) #IMPLIED>
+
+<!ELEMENT text:bookmark-ref (#PCDATA)>
+<!ATTLIST text:bookmark-ref text:ref-name %string; #REQUIRED>
+<!ATTLIST text:bookmark-ref text:reference-format (page|chapter|text|direction) #IMPLIED>
+
+<!ELEMENT text:footnote-ref (#PCDATA)>
+<!ATTLIST text:footnote-ref text:ref-name %string; #REQUIRED>
+<!ATTLIST text:footnote-ref text:reference-format (page|chapter|text|direction) #IMPLIED>
+
+<!ELEMENT text:endnote-ref (#PCDATA)>
+<!ATTLIST text:endnote-ref text:ref-name %string; #REQUIRED>
+<!ATTLIST text:endnote-ref text:reference-format (page|chapter|text|direction) #IMPLIED>
+
+<!ELEMENT text:sheet-name (#PCDATA)>
+
+<!ELEMENT text:page-count (#PCDATA)>
+<!ATTLIST text:page-count style:num-format %string; #IMPLIED>
+<!ATTLIST text:page-count style:num-letter-sync %boolean; "false">
+
+<!ELEMENT text:paragraph-count (#PCDATA)>
+<!ATTLIST text:paragraph-count style:num-format %string; #IMPLIED>
+<!ATTLIST text:paragraph-count style:num-letter-sync %boolean; "false">
+
+<!ELEMENT text:word-count (#PCDATA)>
+<!ATTLIST text:word-count style:num-format %string; #IMPLIED>
+<!ATTLIST text:word-count style:num-letter-sync %boolean; "false">
+
+<!ELEMENT text:character-count (#PCDATA)>
+<!ATTLIST text:character-count style:num-format %string; #IMPLIED>
+<!ATTLIST text:character-count style:num-letter-sync %boolean; "false">
+
+<!ELEMENT text:table-count (#PCDATA)>
+<!ATTLIST text:table-count style:num-format %string; #IMPLIED>
+<!ATTLIST text:table-count style:num-letter-sync %boolean; "false">
+
+<!ELEMENT text:image-count (#PCDATA)>
+<!ATTLIST text:image-count style:num-format %string; #IMPLIED>
+<!ATTLIST text:image-count style:num-letter-sync %boolean; "false">
+
+<!ELEMENT text:object-count (#PCDATA)>
+<!ATTLIST text:object-count style:num-format %string; #IMPLIED>
+<!ATTLIST text:object-count style:num-letter-sync %boolean; "false">
+
+<!ELEMENT text:bibliography-mark (#PCDATA)>
+<!ATTLIST text:bibliography-mark text:bibliography-type 
+	( article | book | booklet | conference | custom1 | custom2 | custom3 | 
+	  custom4 | custom5 | email | inbook | incollection | inproceedings | 
+	  journal | manual | mastersthesis | misc | phdthesis | proceedings | 
+	  techreport | unpublished | www ) #REQUIRED >
+<!ATTLIST text:bibliography-mark text:identifier CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:address CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:annote CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:author CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:booktitle CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:chapter CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:edition CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:editor CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:howpublished CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:institution CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:journal CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:month CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:note CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:number CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:organizations CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:pages CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:publisher CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:school CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:series CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:title CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:report-type CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:volume CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:year CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:url CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:custom1 CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:custom2 CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:custom3 CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:custom4 CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:custom5 CDATA #IMPLIED>
+<!ATTLIST text:bibliography-mark text:isbn CDATA #IMPLIED>
+
+
+<!ELEMENT text:bookmark EMPTY>
+<!ATTLIST text:bookmark text:name CDATA #REQUIRED>
+
+<!ELEMENT text:bookmark-start EMPTY>
+<!ATTLIST text:bookmark-start text:name CDATA #REQUIRED>
+
+<!ELEMENT text:bookmark-end EMPTY>
+<!ATTLIST text:bookmark-end text:name CDATA #REQUIRED>
+
+<!ELEMENT text:reference-mark EMPTY>
+<!ATTLIST text:reference-mark text:name CDATA #REQUIRED>
+
+<!ELEMENT text:reference-mark-start EMPTY>
+<!ATTLIST text:reference-mark-start text:name CDATA #REQUIRED>
+
+<!ELEMENT text:reference-mark-end EMPTY>
+<!ATTLIST text:reference-mark-end text:name CDATA #REQUIRED>
+
+<!ELEMENT text:footnotes-configuration (text:footnote-continuation-notice-forward?,text:footnote-continuation-notice-backward?)>
+<!ATTLIST text:footnotes-configuration style:num-prefix %string; #IMPLIED>
+<!ATTLIST text:footnotes-configuration style:num-suffix %string; #IMPLIED>
+<!ATTLIST text:footnotes-configuration style:num-format %string; #IMPLIED>
+<!ATTLIST text:footnotes-configuration style:num-letter-sync %string; #IMPLIED>
+<!ATTLIST text:footnotes-configuration text:citation-body-style-name %styleName; #IMPLIED>
+<!ATTLIST text:footnotes-configuration text:citation-style-name %styleName; #IMPLIED>
+<!ATTLIST text:footnotes-configuration text:default-style-name  %styleName; #IMPLIED>
+<!ATTLIST text:footnotes-configuration text:master-page-name %styleName; #IMPLIED>
+<!ATTLIST text:footnotes-configuration text:start-value %integer; #IMPLIED>
+<!ATTLIST text:footnotes-configuration text:footnotes-position (document|page) "page">
+<!ATTLIST text:footnotes-configuration text:start-numbering-at (document|chapter|page) "document">
+
+<!ELEMENT text:footnote-continuation-notice-forward (#PCDATA)> 
+<!ELEMENT text:footnote-continuation-notice-backward (#PCDATA)>
+
+<!ELEMENT text:endnotes-configuration EMPTY>
+<!ATTLIST text:endnotes-configuration style:num-prefix %string; #IMPLIED>
+<!ATTLIST text:endnotes-configuration style:num-suffix %string; #IMPLIED>
+<!ATTLIST text:endnotes-configuration style:num-format %string; #IMPLIED>
+<!ATTLIST text:endnotes-configuration style:num-letter-sync %string; #IMPLIED>
+<!ATTLIST text:endnotes-configuration text:start-value %integer; #IMPLIED>
+<!ATTLIST text:endnotes-configuration text:citation-style-name %styleName; #IMPLIED>
+<!ATTLIST text:endnotes-configuration text:citation-body-style-name %styleName; #IMPLIED>
+<!ATTLIST text:endnotes-configuration text:default-style-name %styleName; #IMPLIED>
+<!ATTLIST text:endnotes-configuration text:master-page-name %styleName; #IMPLIED>
+
+<!-- Validity constraint: text:footnote and text:endnote elements may not 
+	contain other text:footnote or text:endnote elements, even though the DTD
+	allows this (via the %text; in the foot-/endnote-body).
+	Unfortunatetly, this constraint cannot be easily specified in the DTD.
+-->
+<!ELEMENT text:footnote (text:footnote-citation, text:footnote-body)>
+<!ATTLIST text:footnote text:id ID #IMPLIED>
+
+<!ELEMENT text:footnote-citation (#PCDATA)>
+<!ATTLIST text:footnote-citation text:label %string; #IMPLIED>
+
+<!ELEMENT text:footnote-body (text:h|text:p|
+							  text:ordered-list|text:unordered-list)*>
+
+<!ELEMENT text:endnote (text:endnote-citation, text:endnote-body)>
+<!ATTLIST text:endnote text:id ID #IMPLIED>
+
+<!ELEMENT text:endnote-citation (#PCDATA)>
+<!ATTLIST text:endnote-citation text:label %string; #IMPLIED>
+
+<!ELEMENT text:endnote-body (text:h|text:p|
+							 text:ordered-list|text:unordered-list)*>
+
+<!ENTITY % sectionAttr "text:name CDATA #REQUIRED
+                        text:style-name %styleName; #IMPLIED
+                        text:protected %boolean; 'false' ">
+
+
+<!ELEMENT text:section ((text:section-source|office:dde-source)?,
+						%sectionText;) >
+
+<!ATTLIST text:section %sectionAttr;>
+<!ATTLIST text:section text:display (true|none|condition) "true">
+<!ATTLIST text:section text:condition %formula; #IMPLIED>
+<!ATTLIST text:section text:protection-key CDATA #IMPLIED>
+<!ATTLIST text:section text:is-hidden %boolean; #IMPLIED>
+
+<!ELEMENT text:section-source EMPTY>
+<!ATTLIST text:section-source xlink:href %string; #IMPLIED>
+<!ATTLIST text:section-source xlink:type (simple) #FIXED "simple">
+<!ATTLIST text:section-source xlink:show (embed) #FIXED "embed">
+<!ATTLIST text:section-source text:section-name %string; #IMPLIED>
+<!ATTLIST text:section-source text:filter-name %string; #IMPLIED>
+
+<!ELEMENT text:table-of-content (text:table-of-content-source, 
+								 text:index-body)   >
+<!ATTLIST text:table-of-content %sectionAttr;>
+
+<!ELEMENT text:table-of-content-source (text:index-title-template? , 
+										text:table-of-content-entry-template*,
+										text:index-source-styles* ) >
+<!ATTLIST text:table-of-content-source text:outline-level %integer; #IMPLIED>
+<!ATTLIST text:table-of-content-source text:use-outline-level %boolean; "true">
+<!ATTLIST text:table-of-content-source text:use-index-marks %boolean; "true">
+<!ATTLIST text:table-of-content-source text:use-index-source-styles 
+															%boolean; "false">
+<!ATTLIST text:table-of-content-source text:index-scope (document|chapter) 
+														"document">
+<!ATTLIST text:table-of-content-source text:relative-tab-stop-position 
+															%boolean; "true">
+<!ATTLIST text:table-of-content-source fo:language %string; #IMPLIED>
+<!ATTLIST text:table-of-content-source fo:country %string; #IMPLIED>
+<!ATTLIST text:table-of-content-source text:sort-algorithm %string; #IMPLIED>
+
+<!ELEMENT text:table-of-content-entry-template (text:index-entry-chapter-number |
+												text:index-entry-page-number |
+												text:index-entry-text |
+												text:index-entry-span |
+												text:index-entry-tab-stop |
+												text:index-entry-link-start |
+												text:index-entry-link-end)* >
+<!ATTLIST text:table-of-content-entry-template text:outline-level 
+						%integer; #REQUIRED>
+<!ATTLIST text:table-of-content-entry-template text:style-name 
+						%styleName; #REQUIRED>
+
+<!ELEMENT text:illustration-index 
+			(text:illustration-index-source, text:index-body)>
+<!ATTLIST text:illustration-index %sectionAttr;>
+
+<!ELEMENT text:illustration-index-source (text:index-title-template?,
+									text:illustration-index-entry-template?) >
+<!ATTLIST text:illustration-index-source text:index-scope 
+									(document|chapter) "document">
+<!ATTLIST text:illustration-index-source text:relative-tab-stop-position 
+									%boolean; "true">
+<!ATTLIST text:illustration-index-source text:use-caption %boolean; "true">
+<!ATTLIST text:illustration-index-source text:caption-sequence-name 
+									%string; #IMPLIED>
+<!ATTLIST text:illustration-index-source text:caption-sequence-format 
+									(text|category-and-value|caption) "text">
+<!ATTLIST text:illustration-index-source fo:language %string; #IMPLIED>
+<!ATTLIST text:illustration-index-source fo:country %string; #IMPLIED>
+<!ATTLIST text:illustration-index-source text:sort-algorithm %string; #IMPLIED>
+
+<!ELEMENT text:illustration-index-entry-template 
+								( text:index-entry-page-number |
+								  text:index-entry-text |
+								  text:index-entry-span |
+								  text:index-entry-tab-stop )* >
+<!ATTLIST text:illustration-index-entry-template text:style-name 
+									%styleName; #REQUIRED>
+
+<!ELEMENT text:table-index (text:table-index-source, text:index-body)>
+<!ATTLIST text:table-index %sectionAttr;>
+
+<!ELEMENT text:table-index-source (text:index-title-template?, 
+									text:table-index-entry-template?) >
+<!ATTLIST text:table-index-source text:index-scope 
+									(document|chapter) "document">
+<!ATTLIST text:table-index-source text:relative-tab-stop-position 
+									%boolean; "true">
+<!ATTLIST text:table-index-source text:use-caption %boolean; "true">
+<!ATTLIST text:table-index-source text:caption-sequence-name 
+									%string; #IMPLIED>
+<!ATTLIST text:table-index-source text:caption-sequence-format 
+									(text|category-and-value|caption) "text">
+<!ATTLIST text:table-index-source fo:language %string; #IMPLIED>
+<!ATTLIST text:table-index-source fo:country %string; #IMPLIED>
+<!ATTLIST text:table-index-source text:sort-algorithm %string; #IMPLIED>
+
+<!ELEMENT text:table-index-entry-template ( text:index-entry-page-number |
+											text:index-entry-text |
+											text:index-entry-span |
+											text:index-entry-tab-stop )* >
+<!ATTLIST text:table-index-entry-template text:style-name 
+											%styleName; #REQUIRED>
+
+<!ELEMENT text:object-index ( text:object-index-source, text:index-body ) >
+<!ATTLIST text:object-index %sectionAttr;>
+
+<!ELEMENT text:object-index-source ( text:index-title-template?,
+									 text:object-index-entry-template? ) >
+<!ATTLIST text:object-index-source text:index-scope 
+									(document|chapter) "document">
+<!ATTLIST text:object-index-source text:relative-tab-stop-position 
+									%boolean; "true">
+<!ATTLIST text:object-index-source text:use-spreadsheet-objects 
+									%boolean; "false">
+<!ATTLIST text:object-index-source text:use-draw-objects %boolean; "false">
+<!ATTLIST text:object-index-source text:use-chart-objects %boolean; "false">
+<!ATTLIST text:object-index-source text:use-other-objects %boolean; "false">
+<!ATTLIST text:object-index-source text:use-math-objects %boolean; "false">
+<!ATTLIST text:object-index-source fo:language %string; #IMPLIED>
+<!ATTLIST text:object-index-source fo:country %string; #IMPLIED>
+<!ATTLIST text:object-index-source text:sort-algorithm %string; #IMPLIED>
+
+<!ELEMENT text:object-index-entry-template ( text:index-entry-page-number |
+											 text:index-entry-text |
+											 text:index-entry-span |
+											 text:index-entry-tab-stop )* >
+<!ATTLIST text:object-index-entry-template text:style-name 
+											%styleName; #REQUIRED >
+
+<!ELEMENT text:user-index (text:user-index-source, text:index-body) >
+<!ATTLIST text:user-index %sectionAttr;>
+
+<!ELEMENT text:user-index-source ( text:index-title-template?,
+								   text:user-index-entry-template*,
+								   text:index-source-styles* ) >
+<!ATTLIST text:user-index-source text:index-scope 
+									(document|chapter) "document">
+<!ATTLIST text:user-index-source text:relative-tab-stop-position
+									%boolean; "true">
+<!ATTLIST text:user-index-source text:use-index-marks %boolean; "false">
+<!ATTLIST text:user-index-source text:use-graphics %boolean; "false">
+<!ATTLIST text:user-index-source text:use-tables %boolean; "false">
+<!ATTLIST text:user-index-source text:use-floating-frames %boolean; "false">
+<!ATTLIST text:user-index-source text:use-objects %boolean; "false">
+<!ATTLIST text:user-index-source text:use-index-source-styles 
+													%boolean; "false">
+<!ATTLIST text:user-index-source text:copy-outline-levels %boolean; "false">
+<!ATTLIST text:user-index-source fo:language %string; #IMPLIED>
+<!ATTLIST text:user-index-source fo:country %string; #IMPLIED>
+<!ATTLIST text:user-index-source text:sort-algorithm %string; #IMPLIED>
+<!ATTLIST text:user-index-source text:index-name %string; #IMPLIED>
+
+<!ELEMENT text:user-index-entry-template ( text:index-entry-chapter |
+										   text:index-entry-page-number |
+										   text:index-entry-text |
+										   text:index-entry-span |
+										   text:index-entry-tab-stop )* >
+<!ATTLIST text:user-index-entry-template text:outline-level %integer; #REQUIRED>
+<!ATTLIST text:user-index-entry-template text:style-name %styleName; #REQUIRED>
+
+<!ELEMENT text:alphabetical-index (text:alphabetical-index-source, 
+									text:index-body)>
+<!ATTLIST text:alphabetical-index %sectionAttr;>
+
+<!ELEMENT text:alphabetical-index-source ( text:index-title-template?, 
+							text:alphabetical-index-entry-template* ) >
+<!ATTLIST text:alphabetical-index-source text:index-scope 
+												(document|chapter) "document">
+<!ATTLIST text:alphabetical-index-source text:relative-tab-stop-position
+												%boolean; "true">
+<!ATTLIST text:alphabetical-index-source text:ignore-case %boolean; "false">
+<!ATTLIST text:alphabetical-index-source text:main-entry-style-name 
+												%styleName; #IMPLIED>
+<!ATTLIST text:alphabetical-index-source text:alphabetical-separators 
+												%boolean; "false">
+<!ATTLIST text:alphabetical-index-source text:combine-entries
+												%boolean; "true">
+<!ATTLIST text:alphabetical-index-source text:combine-entries-with-dash
+												%boolean; "false">
+<!ATTLIST text:alphabetical-index-source text:combine-entries-with-pp
+												%boolean; "true">
+<!ATTLIST text:alphabetical-index-source text:use-keys-as-entries 
+												%boolean; "false">
+<!ATTLIST text:alphabetical-index-source text:capitalize-entries
+												%boolean; "false">
+<!ATTLIST text:alphabetical-index-source text:comma-separated
+												%boolean; "false">
+<!ATTLIST text:alphabetical-index-source fo:language %string; #IMPLIED>
+<!ATTLIST text:alphabetical-index-source fo:country %string; #IMPLIED>
+<!ATTLIST text:alphabetical-index-source text:sort-algorithm %string; #IMPLIED>
+
+<!ELEMENT text:alphabetical-index-entry-template ( text:index-entry-chapter |
+												text:index-entry-page-number |
+												text:index-entry-text |
+												text:index-entry-span |
+												text:index-entry-tab-stop )* >
+<!ATTLIST text:alphabetical-index-entry-template text:outline-level 
+												(1|2|3|separator) #REQUIRED>
+<!ATTLIST text:alphabetical-index-entry-template text:style-name 
+												%styleName; #REQUIRED>
+
+<!ELEMENT text:alphabetical-index-auto-mark-file EMPTY>
+<!ATTLIST text:alphabetical-index-auto-mark-file xlink:href CDATA #IMPLIED>
+<!ATTLIST text:alphabetical-index-auto-mark-file xlink:type (simple) #FIXED "simple">
+
+<!ELEMENT text:bibliography (text:bibliography-source, text:index-body) >
+<!ATTLIST text:bibliography %sectionAttr;>
+
+<!ELEMENT text:bibliography-source ( text:index-title-template?,
+									 text:bibliography-entry-template* ) >
+
+<!ELEMENT text:bibliography-entry-template ( text:index-entry-span |
+											 text:index-entry-tab-stop |
+											 text:index-entry-bibliography )* >
+<!ATTLIST text:bibliography-entry-template text:bibliography-type 
+				( article | book | booklet | conference | custom1 | custom2 | 
+				  custom3 | custom4 | custom5 | email | inbook | incollection |
+				  inproceedings | journal | manual | mastersthesis | misc | 
+				  phdthesis | proceedings | techreport | unpublished | www ) 
+				#REQUIRED >
+<!ATTLIST text:bibliography-entry-template text:style-name 
+													%styleName; #REQUIRED>
+
+<!ELEMENT text:index-body %sectionText; >
+
+<!-- 
+Validity constraint: text:index-title elements may appear only in
+indices, and there may be only one text:index-title element.  
+-->
+<!ELEMENT text:index-title %sectionText; >
+<!ATTLIST text:index-title text:style-name %styleName; #IMPLIED>
+<!ATTLIST text:index-title text:name %string; #IMPLIED>
+
+<!ELEMENT text:index-title-template (#PCDATA)>
+<!ATTLIST text:index-title-template text:style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:index-entry-chapter-number EMPTY>
+<!ATTLIST text:index-entry-chapter-number text:style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:index-entry-chapter EMPTY>
+<!ATTLIST text:index-entry-chapter text:style-name %styleName; #IMPLIED>
+<!ATTLIST text:index-entry-chapter text:display (name|number|number-and-name) 
+															"number-and-name" >
+
+<!ELEMENT text:index-entry-text EMPTY>
+<!ATTLIST text:index-entry-text text:style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:index-entry-page-number EMPTY>
+<!ATTLIST text:index-entry-page-number text:style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:index-entry-span (#PCDATA)>
+<!ATTLIST text:index-entry-span text:style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:index-entry-bibliography EMPTY>
+<!ATTLIST text:index-entry-bibliography text:style-name %styleName; #IMPLIED>
+<!ATTLIST text:index-entry-bibliography text:bibliography-data-field
+							( address | annote | author | bibliography-type |
+							  booktitle | chapter | custom1 | custom2 | 
+							  custom3 | custom4 | custom5 | edition | editor |
+							  howpublished | identifier | institution | isbn |
+							  journal | month | note | number | organizations |
+							  pages | publisher | report-type | school | 
+							  series | title | url | volume | year ) #REQUIRED>
+
+
+<!ELEMENT text:index-entry-tab-stop EMPTY>
+<!ATTLIST text:index-entry-tab-stop text:style-name %styleName; #IMPLIED>
+<!ATTLIST text:index-entry-tab-stop style:leader-char %character; " ">
+<!ATTLIST text:index-entry-tab-stop style:type (left|right) "left">
+<!ATTLIST text:index-entry-tab-stop style:position %length; #IMPLIED>
+
+<!ELEMENT text:index-entry-link-start EMPTY>
+<!ATTLIST text:index-entry-link-start text:style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:index-entry-link-end EMPTY>
+<!ATTLIST text:index-entry-link-end text:style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:index-source-styles (text:index-source-style)*>
+<!ATTLIST text:index-source-styles text:outline-level %integer; #REQUIRED>
+
+<!ELEMENT text:index-source-style EMPTY>
+<!ATTLIST text:index-source-style text:style-name %styleName; #REQUIRED>
+
+<!ELEMENT text:toc-mark-start EMPTY>
+<!ATTLIST text:toc-mark-start text:id %string; #REQUIRED>
+<!ATTLIST text:toc-mark-start text:outline-level %integer; #IMPLIED>
+
+<!ELEMENT text:toc-mark-end EMPTY>
+<!ATTLIST text:toc-mark-end text:id %string; #REQUIRED>
+
+<!ELEMENT text:toc-mark EMPTY>
+<!ATTLIST text:toc-mark text:string-value %string; #REQUIRED>
+<!ATTLIST text:toc-mark text:outline-level %integer; #IMPLIED>
+
+<!ELEMENT text:user-index-mark-start EMPTY>
+<!ATTLIST text:user-index-mark-start text:id %string; #REQUIRED>
+<!ATTLIST text:user-index-mark-start text:outline-level %integer; #IMPLIED>
+<!ATTLIST text:user-index-mark-start text:index-name %string; #IMPLIED>
+
+<!ELEMENT text:user-index-mark-end EMPTY>
+<!ATTLIST text:user-index-mark-end text:id %string; #REQUIRED>
+
+<!ELEMENT text:user-index-mark EMPTY>
+<!ATTLIST text:user-index-mark text:string-value %string; #REQUIRED>
+<!ATTLIST text:user-index-mark text:outline-level %integer; #IMPLIED>
+<!ATTLIST text:user-index-mark text:index-name %string; #IMPLIED>
+
+<!ELEMENT text:alphabetical-index-mark-start EMPTY>
+<!ATTLIST text:alphabetical-index-mark-start text:id %string; #REQUIRED>
+<!ATTLIST text:alphabetical-index-mark-start text:key1 %string; #IMPLIED>
+<!ATTLIST text:alphabetical-index-mark-start text:key2 %string; #IMPLIED>
+<!ATTLIST text:alphabetical-index-mark-start text:main-etry %boolean; "false">
+
+<!ELEMENT text:alphabetical-index-mark-end EMPTY>
+<!ATTLIST text:alphabetical-index-mark-end text:id %string; #REQUIRED>
+
+<!ELEMENT text:alphabetical-index-mark EMPTY>
+<!ATTLIST text:alphabetical-index-mark text:string-value %string; #REQUIRED>
+<!ATTLIST text:alphabetical-index-mark text:key1 %string; #IMPLIED>
+<!ATTLIST text:alphabetical-index-mark text:key2 %string; #IMPLIED>
+<!ATTLIST text:alphabetical-index-mark text:main-etry %boolean; "false">
+
+<!ELEMENT text:bibliography-configuration (text:sort-key)*>
+<!ATTLIST text:bibliography-configuration text:prefix %string; #IMPLIED>
+<!ATTLIST text:bibliography-configuration text:suffix %string; #IMPLIED>
+<!ATTLIST text:bibliography-configuration text:sort-by-position %boolean; "true">
+<!ATTLIST text:bibliography-configuration text:numbered-entries %boolean; "false">
+<!ATTLIST text:bibliography-configuration fo:language %string; #IMPLIED>
+<!ATTLIST text:bibliography-configuration fo:country %string; #IMPLIED>
+<!ATTLIST text:bibliography-configuration text:sort-algorithm %string; #IMPLIED>
+
+<!ELEMENT text:sort-key EMPTY>
+<!ATTLIST text:sort-key text:key ( address | annote | author | 
+	bibliography-type | booktitle | chapter | custom1 | custom2 | 
+	custom3 | custom4 | custom5 | edition | editor | howpublished | 
+	identifier | institution | isbn | journal | month | note | number | 
+	organizations | pages | publisher | report-type | school | series | 
+	title | url | volume | year ) #REQUIRED>
+<!ATTLIST text:sort-key text:sort-ascending %boolean; "true">
+
+<!ELEMENT text:linenumbering-configuration (text:linenumbering-separator?)>
+<!ATTLIST text:linenumbering-configuration text:style-name %styleName; #IMPLIED>
+<!ATTLIST text:linenumbering-configuration text:number-lines %boolean; "true">
+<!ATTLIST text:linenumbering-configuration text:count-empty-lines %boolean; "true">
+<!ATTLIST text:linenumbering-configuration text:count-in-floating-frames %boolean; "false">
+<!ATTLIST text:linenumbering-configuration text:restart-numbering %boolean; "false">
+<!ATTLIST text:linenumbering-configuration text:offset %nonNegativeLength; #IMPLIED>
+<!ATTLIST text:linenumbering-configuration style:num-format (1|a|A|i|I) "1">
+<!ATTLIST text:linenumbering-configuration style:num-letter-sync %boolean; "false">
+<!ATTLIST text:linenumbering-configuration text:number-position (left|rigth|inner|outer) "left">
+<!ATTLIST text:linenumbering-configuration text:increment %nonNegativeInteger; #IMPLIED>
+
+<!ELEMENT text:linenumbering-separator (#PCDATA)>
+<!ATTLIST text:linenumbering-separator text:increment %nonNegativeInteger; #IMPLIED>
+
+<!ELEMENT text:script (#PCDATA)>
+<!ATTLIST text:script script:language CDATA #REQUIRED>
+<!ATTLIST text:script xlink:href CDATA #IMPLIED>
+<!ATTLIST text:script xlink:type (simple) #FIXED "simple">
+
+<!ELEMENT text:measure (#PCDATA)>
+<!ATTLIST text:measure text:kind (value|unit|gap) #REQUIRED>
+
+<!ELEMENT text:ruby (text:ruby-base, text:ruby-text)>
+<!ATTLIST text:ruby text:style-name %styleName; #IMPLIED>
+
+<!ELEMENT text:ruby-base %inline-text;>
+
+<!ELEMENT text:ruby-text (#PCDATA)>
+<!ATTLIST text:ruby-text text:style-name %styleName; #IMPLIED>
+
+<!-- elements for change tracking -->
+
+<!ELEMENT text:change EMPTY>
+<!ATTLIST text:change text:change-id CDATA #REQUIRED>
+
+<!ELEMENT text:change-start EMPTY>
+<!ATTLIST text:change-start text:change-id CDATA #REQUIRED>
+
+<!ELEMENT text:change-end EMPTY>
+<!ATTLIST text:change-end text:change-id CDATA #REQUIRED>
+
+<!ELEMENT text:tracked-changes (text:changed-region)*>
+<!ATTLIST text:tracked-changes text:track-changes %boolean; "true">
+<!ATTLIST text:tracked-changes text:protection-key CDATA #IMPLIED>
+
+<!ELEMENT text:changed-region (text:insertion | 
+							   (text:deletion, text:insertion?) | 
+                               text:format-change) >
+<!ATTLIST text:changed-region text:id ID #REQUIRED>
+<!ATTLIST text:changed-region text:merge-last-paragraph %boolean; "true">
+
+<!ELEMENT text:insertion (office:change-info, %sectionText;)>
+<!ELEMENT text:deletion (office:change-info, %sectionText;)>
+<!ELEMENT text:format-change (office:change-info)>
+
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/toolbar.dtd
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/toolbar.dtd	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/oofficeDTDs/toolbar.dtd	(revision 28000)
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	$Id: toolbar.dtd,v 1.7 2002/07/11 14:58:04 cd Exp $
+
+   The Contents of this file are made available subject to the terms of
+   either of the following licenses
+
+          - GNU Lesser General Public License Version 2.1
+          - Sun Industry Standards Source License Version 1.1
+
+   Sun Microsystems Inc., October, 2000
+
+   GNU Lesser General Public License Version 2.1
+   =============================================
+   Copyright 2000 by Sun Microsystems, Inc.
+   901 San Antonio Road, Palo Alto, CA 94303, USA
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License version 2.1, as published by the Free Software Foundation.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+   MA  02111-1307  USA
+
+
+   Sun Industry Standards Source License Version 1.1
+   =================================================
+   The contents of this file are subject to the Sun Industry Standards
+   Source License Version 1.1 (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.openoffice.org/license.html.
+
+   Software provided under this License is provided on an "AS IS" basis,
+   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+   See the License for the specific provisions governing your rights and
+   obligations concerning the Software.
+
+   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+
+   Copyright: 2000 by Sun Microsystems, Inc.
+
+   All Rights Reserved.
+
+   Contributor(s): _______________________________________
+-->
+<!ENTITY % boolean "(true|false)">
+<!ENTITY % numeric "CDATA">
+<!ENTITY % alignment "(top|bottom|left|right)">
+<!ENTITY % style "(symbol|text|symboltext)">
+<!ELEMENT toolbar:toolbar (toolbar:toolbaritem | toolbar:toolbarspace | toolbar:toolbarbreak | toolbar:toolbarseparator)*>
+<!ATTLIST toolbar:toolbar
+	xmlns:toolbar CDATA #FIXED "http://openoffice.org/2001/toolbar"
+	xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink"
+>
+<!ELEMENT toolbar:toolbaritem EMPTY>
+<!ATTLIST toolbar:toolbaritem
+	xlink:href CDATA #REQUIRED
+	toolbar:visible %boolean; "true"
+	toolbar:userdefined %boolean; "false"
+	toolbar:text CDATA #IMPLIED
+	toolbar:width %numeric; "0"
+	toolbar:style CDATA #IMPLIED
+	toolbar:bitmap CDATA #IMPLIED
+	toolbar:helpid CDATA #IMPLIED
+>
+<!ELEMENT toolbar:toolbarspace EMPTY>
+<!ELEMENT toolbar:toolbarbreak EMPTY>
+<!ELEMENT toolbar:toolbarseparator EMPTY>
+<!ELEMENT toolbar:toolbarlayouts (toolbar:toolbarlayout*)>
+<!ATTLIST toolbar:toolbarlayouts
+	xmlns:toolbar CDATA #FIXED "http://openoffice.org/2001/toolbar"
+>
+<!ELEMENT toolbar:toolbarlayout EMPTY>
+<!ATTLIST toolbar:toolbarlayout
+	toolbar:id CDATA #REQUIRED
+	toolbar:floatingposleft %numeric; #IMPLIED
+	toolbar:floatingpostop %numeric; #IMPLIED
+	toolbar:floatinglines %numeric; "0"
+	toolbar:dockinglines %numeric; "1"
+	toolbar:align %alignment; "left"
+	toolbar:visible %boolean; "false"
+	toolbar:floating %boolean; "false"
+	toolbar:style %style; "symbol"
+	toolbar:userdefname CDATA #IMPLIED
+>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Cell.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Cell.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Cell.java	(revision 28000)
@@ -0,0 +1,185 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+/*
+ * Cell created on 10 décembre 2005
+ */
+package org.jopendocument.dom.spreadsheet;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+import org.jdom.Text;
+import org.jopendocument.dom.ODDocument;
+import org.jopendocument.dom.ODValueType;
+import org.jopendocument.dom.XMLVersion;
+import org.jopendocument.util.CollectionUtils;
+
+/**
+ * A cell in a calc document. If you want to change a cell value you must obtain a MutableCell.
+ * 
+ * @author Sylvain
+ * @param <D> type of document
+ */
+public class Cell<D extends ODDocument> extends TableCalcNode<CellStyle, D> {
+
+    // see 5.1.1
+    private static final Pattern multiSpacePattern = Pattern.compile("[\t\r\n ]+");
+    private static boolean OO_MODE = true;
+
+    /**
+     * Set whether {@link #getTextValue()} parses strings using the standard way or using the
+     * OpenOffice.org way.
+     * 
+     * @param ooMode <code>true</code> if strings should be parsed the OO way.
+     * @see #getTextValue(boolean)
+     */
+    /*public static void setTextValueMode(boolean ooMode) {
+        OO_MODE = ooMode;
+    }*/
+
+    public static boolean getTextValueMode() {
+        return OO_MODE;
+    }
+
+    private final Row<D> row;
+
+    Cell(Row<D> parent, Element elem) {
+        super(parent.getODDocument(), elem, CellStyle.class);
+        this.row = parent;
+    }
+
+    protected final Row<D> getRow() { // NO_UCD
+        return this.row;
+    }
+
+    protected final XMLVersion getNS() {
+        return this.getODDocument().getVersion();
+    }
+
+    protected final Namespace getValueNS() {
+        final XMLVersion ns = this.getNS();
+        return ns == XMLVersion.OD ? ns.getOFFICE() : ns.getTABLE();
+    }
+
+    protected final String getType() {
+        return this.getElement().getAttributeValue("value-type", getValueNS());
+    }
+
+    public final ODValueType getValueType() {
+        final String type = this.getType();
+        return type == null ? null : ODValueType.get(type);
+    }
+
+    // cannot resolve our style since a single instance of Cell is used for all
+    // repeated and thus if we need to check table-column table:default-cell-style-name
+    // we wouldn't know which column to check.
+    @Override
+    protected String getStyleName() {
+        throw new UnsupportedOperationException("cannot resolve our style, use MutableCell");
+    }
+
+    private final String getValue(String attrName) {
+        return this.getElement().getAttributeValue(attrName, getValueNS());
+    }
+
+    public Object getValue() { // NO_UCD
+        final ODValueType vt = this.getValueType();
+        if (vt == null || vt == ODValueType.STRING) {
+            // ATTN oo generates string value-types w/o any @string-value
+            final String attr = vt == null ? null : this.getValue(vt.getValueAttribute());
+            if (attr != null)
+                return attr;
+            else {
+                return getTextValue();
+            }
+        } else {
+            return vt.parse(this.getValue(vt.getValueAttribute()));
+        }
+    }
+
+    /**
+     * Calls {@link #getTextValue(boolean)} using {@link #getTextValueMode()}.
+     * 
+     * @return a string for the content of this cell.
+     */
+    public String getTextValue() {
+        return this.getTextValue(getTextValueMode());
+    }
+
+    /**
+     * Return the text value of this cell. This is often the formatted string of a value, e.g.
+     * "11 novembre 2009" for a date. This method doesn't just return the text content it also
+     * parses XML elements (like paragraphs, tabs and line-breaks). For the differences between the
+     * OO way (as of 3.1) and the OpenDocument way see section 5.1.1 White-space Characters of
+     * OpenDocument-v1.0-os and OpenDocument-v1.2-part1. In essence OpenOffice never trim strings.
+     * 
+     * @param ooMode whether to use the OO way or the standard way.
+     * @return a string for the content of this cell.
+     */
+    public String getTextValue(final boolean ooMode) {
+        final List<String> ps = new ArrayList<String>();
+        for (final Object o : this.getElement().getChildren()) {
+            final Element child = (Element) o;
+            if ((child.getName().equals("p") || child.getName().equals("h")) && child.getNamespacePrefix().equals("text")) {
+                ps.add(getStringValue(child, ooMode));
+            }
+        }
+        return CollectionUtils.join(ps, "\n");
+    }
+
+    private String getStringValue(final Element pElem, final boolean ooMode) {
+        final StringBuilder sb = new StringBuilder();
+        final Namespace textNS = pElem.getNamespace();
+        // true if the string ends with a space that wasn't expanded from an XML element (e.g.
+        // <tab/> or <text:s/>)
+        boolean spaceSuffix = false;
+        final Iterator<?> iter = pElem.getDescendants();
+        while (iter.hasNext()) {
+            final Object o = iter.next();
+            if (o instanceof Text) {
+                final String text = multiSpacePattern.matcher(((Text) o).getText()).replaceAll(" ");
+                // trim leading
+                if (!ooMode && text.startsWith(" ") && (spaceSuffix || sb.length() == 0))
+                    sb.append(text.substring(1));
+                else
+                    sb.append(text);
+                spaceSuffix = text.endsWith(" ");
+            } else if (o instanceof Element) {
+                final Element elem = (Element) o;
+                if (elem.getName().equals("tab") && elem.getNamespace().equals(textNS)) {
+                    sb.append("\t");
+                } else if (elem.getName().equals("line-break") && elem.getNamespace().equals(textNS)) {
+                    sb.append("\n");
+                } else if (elem.getName().equals("s") && elem.getNamespace().equals(textNS)) {
+                    final int count = Integer.valueOf(elem.getAttributeValue("c", textNS, "1"));
+                    final char[] toAdd = new char[count];
+                    Arrays.fill(toAdd, ' ');
+                    sb.append(toAdd);
+                }
+            }
+        }
+        // trim trailing
+        if (!ooMode && spaceSuffix)
+            sb.deleteCharAt(sb.length() - 1);
+
+        return sb.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/CellStyle.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/CellStyle.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/CellStyle.java	(revision 28000)
@@ -0,0 +1,51 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom.spreadsheet;
+
+import java.util.Arrays;
+
+import org.jdom.Element;
+import org.jopendocument.dom.ODPackage;
+import org.jopendocument.dom.StyleDesc;
+import org.jopendocument.dom.StyleStyle;
+import org.jopendocument.dom.XMLVersion;
+
+public class CellStyle extends StyleStyle {
+
+    /*static public enum Side {
+        TOP, BOTTOM, LEFT, RIGHT
+    }*/
+
+    static public final String STYLE_FAMILY = "table-cell";
+
+    // from section 18.728 in v1.2-part1
+    public static final StyleDesc<CellStyle> DESC = new StyleDesc<CellStyle>(CellStyle.class, XMLVersion.OD, STYLE_FAMILY, "ce", "table", Arrays.asList("table:body", "table:covered-table-cell",
+            "table:even-rows", "table:first-column", "table:first-row", "table:last-column", "table:last-row", "table:odd-columns", "table:odd-rows", "table:table-cell")) {
+
+        {
+            this.getMultiRefElementsMap().putAll("table:default-cell-style-name", "table:table-column", "table:table-row");
+        }
+
+        @Override
+        public CellStyle create(ODPackage pkg, Element e) {
+            return new CellStyle(pkg, e);
+        }
+    };
+
+    public CellStyle(final ODPackage pkg, Element tableColElem) {
+        super(pkg, tableColElem);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Column.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Column.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Column.java	(revision 28000)
@@ -0,0 +1,26 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom.spreadsheet;
+
+import org.jdom.Element;
+import org.jopendocument.dom.ODDocument;
+
+public class Column<D extends ODDocument> extends TableCalcNode<ColumnStyle, D> {
+
+    public Column(final Table<D> parent, Element tableColElem) {
+        super(parent.getODDocument(), tableColElem, ColumnStyle.class);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/ColumnStyle.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/ColumnStyle.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/ColumnStyle.java	(revision 28000)
@@ -0,0 +1,38 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom.spreadsheet;
+
+import org.jdom.Element;
+import org.jopendocument.dom.ODPackage;
+import org.jopendocument.dom.StyleDesc;
+import org.jopendocument.dom.StyleStyle;
+import org.jopendocument.dom.XMLVersion;
+
+public class ColumnStyle extends StyleStyle {
+
+    static public final String STYLE_FAMILY = "table-column";
+    // from section 18.728 in v1.2-part1
+    public static final StyleDesc<ColumnStyle> DESC = new StyleDesc<ColumnStyle>(ColumnStyle.class, XMLVersion.OD, STYLE_FAMILY, "co", "table") {
+        @Override
+        public ColumnStyle create(ODPackage pkg, Element e) {
+            return new ColumnStyle(pkg, e);
+        }
+    };
+
+    public ColumnStyle(final ODPackage pkg, Element tableColElem) {
+        super(pkg, tableColElem);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Row.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Row.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Row.java	(revision 28000)
@@ -0,0 +1,87 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+/*
+ * Row created on 10 décembre 2005
+ */
+package org.jopendocument.dom.spreadsheet;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jdom.Element;
+import org.jopendocument.dom.ODDocument;
+
+/**
+ * A row in a Calc document. This class will only break "repeated" attributes on demand (eg for
+ * setting a value).
+ * 
+ * @author Sylvain
+ * @param <D> type of document
+ */
+public class Row<D extends ODDocument> extends TableCalcNode<RowStyle, D> {
+
+    private final Table<D> parent;
+    private final int index;
+    // the same immutable cell instance is repeated, but each MutableCell is only once
+    // ATTN MutableCell have their index as attribute
+    private final List<Cell<D>> cells;
+
+    Row(Table<D> parent, Element tableRowElem, int index) {
+        super(parent.getODDocument(), tableRowElem, RowStyle.class);
+        this.parent = parent;
+        this.index = index;
+        this.cells = new ArrayList<Cell<D>>();
+        for (final Element cellElem : this.getCellElements()) {
+            addCellElem(cellElem);
+        }
+    }
+
+    protected final Table<D> getSheet() {
+        return this.parent;
+    }
+
+    final int getY() { // NO_UCD
+        return this.index;
+    }
+
+    private void addCellElem(final Element cellElem) {
+        final Cell<D> cell = new Cell<D>(this, cellElem);
+        this.cells.add(cell);
+
+        final String repeatedS = cellElem.getAttributeValue("number-columns-repeated", this.getSheet().getTABLE());
+        if (repeatedS != null) {
+            final int toRepeat = Integer.parseInt(repeatedS) - 1;
+            for (int i = 0; i < toRepeat; i++) {
+                this.cells.add(cell);
+            }
+        }
+    }
+
+    /**
+     * All cells of this row.
+     * 
+     * @return cells of this row, only "table-cell" and "covered-table-cell".
+     */
+    @SuppressWarnings("unchecked")
+    private List<Element> getCellElements() {
+        // seuls table-cell et covered-table-cell sont légaux
+        return this.getElement().getChildren();
+    }
+
+    protected final Cell<D> getCellAt(int col) { // NO_UCD
+        return this.cells.get(col);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/RowStyle.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/RowStyle.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/RowStyle.java	(revision 28000)
@@ -0,0 +1,39 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom.spreadsheet;
+
+import org.jdom.Element;
+import org.jopendocument.dom.ODPackage;
+import org.jopendocument.dom.StyleDesc;
+import org.jopendocument.dom.StyleStyle;
+import org.jopendocument.dom.XMLVersion;
+
+public class RowStyle extends StyleStyle {
+
+    static public final String STYLE_FAMILY = "table-row";
+    // from section 18.728 in v1.2-part1
+    public static final StyleDesc<RowStyle> DESC = new StyleDesc<RowStyle>(RowStyle.class, XMLVersion.OD, STYLE_FAMILY, "ro", "table") {
+        @Override
+        public RowStyle create(ODPackage pkg, Element e) {
+            return new RowStyle(pkg, e);
+        }
+    };
+
+    public RowStyle(final ODPackage pkg, Element tableColElem) {
+        super(pkg, tableColElem);
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Sheet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Sheet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Sheet.java	(revision 28000)
@@ -0,0 +1,40 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom.spreadsheet;
+
+import org.jdom.Element;
+
+/**
+ * A single sheet in a spreadsheet.
+ * 
+ * @author Sylvain
+ */
+public class Sheet extends Table<SpreadSheet> {
+
+    Sheet(SpreadSheet parent, Element local) {
+        super(parent, local);
+    }
+
+    public final SpreadSheet getSpreadSheet() {
+        return this.getODDocument();
+    }
+
+    @Override
+    public void detach() {
+        super.detach();
+        this.getSpreadSheet().invalidate(getElement());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/SpreadSheet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/SpreadSheet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/SpreadSheet.java	(revision 28000)
@@ -0,0 +1,132 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom.spreadsheet;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jopendocument.dom.ODDocument;
+import org.jopendocument.dom.ODPackage;
+import org.jopendocument.dom.XMLVersion;
+
+/**
+ * A calc document.
+ * 
+ * @author Sylvain
+ */
+public class SpreadSheet implements ODDocument {
+
+    private final ODPackage originalFile;
+    private final Map<Element, Sheet> sheets;
+
+    private SpreadSheet(final Document doc, final Document styles, final ODPackage orig) {
+        if (orig != null) {
+            // ATTN OK because this is our private instance (see createFromFile())
+            this.originalFile = orig;
+        } else {
+            this.originalFile = new ODPackage();
+        }
+        this.originalFile.putFile("content.xml", doc);
+        if (styles != null)
+            this.originalFile.putFile("styles.xml", styles);
+
+        // map Sheet by XML elements so has not to depend on ordering or name
+        this.sheets = new HashMap<Element, Sheet>();
+    }
+
+    final Document getContent() {
+        return this.getPackage().getContent().getDocument();
+    }
+
+    @Override
+    public final XMLVersion getVersion() {
+        return this.getPackage().getVersion();
+    }
+
+    private Element getBody() {
+        final Element body = this.getContent().getRootElement().getChild("body", this.getVersion().getOFFICE());
+        if (this.getVersion().equals(XMLVersion.OOo))
+            return body;
+        else
+            return body.getChild("spreadsheet", this.getVersion().getOFFICE());
+    }
+
+
+    // query directly the DOM, that way don't need to listen to it (eg for name, size or order
+    // change)
+    @SuppressWarnings("unchecked")
+    private final List<Element> getTables() {
+        return this.getBody().getChildren("table", this.getVersion().getTABLE());
+    }
+
+    public int getSheetCount() { // NO_UCD
+        return this.getTables().size();
+    }
+
+    public Sheet getSheet(int i) { // NO_UCD
+        return this.getSheet(getTables().get(i));
+    }
+
+    public Sheet getSheet(String name) { // NO_UCD
+        return this.getSheet(name, false);
+    }
+
+    /**
+     * Return the first sheet with the passed name.
+     * 
+     * @param name the name of a sheet.
+     * @param mustExist what to do when no match is found : <code>true</code> to throw an exception,
+     *        <code>false</code> to return null.
+     * @return the first matching sheet, <code>null</code> if <code>mustExist</code> is
+     *         <code>false</code> and no match is found.
+     * @throws NoSuchElementException if <code>mustExist</code> is <code>true</code> and no match is
+     *         found.
+     */
+    public Sheet getSheet(String name, final boolean mustExist) throws NoSuchElementException {
+        for (final Element table : getTables()) {
+            if (name.equals(Table.getName(table)))
+                return getSheet(table);
+        }
+        if (mustExist)
+            throw new NoSuchElementException("no such sheet: " + name);
+        else
+            return null;
+    }
+
+    private final Sheet getSheet(Element table) {
+        Sheet res = this.sheets.get(table);
+        if (res == null) {
+            res = new Sheet(this, table);
+            this.sheets.put(table, res);
+        }
+        return res;
+    }
+
+    void invalidate(Element element) {
+        this.sheets.remove(element);
+    }
+
+    // *** Files
+
+    @Override
+    public final ODPackage getPackage() {
+        return this.originalFile;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Table.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Table.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/Table.java	(revision 28000)
@@ -0,0 +1,147 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom.spreadsheet;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.jdom.Attribute;
+import org.jdom.Element;
+import org.jopendocument.dom.ODDocument;
+import org.jopendocument.util.Tuple2;
+
+/**
+ * A single sheet in a spreadsheet.
+ * 
+ * @author Sylvain
+ * @param <D> type of table parent
+ */
+public class Table<D extends ODDocument> extends TableCalcNode<TableStyle, D> {
+
+    static final String getName(final Element elem) {
+        return elem.getAttributeValue("name", elem.getNamespace("table"));
+    }
+
+    // ATTN Row have their index as attribute
+    private final List<Row<D>> rows;
+    private final List<Column<D>> cols;
+
+    public Table(D parent, Element local) {
+        super(parent, local, TableStyle.class);
+
+        this.rows = new ArrayList<Row<D>>();
+        this.cols = new ArrayList<Column<D>>();
+
+        this.readColumns();
+        this.readRows();
+    }
+
+    private void readColumns() {
+        this.read(true);
+    }
+
+    private final void readRows() {
+        this.read(false);
+    }
+
+    private final void read(final boolean col) {
+        final Tuple2<List<Element>, Integer> r = flatten(col);
+        (col ? this.cols : this.rows).clear();
+        for (final Element clone : r.get0()) {
+            if (col)
+                this.addCol(clone);
+            else
+                this.addRow(clone);
+        }
+    }
+
+    private final void addCol(Element clone) {
+        this.cols.add(new Column<D>(this, clone));
+    }
+
+    private Tuple2<List<Element>, Integer> flatten(boolean col) {
+        final List<Element> res = new ArrayList<Element>();
+        final Element header = this.getElement().getChild("table-header-" + getName(col) + "s", getTABLE());
+        if (header != null)
+            res.addAll(flatten(header, col));
+        final int headerCount = res.size();
+
+        res.addAll(flatten(getElement(), col));
+
+        return Tuple2.create(res, headerCount);
+    }
+
+    @SuppressWarnings("unchecked")
+    private List<Element> flatten(final Element elem, boolean col) {
+        final String childName = getName(col);
+        final List<Element> children = elem.getChildren("table-" + childName, getTABLE());
+        // not final, since iter.add() does not work consistently, and
+        // thus we must recreate an iterator each time
+        ListIterator<Element> iter = children.listIterator();
+        while (iter.hasNext()) {
+            final Element row = iter.next();
+            final Attribute repeatedAttr = row.getAttribute("number-" + childName + "s-repeated", getTABLE());
+            if (repeatedAttr != null) {
+                row.removeAttribute(repeatedAttr);
+                final int index = iter.previousIndex();
+                int repeated = Integer.parseInt(repeatedAttr.getValue());
+                if (repeated > 60000) {
+                    repeated = 10;
+                }
+                // -1 : we keep the original row
+                for (int i = 0; i < repeated - 1; i++) {
+                    final Element clone = (Element) row.clone();
+                    // cannot use iter.add() since on JDOM 1.1 if row is the last table-column
+                    // before table-row the clone is added at the very end
+                    children.add(index, clone);
+                }
+                // restart after the added rows
+                iter = children.listIterator(index + repeated);
+            }
+        }
+
+        return children;
+    }
+
+    public void detach() {
+        this.getElement().detach();
+    }
+
+    private final String getName(boolean col) {
+        return col ? "column" : "row";
+    }
+
+
+    private synchronized void addRow(Element child) {
+        this.rows.add(new Row<D>(this, child, this.rows.size()));
+    }
+
+
+    // *** get count
+
+    public final Column<D> getColumn(int i) { // NO_UCD
+        return this.cols.get(i);
+    }
+
+    public final int getRowCount() { // NO_UCD
+        return this.rows.size();
+    }
+
+    public final int getColumnCount() { // NO_UCD
+        return this.cols.size();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/TableCalcNode.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/TableCalcNode.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/TableCalcNode.java	(revision 28000)
@@ -0,0 +1,41 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom.spreadsheet;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+import org.jopendocument.dom.ImmutableDocStyledNode;
+import org.jopendocument.dom.ODDocument;
+import org.jopendocument.dom.StyleStyle;
+
+class TableCalcNode<S extends StyleStyle, D extends ODDocument> extends ImmutableDocStyledNode<S, D> {
+
+    /**
+     * Create a new instance. We used to find the {@link StyleStyle} class with reflection but this
+     * was slow.
+     * 
+     * @param parent the parent document.
+     * @param local our XML model.
+     * @param styleClass our class of style, cannot be <code>null</code>.
+     */
+    public TableCalcNode(D parent, Element local, final Class<S> styleClass) {
+        super(parent, local, styleClass);
+    }
+
+    protected final Namespace getTABLE() {
+        return this.getODDocument().getVersion().getTABLE();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/TableStyle.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/TableStyle.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/TableStyle.java	(revision 28000)
@@ -0,0 +1,40 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.dom.spreadsheet;
+
+import java.util.Arrays;
+
+import org.jdom.Element;
+import org.jopendocument.dom.ODPackage;
+import org.jopendocument.dom.StyleDesc;
+import org.jopendocument.dom.StyleStyle;
+import org.jopendocument.dom.XMLVersion;
+
+public class TableStyle extends StyleStyle {
+
+    static public final String STYLE_FAMILY = "table";
+    // from section 18.728 in v1.2-part1
+    public static final StyleDesc<TableStyle> DESC = new StyleDesc<TableStyle>(TableStyle.class, XMLVersion.OD, STYLE_FAMILY, "ta", "table", Arrays.asList("table:background", "table:table")) {
+        @Override
+        public TableStyle create(ODPackage pkg, Element e) {
+            return new TableStyle(pkg, e);
+        }
+    };
+
+    public TableStyle(final ODPackage pkg, Element tableColElem) {
+        super(pkg, tableColElem);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/dom/spreadsheet/package.html	(revision 28000)
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Classes needed to handle Spreadsheet documents.
+
+@see org.jopendocument.dom.spreadsheet.SpreadSheet
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/io/SaxContentUnmarshaller.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/io/SaxContentUnmarshaller.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/io/SaxContentUnmarshaller.java	(revision 28000)
@@ -0,0 +1,399 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.io;
+
+import java.util.Stack;
+
+import org.jopendocument.model.office.OfficeBody;
+import org.jopendocument.model.office.OfficeSpreadsheet;
+import org.jopendocument.model.table.TableTable;
+import org.jopendocument.model.table.TableTableCell;
+import org.jopendocument.model.table.TableTableColumn;
+import org.jopendocument.model.table.TableTableRow;
+import org.jopendocument.model.text.TextP;
+import org.jopendocument.model.text.TextSpan;
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class SaxContentUnmarshaller extends DefaultHandler {
+
+    private OfficeBody body;
+
+    private Object current;
+
+    private final Stack<Object> stack;
+
+    // -----
+
+    public SaxContentUnmarshaller() {
+        this.stack = new Stack<Object>();
+    }
+
+    // ----- callbacks: -----
+
+    private void assertParsed(final Attributes attribs, final int l) {
+        if (attribs.getLength() > l) {
+            for (int i = 0; i < attribs.getLength(); i++) {
+                System.err.println(attribs.getQName(i) + "  -> " + attribs.getValue(i));
+            }
+            throw new IllegalStateException("Somme attributes are not parsed");
+        }
+    }
+
+    public void characters(final char[] data, final int start, final int length) {
+        final StringBuffer s = new StringBuffer();
+        s.append(data, start, length);
+        if (this.current instanceof TextP) {
+            ((TextP) this.current).addToLastTextSpan(s.toString());
+        } else if (this.current instanceof TextSpan) {
+            ((TextSpan) this.current).concantValue(s.toString());
+        }
+    }
+
+    // -----
+
+    public void endElement(final String uri, final String localName, final String qName) {
+        this.pop();
+    }
+
+    // -----
+
+    public OfficeBody getBody() {
+        return this.body;
+    }
+
+    // -----
+
+    private void pop() {
+
+        if (!this.stack.isEmpty()) {
+            this.stack.pop();
+
+        }
+        if (!this.stack.isEmpty()) {
+            this.current = this.stack.peek();
+        }
+    }
+
+    private void push(final Object o) {
+        this.current = o;
+        this.stack.push(o);
+
+    }
+
+    public void startElement(final String uri, final String localName, final String qName, final Attributes attribs) {
+
+        if (qName.equals("office:automatic-styles")) {
+            /*this.autostyles = new OfficeAutomaticStyles();
+            this.document.setAutomaticStyles(this.autostyles);
+            this.push(this.autostyles);*/
+        	this.push(new Object());
+        } else if (qName.equals("style:style")) {
+            final Object style = new Object();
+        	/*final StyleStyle style = new StyleStyle();
+            style.setStyleName(attribs.getValue("style:name"));
+            style.setStyleFamily(attribs.getValue("style:family"));
+            style.setStyleParentStyleName(attribs.getValue("style:parent-style-name"));
+            style.setMasterPageName(attribs.getValue("style:master-page-name"));
+
+            // style:data-style-name="N108"
+            if (this.current instanceof OfficeAutomaticStyles) {
+                this.autostyles.addStyle(style);
+            } else {
+                System.err.println("Not OfficeAutomaticStyles:" + this.current);
+                Thread.dumpStack();
+            }*/
+            this.push(style);
+        } else if (qName.equals("number:number-style")) {
+        	final Object style = new Object();
+            /*final NumberNumberStyle style = new NumberNumberStyle();
+            style.setStyleName(attribs.getValue("style:name"));
+            style.setStyleFamily(attribs.getValue("style:family"));
+
+            // style:data-style-name="N108"
+            if (this.current instanceof OfficeAutomaticStyles) {
+                this.autostyles.addStyle(style);
+            } else {
+                System.err.println("Not OfficeAutomaticStyles:" + this.current);
+                Thread.dumpStack();
+            }*/
+            this.push(style);
+        } else if (qName.equals("style:table-row-properties")) {
+        	final Object props = new Object();
+            /*final StyleTableRowProperties props = new StyleTableRowProperties();
+            props.setFoBreakBefore(attribs.getValue("fo:break-before"));
+            props.setRowHeight(attribs.getValue("style:row-height"));
+            //props.setUseOptimalRowHeight(attribs.getValue("style:use-optimal-row-height"));
+            if (this.current instanceof StyleStyle) {
+                ((StyleStyle) this.current).setTableRowProperties(props);
+            } else {
+                System.err.println("Not StyleStyle:" + this.current);
+                Thread.dumpStack();
+            }*/
+            this.push(props);
+        } else if (qName.equals("style:table-properties")) {
+            //final StyleTableProperties props = new StyleTableProperties();
+            final Object props = new Object();
+            //props.setDisplay(ValueHelper.getBoolean(attribs.getValue("table:display")));
+            //props.setWritingMode(attribs.getValue("style:writing-mode"));
+
+            /*if (this.current instanceof StyleStyle) {
+                ((StyleStyle) this.current).setTableProperties(props);
+            } else {
+                System.err.println("Not StyleStyle:" + this.current);
+                Thread.dumpStack();
+            }*/
+            this.push(props);
+        } else if (qName.equals("style:table-cell-properties")) {
+        	final Object props = new Object();
+            /*final StyleTableCellProperties props = new StyleTableCellProperties();
+            props.setVerticalAlign(attribs.getValue("style:vertical-align"));
+            props.setBackgroundColor(attribs.getValue("fo:background-color"));
+
+            props.setPadding(attribs.getValue("fo:padding"));
+
+            props.setTextAlignSource(attribs.getValue("style:text-align-source"));
+            props.setRepeatContent(attribs.getValue("style:repeat-content"));
+
+            props.setBorderLeft(attribs.getValue("fo:border-left"));
+            props.setBorderRight(attribs.getValue("fo:border-right"));
+
+            props.setBorderTop(attribs.getValue("fo:border-top"));
+            props.setBorderBottom(attribs.getValue("fo:border-bottom"));
+            // doit etre apres pour overrider le border!
+            props.setBorder(attribs.getValue("fo:border"));
+            props.setWrapOption(attribs.getValue("fo:wrap-option"));
+            if (this.current instanceof StyleStyle) {
+                ((StyleStyle) this.current).setTableCellProperties(props);
+
+            } else {
+                System.err.println("Not StyleStyle:" + this.current);
+                Thread.dumpStack();
+            }*/
+            this.push(props);
+        } else if (qName.equals("style:text-properties")) {
+        	final Object props = new Object();
+            /*final StyleTextProperties props = new StyleTextProperties();
+            props.setFontName(attribs.getValue("style:font-name"));
+            props.setFontSize(attribs.getValue("fo:font-size"));
+            props.setFontWeight(attribs.getValue("fo:font-weight"));
+            props.setColor(attribs.getValue("fo:color"));
+            // fo:hyphenate="true"
+            if (this.current instanceof StyleStyle) {
+                ((StyleStyle) this.current).setTextProperties(props);
+            } else {
+                System.err.println("Not StyleStyle:" + this.current);
+                Thread.dumpStack();
+            }*/
+            this.push(props);
+        } else if (qName.equals("style:table-column-properties")) {
+        	final Object props = new Object();
+            /*final StyleTableColumnProperties props = new StyleTableColumnProperties();
+            props.setFoBreakBefore(attribs.getValue("fo:break-before"));
+            props.setStyleColumnWidth(attribs.getValue("style:column-width"));
+
+            if (this.current instanceof StyleStyle) {
+                ((StyleStyle) this.current).setTableColumnProperties(props);
+            } else {
+                System.err.println("Not StyleStyle:" + this.current);
+                Thread.dumpStack();
+            }*/
+            this.push(props);
+        } else if (qName.equals("style:paragraph-properties")) {
+        	final Object props = new Object();
+            /*final StyleParagraphProperties props = new StyleParagraphProperties();
+            props.setTextAlign(attribs.getValue("fo:text-align"));
+            props.setMarginLeft(attribs.getValue("fo:margin-left"));
+
+            if (this.current instanceof StyleStyle) {
+                ((StyleStyle) this.current).setParagraphProperties(props);
+            } else {
+                System.err.println("Not StyleStyle:" + this.current);
+                Thread.dumpStack();
+            }*/
+            this.push(props);
+        } else if (qName.equals("office:body")) {
+            this.body = new OfficeBody();
+            this.push(this.body);
+        } else if (qName.equals("office:spreadsheet")) {
+            final OfficeSpreadsheet spread = new OfficeSpreadsheet();
+            if (this.current instanceof OfficeBody) {
+                ((OfficeBody) this.current).addOfficeSpreadsheet(spread);
+            } else {
+                System.err.println("Not StyleStyle:" + this.current);
+                Thread.dumpStack();
+            }
+
+            this.push(spread);
+
+        } else if (qName.equals("table:table")) {
+            final TableTable table = new TableTable();
+            final String printranges = attribs.getValue("table:print-ranges");
+            if (printranges != null) {
+                table.setTablePrintRanges(printranges);
+            }
+            this.assertParsed(attribs, 3);
+            if (this.current instanceof OfficeSpreadsheet) {
+                ((OfficeSpreadsheet) this.current).addTable(table);
+            } else {
+                System.err.println("Not OfficeSpreadsheet:" + this.current);
+                Thread.dumpStack();
+            }
+            this.push(table);
+
+        } else if (qName.equals("table:table-column")) {
+            final TableTableColumn col = new TableTableColumn();
+            col.setTableStyleName(attribs.getValue("table:style-name"));
+            col.setTableDefaultCellStyleName(attribs.getValue("table:default-cell-style-name"));
+            col.setTableNumberColumnsRepeated(attribs.getValue("table:number-columns-repeated"));
+
+            this.assertParsed(attribs, 3);
+            if (this.current instanceof TableTable) {
+                ((TableTable) this.current).addColumn(col);
+            } else {
+                System.err.println("Not TableTable:" + this.current);
+                Thread.dumpStack();
+            }
+            this.push(col);
+
+        } else if (qName.equals("table:table-row")) {
+
+            final TableTableRow row = new TableTableRow();
+            row.setTableNumberRowsRepeated(attribs.getValue("table:number-rows-repeated"));
+
+            if (this.current instanceof TableTable) {
+                ((TableTable) this.current).addRow(row);
+            } else {
+                System.err.println("Not TableTable:" + this.current);
+            }
+            this.push(row);
+
+        } else if (qName.equals("table:table-cell") || qName.equals("table:covered-table-cell")) {
+            final TableTableCell cell = new TableTableCell();
+            cell.setTableStyleName(attribs.getValue("table:style-name"));
+            //cell.setTableNumberColumnsRepeated(attribs.getValue("table:number-columns-repeated"));
+            //cell.setTableNumberColumnsSpanned(attribs.getValue("table:number-columns-spanned"));
+            //cell.setTableNumberRowsSpanned(attribs.getValue("table:number-rows-spanned"));
+            //cell.setTableValueType(attribs.getValue("office:value-type"));
+
+            if (this.current instanceof TableTableRow) {
+                ((TableTableRow) this.current).addCell(cell);
+            } else {
+                System.err.println("Not TableTableRow:" + this.current);
+                Thread.dumpStack();
+            }
+            this.push(cell);
+
+        } else if (qName.equals("text:p")) {
+            final TextP p = new TextP();
+            // TODO: gerer le multi textp dans une cellule
+            if (this.current instanceof TableTableCell) {
+                ((TableTableCell) this.current).setTextP(p);
+            } /*else if (this.current instanceof DrawImage) {
+                ((DrawImage) this.current).setTextP(p);
+            }*/ else {
+                System.err.println("Not TableTableCell:" + this.current + " classe:" + this.current.getClass());
+                Thread.dumpStack();
+            }
+            this.push(p);
+
+        } else if (qName.equals("text:span")) {
+            final TextSpan textspan = new TextSpan();
+
+            if (this.current instanceof TextP) {
+                ((TextP) this.current).addTextSpan(textspan);
+            } else {
+                System.err.println("Not TextP:" + this.current);
+                Thread.dumpStack();
+            }
+            this.push(textspan);
+
+        } /*else if (qName.equals("draw:frame")) {
+            final DrawFrame p = new DrawFrame();
+            p.setSvgWidth(attribs.getValue("svg:width"));
+            p.setSvgHeight(attribs.getValue("svg:height"));
+            p.setSvgX(attribs.getValue("svg:x"));
+            p.setSvgY(attribs.getValue("svg:y"));
+
+            if (this.current instanceof TableTableCell) {
+                ((TableTableCell) this.current).addDrawFrame(p);
+            } else if (this.current instanceof TableShapes) {
+                ((TableShapes) this.current).addDrawFrame(p);
+            } else {
+                System.err.println("Not TableTableCell:" + this.current);
+                Thread.dumpStack();
+            }
+            this.push(p);
+
+        } else if (qName.equals("draw:image")) {
+            final DrawImage p = new DrawImage();
+            final String link = attribs.getValue("xlink:href");
+            p.setXlinkHref(link);
+            this.document.preloadImage(link);
+            if (this.current instanceof DrawFrame) {
+                ((DrawFrame) this.current).setDrawImage(p);
+            } else {
+                System.err.println("Not DrawFrame:" + this.current);
+                Thread.dumpStack();
+            }
+            this.push(p);
+
+        } else if (qName.equals("table:shapes")) {
+            final TableShapes p = new TableShapes();
+
+            if (this.current instanceof TableTable) {
+                ((TableTable) this.current).setTableShapes(p);
+            } else {
+                System.err.println("Not TableTable:" + this.current);
+                Thread.dumpStack();
+            }
+            this.push(p);
+
+        } else if (qName.equals("office:scripts")) {
+            this.scripts = new OfficeScripts();
+
+            this.push(this.scripts);
+
+        } else if (qName.equals("office:font-face-decls")) {
+            this.fontDeclarations = new FontFaceDecls();
+
+            this.push(this.fontDeclarations);
+
+        } else if (qName.equals("style:font-face")) {
+            final StyleFontFace p = new StyleFontFace();
+            p.setStyleName(attribs.getValue("style:name"));
+            p.setFontFamily(attribs.getValue("svg:font-family"));
+            p.setFontFamilyGeneric(attribs.getValue("style:font-family-generic"));
+            p.setFontPitch(attribs.getValue("style:font-pitch"));
+
+            if (this.current instanceof FontFaceDecls) {
+                ((FontFaceDecls) this.current).addFontFace(p);
+            } else {
+                System.err.println("Not FontFaceDecls:" + this.current);
+                Thread.dumpStack();
+            }
+            this.push(p);
+
+        }*/
+
+        else {
+            //System.err.println("content.xml : ignoring :" + qName);
+            this.push(uri);
+
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/OpenDocument.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/OpenDocument.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/OpenDocument.java	(revision 28000)
@@ -0,0 +1,44 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.model;
+
+import org.jopendocument.model.office.OfficeBody;
+
+public class OpenDocument {
+
+    private OfficeBody body;
+
+    // split
+
+    /**
+     * Creates an empty document You may use a loadFrom method on it
+     */
+    public OpenDocument() {
+
+    }
+
+    public OfficeBody getBody() {
+        return this.body;
+    }
+
+    public void init(final OfficeBody aBody) {
+        if (aBody == null) {
+            throw new IllegalArgumentException("OfficeBody cannot be null");
+        }
+
+        this.body = aBody;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/office/OfficeBody.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/office/OfficeBody.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/office/OfficeBody.java	(revision 28000)
@@ -0,0 +1,35 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.model.office;
+
+import java.util.List;
+import java.util.Vector;
+
+/**
+ * 
+ */
+public class OfficeBody {
+
+    private final List<OfficeSpreadsheet> officeSpreadsheets = new Vector<OfficeSpreadsheet>();
+
+    public void addOfficeSpreadsheet(final OfficeSpreadsheet spread) {
+        this.officeSpreadsheets.add(spread);
+    }
+
+    public List<OfficeSpreadsheet> getOfficeSpreadsheets() {
+        return this.officeSpreadsheets;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/office/OfficeSpreadsheet.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/office/OfficeSpreadsheet.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/office/OfficeSpreadsheet.java	(revision 28000)
@@ -0,0 +1,39 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.model.office;
+
+import java.util.List;
+import java.util.Vector;
+
+import org.jopendocument.model.table.TableTable;
+
+public class OfficeSpreadsheet {
+    List<TableTable> tables = new Vector<TableTable>();
+
+    public void addTable(final TableTable table) {
+        this.tables.add(table);
+    }
+
+    public List<TableTable> getTables() {
+        return this.tables;
+    }
+
+    @Override
+    public String toString() {
+
+        return "OfficeSpreadsheet: " + this.tables.size() + " tables";
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/table/TableTable.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/table/TableTable.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/table/TableTable.java	(revision 28000)
@@ -0,0 +1,150 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.model.table;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 
+ */
+public class TableTable {
+
+    // Une colonne ou ligne repeated est dupliquée dans la liste
+    ArrayList<TableTableColumn> columns = new ArrayList<TableTableColumn>();
+
+    private int printStartCol = 0;
+
+    private int printStartRow = 0;
+
+    private int printStopCol = 0;
+
+    private int printStopRow = 0;
+
+    ArrayList<TableTableRow> rows = new ArrayList<TableTableRow>();
+
+    public void addColumn(final TableTableColumn col) {
+        for (int i = 0; i < col.getTableNumberColumnsRepeated(); i++) {
+            this.columns.add(col);
+        }
+
+        col.setTable(this);
+
+    }
+
+    public void addRow(final TableTableRow r) {
+        for (int i = 0; i < r.getTableNumberRowsRepeated(); i++) {
+            this.rows.add(r);
+        }
+    }
+
+    public int getPrintStartCol() {
+        return this.printStartCol;
+    }
+
+    public int getPrintStartRow() {
+        return this.printStartRow;
+    }
+
+    public int getPrintStopCol() {
+        return this.printStopCol;
+    }
+
+    public int getPrintStopRow() {
+        return this.printStopRow;
+    }
+
+
+    /**
+     * Return all the rows (duplicated if repeated)
+     */
+    public List<TableTableRow> getRows() {
+        return this.rows;
+    }
+
+    /**
+     * Sets the value of the tablePrintRanges property.
+     * 
+     * @param value allowed object is {@link String }
+     * 
+     */
+    public void setTablePrintRanges(final String value) {
+        if (value == null || !value.contains(":")) {
+            throw new IllegalArgumentException("ranges is null");
+        }
+        //this.tablePrintRanges = value;
+        final int s = value.indexOf(':');
+        final String l = value.substring(0, s);
+        final String r = value.substring(s + 1);
+
+        String vl = l.substring(l.indexOf('.') + 1);
+        String vr = r.substring(r.indexOf('.') + 1);
+        vl = removeDollars(vl);
+        vr = removeDollars(vr);
+
+        {
+            int j = 0;
+            for (int i = vl.length() - 1; i >= 0; i--) {
+                final int c = vl.charAt(i);
+                if (Character.isLetter(c)) {
+                    final int val = c - 'A' + 1;
+                    this.printStartCol += val * Math.pow(26, j);
+                    j++;
+                } else {
+                    this.printStartRow = i;
+                }
+            }
+            final String substring = vl.substring(j);
+            this.printStartRow = Integer.valueOf(substring) - 1;
+            this.printStartCol--;
+        }
+        {
+            int j = 0;
+            for (int i = vr.length() - 1; i >= 0; i--) {
+                final int c = vr.charAt(i);
+                if (Character.isLetter(c)) {
+                    final int val = c - 'A' + 1;
+                    this.printStopCol += val * Math.pow(26, j);
+                    j++;
+                } else {
+                    this.printStopRow = i;
+                }
+            }
+            final String substring = vr.substring(j);
+            this.printStopRow = Integer.valueOf(substring) - 1;
+            this.printStopCol--;
+        }
+    }
+
+    private final String removeDollars(String s) {
+        final int length = s.length();
+        final StringBuilder t = new StringBuilder(length);
+        for (int i = 0; i < length; i++) {
+            char c = s.charAt(i);
+            if (c != '$') {
+                t.append(c);
+            }
+        }
+        return t.toString();
+    }
+
+    @Override
+    public String toString() {
+
+        return "TableTable: print:" + this.getPrintStartCol() + "," + this.getPrintStartRow() + " : " + this.getPrintStopCol() + "," + this.getPrintStopRow();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/table/TableTableCell.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/table/TableTableCell.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/table/TableTableCell.java	(revision 28000)
@@ -0,0 +1,84 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.model.table;
+
+import org.jopendocument.model.text.TextP;
+
+public class TableTableCell {
+
+    private TableTableColumn column;
+
+    protected String tableStyleName;
+
+    private TextP textP;
+
+    private void computeStyle() {
+        if (this.column == null) {
+            return;
+        }
+        String styleName = this.getStyleName();
+
+        if (styleName == null) {
+            styleName = this.column.getTableDefaultCellStyleName();
+        }
+
+    }
+
+    /**
+     * Gets the value of the tableStyleName property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getStyleName() {
+        return this.tableStyleName;
+    }
+
+    public TextP getTextP() {
+        return this.textP;
+    }
+
+    /**
+     * Sets the value of the tableStyleName property.
+     * 
+     * @param value allowed object is {@link String }
+     * 
+     */
+    public void setTableStyleName(final String value) {
+
+        this.tableStyleName = value;
+        this.computeStyle();
+
+    }
+
+
+    public void setTextP(final TextP p) {
+        if (this.textP != null) {
+        	if (p != null && !p.isEmpty()) {
+        		System.err.println("TableTableCell: Warning: no support for multiple TextP in a Cell (current="+this.textP+") (tried="+p+")");
+        	}
+        } else {
+            this.textP = p;
+        }
+
+    }
+
+    @Override
+    public String toString() {
+        return "Cell: style:" + this.getStyleName() + " TestP:" + this.getTextP();
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/table/TableTableColumn.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/table/TableTableColumn.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/table/TableTableColumn.java	(revision 28000)
@@ -0,0 +1,105 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.model.table;
+
+
+public class TableTableColumn {
+
+    protected String tableDefaultCellStyleName;
+
+    protected String tableNumberColumnsRepeated;
+
+    protected String tableStyleName;
+
+    /**
+     * Gets the value of the tableDefaultCellStyleName property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getTableDefaultCellStyleName() {
+        return this.tableDefaultCellStyleName;
+    }
+
+    /**
+     * Gets the value of the tableNumberColumnsRepeated property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public int getTableNumberColumnsRepeated() {
+        if (this.tableNumberColumnsRepeated == null) {
+            return 1;
+        }
+        return Integer.valueOf(this.tableNumberColumnsRepeated).intValue();
+
+    }
+
+    /**
+     * Gets the value of the tableStyleName property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getTableStyleName() {
+        return this.tableStyleName;
+    }
+
+    public void setTable(final TableTable t) {
+    }
+
+    /**
+     * Sets the value of the tableDefaultCellStyleName property.
+     * 
+     * @param value allowed object is {@link String }
+     * 
+     */
+    public void setTableDefaultCellStyleName(final String value) {
+        this.tableDefaultCellStyleName = value;
+    }
+
+    /**
+     * Sets the value of the tableNumberColumnsRepeated property.
+     * 
+     * @param value allowed object is {@link String }
+     * 
+     */
+    public void setTableNumberColumnsRepeated(final String value) {
+        this.tableNumberColumnsRepeated = value;
+    }
+
+    /**
+     * Sets the value of the tableStyleName property.
+     * 
+     * @param value allowed object is {@link String }
+     * 
+     */
+    public void setTableStyleName(final String value) {
+        this.tableStyleName = value;
+    }
+
+    /*
+     * private void setColumnStyle(StyleStyle style) { this.columnStyle=style;
+     * this.width=columnStyle.getWidth(); }
+     */
+
+
+    @Override
+    public String toString() {
+
+        return "TableColumn: style:" + this.getTableStyleName() + " defaultCellStyle:" + this.tableDefaultCellStyleName;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/table/TableTableRow.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/table/TableTableRow.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/table/TableTableRow.java	(revision 28000)
@@ -0,0 +1,86 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.model.table;
+
+import java.util.Vector;
+
+/**
+ * 
+ */
+public class TableTableRow {
+    static int count = 0;
+
+
+    Vector<TableTableCell> cells = new Vector<TableTableCell>();
+
+    int id = 0;
+
+    protected int tableNumberRowsRepeated = 1;
+
+    public TableTableRow() {
+        this.id = count;
+        count++;
+    }
+
+    public void addCell(final TableTableCell c) {
+        this.cells.add(c);
+
+    }
+
+    /**
+     * Gets the value of the tableNumberRowsRepeated property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public int getTableNumberRowsRepeated() {
+
+        return this.tableNumberRowsRepeated;
+
+    }
+
+    // public List<TableTableCell> getCells() {
+    // return cells;
+    // }
+
+
+    public String getText() {
+        String t = "";
+        for (int index = 0; index < this.cells.size(); index++) {
+            final TableTableCell c = this.cells.get(index);
+            t += c.getTextP();
+        }
+        return t;
+    }
+
+    /**
+     * Sets the value of the tableNumberRowsRepeated property.
+     * 
+     * @param value allowed object is {@link String }
+     * 
+     */
+    public void setTableNumberRowsRepeated(final String value) {
+        if (value != null) {
+            this.tableNumberRowsRepeated = Integer.valueOf(value).intValue();
+
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "TableRow" + this.id;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/text/TextP.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/text/TextP.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/text/TextP.java	(revision 28000)
@@ -0,0 +1,58 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.model.text;
+
+import java.util.List;
+import java.util.Vector;
+
+/**
+ * 
+ */
+public class TextP {
+
+    private final List<TextSpan> textSpans = new Vector<TextSpan>();
+
+    public void addTextSpan(final TextSpan p) {
+        if (p == null) {
+            throw new IllegalArgumentException("null argument");
+        }
+        this.textSpans.add(p);
+    }
+
+    public void addToLastTextSpan(final String string) {
+
+        if (this.isEmpty()) {
+            final TextSpan s = new TextSpan();
+            s.setValue(string);
+            this.textSpans.add(s);
+        } else {
+            final TextSpan s = this.textSpans.get(this.textSpans.size() - 1);
+            s.setValue(s.getValue() + string);
+        }
+    }
+
+
+    public boolean isEmpty() {
+        return this.textSpans.isEmpty();
+    }
+
+
+    @Override
+    public String toString() {
+
+        return "TextP:" + this.textSpans;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/text/TextSpan.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/text/TextSpan.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/model/text/TextSpan.java	(revision 28000)
@@ -0,0 +1,64 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.model.text;
+
+
+public class TextSpan {
+
+    private String value;
+
+    public void concantValue(final String string) {
+        if (string == null) {
+            throw new IllegalArgumentException("Style null");
+        }
+
+        if (this.value == null) {
+            this.value = string;
+        } else {
+            this.value += string;
+        }
+    }
+
+
+
+    /**
+     * Gets the value of the value property.
+     * 
+     * @return possible object is {@link String }
+     * 
+     */
+    public String getValue() {
+        return this.value;
+    }
+
+    /**
+     * Sets the value of the value property.
+     * 
+     * @param value allowed object is {@link String }
+     * 
+     */
+    public void setValue(final String value) {
+        if (value == null) {
+            throw new IllegalArgumentException("null argument");
+        }
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return this.value;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/CollectionMap.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/CollectionMap.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/CollectionMap.java	(revision 28000)
@@ -0,0 +1,164 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.util;
+
+import static java.util.Arrays.asList;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections.MultiHashMap;
+import org.apache.commons.collections.MultiMap;
+import org.apache.commons.collections.map.MultiValueMap;
+
+/**
+ * Une MultiMap qui permet de ne pas renvoyer <code>null</code>. De plus elle permet de choisir le
+ * type de Collection utilisé.
+ * 
+ * @author ILM Informatique 8 sept. 2004
+ * @param <K> type of the keys
+ * @param <V> type of elements in collections
+ */
+@SuppressWarnings({ "unchecked", "serial" })
+public class CollectionMap<K, V> extends MultiHashMap {
+
+    private static final int DEFAULT_CAPACITY = 16;
+
+    private final Class<? extends Collection<V>> collectionClass;
+    private final Collection<V> collectionSpecimen;
+
+    /**
+     * Une nouvelle map avec ArrayList comme collection.
+     */
+    public CollectionMap() {
+        this(ArrayList.class);
+    }
+
+    /**
+     * Une nouvelle map. <code>collectionClass</code> doit descendre de Collection, et posséder un
+     * constructeur prenant une Collection (c'est le cas de la majorité des classes de java.util).
+     * 
+     * @param aCollectionClass le type de collection utilisé.
+     */
+    public CollectionMap(Class aCollectionClass) {
+        this(aCollectionClass, DEFAULT_CAPACITY);
+    }
+
+    /**
+     * Une nouvelle map sans préciser le type de collection. Dans ce cas si vous voulez spécifier
+     * une collection surchargez {@link #createCollection(Collection)}. Ce constructeur est donc
+     * utile pour des raisons de performances (évite la réflexion nécessaire avec les autres).
+     * 
+     * @param initialCapacity the initial capacity.
+     */
+    public CollectionMap(final int initialCapacity) {
+        this((Class) null, initialCapacity);
+    }
+
+    public CollectionMap(Class aCollectionClass, final int initialCapacity) {
+        super(initialCapacity);
+        this.collectionClass = aCollectionClass;
+        this.collectionSpecimen = null;
+        new MultiValueMap(); // TODO: use this class instead of deprecated MultiHashMap
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.commons.collections.MultiHashMap#createCollection(java.util.Collection)
+     */
+    public Collection<V> createCollection(Collection coll) {
+        if (this.collectionClass != null)
+            try {
+                if (coll == null) {
+                    return this.collectionClass.newInstance();
+                } else {
+                    return this.collectionClass.getConstructor(new Class[] { Collection.class }).newInstance(new Object[] { coll });
+                }
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        else if (this.collectionSpecimen != null) {
+            try {
+                final Collection<V> res = CopyUtils.copy(this.collectionSpecimen);
+                if (coll != null)
+                    res.addAll(coll);
+                return res;
+            } catch (Exception e) {
+                throw ExceptionUtils.createExn(IllegalStateException.class, "clone() failed", e);
+            }
+        } else
+            return super.createCollection(coll);
+    }
+
+    /**
+     * Fusionne la MultiMap avec celle-ci. C'est à dire rajoute les valeurs de mm à la suite des
+     * valeurs de cette map (contrairement à putAll(Map) qui ajoute les valeurs de mm en tant que
+     * valeur scalaire et non en tant que collection).
+     * 
+     * @param mm la MultiMap à fusionner.
+     */
+    public void merge(MultiMap mm) {
+        // copied from super ctor
+        for (Iterator it = mm.entrySet().iterator(); it.hasNext();) {
+            final Map.Entry entry = (Map.Entry) it.next();
+            Collection<V> coll = (Collection<V>) entry.getValue();
+            Collection newColl = createCollection(coll);
+            this.putAll(entry.getKey(), newColl);
+        }
+    }
+
+    /**
+     * Copies all of the mappings from the specified map to this map. This method is equivalent to
+     * {@link MultiHashMap#MultiHashMap(Map)}. NOTE: cannot use Map<? extends K, ? extends V> since
+     * java complains (MultiHashMap not being generic).
+     * 
+     * @param m mappings to be stored in this map
+     */
+    @Override
+    public void putAll(Map mapToCopy) {
+        if (mapToCopy instanceof MultiMap) {
+            this.merge((MultiMap) mapToCopy);
+        } else {
+            super.putAll(mapToCopy);
+        }
+    }
+
+    public boolean putAll(K key, V... values) {
+        return this.putAll(key, asList(values));
+    }
+
+    // generics : MultiHashMap is not generic but it extends HashMap who does
+    // so just override
+
+    @Override
+    public Set<Map.Entry<K, Collection<V>>> entrySet() {
+        return super.entrySet();
+    }
+
+    @Override
+    public Set<K> keySet() {
+        return super.keySet();
+    }
+
+    @Override
+    public Collection<V> values() {
+        return super.values();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/CollectionUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/CollectionUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/CollectionUtils.java	(revision 28000)
@@ -0,0 +1,80 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.util;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.RandomAccess;
+
+import org.jopendocument.util.cc.ITransformer;
+
+/**
+ * Une classe regroupant des méthodes utilitaires pour les collections.
+ * 
+ * @author ILM Informatique 30 sept. 2004
+ */
+public class CollectionUtils extends org.apache.commons.collections.CollectionUtils {
+
+    /**
+     * Concatene une collection. Cette méthode va appliquer un transformation sur chaque élément
+     * avant d'appeler toString(). join([-1, 3, 0], " ,", doubleTransformer) == "-2, 6, 0"
+     * 
+     * @param <E> type of items
+     * @param c la collection a concaténer.
+     * @param sep le séparateur entre chaque élément.
+     * @param tf la transformation à appliquer à chaque élément.
+     * @return la chaine composée de chacun des éléments séparés par <code>sep</code>.
+     */
+    static public final <E> String join(final Collection<E> c, final String sep, final ITransformer<? super E, ?> tf) {
+        if (c.size() == 0)
+            return "";
+
+        final StringBuffer res = new StringBuffer(c.size() * 4);
+        if (c instanceof RandomAccess && c instanceof List) {
+            final List<E> list = (List<E>) c;
+            final int stop = c.size() - 1;
+            for (int i = 0; i < stop; i++) {
+                res.append(tf.transformChecked(list.get(i)));
+                res.append(sep);
+
+            }
+            res.append(tf.transformChecked(list.get(stop)));
+        } else {
+            final Iterator<E> iter = c.iterator();
+            while (iter.hasNext()) {
+                final E elem = iter.next();
+                res.append(tf.transformChecked(elem));
+                if (iter.hasNext())
+                    res.append(sep);
+            }
+        }
+        return res.toString();
+    }
+
+    /**
+     * Concatene une collection en appelant simplement toString() sur chaque élément.
+     * 
+     * @param <T> type of collection
+     * @param c la collection a concaténer.
+     * @param sep le séparateur entre chaque élément.
+     * @return la chaine composée de chacun des éléments séparés par <code>sep</code>.
+     * @see #join(Collection, String, ITransformer)
+     */
+    static public <T> String join(Collection<T> c, String sep) {
+        return join(c, sep, org.jopendocument.util.cc.Transformer.<T> nopTransformer());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/CopyUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/CopyUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/CopyUtils.java	(revision 28000)
@@ -0,0 +1,57 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.util;
+
+import java.lang.reflect.Method;
+
+public final class CopyUtils {
+
+    /**
+     * Copy the passed object. First tries to clone() it, otherwise tries with a copy constructor.
+     * 
+     * @param <E> the type of object to be copied.
+     * @param object the object to be copied, can be <code>null</code>.
+     * @return a copy of <code>object</code>, or <code>null</code> if object was
+     *         <code>null</code>.
+     * @throws IllegalStateException if the object can't be copied.
+     */
+    @SuppressWarnings("unchecked")
+    public static final <E> E copy(E object) {
+        if (object == null)
+            return null;
+
+        if (object instanceof Cloneable) {
+            final Method m;
+            try {
+                m = object.getClass().getMethod("clone");
+            } catch (NoSuchMethodException e) {
+                throw ExceptionUtils.createExn(IllegalStateException.class, "Cloneable w/o clone()", e);
+            }
+            try {
+                return (E) m.invoke(object);
+            } catch (Exception e) {
+                throw ExceptionUtils.createExn(IllegalStateException.class, "clone() failed", e);
+            }
+        } else {
+            try {
+                return (E) object.getClass().getConstructor(new Class[] { object.getClass() }).newInstance(new Object[] { object });
+            } catch (Exception e) {
+                throw ExceptionUtils.createExn(IllegalStateException.class, "Copy constructor failed", e);
+            }
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/ExceptionUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/ExceptionUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/ExceptionUtils.java	(revision 28000)
@@ -0,0 +1,51 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.util;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Utilitaires pour les exceptions.
+ * 
+ * @author Sylvain CUAZ 25 nov. 2004
+ */
+public class ExceptionUtils {
+    /** Static only. */
+    private ExceptionUtils() {
+        super();
+    }
+
+    /**
+     * Crée une exception avec message et cause.
+     * 
+     * @param <T> le type d'exception à créer.
+     * @param exnClass la classe de l'exception à créer, eg IOException.class.
+     * @param msg le message.
+     * @param cause la cause.
+     * @return une exception initialisée.
+     */
+    static public <T extends Exception> T createExn(Class<T> exnClass, String msg, Throwable cause) {
+        T instance = null;
+        try {
+            Constructor<T> ctor = exnClass.getConstructor(new Class[] { String.class });
+            instance = ctor.newInstance(new Object[] { msg });
+        } catch (Exception exn) {
+            throw new IllegalArgumentException(exnClass + " has no working String constructor");
+        }
+        instance.initCause(cause);
+        return instance;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/FileUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/FileUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/FileUtils.java	(revision 28000)
@@ -0,0 +1,64 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jopendocument.util.StringUtils.Escaper;
+
+public final class FileUtils {
+
+    private FileUtils() {
+        // all static
+    }
+
+    // **io
+
+    private static final Map<String, String> ext2mime;
+    static {
+        ext2mime = new HashMap<String, String>();
+        ext2mime.put(".xml", "text/xml");
+        ext2mime.put(".jpg", "image/jpeg");
+        ext2mime.put(".png", "image/png");
+        ext2mime.put(".tiff", "image/tiff");
+    }
+
+    /**
+     * Try to guess the media type of the passed file name (see <a
+     * href="http://www.iana.org/assignments/media-types">iana</a>).
+     * 
+     * @param fname a file name.
+     * @return its mime type.
+     */
+    public static final String findMimeType(String fname) {
+        for (final Map.Entry<String, String> e : ext2mime.entrySet()) {
+            if (fname.toLowerCase().endsWith(e.getKey()))
+                return e.getValue();
+        }
+        return null;
+    }
+
+    /**
+     * An escaper suitable for producing valid filenames.
+     */
+    public static final Escaper FILENAME_ESCAPER = new StringUtils.Escaper('\'', 'Q');
+    static {
+        // from windows explorer
+        FILENAME_ESCAPER.add('"', 'D').add(':', 'C').add('/', 'S').add('\\', 'A');
+        FILENAME_ESCAPER.add('<', 'L').add('>', 'G').add('*', 'R').add('|', 'P').add('?', 'M');
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/FormatGroup.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/FormatGroup.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/FormatGroup.java	(revision 28000)
@@ -0,0 +1,91 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.util;
+
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.ParsePosition;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A list of related formats.
+ * 
+ * @author Sylvain CUAZ
+ */
+@SuppressWarnings("serial")
+public class FormatGroup extends Format {
+
+    private final List<? extends Format> formats;
+    private int formatIndex;
+
+    public FormatGroup(Format... formats) {
+        this(Arrays.asList(formats));
+    }
+
+    /**
+     * Creates a group, which will try to parse with the given formats. format() is done with the
+     * first format.
+     * 
+     * @param formats a List of Format.
+     * @throws IllegalArgumentException if formats is empty.
+     */
+    public FormatGroup(final List<? extends Format> formats) {
+        if (formats.size() == 0)
+            throw new IllegalArgumentException("formats must not be empty");
+        this.formats = formats;
+        this.formatIndex = 0;
+    }
+
+    @Override
+    public StringBuffer format(Object newVal, StringBuffer toAppendTo, FieldPosition pos) {
+        return this.formats.get(this.formatIndex).format(newVal, toAppendTo, pos);
+    }
+
+    @Override
+    public Object parseObject(String s, ParsePosition pos) {
+        if (pos.getErrorIndex() >= 0)
+            throw new IllegalArgumentException(pos + " has en error at " + pos.getErrorIndex());
+
+        boolean success = false;
+        Object tmpRes = null;
+        final ParsePosition tmpPos = new ParsePosition(pos.getIndex());
+        final Iterator<? extends Format> iter = this.formats.iterator();
+        while (iter.hasNext() && !success) {
+            final Format f = iter.next();
+            mutateTo(tmpPos, pos);
+            tmpRes = f.parseObject(s, tmpPos);
+            success = tmpPos.getIndex() != pos.getIndex() && tmpPos.getErrorIndex() < 0;
+        }
+
+        final Object res;
+        if (!success) {
+            // fail with the same as format()
+            res = this.formats.get(this.formatIndex).parseObject(s, pos);
+        } else {
+            res = tmpRes;
+            mutateTo(pos, tmpPos);
+        }
+
+        return res;
+    }
+
+    private void mutateTo(ParsePosition tmpPos, ParsePosition pos) {
+        tmpPos.setIndex(pos.getIndex());
+        tmpPos.setErrorIndex(pos.getErrorIndex());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/StringUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/StringUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/StringUtils.java	(revision 28000)
@@ -0,0 +1,77 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+/*
+ * Créé le 3 mars 2005
+ */
+package org.jopendocument.util;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author Sylvain CUAZ
+ */
+public class StringUtils {
+
+    public static final class Escaper {
+
+        // eg '
+        private final char esc;
+
+        // eg { '=> S, " => D}
+        private final Map<Character, Character> substitution;
+        private final Map<Character, Character> inv;
+
+        /**
+         * A new escaper that will have <code>esc</code> as escape character.
+         * 
+         * @param esc the escape character, eg '
+         * @param name the character that will be appended to <code>esc</code>, eg with S all
+         *        occurrences of ' will be replaced by 'S
+         */
+        public Escaper(char esc, char name) {
+            super();
+            this.esc = esc;
+            this.substitution = new LinkedHashMap<Character, Character>();
+            this.inv = new HashMap<Character, Character>();
+            this.add(esc, name);
+        }
+
+        public Escaper add(char toRemove, char escapedName) {
+            if (this.inv.containsKey(escapedName))
+                throw new IllegalArgumentException(escapedName + " already replaces " + this.inv.get(escapedName));
+            this.substitution.put(toRemove, escapedName);
+            this.inv.put(escapedName, toRemove);
+            return this;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof Escaper) {
+                final Escaper o = (Escaper) obj;
+                return this.esc == o.esc && this.substitution.equals(o.substitution);
+            } else
+                return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return this.esc + this.substitution.hashCode();
+        }
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/Tuple2.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/Tuple2.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/Tuple2.java	(revision 28000)
@@ -0,0 +1,75 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.util;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A simple class to hold 2 values in a type-safe manner.
+ * 
+ * @author Sylvain
+ * 
+ * @param <A> type of first value.
+ * @param <B> type of second value.
+ */
+public class Tuple2<A, B> {
+
+    // just to make the code shorter
+    public static final <A, B> Tuple2<A, B> create(A a, B b) {
+        return new Tuple2<A, B>(a, b);
+    }
+
+    private final A a;
+    private final B b;
+
+    public Tuple2(A a, B b) {
+        super();
+        this.a = a;
+        this.b = b;
+    }
+
+    public final A get0() {
+        return this.a;
+    }
+
+    public final B get1() {
+        return this.b;
+    }
+
+    public List<Object> asList() {
+        return Arrays.asList(get0(), get1());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof Tuple2) {
+            final Tuple2<?, ?> o = (Tuple2<?, ?>) obj;
+            return this.asList().equals(o.asList());
+        } else
+            return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return this.asList().hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + " " + this.asList();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/XMLDateFormat.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/XMLDateFormat.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/XMLDateFormat.java	(revision 28000)
@@ -0,0 +1,72 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.util;
+
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.ParsePosition;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+/**
+ * Format a {@link Date} according to <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">W3C XML
+ * Schema 1.0 Part 2, Section 3.2.7-14</a>.
+ * 
+ * @author Sylvain CUAZ
+ * @see XMLGregorianCalendar
+ */
+@SuppressWarnings("serial")
+public class XMLDateFormat extends Format {
+
+    private final static DatatypeFactory factory;
+    static {
+        try {
+            factory = DatatypeFactory.newInstance();
+        } catch (DatatypeConfigurationException e) {
+            // shouldn't happen since an implementation is provided with the jre
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @Override
+    public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
+        final GregorianCalendar cal;
+        if (obj instanceof GregorianCalendar)
+            cal = (GregorianCalendar) obj;
+        else {
+            cal = new GregorianCalendar();
+            cal.setTime((Date) obj);
+        }
+        return toAppendTo.append(factory.newXMLGregorianCalendar(cal).toXMLFormat());
+    }
+
+    @Override
+    public Date parseObject(String source, ParsePosition pos) {
+        try {
+            final XMLGregorianCalendar res = factory.newXMLGregorianCalendar(source.substring(pos.getIndex()));
+            pos.setIndex(source.length());
+            return res.toGregorianCalendar().getTime();
+        } catch (Exception e) {
+            e.printStackTrace();
+            pos.setErrorIndex(pos.getIndex());
+            return null;
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/cc/ITransformer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/cc/ITransformer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/cc/ITransformer.java	(revision 28000)
@@ -0,0 +1,22 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.util.cc;
+
+public interface ITransformer<E, T> {
+
+    public abstract T transformChecked(E input);
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/cc/ITransformerWrapper.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/cc/ITransformerWrapper.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/cc/ITransformerWrapper.java	(revision 28000)
@@ -0,0 +1,33 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.util.cc;
+
+public class ITransformerWrapper<E, T> extends Transformer<E, T> {
+
+    private final org.apache.commons.collections.Transformer transf;
+
+    public ITransformerWrapper(final org.apache.commons.collections.Transformer transf) {
+        super();
+        this.transf = transf;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public T transformChecked(E input) {
+        return (T) this.transf.transform(input);
+    }
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/cc/Transformer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/cc/Transformer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/cc/Transformer.java	(revision 28000)
@@ -0,0 +1,32 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ * 
+ * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
+ * 
+ * The contents of this file are subject to the terms of the GNU
+ * General Public License Version 3 only ("GPL").  
+ * You may not use this file except in compliance with the License. 
+ * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
+ * See the License for the specific language governing permissions and limitations under the License.
+ * 
+ * When distributing the software, include this License Header Notice in each file.
+ * 
+ */
+
+package org.jopendocument.util.cc;
+
+import org.apache.commons.collections.TransformerUtils;
+
+public abstract class Transformer<E, T> implements ITransformer<E, T>, org.apache.commons.collections.Transformer {
+
+    public static final <N> ITransformer<N, N> nopTransformer() {
+        return new ITransformerWrapper<N, N>(TransformerUtils.nopTransformer());
+    }
+
+    @SuppressWarnings("unchecked")
+    public final Object transform(Object input) {
+        return this.transformChecked((E) input);
+    }
+
+    public abstract T transformChecked(E input);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/jopendocument/util/package.html	(revision 28000)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+A grab bag of utility classes.
+
+</body>
+</html>
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/Extension.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/Extension.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/Extension.java	(revision 28000)
@@ -0,0 +1,32 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.annotation;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+
+/**
+ * An annotation for classes or method that are <A HREF="http://geoapi.sourceforge.net">GeoAPI</A>
+ * extension. This annotation is mutually exclusive with {@link UML}.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/annotation/Extension.java $
+ */
+@Documented
+@Retention(SOURCE)
+@Target({TYPE, FIELD, METHOD})
+public @interface Extension {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/Obligation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/Obligation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/Obligation.java	(revision 28000)
@@ -0,0 +1,45 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.annotation;
+
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Obligation of the element or entity. The enum values declared here are an exact copy of
+ * the code list elements declared in the {@link org.opengis.metadata.Obligation} code list
+ * from the metadata package.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/annotation/Obligation.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="MD_ObligationCode", specification=ISO_19115)
+public enum Obligation {
+    /**
+     * Element is required when a specific condition is met.
+     */
+    ///@UML(identifier="conditional", obligation=CONDITIONAL, specification=ISO_19115)
+    CONDITIONAL,
+
+    /**
+     * Element is not required.
+     */
+    @UML(identifier="optional", obligation=CONDITIONAL, specification=ISO_19115)
+    OPTIONAL,
+
+    /**
+     * Element is always required.
+     */
+    @UML(identifier="mandatory", obligation=CONDITIONAL, specification=ISO_19115)
+    MANDATORY
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/Specification.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/Specification.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/Specification.java	(revision 28000)
@@ -0,0 +1,78 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.annotation;
+
+
+/**
+ * The specifications from which an interface, method or code list was derived.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/annotation/Specification.java $
+ */
+public enum Specification {
+    /**
+     * ISO 19103, Geographic information - Conceptual schema language.
+     * This is the specification for some interfaces in package {@link org.opengis.util}.
+     */
+    ISO_19103,
+
+    /**
+     * ISO 19107, Feature Geometry (Topic 1).
+     * This is the specification for package {@link org.opengis.geometry} and sub-packages.
+     *
+     * @see <A HREF="http://www.opengeospatial.org/standards/as">Buy from ISO</A>
+     */
+    ISO_19107,
+
+    /**
+     * ISO 19111, Spatial Referencing by Coordinates (Topic 2).
+     * This is the specification for package {@link org.opengis.referencing} and sub-packages.
+     *
+     * @see #OGC_01009
+     * @see <A HREF="http://www.opengeospatial.org/standards/as#04-046r3">Download from OGC</A>
+     */
+    ISO_19111,
+
+    /**
+     * ISO 19115, Metadata (Topic 11).
+     * This is the specification for package {@link org.opengis.metadata} and sub-packages.
+     *
+     * @see <A HREF="http://www.opengeospatial.org/standards/as#01-111">Buy from ISO</A>
+     */
+    ISO_19115,
+
+    /**
+     * Coordinate Transformation Services implementation specification.
+     * This is the specification used as a complement of {@linkplain #ISO_19111 ISO 19111}
+     * when an aspect was not defined in the ISO specification.
+     *
+     * @see #ISO_19111
+     * @see <A HREF="http://www.opengeospatial.org/standards/ct">Download from OGC</A>
+     */
+    OGC_01009,
+
+    /**
+     * Filter encoding implementation specification.
+     * This is the specification for package {@link org.opengis.filter} and sub-packages.
+     *
+     * @see <A HREF="http://www.opengeospatial.org/standards/filter">Download from OGC</A>
+     *
+     * @todo Need to be updated to {@code OGC 04-095}.
+     */
+    OGC_02059,
+
+    /**
+     * Specification not yet determined. This is a temporary enumeration
+     * for the processing of API submitted by some contributors.
+     */
+    UNSPECIFIED
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/UML.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/UML.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/UML.java	(revision 28000)
@@ -0,0 +1,56 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.annotation;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+
+/**
+ * An annotation mapping each interface, methods or fields to
+ * the UML identifier where they come from.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/annotation/UML.java $
+ */
+@Documented
+@Retention(RUNTIME)
+@Target({TYPE, FIELD, METHOD})
+public @interface UML {
+    /**
+     * The UML identifier for the annotated interface, method or code list element.
+     * Scripts can use this identifier in order to maps a GeoAPI method to the UML
+     * entity where it come from.
+     *
+     * @return The UML identifier used in the standard.
+     */
+    String identifier();
+
+    /**
+     * The obligation declared in the UML. This metadata can be queried in order to
+     * determine if a null value is allowed for the annotated method or not. If the
+     * obligation is {@link Obligation#MANDATORY}, then null value are not allowed.
+     *
+     * @return The obligation declared in the standard.
+     */
+    Obligation obligation() default Obligation.MANDATORY;
+
+    /**
+     * The specification where this UML come from.
+     *
+     * @return The originating specification.
+     */
+    Specification specification();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/XmlElement.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/XmlElement.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/annotation/XmlElement.java	(revision 28000)
@@ -0,0 +1,43 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.annotation;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+
+/**
+ * Maps an interface or a method to the XML type, element or attribute.
+ * Interfaces usually map to XML types, while methods map to XML element
+ * or attribute. It is not the purpose of this annotation to differentiate
+ * types from attributes, since this distinction can already be inferred from
+ * Java reflection. This annotation, completed with reflection if needed, should
+ * only provides enough information for finding the corresponding XML element in
+ * the {@linkplain XmlSchema schema}.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/annotation/XmlElement.java $
+ */
+@Documented
+@Target({TYPE,METHOD,FIELD})
+@Retention(RUNTIME)
+public @interface XmlElement {
+    /**
+     * The name of the element in the XML schema.
+     *
+     * @return The XML element name.
+     */
+    String value();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/Attribute.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/Attribute.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/Attribute.java	(revision 28000)
@@ -0,0 +1,103 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature;
+
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.filter.identity.Identifier;
+
+/**
+ * An extension of Property for an attribute, or data.
+ * <p>
+ * The notion of an "attribute" is similar to that of an attribute in UML.
+ * </p>
+ * <p>
+ * This interface is capable of modelling "primitive data", things like strings,
+ * numerics, dates, etc... However for "complex data" (that is non-primitive
+ * data types which are made up other primitive data types), a specific
+ * sub-interface is used, see {@link ComplexAttribute}.
+ * </p>
+ * <p>
+ * An analogy for an attribute is a "field" in a java object. A field also
+ * brings together a field name, value and type.
+ * </p>
+ *
+ * <p>
+ * <h3>Identifiable</h3>
+ *
+ * When an attribute is identifiable the {@link #getID()} method returns a
+ * unique identifier for the attribute. The type of the attribute is used to
+ * determine identifiability.
+ *
+ * <pre>
+ * Attribute attribute = ...;
+ * if ( attribute.getType().isIdentified() ) {
+ *   String id = attribute.getID();
+ * }
+ * </pre>
+ * </p>
+ * <h3>Validation</h3>
+ * 
+ * An attribute may hold any value at runtime; checking that the value meets the constraints
+ * supplied by the AttributeType is the work of the validate() method.
+ * 
+ * @see Property
+ *
+ * @author Jody Garnett (Refractions Research)
+ * @author Justin Deoliveira (The Open Planning Project)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/Attribute.java $
+ */
+public interface Attribute extends Property {
+
+    /**
+     * Override of {@link Property#getDescriptor()} which type narrows to
+     * {@link AttributeDescriptor}.
+     *
+     * @see Property#getDescriptor()
+     * @return The attribute descriptor, may be null if this is a top level type
+     */
+    AttributeDescriptor getDescriptor();
+
+    /**
+     * Override of {@link Property#getType()} which type narrows to
+     * {@link AttributeType}.
+     *
+     * @see Property#getType()
+     * @return The attribute type.
+     */
+    AttributeType getType();
+
+    /**
+     * Unique Identifier for the attribute.
+     * <p>
+     * This value is non-null in the case that
+     * <code>getType().isIdentifiable()</code> is <code>true</code>.
+     * </p>
+     *
+     * @return A unique identifier for the attribute, or <code>null</code> if
+     *         the attribute is non-identifiable.
+     */
+    Identifier getIdentifier();
+    
+    /**
+     * Check the attribute value against the constraints provided by the AttributeDescriptor.
+     * <p>
+     * Please note this method checks the value only - it should have the correct java binding,
+     * it should only be null if isNillable is true; and if a value is provided it should
+     * satisfy all of the restrictions provided.
+     * <p>
+     * To check the the number of times an attribute is used (minOccurs and maxOccurs) please
+     * use ComplexAttribute.validate().
+     * 
+     * @thorws IllegalAttributeException If value fails validation
+     */
+    void validate() throws IllegalAttributeException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/ComplexAttribute.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/ComplexAttribute.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/ComplexAttribute.java	(revision 28000)
@@ -0,0 +1,182 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature;
+
+import java.util.Collection;
+
+import org.opengis.feature.type.ComplexType;
+import org.opengis.feature.type.Name;
+import org.opengis.filter.expression.Expression;
+
+/**
+ * An instance of {@link ComplexType} which is composed of other properties.
+ * <p>
+ * A complex attribute is a container for other properties (attributes +
+ * associations). The value of a complex attribute is a collection of those
+ * contained properties.
+ * </p>
+ * <br/>
+ * <p>
+ * <h3>Property Access</h3>
+ * The {@link #getValue()} method returns a collection of the properties
+ * contained by the complex attribute.
+ *
+ * <pre>
+ *    ComplexAttribute attribute = ...;
+ *
+ *    //loop through all the properties
+ *    for (Property p : attribute.getValue(); ) {
+ *        // do something with the property
+ *    }
+ * </pre>
+ *
+ * <br>
+ * Contained properties can also be fetched by name by {@link Name} with the
+ * {@link #getProperties(Name)} and {@link #getProperties(String)} methods.
+ *
+ * <pre>
+ *    ComplexAttribute attribute = ...;
+ *
+ *    //loop through all the &quot;foo&quot; attributes
+ *    for ( Property p : attribute.getProperties( &quot;foo&quot; ) ) {
+ *        p.getName().getLocalPart() == &quot;foo&quot;;
+ *    }
+ * </pre>
+ *
+ * <br>
+ * Often it is known in advance that a single instance of a particular property
+ * exists. When this is the case the {@link #getProperty(Name)} and
+ * {@link #getProperty(String)} methods can be used to get direct access to the
+ * property.
+ *
+ * <pre>
+ *    ComplexAttribute attribute = ...;
+ *
+ *    //get the single foo attribute
+ *    Property foo = attribute.getProperty( &quot;foo&quot; );
+ * </pre>
+ *
+ * </p>
+ * <br>
+ * <p>
+ * <h3>Xpath and Query Language Access</h3>
+ * The above property access methods perform an exact match on property name
+ * against the name passed in. However, often it is necesary to access
+ * properties via a query language such as xpath.
+ * </p>
+ * <br>
+ * <p>
+ * For instance.the expression <code>"//foo"</code> should return all the
+ * properties named "foo". Or the expression <code>"foo/bar"</code> should
+ * return the "bar" property nested inside of the "foo" property. In these
+ * cases, an {@link Expression} must be used:
+ *
+ * <pre>
+ *   ComplexAttribute attribute = ...;
+ *
+ *   //get the 'foo/bar' property
+ *   FilterFactory factory = ...;
+ *   PropertyName xpath = factory.property( &quot;foo/bar&quot; );
+ *   Property bar = xpath.evaluate( attribute );
+ * </pre>
+ *
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research
+ * @author Gabriel Roldan, Axios Engineering
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/ComplexAttribute.java $
+ */
+public interface ComplexAttribute extends Attribute {
+
+    /**
+     * Override of {@link Attribute#getType()} which type narrows to
+     * {@link ComplexType}.
+     *
+     * @see Attribute#getType()
+     */
+    ComplexType getType();
+
+    /**
+     * Override of {@link Property#getValue()} which returns the collection of
+     * {@link Property} which make up the value of the complex attribute.
+     */
+    Collection<? extends Property> getValue();
+
+    /**
+     * Returns single property of the complex attribute which matches the
+     * specified name.
+     * <p>
+     * Note: This method is a convenience and care should be taken when calling
+     * it if more then a single property matches <tt>name</tt>. In such a
+     * case the first encountered property in which {@link Property#getName()}
+     * is equal to <tt>name</tt> is returned, and no order is guaranteed.
+     * </p>
+     * <p>
+     * This method is a safe convenience for:
+     *
+     * <code>getProperties(name).iterator().next()</code>.
+     *
+     * In the event that no property matches the specified name
+     * <code>null</code> is returned.
+     * </p>
+     *
+     * @param name
+     *            The name of the property to return.
+     *
+     * @return The property matching the specified name, or <code>null</code>.
+     */
+    Property getProperty(Name name);
+
+    /**
+     * Complete collection of properties.
+     * <p>
+     * This method is a convenience method for calling (Collection<Property>) getValue().
+     * </p>
+     * @return The complete collection of properties.
+     */
+    Collection<Property> getProperties();
+
+    /**
+     * Returns single property of the complex attribute which matches the
+     * specified name.
+     * <p>
+     * This method is a convenience for {@link #getProperty(Name)} in which
+     * {@link Name#getNamespaceURI()} is <code>null</code>.
+     * </p>
+     * <p>
+     * Note: This method is a convenience and care should be taken when calling
+     * it if more then a single property matches <tt>name</tt>. In such a
+     * case the first encountered property in which {@link Property#getName()}
+     * is matches <tt>name</tt> is returned, and no order is guaranteed.
+     * </p>
+     * <p>
+     * Note: Special care should be taken when using this method in the case
+     * that two properties with the same local name but different namespace uri
+     * exist. For this reason using {@link #getProperties(Name)} is safer.
+     * </p>
+     *
+     * @param name
+     *            The local name of the property to return.
+     *
+     * @return The property matching the specified name, or <code>null</code>.
+     */
+    Property getProperty(String name);
+    
+    /**
+     * Check the properties against the constraints provided by their AttributeDescriptors.
+     * <p>
+     * Please note this method checks minOccurs and maxOccurs information; and calls each Attribute.validate
+     * on each entry in turn (in order to check isNillable, binding and restrictions).
+     * @throws IllegalAttributeException If any attribute fails validation
+     */
+    void validate() throws IllegalAttributeException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/Feature.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/Feature.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/Feature.java	(revision 28000)
@@ -0,0 +1,94 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature;
+
+import org.opengis.feature.type.FeatureType;
+import org.opengis.filter.identity.FeatureId;
+import org.opengis.geometry.BoundingBox;
+
+/**
+ * An instance of {@link FeatureType} representing a geographic feature composed of geometric
+ * and non-geometric properties. 
+ * <p>
+ * Beyond being a complex attribute, a feature contains the following additional information:
+ * <ul>
+ * <li>A default geometry. To be used when drawing when nothing more
+ *     specific has been provided.
+ * <li>The bounds of all the geometric attributes of the feature
+ * </ul>
+ * </p>
+ * @author Jody Garnett (Refractions Research)
+ * @author Justin Deoliveira (The Open Planning Project)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/Feature.java $
+ * @version GeoAPI 2.2
+ */
+public interface Feature extends ComplexAttribute {
+
+    /**
+     * Override and type narrow to FeatureType.
+     * @return The feature type
+     */
+    FeatureType getType();
+
+    /**
+     * A unique identifier for the feature.
+     * <p>
+     * <code>getType().isIdentifiable()</code> must return <code>true</code>
+     * so this value must not return <code>null</code>.
+     * </p>
+     * <p>
+     * Generation of the identifier is dependent on the underlying data storage
+     * medium. Often this identifier is not persistent. Mediums such shapefiles
+     * and database tables have "keys" built in which map naturally to
+     * persistent feature identifiers. But other mediums do not have such keys
+     * and may have to generate feature identifiers "on-the-fly". This means
+     * that client code being able to depend on this value as a persistent
+     * entity is dependent on which storage medium or data source is being used.
+     * </p>
+     *
+     * @return The feature identifier, never <code>null</code>.
+     */
+    FeatureId getIdentifier();
+
+    /**
+     * The bounds of this Feature, if available.
+     * <p>
+     * This value is derived from any geometric attributes that the feature is
+     * composed of.
+     * </p>
+     * <p>
+     * In the case that the feature has no geometric attributes this method
+     * should return an empty bounds, ie, <code>bounds.isEmpty() == true</code>.
+     * This method should never return <code>null</code>.
+     * </p>
+     * <p>
+     * The coordinate reference system of the returned bounds is derived from
+     * the geometric attributes which were used to compute the bounds. In the
+     * event that the feature contains multiple geometric attributes which have
+     * different crs's, the one defined by {@link #getGeometryDescriptor()} should
+     * take precedence and the others should be reprojected accordingly.
+     * </p>
+     *
+     * @return the feature bounds, possibly empty.
+     */
+    BoundingBox getBounds();
+
+    /**
+     * The default geometric attribute of the feature.
+     * <p>
+     * This method returns <code>null</code> in the case where no such
+     * attribute exists.
+     * </p>
+     *
+     * @return The default geometry attribute, or <code>null</code>.
+     */
+    GeometryAttribute getDefaultGeometryProperty();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/FeatureFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/FeatureFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/FeatureFactory.java	(revision 28000)
@@ -0,0 +1,41 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature;
+
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+/**
+ * Factory for creation of attributes, associations, and features.
+ * <p>
+ * Implementations of this interface should not contain any "special logic" for
+ * creating attributes and features. Method implementations should be straight
+ * through calls to a constructor.
+ * </p>
+ *
+ * @author Gabriel Roldan (Axios Engineering)
+ * @author Justin Deoliveira (The Open Planning Project)
+ * @since 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/FeatureFactory.java $
+ */
+public interface FeatureFactory {
+
+    /**
+     * Create a SimpleFeature from an array of objects.
+     * <p>
+     * Please note that the provided array may be used directly by an implementation.
+     * 
+     * @param array Object array of values; this array may beused directly.
+     * @param type The type of the simple feature.
+     * @param id The id of the feature.
+     */   
+    SimpleFeature createSimpleFeature( Object[] array, SimpleFeatureType type, String id );   
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/FeatureVisitor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/FeatureVisitor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/FeatureVisitor.java	(revision 28000)
@@ -0,0 +1,39 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+
+package org.opengis.feature;
+
+/**
+ * FeatureVisitor interface to allow for container optimised traversal.
+ * <p>
+ * The iterator construct from the Collections api is well understood and
+ * loved, but breaks down for working with large GIS data volumes. By using a
+ * visitor we allow the implementor of a Feature Collection to make use of
+ * additional resources (such as multiple processors or tiled data)
+ * concurrently.
+ * </p>
+ * This interface is most often used for calculations and data
+ * transformations and an implementations may intercept known visitors
+ * (such as "bounds" or reprojection) and engage an alternate work flow.
+ * </p>
+ * @author Cory Horner (Refractions Research, Inc)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/FeatureVisitor.java $
+ */
+public interface FeatureVisitor {
+    /**
+     * Visit the provided feature.
+     * <p>
+     * Please consult the documentation for the FeatureCollection you are visiting
+     * to learn more - the provided feature may be invalid, or read only.
+     * @param feature
+     */
+    void visit(Feature feature);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/GeometryAttribute.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/GeometryAttribute.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/GeometryAttribute.java	(revision 28000)
@@ -0,0 +1,65 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature;
+
+import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.feature.type.GeometryType;
+import org.opengis.geometry.BoundingBox;
+
+/**
+ * An attribute which has a geometric value.
+ * <p>
+ * The type of the value of the attribute is an arbitrary object and is
+ * implementation dependent. Implementations of this interface may wish to type
+ * narrow {@link Property#getValue()} to be specific about the type geometry.
+ * For instance to return explicitly a JTS geometry.
+ * </p>
+ * <p>
+ * Past a regular attribute, GeometryAttribute provides a method for obtaining
+ * the bounds of the underlying geometry, {@link #getBounds()}. The
+ * {@link #setBounds(BoundingBox)} method is used to explicitly set the bounds
+ * which can be useful in situations where the data source stores the bounds
+ * explicitly along with the geometry.
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/GeometryAttribute.java $
+ */
+public interface GeometryAttribute extends Attribute {
+
+    /**
+     * Override and type narrow to GeometryType.
+     */
+    GeometryType getType();
+
+    /**
+     * Override and type narrow to GeometryDescriptor.
+     * @return The geometry descriptor, may be null if this is a top-level value
+     */
+    GeometryDescriptor getDescriptor();
+
+    /**
+     * The bounds of the attribute.
+     * <p>
+     * This value should be derived unless explicitly set via
+     * {@link #setBounds(BoundingBox)}.
+     * </p>
+     * <p>
+     * In the case that the underlying geometry is <code>null</code>, this
+     * method should return an empty bounds as opposed to returning
+     * <code>null</code>.
+     * </p>
+     *
+     * @return The bounds of the underlying geometry, possibly empty.
+     */
+    BoundingBox getBounds();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/IllegalAttributeException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/IllegalAttributeException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/IllegalAttributeException.java	(revision 28000)
@@ -0,0 +1,68 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2008 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature;
+
+import org.opengis.feature.type.AttributeDescriptor;
+
+/**
+ * Indicates a validation check has failed; the provided descriptor and value are available via this
+ * exception.
+ * 
+ * @author Jody Garnett (Refractions Research, Inc.)
+ * @since GeoAPI 2.2
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/IllegalAttributeException.java $
+ */
+public class IllegalAttributeException extends IllegalArgumentException {
+    private static final long serialVersionUID = 3373066465585246605L;
+
+    /**
+     * AttributeDescriptor being used to validate against.
+     */
+    final private AttributeDescriptor descriptor;
+
+    /**
+     * Object that failed validation.
+     */
+    final private Object value;
+
+    public IllegalAttributeException(AttributeDescriptor descriptor, Object value) {
+        super();
+        this.descriptor = descriptor;
+        this.value = value;
+    }
+
+    public IllegalAttributeException(AttributeDescriptor descriptor, Object value, String message) {
+        super(message);
+        this.descriptor = descriptor;
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        String s = getClass().getName();
+        String message = getLocalizedMessage();
+        
+        StringBuffer buf = new StringBuffer();
+        buf.append(s);
+        if( message != null){
+            buf.append(":");
+            buf.append(message);
+        }
+        if( descriptor != null ){
+            buf.append(":");
+            buf.append( descriptor.getName() );
+        }
+        buf.append(" value:");
+        buf.append( value );
+        
+        return buf.toString();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/Property.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/Property.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/Property.java	(revision 28000)
@@ -0,0 +1,171 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature;
+
+import java.util.Map;
+
+import org.opengis.feature.type.Name;
+import org.opengis.feature.type.PropertyDescriptor;
+import org.opengis.feature.type.PropertyType;
+
+/**
+ * An instance of a {@link PropertyType} relised as a {@link Attribute} or {@link Association}.
+ * <p>
+ * A property is a wrapper around an arbitrary object or value. The value is
+ * available via the {@link #getValue()} and {@link #setValue(Object)}.
+ *
+ * <pre>
+ *  Property property = ...;
+ *
+ *  //set the value
+ *  property.setValue( &quot;foo&quot; );
+ *
+ *  //get the value
+ *  String value = (String) property.getValue();
+ * </pre>
+ *
+ * </p>
+ * <p>
+ * Every property has a type. This {@link PropertyType} defines information
+ * about the property. This includes which java class the value of the property
+ * is an instance of, any restrictions on the value, etc... 
+ * The type is available via the {@link #getType()} method.
+ *
+ * <pre>
+ *   Property property = ...;
+ *
+ *   //get the type
+ *   PropertyType type = property.getType();
+ *
+ *   //get the class of the value
+ *   Class&lt;String&gt; valueClass = (Class&lt;String&gt;)type.getBinding();
+ *
+ * </pre>
+ *
+ * </p>
+ * <p>
+ * A property can often be part of another entity such as a {@link Feature} or {@link ComplexAttribute}.
+ * When this is the case, the relationship between the property and its "container" is described by
+ * a {@link PropertyDescriptor}.
+ * The descriptor of a property defines things like nilablility, multiplicity,
+ * etc... See the javadoc of {@link PropertyDescriptor} for more details. The
+ * descriptor is available via the {@link #getDescriptor()} method.
+ *
+ * <pre>
+ *   Property property = ...;
+ *
+ *   //get the descriptor
+ *   PropertyDescriptor descriptor = property.getDescriptor()l
+ *
+ *   //is the value allowed to be null?
+ *   descriptor.isNillable();
+ *
+ *   //how many instances of this property are allowed?
+ *   descriptor.getMaxOccurs();
+ * </pre>
+ *
+ * @author Jody Garnett (Refractions Research)
+ * @author Justin Deoliveira (The Open Planning Project)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/Property.java $
+ */
+public interface Property {
+
+    /**
+     * The value or content of the property.
+     * <p>
+     * The class of this object is defined by
+     * <code>getType().getBinding()</code>.
+     * </p>
+     * <p>
+     * This value may be <code>null</code>. In this case
+     * <code>getDescriptor().isNillable()</code> would be <code>true</code>.
+     * </p>
+     *
+     * @return The value of the property.
+     */
+    Object getValue();
+
+    /**
+     * The type of the property.
+     * <p>
+     * The type contains information about the value or content of the property
+     * such as its java class.
+     * </p>
+     * <p>
+     * This value is also available via <code>getDescriptor().getType()</code>.
+     * </p>
+     *
+     * @return The property type.
+     */
+    PropertyType getType();
+
+    /**
+     * The {@link PropertyDscriptor} of the property, null if this is a top-level value.
+     * <p>
+     * The descriptor provides information about the property with respect to
+     * its containing entity (more often then not a {@link Feature} or {@link ComplexAttribute}.
+     * </p>
+     *
+     * @return The property descriptor, null if this is a top-level value.
+     * @see ComplexAttribute
+     */
+    PropertyDescriptor getDescriptor();
+
+    /**
+     * The name of the property with respect to its descriptor.
+     * <p>
+     * This method is convenience for <code>getDescriptor().getName()</code>.
+     * </p>
+     *
+     * @return name of the property.
+     */
+    Name getName();
+
+    /**
+     * Flag indicating if <code>null</code> is an acceptable value for the
+     * property.
+     * <p>
+     * This method is convenience for <code>getDescriptor().isNillable()</code>.
+     * </p>
+     *
+     * @return <code>true</code> if the value of the property is allowed to be
+     *         <code>null</code>, otherwise <code>false</code>.
+     */
+    boolean isNillable();
+
+    /**
+     * A map of "user data" which enables applications to store
+     * "application-specific" information against a property.
+     * <p>
+     * An example of information that may wish to be stored along with an
+     * attribute could be its srs information (in the case of a geometric
+     * attribute ).
+     *
+     * <pre>
+     * <code>
+     *  GeometryAttribute attribute = ...;
+     *
+     *  //set the crs
+     *  CoordinateReferenceSystem crs = CRS.decode(&quot;EPSG:4326&quot;);
+     *  attribute.setCRS( crs );
+     *
+     *  //set the srs
+     *  attribute.getUserData().put( &quot;srs&quot;, &quot;EPSG:4326&quot; );
+     * </code>
+     * </pre>
+     *
+     * </p>
+     *
+     * @return A map of user data.
+     */
+    Map<Object, Object> getUserData();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/simple/SimpleFeature.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/simple/SimpleFeature.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/simple/SimpleFeature.java	(revision 28000)
@@ -0,0 +1,246 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature.simple;
+
+import java.util.List;
+
+import org.opengis.feature.ComplexAttribute;
+import org.opengis.feature.Feature;
+import org.opengis.feature.type.Name;
+
+/**
+ * An instance of {@link SimpleFeature} composed of fixed list values in a known order.
+ * <p>
+ * The definition of a "simple feature" can be summed up as the following:
+ * <ul>
+ *   <li>made up of only non-complex attributes, no associations
+ *   <li>attributes are of multiplicity 1
+ *   <li>attributes are ordered
+ *   <li>attribute names are unqualified (namespaceURI == null)
+ * </ul>
+ * </p>
+ * <p>
+ *  <h3>Attribute Access</h3>
+ *  The order and multiplicity restrictions on simple feature make attribute
+ *  values accessible via an index. For example consider the following shapefile
+ *  entry:
+ *  <pre>
+ *  | GEOMETRY | INT | STRING |
+ *  |POINT(0 0)|  0  | "zero" |
+ *  </pre>
+ *  Accessing attributes via index would look like:
+ *  <pre>
+ *  SimpleFeature feature = ...;
+ *
+ *  Geometry g = (Geometry) feature.getAttribute( 0 );
+ *  Integer i = (Integer) feature.getAttribute( 1 );
+ *  String s = (String) feature.getAttribute( 2 );
+ *  </pre>
+ *  One could also access by name:
+ *  <pre>
+ *  SimpleFeature feature = ...;
+ *
+ *  Geometry g = (Geometry) feature.getAttribute( "GEOMETRY" );
+ *  Integer i = (Integer) feature.getAttribute( "INT" );
+ *  String s = (String) feature.getAttribute( "STRING" );
+ *  </pre>
+ * </p>
+ * <p>
+ * <b>Note:</b> Attribute access via getAttribute() methods returns attribute
+ * values, and not the attributes themselves. For access to the actual attributes
+ * {@link ComplexAttribute#getProperty(String)} can be used.
+ * </p>
+ *
+ * @see SimpleFeatureType
+ *
+ * @author Jody Garnett (Refractions Research)
+ * @author Justin Deoliveira (The Open Planning Project)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/simple/SimpleFeature.java $
+ */
+public interface SimpleFeature extends Feature {
+    /**
+     * Unique Identifier for the SimpleFeature
+     * <p>
+     * This value is non-null and should be the same as getIdentifier().toString().
+     * Please note that an ID may be provided  
+     * </p>
+     *
+     * @return A unique identifier for the attribute, or <code>null</code> if
+     *         the attribute is non-identifiable.
+     */
+	String getID();
+	
+    /**
+     * Override and type narrow to SimpleFeatureType.
+     */
+    SimpleFeatureType getType();
+
+    /**
+     * The type of the feature.
+     * <p>
+     * This method is a synonym for {@link #getType()}.
+     * </p>
+     * @see #getType()
+     */
+    SimpleFeatureType getFeatureType();
+
+    /**
+     * Returns a list of the values of the attributes contained by the feature.
+     * <br>
+     * <p>
+     * This method is a convenience for:
+     * <pre>
+     * List values = new ArrayList();
+     * for ( Property p : getProperties(); ) {
+     *   values.add( p.getValue() );
+     * }
+     *
+     * return values;
+     * </pre>
+     * </p>
+     *
+     * @return List of attribute values for the feature.
+     */
+    List<Object> getAttributes();
+
+    /**
+     * Sets the values of the attributes contained by the feature.
+     * <p>
+     * The <tt>values</tt> must be in the order of the attributes defined by the
+     * feature type.
+     * </p>
+     * <p>
+     * This method is a convenience for:
+     * <pre>
+     * int i = 0;
+     * for ( Property p : getProperties() ) {
+     *   p.setValue( values.get( i++ ) );
+     * }
+     * </pre>
+     * </p>
+     * @param values The attribute values to set.
+     */
+    void setAttributes( List<Object> values );
+
+    /**
+     * Gets an attribute value by name.
+     * <p>
+     * This method is a convenience for:
+     * <pre>
+     * Property p = getProperty( name );
+     * return p.getValue();
+     * </pre>
+     * </p>
+     * @param name The name of the attribute whose value to retrieve.
+     *
+     * @return The attribute value, or <code>null</code> if no such attribute
+     * exists with the specified name.
+     */
+    Object getAttribute( String name );
+
+    /**
+     * Sets an attribute value by name.
+     * <p>
+     * This method is a convenience for:
+     * <pre>
+     * Property p = getProperty( name );
+     * p.setValue(value);
+     * </pre>
+     * </p>
+     * @param name The name of the attribute whose value to set.
+     * @param value The new value of the attribute.
+     */
+    void setAttribute( String name, Object value );
+
+    /**
+     * Gets an attribute value by name.
+     * <p>
+     * This method is a convenience for:
+     * <pre>
+     * Property p = getProperty( name );
+     * return p.getValue();
+     * </pre>
+     * </p>
+     * <p>
+     * Since attribute names in simple features do not have a namespace uri
+     * this method is equivalent to calling <code>getAttribute(name.getLocalPart())</code>.
+     * </p>
+     * @param name The name of the attribute whose value to retrieve.
+     *
+     * @return The attribute value, or <code>null</code> if no such attribute
+     * exists with the specified name.
+     */
+    Object getAttribute( Name name );
+
+    /**
+     * Sets an attribute value by name.
+     * <p>
+     * This method is a convenience for:
+     * <pre>
+     * Property p = getProperty( name );
+     * p.setValue(value);
+     * </pre>
+     * </p>
+     * <p>
+     * Since attribute names in simple features do not have a namespace uri
+     * this method is equivalent to calling <code>setAttribute(name.getLocalPart(), value)</code>.
+     * </p>
+     * @param name The name of the attribute whose value to set.
+     * @param value The new value of the attribute.
+     */
+    void setAttribute( Name name, Object value );
+
+    /**
+     * Gets an attribute value by index.
+     * <p>
+     * This method is a convenience for:
+     * <pre>
+     * Property p = ((List)getProperties()).get( i ) ;
+     * return p.getValue();
+     * </pre>
+     * </p>
+     * @param index The index of the attribute whose value to get.
+     *
+     * @return The attribute value at the specified index.
+     * @throws IndexOutOfBoundsException If the specified index is out of bounds.
+     */
+    Object getAttribute( int index ) throws IndexOutOfBoundsException;
+
+    /**
+     * Sets an attribute value by index.
+     * <p>
+     * This method is a convenience for:
+     * <pre>
+     * Property p = ((List)getProperties()).get( i ) ;
+     * p.setValue(value);
+     * </pre>
+     * </p>
+     * @param index The index of the attribute whose value to set.
+     * @param value The new value of the attribute.
+     *
+     * @throws IndexOutOfBoundsException If the specified index is out of bounds.
+     */
+    void setAttribute( int index, Object value ) throws IndexOutOfBoundsException;
+
+    /**
+     * Returns the value of the default geometry of the feature.
+     * <p>
+     * This method is convenience for:
+     * <pre>
+     * return getDefaultGeometry().getValue();
+     * </pre>
+     * </p>
+     * @return The default geometry, or <code>null</code> if no default geometry
+     * attribute exists.
+     *
+     */
+    Object getDefaultGeometry();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/simple/SimpleFeatureType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/simple/SimpleFeatureType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/simple/SimpleFeatureType.java	(revision 28000)
@@ -0,0 +1,238 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature.simple;
+
+import java.util.List;
+
+import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.FeatureType;
+import org.opengis.feature.type.Name;
+
+/**
+ * The type of a SimpleFeature.
+ * <p>
+ * The definition of a "simple feature" can be summed up as the following:
+ * <ul>
+ * <li>made up of only non-complex attributes, no associations
+ * <li>attributes are of multiplicity 1
+ * <li>attributes are ordered
+ * <li>attribute names are unqualified (namespaceURI == null)
+ * </ul>
+ * </p>
+ * <p>
+ * <h3>Attribute Indexing</h3>
+ * The attributes which compose a simple feature type are ordered. For this
+ * reason attributes are available via a simple index. Given the following type
+ * definition:
+ *
+ * <pre>
+ *   &lt;complexType name=&quot;mySimpleType&quot;/&gt;
+ *     &lt;sequence&gt;
+ *        &lt;element name=&quot;foo&quot; type=&quot;xs:string&quot;/&gt;
+ *        &lt;element name=&quot;bar&quot; type=&quot;xs:integer&quot;/&gt;
+ *     &lt;/sequence&gt;
+ *   &lt;/complexType&gt;
+ * </pre>
+ *
+ * <br>
+ * The attribute descriptor are addressable via index:
+ *
+ * <pre>
+ *   SimpleFeatureType type = ...;
+ *
+ *   AttributeDescriptor foo = type.getAttribute( 0 );
+ *   AttributeDescriptor bar-= type.getAttribute( 1 );
+ * </pre>
+ *
+ * <p>
+ * <h3>Attribute Multiplicity</h3>
+ * With simple feature types, the multiplicity of attributes is always assumed
+ * to be 1, ie, <code>getMinOccurs() == 1</code> and
+ * <code>getMaxOccurs() == 1</code>. A consequence of this is that attributes
+ * from a simple feature always line up 1 to 1 with the descriptors from the
+ * type:
+ *
+ * <pre>
+ *   SimpleFeature feature = ...;
+ *   SimpleFeatureType type = feature.getType();
+ *
+ *   type.getAttribute( 0 ).getDescriptor() == type.getAttribute( 0 );
+ *   type.getAttribute( 1 ).getDescriptor() == type.getAttribute( 1 );
+ * </pre>
+ *
+ * </p>
+ *
+ * <p>
+ * <h3>Attribute Naming</h3>
+ * The names of attributes in a simple feature type are never namespace
+ * qualified. For this reason there is no difference between accessing an
+ * attribute with {@link #getDescriptor(String)} and {@link #getDescriptor(Name)}.
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/simple/SimpleFeatureType.java $
+ */
+public interface SimpleFeatureType extends FeatureType {
+
+    /**
+     * The local name for this FeatureType.
+     *
+     * Specifically this method returns <code>getName().getLocalPart().</code>
+     * @return The local name for this FeatureType.
+     */
+    String getTypeName();
+
+    /**
+     * The list of attribute descriptors which make up the feature type.
+     * <p>
+     * This method is a convenience for:
+     *
+     * <pre>
+     * return (List&lt;AttributeDescriptor&gt;) getProperties();
+     * </pre>
+     *
+     * </p>
+     *
+     * @return The ordered list of attribute descriptors.
+     */
+    List<AttributeDescriptor> getAttributeDescriptors();
+
+    /**
+     * Returns the attribute descriptor which matches the specified name.
+     * <p>
+     * This method is convenience for:
+     *
+     * <pre>
+     * return (AttributeDescriptor) getProperty(name);
+     * </pre>
+     *
+     * </p>
+     * <p>
+     * This method returns <code>null</code> if no such attribute exists.
+     * </p>
+     *
+     * @param name
+     *            The name of the descriptor to return.
+     *
+     * @return The attribute descriptor matching the specified name, or
+     *         <code>null</code> if no such attribute exists.
+     */
+    AttributeDescriptor getDescriptor(String name);
+
+    /**
+     * Returns the attribute descriptor which matches the specified name.
+     * <p>
+     * This method is convenience for:
+     *
+     * <pre>
+     * return (AttributeDescriptor) getProperty(name);
+     * </pre>
+     *
+     * </p>
+     * <p>
+     * This method returns <code>null</code> if no such attribute exists.
+     * </p>
+     *
+     * @param name
+     *            The name of the descriptor to return.
+     *
+     * @return The attribute descriptor matching the specified name, or
+     *         <code>null</code> if no such attribute exists.
+     */
+    AttributeDescriptor getDescriptor(Name name);
+
+    /**
+     * Returns the attribute descriptor at the specified index.
+     * <p>
+     * This method is convenience for:
+     *
+     * <pre>
+     * return (AttributeDescriptor) ((List) getProperties()).get(index);
+     * </pre>
+     *
+     * </p>
+     *
+     * @param name
+     *            The name of the descriptor to return.
+     *
+     * @return The attribute descriptor at the specified index.
+     *
+     * @throws IndexOutOfBoundsException
+     *             When the index is out of bounds.
+     */
+    AttributeDescriptor getDescriptor(int index)
+            throws IndexOutOfBoundsException;
+
+    /**
+     * Returns the number of attributes composing the feature type
+     * <p>
+     * This method is convenience for <code>getAttributes().size()</code>.
+     * </p>
+     * @return The number of attributes.
+     */
+    int getAttributeCount();
+
+    /**
+     * Returns the types of all the attributes which make up the feature.
+     * <p>
+     * This method is convenience for:
+     *
+     * <pre>
+     * List types = new ArrayList();
+     * for (Property p : getProperties()) {
+     *     types.add(p.getType());
+     * }
+     * return types;
+     * </pre>
+     *
+     * </p>
+     *
+     * @return The list of attribute types.
+     */
+    List<AttributeType> getTypes();
+
+    /**
+     * Returns the type of the attribute at the specified index.
+     * <p>
+     * This method is convenience for:
+     *
+     * <pre>
+     *   return (AttributeType)((List)getProperties()).get(index)).getType();
+     * </pre>
+     *
+     * </p>
+     *
+     * @param index
+     *            The index of the attribute whose type to return.
+     *
+     * @return The attribute type at the specified index.
+     *
+     * @throws IndexOutOfBoundsException
+     *             When the index is out of bounds.
+     */
+    AttributeType getType(int index) throws IndexOutOfBoundsException;
+
+    /**
+     * Returns the index of the attribute which matches the specified name.
+     * <p>
+     * -1 is returned in the instance there is no attribute matching the
+     * specified name.
+     * </p>
+     *
+     * @param name
+     *            The name of the attribute whose index to return.
+     *
+     * @return index of named attribute, or -1 if not found.
+     */
+    int indexOf(String name);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/simple/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/simple/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/simple/package.html	(revision 28000)
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+<HEAD>
+<TITLE>package org.opengis.feature.simple</TITLE>
+</HEAD>
+<BODY>
+Profile of the general ISO 19107 feature model built around the idea of a simple feature
+composed of a list of values.
+
+<p>
+A {@link SimpleFeature} is a wrapper around a list of values. The values are interpreted
+based on order; and must be supplied in exactly the the order indicated by the {@link SimpleFeatureType}.
+
+<center><img src="doc-files/simple.GIF"></center>
+
+This model matches the assumptions of GeoAPI 2.1 and is applicable in a wide range of applications
+from the representation of shapefiles; to simple database tables (with no external references).
+
+</BODY>
+
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/AttributeDescriptor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/AttributeDescriptor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/AttributeDescriptor.java	(revision 28000)
@@ -0,0 +1,57 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature.type;
+
+/**
+ * Describes an instance of an Attribute.
+ * <p>
+ * An AttributeDescriptor is an extension of {@link PropertyDescriptor} which
+ * defines some additional information:
+ * <ul>
+ *   <li>A default value for an attribute
+ * </ul>
+ * </p>
+ * <p>
+ *
+ * @author Jody Garnett, Refractions Research
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/type/AttributeDescriptor.java $
+ */
+public interface AttributeDescriptor extends PropertyDescriptor {
+
+    /**
+     * Override of {@link PropertyDescriptor#getType()} which type narrows to
+     * {@link AttributeType}.
+     *
+     *  @see PropertyDescriptor#getType()
+     */
+    AttributeType getType();
+
+    /**
+     * The local name for this AttributeDescriptor.
+     * Specifically this returns <code>getName().getLocalPart</code>().
+     * @return The local name for this attribute descriptor.
+     */
+    String getLocalName();
+
+    /**
+     * The default value for the attribute.
+     * <p>
+     * This value is used when an attribute is created and no value for it is
+     * specified.
+     * </p>
+     * <p>
+     * This value may be <code>null</code>. If it is non-null it should be an
+     * instance of of the class specified by <code>getType().getBinding()</code>.
+     * </p>
+     */
+    Object getDefaultValue();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/AttributeType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/AttributeType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/AttributeType.java	(revision 28000)
@@ -0,0 +1,56 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature.type;
+
+import org.opengis.feature.Attribute;
+
+/**
+ * The type of an attribute.
+ * <p>
+ * An attribute is similar to the notion of a UML attribute, or a field of a java
+ * object. See the javadoc of {@link Attribute} for more info on the semantics
+ * of attributes.
+ * </p>
+ * <p>
+ * <h3>Identifiablily</h3>
+ * An attribute may be "identifiable". When this is the case the attribute has a
+ * unique identifier associated with it. See {@link Attribute#getID()}. The type
+ * of the attribute specifies wether it is identifiable or not ({@link #isIdentified()}.
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/type/AttributeType.java $
+ */
+public interface AttributeType extends PropertyType {
+
+    /**
+     * Indicates if the type is identified or not.
+     * <p>
+     * If this method returns <code>true</code>, then the corresponding
+     * attribute must have a unique identifier, ie, {@link Attribute#getID()}
+     * must return a value, and cannot be <code>null</code>.
+     * </p>
+     *
+     * @return <code>true</code> if the attribute is identified, otherwise <code>false</code>.
+     *
+     * @see Attribute#getID()
+     */
+    boolean isIdentified();
+
+    /**
+     * Override of {@link PropertyType#getSuper()} which type narrows to
+     * {@link AttributeType}.
+     *
+     * @see PropertyType#getSuper()
+     */
+    AttributeType getSuper();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/ComplexType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/ComplexType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/ComplexType.java	(revision 28000)
@@ -0,0 +1,159 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature.type;
+
+import java.util.Collection;
+
+import org.opengis.feature.ComplexAttribute;
+import org.opengis.feature.Property;
+
+/**
+ * The type of a complex attribute.
+ * <br/>
+ * <p>
+ * Similar to how a complex attribute is composed of other properties, a complex
+ * type is composed of property descriptors. A complex type is very much like a
+ * complex type from xml schema. Consider the following xml schema complex type:
+ * <pre>
+ * &lt;element name="myComplexElement" type="myComplexType"/>
+ * &lt;complexType name="myComplexType">
+ *   &lt;sequence>
+ *     &lt;element name="foo" type="xs:string" minOccurs="2" maxOccurs="4">
+ *     &lt;element name="bar" type="xs:int" nillable=false/>
+ *   &lt;/sequence>
+ * &lt;/complexType>
+ * </pre>
+ *
+ * The corresponding complex type that would emerge would be composed as follows:
+ * <pre>
+ *   ComplexType complexType = ...;
+ *   complexType.getProperties().size() == 2;
+ *
+ *   //the foo property descriptor
+ *   PropertyDescriptor foo = complexType.getProperty( "foo" );
+ *   foo.getName().getLocalPart() == "foo";
+ *   foo.getMinOccurs() == 2;
+ *   foo.getMaxOccurs() == 4;
+ *   foo.isNillable() == true;
+ *   foo.getType().getName().getLocalPart() == "string";
+ *
+ *   //the bar property descriptor
+ *   PropertyDescriptor bar = complexType.getProperty( "bar" );
+ *   foo.getName().getLocalPart() == "bar";
+ *   foo.getMinOccurs() == 1;
+ *   foo.getMaxOccurs() == 1;
+ *   foo.isNillable() == false;
+ *   foo.getType().getName().getLocalPart() == "int";
+ * </pre>
+ * </p>
+ * Now consider the following xml instance document:
+ * <pre>
+ * &lt;myComplexElement>
+ *   &lt;foo>one&lt;/foo>
+ *   &lt;foo>two&lt;/foo>
+ *   &lt;foo>three&lt;/foo>
+ *   &lt;bar>1&lt;/bar>
+ * &lt;/myComplexElement>
+ * </pre>
+ * <br>
+ * The resulting complex attribute would be composed as follows:
+ * <pre>
+ *   ComplexAttribute attribute = ...;
+ *   attribute.getName().getLocalPart() == "myComplexElement";
+ *   attribute.getType().getName().getLocalPart() == "myComplexType";
+ *
+ *   Collection foo = attribute.getProperties( "foo" );
+ *   foo.size() == 3;
+ *   foo.get(0).getValue() == "one";
+ *   foo.get(1).getValue() == "two";
+ *   foo.get(2).getValue() == "three";
+ *
+ *   Property bar = attribute.getProperty( "bar" );
+ *   bar.getValue() == 1;
+ * </pre>
+ * </p>
+ * @see ComplexAttribute
+ *
+ * @author Jody Garnett (Refractions Research)
+ * @author Justin Deoliveira (The Open Planning Project)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/type/ComplexType.java $
+ */
+public interface ComplexType extends AttributeType {
+    /**
+     * Override and type narrow to Collection<Property>.class.
+     */
+    Class<Collection<Property>> getBinding();
+
+    /**
+     * The property descriptor which compose the complex type.
+     * <p>
+     * A complex type can be composed of attributes and associations which means
+     * this collection returns instances of {@link AttributeDescriptor} and
+     * {@link AssociationDescriptor}.
+     * </p>
+     *
+     * @return Collection of descriptors representing the composition of the
+     * complex type.
+     */
+    Collection<PropertyDescriptor> getDescriptors();
+
+    /**
+     * Describe a single property by name.
+     * <p>
+     * This method returns <code>null</code> if no such property is found.
+     * </p>
+     * @param name The name of the property to get.
+     *
+     * @return The property matching the specified name, or <code>null</code>.
+     */
+    PropertyDescriptor getDescriptor( Name name );
+
+    /**
+     * Describe a single property by unqualified name.
+     * <p>
+     * Note: Special care should be taken when using this method in the case
+     * that two properties with the same local name but different namespace uri
+     * exist. For this reason using {@link #getDescriptor(Name)} is safer.
+     * </p>
+     * <p>
+     * This method returns <code>null</code> if no such property is found.
+     * </p>
+     * @param name The name of the property to get.
+     *
+     * @return The property matching the specified name, or <code>null</code>.
+     */
+    PropertyDescriptor getDescriptor( String name );
+
+    /**
+     * Describes allowable content, indicating containment.
+     * <p>
+     * A collection of AttributeDescriptors (name and AttributeType) is used.
+     * We make no restrictions as to attribute order. All attributes are considered
+     * accessable by name (and order is thus insignificant).
+     * </p>
+     * <p>
+     * If you are modling a typing system where attribute order is relevant
+     * you may make use of a List. Similarly if duplicate attributes are
+     * disallowed you may make use of a Set.
+     * </p>
+     * <p>
+     * This method follows JavaBeans naming convention indicating this is part of
+     * our data model.
+     * </p>
+     */
+    //Collection<AttributeDescriptor> attributes();
+
+    /**
+     * Allowable associations, indicating non containment relationships.
+     */
+    //Collection<AssociationDescriptor> associations();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/FeatureType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/FeatureType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/FeatureType.java	(revision 28000)
@@ -0,0 +1,63 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature.type;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+/**
+ * The type of a Feature.
+ * <p>
+ * Beyond a complex type, a feature defines some additional information:
+ * <ul>
+ *   <li>The default geometric attribute
+ *   <li>The coordinate referencing system (derived from the default geometry)
+ * </ul>
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/type/FeatureType.java $
+ */
+public interface FeatureType extends ComplexType {
+
+    /**
+     * Features are always identified.
+     *
+     * @return <code>true</code>
+     */
+    boolean isIdentified();
+
+    /**
+     * Describe the default geometric attribute for this feature.
+     * <p>
+     * This method returns <code>null</code> in the case where no such attribute
+     * exists.
+     * </p>
+     * @return The descriptor of the default geometry attribute, or <code>null</code>.
+     */
+    GeometryDescriptor getGeometryDescriptor();
+
+    /**
+     * The coordinate reference system of the feature.
+     * <p>
+     * This value is derived from the default geometry attribute:
+     * <pre>
+     *   ((GeometryType)getDefaultGeometry().getType()).getCRS();
+     * </pre>
+     * </p>
+     * <p>
+     * This method will return <code>null</code> in the case where no default
+     * geometric attribute is defined.
+     * </p>
+     * @return The coordinate referencing system, or <code>null</code>.
+     */
+    CoordinateReferenceSystem getCoordinateReferenceSystem();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/FeatureTypeFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/FeatureTypeFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/FeatureTypeFactory.java	(revision 28000)
@@ -0,0 +1,145 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature.type;
+
+import java.util.List;
+
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.util.InternationalString;
+
+/**
+ * Factory for types and descriptors.
+ * <p>
+ * Implementations of this interface should not contain any "special logic" for
+ * creating types. Method implementations should be straight through calls to a
+ * constructor.
+ * </p>
+ * @author Gabriel Roldan (Axios Engineering)
+ * @author Justin Deoliveira (The Open Planning Project)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/type/FeatureTypeFactory.java $
+ */
+public interface FeatureTypeFactory {
+
+    /**
+     * Creates an attribute descriptor.
+     *
+     * @param type
+     *  The type of the described attribute.
+     * @param name
+     *  The name of the described attribute.
+     * @param minOccurs
+     *  The minimum number of occurences of the described attribute.
+     * @param maxOccurs
+     *  The maximum number of occurences of the described attribute.
+     * @param isNillable
+     *  Flag indicating if the described attribute may have a null value.
+     * @param defaulValue
+     *  The default value of the described attribute.
+     */
+    AttributeDescriptor createAttributeDescriptor(
+        AttributeType type, Name name, int minOccurs, int maxOccurs,
+        boolean isNillable, Object defaultValue
+    );
+
+    /**
+     * Creates a geometry descriptor.
+     *
+     * @param type
+     *  The type of the described attribute.
+     * @param name
+     *  The name of the described attribute.
+     * @param minOccurs
+     *  The minimum number of occurences of the described attribute.
+     * @param maxOccurs
+     *  The maximum number of occurences of the described attribute.
+     * @param isNillable
+     *  Flag indicating if the described attribute may have a null value.
+     * @param defaulValue
+     *  The default value of the described attribute.
+     */
+    GeometryDescriptor createGeometryDescriptor(
+        GeometryType type, Name name, int minOccurs, int maxOccurs,
+        boolean isNillable, Object defaultValue
+    );
+
+    /**
+     * Creates an attribute type.
+     *
+     * @param name
+     *  The name of the type.
+     * @param binding
+     *  The class that values of attributes of the type.
+     * @param isIdentifiable
+     *  Flag indicating if the attribute is identifiable.
+     * @param isAbstract
+     *  Flag indicating if the type is abstract.
+     * @param restrictions
+     *  Set of restrictions on the attribute.
+     * @param superType
+     *  Parent type.
+     * @param description
+     *  A description of the type.
+     */
+    AttributeType createAttributeType(
+        Name name, Class<?> binding, boolean isIdentifiable, boolean isAbstract,
+        List<Filter> restrictions, AttributeType superType, InternationalString description
+    );
+
+    /**
+     * Creates a geometric attribute type.
+     *
+     * @param name
+     *  The name of the type.
+     * @param binding
+     *  The class of values of attributes of the type.
+     * @param crs
+     *  The coordinate reference system of the type.
+     * @param isIdentifiable
+     *  Flag indicating if the attribute is identifiable.
+     * @param isAbstract
+     *  Flag indicating if the type is abstract.
+     * @param restrictions
+     *  Set of restrictions on the attribute.
+     * @param superType
+     *  Parent type.
+     * @param description
+     *  A description of the type.
+     */
+    GeometryType createGeometryType(
+        Name name, Class<?> binding, CoordinateReferenceSystem crs, boolean isIdentifiable,
+        boolean isAbstract, List<Filter> restrictions, AttributeType superType,
+        InternationalString description
+    );
+
+    /**
+     * Creates a simple feature type.
+     *
+     * @param name
+     *  The name of the type.
+     * @param schema
+     *  List of attribute descriptors which define the type.
+     * @param isAbstract
+     *  Flag indicating if the type is abstract.
+     * @param restrictions
+     *  Set of restrictions on the attribute.
+     * @param superType
+     *  Parent type.
+     * @param description
+     *  A description of the type.
+     */
+    SimpleFeatureType createSimpleFeatureType(
+        Name name, List<AttributeDescriptor> schema, GeometryDescriptor defaultGeometry,
+        boolean isAbstract, List<Filter> restrictions, AttributeType superType,
+        InternationalString description
+    );
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/GeometryDescriptor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/GeometryDescriptor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/GeometryDescriptor.java	(revision 28000)
@@ -0,0 +1,41 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature.type;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+/**
+ * Describes an instance of a geometry attribute.
+ * <p>
+ * This interface adds no additional methods, the point of it is convenience
+ * to type narrow {@link #getType()} to {@link GeometryType}.
+ * </p>
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/type/GeometryDescriptor.java $
+ */
+public interface GeometryDescriptor extends AttributeDescriptor {
+    /**
+     * Override of {@link AttributeDescriptor#getType()} which type narrows
+     * to {@link GeometryType}.
+     */
+    GeometryType getType();
+
+    /**
+     * The coordinate reference system in which these geometries are defined.
+     * <p>
+     * This method may return <code>null</code>, but this should only occur in
+     * cases where the actual crs is not known. A common case is when a shapefile
+     * does not have an accompanied .prj file.
+     * </p>
+     */
+    CoordinateReferenceSystem getCoordinateReferenceSystem();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/GeometryType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/GeometryType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/GeometryType.java	(revision 28000)
@@ -0,0 +1,36 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature.type;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+/**
+ * The type of a GeometryAttribute.
+ * <p>
+ * Beyond AttributeType, this class stores the coordinate reference system that
+ * geometries are defined in, see {@link #getCoordinateReferenceSystem()}.
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/type/GeometryType.java $
+ */
+public interface GeometryType extends AttributeType {
+    /**
+     * The coordinate reference system in which geometries are defined.
+     * <p>
+     * This method may return <code>null</code>, but this should only occur in
+     * cases where the actual crs is not known. A common case is when a shapefile
+     * does not have an accompanied .prj file.
+     * </p>
+     */
+    CoordinateReferenceSystem getCoordinateReferenceSystem();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/Name.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/Name.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/Name.java	(revision 28000)
@@ -0,0 +1,149 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature.type;
+
+import static org.opengis.annotation.Obligation.MANDATORY;
+import static org.opengis.annotation.Specification.ISO_19103;
+
+import org.opengis.annotation.UML;
+
+/**
+ * A qualified Name (with respect to a namespace rather than just a simple prefix).
+ * <p>
+ * This interface provides method names similar to the Java QName interface in
+ * order to facilitate those transition from an XML models. We are recording
+ * the a full namespace (rather than just a prefix) in order to sensibly compare
+ * Names produced from different contexts. Since the idea of a "prefix" in a QName
+ * is only used to refer to a namespace defined earlier in the document it is sensible
+ * for us to ask this prefix be resolved (allowing us to reliability compare names
+ * produced from different documents; or defined by different repositories).
+ * </p>
+ * Notes:
+ * <ul>
+ * <li>You should not need to use the "separator" when working with Name as a programmer. There
+ * is no need to do a string concatenation; just compare getNamespaceURI() and compare
+ * getLocalPart(). Do not build a lot of strings to throw away.
+ * <li>prefix: If you need to store the prefix information please make use of
+ * "client properties" facilities located on PropertyType data structure. The prefix is not
+ * a logical part of a Name; but often it is nice to preserve prefix when processing data
+ * in order not to disrupt other components in a processing chain.
+ * <li>Name is to be understood with respect to its getNamespaceURI(), if needed
+ * you make look up a Namespace using this information. This is however not a
+ * backpointer (Name does not require a Namespace to be constructed) and the
+ * lookup mechanism is not specified, indeed we would recommend the use of JNDI
+ * , and we suspect that the Namespace should be lazily created as required.
+ * <li>Name may also be "global" in which case the getNamespaceURI() is <code>null</code>, we
+ * have made a test for this case explicit with the isGlobal() method.
+ * </ul>
+ * Name is a lightweight data object with identity (equals method) based on
+ * getNameSpaceURI() and getLocalPart() information. This interface is strictly used for
+ * identification and should not be extended to express additional functionality.
+ * </p>
+ *
+ * @author Jody Garnett (Refractions Research, Inc.)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/type/Name.java $
+ */
+public interface Name {
+
+    /**
+     * Returns the URI of the namespace for this name.
+     * <p>
+     * In ISO 19103 this is known as <b>scope</b> and containes a backpointer
+     * to the containing namespace. This solution is too heavy for our purposes,
+     * and we expect applications to provide their own lookup mechanism through
+     * which they can use this URI.
+     * </p>
+     * The namespace URI does serve to make this name unique and is checked as
+     * part of the equals operation.
+     * </p>
+     *
+     * @since GeoAPI 2.1
+     */
+    @UML(identifier = "scope", obligation = MANDATORY, specification = ISO_19103)
+    String getNamespaceURI();
+
+    /**
+     * Separator to use between getNamespaceURI() and getLocalPart() when
+     * constructing getURI().
+     * <p>
+     * This separator is only used to construct a visually pleasing getURI()
+     * result. The value to use as a separator depends on the registry
+     * or namespace you are working with. JNDI naming services have 
+     * been known to use "/" and ":". Referring to an element in an XMLSchema
+     * document has been represented with a "#" symbol.
+     * <p>
+     * @return A separator (such as "/" or ":").
+     */
+    String getSeparator();
+    
+    /**
+     * Retrieve the "local" name.
+     * <p>
+     * This mechanism captures the following ISO 19103 concerns:
+     * <ul>
+     * <li>GenericName.depth(): this concept is not interesting, we assume a
+     * namespace would be able to navigate through contained namespace on its
+     * own based on this local part.
+     * <li>GenericName.asLocalName()
+     * <li>GenericName.name()
+     * </ul>
+     * @return local name (can be used in namespace lookup)
+     */
+    String getLocalPart();
+
+    /**
+     * Convert this name to a complete URI.
+     * <p>
+     * This URI is constructed with the getNamespaceURI(), getSeparator() and getLocalPart().
+     * </p>
+     * <p>
+     * This method captures the following concerns of ISO 19103 concerns:
+     * <ul>
+     * <li>GenericName.getParsedNames()
+     * <li>toFullyQuantifiedName()
+     * </ul>
+     * <p>
+     * As an example:
+     * <ul>
+     * <li>namespace: "gopher://localhost/example" separator: "/" local: "name"
+     * <li>namespace: "gopher://localhost" separator: "/" local: "example/name"
+     * </ul>
+     * Both return: "gopher://localhost/example/name" as they indicate the same entry
+     * in the namespace system (such as a Registry or JNDI naming service).
+     * </p>
+     * @return a complete URI constructed of namespace URI and the local part.
+     */
+    @UML(identifier = "parsedName", obligation = MANDATORY, specification = ISO_19103)
+    String getURI();
+
+    /**
+     * Must be based on getURI().
+     *
+     * @return a hascode based on getURI()
+     */
+    ///@Override
+    int hashCode();
+
+    /**
+     * <code>true</code> if getURI is equal.
+     *
+     * @param other
+     * @return <code>true</code> if getURI is equal.
+     */
+    ///@Override
+    boolean equals(Object obj);
+
+    /**
+     * A local-independent representation of this name, see getURI().
+     */
+    ///@Override
+    String toString();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/PropertyDescriptor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/PropertyDescriptor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/PropertyDescriptor.java	(revision 28000)
@@ -0,0 +1,144 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature.type;
+
+import java.util.Map;
+
+import org.opengis.feature.ComplexAttribute;
+
+/**
+ * Describes a Property, and how it relates to its containing entity, which is
+ * often a {@link ComplexAttribute}.
+ * <br>
+ * <p>
+ * A property descriptor defines the following about the property:
+ * <ul>
+ *   <li>type of the property
+ *   <li>the name of the property
+ *   <li>number of allowable occurrences of the property
+ *   <li>nilability of the property
+ * </ul>
+ * </p>
+ * <br>
+ * <p>
+ * The concept of a descriptor is similar to that of a element declaration in
+ * xml. Consider the following xml schema definition:
+ * <pre>
+ *   &lt;complexType name="someComplexType">
+ *     &lt;sequence>
+ *       &lt;element name="foo" minOccurs="2" maxOccurs="4" type="xs:string" nillable="false"/>
+ *     &lt;sequence>
+ *   &lt;complexType>
+ * </pre>
+ * <br>
+ * In the above, the element declaration named "foo" maps to a property descriptor.
+ * From the above schema, the following property descriptor would result:
+ * <pre>
+ *  //the complex type
+ *  ComplexType complexType = ...;
+ *
+ *  //get the descriptor
+ *  PropertyDescriptor descriptor = complexType.getProperty( "foo" );
+ *
+ *  //make the following assertions
+ *  descriptor.getName().getLocalPart().equals( "foo" );
+ *
+ *  descriptor.getType().getName().getNamespaceURI().equals( "http://www.w3.org/2001/XMLSchema" )
+ *  descriptor.getType().getName().getLocalPart().equals( "string" );
+ *  descriptor.getMinOccurs() == 2;
+ *  descriptor.getMaxOccurs() == 4;
+ *  descriptor.isNillable() == true;
+ *
+ *  //the complex attribute
+ *  ComplexAttribute complexAttribute = ...
+ *  complexAttribute.getType() == complexType;
+ *
+ *  //get the properties
+ *  Collection properties = complexAttribute.getProperties( "foo" );
+ *
+ *  //make assertions about properties
+ *  properties.size() >= 2;  //minOccurs = 2
+ *  properties.size() <= 4; //maxOccurs = 4
+ *
+ *  for ( Property p : properties ) {
+ *      p.getDescriptor() == descriptor
+ *
+ *      p.getValue() != null; //nilable = false
+ *      p.getType().getBinding() == String.class; //type = xs:string
+ *      p.getValue() instanceof String; //type = xs:string
+ *  }
+ * </pre>
+ * <p>
+ *
+ * @author Jody Garnett, Refractions Research
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/type/PropertyDescriptor.java $
+ */
+public interface PropertyDescriptor {
+    /**
+     * The type of the property defined by the descriptor.
+     * <p>
+     * This value should never be <code>null</code>. The type contains information
+     * about the value of the property such as its java class.
+     * </p>
+     */
+    PropertyType getType();
+
+    /**
+     * The name of the property defined by the descriptor, with respect to its
+     * containing type or entity..
+     * <p>
+     * This value may be <code>null</code> in some instances. Also note that this
+     * is not the same name as <code>getType().getName()</code>. The former is
+     * the name of the instance, the latter is the name of the type of the
+     * instance.
+     * </p>
+     */
+    Name getName();
+
+    /**
+     * The minimum number of occurrences of the property within its containing
+     * entity.
+     * <p>
+     * This value is always an integer greater than or equal to zero.
+     * </p>
+     * @return An integer >= 0
+     */
+    int getMinOccurs();
+
+    /**
+     * The maximum number of occurrences of the property within its containing
+     * entity.
+     * <p>
+     * This value is a positive integer. A value of <code>-1</code> means that
+     * the max number of occurrences is unbounded.
+     * </p>
+     * @return An integer >= 0, or -1.
+     */
+    int getMaxOccurs();
+
+    /**
+     * Flag indicating if <code>null</code> is an allowable value for the
+     * property.
+     *
+     * @return <code>true</code> if the property is allowed to be <code>null</code>,
+     * otherwise <code>false</code>.
+     */
+    boolean isNillable();
+
+    /**
+     * A map of "user data" which enables applications to store "application-specific"
+     * information against a property descriptor.
+     *
+     * @return A map of user data.
+     */
+    Map<Object,Object> getUserData();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/PropertyType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/PropertyType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/PropertyType.java	(revision 28000)
@@ -0,0 +1,224 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature.type;
+
+import java.util.List;
+import java.util.Map;
+
+import org.opengis.feature.Property;
+import org.opengis.filter.Filter;
+import org.opengis.util.InternationalString;
+
+/**
+ * The type of a Property.
+ * <p>
+ * A property type defines information about the value of a property. This
+ * includes:
+ * <ul>
+ *   <li>java class of the value of the property ((also known as the property "binding")
+ *   <li>any restrictions on the value of the property
+ *   <li>a description of the property
+ *   <li>if the type is abstract or not
+ * </ul>
+ * </p>
+ * <br/>
+ * <p>
+ *  <h3>Binding</h3>
+ *  The {@link #getBinding()} method returns the java class of which the value
+ *  of the property is an instance of.
+ *  <pre>
+ *   Property property = ...;
+ *   property.getType().getBinding().isAssignableFrom(property.getValue().getClass());
+ *  </pre>
+ * </p>
+ * <p>
+ * <h3>Restrictions</h3>
+ * The {@link #getRestrictions()} method returns a set of {@link Filter} objects
+ * which define additional restrictions on the value of the property.
+ * <pre>
+ *   Property property = ...;
+ *   for ( Filter restriction : property.getType().getRestrictions() ) {
+ *       restriction.evaluate( property ) == true;
+ *   }
+ * </pre>
+ * </p>
+ * <p>
+ * <h3>Inheritance</h3>
+ * A property type may extend from another property type. When this occurs any
+ * restrictions defined by the parent type are inherited by the child type. The
+ * binding declared by the super type may or may not be a super class of the
+ * binding declared by the child type.
+ * </p>
+ * <p>
+ * <h3>Abstract Types</h3>
+ * A property type may be abstract similar to how a java class can be abstract.
+ * Such property types are usually not referenced directly by a descriptor, but
+ * usually are the parent type of a non-abstract property type.
+ * </p>
+ * <p>
+ *  <h3>Example</h3>
+ *  Property, PropertyDescriptor, and PropertyType are very similar to concepts
+ *  encountered in xml schema. Consider the following xml schema:
+ *  <pre>
+ *    &lt; simpleType name="number"/>
+ *
+ *    &lt; simpleType name="integer"/>
+ *
+ *    &lt; complexType name="myComplexType"/>
+ *      &lt;element name="foo" type="integer"/>
+ *    &lt;/complexType>
+ *  </pre>
+ *  <br>
+ *  In the above, "number", "integer", and "myComplexType" all map to PropertyType.
+ *  While "foo" maps to a PropertyDescriptor. Consider a complex attribute which is
+ *  of type "myComplexType:
+ *  <pre>
+ *  ComplexAttribute complexAttribute = ...;
+ *  ComplexType complexType = complexAttribute.getType();
+ *
+ *  complexType.getName().getLocalPart() == "myComplexType";
+ *
+ *  //the property descriptor
+ *  PropertyDescriptor propertyDescriptor = complexType.getProperty( "foo" );
+ *  propertyDescriptor.getName().getLocalPart() == "foo";
+ *
+ *  //the property type
+ *  PropertyType propertyType = propertyDescriptor.getType();
+ *  propertyType.getName().getLocalPart() == "integer";
+ *  propertyType.getBinding() == Integer.class;
+ *  propertyType.getSuper().getName().getLocalPart() == "number";
+ *  propertyType.getSuper().getBinding() == Number.class;
+ *
+ *  //the property
+ *  Property property = complexAttribute.getProperty( "foo" );
+ *  property.getDescriptor() == propertyDescriptor;
+ *  property.getType() == propertyType;
+ *  property.getName().getLocalPart() == "foo";
+ *  property.getValue() instanceof Integer;
+ *  </pre>
+ * </p>
+
+ * @author Jody Garnett, Refractions Research, Inc.
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/type/PropertyType.java $
+ */
+public interface PropertyType {
+    /**
+     * The name of the property type.
+     * <p>
+     * Note that this is not the same name as {@link Property#getName()}, which
+     * is the name of the instance of the type, not the type itself.
+     * </p>
+     * <p>
+     * The returned name is a qualified name made up of two parts. The first
+     * a namespace uri ({@link Name#getNamespaceURI()}, and the second a local
+     * part ({@link Name#getLocalPart()}.
+     * </p>
+     * <p>
+     * This value is never <code>null</code>.
+     * </p>
+     * @return The name of the property type.
+     */
+    Name getName();
+
+    /**
+     * The java class that values of properties of the property type are bound
+     * to.
+     * <p>
+     * This value is never <code>null</code>.
+     * </p>
+     * @return The binding of the property type.
+     */
+    Class<?> getBinding();
+
+    /**
+     * The parent type of the property type.
+     * <p>
+     * This method returns <code>null</code> if no super type is defined.
+     * </p>
+     * <p>
+     * The super type may contain additional restrictions to be considered against
+     * properties of the the property type.
+     * </p>
+     *
+     * @return The parent or super type, or <code>null</code>.
+     */
+    PropertyType getSuper();
+
+    /**
+     * Flag indicating if the type is abstract or not.
+     *
+     * @return <code>true</code> if the type is abstract, otherwise <code>false</code>.
+     */
+    boolean isAbstract();
+
+    /**
+     * List of restrictions used define valid values for properties of this
+     * property type.
+     * <p>
+     * Each restriction is a {@link Filter} object in which the property is
+     * passed through. If {@link Filter#evaluate(Object)} returns <code>true</code>
+     * the restriction is met. If <code>false</code> is returned then the
+     * restriction has not been met and the property should be considered invalid.
+     * Remember to check getSuper().getRestrictions() as well.
+     * <p>
+     * This method returns an empty set in the case of no restrictions and should
+     * not return <code>null</code>.
+     * </p>
+     * @return List<Restriction> used to validate allowable values.
+     */
+    List<Filter> getRestrictions();
+
+    /**
+     * Human readable description of this property type.
+     *
+     * @return Human readable description of this property type.
+     */
+    InternationalString getDescription();
+
+    /**
+     * A map of "user data" which enables applications to store "application-specific"
+     * information against a property type.
+     * <p>
+     * As an example, consider an application that builds a PropertyType from an
+     * xml schema. A useful bit of information to attach to the PropertyType is
+     * the original schema itself, in whatever construct it might be stored in:
+     * <pre>
+     * <code>
+     * XSDComplexTypeDefinition complexTypeDef = ...;
+     * PropertyType type = buildPropertyType( complexTypeDef );
+     *
+     * type.getUserData().put( XSDComplexTypeDefintion.class, complexTypeDef );
+     * </code>
+     * </pre>
+     * </p>
+     *
+     * @return A map of user data.
+     */
+    Map<Object,Object> getUserData();
+
+    /**
+     * Equality based on property {@link #getName()}.
+     * </p>
+     *
+     * @return <code>true</code> if other is a PropertyType with the same name
+     */
+    ///@Override    
+    boolean equals(Object other);
+
+    /**
+     * Hashcode override based on {@link #getName()}.
+     *
+     * @return getName().hashCode()
+     */
+    ///@Override
+    int hashCode();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/Schema.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/Schema.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/Schema.java	(revision 28000)
@@ -0,0 +1,76 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2007 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.feature.type;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A collection of AttributeType.
+ * <p>
+ * A schema is organized as a map of {@link Name} to {@link AttributeType}. In
+ * each name,type tuple, the name matches the name of the type.
+ * <pre>
+ *   //create some attribute types
+ *   AttributeType pointType =
+ *     new AttributeTypeImpl( new NameImpl( "http://www.opengis.net/gml", "PointType" ), ... );
+ *   AttributeType lineStringType =
+ *     new AttributeTypeImpl( new NameImpl( "http://www.opengis.net/gml", "LineStringType" ), ... );
+ *   AttributeType polygonType =
+ *     new AttributeTypeImpl( new NameImpl( "http://www.opengis.net/gml", "PolygonType" ), ... );
+ *
+ *   //create a schema
+ *   Schema schema = new SchemaImpl( "http://www.opengis.net/gml" );
+ *
+ *   //add types to the schema
+ *   schema.add( pointType );
+ *   schema.add( lineStringType );
+ *   schema.add( polygonType );
+ * </pre>
+ * </p>
+ * <p>
+ * The intention of a schema is to provide a resuable set of attribute types.
+ * These types are used when building attribute instances.
+ * </p>
+ *
+ * @author Jody Garnett, Refractions Research, Inc.
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/feature/type/Schema.java $
+ */
+public interface Schema extends Map<Name, AttributeType> {
+
+    /**
+     * The uri of the schema.
+     * <p>
+     * This method is a convenience for <code>keySet().getURI()</code>.
+     * </p>
+     *
+     * @return The uri of the schema.
+     */
+    String getURI();
+
+    /**
+     * Profiles the schema, creating a new schema in the process.
+     * <p>
+     * A profile of a schema is a subset of the schema, and it also a schema
+     * itself.
+     * </p>
+     * <p>
+     * Used to select a subset of types for a specific application. Profiles
+     * often are used to express limitiations of a source of data.
+     * </p>
+     * @param profile The set of names which corresond to entries that will make
+     * up the profile.
+     *
+     * @return The profile of the original schema.
+     */
+    Schema profile( Set<Name> profile );
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/feature/type/package.html	(revision 28000)
@@ -0,0 +1,156 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+<HEAD>
+<TITLE>package org.opengis.feature.type</TITLE>
+</HEAD>
+<BODY>
+Feature model ISO 19109 with allowances for usability.
+
+<p>This package captures the type information for a general feature model. This feature model has been produced after review of the ISO 19109 
+specification, and a review of several java implementations. </p>
+
+<p>Capabilities:
+<ul>
+    <li>Provide information for the creation of new feature data and the validaiton of existing feature data
+	<li>Provide enough description to support the use of a Query Language for data access. We have tested with
+	the Filter 1.0, Filter 1.0 and Common Query Lanague at this time.
+	<li>Capture enough information to permit the seamless handling of models
+	taken from XML specifications, in particular the use of Sequence,
+	Choice and support XPath access have proven a challenge.
+	<li>Provide for a definition of a SimpleFeatureType similar in spirit to
+	the previous GeoAPI feature model in which access methods may be used
+	directly and are based around simple Strings.
+	<li>Consistent with common java usage conventions
+</ul>
+
+Possibilities for future work:
+<ul>
+<li>Representation of application schema as a first class object
+<li>Using naming consistent with ISO 19109 specification
+</ul>
+
+<h2>Type System</h2>
+
+PropertyType forms a class hierarchy representing type information for the feature model.
+
+<center><img src="doc-files/feature_type.gif"></center>
+
+<p>The following ideas are central to the functioning of this package as
+a feature model:
+<ul>
+    <li>AttributeType is the base "Type" in the system, it is bound against
+	a java Class and may be reused.
+	
+	<li>AttributeType may indicate available operations using
+	"OperationDescriptors", these descriptors have an OperationType
+	describing their required parameters as list of AttributeTypes
+	
+	<li>AttributeType contains set of Filters that are used to "constrain"
+	the permissible value
+	
+	<li>AttributeType is allowed to be an extension of a super type. This
+	presents one known issue: the bound java classes may not be compatible
+	even if the modelling a subset is properly represented <br>
+	(An example is Integer representing a subset of BigInteger).
+		
+	<li>ComplexType contains additional PropertyDescriptors describing
+	attributes and associations along with cardinality information. Each
+	descriptor is named (in a similar fashion to Java fields being named
+	in a Class).
+	
+	<li>FeatureType explicitly represents a spatial type, with additional
+	information such as CRS and default geometry.
+</ul>
+</p>
+Identified objects allow for a String "ID" that; the use of which is application specific.
+Some applications, such as GML, have strict guidelines on the use of identifiers.
+</p>
+
+<p>As pointed out above ComplexType can be used to represent data with interesting
+internal structure. Descriptors are provided to document formally what information is
+available for retrieval by a query language.
+</p>
+
+<center><img src="doc-files/descriptor.GIF"></center>
+
+Descriptors are used to describe the composition and relationships between entities in our feature model.
+AssociationDescriptors are used describe relationships between entities; AttributeDescriptors are used
+to describe aggregation. Several specific subclasses of AttributeDescriptor are available for working
+with specific kind of content such as GeometryDescriptor.
+
+
+<h2>Differences from ISO 19103 with respect to Naming</h2>
+
+<p>We have explicitly made the following break with ISO 19103:
+<ul>
+	<li>Name - we have adopted a simple definition of Name based on QName.
+	The ISO implementation combined the responsibilities of naming with the
+	implementation of a chained linked list of names. The result was heavy
+	weight, and strange and has not proved intuitive in practice.
+	<li>Namespace - implemented as Set<Name>, this is also a tagged with its
+	own Namespace. The ISO implementation combined the responsibilities of
+	lookup with those of maintaining a namespace scope for a provided name
+	(ie bidirectional link between Namespace and Name). The required
+	backpointer prevented Name from being lightweight and has been removed.</li>
+</ul>
+As indicated above we have removed the "back pointers" required to navigate from Name to
+its "context", instead we have provided a URI which should be used with your lookup system
+of choice. This choice may in fact be Namespace (and is when working with TypeNames
+in a Schema), however the actual implementation should be provided by the hosting
+language in many cases.
+
+<center><img src="doc-files/name.png"></center>
+
+Many applicaitons will make use of their own register when resolving names;
+we offer the use of javax.naming.Name API as a recommendation.
+
+<h2>Differences from ISO 19109 with respect to General Feature Model</h2>
+
+<p>We have explicitly made the following break with ISO 19109:
+<ul>
+	<li>TypeName - we have separated out the concerns of TypeDefinition
+	from TypeName, in ISO 19109 these were combined and caused great
+	confusion when implementing.
+	<li>AttributeName - also separated from AttributeType in a similar
+	manner.
+</ul>
+Numerous other changes have been made to leverage Java collection API
+where appropriate. These represent a direct mapping onto the language
+constructs and may or may not prove significant to those arriving from an
+ISO 19109 background.
+</p>
+
+<h2>Relationship to ISO 19109 Primer</h2>
+<p>This work is greatly informed from a proposal included in the ISO
+19109 primer - written by Bryce. In particular the requirement for
+operations, associations and detailed review of ISO19109, and EMF was a
+great asset. This primer also served as the only public documentation of
+the ISO 19109 material available for open development.
+<p>Differences from Bryce's proposal:
+<ul>
+	<li>Name, TypeName and Namespace as above
+	<li>Schema - we once again do not combine implementation with
+	identification (the proposal for Package extended ScopedName). We have
+	implemened a Schema class as a Map<TypeName ,AttributeType> this works
+	out nicely as the keySet ends up being the Namespace for the Schema.
+	<li>Factory and Type separation, we have explicitly not extended our
+	type Schema class in order to make a FeatureFactory. A requirement of
+	the type system is to allow for application supplied FeatureType
+	creation, this is a seperate concern then modeling and grouping feature
+	types.
+</ul>
+The definition of Record and Name wsere unresolved at the time of this
+work and has not been integrated. In particular the definition of Name
+was taken as "too complicated".
+</p>
+<p>We also disagreed with one of the goals of the proposal: <i>convention
+that the creation of objects inside an application schema is the
+responsibility of the schema author</i>. This goal is in conflict with
+our need to allow applications to create instances of their own
+devising. This need is particulary apparent when an application needs to
+ensure the use of a specific base class (for example to work with a
+persistence system Jaxtor, or modeling system like EMF).</p>
+</BODY>
+
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/And.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/And.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/And.java	(revision 28000)
@@ -0,0 +1,33 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter;
+
+// Annotations
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * {@linkplain #evaluate Evaluates} to {@code true} if all the combined expressions evaluate to {@code true}.
+ * This interface exposes no additional methods beyond those of {@link BinaryLogicOperator}.
+ * It only serves as a marker of what type of operator this is.
+ * <p>
+ * You can check if the And operation is supported using:<pre><code>
+ * scalarCapabilities.hasLogicalOperators() == true
+ * </code></pre>
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/And.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("And")
+public interface And extends BinaryLogicOperator {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/BinaryComparisonOperator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/BinaryComparisonOperator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/BinaryComparisonOperator.java	(revision 28000)
@@ -0,0 +1,40 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter;
+
+// OpenGIS direct dependencies
+import org.opengis.annotation.XmlElement;
+import org.opengis.filter.expression.Expression;
+
+
+/**
+ * Abstract base class for filters that compare exactly two values against each
+ * other.  The nature of the comparison is dependent on the subclass.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/BinaryComparisonOperator.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("BinaryComparisonOpType")
+public interface BinaryComparisonOperator extends Filter {
+    /**
+     * Returns the first of the two expressions to be compared by this operator.
+     */
+    @XmlElement("expression")
+    Expression getExpression1();
+
+   /**
+     * Returns the second of the two expressions to be compared by this operator.
+     */
+    @XmlElement("expression")
+    Expression getExpression2();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/BinaryLogicOperator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/BinaryLogicOperator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/BinaryLogicOperator.java	(revision 28000)
@@ -0,0 +1,39 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter;
+
+// J2SE direct dependencies
+import java.util.List;
+
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * Abstract super-interface for logical operators that accept two or more
+ * other logical values as inputs.  Currently, the only two subclasses are
+ * {@link And} and {@link Or}.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/BinaryLogicOperator.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("BinaryLogicOpType")
+public interface BinaryLogicOperator extends Filter {
+    /**
+     * Returns a list containing all of the child filters of this object.
+     * <p>
+     * This list will contain at least two elements, and each element will be an
+     * instance of {@code Filter}.
+     * </p>
+     */
+    List<Filter> getChildren();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/ExcludeFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/ExcludeFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/ExcludeFilter.java	(revision 28000)
@@ -0,0 +1,65 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter;
+
+import java.io.Serializable;
+
+
+/**
+ * Indicating "filter all", evaluates to {@code false}.
+ * This is a placeholder filter intended to be used in data structuring definition.
+ * <p>
+ * <ul>
+ *   <li>EXCLUDE or Filter ==> Filter</li>
+ *   <li>EXCLUDE and Filter ==> EXCLUDE</li>
+ *   <li>EXCLUDE ==> INCLUDE</li>
+ * </ul>
+ * <p>
+ * The above does imply that the AND opperator can short circuit on encountering ALL.
+ *
+ * @author Jody Garnett (Refractions Research, Inc.)
+ * @author Martin Desruisseaux (Geomatys)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/ExcludeFilter.java $
+ */
+public final class ExcludeFilter implements Filter, Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -716705962006999508L;
+
+    /**
+     * Not extensible.
+     */
+    ExcludeFilter() {
+    }
+
+    /**
+     * Accepts a visitor.
+     */
+    public Object accept(FilterVisitor visitor, Object extraData) {
+        return visitor.visit(this, extraData);
+    }
+
+    /**
+     * Returns {@code false}, content is excluded.
+     */
+    public boolean evaluate(Object object) {
+        return false;
+    }
+
+    /**
+     * Returns a string representation of this filter.
+     */
+    @Override
+    public String toString() {
+        return "Filter.EXCLUDE";
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/Filter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/Filter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/Filter.java	(revision 28000)
@@ -0,0 +1,83 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter;
+
+import org.opengis.annotation.Extension;
+import org.opengis.annotation.XmlElement;
+import org.opengis.feature.Feature;
+
+
+/**
+ * Defines a constraint that can be checked against an instance of an object (Usually a Feature).
+ * <p?
+ * This is an abstract super type of the Filters defined by the Filter specification; you are not
+ * free to define your own filters. For extensibility please explore the definition of
+ * your own {@link Function}.
+ * <p>
+ * Often a filter is used to to define a set {@linkplain Feature feature} instances
+ * that are to be operated upon. The operating set can be comprised of one or more
+ * enumerated features or a set of features defined by specifying spatial and
+ * non-spatial constraints on the geometric and scalar properties of a feature type.
+ * <p>
+ * Roughly speaking, a filter encodes the information present in the {@code WHERE}
+ * clause of a SQL statement.  There are various subclasses of this class that
+ * implement many types of filters, such as simple property comparisons or spatial
+ * queries.
+ * <p>
+ * The second use of Filter focuses on expressing constraints (or Facets). This use
+ * places restrictions on the allowable and is captured as part of schema information
+ * (@linkplain FeatureType). This is similar to the XML concept of "facets".
+ * </p>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/Filter.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("Filter")
+public interface Filter {
+    /**
+     * Placeholder Filter that evaulates to {@code true}.
+     * <p>
+     * Filtering a set with {@code Filter.INCLUDE} results in the origional set.
+     */
+    IncludeFilter INCLUDE = new IncludeFilter();
+
+    /**
+     * Placeholder Filter that evaulates to {@code false}.
+     * <p>
+     * Filtering a set with {@code Filter.EXCLUDE} results in the empty Set.
+     */
+    ExcludeFilter EXCLUDE = new ExcludeFilter();
+
+    /**
+     * Give an object, this method determines if the test(s) represented by this filter object
+     * are passed.
+     * <p>
+     * This ability is used to allow Queries against both Features and and non spatial data (such as Record) and
+     * to express constraints on permissable data values.
+     * </p>
+     * @param object
+     * @return <code>true</true> if the test(s) are passed for the provided object
+     */
+    boolean evaluate(Object object);
+
+    /**
+     * Accepts a visitor.
+     * <p>
+     * Implementations of all subinterfaces must have with a
+     * method whose content is the following:
+     * <pre>return visitor.{@linkplain FilterVisitor#visit visit}(this, extraData);</pre>
+     * </p>
+     */
+    @Extension
+    Object accept(FilterVisitor visitor, Object extraData);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/FilterFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/FilterFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/FilterFactory.java	(revision 28000)
@@ -0,0 +1,114 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter;
+
+import java.util.List;
+import java.util.Set;
+
+import org.opengis.filter.capability.FunctionName;
+import org.opengis.filter.expression.Add;
+import org.opengis.filter.expression.Divide;
+import org.opengis.filter.expression.Expression;
+import org.opengis.filter.expression.Function;
+import org.opengis.filter.expression.Literal;
+import org.opengis.filter.expression.Multiply;
+import org.opengis.filter.expression.PropertyName;
+import org.opengis.filter.expression.Subtract;
+import org.opengis.filter.identity.FeatureId;
+import org.opengis.filter.identity.Identifier;
+
+
+/**
+ * Interface whose methods allow the caller to create instances of the various
+ * {@link Filter} and {@link Expression} subclasses.
+ * <p>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/FilterFactory.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+public interface FilterFactory {
+        /**
+         * The FilterCapabilities data structure is used to describe the abilities of
+         * this FilterFactory, it includes restrictions on the available spatial operations,
+         * scalar operations, lists the supported functions, and describes what geometry
+         * literals are understood.
+         * @return FilterCapabilities describing the abilities of this FilterFactory
+         */
+        // FilterCapabilities getCapabilities();
+        
+////////////////////////////////////////////////////////////////////////////////
+//
+//  IDENTIFIERS
+//
+////////////////////////////////////////////////////////////////////////////////
+    /** Creates a new feautre id from a string */
+    FeatureId featureId(String id);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//  FILTERS
+//
+////////////////////////////////////////////////////////////////////////////////
+
+    /** {@code AND} filter between two filters. */
+    And and(Filter f, Filter g);
+
+    /** {@code AND} filter between a list of filters. */
+    And and(List<Filter> f);
+
+    /** {@code OR} filter between two filters. */
+    Or or(Filter f, Filter g);
+
+    /** {@code OR} filter between a list of filters. */
+    Or or (List<Filter> f);
+
+    /** Reverses the logical value of a filter. */
+    Not not(Filter f);
+
+    /** Passes only for objects that have one of the IDs given to this object. */
+    Id id(Set<? extends Identifier> ids);
+
+    /** Retrieves the value of a {@linkplain org.opengis.feature.Feature feature}'s property. */
+    PropertyName property(String name);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//  EXPRESSIONS
+//
+////////////////////////////////////////////////////////////////////////////////
+
+    /** Computes the numeric addition of the first and second operand. */
+    Add       add(Expression expr1, Expression expr2);
+
+    /** Computes the numeric quotient resulting from dividing the first operand by the second. */
+    Divide    divide(Expression expr1, Expression expr2);
+
+    /** Computes the numeric product of their first and second operand. */
+    Multiply  multiply(Expression expr1, Expression expr2);
+
+    /** Computes the numeric difference between the first and second operand. */
+    Subtract  subtract(Expression expr1, Expression expr2);
+
+    /** Call into some implementation-specific function. */
+    Function  function(String name, Expression ... args);
+
+    /** A constant, literal value that can be used in expressions. */
+    Literal  literal(Object obj);
+
+    ////////////////////////////////////////////////////////////////////////////////
+    //
+    //  CAPABILITIES
+    //
+    ////////////////////////////////////////////////////////////////////////////////
+    /** function name */
+    FunctionName functionName(String name, int nargs);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/FilterFactory2.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/FilterFactory2.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/FilterFactory2.java	(revision 28000)
@@ -0,0 +1,46 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter;
+
+import org.opengis.filter.expression.PropertyName;
+import org.xml.sax.helpers.NamespaceSupport;
+
+
+/**
+ * Allows creation of additional Filter constructs.
+ * <p>
+ * Why do we need this? Because not all implementations are going
+ * to be using geoapi Geometry. This allows the creation of complient
+ * filters with SFSQL Geometry constructs. Consider this a bridge to
+ * existing projects allowing GeoAPI to be used.
+ * </p>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/FilterFactory2.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.1</A>
+ * @author Jody Garnett, Refractions Research Inc.
+ * @since GeoAPI 2.1
+ */
+public interface FilterFactory2 extends FilterFactory {
+////////////////////////////////////////////////////////////////////////////////
+//
+//  FILTERS
+//
+////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Retrieves the value of a {@linkplain org.opengis.feature.Feature feature}'s property.
+     * 
+     * @param xpath XPath expression (subject to the restrictions of filter specificaiton)
+     * @param namespaceContext Used to interpret any namespace prefixs in above xpath expression
+     * @return PropertyName
+     */
+     
+    PropertyName property(String xpath, NamespaceSupport namespaceContext);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/FilterVisitor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/FilterVisitor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/FilterVisitor.java	(revision 28000)
@@ -0,0 +1,59 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter;
+
+import org.opengis.annotation.Extension;
+
+
+/**
+ * Visitor with {@code visit} methods to be called by {@link Filter#accept Filter.accept(...)}.
+ * <p>
+ * Consider: It is unclear if this visitor should be applied directly to Filter, or should be walked accross
+ * the data structure by hand.  The standard complient structure is well defined, and this should negate
+ * the need for a formal visitor (we don't have internal structure we are hiding).
+ * </p>
+ * <p>
+ * There is still a very valid use for FilterVisitor, a instance may implement both FilterVisitor and ExpressionVisitor
+ * and ExpressionVisitory in one direction, and a FilterVisitor and a StyleVisitor in the other. The ability
+ * to directly focus on transforming data within a larger structure is something a normal data walk
+ * can not accomplish in a scalable manner.
+ * </p>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/FilterVisitor.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@Extension
+public interface FilterVisitor {
+
+    /**
+     * Visit {@link Filter#EXCLUDE} (often used during data structure transformations).
+     *
+     * @param filter {@link Filter#EXCLUDE}.
+     * @param extraData Value object provided to visitor
+     * @return subclass supplied
+     */
+    Object visit(ExcludeFilter filter, Object extraData);
+
+    /**
+     * Visit {@link Filter#INCLUDE} (often used during data structure transformations).
+     *
+     * @param filter {@link Filter#INCLUDE}.
+     * @param extraData Value object provided to visitor
+     * @return subclass supplied
+     */
+    Object visit(IncludeFilter filter, Object extraData);
+
+    Object visit(And filter,                            Object extraData);
+    Object visit(Id filter,                             Object extraData);
+    Object visit(Not filter,                            Object extraData);
+    Object visit(Or filter,                             Object extraData);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/Id.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/Id.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/Id.java	(revision 28000)
@@ -0,0 +1,50 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter;
+
+import java.util.Set;
+
+import org.opengis.filter.identity.Identifier;
+
+/**
+ * A filter that passes only the Identifiers listed.
+ * <p>
+ * This application of this filter for Features is well established:
+ * <ul>
+ *   <li>FeatureId - used for GML2 Features</li>
+ *   <li>GeometryId - used for GML3 Features and Geometry constructs</li>
+ * </ul>
+ * We also have the following identifiers:
+ * <ul>
+ *   <li>RecordId - from CSW-2</li>
+ *   <li>ObjectId - from CSW-2</li>
+ * </ul>
+ * <p>
+ * You can check what kind of Identifiers are supported using:<pre><code>
+ * idCapabilities.hasFID() == true; // for FeatureId
+ * idCapabilities.hasEID() == true; // no idea ...
+ * </code></pre>
+ * 
+ * @author Chris Dillard (SYS Technologies)
+ * @author Justin Deoliveira (The Open Planning Project)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/Id.java $
+ */
+public interface Id extends Filter {
+    /**
+     * Set of IDs representing the Identifiers used by this filter.
+     */
+    Set<Object> getIDs();
+
+    /**
+     * Returns the set of identifiers used by this filter.
+     */
+    Set<Identifier> getIdentifiers();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/IncludeFilter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/IncludeFilter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/IncludeFilter.java	(revision 28000)
@@ -0,0 +1,65 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter;
+
+import java.io.Serializable;
+
+
+/**
+ * Indicating "no filtering", evaluates to {@code true}.
+ * This is a placeholder filter intended to be used in data structuring definition.
+ * <p>
+ * <ul>
+ *   <li>INCLUDE or  Filter ==> INCLUDE</li>
+ *   <li>INCLUDE and Filter ==> Filter</li>
+ *   <li>not INCLUDE ==> EXCLUDE</li>
+ * </ul>
+ * <p>
+ * The above does imply that the OR opperator can short circuit on encountering NONE.
+ *
+ * @author Jody Garnett (Refractions Research, Inc.)
+ * @author Martin Desruisseaux (Geomatys)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/IncludeFilter.java $
+ */
+public final class IncludeFilter implements Filter, Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -8429407144421087160L;
+
+    /**
+     * Not extensible.
+     */
+    IncludeFilter() {
+    }
+
+    /**
+     * Accepts a visitor.
+     */
+    public Object accept(FilterVisitor visitor, Object extraData) {
+        return visitor.visit( this, extraData );
+    }
+
+    /**
+     * Returns {@code true}, content is included.
+     */
+    public boolean evaluate(Object object) {
+        return true;
+    }
+
+    /**
+     * Returns a string representation of this filter.
+     */
+    @Override
+    public String toString() {
+        return "Filter.INCLUDE";
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/Not.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/Not.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/Not.java	(revision 28000)
@@ -0,0 +1,35 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter;
+
+// Annotations
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * Reverses the logical value of an expression.
+ * <p>
+ * You can check if the Not operation is supported using:<pre><code>
+ * scalarCapabilities.hasLogicalOperators() == true
+ * </code></pre>
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/Not.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("Not")
+public interface Not extends Filter {
+    /**
+     * The filter to reverse.
+     */
+    Filter getFilter();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/Or.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/Or.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/Or.java	(revision 28000)
@@ -0,0 +1,35 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter;
+
+// Annotations
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * {@linkplain #evaluate Evaluates} to {@code true} if any of the combined expressions evaluate to {@code true}.
+ * <p>
+ * This interface exposes no additional methods beyond those of {@link BinaryLogicOperator}.
+ * It only serves as a marker of what type of operator this is.
+ * </p>
+ * <p>
+ * You can check if the Or operation is supported using:<pre><code>
+ * scalarCapabilities.hasLogicalOperators() == true
+ * </code></pre>
+ * 
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/Or.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("Or")
+public interface Or extends BinaryLogicOperator {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/capability/FunctionName.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/capability/FunctionName.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/capability/FunctionName.java	(revision 28000)
@@ -0,0 +1,44 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    (C) 2001-2004 EXSE, Department of Geography, University of Bonn
+ *                  lat/lon Fitzke/Fretter/Poth GbR
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation; either
+ *    version 2.1 of the License, or (at your option) any later version.
+ *   
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.opengis.filter.capability;
+
+// Annotations
+
+/**
+ * Function provided in a filter capabilities.
+ * <p>
+ * <pre>
+ * &lt;xsd:complexType name="FunctionNameType">
+ *     &lt;xsd:simpleContent>
+ *        &lt;xsd:extension base="xsd:string">
+ *           &lt;xsd:attribute name="nArgs" type="xsd:string" use="required"/>
+ *        &lt;/xsd:extension>
+ *     &lt;/xsd:simpleContent>
+ *  &lt;/xsd:complexType>
+ * </pre>
+ * </p>
+ * 
+ * @author <a href="mailto:tfr@users.sourceforge.net">Torsten Friebe </A>
+ * @author Justin Deoliveira, The Open Planning Project
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/capability/FunctionName.java $
+ */
+public interface FunctionName extends Operator {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/capability/Operator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/capability/Operator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/capability/Operator.java	(revision 28000)
@@ -0,0 +1,79 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    (C) 2001-2004 EXSE, Department of Geography, University of Bonn
+ *                  lat/lon Fitzke/Fretter/Poth GbR
+ *    
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation; either
+ *    version 2.1 of the License, or (at your option) any later version.
+ *   
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ */
+package org.opengis.filter.capability;
+
+// Annotations
+import static org.opengis.annotation.Specification.UNSPECIFIED;
+
+import org.opengis.annotation.UML;
+
+/**
+ * Indicates a supported Operator.
+ * <p>
+ * The operator that is supported is indicated by the getName() field, these
+ * names are formally defined to match:
+ * <ul>
+ * <li>A subclass of Filter. Examples include "BBOX" and "EqualsTo"
+ * <li>A subclass of Expression or Function. Examples include "ADD" and "Length"
+ * </ul>
+ * Each filter subclass has an associated name (such as BBOX or EqualsTo), you
+ * can use this name to determine if a matching Operator is defined as part of
+ * FilterCapabilities.
+ * 
+ * @author <a href="mailto:tfr@users.sourceforge.net">Torsten Friebe</A>
+ * @author Jody Garnett (Refractions Research)
+ * @todo Which relationship with Filter and expressions?
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/capability/Operator.java $
+ */
+public interface Operator {	
+    /**
+     * Name of supported Operator.
+     * <p>
+     * Each filter subclass has an associated name (such as BBOX or EqualsTo), you
+     * can use this name to determine if a matching Operator is defined as part of
+     * FilterCapabilities. 
+     */
+    @UML(identifier="name", specification=UNSPECIFIED)
+    String getName();
+    
+    /**
+     * The supported interface enabled by this Operator.
+     * <p>
+     * The mapping from getName() to supported interface is formally defined; and
+     * is must agree with the interfaces defined in org.opengis.filter. Because this
+     * binding is formal we should replace Operator here with a CodeList and capture
+     * it as part of the GeoAPI project.
+     * </p>
+     * @return Interface marked as supported by this Operator
+     */
+    //Class getSupportedType();
+    
+    /**
+     * Equals should be implemented simply in terms of getName()
+     */
+    ///@Override
+    boolean equals(Object obj);
+    /**
+     * HashCode should be implemented simply in terms of getName().
+     */
+    ///@Override
+    int hashCode();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Add.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Add.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Add.java	(revision 28000)
@@ -0,0 +1,34 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.expression;
+
+// Annotations
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * Encodes the operation of addition.
+ * <p>
+ * Instances of this interface implement their {@link #evaluate evaluate} method by
+ * computing the numeric addition of their {@linkplain #getExpression1 first} and
+ * {@linkplain #getExpression2 second} operand.
+ * </p>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/expression/Add.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("Add")
+public interface Add extends BinaryExpression {
+	/** Operator name used to check FilterCapabilities */
+	public static String NAME = "Add"; // NO_UCD
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/BinaryExpression.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/BinaryExpression.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/BinaryExpression.java	(revision 28000)
@@ -0,0 +1,42 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.expression;
+
+// Annotations
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * Abstract base class for the various filter expressions that compute some
+ * value from two input values.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/expression/BinaryExpression.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("BinaryOperatorType")
+public interface BinaryExpression extends Expression {
+    /**
+     * Returns the expression that represents the first (left) value that will
+     * be used in the computation of another value.
+     */
+    @XmlElement("expression")
+    Expression getExpression1();
+
+    /**
+     * Returns the expression that represents the second (right) value that will
+     * be used in the computation of another value.
+     */
+    @XmlElement("expression")
+    Expression getExpression2();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Divide.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Divide.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Divide.java	(revision 28000)
@@ -0,0 +1,34 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.expression;
+
+// Annotations
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * Encodes the operation of division where the first argument is divided by the second argument.
+ * <p>
+ * Instances of this interface implement their {@link #evaluate evaluate} method by
+ * computing the numeric quotient resulting from dividing the {@linkplain #getExpression1 first}
+ * operand by the {@linkplain #getExpression2 second}. The second argument or expression cannot
+ * evaluate to zero.
+ * </p>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/expression/Divide.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("Div")
+public interface Divide extends BinaryExpression {
+	/** Operator name used to check FilterCapabilities */
+	public static String NAME = "Div"; // NO_UCD
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Expression.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Expression.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Expression.java	(revision 28000)
@@ -0,0 +1,78 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.expression;
+
+import org.opengis.annotation.Extension;
+import org.opengis.annotation.XmlElement;
+import org.opengis.feature.Feature;
+
+
+/**
+ * Interface for all the OGC Filter elements that compute values.
+ * <p>
+ * The most common use is with potentially using {@linkplain Feature feature} and
+ * metadata.  The ability to access "attributes" based on the provided content is
+ * defined based on XPath queries currently.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/expression/Expression.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @author Justin Deoliveira (The Open Planning Project)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("expression")
+public interface Expression {
+
+    /**
+     * Evaluates the given expression based on the content of the given object.
+     */
+    @Extension
+    Object evaluate(Object object);
+
+    /**
+     * Evaluates the given expressoin based on the content of the given object
+     * and the context type.
+     * <p>
+     * The {@code context} parameter is used to control the type of the
+     * result of the expression. A particular expression may not be able to evaluate
+     * to an instance of {@code context}. Therefore to be safe calling code
+     * should do a null check on the return value of this method, and call {@link #evaluate(Object)}
+     * if neccessary. Example:
+     * <pre>
+     *  Object input = ...;
+     *  String result = expression.evaluate( input, String.class );
+     *  if ( result == null ) {
+     *     result = expression.evalute( input ).toString();
+     *  }
+     *  ...
+     * </pre>
+     * </p>
+     * <p>
+     * Implementations that can not return a result as an instance of {@code context}
+     * should return {@code null}.
+     * </p>
+     * @param <T> The type of the returned object.
+     * @param object The object to evaluate the expression against.
+     * @param context The type of the resulting value of the expression.
+     *
+     * @return Evaluates the given expression based on the content of the given object an
+     *         an instance of {@code context}.
+     */
+    @Extension
+    <T> T evaluate( Object object, Class<T> context );
+
+    /**
+     * Accepts a visitor. Subclasses must implement with a method whose content is the following:
+     * <pre>return visitor.{@linkplain ExpressionVisitor#visit visit}(this, extraData);</pre>
+     */
+    @Extension
+    Object accept(ExpressionVisitor visitor, Object extraData);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/ExpressionVisitor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/ExpressionVisitor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/ExpressionVisitor.java	(revision 28000)
@@ -0,0 +1,54 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.expression;
+
+// Annotation
+import org.opengis.annotation.Extension;
+
+
+/**
+ * Visitor with {@code visit} methods to be called by {@link Expression#accept Expression.accept(...)}.
+ * <p>
+ * Please note that a generic visit( Expression ) entry point has not been provided, although Expression
+ * forms a heirarchy for your convience it is not an open heirarchy. If you need to extend this system
+ * please make use of {code Function}, this will allow extention while remaining standards complient.
+ * </p>
+ * <p>
+ * It is very common for a single instnace to implement both ExpressionVisitor and FilterVisitor.
+ * </p>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/expression/ExpressionVisitor.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@Extension
+public interface ExpressionVisitor {
+    /**
+     * Used to visit a Expression.NIL, also called for <code>null</code> where an
+     * expression is expected.
+     * <p>
+     * This is particularly useful when doing data transformations, as an example when
+     * using a StyleSymbolizer Expression.NIL can be used to represent the default
+     * stroke color.
+     * </p>
+     * @param extraData
+     * @return implementation specific
+     */
+    Object visit(NilExpression  expression, Object extraData);
+    Object visit(Add            expression, Object extraData);
+    Object visit(Divide         expression, Object extraData);
+    Object visit(Function       expression, Object extraData);
+    Object visit(Literal        expression, Object extraData);
+    Object visit(Multiply       expression, Object extraData);
+    Object visit(PropertyName   expression, Object extraData);
+    Object visit(Subtract       expression, Object extraData);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Function.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Function.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Function.java	(revision 28000)
@@ -0,0 +1,52 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */package org.opengis.filter.expression;
+
+import java.util.List;
+
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * Instances of this class represent a function call into some implementation-specific
+ * function.
+ * <p>
+ * Each execution environment should provide a list of supported functions
+ * (and the number of arguments they expect) as part of a FilterCapabilities
+ * data structure.
+ * <p>
+ * This is included for completeness with respect to the
+ * OGC Filter specification.  However, no functions are required to be supported
+ * by that specification.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/expression/Function.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @version <A HREF="http://www.opengeospatial.org/standards/symbol">Symbology Encoding Implementation Specification 1.1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("Function")
+public interface Function extends Expression {
+    /**
+     * Returns the name of the function to be called.  For example, this might
+     * be "{@code cos}" or "{@code atan2}".
+     * <p>
+     * You can use this name to look up the number of required parameters
+     * in a FilterCapabilities data structure. For the specific meaning of
+     * the required parameters you will need to consult the documentation.
+     */
+    String getName();
+
+   /**
+     * Returns the list subexpressions that will be evaluated to provide the
+     * parameters to the function.
+     */
+    List<Expression> getParameters();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Literal.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Literal.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Literal.java	(revision 28000)
@@ -0,0 +1,45 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.expression;
+
+// Annotations
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * Instances of this interface provide a constant, literal value that can be
+ * used in expressions.
+ * <p>
+ * The {@link #evaluate evaluate} method of this class must return the same
+ * value as {@link #getValue()}.
+ * </p>
+ * <p>
+ * It should be noted that content of getValue() may be persisted with with
+ * XML based technologies. As an example a geoapi Geometry may be written out
+ * uding GML3, while a JTS Geometry may be written out using GML2. You should
+ * not assume that the same instance will be made available to all callers,
+ * please limit your self to pure data objects and don't use Literal to pass
+ * state or operations between systems.
+ * <p>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/expression/Literal.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("Literal")
+public interface Literal extends Expression {
+    /**
+     * Returns the constant value held by this object.
+     */
+    Object getValue();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Multiply.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Multiply.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Multiply.java	(revision 28000)
@@ -0,0 +1,33 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.expression;
+
+// Annotations
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * Encodes the operation of multiplication.
+ * <p>
+ * Instances of this interface implement their {@link #evaluate evaluate} method by
+ * computing the numeric product of their {@linkplain #getExpression1 first} and
+ * {@linkplain #getExpression2 second} operand.
+ * </p>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/expression/Multiply.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("Mul")
+public interface Multiply extends BinaryExpression {
+	/** Operator name used to check FilterCapabilities */
+	public static String NAME = "Mul"; // NO_UCD
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/NilExpression.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/NilExpression.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/NilExpression.java	(revision 28000)
@@ -0,0 +1,66 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.expression;
+
+import java.io.Serializable;
+
+
+/**
+ * Placeholder class used to represent a NIL expression, evaluates to {@code null}.
+ * This placeholder class allows data structures to avoid the use of {@code null}.
+ * Please note that {@link Expression#NIL} is not considered a Literal with value
+ * {@code null} (since the literal may have its value changed).
+ *
+ * @author Jody Garnett (Refractions Research, Inc.)
+ * @author Martin Desruisseaux (Geomatys)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/expression/NilExpression.java $
+ */
+public final class NilExpression implements Expression, Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 4999313240542653655L;
+
+    /**
+     * Not extensible.
+     */
+    NilExpression() {
+    }
+
+    /**
+     * Accepts a visitor.
+     */
+    public Object accept(ExpressionVisitor visitor, Object extraData) {
+        return visitor.visit(this, extraData);
+    }
+
+    /**
+     * Returns {@code null}.
+     */
+    public Object evaluate(Object object) {
+        return null;
+    }
+
+    /**
+     * Returns {@code null}.
+     */
+    public <T> T evaluate(Object object, Class<T> context) {
+        return null;
+    }
+
+    /**
+     * Returns a string representation of this expression.
+     */
+    @Override
+    public String toString() {
+        return "Expression.NIL";
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/PropertyName.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/PropertyName.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/PropertyName.java	(revision 28000)
@@ -0,0 +1,51 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.expression;
+
+// Annotations
+import org.opengis.annotation.XmlElement;
+import org.xml.sax.helpers.NamespaceSupport;
+
+
+/**
+ * Expression class whose value is computed by retrieving the value indicated
+ * by the provided name.
+ * <p>
+ * The most common applicatoin of this is to retrive
+ * a {@linkplain org.opengis.feature.Feature feature}'s property using
+ * an xpath expression.
+ * </p>
+ * <p>
+ * Please note that the Filter specification allows a limited subset of
+ * XPath to be used for the PropertyName. We encourage implementations to
+ * match this functionality.
+ * </p>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/expression/PropertyName.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("PropertyName")
+public interface PropertyName extends Expression {
+    /**
+     * Returns the name of the property whose value will be returned by the
+     * {@link #evaluate evaluate} method.
+     */
+    String getPropertyName();
+    
+    /**
+     * Returns namespace context information, or null if unavailable/inapplicable
+     * 
+     * @return namespace context information, or null if unavailable/inapplicable
+     */
+    NamespaceSupport getNamespaceContext();
+
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Subtract.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Subtract.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/Subtract.java	(revision 28000)
@@ -0,0 +1,33 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005 Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.expression;
+
+// Annotations
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * Encodes the operation of subtraction where the second argument is subtracted from the first.
+ * <p>
+ * Instances of this interface implement their {@link #evaluate evaluate} method by
+ * computing the numeric difference between the {@linkplain #getExpression1 first} and
+ * {@linkplain #getExpression2 second} operand.
+ * </p>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/expression/Subtract.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("Sub")
+public interface Subtract extends BinaryExpression {
+	/** Operator name used to check FilterCapabilities */
+	public static String NAME = "Sub"; // NO_UCD
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/expression/package.html	(revision 28000)
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.opengis.filter.expression</TITLE>
+  </HEAD>
+  <BODY>
+    An <CITE>expression</CITE> is a combination of one or more elements that
+    evaluate to single {@link java.lang.Object} value.
+    
+    The following is adapted from Filter encoding specifications:
+    <ul>
+    <li><A HREF="http://www.opengis.org/docs/02-059.pdf">Filter Encoding 1.0</a>
+    <li><A HREF="http://portal.opengeospatial.org/files/?artifact_id=8340">OpenGIS&reg; Filter Encoding Implementation Specification Version 1.1</a>
+    <li><A HREF="http://portal.opengeospatial.org/files/?artifact_id=5929">OpenGIS&reg; Catalogue Service Implementation Specification 2.0.1</a>
+    </ul>
+
+    <P ALIGN="justify">An <CITE>expression</CITE> can be formed using the elements:
+    {@link org.opengis.filter.expression.Add}, {@link org.opengis.filter.expression.Subtract},
+    {@link org.opengis.filter.expression.Multiply}, {@link org.opengis.filter.expression.Divide},
+    {@link org.opengis.filter.expression.PropertyName}, {@link org.opengis.filter.expression.Literal}
+    and {@link org.opengis.filter.expression.Function}. They all belong to the substitution group
+    expression which means that any of them can be used wherever an expression is called for. In addition,
+    the combinaison of these elements are themselves expressions and can be used wherever an expression is
+    called for.</P>
+
+    <H3>Arithmetic operators</H3>
+    <P ALIGN="justify">The elements defined in this package are used to encode the fundamental arithmetic
+    operations of addition, subtraction, multiplication and division. Arithmetic operators are binary
+    operators meaning that they accept two arguments and evaluate to a single result.</P>
+
+    <H3>Literals</H3>
+    <P ALIGN="justify">A literal value is any part of a statement or expression that is to
+    be used exactly as it is specified, rather than as a variable or other element. The
+    {@link org.opengis.filter.expression.Literal} element is used to encode literal scalar
+    and geometric values.</P>
+
+    <H3>Functions</H3>
+    <P ALIGN="justify">A function is a named procedure that performs a distinct computation.
+    A function may accept zero or more arguments as input and generates a single result. A
+    function is composed of the name of the function, encoded using the attribute name, and
+    zero or more arguments contained within the {@link org.opengis.filter.expression.Function}
+    element. The arguments themselves are {@linkplain org.opengis.filter.expression.Expression expressions}.</P>
+    
+    <h3>Data Access<h3>
+    <P ALIGN="justify">Data access is acomplished by means of {@link org.opengis.filter.expression.PropertyName}
+    expressions. These Expressions are independent of the data being queried and form the foundation of
+    a, very simple, general query language offering independence specific bindings to
+    Feature, Metadata and Record data structures.
+    </p>
+    
+    <h3>Filter Encodings<h3>
+    <P ALIGN="justify">At the time of this writing the Filter API has standard encodings for XML (Filter 1.0
+    and Filter 1.1) and Text (a BNF form is provided in the Catalog 2.0.1 specification above). You should
+    be warned that not all content can be expressed in all encodings, please refer to the javadocs for
+    specific limitations.</p>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/identity/FeatureId.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/identity/FeatureId.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/identity/FeatureId.java	(revision 28000)
@@ -0,0 +1,33 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.identity;
+
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * Feature identifier.
+ * Features are identified as strings.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/identity/FeatureId.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @author Justin Deoliveira (The Open Planning Project)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("FeatureId")
+public interface FeatureId extends Identifier {
+    /**
+     * The identifier value, which is a string.
+     */
+    @XmlElement("fid")
+    String getID();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/identity/Identifier.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/identity/Identifier.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/identity/Identifier.java	(revision 28000)
@@ -0,0 +1,59 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.identity;
+
+/**
+ * An object identifier.
+ * <p>
+ * This class is an abstract base for identifiers. Some known identifiers are:
+ * <ul>
+ *   <li>FeatureId</li>
+ *   <li>GMLObjectId</li>
+ *   <li>RecordId</li>
+ * </ul>
+ * </p>
+ *
+ * @param <T> The type of the identifier itself.
+ * @param <O> The type of objects to be identified.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/identity/Identifier.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Jody Garnett (Refractions Research)
+ * @author Justin Deoliveira (The Open Planning Project)
+ */
+public interface Identifier {
+    /**
+     * Returns the identifier itself.
+     */
+    Object getID();
+
+    /**
+     * Identifier is a data object, equals is based just on getID()
+     * @param obj
+     * @return true if obj is an Identifier with the same getID()
+     */
+    ///@Override
+    public boolean equals(Object obj);
+    
+    /**
+     * Identifier is a data object, hashCode is based just on getID()
+     * @return hashCode based on getID()
+     */
+    ///@Override
+    public int hashCode();
+    
+    /**
+     * Returns a string representation of the identifier.
+     * @return getID().toString()
+     */
+    ///@Override 
+    String toString();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/identity/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/identity/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/identity/package.html	(revision 28000)
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.opengis.filter.identity</TITLE>
+  </HEAD>
+  <BODY>
+    An <CITE>Identifier</CITE> indicates object identity requested during data query or reference.
+    
+    The following is adapted from the following specifications:
+    <ul>
+    <li><A HREF="http://portal.opengeospatial.org/files/?artifact_id=8340">OpenGIS&reg; Filter Encoding Implementation Specification Version 1.1</a>
+    <li><A HREF="http://portal.opengeospatial.org/files/?artifact_id=5929">OpenGIS&reg; Catalogue Service Implementation Specification 2.0.1</a>
+    </ul>
+
+    <H3>Catalog and Web Feature Server</H3>
+    <P ALIGN="justify">Both the Catalog and Web Feature Server specifications use specific identifiers (like FeatureId)
+    during their requests and responses.</P>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/package.html	(revision 28000)
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.opengis.filter</TITLE>
+  </HEAD>
+  <BODY>
+    Filters {@linkplain org.opengis.feature.Feature features} according their properties.
+    A <CITE>filter expression</CITE> is a construct used to constraints the property
+    values of an object type for the purpose of identifying a subset of object instances
+    to be operated upon in some manner.
+    <p>
+    The following is adapted from the <a href="http://www.opengeospatial.org/standards/filter">OpenGIS&reg;
+    Filter Encoding Implementation Specification</a>:
+    <ul>
+    <li><a href="http://portal.opengeospatial.org/files/?artifact_id=1171">02-059 1.0 Filter Encoding</a>
+    <li><a href="http://portal.opengeospatial.org/files/?artifact_id=1171">04-095 1.1 Filter Encoding Implementation Specification</a>
+    </ul>
+
+    <H3>Comparison operators</H3>
+    <P ALIGN="justify">A comparison operator is used to form expressions that evaluate
+    the mathematical comparison between two arguments. If the arguments satisfy the comparison
+    then the expression {@linkplain org.opengis.filter.Filter#evaluate evaluates} to {@code true}.
+    Otherwise the expression evaluates to {@code false}.</P>
+
+    <P ALIGN="justify">In addition to the standard set
+    ({@code =},{@code <},{@code >},{@code >=},{@code <=},{@code <>}) of comparison operators,
+    this package defines the elements {@link org.opengis.filter.PropertyIsLike},
+    {@link org.opengis.filter.PropertyIsBetween} and {@link org.opengis.filter.PropertyIsNull}.</P>
+
+    <H3>Logical operators</H3>
+    <P ALIGN="justify">A logical operator can be used to combine one or more conditional expressions.
+    The logical operator {@link org.opengis.filter.And} evaluates to {@code true} if all the combined
+    expressions evaluate to {@code true}. The operator {@link org.opengis.filter.Or} operator evaluates
+    to {@code true} is any of the combined expressions evaluate to {@code true}. The
+    {@link org.opengis.filter.Not} operator reverses the logical value of an expression.
+    The elements {@code And}, {@code Or} and {@code Not} can be used to combine scalar,
+    spatial and other logical expressions to form more complex compound expressions.</P>
+    
+    <H3>Identity</H3>
+    <P ALIGN="justify">Identity can be checked using {@link org.opengis.filter.Id}, selected objects
+    will are matched against a set of {@link org.opengis.filter.identiy.Identifier}.</p>
+      </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/sort/NullSortBy.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/sort/NullSortBy.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/sort/NullSortBy.java	(revision 28000)
@@ -0,0 +1,75 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.sort;
+
+import java.io.Serializable;
+
+import org.opengis.filter.expression.PropertyName;
+
+
+/**
+ * Default implementation of {@link SortBy} as a "null object". Used for {@link SortBy} constants.
+ *
+ * @author Jody Garnett (Refractions Research)
+ * @author Martin Desruisseaux (Geomatys)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/sort/NullSortBy.java $
+ */
+final class NullSortBy implements SortBy, Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -4846119001746135007L;
+
+    /**
+     * The sort order.
+     */
+    private final SortOrder order;
+
+    /**
+     * Creates a new Null object for the specified sort order.
+     */
+    NullSortBy(final SortOrder order) {
+        this.order = order;
+    }
+
+    /**
+     * Natural order usually associated with FID, or Key Attribtues.
+     */
+    public PropertyName getPropertyName() {
+        return null;
+    }
+
+    /**
+     * Returns the sort order.
+     */
+    public SortOrder getSortOrder() {
+        return order;
+    }
+
+    /**
+     * Returns a hash code value for this object.
+     */
+    @Override
+    public int hashCode() {
+        return (int) serialVersionUID ^ order.hashCode();
+    }
+
+    /**
+     * Compares this object with the specified one for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object instanceof NullSortBy) {
+            return order.equals(((NullSortBy) object).order);
+        }
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/sort/SortBy.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/sort/SortBy.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/sort/SortBy.java	(revision 28000)
@@ -0,0 +1,103 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.sort;
+
+import org.opengis.filter.expression.PropertyName;
+
+
+/**
+ * Defines the sort order, based on a property and ascending/descending.
+ * <p>
+ * Having SortBy at the Filter level is an interesting undertaking of Filter 1.1
+ * support. Why you ask? It is at the Same level as Filter, it is not *used* by
+ * Filter itself. The services that make use of Filter, such as WFS are starting
+ * to make use of SortBy in the same breath.
+ * </p>
+ * <p>
+ * Where is SortBy used:
+ * <ul>
+ * <li>WFS 1.1 Query
+ * <li>CSW 2.0.1 AbstractQuery
+ * </ul>
+ * There may be more ...
+ * </p>
+ * <p>
+ * What this means is that the GeoTools Query will make use of this
+ * construct. As for sorting the result of an expression (where an
+ * expression matches more then one element), we will splice it in to
+ * AttributeExpression as an optional parameter. Note function is defined
+ * to return a single value (so we don't need to worry there).
+ * </p>
+ * @see <a href="http://schemas.opengis.net/filter/1.1.0/sort.xsd">
+ * @see <a href="http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
+ *
+ * @since GeoAPI 2.1
+ * @author Jody Garnett (Refractions Research)
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/sort/SortBy.java $
+ */
+public interface SortBy {
+    /**
+     * Used to indicate lack of a sorting order.
+     * <p>
+     * This is the default value for used when setting up a Query.
+     * </p>
+     */
+    SortBy[] UNSORTED = new SortBy[0];
+
+    /**
+     * Used to indicate "natural" sorting order, usually according
+     * FID (hopefully based on Key attribtues).
+     * <p>
+     * This is the order that is most likely to be available in optimzied
+     * form, if an Attribute is marked as "key" an optimized ordering should
+     * be considered avaialble.
+     * </p>
+     * <p>
+     * Non optimized orderings are will at the very least require as pass
+     * through the data to bring it into memory, you can assume somekind
+     * of TreeSet would be used. Where the nodes in the tree would indicate
+     * a list of FeatureIds assoicated with the node, in the order encountered.
+     * </p>
+     * <p>
+     * This is a "NullObject".
+     * </p>
+     */
+    SortBy NATURAL_ORDER = new NullSortBy(SortOrder.ASCENDING);
+
+    /**
+     * Indicate the reverse order, usually assoicated with "Fid".
+     * <p>
+     * This is a "NullObject".
+     * </p>
+     */
+    SortBy REVERSE_ORDER = new NullSortBy(SortOrder.DESCENDING);
+
+    /**
+     * Indicate property to sort by, specification is limited to PropertyName.
+     * <p>
+     * Not sure if this is allowed to be a xPath expression?
+     * <ul>
+     *   <li>It would be consist with our use in GeoTools</li>
+     *   <li>It would not seem to agree with the short hand notation
+     *       used by WFS1.1 (ie. "year A, month A, day A" )</li>
+     * </ul>
+     * </p>
+     * @todo Use QName
+     * @return Name of property to sort by.
+     */
+    PropertyName getPropertyName();
+
+    /**
+     * The the sort order - one of {@link SortOrder#ASCENDING ASCENDING}
+     * or {@link SortOrder#DESCENDING DESCENDING}.
+     */
+    SortOrder getSortOrder();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/sort/SortOrder.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/sort/SortOrder.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/sort/SortOrder.java	(revision 28000)
@@ -0,0 +1,109 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.sort;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.opengis.annotation.UML;
+import org.opengis.util.CodeList;
+
+import static org.opengis.annotation.Obligation.CONDITIONAL;
+import static org.opengis.annotation.Specification.OGC_02059;
+
+
+/**
+ * Captures the {@link SortBy} order, {@code ASC} or {@code DESC}.
+ *
+ * @see <a href="http://schemas.opengis.net/filter/1.1.0/sort.xsd">
+ * @author Jody Garnett (Refractions Research)
+ * @since GeoAPI 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/sort/SortOrder.java $
+ */
+public final class SortOrder extends CodeList<SortOrder> {
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = 7840334200112859571L;
+
+    /**
+     * The list of enumeration available in this virtual machine.
+     * <strong>Must be declared first!</strong>.
+     */
+    private static final List<SortOrder> VALUES = new ArrayList<SortOrder>(2);
+
+    /**
+     * Represents acending order.
+     * <p>
+     * Note this has the string representation of {@code "ASC"} to agree
+     * with the Filter 1.1 specification.
+     * </p>
+     */
+    @UML(identifier="ASC", obligation=CONDITIONAL, specification=OGC_02059)
+    public static final SortOrder ASCENDING  = new SortOrder("ASCENDING", "ASC");
+
+    /**
+     * Represents descending order.
+     * <p>
+     * Note this has the string representation of {@code "DESC"} to agree
+     * with the Filter 1.1 specification.
+     * </p>
+     */
+    @UML(identifier="DESC", obligation=CONDITIONAL, specification=OGC_02059)
+    public static final SortOrder DESCENDING = new SortOrder("DESCENDING", "DESC");
+
+    /**
+     * Constructs an enum with the given name. The new enum is
+     * automatically added to the list returned by {@link #values}.
+     *
+     * @param name The enum name. This name must not be in use by an other enum of this type.
+     * @param sqlKeyword The SQL keyword for this sorting order.
+     */
+    private SortOrder(final String name, final String sqlKeyword) {
+        super(name, VALUES);
+    }
+
+    /**
+     * Constructs an enum with identical name and SQL keyword.
+     * This is needed for {@link CodeList#valueOf} reflection.
+     */
+    private SortOrder(final String name) {
+        this(name, name);
+    }
+
+    /**
+     * Returns the list of {@code SortOrder}s.
+     *
+     * @return The list of codes declared in the current JVM.
+     */
+    public static SortOrder[] values() {
+        synchronized (VALUES) {
+            return VALUES.toArray(new SortOrder[VALUES.size()]);
+        }
+    }
+
+    /**
+     * Returns the list of enumerations of the same kind than this enum.
+     */
+    public SortOrder[] family() {
+        return values();
+    }
+
+    /**
+     * Returns the sort order that matches the given string, or returns a
+     * new one if none match it.
+     *
+     * @param code The name of the code to fetch or to create.
+     * @return A code matching the given name.
+     */
+    public static SortOrder valueOf(String code) {
+        return valueOf(SortOrder.class, code);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/sort/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/sort/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/sort/package.html	(revision 28000)
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.opengis.filter.sort</TITLE>
+  </HEAD>
+  <BODY>
+    An <CITE>SortBy</CITE> indicates the ordering requested during a data query.
+    
+    The following is adapted from the following specifications:
+    <ul>
+    <li><A HREF="http://portal.opengeospatial.org/files/?artifact_id=8340">OpenGIS&reg; Filter Encoding Implementation Specification Version 1.1</a>
+    <li><A HREF="http://portal.opengeospatial.org/files/?artifact_id=5929">OpenGIS&reg; Catalogue Service Implementation Specification 2.0.1</a>
+    </ul>
+
+    <P ALIGN="justify">An <CITE>SortBy</CITE> can be formed using the elements:
+    {@link org.opengis.filter.expression.Add}, {@link org.opengis.filter.expression.Subtract},
+    {@link org.opengis.filter.expression.Multiply}, {@link org.opengis.filter.expression.Divide},
+    {@link org.opengis.filter.expression.PropertyName}, {@link org.opengis.filter.expression.Literal}
+    and {@link org.opengis.filter.expression.Function}. They all belong to the substitution group
+    expression which means that any of them can be used wherever an expression is called for. In addition,
+    the combinaison of these elements are themselves expressions and can be used wherever an expression is
+    called for.</P>
+
+    <H3>FeatureCollections</H3>
+    <P ALIGN="justify">The contents of a FeatureCollection are not defined with respect to order.</P>
+
+    <H3>FeatureLists</H3>
+    <P ALIGN="justify">A FeatureList represents an ordered collection of features, possibly using a
+    siers of SortBy elements to define the intended order.</P>
+
+    <H3>Catalog and Web Feature Server</H3>
+    <P ALIGN="justify">Both the Catalog and Web Feature Server specifications all the use of SortBy
+    during requests.</P>
+    </p>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/spatial/BinarySpatialOperator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/spatial/BinarySpatialOperator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/spatial/BinarySpatialOperator.java	(revision 28000)
@@ -0,0 +1,46 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.spatial;
+
+// OpenGIS direct dependencies
+import org.opengis.filter.expression.Expression;
+
+// Annotations
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * Abstract superclass for filter operators that perform some sort of spatial
+ * comparison on two geometric objects.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/spatial/BinarySpatialOperator.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("BinarySpatialOpType")
+public interface BinarySpatialOperator extends SpatialOperator {
+	/**
+     * Returns an expression that will be evaluated to determine the first
+     * operand to the spatial predicate represented by this operator.  The
+     * result of evaluating this expression must be a geometry object.
+     */
+    @XmlElement("expression")
+    Expression getExpression1();
+
+    /**
+     * Returns an expression that will be evaluated to determine the second
+     * operand to the spatial predicate represented by this operator.  The
+     * result of evaluating this expression must be a geometry object.
+     */
+    @XmlElement("expression")
+    Expression getExpression2();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/spatial/DistanceBufferOperator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/spatial/DistanceBufferOperator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/spatial/DistanceBufferOperator.java	(revision 28000)
@@ -0,0 +1,29 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.spatial;
+
+// Annotations
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * Abstract superclass for spatial operators that check that one shape satisfies
+ * some relation to a buffer around another shape.  This could be used to find,
+ * for example, all the geometries that come within 10 meters of a river.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/spatial/DistanceBufferOperator.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("DistanceBufferType")
+public interface DistanceBufferOperator extends BinarySpatialOperator {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/spatial/SpatialOperator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/spatial/SpatialOperator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/spatial/SpatialOperator.java	(revision 28000)
@@ -0,0 +1,31 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.filter.spatial;
+
+// OpenGIS direct dependencies
+import org.opengis.filter.Filter;
+
+// Annotations
+import org.opengis.annotation.XmlElement;
+
+
+/**
+ * Abstract base class for operators that perform a spatial comparison on
+ * geometric attributes of a feature.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/filter/spatial/SpatialOperator.java $
+ * @version <A HREF="http://www.opengis.org/docs/02-059.pdf">Implementation specification 1.0</A>
+ * @author Chris Dillard (SYS Technologies)
+ * @since GeoAPI 2.0
+ */
+@XmlElement("SpatialOpsType")
+public interface SpatialOperator extends Filter {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/spatial/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/spatial/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/filter/spatial/package.html	(revision 28000)
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.opengis.filter.spatial</TITLE>
+  </HEAD>
+  <BODY>
+    A <CITE>spatial operator</CITE> determines whether its geometric arguments satisfy
+    the stated spatial relationship. The operator {@linkplain org.opengis.filter.Filter#evaluate evaluates}
+    to {@code true} if the spatial relationship is satisfied. Otherwise the operator evaluates to {@code false}.
+    The following is adapted from
+    <A HREF="http://www.opengis.org/docs/02-059.pdf">Filter encoding implementation</A>:
+
+    <P ALIGN="justify">{@linkplain org.opengis.filter.spatial.SpatialOperator Spatial operators}
+    are used to test whether the value of a geometric property, potentially referenced using the name of the
+    property, and a (potentially literal) geometric value satisfy the spatial relationship implied by the operator.
+    For example, the {@link org.opengis.filter.spatial.Overlaps} operator evaluates whether the
+    value of the specified geometric property and the specified literal geometric value spatially
+    overlap.</P>
+
+    <P ALIGN="justify">The {@link org.opengis.filter.spatial.BBOX} element is defined as a convenient
+    and more compact way of encoding the very common bounding box constraint based on the {@code gml:Box}
+    geometry. The {@code BBOX} operator should identify all geometries that spatially interact with the box
+    in some manner.</P>
+
+    <P ALIGN="justify">The spatial operators {@link org.opengis.filter.spatial.DWithin} and
+    {@link org.opengis.filter.spatial.Beyond} test whether the value of a geometric property is
+    within or beyond a specified distance of the specified literal geometric value. Distance values
+    are expressed using the {@linkplain org.opengis.filter.spatial.DistanceBufferOperator#getDistance distance}
+    attribute. The content of the distance attribute represents the magnitude of the distance and the
+    {@linkplain org.opengis.filter.spatial.DistanceBufferOperator#getDistanceUnits units} attribute
+    is used to specify the units of measure.</P>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/BoundingBox.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/BoundingBox.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/BoundingBox.java	(revision 28000)
@@ -0,0 +1,126 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.geometry;
+
+import java.awt.geom.Rectangle2D;
+
+import org.opengis.annotation.Extension;
+import org.opengis.metadata.extent.GeographicBoundingBox;
+import org.opengis.referencing.cs.AxisDirection;
+
+
+/**
+ * Represents a two-dimensional {@linkplain Envelope envelope}.
+ * This interface combines the ideas of {@link GeographicBoundingBox} with
+ * those of {@link Envelope}. It provides convenience methods to assist
+ * in accessing the formal properties of this object. Those methods
+ * (for example {@link #getMinX()}) match common usage in existing libraries
+ * like {@linkplain Rectangle2D Java2D}.
+ * <p>
+ * This object contains no additional information beyond that provided
+ * by {@link Envelope}.
+ *
+ * @author Jody Garnett (Refractions Research)
+ * @author Martin Desruisseaux (Geomatys)
+ * @since GeoAPI 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/geometry/BoundingBox.java $
+ */
+@Extension
+public interface BoundingBox extends Envelope {
+
+    /**
+     * Provides the minimum ordinate along the first axis.
+     * This is equivalent to <code>{@linkplain #getMinimum getMinimum}(0)</code>.
+     * There is no guarantee that this axis is oriented toward
+     * {@linkplain AxisDirection#EAST East}.
+     *
+     * @return The minimum ordinate along the first axis.
+     */
+    double getMinX();
+
+    /**
+     * Provides the maximum ordinate along the first axis.
+     * This is equivalent to <code>{@linkplain #getMaximum getMaximum}(0)</code>.
+     * There is no guarantee that this axis is oriented toward
+     * {@linkplain AxisDirection#EAST East}.
+     *
+     * @return The maximum ordinate along the first axis.
+     */
+    double getMaxX();
+
+    /**
+     * Provides the minimum ordinate along the second axis.
+     * This is equivalent to <code>{@linkplain #getMinimum getMinimum}(1)</code>.
+     * There is no guarantee that this axis is oriented toward
+     * {@linkplain AxisDirection#NORTH North}.
+     *
+     * @return The minimum ordinate along the second axis.
+     */
+    double getMinY();
+
+    /**
+     * Provides the maximum ordinate along the second axis.
+     * This is equivalent to <code>{@linkplain #getMaximum getMaximum}(1)</code>.
+     * There is no guarantee that this axis is oriented toward
+     * {@linkplain AxisDirection#NORTH North}.
+     *
+     * @return The maximum ordinate along the second axis.
+     */
+    double getMaxY();
+
+    /**
+     * Provides the difference between {@linkplain #getMinX minimum} and
+     * {@linkplain #getMaxX maximum} ordinate along the first axis.
+     * This is equivalent to <code>{@linkplain #getLength getLength}(0)</code>.
+     * There is no guarantee that this axis is oriented toward
+     * {@linkplain AxisDirection#EAST East}.
+     *
+     * @return The span along the first axis.
+     */
+    double getWidth();
+
+    /**
+     * Provides the difference between {@linkplain #getMinX minimum} and
+     * {@linkplain #getMaxX maximum} ordinate along the second axis.
+     * This is equivalent to <code>{@linkplain #getLength getLength}(1)</code>.
+     * There is no guarantee that this axis is oriented toward
+     * {@linkplain AxisDirection#NORTH North}.
+     *
+     * @return The span along the second axis.
+     */
+    double getHeight();
+
+    /**
+     * Returns {@code true} if {@linkplain #getSpan spans} along all dimension are zero
+     * or negative.
+     *
+     * @return {@code true} if this bounding box is empty.
+     */
+    boolean isEmpty();
+
+    /**
+     * Includes the provided bounding box, expanding as necesary.
+     *
+     * @param bounds The bounds to add to this geographic bounding box.
+     */
+    void include(BoundingBox bounds);
+
+    /**
+     * Includes the provided coordinates, expanding as necessary. Note that there is no
+     * guarantee that the (<var>x</var>, <var>x</var>) values are oriented toward
+     * ({@linkplain AxisDirection#EAST East}, {@linkplain AxisDirection#NORTH North}),
+     * since it depends on the {@linkplain #getCoordinateReferenceSystem envelope CRS}.
+     *
+     * @param x The first ordinate value.
+     * @param y The second ordinate value.
+     */
+    void include(double x, double y);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/DirectPosition.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/DirectPosition.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/DirectPosition.java	(revision 28000)
@@ -0,0 +1,170 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.geometry;
+
+import org.opengis.geometry.coordinate.Position;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Holds the coordinates for a position within some coordinate reference system. Since
+ * {@code DirectPosition}s, as data types, will often be included in larger objects (such as
+ * {@linkplain org.opengis.geometry.Geometry geometries}) that have references to
+ * {@linkplain CoordinateReferenceSystem coordinate reference system}, the
+ * {@link #getCoordinateReferenceSystem} method may returns {@code null} if this particular
+ * {@code DirectPosition} is included in a larger object with such a reference to a
+ * {@linkplain CoordinateReferenceSystem coordinate reference system}. In this case,
+ * the cordinate reference system is implicitly assumed to take on the value of the containing
+ * object's {@linkplain CoordinateReferenceSystem coordinate reference system}.
+ * <p>
+ * <b>Note:</b> this interface does not extends {@link org.opengis.util.Cloneable} on purpose,
+ * since {@code DirectPosition} implementations are most likely to be backed by references to
+ * internal structures of the geometry containing this position. A direct position may or may
+ * not be cloneable at implementor choice.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/geometry/DirectPosition.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as">ISO 19107</A>
+ * @author Martin Desruisseaux (IRD)
+ * @since GeoAPI 1.0
+ */
+@UML(identifier="DirectPosition", specification=ISO_19107)
+public interface DirectPosition extends Position {
+    /**
+     * The coordinate reference system in which the coordinate is given. May be {@code null} if this
+     * particular {@code DirectPosition} is included in a larger object with such a reference to a
+     * {@linkplain CoordinateReferenceSystem coordinate reference system}. In this case, the
+     * cordinate reference system is implicitly assumed to take on the value of the containing
+     * object's {@linkplain CoordinateReferenceSystem coordinate reference system}.
+     *
+     * @return The coordinate reference system, or {@code null}.
+     */
+    @UML(identifier="coordinateReferenceSystem", obligation=MANDATORY, specification=ISO_19107)
+    CoordinateReferenceSystem getCoordinateReferenceSystem();
+
+    /**
+     * The length of coordinate sequence (the number of entries). This is determined by the
+     * {@linkplain #getCoordinateReferenceSystem() coordinate reference system}.
+     *
+     * @return The dimensionality of this position.
+     */
+    @UML(identifier="dimension", obligation=MANDATORY, specification=ISO_19107)
+    int getDimension();
+
+    /**
+     * A <b>copy</b> of the ordinates presented as an array of double values.
+     * Please note that this is only a copy (the real values may be stored in
+     * another format) so changes to the returned array will not affect the
+     * source DirectPosition.
+     *
+     * <blockquote><pre>
+     * final int dim = position.{@linkplain #getDimension getDimension}();
+     * for (int i=0; i&lt;dim; i++) {
+     *     position.{@linkplain #getOrdinate getOrdinate}(i); // no copy overhead
+     * }
+     * </pre></blockquote>
+     *
+     * To manipulate ordinates, the following idiom can be used:
+     *
+     * <blockquote><pre>
+     * position.{@linkplain #setOrdinate setOrdinate}(i, value); // edit in place
+     * </pre></blockquote>
+     *
+     * There are a couple reasons for requerying a copy:
+     * <p>
+     * <ul>
+     *   <li>We want an array of coordinates with the intend to modify it for computation purpose
+     *       (without modifying the original {@code DirectPosition}), or we want to protect the
+     *       array from future {@code DirectPosition} changes.</li>
+     *   <li>If {@code DirectPosition.getOrdinates()} is garanteed to not return the backing array,
+     *       then we can work directly on this array. If we don't have this garantee, then we must
+     *       conservatively clone the array in every cases.</li>
+     *   <li>Cloning the returned array is useless if the implementation cloned the array or was
+     *       forced to returns a new array anyway (for example because the coordinates were
+     *       computed on the fly)</li>
+     * </ul>
+     * <p>
+     * Precedence is given to data integrity over {@code getOrdinates()} performance.
+     * Performance concern can be avoided with usage of {@link #getOrdinate(int)}.
+     *
+     * @return A copy of the coordinates. Changes in the returned array will not be reflected back
+     *         in this {@code DirectPosition} object.
+     */
+    @UML(identifier="coordinate", obligation=MANDATORY, specification=ISO_19107)
+    double[] getCoordinate();
+
+    /**
+     * Returns the ordinate at the specified dimension.
+     *
+     * @param dimension The dimension in the range 0 to {@linkplain #getDimension dimension}-1.
+     * @return The coordinate at the specified dimension.
+     * @throws IndexOutOfBoundsException If the given index is negative or is equals or greater
+     *         than the {@linkplain #getDimension envelope dimension}.
+     */
+    double getOrdinate(int dimension) throws IndexOutOfBoundsException;
+
+    /**
+     * Sets the ordinate value along the specified dimension.
+     *
+     * @param dimension the dimension for the ordinate of interest.
+     * @param value the ordinate value of interest.
+     * @throws IndexOutOfBoundsException If the given index is negative or is equals or greater
+     *         than the {@linkplain #getDimension envelope dimension}.
+     * @throws UnsupportedOperationException if this direct position is immutable.
+     */
+    void setOrdinate(int dimension, double value)
+            throws IndexOutOfBoundsException, UnsupportedOperationException;
+
+    /**
+     * Compares this direct position with the specified object for equality.
+     * Two direct positions are considered equal if the following conditions
+     * are meet:
+     * <p>
+     * <ul>
+     *   <li>{@code object} is non-null and is an instance of {@code DirectPosition}.</li>
+     *   <li>Both direct positions have the same {@linkplain #getDimension number of dimension}.</li>
+     *   <li>Both direct positions have the same or equal {@linkplain #getCoordinateReferenceSystem
+     *       coordinate reference system}.</li>
+     *   <li>For all dimension <var>i</var>, the {@linkplain #getOrdinate ordinate value} of both
+     *       direct positions at that dimension are equals in the sense of {@link Double#equals}.
+     *       In other words, <code>{@linkplain java.util.Arrays#equals(double[],double[])
+     *       Arrays.equals}({@linkplain #getCoordinate()}, object.getCoordinate())</code>
+     *       returns {@code true}.</li>
+     * </ul>
+     *
+     * @param object The object to compare with this direct position for equality.
+     * @return {@code true} if the given object is equals to this direct position.
+     *
+     * @since GeoAPI 2.1
+     */
+    ///@Override
+    boolean equals(Object object);
+
+    /**
+     * Returns a hash code value for this direct position. This method should returns
+     * the same value as:
+     *
+     * <code>{@linkplain java.util.Arrays.hashCode(double[]) Arrays.hashCode}({@linkplain
+     * #getCoordinate()}) + {@linkplain #getCoordinateReferenceSystem()}.hashCode()</code>
+     *
+     * where the right hand side of the addition is omitted if the coordinate reference
+     * system is null.
+     *
+     * @return A hash code value for this direct position.
+     *
+     * @since GeoAPI 2.1
+     */
+    ///@Override
+    int hashCode();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/Envelope.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/Envelope.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/Envelope.java	(revision 28000)
@@ -0,0 +1,185 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.geometry;
+
+import static org.opengis.annotation.Specification.ISO_19107;
+
+import java.awt.geom.Rectangle2D;
+
+import org.opengis.annotation.Extension;
+import org.opengis.annotation.UML;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+
+/**
+ * A minimum bounding box or rectangle. Regardless of dimension, an {@code Envelope} can
+ * be represented without ambiguity as two direct positions (coordinate points). To encode an
+ * {@code Envelope}, it is sufficient to encode these two points. This is consistent with
+ * all of the data types in this specification, their state is represented by their publicly
+ * accessible attributes.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/geometry/Envelope.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as">ISO 19107</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.coverage.grid.GridEnvelope
+ */
+@UML(identifier="GM_Envelope", specification=ISO_19107)
+public interface Envelope {
+    /**
+     * Returns the envelope coordinate reference system, or {@code null} if unknown.
+     * If non-null, it shall be the same as {@linkplain #getLowerCorner lower corner}
+     * and {@linkplain #getUpperCorner upper corner} CRS.
+     *
+     * @return The envelope CRS, or {@code null} if unknown.
+     *
+     * @since GeoAPI 2.1
+     */
+    @Extension
+    CoordinateReferenceSystem getCoordinateReferenceSystem();
+
+    /**
+     * The length of coordinate sequence (the number of entries) in this envelope. Mandatory
+     * even when the {@linkplain #getCoordinateReferenceSystem coordinate reference system}
+     * is unknown.
+     *
+     * @return The dimensionality of this envelope.
+     *
+     * @since GeoAPI 2.0
+     */
+    @Extension
+    int getDimension();
+
+    /**
+     * Returns the minimal ordinate along the specified dimension. This is a shortcut for
+     * the following without the cost of creating a temporary {@link DirectPosition} object:
+     *
+     * <blockquote><code>
+     * {@linkplain #getLowerCorner}.{@linkplain DirectPosition#getOrdinate getOrdinate}(dimension)
+     * </code></blockquote>
+     *
+     * @param  dimension The dimension for which to obtain the ordinate value.
+     * @return The minimal ordinate at the given dimension.
+     * @throws IndexOutOfBoundsException If the given index is negative or is equals or greater
+     *         than the {@linkplain #getDimension envelope dimension}.
+     *
+     * @see Rectangle2D#getMinX
+     * @see Rectangle2D#getMinY
+     *
+     * @since GeoAPI 2.0
+     */
+    @Extension
+    double getMinimum(int dimension) throws IndexOutOfBoundsException;
+
+    /**
+     * Returns the maximal ordinate along the specified dimension. This is a shortcut for
+     * the following without the cost of creating a temporary {@link DirectPosition} object:
+     *
+     * <blockquote><code>
+     * {@linkplain #getUpperCorner}.{@linkplain DirectPosition#getOrdinate getOrdinate}(dimension)
+     * </code></blockquote>
+     *
+     * @param  dimension The dimension for which to obtain the ordinate value.
+     * @return The maximal ordinate at the given dimension.
+     * @throws IndexOutOfBoundsException If the given index is negative or is equals or greater
+     *         than the {@linkplain #getDimension envelope dimension}.
+     *
+     * @see Rectangle2D#getMaxX
+     * @see Rectangle2D#getMaxY
+     *
+     * @since GeoAPI 2.0
+     */
+    @Extension
+    double getMaximum(int dimension) throws IndexOutOfBoundsException;
+
+    /**
+     * Returns the center ordinate along the specified dimension.
+     *
+     * @param  dimension The dimension for which to obtain the ordinate value.
+     * @return The center ordinate at the given dimension.
+     * @throws IndexOutOfBoundsException If the given index is negative or is equals or greater
+     *         than the {@linkplain #getDimension envelope dimension}.
+     *
+     * @see Rectangle2D#getCenterX
+     * @see Rectangle2D#getCenterY
+     *
+     * @since GeoAPI 2.0
+     *
+     * @deprecated Renamed as {@link #getMedian}.
+     */
+    @Extension
+    @Deprecated
+    double getCenter(int dimension) throws IndexOutOfBoundsException;
+
+    /**
+     * Returns the median ordinate along the specified dimension. The result should be equals
+     * (minus rounding error) to:
+     *
+     * <blockquote><code>
+     * ({@linkplain #getMinimum getMinimum}(dimension) + {@linkplain #getMaximum getMaximum}(dimension)) / 2
+     * </code></blockquote>
+     *
+     * @param  dimension The dimension for which to obtain the ordinate value.
+     * @return The median ordinate at the given dimension.
+     * @throws IndexOutOfBoundsException If the given index is negative or is equals or greater
+     *         than the {@linkplain #getDimension envelope dimension}.
+     *
+     * @see Rectangle2D#getCenterX
+     * @see Rectangle2D#getCenterY
+     *
+     * @since GeoAPI 2.2
+     */
+    @Extension
+    double getMedian(int dimension) throws IndexOutOfBoundsException;
+
+    /**
+     * Returns the envelope length along the specified dimension.
+     * This length is equals to the {@linkplain #getMaximum maximum ordinate}
+     * minus the {@linkplain #getMinimum minimal ordinate}.
+     *
+     * @param  dimension The dimension for which to obtain the ordinate value.
+     * @return The length at the given dimension.
+     * @throws IndexOutOfBoundsException If the given index is negative or is equals or greater
+     *         than the {@linkplain #getDimension envelope dimension}.
+     *
+     * @see Rectangle2D#getWidth
+     * @see Rectangle2D#getHeight
+     *
+     * @since GeoAPI 2.0
+     *
+     * @deprecated Renamed as {@link #getSpan}.
+     */
+    @Extension
+    @Deprecated
+    double getLength(int dimension) throws IndexOutOfBoundsException;
+
+    /**
+     * Returns the envelope span (typically width or height) along the specified dimension.
+     * The result should be equals (minus rounding error) to:
+     *
+     * <blockquote><code>
+     * {@linkplain #getMaximum getMaximum}(dimension) - {@linkplain #getMinimum getMinimum}(dimension)
+     * </code></blockquote>
+     *
+     * @param  dimension The dimension for which to obtain the ordinate value.
+     * @return The span (typically width or height) at the given dimension.
+     * @throws IndexOutOfBoundsException If the given index is negative or is equals or greater
+     *         than the {@linkplain #getDimension envelope dimension}.
+     *
+     * @see Rectangle2D#getWidth
+     * @see Rectangle2D#getHeight
+     *
+     * @since GeoAPI 2.2
+     */
+    @Extension
+    double getSpan(int dimension) throws IndexOutOfBoundsException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/MismatchedDimensionException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/MismatchedDimensionException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/MismatchedDimensionException.java	(revision 28000)
@@ -0,0 +1,44 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.geometry;
+
+
+/**
+ * Indicates that an operation cannot be completed properly because
+ * of a mismatch in the dimensions of object attributes.
+ *
+ * @author Martin Desruisseaux (IRD)
+ * @since GeoAPI 1.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/geometry/MismatchedDimensionException.java $
+ */
+public class MismatchedDimensionException extends IllegalArgumentException {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 3138484331425225155L;
+
+    /**
+     * Creates an exception with no message.
+     */
+    public MismatchedDimensionException() {
+        super();
+    }
+
+    /**
+     * Creates an exception with the specified message.
+     *
+     * @param  message The detail message. The detail message is saved for
+     *         later retrieval by the {@link #getMessage()} method.
+     */
+    public MismatchedDimensionException(final String message) {
+        super(message);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/MismatchedReferenceSystemException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/MismatchedReferenceSystemException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/MismatchedReferenceSystemException.java	(revision 28000)
@@ -0,0 +1,45 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.geometry;
+
+
+/**
+ * Indicates that an object cannot be constructed because of a mismatch in the
+ * {@linkplain org.opengis.referencing.ReferenceSystem reference systems} of
+ * geometric components.
+ *
+ * @author Martin Desruisseaux (IRD)
+ * @since GeoAPI 2.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/geometry/MismatchedReferenceSystemException.java $
+ */
+public class MismatchedReferenceSystemException extends IllegalArgumentException {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 6222334569692693273L;
+
+    /**
+     * Creates an exception with no message.
+     */
+    public MismatchedReferenceSystemException() {
+        super();
+    }
+
+    /**
+     * Creates an exception with the specified message.
+     *
+     * @param  message The detail message. The detail message is saved for
+     *         later retrieval by the {@link #getMessage()} method.
+     */
+    public MismatchedReferenceSystemException(final String message) {
+        super(message);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/coordinate/Position.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/coordinate/Position.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/coordinate/Position.java	(revision 28000)
@@ -0,0 +1,42 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.geometry.coordinate;
+
+import static org.opengis.annotation.Specification.ISO_19107;
+
+import org.opengis.annotation.UML;
+import org.opengis.geometry.DirectPosition;
+
+
+/**
+ * A type consisting of either a {@linkplain DirectPosition direct position} or of a
+ * {@linkplain Point point} from which a {@linkplain DirectPosition direct position}
+ * shall be obtained. The use of this data type allows the identification of a position
+ * either directly as a coordinate (variant direct) or indirectly as a {@linkplain Point point}
+ * (variant indirect).
+ *
+ * @departure
+ *   ISO 19111 defines {@code Position} like a C/C++ {@code union} of {@code DirectPosition} and
+ *   {@code Point}. Since unions are not allowed in Java, GeoAPI defines {@code Position} as the
+ *   base interface of the above. This leads to a slightly different semantic since ISO defines
+ *   {@link #getDirectPosition} as conditional, while GeoAPI defines it as mandatory by allowing
+ *   the method to return {@code this}.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/geometry/coordinate/Position.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as">ISO 19107</A>
+ * @author Martin Desruisseaux (IRD)
+ * @since GeoAPI 1.0
+ *
+ * @issue http://jira.codehaus.org/browse/GEO-87
+ */
+@UML(identifier="GM_Position", specification=ISO_19107)
+public interface Position {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/coordinate/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/coordinate/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/coordinate/package.html	(revision 28000)
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.opengis.geometry.coordinate</TITLE>
+  </HEAD>
+  <BODY>
+  Set of geometric objects. The following is adapted from
+  <A HREF="http://www.opengis.org/docs/01-101.pdf">Feature Geometry (Topic 1)</A> specification.
+
+  <P ALIGN="justify">A geometric object shall be a combination of a coordinate geometry and a coordinate
+  reference system. In all of the operations, all geometric calculations shall be done in the coordinate
+  reference system of the first geometric object accessed, which is normally the object whose operation
+  is being invoked. Returned objects shall be in the coordinate reference system in which the calculations
+  are done unless explicitly stated otherwise. The interface defined in this package are basically those
+  of set theory. In general a geometric object is a set of geometric points, represented by
+  {@link org.opengis.geometry.DirectPosition}. Object instantiations of geometric objects are
+  {@link org.opengis.geometry.Geometry}. Object instantiations of geometric points, when used as values,
+  are {@link org.opengis.geometry.DirectPosition}s. General set theory operations defined at
+  {@link org.opengis.geometry.Geometry} differentiate further down the class hierarchy depending on
+  whether or not the boundary {@link org.opengis.geometry.DirectPosition} are included as set
+  elements. Subtypes of {@link org.opengis.geometry.primitive.Primitive} do not contain boundary points,
+  while subtypes of {@link org.opengis.geometry.complex.Complex} do.</P>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/geometry/package.html	(revision 28000)
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.opengis.geometry</TITLE>
+  </HEAD>
+  <BODY>
+  Root package for {@linkplain org.opengis.geometry.Geometry geometries}. The following is adapted from
+  <A HREF="http://www.opengis.org/docs/01-101.pdf">Feature Geometry (Topic 1)</A> specification.
+
+  <P ALIGN="justify">The geometry packages contain the various classes for coordinate geometry.
+  All of these classes through the root class {@link org.opengis.geometry.Geometry} inherit an optional
+  association to a coordinate reference system. All direct positions exposed through the interfaces
+  defined in this specification shall be in the coordinate reference system of the geometric object
+  accessed. All elements of a geometric complex, composite, or aggregate shall be associated to the
+  same coordinate reference system. When instances of {@link org.opengis.geometry.Geometry} are aggregated
+  in another {@link org.opengis.geometry.Geometry} (such as a {@link org.opengis.geometry.aggregate.Aggregate},
+  or {@link org.opengis.geometry.complex.Complex}) which already has a coordinate reference system specified,
+  then these elements are assumed to be in that same coordinate reference system unless otherwise
+  specified.</P>
+
+  <P ALIGN="justify">The geometry package has several internal packages that separate primitive
+  geometric objects, aggregates and complexes, which have a more elaborate internal structure
+  than simple aggregates.</P>
+
+  <P ALIGN="justify">Any object that inherits the semantics of the {@link org.opengis.geometry.Geometry}
+  acts as a set of direct positions. Its behavior will be determined by which direct positions it
+  contains. Objects under {@link org.opengis.geometry.primitive.Primitive} will be open, that is, they
+  will not contain their boundary points; curves will not contain their end points, surfaces will
+  not contain their boundary curves, and solids will not contain their bounding surfaces. Objects
+  under {@link org.opengis.geometry.complex.Complex} will be closed, that is, they will contain their
+  boundary points. This leads to some apparent ambiguity. A representation of a line as a primitive
+  must reference its end points, but will not contain these points as a set of direct positions. A
+  representation of a line as a complex will also reference its end points, and will contain these
+  points as a set of direct positions. This means that identical digital representations will have
+  slightly different semantics depending on whether they are accessed as primitives or complexes.</P>
+
+  <P ALIGN="justify">This difference of semantics is most striking in the
+  {@link org.opengis.geometry.complex.CompositeCurve}. Composite curves are used to represent features whose
+  geometry could also be represented as curve primitives. From a cartographic point of view, these
+  two representations are not different. From a topological point of view, they are different. This
+  distinction appears as an inheritance relationship between {@link org.opengis.geometry.complex.CompositeCurve}
+  and {@link org.opengis.geometry.primitive.OrientableCurve}. The primary semantics of a
+  {@link org.opengis.geometry.complex.CompositeCurve} is as a closed {@link org.opengis.geometry.Geometry}, but it
+  may also act as an open {@link org.opengis.geometry.Geometry} under {@link org.opengis.geometry.primitive.Primitive}
+  operations. Interface protocols depending upon the topological details of this object will have to
+  be distinguished as to whether they have been inherited from {@link org.opengis.geometry.primitive.Primitive}
+  or {@link org.opengis.geometry.complex.Complex}, where the distinction first occurs. Even though these protocols
+  have been inherited from the same operations defined at {@link org.opengis.geometry.Geometry}, they will act
+  differently depending upon the branch of the inheritance tree from which they have inherited semantics.
+  Creators of implementation profiles may take this into account and use a proxy mechanism for realization
+  relationships that cause semantic dissonance.</P>
+
+  <P ALIGN="justify">{@link org.opengis.geometry.Geometry} and {@link org.opengis.geometry.primitive.Primitive}
+  are purely abstract in the sense that no object or data structure from an application can
+  instantiate them directly. Instances of these classes must be instances of one of their non-abstract
+  subtypes, such as {@link org.opengis.geometry.primitive.Point}, {@link org.opengis.geometry.primitive.Curve}, or
+  {@link org.opengis.geometry.primitive.Surface}. This is not the case for {@link org.opengis.geometry.complex.Complex},
+  which can be directly instantiated by an application, and need not be an instance of one of the
+  non-abstract subclasses of {@link org.opengis.geometry.complex.Composite}.</P>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/Identifier.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/Identifier.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/Identifier.java	(revision 28000)
@@ -0,0 +1,64 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata;
+
+import org.opengis.metadata.citation.Citation;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Value uniquely identifying an object within a namespace.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/Identifier.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="MD_Identifier", specification=ISO_19115)
+public interface Identifier {
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain org.opengis.referencing.ObjectFactory CRS factory} <code>createFoo(&hellip;)</code>
+     * methods. This is used for setting the value to be returned by {@link #getCode}.
+     *
+     * @see #getCode
+     */
+    String CODE_KEY = "code";
+
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain org.opengis.referencing.ObjectFactory CRS factory} <code>createFoo(&hellip;)</code>
+     * methods. This is used for setting the value to be returned by {@link #getAuthority}.
+     *
+     * @see #getAuthority
+     */
+    String AUTHORITY_KEY = "authority";
+
+    /**
+     * Alphanumeric value identifying an instance in the namespace.
+     *
+     * @return Value identifying an instance in the namespace.
+     */
+    @UML(identifier="code", obligation=MANDATORY, specification=ISO_19115)
+    String getCode();
+
+    /**
+     * Organization or party responsible for definition and maintenance of the
+     * {@linkplain #getCode code}.
+     *
+     * @return Party responsible for definition and maintenance of the code.
+     */
+    @UML(identifier="authority", obligation=OPTIONAL, specification=ISO_19115)
+    Citation getAuthority();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Address.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Address.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Address.java	(revision 28000)
@@ -0,0 +1,28 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.citation;
+
+import static org.opengis.annotation.Specification.ISO_19115;
+
+import org.opengis.annotation.UML;
+
+
+/**
+ * Location of the responsible individual or organization.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/citation/Address.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CI_Address", specification=ISO_19115)
+public interface Address {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Citation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Citation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Citation.java	(revision 28000)
@@ -0,0 +1,77 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.citation;
+
+import static org.opengis.annotation.Obligation.MANDATORY;
+import static org.opengis.annotation.Obligation.OPTIONAL;
+import static org.opengis.annotation.Specification.ISO_19115;
+
+import java.util.Collection;
+
+import org.opengis.annotation.UML;
+import org.opengis.metadata.Identifier;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * Standardized resource reference.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/citation/Citation.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @author  Cory Horner (Refractions Research)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CI_Citation", specification=ISO_19115)
+public interface Citation {
+    /**
+     * Name by which the cited resource is known.
+     *
+     * @return The cited resource name.
+     */
+    @UML(identifier="title", obligation=MANDATORY, specification=ISO_19115)
+    InternationalString getTitle();
+
+    /**
+     * Short name or other language name by which the cited information is known.
+     * Example: "DCW" as an alternative title for "Digital Chart of the World".
+     *
+     * @return Other names for the resource, or an empty collection if none.
+     */
+    @UML(identifier="alternateTitle", obligation=OPTIONAL, specification=ISO_19115)
+    Collection<? extends InternationalString> getAlternateTitles();
+
+    /**
+     * Unique identifier for the resource. Example: Universal Product Code (UPC),
+     * National Stock Number (NSN).
+     *
+     * @return The identifiers, or an empty collection if none.
+     */
+    @UML(identifier="identifier", obligation=OPTIONAL, specification=ISO_19115)
+    Collection<? extends Identifier> getIdentifiers();
+
+    /**
+     * Name and position information for an individual or organization that is responsible
+     * for the resource. Returns an empty string if there is none.
+     *
+     * @return The individual or organization that is responsible, or an empty collection if none.
+     */
+    @UML(identifier="citedResponsibleParty", obligation=OPTIONAL, specification=ISO_19115)
+    Collection<? extends ResponsibleParty> getCitedResponsibleParties();
+
+    /**
+     * Mode in which the resource is represented, or an empty string if none.
+     *
+     * @return The presentation mode, or an empty collection if none.
+     */
+    @UML(identifier="presentationForm", obligation=OPTIONAL, specification=ISO_19115)
+    Collection<PresentationForm> getPresentationForm();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/CitationDate.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/CitationDate.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/CitationDate.java	(revision 28000)
@@ -0,0 +1,28 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.citation;
+
+import static org.opengis.annotation.Specification.ISO_19115;
+
+import org.opengis.annotation.UML;
+
+
+/**
+ * Reference date and event used to describe it.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/citation/CitationDate.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="CI_Date", specification=ISO_19115)
+public interface CitationDate {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Contact.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Contact.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Contact.java	(revision 28000)
@@ -0,0 +1,28 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.citation;
+
+import static org.opengis.annotation.Specification.ISO_19115;
+
+import org.opengis.annotation.UML;
+
+
+/**
+ * Information required to enable contact with the responsible person and/or organization.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/citation/Contact.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CI_Contact", specification=ISO_19115)
+public interface Contact {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/OnLineFunction.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/OnLineFunction.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/OnLineFunction.java	(revision 28000)
@@ -0,0 +1,94 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.citation;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.opengis.util.CodeList;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Class of information to which the referencing entity applies.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/citation/OnLineFunction.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="CI_OnLineFunctionCode", specification=ISO_19115)
+public final class OnLineFunction extends CodeList<OnLineFunction> {
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = 2333803519583053407L;
+
+    /**
+     * List of all enumerations of this type.
+     * Must be declared before any enum declaration.
+     */
+    private static final List<OnLineFunction> VALUES = new ArrayList<OnLineFunction>(5);
+
+    /**
+     * Online instructions for transferring data from one storage device or system to another.
+     */
+    @UML(identifier="download", obligation=CONDITIONAL, specification=ISO_19115)
+    public static final OnLineFunction DOWNLOAD = new OnLineFunction("DOWNLOAD");
+
+    /**
+     * Online information about the resource.
+     */
+    @UML(identifier="information", obligation=CONDITIONAL, specification=ISO_19115)
+    public static final OnLineFunction INFORMATION = new OnLineFunction("INFORMATION");
+
+    /**
+     * Constructs an enum with the given name. The new enum is
+     * automatically added to the list returned by {@link #values}.
+     *
+     * @param name The enum name. This name must not be in use by an other enum of this type.
+     */
+    private OnLineFunction(final String name) {
+        super(name, VALUES);
+    }
+
+    /**
+     * Returns the list of {@code OnLineFunction}s.
+     *
+     * @return The list of codes declared in the current JVM.
+     */
+    public static OnLineFunction[] values() {
+        synchronized (VALUES) {
+            return VALUES.toArray(new OnLineFunction[VALUES.size()]);
+        }
+    }
+
+    /**
+     * Returns the list of enumerations of the same kind than this enum.
+     */
+    public OnLineFunction[] family() {
+        return values();
+    }
+
+    /**
+     * Returns the on line function that matches the given string, or returns a
+     * new one if none match it.
+     *
+     * @param code The name of the code to fetch or to create.
+     * @return A code matching the given name.
+     */
+    public static OnLineFunction valueOf(String code) {
+        return valueOf(OnLineFunction.class, code);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/OnLineResource.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/OnLineResource.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/OnLineResource.java	(revision 28000)
@@ -0,0 +1,30 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.citation;
+
+import static org.opengis.annotation.Specification.ISO_19115;
+
+import org.opengis.annotation.UML;
+
+
+/**
+ * Information about on-line sources from which the dataset, specification, or
+ * community profile name and extended metadata elements can be obtained.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/citation/OnLineResource.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @author  Cory Horner (Refractions Research)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CI_OnlineResource", specification=ISO_19115)
+public interface OnLineResource {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/PresentationForm.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/PresentationForm.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/PresentationForm.java	(revision 28000)
@@ -0,0 +1,94 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.citation;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.opengis.util.CodeList;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Mode in which the data is represented.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/citation/PresentationForm.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="CI_PresentationFormCode", specification=ISO_19115)
+public final class PresentationForm extends CodeList<PresentationForm> {
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = 5668779490885399888L;
+
+    /**
+     * List of all enumerations of this type.
+     * Must be declared before any enum declaration.
+     */
+    private static final List<PresentationForm> VALUES = new ArrayList<PresentationForm>(14);
+
+    /**
+     * Digital representation of a primarily textual item (can contain illustrations also).
+     */
+    @UML(identifier="documentDigital", obligation=CONDITIONAL, specification=ISO_19115)
+    public static final PresentationForm DOCUMENT_DIGITAL = new PresentationForm("DOCUMENT_DIGITAL");
+
+    /**
+     * Digital representation of facts or figures systematically displayed, especially in columns.
+     */
+    @UML(identifier="tableDigital", obligation=CONDITIONAL, specification=ISO_19115)
+    public static final PresentationForm TABLE_DIGITAL = new PresentationForm("TABLE_DIGITAL");
+
+    /**
+     * Constructs an enum with the given name. The new enum is
+     * automatically added to the list returned by {@link #values}.
+     *
+     * @param name The enum name. This name must not be in use by an other enum of this type.
+     */
+    private PresentationForm(final String name) {
+        super(name, VALUES);
+    }
+
+    /**
+     * Returns the list of {@code PresentationForm}s.
+     *
+     * @return The list of codes declared in the current JVM.
+     */
+    public static PresentationForm[] values() {
+        synchronized (VALUES) {
+            return VALUES.toArray(new PresentationForm[VALUES.size()]);
+        }
+    }
+
+    /**
+     * Returns the list of enumerations of the same kind than this enum.
+     */
+    public PresentationForm[] family() {
+        return values();
+    }
+
+    /**
+     * Returns the presentation form that matches the given string, or returns a
+     * new one if none match it.
+     *
+     * @param code The name of the code to fetch or to create.
+     * @return A code matching the given name.
+     */
+    public static PresentationForm valueOf(String code) {
+        return valueOf(PresentationForm.class, code);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/ResponsibleParty.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/ResponsibleParty.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/ResponsibleParty.java	(revision 28000)
@@ -0,0 +1,60 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.citation;
+
+import static org.opengis.annotation.Obligation.CONDITIONAL;
+import static org.opengis.annotation.Specification.ISO_19115;
+
+import org.opengis.annotation.UML;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * Identification of, and means of communication with, person(s) and
+ * organizations associated with the dataset.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/citation/ResponsibleParty.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CI_ResponsibleParty", specification=ISO_19115)
+public interface ResponsibleParty {
+    /**
+     * Name of the responsible person- surname, given name, title separated by a delimiter.
+     * Only one of {@code individualName}, {@link #getOrganisationName organisationName}
+     * and {@link #getPositionName positionName} should be provided.
+     *
+     * @return Name, surname, given name and title of the responsible person, or {@code null}.
+     */
+    @UML(identifier="individualName", obligation=CONDITIONAL, specification=ISO_19115)
+    String getIndividualName();
+
+    /**
+     * Name of the responsible organization.
+     * Only one of {@link #getIndividualName individualName}, {@code organisationName}
+     * and {@link #getPositionName positionName} should be provided.
+     *
+     * @return Name of the responsible organization, or {@code null}.
+     */
+    @UML(identifier="organisationName", obligation=CONDITIONAL, specification=ISO_19115)
+    InternationalString getOrganisationName();
+
+    /**
+     * Role or position of the responsible person.
+     * Only one of {@link #getIndividualName individualName}, {@link #getOrganisationName organisationName}
+     * and {@code positionName} should be provided.
+     *
+     * @return Role or position of the responsible person, or {@code null}
+     */
+    @UML(identifier="positionName", obligation=CONDITIONAL, specification=ISO_19115)
+    InternationalString getPositionName();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Role.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Role.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Role.java	(revision 28000)
@@ -0,0 +1,107 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.citation;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.opengis.util.CodeList;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Function performed by the responsible party.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/citation/Role.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @author  Cory Horner (Refractions Research)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="CI_RoleCode", specification=ISO_19115)
+public final class Role extends CodeList<Role> {
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = -7763516018565534103L;
+
+    /**
+     * List of all enumerations of this type.
+     * Must be declared before any enum declaration.
+     */
+    private static final List<Role> VALUES = new ArrayList<Role>(11);
+
+    /**
+     * Party that supplies the resource.
+     */
+    @UML(identifier="resourceProvider", obligation=CONDITIONAL, specification=ISO_19115)
+    public static final Role RESOURCE_PROVIDER = new Role("RESOURCE_PROVIDER");
+
+    /**
+     * Party that owns the resource.
+     */
+    @UML(identifier="owner", obligation=CONDITIONAL, specification=ISO_19115)
+    public static final Role OWNER = new Role("OWNER");
+
+    /**
+     * Key party responsible for gathering information and conducting research.
+     */
+    @UML(identifier="principalInvestigator", obligation=CONDITIONAL, specification=ISO_19115)
+    public static final Role PRINCIPAL_INVESTIGATOR = new Role("PRINCIPAL_INVESTIGATOR");
+
+    /**
+     * Party who published the resource.
+     */
+    @UML(identifier="publisher", obligation=CONDITIONAL, specification=ISO_19115)
+    public static final Role PUBLISHER = new Role("PUBLISHER");
+
+    /**
+     * Constructs an enum with the given name. The new enum is
+     * automatically added to the list returned by {@link #values}.
+     *
+     * @param name The enum name. This name must not be in use by an other enum of this type.
+     */
+    private Role(final String name) {
+        super(name, VALUES);
+    }
+
+    /**
+     * Returns the list of {@code Role}s.
+     *
+     * @return The list of codes declared in the current JVM.
+     */
+    public static Role[] values() {
+        synchronized (VALUES) {
+            return VALUES.toArray(new Role[VALUES.size()]);
+        }
+    }
+
+    /**
+     * Returns the list of enumerations of the same kind than this enum.
+     */
+    public Role[] family() {
+        return values();
+    }
+
+    /**
+     * Returns the role that matches the given string, or returns a
+     * new one if none match it.
+     *
+     * @param code The name of the code to fetch or to create.
+     * @return A code matching the given name.
+     */
+    public static Role valueOf(String code) {
+        return valueOf(Role.class, code);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Series.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Series.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Series.java	(revision 28000)
@@ -0,0 +1,28 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.citation;
+
+import static org.opengis.annotation.Specification.ISO_19115;
+
+import org.opengis.annotation.UML;
+
+
+/**
+ * Information about the series, or aggregate dataset, to which a dataset belongs.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/citation/Series.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CI_Series", specification=ISO_19115)
+public interface Series {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Telephone.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Telephone.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/citation/Telephone.java	(revision 28000)
@@ -0,0 +1,29 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.citation;
+
+import static org.opengis.annotation.Specification.ISO_19115;
+
+import org.opengis.annotation.UML;
+
+
+/**
+ * Telephone numbers for contacting the responsible individual or organization.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/citation/Telephone.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @author  Cory Horner (Refractions Research)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CI_Telephone", specification=ISO_19115)
+public interface Telephone {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/extent/Extent.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/extent/Extent.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/extent/Extent.java	(revision 28000)
@@ -0,0 +1,44 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.extent;
+
+import static org.opengis.annotation.Obligation.CONDITIONAL;
+import static org.opengis.annotation.Specification.ISO_19115;
+
+import java.util.Collection;
+
+import org.opengis.annotation.UML;
+
+
+/**
+ * Information about spatial, vertical, and temporal extent.
+ * This interface has four optional attributes
+ * ({@linkplain #getGeographicElements geographic elements},
+ *  {@linkplain #getTemporalElements temporal elements}, and
+ *  {@linkplain #getVerticalElements vertical elements}) and an element called
+ *  {@linkplain #getDescription description}.
+ *  At least one of the four shall be used.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/extent/Extent.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="EX_Extent", specification=ISO_19115)
+public interface Extent {
+    /**
+     * Provides geographic component of the extent of the referring object
+     *
+     * @return The geographic extent, or an empty set if none.
+     */
+    @UML(identifier="geographicElement", obligation=CONDITIONAL, specification=ISO_19115)
+    Collection<? extends GeographicExtent> getGeographicElements();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/extent/GeographicBoundingBox.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/extent/GeographicBoundingBox.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/extent/GeographicBoundingBox.java	(revision 28000)
@@ -0,0 +1,73 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.extent;
+
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Geographic position of the dataset. This is only an approximate
+ * so specifying the co-ordinate reference system is unnecessary.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/extent/GeographicBoundingBox.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="EX_GeographicBoundingBox", specification=ISO_19115)
+public interface GeographicBoundingBox extends GeographicExtent {
+    /**
+     * Returns the western-most coordinate of the limit of the
+     * dataset extent. The value is expressed in longitude in
+     * decimal degrees (positive east).
+     *
+     * @return The western-most longitude between -180 and +180&deg;.
+     * @unitof Angle
+     */
+    @UML(identifier="westBoundLongitude", obligation=MANDATORY, specification=ISO_19115)
+    double getWestBoundLongitude();
+
+    /**
+     * Returns the eastern-most coordinate of the limit of the
+     * dataset extent. The value is expressed in longitude in
+     * decimal degrees (positive east).
+     *
+     * @return The eastern-most longitude between -180 and +180&deg;.
+     * @unitof Angle
+     */
+    @UML(identifier="eastBoundLongitude", obligation=MANDATORY, specification=ISO_19115)
+    double getEastBoundLongitude();
+
+    /**
+     * Returns the southern-most coordinate of the limit of the
+     * dataset extent. The value is expressed in latitude in
+     * decimal degrees (positive north).
+     *
+     * @return The southern-most latitude between -90 and +90&deg;.
+     * @unitof Angle
+     */
+    @UML(identifier="southBoundLatitude", obligation=MANDATORY, specification=ISO_19115)
+    double getSouthBoundLatitude();
+
+    /**
+     * Returns the northern-most, coordinate of the limit of the
+     * dataset extent. The value is expressed in latitude in
+     * decimal degrees (positive north).
+     *
+     * @return The northern-most latitude between -90 and +90&deg;.
+     * @unitof Angle
+     */
+    @UML(identifier="northBoundLatitude", obligation=MANDATORY, specification=ISO_19115)
+    double getNorthBoundLatitude();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/extent/GeographicExtent.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/extent/GeographicExtent.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/extent/GeographicExtent.java	(revision 28000)
@@ -0,0 +1,38 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.extent;
+
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Base interface for geographic area of the dataset.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/extent/GeographicExtent.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @author  Cory Horner (Refractions Research)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="EX_GeographicExtent", specification=ISO_19115)
+public interface GeographicExtent {
+    /**
+     * Indication of whether the bounding polygon encompasses an area covered by the data
+     * (<cite>inclusion</cite>) or an area where data is not present (<cite>exclusion</cite>).
+     *
+     * @return {@code true} for inclusion, {@code false} for exclusion, or {@code null} if unspecified.
+     */
+    @UML(identifier="extentTypeCode", obligation=OPTIONAL, specification=ISO_19115)
+    Boolean getInclusion();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/AbsoluteExternalPositionalAccuracy.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/AbsoluteExternalPositionalAccuracy.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/AbsoluteExternalPositionalAccuracy.java	(revision 28000)
@@ -0,0 +1,27 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.quality;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Closeness of reported coordinate values to values accepted as or being true.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/quality/AbsoluteExternalPositionalAccuracy.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="DQ_AbsoluteExternalPositionalAccuracy", specification=ISO_19115)
+public interface AbsoluteExternalPositionalAccuracy extends PositionalAccuracy {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/ConformanceResult.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/ConformanceResult.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/ConformanceResult.java	(revision 28000)
@@ -0,0 +1,30 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.quality;
+
+import static org.opengis.annotation.Specification.ISO_19115;
+
+import org.opengis.annotation.UML;
+
+
+/**
+ * Information about the outcome of evaluating the obtained value (or set of values) against
+ * a specified acceptable conformance quality level.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/quality/ConformanceResult.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @author  Cory Horner (Refractions Research)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="DQ_ConformanceResult", specification=ISO_19115)
+public interface ConformanceResult extends Result {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/Element.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/Element.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/Element.java	(revision 28000)
@@ -0,0 +1,29 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.quality;
+
+import static org.opengis.annotation.Specification.ISO_19115;
+
+import org.opengis.annotation.UML;
+
+
+/**
+ * Type of test applied to the data specified by a data quality scope.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/quality/Element.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @author  Cory Horner (Refractions Research)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="DQ_Element", specification=ISO_19115)
+public interface Element {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/EvaluationMethodType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/EvaluationMethodType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/EvaluationMethodType.java	(revision 28000)
@@ -0,0 +1,89 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.quality;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.opengis.util.CodeList;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Type of method for evaluating an identified data quality measure.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/quality/EvaluationMethodType.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="DQ_EvaluationMethodTypeCode", specification=ISO_19115)
+public final class EvaluationMethodType extends CodeList<EvaluationMethodType> {
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = -2481257874205996202L;
+
+    /**
+     * List of all enumerations of this type.
+     * Must be declared before any enum declaration.
+     */
+    private static final List<EvaluationMethodType> VALUES = new ArrayList<EvaluationMethodType>(3);
+
+    /**
+     * Method of evaluating the quality of a dataset based on inspection of items within
+     * the dataset, where all data required is internal to the dataset being evaluated.
+     */
+    @UML(identifier="directInternal", obligation=CONDITIONAL, specification=ISO_19115)
+    public static final EvaluationMethodType DIRECT_INTERNAL = new EvaluationMethodType("DIRECT_INTERNAL");
+
+    /**
+     * Constructs an enum with the given name. The new enum is
+     * automatically added to the list returned by {@link #values}.
+     *
+     * @param name The enum name. This name must not be in use by an other enum of this type.
+     */
+    private EvaluationMethodType(final String name) {
+        super(name, VALUES);
+    }
+
+    /**
+     * Returns the list of {@code EvaluationMethodType}s.
+     *
+     * @return The list of codes declared in the current JVM.
+     */
+    public static EvaluationMethodType[] values() {
+        synchronized (VALUES) {
+            return VALUES.toArray(new EvaluationMethodType[VALUES.size()]);
+        }
+    }
+
+    /**
+     * Returns the list of enumerations of the same kind than this enum.
+     */
+    public EvaluationMethodType[] family() {
+        return values();
+    }
+
+    /**
+     * Returns the evaluation method type that matches the given string, or returns a
+     * new one if none match it.
+     *
+     * @param code The name of the code to fetch or to create.
+     * @return A code matching the given name.
+     */
+    public static EvaluationMethodType valueOf(String code) {
+        return valueOf(EvaluationMethodType.class, code);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/PositionalAccuracy.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/PositionalAccuracy.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/PositionalAccuracy.java	(revision 28000)
@@ -0,0 +1,27 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.quality;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Accuracy of the position of features.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/quality/PositionalAccuracy.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="DQ_PositionalAccuracy", specification=ISO_19115)
+public interface PositionalAccuracy extends Element {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/Result.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/Result.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/metadata/quality/Result.java	(revision 28000)
@@ -0,0 +1,27 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2004-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.metadata.quality;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Base interface of more specific result classes.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/metadata/quality/Result.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="DQ_Result", specification=ISO_19115)
+public interface Result {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/GeneralParameterDescriptor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/GeneralParameterDescriptor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/GeneralParameterDescriptor.java	(revision 28000)
@@ -0,0 +1,69 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.parameter;
+
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.annotation.UML;
+import org.opengis.annotation.Extension;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Abstract definition of a parameter or group of parameters used by an operation method.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/parameter/GeneralParameterDescriptor.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @author  Jody Garnett (Refractions Research)
+ * @since   GeoAPI 2.0
+ *
+ * @see GeneralParameterValue
+ */
+@UML(identifier="CC_GeneralOperationParameter", specification=ISO_19111)
+public interface GeneralParameterDescriptor extends IdentifiedObject {
+    /**
+     * Creates a new instance of {@linkplain GeneralParameterValue parameter value or group}
+     * initialized with the {@linkplain ParameterDescriptor#getDefaultValue default value(s)}.
+     * The {@linkplain GeneralParameterValue#getDescriptor parameter value descriptor} for
+     * the created parameter value(s) will be {@code this} object.
+     *
+     * @return A new parameter initialized to its default value.
+     */
+    @Extension
+    GeneralParameterValue createValue();
+
+    /**
+     * The minimum number of times that values for this parameter group or
+     * parameter are required. The default value is one. A value of 0 means
+     * an optional parameter.
+     *
+     * @return The minimum occurence.
+     *
+     * @see #getMaximumOccurs
+     */
+    @UML(identifier="minimumOccurs", obligation=OPTIONAL, specification=ISO_19111)
+    int getMinimumOccurs();
+
+    /**
+     * The maximum number of times that values for this parameter group or
+     * parameter can be included. For a {@linkplain ParameterDescriptor single parameter},
+     * the value is always 1. For a {@linkplain ParameterDescriptorGroup parameter group},
+     * it may vary. The default value is one.
+     *
+     * @return The maximum occurence.
+     *
+     * @see #getMinimumOccurs
+     */
+    @UML(identifier="CC_OperationParameterGroup.maximumOccurs", obligation=OPTIONAL, specification=ISO_19111)
+    int getMaximumOccurs();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/GeneralParameterValue.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/GeneralParameterValue.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/GeneralParameterValue.java	(revision 28000)
@@ -0,0 +1,45 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.parameter;
+
+import org.opengis.util.Cloneable;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Abstract parameter value or group of parameter values.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/parameter/GeneralParameterValue.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @author  Jody Garnett (Refractions Research)
+ * @since   GeoAPI 1.0
+ *
+ * @see GeneralParameterDescriptor
+ */
+@UML(identifier="CC_GeneralParameterValue", specification=ISO_19111)
+public interface GeneralParameterValue extends Cloneable {
+    /**
+     * Returns the abstract definition of this parameter or group of parameters.
+     *
+     * @return The abstract definition of this parameter or group of parameters.
+     */
+    GeneralParameterDescriptor getDescriptor();
+
+    /**
+     * Returns a copy of this parameter value or group.
+     *
+     * @return A copy of this parameter value or group.
+     */
+    GeneralParameterValue clone();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/InvalidParameterCardinalityException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/InvalidParameterCardinalityException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/InvalidParameterCardinalityException.java	(revision 28000)
@@ -0,0 +1,53 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.parameter;
+
+import java.util.List;
+
+
+/**
+ * Throws if adding a {@linkplain ParameterValue parameter value} to a
+ * {@linkplain ParameterValueGroup group} would result in more parameters
+ * than the {@linkplain ParameterDescriptor#getMaximumOccurs maximum occurence}
+ * allowed. This operation may be throws during {@linkplain List#add} or
+ * {@linkplain List#remove} operation on the list returned by
+ * {@link ParameterValueGroup#values}.
+ * <p>
+ * <b>Note:</b> This exception is of kind "{@linkplain IllegalStateException illegal state}"
+ * rather than "{@linkplain IllegalArgumentException illegal argument}" because it is not
+ * caused by a bad argument; it is rather a consequence of an {@linkplain ParameterValueGroup
+ * parameter value group} being "full".
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ *
+ * @see ParameterValueGroup#values
+ * @see ParameterDescriptor#getMinimumOccurs
+ * @see ParameterDescriptor#getMaximumOccurs
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/parameter/InvalidParameterCardinalityException.java $
+ */
+public class InvalidParameterCardinalityException extends IllegalStateException {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 4030549323541812311L;
+
+    /**
+     * Creates an exception with the specified message and parameter name.
+     *
+     * @param message The detail message. The detail message is saved for
+     *                later retrieval by the {@link #getMessage()} method.
+     * @param parameterName The name of the parameter with invalid cardinality.
+     */
+    public InvalidParameterCardinalityException(String message, String parameterName) {
+        super(message);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/InvalidParameterNameException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/InvalidParameterNameException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/InvalidParameterNameException.java	(revision 28000)
@@ -0,0 +1,43 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.parameter;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Thrown when an unexpected parameter was found in a
+ * {@linkplain ParameterDescriptorGroup parameter group}.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/parameter/InvalidParameterNameException.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-004.pdf">Grid Coverage specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="GC_InvalidParameterName", specification=ISO_19111)
+public class InvalidParameterNameException extends IllegalArgumentException {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -8473266898408204803L;
+
+    /**
+     * Creates an exception with the specified message and parameter name.
+     *
+     * @param  message The detail message. The detail message is saved for
+     *         later retrieval by the {@link #getMessage()} method.
+     * @param parameterName The invalid parameter name.
+     */
+    public InvalidParameterNameException(String message, String parameterName) {
+        super(message);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/InvalidParameterTypeException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/InvalidParameterTypeException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/InvalidParameterTypeException.java	(revision 28000)
@@ -0,0 +1,47 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.parameter;
+
+
+/**
+ * Thrown when a parameter can't be cast to the requested type. For example this exception
+ * is thrown when {@link ParameterValue#doubleValue} is invoked but the value is not
+ * convertible to a {@code double}.
+ * <p>
+ * <b>Note:</b> This exception is of kind "{@linkplain IllegalStateException illegal state}"
+ * rather than "{@linkplain IllegalArgumentException illegal argument}" because it is not
+ * caused by a bad argument. It is rather a consequence of invoking the wrong zero-argument
+ * method.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see ParameterValue#intValue
+ * @see ParameterValue#doubleValue
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/parameter/InvalidParameterTypeException.java $
+ */
+public class InvalidParameterTypeException extends IllegalStateException {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 2740762597003093176L;
+
+    /**
+     * Creates an exception with the specified message and parameter name.
+     *
+     * @param message The detail message. The detail message is saved for
+     *                later retrieval by the {@link #getMessage()} method.
+     * @param parameterName The parameter name.
+     */
+    public InvalidParameterTypeException(String message, String parameterName) {
+        super(message);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/InvalidParameterValueException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/InvalidParameterValueException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/InvalidParameterValueException.java	(revision 28000)
@@ -0,0 +1,59 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.parameter;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Thrown when an invalid value was given to a {@linkplain ParameterValue parameter}.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/parameter/InvalidParameterValueException.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-004.pdf">Grid Coverage specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see ParameterValue#setValue(int)
+ * @see ParameterValue#setValue(double)
+ * @see ParameterValue#setValue(Object)
+ */
+@UML(identifier="GC_InvalidParameterValue", specification=ISO_19111)
+public class InvalidParameterValueException extends IllegalArgumentException {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 3814037056147642789L;
+
+    /**
+     * Creates an exception with the specified invalid value.
+     *
+     * @param message The detail message. The detail message is saved for
+     *                later retrieval by the {@link #getMessage()} method.
+     * @param parameterName The parameter name.
+     * @param value The invalid parameter value.
+     */
+    public InvalidParameterValueException(String message, String parameterName, Object value) {
+        super(message);
+    }
+
+    /**
+     * Creates an exception with the specified invalid value as a floating point.
+     *
+     * @param  message The detail message. The detail message is saved for
+     *         later retrieval by the {@link #getMessage()} method.
+     * @param  parameterName The parameter name.
+     * @param  value The invalid parameter value.
+     */
+    public InvalidParameterValueException(String message, String parameterName, double value) {
+        this(message, parameterName, Double.valueOf(value));
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterDescriptor.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterDescriptor.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterDescriptor.java	(revision 28000)
@@ -0,0 +1,119 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.parameter;
+
+import java.util.Set;
+import javax.measure.unit.Unit;
+import org.opengis.util.CodeList;
+import org.opengis.annotation.UML;
+import org.opengis.annotation.Extension;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * The definition of a parameter used by an operation method. Most parameter values are
+ * numeric, but other types of parameter values are possible.
+ *
+ * @param <T> The type of parameter values.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/parameter/ParameterDescriptor.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @author  Jody Garnett (Refractions Research)
+ * @since   GeoAPI 2.0
+ *
+ * @see ParameterValue
+ * @see ParameterDescriptorGroup
+ */
+@UML(identifier="CC_OperationParameter", specification=ISO_19111)
+public interface ParameterDescriptor<T> extends GeneralParameterDescriptor {
+    /**
+     * Creates a new instance of {@linkplain ParameterValue parameter value} initialized with the
+     * {@linkplain #getDefaultValue default value}. The {@linkplain ParameterValue#getDescriptor
+     * parameter value descriptor} for the created parameter value will be {@code this} object.
+     */
+    @Extension
+    ParameterValue<T> createValue();
+
+    /**
+     * Returns the class that describe the type of the parameter.
+     *
+     * @return The type of parameter values.
+     */
+    @UML(identifier="GC_ParameterInfo.type", obligation=MANDATORY, specification=ISO_19111)
+    Class<T> getValueClass();
+
+    /**
+     * Returns the set of allowed values when these are restricted to some finite set or returns
+     * {@code null} otherwise. The returned set usually contains {@linkplain CodeList code list}
+     * or enumeration elements.
+     *
+     * @return A finite set of valid values (usually from a {@linkplain CodeList code list}),
+     *         or {@code null} if it doesn't apply.
+     */
+    @Extension
+    Set<T> getValidValues();
+
+    /**
+     * Returns the default value for the parameter. The return type can be any type
+     * including a {@link Number} or a {@link String}. If there is no default value,
+     * then this method returns {@code null}.
+     *
+     * @return The default value, or {@code null} in none.
+     */
+    @UML(identifier="GC_ParameterInfo.defaultValue", obligation=OPTIONAL, specification=ISO_19111)
+    T getDefaultValue();
+
+    /**
+     * Returns the minimum parameter value.
+     *
+     * If there is no minimum value, or if minimum
+     * value is inappropriate for the {@linkplain #getValueClass parameter type}, then
+     * this method returns {@code null}.
+     * <p>
+     * When the getValueClass() is an array or Collection getMinimumValue
+     * may be used to constrain the contained elements.
+     * </p>
+     * @return The minimum parameter value (often an instance of {@link Double}), or {@code null}.
+     */
+    @UML(identifier="GC_ParameterInfo.minimumValue", obligation=OPTIONAL, specification=ISO_19111)
+    Comparable<T> getMinimumValue();
+
+    /**
+     * Returns the maximum parameter value.
+     *
+     * If there is no maximum value, or if maximum
+     * value is inappropriate for the {@linkplain #getValueClass parameter type}, then
+     * this method returns {@code null}.
+     * <p>
+     * When the getValueClass() is an array or Collection getMaximumValue
+     * may be used to constratin the contained elements.
+     *
+     * @return The minimum parameter value (often an instance of {@link Double}), or {@code null}.
+     */
+    @UML(identifier="GC_ParameterInfo.maximumValue", obligation=OPTIONAL, specification=ISO_19111)
+    Comparable<T> getMaximumValue();
+
+    /**
+     * Returns the unit for
+     * {@linkplain #getDefaultValue default},
+     * {@linkplain #getMinimumValue minimum} and
+     * {@linkplain #getMaximumValue maximum} values.
+     * This attribute apply only if the values is of numeric type (usually an instance
+     * of {@link Double}).
+     *
+     * @return The unit for numeric value, or {@code null} if it doesn't apply to the value type.
+     */
+    @Extension
+    Unit<?> getUnit();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterDescriptorGroup.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterDescriptorGroup.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterDescriptorGroup.java	(revision 28000)
@@ -0,0 +1,78 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.parameter;
+
+import java.util.List;
+import org.opengis.metadata.Identifier;
+import org.opengis.annotation.UML;
+import org.opengis.annotation.Extension;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * The definition of a group of related parameters used by an operation method.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/parameter/ParameterDescriptorGroup.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @author  Jody Garnett (Refractions Research)
+ * @since   GeoAPI 2.0
+ *
+ * @see ParameterValueGroup
+ * @see ParameterDescriptor
+ */
+@UML(identifier="CC_OperationParameterGroup", specification=ISO_19111)
+public interface ParameterDescriptorGroup extends GeneralParameterDescriptor {
+    /**
+     * Creates a new instance of {@linkplain ParameterValueGroup parameter value group}
+     * initialized with the {@linkplain ParameterDescriptor#getDefaultValue default values}.
+     * The {@linkplain ParameterValueGroup#getDescriptor parameter value descriptor}
+     * for the created group will be {@code this} object.
+     *
+     * The number of {@link ParameterValue} objects included must be between the
+     * {@linkplain ParameterDescriptor#getMinimumOccurs minimum} and
+     * {@linkplain ParameterDescriptor#getMaximumOccurs maximum occurences} required.
+     * For example:
+     * <ul>
+     * <li>For {@link ParameterDescriptor} with cardinality 1:* a {@link ParameterValue} will
+     *     be included with the {@linkplain ParameterDescriptor#getDefaultValue default value}
+     *     (even if this default value is null).</li>
+     * <li>For {@link ParameterDescriptor} with cardinality 0:* no entry is required.
+     *     {@link ParameterValue} entries may be created only as needed.</li>
+     * </ul>
+     *
+     * @return A new parameter instance initialized to the default value.
+     */
+    @Extension
+    ParameterValueGroup createValue();
+
+    /**
+     * Returns the parameters in this group.
+     *
+     * @return The descriptor of this group.
+     */
+    @UML(identifier="includesParameter", obligation=MANDATORY, specification=ISO_19111)
+    List<GeneralParameterDescriptor> descriptors();
+
+    /**
+     * Returns the parameter descriptor in this group for the specified
+     * {@linkplain Identifier#getCode identifier code}.
+     *
+     * @param  name The case insensitive {@linkplain Identifier#getCode identifier code} of the
+     *              parameter to search for.
+     * @return The parameter for the given identifier code.
+     * @throws ParameterNotFoundException if there is no parameter for the given identifier code.
+     */
+    @Extension
+    GeneralParameterDescriptor descriptor(String name) throws ParameterNotFoundException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterNotFoundException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterNotFoundException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterNotFoundException.java	(revision 28000)
@@ -0,0 +1,56 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.parameter;
+
+
+/**
+ * Thrown when a required parameter was not found in a
+ * {@linkplain ParameterDescriptorGroup parameter group}.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see ParameterDescriptorGroup#descriptor
+ * @see ParameterValueGroup#parameter
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/parameter/ParameterNotFoundException.java $
+ */
+public class ParameterNotFoundException extends IllegalArgumentException {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -8074834945993975175L;
+
+    /**
+     * The invalid parameter name.
+     */
+    private final String parameterName;
+
+    /**
+     * Creates an exception with the specified message and parameter name.
+     *
+     * @param message The detail message. The detail message is saved for
+     *        later retrieval by the {@link #getMessage()} method.
+     * @param parameterName The name of the parameter which was required but not found.
+     */
+    public ParameterNotFoundException(String message, String parameterName) {
+        super(message);
+        this.parameterName = parameterName;
+    }
+
+    /**
+     * Returns the name of the parameter which was required but not found.
+     *
+     * @return The required parameter name.
+     */
+    public String getParameterName() {
+        return parameterName;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterValue.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterValue.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterValue.java	(revision 28000)
@@ -0,0 +1,200 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.parameter;
+
+import java.net.URI;
+import javax.measure.unit.Unit;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A parameter value used by an operation method. Most parameter values are numeric, but
+ * other types of parameter values are possible. The parameter type can be fetch with the
+ * <code>{@linkplain #getValue()}.{@linkplain Object#getClass() getClass()}</code> idiom.
+ * The {@link #getValue()} and {@link #setValue(Object)} methods can be invoked at any time.
+ * Others getters and setters are parameter-type dependents.
+ *
+ * @param <T> The type of parameter values.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/parameter/ParameterValue.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @author  Jody Garnett (Refractions Research)
+ * @since   GeoAPI 1.0
+ *
+ * @see ParameterDescriptor
+ * @see ParameterValueGroup
+ */
+@UML(identifier="CC_ParameterValue", specification=ISO_19111)
+public interface ParameterValue<T> extends GeneralParameterValue {
+    /**
+     * Returns the abstract definition of this parameter value.
+     *
+     * @return The abstract definition of this parameter value.
+     */
+    ParameterDescriptor<T> getDescriptor();
+
+    /**
+     * Returns the unit of measure of the {@linkplain #doubleValue() parameter value}.
+     * If the parameter value has no unit (for example because it is a {@link String} type),
+     * then this method returns {@code null}. Note that "no unit" doesn't means
+     * "dimensionless".
+     *
+     * @return The unit of measure of the parameter value.
+     *
+     * @see #doubleValue()
+     * @see #doubleValueList
+     * @see #getValue
+     */
+    Unit<?> getUnit();
+
+    /**
+     * Returns the numeric value of the coordinate operation parameter in the specified unit
+     * of measure. This convenience method applies unit conversion on the fly as needed.
+     *
+     * @param  unit The unit of measure for the value to be returned.
+     * @return The numeric value represented by this parameter after conversion to type
+     *         {@code double} and conversion to {@code unit}.
+     * @throws InvalidParameterTypeException if the value is not a numeric type.
+     * @throws IllegalArgumentException if the specified unit is invalid for this parameter.
+     *
+     * @see #getUnit
+     * @see #setValue(double,Unit)
+     * @see #doubleValueList(Unit)
+     */
+    double doubleValue(Unit<?> unit) throws InvalidParameterTypeException;
+
+    /**
+     * Returns the numeric value of the coordinate operation parameter with its
+     * associated {@linkplain #getUnit unit of measure}.
+     *
+     * @return The numeric value represented by this parameter after conversion to type {@code double}.
+     * @throws InvalidParameterTypeException if the value is not a numeric type.
+     * @unitof Measure
+     *
+     * @rename Renamed {@code value} to {@code doubleValue} for consistency with
+     *         {@link Number#doubleValue} and the other {@code fooValue} in this interface.
+     *         Also because {@link #getValue} is already used for an {@link Object} type, for
+     *         consistency with {@link #setValue(Object)}.
+     *
+     * @see #getUnit
+     * @see #setValue(double)
+     * @see #doubleValueList
+     */
+    @UML(identifier="value", obligation=CONDITIONAL, specification=ISO_19111)
+    double doubleValue() throws InvalidParameterTypeException;
+
+    /**
+     * Returns the positive integer value of an operation parameter, usually used
+     * for a count. An integer value does not have an associated unit of measure.
+     *
+     * @return The numeric value represented by this parameter after conversion to type {@code int}.
+     * @throws InvalidParameterTypeException if the value is not an integer type.
+     *
+     * @rename Renamed {@code integerValue} to {@code intValue} for consistency with
+     *         {@link Number#intValue} and the Java primitive type {@code int}.
+     *
+     * @see #setValue(int)
+     * @see #intValueList
+     */
+    @UML(identifier="integerValue", obligation=CONDITIONAL, specification=ISO_19111)
+    int intValue() throws InvalidParameterTypeException;
+
+    /**
+     * Returns the parameter value as an object. The object type is typically a {@link Double},
+     * {@link Integer}, {@link Boolean}, {@link String}, {@link URI}, {@code double[]} or
+     * {@code int[]}.
+     *
+     * @return The parameter value as an object.
+     *
+     * @see #setValue(Object)
+     */
+    @UML(identifier="value", obligation=CONDITIONAL, specification=ISO_19111)
+    T getValue();
+
+    /**
+     * Sets the parameter value as an array of floating point and their associated unit.
+     *
+     * @param  values The parameter values.
+     * @param  unit The unit for the specified value.
+     * @throws InvalidParameterValueException if the floating point type is inappropriate for this
+     *         parameter, or if the value is illegal for some other reason (for example a value out
+     *         of range).
+     */
+    void setValue(double[] values, Unit<?> unit) throws InvalidParameterValueException;
+
+    /**
+     * Sets the parameter value as a floating point and its associated unit.
+     *
+     * @param  value The parameter value.
+     * @param  unit The unit for the specified value.
+     * @throws InvalidParameterValueException if the floating point type is inappropriate for this
+     *         parameter, or if the value is illegal for some other reason (for example a value out
+     *         of range).
+     *
+     * @see #setValue(double)
+     * @see #doubleValue(Unit)
+     */
+    void setValue(double value, Unit<?> unit) throws InvalidParameterValueException;
+
+    /**
+     * Sets the parameter value as a floating point.
+     *
+     * @param  value The parameter value.
+     * @throws InvalidParameterValueException if the floating point type is inappropriate for this
+     *         parameter, or if the value is illegal for some other reason (for example a value out
+     *         of range).
+     *
+     * @see #setValue(double,Unit)
+     * @see #doubleValue()
+     */
+    void setValue(double value) throws InvalidParameterValueException;
+
+    /**
+     * Set the parameter value as an integer.
+     *
+     * @param  value The parameter value.
+     * @throws InvalidParameterValueException if the integer type is inappropriate for this parameter,
+     *         or if the value is illegal for some other reason (for example a value out of range).
+     *
+     * @see #intValue
+     */
+    void setValue(int value) throws InvalidParameterValueException;
+
+    /**
+     * Set the parameter value as an object. The object type is typically a {@link Double},
+     * {@link Integer}, {@link Boolean}, {@link String}, {@link URI}, {@code double[]}
+     * or {@code int[]}.
+     * <p>
+     * The argument is not restricted to the parameterized type {@code T} because the type
+     * is typically unknown (as in <code>group.{@linkplain ParameterValueGroup#parameter
+     * parameter}("<var>name</var>").setValue(<var>value</var>)</code>) and
+     * because some implementations may choose to convert a wider range of types.
+     *
+     * @param  value The parameter value.
+     * @throws InvalidParameterValueException if the type of {@code value} is inappropriate
+     *         for this parameter, or if the value is illegal for some other reason (for example
+     *         the value is numeric and out of range).
+     *
+     * @see #getValue
+     */
+    void setValue(Object value) throws InvalidParameterValueException;
+
+    /**
+     * Returns a copy of this parameter value.
+     *
+     * @return A copy of this parameter value.
+     */
+    ParameterValue clone();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterValueGroup.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterValueGroup.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/parameter/ParameterValueGroup.java	(revision 28000)
@@ -0,0 +1,126 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.parameter;
+
+import java.util.List;
+import org.opengis.metadata.Identifier;
+import org.opengis.annotation.UML;
+import org.opengis.annotation.Extension;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A group of related parameter values. The same group can be repeated more than once in an
+ * {@linkplain org.opengis.referencing.operation.Operation operation} or higher level {@code ParameterValueGroup},
+ * if those instances contain different values of one or more {@link ParameterValue}s which suitably
+ * distinquish among those groups.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/parameter/ParameterValueGroup.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @author  Jody Garnett (Refractions Research)
+ * @since   GeoAPI 1.0
+ *
+ * @see ParameterDescriptorGroup
+ * @see ParameterValue
+ */
+@UML(identifier="CC_ParameterValueGroup", specification=ISO_19111)
+public interface ParameterValueGroup extends GeneralParameterValue {
+    /**
+     * The abstract definition of this group of parameters.
+     *
+     * @departure
+     *   The ISO name was {@code "valuesOfGroup"}. GeoAPI uses {@code "descriptor"} instead in order
+     *   to override the {@linkplain GeneralParameterValue#getDescriptor generic method provided in
+     *   the parent interface}. The "descriptor" name make more apparent that this method returns an
+     *   abstract definition of parameters - not their actual values - and is consistent with usage
+     *   in other Java libraries like {@link javax.media.jai.ParameterList#getParameterListDescriptor
+     *   ParameterList}.
+     */
+    @UML(identifier="valuesOfGroup", obligation=MANDATORY, specification=ISO_19111)
+    ParameterDescriptorGroup getDescriptor();
+
+    /**
+     * Returns the values in this group. The returned list may or may not be unmodifiable;
+     * this is implementation-dependent. However, if some aspects of this list are modifiable,
+     * then any modification shall be reflected back into this {@code ParameterValueGroup}.
+     * More specifically:
+     *
+     * <UL>
+     *   <LI><P>If the list supports the {@link List#add(Object) add} operation, then it should
+     *       ensure that the added {@linkplain GeneralParameterValue general parameter value} is
+     *       valid and can be added to this group.
+     *       An {@link InvalidParameterCardinalityException} (or any other appropriate exception)
+     *       shall be thrown if it is not the case.</P></LI>
+     *   <LI><P>The list may also supports the {@link List#remove(Object) remove} operation as a
+     *       way to remove parameter created by the {@link #parameter} method.</P></LI>
+     * </UL>
+     *
+     * @return The values in this group.
+     */
+    @UML(identifier="includesValue", obligation=MANDATORY, specification=ISO_19111)
+    List<GeneralParameterValue> values();
+
+    /**
+     * Returns the value in this group for the specified {@linkplain Identifier#getCode
+     * identifier code}. If no {@linkplain ParameterValue parameter value} is found but
+     * a {@linkplain ParameterDescriptor parameter descriptor} is found (which may occurs
+     * if the parameter is optional, i.e. <code>{@linkplain ParameterDescriptor#getMinimumOccurs
+     * minimumOccurs} == 0</code>), then a {@linkplain ParameterValue parameter value} is
+     * automatically created and initialized to its {@linkplain ParameterDescriptor#getDefaultValue
+     * default value} (if any).
+     * <p>
+     * This convenience method provides a way to get and set parameter values by name. For
+     * example the following idiom fetches a floating point value for the
+     * {@code "false_easting"} parameter:
+     *
+     * <blockquote><code>
+     * double value = parameter("false_easting").{@linkplain ParameterValue#doubleValue() doubleValue()};
+     * </code></blockquote>
+     *
+     * This method do not search recursively in subgroups. This is because more than one
+     * subgroup may exist for the same {@linkplain ParameterDescriptorGroup descriptor}.
+     * The user must {@linkplain #groups query all subgroups} and select explicitly the
+     * appropriate one to use.
+     *
+     * @param  name The case insensitive {@linkplain Identifier#getCode identifier code} of the
+     *              parameter to search for.
+     * @return The parameter value for the given identifier code.
+     * @throws ParameterNotFoundException if there is no parameter value for the given identifier code.
+     */
+    @Extension
+    ParameterValue<?> parameter(String name) throws ParameterNotFoundException;
+
+    /**
+     * Returns all subgroups with the specified name. This method do not create new groups.
+     * If the requested group is optional (i.e.
+     * <code>{@linkplain ParameterDescriptor#getMinimumOccurs minimumOccurs} == 0</code>)
+     * and no value were defined previously, then this method returns an empty set.
+     *
+     * @param  name The case insensitive {@linkplain Identifier#getCode identifier code} of the
+     *              parameter group to search for.
+     * @return The set of all parameter group for the given identifier code.
+     * @throws ParameterNotFoundException if no {@linkplain ParameterDescriptorGroup descriptor}
+     *         was found for the given name.
+     */
+    @Extension
+    List<ParameterValueGroup> groups(String name) throws ParameterNotFoundException;
+
+    /**
+     * Returns a copy of this group of parameter values.
+     * Included parameter values and subgroups are cloned recursively.
+     *
+     * @return A copy of this group of parameter values.
+     */
+    ParameterValueGroup clone();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/AuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/AuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/AuthorityFactory.java	(revision 28000)
@@ -0,0 +1,106 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing;
+
+import java.util.Set;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.util.InternationalString;
+import org.opengis.annotation.UML;
+import org.opengis.annotation.Extension;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Base interface for all authority factories. An <cite>authority</cite> is an
+ * organization that maintains definitions of authority codes. An <cite>authority
+ * code</cite> is a compact string defined by an authority to reference a particular
+ * spatial reference object. For example the
+ * <A HREF="http://www.epsg.org">European Petroleum Survey Group (EPSG)</A> maintains
+ * a database of coordinate systems, and other spatial referencing objects, where each
+ * object has a code number ID. For example, the EPSG code for a WGS84 Lat/Lon coordinate
+ * system is '4326'.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/AuthorityFactory.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-009.pdf">Implementation specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CS_CoordinateSystemAuthorityFactory", specification=OGC_01009)
+public interface AuthorityFactory extends Factory {
+    /**
+     * Returns the organization or party responsible for definition and maintenance of the
+     * database.
+     *
+     * @return The organization reponsible for definition of the database.
+     */
+    @UML(identifier="getAuthority", specification=OGC_01009)
+    Citation getAuthority();
+
+    /**
+     * Returns the set of authority codes of the given type. The {@code type}
+     * argument specify the base class. For example if this factory is an instance
+     * of {@link org.opengis.referencing.crs.CRSAuthorityFactory}, then:
+     * <ul>
+     *   <li><b><code>{@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem}.class&nbsp;</code></b>
+     *       asks for all authority codes accepted by one of
+     *       {@link org.opengis.referencing.crs.CRSAuthorityFactory#createGeographicCRS createGeographicCRS},
+     *       {@link org.opengis.referencing.crs.CRSAuthorityFactory#createProjectedCRS createProjectedCRS},
+     *       {@link org.opengis.referencing.crs.CRSAuthorityFactory#createVerticalCRS createVerticalCRS},
+     *       {@link org.opengis.referencing.crs.CRSAuthorityFactory#createTemporalCRS createTemporalCRS}
+     *       and their friends.</li>
+     *   <li><b><code>{@linkplain org.opengis.referencing.crs.ProjectedCRS}.class&nbsp;</code></b>
+     *       asks only for authority codes accepted by
+     *       {@link org.opengis.referencing.crs.CRSAuthorityFactory#createProjectedCRS createProjectedCRS}.</li>
+     * </ul>
+     *
+     * @param  type The spatial reference objects type.
+     * @return The set of authority codes for spatial reference objects of the given type.
+     *         If this factory doesn't contains any object of the given type, then this method
+     *         returns an {@linkplain java.util.Collections#EMPTY_SET empty set}.
+     * @throws FactoryException if access to the underlying database failed.
+     */
+    @Extension
+    Set<String> getAuthorityCodes(Class<? extends IdentifiedObject> type) throws FactoryException;
+
+    /**
+     * Gets a description of the object corresponding to a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return A description of the object, or {@code null} if the object
+     *         corresponding to the specified {@code code} has no description.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the query failed for some other reason.
+     */
+    @UML(identifier="descriptionText", specification=OGC_01009)
+    InternationalString getDescriptionText(String code) throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Returns an arbitrary object from a code. The returned object will typically be an
+     * instance of {@link org.opengis.referencing.datum.Datum}, {@link org.opengis.referencing.cs.CoordinateSystem},
+     * {@link org.opengis.referencing.ReferenceSystem} or {@link org.opengis.referencing.operation.CoordinateOperation}.
+     * If the type of the object is know at compile time, it is recommended to invoke the
+     * most precise method instead of this one (for example
+     * <code>&nbsp;{@linkplain org.opengis.referencing.crs.CRSAuthorityFactory#createCoordinateReferenceSystem
+     * createCoordinateReferenceSystem}(code)&nbsp;</code> instead of <code>&nbsp;createObject(code)&nbsp;</code>
+     * if the caller know he is asking for a {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem coordinate
+     * reference system}).
+     *
+     * @param  code Value allocated by authority.
+     * @return The object for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createDatum
+     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createCoordinateReferenceSystem
+     */
+    @Extension
+    IdentifiedObject createObject(String code) throws NoSuchAuthorityCodeException, FactoryException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/Factory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/Factory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/Factory.java	(revision 28000)
@@ -0,0 +1,44 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing;
+
+import org.opengis.metadata.citation.Citation;
+import org.opengis.annotation.Extension;
+
+
+/**
+ * Base interface for all factories. Factories can be grouped in two categories:
+ * <p>
+ * <UL>
+ *   <LI>{@linkplain AuthorityFactory Authority factories} creates objects from
+ *       a compact string defined by an authority.</LI>
+ *   <LI>{@linkplain ObjectFactory Object factories} allows applications
+ *       to make objects that cannot be created by an authority factory.
+ *       This factory is very flexible, whereas the authority factory is
+ *       easier to use.</LI>
+ * </UL>
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/Factory.java $
+ */
+@Extension
+public interface Factory {
+    /**
+     * Returns the vendor responsible for creating this factory implementation. Many implementations
+     * may be available for the same factory interface. Implementations are usually managed by a
+     * {@linkplain javax.imageio.spi.ServiceRegistry service registry}.
+     *
+     * @return The vendor for this factory implementation.
+     */
+    @Extension
+    Citation getVendor();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/FactoryException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/FactoryException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/FactoryException.java	(revision 28000)
@@ -0,0 +1,80 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing;
+
+
+/**
+ * Thrown when a {@linkplain Factory factory} can't create an instance
+ * of the requested object. It may be a failure to create a
+ * {@linkplain org.opengis.referencing.datum.Datum datum}, a
+ * {@linkplain org.opengis.referencing.cs.CoordinateSystem coordinate system}, a
+ * {@linkplain org.opengis.referencing.ReferenceSystem reference system} or a
+ * {@linkplain org.opengis.referencing.operation.CoordinateOperation coordinate operation}.
+ *
+ * If the failure is caused by an illegal authority code, then the actual exception should
+ * be {@link NoSuchAuthorityCodeException}. Otherwise, if the failure is caused by some
+ * error in the underlying database (e.g. {@link java.io.IOException} or
+ * {@link java.sql.SQLException}), then this cause should be specified.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.operation.CoordinateOperationFactory
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/FactoryException.java $
+ */
+public class FactoryException extends Exception {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -3414250034883898315L;
+
+    /**
+     * Construct an exception with no detail message.
+     */
+    public FactoryException() {
+    }
+
+    /**
+     * Construct an exception with the specified detail message.
+     *
+     * @param  message The detail message. The detail message is saved
+     *         for later retrieval by the {@link #getMessage()} method.
+     */
+    public FactoryException(String message) {
+        super(message);
+    }
+
+    /**
+     * Construct an exception with the specified cause. The detail message
+     * is copied from the cause {@linkplain Exception#getLocalizedMessage
+     * localized message}.
+     *
+     * @param  cause The cause for this exception. The cause is saved
+     *         for later retrieval by the {@link #getCause()} method.
+     */
+    public FactoryException(Exception cause) {
+        super(cause.getLocalizedMessage(), cause);
+    }
+
+    /**
+     * Construct an exception with the specified detail message and cause.
+     * The cause is the exception thrown in the underlying database
+     * (e.g. {@link java.io.IOException} or {@link java.sql.SQLException}).
+     *
+     * @param  message The detail message. The detail message is saved
+     *         for later retrieval by the {@link #getMessage()} method.
+     * @param  cause The cause for this exception. The cause is saved
+     *         for later retrieval by the {@link #getCause()} method.
+     */
+    public FactoryException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/IdentifiedObject.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/IdentifiedObject.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/IdentifiedObject.java	(revision 28000)
@@ -0,0 +1,115 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing;
+
+import static org.opengis.annotation.Obligation.MANDATORY;
+import static org.opengis.annotation.Obligation.OPTIONAL;
+import static org.opengis.annotation.Specification.ISO_19111;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.opengis.annotation.UML;
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * Supplementary identification and remarks information for a CRS or CRS-related object.
+ * When {@link org.opengis.referencing.crs.CRSAuthorityFactory} is used to create an object,
+ * the {@linkplain ReferenceIdentifier#getAuthority authority} and
+ * {@linkplain ReferenceIdentifier#getCode authority code} values should be set to the
+ * authority name of the factory object, and the authority code supplied by the client,
+ * respectively. The other values may or may not be set. If the authority is EPSG, the
+ * implementer may consider using the corresponding metadata values in the EPSG tables.
+ *
+ * @departure
+ *   ISO 19111 defines also an {@code IdentifiedObjectBase} interface. The later is omitted in GeoAPI
+ *   because the split between {@code IdentifiedObject} and {@code IdentifiedObjectBase} in OGC/ISO
+ *   specification was mostly a workaround for introducing {@code IdentifiedObject} in ISO 19111
+ *   without changing the {@code ReferenceSystem} definition in ISO 19115.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/IdentifiedObject.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="IO_IdentifiedObject", specification=ISO_19111)
+public interface IdentifiedObject {
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain ObjectFactory object factory} <code>createFoo(&hellip;)</code> methods.
+     * This is used for setting the value to be returned by {@link #getName}.
+     *
+     * @see #getName
+     */
+    String NAME_KEY = "name";
+
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain ObjectFactory object factory} <code>createFoo(&hellip;)</code> methods.
+     * This is used for setting the value to be returned by {@link #getAlias}.
+     *
+     * @see #getAlias
+     */
+    String ALIAS_KEY = "alias";
+
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain ObjectFactory object factory} <code>createFoo(&hellip;)</code> methods.
+     * This is used for setting the value to be returned by {@link #getIdentifiers}.
+     *
+     * @see #getIdentifiers
+     */
+    String IDENTIFIERS_KEY = "identifiers";
+
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain ObjectFactory object factory} <code>createFoo(&hellip;)</code> methods.
+     * This is used for setting the value to be returned by {@link #getRemarks}.
+     *
+     * @see #getRemarks
+     */
+    String REMARKS_KEY = "remarks";
+
+    /**
+     * The primary name by which this object is identified.
+     *
+     * @return The primary name.
+     */
+    @UML(identifier="name", obligation=MANDATORY, specification=ISO_19111)
+    ReferenceIdentifier getName();
+
+    /**
+     * An alternative name by which this object is identified.
+     *
+     * @return The aliases, or an empty collection if there is none.
+     */
+    @UML(identifier="alias", obligation=OPTIONAL, specification=ISO_19111)
+    Collection<GenericName> getAlias();
+
+    /**
+     * An identifier which references elsewhere the object's defining information.
+     * Alternatively an identifier by which this object can be referenced.
+     *
+     * @return This object identifiers, or an empty set if there is none.
+     */
+    @UML(identifier="identifier", obligation=OPTIONAL, specification=ISO_19111)
+    Set<ReferenceIdentifier> getIdentifiers();
+
+    /**
+     * Comments on or information about this object, including data source information.
+     *
+     * @return The remarks, or {@code null} if none.
+     */
+    @UML(identifier="remarks", obligation=OPTIONAL, specification=ISO_19111)
+    InternationalString getRemarks();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/NoSuchAuthorityCodeException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/NoSuchAuthorityCodeException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/NoSuchAuthorityCodeException.java	(revision 28000)
@@ -0,0 +1,42 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing;
+
+
+/**
+ * Thrown when an {@linkplain AuthorityFactory authority factory} can't find
+ * the requested authority code.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.datum.DatumAuthorityFactory
+ * @see org.opengis.referencing.crs.CRSAuthorityFactory
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/NoSuchAuthorityCodeException.java $
+ */
+public class NoSuchAuthorityCodeException extends FactoryException {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -1573748311981746573L;
+
+    /**
+     * Constructs an exception with the specified detail message and authority code.
+     *
+     * @param  message The detail message. The detail message is saved
+     *         for later retrieval by the {@link #getMessage()} method.
+     * @param  authority The authority.
+     * @param  code The invalid authority code.
+     */
+    public NoSuchAuthorityCodeException(String message, String authority, String code) {
+        super(message);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/NoSuchIdentifierException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/NoSuchIdentifierException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/NoSuchIdentifierException.java	(revision 28000)
@@ -0,0 +1,41 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing;
+
+
+/**
+ * Thrown when a {@linkplain org.opengis.referencing.operation.MathTransform math transform}
+ * as been requested with an unknow {@linkplain org.opengis.referencing.operation.OperationMethod
+ * operation method} identifier.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.operation.MathTransformFactory#createParameterizedTransform
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/NoSuchIdentifierException.java $
+ */
+public class NoSuchIdentifierException extends FactoryException {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -6846799994429345902L;
+
+    /**
+     * Constructs an exception with the specified detail message and classification name.
+     *
+     * @param  message The detail message. The detail message is saved
+     *         for later retrieval by the {@link #getMessage()} method.
+     * @param identifier {@linkplain ReferenceIdentifier#getCode identifier code}.
+     */
+    public NoSuchIdentifierException(final String message, final String identifier) {
+        super(message);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/ObjectFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/ObjectFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/ObjectFactory.java	(revision 28000)
@@ -0,0 +1,102 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing;
+
+import java.util.Map;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.Collections;
+import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.Citation;
+import org.opengis.util.InternationalString;
+import org.opengis.util.GenericName;
+import org.opengis.annotation.Extension;
+
+
+/**
+ * Base interface for all factories of {@linkplain IdentifiedObject identified objects}. Factories
+ * build up complex objects from simpler objects or values. This factory allows applications to make
+ * {@linkplain org.opengis.referencing.cs.CoordinateSystem coordinate systems},
+ * {@linkplain org.opengis.referencing.datum.Datum datum} or
+ * {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference systems}
+ * that cannot be created by an {@linkplain AuthorityFactory authority factory}. This factory is
+ * very flexible, whereas the authority factory is easier to use.
+ * <p>
+ * <b>Object properties</b><br>
+ * Most factory methods expect a {@link Map} argument. The map can be a {@link Properties} instance.
+ * The map shall contains at least a {@code "name"} property. In the common case where the name is
+ * the only property, the map may be constructed with
+ *
+ * <code>Collections.{@linkplain Collections#singletonMap singletonMap}("name", <var>theName</var>)</code>
+ *
+ * where <var>theName</var> is an arbitrary name as free text.
+ * <p>
+ * Implementations are encouraged to recognize at least the properties listed in the following
+ * table. Additional implementation-specific properties can be added. Unknown properties shall
+ * be ignored.
+ * <p>
+ * <table border='1'>
+ *   <tr bgcolor="#CCCCFF" class="TableHeadingColor">
+ *     <th nowrap>Property name</th>
+ *     <th nowrap>Value type</th>
+ *     <th nowrap>Value given to</th>
+ *   </tr>
+ *   <tr>
+ *     <td nowrap>&nbsp;{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link org.opengis.referencing.ReferenceIdentifier} or {@link String}&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link IdentifiedObject#getName}</td>
+ *   </tr>
+ *   <tr>
+ *     <td nowrap>&nbsp;{@value org.opengis.referencing.IdentifiedObject#ALIAS_KEY}&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link String}, <code>{@linkplain String}[]</code>,
+ *     {@link GenericName} or <code>{@linkplain GenericName}[]</code>&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link IdentifiedObject#getAlias}</td>
+ *   </tr>
+ *   <tr>
+ *     <td nowrap>&nbsp;{@value org.opengis.metadata.Identifier#AUTHORITY_KEY}&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link String} or {@link Citation}&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link Identifier#getAuthority} on the {@linkplain IdentifiedObject#getName name}</td>
+ *   </tr>
+ *   <tr>
+ *     <td nowrap>&nbsp;{@value org.opengis.referencing.ReferenceIdentifier#CODESPACE_KEY}&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link String}&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link ReferenceIdentifier#getCodeSpace} on the {@linkplain IdentifiedObject#getName name}</td>
+ *   </tr>
+ *   <tr>
+ *     <td nowrap>&nbsp;{@value org.opengis.referencing.ReferenceIdentifier#VERSION_KEY}&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link String}&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link ReferenceIdentifier#getVersion} on the {@linkplain IdentifiedObject#getName name}</td>
+ *   </tr>
+ *   <tr>
+ *     <td nowrap>&nbsp;{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link Identifier} or <code>{@linkplain Identifier}[]</code>&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link IdentifiedObject#getIdentifiers}</td>
+ *   </tr>
+ *   <tr>
+ *     <td nowrap>&nbsp;{@value org.opengis.referencing.IdentifiedObject#REMARKS_KEY}&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link String} or {@link InternationalString}&nbsp;</td>
+ *     <td nowrap>&nbsp;{@link IdentifiedObject#getRemarks}</td>
+ *   </tr>
+ * </table>
+ * <p>
+ * The {@code "name"} property is mandatory. All others are optional. All localizable attributes
+ * like {@code "remarks"} can have a language and country code suffix. For example the
+ * {@code "remarks_fr"} property stands for remarks in {@linkplain Locale#FRENCH French} and the
+ * {@code "remarks_fr_CA"} property stands for remarks in {@linkplain Locale#CANADA_FRENCH French Canadian}.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/ObjectFactory.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-009.pdf">Implementation specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ */
+@Extension
+public interface ObjectFactory extends Factory {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/ReferenceIdentifier.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/ReferenceIdentifier.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/ReferenceIdentifier.java	(revision 28000)
@@ -0,0 +1,55 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing;
+
+import org.opengis.annotation.UML;
+import org.opengis.metadata.Identifier;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Identifier used for reference systems.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/ReferenceIdentifier.java $
+ * @version <A HREF="http://www.opengeospatial.org/standards/as#01-111">ISO 19115</A>
+ * @author  Ely Conn (Leica Geosystems Geospatial Imaging, LLC)
+ * @since   GeoAPI 2.1
+ */
+@UML(identifier="RS_Identifier", specification=ISO_19115)
+public interface ReferenceIdentifier extends Identifier {
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain org.opengis.referencing.ObjectFactory CRS factory} <code>createFoo(&hellip;)</code>
+     * methods. This is used for setting the value to be returned by {@link #getCodeSpace}.
+     *
+     * @see #getCodeSpace
+     */
+    String CODESPACE_KEY = "codespace";
+
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain org.opengis.referencing.ObjectFactory CRS factory} <code>createFoo(&hellip;)</code>
+     * methods. This is used for setting the value to be returned by {@link #getVersion}.
+     *
+     * @see #getVersion
+     */
+    String VERSION_KEY = "version";
+
+    /**
+     * Name or identifier of the person or organization responsible for namespace.
+     *
+     * @return The identifier code space.
+     */
+    @UML(identifier="codeSpace", obligation=OPTIONAL, specification=ISO_19115)
+    String getCodeSpace();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/ReferenceSystem.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/ReferenceSystem.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/ReferenceSystem.java	(revision 28000)
@@ -0,0 +1,77 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing;
+
+import org.opengis.metadata.extent.Extent;
+import org.opengis.util.InternationalString;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Description of a spatial and temporal reference system used by a dataset.
+ *
+ * @departure
+ *   This interface was initially derived from an ISO 19111 specification published in 2003. Later
+ *   revisions (in 2005) rely on an interface defined in ISO 19115 instead. The annotations were
+ *   updated accordingly, but this interface is still defined in the referencing package instead
+ *   of metadata and the {@link #getScope()} method still defined here for this historical reason.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/ReferenceSystem.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.crs.CoordinateReferenceSystem
+ */
+@UML(identifier="RS_ReferenceSystem", specification=ISO_19115)
+public interface ReferenceSystem extends IdentifiedObject {
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain ObjectFactory object factory} <code>createFoo(&hellip;)</code> methods.
+     * This is used for setting the value to be returned by {@link #getDomainOfValidity}.
+     *
+     * @see #getDomainOfValidity
+     *
+     * @since GeoAPI 2.1
+     */
+    String DOMAIN_OF_VALIDITY_KEY = "domainOfValidity";
+
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain ObjectFactory object factory} <code>createFoo(&hellip;)</code> methods.
+     * This is used for setting the value to be returned by {@link #getScope}.
+     *
+     * @see #getScope
+     */
+    String SCOPE_KEY = "scope";
+
+    /**
+     * Area or region or timeframe in which this (coordinate) reference system is valid.
+     *
+     * @return The reference system valid domain, or {@code null} if not available.
+     *
+     * @since GeoAPI 2.1
+     */
+    @UML(identifier="domainOfValidity", obligation=OPTIONAL, specification=ISO_19111)
+    Extent getDomainOfValidity();
+
+    /**
+     * Description of domain of usage, or limitations of usage, for which this
+     * (coordinate) reference system object is valid.
+     *
+     * @return The domain of usage, or {@code null} if none.
+     */
+    @UML(identifier="SC_CRS.scope", obligation=OPTIONAL, specification=ISO_19111)
+    InternationalString getScope();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/CRSAuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/CRSAuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/CRSAuthorityFactory.java	(revision 28000)
@@ -0,0 +1,173 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import org.opengis.referencing.AuthorityFactory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;  // For javadoc
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Creates {@linkplain CoordinateReferenceSystem coordinate reference systems} using authority codes. External authorities
+ * are used to manage definitions of objects used in this interface. The definitions of these objects are
+ * referenced using code strings. A commonly used authority is <A HREF="http://www.epsg.org">EPSG</A>,
+ * which is also used in the <A HREF="http://www.remotesensing.org/geotiff/geotiff.html">GeoTIFF</A>
+ * standard.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/CRSAuthorityFactory.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-009.pdf">Implementation specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.cs.CSAuthorityFactory
+ * @see org.opengis.referencing.datum.DatumAuthorityFactory
+ */
+@UML(identifier="CS_CoordinateSystemAuthorityFactory", specification=OGC_01009)
+public interface CRSAuthorityFactory extends AuthorityFactory {
+    /**
+     * Returns an arbitrary {@linkplain CoordinateReferenceSystem coordinate reference system} from a code. If the
+     * coordinate reference system type is know at compile time, it is recommended to invoke the most precise method
+     * instead of this one (for example
+     * <code>&nbsp;{@linkplain #createGeographicCRS createGeographicCRS}(code)&nbsp;</code>
+     * instead of <code>&nbsp;createCoordinateReferenceSystem(code)&nbsp;</code> if the caller
+     * know he is asking for a {@linkplain GeographicCRS geographic coordinate reference system}).
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createGeographicCRS
+     * @see #createProjectedCRS
+     * @see #createVerticalCRS
+     * @see #createTemporalCRS
+     * @see #createCompoundCRS
+     */
+    @UML(identifier="createHorizontalCoordinateSystem", specification=OGC_01009)
+    CoordinateReferenceSystem createCoordinateReferenceSystem(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates a 3D coordinate reference system from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    @UML(identifier="createCompoundCoordinateSystem", specification=OGC_01009)
+    CompoundCRS createCompoundCRS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates a derived coordinate reference system from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    DerivedCRS createDerivedCRS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Create a {@linkplain EngineeringCRS engineering coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    EngineeringCRS createEngineeringCRS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Returns a {@linkplain GeographicCRS geographic coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createGeodeticDatum
+     */
+    @UML(identifier="createGeographicCoordinateSystem", specification=OGC_01009)
+    GeographicCRS createGeographicCRS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Returns a {@linkplain GeocentricCRS geocentric coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createGeodeticDatum
+     */
+    GeocentricCRS createGeocentricCRS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Create a {@linkplain ImageCRS image coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    ImageCRS createImageCRS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Returns a {@linkplain ProjectedCRS projected coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createGeodeticDatum
+     */
+    @UML(identifier="createProjectedCoordinateSystem", specification=OGC_01009)
+    ProjectedCRS createProjectedCRS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Create a {@linkplain TemporalCRS temporal coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createTemporalDatum
+     */
+    TemporalCRS createTemporalCRS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Create a {@linkplain VerticalCRS vertical coordinate reference system} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate reference system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createVerticalDatum
+     */
+    @UML(identifier="createVerticalCoordinateSystem", specification=OGC_01009)
+    VerticalCRS createVerticalCRS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/CRSFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/CRSFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/CRSFactory.java	(revision 28000)
@@ -0,0 +1,225 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import java.util.Map;
+import org.opengis.referencing.cs.*;
+import org.opengis.referencing.datum.*;
+import org.opengis.referencing.operation.*;
+import org.opengis.referencing.ObjectFactory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Builds up complex {@linkplain CoordinateReferenceSystem coordinate reference systems}
+ * from simpler objects or values. {@code CRSFactory} allows applications to make
+ * {@linkplain CoordinateReferenceSystem coordinate reference systems} that cannot be
+ * created by a {@link CRSAuthorityFactory}. This factory is very flexible, whereas the
+ * authority factory is easier to use.
+ *
+ * So {@link CRSAuthorityFactory} can be used to make "standard" coordinate reference systems,
+ * and {@code CRSFactory} can be used to make "special" coordinate reference systems.
+ *
+ * For example, the EPSG authority has codes for USA state plane coordinate systems
+ * using the NAD83 datum, but these coordinate systems always use meters.  EPSG does
+ * not have codes for NAD83 state plane coordinate systems that use feet units.  This
+ * factory lets an application create such a hybrid coordinate system.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/CRSFactory.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-009.pdf">Implementation specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.cs.CSFactory
+ * @see org.opengis.referencing.datum.DatumFactory
+ */
+@UML(identifier="CS_CoordinateSystemFactory", specification=OGC_01009)
+public interface CRSFactory extends ObjectFactory {
+    /**
+     * Creates a compound coordinate reference system from an ordered
+     * list of {@code CoordinateReferenceSystem} objects.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  elements ordered array of {@code CoordinateReferenceSystem} objects.
+     * @return The coordinate reference system for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createCompoundCoordinateSystem", specification=OGC_01009)
+    CompoundCRS createCompoundCRS(Map<String, ?>              properties,
+                                  CoordinateReferenceSystem[] elements) throws FactoryException;
+
+    /**
+     * Creates a engineering coordinate reference system.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  datum Engineering datum to use in created CRS.
+     * @param  cs The coordinate system for the created CRS.
+     * @return The coordinate reference system for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createLocalCoordinateSystem", specification=OGC_01009)
+    EngineeringCRS createEngineeringCRS(Map<String, ?>   properties,
+                                        EngineeringDatum datum,
+                                        CoordinateSystem cs) throws FactoryException;
+
+    /**
+     * Creates a vertical coordinate reference system.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  datum Vertical datum to use in created CRS.
+     * @param  cs The Vertical coordinate system for the created CRS.
+     * @return The coordinate reference system for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createVerticalCoordinateSystem", specification=OGC_01009)
+    VerticalCRS createVerticalCRS(Map<String, ?> properties,
+                                  VerticalDatum  datum,
+                                  VerticalCS     cs) throws FactoryException;
+
+    /**
+     * Creates a geocentric coordinate reference system from a {@linkplain CartesianCS
+     * cartesian coordinate system}.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  datum Geodetic datum to use in created CRS.
+     * @param  cs The cartesian coordinate system for the created CRS.
+     * @return The coordinate reference system for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    GeocentricCRS createGeocentricCRS(Map<String, ?> properties,
+                                      GeodeticDatum  datum,
+                                      CartesianCS    cs) throws FactoryException;
+
+    /**
+     * Creates a geographic coordinate reference system.
+     * It could be <var>Latitude</var>/<var>Longitude</var> or
+     * <var>Longitude</var>/<var>Latitude</var>.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  datum Geodetic datum to use in created CRS.
+     * @param  cs The ellipsoidal coordinate system for the created CRS.
+     * @return The coordinate reference system for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createGeographicCoordinateSystem", specification=OGC_01009)
+    GeographicCRS createGeographicCRS(Map<String, ?> properties,
+                                      GeodeticDatum  datum,
+                                      EllipsoidalCS  cs) throws FactoryException;
+
+    /**
+     * Creates a derived coordinate reference system. If the transform is an affine
+     * map performing a rotation, then any mixed axes must have identical units.
+     * For example, a (<var>lat_deg</var>, <var>lon_deg</var>, <var>height_feet</var>)
+     * system can be rotated in the (<var>lat</var>, <var>lon</var>) plane, since both
+     * affected axes are in degrees. But the transform should not rotate this coordinate
+     * system in any other plane.
+     * <p>
+     * The {@code conversionFromBase} shall contains the {@linkplain Conversion#getParameterValues
+     * parameter values} required for the conversion. It may or may not contain the corresponding
+     * "{@linkplain Conversion#getMathTransform base to derived}" transform, at user's choice. If
+     * a transform is provided, this method may or may not use it at implementation choice.
+     * Otherwise it shall creates the transform from the parameters.
+     * <p>
+     * It is the user's responsability to ensure that the conversion performs all required steps,
+     * including unit conversions and change of axis order, if needed. Note that this behavior is
+     * different than {@link #createProjectedCRS createProjectedCRS} because transforms other than
+     * <cite>cartographic projections</cite> are not standardized.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  baseCRS Coordinate reference system to base the projection on. The number of axes
+     *         must matches the {@linkplain OperationMethod#getSourceDimensions source dimensions}
+     *         of the conversion from base.
+     * @param  conversionFromBase The
+     *         {@linkplain CoordinateOperationFactory#createDefiningConversion defining conversion}.
+     * @param  derivedCS The coordinate system for the derived CRS. The number of axes must matches
+     *         the {@linkplain OperationMethod#getTargetDimensions target dimensions} of the conversion
+     *         from base.
+     * @return The coordinate reference system for the given properties.
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see CoordinateOperationFactory#createDefiningConversion
+     * @see MathTransformFactory#createBaseToDerived
+     *
+     * @since GeoAPI 2.1
+     */
+    @UML(identifier="createFittedCoordinateSystem", specification=OGC_01009)
+    DerivedCRS createDerivedCRS(Map<String,?>          properties,
+                                CoordinateReferenceSystem baseCRS,
+                                Conversion     conversionFromBase,
+                                CoordinateSystem derivedCS) throws FactoryException;
+
+    /**
+     * Creates a projected coordinate reference system from a defining conversion.
+     * The {@code conversionFromBase} shall contains the {@linkplain Conversion#getParameterValues
+     * parameter values} required for the projection. It may or may not contain the corresponding
+     * "{@linkplain Conversion#getMathTransform base to derived}" transform, at user's choice. If
+     * a transform is provided, this method may or may not use it at implementation choice.
+     * Otherwise it shall creates the transform from the parameters.
+     * <p>
+     * The supplied conversion should <strong>not</strong> includes the operation steps for
+     * performing {@linkplain CoordinateSystemAxis#getUnit unit} conversions and change of
+     * {@linkplain CoordinateSystem#getAxis axis} order; those operations shall be inferred
+     * by this constructor by some code equivalent to:
+     *
+     * <blockquote><code>
+     * MathTransform baseToDerived = {@linkplain MathTransformFactory#createBaseToDerived
+     * MathTransformFactory.createBaseToDerived}(baseCRS, parameters, derivedCS)
+     * </code></blockquote>
+     *
+     * This behavior is different than {@link #createDerivedCRS createDerivedCRS} because
+     * parameterized transforms are standardized for projections. See the {@linkplain
+     * MathTransformFactory#createParameterizedTransform note on cartographic projections}.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  baseCRS Geographic coordinate reference system to base the projection on. The number
+     *         of axes must matches the {@linkplain OperationMethod#getSourceDimensions source dimensions}
+     *         of the conversion from base.
+     * @param  conversionFromBase The
+     *         {@linkplain CoordinateOperationFactory#createDefiningConversion defining conversion}.
+     * @param  derivedCS The coordinate system for the projected CRS. The number of axes must matches
+     *         the {@linkplain OperationMethod#getTargetDimensions target dimensions} of the conversion
+     *         from base.
+     * @return The coordinate reference system for the given properties.
+     * @throws FactoryException if the object creation failed.
+     *
+     * @see CoordinateOperationFactory#createDefiningConversion
+     * @see MathTransformFactory#createBaseToDerived
+     *
+     * @since GeoAPI 2.1
+     */
+    @UML(identifier="createProjectedCoordinateSystem", specification=OGC_01009)
+    ProjectedCRS createProjectedCRS(Map<String,?> properties,
+                                    GeographicCRS baseCRS,
+                                    Conversion    conversionFromBase,
+                                    CartesianCS   derivedCS) throws FactoryException;
+
+    /**
+     * Creates a coordinate reference system object from a string.
+     * The <A HREF="../doc-files/WKT.html">definition for WKT</A>
+     * is shown using Extended Backus Naur Form (EBNF).
+     *
+     * @param  wkt Coordinate system encoded in Well-Known Text format.
+     * @return The coordinate reference system for the given WKT.
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createFromWKT", specification=OGC_01009)
+    CoordinateReferenceSystem createFromWKT(String wkt) throws FactoryException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/CompoundCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/CompoundCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/CompoundCRS.java	(revision 28000)
@@ -0,0 +1,66 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import java.util.List;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A coordinate reference system describing the position of points through two or more
+ * independent coordinate reference systems. Thus it is associated with two or more
+ * {@linkplain org.opengis.referencing.cs.CoordinateSystem Coordinate Systems} and
+ * {@linkplain org.opengis.referencing.datum.Datum Datums} by defining the compound CRS
+ * as an ordered set of two or more instances of {@link CoordinateReferenceSystem}.
+ * <p>
+ * In general, a Compound CRS may contain any number of axes. The Compound CRS contains an
+ * ordered set of coordinate reference systems and the tuple order of a compound coordinate
+ * set shall follow that order, while the subsets of the tuple, described by each of the
+ * composing coordinate reference systems, follow the tuple order valid for their respective
+ * coordinate reference systems.
+ * <p>
+ * For spatial coordinates, a number of constraints exist for the construction of Compound CRSs.
+ * For example, the coordinate reference systems that are combined should not contain any duplicate
+ * or redundant axes. Valid combinations include:
+ * <p>
+ * <UL>
+ *   <LI>Geographic 2D + Vertical</LI>
+ *   <LI>Geographic 2D + Engineering 1D (near vertical)</LI>
+ *   <LI>Projected + Vertical</LI>
+ *   <LI>Projected + Engineering 1D (near vertical)</LI>
+ *   <LI>Engineering (horizontal 2D or 1D linear) + Vertical</LI>
+ * </UL>
+ * <p>
+ * Any coordinate reference system, or any of the above listed combinations of coordinate
+ * reference systems, can have a Temporal CRS added. More than one Temporal CRS may be added
+ * if these axes represent different time quantities. For example, the oil industry sometimes
+ * uses "4D seismic", by which is meant seismic data with the vertical axis expressed in
+ * milliseconds (signal travel time). A second time axis indicates how it changes with time
+ * (years), e.g. as a reservoir is gradually exhausted of its recoverable oil or gas).
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/CompoundCRS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="SC_CompoundCRS", specification=ISO_19111)
+public interface CompoundCRS extends CoordinateReferenceSystem {
+    /**
+     * The ordered list of coordinate reference systems.
+     *
+     * @return The ordered list of coordinate reference systems.
+     */
+    @UML(identifier="includesCRS", obligation=MANDATORY, specification=ISO_19111)
+    List<CoordinateReferenceSystem> getCoordinateReferenceSystems();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/CoordinateReferenceSystem.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/CoordinateReferenceSystem.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/CoordinateReferenceSystem.java	(revision 28000)
@@ -0,0 +1,77 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import org.opengis.referencing.ReferenceSystem;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.annotation.UML;
+import org.opengis.annotation.Extension;
+
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Abstract coordinate reference system, usually defined by a
+ * {@linkplain org.opengis.referencing.cs.CoordinateSystem coordinate system} and a
+ * {@linkplain org.opengis.referencing.datum.Datum datum}. The concept of a coordinate
+ * reference system (CRS) captures the choice of values for the parameters that constitute
+ * the degrees of freedom of the coordinate space. The fact that such a choice has to be made,
+ * either arbitrarily or by adopting values from survey measurements, leads to the large number
+ * of coordinate reference systems in use around the world. It is also the cause of the little
+ * understood fact that the latitude and longitude of a point are not unique. Without the full
+ * specification of the coordinate reference system, coordinates are ambiguous at best and
+ * meaningless at worst. However for some interchange purposes it is sufficient to confirm the
+ * {@linkplain #getName identity of the system} without necessarily having the full system
+ * definition.
+ * <p>
+ * The concept of coordinates may be expanded from a strictly spatial context to include time.
+ * Time is then added as another coordinate to the coordinate tuple. It is even possible to add
+ * two time-coordinates, provided the two coordinates describe different independent quantities.
+ * An example of the latter is the time/space position of a subsurface point of which the vertical
+ * coordinate is expressed as the two-way travel time of a sound signal in milliseconds, as is
+ * common in seismic imaging. A second time-coordinate indicates the time of observation, usually
+ * expressed in whole years.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/CoordinateReferenceSystem.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="SC_CRS", specification=ISO_19111)
+public interface CoordinateReferenceSystem extends ReferenceSystem {
+    /**
+     * Returns a relevant coordinate system instance. Special cases:
+     *
+     * <ul>
+     *   <li><p>If the CRS instance on which this method is invoked is an instance of the
+     *       {@linkplain SingleCRS single CRS} interface, then the CS instance which is
+     *       returned shall be one of the defined sub-interfaces of {@linkplain CoordinateSystem
+     *       coordinate system}.</p></li>
+     *
+     *   <li><p>If the CRS instance on which this method is invoked is an instance of the
+     *       {@linkplain CompoundCRS compound CRS} interface, then the CS instance which is
+     *       returned shall have dimension and axis components obtained from different
+     *       {@linkplain CompoundCRS#getCoordinateReferenceSystems components} of the instance
+     *       CRS.</p></li>
+     * </ul>
+     *
+     * @departure
+     *   Strictly speaking, this method is defined by ISO 19111 for {@linkplain SingleCRS single CRS}
+     *   only. GeoAPI declares this method in this parent interface for user convenience, since CS
+     *   {@linkplain CoordinateSystem#getDimension dimension} and {@linkplain CoordinateSystem#getAxis axis}
+     *   are commonly requested information and shall be available, directly or indirectly, in all cases
+     *   (including {@linkplain CompoundCRS compound CRS}).
+     *
+     * @return The coordinate system.
+     */
+    @Extension
+    CoordinateSystem getCoordinateSystem();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/DerivedCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/DerivedCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/DerivedCRS.java	(revision 28000)
@@ -0,0 +1,35 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A coordinate reference system that is defined by its coordinate conversion from another
+ * coordinate reference system but is not a projected coordinate reference system. This
+ * category includes coordinate reference systems derived from a {@linkplain ProjectedCRS
+ * projected coordinate reference system}.
+ *
+ * @departure
+ *   ISO 19111 defines a {@code DerivedCRSType} code list. The later is omitted in GeoAPI since
+ *   Java expressions like {@code (baseCRS instanceof FooCRS)} provides the same capability
+ *   with more flexibility.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/DerivedCRS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="SC_DerivedCRS", specification=ISO_19111)
+public interface DerivedCRS extends GeneralDerivedCRS {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/EngineeringCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/EngineeringCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/EngineeringCRS.java	(revision 28000)
@@ -0,0 +1,73 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import org.opengis.referencing.datum.EngineeringDatum;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A contextually local coordinate reference system. It can be divided into two broad categories:
+ * <p>
+ * <ul>
+ *   <li>earth-fixed systems applied to engineering activities on or near the surface of the
+ *       earth;</li>
+ *   <li>CRSs on moving platforms such as road vehicles, vessels, aircraft, or spacecraft.</li>
+ * </ul>
+ * <p>
+ * Earth-fixed Engineering CRSs are commonly based on a simple flat-earth approximation of the
+ * earth's surface, and the effect of earth curvature on feature geometry is ignored: calculations
+ * on coordinates use simple plane arithmetic without any corrections for earth curvature. The
+ * application of such Engineering CRSs to relatively small areas and "contextually local" is in
+ * this case equivalent to "spatially local".
+ * <p>
+ * Engineering CRSs used on moving platforms are usually intermediate coordinate reference
+ * systems that are computationally required to calculate coordinates referenced to
+ * {@linkplain GeocentricCRS geocentric}, {@linkplain GeographicCRS geographic} or
+ * {@linkplain ProjectedCRS projected} CRSs. These engineering coordinate reference
+ * systems are subject to all the motions of the platform with which they are associated.
+ * In this case "contextually local" means that the associated coordinates are meaningful
+ * only relative to the moving platform. Earth curvature is usually irrelevant and is therefore
+ * ignored. In the spatial sense their applicability may extend from the immediate vicinity of
+ * the platform (e.g. a moving seismic ship) to the entire earth (e.g. in space applications).
+ * The determining factor is the mathematical model deployed in the positioning calculations.
+ * Transformation of coordinates from these moving Engineering CRSs to earth-referenced coordinate
+ * reference systems involves time-dependent coordinate operation parameters.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.cs.AffineCS           Affine},
+ *   {@link org.opengis.referencing.cs.CartesianCS        Cartesian},
+ *   {@link org.opengis.referencing.cs.EllipsoidalCS      Ellipsoidal},
+ *   {@link org.opengis.referencing.cs.SphericalCS        Spherical},
+ *   {@link org.opengis.referencing.cs.CylindricalCS      Cylindrical},
+ *   {@link org.opengis.referencing.cs.PolarCS            Polar},
+ *   {@link org.opengis.referencing.cs.VerticalCS         Vertical},
+ *   {@link org.opengis.referencing.cs.LinearCS           Linear}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/EngineeringCRS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="SC_EngineeringCRS", specification=ISO_19111)
+public interface EngineeringCRS extends SingleCRS {
+    /**
+     * Returns the datum, which must be an engineering one.
+     */
+    @UML(identifier="usesDatum", obligation=MANDATORY, specification=ISO_19111)
+    EngineeringDatum getDatum();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/GeneralDerivedCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/GeneralDerivedCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/GeneralDerivedCRS.java	(revision 28000)
@@ -0,0 +1,53 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A coordinate reference system that is defined by its coordinate
+ * {@linkplain Conversion conversion} from another coordinate reference system
+ * (not by a {@linkplain org.opengis.referencing.datum.Datum datum}).
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/GeneralDerivedCRS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="SC_GeneralDerivedCRS", specification=ISO_19111)
+public interface GeneralDerivedCRS extends SingleCRS {
+    /**
+     * Returns the base coordinate reference system.
+     *
+     * @return The base coordinate reference system.
+     */
+    @UML(identifier="baseCRS", obligation=MANDATORY, specification=ISO_19111)
+    CoordinateReferenceSystem getBaseCRS();
+
+    /**
+     * Returns the conversion from the {@linkplain #getBaseCRS base CRS} to this CRS.
+     *
+     * @return The conversion from the base CRS.
+     *
+     * @rename {@code definedByConversion} may be a precise description of the association,
+     *         but may be confusing as a method name since it doesn't said which CRS is the
+     *         source or which one is the target. OGC document 01-009 used {@code toBase()}
+     *         method name. By analogy with 01-009, this new interface specifies a method
+     *         name which contains the {@code FromBase} words.
+     */
+    @UML(identifier="definedByConversion", obligation=MANDATORY, specification=ISO_19111)
+    Conversion getConversionFromBase();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/GeocentricCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/GeocentricCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/GeocentricCRS.java	(revision 28000)
@@ -0,0 +1,47 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.cs.SphericalCS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A 3D coordinate reference system with the origin at the approximate centre of mass of the earth.
+ * A geocentric CRS deals with the earth's curvature by taking a 3D spatial view, which obviates
+ * the need to model the earth's curvature.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.cs.CartesianCS Cartesian},
+ *   {@link org.opengis.referencing.cs.SphericalCS Spherical}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/GeocentricCRS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="SC_GeocentricCRS", specification=ISO_19111)
+public interface GeocentricCRS extends GeodeticCRS {
+    /**
+     * Returns the coordinate system, which must be {@linkplain CartesianCS cartesian}
+     * or {@linkplain SphericalCS spherical}.
+     */
+    @UML(identifier="usesCartesianCS, usesSphericalCS", obligation=MANDATORY, specification=ISO_19111)
+    CoordinateSystem getCoordinateSystem();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/GeodeticCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/GeodeticCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/GeodeticCRS.java	(revision 28000)
@@ -0,0 +1,43 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import org.opengis.referencing.datum.GeodeticDatum;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A coordinate reference system associated with a geodetic datum.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.cs.CartesianCS   Cartesian}
+ *   {@link org.opengis.referencing.cs.SphericalCS   Spherical}
+ *   {@link org.opengis.referencing.cs.EllipsoidalCS Ellipsoidal}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/GeodeticCRS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.1
+ */
+@UML(identifier="SC_GeodeticCRS", specification=ISO_19111)
+public interface GeodeticCRS extends SingleCRS {
+    /**
+     * Returns the datum, which must be geodetic.
+     */
+    @UML(identifier="usesDatum", obligation=MANDATORY, specification=ISO_19111)
+    GeodeticDatum getDatum();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/GeographicCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/GeographicCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/GeographicCRS.java	(revision 28000)
@@ -0,0 +1,48 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import org.opengis.referencing.cs.EllipsoidalCS;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A coordinate reference system based on an ellipsoidal approximation of the geoid; this provides
+ * an accurate representation of the geometry of geographic features for a large portion of the
+ * earth's surface.
+ * <P>
+ * A Geographic CRS is not suitable for mapmaking on a planar surface, because it describes geometry
+ * on a curved surface. It is impossible to represent such geometry in a Euclidean plane without
+ * introducing distortions. The need to control these distortions has given rise to the development
+ * of the science of {@linkplain org.opengis.referencing.operation.Projection map projections}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.cs.EllipsoidalCS Ellipsoidal}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/GeographicCRS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="SC_GeographicCRS", specification=ISO_19111)
+public interface GeographicCRS extends GeodeticCRS {
+    /**
+     * Returns the coordinate system, which must be ellipsoidal.
+     */
+    @UML(identifier="usesCS", obligation=MANDATORY, specification=ISO_19111)
+    EllipsoidalCS getCoordinateSystem();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/ImageCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/ImageCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/ImageCRS.java	(revision 28000)
@@ -0,0 +1,51 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import org.opengis.referencing.cs.AffineCS;
+import org.opengis.referencing.datum.ImageDatum;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * An engineering coordinate reference system applied to locations in images. Image coordinate
+ * reference systems are treated as a separate sub-type because a separate user community exists
+ * for images with its own terms of reference.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.cs.CartesianCS Cartesian},
+ *   {@link org.opengis.referencing.cs.AffineCS    Affine}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/ImageCRS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="SC_ImageCRS", specification=ISO_19111)
+public interface ImageCRS extends SingleCRS {
+    /**
+     * Returns the cartesian coordinate system.
+     */
+    @UML(identifier="usesObliqueCartesianCS, usesCartesianCS", obligation=MANDATORY, specification=ISO_19111)
+    AffineCS getCoordinateSystem();
+
+    /**
+     * Returns the datum, which must be an image one.
+     */
+    @UML(identifier="usesDatum", obligation=MANDATORY, specification=ISO_19111)
+    ImageDatum getDatum();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/ProjectedCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/ProjectedCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/ProjectedCRS.java	(revision 28000)
@@ -0,0 +1,61 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.datum.GeodeticDatum;
+import org.opengis.referencing.operation.Projection;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A 2D coordinate reference system used to approximate the shape of the earth on a planar surface.
+ * It is done in such a way that the distortion that is inherent to the approximation is carefully
+ * controlled and known. Distortion correction is commonly applied to calculated bearings and
+ * distances to produce values that are a close match to actual field values.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.cs.CartesianCS Cartesian}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/ProjectedCRS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="SC_ProjectedCRS", specification=ISO_19111)
+public interface ProjectedCRS extends GeneralDerivedCRS {
+    /**
+     * Returns the base coordinate reference system, which must be geographic.
+     */
+    GeographicCRS getBaseCRS();
+
+    /**
+     * Returns the map projection from the {@linkplain #getBaseCRS base CRS} to this CRS.
+     */
+    Projection getConversionFromBase();
+
+    /**
+     * Returns the coordinate system, which must be cartesian.
+     */
+    @UML(identifier="usesCS", obligation=MANDATORY, specification=ISO_19111)
+    CartesianCS getCoordinateSystem();
+
+    /**
+     * Returns the datum.
+     */
+    GeodeticDatum getDatum();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/SingleCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/SingleCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/SingleCRS.java	(revision 28000)
@@ -0,0 +1,63 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import org.opengis.referencing.datum.Datum;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Abstract coordinate reference system, consisting of a single
+ * {@linkplain CoordinateSystem Coordinate System} and a single
+ * {@linkplain Datum Datum} (as opposed to {@linkplain CompoundCRS Compound CRS}).
+ * <p>
+ * A coordinate reference system consists of an ordered sequence of coordinate system
+ * axes that are related to the earth through a datum. A coordinate reference system
+ * is defined by one datum and by one coordinate system. Most coordinate reference system
+ * do not move relative to the earth, except for engineering coordinate reference systems
+ * defined on moving platforms such as cars, ships, aircraft, and spacecraft.
+ * <p>
+ * Coordinate reference systems are commonly divided into sub-types. The common classification
+ * criterion for sub-typing of coordinate reference systems is the way in which they deal with
+ * earth curvature. This has a direct effect on the portion of the earth's surface that can be
+ * covered by that type of CRS with an acceptable degree of error. The exception to the rule is
+ * the subtype "Temporal" which has been added by analogy.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/SingleCRS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ *
+ * @see org.opengis.referencing.cs.CoordinateSystem
+ * @see org.opengis.referencing.datum.Datum
+ */
+@UML(identifier="SC_SingleCRS", specification=ISO_19111)
+public interface SingleCRS extends CoordinateReferenceSystem {
+    /**
+     * Returns the coordinate system.
+     *
+     * @rename Expanded the "CS" abbreviation into "CoordinateSystem".
+     */
+    @UML(identifier="usesCS", obligation=MANDATORY, specification=ISO_19111)
+    CoordinateSystem getCoordinateSystem();
+
+    /**
+     * Returns the datum.
+     *
+     * @return The datum.
+     */
+    @UML(identifier="usesDatum", obligation=MANDATORY, specification=ISO_19111)
+    Datum getDatum();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/TemporalCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/TemporalCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/TemporalCRS.java	(revision 28000)
@@ -0,0 +1,48 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import org.opengis.referencing.cs.TimeCS;
+import org.opengis.referencing.datum.TemporalDatum;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A 1D coordinate reference system used for the recording of time.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.cs.TimeCS Time}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/TemporalCRS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="SC_TemporalCRS", specification=ISO_19111)
+public interface TemporalCRS extends SingleCRS {
+    /**
+     * Returns the coordinate system, which must be temporal.
+     */
+    @UML(identifier="usesCS", obligation=MANDATORY, specification=ISO_19111)
+    TimeCS getCoordinateSystem();
+
+    /**
+     * Returns the datum, which must be temporal.
+     */
+    @UML(identifier="usesDatum", obligation=MANDATORY, specification=ISO_19111)
+    TemporalDatum getDatum();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/VerticalCRS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/VerticalCRS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/crs/VerticalCRS.java	(revision 28000)
@@ -0,0 +1,68 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.crs;
+
+import org.opengis.referencing.cs.VerticalCS;
+import org.opengis.referencing.datum.VerticalDatum;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A 1D coordinate reference system used for recording heights or depths. Vertical CRSs make use
+ * of the direction of gravity to define the concept of height or depth, but the relationship with
+ * gravity may not be straightforward.
+ * <p>
+ * By implication, ellipsoidal heights (<var>h</var>) cannot be captured in a vertical coordinate
+ * reference system. Ellipsoidal heights cannot exist independently, but only as inseparable part
+ * of a 3D coordinate tuple defined in a geographic 3D coordinate reference system. However GeoAPI
+ * does not enforce this rule. Some applications may relax this rule and accept ellipsoidal heights
+ * in the following context:
+ *
+ * <ul>
+ *   <li><p>As a transient state while parsing <A HREF="../doc-files/WKT.html">Well Known Text</A>,
+ *       or any other format based on legacy specifications where ellipsoidal heights were allowed
+ *       as an independant axis.</p></li>
+ *
+ *   <li><p>As short-lived objects to be passed or returned by methods enforcing type safety, for
+ *       example {@link org.opengis.metadata.extent.VerticalExtent#getVerticalCRS}.</p></li>
+ *
+ *   <li><p>Other cases at implementor convenience. However implementors are encouraged to
+ *       assemble the full 3D CRS as soon as they can.</p></li>
+ * </ul>
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.cs.VerticalCS Vertical}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/crs/VerticalCRS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="SC_VerticalCRS", specification=ISO_19111)
+public interface VerticalCRS extends SingleCRS {
+    /**
+     * Returns the coordinate system, which must be vertical.
+     */
+    @UML(identifier="usesCS", obligation=MANDATORY, specification=ISO_19111)
+    VerticalCS getCoordinateSystem();
+
+    /**
+     * Returns the datum, which must be vertical.
+     */
+    @UML(identifier="usesDatum", obligation=MANDATORY, specification=ISO_19111)
+    VerticalDatum getDatum();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/AffineCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/AffineCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/AffineCS.java	(revision 28000)
@@ -0,0 +1,37 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A two- or three-dimensional coordinate system with straight axes that are not necessarily orthogonal.
+ * An {@code AffineCS} shall have two or three {@linkplain #getAxis axis associations}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.crs.EngineeringCRS Engineering},
+ *   {@link org.opengis.referencing.crs.ImageCRS       Image}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/AffineCS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ *
+ * @see CartesianCS
+ */
+@UML(identifier="CS_AffineCS", specification=ISO_19111)
+public interface AffineCS extends CoordinateSystem {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/AxisDirection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/AxisDirection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/AxisDirection.java	(revision 28000)
@@ -0,0 +1,414 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.opengis.util.CodeList;
+import org.opengis.annotation.UML;
+import org.opengis.annotation.Extension;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * The direction of positive increments in the coordinate value for a coordinate system
+ * axis. This direction is exact in some cases, and is approximate in other cases.
+ * <p>
+ * Some coordinate systems use non-standard orientations.  For example,
+ * the first axis in South African grids usually points West, instead of
+ * East. This information is obviously relevant for algorithms converting
+ * South African grid coordinates into Lat/Long.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/AxisDirection.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CS_AxisDirection", specification=ISO_19111)
+public final class AxisDirection extends CodeList<AxisDirection> {
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = -4405275475770755714L;
+
+    /**
+     * List of all enumerations of this type.
+     * Must be declared before any enum declaration.
+     */
+    private static final List<AxisDirection> VALUES = new ArrayList<AxisDirection>(32);
+
+    /**
+     * Unknown or unspecified axis orientation.
+     */
+    @UML(identifier="CS_AxisOrientationEnum.CS_AO_Other", specification=OGC_01009)
+    public static final AxisDirection OTHER = new AxisDirection("OTHER");
+    static {
+        OTHER.opposite = OTHER;
+    }
+
+    /**
+     * Axis positive direction is north. In a geographic or projected CRS,
+     * north is defined through the geodetic datum. In an engineering CRS,
+     * north may be defined with respect to an engineering object rather
+     * than a geographical direction.
+     */
+    @UML(identifier="north", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection NORTH = new AxisDirection("NORTH");
+
+    /**
+     * Axis positive direction is approximately north-north-east.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="northNorthEast", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection NORTH_NORTH_EAST = new AxisDirection("NORTH_NORTH_EAST");
+
+    /**
+     * Axis positive direction is approximately north-east.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="northEast", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection NORTH_EAST = new AxisDirection("NORTH_EAST");
+
+    /**
+     * Axis positive direction is approximately east-north-east.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="eastNorthEast", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection EAST_NORTH_EAST = new AxisDirection("EAST_NORTH_EAST");
+
+    /**
+     * Axis positive direction is &pi;/2 radians clockwise from north.
+     * This is usually used for Grid X coordinates and Longitude.
+     */
+    @UML(identifier="east", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection EAST = new AxisDirection("EAST");
+
+    /**
+     * Axis positive direction is approximately east-south-east.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="eastSouthEast", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection EAST_SOUTH_EAST = new AxisDirection("EAST_SOUTH_EAST");
+
+    /**
+     * Axis positive direction is approximately south-east.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="southEast", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection SOUTH_EAST = new AxisDirection("SOUTH_EAST");
+
+    /**
+     * Axis positive direction is approximately south-south-east.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="southSouthEast", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection SOUTH_SOUTH_EAST = new AxisDirection("SOUTH_SOUTH_EAST");
+
+    /**
+     * Axis positive direction is &pi; radians clockwise from north.
+     */
+    @UML(identifier="south", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection SOUTH = new AxisDirection("SOUTH", NORTH);
+
+    /**
+     * Axis positive direction is approximately south-south-west.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="southSouthWest", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection SOUTH_SOUTH_WEST = new AxisDirection("SOUTH_SOUTH_WEST", NORTH_NORTH_EAST);
+
+    /**
+     * Axis positive direction is approximately south-west.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="southWest", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection SOUTH_WEST = new AxisDirection("SOUTH_WEST", NORTH_EAST);
+
+    /**
+     * Axis positive direction is approximately west-south-west.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="westSouthWest", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection WEST_SOUTH_WEST = new AxisDirection("WEST_SOUTH_WEST", EAST_NORTH_EAST);
+
+    /**
+     * Axis positive direction is 3&pi;/2 radians clockwise from north.
+     * This is usually used for Grid X coordinates and Longitude.
+     */
+    @UML(identifier="west", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection WEST = new AxisDirection("WEST", EAST);
+
+    /**
+     * Axis positive direction is approximately west-north-west.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="westNorthWest", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection WEST_NORTH_WEST = new AxisDirection("WEST_NORTH_WEST", EAST_SOUTH_EAST);
+
+    /**
+     * Axis positive direction is approximately north-west.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="northWest", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection NORTH_WEST = new AxisDirection("NORTH_WEST", SOUTH_EAST);
+
+    /**
+     * Axis positive direction is approximately north-north-west.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="northNorthWest", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection NORTH_NORTH_WEST = new AxisDirection("NORTH_NORTH_WEST", SOUTH_SOUTH_EAST);
+
+    /**
+     * Axis positive direction is up relative to gravity.
+     * This is used for {@linkplain org.opengis.referencing.crs.VerticalCRS vertical}
+     * coordinate reference systems.
+     */
+    @UML(identifier="up", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection UP = new AxisDirection("UP");
+
+    /**
+     * Axis positive direction is down relative to gravity.
+     * This is used for {@linkplain org.opengis.referencing.crs.VerticalCRS vertical}
+     * coordinate reference systems.
+     */
+    @UML(identifier="down", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection DOWN = new AxisDirection("DOWN", UP);
+
+    /**
+     * Axis positive direction is in the equatorial plane from the centre of the
+     * modelled earth towards the intersection of the equator with the prime meridian.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="geocentricX", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection GEOCENTRIC_X = new AxisDirection("GEOCENTRIC_X");
+
+    /**
+     * Axis positive direction is in the equatorial plane from the centre of the
+     * modelled earth towards the intersection of the equator and the meridian &pi;/2
+     * radians eastwards from the prime meridian.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="geocentricY", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection GEOCENTRIC_Y = new AxisDirection("GEOCENTRIC_Y");
+
+    /**
+     * Axis positive direction is from the centre of the modelled earth parallel to
+     * its rotation axis and towards its north pole.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="geocentricZ", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection GEOCENTRIC_Z = new AxisDirection("GEOCENTRIC_Z");
+
+    /**
+     * Axis positive direction is towards the future.
+     * This is used for {@linkplain org.opengis.referencing.crs.TemporalCRS temporal}
+     * coordinate reference systems.
+     */
+    @UML(identifier="future", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection FUTURE = new AxisDirection("FUTURE");
+
+    /**
+     * Axis positive direction is towards the past.
+     * This is used for {@linkplain org.opengis.referencing.crs.TemporalCRS temporal}
+     * coordinate reference systems.
+     */
+    @UML(identifier="past", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection PAST = new AxisDirection("PAST", FUTURE);
+
+    /**
+     * Axis positive direction is towards higher pixel column.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="columnPositive", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection COLUMN_POSITIVE = new AxisDirection("COLUMN_POSITIVE");
+
+    /**
+     * Axis positive direction is towards lower pixel column.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="columnNegative", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection COLUMN_NEGATIVE = new AxisDirection("COLUMN_NEGATIVE", COLUMN_POSITIVE);
+
+    /**
+     * Axis positive direction is towards higher pixel row.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="rowPositive", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection ROW_POSITIVE = new AxisDirection("ROW_POSITIVE");
+
+    /**
+     * Axis positive direction is towards lower pixel row.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="rowNegative", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection ROW_NEGATIVE = new AxisDirection("ROW_NEGATIVE", ROW_POSITIVE);
+
+    /**
+     * Axis positive direction is right in display.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="displayRight", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection DISPLAY_RIGHT = new AxisDirection("DISPLAY_RIGHT");
+
+    /**
+     * Axis positive direction is left in display.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="displayLeft", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection DISPLAY_LEFT = new AxisDirection("DISPLAY_LEFT", DISPLAY_RIGHT);
+
+    /**
+     * Axis positive direction is towards top of approximately vertical display surface.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="displayUp", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection DISPLAY_UP = new AxisDirection("DISPLAY_UP");
+
+    /**
+     * Axis positive direction is towards bottom of approximately vertical display surface.
+     *
+     * @since GeoAPI 2.0
+     */
+    @UML(identifier="displayDown", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final AxisDirection DISPLAY_DOWN = new AxisDirection("DISPLAY_DOWN", DISPLAY_UP);
+
+    /**
+     * The opposite direction for this axis, or {@code null} if the opposite
+     * direction has not yet been specified.
+     */
+    private transient AxisDirection opposite;
+
+    /**
+     * Constructs an enum with the given name. The new enum is
+     * automatically added to the list returned by {@link #values}.
+     *
+     * @param name The enum name. This name must not be in use by an other enum of this type.
+     */
+    private AxisDirection(final String name) {
+        super(name, VALUES);
+    }
+
+    /**
+     * Constructs an axis direction which is the opposite of the specified direction.
+     */
+    private AxisDirection(final String name, final AxisDirection opposite) {
+        this(name);
+        if (opposite.opposite != null) {
+            throw new IllegalArgumentException(String.valueOf(opposite));
+        }
+        this.opposite = opposite;
+        opposite.opposite = this;
+    }
+
+    /**
+     * Returns the list of {@code AxisDirection}s.
+     *
+     * @return The list of codes declared in the current JVM.
+     */
+    public static AxisDirection[] values() {
+        synchronized (VALUES) {
+            return VALUES.toArray(new AxisDirection[VALUES.size()]);
+        }
+    }
+
+    /**
+     * Returns the list of enumerations of the same kind than this enum.
+     */
+    public AxisDirection[] family() {
+        return values();
+    }
+
+    /**
+     * Returns the "absolute" direction of this axis.
+     * This "absolute" operation is similar to the {@code Math.abs(int)}
+     * method in that "negative" directions like ({@link #SOUTH}, {@link #WEST},
+     * {@link #DOWN}, {@link #PAST}) are changed for their "positive" counterparts
+     * ({@link #NORTH}, {@link #EAST}, {@link #UP}, {@link #FUTURE}).
+     * More specifically, the following conversion table is applied:
+     * <br>&nbsp;
+     * <table cellpadding="9"><tr>
+     * <td width='50%'><table border="1" bgcolor="F4F8FF">
+     *   <tr bgcolor="#B9DCFF">
+     *     <th nowrap width='50%'>&nbsp;&nbsp;Direction&nbsp;&nbsp;</th>
+     *     <th nowrap width='50%'>&nbsp;&nbsp;Absolute value&nbsp;&nbsp;</th>
+     *   </tr>
+     *   <tr><td width='50%'>&nbsp;{@link #NORTH}</td> <td width='50%'>&nbsp;{@link #NORTH}</td> </tr>
+     *   <tr><td width='50%'>&nbsp;{@link #SOUTH}</td> <td width='50%'>&nbsp;{@link #NORTH}</td> </tr>
+     *   <tr><td width='50%'>&nbsp;{@link #EAST}</td>  <td width='50%'>&nbsp;{@link #EAST}</td>  </tr>
+     *   <tr><td width='50%'>&nbsp;{@link #WEST}</td>  <td width='50%'>&nbsp;{@link #EAST}</td>  </tr>
+     *   <tr><td width='50%'>&nbsp;{@link #UP}</td>    <td width='50%'>&nbsp;{@link #UP}</td>    </tr>
+     *   <tr><td width='50%'>&nbsp;{@link #DOWN}</td>  <td width='50%'>&nbsp;{@link #UP}</td>    </tr>
+     * </table></td>
+     * <td width='50%'><table border="1" bgcolor="F4F8FF">
+     *   <tr bgcolor="#B9DCFF">
+     *     <th nowrap width='50%'>&nbsp;&nbsp;Direction&nbsp;&nbsp;</th>
+     *     <th nowrap width='50%'>&nbsp;&nbsp;Absolute value&nbsp;&nbsp;</th>
+     *   </tr>
+     *   <tr><td width='50%'>&nbsp;{@link #DISPLAY_RIGHT}</td> <td width='50%'>&nbsp;{@link #DISPLAY_RIGHT}</td> </tr>
+     *   <tr><td width='50%'>&nbsp;{@link #DISPLAY_LEFT}</td>  <td width='50%'>&nbsp;{@link #DISPLAY_RIGHT}</td> </tr>
+     *   <tr><td width='50%'>&nbsp;{@link #DISPLAY_UP}</td>    <td width='50%'>&nbsp;{@link #DISPLAY_UP}</td>    </tr>
+     *   <tr><td width='50%'>&nbsp;{@link #DISPLAY_DOWN}</td>  <td width='50%'>&nbsp;{@link #DISPLAY_UP}</td>    </tr>
+     *   <tr><td width='50%'>&nbsp;{@link #FUTURE}</td>        <td width='50%'>&nbsp;{@link #FUTURE}</td>        </tr>
+     *   <tr><td width='50%'>&nbsp;{@link #PAST}</td>          <td width='50%'>&nbsp;{@link #FUTURE}</td>        </tr>
+     * </table></td></tr>
+     *   <tr align="center"><td width='50%'>{@link #OTHER}</td><td width='50%'>{@link #OTHER}</td></tr>
+     * </table>
+     *
+     * @return The direction from the above table.
+     */
+    @Extension
+    public AxisDirection absolute() {
+        final AxisDirection opposite = this.opposite;
+        if (opposite != null) {
+            if (opposite.ordinal() < ordinal()) {
+                return opposite;
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Returns the axis direction that matches the given string, or returns a
+     * new one if none match it.
+     *
+     * @param code The name of the code to fetch or to create.
+     * @return A code matching the given name.
+     */
+    public static AxisDirection valueOf(String code) {
+        return valueOf(AxisDirection.class, code);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CSAuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CSAuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CSAuthorityFactory.java	(revision 28000)
@@ -0,0 +1,155 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import javax.measure.unit.Unit;
+import org.opengis.referencing.AuthorityFactory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.annotation.UML;
+import org.opengis.annotation.Extension;
+
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Creates {@linkplain CoordinateSystem coordinate systems} using authority codes. External authorities
+ * are used to manage definitions of objects used in this interface. The definitions of these objects are
+ * referenced using code strings. A commonly used authority is <A HREF="http://www.epsg.org">EPSG</A>,
+ * which is also used in the <A HREF="http://www.remotesensing.org/geotiff/geotiff.html">GeoTIFF</A>
+ * standard.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/CSAuthorityFactory.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-009.pdf">Implementation specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.crs.CRSAuthorityFactory
+ * @see org.opengis.referencing.datum.DatumAuthorityFactory
+ */
+@Extension
+public interface CSAuthorityFactory extends AuthorityFactory {
+    /**
+     * Returns an arbitrary {@linkplain CoordinateSystem coordinate system} from a code.
+     * If the coordinate system type is know at compile time, it is recommended to invoke
+     * the most precise method instead of this one (for example
+     * <code>&nbsp;{@linkplain #createCartesianCS createCartesianCS}(code)&nbsp;</code>
+     * instead of <code>&nbsp;createCoordinateSystem(code)&nbsp;</code> if the caller
+     * know he is asking for a {@linkplain CartesianCS cartesian coordinate system}).
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    CoordinateSystem createCoordinateSystem(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates a cartesian coordinate system from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    CartesianCS createCartesianCS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates a polar coordinate system from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    PolarCS createPolarCS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates a cylindrical coordinate system from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    CylindricalCS createCylindricalCS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates a spherical coordinate system from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    SphericalCS createSphericalCS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates an ellipsoidal coordinate system from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    EllipsoidalCS createEllipsoidalCS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates a vertical coordinate system from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    VerticalCS createVerticalCS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates a temporal coordinate system from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The coordinate system for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    TimeCS createTimeCS(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Returns a {@linkplain CoordinateSystemAxis coordinate system axis} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The axis for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    CoordinateSystemAxis createCoordinateSystemAxis(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Returns an {@linkplain Unit unit} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The unit for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    @UML(identifier="CS_CoordinateSystemAuthorityFactory.createLinearUnit, createAngularUnit", specification=OGC_01009)
+    Unit<?> createUnit(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CSFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CSFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CSFactory.java	(revision 28000)
@@ -0,0 +1,126 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import java.util.Map;
+import javax.measure.unit.Unit;
+import org.opengis.referencing.ObjectFactory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.annotation.Extension;
+
+
+/**
+ * Builds up complex {@linkplain CoordinateSystem coordinate systems} from simpler
+ * objects or values. {@code CSFactory} allows applications to make {@linkplain
+ * CoordinateSystem coordinate systems} that cannot be created by a {@link CSAuthorityFactory}.
+ * This factory is very flexible, whereas the authority factory is easier to use.
+ *
+ * So {@link CSAuthorityFactory} can be used to make "standard" coordinate systems,
+ * and {@code CSFactory} can be used to make "special" coordinate systems.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/CSFactory.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-009.pdf">Implementation specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.crs.CRSFactory
+ * @see org.opengis.referencing.datum.DatumFactory
+ */
+@Extension
+public interface CSFactory extends ObjectFactory {
+    /**
+     * Creates a coordinate system axis from an abbreviation and a unit.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  abbreviation The coordinate axis abbreviation.
+     * @param  direction The axis direction.
+     * @param  unit The coordinate axis unit.
+     * @return The axis for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    CoordinateSystemAxis createCoordinateSystemAxis(Map<String,?> properties,
+                                                    String        abbreviation,
+                                                    AxisDirection direction,
+                                                    Unit<?>       unit) throws FactoryException;
+
+    /**
+     * Creates a two dimensional cartesian coordinate system from the given pair of axis.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  axis0 The first  axis.
+     * @param  axis1 The second axis.
+     * @return The coordinate system for the given properties and axes.
+     * @throws FactoryException if the object creation failed.
+     */
+    CartesianCS createCartesianCS(Map<String, ?>  properties,
+                                  CoordinateSystemAxis axis0,
+                                  CoordinateSystemAxis axis1) throws FactoryException;
+
+    /**
+     * Creates a three dimensional cartesian coordinate system from the given set of axis.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  axis0 The first  axis.
+     * @param  axis1 The second axis.
+     * @param  axis2 The third  axis.
+     * @return The coordinate system for the given properties and axes.
+     * @throws FactoryException if the object creation failed.
+     */
+    CartesianCS createCartesianCS(Map<String, ?>  properties,
+                                  CoordinateSystemAxis axis0,
+                                  CoordinateSystemAxis axis1,
+                                  CoordinateSystemAxis axis2) throws FactoryException;
+
+    /**
+     * Creates an ellipsoidal coordinate system without ellipsoidal height.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  axis0 The first  axis.
+     * @param  axis1 The second axis.
+     * @return The coordinate system for the given properties and axes.
+     * @throws FactoryException if the object creation failed.
+     */
+    EllipsoidalCS createEllipsoidalCS(Map<String, ?>  properties,
+                                      CoordinateSystemAxis axis0,
+                                      CoordinateSystemAxis axis1) throws FactoryException;
+
+    /**
+     * Creates an ellipsoidal coordinate system with ellipsoidal height.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  axis0 The first  axis.
+     * @param  axis1 The second axis.
+     * @param  axis2 The third  axis.
+     * @return The coordinate system for the given properties and axes.
+     * @throws FactoryException if the object creation failed.
+     */
+    EllipsoidalCS createEllipsoidalCS(Map<String, ?>  properties,
+                                      CoordinateSystemAxis axis0,
+                                      CoordinateSystemAxis axis1,
+                                      CoordinateSystemAxis axis2) throws FactoryException;
+
+    /**
+     * Creates a vertical coordinate system.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  axis The axis.
+     * @return The coordinate system for the given properties and axes.
+     * @throws FactoryException if the object creation failed.
+     */
+    VerticalCS createVerticalCS(Map<String, ?> properties,
+                                CoordinateSystemAxis axis) throws FactoryException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CartesianCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CartesianCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CartesianCS.java	(revision 28000)
@@ -0,0 +1,42 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A 1-, 2-, or 3-dimensional coordinate system. Gives the position of points relative to
+ * orthogonal straight axes in the 2- and 3-dimensional cases. In the 1-dimensional case,
+ * it contains a single straight coordinate axis. In the multi-dimensional case, all axes
+ * shall have the same length unit of measure. A {@code CartesianCS} shall have one,
+ * two, or three {@linkplain #getAxis axis associations}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.crs.GeocentricCRS  Geocentric},
+ *   {@link org.opengis.referencing.crs.ProjectedCRS   Projected},
+ *   {@link org.opengis.referencing.crs.EngineeringCRS Engineering},
+ *   {@link org.opengis.referencing.crs.ImageCRS       Image}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/CartesianCS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see AffineCS
+ */
+@UML(identifier="CS_CartesianCS", specification=ISO_19111)
+public interface CartesianCS extends AffineCS {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CoordinateSystem.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CoordinateSystem.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CoordinateSystem.java	(revision 28000)
@@ -0,0 +1,56 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * The set of coordinate system axes that spans a given coordinate space. A coordinate system (CS)
+ * is derived from a set of (mathematical) rules for specifying how coordinates in a given space
+ * are to be assigned to points. The coordinate values in a coordinate tuple shall be recorded in
+ * the order in which the coordinate system axes associations are recorded, whenever those
+ * coordinates use a coordinate reference system that uses this coordinate system.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/CoordinateSystem.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.cs.CoordinateSystemAxis
+ * @see javax.measure.unit.Unit
+ * @see org.opengis.referencing.datum.Datum
+ * @see org.opengis.referencing.crs.CoordinateReferenceSystem
+ */
+@UML(identifier="CS_CoordinateSystem", specification=ISO_19111)
+public interface CoordinateSystem extends IdentifiedObject {
+    /**
+     * Returns the dimension of the coordinate system.
+     *
+     * @return The dimension of the coordinate system.
+     */
+    int getDimension();
+
+    /**
+     * Returns the axis for this coordinate system at the specified dimension.
+     * Each coordinate system must have at least one axis.
+     *
+     * @param  dimension The zero based index of axis.
+     * @return The axis at the specified dimension.
+     * @throws IndexOutOfBoundsException if {@code dimension} is out of bounds.
+     */
+    @UML(identifier="usesAxis", obligation=MANDATORY, specification=ISO_19111)
+    CoordinateSystemAxis getAxis(int dimension) throws IndexOutOfBoundsException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CoordinateSystemAxis.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CoordinateSystemAxis.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CoordinateSystemAxis.java	(revision 28000)
@@ -0,0 +1,108 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import javax.measure.unit.Unit;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Definition of a coordinate system axis.
+ * See <A HREF="package-summary.html#AxisNames">axis name constraints</A>.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/CoordinateSystemAxis.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see CoordinateSystem
+ * @see Unit
+ */
+@UML(identifier="CS_CoordinateSystemAxis", specification=ISO_19111)
+public interface CoordinateSystemAxis extends IdentifiedObject {
+    /**
+     * The abbreviation used for this coordinate system axes. This abbreviation is also
+     * used to identify the ordinates in coordinate tuple. Examples are "<var>X</var>"
+     * and "<var>Y</var>".
+     *
+     * @return The coordinate system axis abbreviation.
+     */
+    @UML(identifier="axisAbbrev", obligation=MANDATORY, specification=ISO_19111)
+    String getAbbreviation();
+
+    /**
+     * Direction of this coordinate system axis. In the case of Cartesian projected
+     * coordinates, this is the direction of this coordinate system axis locally.
+     * Examples:
+     * {@linkplain AxisDirection#NORTH north} or {@linkplain AxisDirection#SOUTH south},
+     * {@linkplain AxisDirection#EAST  east}  or {@linkplain AxisDirection#WEST  west},
+     * {@linkplain AxisDirection#UP    up}    or {@linkplain AxisDirection#DOWN  down}.
+     * Within any set of coordinate system axes, only one of each pair of terms
+     * can be used. For earth-fixed coordinate reference systems, this direction is often
+     * approximate and intended to provide a human interpretable meaning to the axis. When a
+     * geodetic datum is used, the precise directions of the axes may therefore vary slightly
+     * from this approximate direction.
+     *
+     * Note that an {@link org.opengis.referencing.crs.EngineeringCRS} often requires
+     * specific descriptions of the directions of its coordinate system axes.
+     *
+     * @return The coordinate system axis direction.
+     */
+    @UML(identifier="axisDirection", obligation=MANDATORY, specification=ISO_19111)
+    AxisDirection getDirection();
+
+    /**
+     * Returns the minimum value normally allowed for this axis, in the
+     * {@linkplain #getUnit unit of measure for the axis}. If there is no minimum value, then
+     * this method returns {@linkplain Double#NEGATIVE_INFINITY negative infinity}.
+     *
+     * @return The minimum value, or {@link Double#NEGATIVE_INFINITY} if none.
+     */
+    @UML(identifier="minimumValue", obligation=OPTIONAL, specification=ISO_19111)
+    double getMinimumValue();
+
+    /**
+     * Returns the maximum value normally allowed for this axis, in the
+     * {@linkplain #getUnit unit of measure for the axis}. If there is no maximum value, then
+     * this method returns {@linkplain Double#POSITIVE_INFINITY positive infinity}.
+     *
+     * @return The maximum value, or {@link Double#POSITIVE_INFINITY} if none.
+     */
+    @UML(identifier="maximumValue", obligation=OPTIONAL, specification=ISO_19111)
+    double getMaximumValue();
+
+    /**
+     * Returns the meaning of axis value range specified by the {@linkplain #getMinimumValue
+     * minimum} and {@linkplain #getMaximumValue maximum} values. This element shall be omitted
+     * when both minimum and maximum values are omitted. It may be included when minimum and/or
+     * maximum values are included. If this element is omitted when minimum or maximum values are
+     * included, the meaning is unspecified.
+     *
+     * @return The range meaning, or {@code null} in none.
+     */
+    @UML(identifier="rangeMeaning", obligation=CONDITIONAL, specification=ISO_19111)
+    RangeMeaning getRangeMeaning();
+
+    /**
+     * The unit of measure used for this coordinate system axis. The value of this
+     * coordinate in a coordinate tuple shall be recorded using this unit of measure,
+     * whenever those coordinates use a coordinate reference system that uses a
+     * coordinate system that uses this axis.
+     *
+     * @return  The coordinate system axis unit.
+     */
+    @UML(identifier="axisUnitID", obligation=MANDATORY, specification=ISO_19111)
+    Unit<?> getUnit();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CylindricalCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CylindricalCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/CylindricalCS.java	(revision 28000)
@@ -0,0 +1,38 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A three-dimensional coordinate system consisting of a {@linkplain PolarCS polar coordinate
+ * system} extended by a straight coordinate axis perpendicular to the plane spanned by the
+ * polar coordinate system. A {@code CylindricalCS} shall have three
+ * {@linkplain #getAxis axis associations}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.crs.EngineeringCRS Engineering}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/CylindricalCS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see PolarCS
+ */
+@UML(identifier="CS_CylindricalCS", specification=ISO_19111)
+public interface CylindricalCS extends CoordinateSystem {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/EllipsoidalCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/EllipsoidalCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/EllipsoidalCS.java	(revision 28000)
@@ -0,0 +1,36 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A two- or three-dimensional coordinate system in which position is specified by geodetic
+ * latitude, geodetic longitude, and (in the three-dimensional case) ellipsoidal height. An
+ * {@code EllipsoidalCS} shall have two or three {@linkplain #getAxis axis associations}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.crs.GeographicCRS  Geographic},
+ *   {@link org.opengis.referencing.crs.EngineeringCRS Engineering}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/EllipsoidalCS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CS_EllipsoidalCS", specification=ISO_19111)
+public interface EllipsoidalCS extends CoordinateSystem {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/LinearCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/LinearCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/LinearCS.java	(revision 28000)
@@ -0,0 +1,37 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A one-dimensional coordinate system that consists of the points that lie on the single axis
+ * described. The associated ordinate is the distance from the specified origin to the point
+ * along the axis. Example: usage of the line feature representing a road to describe points
+ * on or along that road. A {@code LinearCS} shall have one
+ * {@linkplain #getAxis axis association}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.crs.EngineeringCRS Engineering}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/LinearCS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CS_LinearCS", specification=ISO_19111)
+public interface LinearCS extends CoordinateSystem {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/PolarCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/PolarCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/PolarCS.java	(revision 28000)
@@ -0,0 +1,37 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A two-dimensional coordinate system in which position is specified by the distance from the
+ * origin and the angle between the line from the origin to a point and a reference direction.
+ * A {@code PolarCS} shall have two {@linkplain #getAxis axis associations}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.crs.EngineeringCRS Engineering}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/PolarCS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see CylindricalCS
+ */
+@UML(identifier="CS_PolarCS", specification=ISO_19111)
+public interface PolarCS extends CoordinateSystem {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/RangeMeaning.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/RangeMeaning.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/RangeMeaning.java	(revision 28000)
@@ -0,0 +1,103 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.opengis.util.CodeList;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Meaning of the axis value range specified through
+ * {@linkplain CoordinateSystemAxis#getMinimumValue minimum value} and
+ * {@linkplain CoordinateSystemAxis#getMaximumValue maximum value}.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/RangeMeaning.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.1
+ *
+ * @see CoordinateSystemAxis#getRangeMeaning
+ */
+@UML(identifier="CS_RangeMeaning", specification=ISO_19111)
+public final class RangeMeaning extends CodeList<RangeMeaning> {
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = -3525560558294789416L;
+
+    /**
+     * List of all enumerations of this type.
+     * Must be declared before any enum declaration.
+     */
+    private static final List<RangeMeaning> VALUES = new ArrayList<RangeMeaning>(2);
+
+    /**
+     * Any value between and including {@linkplain CoordinateSystemAxis#getMinimumValue minimum value}
+     * and {@linkplain CoordinateSystemAxis#getMaximumValue maximum value} is valid.
+     */
+    @UML(identifier="exact", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final RangeMeaning EXACT = new RangeMeaning("EXACT");
+
+    /**
+     * The axis is continuous with values wrapping around at the
+     * {@linkplain CoordinateSystemAxis#getMinimumValue minimum value} and
+     * {@linkplain CoordinateSystemAxis#getMaximumValue maximum value}.
+     * Values with the same meaning repeat modulo the difference between maximum value and
+     * minimum value.
+     */
+    @UML(identifier="wraparound", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final RangeMeaning WRAPAROUND = new RangeMeaning("WRAPAROUND");
+
+    /**
+     * Constructs an enum with the given name. The new enum is
+     * automatically added to the list returned by {@link #values}.
+     *
+     * @param name The enum name. This name must not be in use by an other enum of this type.
+     */
+    private RangeMeaning(final String name) {
+        super(name, VALUES);
+    }
+
+    /**
+     * Returns the list of {@code RangeMeaning}s.
+     *
+     * @return The list of codes declared in the current JVM.
+     */
+    public static RangeMeaning[] values() {
+        synchronized (VALUES) {
+            return VALUES.toArray(new RangeMeaning[VALUES.size()]);
+        }
+    }
+
+    /**
+     * Returns the list of enumerations of the same kind than this enum.
+     */
+    public RangeMeaning[] family() {
+        return values();
+    }
+
+    /**
+     * Returns the range meaning that matches the given string, or returns a
+     * new one if none match it.
+     *
+     * @param code The name of the code to fetch or to create.
+     * @return A code matching the given name.
+     */
+    public static RangeMeaning valueOf(String code) {
+        return valueOf(RangeMeaning.class, code);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/SphericalCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/SphericalCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/SphericalCS.java	(revision 28000)
@@ -0,0 +1,37 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A three-dimensional coordinate system with one distance measured from the origin and two
+ * angular coordinates. Not to be confused with an {@linkplain EllipsoidalCS ellipsoidal
+ * coordinate system} based on an ellipsoid "degenerated" into a sphere.
+ * A {@code SphericalCS} shall have three {@linkplain #getAxis axis associations}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.crs.GeocentricCRS  Geocentric},
+ *   {@link org.opengis.referencing.crs.EngineeringCRS Engineering}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/SphericalCS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CS_SphericalCS", specification=ISO_19111)
+public interface SphericalCS extends CoordinateSystem {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/TimeCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/TimeCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/TimeCS.java	(revision 28000)
@@ -0,0 +1,35 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A one-dimensional coordinate system containing a single time axis, used to describe the
+ * temporal position of a point in the specified time units from a specified time origin.
+ * A {@code TimeCS} shall have one {@linkplain #getAxis axis association}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.crs.TemporalCRS Temporal}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/TimeCS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 2.0
+ */
+@UML(identifier="CS_TimeCS", specification=ISO_19111)
+public interface TimeCS extends CoordinateSystem {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/UserDefinedCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/UserDefinedCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/UserDefinedCS.java	(revision 28000)
@@ -0,0 +1,33 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A two- or three-dimensional coordinate system that consists of any combination of coordinate
+ * axes not covered by any other Coordinate System type. An example is a multilinear coordinate
+ * system which contains one coordinate axis that may have any 1-D shape which has no intersections
+ * with itself. This non-straight axis is supplemented by one or two straight axes to complete a 2
+ * or 3 dimensional coordinate system. The non-straight axis is typically incrementally straight or
+ * curved. A {@code UserDefinedCS} shall have two or three
+ * {@linkplain #getAxis axis associations}.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/UserDefinedCS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CS_UserDefinedCS", specification=ISO_19111)
+public interface UserDefinedCS extends CoordinateSystem {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/VerticalCS.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/VerticalCS.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/cs/VerticalCS.java	(revision 28000)
@@ -0,0 +1,38 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.cs;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A one-dimensional coordinate system used to record the heights (or depths) of points. Such a
+ * coordinate system is usually dependent on the Earth's gravity field, perhaps loosely as when
+ * atmospheric pressure is the basis for the vertical coordinate system axis. An exact definition
+ * is deliberately not provided as the complexities of the subject fall outside the scope of this
+ * specification. A {@code VerticalCS} shall have one {@linkplain #getAxis axis association}.
+ *
+ * <TABLE CELLPADDING='6' BORDER='1'>
+ * <TR BGCOLOR="#EEEEFF"><TH NOWRAP>Used with CRS type(s)</TH></TR>
+ * <TR><TD>
+ *   {@link org.opengis.referencing.crs.VerticalCRS    Vertical},
+ *   {@link org.opengis.referencing.crs.EngineeringCRS Engineering}
+ * </TD></TR></TABLE>
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/cs/VerticalCS.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CS_VerticalCS", specification=ISO_19111)
+public interface VerticalCS extends CoordinateSystem {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/Datum.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/Datum.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/Datum.java	(revision 28000)
@@ -0,0 +1,95 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.datum;
+
+import static org.opengis.annotation.Obligation.OPTIONAL;
+import static org.opengis.annotation.Specification.ISO_19111;
+
+import org.opengis.annotation.UML;
+import org.opengis.metadata.extent.Extent;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.util.InternationalString;
+
+
+/**
+ * Specifies the relationship of a coordinate system to the earth, thus creating a {@linkplain
+ * org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference system}. A datum uses a
+ * parameter or set of parameters that determine the location of the origin of the coordinate
+ * reference system. Each datum subtype can be associated with only specific types of
+ * {@linkplain org.opengis.referencing.cs.CoordinateSystem coordinate systems}.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/datum/Datum.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.cs.CoordinateSystem
+ * @see org.opengis.referencing.crs.CoordinateReferenceSystem
+ */
+@UML(identifier="CD_Datum", specification=ISO_19111)
+public interface Datum extends IdentifiedObject {
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain DatumFactory datum factory} <code>createFoo(&hellip;)</code> methods.
+     * This is used for setting the value to be returned by {@link #getAnchorPoint}.
+     *
+     * @see #getAnchorPoint
+     */
+    String ANCHOR_POINT_KEY = "anchorPoint";
+
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain DatumFactory datum factory} <code>createFoo(&hellip;)</code> methods.
+     * This is used for setting the value to be returned by {@link #getRealizationEpoch}.
+     *
+     * @see #getRealizationEpoch
+     */
+    String REALIZATION_EPOCH_KEY = "realizationEpoch";
+
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain DatumFactory datum factory} <code>createFoo(&hellip;)</code> methods.
+     * This is used for setting the value to be returned by {@link #getDomainOfValidity}.
+     *
+     * @see #getDomainOfValidity
+     *
+     * @since GeoAPI 2.1
+     */
+    String DOMAIN_OF_VALIDITY_KEY = "domainOfValidity";
+
+    /**
+     * Key for the <code>{@value}</code> property to be given to the
+     * {@linkplain DatumFactory datum factory} <code>createFoo(&hellip;)</code> methods.
+     * This is used for setting the value to be returned by {@link #getScope}.
+     *
+     * @see #getScope
+     */
+    String SCOPE_KEY = "scope";
+
+    /**
+     * Area or region or timeframe in which this datum is valid.
+     *
+     * @return The datum valid domain, or {@code null} if not available.
+     *
+     * @since GeoAPI 2.1
+     */
+    @UML(identifier="domainOfValidity", obligation=OPTIONAL, specification=ISO_19111)
+    Extent getDomainOfValidity();
+
+    /**
+     * Description of domain of usage, or limitations of usage, for which this
+     * datum object is valid.
+     *
+     * @return A description of domain of usage, or {@code null} if none.
+     */
+    @UML(identifier="scope", obligation=OPTIONAL, specification=ISO_19111)
+    InternationalString getScope();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/DatumAuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/DatumAuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/DatumAuthorityFactory.java	(revision 28000)
@@ -0,0 +1,154 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.datum;
+
+import org.opengis.referencing.AuthorityFactory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Creates {@linkplain Datum datum} objects using authority codes. External authorities are used to
+ * manage definitions of objects used in this interface. The definitions of these objects are
+ * referenced using code strings. A commonly used authority is <A HREF="http://www.epsg.org">EPSG</A>,
+ * which is also used in the <A HREF="http://www.remotesensing.org/geotiff/geotiff.html">GeoTIFF</A>
+ * standard.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/datum/DatumAuthorityFactory.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-009.pdf">Implementation specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.cs.CSAuthorityFactory
+ * @see org.opengis.referencing.crs.CRSAuthorityFactory
+ */
+@UML(identifier="CS_CoordinateSystemAuthorityFactory", specification=OGC_01009)
+public interface DatumAuthorityFactory extends AuthorityFactory {
+    /**
+     * Returns an arbitrary {@linkplain Datum datum} from a code. If the datum type is know at
+     * compile time, it is recommended to invoke the most precise method instead of this one
+     * (for example <code>&nbsp;{@linkplain #createGeodeticDatum createGeodeticDatum}(code)&nbsp;</code>
+     * instead of <code>&nbsp;createDatum(code)&nbsp;</code> if the caller know he is asking for a
+     * {@linkplain GeodeticDatum geodetic datum}).
+     *
+     * @param  code Value allocated by authority.
+     * @return The datum for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createGeodeticDatum
+     * @see #createVerticalDatum
+     * @see #createTemporalDatum
+     */
+    Datum createDatum(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates a {@linkplain EngineeringDatum engineering datum} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The datum for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createEngineeringCRS
+     */
+    EngineeringDatum createEngineeringDatum(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates a {@linkplain ImageDatum image datum} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The datum for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createImageCRS
+     */
+    ImageDatum createImageDatum(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates a {@linkplain VerticalDatum vertical datum} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The datum for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createVerticalCRS
+     */
+    @UML(identifier="createVerticalDatum", specification=OGC_01009)
+    VerticalDatum createVerticalDatum(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates a {@linkplain TemporalDatum temporal datum} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The datum for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createTemporalCRS
+     */
+    TemporalDatum createTemporalDatum(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Returns a {@linkplain GeodeticDatum geodetic datum} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The datum for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createEllipsoid
+     * @see #createPrimeMeridian
+     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createGeographicCRS
+     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createProjectedCRS
+     */
+    @UML(identifier="createHorizontalDatum", specification=OGC_01009)
+    GeodeticDatum createGeodeticDatum(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Returns an {@linkplain Ellipsoid ellipsoid} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The ellipsoid for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createGeodeticDatum
+     */
+    @UML(identifier="createEllipsoid", specification=OGC_01009)
+    Ellipsoid createEllipsoid(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Returns a {@linkplain PrimeMeridian prime meridian} from a code.
+     *
+     * @param  code Value allocated by authority.
+     * @return The prime meridian for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     *
+     * @see #createGeodeticDatum
+     */
+    @UML(identifier="createPrimeMeridian", specification=OGC_01009)
+    PrimeMeridian createPrimeMeridian(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/DatumFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/DatumFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/DatumFactory.java	(revision 28000)
@@ -0,0 +1,156 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.datum;
+
+import java.util.Map;
+import java.util.Date;
+import javax.measure.unit.Unit;
+import javax.measure.quantity.Angle;
+import javax.measure.quantity.Length;
+import org.opengis.referencing.ObjectFactory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Builds up complex {@linkplain Datum datums} from simpler objects or values.
+ * {@code DatumFactory} allows applications to make {@linkplain Datum datums}
+ * that cannot be created by a {@link DatumAuthorityFactory}. This factory is very
+ * flexible, whereas the authority factory is easier to use.
+ * So {@link DatumAuthorityFactory} can be used to make "standard" datums, and
+ * {@code DatumFactory} can be used to make "special" datums.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/datum/DatumFactory.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-009.pdf">Implementation specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.cs.CSFactory
+ * @see org.opengis.referencing.crs.CRSFactory
+ */
+@UML(identifier="CS_CoordinateSystemFactory", specification=OGC_01009)
+public interface DatumFactory extends ObjectFactory {
+    /**
+     * Creates an engineering datum.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @return The datum for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createLocalDatum", specification=OGC_01009)
+    EngineeringDatum createEngineeringDatum(Map<String, ?> properties)
+            throws FactoryException;
+
+    /**
+     * Creates geodetic datum from ellipsoid and (optionaly) Bursa-Wolf parameters.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  ellipsoid Ellipsoid to use in new geodetic datum.
+     * @param  primeMeridian Prime meridian to use in new geodetic datum.
+     * @return The datum for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createHorizontalDatum", specification=OGC_01009)
+    GeodeticDatum createGeodeticDatum(Map<String, ?> properties,
+                                      Ellipsoid      ellipsoid,
+                                      PrimeMeridian  primeMeridian) throws FactoryException;
+
+    /**
+     * Creates an image datum.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  pixelInCell Specification of the way the image grid is associated
+     *         with the image data attributes.
+     * @return The datum for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    ImageDatum createImageDatum(Map<String, ?> properties,
+                                PixelInCell    pixelInCell) throws FactoryException;
+
+    /**
+     * Creates a temporal datum from an enumerated type value.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  origin The date and time origin of this temporal datum.
+     * @return The datum for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    TemporalDatum createTemporalDatum(Map<String, ?> properties,
+                                      Date           origin) throws FactoryException;
+
+    /**
+     * Creates a vertical datum from an enumerated type value.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  type The type of this vertical datum (often "geoidal").
+     * @return The datum for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createVerticalDatum", specification=OGC_01009)
+    VerticalDatum createVerticalDatum(Map<String, ?>    properties,
+                                      VerticalDatumType type) throws FactoryException;
+
+    /**
+     * Creates an ellipsoid from radius values.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  semiMajorAxis Equatorial radius in supplied linear units.
+     * @param  semiMinorAxis Polar radius in supplied linear units.
+     * @param  unit Linear units of ellipsoid axes.
+     * @return The ellipsoid for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createEllipsoid", specification=OGC_01009)
+    Ellipsoid createEllipsoid(Map<String, ?> properties,
+                              double         semiMajorAxis,
+                              double         semiMinorAxis,
+                              Unit<Length>   unit) throws FactoryException;
+
+    /**
+     * Creates an ellipsoid from an major radius, and inverse flattening.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  semiMajorAxis Equatorial radius in supplied linear units.
+     * @param  inverseFlattening Eccentricity of ellipsoid.
+     * @param  unit Linear units of major axis.
+     * @return The ellipsoid for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createFlattenedSphere", specification=OGC_01009)
+    Ellipsoid createFlattenedSphere(Map<String, ?> properties,
+                                    double         semiMajorAxis,
+                                    double         inverseFlattening,
+                                    Unit<Length>   unit) throws FactoryException;
+
+    /**
+     * Creates a prime meridian, relative to Greenwich.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  longitude Longitude of prime meridian in supplied angular units East of Greenwich.
+     * @param  unit Angular units of longitude.
+     * @return The prime meridian for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createPrimeMeridian", specification=OGC_01009)
+    PrimeMeridian createPrimeMeridian(Map<String, ?> properties,
+                                      double         longitude,
+                                      Unit<Angle>    unit) throws FactoryException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/Ellipsoid.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/Ellipsoid.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/Ellipsoid.java	(revision 28000)
@@ -0,0 +1,89 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.datum;
+
+import javax.measure.unit.Unit;
+import javax.measure.quantity.Length;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Geometric figure that can be used to describe the approximate shape of the earth.
+ * In mathematical terms, it is a surface formed by the rotation of an ellipse about
+ * its minor axis. An ellipsoid requires two defining parameters:
+ * <p>
+ * <ul>
+ *   <li>{@linkplain #getSemiMajorAxis semi-major axis} and
+ *       {@linkplain #getInverseFlattening inverse flattening}, or</li>
+ *   <li>{@linkplain #getSemiMajorAxis semi-major axis} and
+ *       {@linkplain #getSemiMinorAxis semi-minor axis}.</li>
+ * </ul>
+ * <p>
+ * There is not just one ellipsoid. An ellipsoid is a matter of choice, and therefore many
+ * choices are possible. The size and shape of an ellipsoid was traditionally chosen such
+ * that the surface of the geoid is matched as closely as possible locally, e.g. in a country.
+ * A number of global best-fit ellipsoids are now available. An association of an ellipsoid with
+ * the earth is made through the definition of the size and shape of the ellipsoid and the position
+ * and orientation of this ellipsoid with respect to the earth. Collectively this choice is captured
+ * by the concept of "{@linkplain GeodeticDatum geodetic datum}". A change of size, shape, position
+ * or orientation of an ellipsoid will result in a change of geographic coordinates of a point and
+ * be described as a different geodetic datum. Conversely geographic coordinates are unambiguous
+ * only when associated with a geodetic datum.
+ *
+ * @departure
+ *   ISO 19111 defines {@link #getSemiMinorAxis semiMinorAxis}, {@link #getInverseFlattening
+ *   inverseFlattening} and {@link #isIvfDefinitive isSphere} in a separated structure named
+ *   {@code secondDefiningParameter} of type {@code union}. The C/C++ concept of {@code union}
+ *   doesn't exist in Java, but implementors can achieve the same functionality by providing
+ *   different {@code Ellipsoid} subclasses computing one parameter on-the-fly from the other
+ *   one. The {@link #isIvfDefinitive isIvfDefinitive} attribute imported from OGC 01-004 can
+ *   be used for distinguishing between the two cases.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/datum/Ellipsoid.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CD_Ellipsoid", specification=ISO_19111)
+public interface Ellipsoid extends IdentifiedObject {
+    /**
+     * Returns the linear unit of the {@linkplain #getSemiMajorAxis semi-major}
+     * and {@linkplain #getSemiMinorAxis semi-minor} axis values.
+     *
+     * @return The axis linear unit.
+     */
+    @UML(identifier="getAxisUnit", specification=OGC_01009)
+    Unit<Length> getAxisUnit();
+
+    /**
+     * Length of the semi-major axis of the ellipsoid. This is the
+     * equatorial radius in {@linkplain #getAxisUnit axis linear unit}.
+     *
+     * @return Length of semi-major axis.
+     * @unitof Length
+     */
+    @UML(identifier="semiMajorAxis", obligation=MANDATORY, specification=ISO_19111)
+    double getSemiMajorAxis();
+
+    /**
+     * Length of the semi-minor axis of the ellipsoid. This is the
+     * polar radius in {@linkplain #getAxisUnit axis linear unit}.
+     *
+     * @return Length of semi-minor axis.
+     * @unitof Length
+     */
+    @UML(identifier="secondDefiningParameter.semiMinorAxis", obligation=CONDITIONAL, specification=ISO_19111)
+    double getSemiMinorAxis();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/EngineeringDatum.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/EngineeringDatum.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/EngineeringDatum.java	(revision 28000)
@@ -0,0 +1,30 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.datum;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Defines the origin of an engineering coordinate reference system. An engineering datum is used
+ * in a region around that origin. This origin can be fixed with respect to the earth (such as a
+ * defined point at a construction site), or be a defined point on a moving vehicle (such as on a
+ * ship or satellite).
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/datum/EngineeringDatum.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CD_EngineeringDatum", specification=ISO_19111)
+public interface EngineeringDatum extends Datum {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/GeodeticDatum.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/GeodeticDatum.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/GeodeticDatum.java	(revision 28000)
@@ -0,0 +1,49 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.datum;
+
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Defines the location and precise orientation in 3-dimensional space of a defined ellipsoid
+ * (or sphere) that approximates the shape of the earth. Used also for Cartesian coordinate
+ * system centered in this ellipsoid (or sphere).
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/datum/GeodeticDatum.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see Ellipsoid
+ * @see PrimeMeridian
+ */
+@UML(identifier="CD_GeodeticDatum", specification=ISO_19111)
+public interface GeodeticDatum extends Datum {
+    /**
+     * Returns the ellipsoid.
+     *
+     * @return The ellipsoid.
+     */
+    @UML(identifier="usesEllipsoid", obligation=MANDATORY, specification=ISO_19111)
+    Ellipsoid getEllipsoid();
+
+    /**
+     * Returns the prime meridian.
+     *
+     * @return The prime meridian.
+     */
+    @UML(identifier="usesPrimeMeridian", obligation=MANDATORY, specification=ISO_19111)
+    PrimeMeridian getPrimeMeridian();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/ImageDatum.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/ImageDatum.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/ImageDatum.java	(revision 28000)
@@ -0,0 +1,30 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.datum;
+
+import static org.opengis.annotation.Specification.ISO_19111;
+
+import org.opengis.annotation.UML;
+
+
+/**
+ * Defines the origin of an image coordinate reference system. An image datum is used in a local
+ * context only. For an image datum, the anchor point is usually either the centre of the image
+ * or the corner of the image.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/datum/ImageDatum.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CD_ImageDatum", specification=ISO_19111)
+public interface ImageDatum extends Datum {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/PixelInCell.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/PixelInCell.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/PixelInCell.java	(revision 28000)
@@ -0,0 +1,84 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.datum;
+
+import static org.opengis.annotation.Specification.ISO_19111;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opengis.annotation.UML;
+import org.opengis.util.CodeList;
+
+
+/**
+ * Specification of the way the image grid is associated with the image data attributes.
+ * <p>
+ * This code list is similar to {@link org.opengis.metadata.spatial.PixelOrientation}
+ * except that the later is more clearly restricted to the two-dimensional case.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/datum/PixelInCell.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CD_PixelInCell", specification=ISO_19111)
+public final class PixelInCell extends CodeList<PixelInCell> {
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = 2857889370030758462L;
+
+    /**
+     * List of all enumerations of this type.
+     * Must be declared before any enum declaration.
+     */
+    private static final List<PixelInCell> VALUES = new ArrayList<PixelInCell>(2);
+
+    /**
+     * Constructs an enum with the given name. The new enum is
+     * automatically added to the list returned by {@link #values}.
+     *
+     * @param name The enum name. This name must not be in use by an other enum of this type.
+     */
+    private PixelInCell(final String name) {
+        super(name, VALUES);
+    }
+
+    /**
+     * Returns the list of {@code PixelInCell}s.
+     *
+     * @return The list of codes declared in the current JVM.
+     */
+    public static PixelInCell[] values() {
+        synchronized (VALUES) {
+            return VALUES.toArray(new PixelInCell[VALUES.size()]);
+        }
+    }
+
+    /**
+     * Returns the list of enumerations of the same kind than this enum.
+     */
+    public PixelInCell[] family() {
+        return values();
+    }
+
+    /**
+     * Returns the pixel in cell that matches the given string, or returns a
+     * new one if none match it.
+     *
+     * @param code The name of the code to fetch or to create.
+     * @return A code matching the given name.
+     */
+    public static PixelInCell valueOf(String code) {
+        return valueOf(PixelInCell.class, code);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/PrimeMeridian.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/PrimeMeridian.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/PrimeMeridian.java	(revision 28000)
@@ -0,0 +1,52 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.datum;
+
+import javax.measure.unit.Unit;
+import javax.measure.quantity.Angle;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A prime meridian defines the origin from which longitude values are determined.
+ * The {@link #getName name} initial value is "Greenwich", and that value shall be
+ * used when the {@linkplain #getGreenwichLongitude greenwich longitude} value is
+ * zero.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/datum/PrimeMeridian.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CD_PrimeMeridian", specification=ISO_19111)
+public interface PrimeMeridian extends IdentifiedObject {
+    /**
+     * Longitude of the prime meridian measured from the Greenwich meridian, positive eastward.
+     * The {@code greenwichLongitude} initial value is zero, and that value shall be used
+     * when the {@linkplain #getName meridian name} value is "Greenwich".
+     *
+     * @return The prime meridian Greenwich longitude, in {@linkplain #getAngularUnit angular unit}.
+     */
+    @UML(identifier="greenwichLongitude", obligation=CONDITIONAL, specification=ISO_19111)
+    double getGreenwichLongitude();
+
+    /**
+     * Returns the angular unit of the {@linkplain #getGreenwichLongitude Greenwich longitude}.
+     *
+     * @return The angular unit of greenwich longitude.
+     */
+    @UML(identifier="getAngularUnit", specification=OGC_01009)
+    Unit<Angle> getAngularUnit();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/TemporalDatum.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/TemporalDatum.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/TemporalDatum.java	(revision 28000)
@@ -0,0 +1,38 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.datum;
+
+import static org.opengis.annotation.Obligation.MANDATORY;
+import static org.opengis.annotation.Specification.ISO_19111;
+
+import java.util.Date;
+
+import org.opengis.annotation.UML;
+
+
+/**
+ * A temporal datum defines the origin of a temporal coordinate reference system.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/datum/TemporalDatum.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CD_TemporalDatum", specification=ISO_19111)
+public interface TemporalDatum extends Datum {
+    /**
+     * The date and time origin of this temporal datum.
+     *
+     * @return The date and time origin of this temporal datum.
+     */
+    @UML(identifier="origin", obligation=MANDATORY, specification=ISO_19111)
+    Date getOrigin();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/VerticalDatum.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/VerticalDatum.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/VerticalDatum.java	(revision 28000)
@@ -0,0 +1,41 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.datum;
+
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A textual description and/or a set of parameters identifying a particular reference level
+ * surface used as a zero-height surface. The description includes its position with respect
+ * to the Earth for any of the height types recognized by this standard. There are several
+ * types of Vertical Datums, and each may place constraints on the
+ * {@linkplain org.opengis.referencing.cs.CoordinateSystemAxis Coordinate Axis} with which
+ * it is combined to create a {@linkplain org.opengis.referencing.crs.VerticalCRS Vertical CRS}.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/datum/VerticalDatum.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CD_VerticalDatum", specification=ISO_19111)
+public interface VerticalDatum extends Datum {
+    /**
+     * The type of this vertical datum. Default is "geoidal".
+     *
+     * @return The type of this vertical datum.
+     */
+    @UML(identifier="vertDatumType", obligation=MANDATORY, specification=ISO_19111)
+    VerticalDatumType getVerticalDatumType();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/VerticalDatumType.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/VerticalDatumType.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/datum/VerticalDatumType.java	(revision 28000)
@@ -0,0 +1,153 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.datum;
+
+import java.util.List;
+import java.util.ArrayList;
+import org.opengis.util.CodeList;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Type of a vertical datum.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/datum/VerticalDatumType.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CD_VerticalDatumType", specification=ISO_19111)
+public final class VerticalDatumType extends CodeList<VerticalDatumType> {
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = -8161084528823937553L;
+
+    /**
+     * List of all enumerations of this type.
+     * Must be declared before any enum declaration.
+     */
+    private static final List<VerticalDatumType> VALUES = new ArrayList<VerticalDatumType>(6);
+
+    /**
+     * In some cases, e.g. oil exploration and production, a geological feature, such as the top
+     * or bottom of a geologically identifiable and meaningful subsurface layer, is used as a
+     * vertical datum. Other variations to the above three vertical datum types may exist
+     * and are all included in this type.
+     */
+    @UML(identifier="other surface", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final VerticalDatumType OTHER_SURFACE = new VerticalDatumType("OTHER_SURFACE");
+
+    /**
+     * The zero value of the associated vertical coordinate system axis is defined to approximate
+     * a constant potential surface, usually the geoid. Such a reference surface is usually
+     * determined by a national or scientific authority, and is then a well-known, named datum.
+     */
+    @UML(identifier="geoidal", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final VerticalDatumType GEOIDAL = new VerticalDatumType("GEOIDAL");
+
+    /**
+     * A vertical datum for ellipsoidal heights that are measured along the
+     * normal to the ellipsoid used in the definition of horizontal datum.
+     *
+     * @departure
+     *   This code is a violation of ISO 19111 specification, which does not allow instantation of
+     *   {@linkplain org.opengis.referencing.crs.VerticalCRS Vertical CRS} for ellipsoidal height.
+     *   More specifically {@linkplain org.opengis.referencing.crs.GeographicCRS Geographic CRS}
+     *   with ellipsoidal height shall be backed by a three-dimensional
+     *   {@linkplain org.opengis.referencing.cs.EllipsoidalCS Ellipsoidal CS}; they should never
+     *   be built as {@linkplain org.opengis.referencing.crs.CompoundCRS Compound CRS}.
+     *   <p>
+     *   However some API need to express the ellipsoidal height alone, e.g. for type safety
+     *   in methods like {@link org.opengis.metadata.extent.VerticalExtent#getVerticalCRS}.
+     *   The alternative would be to pass an arbitrary
+     *   {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem Coordinate Reference System}
+     *   and let the user extracts the vertical component himself.
+     *   <p>
+     *   Furthermore the <A HREF="../doc-files/WKT.html">WKT format</A> still in wide use, and this
+     *   format (defined before ISO 19111) does not treat ellipsoidal height in a special way. A WKT
+     *   parser needs to get the vertical CRS separatly before to merge it with the geographic CRS.
+     *
+     * @issue http://jira.codehaus.org/browse/GEO-133
+     */
+    @UML(identifier="CS_DatumType.CS_VD_Ellipsoidal", obligation=CONDITIONAL, specification=OGC_01009)
+    public static final VerticalDatumType ELLIPSOIDAL = new VerticalDatumType("ELLIPSOIDAL");
+
+    /**
+     * The zero point of the vertical axis is defined by a surface that has meaning for the
+     * purpose which the associated vertical measurements are used for. For hydrographic charts,
+     * this is often a predicted nominal sea surface (i.e., without waves or other wind and current
+     * effects) that occurs at low tide. Depths are measured in the direction perpendicular
+     * (approximately) to the actual equipotential surfaces of the earth's gravity field,
+     * using such procedures as echo-sounding.
+     */
+    @UML(identifier="depth", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final VerticalDatumType DEPTH = new VerticalDatumType("DEPTH");
+
+    /**
+     * Atmospheric pressure is the basis for the definition of the origin of the
+     * associated vertical coordinate system axis. These are approximations of
+     * orthometric heights obtained with the help of a barometer or a barometric
+     * altimeter. These values are usually expressed in one of the following units:
+     * meters, feet, millibars (used to measure pressure levels), or theta value
+     * (units used to measure geopotential height).
+     */
+    @UML(identifier="barometric", obligation=CONDITIONAL, specification=ISO_19111)
+    public static final VerticalDatumType BAROMETRIC = new VerticalDatumType("BAROMETRIC");
+
+    /**
+     * A vertical datum for orthometric heights that are measured along the plumb line.
+     */
+    @UML(identifier="CS_DatumType.CS_VD_Orthometric", obligation=CONDITIONAL, specification=OGC_01009)
+    public static final VerticalDatumType ORTHOMETRIC = new VerticalDatumType("ORTHOMETRIC");
+
+    /**
+     * Constructs an enum with the given name. The new enum is
+     * automatically added to the list returned by {@link #values}.
+     *
+     * @param name The enum name. This name must not be in use by an other enum of this type.
+     */
+    private VerticalDatumType(final String name) {
+        super(name, VALUES);
+    }
+
+    /**
+     * Returns the list of {@code VerticalDatumType}s.
+     *
+     * @return The list of codes declared in the current JVM.
+     */
+    public static VerticalDatumType[] values() {
+        synchronized (VALUES) {
+            return VALUES.toArray(new VerticalDatumType[VALUES.size()]);
+        }
+    }
+
+    /**
+     * Returns the list of enumerations of the same kind than this enum.
+     */
+    public VerticalDatumType[] family() {
+        return values();
+    }
+
+    /**
+     * Returns the vertical datum type that matches the given string, or returns a
+     * new one if none match it.
+     *
+     * @param code The name of the code to fetch or to create.
+     * @return A code matching the given name.
+     */
+    public static VerticalDatumType valueOf(String code) {
+        return valueOf(VerticalDatumType.class, code);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/ConcatenatedOperation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/ConcatenatedOperation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/ConcatenatedOperation.java	(revision 28000)
@@ -0,0 +1,44 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import java.util.List;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * An ordered sequence of two or more single coordinate operations. The sequence of operations is
+ * constrained by the requirement that the source coordinate reference system of step
+ * (<var>n</var>+1) must be the same as the target coordinate reference system of step
+ * (<var>n</var>). The source coordinate reference system of the first step and the target
+ * coordinate reference system of the last step are the source and target coordinate reference
+ * system associated with the concatenated operation. Instead of a forward operation, an inverse
+ * operation may be used for one or more of the operation steps mentioned above, if the inverse
+ * operation is uniquely defined by the forward operation.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/ConcatenatedOperation.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CC_ConcatenatedOperation", specification=ISO_19111)
+public interface ConcatenatedOperation extends CoordinateOperation {
+    /**
+     * Returns the sequence of operations.
+     *
+     * @return The sequence of operations.
+     */
+    @UML(identifier="usesOperation", obligation=MANDATORY, specification=ISO_19111)
+    List<SingleOperation> getOperations();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/ConicProjection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/ConicProjection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/ConicProjection.java	(revision 28000)
@@ -0,0 +1,31 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.annotation.Extension;
+
+
+/**
+ * Base interface for conical map projections.
+ *
+ * <p>&nbsp;</p>
+ * <p align="center"><img src="../doc-files/ConicProjection.png"></p>
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.crs.ProjectedCRS
+ * @see <A HREF="http://mathworld.wolfram.com/ConicProjection.html">Conic projection on MathWorld</A>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/ConicProjection.java $
+ */
+@Extension
+public interface ConicProjection extends Projection {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Conversion.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Conversion.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Conversion.java	(revision 28000)
@@ -0,0 +1,62 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * An operation on coordinates that does not include any change of Datum. The best-known
+ * example of a coordinate conversion is a map projection. The parameters describing
+ * coordinate conversions are defined rather than empirically derived.
+ * <p>
+ * Note that some conversions have no parameters.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/Conversion.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see Transformation
+ */
+@UML(identifier="CC_Conversion", specification=ISO_19111)
+public interface Conversion extends Operation {
+    /**
+     * Returns the source CRS. Conversions may have a source CRS that
+     * is not specified here, but through
+     * {@link org.opengis.referencing.crs.GeneralDerivedCRS#getBaseCRS} instead.
+     *
+     * @return The source CRS, or {@code null} if not available.
+     */
+    @UML(identifier="sourceCRS", obligation=OPTIONAL, specification=ISO_19111)
+    CoordinateReferenceSystem getSourceCRS();
+
+    /**
+     * Returns the target CRS. {@linkplain Conversion Conversions} may have a target CRS
+     * that is not specified here, but through
+     * {@link org.opengis.referencing.crs.GeneralDerivedCRS} instead.
+     *
+     * @return The target CRS, or {@code null} if not available.
+     */
+    @UML(identifier="targetCRS", obligation=OPTIONAL, specification=ISO_19111)
+    CoordinateReferenceSystem getTargetCRS();
+
+    /**
+     * This attribute is declared in {@link CoordinateOperation} but is not used in a conversion.
+     *
+     * @return Always {@code null}.
+     */
+    @UML(identifier="operationVersion", obligation=CONDITIONAL, specification=ISO_19111)
+    String getOperationVersion();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/CoordinateOperation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/CoordinateOperation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/CoordinateOperation.java	(revision 28000)
@@ -0,0 +1,162 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import java.util.Collection;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.metadata.quality.PositionalAccuracy;
+import org.opengis.metadata.extent.Extent;
+import org.opengis.util.InternationalString;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A mathematical operation on coordinates that transforms or converts coordinates to
+ * another coordinate reference system. Many but not all coordinate operations (from
+ * {@linkplain CoordinateReferenceSystem coordinate reference system} <VAR>A</VAR> to
+ * {@linkplain CoordinateReferenceSystem coordinate reference system} <VAR>B</VAR>)
+ * also uniquely define the inverse operation (from
+ * {@linkplain CoordinateReferenceSystem coordinate reference system} <VAR>B</VAR> to
+ * {@linkplain CoordinateReferenceSystem coordinate reference system} <VAR>A</VAR>).
+ * In some cases, the operation method algorithm for the inverse operation is the same
+ * as for the forward algorithm, but the signs of some operation parameter values must
+ * be reversed. In other cases, different algorithms are required for the forward and
+ * inverse operations, but the same operation parameter values are used. If (some)
+ * entirely different parameter values are needed, a different coordinate operation
+ * shall be defined.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/CoordinateOperation.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CC_CoordinateOperation", specification=ISO_19111)
+public interface CoordinateOperation extends IdentifiedObject {
+    /**
+     * Key for the <code>{@value}</code> property.
+     * This is used for setting the value to be returned by {@link #getOperationVersion}.
+     *
+     * @see #getOperationVersion
+     */
+    String OPERATION_VERSION_KEY = "operationVersion";
+
+    /**
+     * Key for the <code>{@value}</code> property.
+     * This is used for setting the value to be returned by {@link #getCoordinateOperationAccuracy}.
+     *
+     * @see #getCoordinateOperationAccuracy
+     *
+     * @since GeoAPI 2.1
+     */
+    String COORDINATE_OPERATION_ACCURACY_KEY = "coordinateOperationAccuracy";
+
+    /**
+     * Key for the <code>{@value}</code> property.
+     * This is used for setting the value to be returned by {@link #getDomainOfValidity}.
+     *
+     * @see #getDomainOfValidity
+     *
+     * @since GeoAPI 2.1
+     */
+    String DOMAIN_OF_VALIDITY_KEY = "domainOfValidity";
+
+    /**
+     * Key for the <code>{@value}</code> property.
+     * This is used for setting the value to be returned by {@link #getScope}.
+     *
+     * @see #getScope
+     */
+    String SCOPE_KEY = "scope";
+
+    /**
+     * Returns the source CRS. The source CRS is mandatory for {@linkplain Transformation
+     * transformations} only. {@linkplain Conversion Conversions} may have a source CRS that
+     * is not specified here, but through
+     * {@link org.opengis.referencing.crs.GeneralDerivedCRS#getBaseCRS} instead.
+     *
+     * @return The source CRS, or {@code null} if not available.
+     *
+     * @see Conversion#getSourceCRS
+     * @see Transformation#getSourceCRS
+     */
+    @UML(identifier="sourceCRS", obligation=CONDITIONAL, specification=ISO_19111)
+    CoordinateReferenceSystem getSourceCRS();
+
+    /**
+     * Returns the target CRS. The target CRS is mandatory for {@linkplain Transformation
+     * transformations} only. {@linkplain Conversion Conversions} may have a target CRS
+     * that is not specified here, but through
+     * {@link org.opengis.referencing.crs.GeneralDerivedCRS} instead.
+     *
+     * @return The target CRS, or {@code null} if not available.
+     *
+     * @see Conversion#getTargetCRS
+     * @see Transformation#getTargetCRS
+     */
+    @UML(identifier="targetCRS", obligation=CONDITIONAL, specification=ISO_19111)
+    CoordinateReferenceSystem getTargetCRS();
+
+    /**
+     * Version of the coordinate transformation (i.e., instantiation due to the stochastic
+     * nature of the parameters). Mandatory when describing a transformation, and should not
+     * be supplied for a conversion.
+     *
+     * @return The coordinate operation version, or {@code null} in none.
+     */
+    @UML(identifier="operationVersion", obligation=CONDITIONAL, specification=ISO_19111)
+    String getOperationVersion();
+
+    /**
+     * Estimate(s) of the impact of this operation on point accuracy. Gives
+     * position error estimates for target coordinates of this coordinate
+     * operation, assuming no errors in source coordinates.
+     *
+     * @return The position error estimates, or an empty collection if not available.
+     *
+     * @since GeoAPI 2.1
+     */
+    @UML(identifier="coordinateOperationAccuracy", obligation=OPTIONAL, specification=ISO_19111)
+    Collection<PositionalAccuracy> getCoordinateOperationAccuracy();
+
+    /**
+     * Area or region or timeframe in which this coordinate operation is valid.
+     *
+     * @return The coordinate operation valid domain, or {@code null} if not available.
+     *
+     * @since GeoAPI 2.1
+     */
+    @UML(identifier="domainOfValidity", obligation=OPTIONAL, specification=ISO_19111)
+    Extent getDomainOfValidity();
+
+    /**
+     * Description of domain of usage, or limitations of usage, for which this operation is valid.
+     *
+     * @return A description of domain of usage, or {@code null} if none.
+     */
+    @UML(identifier="scope", obligation=OPTIONAL, specification=ISO_19111)
+    InternationalString getScope();
+
+    /**
+     * Gets the math transform. The math transform will transform positions in the
+     * {@linkplain #getSourceCRS source coordinate reference system} into positions in the
+     * {@linkplain #getTargetCRS target coordinate reference system}. It may be {@code null}
+     * in the case of {@linkplain CoordinateOperationFactory#createDefiningConversion
+     * defining conversions}.
+     *
+     * @return The transform from source to target CRS, or {@code null} if not applicable.
+     */
+    @UML(identifier="CT_CoordinateTransformation.getMathTransform", specification=OGC_01009)
+    MathTransform getMathTransform();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/CoordinateOperationAuthorityFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/CoordinateOperationAuthorityFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/CoordinateOperationAuthorityFactory.java	(revision 28000)
@@ -0,0 +1,70 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import java.util.Set;
+import org.opengis.metadata.Identifier;
+import org.opengis.referencing.AuthorityFactory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Creates coordinate transformation objects from codes. The codes are maintained by an
+ * external authority. A commonly used authority is <A HREF="http://www.epsg.org">EPSG</A>,
+ * which is also used in the GeoTIFF standard.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/CoordinateOperationAuthorityFactory.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-009.pdf">Implementation specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CT_CoordinateTransformationAuthorityFactory", specification=OGC_01009)
+public interface CoordinateOperationAuthorityFactory extends AuthorityFactory {
+    /**
+     * Creates an operation from a single operation code. The "{@linkplain Identifier#getAuthority
+     * authority}" and "{@linkplain Identifier#getCode code}" values of the created object will be
+     * set to the authority of this object, and the code specified by the client, respectively. The
+     * other metadata values may or may not be set.
+     *
+     * @param  code Coded value for transformation.
+     * @return The operation for the given code.
+     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    @UML(identifier="createFromTransformationCode", specification=OGC_01009)
+    CoordinateOperation createCoordinateOperation(String code)
+            throws NoSuchAuthorityCodeException, FactoryException;
+
+    /**
+     * Creates operations from {@linkplain CoordinateReferenceSystem coordinate reference system}
+     * codes. This method returns only the operations declared by the authority, with preferred
+     * operations first. This method doesn't need to compute operations from {@code source} to
+     * {@code target} CRS if no such operations were explicitly defined in the authority database.
+     * Computation of arbitrary operations can be performed by
+     * <code>{@linkplain CoordinateOperationFactory#createOperation(CoordinateReferenceSystem,
+     * CoordinateReferenceSystem) CoordinateOperationFactory.createOperation}(sourceCRS, targetCRS)</code>
+     * instead.
+     *
+     * @param  sourceCRS   Coded value of source coordinate reference system.
+     * @param  targetCRS   Coded value of target coordinate reference system.
+     * @return The operations from {@code sourceCRS} to {@code targetCRS}.
+     * @throws NoSuchAuthorityCodeException if a specified code was not found.
+     * @throws FactoryException if the object creation failed for some other reason.
+     */
+    @UML(identifier="createFromCoordinateSystemCodes", specification=OGC_01009)
+    Set<CoordinateOperation> createFromCoordinateReferenceSystemCodes(String sourceCRS, String targetCRS)
+            throws NoSuchAuthorityCodeException, FactoryException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/CoordinateOperationFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/CoordinateOperationFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/CoordinateOperationFactory.java	(revision 28000)
@@ -0,0 +1,109 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import static org.opengis.annotation.Specification.OGC_01009;
+
+import java.util.Map;
+
+import org.opengis.annotation.Extension;
+import org.opengis.annotation.UML;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.ObjectFactory;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+
+/**
+ * Creates {@linkplain CoordinateOperation coordinate operations}.
+ * This factory is capable to find coordinate {@linkplain Transformation transformations}
+ * or {@linkplain Conversion conversions} between two
+ * {@linkplain CoordinateReferenceSystem coordinate reference systems}.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/CoordinateOperationFactory.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-009.pdf">Implementation specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CT_CoordinateTransformationFactory", specification=OGC_01009)
+public interface CoordinateOperationFactory extends ObjectFactory {
+    /**
+     * Returns an operation for conversion or transformation between two coordinate reference systems.
+     * <ul>
+     *   <li>If an operation exists, it is returned.</li>
+     *   <li>If more than one operation exists, the default is returned.</li>
+     *   <li>If no operation exists, then the exception is thrown.</li>
+     * </ul>
+     * <p>
+     * Implementations may try to
+     * {@linkplain CoordinateOperationAuthorityFactory#createFromCoordinateReferenceSystemCodes
+     * query an authority factory} first, and compute the operation next if no operation from
+     * {@code source} to {@code target} code was explicitly defined by the authority.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS}
+     *         to {@code targetCRS}.
+     * @throws FactoryException if the operation creation failed for some other reason.
+     */
+    @UML(identifier="createFromCoordinateSystems", specification=OGC_01009)
+    CoordinateOperation createOperation(CoordinateReferenceSystem sourceCRS,
+                                        CoordinateReferenceSystem targetCRS)
+            throws OperationNotFoundException, FactoryException;
+
+    /**
+     * Returns an operation using a particular method for conversion or transformation
+     * between two coordinate reference systems.
+     * <ul>
+     *   <li>If the operation exists on the implementation, then it is returned.</li>
+     *   <li>If the operation does not exist on the implementation, then the implementation
+     *       has the option of inferring the operation from the argument objects.</li>
+     *   <li>If for whatever reason the specified operation will not be returned, then
+     *       the exception is thrown.</li>
+     * </ul>
+     * <p>
+     * <b>Example:</b> A transformation between two {@linkplain org.opengis.referencing.crs.GeographicCRS
+     * geographic CRS} using different {@linkplain org.opengis.datum.GeodeticDatum datum} requires a
+     * <cite>datum shift</cite>. Many methods exist for this purpose, including interpolations in a
+     * grid, a scale/rotation/translation in geocentric coordinates or the Molodenski approximation.
+     * When invoking {@code createOperation} without operation method, this factory may select by
+     * default the most accurate transformation (typically interpolation in a grid). When invoking
+     * {@code createOperation} with an operation method, user can force usage of Molodenski
+     * approximation for instance.
+     *
+     * @param  sourceCRS Input coordinate reference system.
+     * @param  targetCRS Output coordinate reference system.
+     * @param  method The algorithmic method for conversion or transformation.
+     * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+     * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS}
+     *         to {@code targetCRS}.
+     * @throws FactoryException if the operation creation failed for some other reason.
+     */
+    @Extension
+    CoordinateOperation createOperation(CoordinateReferenceSystem sourceCRS,
+                                        CoordinateReferenceSystem targetCRS,
+                                        OperationMethod           method)
+            throws OperationNotFoundException, FactoryException;
+
+    /**
+     * Creates a concatenated operation from a sequence of operations.
+     *
+     * @param  properties Name and other properties to give to the new object.
+     *         Available properties are {@linkplain ObjectFactory listed there}.
+     * @param  operations The sequence of operations.
+     * @return The concatenated operation.
+     * @throws FactoryException if the object creation failed.
+     */
+    @Extension
+    CoordinateOperation createConcatenatedOperation(Map<String, ?> properties,
+                                                    CoordinateOperation[] operations)
+            throws FactoryException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/CylindricalProjection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/CylindricalProjection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/CylindricalProjection.java	(revision 28000)
@@ -0,0 +1,31 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.annotation.Extension;
+
+
+/**
+ * Base interface for cylindrical map projections.
+ *
+ * <p>&nbsp;</p>
+ * <p align="center"><img src="../doc-files/CylindricalProjection.png"></p>
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.crs.ProjectedCRS
+ * @see <A HREF="http://mathworld.wolfram.com/CylindricalProjection.html">Cylindrical projection on MathWorld</A>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/CylindricalProjection.java $
+ */
+@Extension
+public interface CylindricalProjection extends Projection {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/MathTransform.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/MathTransform.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/MathTransform.java	(revision 28000)
@@ -0,0 +1,267 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Transforms multi-dimensional coordinate points. This interface transforms coordinate
+ * value for a point given in the {@linkplain CoordinateOperation#getSourceCRS source
+ * coordinate reference system} to coordinate value for the same point in the
+ * {@linkplain CoordinateOperation#getTargetCRS target coordinate reference system}.
+ *
+ * In a {@linkplain Conversion conversion}, the transformation is accurate to within the
+ * limitations of the computer making the calculations. In a {@linkplain Transformation
+ * transformation}, where some of the operational parameters are derived from observations,
+ * the transformation is accurate to within the limitations of those observations.
+ *
+ * If a client application wishes to query the source and target
+ * {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference systems}
+ * of an operation, then it should keep hold of the {@link CoordinateOperation} interface,
+ * and use the contained math transform object whenever it wishes to perform a transform.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/MathTransform.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-009.pdf">Implementation specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see java.awt.geom.AffineTransform
+ * @see javax.media.jai.PerspectiveTransform
+ * @see javax.media.j3d.Transform3D
+ * @see MathTransformFactory
+ * @see CoordinateOperation#getMathTransform
+ */
+@UML(identifier="CT_MathTransform", specification=OGC_01009)
+public interface MathTransform {
+    /**
+     * Gets the dimension of input points.
+     *
+     * @return The dimension of input points.
+     */
+    @UML(identifier="getDimSource", specification=OGC_01009)
+    int getSourceDimensions();
+
+    /**
+     * Gets the dimension of output points.
+     *
+     * @return The dimension of output points.
+     */
+    @UML(identifier="getDimTarget", specification=OGC_01009)
+    int getTargetDimensions();
+
+    /**
+     * Transforms the specified {@code ptSrc} and stores the result in
+     * {@code ptDst}. If {@code ptDst} is {@code null}, a new
+     * {@link DirectPosition} object is allocated and then the result of the
+     * transformation is stored in this object. In either case, {@code ptDst},
+     * which contains the transformed point, is returned for convenience.
+     * If {@code ptSrc} and {@code ptDst} are the same object,
+     * the input point is correctly overwritten with the transformed point.
+     *
+     * @param  ptSrc the specified coordinate point to be transformed.
+     * @param  ptDst the specified coordinate point that stores the result of transforming
+     *         {@code ptSrc}, or {@code null}.
+     * @return the coordinate point after transforming {@code ptSrc} and storing the result
+     *         in {@code ptDst}, or a newly created point if {@code ptDst} was null.
+     * @throws MismatchedDimensionException if {@code ptSrc} or
+     *         {@code ptDst} doesn't have the expected dimension.
+     * @throws TransformException if the point can't be transformed.
+     */
+    @UML(identifier="transform", specification=OGC_01009)
+    DirectPosition transform(DirectPosition ptSrc, DirectPosition ptDst)
+            throws MismatchedDimensionException, TransformException;
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     * This method is provided for efficiently transforming many points.
+     * The supplied array of ordinal values will contain packed ordinal
+     * values. For example, if the source dimension is 3, then the ordinals
+     * will be packed in this order:
+     *
+     * (<var>x<sub>0</sub></var>,<var>y<sub>0</sub></var>,<var>z<sub>0</sub></var>,
+     *  <var>x<sub>1</sub></var>,<var>y<sub>1</sub></var>,<var>z<sub>1</sub></var> ...).
+     *
+     * @param  srcPts the array containing the source point coordinates.
+     * @param  srcOff the offset to the first point to be transformed in the source array.
+     * @param  dstPts the array into which the transformed point coordinates are returned.
+     *                 May be the same than {@code srcPts}.
+     * @param  dstOff the offset to the location of the first transformed point that is
+     *                stored in the destination array.
+     * @param  numPts the number of point objects to be transformed.
+     * @throws TransformException if a point can't be transformed. Some implementations will stop
+     *         at the first failure, wile some other implementations will fill the untransformable
+     *         points with {@linkplain Double#NaN NaN} values, continue and throw the exception
+     *         only at end. Implementations that fall in the later case should set the {@linkplain
+     *         TransformException#getLastCompletedTransform last completed transform} to {@code this}.
+     */
+    @UML(identifier="transformList", specification=OGC_01009)
+    void transform(double[] srcPts, int srcOff,
+                   double[] dstPts, int dstOff, int numPts) throws TransformException;
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     * This method is provided for efficiently transforming many points.
+     * The supplied array of ordinal values will contain packed ordinal
+     * values.  For example, if the source dimension is 3, then the ordinals
+     * will be packed in this order:
+     *
+     * (<var>x<sub>0</sub></var>,<var>y<sub>0</sub></var>,<var>z<sub>0</sub></var>,
+     *  <var>x<sub>1</sub></var>,<var>y<sub>1</sub></var>,<var>z<sub>1</sub></var> ...).
+     *
+     * @param  srcPts the array containing the source point coordinates.
+     * @param  srcOff the offset to the first point to be transformed in the source array.
+     * @param  dstPts the array into which the transformed point coordinates are returned.
+     *                May be the same than {@code srcPts}.
+     * @param  dstOff the offset to the location of the first transformed point that is
+     *                stored in the destination array.
+     * @param  numPts the number of point objects to be transformed.
+     * @throws TransformException if a point can't be transformed. Some implementations will stop
+     *         at the first failure, wile some other implementations will fill the untransformable
+     *         points with {@linkplain Double#NaN NaN} values, continue and throw the exception
+     *         only at end. Implementations that fall in the later case should set the {@linkplain
+     *         TransformException#getLastCompletedTransform last completed transform} to {@code this}.
+     */
+    void transform(float[] srcPts, int srcOff,
+                   float[] dstPts, int dstOff, int numPts) throws TransformException;
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     * This method is provided for efficiently transforming many points.
+     * The supplied array of ordinal values will contain packed ordinal
+     * values.  For example, if the source dimension is 3, then the ordinals
+     * will be packed in this order:
+     *
+     * (<var>x<sub>0</sub></var>,<var>y<sub>0</sub></var>,<var>z<sub>0</sub></var>,
+     *  <var>x<sub>1</sub></var>,<var>y<sub>1</sub></var>,<var>z<sub>1</sub></var> ...).
+     *
+     * @param  srcPts the array containing the source point coordinates.
+     * @param  srcOff the offset to the first point to be transformed in the source array.
+     * @param  dstPts the array into which the transformed point coordinates are returned.
+     * @param  dstOff the offset to the location of the first transformed point that is
+     *                stored in the destination array.
+     * @param  numPts the number of point objects to be transformed.
+     * @throws TransformException if a point can't be transformed. Some implementations will stop
+     *         at the first failure, wile some other implementations will fill the untransformable
+     *         points with {@linkplain Double#NaN NaN} values, continue and throw the exception
+     *         only at end. Implementations that fall in the later case should set the {@linkplain
+     *         TransformException#getLastCompletedTransform last completed transform} to {@code this}.
+     *
+     * @since GeoAPI 2.2
+     */
+    void transform(float [] srcPts, int srcOff,
+                   double[] dstPts, int dstOff, int numPts) throws TransformException;
+
+    /**
+     * Transforms a list of coordinate point ordinal values.
+     * This method is provided for efficiently transforming many points.
+     * The supplied array of ordinal values will contain packed ordinal
+     * values.  For example, if the source dimension is 3, then the ordinals
+     * will be packed in this order:
+     *
+     * (<var>x<sub>0</sub></var>,<var>y<sub>0</sub></var>,<var>z<sub>0</sub></var>,
+     *  <var>x<sub>1</sub></var>,<var>y<sub>1</sub></var>,<var>z<sub>1</sub></var> ...).
+     *
+     * @param  srcPts the array containing the source point coordinates.
+     * @param  srcOff the offset to the first point to be transformed in the source array.
+     * @param  dstPts the array into which the transformed point coordinates are returned.
+     * @param  dstOff the offset to the location of the first transformed point that is
+     *                stored in the destination array.
+     * @param  numPts the number of point objects to be transformed.
+     * @throws TransformException if a point can't be transformed. Some implementations will stop
+     *         at the first failure, wile some other implementations will fill the untransformable
+     *         points with {@linkplain Double#NaN NaN} values, continue and throw the exception
+     *         only at end. Implementations that fall in the later case should set the {@linkplain
+     *         TransformException#getLastCompletedTransform last completed transform} to {@code this}.
+     *
+     * @since GeoAPI 2.2
+     */
+    void transform(double[] srcPts, int srcOff,
+                   float [] dstPts, int dstOff, int numPts) throws TransformException;
+
+    /**
+     * Gets the derivative of this transform at a point. The derivative is the
+     * matrix of the non-translating portion of the approximate affine map at
+     * the point. The matrix will have dimensions corresponding to the source
+     * and target coordinate systems. If the input dimension is <var>M</var>,
+     * and the output dimension is <var>N</var>, then the matrix will have size
+     * <code>N&times;M</code>. The elements of the matrix
+     *
+     *              <code>{e<sub>n,m</sub> : n=0..(N-1)}</code>
+     *
+     * form a vector in the output space which is parallel to the displacement
+     * caused by a small change in the <var>m</var>'th ordinate in the input space.
+     * <p>
+     * For example, if the input dimension is 4 and the
+     * output dimension is 3, then a small displacement
+     *
+     * <code>(x<sub>0</sub>,&nbsp;x<sub>1</sub>,&nbsp;x<sub>2</sub>,&nbsp;x<sub>3</sub>)</code>
+     *
+     * in the input space will result in a displacement
+     *
+     * <code>(y<sub>0</sub>,&nbsp;y<sub>1</sub>,&nbsp;y<sub>2</sub>)</code>
+     *
+     * in the output space computed as below (<code>e<sub>n,m</sub></code>
+     * are the matrix's elements):
+     *
+     * <pre>
+     * [ y<sub>0</sub> ]     [ e<sub>00</sub>  e<sub>01</sub>  e<sub>02</sub>  e<sub>03</sub> ] [ x<sub>0</sub> ]
+     * [ y<sub>1</sub> ]  =  [ e<sub>10</sub>  e<sub>11</sub>  e<sub>12</sub>  e<sub>13</sub> ] [ x<sub>1</sub> ]
+     * [ y<sub>2</sub> ]     [ e<sub>20</sub>  e<sub>21</sub>  e<sub>22</sub>  e<sub>23</sub> ] [ x<sub>2</sub> ]
+     *    <sub> </sub>          <sub>  </sub>   <sub>  </sub>   <sub>  </sub>   <sub>  </sub>   [ x<sub>3</sub> ]
+     * </pre>
+     *
+     * @param  point The coordinate point where to evaluate the derivative. Null
+     *         value is accepted only if the derivative is the same everywhere.
+     *         For example affine transform accept null value since they produces
+     *         identical derivative no matter the coordinate value. But most map
+     *         projection will requires a non-null value.
+     * @return The derivative at the specified point (never {@code null}).
+     *         This method never returns an internal object: changing the matrix
+     *         will not change the state of this math transform.
+     * @throws NullPointerException if the derivative dependents on coordinate
+     *         and {@code point} is {@code null}.
+     * @throws MismatchedDimensionException if {@code point} doesn't have
+     *         the expected dimension.
+     * @throws TransformException if the derivative can't be evaluated at the
+     *         specified point.
+     */
+    @UML(identifier="derivative", specification=OGC_01009)
+    Matrix derivative(final DirectPosition point)
+            throws MismatchedDimensionException, TransformException;
+
+    /**
+     * Creates the inverse transform of this object. The target of the inverse transform
+     * is the source of the original. The source of the inverse transform is the target
+     * of the original. Using the original transform followed by the inverse's transform
+     * will result in an identity map on the source coordinate space, when allowances for
+     * error are made. This method may fail if the transform is not one to one. However,
+     * all cartographic projections should succeed.
+     *
+     * @return The inverse transform.
+     * @throws NoninvertibleTransformException if the transform can't be inversed.
+     */
+    @UML(identifier="inverse", specification=OGC_01009)
+    MathTransform inverse() throws NoninvertibleTransformException;
+
+    /**
+     * Tests whether this transform does not move any points.
+     *
+     * @return {@code true} if this {@code MathTransform} is
+     *         an identity transform; {@code false} otherwise.
+     */
+    @UML(identifier="isIdentity", specification=OGC_01009)
+    boolean isIdentity();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/MathTransform1D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/MathTransform1D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/MathTransform1D.java	(revision 28000)
@@ -0,0 +1,59 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.annotation.Extension;
+
+
+/**
+ * Transforms one-dimensional coordinate points.
+ * {@link CoordinateOperation#getMathTransform} may returns instance of this
+ * interface when source and destination coordinate systems are both one dimensional.
+ * {@code MathTransform1D} extends {@link MathTransform} by adding a simple method
+ * transforming a value without the overhead of creating data array.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/MathTransform1D.java $
+ */
+@Extension
+public interface MathTransform1D extends MathTransform {
+    /**
+     * Transforms the specified value.
+     *
+     * @param value The value to transform.
+     * @return the transformed value.
+     * @throws TransformException if the value can't be transformed.
+     */
+    double transform(double value) throws TransformException;
+
+    /**
+     * Gets the derivative of this function at a value. The derivative is the
+     * 1&times;1 matrix of the non-translating portion of the approximate affine
+     * map at the value.
+     *
+     * @param  value The value where to evaluate the derivative.
+     * @return The derivative at the specified point.
+     * @throws TransformException if the derivative can't be evaluated at the
+     *         specified point.
+     */
+    double derivative(double value) throws TransformException;
+
+    /**
+     * Creates the inverse transform of this object.
+     *
+     * @return The inverse transform.
+     * @throws NoninvertibleTransformException if the transform can't be inversed.
+     *
+     * @since GeoAPI 2.2
+     */
+    MathTransform1D inverse() throws NoninvertibleTransformException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/MathTransform2D.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/MathTransform2D.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/MathTransform2D.java	(revision 28000)
@@ -0,0 +1,92 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import java.awt.Shape;
+import java.awt.geom.Point2D;
+import org.opengis.annotation.Extension;
+
+
+/**
+ * Transforms two-dimensional coordinate points. {@link CoordinateOperation#getMathTransform} may
+ * returns instance of this interface when source and destination coordinate systems are both two
+ * dimensional. {@code MathTransform2D} extends {@link MathTransform} by adding some methods for
+ * easier interoperability with <A HREF="http://java.sun.com/products/java-media/2D/">Java2D</A>.
+ * <p>
+ * If the transformation is affine, then {@code MathTransform} shall be an
+ * immutable instance of {@link java.awt.geom.AffineTransform}.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/MathTransform2D.java $
+ */
+@Extension
+public interface MathTransform2D extends MathTransform {
+    /**
+     * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
+     * If {@code ptDst} is {@code null}, a new {@link Point2D} object is allocated
+     * and then the result of the transformation is stored in this object. In either case,
+     * {@code ptDst}, which contains the transformed point, is returned for convenience.
+     * If {@code ptSrc} and {@code ptDst} are the same object, the input point is
+     * correctly overwritten with the transformed point.
+     *
+     * @param  ptSrc the coordinate point to be transformed.
+     * @param  ptDst the coordinate point that stores the result of transforming {@code ptSrc},
+     *         or {@code null} if a new point should be created.
+     * @return the coordinate point after transforming {@code ptSrc} and stroring the result
+     *         in {@code ptDst} or in a new point if {@code ptDst} was null.
+     * @throws TransformException if the point can't be transformed.
+     */
+    Point2D transform(final Point2D ptSrc, final Point2D ptDst) throws TransformException;
+
+    /**
+     * Transforms the specified shape. This method may replace straight lines by quadratic curves
+     * when applicable. It may also do the opposite (replace curves by straight lines). The returned
+     * shape doesn't need to have the same number of points than the original shape.
+     *
+     * @param  shape The Shape to transform.
+     * @return The transformed shape. Some implementations may returns
+     *         {@code shape} unmodified if this transform is identity.
+     * @throws TransformException if a transform failed.
+     */
+    @Extension
+    Shape createTransformedShape(final Shape shape) throws TransformException;
+
+    /**
+     * Gets the derivative of this transform at a point. The derivative is the
+     * matrix of the non-translating portion of the approximate affine map at
+     * the point.
+     *
+     * @param  point The coordinate point where to evaluate the derivative. Null value is
+     *         accepted only if the derivative is the same everywhere. For example affine
+     *         transform accept null value since they produces identical derivative no
+     *         matter the coordinate value. But most map projection will requires a non-null
+     *         value.
+     * @return The derivative at the specified point as a 2&times;2 matrix.  This method
+     *         never returns an internal object: changing the matrix will not change the
+     *         state of this math transform.
+     * @throws NullPointerException if the derivative dependents on coordinate
+     *         and {@code point} is {@code null}.
+     * @throws TransformException if the derivative can't be evaluated at the
+     *         specified point.
+     */
+    Matrix derivative(final Point2D point) throws TransformException;
+
+    /**
+     * Creates the inverse transform of this object.
+     *
+     * @return The inverse transform.
+     * @throws NoninvertibleTransformException if the transform can't be inversed.
+     *
+     * @since GeoAPI 2.2
+     */
+    MathTransform2D inverse() throws NoninvertibleTransformException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/MathTransformFactory.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/MathTransformFactory.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/MathTransformFactory.java	(revision 28000)
@@ -0,0 +1,255 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import java.util.Set;
+import org.opengis.referencing.Factory;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchIdentifierException;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.datum.Ellipsoid;
+import org.opengis.referencing.crs.*; // Contains some import for javadoc.
+import org.opengis.parameter.*;       // Contains some import for javadoc.
+import org.opengis.annotation.UML;
+import org.opengis.annotation.Extension;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Low level factory for creating {@linkplain MathTransform math transforms}.
+ * Many high level GIS applications will never need to use this factory directly;
+ * they can use a {@linkplain CoordinateOperationFactory coordinate operation factory}
+ * instead. However, the {@code MathTransformFactory} interface can be used directly
+ * by applications that wish to transform other types of coordinates (e.g. color coordinates,
+ * or image pixel coordinates).
+ * <p>
+ * A {@linkplain MathTransform math transform} is an object that actually does
+ * the work of applying formulae to coordinate values. The math transform does
+ * not know or care how the coordinates relate to positions in the real world.
+ * This lack of semantics makes implementing {@code MathTransformFactory}
+ * significantly easier than it would be otherwise.
+ * <p>
+ * For example the affine transform applies a matrix to the coordinates
+ * without knowing how what it is doing relates to the real world. So if
+ * the matrix scales <var>Z</var> values by a factor of 1000, then it could
+ * be converting meters into millimeters, or it could be converting kilometers
+ * into meters.
+ * <p>
+ * Because {@linkplain MathTransform math transforms} have low semantic value
+ * (but high mathematical value), programmers who do not have much knowledge
+ * of how GIS applications use coordinate systems, or how those coordinate
+ * systems relate to the real world can implement {@code MathTransformFactory}.
+ * The low semantic content of {@linkplain MathTransform math transforms} also
+ * means that they will be useful in applications that have nothing to do with
+ * GIS coordinates. For example, a math transform could be used to map color
+ * coordinates between different color spaces, such as converting (red, green, blue)
+ * colors into (hue, light, saturation) colors.
+ * <p>
+ * Since a {@linkplain MathTransform math transform} does not know what its source
+ * and target coordinate systems mean, it is not necessary or desirable for a math
+ * transform object to keep information on its source and target coordinate systems.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/MathTransformFactory.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-009.pdf">Implementation specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/">Projection transform list on RemoteSensing.org</A>
+ */
+@UML(identifier="CT_MathTransformFactory", specification=OGC_01009)
+public interface MathTransformFactory extends Factory {
+    /**
+     * Returns a set of available methods for {@linkplain MathTransform math transforms}. For
+     * each element in this set, the {@linkplain OperationMethod#getName operation method name}
+     * must be known to the {@link #getDefaultParameters} method in this factory.
+     * The set of available methods is implementation dependent.
+     *
+     * @param  type <code>{@linkplain Operation}.class</code> for fetching all operation methods,
+     *           or <code>{@linkplain Projection}.class</code> for fetching only map projection
+     *           methods.
+     * @return All {@linkplain MathTransform math transform} methods available in this factory.
+     *
+     * @see #getDefaultParameters
+     * @see #createParameterizedTransform
+     */
+    @Extension
+    Set<OperationMethod> getAvailableMethods(Class<? extends Operation> type);
+
+    /**
+     * Returns the operation method used for the latest call to
+     * {@link #createParameterizedTransform createParameterizedTransform},
+     * or {@code null} if not applicable.
+     * <p>
+     * Implementors should document how their implementation behave in a multi-threads environment.
+     * For example some implementations use {@linkplain java.lang.ThreadLocal thread local variables},
+     * while other can choose to returns {@code null} in all cases since this method is optional.
+     * <p>
+     * Note that this method may apply as well to convenience methods that delegate their work to
+     * {@code createParameterizedTransform}, like {@link #createBaseToDerived createBaseToDerived}.
+     *
+     * @return The last method used, or {@code null} if unknown of unsupported.
+     *
+     * @since GeoAPI 2.1
+     */
+    @Extension
+    OperationMethod getLastMethodUsed();
+
+    /**
+     * Returns the default parameter values for a math transform using the given method.
+     * The {@code method} argument is the name of any operation method returned by
+     * <code>{@link #getAvailableMethods getAvailableMethods}({@linkplain Operation}.class)</code>.
+     * A typical example is
+     * <code>"<A HREF="http://www.remotesensing.org/geotiff/proj_list/transverse_mercator.html">Transverse_Mercator</A>"</code>).
+     * <P>
+     * The {@linkplain ParameterDescriptorGroup#getName parameter group name} shall be the
+     * method name, or an alias to be understood by <code>{@linkplain #createParameterizedTransform
+     * createParameterizedTransform}(parameters)</code>. This method creates new parameter instances
+     * at every call. Parameters are intented to be modified by the user before to be given to the
+     * above-cited {@code createParameterizedTransform} method.
+     *
+     * @param  method The case insensitive name of the method to search for.
+     * @return The default parameter values.
+     * @throws NoSuchIdentifierException if there is no transform registered for the specified method.
+     *
+     * @see #getAvailableMethods
+     * @see #createParameterizedTransform
+     */
+    @Extension
+    ParameterValueGroup getDefaultParameters(String method) throws NoSuchIdentifierException;
+
+    /**
+     * Creates a {@linkplain #createParameterizedTransform parameterized transform} from a base CRS
+     * to a derived CS. This convenience method {@linkplain #createConcatenatedTransform concatenates}
+     * the parameterized transform with any other transform required for performing units changes and
+     * ordinates swapping, as described in the {@linkplain #createParameterizedTransform note on
+     * cartographic projections}.
+     * <p>
+     * In addition, implementations are encouraged to infer the {@code "semi_major"} and
+     * {@code "semi_minor"} parameter values from the {@linkplain Ellipsoid ellipsoid}, if
+     * they are not explicitly given.
+     *
+     * @param  baseCRS The source coordinate reference system.
+     * @param  parameters The parameter values for the transform.
+     * @param  derivedCS The target coordinate system.
+     * @return The parameterized transform.
+     * @throws NoSuchIdentifierException if there is no transform registered for the method.
+     * @throws FactoryException if the object creation failed. This exception is thrown
+     *         if some required parameter has not been supplied, or has illegal value.
+     *
+     * @since GeoAPI 2.1
+     */
+    @Extension
+    MathTransform createBaseToDerived(CoordinateReferenceSystem baseCRS,
+                                      ParameterValueGroup       parameters,
+                                      CoordinateSystem          derivedCS)
+            throws NoSuchIdentifierException, FactoryException;
+
+    /**
+     * Creates a transform from a group of parameters. The method name is inferred from
+     * the {@linkplain ParameterDescriptorGroup#getName parameter group name}. Example:
+     *
+     * <blockquote><pre>
+     * ParameterValueGroup p = factory.getDefaultParameters("Transverse_Mercator");
+     * p.parameter("semi_major").setValue(6378137.000);
+     * p.parameter("semi_minor").setValue(6356752.314);
+     * MathTransform mt = factory.createParameterizedTransform(p);
+     * </pre></blockquote>
+     *
+     * <b>Note on cartographic projections:</b>
+     * <P>Cartographic projection transforms are used by {@linkplain ProjectedCRS projected coordinate reference systems}
+     * to map geographic coordinates (e.g. <var>longitude</var> and <var>latitude</var>) into (<var>x</var>,<var>y</var>)
+     * coordinates. These (<var>x</var>,<var>y</var>) coordinates can be imagined to lie on a plane, such as a paper map
+     * or a screen. All cartographic projection transforms created through this method will have the following properties:</P>
+     * <UL>
+     *   <LI>Converts from (<var>longitude</var>,<var>latitude</var>) coordinates to (<var>x</var>,<var>y</var>).</LI>
+     *   <LI>All angles are assumed to be degrees, and all distances are assumed to be meters.</LI>
+     *   <LI>The domain should be a subset of {[-180,180)&times;(-90,90)}.</LI>
+     * </UL>
+     * <P>Although all cartographic projection transforms must have the properties listed above, many projected coordinate
+     * reference systems have different properties. For example, in Europe some projected CRSs use grads instead of degrees,
+     * and often the {@linkplain ProjectedCRS#getBaseCRS base geographic CRS} is (<var>latitude</var>, <var>longitude</var>)
+     * instead of (<var>longitude</var>, <var>latitude</var>). This means that the cartographic projected transform is often
+     * used as a single step in a series of transforms, where the other steps change units and swap ordinates.</P>
+     *
+     * @param  parameters The parameter values.
+     * @return The parameterized transform.
+     * @throws NoSuchIdentifierException if there is no transform registered for the method.
+     * @throws FactoryException if the object creation failed. This exception is thrown
+     *         if some required parameter has not been supplied, or has illegal value.
+     *
+     * @see #getDefaultParameters
+     * @see #getAvailableMethods
+     */
+    @UML(identifier="createParameterizedTransform", obligation=MANDATORY, specification=OGC_01009)
+    MathTransform createParameterizedTransform(ParameterValueGroup parameters)
+            throws NoSuchIdentifierException, FactoryException;
+
+    /**
+     * Creates an affine transform from a matrix.
+     * If the transform's input dimension is {@code M}, and output dimension
+     * is {@code N}, then the matrix will have size {@code [N+1][M+1]}.
+     * The +1 in the matrix dimensions allows the matrix to do a shift, as well as
+     * a rotation. The {@code [M][j]} element of the matrix will be the j'th
+     * ordinate of the moved origin. The {@code [i][N]} element of the matrix
+     * will be 0 for <var>i</var> less than {@code M}, and 1 for <var>i</var>
+     * equals {@code M}.
+     *
+     * @param matrix The matrix used to define the affine transform.
+     * @return The affine transform.
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createAffineTransform", obligation=MANDATORY, specification=OGC_01009)
+    MathTransform createAffineTransform(Matrix matrix) throws FactoryException;
+
+    /**
+     * Creates a transform by concatenating two existing transforms.
+     * A concatenated transform acts in the same way as applying two
+     * transforms, one after the other.
+     *
+     * The dimension of the output space of the first transform must match
+     * the dimension of the input space in the second transform.
+     * If you wish to concatenate more than two transforms, then you can
+     * repeatedly use this method.
+     *
+     * @param  transform1 The first transform to apply to points.
+     * @param  transform2 The second transform to apply to points.
+     * @return The concatenated transform.
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createConcatenatedTransform", obligation=MANDATORY, specification=OGC_01009)
+    MathTransform createConcatenatedTransform(MathTransform transform1,
+                                              MathTransform transform2) throws FactoryException;
+
+    /**
+     * Creates a transform which passes through a subset of ordinates to another transform.
+     * This allows transforms to operate on a subset of ordinates. For example giving
+     * (<var>latitude</var>, <var>longitude</var>, <var>height</var>) coordinates, a pass
+     * through transform can convert the height values from meters to feet without affecting
+     * the (<var>latitude</var>, <var>longitude</var>) values.
+     *
+     * @param  firstAffectedOrdinate The lowest index of the affected ordinates.
+     * @param  subTransform Transform to use for affected ordinates.
+     * @param  numTrailingOrdinates Number of trailing ordinates to pass through.
+     *         Affected ordinates will range from {@code firstAffectedOrdinate}
+     *         inclusive to {@code dimTarget-numTrailingOrdinates} exclusive.
+     * @return A pass through transform with the following dimensions:<br>
+     *         <pre>
+     * Source: firstAffectedOrdinate + subTransform.getDimSource() + numTrailingOrdinates
+     * Target: firstAffectedOrdinate + subTransform.getDimTarget() + numTrailingOrdinates</pre>
+     * @throws FactoryException if the object creation failed.
+     */
+    @UML(identifier="createPassThroughTransform", obligation=MANDATORY, specification=OGC_01009)
+    MathTransform createPassThroughTransform(int firstAffectedOrdinate,
+                                             MathTransform subTransform,
+                                             int numTrailingOrdinates) throws FactoryException;
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Matrix.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Matrix.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Matrix.java	(revision 28000)
@@ -0,0 +1,98 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.util.Cloneable;
+import org.opengis.annotation.UML;
+import org.opengis.annotation.Extension;
+
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A two dimensional array of numbers. Row and column numbering begins with zero. The API for
+ * this interface matches closely the API in various {@linkplain javax.vecmath.GMatrix matrix}
+ * implementations available in <A HREF="http://java.sun.com/products/java-media/3D/">Java3D</A>,
+ * which should enable straightforward implementations. Java3D provides matrix for the general
+ * case and optimized versions for 3&times;3 and 4&times;4 cases, which are quite common in a
+ * transformation package.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/Matrix.java $
+ * @version <A HREF="http://www.opengis.org/docs/01-009.pdf">Implementation specification 1.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see javax.vecmath.Matrix3d
+ * @see javax.vecmath.Matrix4d
+ * @see javax.vecmath.GMatrix
+ * @see java.awt.geom.AffineTransform
+ * @see javax.media.jai.PerspectiveTransform
+ * @see javax.media.j3d.Transform3D
+ * @see <A HREF="http://math.nist.gov/javanumerics/jama/">Jama matrix</A>
+ * @see <A HREF="http://jcp.org/jsr/detail/83.jsp">JSR-83 Multiarray package</A>
+ */
+@UML(identifier="PT_Matrix", specification=OGC_01009)
+public interface Matrix extends Cloneable {
+    /**
+     * Returns the number of rows in this matrix.
+     *
+     * @return The number of rows in this matrix.
+     */
+    @Extension
+    int getNumRow();
+    // Same signature than GMatrix, for straightforward implementation.
+
+    /**
+     * Returns the number of columns in this matrix.
+     *
+     * @return The number of columns in this matrix.
+     */
+    @Extension
+    int getNumCol();
+    // Same signature than GMatrix, for straightforward implementation.
+
+    /**
+     * Retrieves the value at the specified row and column of this matrix.
+     *
+     * @param row    The row number to be retrieved (zero indexed).
+     * @param column The column number to be retrieved (zero indexed).
+     * @return The value at the indexed element.
+     */
+    @Extension
+    double getElement(int row, int column);
+    // Same signature than GMatrix, for straightforward implementation.
+
+    /**
+     * Modifies the value at the specified row and column of this matrix.
+     *
+     * @param row    The row number to be retrieved (zero indexed).
+     * @param column The column number to be retrieved (zero indexed).
+     * @param value  The new matrix element value.
+     */
+    @Extension
+    void setElement(int row, int column, double value);
+    // Same signature than GMatrix, for straightforward implementation.
+
+    /**
+     * Returns {@code true} if this matrix is an identity matrix.
+     *
+     * @return {@code true} if this matrix is an identity matrix.
+     */
+    @Extension
+    boolean isIdentity();
+
+    /**
+     * Returns a clone of this matrix.
+     *
+     * @return A clone of this matrix.
+     */
+    Matrix clone();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/NoninvertibleTransformException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/NoninvertibleTransformException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/NoninvertibleTransformException.java	(revision 28000)
@@ -0,0 +1,59 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+
+/**
+ * Thrown when {@link MathTransform#inverse} is
+ * invoked but the transform can't be inverted.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.operation.CoordinateOperationFactory
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/NoninvertibleTransformException.java $
+ */
+public class NoninvertibleTransformException extends TransformException {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = 9184806660368158575L;
+
+    /**
+     * Construct an exception with no detail message.
+     */
+    public NoninvertibleTransformException() {
+    }
+
+    /**
+     * Construct an exception with the specified detail message.
+     *
+     * @param  message The detail message. The detail message is saved
+     *         for later retrieval by the {@link #getMessage()} method.
+     */
+    public NoninvertibleTransformException(String message) {
+        super(message);
+    }
+
+    /**
+     * Construct an exception with the specified detail message and cause. The cause
+     * is typically an other {@link java.lang.geom.NoninvertibleTransformException}
+     * emitted by Java2D.
+     *
+     * @param  message The detail message. The detail message is saved
+     *         for later retrieval by the {@link #getMessage()} method.
+     * @param  cause The cause for this exception. The cause is saved
+     *         for later retrieval by the {@link #getCause()} method.
+     */
+    public NoninvertibleTransformException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Operation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Operation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Operation.java	(revision 28000)
@@ -0,0 +1,51 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A parameterized mathematical operation on coordinates that transforms or converts
+ * coordinates to another coordinate reference system. This coordinate operation thus
+ * uses an operation method, usually with associated parameter values.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/Operation.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see OperationMethod
+ */
+@UML(identifier="CC_Operation", specification=ISO_19111)
+public interface Operation extends SingleOperation {
+    /**
+     * Returns the operation method.
+     *
+     * @return The operation method.
+     */
+    @UML(identifier="usesMethod", obligation=MANDATORY, specification=ISO_19111)
+    OperationMethod getMethod();
+
+    /**
+     * Returns the parameter values.
+     *
+     * @return The parameter values.
+     *
+     * @rename Added "{@code Parameter}" prefix for more consistency with the return type.
+     */
+    @UML(identifier="usesValue", obligation=MANDATORY, specification=ISO_19111)
+    ParameterValueGroup getParameterValues();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/OperationMethod.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/OperationMethod.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/OperationMethod.java	(revision 28000)
@@ -0,0 +1,77 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.util.InternationalString;
+import org.opengis.annotation.UML;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Definition of an algorithm used to perform a coordinate operation. Most operation
+ * methods use a number of operation parameters, although some coordinate conversions
+ * use none. Each coordinate operation using the method assigns values to these parameters.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/OperationMethod.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see Operation
+ */
+@UML(identifier="CC_OperationMethod", specification=ISO_19111)
+public interface OperationMethod extends IdentifiedObject {
+    /**
+     * Key for the <code>{@value}</code> property.
+     * This is used for setting the value to be returned by {@link #getFormula}.
+     *
+     * @see #getFormula
+     */
+    String FORMULA_KEY = "formula";
+
+    /**
+     * Formula(s) or procedure used by this operation method. This may be a reference to a
+     * publication. Note that the operation method may not be analytic, in which case this
+     * attribute references or contains the procedure, not an analytic formula.
+     *
+     * @return The formula used by this method.
+     */
+    @UML(identifier="formula", obligation=MANDATORY, specification=ISO_19111)
+    InternationalString getFormula();
+
+    /**
+     * Number of dimensions in the source CRS of this operation method.
+     *
+     * @return The dimension of source CRS.
+     */
+    @UML(identifier="sourceDimensions", obligation=MANDATORY, specification=ISO_19111)
+    int getSourceDimensions();
+
+    /**
+     * Number of dimensions in the target CRS of this operation method.
+     *
+     * @return The dimension of target CRS.
+     */
+    @UML(identifier="targetDimensions", obligation=MANDATORY, specification=ISO_19111)
+    int getTargetDimensions();
+
+    /**
+     * The set of parameters.
+     *
+     * @return The parameters, or an empty group if none.
+     */
+    @UML(identifier="usesParameter", obligation=MANDATORY, specification=ISO_19111)
+    ParameterDescriptorGroup getParameters();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/OperationNotFoundException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/OperationNotFoundException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/OperationNotFoundException.java	(revision 28000)
@@ -0,0 +1,57 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+
+/**
+ * Thrown when a {@linkplain CoordinateOperation coordinate operation} is not found.
+ * It may be because there is no known path between source and target
+ * {@linkplain CoordinateReferenceSystem coordinate reference systems},
+ * or because the requested operation is not available in the environment.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/OperationNotFoundException.java $
+ */
+public class OperationNotFoundException extends FactoryException {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -382625493416204214L;
+
+    /**
+     * Construct an exception with no detail message.
+     */
+    public OperationNotFoundException() {
+    }
+
+    /**
+     * Construct an exception with the specified detail message.
+     *
+     * @param message The details message.
+     */
+    public OperationNotFoundException(final String message) {
+        super(message);
+    }
+
+    /**
+     * Construct an exception with the specified detail message and cause.
+     *
+     * @param message The details message.
+     * @param cause The cause for this exception.
+     */
+    public OperationNotFoundException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/PassThroughOperation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/PassThroughOperation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/PassThroughOperation.java	(revision 28000)
@@ -0,0 +1,29 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import static org.opengis.annotation.Specification.ISO_19111;
+
+import org.opengis.annotation.UML;
+
+
+/**
+ * A pass-through operation specifies that a subset of a coordinate tuple is subject to a specific
+ * coordinate operation.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/PassThroughOperation.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CC_PassThroughOperation", specification=ISO_19111)
+public interface PassThroughOperation extends SingleOperation {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/PlanarProjection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/PlanarProjection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/PlanarProjection.java	(revision 28000)
@@ -0,0 +1,31 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.annotation.Extension;
+
+
+/**
+ * Base interface for for azimuthal (or planar) map projections.
+ *
+ * <p>&nbsp;</p>
+ * <p align="center"><img src="../doc-files/PlanarProjection.png"></p>
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.crs.ProjectedCRS
+ * @see <A HREF="http://mathworld.wolfram.com/AzimuthalProjection.html">Azimuthal projection on MathWorld</A>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/PlanarProjection.java $
+ */
+@Extension
+public interface PlanarProjection extends Projection {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Projection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Projection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Projection.java	(revision 28000)
@@ -0,0 +1,48 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.annotation.Extension;
+
+
+/**
+ * A {@linkplain org.opengis.referencing.operation.Conversion conversion} transforming
+ * (<var>longitude</var>,<var>latitude</var>) coordinates to cartesian coordinates
+ * (<var>x</var>,<var>y</var>). Although some map projections can be represented as a
+ * geometric process, in general a map projection is a set of formulae that converts geodetic
+ * latitude and longitude to plane (map) coordinates. Height plays no role in this process,
+ * which is entirely two-dimensional. The same map projection can be applied to many
+ * {@linkplain org.opengis.referencing.crs.GeographicCRS geographic CRSs}, resulting in many
+ * {@linkplain org.opengis.referencing.crs.ProjectedCRS projected CRSs} each of which is related
+ * to the same {@linkplain org.opengis.referencing.datum.GeodeticDatum geodetic datum} as the
+ * geographic CRS on which it was based.
+ * <P>
+ * An unofficial list of projections and their parameters can
+ * be found <A HREF="http://www.remotesensing.org/geotiff/proj_list/">there</A>.
+ * Most projections expect the following parameters:
+ *  <code>"semi_major"</code> (mandatory),
+ *  <code>"semi_minor"</code> (mandatory),
+ *  <code>"central_meridian"</code> (default to 0),
+ *  <code>"latitude_of_origin"</code> (default to 0),
+ *  <code>"scale_factor"</code> (default to 1),
+ *  <code>"false_easting"</code> (default to 0) and
+ *  <code>"false_northing"</code> (default to 0).
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see org.opengis.referencing.crs.ProjectedCRS
+ * @see <A HREF="http://mathworld.wolfram.com/MapProjection.html">Map projections on MathWorld</A>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/Projection.java $
+ */
+@Extension
+public interface Projection extends Conversion {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/SingleOperation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/SingleOperation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/SingleOperation.java	(revision 28000)
@@ -0,0 +1,27 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A single (not {@linkplain ConcatenatedOperation concatenated}) coordinate operation.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/SingleOperation.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ */
+@UML(identifier="CC_SingleOperation", specification=ISO_19111)
+public interface SingleOperation extends CoordinateOperation {
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/TransformException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/TransformException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/TransformException.java	(revision 28000)
@@ -0,0 +1,63 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.geometry.DirectPosition;  // For javadoc
+
+
+/**
+ * Common superclass for a number of transformation-related exceptions.
+ * {@code TransformException} are thrown by {@link MathTransform}
+ * when a coordinate transformation can't be {@linkplain MathTransform#inverse inverted}
+ * ({@link NoninvertibleTransformException}), when the
+ * {@linkplain MathTransform#derivative derivative} can't be computed or when a coordinate
+ * can't be {@linkplain MathTransform#transform(DirectPosition,DirectPosition) transformed}.
+ * It is also thrown when {@link CoordinateOperationFactory} fails to find a path between two
+ * {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference systems}.
+ *
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/TransformException.java $
+ */
+public class TransformException extends Exception {
+    /**
+     * Serial number for interoperability with different versions.
+     */
+    private static final long serialVersionUID = -8923944544398567533L;
+
+    /**
+     * Constructs an exception with no detail message.
+     */
+    public TransformException() {
+    }
+
+    /**
+     * Constructs an exception with the specified detail message.
+     *
+     * @param  message The detail message. The detail message is saved
+     *         for later retrieval by the {@link #getMessage()} method.
+     */
+    public TransformException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs an exception with the specified detail message and cause.
+     *
+     * @param  message The detail message. The detail message is saved
+     *         for later retrieval by the {@link #getMessage()} method.
+     * @param  cause The cause for this exception. The cause is saved
+     *         for later retrieval by the {@link #getCause()} method.
+     */
+    public TransformException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Transformation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Transformation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/referencing/operation/Transformation.java	(revision 28000)
@@ -0,0 +1,60 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.referencing.operation;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.annotation.UML;
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * An operation on coordinates that usually includes a change of Datum. The parameters
+ * of a coordinate transformation are empirically derived from data containing the coordinates
+ * of a series of points in both coordinate reference systems. This computational process
+ * is usually "over-determined", allowing derivation of error (or accuracy) estimates
+ * for the transformation. Also, the stochastic nature of the parameters may result
+ * in multiple (different) versions of the same coordinate transformation.
+ *
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/referencing/operation/Transformation.java $
+ * @version <A HREF="http://portal.opengeospatial.org/files/?artifact_id=6716">Abstract specification 2.0</A>
+ * @author  Martin Desruisseaux (IRD)
+ * @since   GeoAPI 1.0
+ *
+ * @see Conversion
+ */
+@UML(identifier="CC_Transformation", specification=ISO_19111)
+public interface Transformation extends Operation {
+    /**
+     * Returns the source CRS.
+     *
+     * @return The source CRS (never {@code null}).
+     */
+    @UML(identifier="sourceCRS", obligation=MANDATORY, specification=ISO_19111)
+    CoordinateReferenceSystem getSourceCRS();
+
+    /**
+     * Returns the target CRS.
+     *
+     * @return The target CRS (never {@code null}).
+     */
+    @UML(identifier="targetCRS", obligation=MANDATORY, specification=ISO_19111)
+    CoordinateReferenceSystem getTargetCRS();
+
+    /**
+     * Version of the coordinate transformation (i.e., instantiation due to the stochastic
+     * nature of the parameters). This attribute is mandatory in a Transformation.
+     *
+     * @return The coordinate operation version.
+     */
+    @UML(identifier="operationVersion", obligation=MANDATORY, specification=ISO_19111)
+    String getOperationVersion();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/util/Cloneable.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/util/Cloneable.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/util/Cloneable.java	(revision 28000)
@@ -0,0 +1,50 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.util;
+
+
+/**
+ * Indicates that it is legal to make a field-for-field copy of instances of implementing classes.
+ * A cloneable class implements the J2SE's {@link java.lang.Cloneable} standard interface and
+ * additionnaly overrides the {@link Object#clone()} method with public access.
+ * <p>
+ * Because the {@link Object#clone()} method has protected access, containers wanting to clone
+ * theirs elements need to 1) use Java reflection (which is less efficient than standard method
+ * calls), or 2) cast every elements to a specific type like {@link java.util.Date} (which may
+ * require a large amount of "{@code if (x instanceof y)}" checks if arbitrary classes are
+ * allowed). This {@code Cloneable} interface had a third alternative: checks only for this
+ * interface instead of a list of particular cases.
+ * <p>
+ * Implementors of cloneable classes may consider implementing this interface, but this is not
+ * mandatory. A large amount of independant classes like {@link java.util.Date} will continue to
+ * ignore this interface, so no rule can be enforced anyway. However this interface may help the
+ * work of containers in some case. For example a container may checks for this interface first,
+ * and uses Java reflection as a fallback.
+ *
+ * @author Martin Desruisseaux (IRD)
+ * @since GeoAPI 1.0
+ *
+ * @see java.lang.Cloneable
+ * @see <A HREF="http://developer.java.sun.com/developer/bugParade/bugs/4098033.html">&quot;<cite>Cloneable
+ *      doesn't define <code>clone()</code></cite>&quot; on Sun's bug parade</A>
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/util/Cloneable.java $
+ */
+public interface Cloneable extends java.lang.Cloneable {
+    /**
+     * Creates and returns a copy of this object.
+     * The precise meaning of "copy" may depend on the class of the object.
+     *
+     * @return A copy of this object.
+     *
+     * @see Object#clone
+     */
+    Object clone();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/util/CodeList.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/util/CodeList.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/util/CodeList.java	(revision 28000)
@@ -0,0 +1,325 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.util;
+
+import java.io.Serializable;
+import java.io.ObjectStreamException;
+import java.io.InvalidObjectException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import org.opengis.annotation.UML;
+
+
+/**
+ * Base class for all code lists. Subclasses shall provides a {@code values()} method
+ * which returns all {@code CodeList} element in an array of the appropriate class.
+ * Code list are extensible, i.e. invoking the public constructor in any subclass will
+ * automatically add the newly created {@code CodeList} element in the array to be
+ * returned by {@code values()}.
+ *
+ * @param <E> The type of this code list.
+ *
+ * @author Martin Desruisseaux (IRD)
+ * @since GeoAPI 1.0
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/util/CodeList.java $
+ */
+public abstract class CodeList<E extends CodeList<E>> implements Comparable<E>, Serializable {
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = 5655809691319522885L;
+
+    /**
+     * The values for each code list.
+     */
+    private static final Map<Class<? extends CodeList>, Collection<? extends CodeList>> VALUES =
+            new HashMap<Class<? extends CodeList>, Collection<? extends CodeList>>();
+
+    /**
+     * The types expected in constructors.
+     */
+    @SuppressWarnings("unchecked")
+    private static final Class<String>[] CONSTRUCTOR_PARAMETERS = new Class[] {
+        String.class
+    };
+
+    /**
+     * The code value.
+     */
+    private transient final int ordinal;
+
+    /**
+     * The code name.
+     */
+    private final String name;
+
+    /**
+     * The identifier declared in the {@link UML} annotation, or an empty string if there is
+     * no such annotation or if the annotation contains an empty string.  This field will be
+     * computed only when first needed.
+     */
+    private transient String identifier;
+
+    /**
+     * Creates a new code list element and add it to the given collection. Subclasses
+     * will typically give a static reference to an {@link java.util.ArrayList} for
+     * the {@code values} argument. This list is used for {@code values()}
+     * method implementations.
+     *
+     * @param name   The code name.
+     * @param values The collection to add the element to.
+     */
+    @SuppressWarnings("unchecked")
+    protected CodeList(String name, final Collection<E> values) {
+        this.name = (name = name.trim());
+        synchronized (values) {
+            this.ordinal = values.size();
+            if (!values.add((E) this)) {
+                throw new IllegalArgumentException("Duplicated value: " + name);
+            }
+        }
+        final Class<? extends CodeList> codeType = getClass();
+        synchronized (VALUES) {
+            final Collection<? extends CodeList> previous = VALUES.put(codeType, values);
+            if (previous != null && previous != values) {
+                VALUES.put(codeType, previous); // Roll back
+                throw new IllegalArgumentException("List already exists: " + values);
+            }
+        }
+    }
+
+    /**
+     * Returns the code of the given type that matches the given name, or returns a new one if none
+     * match it. More specifically, this methods returns the first element of the given class where
+     * <code>{@linkplain #matches matches}(name)</code> returned {@code true}. If no such element is
+     * found, then a new instance is created using the constructor expecting a single {@link String}
+     * argument.
+     *
+     * @param <T> The compile-time type given as the {@code codeType} parameter.
+     * @param codeType The type of code list.
+     * @param name The name of the code to obtain.
+     * @return A code matching the given name.
+     */
+    public static <T extends CodeList> T valueOf(final Class<T> codeType, String name) {
+        if (name == null) {
+            return null;
+        }
+        name = name.trim();
+        final Collection<? extends CodeList> values;
+        synchronized (VALUES) {
+            values = VALUES.get(codeType);
+            if (values == null) {
+                if (codeType == null) {
+                    throw new IllegalArgumentException("Code type is null");
+                } else {
+                    throw new IllegalStateException("No collection of " + codeType.getSimpleName());
+                }
+            }
+        }
+        synchronized (values) {
+            for (final CodeList code : values) {
+                if (code.matches(name)) {
+                    return codeType.cast(code);
+                }
+            }
+            try {
+                final Constructor<T> constructor = codeType.getDeclaredConstructor(CONSTRUCTOR_PARAMETERS);
+                constructor.setAccessible(true);
+                return constructor.newInstance(name);
+            } catch (Exception exception) {
+                throw new IllegalArgumentException("Can't create code of type " + codeType.getSimpleName(), exception);
+            }
+        }
+    }
+
+    /**
+     * Returns the ordinal of this code constant. This is its position in its elements declaration,
+     * where the initial constant is assigned an ordinal of zero.
+     *
+     * @return The position of this code constants in elements declaration.
+     */
+    public final int ordinal() {
+        return ordinal;
+    }
+
+    /**
+     * Returns the identifier declared in the {@link UML} annotation, or {@code null} if none.
+     * The UML identifier shall be the ISO or OGC name for this code constant.
+     *
+     * @return The ISO/OGC identifier for this code constant, or {@code null} if none.
+     *
+     * @since GeoAPI 2.2
+     */
+    public String identifier() {
+        // Save the field in a local variable for protection against concurrent change (this
+        // operation is garanteed atomic according Java specification). We don't synchronize
+        // since it is not a problem if this method is executed twice in concurrent threads.
+        String identifier = this.identifier;
+        if (identifier == null) {
+            final Class<? extends CodeList> codeType = getClass();
+            Field field;
+            try {
+                field = codeType.getField(name);
+            } catch (NoSuchFieldException e) {
+                // There is no field for a code of this name. It may be normal, since the user
+                // may have created a custom CodeList without declaring it as a constant.
+                field = null;
+            }
+            if (field != null && Modifier.isStatic(field.getModifiers())) {
+                final Object value;
+                try {
+                    value = field.get(null);
+                } catch (IllegalAccessException e) {
+                    // Should never happen since getField(String) returns only public fields.
+                    throw new AssertionError(e);
+                }
+                if (equals(value)) {
+                    final UML annotation = field.getAnnotation(UML.class);
+                    if (annotation != null) {
+                        identifier = annotation.identifier();
+                    }
+                }
+            }
+            if (identifier == null) {
+                identifier = "";
+            }
+            this.identifier = identifier;
+        }
+        return identifier.length() != 0 ? identifier : null;
+    }
+
+    /**
+     * Returns the name of this code list constant.
+     *
+     * @return The name of this code constant.
+     */
+    public final String name() {
+        return name;
+    }
+
+    /**
+     * Returns {@code true} if the given name matches the {@linkplain #name name},
+     * {@linkplain #identifier identifier} or any other identification string of
+     * this code list element. The comparison is case-insensitive.
+     *
+     * @param name The name to check.
+     * @return {@code true} if the given name matches the code name or identifier.
+     *
+     * @since GeoAPI 2.2
+     */
+    public boolean matches(String name) {
+        if (name == null) {
+            return false;
+        }
+        if (name.equalsIgnoreCase(this.name)) {
+            return true;
+        }
+        final String identifier = identifier();
+        return (identifier != null) && name.equalsIgnoreCase(identifier);
+    }
+
+    /**
+     * Returns the list of codes of the same kind than this code.
+     *
+     * @return The codes of the same kind than this code.
+     */
+    public abstract E[] family();
+
+    /**
+     * Compares this code with the specified object for order. Returns a
+     * negative integer, zero, or a positive integer as this object is less
+     * than, equal to, or greater than the specified object.
+     * <p>
+     * Code list constants are only comparable to other code list constants of the
+     * same type.  The natural order implemented by this method is the order in which
+     * the constants are declared.
+     *
+     * @param other The code constant to compare with this code.
+     * @return -1 if the given code is less than this code, +1 if greater or 0 if equal.
+     */
+    public final int compareTo(final E other) {
+        final Class<? extends CodeList> ct =  this.getClass();
+        final Class<? extends CodeList> co = other.getClass();
+        if (!ct.equals(co)) {
+            throw new ClassCastException("Can't compare " + ct.getSimpleName() + " to " + co.getSimpleName());
+        }
+        return ordinal - ((CodeList) other).ordinal;
+    }
+
+    /**
+     * Compares the specified object with this code list for equality. This method compares only
+     * {@linkplain #ordinal ordinal} values for consistency with the {@link #compareTo} method.
+     * Ordinal values are unique for each code list element of the same class.
+     *
+     * @param object The object to compare with this code.
+     * @return {@code true} if the given object is equals to this code.
+     *
+     * @since GeoAPI 2.2
+     */
+    @Override
+    public final boolean equals(final Object object) {
+        if (object != null && object.getClass().equals(getClass())) {
+            return ordinal == ((CodeList) object).ordinal;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a string representation of this code list.
+     */
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + '[' + name + ']';
+    }
+
+    /**
+     * Resolves the code list to an unique instance after deserialization. The instance is resolved
+     * using its {@linkplain #name() name} only (not its {@linkplain #ordinal() ordinal}).
+     *
+     * @return This code list as an unique instance.
+     * @throws ObjectStreamException if the deserialization failed.
+     */
+    protected Object readResolve() throws ObjectStreamException {
+        final Class<? extends CodeList> codeType = getClass();
+        final Collection<? extends CodeList> values;
+        synchronized (VALUES) {
+            values = VALUES.get(codeType);
+        }
+        if (values != null) {
+            synchronized (values) {
+                for (final CodeList code : values) {
+                    if (!codeType.isInstance(code)) {
+                        // Paranoiac check - should never happen unless the subclass
+                        // modifies itself the collection given to the constructor,
+                        // in which case we will not touch it.
+                        return this;
+                    }
+                    if (code.matches(name)) {
+                        return code;
+                    }
+                }
+                // We have verified with codeType.isInstance(code) that every elements are
+                // of the appropriate class. This is the best we can do for type safety.
+                @SuppressWarnings("unchecked")
+                final Collection<CodeList> unsafe = (Collection) values;
+                if (!unsafe.add(this)) {
+                    // Paranoiac check - should never happen.
+                    throw new InvalidObjectException(name);
+                }
+            }
+        }
+        return this;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/util/GenericName.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/util/GenericName.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/util/GenericName.java	(revision 28000)
@@ -0,0 +1,310 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.util;
+
+import java.util.List;
+import org.opengis.annotation.UML;
+import org.opengis.annotation.Extension;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * A sequence of identifiers rooted within the context of a {@linkplain NameSpace namespace}.
+ * This interface is similar in purpose to {@link javax.naming.Name} from the <cite>Java Naming
+ * and Directory Interface</cite>. All generic names:
+ * <p>
+ * <ul>
+ *   <li>carry an association with their {@linkplain #scope scope} in which they are
+ *       considered local;</li>
+ *   <li>have the ability to provide a {@linkplain #getParsedNames parsed} version of
+ *       themselves.</li>
+ * </ul>
+ * <p>
+ * Names are <em>immutables</em>. They may be {@linkplain #toFullyQualifiedName fully qualified}
+ * like {@code "org.opengis.util.Record"}, or they may be relative to a {@linkplain #scope scope}
+ * like {@code "util.Record"} in the {@code "org.opengis"} scope. The illustration below shows all
+ * possible constructions for {@code "org.opengis.util.Record"}.
+ *
+ * <blockquote><table border="1" cellpadding="15"><tr><td><table border="0" cellspacing="0">
+ *   <tr>
+ *     <th align="right">org</th>
+ *     <th>.</th><th>opengis</th>
+ *     <th>.</th><th>util</th>
+ *     <th>.</th><th>Record</th>
+ *     <th width="50"></th>
+ *     <th>{@link #scope}</th>
+ *     <th>{@link #getParsedNames}</th>
+ *   </tr>
+ *
+ *   <tr align="center">
+ *     <td bgcolor="palegoldenrod" colspan="1"><font size="-1">{@linkplain #head head}</font></td><td></td>
+ *     <td bgcolor="palegoldenrod" colspan="5"><font size="-1">{@linkplain ScopedName#tail tail}</font></td>
+ *     <td rowspan="3"></td>
+ *     <td rowspan="3" bgcolor="beige" align="left">{@linkplain NameSpace#isGlobal global}</td>
+ *     <td rowspan="3" bgcolor="beige" align="right">{@literal {"org", "opengis", "util", "Record"}}</td>
+ *   </tr>
+ *   <tr align="center">
+ *     <td bgcolor="wheat" colspan="5"><font size="-1">{@linkplain ScopedName#path path}</font></td><td></td>
+ *     <td bgcolor="wheat" colspan="1"><font size="-1">{@linkplain #tip tip}</font></td>
+ *   </tr>
+ *   <tr align="center">
+ *     <td bgcolor="burlywood" colspan="7">{@linkplain ScopedName}</td>
+ *   </tr>
+ *
+ *   <tr><td colspan="7" height="3"></td></tr>
+ *   <tr align="center">
+ *     <td bgcolor="palegoldenrod" colspan="1" rowspan="3"><font size="-1">{@linkplain #scope scope}</font></td><td rowspan="3"></td>
+ *     <td bgcolor="palegoldenrod" colspan="1"><font size="-1">head</font></td><td></td>
+ *     <td bgcolor="palegoldenrod" colspan="3"><font size="-1">tail</font></td>
+ *     <td rowspan="3"></td>
+ *     <td rowspan="3" bgcolor="beige" align="left">{@literal "org"}</td>
+ *     <td rowspan="3" bgcolor="beige" align="right">{@literal {"opengis", "util", "Record"}}</td>
+ *   </tr>
+ *   <tr align="center">
+ *     <td bgcolor="wheat" colspan="3"><font size="-1">path</font></td><td></td>
+ *     <td bgcolor="wheat" colspan="1"><font size="-1">tip</font></td>
+ *   </tr>
+ *   <tr align="center">
+ *     <td bgcolor="burlywood" colspan="5">ScopedName</td>
+ *   </tr>
+ *
+ *   <tr><td colspan="7" height="3"></td></tr>
+ *   <tr align="center">
+ *     <td bgcolor="palegoldenrod" colspan="3" rowspan="3"><font size="-1">scope</font></td><td rowspan="3"></td>
+ *     <td bgcolor="palegoldenrod" colspan="1"><font size="-1">head</font></td><td></td>
+ *     <td bgcolor="palegoldenrod" colspan="1"><font size="-1">tail</font></td>
+ *     <td rowspan="3"></td>
+ *     <td rowspan="3" bgcolor="beige" align="left">{@literal "org.opengis"}</td>
+ *     <td rowspan="3" bgcolor="beige" align="right">{@literal {"util", "Record"}}</td>
+ *   </tr>
+ *   <tr align="center">
+ *     <td bgcolor="wheat" colspan="1"><font size="-1">path</font></td><td></td>
+ *     <td bgcolor="wheat" colspan="1"><font size="-1">tip</font></td>
+ *   </tr>
+ *   <tr align="center">
+ *     <td bgcolor="burlywood" colspan="3">ScopedName</td>
+ *   </tr>
+ *
+ *   <tr><td colspan="7" height="3"></td></tr>
+ *   <tr align="center">
+ *     <td bgcolor="palegoldenrod" colspan="5" rowspan="3"><font size="-1">scope</font></td><td rowspan="3"></td>
+ *     <td bgcolor="palegoldenrod" colspan="1"><font size="-1">head</font></td>
+ *     <td rowspan="3"></td>
+ *     <td rowspan="3" bgcolor="beige" align="left">{@literal "org.opengis.util"}</td>
+ *     <td rowspan="3" bgcolor="beige" align="right">{@literal {"Record"}}</td>
+ *   </tr>
+ *   <tr align="center">
+ *     <td bgcolor="wheat" colspan="1"><font size="-1">tip</font></td>
+ *   </tr>
+ *   <tr align="center">
+ *     <td bgcolor="burlywood" colspan="1">{@linkplain LocalName}</td>
+ *   </tr>
+ * </table></td></tr></table></blockquote>
+ * <p>
+ * The {@linkplain Comparable natural ordering} for generic names is implementation dependent.
+ * A recommended practice is to {@linkplain String#compareTo compare lexicographically} each
+ * element in the {@linkplain #getParsedNames list of parsed names}. Specific attributes of
+ * the name, such as how it treats case, may affect the ordering. In general, two names of
+ * different classes may not be compared.
+ *
+ * @author Martin Desruisseaux (IRD)
+ * @author Bryce Nordgren (USDA)
+ * @since GeoAPI 1.0
+ *
+ * @see javax.naming.Name
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/util/GenericName.java $
+ */
+@UML(identifier="GenericName", specification=ISO_19103)
+public interface GenericName extends Comparable<GenericName> {
+    /**
+     * Returns the scope (name space) in which this name is local. The scope is set on creation
+     * and is not modifiable. The scope of a name determines where a name starts.
+     * <p>
+     * <b>Example</b>:
+     * For a {@linkplain #toFullyQualifiedName fully qualified name} (a name having a
+     * {@linkplain NameSpace#isGlobal global namespace}) {@code "org.opengis.util.Record"},
+     * if this instance is the name {@code "util.Record"}, then the scope of this instance
+     * has the {@linkplain NameSpace#name name} {@code "org.opengis"}.
+     *
+     * @return The scope of this name.
+     *
+     * @since GeoAPI 2.1
+     */
+    @UML(identifier="scope", obligation=MANDATORY, specification=ISO_19103)
+    NameSpace scope();
+
+    /**
+     * Indicates the number of levels specified by this name. The depth is the {@linkplain List#size size}
+     * of the list returned by the {@link #getParsedNames} method. As such it is a derived parameter. For
+     * any {@link LocalName}, it is always one. For a {@link ScopedName} it is some number greater than or
+     * equal to 2.
+     * <p>
+     * This method is similar in purpose to {@link javax.naming.Name#size()}
+     * from the <cite>Java Naming and Directory Interface</cite>.
+     * <p>
+     * <b>Example</b>:
+     * If {@code this} name is {@code "org.opengis.util.Record"}, then this method shall returns
+     * {@code 4}. If this name is {@code "util.Record"} in scope {@code "org.opengis"}, then this
+     * method shall returns {@code 2}.
+     *
+     * @return The depth of this name.
+     *
+     * @since GeoAPI 2.1
+     */
+    @UML(identifier="depth", obligation=MANDATORY, specification=ISO_19103)
+    int depth();
+
+    /**
+     * Returns the sequence of {@linkplain LocalName local names} making this generic name.
+     * The length of this sequence is the {@linkplain #depth depth}. It does not include the
+     * {@linkplain #scope scope}.
+     * <p>
+     * This method is similar in purpose to {@link javax.naming.Name#getAll()}
+     * from the <cite>Java Naming and Directory Interface</cite>.
+     * <p>
+     * <b>Example</b>:
+     * If {@code this} name is {@code "org.opengis.util.Record"}, then this method shall returns a
+     * list containing {@code {"org", "opengis", "util", "Record"}} elements in that iteration order.
+     * If this name is {@code "util.Record"} in scope {@code "org.opengis"}, then this method shall
+     * returns a list containing only {@code {"util", "Record"}} elements.
+     *
+     * @return The local names making this generic name, without the {@linkplain #scope scope}.
+     *         Shall never be {@code null} neither {@linkplain List#isEmpty empty}.
+     */
+    @UML(identifier="parsedName", obligation=MANDATORY, specification=ISO_19103)
+    List<? extends LocalName> getParsedNames();
+
+    /**
+     * Returns the first element in the sequence of {@linkplain #getParsedNames parsed names}.
+     * For any {@link LocalName}, this is always {@code this}.
+     * <p>
+     * This method is similar in purpose to <code>{@linkplain javax.naming.Name#get(int)
+     * Name.get}(0)</code> from the <cite>Java Naming and Directory Interface</cite>.
+     * <p>
+     * <b>Example</b>:
+     * If {@code this} name is {@code "org.opengis.util.Record"} (no matter its
+     * {@linkplain #scope scope}), then this method shall returns {@code "org"}.
+     *
+     * @return The first element in the list of {@linkplain #getParsedNames parsed names}.
+     *
+     * @since GeoAPI 2.2
+     */
+    @UML(identifier="ScopedName.head", obligation=MANDATORY, specification=ISO_19103)
+    LocalName head();
+
+    /**
+     * Returns the last element in the sequence of {@linkplain #getParsedNames parsed names}.
+     * For any {@link LocalName}, this is always {@code this}.
+     * <p>
+     * This method is similar in purpose to <code>{@linkplain javax.naming.Name#get(int)
+     * Name.get}(size-1)</code> from the <cite>Java Naming and Directory Interface</cite>.
+     * <p>
+     * <b>Example</b>:
+     * If {@code this} name is {@code "org.opengis.util.Record"} (no matter its
+     * {@linkplain #scope scope}), then this method shall returns {@code "Record"}.
+     *
+     * @return The last element in the list of {@linkplain #getParsedNames parsed names}.
+     *
+     * @since GeoAPI 2.1
+     */
+    @Extension
+    LocalName tip();
+
+    /**
+     * Returns a view of this name as a fully-qualified name. The {@linkplain #scope scope}
+     * of a fully qualified name must be {@linkplain NameSpace#isGlobal global}. If the scope
+     * of this name is already global, then this method shall returns {@code this}.
+     * <p>
+     * <b>Example</b>:
+     * If {@code this} name is {@code "util.Record"} ({@linkplain #depth depth} of two) and its
+     * {@linkplain #scope scope} has the {@linkplain NameSpace#name name} {@code "org.opengis"},
+     * then the fully qualified name shall be {@code "org.opengis.util.Record"}.
+     *
+     * @return The fully-qualified name (never {@code null}).
+     *
+     * @since GeoAPI 2.1
+     */
+    @Extension
+    GenericName toFullyQualifiedName();
+
+    /**
+     * Returns this name expanded with the specified scope. One may represent this operation
+     * as a concatenation of the specified {@code scope} with {@code this}. In pseudo-code,
+     * the following relationships must hold (the last one is specific to {@link ScopedName}):
+     * <p>
+     * <ul>
+     *   <li><code>push(</code><var>foo</var><code> : LocalName).{@linkplain #head}</code>
+     *       {@linkplain #equals equals} <var>foo</var></li>
+     *
+     *   <li><code>push(</code><var>foo</var><code> : LocalName).{@linkplain ScopedName#tail tail()}</code>
+     *       {@linkplain #equals equals} <var>this</var></li>
+     *
+     *   <li><code>push(</code><var>foo</var><code> : GenericName).{@linkplain #scope}</code>
+     *       {@linkplain #equals equals} <var>foo</var>.{@link #scope()}</li>
+     *
+     *   <li><code>push(</code><var>foo</var><code> : GenericName).{@linkplain #getParsedNames}</code>
+     *       {@linkplain List#equals equals} <var>foo</var>.<code>getParsedNames().{@linkplain
+     *       List#addAll addAll}(</code><var>this</var>.<code>getParsedNames())</code></li>
+     * </ul>
+     * <p>
+     * This method is similar in purpose to <code>{@linkplain javax.naming.Name#addAll(int,javax.naming.Name)
+     * Name.addAll}(0,name)</code> from the <cite>Java Naming and Directory Interface</cite>.
+     * <p>
+     * <b>Example</b>:
+     * If {@code this} name is {@code "util.Record"} and the given {@code scope} argument is
+     * {@code "org.opengis"}, then {@code this.push(scope)} shall returns
+     * {@code "org.opengis.util.Record"}.
+     *
+     * @param scope The name to use as prefix.
+     * @return A concatenation of the given name with this name.
+     *
+     * @since GeoAPI 2.1
+     */
+    @UML(identifier="push", obligation=MANDATORY, specification=ISO_19103)
+    ScopedName push(GenericName scope);
+
+    /**
+     * Returns a string representation of this generic name. This string representation is
+     * local-independant. It contains all elements listed by {@link #getParsedNames} separated
+     * by a namespace-dependant character (usually {@code :} or {@code /}). This rule implies
+     * that the result may or may not be fully qualified. Special cases:
+     * <p>
+     * <ul>
+     *   <li><code>{@linkplain #toFullyQualifiedName}.toString()</code> is garanteed to
+     *       contains the {@linkplain #scope scope} (if any).</li>
+     *   <li><code>{@linkplain #name}.toString()</code> is garanteed to <strong>not</strong>
+     *       contains any scope.</li>
+     * </ul>
+     *
+     * @return A local-independant string representation of this name.
+     */
+/// @Override
+    @Extension
+    String toString();
+
+    /**
+     * Returns a local-dependent string representation of this generic name. This string
+     * is similar to the one returned by {@link #toString} except that each element has
+     * been localized in the {@linkplain InternationalString#toString(java.util.Locale)
+     * specified locale}. If no international string is available, then this method shall
+     * returns an implementation mapping to {@link #toString} for all locales.
+     * <p>
+     * <b>Example</b>:
+     * An implementation may want to localize the {@code "My Documents"} directory name
+     * into {@code "Mes Documents"} on French installation of Windows operating system.
+     *
+     * @return A localizable string representation of this name.
+     */
+    @Extension
+    InternationalString toInternationalString();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/util/InternationalString.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/util/InternationalString.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/util/InternationalString.java	(revision 28000)
@@ -0,0 +1,60 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.util;
+
+import java.util.Locale;
+import org.opengis.annotation.Extension;
+
+
+/**
+ * A {@linkplain String string} that has been internationalized into several {@linkplain Locale locales}.
+ * This interface is used as a replacement for the {@link String} type whenever an attribute needs to be
+ * internationalization capable.
+ *
+ * <P>The {@linkplain Comparable natural ordering} is defined by the {@linkplain String#compareTo
+ * lexicographical ordering of strings} in the default locale, as returned by {@link #toString()}.
+ * This string also defines the {@linkplain CharSequence character sequence} for this object.</P>
+ *
+ * @author Martin Desruisseaux (IRD)
+ * @since GeoAPI 2.0
+ *
+ * @see javax.xml.registry.infomodel.InternationalString
+ * @see NameFactory#createInternationalString
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/util/InternationalString.java $
+ */
+@Extension
+public interface InternationalString extends CharSequence, Comparable<InternationalString> {
+    /**
+     * Returns this string in the given locale. If no string is available in the given locale,
+     * then some default locale is used. The default locale is implementation-dependent. It
+     * may or may not be the {@linkplain Locale#getDefault() system default}.
+     *
+     * @param  locale The desired locale for the string to be returned, or {@code null}
+     *         for a string in the implementation default locale.
+     * @return The string in the given locale if available, or in the default locale otherwise.
+     */
+    String toString(Locale locale);
+
+    /**
+     * Returns this string in the default locale. The default locale is implementation-dependent.
+     * It may or may not be the {@linkplain Locale#getDefault() system default}. If the default
+     * locale is the {@linkplain Locale#getDefault() system default} (a recommended practice),
+     * then invoking this method is equivalent to invoking
+     * <code>{@linkplain #toString(Locale) toString}({@linkplain Locale#getDefault})</code>.
+     *
+     * <P>All methods from {@link CharSequence} operate on this string. This string is also
+     * used as the criterion for {@linkplain Comparable natural ordering}.</P>
+     *
+     * @return The string in the default locale.
+     */
+    ///@Override    
+    String toString();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/util/LocalName.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/util/LocalName.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/util/LocalName.java	(revision 28000)
@@ -0,0 +1,73 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.util;
+
+import java.util.List;
+import java.util.Collections;
+import org.opengis.annotation.UML;
+import org.opengis.annotation.Extension;
+
+import static org.opengis.annotation.Obligation.*;
+import static org.opengis.annotation.Specification.*;
+
+
+/**
+ * Identifier within a {@linkplain NameSpace name space} for a local object. Local names are names
+ * which are directly accessible to and maintained by a {@linkplain NameSpace name space}. Names are
+ * local to one and only one name space. The name space within which they are local is indicated by
+ * the {@linkplain #scope scope}.
+ *
+ * @author Martin Desruisseaux (IRD)
+ * @author Bryce Nordgren (USDA)
+ * @since GeoAPI 2.0
+ *
+ * @see NameFactory#createLocalName
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/util/LocalName.java $
+ */
+@UML(identifier="LocalName", specification=ISO_19103)
+public interface LocalName extends GenericName {
+    /**
+     * Returns the depth, which is always 1 for a local name.
+     */
+    int depth();
+
+    /**
+     * Returns the sequence of local name. Since this object is itself a locale name,
+     * this method always returns a {@linkplain Collections#singleton singleton}
+     * containing only {@code this}.
+     */
+    @UML(identifier="parsedName", obligation=MANDATORY, specification=ISO_19103)
+    List<? extends LocalName> getParsedNames();
+
+    /**
+     * Returns {@code this} since this object is already a local name.
+     *
+     * @since GeoAPI 2.2
+     */
+/// @Override
+    LocalName head();
+
+    /**
+     * Returns {@code this} since this object is already a local name.
+     *
+     * @since GeoAPI 2.1
+     */
+/// @Override
+    @Extension
+    LocalName tip();
+
+    /**
+     * Returns a locale-independant string representation of this local name.
+     */
+/// @Override
+    @UML(identifier="aName", obligation=MANDATORY, specification=ISO_19103)
+    String toString();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/util/NameSpace.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/util/NameSpace.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/util/NameSpace.java	(revision 28000)
@@ -0,0 +1,40 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.util;
+
+import static org.opengis.annotation.Obligation.MANDATORY;
+import static org.opengis.annotation.Specification.ISO_19103;
+
+import org.opengis.annotation.UML;
+
+
+/**
+ * A domain in which {@linkplain GenericName names} given by character strings are defined.
+ *
+ * @author Bryce Nordgren (USDA)
+ * @author Martin Desruisseaux (IRD)
+ * @since GeoAPI 2.1
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/util/NameSpace.java $
+ */
+@UML(identifier="NameSpace", specification=ISO_19103)
+public interface NameSpace {
+
+    /**
+     * Represents the identifier of this namespace. If the {@linkplain #isGlobal global} attribute is
+     * {@code true}, indicating that this is a top level {@code NameSpace}, then the name should be a
+     * {@linkplain LocalName local name}. If {@code false}, name should be a fully-qualified name where
+     * <code>name.{@linkplain GenericName#scope() scope()}.{@linkplain #isGlobal} == true</code>.
+     *
+     * @return The identifier of this namespace.
+     */
+    @UML(identifier="name", obligation=MANDATORY, specification=ISO_19103)
+    GenericName name();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/util/ProgressListener.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/util/ProgressListener.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/util/ProgressListener.java	(revision 28000)
@@ -0,0 +1,86 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.util;
+
+import org.opengis.annotation.Extension;
+
+
+/**
+ * Monitor the progress of some lengthly operation, and allows cancelation.
+ * This interface makes no assumption about the output device. Additionnaly, this
+ * interface provides support for non-fatal warning and exception reports.
+ * <p>
+ * All implementations should be multi-thread safe, even the ones that provide
+ * feedback to a user interface thread.
+ * <p>
+ * Usage example:
+ * <blockquote><pre>
+ * float scale = 100f / maximumCount;
+ * listener.started();
+ * for (int counter=0; counter&lt;maximumCount; counter++) {
+ *     if (listener.isCanceled()) {
+ *         break;
+ *     }
+ *     listener.progress(scale * counter);
+ *     try {
+ *         // Do some work...
+ *     } catch (NonFatalException e) {
+ *         listener.exceptionOccurred(e);
+ *     }
+ * }
+ * listener.complete();
+ * </pre></blockquote>
+ *
+ * @since  GeoAPI 2.1
+ * @author Martin Desruisseaux
+ * @author Jody Garnet
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/util/ProgressListener.java $
+ */
+@Extension
+public interface ProgressListener {
+
+    /**
+     * Notifies this listener that the operation begins.
+     */
+    void started();
+
+    /**
+     * Notifies this listener of progress in the lengthly operation. Progress are reported
+     * as a value between 0 and 100 inclusive. Values out of bounds will be clamped.
+     *
+     * @param percent The progress as a value between 0 and 100 inclusive.
+     *
+     * @todo Should be renamed setProgress(float) for consistency with getProgress().
+     */
+    void progress(float percent);
+
+    /**
+     * Notifies this listener that the operation has finished. The progress indicator will
+     * shows 100% or disappears, at implementor choice. If warning messages were pending,
+     * they will be displayed now.
+     */
+    void complete();
+
+    /**
+     * Returns {@code true} if this job is cancelled.
+     *
+     * @return {@code true} if this job is cancelled.
+     */
+    boolean isCanceled();
+
+    /**
+     * Reports an exception. This method may prints the stack trace to the {@linkplain System#err
+     * standard error stream} or display it in a dialog box, at implementor choice.
+     *
+     * @param exception The exception to report.
+     */
+    void exceptionOccurred(Throwable exception);
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/util/ScopedName.java
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/util/ScopedName.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/util/ScopedName.java	(revision 28000)
@@ -0,0 +1,116 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2011, Open Source Geospatial Foundation (OSGeo)
+ *    (C) 2003-2005, Open Geospatial Consortium Inc.
+ *    
+ *    All Rights Reserved. http://www.opengis.org/legal/
+ */
+package org.opengis.util;
+
+import static org.opengis.annotation.Obligation.MANDATORY;
+import static org.opengis.annotation.Specification.ISO_19103;
+
+import org.geotools.util.NameFactory;
+import org.opengis.annotation.Extension;
+import org.opengis.annotation.UML;
+
+
+/**
+ * A composite of a {@linkplain LocalName local name} (as {@linkplain #head head}) for locating
+ * another {@linkplain NameSpace name space}, and a {@linkplain GenericName generic name} (as
+ * {@linkplain #tail tail}) valid in that name space. This definition allows for iteration. The
+ * {@linkplain #tail tail} may be either a {@linkplain LocalName local name} or a scoped name.
+ * If it is a scoped name, then another another step towards a remote {@linkplain LocalName local
+ * name} is taken. In this way, a scoped name may represent an arbitrarily distant
+ * {@linkplain LocalName local name} simply by the number of times the {@link #tail()} method
+ * evaluates to a {@code ScopedName} before finally terminating on a {@link LocalName}.
+ * <p>
+ * It may be seen that {@code ScopedName} is the means by which fully-qualified names are expressed.
+ * However, a {@code ScopedName} is not, in itself, what is commonly thought of as a <cite>fully
+ * qualified</cite> name. The {@code ScopedName} type is one link in the chain, not the entire chain.
+ * A scoped name is a fully qualified name only if its {@linkplain #scope scope} is
+ * {@linkplain NameSpace#isGlobal global}.
+ * <p>
+ * <b>Example</b>:
+ * The illustration below shows the head, tail, path and name of {@code "org.opengis.util.Record"}.
+ * <blockquote><table border="1" cellpadding="15"><tr><td><table border="0">
+ *   <tr>
+ *     <th align="right">org</th>
+ *     <th>.</th><th>opengis</th>
+ *     <th>.</th><th>util</th>
+ *     <th>.</th><th>Record</th>
+ *   </tr>
+ *   <tr align="center">
+ *     <td bgcolor="palegoldenrod" colspan="1">{@linkplain #head head}</td><td></td>
+ *     <td bgcolor="palegoldenrod" colspan="5">{@linkplain #tail tail}</td>
+ *   </tr>
+ *   <tr align="center">
+ *     <td bgcolor="wheat" colspan="5">{@linkplain #path path}</td><td></td>
+ *     <td bgcolor="wheat" colspan="1">{@linkplain #tip tip}</td>
+ *   </tr>
+ * </table></td></tr></table></blockquote>
+ *
+ * @author Martin Desruisseaux (IRD)
+ * @author Bryce Nordgren (USDA)
+ * @since GeoAPI 2.0
+ *
+ * @see NameFactory#createScopedName
+ *
+ * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/library/opengis/src/main/java/org/opengis/util/ScopedName.java $
+ */
+@UML(identifier="ScopedName", specification=ISO_19103)
+public interface ScopedName extends GenericName {
+    /**
+     * Returns the first element in the sequence of {@linkplain #getParsedNames parsed names}.
+     * The head element must exists in the same {@linkplain NameSpace name space} than this
+     * scoped name. In other words, the following relationship must holds:
+     * <p>
+     * <ul>
+     *   <li><code>head().scope() {@linkplain NameSpace#equals equals}
+     *       this.{@linkplain #scope scope()}</code></li>
+     * </ul>
+     * <p>
+     * This method is similar in purpose to <code>{@linkplain javax.naming.Name#get Name.get}(0)</code>
+     * from the <cite>Java Naming and Directory Interface</cite>.
+     * <p>
+     * <b>Example</b>:
+     * If {@code this} name is {@code "org.opengis.util.Record"}, then this method
+     * shall returns {@code "org"}.
+     *
+     * @return The first element in the list of {@linkplain #getParsedNames parsed names}.
+     *
+     * @since GeoAPI 2.2
+     */
+/// @Override
+    @UML(identifier="head", obligation=MANDATORY, specification=ISO_19103)
+    LocalName head();
+
+    /**
+     * Returns the last element in the sequence of {@linkplain #getParsedNames parsed names}.
+     * <p>
+     * This method is similar in purpose to <code>{@linkplain javax.naming.Name#get(int)
+     * Name.get}(size-1)</code> from the <cite>Java Naming and Directory Interface</cite>.
+     *
+     * @return The last element in the list of {@linkplain #getParsedNames parsed names}.
+     *
+     * @since GeoAPI 2.1
+     */
+/// @Override
+    @Extension
+    LocalName tip();
+
+    /**
+     * Returns a locale-independent string representation of this scoped name.
+     * This method encapsulates the domain logic which formats the {@linkplain #getParsedNames
+     * parsed names} into a legal string representation of the name. There will be variants on
+     * this theme. XML aficionados may require URIs. For Java classes, a dotted notation is more
+     * appropriate, for C/C++, a double-colon, for directories, a forward or reverse slash,
+     * and for {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem CRS}, it
+     * will depend on the mode of expression: URN or {@code Authority:Identifier} notation.
+     */
+/// @Override
+    @UML(identifier="scopedName", obligation=MANDATORY, specification=ISO_19103)
+    String toString();
+}
Index: /applications/editors/josm/plugins/opendata/includes/org/opengis/util/package.html
===================================================================
--- /applications/editors/josm/plugins/opendata/includes/org/opengis/util/package.html	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/includes/org/opengis/util/package.html	(revision 28000)
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>package org.opengis.util</TITLE>
+  </HEAD>
+  <BODY>
+  A set of base types from ISO 19103 which can not be mapped directly from Java, plus utilities.
+
+  <h3>Names and Namespaces</h3>
+  <p align="justify">The job of a "name" in the context of ISO 19103 is to associate that name
+  with an {@link java.lang.Object}.  Examples given are <cite>objects</cite>: which form namespaces
+  for their attributes, and <cite>Schema</cite>: which form namespaces for their components.
+  A straightforward and natural use of the namespace structure defined in 19103 is the translation
+  of given names into specific storage formats.  XML has different naming rules than shapefiles,
+  and both are different than NetCDF.  This common framework can easily be harnessed to impose
+  constraints specific to a particular application without requiring that a separate implementation
+  of namespaces be provided for each format.</p>
+
+  <h3>Records and Schemas</h3>
+  <p align="justify">Records and Schemas are similar to a {@code struct} in C/C++, a table in SQL,
+  a {@code RECORD} in Pascal, or an attribute-only class in Java if it were stripped of all notions
+  of inheritance.  They are organized into named collections called Schemas. Both records and schemas
+  behave as dictionaries for their members and are similar to "packages" in Java.</p>
+  </BODY>
+</HTML>
Index: /applications/editors/josm/plugins/opendata/licenses/JDOM_LICENSE.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/licenses/JDOM_LICENSE.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/licenses/JDOM_LICENSE.txt	(revision 28000)
@@ -0,0 +1,56 @@
+/*-- 
+
+ $Id: LICENSE.txt,v 1.11 2004/02/06 09:32:57 jhunter Exp $
+
+ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows 
+    these conditions in the documentation and/or other materials 
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+ 
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+ 
+ In addition, we request (but do not require) that you include in the 
+ end-user documentation provided with the redistribution and/or in the 
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos 
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many 
+ individuals on behalf of the JDOM Project and was originally 
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>. 
+
+ */
+
Index: /applications/editors/josm/plugins/opendata/licenses/LICENSE-2.0.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/licenses/LICENSE-2.0.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/licenses/LICENSE-2.0.txt	(revision 28000)
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
Index: /applications/editors/josm/plugins/opendata/licenses/gpl-2.0.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/licenses/gpl-2.0.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/licenses/gpl-2.0.txt	(revision 28000)
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
Index: /applications/editors/josm/plugins/opendata/licenses/gpl-3.0.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/licenses/gpl-3.0.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/licenses/gpl-3.0.txt	(revision 28000)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: /applications/editors/josm/plugins/opendata/licenses/lgpl-2.1.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/licenses/lgpl-2.1.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/licenses/lgpl-2.1.txt	(revision 28000)
@@ -0,0 +1,511 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
Index: /applications/editors/josm/plugins/opendata/modules/00_module_dir_template/README
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/00_module_dir_template/README	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/00_module_dir_template/README	(revision 28000)
@@ -0,0 +1,11 @@
+README 
+======
+
+Readme for XXXXXXX module of JOSM Open Data plugin
+
+    * Author: XXXXXXX
+    * License: GPL v3 (see gpl-3.0.txt)
+
+-------------------------------- DOCUMENTATION --------------------------------
+
+See http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/XXXXXXX
Index: /applications/editors/josm/plugins/opendata/modules/00_module_dir_template/build.xml
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/00_module_dir_template/build.xml	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/00_module_dir_template/build.xml	(revision 28000)
@@ -0,0 +1,231 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!--
+** This is a template build file for a module of the JOSM opendata plugin.
+**
+** Usage
+** =====
+** To build it run
+**
+**    > ant dist
+**
+** To install the generated module locally (in you default opendata modules directory) run
+**
+**    > ant install
+**
+** The generated module jar is not automatically available in JOSMs opendata plugin configuration
+** dialog. You have to check it in first.
+**
+** Use the ant target 'publish' to check in the module and make it available to other
+** JOSM users:
+**    set the property commit.message
+** and run
+**    > ant publish
+**
+-->
+<project name="your_country.your_module" default="dist" basedir=".">
+    <!-- enter the SVN commit message -->
+    <property name="commit.message" value="Commit message"/>
+    <!-- should not be necessary to change the following properties -->
+    <property name="josm" location="../../../../core/dist/josm-custom.jar"/>
+    <property name="plugin.dist.dir" value="../../../../dist"/>
+    <property name="opendata" location="${plugin.dist.dir}/opendata.jar"/>
+    <property name="module.build.dir" value="build"/>
+    <property name="module.src.dir" value="src"/>
+    <property name="ant.build.javac.source" value="1.6"/>
+    <property name="ant.build.javac.target" value="1.6"/>
+    <!-- this is the directory where the module jar is copied to -->
+    <property name="module.dist.dir" value="../../dist"/>
+    <property name="module.jar" value="${module.dist.dir}/${ant.project.name}.jar"/>
+	<!-- conditions -->
+    <condition property="resources.exist">
+        <available file="resources" type="dir" />
+    </condition>
+    <condition property="images.exist">
+        <available file="images" type="dir" />
+    </condition>
+    <!--
+    **********************************************************
+    ** init - initializes the build
+    **********************************************************
+    -->
+    <target name="init">
+        <mkdir dir="${module.build.dir}"/>
+        <mkdir dir="${module.build.dir}/META-INF"/>
+    </target>
+    <!--
+    **********************************************************
+    ** compile - compiles the source tree
+    **********************************************************
+    -->
+    <target name="compile" depends="init">
+        <echo message="compiling sources for ${module.jar} ... "/>
+        <javac srcdir="${module.src.dir}" debug="true" destdir="${module.build.dir}" includeAntRuntime="false">
+            <classpath>
+                <pathelement location="${josm}"/>
+                <pathelement location="${opendata}"/>
+            </classpath>
+            <compilerarg value="-Xlint:deprecation"/>
+            <compilerarg value="-Xlint:unchecked"/>
+        </javac>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-resources - copies resources dir to build dir
+    **********************************************************
+    -->
+	<target name="copy-resources" if="resources.exist">
+        <copy todir="${module.build.dir}">
+            <fileset dir="resources" />
+        </copy>
+	</target>
+    <!--
+    **********************************************************
+    ** copy-images - copies images dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-images" if="images.exist">
+        <copy todir="${module.build.dir}/images">
+            <fileset dir="images" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** dist - creates the module jar
+    **********************************************************
+    -->
+    <target name="dist" depends="compile,revision,copy-resources, copy-images">
+        <echo message="creating ${ant.project.name}.jar ... "/>
+        <copy todir="${module.build.dir}">
+            <fileset dir=".">
+                <include name="README"/>
+                <include name="gpl-3.0.txt"/>
+            </fileset>
+        </copy>
+        <jar destfile="${module.jar}" basedir="${module.build.dir}">
+            <!--
+            ************************************************
+            ** configure these properties. Most of them will
+            ** be copied to the module manifest file.
+            **
+            ************************************************
+            -->
+            <manifest>
+                <attribute name="Author" value=""/>
+                <attribute name="Module-Class" value="org.openstreetmap.josm.plugins.opendata.modules.your_country.your_module.Your_Module"/>
+                <attribute name="Module-Date" value="${version.entry.commit.date}"/>
+                <attribute name="Module-Description" value="A description for your module"/>
+                <attribute name="Module-Icon" value="images/dialogs/your_image_of_24_px.png"/>
+                <attribute name="Module-Link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/YourModule"/>
+                <attribute name="Module-Version" value="${version.entry.commit.revision}"/>
+            </manifest>
+        </jar>
+    </target>
+    <!--
+    **********************************************************
+    ** revision - extracts the current revision number for the
+    **    file build.number and stores it in the XML property
+    **    version.*
+    **********************************************************
+    -->
+    <target name="revision">
+        <exec append="false" output="REVISION" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="info"/>
+            <arg value="--xml"/>
+            <arg value="."/>
+        </exec>
+        <xmlproperty file="REVISION" prefix="version" keepRoot="false" collapseAttributes="true"/>
+        <delete file="REVISION"/>
+    </target>
+    <!--
+    **********************************************************
+    ** clean - clean up the build environment
+    **********************************************************
+    -->
+    <target name="clean">
+        <delete dir="${module.build.dir}"/>
+        <delete file="${module.jar}"/>
+    </target>
+    <!--
+    **********************************************************
+    ** install - install the module in your local JOSM installation
+    **********************************************************
+    -->
+    <target name="install" depends="dist">
+        <property environment="env"/>
+        <condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins">
+            <and>
+                <os family="windows"/>
+            </and>
+        </condition>
+        <copy file="${module.jar}" todir="${josm.plugins.dir}/opendata/modules" overwrite="yes"/>
+    </target>
+    <!--
+    ************************** Publishing the module *********************************** 
+    -->
+    <!-- commits the source tree for this module -->
+    <target name="commit-current">
+        <echo>Commiting the module source with message '${commit.message}' ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="commit"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="."/>
+        </exec>
+    </target>
+    <!-- updates (svn up) the source tree for this module -->
+    <target name="update-current">
+        <echo>Updating module source ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="."/>
+        </exec>
+        <echo>Updating ${module.jar} ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="../dist/${module.jar}"/>
+        </exec>
+    </target>
+    <!-- commits the module.jar -->
+    <target name="commit-dist">
+        <echo>
+    ***** Properties of published ${module.jar} *****
+    Commit message    : '${commit.message}'                    
+    Module-Version    : ${version.entry.commit.revision}
+    ***** / Properties of published ${module.jar} *****                    
+                        
+    Now commiting ${module.jar} ...
+    </echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="commit"/>
+            <arg value="${module.jar}"/>
+        </exec>
+    </target>
+    <!-- make sure svn is present as a command line tool -->
+    <target name="ensure-svn-present">
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false" failonerror="false" resultproperty="svn.exit.code">
+            <env key="LANG" value="C"/>
+            <arg value="--version"/>
+        </exec>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure svn is installed on your system.">
+            <!-- return code not set at all? Most likely svn isn't installed -->
+            <condition>
+                <not>
+                    <isset property="svn.exit.code"/>
+                </not>
+            </condition>
+        </fail>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure a working copy of svn is installed on your system.">
+            <!-- error code from SVN? Most likely svn is not what we are looking on this system -->
+            <condition>
+                <isfailure code="${svn.exit.code}"/>
+            </condition>
+        </fail>
+    </target>
+    <target name="publish" depends="ensure-svn-present,commit-current,update-current,clean,dist,commit-dist">
+    </target>
+</project>
Index: /applications/editors/josm/plugins/opendata/modules/00_module_dir_template/gpl-3.0.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/00_module_dir_template/gpl-3.0.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/00_module_dir_template/gpl-3.0.txt	(revision 28000)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: /applications/editors/josm/plugins/opendata/modules/be.bruxelles/README
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.bruxelles/README	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.bruxelles/README	(revision 28000)
@@ -0,0 +1,11 @@
+README 
+======
+
+Readme for Bruxelles module of JOSM Open Data plugin
+
+    * Author: Don-vip
+    * License: GPL v3 (see gpl-3.0.txt)
+
+-------------------------------- DOCUMENTATION --------------------------------
+
+See http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/Bruxelles
Index: /applications/editors/josm/plugins/opendata/modules/be.bruxelles/build.xml
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.bruxelles/build.xml	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.bruxelles/build.xml	(revision 28000)
@@ -0,0 +1,231 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!--
+** This is a template build file for a module of the JOSM opendata plugin.
+**
+** Usage
+** =====
+** To build it run
+**
+**    > ant dist
+**
+** To install the generated module locally (in you default opendata modules directory) run
+**
+**    > ant install
+**
+** The generated module jar is not automatically available in JOSMs opendata plugin configuration
+** dialog. You have to check it in first.
+**
+** Use the ant target 'publish' to check in the module and make it available to other
+** JOSM users:
+**    set the property commit.message
+** and run
+**    > ant publish
+**
+-->
+<project name="be.bruxelles" default="dist" basedir=".">
+    <!-- enter the SVN commit message -->
+    <property name="commit.message" value="Commit message"/>
+    <!-- should not be necessary to change the following properties -->
+    <property name="josm" location="../../../../core/dist/josm-custom.jar"/>
+    <property name="plugin.dist.dir" value="../../../../dist"/>
+    <property name="opendata" location="${plugin.dist.dir}/opendata.jar"/>
+    <property name="module.build.dir" value="build"/>
+    <property name="module.src.dir" value="src"/>
+    <property name="ant.build.javac.source" value="1.6"/>
+    <property name="ant.build.javac.target" value="1.6"/>
+    <!-- this is the directory where the module jar is copied to -->
+    <property name="module.dist.dir" value="../../dist"/>
+    <property name="module.jar" value="${module.dist.dir}/${ant.project.name}.jar"/>
+	<!-- conditions -->
+    <condition property="resources.exist">
+        <available file="resources" type="dir" />
+    </condition>
+    <condition property="images.exist">
+        <available file="images" type="dir" />
+    </condition>
+    <!--
+    **********************************************************
+    ** init - initializes the build
+    **********************************************************
+    -->
+    <target name="init">
+        <mkdir dir="${module.build.dir}"/>
+        <mkdir dir="${module.build.dir}/META-INF"/>
+    </target>
+    <!--
+    **********************************************************
+    ** compile - compiles the source tree
+    **********************************************************
+    -->
+    <target name="compile" depends="init">
+        <echo message="compiling sources for ${module.jar} ... "/>
+        <javac srcdir="${module.src.dir}" debug="true" destdir="${module.build.dir}" includeAntRuntime="false">
+            <classpath>
+                <pathelement location="${josm}"/>
+                <pathelement location="${opendata}"/>
+            </classpath>
+            <compilerarg value="-Xlint:deprecation"/>
+            <compilerarg value="-Xlint:unchecked"/>
+        </javac>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-resources - copies resources dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-resources" if="resources.exist">
+        <copy todir="${module.build.dir}">
+            <fileset dir="resources" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-images - copies images dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-images" if="images.exist">
+        <copy todir="${module.build.dir}/images">
+            <fileset dir="images" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** dist - creates the module jar
+    **********************************************************
+    -->
+    <target name="dist" depends="compile,revision,copy-resources, copy-images">
+        <echo message="creating ${ant.project.name}.jar ... "/>
+        <copy todir="${module.build.dir}">
+            <fileset dir=".">
+                <include name="README"/>
+                <include name="gpl-3.0.txt"/>
+            </fileset>
+        </copy>
+        <jar destfile="${module.jar}" basedir="${module.build.dir}">
+            <!--
+            ************************************************
+            ** configure these properties. Most of them will
+            ** be copied to the module manifest file.
+            **
+            ************************************************
+            -->
+            <manifest>
+                <attribute name="Author" value="Don-vip"/>
+                <attribute name="Module-Class" value="org.openstreetmap.josm.plugins.opendata.modules.be.bruxelles.BruxellesModule"/>
+                <attribute name="Module-Date" value="${version.entry.commit.date}"/>
+                <attribute name="Module-Description" value="Bruxelles"/>
+                <attribute name="Module-Icon" value="images/data.be.bruxelles_24.png"/>
+                <!--<attribute name="Module-Link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/Bruxelles"/>-->
+                <attribute name="Module-Version" value="${version.entry.commit.revision}"/>
+            </manifest>
+        </jar>
+    </target>
+    <!--
+    **********************************************************
+    ** revision - extracts the current revision number for the
+    **    file build.number and stores it in the XML property
+    **    version.*
+    **********************************************************
+    -->
+    <target name="revision">
+        <exec append="false" output="REVISION" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="info"/>
+            <arg value="--xml"/>
+            <arg value="."/>
+        </exec>
+        <xmlproperty file="REVISION" prefix="version" keepRoot="false" collapseAttributes="true"/>
+        <delete file="REVISION"/>
+    </target>
+    <!--
+    **********************************************************
+    ** clean - clean up the build environment
+    **********************************************************
+    -->
+    <target name="clean">
+        <delete dir="${module.build.dir}"/>
+        <delete file="${module.jar}"/>
+    </target>
+    <!--
+    **********************************************************
+    ** install - install the module in your local JOSM installation
+    **********************************************************
+    -->
+    <target name="install" depends="dist">
+        <property environment="env"/>
+        <condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins">
+            <and>
+                <os family="windows"/>
+            </and>
+        </condition>
+        <copy file="${module.jar}" todir="${josm.plugins.dir}/opendata/modules" overwrite="yes"/>
+    </target>
+    <!--
+    ************************** Publishing the module *********************************** 
+    -->
+    <!-- commits the source tree for this module -->
+    <target name="commit-current">
+        <echo>Commiting the module source with message '${commit.message}' ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="commit"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="."/>
+        </exec>
+    </target>
+    <!-- updates (svn up) the source tree for this module -->
+    <target name="update-current">
+        <echo>Updating module source ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="."/>
+        </exec>
+        <echo>Updating ${module.jar} ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="../dist/${module.jar}"/>
+        </exec>
+    </target>
+    <!-- commits the module.jar -->
+    <target name="commit-dist">
+        <echo>
+    ***** Properties of published ${module.jar} *****
+    Commit message    : '${commit.message}'                    
+    Module-Version    : ${version.entry.commit.revision}
+    ***** / Properties of published ${module.jar} *****                    
+                        
+    Now commiting ${module.jar} ...
+    </echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="commit"/>
+            <arg value="${module.jar}"/>
+        </exec>
+    </target>
+    <!-- make sure svn is present as a command line tool -->
+    <target name="ensure-svn-present">
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false" failonerror="false" resultproperty="svn.exit.code">
+            <env key="LANG" value="C"/>
+            <arg value="--version"/>
+        </exec>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure svn is installed on your system.">
+            <!-- return code not set at all? Most likely svn isn't installed -->
+            <condition>
+                <not>
+                    <isset property="svn.exit.code"/>
+                </not>
+            </condition>
+        </fail>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure a working copy of svn is installed on your system.">
+            <!-- error code from SVN? Most likely svn is not what we are looking on this system -->
+            <condition>
+                <isfailure code="${svn.exit.code}"/>
+            </condition>
+        </fail>
+    </target>
+    <target name="publish" depends="ensure-svn-present,commit-current,update-current,clean,dist,commit-dist">
+    </target>
+</project>
Index: /applications/editors/josm/plugins/opendata/modules/be.bruxelles/gpl-3.0.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.bruxelles/gpl-3.0.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.bruxelles/gpl-3.0.txt	(revision 28000)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: /applications/editors/josm/plugins/opendata/modules/be.bruxelles/src/org/openstreetmap/josm/plugins/opendata/modules/be/bruxelles/BruxellesConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.bruxelles/src/org/openstreetmap/josm/plugins/opendata/modules/be/bruxelles/BruxellesConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.bruxelles/src/org/openstreetmap/josm/plugins/opendata/modules/be/bruxelles/BruxellesConstants.java	(revision 28000)
@@ -0,0 +1,33 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.be.bruxelles;
+
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+
+public interface BruxellesConstants extends OdConstants {
+	
+	/**
+	 * Source
+	 */
+	public static final String SOURCE_BRUXELLES = "Ville de Bruxelles";
+	
+	/**
+	 * Portal
+	 */
+	public static final String PORTAL_EN = "http://www.brussels.be";
+	public static final String PORTAL_FR = "http://www.bruxelles.be";
+	public static final String PORTAL_NL = "http://www.brussel.be";
+}
Index: /applications/editors/josm/plugins/opendata/modules/be.bruxelles/src/org/openstreetmap/josm/plugins/opendata/modules/be/bruxelles/BruxellesModule.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.bruxelles/src/org/openstreetmap/josm/plugins/opendata/modules/be/bruxelles/BruxellesModule.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.bruxelles/src/org/openstreetmap/josm/plugins/opendata/modules/be/bruxelles/BruxellesModule.java	(revision 28000)
@@ -0,0 +1,28 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.be.bruxelles;
+
+import org.openstreetmap.josm.plugins.opendata.core.modules.AbstractModule;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleInformation;
+import org.openstreetmap.josm.plugins.opendata.modules.be.bruxelles.datasets.culture.BDHandler;
+
+public class BruxellesModule extends AbstractModule {
+
+	public BruxellesModule(ModuleInformation info) {
+		super(info);
+		handlers.add(new BDHandler());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/modules/be.bruxelles/src/org/openstreetmap/josm/plugins/opendata/modules/be/bruxelles/datasets/BruxellesDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.bruxelles/src/org/openstreetmap/josm/plugins/opendata/modules/be/bruxelles/datasets/BruxellesDataSetHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.bruxelles/src/org/openstreetmap/josm/plugins/opendata/modules/be/bruxelles/datasets/BruxellesDataSetHandler.java	(revision 28000)
@@ -0,0 +1,92 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.be.bruxelles.datasets;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Locale;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.be.BelgianDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.be.bruxelles.BruxellesConstants;
+
+public abstract class BruxellesDataSetHandler extends BelgianDataSetHandler implements BruxellesConstants {
+	
+	private Integer localPortalId;
+	
+	public BruxellesDataSetHandler() {
+		init(null, null);
+	}
+
+	public BruxellesDataSetHandler(Integer portalId) {
+		init(portalId, null);
+	}
+
+	public BruxellesDataSetHandler(Integer portalId, Projection singleProjection) {
+		init(portalId, singleProjection);
+	}
+
+	public BruxellesDataSetHandler(Integer portalId, Projection singleProjection, String relevantTag) {
+		super(relevantTag);
+		init(portalId, singleProjection);
+	}
+
+	public BruxellesDataSetHandler(Integer portalId, String relevantTag) {
+		super(relevantTag);
+		init(portalId, null);
+	}
+
+	private void init(Integer portalId, Projection singleProjection) {
+		setSingleProjection(singleProjection);
+		this.localPortalId = portalId;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getSource()
+	 */
+	@Override
+	public String getSource() {
+		return SOURCE_BRUXELLES;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getLocalPortalURL()
+	 */
+	@Override
+	public URL getLocalPortalURL() {
+		String basePortal = null;
+		String lang = Main.pref.get("language");
+		if (lang == null || lang.isEmpty()) {
+			lang = Locale.getDefault().toString();
+		}
+			
+		if (lang.startsWith("fr")) {
+			basePortal = PORTAL_FR;
+		} else if (lang.startsWith("nl")) {
+			basePortal = PORTAL_NL;
+		} else {
+			basePortal = PORTAL_EN;
+		}
+
+		try {
+			return new URL(basePortal + "/artdet.cfm?id=" + localPortalId);
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/be.bruxelles/src/org/openstreetmap/josm/plugins/opendata/modules/be/bruxelles/datasets/culture/BDHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.bruxelles/src/org/openstreetmap/josm/plugins/opendata/modules/be/bruxelles/datasets/culture/BDHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.bruxelles/src/org/openstreetmap/josm/plugins/opendata/modules/be/bruxelles/datasets/culture/BDHandler.java	(revision 28000)
@@ -0,0 +1,29 @@
+package org.openstreetmap.josm.plugins.opendata.modules.be.bruxelles.datasets.culture;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.be.bruxelles.datasets.BruxellesDataSetHandler;
+
+public class BDHandler extends BruxellesDataSetHandler {
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvFilename(filename, "textfile");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.put("tourism", "artwork");
+			replace(n, "Description", "name");
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getCsvSeparator()
+	 */
+	@Override
+	public String getCsvSeparator() {
+		return ",";
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/be.datagovbe/README
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.datagovbe/README	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.datagovbe/README	(revision 28000)
@@ -0,0 +1,11 @@
+README 
+======
+
+Readme for Data.gov.be module of JOSM Open Data plugin
+
+    * Author: Don-vip
+    * License: GPL v3 (see gpl-3.0.txt)
+
+-------------------------------- DOCUMENTATION --------------------------------
+
+See http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/Data.gov.be
Index: /applications/editors/josm/plugins/opendata/modules/be.datagovbe/build.xml
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.datagovbe/build.xml	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.datagovbe/build.xml	(revision 28000)
@@ -0,0 +1,231 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!--
+** This is a template build file for a module of the JOSM opendata plugin.
+**
+** Usage
+** =====
+** To build it run
+**
+**    > ant dist
+**
+** To install the generated module locally (in you default opendata modules directory) run
+**
+**    > ant install
+**
+** The generated module jar is not automatically available in JOSMs opendata plugin configuration
+** dialog. You have to check it in first.
+**
+** Use the ant target 'publish' to check in the module and make it available to other
+** JOSM users:
+**    set the property commit.message
+** and run
+**    > ant publish
+**
+-->
+<project name="be.datagovbe" default="dist" basedir=".">
+    <!-- enter the SVN commit message -->
+    <property name="commit.message" value="Commit message"/>
+    <!-- should not be necessary to change the following properties -->
+    <property name="josm" location="../../../../core/dist/josm-custom.jar"/>
+    <property name="plugin.dist.dir" value="../../../../dist"/>
+    <property name="opendata" location="${plugin.dist.dir}/opendata.jar"/>
+    <property name="module.build.dir" value="build"/>
+    <property name="module.src.dir" value="src"/>
+    <property name="ant.build.javac.source" value="1.6"/>
+    <property name="ant.build.javac.target" value="1.6"/>
+    <!-- this is the directory where the module jar is copied to -->
+    <property name="module.dist.dir" value="../../dist"/>
+    <property name="module.jar" value="${module.dist.dir}/${ant.project.name}.jar"/>
+	<!-- conditions -->
+    <condition property="resources.exist">
+        <available file="resources" type="dir" />
+    </condition>
+    <condition property="images.exist">
+        <available file="images" type="dir" />
+    </condition>
+    <!--
+    **********************************************************
+    ** init - initializes the build
+    **********************************************************
+    -->
+    <target name="init">
+        <mkdir dir="${module.build.dir}"/>
+        <mkdir dir="${module.build.dir}/META-INF"/>
+    </target>
+    <!--
+    **********************************************************
+    ** compile - compiles the source tree
+    **********************************************************
+    -->
+    <target name="compile" depends="init">
+        <echo message="compiling sources for ${module.jar} ... "/>
+        <javac srcdir="${module.src.dir}" debug="true" destdir="${module.build.dir}" includeAntRuntime="false">
+            <classpath>
+                <pathelement location="${josm}"/>
+                <pathelement location="${opendata}"/>
+            </classpath>
+            <compilerarg value="-Xlint:deprecation"/>
+            <compilerarg value="-Xlint:unchecked"/>
+        </javac>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-resources - copies resources dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-resources" if="resources.exist">
+        <copy todir="${module.build.dir}">
+            <fileset dir="resources" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-images - copies images dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-images" if="images.exist">
+        <copy todir="${module.build.dir}/images">
+            <fileset dir="images" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** dist - creates the module jar
+    **********************************************************
+    -->
+    <target name="dist" depends="compile,revision,copy-resources, copy-images">
+        <echo message="creating ${ant.project.name}.jar ... "/>
+        <copy todir="${module.build.dir}">
+            <fileset dir=".">
+                <include name="README"/>
+                <include name="gpl-3.0.txt"/>
+            </fileset>
+        </copy>
+        <jar destfile="${module.jar}" basedir="${module.build.dir}">
+            <!--
+            ************************************************
+            ** configure these properties. Most of them will
+            ** be copied to the module manifest file.
+            **
+            ************************************************
+            -->
+            <manifest>
+                <attribute name="Author" value="Don-vip"/>
+                <attribute name="Module-Class" value="org.openstreetmap.josm.plugins.opendata.modules.be.datagovbe.DataGovBeModule"/>
+                <attribute name="Module-Date" value="${version.entry.commit.date}"/>
+                <attribute name="Module-Description" value="Belgian Open Data initiative"/>
+                <attribute name="Module-Icon" value="images/be24.png"/>
+                <!--<attribute name="Module-Link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/Datagov.be"/>-->
+                <attribute name="Module-Version" value="${version.entry.commit.revision}"/>
+            </manifest>
+        </jar>
+    </target>
+    <!--
+    **********************************************************
+    ** revision - extracts the current revision number for the
+    **    file build.number and stores it in the XML property
+    **    version.*
+    **********************************************************
+    -->
+    <target name="revision">
+        <exec append="false" output="REVISION" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="info"/>
+            <arg value="--xml"/>
+            <arg value="."/>
+        </exec>
+        <xmlproperty file="REVISION" prefix="version" keepRoot="false" collapseAttributes="true"/>
+        <delete file="REVISION"/>
+    </target>
+    <!--
+    **********************************************************
+    ** clean - clean up the build environment
+    **********************************************************
+    -->
+    <target name="clean">
+        <delete dir="${module.build.dir}"/>
+        <delete file="${module.jar}"/>
+    </target>
+    <!--
+    **********************************************************
+    ** install - install the module in your local JOSM installation
+    **********************************************************
+    -->
+    <target name="install" depends="dist">
+        <property environment="env"/>
+        <condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins">
+            <and>
+                <os family="windows"/>
+            </and>
+        </condition>
+        <copy file="${module.jar}" todir="${josm.plugins.dir}/opendata/modules" overwrite="yes"/>
+    </target>
+    <!--
+    ************************** Publishing the module *********************************** 
+    -->
+    <!-- commits the source tree for this module -->
+    <target name="commit-current">
+        <echo>Commiting the module source with message '${commit.message}' ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="commit"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="."/>
+        </exec>
+    </target>
+    <!-- updates (svn up) the source tree for this module -->
+    <target name="update-current">
+        <echo>Updating module source ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="."/>
+        </exec>
+        <echo>Updating ${module.jar} ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="../dist/${module.jar}"/>
+        </exec>
+    </target>
+    <!-- commits the module.jar -->
+    <target name="commit-dist">
+        <echo>
+    ***** Properties of published ${module.jar} *****
+    Commit message    : '${commit.message}'                    
+    Module-Version    : ${version.entry.commit.revision}
+    ***** / Properties of published ${module.jar} *****                    
+                        
+    Now commiting ${module.jar} ...
+    </echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="commit"/>
+            <arg value="${module.jar}"/>
+        </exec>
+    </target>
+    <!-- make sure svn is present as a command line tool -->
+    <target name="ensure-svn-present">
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false" failonerror="false" resultproperty="svn.exit.code">
+            <env key="LANG" value="C"/>
+            <arg value="--version"/>
+        </exec>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure svn is installed on your system.">
+            <!-- return code not set at all? Most likely svn isn't installed -->
+            <condition>
+                <not>
+                    <isset property="svn.exit.code"/>
+                </not>
+            </condition>
+        </fail>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure a working copy of svn is installed on your system.">
+            <!-- error code from SVN? Most likely svn is not what we are looking on this system -->
+            <condition>
+                <isfailure code="${svn.exit.code}"/>
+            </condition>
+        </fail>
+    </target>
+    <target name="publish" depends="ensure-svn-present,commit-current,update-current,clean,dist,commit-dist">
+    </target>
+</project>
Index: /applications/editors/josm/plugins/opendata/modules/be.datagovbe/gpl-3.0.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.datagovbe/gpl-3.0.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.datagovbe/gpl-3.0.txt	(revision 28000)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: /applications/editors/josm/plugins/opendata/modules/be.datagovbe/src/org/openstreetmap/josm/plugins/opendata/modules/be/datagovbe/DataGovBeConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.datagovbe/src/org/openstreetmap/josm/plugins/opendata/modules/be/datagovbe/DataGovBeConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.datagovbe/src/org/openstreetmap/josm/plugins/opendata/modules/be/datagovbe/DataGovBeConstants.java	(revision 28000)
@@ -0,0 +1,26 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.be.datagovbe;
+
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+
+public interface DataGovBeConstants extends OdConstants {
+	
+	/**
+	 * Source
+	 */
+	public static final String SOURCE_DATAGOVBE = "data.gov.be";
+}
Index: /applications/editors/josm/plugins/opendata/modules/be.datagovbe/src/org/openstreetmap/josm/plugins/opendata/modules/be/datagovbe/DataGovBeModule.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.datagovbe/src/org/openstreetmap/josm/plugins/opendata/modules/be/datagovbe/DataGovBeModule.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.datagovbe/src/org/openstreetmap/josm/plugins/opendata/modules/be/datagovbe/DataGovBeModule.java	(revision 28000)
@@ -0,0 +1,28 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.be.datagovbe;
+
+import org.openstreetmap.josm.plugins.opendata.core.modules.AbstractModule;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleInformation;
+import org.openstreetmap.josm.plugins.opendata.modules.be.datagovbe.datasets.culture.ArchitecturalHeritageHandler;
+
+public class DataGovBeModule extends AbstractModule {
+
+	public DataGovBeModule(ModuleInformation info) {
+		super(info);
+		handlers.add(new ArchitecturalHeritageHandler());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/modules/be.datagovbe/src/org/openstreetmap/josm/plugins/opendata/modules/be/datagovbe/datasets/DataGovDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.datagovbe/src/org/openstreetmap/josm/plugins/opendata/modules/be/datagovbe/datasets/DataGovDataSetHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.datagovbe/src/org/openstreetmap/josm/plugins/opendata/modules/be/datagovbe/datasets/DataGovDataSetHandler.java	(revision 28000)
@@ -0,0 +1,68 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.be.datagovbe.datasets;
+
+import java.net.URL;
+
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.be.BelgianDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.be.datagovbe.DataGovBeConstants;
+
+public abstract class DataGovDataSetHandler extends BelgianDataSetHandler implements DataGovBeConstants {
+	
+	public DataGovDataSetHandler() {
+		init(null, null, null, null, null);
+	}
+
+	public DataGovDataSetHandler(String portalPathDe, String portalPathEn, String portalPathFr, String portalPathNl) {
+		init(portalPathDe, portalPathEn, portalPathFr, portalPathNl, null);
+	}
+
+	public DataGovDataSetHandler(String portalPathDe, String portalPathEn, String portalPathFr, String portalPathNl, Projection singleProjection) {
+		init(portalPathDe, portalPathEn, portalPathFr, portalPathNl, singleProjection);
+	}
+
+	public DataGovDataSetHandler(String portalPathDe, String portalPathEn, String portalPathFr, String portalPathNl, Projection singleProjection, String relevantTag) {
+		super(relevantTag);
+		init(portalPathDe, portalPathEn, portalPathFr, portalPathNl, singleProjection);
+	}
+
+	public DataGovDataSetHandler(String portalPathDe, String portalPathEn, String portalPathFr, String portalPathNl, String relevantTag) {
+		super(relevantTag);
+		init(portalPathDe, portalPathEn, portalPathFr, portalPathNl, null);
+	}
+
+	private void init(String portalPathDe, String portalPathEn, String portalPathFr, String portalPathNl, Projection singleProjection) {
+		setNationalPortalPath(portalPathDe, portalPathEn, portalPathFr, portalPathNl);
+		setSingleProjection(singleProjection);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getSource()
+	 */
+	@Override
+	public String getSource() {
+		return SOURCE_DATAGOVBE;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getLocalPortalURL()
+	 */
+	@Override
+	public URL getLocalPortalURL() {
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/be.datagovbe/src/org/openstreetmap/josm/plugins/opendata/modules/be/datagovbe/datasets/culture/ArchitecturalHeritageHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/be.datagovbe/src/org/openstreetmap/josm/plugins/opendata/modules/be/datagovbe/datasets/culture/ArchitecturalHeritageHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/be.datagovbe/src/org/openstreetmap/josm/plugins/opendata/modules/be/datagovbe/datasets/culture/ArchitecturalHeritageHandler.java	(revision 28000)
@@ -0,0 +1,36 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.be.datagovbe.datasets.culture;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.plugins.opendata.modules.be.datagovbe.datasets.DataGovDataSetHandler;
+
+public class ArchitecturalHeritageHandler extends DataGovDataSetHandler {
+
+	public ArchitecturalHeritageHandler() {
+		super("inventar-des-architektonischen-erbes", "inventory-architectural-heritage", "iventaire-heritage-architectural", "inventaris-bouwkundig-erfgoed");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzFilename(filename, "dibe(_geheel)?") || acceptsZipFilename(filename, "dibegis") || acceptsShpFilename(filename, "dibe_(gehelen|orgels|relicten)");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		// TODO Auto-generated method stub
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/build.xml
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/build.xml	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/build.xml	(revision 28000)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project name="josm-opendata-modules" default="dist" basedir=".">
+	<macrodef name="run_target">
+        <attribute name="target" />
+		<sequential>
+            <ant antfile="build.xml" target="@{target}" dir="be.bruxelles"/>
+			<ant antfile="build.xml" target="@{target}" dir="be.datagovbe"/>
+	        <ant antfile="build.xml" target="@{target}" dir="fr.cg41"/>
+	        <ant antfile="build.xml" target="@{target}" dir="fr.datagouvfr"/>
+	        <ant antfile="build.xml" target="@{target}" dir="fr.paris"/>
+	        <ant antfile="build.xml" target="@{target}" dir="fr.sncf"/>
+	        <ant antfile="build.xml" target="@{target}" dir="fr.toulouse"/>
+		</sequential>
+	</macrodef>
+    <target name="dist">
+        <mkdir dir="../dist"/>
+    	<run_target target="dist"/>
+    	<antcall target="list" />
+    </target>
+    <target name="clean">
+        <run_target target="clean"/>
+    </target>
+    <target name="install" depends="dist">
+        <run_target target="install"/>
+    </target>
+	<target name="list">
+		<mkdir dir="build"/>
+		<javac srcdir="../util" destdir="build" includes="opendata/**" includeantruntime="false" />
+		<java classpath="build" classname="opendata.ModuleListGenerator">
+			<arg line="../"/>
+		</java>
+		<delete dir="build" />
+	</target>
+</project>
Index: /applications/editors/josm/plugins/opendata/modules/fr.cg41/README
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.cg41/README	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.cg41/README	(revision 28000)
@@ -0,0 +1,11 @@
+README 
+======
+
+Readme for CG41 module of JOSM Open Data plugin
+
+    * Author: Don-vip
+    * License: GPL v3 (see gpl-3.0.txt)
+
+-------------------------------- DOCUMENTATION --------------------------------
+
+See http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/CG41
Index: /applications/editors/josm/plugins/opendata/modules/fr.cg41/build.xml
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.cg41/build.xml	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.cg41/build.xml	(revision 28000)
@@ -0,0 +1,231 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!--
+** This is a template build file for a module of the JOSM opendata plugin.
+**
+** Usage
+** =====
+** To build it run
+**
+**    > ant dist
+**
+** To install the generated module locally (in you default opendata modules directory) run
+**
+**    > ant install
+**
+** The generated module jar is not automatically available in JOSMs opendata plugin configuration
+** dialog. You have to check it in first.
+**
+** Use the ant target 'publish' to check in the module and make it available to other
+** JOSM users:
+**    set the property commit.message
+** and run
+**    > ant publish
+**
+-->
+<project name="fr.cg41" default="dist" basedir=".">
+    <!-- enter the SVN commit message -->
+    <property name="commit.message" value="Commit message"/>
+    <!-- should not be necessary to change the following properties -->
+    <property name="josm" location="../../../../core/dist/josm-custom.jar"/>
+    <property name="plugin.dist.dir" value="../../../../dist"/>
+    <property name="opendata" location="${plugin.dist.dir}/opendata.jar"/>
+    <property name="module.build.dir" value="build"/>
+    <property name="module.src.dir" value="src"/>
+    <property name="ant.build.javac.source" value="1.6"/>
+    <property name="ant.build.javac.target" value="1.6"/>
+    <!-- this is the directory where the module jar is copied to -->
+    <property name="module.dist.dir" value="../../dist"/>
+    <property name="module.jar" value="${module.dist.dir}/${ant.project.name}.jar"/>
+	<!-- conditions -->
+    <condition property="resources.exist">
+        <available file="resources" type="dir" />
+    </condition>
+    <condition property="images.exist">
+        <available file="images" type="dir" />
+    </condition>
+    <!--
+    **********************************************************
+    ** init - initializes the build
+    **********************************************************
+    -->
+    <target name="init">
+        <mkdir dir="${module.build.dir}"/>
+        <mkdir dir="${module.build.dir}/META-INF"/>
+    </target>
+    <!--
+    **********************************************************
+    ** compile - compiles the source tree
+    **********************************************************
+    -->
+    <target name="compile" depends="init">
+        <echo message="compiling sources for ${module.jar} ... "/>
+        <javac srcdir="${module.src.dir}" debug="true" destdir="${module.build.dir}" includeAntRuntime="false">
+            <classpath>
+                <pathelement location="${josm}"/>
+                <pathelement location="${opendata}"/>
+            </classpath>
+            <compilerarg value="-Xlint:deprecation"/>
+            <compilerarg value="-Xlint:unchecked"/>
+        </javac>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-resources - copies resources dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-resources" if="resources.exist">
+        <copy todir="${module.build.dir}">
+            <fileset dir="resources" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-images - copies images dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-images" if="images.exist">
+        <copy todir="${module.build.dir}/images">
+            <fileset dir="images" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** dist - creates the module jar
+    **********************************************************
+    -->
+    <target name="dist" depends="compile,revision,copy-resources, copy-images">
+        <echo message="creating ${ant.project.name}.jar ... "/>
+        <copy todir="${module.build.dir}">
+            <fileset dir=".">
+                <include name="README"/>
+                <include name="gpl-3.0.txt"/>
+            </fileset>
+        </copy>
+        <jar destfile="${module.jar}" basedir="${module.build.dir}">
+            <!--
+            ************************************************
+            ** configure these properties. Most of them will
+            ** be copied to the module manifest file.
+            **
+            ************************************************
+            -->
+            <manifest>
+                <attribute name="Author" value="Don-vip"/>
+                <attribute name="Module-Class" value="org.openstreetmap.josm.plugins.opendata.modules.fr.cg41.Cg41Module"/>
+                <attribute name="Module-Date" value="${version.entry.commit.date}"/>
+                <attribute name="Module-Description" value="CG41 - Loir-et-Cher"/>
+                <attribute name="Module-Icon" value="images/data.fr.cg41_24.png"/>
+                <!--<attribute name="Module-Link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/CG41"/>-->
+                <attribute name="Module-Version" value="${version.entry.commit.revision}"/>
+            </manifest>
+        </jar>
+    </target>
+    <!--
+    **********************************************************
+    ** revision - extracts the current revision number for the
+    **    file build.number and stores it in the XML property
+    **    version.*
+    **********************************************************
+    -->
+    <target name="revision">
+        <exec append="false" output="REVISION" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="info"/>
+            <arg value="--xml"/>
+            <arg value="."/>
+        </exec>
+        <xmlproperty file="REVISION" prefix="version" keepRoot="false" collapseAttributes="true"/>
+        <delete file="REVISION"/>
+    </target>
+    <!--
+    **********************************************************
+    ** clean - clean up the build environment
+    **********************************************************
+    -->
+    <target name="clean">
+        <delete dir="${module.build.dir}"/>
+        <delete file="${module.jar}"/>
+    </target>
+    <!--
+    **********************************************************
+    ** install - install the module in your local JOSM installation
+    **********************************************************
+    -->
+    <target name="install" depends="dist">
+        <property environment="env"/>
+        <condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins">
+            <and>
+                <os family="windows"/>
+            </and>
+        </condition>
+        <copy file="${module.jar}" todir="${josm.plugins.dir}/opendata/modules" overwrite="yes"/>
+    </target>
+    <!--
+    ************************** Publishing the module *********************************** 
+    -->
+    <!-- commits the source tree for this module -->
+    <target name="commit-current">
+        <echo>Commiting the module source with message '${commit.message}' ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="commit"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="."/>
+        </exec>
+    </target>
+    <!-- updates (svn up) the source tree for this module -->
+    <target name="update-current">
+        <echo>Updating module source ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="."/>
+        </exec>
+        <echo>Updating ${module.jar} ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="../dist/${module.jar}"/>
+        </exec>
+    </target>
+    <!-- commits the module.jar -->
+    <target name="commit-dist">
+        <echo>
+    ***** Properties of published ${module.jar} *****
+    Commit message    : '${commit.message}'                    
+    Module-Version    : ${version.entry.commit.revision}
+    ***** / Properties of published ${module.jar} *****                    
+                        
+    Now commiting ${module.jar} ...
+    </echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="commit"/>
+            <arg value="${module.jar}"/>
+        </exec>
+    </target>
+    <!-- make sure svn is present as a command line tool -->
+    <target name="ensure-svn-present">
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false" failonerror="false" resultproperty="svn.exit.code">
+            <env key="LANG" value="C"/>
+            <arg value="--version"/>
+        </exec>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure svn is installed on your system.">
+            <!-- return code not set at all? Most likely svn isn't installed -->
+            <condition>
+                <not>
+                    <isset property="svn.exit.code"/>
+                </not>
+            </condition>
+        </fail>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure a working copy of svn is installed on your system.">
+            <!-- error code from SVN? Most likely svn is not what we are looking on this system -->
+            <condition>
+                <isfailure code="${svn.exit.code}"/>
+            </condition>
+        </fail>
+    </target>
+    <target name="publish" depends="ensure-svn-present,commit-current,update-current,clean,dist,commit-dist">
+    </target>
+</project>
Index: /applications/editors/josm/plugins/opendata/modules/fr.cg41/gpl-3.0.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.cg41/gpl-3.0.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.cg41/gpl-3.0.txt	(revision 28000)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/Cg41Constants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/Cg41Constants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/Cg41Constants.java	(revision 28000)
@@ -0,0 +1,37 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.cg41;
+
+import org.openstreetmap.josm.plugins.opendata.core.datasets.fr.FrenchConstants;
+
+public interface Cg41Constants extends FrenchConstants {
+	
+	/**
+	 * Source
+	 */
+	public static final String SOURCE_CG41 = "Conseil général du Loir-et-Cher";
+
+	/**
+	 * Icons
+	 */
+	public static final String ICON_CG41_16 = "data.fr.cg41_16.png";
+	public static final String ICON_CG41_24 = "data.fr.cg41_24.png";
+	
+	/**
+	 * Portal
+	 */
+	public static final String PORTAL_CG41 = "http://www.pilote41.fr/geosource/srv/fr/metadata.show?id=";
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/Cg41Module.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/Cg41Module.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/Cg41Module.java	(revision 28000)
@@ -0,0 +1,30 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.cg41;
+
+import org.openstreetmap.josm.plugins.opendata.core.modules.AbstractModule;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleInformation;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.cg41.datasets.environnement.ZonesInondablesBrayeHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.cg41.datasets.transport.ArretsBusHandler;
+
+public class Cg41Module extends AbstractModule {
+
+	public Cg41Module(ModuleInformation info) {
+		super(info);
+		handlers.add(new ArretsBusHandler());
+		handlers.add(new ZonesInondablesBrayeHandler());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/datasets/Cg41DataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/datasets/Cg41DataSetHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/datasets/Cg41DataSetHandler.java	(revision 28000)
@@ -0,0 +1,76 @@
+package org.openstreetmap.josm.plugins.opendata.modules.fr.cg41.datasets;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.openstreetmap.josm.data.osm.Tag;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.fr.FrenchDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.cg41.Cg41Constants;
+
+public abstract class Cg41DataSetHandler extends FrenchDataSetHandler implements Cg41Constants {
+	
+	private int portalId;
+	
+	public Cg41DataSetHandler(int portalId, String nationalPath) {
+		init(portalId, nationalPath);
+	}
+	
+	public Cg41DataSetHandler(int portalId, String nationalPath, String relevantTag) {
+		super(relevantTag);
+		init(portalId, nationalPath);
+	}
+	
+	public Cg41DataSetHandler(int portalId, String nationalPath, boolean relevantUnion, String ... relevantTags) {
+		super(relevantUnion, relevantTags);
+		init(portalId, nationalPath);
+	}
+
+	public Cg41DataSetHandler(int portalId, String nationalPath, String ... relevantTags) {
+		this(portalId, nationalPath, false, relevantTags);
+	}
+
+	public Cg41DataSetHandler(int portalId, String nationalPath, boolean relevantUnion, Tag ... relevantTags) {
+		super(relevantUnion, relevantTags);
+		init(portalId, nationalPath);
+	}
+
+	private final void init(int portalId, String nationalPath) {
+		this.portalId = portalId;
+		setNationalPortalPath(nationalPath);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getSource()
+	 */
+	@Override
+	public String getSource() {
+		return SOURCE_CG41;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getLocalPortalIconName()
+	 */
+	@Override
+	public String getLocalPortalIconName() {
+		return ICON_CG41_24;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getDataLayerIconName()
+	 */
+	@Override
+	public String getDataLayerIconName() {
+		return ICON_CG41_16;
+	}
+
+	public final URL getLocalPortalURL() {
+		try {
+			if (portalId > 0) {
+				return new URL(PORTAL_CG41 + portalId);
+			}
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/datasets/environnement/ZonesInondablesBrayeHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/datasets/environnement/ZonesInondablesBrayeHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/datasets/environnement/ZonesInondablesBrayeHandler.java	(revision 28000)
@@ -0,0 +1,35 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.cg41.datasets.environnement;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.cg41.datasets.Cg41DataSetHandler;
+
+public class ZonesInondablesBrayeHandler extends Cg41DataSetHandler {
+	public ZonesInondablesBrayeHandler() {
+		super(14624, "Zone-inondable-de-la-Braye-au-1-25000-(partie-Loir-et-Cher)-30383255");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsMifFilename(filename, "aleas_braye");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		// TODO Auto-generated method stub
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/datasets/transport/ArretsBusHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/datasets/transport/ArretsBusHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.cg41/src/org/openstreetmap/josm/plugins/opendata/modules/fr/cg41/datasets/transport/ArretsBusHandler.java	(revision 28000)
@@ -0,0 +1,36 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.cg41.datasets.transport;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.cg41.datasets.Cg41DataSetHandler;
+
+public class ArretsBusHandler extends Cg41DataSetHandler {
+
+	public ArretsBusHandler() {
+		super(14615, "Points-d'arrêt-du-réseau-de-transport-départemental-\"Route41\"-30383156");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsShpFilename(filename, "Points_ROUTE41");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		// TODO Auto-generated method stub
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/README
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/README	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/README	(revision 28000)
@@ -0,0 +1,11 @@
+README 
+======
+
+Readme for Data.gouv.fr module of JOSM Open Data plugin
+
+    * Author: Don-vip
+    * License: GPL v3 (see gpl-3.0.txt)
+
+-------------------------------- DOCUMENTATION --------------------------------
+
+See http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/Data.gouv.fr
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/build.xml
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/build.xml	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/build.xml	(revision 28000)
@@ -0,0 +1,231 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!--
+** This is a template build file for a module of the JOSM opendata plugin.
+**
+** Usage
+** =====
+** To build it run
+**
+**    > ant dist
+**
+** To install the generated module locally (in you default opendata modules directory) run
+**
+**    > ant install
+**
+** The generated module jar is not automatically available in JOSMs opendata plugin configuration
+** dialog. You have to check it in first.
+**
+** Use the ant target 'publish' to check in the module and make it available to other
+** JOSM users:
+**    set the property commit.message
+** and run
+**    > ant publish
+**
+-->
+<project name="fr.datagouvfr" default="dist" basedir=".">
+    <!-- enter the SVN commit message -->
+    <property name="commit.message" value="Commit message"/>
+    <!-- should not be necessary to change the following properties -->
+    <property name="josm" location="../../../../core/dist/josm-custom.jar"/>
+    <property name="plugin.dist.dir" value="../../../../dist"/>
+    <property name="opendata" location="${plugin.dist.dir}/opendata.jar"/>
+    <property name="module.build.dir" value="build"/>
+    <property name="module.src.dir" value="src"/>
+    <property name="ant.build.javac.source" value="1.6"/>
+    <property name="ant.build.javac.target" value="1.6"/>
+    <!-- this is the directory where the module jar is copied to -->
+    <property name="module.dist.dir" value="../../dist"/>
+    <property name="module.jar" value="${module.dist.dir}/${ant.project.name}.jar"/>
+	<!-- conditions -->
+    <condition property="resources.exist">
+        <available file="resources" type="dir" />
+    </condition>
+    <condition property="images.exist">
+        <available file="images" type="dir" />
+    </condition>
+    <!--
+    **********************************************************
+    ** init - initializes the build
+    **********************************************************
+    -->
+    <target name="init">
+        <mkdir dir="${module.build.dir}"/>
+        <mkdir dir="${module.build.dir}/META-INF"/>
+    </target>
+    <!--
+    **********************************************************
+    ** compile - compiles the source tree
+    **********************************************************
+    -->
+    <target name="compile" depends="init">
+        <echo message="compiling sources for ${module.jar} ... "/>
+        <javac srcdir="${module.src.dir}" debug="true" destdir="${module.build.dir}" includeAntRuntime="false">
+            <classpath>
+                <pathelement location="${josm}"/>
+                <pathelement location="${opendata}"/>
+            </classpath>
+            <compilerarg value="-Xlint:deprecation"/>
+            <compilerarg value="-Xlint:unchecked"/>
+        </javac>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-resources - copies resources dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-resources" if="resources.exist">
+        <copy todir="${module.build.dir}">
+            <fileset dir="resources" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-images - copies images dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-images" if="images.exist">
+        <copy todir="${module.build.dir}/images">
+            <fileset dir="images" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** dist - creates the module jar
+    **********************************************************
+    -->
+    <target name="dist" depends="compile,revision,copy-resources, copy-images">
+        <echo message="creating ${ant.project.name}.jar ... "/>
+        <copy todir="${module.build.dir}">
+            <fileset dir=".">
+                <include name="README"/>
+                <include name="gpl-3.0.txt"/>
+            </fileset>
+        </copy>
+        <jar destfile="${module.jar}" basedir="${module.build.dir}">
+            <!--
+            ************************************************
+            ** configure these properties. Most of them will
+            ** be copied to the module manifest file.
+            **
+            ************************************************
+            -->
+            <manifest>
+                <attribute name="Author" value="Don-vip"/>
+                <attribute name="Module-Class" value="org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.DataGouvFrModule"/>
+                <attribute name="Module-Date" value="${version.entry.commit.date}"/>
+                <attribute name="Module-Description" value="data.gouv.fr"/>
+                <attribute name="Module-Icon" value="images/fr24.png"/>
+                <attribute name="Module-Link" value="http://wiki.openstreetmap.org/wiki/WikiProject_France/data.gouv.fr"/>
+                <attribute name="Module-Version" value="${version.entry.commit.revision}"/>
+            </manifest>
+        </jar>
+    </target>
+    <!--
+    **********************************************************
+    ** revision - extracts the current revision number for the
+    **    file build.number and stores it in the XML property
+    **    version.*
+    **********************************************************
+    -->
+    <target name="revision">
+        <exec append="false" output="REVISION" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="info"/>
+            <arg value="--xml"/>
+            <arg value="."/>
+        </exec>
+        <xmlproperty file="REVISION" prefix="version" keepRoot="false" collapseAttributes="true"/>
+        <delete file="REVISION"/>
+    </target>
+    <!--
+    **********************************************************
+    ** clean - clean up the build environment
+    **********************************************************
+    -->
+    <target name="clean">
+        <delete dir="${module.build.dir}"/>
+        <delete file="${module.jar}"/>
+    </target>
+    <!--
+    **********************************************************
+    ** install - install the module in your local JOSM installation
+    **********************************************************
+    -->
+    <target name="install" depends="dist">
+        <property environment="env"/>
+        <condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins">
+            <and>
+                <os family="windows"/>
+            </and>
+        </condition>
+        <copy file="${module.jar}" todir="${josm.plugins.dir}/opendata/modules" overwrite="yes"/>
+    </target>
+    <!--
+    ************************** Publishing the module *********************************** 
+    -->
+    <!-- commits the source tree for this module -->
+    <target name="commit-current">
+        <echo>Commiting the module source with message '${commit.message}' ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="commit"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="."/>
+        </exec>
+    </target>
+    <!-- updates (svn up) the source tree for this module -->
+    <target name="update-current">
+        <echo>Updating module source ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="."/>
+        </exec>
+        <echo>Updating ${module.jar} ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="../dist/${module.jar}"/>
+        </exec>
+    </target>
+    <!-- commits the module.jar -->
+    <target name="commit-dist">
+        <echo>
+    ***** Properties of published ${module.jar} *****
+    Commit message    : '${commit.message}'                    
+    Module-Version    : ${version.entry.commit.revision}
+    ***** / Properties of published ${module.jar} *****                    
+                        
+    Now commiting ${module.jar} ...
+    </echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="commit"/>
+            <arg value="${module.jar}"/>
+        </exec>
+    </target>
+    <!-- make sure svn is present as a command line tool -->
+    <target name="ensure-svn-present">
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false" failonerror="false" resultproperty="svn.exit.code">
+            <env key="LANG" value="C"/>
+            <arg value="--version"/>
+        </exec>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure svn is installed on your system.">
+            <!-- return code not set at all? Most likely svn isn't installed -->
+            <condition>
+                <not>
+                    <isset property="svn.exit.code"/>
+                </not>
+            </condition>
+        </fail>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure a working copy of svn is installed on your system.">
+            <!-- error code from SVN? Most likely svn is not what we are looking on this system -->
+            <condition>
+                <isfailure code="${svn.exit.code}"/>
+            </condition>
+        </fail>
+    </target>
+    <target name="publish" depends="ensure-svn-present,commit-current,update-current,clean,dist,commit-dist">
+    </target>
+</project>
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/gpl-3.0.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/gpl-3.0.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/gpl-3.0.txt	(revision 28000)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/resources/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/agriculture/RegistreParcellaire.mapcss
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/resources/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/agriculture/RegistreParcellaire.mapcss	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/resources/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/agriculture/RegistreParcellaire.mapcss	(revision 28000)
@@ -0,0 +1,86 @@
+area[code:FR:RPG=0] {
+}
+area[code:FR:RPG=1] {
+  fill-color: #FFFF90;
+}
+area[code:FR:RPG=2] {
+  fill-color: #00FF00;
+}
+area[code:FR:RPG=3] {
+  fill-color: #F0FF70;
+}
+area[code:FR:RPG=4] {
+  fill-color: #DAEB00;
+}
+area[code:FR:RPG=5] {
+  fill-color: #FFECB0;
+}
+area[code:FR:RPG=6] {
+  fill-color: #FFFF00;
+}
+area[code:FR:RPG=7] {
+  fill-color: #FFC000;
+}
+area[code:FR:RPG=8] {
+  fill-color: #F0B400;
+}
+area[code:FR:RPG=9] {
+  fill-color: #C09000;
+}
+area[code:FR:RPG=10] {
+  fill-color: #604800;
+}
+area[code:FR:RPG=11] {
+  fill-color: #F0F0F0;
+}
+area[code:FR:RPG=12] {
+  fill-color: #B0B0B0;
+}
+area[code:FR:RPG=13] {
+  fill-color: #D0D0D0;
+}
+area[code:FR:RPG=14] {
+  fill-color: #90B5FF;
+}
+area[code:FR:RPG=15] {
+  fill-color: #FFA080;
+}
+area[code:FR:RPG=16] {
+  fill-color: #9FC75D;
+}
+area[code:FR:RPG=17] {
+  fill-color: #B5E66B;
+}
+area[code:FR:RPG=18] {
+  fill-color: #C0FF60;
+}
+area[code:FR:RPG=19] {
+  fill-color: #E0FFB0;
+}
+area[code:FR:RPG=20] {
+  fill-color: #FF0000;
+}
+area[code:FR:RPG=21] {
+  fill-color: #E000E0;
+}
+area[code:FR:RPG=22] {
+  fill-color: #008000;
+}
+area[code:FR:RPG=23] {
+  fill-color: #A2A200;
+}
+area[code:FR:RPG=24] {
+  fill-color: #008080;
+}
+area[code:FR:RPG=25] {
+  fill-color: #FFA0D0;
+}
+area[code:FR:RPG=26] {
+  fill-color: #0000FF;
+}
+area[code:FR:RPG=27] {
+  fill-color: #00B058;
+}
+area[code:FR:RPG=28] {
+  fill-color: #800080;
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/DataGouvFrConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/DataGouvFrConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/DataGouvFrConstants.java	(revision 28000)
@@ -0,0 +1,36 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr;
+
+import org.openstreetmap.josm.plugins.opendata.core.datasets.fr.FrenchConstants;
+
+public interface DataGouvFrConstants extends FrenchConstants {
+	
+	/**
+	 * Wiki
+	 */
+	public static final String WIKI = "http://wiki.openstreetmap.org/wiki/WikiProject_France/data.gouv.fr";
+
+	/**
+	 * Source
+	 */
+	public static final String SOURCE_DATAGOUVFR = "data.gouv.fr";
+	
+	/**
+	 * Icons
+	 */
+	public static final String ICON_IGN_24 = "data.fr.ign_24.png";
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/DataGouvFrModule.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/DataGouvFrModule.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/DataGouvFrModule.java	(revision 28000)
@@ -0,0 +1,44 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr;
+
+import org.openstreetmap.josm.plugins.opendata.core.modules.AbstractModule;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleInformation;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.administration.GeoFlaHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.agriculture.RegistreParcellaireHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.culture.BibliothequesHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.diplomatie.EtabAEFEHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.ecologie.AssainissementHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.education.Etab1er2ndDegreHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.education.EtabSupHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.hydrologie.ROEHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.transport.PassageNiveauHandler;
+
+public class DataGouvFrModule extends AbstractModule {
+
+	public DataGouvFrModule(ModuleInformation info) {
+		super(info);
+        handlers.add(new Etab1er2ndDegreHandler());
+        handlers.add(new EtabAEFEHandler());
+        handlers.add(new BibliothequesHandler());
+        handlers.add(new EtabSupHandler());
+        handlers.add(new AssainissementHandler());
+        handlers.add(new RegistreParcellaireHandler());
+        handlers.add(new GeoFlaHandler());
+        handlers.add(new PassageNiveauHandler());
+        handlers.add(new ROEHandler());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/DataGouvDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/DataGouvDataSetHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/DataGouvDataSetHandler.java	(revision 28000)
@@ -0,0 +1,68 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets;
+
+import java.net.URL;
+
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.fr.FrenchDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.DataGouvFrConstants;
+
+public abstract class DataGouvDataSetHandler extends FrenchDataSetHandler implements DataGouvFrConstants {
+	
+	public DataGouvDataSetHandler() {
+		init(null, null);
+	}
+
+	public DataGouvDataSetHandler(String portalPath) {
+		init(portalPath, null);
+	}
+
+	public DataGouvDataSetHandler(String portalPath, Projection singleProjection) {
+		init(portalPath, singleProjection);
+	}
+
+	public DataGouvDataSetHandler(String portalPath, Projection singleProjection, String relevantTag) {
+		super(relevantTag);
+		init(portalPath, singleProjection);
+	}
+
+	public DataGouvDataSetHandler(String portalPath, String relevantTag) {
+		super(relevantTag);
+		init(portalPath, null);
+	}
+
+	private void init(String portalPath, Projection singleProjection) {
+		setNationalPortalPath(portalPath);
+		setSingleProjection(singleProjection);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getSource()
+	 */
+	@Override
+	public String getSource() {
+		return SOURCE_DATAGOUVFR;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getLocalPortalURL()
+	 */
+	@Override
+	public URL getLocalPortalURL() {
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/administration/GeoFlaHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/administration/GeoFlaHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/administration/GeoFlaHandler.java	(revision 28000)
@@ -0,0 +1,203 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.administration;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.lang3.text.WordUtils;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.DataGouvDataSetHandler;
+
+public class GeoFlaHandler extends DataGouvDataSetHandler {
+	
+	public GeoFlaHandler() {
+		super();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.portals.fr.datagouvfr.datasets.DataGouvDataSetHandler#getLocalPortalURL()
+	 */
+	@Override
+	public URL getLocalPortalURL() {
+		try {
+			return new URL("http://professionnels.ign.fr/ficheProduitCMS.do?idDoc=6185461");
+		} catch (MalformedURLException e) {
+			System.err.println(e.getMessage());
+			return null;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.fr.FrenchDataSetHandler#getLocalPortalIconName()
+	 */
+	@Override
+	public String getLocalPortalIconName() {
+		return ICON_IGN_24;
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return isDepartementFile(filename) || isCommuneFile(filename) || isCantonFile(filename) || isArrondissementFile(filename);
+	}
+		
+	protected boolean isDepartementFile(String filename) {
+		return acceptsShpMifFilename(filename, "DEPARTEMENT") || acceptsShpMifFilename(filename, "LIMITE_DEPARTEMENT");
+	}
+
+	protected boolean isCommuneFile(String filename) {
+		return acceptsShpFilename(filename, "COMMUNE") || acceptsShpFilename(filename, "LIMITE_COMMUNE");
+	}
+
+	protected boolean isCantonFile(String filename) {
+		return acceptsShpFilename(filename, "CANTON") || acceptsShpFilename(filename, "LIMITE_CANTON");
+	}
+
+	protected boolean isArrondissementFile(String filename) {
+		return acceptsShpFilename(filename, "ARRONDISSEMENT") || acceptsShpFilename(filename, "LIMITE_ARRONDISSEMENT");
+	}
+
+	@Override
+	public boolean preferMultipolygonToSimpleWay() {
+		return true;
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		final String filename = getAssociatedFile().getName();
+		if (isDepartementFile(filename)) {
+			setNationalPortalPath("GEOFLA®-Départements-30383060");
+		} else if (isCommuneFile(filename)) {
+			setNationalPortalPath("GEOFLA®-Communes-30383083");
+		}
+		for (OsmPrimitive p : ds.allPrimitives()) {
+			if (hasKeyIgnoreCase(p, "Id_geofla", "Id_GéoFLA")) {
+				String deptName = WordUtils.capitalizeFully(getAndRemoveIgnoreCase(p, "Nom_dept", "Nom_Département"));
+				if ("Reunion".equals(deptName)) {
+					deptName = "La Réunion";
+				}
+				if (isDepartementFile(filename)) {
+					p.put("name", deptName);
+				} else if (isCommuneFile(filename)) {
+					p.put("name", WordUtils.capitalizeFully(getAndRemoveIgnoreCase(p, "NOM_COMM")));
+					replace(p, "INSEE_COM", "ref:INSEE");
+				}
+				p.put("boundary", "administrative");
+				String nature = getIgnoreCase(p, "Nature");
+				if ("Frontière internationale".equalsIgnoreCase(nature) || "Limite côtière".equalsIgnoreCase(nature)) {
+					p.put("admin_level", "2");
+				} else if ("Limite de région".equalsIgnoreCase(nature)) {
+					p.put("admin_level", "4");
+				} else if (isDepartementFile(filename) || "Limite de département".equalsIgnoreCase(nature)) {
+					p.put("admin_level", "6");
+				} else if(isArrondissementFile(filename) || "Limite d'arrondissement".equalsIgnoreCase(nature)) {
+					p.put("admin_level", "7");
+				} else if(isCommuneFile(filename)) {
+					p.put("admin_level", "8");
+				}
+				if (p instanceof Relation) {
+					p.put("type", "boundary");
+				}
+				LatLon llCentroid = getLatLon(p, deptName, "centroid", "Centroïde");
+				if (llCentroid != null) {
+					Node centroid = new Node(llCentroid);
+					ds.addPrimitive(centroid);
+					//centroid.put("name", p.get("name"));
+					if (p instanceof Relation) {
+						((Relation) p).addMember(new RelationMember("centroid", centroid));
+					}
+				}
+				LatLon llChefLieu = getLatLon(p, deptName, "chf_lieu", "Chef_Lieu");
+				if (llChefLieu != null) {
+					Node chefLieu = new Node(llChefLieu);
+					ds.addPrimitive(chefLieu);
+					//chefLieu.put("Code_chf", getAndRemoveIgnoreCase(p, "Code_chf", "Code_Chef_Lieu"));
+					String name = WordUtils.capitalizeFully(getAndRemoveIgnoreCase(p, "Nom_chf", "Nom_Chef_lieu"));
+					if (isArrondissementFile(filename)) {
+						p.put("name", name);
+					}
+					chefLieu.put("name", name);
+					if (p instanceof Relation) {
+						((Relation) p).addMember(new RelationMember("admin_centre", chefLieu));
+					}
+				}
+			}
+		}
+	}
+	
+	protected static boolean hasKeyIgnoreCase(OsmPrimitive p, String ... strings) {
+		return getIgnoreCase(p, strings) != null;
+	}
+
+	protected static String getIgnoreCase(OsmPrimitive p, String ... strings) {
+		String result = null;
+		for (String s : strings) {
+			if (result == null) result = p.get(s);
+			if (result == null) result = p.get(s.toUpperCase());
+			if (result == null) result = p.get(s.toLowerCase());
+		}
+		return result;
+	}
+
+	protected static void removeIgnoreCase(OsmPrimitive p, String ... strings) {
+		for (String s : strings) {
+			p.remove(s);
+			p.remove(s.toUpperCase());
+			p.remove(s.toLowerCase());
+		}
+	}
+	
+	protected static String getAndRemoveIgnoreCase(OsmPrimitive p, String ... strings) {
+		String result = getIgnoreCase(p, strings);
+		removeIgnoreCase(p, strings);
+		return result;
+	}
+
+	protected static LatLon getLatLon(OsmPrimitive p, String dptName, String shortAttribute, String longAttribute) {
+		String x = getAndRemoveIgnoreCase(p, "X_"+shortAttribute, "Abscisse_"+longAttribute);
+		String y = getAndRemoveIgnoreCase(p, "Y_"+shortAttribute, "Ordonnée_"+longAttribute);
+		if (x != null && y != null) {
+			try {
+				String dptCode = getIgnoreCase(p, "Code_dept", "Code_Département");
+				if (dptCode != null && dptCode.equals("97") && dptName != null) {
+					if (dptName.equals("Guadeloupe")) {
+						dptCode = "971";
+					} else if (dptName.equals("Martinique")) {
+						dptCode = "972";
+					} else if (dptName.equals("Guyane")) {
+						dptCode = "973";
+					} else if (dptName.equals("La Réunion")) {
+						dptCode = "974";
+					} else if (dptName.equals("Mayotte")) {
+						dptCode = "976";
+					} else {
+						System.err.println("Unknown French department: "+dptName);
+					}
+				}
+				return getLatLonByDptCode(new EastNorth(Double.parseDouble(x)*100.0, Double.parseDouble(y)*100.0), dptCode, false);
+			} catch (NumberFormatException e) {
+				System.err.println(e.getMessage());
+			}
+		}
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/agriculture/RegistreParcellaireHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/agriculture/RegistreParcellaireHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/agriculture/RegistreParcellaireHandler.java	(revision 28000)
@@ -0,0 +1,126 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.agriculture;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.preferences.SourceEditor.ExtendedSourceEntry;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.DataGouvDataSetHandler;
+
+public class RegistreParcellaireHandler extends DataGouvDataSetHandler {
+	
+	protected static final int PAS_D_INFORMATION = 0;
+	protected static final int BLE_TENDRE = 1;
+	protected static final int MAIS_GRAIN_ET_ENSILAGE = 2;
+	protected static final int ORGE = 3;
+	protected static final int AUTRES_CEREALES = 4;
+	protected static final int COLZA = 5;
+	protected static final int TOURNESOL = 6;
+	protected static final int AUTRES_OLEAGINEUX = 7;
+	protected static final int PROTEAGINEUX = 8;
+	protected static final int PLANTES_A_FIBRES = 9;
+	protected static final int SEMENCES = 10;
+	protected static final int GEL_SURFACES_GELEES_SANS_PRODUCTION = 11;
+	protected static final int GEL_INDUSTRIEL = 12;
+	protected static final int AUTRES_GELS = 13;
+	protected static final int RIZ = 14;
+	protected static final int LEGUMINEUSES_A_GRAINS = 15;
+	protected static final int FOURRAGE = 16;
+	protected static final int ESTIVES_LANDES = 17;
+	protected static final int PRAIRIES_PERMANENTES = 18;
+	protected static final int PRAIRIES_TEMPORAIRES = 19;
+	protected static final int VERGERS = 20;
+	protected static final int VIGNES = 21;
+	protected static final int FRUITS_A_COQUE = 22;
+	protected static final int OLIVIERS = 23;
+	protected static final int AUTRES_CULTURES_INDUSTRIELLES = 24;
+	protected static final int LEGUMES_FLEURS = 25;
+	protected static final int CANNE_A_SUCRE = 26;
+	protected static final int ARBORICULTURE = 27;
+	protected static final int DIVERS = 28;
+	
+	public RegistreParcellaireHandler() {
+		super();
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsShpFilename(filename, "RPG_20.._...");
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getMapPaintStyle()
+	 */
+	@Override
+	public ExtendedSourceEntry getMapPaintStyle() {
+		return getMapPaintStyle("Registre Parcellaire Graphique (France)");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (OsmPrimitive p : ds.allPrimitives()) {
+			String code = p.get("CULT_MAJ");
+			
+			if (code != null && !code.isEmpty()) {
+				replace(p, "NUM_ILOT", "ref:FR:RPG");
+				replace(p, "CULT_MAJ", "code:FR:RPG");
+				
+				switch (Integer.parseInt(code)) {
+				case ARBORICULTURE:
+					p.put("landuse", "forest");
+					break;
+				case FOURRAGE:
+				case PRAIRIES_PERMANENTES:
+				case PRAIRIES_TEMPORAIRES:
+				case ESTIVES_LANDES:
+				case GEL_SURFACES_GELEES_SANS_PRODUCTION:
+				case GEL_INDUSTRIEL:
+				case AUTRES_GELS:
+					p.put("landuse", "meadow");
+					break;
+				case OLIVIERS:
+					p.put("trees", "olive_tree");
+				case VERGERS:
+					p.put("landuse", "orchard");
+					break;
+				case VIGNES:
+					p.put("landuse", "vineyard");
+					break;
+				case PAS_D_INFORMATION:
+				case BLE_TENDRE:
+				case MAIS_GRAIN_ET_ENSILAGE:
+				case ORGE:
+				case AUTRES_CEREALES:
+				case COLZA:
+				case TOURNESOL:
+				case AUTRES_OLEAGINEUX:
+				case PROTEAGINEUX:
+				case PLANTES_A_FIBRES:
+				case SEMENCES:
+				case RIZ:
+				case LEGUMINEUSES_A_GRAINS:
+				case FRUITS_A_COQUE:
+				case AUTRES_CULTURES_INDUSTRIELLES:
+				case LEGUMES_FLEURS:
+				case CANNE_A_SUCRE:
+				case DIVERS:
+				default:
+					p.put("landuse", "farm");
+				}
+			}
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/culture/BibliothequesHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/culture/BibliothequesHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/culture/BibliothequesHandler.java	(revision 28000)
@@ -0,0 +1,47 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.culture;
+
+import java.nio.charset.Charset;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.DataGouvDataSetHandler;
+
+public class BibliothequesHandler extends DataGouvDataSetHandler {
+
+	public BibliothequesHandler() {
+		super("Adresses-des-bibliothèques-municipales-30382179", lambert93);
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvFilename(filename, "lieux de lecture_geoloc.txt-fr");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getCsvCharset()
+	 */
+	@Override
+	public Charset getCsvCharset() {
+		return Charset.forName(ISO8859_15);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/diplomatie/EtabAEFEHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/diplomatie/EtabAEFEHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/diplomatie/EtabAEFEHandler.java	(revision 28000)
@@ -0,0 +1,52 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.diplomatie;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.DataGouvDataSetHandler;
+
+public class EtabAEFEHandler extends DataGouvDataSetHandler {
+
+	public EtabAEFEHandler() {
+		super("Géolocalisation-des-établissements-du-réseau-d'enseignement-de-l'AEFE-30382449", wgs84);
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvFilename(filename, "ETALAB_MAEE_Extraction_LDAP_geoloc_AEFE_20..-..-..\\.csv-fr");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.put("amenity", "school");
+			replace(n, "code_etab", "ref");
+			replace(n, "ENTStructureNomCourant", "name:fr");
+			replace(n, "adresse", "addr");
+			replace(n, "ENTStructureSiteWeb", "website");
+			replace(n, "ENTStructureEmail", "contact:email");
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getCsvSeparator()
+	 */
+	@Override
+	public String getCsvSeparator() {
+		return ",";
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/ecologie/AssainissementHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/ecologie/AssainissementHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/ecologie/AssainissementHandler.java	(revision 28000)
@@ -0,0 +1,44 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.ecologie;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.DataGouvDataSetHandler;
+
+public class AssainissementHandler extends DataGouvDataSetHandler {
+
+	public AssainissementHandler() {
+		super("assainissement-collectif-30381843");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsOdsFilename(filename, "Export_ERU_20..");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		// TODO Auto-generated method stub
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getSheetNumber()
+	 */
+	@Override
+	public int getSheetNumber() {
+		return 1;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/education/Etab1er2ndDegreHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/education/Etab1er2ndDegreHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/education/Etab1er2ndDegreHandler.java	(revision 28000)
@@ -0,0 +1,77 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.education;
+
+import java.nio.charset.Charset;
+
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.DataGouvDataSetHandler;
+
+public class Etab1er2ndDegreHandler extends DataGouvDataSetHandler {
+
+	public Etab1er2ndDegreHandler() {
+		super("Géolocalisation-des-établissements-d'enseignement-du-premier-degré-et-du-second-degré-du-ministère-d-30378093");
+	}
+	
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvFilename(filename, "MENJVA_etab_geoloc.csv-fr");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.put("amenity", "school");
+			replace(n, "numero_uai", "ref:FR:UAI");
+			replace(n, "appellation_officielle_uai", "name");
+			add(n, "lib_nature", "school:FR", 
+					new String[]{".*MATERNELLE.*", ".*ELEMENTAIRE.*", "COLLEGE.*", "LYCEE.*"}, 
+					new String[]{"maternelle", "élémentaire", "college", "lycée"});
+			n.remove("etat_etablissement"); // Toujours a 1
+			n.remove("nature_uai"); // cle numerique associe au champ lib_nature, redondant, donc
+			n.remove("patronyme_uai"); // deja dans le nom
+			n.remove("sous_fic"); // cycle ? 1 pour ecoles, 3 pour colleges et lycees
+			// Voir http://www.infocentre.education.fr/bcn/domaine/voir/id/31
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#handlesCsvProjection()
+	 */
+	@Override
+	public boolean handlesSpreadSheetProjection() {
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getCsvCoor(org.openstreetmap.josm.data.coor.EastNorth, java.lang.String[])
+	 */
+	@Override
+	public LatLon getSpreadSheetCoor(EastNorth en, String[] fields) {
+		return getLatLonByDptCode(en, fields[0].substring(0, 3), false);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getCsvCharset()
+	 */
+	@Override
+	public Charset getCsvCharset() {
+		return Charset.forName(ISO8859_15);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/education/EtabSupHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/education/EtabSupHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/education/EtabSupHandler.java	(revision 28000)
@@ -0,0 +1,51 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.education;
+
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.DataGouvDataSetHandler;
+
+public class EtabSupHandler extends DataGouvDataSetHandler {
+
+	public EtabSupHandler() {
+		super("Etablissements-d'enseignement-supérieur-30382046", wgs84);
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsXlsFilename(filename, "livraison ETALAB .. .. 20..\\.xls-fr");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			replace(n, "NOM_ETABLISSEMENT", "name");
+			n.put("amenity", "university");
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.portals.fr.datagouvfr.datasets.DataGouvDataSetHandler#getSpreadSheetCoor(org.openstreetmap.josm.data.coor.EastNorth, java.lang.String[])
+	 */
+	@Override
+	public LatLon getSpreadSheetCoor(EastNorth en, String[] fields) {
+		// X/Y sont inversees dans le fichier
+		return wgs84.eastNorth2latlon(new EastNorth(en.north(), en.east()));
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/hydrologie/ROEHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/hydrologie/ROEHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/hydrologie/ROEHandler.java	(revision 28000)
@@ -0,0 +1,48 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.hydrologie;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.DataGouvDataSetHandler;
+
+public class ROEHandler extends DataGouvDataSetHandler {
+
+	public ROEHandler() {
+		super("référentiel-des-obstacles-à-l'écoulement-30381987");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsMifTabFilename(filename, "roe_version._20......_wlatin1") 
+			|| acceptsShpFilename(filename, "roe_version._20......_system_L93")
+			|| acceptsXlsFilename(filename, "roe_version._20......_wlatin1");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			replace(n, "Id_ROE", "ref:FR:ROE");
+			replace(n, "Nom", "name");
+			n.remove("XL2e"); n.remove("YL2e");
+			n.remove("XL93"); n.remove("YL93");
+			replace(n, "typeCd", "waterway", new String[]{"1.1", "1.2", "1.6"}, new String[]{"dam", "weir", "lock_gate"});
+			replace(n, "typeCd", "man_made", new String[]{"1.3", "1.5"}, new String[]{"dyke", "groyne"});
+			replace(n, "typeCd", "bridge", new String[]{"1.4"}, new String[]{"yes"});
+			n.remove("typeCd");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/transport/PassageNiveauHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/transport/PassageNiveauHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.datagouvfr/src/org/openstreetmap/josm/plugins/opendata/modules/fr/datagouvfr/datasets/transport/PassageNiveauHandler.java	(revision 28000)
@@ -0,0 +1,49 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.transport;
+
+import java.nio.charset.Charset;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.DataGouvDataSetHandler;
+
+public class PassageNiveauHandler extends DataGouvDataSetHandler {
+
+	public PassageNiveauHandler() {
+		super("Passages-à-niveau-30383135");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvFilename(filename, "passage_a_niveau.csv-fr");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.put("railway", "level_crossing");
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getCsvCharset()
+	 */
+	@Override
+	public Charset getCsvCharset() {
+		return Charset.forName(ISO8859_15);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.paris/README
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.paris/README	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.paris/README	(revision 28000)
@@ -0,0 +1,11 @@
+README 
+======
+
+Readme for Paris module of JOSM Open Data plugin
+
+    * Author: Don-vip
+    * License: GPL v3 (see gpl-3.0.txt)
+
+-------------------------------- DOCUMENTATION --------------------------------
+
+See http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/Paris
Index: /applications/editors/josm/plugins/opendata/modules/fr.paris/build.xml
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.paris/build.xml	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.paris/build.xml	(revision 28000)
@@ -0,0 +1,231 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!--
+** This is a template build file for a module of the JOSM opendata plugin.
+**
+** Usage
+** =====
+** To build it run
+**
+**    > ant dist
+**
+** To install the generated module locally (in you default opendata modules directory) run
+**
+**    > ant install
+**
+** The generated module jar is not automatically available in JOSMs opendata plugin configuration
+** dialog. You have to check it in first.
+**
+** Use the ant target 'publish' to check in the module and make it available to other
+** JOSM users:
+**    set the property commit.message
+** and run
+**    > ant publish
+**
+-->
+<project name="fr.paris" default="dist" basedir=".">
+    <!-- enter the SVN commit message -->
+    <property name="commit.message" value="Commit message"/>
+    <!-- should not be necessary to change the following properties -->
+    <property name="josm" location="../../../../core/dist/josm-custom.jar"/>
+    <property name="plugin.dist.dir" value="../../../../dist"/>
+    <property name="opendata" location="${plugin.dist.dir}/opendata.jar"/>
+    <property name="module.build.dir" value="build"/>
+    <property name="module.src.dir" value="src"/>
+    <property name="ant.build.javac.source" value="1.6"/>
+    <property name="ant.build.javac.target" value="1.6"/>
+    <!-- this is the directory where the module jar is copied to -->
+    <property name="module.dist.dir" value="../../dist"/>
+    <property name="module.jar" value="${module.dist.dir}/${ant.project.name}.jar"/>
+	<!-- conditions -->
+    <condition property="resources.exist">
+        <available file="resources" type="dir" />
+    </condition>
+    <condition property="images.exist">
+        <available file="images" type="dir" />
+    </condition>
+    <!--
+    **********************************************************
+    ** init - initializes the build
+    **********************************************************
+    -->
+    <target name="init">
+        <mkdir dir="${module.build.dir}"/>
+        <mkdir dir="${module.build.dir}/META-INF"/>
+    </target>
+    <!--
+    **********************************************************
+    ** compile - compiles the source tree
+    **********************************************************
+    -->
+    <target name="compile" depends="init">
+        <echo message="compiling sources for ${module.jar} ... "/>
+        <javac srcdir="${module.src.dir}" debug="true" destdir="${module.build.dir}" includeAntRuntime="false">
+            <classpath>
+                <pathelement location="${josm}"/>
+                <pathelement location="${opendata}"/>
+            </classpath>
+            <compilerarg value="-Xlint:deprecation"/>
+            <compilerarg value="-Xlint:unchecked"/>
+        </javac>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-resources - copies resources dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-resources" if="resources.exist">
+        <copy todir="${module.build.dir}">
+            <fileset dir="resources" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-images - copies images dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-images" if="images.exist">
+        <copy todir="${module.build.dir}/images">
+            <fileset dir="images" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** dist - creates the module jar
+    **********************************************************
+    -->
+    <target name="dist" depends="compile,revision,copy-resources, copy-images">
+        <echo message="creating ${ant.project.name}.jar ... "/>
+        <copy todir="${module.build.dir}">
+            <fileset dir=".">
+                <include name="README"/>
+                <include name="gpl-3.0.txt"/>
+            </fileset>
+        </copy>
+        <jar destfile="${module.jar}" basedir="${module.build.dir}">
+            <!--
+            ************************************************
+            ** configure these properties. Most of them will
+            ** be copied to the module manifest file.
+            **
+            ************************************************
+            -->
+            <manifest>
+                <attribute name="Author" value="Don-vip"/>
+                <attribute name="Module-Class" value="org.openstreetmap.josm.plugins.opendata.modules.fr.paris.ParisModule"/>
+                <attribute name="Module-Date" value="${version.entry.commit.date}"/>
+                <attribute name="Module-Description" value="Paris"/>
+            	<attribute name="Module-Icon" value="images/data.fr.paris_24.png"/>
+                <!--<attribute name="Module-Link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/Paris"/>-->
+                <attribute name="Module-Version" value="${version.entry.commit.revision}"/>
+            </manifest>
+        </jar>
+    </target>
+    <!--
+    **********************************************************
+    ** revision - extracts the current revision number for the
+    **    file build.number and stores it in the XML property
+    **    version.*
+    **********************************************************
+    -->
+    <target name="revision">
+        <exec append="false" output="REVISION" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="info"/>
+            <arg value="--xml"/>
+            <arg value="."/>
+        </exec>
+        <xmlproperty file="REVISION" prefix="version" keepRoot="false" collapseAttributes="true"/>
+        <delete file="REVISION"/>
+    </target>
+    <!--
+    **********************************************************
+    ** clean - clean up the build environment
+    **********************************************************
+    -->
+    <target name="clean">
+        <delete dir="${module.build.dir}"/>
+        <delete file="${module.jar}"/>
+    </target>
+    <!--
+    **********************************************************
+    ** install - install the module in your local JOSM installation
+    **********************************************************
+    -->
+    <target name="install" depends="dist">
+        <property environment="env"/>
+        <condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins">
+            <and>
+                <os family="windows"/>
+            </and>
+        </condition>
+        <copy file="${module.jar}" todir="${josm.plugins.dir}/opendata/modules" overwrite="yes" />
+    </target>
+    <!--
+    ************************** Publishing the module *********************************** 
+    -->
+    <!-- commits the source tree for this module -->
+    <target name="commit-current">
+        <echo>Commiting the module source with message '${commit.message}' ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="commit"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="."/>
+        </exec>
+    </target>
+    <!-- updates (svn up) the source tree for this module -->
+    <target name="update-current">
+        <echo>Updating module source ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="."/>
+        </exec>
+        <echo>Updating ${module.jar} ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="../dist/${module.jar}"/>
+        </exec>
+    </target>
+    <!-- commits the module.jar -->
+    <target name="commit-dist">
+        <echo>
+    ***** Properties of published ${module.jar} *****
+    Commit message    : '${commit.message}'                    
+    Module-Version    : ${version.entry.commit.revision}
+    ***** / Properties of published ${module.jar} *****                    
+                        
+    Now commiting ${module.jar} ...
+    </echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="commit"/>
+            <arg value="${module.jar}"/>
+        </exec>
+    </target>
+    <!-- make sure svn is present as a command line tool -->
+    <target name="ensure-svn-present">
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false" failonerror="false" resultproperty="svn.exit.code">
+            <env key="LANG" value="C"/>
+            <arg value="--version"/>
+        </exec>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure svn is installed on your system.">
+            <!-- return code not set at all? Most likely svn isn't installed -->
+            <condition>
+                <not>
+                    <isset property="svn.exit.code"/>
+                </not>
+            </condition>
+        </fail>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure a working copy of svn is installed on your system.">
+            <!-- error code from SVN? Most likely svn is not what we are looking on this system -->
+            <condition>
+                <isfailure code="${svn.exit.code}"/>
+            </condition>
+        </fail>
+    </target>
+    <target name="publish" depends="ensure-svn-present,commit-current,update-current,clean,dist,commit-dist">
+    </target>
+</project>
Index: /applications/editors/josm/plugins/opendata/modules/fr.paris/gpl-3.0.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.paris/gpl-3.0.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.paris/gpl-3.0.txt	(revision 28000)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/ParisConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/ParisConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/ParisConstants.java	(revision 28000)
@@ -0,0 +1,36 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.paris;
+
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+
+public interface ParisConstants extends OdConstants {
+		
+	/**
+	 * Source
+	 */
+	public static final String SOURCE = "opendataparis";
+	
+	/**
+	 * Portal
+	 */
+	public static final String PORTAL = "http://opendata.paris.fr/opendata/jsp/site/Portal.jsp?";
+
+	/**
+	 * Icons
+	 */
+	public static final String ICON_PARIS_24 = "data.fr.paris_24.png";
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/ParisModule.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/ParisModule.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/ParisModule.java	(revision 28000)
@@ -0,0 +1,28 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.paris;
+
+import org.openstreetmap.josm.plugins.opendata.core.modules.AbstractModule;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleInformation;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.paris.datasets.urbanisme.SanisettesHandler;
+
+public class ParisModule extends AbstractModule {
+
+	public ParisModule(ModuleInformation info) {
+		super(info);
+        handlers.add(new SanisettesHandler());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/datasets/ParisDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/datasets/ParisDataSetHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/datasets/ParisDataSetHandler.java	(revision 28000)
@@ -0,0 +1,84 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.paris.datasets;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.openstreetmap.josm.data.osm.Tag;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.fr.FrenchDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.paris.ParisConstants;
+
+public abstract class ParisDataSetHandler extends FrenchDataSetHandler implements ParisConstants {
+	
+	private int documentId;
+	private int portletId;
+	
+	public ParisDataSetHandler(int documentId, int portletId) {
+		init(documentId, portletId);
+	}
+	
+	public ParisDataSetHandler(int documentId, int portletId, String relevantTag) {
+		super(relevantTag);
+		init(documentId, portletId);
+	}
+	
+	public ParisDataSetHandler(int documentId, int portletId, boolean relevantUnion, String ... relevantTags) {
+		super(relevantUnion, relevantTags);
+		init(documentId, portletId);
+	}
+
+	public ParisDataSetHandler(int documentId, int portletId, String ... relevantTags) {
+		this(documentId, portletId, false, relevantTags);
+	}
+
+	public ParisDataSetHandler(int documentId, int portletId, boolean relevantUnion, Tag ... relevantTags) {
+		super(relevantUnion, relevantTags);
+		init(documentId, portletId);
+	}
+
+	private final void init(int documentId, int portletId) {
+		this.documentId = documentId;
+		this.portletId = portletId;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getSource()
+	 */
+	@Override
+	public String getSource() {
+		return SOURCE;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getLocalPortalIconName()
+	 */
+	@Override
+	public String getLocalPortalIconName() {
+		return ICON_PARIS_24;
+	}
+
+	public final URL getLocalPortalURL() {
+		try {
+			if (documentId > 0) {
+				return new URL(PORTAL + "document_id="+documentId + "&portlet_id="+portletId);
+			}
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/datasets/urbanisme/SanisettesHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/datasets/urbanisme/SanisettesHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.paris/src/org/openstreetmap/josm/plugins/opendata/modules/fr/paris/datasets/urbanisme/SanisettesHandler.java	(revision 28000)
@@ -0,0 +1,35 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.paris.datasets.urbanisme;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.paris.datasets.ParisDataSetHandler;
+
+public class SanisettesHandler extends ParisDataSetHandler {
+
+	public SanisettesHandler() {
+		super(93, 106);
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsShpFilename(filename, "sanisettes");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.sncf/README
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.sncf/README	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.sncf/README	(revision 28000)
@@ -0,0 +1,11 @@
+README 
+======
+
+Readme for SNCF module of JOSM Open Data plugin
+
+    * Author: Don-vip
+    * License: GPL v3 (see gpl-3.0.txt)
+
+-------------------------------- DOCUMENTATION --------------------------------
+
+See http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/SNCF
Index: /applications/editors/josm/plugins/opendata/modules/fr.sncf/build.xml
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.sncf/build.xml	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.sncf/build.xml	(revision 28000)
@@ -0,0 +1,231 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!--
+** This is a template build file for a module of the JOSM opendata plugin.
+**
+** Usage
+** =====
+** To build it run
+**
+**    > ant dist
+**
+** To install the generated module locally (in you default opendata modules directory) run
+**
+**    > ant install
+**
+** The generated module jar is not automatically available in JOSMs opendata plugin configuration
+** dialog. You have to check it in first.
+**
+** Use the ant target 'publish' to check in the module and make it available to other
+** JOSM users:
+**    set the property commit.message
+** and run
+**    > ant publish
+**
+-->
+<project name="fr.sncf" default="dist" basedir=".">
+    <!-- enter the SVN commit message -->
+    <property name="commit.message" value="Commit message"/>
+    <!-- should not be necessary to change the following properties -->
+    <property name="josm" location="../../../../core/dist/josm-custom.jar"/>
+    <property name="plugin.dist.dir" value="../../../../dist"/>
+    <property name="opendata" location="${plugin.dist.dir}/opendata.jar"/>
+    <property name="module.build.dir" value="build"/>
+    <property name="module.src.dir" value="src"/>
+    <property name="ant.build.javac.source" value="1.6"/>
+    <property name="ant.build.javac.target" value="1.6"/>
+    <!-- this is the directory where the module jar is copied to -->
+    <property name="module.dist.dir" value="../../dist"/>
+    <property name="module.jar" value="${module.dist.dir}/${ant.project.name}.jar"/>
+	<!-- conditions -->
+    <condition property="resources.exist">
+        <available file="resources" type="dir" />
+    </condition>
+    <condition property="images.exist">
+        <available file="images" type="dir" />
+    </condition>
+    <!--
+    **********************************************************
+    ** init - initializes the build
+    **********************************************************
+    -->
+    <target name="init">
+        <mkdir dir="${module.build.dir}"/>
+        <mkdir dir="${module.build.dir}/META-INF"/>
+    </target>
+    <!--
+    **********************************************************
+    ** compile - compiles the source tree
+    **********************************************************
+    -->
+    <target name="compile" depends="init">
+        <echo message="compiling sources for ${module.jar} ... "/>
+        <javac srcdir="${module.src.dir}" debug="true" destdir="${module.build.dir}" includeAntRuntime="false">
+            <classpath>
+                <pathelement location="${josm}"/>
+                <pathelement location="${opendata}"/>
+            </classpath>
+            <compilerarg value="-Xlint:deprecation"/>
+            <compilerarg value="-Xlint:unchecked"/>
+        </javac>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-resources - copies resources dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-resources" if="resources.exist">
+        <copy todir="${module.build.dir}">
+            <fileset dir="resources" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-images - copies images dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-images" if="images.exist">
+        <copy todir="${module.build.dir}/images">
+            <fileset dir="images" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** dist - creates the module jar
+    **********************************************************
+    -->
+    <target name="dist" depends="compile,revision,copy-resources, copy-images">
+        <echo message="creating ${ant.project.name}.jar ... "/>
+        <copy todir="${module.build.dir}">
+            <fileset dir=".">
+                <include name="README"/>
+                <include name="gpl-3.0.txt"/>
+            </fileset>
+        </copy>
+        <jar destfile="${module.jar}" basedir="${module.build.dir}">
+            <!--
+            ************************************************
+            ** configure these properties. Most of them will
+            ** be copied to the module manifest file.
+            **
+            ************************************************
+            -->
+            <manifest>
+                <attribute name="Author" value="Don-vip"/>
+                <attribute name="Module-Class" value="org.openstreetmap.josm.plugins.opendata.modules.fr.sncf.SncfModule"/>
+                <attribute name="Module-Date" value="${version.entry.commit.date}"/>
+                <attribute name="Module-Description" value="SNCF"/>
+                <attribute name="Module-Icon" value="images/data.fr.sncf_24.png"/>
+                <!--<attribute name="Module-Link" value="http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/SNCF"/>-->
+                <attribute name="Module-Version" value="${version.entry.commit.revision}"/>
+            </manifest>
+        </jar>
+    </target>
+    <!--
+    **********************************************************
+    ** revision - extracts the current revision number for the
+    **    file build.number and stores it in the XML property
+    **    version.*
+    **********************************************************
+    -->
+    <target name="revision">
+        <exec append="false" output="REVISION" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="info"/>
+            <arg value="--xml"/>
+            <arg value="."/>
+        </exec>
+        <xmlproperty file="REVISION" prefix="version" keepRoot="false" collapseAttributes="true"/>
+        <delete file="REVISION"/>
+    </target>
+    <!--
+    **********************************************************
+    ** clean - clean up the build environment
+    **********************************************************
+    -->
+    <target name="clean">
+        <delete dir="${module.build.dir}"/>
+        <delete file="${module.jar}"/>
+    </target>
+    <!--
+    **********************************************************
+    ** install - install the module in your local JOSM installation
+    **********************************************************
+    -->
+    <target name="install" depends="dist">
+        <property environment="env"/>
+        <condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins">
+            <and>
+                <os family="windows"/>
+            </and>
+        </condition>
+        <copy file="${module.jar}" todir="${josm.plugins.dir}/opendata/modules" overwrite="yes"/>
+    </target>
+    <!--
+    ************************** Publishing the module *********************************** 
+    -->
+    <!-- commits the source tree for this module -->
+    <target name="commit-current">
+        <echo>Commiting the module source with message '${commit.message}' ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="commit"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="."/>
+        </exec>
+    </target>
+    <!-- updates (svn up) the source tree for this module -->
+    <target name="update-current">
+        <echo>Updating module source ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="."/>
+        </exec>
+        <echo>Updating ${module.jar} ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="../dist/${module.jar}"/>
+        </exec>
+    </target>
+    <!-- commits the module.jar -->
+    <target name="commit-dist">
+        <echo>
+    ***** Properties of published ${module.jar} *****
+    Commit message    : '${commit.message}'                    
+    Module-Version    : ${version.entry.commit.revision}
+    ***** / Properties of published ${module.jar} *****                    
+                        
+    Now commiting ${module.jar} ...
+    </echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="commit"/>
+            <arg value="${module.jar}"/>
+        </exec>
+    </target>
+    <!-- make sure svn is present as a command line tool -->
+    <target name="ensure-svn-present">
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false" failonerror="false" resultproperty="svn.exit.code">
+            <env key="LANG" value="C"/>
+            <arg value="--version"/>
+        </exec>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure svn is installed on your system.">
+            <!-- return code not set at all? Most likely svn isn't installed -->
+            <condition>
+                <not>
+                    <isset property="svn.exit.code"/>
+                </not>
+            </condition>
+        </fail>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure a working copy of svn is installed on your system.">
+            <!-- error code from SVN? Most likely svn is not what we are looking on this system -->
+            <condition>
+                <isfailure code="${svn.exit.code}"/>
+            </condition>
+        </fail>
+    </target>
+    <target name="publish" depends="ensure-svn-present,commit-current,update-current,clean,dist,commit-dist">
+    </target>
+</project>
Index: /applications/editors/josm/plugins/opendata/modules/fr.sncf/gpl-3.0.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.sncf/gpl-3.0.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.sncf/gpl-3.0.txt	(revision 28000)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/SncfConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/SncfConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/SncfConstants.java	(revision 28000)
@@ -0,0 +1,37 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.sncf;
+
+import org.openstreetmap.josm.plugins.opendata.core.datasets.fr.FrenchConstants;
+
+public interface SncfConstants extends FrenchConstants {
+	
+	/**
+	 * Source
+	 */
+	public static final String SOURCE = "SNCF";
+	
+	/**
+	 * Portal
+	 */
+	public static final String PORTAL = "http://opendata-test.tumblr.com/";
+
+	/**
+	 * Icons
+	 */
+	public static final String ICON_16 = "data.fr.sncf_16.png";
+	public static final String ICON_24 = "data.fr.sncf_24.png";
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/SncfModule.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/SncfModule.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/SncfModule.java	(revision 28000)
@@ -0,0 +1,28 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.sncf;
+
+import org.openstreetmap.josm.plugins.opendata.core.modules.AbstractModule;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleInformation;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.sncf.datasets.EquipementsHandler;
+
+public class SncfModule extends AbstractModule {
+
+	public SncfModule(ModuleInformation info) {
+		super(info);
+		handlers.add(new EquipementsHandler());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/datasets/EquipementsHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/datasets/EquipementsHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/datasets/EquipementsHandler.java	(revision 28000)
@@ -0,0 +1,36 @@
+package org.openstreetmap.josm.plugins.opendata.modules.fr.sncf.datasets;
+
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+
+public class EquipementsHandler extends SncfDataSetHandler {
+
+	public EquipementsHandler() {
+		super("equipementsgares");
+		setSingleProjection(lambert4Zones[1]); // Lambert II
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsXlsFilename(filename, "gare_20......");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			replace(n, "nom gare", "name");
+			n.put("railway", "station");
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.fr.FrenchDataSetHandler#getSpreadSheetCoor(org.openstreetmap.josm.data.coor.EastNorth, java.lang.String[])
+	 */
+	@Override
+	public LatLon getSpreadSheetCoor(EastNorth en, String[] fields) {
+		// Lambert II coordinates offset by 2000000 (see http://fr.wikipedia.org/wiki/Projection_conique_conforme_de_Lambert#Projections_officielles_en_France_m.C3.A9tropolitaine)
+		return super.getSpreadSheetCoor(new EastNorth(en.getX(), en.getY()-2000000), fields);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/datasets/SncfDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/datasets/SncfDataSetHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.sncf/src/org/openstreetmap/josm/plugins/opendata/modules/fr/sncf/datasets/SncfDataSetHandler.java	(revision 28000)
@@ -0,0 +1,84 @@
+package org.openstreetmap.josm.plugins.opendata.modules.fr.sncf.datasets;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.openstreetmap.josm.data.osm.Tag;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.fr.FrenchDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.sncf.SncfConstants;
+
+public abstract class SncfDataSetHandler extends FrenchDataSetHandler implements SncfConstants {
+	
+	private String portalId;
+	
+	public SncfDataSetHandler(String portalId) {
+		init(portalId);
+	}
+	
+	public SncfDataSetHandler(String portalId, String relevantTag) {
+		super(relevantTag);
+		init(portalId);
+	}
+	
+	public SncfDataSetHandler(String portalId, boolean relevantUnion, String ... relevantTags) {
+		super(relevantUnion, relevantTags);
+		init(portalId);
+	}
+
+	public SncfDataSetHandler(String portalId, String ... relevantTags) {
+		this(portalId, false, relevantTags);
+	}
+
+	/*public ToulouseDataSetHandler(int portalId, Tag relevantTag) {
+		super(relevantTag);
+		init(portalId);
+	}*/
+	
+	public SncfDataSetHandler(String portalId, boolean relevantUnion, Tag ... relevantTags) {
+		super(relevantUnion, relevantTags);
+		init(portalId);
+	}
+
+	/*public ToulouseDataSetHandler(int portalId, Tag ... relevantTags) {
+		this(portalId, false, relevantTags);
+	}*/
+	
+	private final void init(String portalId) {
+		this.portalId = portalId;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getSource()
+	 */
+	@Override
+	public String getSource() {
+		return SOURCE;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getLocalPortalIconName()
+	 */
+	@Override
+	public String getLocalPortalIconName() {
+		return ICON_24;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getDataLayerIconName()
+	 */
+	@Override
+	public String getDataLayerIconName() {
+		return ICON_16;
+	}
+
+	public final URL getLocalPortalURL() {
+		try {
+			if (portalId != null) {
+				return new URL(PORTAL + portalId);
+			}
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/README
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/README	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/README	(revision 28000)
@@ -0,0 +1,11 @@
+README 
+======
+
+Readme for Toulouse module of JOSM Open Data plugin
+
+    * Author: Don-vip
+    * License: GPL v3 (see gpl-3.0.txt)
+
+-------------------------------- DOCUMENTATION --------------------------------
+
+See http://wiki.openstreetmap.org/wiki/JOSM/Plugins/OpenData/Toulouse
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/build.xml
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/build.xml	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/build.xml	(revision 28000)
@@ -0,0 +1,231 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<!--
+** This is a template build file for a module of the JOSM opendata plugin.
+**
+** Usage
+** =====
+** To build it run
+**
+**    > ant dist
+**
+** To install the generated module locally (in you default opendata modules directory) run
+**
+**    > ant install
+**
+** The generated module jar is not automatically available in JOSMs opendata plugin configuration
+** dialog. You have to check it in first.
+**
+** Use the ant target 'publish' to check in the module and make it available to other
+** JOSM users:
+**    set the property commit.message
+** and run
+**    > ant publish
+**
+-->
+<project name="fr.toulouse" default="dist" basedir=".">
+    <!-- enter the SVN commit message -->
+    <property name="commit.message" value="Commit message"/>
+    <!-- should not be necessary to change the following properties -->
+    <property name="josm" location="../../../../core/dist/josm-custom.jar"/>
+    <property name="plugin.dist.dir" value="../../../../dist"/>
+    <property name="opendata" location="${plugin.dist.dir}/opendata.jar"/>
+    <property name="module.build.dir" value="build"/>
+    <property name="module.src.dir" value="src"/>
+    <property name="ant.build.javac.source" value="1.6"/>
+    <property name="ant.build.javac.target" value="1.6"/>
+    <!-- this is the directory where the module jar is copied to -->
+    <property name="module.dist.dir" value="../../dist"/>
+    <property name="module.jar" value="${module.dist.dir}/${ant.project.name}.jar"/>
+	<!-- conditions -->
+    <condition property="resources.exist">
+        <available file="resources" type="dir" />
+    </condition>
+    <condition property="images.exist">
+        <available file="images" type="dir" />
+    </condition>
+    <!--
+    **********************************************************
+    ** init - initializes the build
+    **********************************************************
+    -->
+    <target name="init">
+        <mkdir dir="${module.build.dir}"/>
+        <mkdir dir="${module.build.dir}/META-INF"/>
+    </target>
+    <!--
+    **********************************************************
+    ** compile - compiles the source tree
+    **********************************************************
+    -->
+    <target name="compile" depends="init">
+        <echo message="compiling sources for ${module.jar} ... "/>
+        <javac srcdir="${module.src.dir}" debug="true" destdir="${module.build.dir}" includeAntRuntime="false">
+            <classpath>
+                <pathelement location="${josm}"/>
+                <pathelement location="${opendata}"/>
+            </classpath>
+            <compilerarg value="-Xlint:deprecation"/>
+            <compilerarg value="-Xlint:unchecked"/>
+        </javac>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-resources - copies resources dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-resources" if="resources.exist">
+        <copy todir="${module.build.dir}">
+            <fileset dir="resources" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** copy-images - copies images dir to build dir
+    **********************************************************
+    -->
+    <target name="copy-images" if="images.exist">
+        <copy todir="${module.build.dir}/images">
+            <fileset dir="images" />
+        </copy>
+    </target>
+    <!--
+    **********************************************************
+    ** dist - creates the module jar
+    **********************************************************
+    -->
+    <target name="dist" depends="compile,revision,copy-resources, copy-images">
+        <echo message="creating ${ant.project.name}.jar ... "/>
+        <copy todir="${module.build.dir}">
+            <fileset dir=".">
+                <include name="README"/>
+                <include name="gpl-3.0.txt"/>
+            </fileset>
+        </copy>
+        <jar destfile="${module.jar}" basedir="${module.build.dir}">
+            <!--
+            ************************************************
+            ** configure these properties. Most of them will
+            ** be copied to the module manifest file.
+            **
+            ************************************************
+            -->
+            <manifest>
+                <attribute name="Author" value="Don-vip"/>
+                <attribute name="Module-Class" value="org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.ToulouseModule"/>
+                <attribute name="Module-Date" value="${version.entry.commit.date}"/>
+                <attribute name="Module-Description" value="Toulouse"/>
+                <attribute name="Module-Icon" value="images/data.fr.toulouse_24.png"/>
+                <attribute name="Module-Link" value="http://wiki.openstreetmap.org/wiki/Toulouse/GrandToulouseData"/>
+                <attribute name="Module-Version" value="${version.entry.commit.revision}"/>
+            </manifest>
+        </jar>
+    </target>
+    <!--
+    **********************************************************
+    ** revision - extracts the current revision number for the
+    **    file build.number and stores it in the XML property
+    **    version.*
+    **********************************************************
+    -->
+    <target name="revision">
+        <exec append="false" output="REVISION" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="info"/>
+            <arg value="--xml"/>
+            <arg value="."/>
+        </exec>
+        <xmlproperty file="REVISION" prefix="version" keepRoot="false" collapseAttributes="true"/>
+        <delete file="REVISION"/>
+    </target>
+    <!--
+    **********************************************************
+    ** clean - clean up the build environment
+    **********************************************************
+    -->
+    <target name="clean">
+        <delete dir="${module.build.dir}"/>
+        <delete file="${module.jar}"/>
+    </target>
+    <!--
+    **********************************************************
+    ** install - install the module in your local JOSM installation
+    **********************************************************
+    -->
+    <target name="install" depends="dist">
+        <property environment="env"/>
+        <condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins">
+            <and>
+                <os family="windows"/>
+            </and>
+        </condition>
+        <copy file="${module.jar}" todir="${josm.plugins.dir}/opendata/modules" overwrite="yes"/>
+    </target>
+    <!--
+    ************************** Publishing the module *********************************** 
+    -->
+    <!-- commits the source tree for this module -->
+    <target name="commit-current">
+        <echo>Commiting the module source with message '${commit.message}' ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="commit"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="."/>
+        </exec>
+    </target>
+    <!-- updates (svn up) the source tree for this module -->
+    <target name="update-current">
+        <echo>Updating module source ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="."/>
+        </exec>
+        <echo>Updating ${module.jar} ...</echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="up"/>
+            <arg value="../dist/${module.jar}"/>
+        </exec>
+    </target>
+    <!-- commits the module.jar -->
+    <target name="commit-dist">
+        <echo>
+    ***** Properties of published ${module.jar} *****
+    Commit message    : '${commit.message}'                    
+    Module-Version    : ${version.entry.commit.revision}
+    ***** / Properties of published ${module.jar} *****                    
+                        
+    Now commiting ${module.jar} ...
+    </echo>
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false">
+            <env key="LANG" value="C"/>
+            <arg value="-m '${commit.message}'"/>
+            <arg value="commit"/>
+            <arg value="${module.jar}"/>
+        </exec>
+    </target>
+    <!-- make sure svn is present as a command line tool -->
+    <target name="ensure-svn-present">
+        <exec append="true" output="svn.log" executable="svn" failifexecutionfails="false" failonerror="false" resultproperty="svn.exit.code">
+            <env key="LANG" value="C"/>
+            <arg value="--version"/>
+        </exec>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure svn is installed on your system.">
+            <!-- return code not set at all? Most likely svn isn't installed -->
+            <condition>
+                <not>
+                    <isset property="svn.exit.code"/>
+                </not>
+            </condition>
+        </fail>
+        <fail message="Fatal: command 'svn --version' failed. Please make sure a working copy of svn is installed on your system.">
+            <!-- error code from SVN? Most likely svn is not what we are looking on this system -->
+            <condition>
+                <isfailure code="${svn.exit.code}"/>
+            </condition>
+        </fail>
+    </target>
+    <target name="publish" depends="ensure-svn-present,commit-current,update-current,clean,dist,commit-dist">
+    </target>
+</project>
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/gpl-3.0.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/gpl-3.0.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/gpl-3.0.txt	(revision 28000)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/ToulouseConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/ToulouseConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/ToulouseConstants.java	(revision 28000)
@@ -0,0 +1,42 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse;
+
+import org.openstreetmap.josm.plugins.opendata.core.datasets.fr.FrenchConstants;
+
+public interface ToulouseConstants extends FrenchConstants {
+	
+	/**
+	 * Source
+	 */
+	public static final String SOURCE = "GrandToulouse";
+	
+	/**
+	 * Wiki
+	 */
+	public static final String WIKI = "http://wiki.openstreetmap.org/wiki/Toulouse/GrandToulouseData";
+
+	/**
+	 * Portal
+	 */
+	public static final String PORTAL = "http://data.grandtoulouse.fr/les-donnees/-/opendata/card/";
+
+	/**
+	 * Icons
+	 */
+	public static final String ICON_CROIX_16 = "data.fr.toulouse_16.png";
+	public static final String ICON_CROIX_24 = "data.fr.toulouse_24.png";
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/ToulouseModule.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/ToulouseModule.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/ToulouseModule.java	(revision 28000)
@@ -0,0 +1,98 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse;
+
+import org.openstreetmap.josm.plugins.opendata.core.modules.AbstractModule;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleInformation;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.associations.Club3eAgeHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.citoyennete.BureauxVoteHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.citoyennete.MairieAnnexeHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.citoyennete.MairieHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.citoyennete.PolesTerritoriauxHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.citoyennete.QuartiersHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.citoyennete.SecteursHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.culture.BibliothequesHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.culture.EquipementCulturelBalmaHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.culture.LudothequeHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.culture.MuseeHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.culture.TheatreHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.enfance.CrechesHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.enfance.EcoleBalmaHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.enfance.EcoleElementaireHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.enfance.EcoleMaternelleHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.enfance.PetiteEnfanceEtJeunesseBalmaHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.environnement.RecupEmballageHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.environnement.RecupVerreHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.environnement.StationEpurationHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.patrimoine.Parcelles1680Handler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.patrimoine.Parcelles1830Handler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.sport.InstallationSportiveBalmaHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.topographie.AltimetrieVoieHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport.HorodateurHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport.MetroStationHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport.PMRHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport.PistesCyclablesHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport.ReseauTisseoHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport.TramwayStationHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport.VeloToulouseHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport.Zone30Handler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.urbanisme.CommuneHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.urbanisme.NumerosRueHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.urbanisme.SanisetteHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.urbanisme.VoirieHandler;
+
+public class ToulouseModule extends AbstractModule {
+
+	public ToulouseModule(ModuleInformation info) {
+		super(info);
+        handlers.add(new SanisetteHandler());
+        handlers.add(new NumerosRueHandler());
+        handlers.add(new CommuneHandler());
+        handlers.add(new VoirieHandler());
+        handlers.add(new Zone30Handler());
+        handlers.add(new HorodateurHandler());
+        handlers.add(new VeloToulouseHandler());
+        handlers.add(new AltimetrieVoieHandler());
+        handlers.add(new MetroStationHandler());
+        handlers.add(new TramwayStationHandler());
+        handlers.add(new Parcelles1680Handler());
+        handlers.add(new Parcelles1830Handler());
+        handlers.add(new PMRHandler());
+        handlers.add(new PistesCyclablesHandler());
+        handlers.add(new BureauxVoteHandler());
+        handlers.add(new Club3eAgeHandler());
+        handlers.add(new CrechesHandler());
+        handlers.add(new EcoleElementaireHandler());
+        handlers.add(new EcoleMaternelleHandler());
+        handlers.add(new LudothequeHandler());
+        handlers.add(new MairieHandler());
+        handlers.add(new MairieAnnexeHandler());
+        handlers.add(new BibliothequesHandler());
+        handlers.add(new MuseeHandler());
+        handlers.add(new PolesTerritoriauxHandler());
+        handlers.add(new QuartiersHandler());
+        handlers.add(new SecteursHandler());
+        handlers.add(new StationEpurationHandler());
+        handlers.add(new TheatreHandler());
+        handlers.add(new RecupEmballageHandler());
+        handlers.add(new RecupVerreHandler());
+        handlers.add(new ReseauTisseoHandler());
+        handlers.add(new EcoleBalmaHandler());
+        handlers.add(new PetiteEnfanceEtJeunesseBalmaHandler());
+        handlers.add(new EquipementCulturelBalmaHandler());
+        handlers.add(new InstallationSportiveBalmaHandler());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/ToulouseDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/ToulouseDataSetHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/ToulouseDataSetHandler.java	(revision 28000)
@@ -0,0 +1,104 @@
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.openstreetmap.josm.data.osm.Tag;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.fr.FrenchDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.ToulouseConstants;
+
+public abstract class ToulouseDataSetHandler extends FrenchDataSetHandler implements ToulouseConstants {
+	
+	private int portalId;
+	private String wikiPage;
+	
+	public ToulouseDataSetHandler(int portalId) {
+		init(portalId);
+	}
+	
+	public ToulouseDataSetHandler(int portalId, String relevantTag) {
+		super(relevantTag);
+		init(portalId);
+	}
+	
+	public ToulouseDataSetHandler(int portalId, boolean relevantUnion, String ... relevantTags) {
+		super(relevantUnion, relevantTags);
+		init(portalId);
+	}
+
+	public ToulouseDataSetHandler(int portalId, String ... relevantTags) {
+		this(portalId, false, relevantTags);
+	}
+
+	/*public ToulouseDataSetHandler(int portalId, Tag relevantTag) {
+		super(relevantTag);
+		init(portalId);
+	}*/
+	
+	public ToulouseDataSetHandler(int portalId, boolean relevantUnion, Tag ... relevantTags) {
+		super(relevantUnion, relevantTags);
+		init(portalId);
+	}
+
+	/*public ToulouseDataSetHandler(int portalId, Tag ... relevantTags) {
+		this(portalId, false, relevantTags);
+	}*/
+	
+	private final void init(int portalId) {
+		this.portalId = portalId;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getSource()
+	 */
+	@Override
+	public String getSource() {
+		return SOURCE;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getLocalPortalIconName()
+	 */
+	@Override
+	public String getLocalPortalIconName() {
+		return ICON_CROIX_24;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getDataLayerIconName()
+	 */
+	@Override
+	public String getDataLayerIconName() {
+		return ICON_CROIX_16;
+	}
+
+	public final URL getLocalPortalURL() {
+		try {
+			if (portalId > 0) {
+				return new URL(PORTAL + portalId + "--");
+			}
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.fr.opendata.datasets.AbstractDataSetHandler#getWikiURL()
+	 */
+	@Override
+	public URL getWikiURL() {
+		try {
+			if (wikiPage != null && !wikiPage.isEmpty()) {
+				return new URL(WIKI + "/" + wikiPage);
+			}
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+	
+	protected final void setWikiPage(String wikiPage) {
+		this.wikiPage = wikiPage;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/associations/Club3eAgeHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/associations/Club3eAgeHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/associations/Club3eAgeHandler.java	(revision 28000)
@@ -0,0 +1,42 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.associations;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class Club3eAgeHandler extends ToulouseDataSetHandler {
+
+	public Club3eAgeHandler() {
+		super(12587, "leisure=club", "club=elderly");
+		setWikiPage("Clubs du 3ème âge");
+	}
+	
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Club_3E_AGE");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			replace(n, "Nom", "name");
+			n.put("leisure", "club");
+			n.put("club", "elderly");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/BureauxVoteHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/BureauxVoteHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/BureauxVoteHandler.java	(revision 28000)
@@ -0,0 +1,41 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.citoyennete;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class BureauxVoteHandler extends ToulouseDataSetHandler {
+
+	public BureauxVoteHandler() {
+		super(12550, "polling_station");
+		setWikiPage("Bureaux de vote 2012");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzTabFilename(filename, "Lieu_vote_2012");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Relation r : ds.getRelations()) {
+			replace(r, "TEXT", "name");
+			r.put("polling_station", "2012");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/MairieAnnexeHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/MairieAnnexeHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/MairieAnnexeHandler.java	(revision 28000)
@@ -0,0 +1,44 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.citoyennete;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+
+
+public class MairieAnnexeHandler extends MairieHandler {
+	
+	public MairieAnnexeHandler() {
+		super(12560, "Mairies annexes");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Mairie_Annexe");
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.portals.fr.toulouse.datasets.citoyennete.MairieHandler#updateDataSet(org.openstreetmap.josm.data.osm.DataSet)
+	 */
+	@Override
+	public void updateDataSet(DataSet ds) {
+		super.updateDataSet(ds);
+		for (Node n : ds.getNodes()) {
+			replaceFax(n, "Fax");
+			n.remove("Num");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/MairieHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/MairieHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/MairieHandler.java	(revision 28000)
@@ -0,0 +1,50 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.citoyennete;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class MairieHandler extends ToulouseDataSetHandler {
+
+	public MairieHandler() {
+		this(12554, "Mairies");
+	}
+	
+	protected MairieHandler(int portalId, String wikiPage) {
+		super(portalId, "amenity=townhall");
+		setWikiPage(wikiPage);
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Mairie");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			replace(n, "Mairie", "name");
+			n.put("amenity", "townhall");
+			replaceOpeningHours(n, "Horaire_ouverture");
+			n.remove("INSEE");
+			n.remove("Libelle");
+			replacePhone(n, "Telephone");
+			n.remove("Type");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/PolesTerritoriauxHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/PolesTerritoriauxHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/PolesTerritoriauxHandler.java	(revision 28000)
@@ -0,0 +1,39 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.citoyennete;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class PolesTerritoriauxHandler extends ToulouseDataSetHandler {
+
+	public PolesTerritoriauxHandler() {
+		super(12568);
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzTabFilename(filename, "Poles_territoriaux");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Relation r : ds.getRelations()) {
+			replace(r, "Nom_pole", "name");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/QuartiersHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/QuartiersHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/QuartiersHandler.java	(revision 28000)
@@ -0,0 +1,50 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.citoyennete;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class QuartiersHandler extends ToulouseDataSetHandler {
+
+	public QuartiersHandler() {
+		super(12574, "admin_level=11");
+		setWikiPage("Quartiers de proximité");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzTabFilename(filename, "Quartiers");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Relation r : ds.getRelations()) {
+			r.remove("name");
+			replace(r, "Quartier", "ref");
+			replace(r, "Nom_Quartier", "description");
+			r.put("type", "boundary");
+			r.put("boundary", "administrative");
+			r.put("admin_level", "11");
+			r.remove("Adjoint_Secteur");
+			r.remove("Elu_Referent_Quartier");
+			r.remove("Id");
+			r.remove("Nom_Secteur");
+			r.remove("Secteur");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/SecteursHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/SecteursHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/citoyennete/SecteursHandler.java	(revision 28000)
@@ -0,0 +1,47 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.citoyennete;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class SecteursHandler extends ToulouseDataSetHandler {
+
+	public SecteursHandler() {
+		super(12580, "admin_level=10");
+		setWikiPage("Secteurs de proximité");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzTabFilename(filename, "Secteurs");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Relation r : ds.getRelations()) {
+			r.remove("name");
+			replace(r, "Secteur", "ref");
+			replace(r, "Nom_Secteur", "description");
+			r.put("type", "boundary");
+			r.put("boundary", "administrative");
+			r.put("admin_level", "10");
+			r.remove("Adjoint_Secteur");
+			r.remove("Charge_de_Secteur");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/BibliothequesHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/BibliothequesHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/BibliothequesHandler.java	(revision 28000)
@@ -0,0 +1,42 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.culture;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class BibliothequesHandler extends ToulouseDataSetHandler {
+
+	public BibliothequesHandler() {
+		super(12402, "amenity=library");
+		setWikiPage("Médiathèques, bibliothèques et bibliobus");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Bibliotheques");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			replace(n, "Nom", "name");
+			replace(n, "Site_Internet", "website");
+			n.put("amenity", "library");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/EquipementCulturelBalmaHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/EquipementCulturelBalmaHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/EquipementCulturelBalmaHandler.java	(revision 28000)
@@ -0,0 +1,44 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.culture;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class EquipementCulturelBalmaHandler extends ToulouseDataSetHandler {
+
+	public EquipementCulturelBalmaHandler() {
+		super(13997);
+		setWikiPage("Équipements Culturels");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzFilename(filename, "culture");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			if (n.get("name").equalsIgnoreCase("Bibliothèque")) {
+				n.put("amenity", "library");
+			} else if (n.get("name").equalsIgnoreCase("Auditorium")) {
+				n.put("amenity", "auditorium");
+			}
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/LudothequeHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/LudothequeHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/LudothequeHandler.java	(revision 28000)
@@ -0,0 +1,48 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.culture;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class LudothequeHandler extends ToulouseDataSetHandler {
+
+	public LudothequeHandler() {
+		super(12420, "amenity=toy_library");
+		setWikiPage("Ludothèques");
+	}
+	
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Ludotheques");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			replace(n, "NOM", "name");
+			n.put("amenity", "toy_library");
+			n.remove("ADRESSE");
+			n.remove("CP");
+			n.remove("INSEE");
+			n.remove("NATURE");
+			n.remove("NUM");
+			n.remove("QUARTIER");
+			n.remove("STIADR");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/MuseeHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/MuseeHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/MuseeHandler.java	(revision 28000)
@@ -0,0 +1,56 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.culture;
+
+import org.apache.commons.lang3.text.WordUtils;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class MuseeHandler extends ToulouseDataSetHandler {
+
+	public MuseeHandler() {
+		super(12426, "tourism=museum");
+		setWikiPage("Musées");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Musee");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			replace(n, "NOMS", "name");
+			replace(n, "SITE_INTERNET", "contact:website");
+			n.put("tourism", "museum");
+			n.remove("ADRESSES");
+			n.remove("Num");
+			n.remove("Index");
+			replacePhone(n, "TELEPHONE");
+			String name = WordUtils.capitalizeFully(n.get("name")).replace("Musee", "Musée").replace(" D ", " d'").replace(" L ", " l'").trim();
+			int index = name.indexOf("Musée");
+			if (index > 1) {
+				name = name.substring(index) + " " + name.substring(0, index-1);
+			}
+			while (name.contains("  ")) {
+				name = name.replace("  ", " ");
+			}
+			n.put("name", name);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/TheatreHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/TheatreHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/culture/TheatreHandler.java	(revision 28000)
@@ -0,0 +1,54 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.culture;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class TheatreHandler extends ToulouseDataSetHandler {
+
+	public TheatreHandler() {
+		super(12448, "amenity=theatre");
+		setWikiPage("Théâtres");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Theatre");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			replace(n, "NOMS", "name");
+			replace(n, "Site_Internet", "contact:website");
+			n.put("amenity", "theatre");
+			n.remove("ADRESSES");
+			n.remove("Description");
+			n.remove("Index");
+			n.remove("NUM");
+			replacePhone(n, "Telephone");
+			String type = n.get("Type");
+			if (type != null) {
+				if (type.equals("MUNICIPAL")) {
+					n.put("operator", "Mairie de Toulouse");
+				}
+				n.remove("Type");
+			}
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/CrechesHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/CrechesHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/CrechesHandler.java	(revision 28000)
@@ -0,0 +1,41 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.enfance;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class CrechesHandler extends ToulouseDataSetHandler {
+
+	public CrechesHandler() {
+		super(12462, "amenity=kindergarten");
+		setWikiPage("Crèches");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Creches");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.put("amenity", "kindergarten");
+			replace(n, "NOM", "name");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleBalmaHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleBalmaHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleBalmaHandler.java	(revision 28000)
@@ -0,0 +1,40 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.enfance;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class EcoleBalmaHandler extends ToulouseDataSetHandler {
+
+	public EcoleBalmaHandler() {
+		super(13993, "amenity=school");
+		setWikiPage("Écoles");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzFilename(filename, "Ecoles");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.put("amenity", "school");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleElementaireHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleElementaireHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleElementaireHandler.java	(revision 28000)
@@ -0,0 +1,46 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.enfance;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class EcoleElementaireHandler extends ToulouseDataSetHandler {
+
+	public EcoleElementaireHandler() {
+		super(12474, "amenity=school");
+		setWikiPage("Écoles élémentaires publiques");
+		for (String forbidden : new String[]{"maternelle","primaire","collège","lycée","secondaire"}) {
+			addForbiddenTag("school:FR="+forbidden);
+		}
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Ecoles_Elem_Publiques");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.put("amenity", "school");
+			n.put("school:FR", "elementaire");
+			n.put("operator", "public");
+			replace(n, "Ecole", "name");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleMaternelleHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleMaternelleHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/EcoleMaternelleHandler.java	(revision 28000)
@@ -0,0 +1,46 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.enfance;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class EcoleMaternelleHandler extends ToulouseDataSetHandler {
+
+	public EcoleMaternelleHandler() {
+		super(12490, "amenity=school");
+		setWikiPage("Écoles maternelles publiques");
+		for (String forbidden : new String[]{"élémentaire","primaire","collège","lycée","secondaire"}) {
+			addForbiddenTag("school:FR="+forbidden);
+		}
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Ecoles_Mat_Publiques");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.put("amenity", "school");
+			n.put("school:FR", "maternelle");
+			n.put("operator", "public");
+			replace(n, "Ecole", "name");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/PetiteEnfanceEtJeunesseBalmaHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/PetiteEnfanceEtJeunesseBalmaHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/enfance/PetiteEnfanceEtJeunesseBalmaHandler.java	(revision 28000)
@@ -0,0 +1,42 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.enfance;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class PetiteEnfanceEtJeunesseBalmaHandler extends ToulouseDataSetHandler {
+
+	public PetiteEnfanceEtJeunesseBalmaHandler() {
+		super(14001);
+		setWikiPage("Petite enfance et jeunesse");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzFilename(filename, "Petite enfance et jeunesse");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			if (n.get("name").equalsIgnoreCase("Crèche")) {
+				n.put("amenity", "kindergarten");
+			}
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/RecupEmballageHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/RecupEmballageHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/RecupEmballageHandler.java	(revision 28000)
@@ -0,0 +1,47 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.environnement;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class RecupEmballageHandler extends ToulouseDataSetHandler {
+
+	public RecupEmballageHandler() {
+		super(12494, "amenity=recycling");
+		setWikiPage("Récup' Emballage");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Recup_Emballage");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.remove("name");
+			n.put("amenity", "recycling");
+			n.put("recycling_type", "container");
+			n.put("recycling:plastic_bottles", "yes");
+			n.put("recycling:beverage_cartons", "yes");
+			n.put("recycling:cardboard", "yes");
+			n.put("recycling:newspaper", "yes");
+			n.put("recycling:magazines", "yes");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/RecupVerreHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/RecupVerreHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/RecupVerreHandler.java	(revision 28000)
@@ -0,0 +1,43 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.environnement;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class RecupVerreHandler extends ToulouseDataSetHandler {
+
+	public RecupVerreHandler() {
+		super(12496, "amenity=recycling");
+		setWikiPage("Récup' Verre");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Recup_Verre");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.remove("name");
+			n.put("amenity", "recycling");
+			n.put("recycling:glass", "no");
+			n.put("recycling:glass_bottles", "yes");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/StationEpurationHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/StationEpurationHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/environnement/StationEpurationHandler.java	(revision 28000)
@@ -0,0 +1,41 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.environnement;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class StationEpurationHandler extends ToulouseDataSetHandler {
+
+	public StationEpurationHandler() {
+		super(12500, "man_made=wastewater_plant");
+		setWikiPage("Stations d'épuration");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Stations_epurations");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			replace(n, "NOM_STATION", "name");
+			n.put("man_made", "wastewater_plant");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/patrimoine/Parcelles1680Handler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/patrimoine/Parcelles1680Handler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/patrimoine/Parcelles1680Handler.java	(revision 28000)
@@ -0,0 +1,39 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.patrimoine;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class Parcelles1680Handler extends ToulouseDataSetHandler {
+
+	public Parcelles1680Handler() {
+		super(12514);
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzTabFilename(filename, "Parcelles_1680");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Relation r : ds.getRelations()) {
+			replace(r, "Nom_prenom", "name");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/patrimoine/Parcelles1830Handler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/patrimoine/Parcelles1830Handler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/patrimoine/Parcelles1830Handler.java	(revision 28000)
@@ -0,0 +1,39 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.patrimoine;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class Parcelles1830Handler extends ToulouseDataSetHandler {
+
+	public Parcelles1830Handler() {
+		super(12534);
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzTabFilename(filename, "Parcelles_1830");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Relation r : ds.getRelations()) {
+			replace(r, "Nom_prenom", "name");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/sport/InstallationSportiveBalmaHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/sport/InstallationSportiveBalmaHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/sport/InstallationSportiveBalmaHandler.java	(revision 28000)
@@ -0,0 +1,57 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.sport;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class InstallationSportiveBalmaHandler extends ToulouseDataSetHandler {
+
+	public InstallationSportiveBalmaHandler() {
+		super(14010);
+		setWikiPage("Installations sportives");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzFilename(filename, "Sports");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			if (n.get("name").startsWith("Gymnase")) {
+				n.put("leisure", "sports_centre");
+			} else if (n.get("name").startsWith("Piscine")) {
+				n.put("leisure", "swimming_pool");
+				n.put("sport", "swimming");
+			} else if (n.get("name").startsWith("Skate")) {
+				n.put("leisure", "skate_park");
+				n.put("sport", "skateboard");
+			} else if (n.get("name").startsWith("Tennis")) {
+				n.put("leisure", "pitch");
+				n.put("sport", "tennis");
+			} else if (n.get("name").startsWith("Stade")) {
+				n.put("leisure", "pitch");
+			} else if (n.get("name").startsWith("Dojo")) {
+				n.put("amenity", "dojo");
+			} else if (n.get("name").startsWith("Boulodrome")) {
+				n.put("sport", "boules");
+			}
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/topographie/AltimetrieVoieHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/topographie/AltimetrieVoieHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/topographie/AltimetrieVoieHandler.java	(revision 28000)
@@ -0,0 +1,40 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.topographie;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class AltimetrieVoieHandler extends ToulouseDataSetHandler  {
+	
+	public AltimetrieVoieHandler() {
+		super(12660, "ele");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "XYZ_PT_ALTI_VOIES");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			//replace(n, "name", "ele");
+			n.put("ele", n.get("name")); // name conserve pour voir la hauteur directement (hack, FIXME)
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/HorodateurHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/HorodateurHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/HorodateurHandler.java	(revision 28000)
@@ -0,0 +1,115 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.text.WordUtils;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class HorodateurHandler extends ToulouseDataSetHandler {
+
+	public HorodateurHandler() {
+		super(12540, "vending=parking_tickets");
+		setWikiPage("Horodateurs");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Horodateur");
+	}
+	
+	private String parseHour(String hour) {
+		String s = hour.replaceFirst("[hH]", ":");
+		if (s.endsWith(":")) {
+			s += "00";
+		}
+		return s;
+	}
+	
+	protected String parseOpeningHours(String horaire) {
+		final String hour = "\\p{Digit}{1,2}[hH]\\p{Digit}{0,2}";
+		final String sep  = "[ -/]+";
+		final String hours = "("+hour+sep+hour+")";
+		final Pattern p = Pattern.compile(hours+"(?:"+sep+hours+")*");
+		final Matcher m = p.matcher(horaire);
+		String opening_hours = "";
+		if (m.matches()) {
+			for (int i = 1; i<=m.groupCount(); i++) {
+				if (m.group(i) != null) {
+					if (!opening_hours.isEmpty()) {
+						opening_hours += "; ";
+					}
+					final Pattern p2 = Pattern.compile("("+hour+")"+sep+"("+hour+")");
+					final Matcher m2 = p2.matcher(m.group(i));
+					if (m2.matches()) {
+						opening_hours += parseHour(m2.group(1)) + "-" + parseHour(m2.group(2));
+					} else {
+						System.err.println(m.group(i)+" does not match "+p2);
+					}
+				}
+			}
+		} else {
+			System.err.println(horaire+" does not match "+p);
+		}
+		return opening_hours;
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.put("amenity", "vending_machine");
+			n.put("vending", "parking_tickets");
+			n.remove("name");
+			n.remove("Code_Insee");
+			n.remove("Lib_voie");
+			n.remove("Mot_dir");
+			n.remove("No");
+			n.remove("Reglementation");
+			n.remove("color");
+			replace(n, "commune", "operator", new ValueReplacer() {
+				@Override
+				public String replace(String value) {
+					return "Mairie de "+WordUtils.capitalizeFully(value);
+				}
+			});
+			replace(n, "horaire", "opening_hours", new ValueReplacer() {
+				@Override
+				public String replace(String value) {
+					return parseOpeningHours(value);
+				}
+			});
+			replace(n, "maj_date", "source:date", new ValueReplacer() {
+				@Override
+				public String replace(String value) {
+					return value.substring(0, 4)+"-"+value.substring(4, 6)+"-"+value.substring(6, 8);
+				}
+			});
+			replace(n, "observations", "note");
+			replace(n, "quartier_residant", "parking:ticket:zone", new ValueReplacer() {
+				@Override
+				public String replace(String value) {
+					return WordUtils.capitalizeFully(value.trim())
+							.replace(" Iv", " IV").replace("Sebastopol", "Sébastopol")
+							.replace("St ", "Saint-").replace("Peri", "Péri");
+				}
+			});
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/MetroStationHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/MetroStationHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/MetroStationHandler.java	(revision 28000)
@@ -0,0 +1,41 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class MetroStationHandler extends ToulouseDataSetHandler {
+
+	public MetroStationHandler() {
+		super(12542, "subway=yes");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Metro_Station");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.put("public_transport", "stop_position");
+			n.put("subway", "yes");
+			replace(n, "NOM", "name");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/PMRHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/PMRHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/PMRHandler.java	(revision 28000)
@@ -0,0 +1,50 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class PMRHandler extends ToulouseDataSetHandler {
+
+	public PMRHandler() {
+		super(12538, "amenity=parking_space");
+		setWikiPage("PMR");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Emplacements_PMR");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.remove("name");
+			n.put("amenity", "parking_space");
+			n.put("access:disabled", "designated");
+			n.put("wheelchair", "designated");
+			replace(n, "nb_places", "capacity:disabled");
+			n.remove("Lib_voie");
+			n.remove("No");
+			n.remove("commune");
+			n.remove("code_insee");
+			n.remove("color");
+			replace(n, "id_PMR", "ref:grandtoulouse");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/PistesCyclablesHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/PistesCyclablesHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/PistesCyclablesHandler.java	(revision 28000)
@@ -0,0 +1,125 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport;
+
+import static org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler.OaQueryType.NODE;
+import static org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler.OaQueryType.WAY;
+import static org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler.OaRecurseType.NODE_RELATION;
+import static org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler.OaRecurseType.RELATION_WAY;
+import static org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler.OaRecurseType.WAY_NODE;
+import static org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler.OaRecurseType.WAY_RELATION;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.IPrimitive;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class PistesCyclablesHandler extends ToulouseDataSetHandler {
+
+	protected final Map<String, Collection<String>> map = new HashMap<String, Collection<String>>();
+	
+	private String streetField;
+	
+	public PistesCyclablesHandler() {
+		this("Nom_voie");
+	}
+	
+	public PistesCyclablesHandler(String streetField) {
+		super(12544, true, "cycleway", "cycleway:right", "cycleway:left", "cycleway:both", "highway=cycleway", "ramp:bicycle=yes", "bicycle=yes", "barrier=cycle_barrier");
+		setWikiPage("Réseau cyclable et vert");
+		addForbiddenTag("cycleway=no");
+		this.streetField = streetField;
+		map.put("secondary", Arrays.asList(new String[] {"AVENUE", "Av ", "av ", "Avenue ", "avenue ", "BOULEVARD ", "bd ", "ALLEE", "Allee", "allee", 
+				"PONT ", "Pont ", "PORT ", "ROUTE ", "Rte ", "BOULINGRIN", "boulingrin"}));
+		map.put("residential", Arrays.asList(new String[] {"CHEMIN ", "Chemin ", "chemin ", "IMPASSE ", "imp ", "PLACE ", "Place ", "place ", 
+				"RUE ", "Rue ", "rue ", "QUAI", "VOIE ", "grand rue"}));
+	}
+	
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzTabFilename(filename, "Pistes_Cyclables");
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.fr.opendata.datasets.SimpleDataSetHandler#getOverpassApiUnion(java.lang.String, java.lang.String[])
+	 */
+	@Override
+	protected String getOverpassApiQueries(String bbox, String... conditions) {
+		return oaQuery(bbox, NODE, conditions) + "\n" + 
+				oaRecurse(NODE_RELATION, RELATION_WAY, WAY_NODE) + "\n" +
+				oaQuery(bbox, WAY, conditions) + "\n" +
+				oaRecurse(WAY_NODE, "nodes") + "\n" +
+				oaRecurse(WAY_RELATION);
+	}
+
+	private String applyHighwayTag(String name, IPrimitive p) {
+		if (name != null && p != null) {
+			for (String key : map.keySet()) {
+				for (String value : map.get(key)) {
+					if (name.startsWith(value)) {
+						p.put("highway", key);
+						return key;
+					}
+				}
+			}
+		}
+		return null;
+	}
+	
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Way w : ds.getWays()) {
+
+			w.remove("name");
+			
+			String obs_type = w.get("obs_type");
+			if (obs_type.equals("bande")) {
+				w.put("cycleway", "lane");
+			} else if (obs_type.equals("bande a contresens") || obs_type.equals("contre allee")) {
+				w.put("cycleway", "opposite_lane");
+			} else if (obs_type.equals("couloir bus")) {
+				w.put("cycleway", "share_busway");
+			} else if (obs_type.equals("trottoir")) {
+				w.put("cycleway", "track");
+			} else if (obs_type.equalsIgnoreCase("cheminement mixte") || obs_type.equals("reseau vert")) {
+				w.put("highway", "cycleway");
+				w.put("foot", "yes");
+			} else if (obs_type.equals("piste") || obs_type.equals("voie verte")) {
+				w.put("highway", "cycleway");
+			} else if (obs_type.equals("zone 30")) {
+				w.put("zone:maxspeed", "FR:30");
+			} else {
+				System.out.println(obs_type);
+			}
+				
+			String name = w.get(streetField);
+			if (name != null) {
+				w.remove(streetField);
+					
+				if (w.get("highway") == null && applyHighwayTag(name, w) == null) {
+					w.put("highway", "road");
+				}
+
+				w.put("name", name);
+			}
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/ReseauTisseoHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/ReseauTisseoHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/ReseauTisseoHandler.java	(revision 28000)
@@ -0,0 +1,37 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class ReseauTisseoHandler extends ToulouseDataSetHandler {
+
+	public ReseauTisseoHandler() {
+		super(14022, "network=fr_tisseo");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsZipFilename(filename, "14022-reseau-tisseo-metro-bus-tram-");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		// TODO Auto-generated method stub
+		
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/TramwayStationHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/TramwayStationHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/TramwayStationHandler.java	(revision 28000)
@@ -0,0 +1,41 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class TramwayStationHandler extends ToulouseDataSetHandler {
+
+	public TramwayStationHandler() {
+		super(12611, "tram=yes");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Tramway_Stations");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.put("public_transport", "stop_position");
+			n.put("tram", "yes");
+			replace(n, "NOM", "name");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/VeloToulouseHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/VeloToulouseHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/VeloToulouseHandler.java	(revision 28000)
@@ -0,0 +1,62 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport;
+
+import org.apache.commons.lang3.text.WordUtils;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class VeloToulouseHandler extends ToulouseDataSetHandler {
+
+	public VeloToulouseHandler() {
+		super(12546, "amenity=bicycle_rental");
+		setWikiPage("Vélô Toulouse");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Velo_Toulouse");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.put("amenity", "bicycle_rental");
+			n.put("network", "VélôToulouse");
+			n.put("operator", "JCDecaux");
+			if (n.hasKey("M_en_S_16_nov_07") && n.get("M_en_S_16_nov_07").equals("O")) {
+				n.put("start_date", "2007-11-16");
+			}
+			n.remove("M_en_S_16_nov_07");
+			n.remove("Mot_Directeur");
+			n.remove("No");
+			n.remove("Nrivoli");
+			n.remove("street");
+			replace(n, "nb_bornettes", "capacity");
+			replace(n, "num_station", "ref");
+			replace(n, "nom", "name");
+			n.put("name", WordUtils.capitalizeFully(n.get("name")));
+			n.remove("code_insee");
+			n.remove("commune");
+			n.remove("color");
+			if (n.hasKey("En_service") && n.get("En_service").equals("N")) {
+				n.put("fixme", "Station pas en service");
+			}
+			n.remove("En_service");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/Zone30Handler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/Zone30Handler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/transport/Zone30Handler.java	(revision 28000)
@@ -0,0 +1,57 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.transport;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.urbanisme.VoirieHandler;
+
+public class Zone30Handler extends VoirieHandler {
+	
+	public Zone30Handler() {
+		super(12548, "Street", "maxspeed=30");
+		setWikiPage("Zones 30");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzTabFilename(filename, "Zone30");
+	}
+	
+	@Override
+	public void updateDataSet(DataSet ds) {
+		super.updateDataSet(ds);
+		
+		for (Way w : ds.getWays()) {
+			w.put("zone:maxspeed", "FR:30");
+			w.put("maxspeed", "30");
+			replace(w, "SensUnique", "oneway", new String[]{"oui", "non"}, new String[]{"yes", "no"});
+			replace(w, "Annee", "start_date");
+			replace(w, "Longueur", "length");
+			w.remove("code_insee");
+			w.remove("commune");
+			w.remove("MotDir");
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.portals.fr.toulouse.datasets.urbanisme.VoirieHandler#getStreetId(org.openstreetmap.josm.data.osm.Way)
+	 */
+	@Override
+	protected String getStreetId(Way w) {
+		return w.get("code_insee")+"/"+w.get("name");
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/CommuneHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/CommuneHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/CommuneHandler.java	(revision 28000)
@@ -0,0 +1,43 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.urbanisme;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class CommuneHandler extends ToulouseDataSetHandler {
+
+	public CommuneHandler() {
+		super(12582, "admin_level=8");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzTabFilename(filename, "Limites_Communes");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Relation r : ds.getRelations()) {
+			r.put("type", "boundary");
+			r.put("boundary", "administrative");
+			r.put("admin_level", "8");
+			replace(r, "libelle", "name");
+			replace(r, "code_insee", "ref:INSEE");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/NumerosRueHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/NumerosRueHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/NumerosRueHandler.java	(revision 28000)
@@ -0,0 +1,65 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.urbanisme;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.plugins.opendata.core.util.NamesFrUtils;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class NumerosRueHandler extends ToulouseDataSetHandler {
+
+	public NumerosRueHandler() {
+		super(12673, "addr:housenumber");
+		setWikiPage("Numéros de rue");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Numeros");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		Map<String, Relation> associatedStreets = new HashMap<String, Relation>();
+		
+		for (Node n : ds.getNodes()) {
+			replace(n, "no", "addr:housenumber");
+			n.remove("numero");
+			replace(n, "lib_off", "addr:street");
+			n.remove("mot_directeur");
+			n.remove("name");
+			n.remove("rivoli");
+			n.remove("nrivoli");
+			//n.remove("sti");
+			n.remove("color");
+			String streetName = NamesFrUtils.checkStreetName(n, "addr:street");
+			Relation street = associatedStreets.get(n.get("sti"));
+			if (street == null) {
+				associatedStreets.put(n.get("sti"), street = new Relation());
+				street.put("type", "associatedStreet");
+				street.put("name", streetName);
+				ds.addPrimitive(street);
+			}
+			street.addMember(new RelationMember("house", n));
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/SanisetteHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/SanisetteHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/SanisetteHandler.java	(revision 28000)
@@ -0,0 +1,57 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.urbanisme;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class SanisetteHandler extends ToulouseDataSetHandler {
+
+	public SanisetteHandler() {
+		super(12584, "amenity=toilets");
+		setWikiPage("Sanisettes");
+	}
+
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsCsvKmzTabFilename(filename, "Sanisette");
+	}
+
+	@Override
+	public void updateDataSet(DataSet ds) {
+		for (Node n : ds.getNodes()) {
+			n.remove("name");
+			n.put("amenity", "toilets");
+			n.put("supervised", "no");
+			n.put("unisex", "yes");
+			n.put("fee", "no");
+			n.put("operator", "JCDecaux");
+			n.put("opening_hours", "24/7");
+			replace(n, "numero", "ref:grandtoulouse");
+			replace(n, "PMR", "wheelchair", new String[]{"true", "false"}, new String[]{"yes", "no"});
+			String valide = n.get("emplacement_valide");
+			if (valide != null && valide.equalsIgnoreCase("non")) {
+				n.put("fixme", "L'emplacement semble invalide !");
+			} else {
+				n.remove("emplacement_valide");
+			}
+			n.remove("adresse");
+			n.remove("INSEE");
+			n.remove("color");
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/VoirieHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/VoirieHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/modules/fr.toulouse/src/org/openstreetmap/josm/plugins/opendata/modules/fr/toulouse/datasets/urbanisme/VoirieHandler.java	(revision 28000)
@@ -0,0 +1,122 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.urbanisme;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.IPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.plugins.opendata.core.util.NamesFrUtils;
+import org.openstreetmap.josm.plugins.opendata.modules.fr.toulouse.datasets.ToulouseDataSetHandler;
+
+public class VoirieHandler extends ToulouseDataSetHandler {
+
+	protected final Map<String, Collection<String>> map = new HashMap<String, Collection<String>>();
+	
+	private String streetField;
+	
+	public VoirieHandler() {
+		this(12693, "lib_off", "highway");
+	}
+	
+	protected VoirieHandler(int portalId, String streetField, String relevantKey) {
+		super(portalId, relevantKey);
+		this.streetField = streetField;
+		map.put("motorway", Arrays.asList(new String[] {"A6", "AUTOROUTE "}));
+		map.put("trunk", Arrays.asList(new String[] {"ROCADE "}));
+		map.put("secondary", Arrays.asList(new String[] {"AV ", "BD ", "ALL ", "PONT ", "RTE ", "PORT ", "BOULINGRIN"}));
+		map.put("residential", Arrays.asList(new String[] {"RUE ", "GRANDE-RUE ", "PROM ", "CHE", "CAMINOT ", "IMP ", "COURS ",
+				"LOT ", "ANC", "VIEUX ", "PL ", "CLOS ", "CITE ", "RESIDENCE ", "SENTIER ", "QU ", "SQ ", "VOIE ", "ESP "}));
+		map.put("unclassified", Arrays.asList(new String[] {"ZONE "}));
+		map.put("road", Arrays.asList(new String[] {"VA "}));
+	}
+	
+	@Override
+	public boolean acceptsFilename(String filename) {
+		return acceptsKmzTabFilename(filename, "Voies");
+	}
+
+	private String applyHighwayTag(String name, IPrimitive p) {
+		if (name != null && p != null) {
+			for (String key : map.keySet()) {
+				for (String value : map.get(key)) {
+					if (name.startsWith(value)) {
+						p.put("highway", key);
+						return key;
+					}
+				}
+			}
+		}
+		return null;
+	}
+	
+	protected String getStreetId(Way w) {
+		return w.get("sti");
+	}
+	
+	@Override
+	public void updateDataSet(DataSet ds) {
+		Map<String, Relation> associatedStreets = new HashMap<String, Relation>();
+		
+		for (Way w : ds.getWays()) {
+			String name = w.get(streetField);
+			if (name != null) {
+				w.remove(streetField);
+				w.remove("mot_directeur");
+				w.remove("color");
+				w.remove("rivoli");
+				w.remove("nrivoli");
+				
+				if (applyHighwayTag(name, w) == null) {
+					w.put("highway", "road");
+				}
+				
+				if (name.startsWith("RPT ") || name.startsWith("GIRATOIRE ")) {
+					// TODO: find correct highway
+					w.put("junction", "roundabout");
+				} else if (name.matches("RTE D[0-9]+")) {
+					w.put("ref", name.split(" ")[1]);
+				}
+				
+				w.put("name", name);
+				
+				if (name.matches("D[0-9]+.*")) {
+					w.put("highway", "secondary");
+					replace(w, "name", "ref");
+				} else if (!name.startsWith("VA ")) { // Unknown labels
+					name = NamesFrUtils.checkStreetName(w, "name");
+				}
+				
+				if (!name.startsWith("VA ")) { // Unknown labels
+					Relation street = associatedStreets.get(getStreetId(w));
+					if (street == null) {
+						associatedStreets.put(getStreetId(w), street = new Relation());
+						street.put("type", "associatedStreet");
+						street.put("name", name);
+						ds.addPrimitive(street);
+					}
+					street.addMember(new RelationMember("street", w));
+				}
+			}
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.catalog.ServiceFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.catalog.ServiceFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.catalog.ServiceFactory	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.catalog.shapefile.ShapefileServiceFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.coverage.grid.GridCoverageFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.coverage.grid.GridCoverageFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.coverage.grid.GridCoverageFactory	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.coverage.grid.GridCoverageFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.data.DataSourceFactorySpi
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.data.DataSourceFactorySpi	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.data.DataSourceFactorySpi	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.data.gml.GMLDataSourceFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.data.DataStoreFactorySpi
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.data.DataStoreFactorySpi	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.data.DataStoreFactorySpi	(revision 28000)
@@ -0,0 +1,2 @@
+org.geotools.data.shapefile.ShapefileDataStoreFactory
+org.geotools.data.shapefile.ShapefileDirectoryFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.data.FeatureLockFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.data.FeatureLockFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.data.FeatureLockFactory	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.data.DefaultFeatureLockFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.data.FileDataStoreFactorySpi
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.data.FileDataStoreFactorySpi	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.data.FileDataStoreFactorySpi	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.data.shapefile.ShapefileDataStoreFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.feature.AttributeTypeFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.feature.AttributeTypeFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.feature.AttributeTypeFactory	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.feature.DefaultAttributeTypeFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.feature.FeatureCollections
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.feature.FeatureCollections	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.feature.FeatureCollections	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.feature.DefaultFeatureCollections
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.feature.FeatureTypeFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.feature.FeatureTypeFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.feature.FeatureTypeFactory	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.feature.DefaultFeatureTypeFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.filter.FunctionExpression
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.filter.FunctionExpression	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.filter.FunctionExpression	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.filter.function.PropertyExistsFunction
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.filter.FunctionFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.filter.FunctionFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.filter.FunctionFactory	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.filter.function.DefaultFunctionFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.filter.expression.PropertyAccessorFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.filter.expression.PropertyAccessorFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.filter.expression.PropertyAccessorFactory	(revision 28000)
@@ -0,0 +1,3 @@
+org.geotools.filter.expression.SimpleFeaturePropertyAccessorFactory
+org.geotools.filter.expression.ThisPropertyAccessorFactory
+org.geotools.filter.expression.DirectPropertyAccessorFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.referencing.operation.MathTransformProvider
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.referencing.operation.MathTransformProvider	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.referencing.operation.MathTransformProvider	(revision 28000)
@@ -0,0 +1,49 @@
+org.geotools.referencing.operation.transform.LogarithmicTransform1D$Provider
+org.geotools.referencing.operation.transform.ExponentialTransform1D$Provider
+org.geotools.referencing.operation.transform.ProjectiveTransform$ProviderAffine
+org.geotools.referencing.operation.transform.ProjectiveTransform$ProviderLongitudeRotation
+org.geotools.referencing.operation.transform.GeocentricTranslation$Provider
+org.geotools.referencing.operation.transform.GeocentricTranslation$ProviderSevenParam
+org.geotools.referencing.operation.transform.GeocentricTranslation$ProviderFrameRotation
+org.geotools.referencing.operation.transform.GeocentricTransform$Provider
+org.geotools.referencing.operation.transform.GeocentricTransform$ProviderInverse
+org.geotools.referencing.operation.transform.MolodenskiTransform$Provider
+org.geotools.referencing.operation.transform.MolodenskiTransform$ProviderAbridged
+#org.geotools.referencing.operation.transform.NADCONTransform$Provider # Need US grids
+#org.geotools.referencing.operation.transform.WarpTransform2D$Provider # Need javax.media 
+#org.geotools.referencing.operation.projection.EquidistantCylindrical$Provider
+#org.geotools.referencing.operation.projection.EquidistantCylindrical$SphericalProvider
+#org.geotools.referencing.operation.projection.PlateCarree$Provider
+#org.geotools.referencing.operation.projection.Mercator1SP$Provider
+#org.geotools.referencing.operation.projection.Mercator2SP$Provider
+#org.geotools.referencing.operation.projection.MercatorPseudoProvider
+org.geotools.referencing.operation.projection.TransverseMercator$Provider
+org.geotools.referencing.operation.projection.TransverseMercator$Provider_SouthOrientated
+#org.geotools.referencing.operation.projection.ObliqueMercator$Provider
+#org.geotools.referencing.operation.projection.ObliqueMercator$Provider_TwoPoint
+#org.geotools.referencing.operation.projection.HotineObliqueMercator$Provider
+#org.geotools.referencing.operation.projection.HotineObliqueMercator$Provider_TwoPoint
+#org.geotools.referencing.operation.projection.AlbersEqualArea$Provider
+org.geotools.referencing.operation.projection.LambertConformal1SP$Provider
+org.geotools.referencing.operation.projection.LambertConformal2SP$Provider
+org.geotools.referencing.operation.projection.LambertConformalBelgium$Provider
+#org.geotools.referencing.operation.projection.LambertAzimuthalEqualArea$Provider
+#org.geotools.referencing.operation.projection.Orthographic$Provider
+#org.geotools.referencing.operation.projection.Stereographic$Provider
+#org.geotools.referencing.operation.projection.ObliqueStereographic$Provider
+#org.geotools.referencing.operation.projection.PolarStereographic$ProviderA
+#org.geotools.referencing.operation.projection.PolarStereographic$ProviderB
+#org.geotools.referencing.operation.projection.PolarStereographic$ProviderNorth
+#org.geotools.referencing.operation.projection.PolarStereographic$ProviderSouth
+#org.geotools.referencing.operation.projection.NewZealandMapGrid$Provider
+#org.geotools.referencing.operation.projection.Krovak$Provider
+#org.geotools.referencing.operation.projection.CassiniSoldner$Provider
+#org.geotools.referencing.operation.projection.EquidistantConic$Provider
+#org.geotools.referencing.operation.projection.Polyconic$Provider
+#org.geotools.referencing.operation.projection.Robinson$Provider
+#org.geotools.referencing.operation.projection.WinkelTripel$WinkelProvider
+#org.geotools.referencing.operation.projection.WinkelTripel$AitoffProvider
+#org.geotools.referencing.operation.projection.EckertIV$Provider
+#org.geotools.referencing.operation.projection.Mollweide$MollweideProvider
+#org.geotools.referencing.operation.projection.Mollweide$WagnerIVProvider
+#org.geotools.referencing.operation.projection.WorldVanDerGrintenI$Provider
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.renderer.style.ExternalGraphicFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.renderer.style.ExternalGraphicFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.renderer.style.ExternalGraphicFactory	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.renderer.style.ImageGraphicFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.renderer.style.MarkFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.renderer.style.MarkFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.renderer.style.MarkFactory	(revision 28000)
@@ -0,0 +1,3 @@
+org.geotools.renderer.style.WellKnownMarkFactory
+org.geotools.renderer.style.TTFMarkFactory
+org.geotools.renderer.style.ShapeMarkFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.util.ConverterFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.util.ConverterFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.util.ConverterFactory	(revision 28000)
@@ -0,0 +1,10 @@
+org.geotools.util.CommonsConverterFactory
+org.geotools.util.NumericConverterFactory
+org.geotools.util.GeometryConverterFactory
+org.geotools.util.GeometryTypeConverterFactory
+org.geotools.util.TemporalConverterFactory
+org.geotools.util.BooleanConverterFactory
+org.geotools.util.ColorConverterFactory
+org.geotools.util.CollectionConverterFactory
+org.geotools.util.CharsetConverterFactory
+org.geotools.util.UuidConverterFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.xml.schema.Schema
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.xml.schema.Schema	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.geotools.xml.schema.Schema	(revision 28000)
@@ -0,0 +1,3 @@
+org.geotools.xml.xLink.XLinkSchema
+org.geotools.xml.gml.GMLSchema
+org.geotools.xml.filter.FilterSchema
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.coverage.processing.Operation
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.coverage.processing.Operation	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.coverage.processing.Operation	(revision 28000)
@@ -0,0 +1,27 @@
+org.geotools.coverage.processing.operation.Absolute
+org.geotools.coverage.processing.operation.AddConst
+org.geotools.coverage.processing.operation.Add
+org.geotools.coverage.processing.operation.Convolve
+org.geotools.coverage.processing.operation.Crop
+org.geotools.coverage.processing.operation.DivideByConst
+org.geotools.coverage.processing.operation.Exp
+org.geotools.coverage.processing.operation.FilteredSubsample
+org.geotools.coverage.processing.operation.GradientMagnitude
+org.geotools.coverage.processing.operation.Interpolate
+org.geotools.coverage.processing.operation.Invert
+org.geotools.coverage.processing.operation.Log
+org.geotools.coverage.processing.operation.MaxFilter
+org.geotools.coverage.processing.operation.MedianFilter
+org.geotools.coverage.processing.operation.MinFilter
+org.geotools.coverage.processing.operation.Multiply
+org.geotools.coverage.processing.operation.MultiplyConst
+org.geotools.coverage.processing.operation.Recolor
+org.geotools.coverage.processing.operation.Resample
+org.geotools.coverage.processing.operation.Rescale
+org.geotools.coverage.processing.operation.Scale
+org.geotools.coverage.processing.operation.SelectSampleDimension
+org.geotools.coverage.processing.operation.SubsampleAverage
+org.geotools.coverage.processing.operation.SubtractConst
+org.geotools.coverage.processing.operation.SubtractFromConst
+org.geotools.coverage.processing.operation.Extrema
+org.geotools.coverage.processing.operation.Histogram
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.feature.FeatureFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.feature.FeatureFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.feature.FeatureFactory	(revision 28000)
@@ -0,0 +1,2 @@
+org.geotools.feature.LenientFeatureFactoryImpl
+org.geotools.feature.ValidatingFeatureFactoryImpl
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.filter.FilterFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.filter.FilterFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.filter.FilterFactory	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.filter.FilterFactoryImpl
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.filter.expression.Function
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.filter.expression.Function	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.filter.expression.Function	(revision 28000)
@@ -0,0 +1,10 @@
+#org.geotools.filter.function.PropertyExistsFunction
+#org.geotools.filter.AreaFunction
+org.geotools.filter.LengthFunction
+#org.geotools.filter.function.CategorizeFunction
+#org.geotools.filter.function.ClassifyFunction
+#org.geotools.filter.function.EqualIntervalFunction
+#org.geotools.filter.function.StandardDeviationFunction
+#org.geotools.filter.function.QuantileFunction
+#org.geotools.filter.function.UniqueIntervalFunction
+#org.geotools.filter.function.EnvFunction
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory	(revision 28000)
@@ -0,0 +1,18 @@
+#org.geotools.referencing.factory.epsg.DefaultFactory
+org.geotools.referencing.factory.epsg.FactoryUsingWKT
+#org.geotools.referencing.factory.epsg.LongitudeFirstFactory
+#org.geotools.referencing.factory.wms.AutoCRSFactory
+#org.geotools.referencing.factory.wms.WebCRSFactory
+#org.geotools.referencing.factory.URN_AuthorityFactory
+#org.geotools.referencing.factory.HTTP_AuthorityFactory
+# pending review
+#org.geotools.referencing.factory.epsg.LongitudeFirstEpsgDecorator
+# WKT
+org.geotools.referencing.crs.EPSGCRSAuthorityFactory
+# Extension ESRI
+org.geotools.referencing.factory.epsg.UnnamedExtension
+org.geotools.referencing.factory.epsg.EsriExtension
+# HSQL
+#org.geotools.referencing.factory.epsg.ThreadedHsqlEpsgFactory
+# pending review
+# org.geotools.referencing.factory.epsg.HsqlDialectEpsgMediator
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.crs.CRSFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.crs.CRSFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.crs.CRSFactory	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.referencing.factory.ReferencingObjectFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.cs.CSAuthorityFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.cs.CSAuthorityFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.cs.CSAuthorityFactory	(revision 28000)
@@ -0,0 +1,10 @@
+#org.geotools.referencing.factory.epsg.DefaultFactory
+#org.geotools.referencing.factory.epsg.LongitudeFirstFactory
+#org.geotools.referencing.factory.URN_AuthorityFactory
+#org.geotools.referencing.factory.HTTP_AuthorityFactory
+# pending review
+#org.geotools.referencing.factory.epsg.LongitudeFirstEpsgDecorator
+# HSQL
+#org.geotools.referencing.factory.epsg.ThreadedHsqlEpsgFactory
+# pending review
+# org.geotools.referencing.factory.epsg.HsqlDialectEpsgMediator
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.cs.CSFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.cs.CSFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.cs.CSFactory	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.referencing.factory.ReferencingObjectFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.datum.DatumAuthorityFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.datum.DatumAuthorityFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.datum.DatumAuthorityFactory	(revision 28000)
@@ -0,0 +1,10 @@
+#org.geotools.referencing.factory.epsg.DefaultFactory
+#org.geotools.referencing.factory.epsg.LongitudeFirstFactory
+#org.geotools.referencing.factory.URN_AuthorityFactory
+#org.geotools.referencing.factory.HTTP_AuthorityFactory
+# pending review
+#org.geotools.referencing.factory.epsg.LongitudeFirstEpsgDecorator
+# HSQL
+#org.geotools.referencing.factory.epsg.ThreadedHsqlEpsgFactory
+# pending review
+# org.geotools.referencing.factory.epsg.HsqlDialectEpsgMediator
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.datum.DatumFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.datum.DatumFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.datum.DatumFactory	(revision 28000)
@@ -0,0 +1,2 @@
+org.geotools.referencing.factory.ReferencingObjectFactory
+org.geotools.referencing.factory.DatumAliases
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.operation.CoordinateOperationAuthorityFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.operation.CoordinateOperationAuthorityFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.operation.CoordinateOperationAuthorityFactory	(revision 28000)
@@ -0,0 +1,10 @@
+#org.geotools.referencing.factory.epsg.DefaultFactory
+#org.geotools.referencing.factory.epsg.LongitudeFirstFactory
+#org.geotools.referencing.factory.URN_AuthorityFactory
+#org.geotools.referencing.factory.HTTP_AuthorityFactory
+# pending review
+#org.geotools.referencing.factory.epsg.LongitudeFirstEpsgDecorator
+# HSQL
+#org.geotools.referencing.factory.epsg.ThreadedHsqlEpsgFactory
+# pending review
+# org.geotools.referencing.factory.epsg.HsqlDialectEpsgMediator
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.operation.CoordinateOperationFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.operation.CoordinateOperationFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.operation.CoordinateOperationFactory	(revision 28000)
@@ -0,0 +1,3 @@
+org.geotools.referencing.operation.DefaultCoordinateOperationFactory
+org.geotools.referencing.operation.AuthorityBackedFactory
+org.geotools.referencing.operation.BufferedCoordinateOperationFactory
Index: /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.operation.MathTransformFactory
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.operation.MathTransformFactory	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/META-INF/services/org.opengis.referencing.operation.MathTransformFactory	(revision 28000)
@@ -0,0 +1,1 @@
+org.geotools.referencing.operation.DefaultMathTransformFactory
Index: /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/crs/epsg.properties
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/crs/epsg.properties	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/crs/epsg.properties	(revision 28000)
@@ -0,0 +1,227 @@
+#Generated from EPSG database version 7.9.0
+#Sun Oct 16 14:49:47 CEST 2011
+2154=PROJCS["RGF93 / Lambert-93", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 46.5], PARAMETER["standard_parallel_1", 49.0], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 6600000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2154"]]
+2192=PROJCS["ED50 / France EuroLambert", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 2.3372291666666656], PARAMETER["latitude_of_origin", 46.8], PARAMETER["scale_factor", 0.99987742], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 2200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2192"]]
+
+2969=PROJCS["Fort Marigot / UTM zone 20N", GEOGCS["Fort Marigot", DATUM["Fort Marigot", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[137.0, 248.0, -430.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6621"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4621"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2969"]]
+2970=PROJCS["Guadeloupe 1948 / UTM zone 20N", GEOGCS["Guadeloupe 1948", DATUM["Guadeloupe 1948", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-472.29, -5.63, -304.12, 0.4362, -0.8374, 0.2563, 1.8984], AUTHORITY["EPSG","6622"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4622"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2970"]]
+2971=PROJCS["CSG67 / UTM zone 22N", GEOGCS["CSG67", DATUM["Centre Spatial Guyanais 1967", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-186.0, 230.0, 110.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6623"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4623"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2971"]]
+2972=PROJCS["RGFG95 / UTM zone 22N", GEOGCS["RGFG95", DATUM["Reseau Geodesique Francais Guyane 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6624"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4624"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2972"]]
+2973=PROJCS["Martinique 1938 / UTM zone 20N", GEOGCS["Martinique 1938", DATUM["Martinique 1938", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[126.93, 547.94, 130.41, -2.7867, 5.1612, -0.8584, 13.8227], AUTHORITY["EPSG","6625"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4625"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2973"]]
+2975=PROJCS["RGR92 / UTM zone 40S", GEOGCS["RGR92", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4627"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2975"]]
+2976=PROJCS["Tahiti 52 / UTM zone 6S", GEOGCS["Tahiti 52", DATUM["Tahiti 52", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[162.0, 117.0, 154.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6628"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4628"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2976"]]
+2980=PROJCS["Combani 1950 / UTM zone 38S", GEOGCS["Combani 1950", DATUM["Combani 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-382.0, -59.0, -262.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6632"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4632"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2980"]]
+2987=PROJCS["Saint Pierre et Miquelon 1950 / UTM zone 21N", GEOGCS["Saint Pierre et Miquelon 1950", DATUM["Saint Pierre et Miquelon 1950", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[30.0, 430.0, 368.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6638"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4638"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2987"]]
+3312=PROJCS["CSG67 / UTM zone 21N", GEOGCS["CSG67", DATUM["Centre Spatial Guyanais 1967", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-186.0, 230.0, 110.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6623"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4623"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3312"]]
+3727=PROJCS["Reunion 1947 / TM Reunion", GEOGCS["Reunion 1947", DATUM["Reunion 1947", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[94.0, -948.0, -1262.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6626"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4626"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 55.53333333333333], PARAMETER["latitude_of_origin", -21.116666666666667], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 160000.0], PARAMETER["false_northing", 50000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3727"]]
+
+3812=PROJCS["ETRS89 / Belgian Lambert 2008", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 4.359215833333335], PARAMETER["latitude_of_origin", 50.79781500000001], PARAMETER["standard_parallel_1", 51.16666666666667], PARAMETER["false_easting", 649328.0], PARAMETER["false_northing", 665262.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 49.833333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3812"]]
+3942=PROJCS["RGF93 / CC42", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 42.0], PARAMETER["standard_parallel_1", 42.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 1200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3942"]]
+3943=PROJCS["RGF93 / CC43", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 43.0], PARAMETER["standard_parallel_1", 43.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 2200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3943"]]
+3944=PROJCS["RGF93 / CC44", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 44.0], PARAMETER["standard_parallel_1", 44.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 3200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3944"]]
+3945=PROJCS["RGF93 / CC45", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 45.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 4200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3945"]]
+3946=PROJCS["RGF93 / CC46", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 46.0], PARAMETER["standard_parallel_1", 46.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 5200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3946"]]
+3947=PROJCS["RGF93 / CC47", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 47.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 6200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3947"]]
+3948=PROJCS["RGF93 / CC48", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 48.0], PARAMETER["standard_parallel_1", 48.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 7200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3948"]]
+3949=PROJCS["RGF93 / CC49", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 49.0], PARAMETER["standard_parallel_1", 49.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 8200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 48.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3949"]]
+3950=PROJCS["RGF93 / CC50", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 50.0], PARAMETER["standard_parallel_1", 50.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 9200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 49.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3950"]]
+
+4171=GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]]
+4230=GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]]
+4258=GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]]
+4275=GEOGCS["NTF", DATUM["Nouvelle Triangulation Francaise", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-168.0, -60.0, 320.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6275"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4275"]]
+4313=GEOGCS["Belge 1972", DATUM["Reseau National Belge 1972", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-106.8686, 52.2978, -103.7239, 0.3366, 0.457, -1.8422, -1.2747], AUTHORITY["EPSG","6313"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4313"]]
+4326=GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]]
+4373=GEOGCS["RGR92 (3D)", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4373"]]
+4374=GEOCCS["RGR92 (geocentric)", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4374"]]
+4463=GEOGCS["RGSPM06", DATUM["Reseau Geodesique de Saint Pierre et Miquelon 2006", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1038"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4463"]]
+4465=GEOCCS["RGSPM06", DATUM["Reseau Geodesique de Saint Pierre et Miquelon 2006", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1038"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4465"]]
+4466=GEOGCS["RGSPM06", DATUM["Reseau Geodesique de Saint Pierre et Miquelon 2006", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1038"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4466"]]
+4467=PROJCS["RGSPM06 / UTM zone 21N", GEOGCS["RGSPM06", DATUM["Reseau Geodesique de Saint Pierre et Miquelon 2006", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1038"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4463"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4467"]]
+4468=GEOCCS["RGM04", DATUM["Reseau Geodesique de Mayotte 2004", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1036"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4468"]]
+4469=GEOGCS["RGM04", DATUM["Reseau Geodesique de Mayotte 2004", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1036"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4469"]]
+4470=GEOGCS["RGM04", DATUM["Reseau Geodesique de Mayotte 2004", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1036"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4470"]]
+4471=PROJCS["RGM04 / UTM zone 38S", GEOGCS["RGM04", DATUM["Reseau Geodesique de Mayotte 2004", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1036"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4470"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4471"]]
+4472=GEOGCS["Cadastre 1997", DATUM["Cadastre 1997", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-381.788, -57.501, -256.673, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1037"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4472"]]
+4473=GEOCCS["Cadastre 1997", DATUM["Cadastre 1997", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-381.788, -57.501, -256.673, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1037"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4473"]]
+4474=PROJCS["Cadastre 1997 / UTM zone 38S", GEOGCS["Combani 1950", DATUM["Combani 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-382.0, -59.0, -262.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6632"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4632"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4474"]]
+4475=GEOGCS["Cadastre 1997", DATUM["Cadastre 1997", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-381.788, -57.501, -256.673, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1037"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4475"]]
+4556=GEOCCS["RRAF 1991", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1047"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4556"]]
+4557=GEOGCS["RRAF 1991", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1047"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4557"]]
+4558=GEOGCS["RRAF 1991", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1047"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4558"]]
+4559=PROJCS["RRAF 1991 / UTM zone 20N", GEOGCS["RRAF 1991", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1047"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4558"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4559"]]
+4621=GEOGCS["Fort Marigot", DATUM["Fort Marigot", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[137.0, 248.0, -430.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6621"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4621"]]
+4622=GEOGCS["Guadeloupe 1948", DATUM["Guadeloupe 1948", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-472.29, -5.63, -304.12, 0.4362, -0.8374, 0.2563, 1.8984], AUTHORITY["EPSG","6622"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4622"]]
+4623=GEOGCS["CSG67", DATUM["Centre Spatial Guyanais 1967", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-186.0, 230.0, 110.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6623"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4623"]]
+4624=GEOGCS["RGFG95", DATUM["Reseau Geodesique Francais Guyane 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6624"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4624"]]
+4625=GEOGCS["Martinique 1938", DATUM["Martinique 1938", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[126.93, 547.94, 130.41, -2.7867, 5.1612, -0.8584, 13.8227], AUTHORITY["EPSG","6625"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4625"]]
+4626=GEOGCS["Reunion 1947", DATUM["Reunion 1947", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[94.0, -948.0, -1262.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6626"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4626"]]
+4627=GEOGCS["RGR92", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4627"]]
+4632=GEOGCS["Combani 1950", DATUM["Combani 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-382.0, -59.0, -262.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6632"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4632"]]
+4638=GEOGCS["Saint Pierre et Miquelon 1950", DATUM["Saint Pierre et Miquelon 1950", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[30.0, 430.0, 368.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6638"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4638"]]
+4807=GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]]
+4936=GEOCCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4936"]]
+4937=GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4937"]]
+4964=GEOCCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4964"]]
+4965=GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4965"]]
+4966=GEOCCS["RGFG95", DATUM["Reseau Geodesique Francais Guyane 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6624"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4966"]]
+4967=GEOGCS["RGFG95", DATUM["Reseau Geodesique Francais Guyane 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6624"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4967"]]
+4968=GEOCCS["RGNC 1991", DATUM["Reseau Geodesique Nouvelle Caledonie 1991", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6645"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4968"]]
+4969=GEOGCS["RGNC 1991", DATUM["Reseau Geodesique Nouvelle Caledonie 1991", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6645"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4969"]]
+4970=GEOCCS["RGR92", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4970"]]
+4971=GEOGCS["RGR92", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4971"]]
+4978=GEOCCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4978"]]
+4979=GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4979"]]
+
+23030=PROJCS["ED50 / UTM zone 30N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23030"]]
+23031=PROJCS["ED50 / UTM zone 31N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23031"]]
+23032=PROJCS["ED50 / UTM zone 32N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23032"]]
+23033=PROJCS["ED50 / UTM zone 33N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23033"]]
+23034=PROJCS["ED50 / UTM zone 34N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23034"]]
+23035=PROJCS["ED50 / UTM zone 35N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23035"]]
+23036=PROJCS["ED50 / UTM zone 36N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23036"]]
+23037=PROJCS["ED50 / UTM zone 37N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23037"]]
+23038=PROJCS["ED50 / UTM zone 38N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23038"]]
+
+# These lines have been copied from spatialreference.org in order to add Bursa Wolf parameters (TOWGS84 clause).
+27561=PROJCS["NTF (Paris) / Lambert Nord France",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",55],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.999877341],PARAMETER["false_easting",600000],PARAMETER["false_northing",200000],AUTHORITY["EPSG","27561"],AXIS["X",EAST],AXIS["Y",NORTH]]
+27562=PROJCS["NTF (Paris) / Lambert Centre France",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",52],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.99987742],PARAMETER["false_easting",600000],PARAMETER["false_northing",200000],AUTHORITY["EPSG","27562"],AXIS["X",EAST],AXIS["Y",NORTH]]
+27563=PROJCS["NTF (Paris) / Lambert Sud France",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",49],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.999877499],PARAMETER["false_easting",600000],PARAMETER["false_northing",200000],AUTHORITY["EPSG","27563"],AXIS["X",EAST],AXIS["Y",NORTH]]
+27564=PROJCS["NTF (Paris) / Lambert Corse",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",46.85],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.99994471],PARAMETER["false_easting",234.358],PARAMETER["false_northing",185861.369],AUTHORITY["EPSG","27564"],AXIS["X",EAST],AXIS["Y",NORTH]]
+27571=PROJCS["NTF (Paris) / Lambert zone I",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",55],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.999877341],PARAMETER["false_easting",600000],PARAMETER["false_northing",1200000],AUTHORITY["EPSG","27571"],AXIS["X",EAST],AXIS["Y",NORTH]]
+27572=PROJCS["NTF (Paris) / Lambert zone II",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",52],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.99987742],PARAMETER["false_easting",600000],PARAMETER["false_northing",2200000],AUTHORITY["EPSG","27572"],AXIS["X",EAST],AXIS["Y",NORTH]]
+27573=PROJCS["NTF (Paris) / Lambert zone III",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",49],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.999877499],PARAMETER["false_easting",600000],PARAMETER["false_northing",3200000],AUTHORITY["EPSG","27573"],AXIS["X",EAST],AXIS["Y",NORTH]]
+27574=PROJCS["NTF (Paris) / Lambert zone IV",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",46.85],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.99994471],PARAMETER["false_easting",234.358],PARAMETER["false_northing",4185861.369],AUTHORITY["EPSG","27574"],AXIS["X",EAST],AXIS["Y",NORTH]]
+#27581=PROJCS["NTF (Paris) / France I (deprecated)",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",55],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.999877341],PARAMETER["false_easting",600000],PARAMETER["false_northing",1200000],AUTHORITY["EPSG","27581"],AXIS["X",EAST],AXIS["Y",NORTH]]
+#27582=PROJCS["NTF (Paris) / France II (deprecated)",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",52],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.99987742],PARAMETER["false_easting",600000],PARAMETER["false_northing",2200000],AUTHORITY["EPSG","27582"],AXIS["X",EAST],AXIS["Y",NORTH]]
+#27583=PROJCS["NTF (Paris) / France III (deprecated)",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",49],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.999877499],PARAMETER["false_easting",600000],PARAMETER["false_northing",3200000],AUTHORITY["EPSG","27583"],AXIS["X",EAST],AXIS["Y",NORTH]]
+#27584=PROJCS["NTF (Paris) / France IV (deprecated)",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",46.85],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.99994471],PARAMETER["false_easting",234.358],PARAMETER["false_northing",4185861.369],AUTHORITY["EPSG","27584"],AXIS["X",EAST],AXIS["Y",NORTH]]
+#27591=PROJCS["NTF (Paris) / Nord France (deprecated)",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",55],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.999877341],PARAMETER["false_easting",600000],PARAMETER["false_northing",200000],AUTHORITY["EPSG","27591"],AXIS["X",EAST],AXIS["Y",NORTH]]
+#27592=PROJCS["NTF (Paris) / Centre France (deprecated)",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",52],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.99987742],PARAMETER["false_easting",600000],PARAMETER["false_northing",200000],AUTHORITY["EPSG","27592"],AXIS["X",EAST],AXIS["Y",NORTH]]
+#27593=PROJCS["NTF (Paris) / Sud France (deprecated)",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",49],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.999877499],PARAMETER["false_easting",600000],PARAMETER["false_northing",200000],AUTHORITY["EPSG","27593"],AXIS["X",EAST],AXIS["Y",NORTH]]
+#27594=PROJCS["NTF (Paris) / Corse (deprecated)",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",46.85],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.99994471],PARAMETER["false_easting",234.358],PARAMETER["false_northing",185861.369],AUTHORITY["EPSG","27594"],AXIS["X",EAST],AXIS["Y",NORTH]]
+
+31300=PROJCS["Belge 1972 / Belge Lambert 72", GEOGCS["Belge 1972", DATUM["Reseau National Belge 1972", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-106.8686, 52.2978, -103.7239, 0.3366, 0.457, -1.8422, -1.2747], AUTHORITY["EPSG","6313"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4313"]], PROJECTION["Lambert_Conformal_Conic_2SP_Belgium", AUTHORITY["EPSG","9803"]], PARAMETER["central_meridian", 4.356939722222222], PARAMETER["latitude_of_origin", 90.0], PARAMETER["standard_parallel_1", 49.833333333333336], PARAMETER["false_easting", 150000.01256], PARAMETER["false_northing", 5400088.4378], PARAMETER["standard_parallel_2", 51.16666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31300"]]
+31370=PROJCS["Belge 1972 / Belgian Lambert 72", GEOGCS["Belge 1972", DATUM["Reseau National Belge 1972", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-106.8686, 52.2978, -103.7239, 0.3366, 0.457, -1.8422, -1.2747], AUTHORITY["EPSG","6313"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4313"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 4.367486666666666], PARAMETER["latitude_of_origin", 90.0], PARAMETER["standard_parallel_1", 51.166667233333335], PARAMETER["false_easting", 150000.013], PARAMETER["false_northing", 5400088.438], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 49.833333900000014], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31370"]]
+
+32660=PROJCS["WGS 84 / UTM zone 60N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32660"]]
+32659=PROJCS["WGS 84 / UTM zone 59N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32659"]]
+32658=PROJCS["WGS 84 / UTM zone 58N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32658"]]
+32657=PROJCS["WGS 84 / UTM zone 57N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32657"]]
+32656=PROJCS["WGS 84 / UTM zone 56N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32656"]]
+32655=PROJCS["WGS 84 / UTM zone 55N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32655"]]
+32654=PROJCS["WGS 84 / UTM zone 54N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32654"]]
+32653=PROJCS["WGS 84 / UTM zone 53N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32653"]]
+32652=PROJCS["WGS 84 / UTM zone 52N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32652"]]
+32651=PROJCS["WGS 84 / UTM zone 51N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32651"]]
+32650=PROJCS["WGS 84 / UTM zone 50N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32650"]]
+32649=PROJCS["WGS 84 / UTM zone 49N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32649"]]
+32648=PROJCS["WGS 84 / UTM zone 48N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32648"]]
+32647=PROJCS["WGS 84 / UTM zone 47N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32647"]]
+32646=PROJCS["WGS 84 / UTM zone 46N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32646"]]
+32645=PROJCS["WGS 84 / UTM zone 45N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32645"]]
+32644=PROJCS["WGS 84 / UTM zone 44N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32644"]]
+32643=PROJCS["WGS 84 / UTM zone 43N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32643"]]
+32642=PROJCS["WGS 84 / UTM zone 42N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32642"]]
+32641=PROJCS["WGS 84 / UTM zone 41N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32641"]]
+32640=PROJCS["WGS 84 / UTM zone 40N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32640"]]
+32639=PROJCS["WGS 84 / UTM zone 39N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32639"]]
+32638=PROJCS["WGS 84 / UTM zone 38N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32638"]]
+32637=PROJCS["WGS 84 / UTM zone 37N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32637"]]
+32636=PROJCS["WGS 84 / UTM zone 36N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32636"]]
+32635=PROJCS["WGS 84 / UTM zone 35N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32635"]]
+32634=PROJCS["WGS 84 / UTM zone 34N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32634"]]
+32633=PROJCS["WGS 84 / UTM zone 33N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32633"]]
+32632=PROJCS["WGS 84 / UTM zone 32N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32632"]]
+32631=PROJCS["WGS 84 / UTM zone 31N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32631"]]
+32630=PROJCS["WGS 84 / UTM zone 30N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32630"]]
+32629=PROJCS["WGS 84 / UTM zone 29N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32629"]]
+32628=PROJCS["WGS 84 / UTM zone 28N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32628"]]
+32627=PROJCS["WGS 84 / UTM zone 27N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32627"]]
+32626=PROJCS["WGS 84 / UTM zone 26N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32626"]]
+32625=PROJCS["WGS 84 / UTM zone 25N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32625"]]
+32624=PROJCS["WGS 84 / UTM zone 24N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32624"]]
+32623=PROJCS["WGS 84 / UTM zone 23N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32623"]]
+32622=PROJCS["WGS 84 / UTM zone 22N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32622"]]
+32621=PROJCS["WGS 84 / UTM zone 21N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32621"]]
+32620=PROJCS["WGS 84 / UTM zone 20N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32620"]]
+32619=PROJCS["WGS 84 / UTM zone 19N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32619"]]
+32618=PROJCS["WGS 84 / UTM zone 18N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32618"]]
+32617=PROJCS["WGS 84 / UTM zone 17N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32617"]]
+32616=PROJCS["WGS 84 / UTM zone 16N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32616"]]
+32615=PROJCS["WGS 84 / UTM zone 15N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32615"]]
+32614=PROJCS["WGS 84 / UTM zone 14N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32614"]]
+32613=PROJCS["WGS 84 / UTM zone 13N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32613"]]
+32612=PROJCS["WGS 84 / UTM zone 12N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32612"]]
+32611=PROJCS["WGS 84 / UTM zone 11N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32611"]]
+32610=PROJCS["WGS 84 / UTM zone 10N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32610"]]
+32609=PROJCS["WGS 84 / UTM zone 9N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32609"]]
+32608=PROJCS["WGS 84 / UTM zone 8N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32608"]]
+32607=PROJCS["WGS 84 / UTM zone 7N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32607"]]
+32606=PROJCS["WGS 84 / UTM zone 6N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32606"]]
+32605=PROJCS["WGS 84 / UTM zone 5N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32605"]]
+32604=PROJCS["WGS 84 / UTM zone 4N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32604"]]
+32603=PROJCS["WGS 84 / UTM zone 3N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32603"]]
+32602=PROJCS["WGS 84 / UTM zone 2N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32602"]]
+32601=PROJCS["WGS 84 / UTM zone 1N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32601"]]
+
+32760=PROJCS["WGS 84 / UTM zone 60S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32760"]]
+32759=PROJCS["WGS 84 / UTM zone 59S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32759"]]
+32758=PROJCS["WGS 84 / UTM zone 58S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32758"]]
+32757=PROJCS["WGS 84 / UTM zone 57S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32757"]]
+32756=PROJCS["WGS 84 / UTM zone 56S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32756"]]
+32755=PROJCS["WGS 84 / UTM zone 55S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32755"]]
+32754=PROJCS["WGS 84 / UTM zone 54S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32754"]]
+32753=PROJCS["WGS 84 / UTM zone 53S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32753"]]
+32752=PROJCS["WGS 84 / UTM zone 52S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32752"]]
+32751=PROJCS["WGS 84 / UTM zone 51S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32751"]]
+32750=PROJCS["WGS 84 / UTM zone 50S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32750"]]
+32749=PROJCS["WGS 84 / UTM zone 49S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32749"]]
+32748=PROJCS["WGS 84 / UTM zone 48S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32748"]]
+32747=PROJCS["WGS 84 / UTM zone 47S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32747"]]
+32746=PROJCS["WGS 84 / UTM zone 46S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32746"]]
+32745=PROJCS["WGS 84 / UTM zone 45S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32745"]]
+32744=PROJCS["WGS 84 / UTM zone 44S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32744"]]
+32743=PROJCS["WGS 84 / UTM zone 43S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32743"]]
+32742=PROJCS["WGS 84 / UTM zone 42S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32742"]]
+32741=PROJCS["WGS 84 / UTM zone 41S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32741"]]
+32740=PROJCS["WGS 84 / UTM zone 40S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32740"]]
+32739=PROJCS["WGS 84 / UTM zone 39S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32739"]]
+32738=PROJCS["WGS 84 / UTM zone 38S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32738"]]
+32737=PROJCS["WGS 84 / UTM zone 37S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32737"]]
+32736=PROJCS["WGS 84 / UTM zone 36S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32736"]]
+32735=PROJCS["WGS 84 / UTM zone 35S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32735"]]
+32734=PROJCS["WGS 84 / UTM zone 34S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32734"]]
+32733=PROJCS["WGS 84 / UTM zone 33S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32733"]]
+32732=PROJCS["WGS 84 / UTM zone 32S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32732"]]
+32731=PROJCS["WGS 84 / UTM zone 31S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32731"]]
+32730=PROJCS["WGS 84 / UTM zone 30S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32730"]]
+32729=PROJCS["WGS 84 / UTM zone 29S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32729"]]
+32728=PROJCS["WGS 84 / UTM zone 28S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32728"]]
+32727=PROJCS["WGS 84 / UTM zone 27S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32727"]]
+32726=PROJCS["WGS 84 / UTM zone 26S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32726"]]
+32725=PROJCS["WGS 84 / UTM zone 25S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32725"]]
+32724=PROJCS["WGS 84 / UTM zone 24S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32724"]]
+32723=PROJCS["WGS 84 / UTM zone 23S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32723"]]
+32722=PROJCS["WGS 84 / UTM zone 22S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32722"]]
+32721=PROJCS["WGS 84 / UTM zone 21S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32721"]]
+32720=PROJCS["WGS 84 / UTM zone 20S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32720"]]
+32719=PROJCS["WGS 84 / UTM zone 19S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32719"]]
+32718=PROJCS["WGS 84 / UTM zone 18S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32718"]]
+32717=PROJCS["WGS 84 / UTM zone 17S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32717"]]
+32716=PROJCS["WGS 84 / UTM zone 16S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32716"]]
+32715=PROJCS["WGS 84 / UTM zone 15S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32715"]]
+32714=PROJCS["WGS 84 / UTM zone 14S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32714"]]
+32713=PROJCS["WGS 84 / UTM zone 13S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32713"]]
+32712=PROJCS["WGS 84 / UTM zone 12S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32712"]]
+32711=PROJCS["WGS 84 / UTM zone 11S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32711"]]
+32710=PROJCS["WGS 84 / UTM zone 10S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32710"]]
+32709=PROJCS["WGS 84 / UTM zone 9S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32709"]]
+32708=PROJCS["WGS 84 / UTM zone 8S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32708"]]
+32707=PROJCS["WGS 84 / UTM zone 7S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32707"]]
+32706=PROJCS["WGS 84 / UTM zone 6S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32706"]]
+32705=PROJCS["WGS 84 / UTM zone 5S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32705"]]
+32704=PROJCS["WGS 84 / UTM zone 4S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32704"]]
+32703=PROJCS["WGS 84 / UTM zone 3S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32703"]]
+32702=PROJCS["WGS 84 / UTM zone 2S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32702"]]
+32701=PROJCS["WGS 84 / UTM zone 1S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32701"]]
Index: /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/crs/epsg_original.properties
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/crs/epsg_original.properties	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/crs/epsg_original.properties	(revision 28000)
@@ -0,0 +1,4895 @@
+#Generated from EPSG database version 7.9.0
+#Sun Oct 16 14:49:47 CEST 2011
+66276413=GEOGCS["RGR92 (3D deg)", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","66276413"]]
+66276405=GEOGCS["RGR92 (deg)", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66276405"]]
+61556405=GEOGCS["Dabola 1981 (deg)", DATUM["Dabola 1981", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-83.0, 37.0, 124.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6155"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61556405"]]
+63046405=GEOGCS["Voirol 1875 (deg)", DATUM["Voirol 1875", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-73.0, -247.0, 227.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6304"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63046405"]]
+66116405=GEOGCS["Hong Kong 1980 (deg)", DATUM["Hong Kong 1980", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-162.619, -276.959, -161.764, 0.067753, -2.243649, -1.158827, -1.094246], AUTHORITY["EPSG","6611"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66116405"]]
+21292=PROJCS["Barbados 1938 / Barbados National Grid", GEOGCS["Barbados 1938", DATUM["Barbados 1938", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[31.95, 300.99, 419.19, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6212"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4212"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -59.55972222222222], PARAMETER["latitude_of_origin", 13.176388888888892], PARAMETER["scale_factor", 0.9999986], PARAMETER["false_easting", 30000.0], PARAMETER["false_northing", 75000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21292"]]
+21291=PROJCS["Barbados 1938 / British West Indies Grid", GEOGCS["Barbados 1938", DATUM["Barbados 1938", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[31.95, 300.99, 419.19, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6212"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4212"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -62.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9995], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21291"]]
+4099=COMPD_CS["ETRS89 / DKTM3 + DVR90 height", PROJCS["ETRS89 / DKTM3", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 11.75], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4095"]], VERT_CS["DVR90 height", VERT_DATUM["Dansk Vertikal Reference 1990", 2005, AUTHORITY["EPSG","5206"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5799"]], AUTHORITY["EPSG","4099"]]
+4098=COMPD_CS["ETRS89 / DKTM2 + DVR90 height", PROJCS["ETRS89 / DKTM2", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 10.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4094"]], VERT_CS["DVR90 height", VERT_DATUM["Dansk Vertikal Reference 1990", 2005, AUTHORITY["EPSG","5206"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5799"]], AUTHORITY["EPSG","4098"]]
+4097=COMPD_CS["ETRS89 / DKTM1 + DVR90 height", PROJCS["ETRS89 / DKTM1", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4093"]], VERT_CS["DVR90 height", VERT_DATUM["Dansk Vertikal Reference 1990", 2005, AUTHORITY["EPSG","5206"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5799"]], AUTHORITY["EPSG","4097"]]
+4096=PROJCS["ETRS89 / DKTM4", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4096"]]
+4095=PROJCS["ETRS89 / DKTM3", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 11.75], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4095"]]
+4094=PROJCS["ETRS89 / DKTM2", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 10.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4094"]]
+4093=PROJCS["ETRS89 / DKTM1", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4093"]]
+4088=PROJCS["World Equidistant Cylindrical (Sphere)", GEOGCS["Unspecified datum based upon the GRS 1980 Authalic Sphere", DATUM["Not specified (based on GRS 1980 Authalic Sphere)", SPHEROID["GRS 1980 Authalic Sphere", 6371007.0, 0.0, AUTHORITY["EPSG","7048"]], AUTHORITY["EPSG","6047"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4047"]], PROJECTION["Equidistant Cylindrical (Spherical)", AUTHORITY["EPSG","1029"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 0.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4088"]]
+4087=PROJCS["WGS 84 / World Equidistant Cylindrical", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Equidistant_Cylindrical", AUTHORITY["EPSG","1028"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 0.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4087"]]
+66666405=GEOGCS["Lisbon 1890 (deg)", DATUM["Lisbon 1890", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[631.392, -66.551, 481.442, 1.09, 4.445, 4.487, -4.43], AUTHORITY["EPSG","6666"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66666405"]]
+4083=PROJCS["REGCAN95 / UTM zone 28N", GEOGCS["REGCAN95", DATUM["Red Geodesica de Canarias 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1035"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4081"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4083"]]
+4082=PROJCS["REGCAN95 / UTM zone 27N", GEOGCS["REGCAN95", DATUM["Red Geodesica de Canarias 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1035"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4081"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4082"]]
+4081=GEOGCS["REGCAN95", DATUM["Red Geodesica de Canarias 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1035"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4081"]]
+61946405=GEOGCS["Qornoq 1927 (deg)", DATUM["Qornoq 1927", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[163.511, 127.533, -159.789, 0.0, 0.0, 0.814, -0.6], AUTHORITY["EPSG","6194"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61946405"]]
+4080=GEOGCS["REGCAN95", DATUM["Red Geodesica de Canarias 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1035"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4080"]]
+62896405=GEOGCS["Amersfoort (deg)", DATUM["Amersfoort", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[565.2369, 50.0087, 465.658, -0.40685733032239757, -0.3507326765425626, 1.8703473836067959, 4.0812], AUTHORITY["EPSG","6289"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62896405"]]
+4079=GEOCCS["REGCAN95", DATUM["Red Geodesica de Canarias 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1035"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4079"]]
+4075=GEOGCS["SREF98", DATUM["Serbian Reference Network 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1034"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4075"]]
+4074=GEOGCS["SREF98", DATUM["Serbian Reference Network 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1034"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4074"]]
+4073=GEOCCS["SREF98", DATUM["Serbian Reference Network 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1034"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4073"]]
+4071=PROJCS["Chua / UTM zone 23S", GEOGCS["Chua", DATUM["Chua", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-144.35, 242.88, -33.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6224"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4224"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4071"]]
+31028=PROJCS["Yoff / UTM zone 28N", GEOGCS["Yoff", DATUM["Yoff", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6310"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4310"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31028"]]
+4063=PROJCS["RGRDC 2005 / UTM zone 35S", GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4046"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4063"]]
+4062=PROJCS["RGRDC 2005 / UTM zone 34S", GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4046"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4062"]]
+4061=PROJCS["RGRDC 2005 / UTM zone 33S", GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4046"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4061"]]
+4060=PROJCS["RGRDC 2005 / Congo TM zone 28", GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4046"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 28.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4060"]]
+68156405=GEOGCS["Greek (Athens) (deg)", DATUM["Greek (Athens)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6815"]], PRIMEM["Athens", 23.7163375, AUTHORITY["EPSG","8912"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","68156405"]]
+4059=PROJCS["RGRDC 2005 / Congo TM zone 26", GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4046"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 26.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4059"]]
+4058=PROJCS["RGRDC 2005 / Congo TM zone 24", GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4046"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4058"]]
+4057=PROJCS["RGRDC 2005 / Congo TM zone 22", GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4046"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 22.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4057"]]
+4056=PROJCS["RGRDC 2005 / Congo TM zone 20", GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4046"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 20.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4056"]]
+4055=GEOGCS["Popular Visualisation CRS", DATUM["Popular Visualisation Datum", SPHEROID["Popular Visualisation Sphere", 6378137.0, 0.0, AUTHORITY["EPSG","7059"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6055"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4055"]]
+4054=GEOGCS["Unspecified datum based upon the Hughes 1980 ellipsoid", DATUM["Not specified (based on Hughes 1980 ellipsoid)", SPHEROID["Hughes 1980", 6378273.0, 298.279411123064, AUTHORITY["EPSG","7058"]], AUTHORITY["EPSG","6054"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4054"]]
+4053=GEOGCS["Unspecified datum based upon the International 1924 Authalic Sphere", DATUM["Not specified (based on International 1924 Authalic Sphere)", SPHEROID["International 1924 Authalic Sphere", 6371228.0, 0.0, AUTHORITY["EPSG","7057"]], AUTHORITY["EPSG","6053"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4053"]]
+4052=GEOGCS["Unspecified datum based upon the Clarke 1866 Authalic Sphere", DATUM["Not specified (based on Clarke 1866 Authalic Sphere)", SPHEROID["Clarke 1866 Authalic Sphere", 6370997.0, 0.0, AUTHORITY["EPSG","7052"]], AUTHORITY["EPSG","6052"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4052"]]
+4051=PROJCS["RGRDC 2005 / Congo TM zone 18", GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4046"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4051"]]
+4050=PROJCS["RGRDC 2005 / Congo TM zone 16", GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4046"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 16.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4050"]]
+4049=PROJCS["RGRDC 2005 / Congo TM zone 14", GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4046"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 14.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4049"]]
+4048=PROJCS["RGRDC 2005 / Congo TM zone 12", GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4046"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4048"]]
+4047=GEOGCS["Unspecified datum based upon the GRS 1980 Authalic Sphere", DATUM["Not specified (based on GRS 1980 Authalic Sphere)", SPHEROID["GRS 1980 Authalic Sphere", 6371007.0, 0.0, AUTHORITY["EPSG","7048"]], AUTHORITY["EPSG","6047"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4047"]]
+4046=GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4046"]]
+4045=GEOGCS["Unknown datum based upon the Everest 1830 (1975 Definition) ellipsoid", DATUM["Not specified (based on Everest 1830 (1975 Definition) ellipsoid)", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], AUTHORITY["EPSG","6045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4045"]]
+4044=GEOGCS["Unknown datum based upon the Everest 1830 (1962 Definition) ellipsoid", DATUM["Not specified (based on Everest 1830 (1962 Definition) ellipsoid)", SPHEROID["Everest 1830 (1962 Definition)", 6377301.243, 300.8017255, AUTHORITY["EPSG","7044"]], AUTHORITY["EPSG","6044"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4044"]]
+4043=GEOGCS["Unknown datum based upon the WGS 72 ellipsoid", DATUM["Not specified (based on WGS 72 ellipsoid)", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], AUTHORITY["EPSG","6043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4043"]]
+4042=GEOGCS["Unknown datum based upon the Everest (1830 Definition) ellipsoid", DATUM["Not specified (based on Everest (1830 Definition) ellipsoid)", SPHEROID["Everest (1830 Definition)", 6377299.36559538, 300.80172554336184, AUTHORITY["EPSG","7042"]], AUTHORITY["EPSG","6042"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4042"]]
+4041=GEOGCS["Unknown datum based upon the Average Terrestrial System 1977 ellipsoid", DATUM["Not specified (based on Average Terrestrial System 1977 ellipsoid)", SPHEROID["Average Terrestrial System 1977", 6378135.0, 298.257, AUTHORITY["EPSG","7041"]], AUTHORITY["EPSG","6041"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4041"]]
+4040=GEOGCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4040"]]
+62736405=GEOGCS["NGO 1948 (deg)", DATUM["NGO 1948", SPHEROID["Bessel Modified", 6377492.018, 299.1528128, AUTHORITY["EPSG","7005"]], TOWGS84[278.3, 93.0, 474.5, 7.889, 0.05, -6.61, 6.21], AUTHORITY["EPSG","6273"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62736405"]]
+4039=GEOCCS["RGRDC 2005", DATUM["Reseau Geodesique de la RDC 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4039"]]
+4038=PROJCS["WGS 84 / TMzn36N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4038"]]
+4037=PROJCS["WGS 84 / TMzn35N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4037"]]
+4036=GEOGCS["Unknown datum based upon the GRS 1967 ellipsoid", DATUM["Not specified (based on GRS 1967 ellipsoid)", SPHEROID["GRS 1967", 6378160.0, 298.247167427, AUTHORITY["EPSG","7036"]], AUTHORITY["EPSG","6036"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4036"]]
+4035=GEOGCS["Unknown datum based upon the Authalic Sphere", DATUM["Not specified (based on Authalic Sphere)", SPHEROID["Sphere", 6371000.0, 0.0, AUTHORITY["EPSG","7035"]], AUTHORITY["EPSG","6035"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4035"]]
+4034=GEOGCS["Unknown datum based upon the Clarke 1880 ellipsoid", DATUM["Not specified (based on Clarke 1880 ellipsoid)", SPHEROID["Clarke 1880", 6378249.144808011, 293.46630765562986, AUTHORITY["EPSG","7034"]], AUTHORITY["EPSG","6034"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4034"]]
+4033=GEOGCS["Unknown datum based upon the OSU91A ellipsoid", DATUM["Not specified (based on OSU91A ellipsoid)", SPHEROID["OSU91A", 6378136.3, 298.257223563, AUTHORITY["EPSG","7033"]], AUTHORITY["EPSG","6033"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4033"]]
+4032=GEOGCS["Unknown datum based upon the OSU86F ellipsoid", DATUM["Not specified (based on OSU86F ellipsoid)", SPHEROID["OSU86F", 6378136.2, 298.257223563, AUTHORITY["EPSG","7032"]], AUTHORITY["EPSG","6032"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4032"]]
+4031=GEOGCS["Unknown datum based upon the GEM 10C ellipsoid", DATUM["Not specified (based on GEM 10C ellipsoid)", SPHEROID["GEM 10C", 6378137.0, 298.257223563, AUTHORITY["EPSG","7031"]], AUTHORITY["EPSG","6031"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4031"]]
+4030=GEOGCS["Unknown datum based upon the WGS 84 ellipsoid", DATUM["Not specified (based on WGS 84 ellipsoid)", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6030"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4030"]]
+4029=GEOGCS["Unknown datum based upon the War Office ellipsoid", DATUM["Not specified (based on War Office ellipsoid)", SPHEROID["War Office", 6378300.0, 296.0, AUTHORITY["EPSG","7029"]], AUTHORITY["EPSG","6029"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4029"]]
+4028=GEOGCS["Unknown datum based upon the Struve 1860 ellipsoid", DATUM["Not specified (based on Struve 1860 ellipsoid)", SPHEROID["Struve 1860", 6378298.3, 294.73, AUTHORITY["EPSG","7028"]], AUTHORITY["EPSG","6028"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4028"]]
+4027=GEOGCS["Unknown datum based upon the Plessis 1817 ellipsoid", DATUM["Not specified (based on Plessis 1817 ellipsoid)", SPHEROID["Plessis 1817", 6376523.0, 308.64, AUTHORITY["EPSG","7027"]], AUTHORITY["EPSG","6027"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4027"]]
+4026=PROJCS["MOLDREF99 / Moldova TM", GEOGCS["MOLDREF99", DATUM["MOLDREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1032"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4023"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 28.4], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99994], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4026"]]
+4025=GEOGCS["Unknown datum based upon the NWL 9D ellipsoid", DATUM["Not specified (based on NWL 9D ellipsoid)", SPHEROID["NWL 9D", 6378145.0, 298.25, AUTHORITY["EPSG","7025"]], AUTHORITY["EPSG","6025"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4025"]]
+4024=GEOGCS["Unknown datum based upon the Krassowsky 1940 ellipsoid", DATUM["Not specified (based on Krassowsky 1940 ellipsoid)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","6024"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4024"]]
+4023=GEOGCS["MOLDREF99", DATUM["MOLDREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1032"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4023"]]
+4022=GEOGCS["Unknown datum based upon the International 1924 ellipsoid", DATUM["Not specified (based on International 1924 ellipsoid)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6022"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4022"]]
+4021=GEOGCS["Unknown datum based upon the Indonesian National Spheroid", DATUM["Not specified (based on Indonesian National Spheroid)", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], AUTHORITY["EPSG","6021"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4021"]]
+4020=GEOGCS["Unknown datum based upon the Helmert 1906 ellipsoid", DATUM["Not specified (based on Helmert 1906 ellipsoid)", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], AUTHORITY["EPSG","6020"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4020"]]
+4019=GEOGCS["Unknown datum based upon the GRS 1980 ellipsoid", DATUM["Not specified (based on GRS 1980 ellipsoid)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6019"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4019"]]
+61456405=GEOGCS["Kalianpur 1962 (deg)", DATUM["Kalianpur 1962", SPHEROID["Everest 1830 (1962 Definition)", 6377301.243, 300.8017255, AUTHORITY["EPSG","7044"]], TOWGS84[275.57, 676.78, 229.6, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6145"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61456405"]]
+4018=GEOGCS["Unknown datum based upon the Everest 1830 Modified ellipsoid", DATUM["Not specified (based on Everest 1830 Modified ellipsoid)", SPHEROID["Everest 1830 Modified", 6377304.063, 300.8017, AUTHORITY["EPSG","7018"]], AUTHORITY["EPSG","6018"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4018"]]
+4017=GEOGCS["MOLDREF99", DATUM["MOLDREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1032"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4017"]]
+4016=GEOGCS["Unknown datum based upon the Everest 1830 (1967 Definition) ellipsoid", DATUM["Not specified (based on Everest 1830 (1967 Definition) ellipsoid)", SPHEROID["Everest 1830 (1967 Definition)", 6377298.556, 300.8017, AUTHORITY["EPSG","7016"]], AUTHORITY["EPSG","6016"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4016"]]
+4015=GEOGCS["Unknown datum based upon the Everest 1830 (1937 Adjustment) ellipsoid", DATUM["Not specified (based on Everest 1830 (1937 Adjustment) ellipsoid)", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], AUTHORITY["EPSG","6015"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4015"]]
+4014=GEOGCS["Unknown datum based upon the Clarke 1880 (SGA 1922) ellipsoid", DATUM["Not specified (based on Clarke 1880 (SGA 1922) ellipsoid)", SPHEROID["Clarke 1880 (SGA 1922)", 6378249.2, 293.46598, AUTHORITY["EPSG","7014"]], AUTHORITY["EPSG","6014"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4014"]]
+4013=GEOGCS["Unknown datum based upon the Clarke 1880 (Arc) ellipsoid", DATUM["Not specified (based on Clarke 1880 (Arc) ellipsoid)", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], AUTHORITY["EPSG","6013"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4013"]]
+4012=GEOGCS["Unknown datum based upon the Clarke 1880 (RGS) ellipsoid", DATUM["Not specified (based on Clarke 1880 (RGS) ellipsoid)", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6012"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4012"]]
+4011=GEOGCS["Unknown datum based upon the Clarke 1880 (IGN) ellipsoid", DATUM["Not specified (based on Clarke 1880 (IGN) ellipsoid)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6011"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4011"]]
+4010=GEOGCS["Unknown datum based upon the Clarke 1880 (Benoit) ellipsoid", DATUM["Not specified (based on Clarke 1880 (Benoit) ellipsoid)", SPHEROID["Clarke 1880 (Benoit)", 6378300.789, 293.4663155389811, AUTHORITY["EPSG","7010"]], AUTHORITY["EPSG","6010"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4010"]]
+4009=GEOGCS["Unknown datum based upon the Clarke 1866 Michigan ellipsoid", DATUM["Not specified (based on Clarke 1866 Michigan ellipsoid)", SPHEROID["Clarke 1866 Michigan", 6378450.047548896, 294.978697164674, AUTHORITY["EPSG","7009"]], AUTHORITY["EPSG","6009"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4009"]]
+4008=GEOGCS["Unknown datum based upon the Clarke 1866 ellipsoid", DATUM["Not specified (based on Clarke 1866 ellipsoid)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6008"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4008"]]
+4007=GEOGCS["Unknown datum based upon the Clarke 1858 ellipsoid", DATUM["Not specified (based on Clarke 1858 ellipsoid)", SPHEROID["Clarke 1858", 6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]], AUTHORITY["EPSG","6007"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4007"]]
+4006=GEOGCS["Unknown datum based upon the Bessel Namibia ellipsoid", DATUM["Not specified (based on Bessel Namibia ellipsoid)", SPHEROID["Bessel Namibia (GLM)", 6377483.865280419, 299.1528128, AUTHORITY["EPSG","7046"]], AUTHORITY["EPSG","6006"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4006"]]
+4005=GEOGCS["Unknown datum based upon the Bessel Modified ellipsoid", DATUM["Not specified (based on Bessel Modified ellipsoid)", SPHEROID["Bessel Modified", 6377492.018, 299.1528128, AUTHORITY["EPSG","7005"]], AUTHORITY["EPSG","6005"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4005"]]
+4004=GEOGCS["Unknown datum based upon the Bessel 1841 ellipsoid", DATUM["Not specified (based on Bessel 1841 ellipsoid)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6004"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4004"]]
+4003=GEOGCS["Unknown datum based upon the Australian National Spheroid", DATUM["Not specified (based on Australian National Spheroid)", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], AUTHORITY["EPSG","6003"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4003"]]
+22994=PROJCS["Egypt 1907 / Extended Purple Belt", GEOGCS["Egypt 1907", DATUM["Egypt 1907", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], TOWGS84[-130.0, 110.0, -13.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6229"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4229"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 1200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22994"]]
+4002=GEOGCS["Unknown datum based upon the Airy Modified 1849 ellipsoid", DATUM["Not specified (based on Airy Modified 1849 ellipsoid)", SPHEROID["Airy Modified 1849", 6377340.189, 299.3249646, AUTHORITY["EPSG","7002"]], AUTHORITY["EPSG","6002"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4002"]]
+22993=PROJCS["Egypt 1907 / Purple Belt", GEOGCS["Egypt 1907", DATUM["Egypt 1907", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], TOWGS84[-130.0, 110.0, -13.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6229"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4229"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22993"]]
+4001=GEOGCS["Unknown datum based upon the Airy 1830 ellipsoid", DATUM["Not specified (based on Airy 1830 ellipsoid)", SPHEROID["Airy 1830", 6377563.396, 299.3249646, AUTHORITY["EPSG","7001"]], AUTHORITY["EPSG","6001"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4001"]]
+22992=PROJCS["Egypt 1907 / Red Belt", GEOGCS["Egypt 1907", DATUM["Egypt 1907", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], TOWGS84[-130.0, 110.0, -13.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6229"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4229"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 31.0], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 615000.0], PARAMETER["false_northing", 810000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22992"]]
+4000=GEOCCS["MOLDREF99", DATUM["MOLDREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1032"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4000"]]
+22991=PROJCS["Egypt 1907 / Blue Belt", GEOGCS["Egypt 1907", DATUM["Egypt 1907", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], TOWGS84[-130.0, 110.0, -13.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6229"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4229"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 35.0], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 1100000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22991"]]
+32766=PROJCS["WGS 84 / TM 36 SE", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 36.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32766"]]
+32761=PROJCS["WGS 84 / UPS South (N,E)", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar_Stereographic", AUTHORITY["EPSG","9810"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 0.994], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 2000000.0], UNIT["m", 1.0], AXIS["Northing", "North along 0 deg"], AXIS["Easting", "North along 90 deg East"], AUTHORITY["EPSG","32761"]]
+32760=PROJCS["WGS 84 / UTM zone 60S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32760"]]
+32759=PROJCS["WGS 84 / UTM zone 59S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32759"]]
+32758=PROJCS["WGS 84 / UTM zone 58S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32758"]]
+32757=PROJCS["WGS 84 / UTM zone 57S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32757"]]
+32756=PROJCS["WGS 84 / UTM zone 56S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32756"]]
+32755=PROJCS["WGS 84 / UTM zone 55S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32755"]]
+32754=PROJCS["WGS 84 / UTM zone 54S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32754"]]
+32753=PROJCS["WGS 84 / UTM zone 53S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32753"]]
+32752=PROJCS["WGS 84 / UTM zone 52S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32752"]]
+32751=PROJCS["WGS 84 / UTM zone 51S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32751"]]
+32750=PROJCS["WGS 84 / UTM zone 50S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32750"]]
+5799=VERT_CS["DVR90 height", VERT_DATUM["Dansk Vertikal Reference 1990", 2005, AUTHORITY["EPSG","5206"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5799"]]
+5798=VERT_CS["EGM84 geoid height", VERT_DATUM["EGM84 geoid", 2005, AUTHORITY["EPSG","5203"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5798"]]
+5797=VERT_CS["AIOC95 height", VERT_DATUM["AIOC 1995", 2005, AUTHORITY["EPSG","5133"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5797"]]
+5796=VERT_CS["Lagos 1955 height", VERT_DATUM["Lagos 1955", 2005, AUTHORITY["EPSG","5194"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5796"]]
+5795=VERT_CS["Guadeloupe 1951 height", VERT_DATUM["Guadeloupe 1951", 2005, AUTHORITY["EPSG","5193"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5795"]]
+5794=VERT_CS["Martinique 1955 height", VERT_DATUM["Martinique 1955", 2005, AUTHORITY["EPSG","5192"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5794"]]
+5793=VERT_CS["Mayotte 1950 height", VERT_DATUM["Mayotte 1950", 2005, AUTHORITY["EPSG","5191"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5793"]]
+5792=VERT_CS["Danger 1950 height", VERT_DATUM["Danger 1950", 2005, AUTHORITY["EPSG","5190"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5792"]]
+5791=VERT_CS["NGC 1948 height", VERT_DATUM["Nivellement General de la Corse 1948", 2005, AUTHORITY["EPSG","5189"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5791"]]
+5790=VERT_CS["KOC CD height", VERT_DATUM["KOC Construction Datum", 2005, AUTHORITY["EPSG","5188"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5790"]]
+20791=PROJCS["Lisbon (Lisbon) / Portuguese Grid", GEOGCS["Lisbon (Lisbon)", DATUM["Lisbon 1937 (Lisbon)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6803"]], PRIMEM["Lisbon", -9.131906111111114, AUTHORITY["EPSG","8902"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4803"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 1.0], PARAMETER["latitude_of_origin", 39.666666666666664], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20791"]]
+20790=PROJCS["Lisbon (Lisbon) / Portuguese National Grid", GEOGCS["Lisbon (Lisbon)", DATUM["Lisbon 1937 (Lisbon)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6803"]], PRIMEM["Lisbon", -9.131906111111114, AUTHORITY["EPSG","8902"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4803"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 1.0], PARAMETER["latitude_of_origin", 39.666666666666664], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20790"]]
+32749=PROJCS["WGS 84 / UTM zone 49S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32749"]]
+32748=PROJCS["WGS 84 / UTM zone 48S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32748"]]
+32747=PROJCS["WGS 84 / UTM zone 47S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32747"]]
+32746=PROJCS["WGS 84 / UTM zone 46S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32746"]]
+32745=PROJCS["WGS 84 / UTM zone 45S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32745"]]
+32744=PROJCS["WGS 84 / UTM zone 44S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32744"]]
+32743=PROJCS["WGS 84 / UTM zone 43S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32743"]]
+32742=PROJCS["WGS 84 / UTM zone 42S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32742"]]
+32741=PROJCS["WGS 84 / UTM zone 41S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32741"]]
+32740=PROJCS["WGS 84 / UTM zone 40S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32740"]]
+5789=VERT_CS["KOC WD depth", VERT_DATUM["KOC Well Datum", 2005, AUTHORITY["EPSG","5187"]], UNIT["m", 1.0], AXIS["Gravity-related depth", DOWN], AUTHORITY["EPSG","5789"]]
+66016405=GEOGCS["Antigua 1943 (deg)", DATUM["Antigua 1943", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-255.0, -15.0, 71.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6601"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66016405"]]
+5788=VERT_CS["Kuwait PWD height", VERT_DATUM["Kuwait PWD", 2005, AUTHORITY["EPSG","5186"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5788"]]
+5787=VERT_CS["EOMA 1980 height", VERT_DATUM["Baltic 1980", 2005, AUTHORITY["EPSG","5185"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5787"]]
+5786=VERT_CS["Baltic 1982 height", VERT_DATUM["Baltic 1982", 2005, AUTHORITY["EPSG","5184"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5786"]]
+5785=VERT_CS["SNN76 height", VERT_DATUM["SNN76", 2005, AUTHORITY["EPSG","5183"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5785"]]
+5784=VERT_CS["DHHN85 height", VERT_DATUM["Deutsches Haupthoehennetz 1985", 2005, AUTHORITY["EPSG","5182"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5784"]]
+5783=VERT_CS["DHHN92 height", VERT_DATUM["Deutsches Haupthoehennetz 1992", 2005, AUTHORITY["EPSG","5181"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5783"]]
+5782=VERT_CS["Alicante height", VERT_DATUM["Alicante", 2005, AUTHORITY["EPSG","5180"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5782"]]
+5781=VERT_CS["Constanta height", VERT_DATUM["Constanta", 2005, AUTHORITY["EPSG","5179"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5781"]]
+5780=VERT_CS["Cascais height", VERT_DATUM["Cascais", 2005, AUTHORITY["EPSG","5178"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5780"]]
+62246405=GEOGCS["Chua (deg)", DATUM["Chua", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-144.35, 242.88, -33.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6224"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62246405"]]
+32739=PROJCS["WGS 84 / UTM zone 39S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32739"]]
+32738=PROJCS["WGS 84 / UTM zone 38S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32738"]]
+32737=PROJCS["WGS 84 / UTM zone 37S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32737"]]
+32736=PROJCS["WGS 84 / UTM zone 36S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32736"]]
+32735=PROJCS["WGS 84 / UTM zone 35S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32735"]]
+32734=PROJCS["WGS 84 / UTM zone 34S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32734"]]
+32733=PROJCS["WGS 84 / UTM zone 33S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32733"]]
+32732=PROJCS["WGS 84 / UTM zone 32S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32732"]]
+32731=PROJCS["WGS 84 / UTM zone 31S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32731"]]
+32730=PROJCS["WGS 84 / UTM zone 30S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32730"]]
+5779=VERT_CS["NVN99 height", VERT_DATUM["National Vertical Network 1999", 2005, AUTHORITY["EPSG","5177"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5779"]]
+5778=VERT_CS["GHA height", VERT_DATUM["Gebrauchshohen ADRIA", 2005, AUTHORITY["EPSG","5176"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5778"]]
+5777=VERT_CS["Durres height", VERT_DATUM["Durres", 2005, AUTHORITY["EPSG","5175"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5777"]]
+5776=VERT_CS["NN54 height", VERT_DATUM["Norway Normal Nul 1954", 2005, AUTHORITY["EPSG","5174"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5776"]]
+5775=VERT_CS["Antalya height", VERT_DATUM["Antalya", 2005, AUTHORITY["EPSG","5173"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5775"]]
+5774=VERT_CS["NG-L height", VERT_DATUM["Nivellement General du Luxembourg", 2005, AUTHORITY["EPSG","5172"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5774"]]
+5773=VERT_CS["EGM96 geoid height", VERT_DATUM["EGM96 geoid", 2005, AUTHORITY["EPSG","5171"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5773"]]
+3599=PROJCS["NAD83(NSRS2007) / Mississippi West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.33333333333333], PARAMETER["latitude_of_origin", 29.5], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3599"]]
+5772=VERT_CS["Stewart Island 1977 height", VERT_DATUM["Stewart Island 1977", 2005, AUTHORITY["EPSG","5170"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5772"]]
+3598=PROJCS["NAD83(NSRS2007) / Mississippi East (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.83333333333333], PARAMETER["latitude_of_origin", 29.5], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3598"]]
+5771=VERT_CS["Chatham Island 1959 height", VERT_DATUM["Waitangi (Chatham Island) 1959", 2005, AUTHORITY["EPSG","5169"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5771"]]
+3597=PROJCS["NAD83(NSRS2007) / Mississippi East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.83333333333333], PARAMETER["latitude_of_origin", 29.5], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3597"]]
+5770=VERT_CS["Wellington 1953 height", VERT_DATUM["Wellington 1953", 2005, AUTHORITY["EPSG","5168"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5770"]]
+3596=PROJCS["NAD83(NSRS2007) / Minnesota South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.0], PARAMETER["latitude_of_origin", 43.0], PARAMETER["standard_parallel_1", 45.21666666666667], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 100000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.78333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3596"]]
+3595=PROJCS["NAD83(NSRS2007) / Minnesota North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.1], PARAMETER["latitude_of_origin", 46.5], PARAMETER["standard_parallel_1", 48.63333333333333], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 100000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.03333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3595"]]
+3594=PROJCS["NAD83(NSRS2007) / Minnesota Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.25], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 47.05], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 100000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.61666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3594"]]
+3593=PROJCS["NAD83(NSRS2007) / Michigan South (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.36666666666666], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.666666666666664], PARAMETER["false_easting", 13123359.580000002], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.1], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3593"]]
+3592=PROJCS["NAD83(NSRS2007) / Michigan South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.36666666666666], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.666666666666664], PARAMETER["false_easting", 4000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.1], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3592"]]
+3591=PROJCS["NAD83(NSRS2007) / Michigan Oblique Mercator", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9812"]], PARAMETER["longitude_of_center", -86.0], PARAMETER["latitude_of_center", 45.30916666666668], PARAMETER["azimuth", 337.25555999999995], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 2546731.496], PARAMETER["false_northing", -4354009.816], PARAMETER["rectified_grid_angle", 337.25555999999995], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3591"]]
+3590=PROJCS["NAD83(NSRS2007) / Michigan North (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 44.78333333333333], PARAMETER["standard_parallel_1", 47.083333333333336], PARAMETER["false_easting", 26246719.160000004], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.48333333333333], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3590"]]
+32729=PROJCS["WGS 84 / UTM zone 29S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32729"]]
+32728=PROJCS["WGS 84 / UTM zone 28S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32728"]]
+32727=PROJCS["WGS 84 / UTM zone 27S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32727"]]
+32726=PROJCS["WGS 84 / UTM zone 26S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32726"]]
+32725=PROJCS["WGS 84 / UTM zone 25S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32725"]]
+32724=PROJCS["WGS 84 / UTM zone 24S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32724"]]
+32723=PROJCS["WGS 84 / UTM zone 23S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32723"]]
+32722=PROJCS["WGS 84 / UTM zone 22S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32722"]]
+32721=PROJCS["WGS 84 / UTM zone 21S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32721"]]
+32720=PROJCS["WGS 84 / UTM zone 20S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32720"]]
+5769=VERT_CS["Taranaki 1970 height", VERT_DATUM["Taranaki 1970", 2005, AUTHORITY["EPSG","5167"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5769"]]
+5768=VERT_CS["Tararu 1952 height", VERT_DATUM["Tararu 1952", 2005, AUTHORITY["EPSG","5166"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5768"]]
+5767=VERT_CS["One Tree Point 1964 height", VERT_DATUM["One Tree Point 1964", 2005, AUTHORITY["EPSG","5165"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5767"]]
+5766=VERT_CS["Nelson 1955 height", VERT_DATUM["Nelson 1955", 2005, AUTHORITY["EPSG","5164"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5766"]]
+5765=VERT_CS["Napier 1962 height", VERT_DATUM["Napier 1962", 2005, AUTHORITY["EPSG","5163"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5765"]]
+5764=VERT_CS["Moturiki 1953 height", VERT_DATUM["Moturiki 1953", 2005, AUTHORITY["EPSG","5162"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5764"]]
+5763=VERT_CS["Lyttelton 1937 height", VERT_DATUM["Lyttelton 1937", 2005, AUTHORITY["EPSG","5161"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5763"]]
+3589=PROJCS["NAD83(NSRS2007) / Michigan North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 44.78333333333333], PARAMETER["standard_parallel_1", 47.083333333333336], PARAMETER["false_easting", 8000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.48333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3589"]]
+5762=VERT_CS["Gisborne 1926 height", VERT_DATUM["Gisborne 1926", 2005, AUTHORITY["EPSG","5160"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5762"]]
+3588=PROJCS["NAD83(NSRS2007) / Michigan Central (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.36666666666666], PARAMETER["latitude_of_origin", 43.31666666666666], PARAMETER["standard_parallel_1", 45.699999999999996], PARAMETER["false_easting", 19685039.369999997], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.18333333333334], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3588"]]
+5761=VERT_CS["Dunedin 1958 height", VERT_DATUM["Dunedin 1958", 2005, AUTHORITY["EPSG","5159"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5761"]]
+3587=PROJCS["NAD83(NSRS2007) / Michigan Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.36666666666666], PARAMETER["latitude_of_origin", 43.31666666666666], PARAMETER["standard_parallel_1", 45.699999999999996], PARAMETER["false_easting", 6000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.18333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3587"]]
+5760=VERT_CS["Bluff 1955 height", VERT_DATUM["Bluff 1955", 2005, AUTHORITY["EPSG","5158"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5760"]]
+3586=PROJCS["NAD83(NSRS2007) / Massachusetts Mainland (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 2460625.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3586"]]
+3585=PROJCS["NAD83(NSRS2007) / Massachusetts Mainland", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 750000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3585"]]
+3584=PROJCS["NAD83(NSRS2007) / Massachusetts Island (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -70.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 41.483333333333334], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.28333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3584"]]
+3583=PROJCS["NAD83(NSRS2007) / Massachusetts Island", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -70.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 41.483333333333334], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.28333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3583"]]
+3582=PROJCS["NAD83(NSRS2007) / Maryland (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.0], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.449999999999996], PARAMETER["false_easting", 1312333.333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.3], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3582"]]
+3581=PROJCS["NAD83(CSRS) / NWT Lambert", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -112.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 70.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 62.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3581"]]
+3580=PROJCS["NAD83 / NWT Lambert", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -112.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 70.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 62.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3580"]]
+32719=PROJCS["WGS 84 / UTM zone 19S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32719"]]
+32718=PROJCS["WGS 84 / UTM zone 18S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32718"]]
+32717=PROJCS["WGS 84 / UTM zone 17S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32717"]]
+32716=PROJCS["WGS 84 / UTM zone 16S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32716"]]
+32715=PROJCS["WGS 84 / UTM zone 15S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32715"]]
+32714=PROJCS["WGS 84 / UTM zone 14S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32714"]]
+32713=PROJCS["WGS 84 / UTM zone 13S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32713"]]
+32712=PROJCS["WGS 84 / UTM zone 12S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32712"]]
+32711=PROJCS["WGS 84 / UTM zone 11S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32711"]]
+32710=PROJCS["WGS 84 / UTM zone 10S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32710"]]
+5759=VERT_CS["Auckland 1946 height", VERT_DATUM["Auckland 1946", 2005, AUTHORITY["EPSG","5157"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5759"]]
+5758=VERT_CS["Reunion 1989 height", VERT_DATUM["Reunion 1989", 2005, AUTHORITY["EPSG","5156"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5758"]]
+5757=VERT_CS["Guadeloupe 1988 height", VERT_DATUM["Guadeloupe 1988", 2005, AUTHORITY["EPSG","5155"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5757"]]
+5756=VERT_CS["Martinique 1987 height", VERT_DATUM["Martinique 1987", 2005, AUTHORITY["EPSG","5154"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5756"]]
+5755=VERT_CS["NGG1977 height", VERT_DATUM["Nivellement General Guyanais 1977", 2005, AUTHORITY["EPSG","5153"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5755"]]
+5754=VERT_CS["Poolbeg height", VERT_DATUM["Poolbeg", 2005, AUTHORITY["EPSG","5152"]], UNIT["m*0.3048007491", 0.3048007491], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5754"]]
+28232=PROJCS["Pointe Noire / UTM zone 32S", GEOGCS["Pointe Noire", DATUM["Congo 1960 Pointe Noire", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-178.3, -316.7, -131.5, 5.278, 6.077, 10.979, 19.166], AUTHORITY["EPSG","6282"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4282"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28232"]]
+5753=VERT_CS["NGNC height", VERT_DATUM["Nivellement General de Nouvelle Caledonie", 2005, AUTHORITY["EPSG","5151"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5753"]]
+3579=PROJCS["NAD83(CSRS) / Yukon Albers", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -132.5], PARAMETER["latitude_of_origin", 59.0], PARAMETER["standard_parallel_1", 61.66666666666667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], PARAMETER["standard_parallel_2", 68.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3579"]]
+5752=VERT_CS["Bandar Abbas height", VERT_DATUM["Bandar Abbas", 2005, AUTHORITY["EPSG","5150"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5752"]]
+3578=PROJCS["NAD83 / Yukon Albers", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -132.5], PARAMETER["latitude_of_origin", 59.0], PARAMETER["standard_parallel_1", 61.66666666666667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], PARAMETER["standard_parallel_2", 68.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3578"]]
+5751=VERT_CS["Fao height", VERT_DATUM["Fao", 2005, AUTHORITY["EPSG","5149"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5751"]]
+3577=PROJCS["GDA94 / Australian Albers", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", -18.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", -36.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3577"]]
+5750=VERT_CS["Douglas height", VERT_DATUM["Douglas", 2005, AUTHORITY["EPSG","5148"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5750"]]
+3576=PROJCS["WGS 84 / North Pole LAEA Russia", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Azimuthal_Equal_Area", AUTHORITY["EPSG","9820"]], PARAMETER["latitude_of_center", 90.0], PARAMETER["longitude_of_center", 90.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "South along 180 deg"], AXIS["Northing", "South along 90 deg West"], AUTHORITY["EPSG","3576"]]
+3575=PROJCS["WGS 84 / North Pole LAEA Europe", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Azimuthal_Equal_Area", AUTHORITY["EPSG","9820"]], PARAMETER["latitude_of_center", 90.0], PARAMETER["longitude_of_center", 10.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "South along 100 deg East"], AXIS["Northing", "South along 170 deg West"], AUTHORITY["EPSG","3575"]]
+3574=PROJCS["WGS 84 / North Pole LAEA Atlantic", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Azimuthal_Equal_Area", AUTHORITY["EPSG","9820"]], PARAMETER["latitude_of_center", 90.0], PARAMETER["longitude_of_center", -40.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "South along 50 deg East"], AXIS["Northing", "South along 140 deg East"], AUTHORITY["EPSG","3574"]]
+3573=PROJCS["WGS 84 / North Pole LAEA Canada", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Azimuthal_Equal_Area", AUTHORITY["EPSG","9820"]], PARAMETER["latitude_of_center", 90.0], PARAMETER["longitude_of_center", -100.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "South along 10 deg West"], AXIS["Northing", "South along 80 deg East"], AUTHORITY["EPSG","3573"]]
+3572=PROJCS["WGS 84 / North Pole LAEA Alaska", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Azimuthal_Equal_Area", AUTHORITY["EPSG","9820"]], PARAMETER["latitude_of_center", 90.0], PARAMETER["longitude_of_center", -150.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "South along 60 deg West"], AXIS["Northing", "South along 30 deg East"], AUTHORITY["EPSG","3572"]]
+61846405=GEOGCS["Azores Oriental 1940 (deg)", DATUM["Azores Oriental Islands 1940", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-203.0, 141.0, 53.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6184"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61846405"]]
+3571=PROJCS["WGS 84 / North Pole LAEA Bering Sea", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Azimuthal_Equal_Area", AUTHORITY["EPSG","9820"]], PARAMETER["latitude_of_center", 90.0], PARAMETER["longitude_of_center", 180.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "South along 90 deg West"], AXIS["Northing", "South along 0 deg"], AUTHORITY["EPSG","3571"]]
+3570=PROJCS["NAD83(HARN) / Utah South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.35], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 9842500.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.21666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3570"]]
+32709=PROJCS["WGS 84 / UTM zone 9S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32709"]]
+32708=PROJCS["WGS 84 / UTM zone 8S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32708"]]
+32707=PROJCS["WGS 84 / UTM zone 7S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32707"]]
+32706=PROJCS["WGS 84 / UTM zone 6S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32706"]]
+32705=PROJCS["WGS 84 / UTM zone 5S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32705"]]
+32704=PROJCS["WGS 84 / UTM zone 4S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32704"]]
+32703=PROJCS["WGS 84 / UTM zone 3S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32703"]]
+32702=PROJCS["WGS 84 / UTM zone 2S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32702"]]
+62796405=GEOGCS["OS(SN)80 (deg)", DATUM["OS (SN) 1980", SPHEROID["Airy 1830", 6377563.396, 299.3249646, AUTHORITY["EPSG","7001"]], AUTHORITY["EPSG","6279"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62796405"]]
+32701=PROJCS["WGS 84 / UTM zone 1S", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32701"]]
+5749=VERT_CS["St Marys height", VERT_DATUM["St Marys", 2005, AUTHORITY["EPSG","5147"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5749"]]
+5748=VERT_CS["Flannan Isles height", VERT_DATUM["Flannan Isles", 2005, AUTHORITY["EPSG","5146"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5748"]]
+5747=VERT_CS["St Kilda height", VERT_DATUM["St Kilda", 2005, AUTHORITY["EPSG","5145"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5747"]]
+5746=VERT_CS["Stornoway height", VERT_DATUM["Stornoway", 2005, AUTHORITY["EPSG","5144"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5746"]]
+5745=VERT_CS["North Rona height", VERT_DATUM["North Rona", 2005, AUTHORITY["EPSG","5143"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5745"]]
+5744=VERT_CS["Sule Skerry height", VERT_DATUM["Sule Skerry", 2005, AUTHORITY["EPSG","5142"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5744"]]
+5743=VERT_CS["Foula height", VERT_DATUM["Foula", 2005, AUTHORITY["EPSG","5141"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5743"]]
+3569=PROJCS["NAD83(HARN) / Utah Central (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 40.65], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 6561666.6667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.016666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3569"]]
+5742=VERT_CS["Lerwick height", VERT_DATUM["Lerwick", 2005, AUTHORITY["EPSG","5140"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5742"]]
+3568=PROJCS["NAD83(HARN) / Utah North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 40.333333333333336], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 3280833.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3568"]]
+5741=VERT_CS["Fair Isle height", VERT_DATUM["Fair Isle", 2005, AUTHORITY["EPSG","5139"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5741"]]
+3567=PROJCS["NAD83 / Utah South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.35], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 9842500.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.21666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3567"]]
+5740=VERT_CS["ODN Orkney height", VERT_DATUM["Ordnance Datum Newlyn (Orkney Isles)", 2005, AUTHORITY["EPSG","5138"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5740"]]
+3566=PROJCS["NAD83 / Utah Central (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 40.65], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 6561666.6667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.016666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3566"]]
+3565=PROJCS["Old Hawaiian / Hawaii zone 5", GEOGCS["Old Hawaiian", DATUM["Old Hawaiian", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[58.0, -283.0, -182.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6135"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4135"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -160.16666666666666], PARAMETER["latitude_of_origin", 21.666666666666668], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3565"]]
+3564=PROJCS["Old Hawaiian / Hawaii zone 4", GEOGCS["Old Hawaiian", DATUM["Old Hawaiian", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[58.0, -283.0, -182.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6135"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4135"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.5], PARAMETER["latitude_of_origin", 21.833333333333332], PARAMETER["scale_factor", 0.99999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3564"]]
+3563=PROJCS["Old Hawaiian / Hawaii zone 3", GEOGCS["Old Hawaiian", DATUM["Old Hawaiian", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[58.0, -283.0, -182.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6135"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4135"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -158.0], PARAMETER["latitude_of_origin", 21.166666666666668], PARAMETER["scale_factor", 0.99999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3563"]]
+3562=PROJCS["Old Hawaiian / Hawaii zone 2", GEOGCS["Old Hawaiian", DATUM["Old Hawaiian", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[58.0, -283.0, -182.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6135"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4135"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -156.66666666666666], PARAMETER["latitude_of_origin", 20.333333333333332], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3562"]]
+3561=PROJCS["Old Hawaiian / Hawaii zone 1", GEOGCS["Old Hawaiian", DATUM["Old Hawaiian", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[58.0, -283.0, -182.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6135"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4135"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -155.5], PARAMETER["latitude_of_origin", 18.833333333333332], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3561"]]
+3560=PROJCS["NAD83 / Utah North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 40.333333333333336], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 3280833.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3560"]]
+5739=VERT_CS["HKCD depth", VERT_DATUM["Hong Kong Chart Datum", 2005, AUTHORITY["EPSG","5136"]], UNIT["m", 1.0], AXIS["Gravity-related depth", DOWN], AUTHORITY["EPSG","5739"]]
+5738=VERT_CS["HKPD height", VERT_DATUM["Hong Kong Principal Datum", 2005, AUTHORITY["EPSG","5135"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5738"]]
+5737=VERT_CS["Yellow Sea 1985 height", VERT_DATUM["Yellow Sea 1985", 2005, AUTHORITY["EPSG","5137"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5737"]]
+5736=VERT_CS["Yellow Sea 1956 height", VERT_DATUM["Yellow Sea 1956", 2005, AUTHORITY["EPSG","5104"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5736"]]
+5735=VERT_CS["Black Sea height", VERT_DATUM["Black Sea", 2005, AUTHORITY["EPSG","5134"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5735"]]
+5734=VERT_CS["AIOC95 depth", VERT_DATUM["AIOC 1995", 2005, AUTHORITY["EPSG","5133"]], UNIT["m", 1.0], AXIS["Gravity-related depth", DOWN], AUTHORITY["EPSG","5734"]]
+5733=VERT_CS["DNN height", VERT_DATUM["Dansk Normal Nul", 2005, AUTHORITY["EPSG","5132"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5733"]]
+3559=PROJCS["NAD83(NSRS2007) / Maryland", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.0], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.449999999999996], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.3], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3559"]]
+5732=VERT_CS["Belfast height", VERT_DATUM["Belfast Lough", 2005, AUTHORITY["EPSG","5131"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5732"]]
+3558=PROJCS["NAD83(NSRS2007) / Maine West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.16666666666667], PARAMETER["latitude_of_origin", 42.833333333333336], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 900000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3558"]]
+5731=VERT_CS["Malin Head height", VERT_DATUM["Malin Head", 2005, AUTHORITY["EPSG","5130"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5731"]]
+3557=PROJCS["NAD83(NSRS2007) / Maine East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -68.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3557"]]
+5730=VERT_CS["EVRF2000 height", VERT_DATUM["European Vertical Reference Frame 2000", 2005, AUTHORITY["EPSG","5129"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5730"]]
+3556=PROJCS["NAD83(NSRS2007) / Maine CS2000 West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.375], PARAMETER["latitude_of_origin", 42.833333333333336], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3556"]]
+3555=PROJCS["NAD83(NSRS2007) / Maine CS2000 East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -67.875], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3555"]]
+3554=PROJCS["NAD83(NSRS2007) / Maine CS2000 Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.12499999999997], PARAMETER["latitude_of_origin", 43.5], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3554"]]
+3553=PROJCS["NAD83(NSRS2007) / Louisiana South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -91.33333333333333], PARAMETER["latitude_of_origin", 28.5], PARAMETER["standard_parallel_1", 30.7], PARAMETER["false_easting", 3280833.3333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.3], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3553"]]
+3552=PROJCS["NAD83(NSRS2007) / Louisiana South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -91.33333333333333], PARAMETER["latitude_of_origin", 28.5], PARAMETER["standard_parallel_1", 30.7], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.3], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3552"]]
+3551=PROJCS["NAD83(NSRS2007) / Louisiana North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.5], PARAMETER["latitude_of_origin", 30.5], PARAMETER["standard_parallel_1", 32.666666666666664], PARAMETER["false_easting", 3280833.3333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 31.166666666666668], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3551"]]
+3550=PROJCS["NAD83(NSRS2007) / Louisiana North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.5], PARAMETER["latitude_of_origin", 30.5], PARAMETER["standard_parallel_1", 32.666666666666664], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 31.166666666666668], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3550"]]
+68056405=GEOGCS["MGI (Ferro) (deg)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","68056405"]]
+5729=VERT_CS["LHN95 height", VERT_DATUM["Landeshohennetz 1995", 2005, AUTHORITY["EPSG","5128"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5729"]]
+5728=VERT_CS["LN02 height", VERT_DATUM["Landesnivellement 1902", 2005, AUTHORITY["EPSG","5127"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5728"]]
+5727=VERT_CS["Hon Dau 1992 height", VERT_DATUM["Hon Dau 1992", 2005, AUTHORITY["EPSG","5126"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5727"]]
+5726=VERT_CS["Ha Tien 1960 height", VERT_DATUM["Ha Tien 1960", 2005, AUTHORITY["EPSG","5125"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5726"]]
+5725=VERT_CS["Fahud HD height", VERT_DATUM["Fahud Height Datum", 2005, AUTHORITY["EPSG","5124"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5725"]]
+5724=VERT_CS["PHD93 height", VERT_DATUM["PDO Height Datum 1993", 2005, AUTHORITY["EPSG","5123"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5724"]]
+5723=VERT_CS["JSLD height", VERT_DATUM["Japanese Standard Levelling Datum 1949", 2005, AUTHORITY["EPSG","5122"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5723"]]
+3549=PROJCS["NAD83(NSRS2007) / Kentucky South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.93333333333333], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.733333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3549"]]
+5722=VERT_CS["Maputo height", VERT_DATUM["Maputo", 2005, AUTHORITY["EPSG","5121"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5722"]]
+3548=PROJCS["NAD83(NSRS2007) / Kentucky South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.93333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.733333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3548"]]
+5721=VERT_CS["IGN78 Corsica height", VERT_DATUM["IGN78 Corsica", 2005, AUTHORITY["EPSG","5120"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5721"]]
+3547=PROJCS["NAD83(NSRS2007) / Kentucky Single Zone (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 38.666666666666664], PARAMETER["false_easting", 4921250.0], PARAMETER["false_northing", 3280833.333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.083333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3547"]]
+5720=VERT_CS["NGF IGN69 height", VERT_DATUM["Nivellement General de la France - IGN69", 2005, AUTHORITY["EPSG","5119"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5720"]]
+3546=PROJCS["NAD83(NSRS2007) / Kentucky Single Zone", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 38.666666666666664], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.083333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3546"]]
+3545=PROJCS["NAD83(NSRS2007) / Kentucky North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.25], PARAMETER["latitude_of_origin", 37.5], PARAMETER["standard_parallel_1", 38.96666666666667], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.96666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3545"]]
+3544=PROJCS["NAD83(NSRS2007) / Kentucky North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.25], PARAMETER["latitude_of_origin", 37.5], PARAMETER["standard_parallel_1", 38.96666666666667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.96666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3544"]]
+3543=PROJCS["NAD83(NSRS2007) / Kansas South (ft US)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.56666666666667], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 1312333.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.266666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3543"]]
+3542=PROJCS["NAD83(NSRS2007) / Kansas South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.56666666666667], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 400000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.266666666666666], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3542"]]
+3541=PROJCS["NAD83(NSRS2007) / Kansas North (ft US)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 39.78333333333333], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3541"]]
+3540=PROJCS["NAD83(NSRS2007) / Kansas North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 39.78333333333333], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3540"]]
+66406413=GEOGCS["RRAF 1991 (3D deg)", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6640"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","66406413"]]
+5719=VERT_CS["NGF Lallemand height", VERT_DATUM["Nivellement General de la France - Lallemand", 2005, AUTHORITY["EPSG","5118"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5719"]]
+5718=VERT_CS["RH70 height", VERT_DATUM["Rikets hojdsystem 1970", 2005, AUTHORITY["EPSG","5117"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5718"]]
+5717=VERT_CS["N60 height", VERT_DATUM["Helsinki 1960", 2005, AUTHORITY["EPSG","5116"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5717"]]
+5716=VERT_CS["Piraeus height", VERT_DATUM["Piraeus Harbour 1986", 2005, AUTHORITY["EPSG","5115"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5716"]]
+5715=VERT_CS["msl depth", VERT_DATUM["Mean Sea Level", 2005, AUTHORITY["EPSG","5100"]], UNIT["m", 1.0], AXIS["Gravity-related depth", DOWN], AUTHORITY["EPSG","5715"]]
+5714=VERT_CS["msl height", VERT_DATUM["Mean Sea Level", 2005, AUTHORITY["EPSG","5100"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5714"]]
+5713=VERT_CS["CGVD28 height", VERT_DATUM["Canadian Geodetic Vertical Datum of 1928", 2005, AUTHORITY["EPSG","5114"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5713"]]
+3539=PROJCS["NAD83(NSRS2007) / Iowa South (ft US)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 40.0], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.61666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3539"]]
+5712=VERT_CS["AHD (Tasmania) height", VERT_DATUM["Australian Height Datum (Tasmania)", 2005, AUTHORITY["EPSG","5112"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5712"]]
+3538=PROJCS["NAD83(NSRS2007) / Iowa South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 40.0], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.61666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3538"]]
+5711=VERT_CS["AHD height", VERT_DATUM["Australian Height Datum", 2005, AUTHORITY["EPSG","5111"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5711"]]
+3537=PROJCS["NAD83(NSRS2007) / Iowa North (ft US)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.266666666666666], PARAMETER["false_easting", 4921250.0], PARAMETER["false_northing", 3280833.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.06666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3537"]]
+5710=VERT_CS["Oostende height", VERT_DATUM["Oostende", 2005, AUTHORITY["EPSG","5110"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5710"]]
+3536=PROJCS["NAD83(NSRS2007) / Iowa North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.266666666666666], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.06666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3536"]]
+3535=PROJCS["NAD83(NSRS2007) / Indiana West (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.08333333333333], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 2952750.0], PARAMETER["false_northing", 820208.333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3535"]]
+3534=PROJCS["NAD83(NSRS2007) / Indiana West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.08333333333333], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 900000.0], PARAMETER["false_northing", 250000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3534"]]
+3533=PROJCS["NAD83(NSRS2007) / Indiana East (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.66666666666667], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 328083.333], PARAMETER["false_northing", 820208.333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3533"]]
+3532=PROJCS["NAD83(NSRS2007) / Indiana East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.66666666666667], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 250000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3532"]]
+3531=PROJCS["NAD83(NSRS2007) / Illinois West (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.16666666666667], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 2296583.3333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3531"]]
+66406405=GEOGCS["RRAF 1991 (deg)", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6640"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66406405"]]
+3530=PROJCS["NAD83(NSRS2007) / Illinois West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.16666666666667], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3530"]]
+5709=VERT_CS["NAP height", VERT_DATUM["Normaal Amsterdams Peil", 2005, AUTHORITY["EPSG","5109"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5709"]]
+62636405=GEOGCS["Minna (deg)", DATUM["Minna", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-111.92, -87.85, 114.5, 1.875, 0.202, 0.219, 0.032], AUTHORITY["EPSG","6263"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62636405"]]
+5706=VERT_CS["Caspian depth", VERT_DATUM["Caspian Sea", 2005, AUTHORITY["EPSG","5106"]], UNIT["m", 1.0], AXIS["Gravity-related depth", DOWN], AUTHORITY["EPSG","5706"]]
+5705=VERT_CS["Baltic height", VERT_DATUM["Baltic Sea", 2005, AUTHORITY["EPSG","5105"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5705"]]
+5704=VERT_CS["Yellow Sea", VERT_DATUM["Yellow Sea 1956", 2005, AUTHORITY["EPSG","5104"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5704"]]
+5703=VERT_CS["NAVD88 height", VERT_DATUM["North American Vertical Datum 1988", 2005, AUTHORITY["EPSG","5103"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5703"]]
+3529=PROJCS["NAD83(NSRS2007) / Illinois East (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.33333333333333], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999975], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3529"]]
+5702=VERT_CS["NGVD29 height", VERT_DATUM["National Geodetic Vertical Datum 1929", 2005, AUTHORITY["EPSG","5102"]], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5702"]]
+3528=PROJCS["NAD83(NSRS2007) / Illinois East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.33333333333333], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999975], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3528"]]
+5701=VERT_CS["ODN height", VERT_DATUM["Ordnance Datum Newlyn", 2005, AUTHORITY["EPSG","5101"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5701"]]
+3527=PROJCS["NAD83(NSRS2007) / Idaho West (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.75], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 2624666.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3527"]]
+3526=PROJCS["NAD83(NSRS2007) / Idaho West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.75], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3526"]]
+3525=PROJCS["NAD83(NSRS2007) / Idaho East (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -112.16666666666667], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3525"]]
+3524=PROJCS["NAD83(NSRS2007) / Idaho East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -112.16666666666667], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3524"]]
+3523=PROJCS["NAD83(NSRS2007) / Idaho Central (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -114.0], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3523"]]
+3522=PROJCS["NAD83(NSRS2007) / Idaho Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -114.0], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3522"]]
+3521=PROJCS["NAD83(NSRS2007) / Georgia West (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -84.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 2296583.333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3521"]]
+3520=PROJCS["NAD83(NSRS2007) / Georgia West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -84.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3520"]]
+3519=PROJCS["NAD83(NSRS2007) / Georgia East (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3519"]]
+3518=PROJCS["NAD83(NSRS2007) / Georgia East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3518"]]
+3517=PROJCS["NAD83(NSRS2007) / Florida West (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3517"]]
+3516=PROJCS["NAD83(NSRS2007) / Florida West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3516"]]
+3515=PROJCS["NAD83(NSRS2007) / Florida North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.5], PARAMETER["latitude_of_origin", 29.0], PARAMETER["standard_parallel_1", 30.75], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.583333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3515"]]
+3514=PROJCS["NAD83(NSRS2007) / Florida North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.5], PARAMETER["latitude_of_origin", 29.0], PARAMETER["standard_parallel_1", 30.75], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.583333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3514"]]
+3513=PROJCS["NAD83(NSRS2007) / Florida GDL Albers", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -84.0], PARAMETER["latitude_of_origin", 24.0], PARAMETER["standard_parallel_1", 24.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 31.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3513"]]
+3512=PROJCS["NAD83(NSRS2007) / Florida East (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3512"]]
+3511=PROJCS["NAD83(NSRS2007) / Florida East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3511"]]
+3510=PROJCS["NAD83(NSRS2007) / Delaware (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.41666666666667], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 0.999995], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3510"]]
+66076405=GEOGCS["St. Vincent 1945 (deg)", DATUM["St. Vincent 1945", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[195.671, 332.517, 274.607, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6607"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66076405"]]
+61356405=GEOGCS["Old Hawaiian (deg)", DATUM["Old Hawaiian", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[58.0, -283.0, -182.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6135"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61356405"]]
+3509=PROJCS["NAD83(NSRS2007) / Delaware", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.41666666666667], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 0.999995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3509"]]
+3508=PROJCS["NAD83(NSRS2007) / Connecticut (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -72.75], PARAMETER["latitude_of_origin", 40.833333333333336], PARAMETER["standard_parallel_1", 41.86666666666669], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.2], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3508"]]
+3507=PROJCS["NAD83(NSRS2007) / Connecticut", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -72.75], PARAMETER["latitude_of_origin", 40.833333333333336], PARAMETER["standard_parallel_1", 41.86666666666669], PARAMETER["false_easting", 304800.6096], PARAMETER["false_northing", 152400.3048], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.2], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3507"]]
+3506=PROJCS["NAD83(NSRS2007) / Colorado South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.233333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3506"]]
+3505=PROJCS["NAD83(NSRS2007) / Colorado South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 914401.8289], PARAMETER["false_northing", 304800.6096], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.233333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3505"]]
+3504=PROJCS["NAD83(NSRS2007) / Colorado North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.78333333333333], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3504"]]
+3503=PROJCS["NAD83(NSRS2007) / Colorado North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.78333333333333], PARAMETER["false_easting", 914401.8289], PARAMETER["false_northing", 304800.6096], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3503"]]
+3502=PROJCS["NAD83(NSRS2007) / Colorado Central (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 37.833333333333336], PARAMETER["standard_parallel_1", 39.75], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.45], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3502"]]
+3501=PROJCS["NAD83(NSRS2007) / Colorado Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 37.833333333333336], PARAMETER["standard_parallel_1", 39.75], PARAMETER["false_easting", 914401.8289], PARAMETER["false_northing", 304800.6096], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.45], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3501"]]
+3500=PROJCS["NAD83(NSRS2007) / California zone 6 (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -116.25], PARAMETER["latitude_of_origin", 32.166666666666664], PARAMETER["standard_parallel_1", 33.88333333333333], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.78333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3500"]]
+62146405=GEOGCS["Beijing 1954 (deg)", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62146405"]]
+29903=PROJCS["TM75 / Irish Grid", GEOGCS["TM75", DATUM["Geodetic Datum of 1965", SPHEROID["Airy Modified 1849", 6377340.189, 299.3249646, AUTHORITY["EPSG","7002"]], TOWGS84[482.5, -130.6, 564.6, -1.042, -0.214, -0.631, 8.15], AUTHORITY["EPSG","6300"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4300"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -8.0], PARAMETER["latitude_of_origin", 53.5], PARAMETER["scale_factor", 1.000035], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 250000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29903"]]
+29902=PROJCS["TM65 / Irish Grid", GEOGCS["TM65", DATUM["TM65", SPHEROID["Airy Modified 1849", 6377340.189, 299.3249646, AUTHORITY["EPSG","7002"]], TOWGS84[482.5, -130.6, 564.6, -1.042, -0.214, -0.631, 8.15], AUTHORITY["EPSG","6299"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4299"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -8.0], PARAMETER["latitude_of_origin", 53.5], PARAMETER["scale_factor", 1.000035], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 250000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29902"]]
+29901=PROJCS["OSNI 1952 / Irish National Grid", GEOGCS["OSNI 1952", DATUM["OSNI 1952", SPHEROID["Airy 1830", 6377563.396, 299.3249646, AUTHORITY["EPSG","7001"]], TOWGS84[482.5, -130.6, 564.6, -1.042, -0.214, -0.631, 8.15], AUTHORITY["EPSG","6188"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4188"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -8.0], PARAMETER["latitude_of_origin", 53.5], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 250000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29901"]]
+29900=PROJCS["TM65 / Irish National Grid", GEOGCS["TM65", DATUM["TM65", SPHEROID["Airy Modified 1849", 6377340.189, 299.3249646, AUTHORITY["EPSG","7002"]], TOWGS84[482.5, -130.6, 564.6, -1.042, -0.214, -0.631, 8.15], AUTHORITY["EPSG","6299"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4299"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -8.0], PARAMETER["latitude_of_origin", 53.5], PARAMETER["scale_factor", 1.000035], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 250000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29900"]]
+66466405=GEOGCS["Grand Comoros (deg)", DATUM["Grand Comoros", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-963.0, 510.0, -359.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6646"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66466405"]]
+61746405=GEOGCS["Sierra Leone 1924 (deg)", DATUM["Sierra Leone Colony 1924", SPHEROID["War Office", 6378300.0, 296.0, AUTHORITY["EPSG","7029"]], AUTHORITY["EPSG","6174"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61746405"]]
+62696405=GEOGCS["NAD83 (deg)", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62696405"]]
+27700=PROJCS["OSGB 1936 / British National Grid", GEOGCS["OSGB 1936", DATUM["OSGB 1936", SPHEROID["Airy 1830", 6377563.396, 299.3249646, AUTHORITY["EPSG","7001"]], TOWGS84[446.448, -125.157, 542.06, 0.15, 0.247, 0.842, -20.489], AUTHORITY["EPSG","6277"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4277"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -2.0], PARAMETER["latitude_of_origin", 49.0], PARAMETER["scale_factor", 0.9996012717], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", -100000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27700"]]
+21150=PROJCS["Batavia / UTM zone 50S", GEOGCS["Batavia", DATUM["Batavia", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-377.7, 675.1, -52.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6211"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4211"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21150"]]
+66306405=GEOGCS["IGN72 Nuku Hiva (deg)", DATUM["IGN72 Nuku Hiva", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[165.732, 216.72, 180.505, 0.6434, -0.4512, -0.0791, 7.4204], AUTHORITY["EPSG","6630"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66306405"]]
+21149=PROJCS["Batavia / UTM zone 49S", GEOGCS["Batavia", DATUM["Batavia", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-377.7, 675.1, -52.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6211"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4211"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21149"]]
+21148=PROJCS["Batavia / UTM zone 48S", GEOGCS["Batavia", DATUM["Batavia", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-377.7, 675.1, -52.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6211"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4211"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21148"]]
+62536405=GEOGCS["Luzon 1911 (deg)", DATUM["Luzon 1911", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-133.0, -77.0, -51.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6253"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62536405"]]
+21100=PROJCS["Batavia (Jakarta) / NEIEZ", GEOGCS["Batavia (Jakarta)", DATUM["Batavia (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6813"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4813"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9804"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 110.0], PARAMETER["scale_factor", 0.997], PARAMETER["false_easting", 3900000.0], PARAMETER["false_northing", 900000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21100"]]
+30494=PROJCS["Voirol 1879 / Sud Algerie (ancienne)", GEOGCS["Voirol 1879", DATUM["Voirol 1879", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6671"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4671"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 2.7], PARAMETER["latitude_of_origin", 33.3], PARAMETER["scale_factor", 0.999625769], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30494"]]
+30493=PROJCS["Voirol 1879 / Nord Algerie (ancienne)", GEOGCS["Voirol 1879", DATUM["Voirol 1879", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6671"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4671"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 2.7], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.999625544], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30493"]]
+30492=PROJCS["Voirol 1875 / Sud Algerie (ancienne)", GEOGCS["Voirol 1875", DATUM["Voirol 1875", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-73.0, -247.0, 227.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6304"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4304"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 2.7], PARAMETER["latitude_of_origin", 33.3], PARAMETER["scale_factor", 0.999625769], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30492"]]
+30491=PROJCS["Voirol 1875 / Nord Algerie (ancienne)", GEOGCS["Voirol 1875", DATUM["Voirol 1875", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-73.0, -247.0, 227.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6304"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4304"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 2.7], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.999625544], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30491"]]
+28193=PROJCS["Palestine 1923 / Israeli CS Grid", GEOGCS["Palestine 1923", DATUM["Palestine 1923", SPHEROID["Clarke 1880 (Benoit)", 6378300.789, 293.4663155389811, AUTHORITY["EPSG","7010"]], TOWGS84[-275.7224, 94.7824, 340.8944, -8.001, -4.42, -11.821, 1.0], AUTHORITY["EPSG","6281"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4281"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 35.212080555555566], PARAMETER["latitude_of_origin", 31.73409694444445], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 170251.555], PARAMETER["false_northing", 1126867.909], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28193"]]
+28192=PROJCS["Palestine 1923 / Palestine Belt", GEOGCS["Palestine 1923", DATUM["Palestine 1923", SPHEROID["Clarke 1880 (Benoit)", 6378300.789, 293.4663155389811, AUTHORITY["EPSG","7010"]], TOWGS84[-275.7224, 94.7824, 340.8944, -8.001, -4.42, -11.821, 1.0], AUTHORITY["EPSG","6281"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4281"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 35.212080555555566], PARAMETER["latitude_of_origin", 31.73409694444445], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 170251.555], PARAMETER["false_northing", 1126867.909], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28192"]]
+28191=PROJCS["Palestine 1923 / Palestine Grid", GEOGCS["Palestine 1923", DATUM["Palestine 1923", SPHEROID["Clarke 1880 (Benoit)", 6378300.789, 293.4663155389811, AUTHORITY["EPSG","7010"]], TOWGS84[-275.7224, 94.7824, 340.8944, -8.001, -4.42, -11.821, 1.0], AUTHORITY["EPSG","6281"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4281"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 35.212080555555566], PARAMETER["latitude_of_origin", 31.73409694444445], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 170251.555], PARAMETER["false_northing", 126867.909], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28191"]]
+32667=PROJCS["WGS 84 / BLM 17N (ftUS)", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32667"]]
+32666=PROJCS["WGS 84 / BLM 16N (ftUS)", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32666"]]
+32665=PROJCS["WGS 84 / BLM 15N (ftUS)", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32665"]]
+32664=PROJCS["WGS 84 / BLM 14N (ftUS)", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32664"]]
+32663=PROJCS["WGS 84 / World Equidistant Cylindrical", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Equidistant_Cylindrical", AUTHORITY["EPSG","9842"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 0.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32663"]]
+32662=PROJCS["WGS 84 / Plate Carree", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Equidistant Cylindrical (Spherical)", AUTHORITY["EPSG","9823"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 0.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32662"]]
+32661=PROJCS["WGS 84 / UPS North (N,E)", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar_Stereographic", AUTHORITY["EPSG","9810"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 90.0], PARAMETER["scale_factor", 0.994], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 2000000.0], UNIT["m", 1.0], AXIS["Northing", "South along 180 deg"], AXIS["Easting", "South along 90 deg East"], AUTHORITY["EPSG","32661"]]
+32660=PROJCS["WGS 84 / UTM zone 60N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32660"]]
+62046405=GEOGCS["Ain el Abd (deg)", DATUM["Ain el Abd 1970", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-85.645, -273.077, -79.708, 2.289, 1.421, -2.532, 3.194], AUTHORITY["EPSG","6204"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62046405"]]
+32659=PROJCS["WGS 84 / UTM zone 59N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32659"]]
+32658=PROJCS["WGS 84 / UTM zone 58N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32658"]]
+32657=PROJCS["WGS 84 / UTM zone 57N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32657"]]
+32656=PROJCS["WGS 84 / UTM zone 56N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32656"]]
+32655=PROJCS["WGS 84 / UTM zone 55N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32655"]]
+62926405=GEOGCS["Sapper Hill 1943 (deg)", DATUM["Sapper Hill 1943", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-355.0, 21.0, 72.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6292"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62926405"]]
+32654=PROJCS["WGS 84 / UTM zone 54N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32654"]]
+32653=PROJCS["WGS 84 / UTM zone 53N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32653"]]
+32652=PROJCS["WGS 84 / UTM zone 52N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32652"]]
+32651=PROJCS["WGS 84 / UTM zone 51N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32651"]]
+32650=PROJCS["WGS 84 / UTM zone 50N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32650"]]
+32649=PROJCS["WGS 84 / UTM zone 49N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32649"]]
+32648=PROJCS["WGS 84 / UTM zone 48N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32648"]]
+32647=PROJCS["WGS 84 / UTM zone 47N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32647"]]
+32646=PROJCS["WGS 84 / UTM zone 46N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32646"]]
+32645=PROJCS["WGS 84 / UTM zone 45N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32645"]]
+32644=PROJCS["WGS 84 / UTM zone 44N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32644"]]
+32643=PROJCS["WGS 84 / UTM zone 43N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32643"]]
+32642=PROJCS["WGS 84 / UTM zone 42N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32642"]]
+32641=PROJCS["WGS 84 / UTM zone 41N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32641"]]
+32640=PROJCS["WGS 84 / UTM zone 40N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32640"]]
+32639=PROJCS["WGS 84 / UTM zone 39N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32639"]]
+32638=PROJCS["WGS 84 / UTM zone 38N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32638"]]
+32637=PROJCS["WGS 84 / UTM zone 37N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32637"]]
+32636=PROJCS["WGS 84 / UTM zone 36N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32636"]]
+32635=PROJCS["WGS 84 / UTM zone 35N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32635"]]
+66366405=GEOGCS["Petrels 1972 (deg)", DATUM["Petrels 1972", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[365.0, 194.0, 166.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6636"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66366405"]]
+32634=PROJCS["WGS 84 / UTM zone 34N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32634"]]
+32633=PROJCS["WGS 84 / UTM zone 33N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32633"]]
+32632=PROJCS["WGS 84 / UTM zone 32N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32632"]]
+32631=PROJCS["WGS 84 / UTM zone 31N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32631"]]
+61646405=GEOGCS["South Yemen (deg)", DATUM["South Yemen", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-76.0, -138.0, 67.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6164"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61646405"]]
+32630=PROJCS["WGS 84 / UTM zone 30N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32630"]]
+3499=PROJCS["NAD83(NSRS2007) / California zone 6", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -116.25], PARAMETER["latitude_of_origin", 32.166666666666664], PARAMETER["standard_parallel_1", 33.88333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.78333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3499"]]
+3498=PROJCS["NAD83(NSRS2007) / California zone 5 (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -118.0], PARAMETER["latitude_of_origin", 33.5], PARAMETER["standard_parallel_1", 35.46666666666667], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.03333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3498"]]
+3497=PROJCS["NAD83(NSRS2007) / California zone 5", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -118.0], PARAMETER["latitude_of_origin", 33.5], PARAMETER["standard_parallel_1", 35.46666666666667], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.03333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3497"]]
+62596405=GEOGCS["Malongo 1987 (deg)", DATUM["Malongo 1987", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-254.1, -5.36, -100.29, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6259"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62596405"]]
+3496=PROJCS["NAD83(NSRS2007) / California zone 4 (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -119.0], PARAMETER["latitude_of_origin", 35.333333333333336], PARAMETER["standard_parallel_1", 37.25], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3496"]]
+3495=PROJCS["NAD83(NSRS2007) / California zone 4", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -119.0], PARAMETER["latitude_of_origin", 35.333333333333336], PARAMETER["standard_parallel_1", 37.25], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3495"]]
+3494=PROJCS["NAD83(NSRS2007) / California zone 3 (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 36.5], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.06666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3494"]]
+3493=PROJCS["NAD83(NSRS2007) / California zone 3", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 36.5], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.06666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3493"]]
+3492=PROJCS["NAD83(NSRS2007) / California zone 2 (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.833333333333336], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.333333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3492"]]
+3491=PROJCS["NAD83(NSRS2007) / California zone 2", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.833333333333336], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.333333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3491"]]
+3490=PROJCS["NAD83(NSRS2007) / California zone 1 (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 41.666666666666664], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3490"]]
+32629=PROJCS["WGS 84 / UTM zone 29N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32629"]]
+32628=PROJCS["WGS 84 / UTM zone 28N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32628"]]
+32627=PROJCS["WGS 84 / UTM zone 27N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32627"]]
+32626=PROJCS["WGS 84 / UTM zone 26N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32626"]]
+32625=PROJCS["WGS 84 / UTM zone 25N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32625"]]
+32624=PROJCS["WGS 84 / UTM zone 24N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32624"]]
+32623=PROJCS["WGS 84 / UTM zone 23N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32623"]]
+32622=PROJCS["WGS 84 / UTM zone 22N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32622"]]
+32621=PROJCS["WGS 84 / UTM zone 21N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32621"]]
+32620=PROJCS["WGS 84 / UTM zone 20N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32620"]]
+3489=PROJCS["NAD83(NSRS2007) / California zone 1", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 41.666666666666664], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3489"]]
+3488=PROJCS["NAD83(NSRS2007) / California Albers", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 34.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", -4000000.0], PARAMETER["standard_parallel_2", 40.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3488"]]
+3487=PROJCS["NAD83(NSRS2007) / Arkansas South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 32.666666666666664], PARAMETER["standard_parallel_1", 34.766666666666666], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 1312333.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.3], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3487"]]
+3486=PROJCS["NAD83(NSRS2007) / Arkansas South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 32.666666666666664], PARAMETER["standard_parallel_1", 34.766666666666666], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 400000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.3], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3486"]]
+3485=PROJCS["NAD83(NSRS2007) / Arkansas North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 34.333333333333336], PARAMETER["standard_parallel_1", 36.233333333333334], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.93333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3485"]]
+3484=PROJCS["NAD83(NSRS2007) / Arkansas North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 34.333333333333336], PARAMETER["standard_parallel_1", 36.233333333333334], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.93333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3484"]]
+3483=PROJCS["NAD83(NSRS2007) / Arizona West (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -113.75], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3483"]]
+3482=PROJCS["NAD83(NSRS2007) / Arizona West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -113.75], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 213360.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3482"]]
+3481=PROJCS["NAD83(NSRS2007) / Arizona East (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.16666666666667], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3481"]]
+3480=PROJCS["NAD83(NSRS2007) / Arizona East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.16666666666667], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 213360.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3480"]]
+32619=PROJCS["WGS 84 / UTM zone 19N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32619"]]
+32618=PROJCS["WGS 84 / UTM zone 18N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32618"]]
+32617=PROJCS["WGS 84 / UTM zone 17N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32617"]]
+32616=PROJCS["WGS 84 / UTM zone 16N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32616"]]
+32615=PROJCS["WGS 84 / UTM zone 15N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32615"]]
+32614=PROJCS["WGS 84 / UTM zone 14N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32614"]]
+32613=PROJCS["WGS 84 / UTM zone 13N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32613"]]
+32612=PROJCS["WGS 84 / UTM zone 12N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32612"]]
+32611=PROJCS["WGS 84 / UTM zone 11N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32611"]]
+32610=PROJCS["WGS 84 / UTM zone 10N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32610"]]
+3479=PROJCS["NAD83(NSRS2007) / Arizona Central (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.91666666666666], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3479"]]
+3478=PROJCS["NAD83(NSRS2007) / Arizona Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.91666666666666], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 213360.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3478"]]
+3477=PROJCS["NAD83(NSRS2007) / Alaska zone 10", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -176.0], PARAMETER["latitude_of_origin", 51.0], PARAMETER["standard_parallel_1", 53.833333333333336], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 51.833333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3477"]]
+3476=PROJCS["NAD83(NSRS2007) / Alaska zone 9", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -170.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3476"]]
+3475=PROJCS["NAD83(NSRS2007) / Alaska zone 8", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -166.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3475"]]
+3474=PROJCS["NAD83(NSRS2007) / Alaska zone 7", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -162.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3474"]]
+3473=PROJCS["NAD83(NSRS2007) / Alaska zone 6", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -158.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3473"]]
+3472=PROJCS["NAD83(NSRS2007) / Alaska zone 5", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -154.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3472"]]
+3471=PROJCS["NAD83(NSRS2007) / Alaska zone 4", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -150.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3471"]]
+3470=PROJCS["NAD83(NSRS2007) / Alaska zone 3", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -146.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3470"]]
+63136405=GEOGCS["Belge 1972 (deg)", DATUM["Reseau National Belge 1972", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-106.8686, 52.2978, -103.7239, 0.3366, 0.457, -1.8422, -1.2747], AUTHORITY["EPSG","6313"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63136405"]]
+32609=PROJCS["WGS 84 / UTM zone 9N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32609"]]
+32608=PROJCS["WGS 84 / UTM zone 8N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32608"]]
+32607=PROJCS["WGS 84 / UTM zone 7N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32607"]]
+32606=PROJCS["WGS 84 / UTM zone 6N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32606"]]
+32605=PROJCS["WGS 84 / UTM zone 5N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32605"]]
+32604=PROJCS["WGS 84 / UTM zone 4N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32604"]]
+32603=PROJCS["WGS 84 / UTM zone 3N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32603"]]
+32602=PROJCS["WGS 84 / UTM zone 2N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32602"]]
+32601=PROJCS["WGS 84 / UTM zone 1N", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32601"]]
+3469=PROJCS["NAD83(NSRS2007) / Alaska zone 2", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -142.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3469"]]
+3468=PROJCS["NAD83(NSRS2007) / Alaska zone 1", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9812"]], PARAMETER["longitude_of_center", -133.66666666666666], PARAMETER["latitude_of_center", 57.0], PARAMETER["azimuth", 323.130102361111], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 5000000.0], PARAMETER["false_northing", -5000000.0], PARAMETER["rectified_grid_angle", 323.130102361111], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3468"]]
+3467=PROJCS["NAD83(NSRS2007) / Alaska Albers", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -154.0], PARAMETER["latitude_of_origin", 50.0], PARAMETER["standard_parallel_1", 55.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 65.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3467"]]
+3466=PROJCS["NAD83(NSRS2007) / Alabama West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.5], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3466"]]
+3465=PROJCS["NAD83(NSRS2007) / Alabama East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.83333333333333], PARAMETER["latitude_of_origin", 30.5], PARAMETER["scale_factor", 0.99996], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3465"]]
+3464=PROJCS["NAD83(HARN) / Maine CS2000 Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.12499999999997], PARAMETER["latitude_of_origin", 43.5], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3464"]]
+3463=PROJCS["NAD83 / Maine CS2000 Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.12499999999997], PARAMETER["latitude_of_origin", 43.5], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3463"]]
+3462=PROJCS["Dabola 1981 / UTM zone 29N", GEOGCS["Dabola 1981", DATUM["Dabola 1981", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-83.0, 37.0, 124.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6155"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4155"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3462"]]
+3461=PROJCS["Dabola 1981 / UTM zone 28N", GEOGCS["Dabola 1981", DATUM["Dabola 1981", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-83.0, 37.0, 124.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6155"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4155"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3461"]]
+3460=PROJCS["Fiji 1986 / Fiji Map Grid", GEOGCS["Fiji 1986", DATUM["Fiji Geodetic Datum 1986", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.2263], AUTHORITY["EPSG","6720"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4720"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 178.75], PARAMETER["latitude_of_origin", -17.0], PARAMETER["scale_factor", 0.99985], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 4000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3460"]]
+66206405=GEOGCS["Point 58 (deg)", DATUM["Point 58", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-106.0, -129.0, 165.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6620"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66206405"]]
+3459=PROJCS["NAD83(HARN) / South Dakota South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 42.333333333333336], PARAMETER["standard_parallel_1", 44.4], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.833333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3459"]]
+3458=PROJCS["NAD83(HARN) / South Dakota North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.68333333333334], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.416666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3458"]]
+3457=PROJCS["NAD83(HARN) / Louisiana South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -91.33333333333333], PARAMETER["latitude_of_origin", 28.5], PARAMETER["standard_parallel_1", 30.7], PARAMETER["false_easting", 3280833.3333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.3], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3457"]]
+3456=PROJCS["NAD83(HARN) / Louisiana North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.5], PARAMETER["latitude_of_origin", 30.5], PARAMETER["standard_parallel_1", 32.666666666666664], PARAMETER["false_easting", 3280833.3333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 31.166666666666668], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3456"]]
+3455=PROJCS["NAD83 / South Dakota South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 42.333333333333336], PARAMETER["standard_parallel_1", 44.4], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.833333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3455"]]
+3454=PROJCS["NAD83 / South Dakota North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 42.333333333333336], PARAMETER["standard_parallel_1", 44.4], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.833333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3454"]]
+3453=PROJCS["NAD83 / Louisiana Offshore (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -91.33333333333333], PARAMETER["latitude_of_origin", 25.5], PARAMETER["standard_parallel_1", 27.833333333333332], PARAMETER["false_easting", 3280833.3333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 26.166666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3453"]]
+3452=PROJCS["NAD83 / Louisiana South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -91.33333333333333], PARAMETER["latitude_of_origin", 28.5], PARAMETER["standard_parallel_1", 30.7], PARAMETER["false_easting", 3280833.3333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.3], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3452"]]
+3451=PROJCS["NAD83 / Louisiana North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.5], PARAMETER["latitude_of_origin", 30.5], PARAMETER["standard_parallel_1", 32.666666666666664], PARAMETER["false_easting", 3280833.3333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 31.166666666666668], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3451"]]
+62436405=GEOGCS["Kalianpur 1880 (deg)", DATUM["Kalianpur 1880", SPHEROID["Everest (1830 Definition)", 6377299.36559538, 300.80172554336184, AUTHORITY["EPSG","7042"]], AUTHORITY["EPSG","6243"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62436405"]]
+3450=PROJCS["JAD2001 / UTM zone 18N", GEOGCS["JAD2001", DATUM["Jamaica 2001", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6758"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4758"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3450"]]
+3449=PROJCS["JAD2001 / UTM zone 17N", GEOGCS["JAD2001", DATUM["Jamaica 2001", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6758"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4758"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3449"]]
+3448=PROJCS["JAD2001 / Jamaica Metric Grid", GEOGCS["JAD2001", DATUM["Jamaica 2001", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6758"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4758"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -77.0], PARAMETER["latitude_of_origin", 18.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 750000.0], PARAMETER["false_northing", 650000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3448"]]
+5621=VERT_CS["EVRF2007 height", VERT_DATUM["European Vertical Reference Frame 2007", 2005, AUTHORITY["EPSG","5215"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5621"]]
+3447=PROJCS["ETRS89 / Belgian Lambert 2005", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 4.359215833333335], PARAMETER["latitude_of_origin", 50.79781500000001], PARAMETER["standard_parallel_1", 51.16666666666667], PARAMETER["false_easting", 150328.0], PARAMETER["false_northing", 166262.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 49.833333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3447"]]
+5620=VERT_CS["IGN 1988 SM height", VERT_DATUM["IGN 1988 SM", 2005, AUTHORITY["EPSG","5214"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5620"]]
+3446=PROJCS["NAD83(HARN) / Rhode Island (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.083333333333336], PARAMETER["scale_factor", 0.99999375], PARAMETER["false_easting", 328083.3333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3446"]]
+3445=PROJCS["NAD83(HARN) / New Hampshire (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.66666666666667], PARAMETER["latitude_of_origin", 42.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3445"]]
+3444=PROJCS["NAD83(HARN) / Illinois West (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.16666666666667], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 2296583.3333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3444"]]
+3443=PROJCS["NAD83(HARN) / Illinois East (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.33333333333333], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999975], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3443"]]
+3442=PROJCS["NAD83(HARN) / Arkansas South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 32.666666666666664], PARAMETER["standard_parallel_1", 34.766666666666666], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 1312333.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.3], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3442"]]
+3441=PROJCS["NAD83(HARN) / Arkansas North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 34.333333333333336], PARAMETER["standard_parallel_1", 36.233333333333334], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.93333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3441"]]
+3440=PROJCS["PSD93 / UTM zone 40N", GEOGCS["PSD93", DATUM["PDO Survey Datum 1993", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-180.624, -225.516, 173.919, -0.81, -1.898, 8.336, 16.71006], AUTHORITY["EPSG","6134"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4134"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3440"]]
+5619=VERT_CS["IGN 1988 SB height", VERT_DATUM["IGN 1988 SB", 2005, AUTHORITY["EPSG","5213"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5619"]]
+5618=VERT_CS["IGN 1992 LD height", VERT_DATUM["IGN 1992 LD", 2005, AUTHORITY["EPSG","5212"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5618"]]
+5617=VERT_CS["IGN 1988 MG height", VERT_DATUM["IGN 1988 MG", 2005, AUTHORITY["EPSG","5211"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5617"]]
+5616=VERT_CS["IGN 1988 LS height", VERT_DATUM["IGN 1988 LS", 2005, AUTHORITY["EPSG","5210"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5616"]]
+5615=VERT_CS["RH00 height", VERT_DATUM["Rikets hojdsystem 1900", 2005, AUTHORITY["EPSG","5209"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5615"]]
+5614=VERT_CS["KOC WD depth (ft)", VERT_DATUM["KOC Well Datum", 2005, AUTHORITY["EPSG","5187"]], UNIT["ft", 0.3048], AXIS["Gravity-related depth", DOWN], AUTHORITY["EPSG","5614"]]
+5613=VERT_CS["RH2000 height", VERT_DATUM["Rikets hojdsystem 2000", 2005, AUTHORITY["EPSG","5208"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5613"]]
+3439=PROJCS["PSD93 / UTM zone 39N", GEOGCS["PSD93", DATUM["PDO Survey Datum 1993", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-180.624, -225.516, 173.919, -0.81, -1.898, 8.336, 16.71006], AUTHORITY["EPSG","6134"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4134"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3439"]]
+5612=VERT_CS["Baltic depth", VERT_DATUM["Baltic Sea", 2005, AUTHORITY["EPSG","5105"]], UNIT["m", 1.0], AXIS["Gravity-related depth", DOWN], AUTHORITY["EPSG","5612"]]
+3438=PROJCS["NAD83 / Rhode Island (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.083333333333336], PARAMETER["scale_factor", 0.99999375], PARAMETER["false_easting", 328083.3333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3438"]]
+5611=VERT_CS["Caspian height", VERT_DATUM["Caspian Sea", 2005, AUTHORITY["EPSG","5106"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5611"]]
+3437=PROJCS["NAD83 / New Hampshire (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.66666666666667], PARAMETER["latitude_of_origin", 42.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3437"]]
+5610=VERT_CS["HVRS71 height", VERT_DATUM["Croatian Vertical Reference System 1971", 2005, AUTHORITY["EPSG","5207"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5610"]]
+3436=PROJCS["NAD83 / Illinois West (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.16666666666667], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 2296583.3333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3436"]]
+3435=PROJCS["NAD83 / Illinois East (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.33333333333333], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999975], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3435"]]
+3434=PROJCS["NAD83 / Arkansas South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 32.666666666666664], PARAMETER["standard_parallel_1", 34.766666666666666], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 1312333.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.3], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3434"]]
+3433=PROJCS["NAD83 / Arkansas North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 34.333333333333336], PARAMETER["standard_parallel_1", 36.233333333333334], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.93333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3433"]]
+3432=PROJCS["NAD83(HARN) / New Jersey (ft US)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.5], PARAMETER["latitude_of_origin", 38.833333333333336], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 492125.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3432"]]
+3431=PROJCS["NAD83(HARN) / Nevada West (ft US)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -118.58333333333333], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 13123333.3333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3431"]]
+3430=PROJCS["NAD83(HARN) / Nevada Central (ft US)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -116.66666666666667], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 19685000.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3430"]]
+5609=VERT_CS["IGLD 1985 height", VERT_DATUM["International Great Lakes Datum 1985", 2005, AUTHORITY["EPSG","5205"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5609"]]
+5608=VERT_CS["IGLD 1955 height", VERT_DATUM["International Great Lakes Datum 1955", 2005, AUTHORITY["EPSG","5204"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5608"]]
+5607=VERT_CS["Bora Bora SAU 2001 height", VERT_DATUM["Bora Bora SAU 2001", 2005, AUTHORITY["EPSG","5202"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5607"]]
+5606=VERT_CS["Tahaa SAU 2001 height", VERT_DATUM["Tahaa SAU 2001", 2005, AUTHORITY["EPSG","5201"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5606"]]
+5605=VERT_CS["Huahine SAU 2001 height", VERT_DATUM["Huahine SAU 2001", 2005, AUTHORITY["EPSG","5200"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5605"]]
+5604=VERT_CS["Maupiti SAU 2001 height", VERT_DATUM["Maupiti SAU 2001", 2005, AUTHORITY["EPSG","5199"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5604"]]
+5603=VERT_CS["Raiatea SAU 2001 height", VERT_DATUM["Raiatea SAU 2001", 2005, AUTHORITY["EPSG","5198"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5603"]]
+3429=PROJCS["NAD83(HARN) / Nevada East (ft US)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.58333333333334], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 656166.6667], PARAMETER["false_northing", 26246666.6667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3429"]]
+5602=VERT_CS["Moorea SAU 1981 height", VERT_DATUM["Moorea SAU 1981", 2005, AUTHORITY["EPSG","5197"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5602"]]
+3428=PROJCS["NAD83(HARN) / Kansas South (ft US)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.56666666666667], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 1312333.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.266666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3428"]]
+5601=VERT_CS["IGN 1966 height", VERT_DATUM["IGN 1966", 2005, AUTHORITY["EPSG","5196"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5601"]]
+3427=PROJCS["NAD83(HARN) / Kansas North (ft US)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 39.78333333333333], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3427"]]
+5600=VERT_CS["NGPF height", VERT_DATUM["Nivellement General de Polynesie Francaise", 2005, AUTHORITY["EPSG","5195"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5600"]]
+3426=PROJCS["NAD83(HARN) / Iowa South (ft US)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 40.0], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.61666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3426"]]
+3425=PROJCS["NAD83(HARN) / Iowa North (ft US)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.266666666666666], PARAMETER["false_easting", 4921250.0], PARAMETER["false_northing", 3280833.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.06666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3425"]]
+3424=PROJCS["NAD83 / New Jersey (ft US)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.5], PARAMETER["latitude_of_origin", 38.833333333333336], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 492125.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3424"]]
+3423=PROJCS["NAD83 / Nevada West (ft US)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -118.58333333333333], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 13123333.3333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3423"]]
+3422=PROJCS["NAD83 / Nevada Central (ft US)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -116.66666666666667], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 19685000.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3422"]]
+3421=PROJCS["NAD83 / Nevada East (ft US)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.58333333333334], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 656166.6667], PARAMETER["false_northing", 26246666.6667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3421"]]
+3420=PROJCS["NAD83 / Kansas South (ft US)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.56666666666667], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 1312333.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.266666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3420"]]
+62986405=GEOGCS["Timbalai 1948 (deg)", DATUM["Timbalai 1948", SPHEROID["Everest 1830 (1967 Definition)", 6377298.556, 300.8017, AUTHORITY["EPSG","7016"]], TOWGS84[-689.5937, 623.84046, -65.93566, -0.02331, -1.17094, 0.80054, 5.88536], AUTHORITY["EPSG","6298"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62986405"]]
+3419=PROJCS["NAD83 / Kansas North (ft US)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 39.78333333333333], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3419"]]
+3418=PROJCS["NAD83 / Iowa South (ft US)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 40.0], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.61666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3418"]]
+3417=PROJCS["NAD83 / Iowa North (ft US)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.266666666666666], PARAMETER["false_easting", 4921250.0], PARAMETER["false_northing", 3280833.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.06666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3417"]]
+3416=PROJCS["ETRS89 / Austria Lambert", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 13.333333333333334], PARAMETER["latitude_of_origin", 47.5], PARAMETER["standard_parallel_1", 49.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 400000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3416"]]
+3415=PROJCS["WGS 72BE / South China Sea Lambert", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", 21.0], PARAMETER["standard_parallel_1", 24.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 18.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3415"]]
+3414=PROJCS["SVY21 / Singapore TM", GEOGCS["SVY21", DATUM["SVY21", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6757"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4757"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 103.83333333333333], PARAMETER["latitude_of_origin", 1.3666666666666667], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 28001.642], PARAMETER["false_northing", 38744.572], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3414"]]
+3413=PROJCS["WGS 84 / NSIDC Sea Ice Polar Stereographic North", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", -45.0], PARAMETER["Standard_Parallel_1", 70.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "South along 45 deg East"], AXIS["Northing", "South along 135 deg East"], AUTHORITY["EPSG","3413"]]
+3412=PROJCS["NSIDC Sea Ice Polar Stereographic South", GEOGCS["Unspecified datum based upon the Hughes 1980 ellipsoid", DATUM["Not specified (based on Hughes 1980 ellipsoid)", SPHEROID["Hughes 1980", 6378273.0, 298.279411123064, AUTHORITY["EPSG","7058"]], AUTHORITY["EPSG","6054"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4054"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 0.0], PARAMETER["Standard_Parallel_1", -70.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 90 deg East"], AXIS["Northing", "North along 0 deg"], AUTHORITY["EPSG","3412"]]
+3411=PROJCS["NSIDC Sea Ice Polar Stereographic North", GEOGCS["Unspecified datum based upon the Hughes 1980 ellipsoid", DATUM["Not specified (based on Hughes 1980 ellipsoid)", SPHEROID["Hughes 1980", 6378273.0, 298.279411123064, AUTHORITY["EPSG","7058"]], AUTHORITY["EPSG","6054"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4054"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", -45.0], PARAMETER["Standard_Parallel_1", 70.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "South along 45 deg East"], AXIS["Northing", "South along 135 deg East"], AUTHORITY["EPSG","3411"]]
+29873=PROJCS["Timbalai 1948 / RSO Borneo (m)", GEOGCS["Timbalai 1948", DATUM["Timbalai 1948", SPHEROID["Everest 1830 (1967 Definition)", 6377298.556, 300.8017, AUTHORITY["EPSG","7016"]], TOWGS84[-689.5937, 623.84046, -65.93566, -0.02331, -1.17094, 0.80054, 5.88536], AUTHORITY["EPSG","6298"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4298"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9815"]], PARAMETER["longitude_of_center", 115.0], PARAMETER["latitude_of_center", 4.0], PARAMETER["azimuth", 53.31582047222221], PARAMETER["scale_factor", 0.99984], PARAMETER["false_easting", 590476.87], PARAMETER["false_northing", 442857.65], PARAMETER["rectified_grid_angle", 53.13010236111111], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29873"]]
+3409=PROJCS["NSIDC EASE-Grid South", GEOGCS["Unspecified datum based upon the International 1924 Authalic Sphere", DATUM["Not specified (based on International 1924 Authalic Sphere)", SPHEROID["International 1924 Authalic Sphere", 6371228.0, 0.0, AUTHORITY["EPSG","7057"]], AUTHORITY["EPSG","6053"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4053"]], PROJECTION["Lambert_Azimuthal_Equal_Area", AUTHORITY["EPSG","1027"]], PARAMETER["latitude_of_center", -90.0], PARAMETER["longitude_of_center", 0.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 90 deg East"], AXIS["Northing", "North along 0 deg"], AUTHORITY["EPSG","3409"]]
+29872=PROJCS["Timbalai 1948 / RSO Borneo (ft)", GEOGCS["Timbalai 1948", DATUM["Timbalai 1948", SPHEROID["Everest 1830 (1967 Definition)", 6377298.556, 300.8017, AUTHORITY["EPSG","7016"]], TOWGS84[-689.5937, 623.84046, -65.93566, -0.02331, -1.17094, 0.80054, 5.88536], AUTHORITY["EPSG","6298"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4298"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9815"]], PARAMETER["longitude_of_center", 115.0], PARAMETER["latitude_of_center", 4.0], PARAMETER["azimuth", 53.31582047222221], PARAMETER["scale_factor", 0.99984], PARAMETER["false_easting", 1937263.44], PARAMETER["false_northing", 1452947.58], PARAMETER["rectified_grid_angle", 53.13010236111111], UNIT["m*0.3047994715386762", 0.3047994715386762], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29872"]]
+3408=PROJCS["NSIDC EASE-Grid North", GEOGCS["Unspecified datum based upon the International 1924 Authalic Sphere", DATUM["Not specified (based on International 1924 Authalic Sphere)", SPHEROID["International 1924 Authalic Sphere", 6371228.0, 0.0, AUTHORITY["EPSG","7057"]], AUTHORITY["EPSG","6053"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4053"]], PROJECTION["Lambert_Azimuthal_Equal_Area", AUTHORITY["EPSG","1027"]], PARAMETER["latitude_of_center", 90.0], PARAMETER["longitude_of_center", 0.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "South along 90 deg East"], AXIS["Northing", "South along 180 deg"], AUTHORITY["EPSG","3408"]]
+29871=PROJCS["Timbalai 1948 / RSO Borneo (ch)", GEOGCS["Timbalai 1948", DATUM["Timbalai 1948", SPHEROID["Everest 1830 (1967 Definition)", 6377298.556, 300.8017, AUTHORITY["EPSG","7016"]], TOWGS84[-689.5937, 623.84046, -65.93566, -0.02331, -1.17094, 0.80054, 5.88536], AUTHORITY["EPSG","6298"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4298"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9815"]], PARAMETER["longitude_of_center", 115.0], PARAMETER["latitude_of_center", 4.0], PARAMETER["azimuth", 53.31582047222221], PARAMETER["scale_factor", 0.99984], PARAMETER["false_easting", 29352.4763], PARAMETER["false_northing", 22014.3572], PARAMETER["rectified_grid_angle", 53.13010236111111], UNIT["m*20.116765121552632", 20.116765121552632], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29871"]]
+3407=PROJCS["Hong Kong 1963 Grid System", GEOGCS["Hong Kong 1963", DATUM["Hong Kong 1963", SPHEROID["Clarke 1858", 6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]], AUTHORITY["EPSG","6738"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4738"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 114.17855555555556], PARAMETER["latitude_of_origin", 22.312133333333335], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 132033.92], PARAMETER["false_northing", 62565.96], UNIT["m*0.3047972654", 0.3047972654], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3407"]]
+3406=PROJCS["VN-2000 / UTM zone 49N", GEOGCS["VN-2000", DATUM["Vietnam 2000", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[-192.873, -39.382, -111.202, -0.00205, 0.0005, -0.00335, 0.0188], AUTHORITY["EPSG","6756"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4756"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3406"]]
+3405=PROJCS["VN-2000 / UTM zone 48N", GEOGCS["VN-2000", DATUM["Vietnam 2000", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[-192.873, -39.382, -111.202, -0.00205, 0.0005, -0.00335, 0.0188], AUTHORITY["EPSG","6756"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4756"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3405"]]
+3404=PROJCS["NAD83(HARN) / North Carolina (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.0], PARAMETER["latitude_of_origin", 33.75], PARAMETER["standard_parallel_1", 36.166666666666664], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.333333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3404"]]
+3403=PROJCS["NAD83(CSRS) / Alberta 10-TM (Resource)", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9992], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3403"]]
+3402=PROJCS["NAD83(CSRS) / Alberta 10-TM (Forest)", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9992], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3402"]]
+3401=PROJCS["NAD83 / Alberta 10-TM (Resource)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9992], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3401"]]
+3400=PROJCS["NAD83 / Alberta 10-TM (Forest)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9992], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3400"]]
+29850=PROJCS["Timbalai 1948 / UTM zone 50N", GEOGCS["Timbalai 1948", DATUM["Timbalai 1948", SPHEROID["Everest 1830 (1967 Definition)", 6377298.556, 300.8017, AUTHORITY["EPSG","7016"]], TOWGS84[-689.5937, 623.84046, -65.93566, -0.02331, -1.17094, 0.80054, 5.88536], AUTHORITY["EPSG","6298"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4298"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29850"]]
+62826405=GEOGCS["Pointe Noire (deg)", DATUM["Congo 1960 Pointe Noire", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-178.3, -316.7, -131.5, 5.278, 6.077, 10.979, 19.166], AUTHORITY["EPSG","6282"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62826405"]]
+29849=PROJCS["Timbalai 1948 / UTM zone 49N", GEOGCS["Timbalai 1948", DATUM["Timbalai 1948", SPHEROID["Everest 1830 (1967 Definition)", 6377298.556, 300.8017, AUTHORITY["EPSG","7016"]], TOWGS84[-689.5937, 623.84046, -65.93566, -0.02331, -1.17094, 0.80054, 5.88536], AUTHORITY["EPSG","6298"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4298"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29849"]]
+63196405=GEOGCS["KUDAMS (deg)", DATUM["Kuwait Utility", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[226.702, -193.337, -35.371, -2.229, 4.391, -9.238, 0.9798], AUTHORITY["EPSG","6319"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63196405"]]
+2999=PROJCS["Grand Comoros / UTM zone 38S", GEOGCS["Grand Comoros", DATUM["Grand Comoros", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-963.0, 510.0, -359.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6646"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4646"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2999"]]
+2998=PROJCS["NEA74 Noumea / UTM zone 58S", GEOGCS["NEA74 Noumea", DATUM["NEA74 Noumea", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-10.18, -350.43, 291.37, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6644"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4644"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2998"]]
+2997=PROJCS["ST71 Belep / UTM zone 58S", GEOGCS["ST71 Belep", DATUM["ST71 Belep", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-480.26, -438.32, -643.429, 16.3119, 20.1721, -4.0349, -111.7002], AUTHORITY["EPSG","6643"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4643"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2997"]]
+2996=PROJCS["ST84 Ile des Pins / UTM zone 58S", GEOGCS["ST84 Ile des Pins", DATUM["ST84 Ile des Pins", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-13.0, -348.0, 292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6642"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4642"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2996"]]
+2995=PROJCS["IGN53 Mare / UTM zone 58S", GEOGCS["IGN53 Mare", DATUM["IGN53 Mare", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[287.58, 177.78, -135.41, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6641"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4641"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2995"]]
+2994=PROJCS["NAD83(HARN) / Oregon Lambert (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 41.75], PARAMETER["standard_parallel_1", 45.5], PARAMETER["false_easting", 1312335.9580000003], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2994"]]
+2993=PROJCS["NAD83(HARN) / Oregon Lambert", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 41.75], PARAMETER["standard_parallel_1", 45.5], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2993"]]
+2992=PROJCS["NAD83 / Oregon Lambert (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 41.75], PARAMETER["standard_parallel_1", 45.5], PARAMETER["false_easting", 1312335.9580000003], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2992"]]
+2991=PROJCS["NAD83 / Oregon Lambert", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 41.75], PARAMETER["standard_parallel_1", 45.5], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2991"]]
+2990=PROJCS["Reunion 1947 / TM Reunion", GEOGCS["Reunion 1947", DATUM["Reunion 1947", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[94.0, -948.0, -1262.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6626"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4626"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 55.53333333333333], PARAMETER["latitude_of_origin", -21.116666666666667], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 50000.0], PARAMETER["false_northing", 160000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2990"]]
+66266405=GEOGCS["Piton des Neiges (deg)", DATUM["Reunion 1947", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[94.0, -948.0, -1262.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6626"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66266405"]]
+61546405=GEOGCS["ED50(ED77) (deg)", DATUM["European Datum 1950(1977)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-123.02, -158.95, -168.47, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6154"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61546405"]]
+69036405=GEOGCS["Madrid 1870 (Madrid) (deg)", DATUM["Madrid 1870 (Madrid)", SPHEROID["Struve 1860", 6378298.3, 294.73, AUTHORITY["EPSG","7028"]], AUTHORITY["EPSG","6903"]], PRIMEM["Madrid", -3.68793888888889, AUTHORITY["EPSG","8905"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","69036405"]]
+2989=PROJCS["RRAF 1991 / UTM zone 20N", GEOGCS["RRAF 1991", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6640"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4640"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2989"]]
+62496405=GEOGCS["Lake (deg)", DATUM["Lake", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6249"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62496405"]]
+2988=PROJCS["MOP78 / UTM zone 1S", GEOGCS["MOP78", DATUM["MOP78", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[253.0, -132.0, -127.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6639"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4639"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2988"]]
+2987=PROJCS["Saint Pierre et Miquelon 1950 / UTM zone 21N", GEOGCS["Saint Pierre et Miquelon 1950", DATUM["Saint Pierre et Miquelon 1950", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[30.0, 430.0, 368.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6638"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4638"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2987"]]
+2984=PROJCS["RGNC 1991 / Lambert New Caledonia", GEOGCS["RGNC 1991", DATUM["Reseau Geodesique Nouvelle Caledonie 1991", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6645"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4645"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 166.0], PARAMETER["latitude_of_origin", -21.5], PARAMETER["standard_parallel_1", -20.666666666666668], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 300000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -22.333333333333332], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2984"]]
+2983=PROJCS["ST87 Ouvea / UTM zone 58S", GEOGCS["ST87 Ouvea", DATUM["ST87 Ouvea", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-122.383, -188.696, 103.344, 3.5107, -4.9668, -5.7047, 4.4798], AUTHORITY["EPSG","6635"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4635"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2983"]]
+2981=PROJCS["IGN56 Lifou / UTM zone 58S", GEOGCS["IGN56 Lifou", DATUM["IGN56 Lifou", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[335.47, 222.58, -230.94, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6633"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4633"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2981"]]
+2980=PROJCS["Combani 1950 / UTM zone 38S", GEOGCS["Combani 1950", DATUM["Combani 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-382.0, -59.0, -262.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6632"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4632"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2980"]]
+2979=PROJCS["K0 1949 / UTM zone 42S", GEOGCS["K0 1949", DATUM["K0 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[145.0, -187.0, 103.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6631"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4631"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2979"]]
+2978=PROJCS["IGN72 Nuku Hiva / UTM zone 7S", GEOGCS["IGN72 Nuku Hiva", DATUM["IGN72 Nuku Hiva", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[165.732, 216.72, 180.505, 0.6434, -0.4512, -0.0791, 7.4204], AUTHORITY["EPSG","6630"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4630"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2978"]]
+2977=PROJCS["Tahaa 54 / UTM zone 5S", GEOGCS["Tahaa 54", DATUM["Tahaa 54", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[72.438, 345.918, 79.486, 1.6045, -0.8823, -0.5565, 1.3746], AUTHORITY["EPSG","6629"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4629"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2977"]]
+2976=PROJCS["Tahiti 52 / UTM zone 6S", GEOGCS["Tahiti 52", DATUM["Tahiti 52", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[162.0, 117.0, 154.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6628"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4628"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2976"]]
+2975=PROJCS["RGR92 / UTM zone 40S", GEOGCS["RGR92", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4627"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2975"]]
+2973=PROJCS["Martinique 1938 / UTM zone 20N", GEOGCS["Martinique 1938", DATUM["Martinique 1938", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[126.93, 547.94, 130.41, -2.7867, 5.1612, -0.8584, 13.8227], AUTHORITY["EPSG","6625"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4625"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2973"]]
+2972=PROJCS["RGFG95 / UTM zone 22N", GEOGCS["RGFG95", DATUM["Reseau Geodesique Francais Guyane 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6624"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4624"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2972"]]
+2971=PROJCS["CSG67 / UTM zone 22N", GEOGCS["CSG67", DATUM["Centre Spatial Guyanais 1967", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-186.0, 230.0, 110.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6623"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4623"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2971"]]
+2970=PROJCS["Guadeloupe 1948 / UTM zone 20N", GEOGCS["Guadeloupe 1948", DATUM["Guadeloupe 1948", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-472.29, -5.63, -304.12, 0.4362, -0.8374, 0.2563, 1.8984], AUTHORITY["EPSG","6622"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4622"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2970"]]
+21097=PROJCS["Arc 1960 / UTM zone 37N", GEOGCS["Arc 1960", DATUM["Arc 1960", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-157.0, -2.0, -299.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6210"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4210"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21097"]]
+21096=PROJCS["Arc 1960 / UTM zone 36N", GEOGCS["Arc 1960", DATUM["Arc 1960", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-157.0, -2.0, -299.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6210"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4210"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21096"]]
+21095=PROJCS["Arc 1960 / UTM zone 35N", GEOGCS["Arc 1960", DATUM["Arc 1960", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-157.0, -2.0, -299.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6210"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4210"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21095"]]
+2969=PROJCS["Fort Marigot / UTM zone 20N", GEOGCS["Fort Marigot", DATUM["Fort Marigot", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[137.0, 248.0, -430.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6621"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4621"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2969"]]
+2968=PROJCS["NAD83(HARN) / Indiana West (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.08333333333333], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 2952750.0], PARAMETER["false_northing", 820208.333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2968"]]
+2967=PROJCS["NAD83(HARN) / Indiana East (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.66666666666667], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 328083.333], PARAMETER["false_northing", 820208.333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2967"]]
+2966=PROJCS["NAD83 / Indiana West (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.08333333333333], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 2952750.0], PARAMETER["false_northing", 820208.333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2966"]]
+2965=PROJCS["NAD83 / Indiana East (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.66666666666667], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 328083.333], PARAMETER["false_northing", 820208.333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2965"]]
+2964=PROJCS["NAD27 / Alaska Albers", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -154.0], PARAMETER["latitude_of_origin", 50.0], PARAMETER["standard_parallel_1", 55.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 65.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2964"]]
+2962=PROJCS["NAD83(CSRS) / UTM zone 21N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2962"]]
+63036405=GEOGCS["TC(1948) (deg)", DATUM["Trucial Coast 1948", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], AUTHORITY["EPSG","6303"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63036405"]]
+2961=PROJCS["NAD83(CSRS) / UTM zone 20N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2961"]]
+2960=PROJCS["NAD83(CSRS) / UTM zone 19N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2960"]]
+2959=PROJCS["NAD83(CSRS) / UTM zone 18N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2959"]]
+2958=PROJCS["NAD83(CSRS) / UTM zone 17N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2958"]]
+2957=PROJCS["NAD83(CSRS) / UTM zone 13N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2957"]]
+2956=PROJCS["NAD83(CSRS) / UTM zone 12N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2956"]]
+2955=PROJCS["NAD83(CSRS) / UTM zone 11N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2955"]]
+2954=PROJCS["NAD83(CSRS) / Prince Edward Isl. Stereographic (NAD83)", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 47.25], PARAMETER["scale_factor", 0.999912], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2954"]]
+2953=PROJCS["NAD83(CSRS) / New Brunswick Stereographic", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", -66.5], PARAMETER["latitude_of_origin", 46.5], PARAMETER["scale_factor", 0.999912], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 7500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2953"]]
+2952=PROJCS["NAD83(CSRS) / MTM zone 10", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2952"]]
+2951=PROJCS["NAD83(CSRS) / MTM zone 9", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -76.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2951"]]
+2950=PROJCS["NAD83(CSRS) / MTM zone 8", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -73.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2950"]]
+66106405=GEOGCS["Xian 1980 (deg)", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66106405"]]
+2949=PROJCS["NAD83(CSRS) / MTM zone 7", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2949"]]
+2948=PROJCS["NAD83(CSRS) / MTM zone 6", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -67.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2948"]]
+2947=PROJCS["NAD83(CSRS) / MTM zone 5", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -64.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2947"]]
+2946=PROJCS["NAD83(CSRS) / MTM zone 4", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -61.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2946"]]
+2945=PROJCS["NAD83(CSRS) / MTM zone 3", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -58.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2945"]]
+2944=PROJCS["NAD83(CSRS) / SCoPQ zone 2", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -55.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2944"]]
+2943=PROJCS["Selvagem Grande / UTM zone 28N", GEOGCS["Selvagem Grande", DATUM["Selvagem Grande", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-289.0, -124.0, 60.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6616"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4616"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2943"]]
+62336405=GEOGCS["Gandajika 1970 (deg)", DATUM["Gandajika 1970", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-133.0, -321.0, 50.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6233"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62336405"]]
+2942=PROJCS["Porto Santo / UTM zone 28N", GEOGCS["Porto Santo", DATUM["Porto Santo 1936", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-499.0, -249.0, 314.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6615"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4615"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2942"]]
+2941=PROJCS["Pulkovo 1942 / CS63 zone K4", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 56.766666666666666], PARAMETER["latitude_of_origin", 0.13333333333333333], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2941"]]
+2940=PROJCS["Pulkovo 1942 / CS63 zone K3", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 53.766666666666666], PARAMETER["latitude_of_origin", 0.13333333333333333], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2940"]]
+23240=PROJCS["Fahud / UTM zone 40N", GEOGCS["Fahud", DATUM["Fahud", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-346.0, -1.0, 224.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6232"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4232"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23240"]]
+2939=PROJCS["Pulkovo 1942 / CS63 zone K2", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 50.766666666666666], PARAMETER["latitude_of_origin", 0.13333333333333333], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2939"]]
+2938=PROJCS["Pulkovo 1942 / CS63 zone A4", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 50.53333333333333], PARAMETER["latitude_of_origin", 0.11666666666666667], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2938"]]
+2937=PROJCS["Pulkovo 1942 / CS63 zone A3", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 47.53333333333333], PARAMETER["latitude_of_origin", 0.11666666666666667], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2937"]]
+2936=PROJCS["Pulkovo 1942 / CS63 zone A2", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 44.53333333333333], PARAMETER["latitude_of_origin", 0.11666666666666667], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2936"]]
+2935=PROJCS["Pulkovo 1942 / CS63 zone A1", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 41.53333333333333], PARAMETER["latitude_of_origin", 0.11666666666666667], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2935"]]
+2934=PROJCS["Segara (Jakarta) / NEIEZ", GEOGCS["Segara (Jakarta)", DATUM["Gunung Segara (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6820"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4820"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9804"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 110.0], PARAMETER["scale_factor", 0.997], PARAMETER["false_easting", 3900000.0], PARAMETER["false_northing", 900000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2934"]]
+23239=PROJCS["Fahud / UTM zone 39N", GEOGCS["Fahud", DATUM["Fahud", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-346.0, -1.0, 224.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6232"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4232"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23239"]]
+2933=PROJCS["Segara / UTM zone 50S", GEOGCS["Segara", DATUM["Gunung Segara", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-404.78, 685.68, 45.47, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6613"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4613"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2933"]]
+2932=PROJCS["QND95 / Qatar National Grid", GEOGCS["QND95", DATUM["Qatar National Datum 1995", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-119.4248, -303.65872, -11.00061, 1.164298, 0.174458, 1.096259, 3.657065], AUTHORITY["EPSG","6614"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4614"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.21666666666667], PARAMETER["latitude_of_origin", 24.45], PARAMETER["scale_factor", 0.99999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2932"]]
+2931=PROJCS["Beduaram / TM 13 NE", GEOGCS["Beduaram", DATUM["Beduaram", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-106.0, -87.0, 188.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6213"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4213"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 13.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2931"]]
+2930=PROJCS["NAD83(HARN) / Wisconsin South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 42.0], PARAMETER["standard_parallel_1", 44.06666666666666], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.73333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2930"]]
+2929=PROJCS["NAD83(HARN) / Wisconsin Central (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.5], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.25], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2929"]]
+2928=PROJCS["NAD83(HARN) / Wisconsin North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 45.166666666666664], PARAMETER["standard_parallel_1", 46.766666666666666], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.56666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2928"]]
+2927=PROJCS["NAD83(HARN) / Washington South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 45.333333333333336], PARAMETER["standard_parallel_1", 47.33333333333333], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.833333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2927"]]
+2926=PROJCS["NAD83(HARN) / Washington North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.83333333333333], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.5], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2926"]]
+2925=PROJCS["NAD83(HARN) / Virginia South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.96666666666667], PARAMETER["false_easting", 11482916.667], PARAMETER["false_northing", 3280833.333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.766666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2925"]]
+2924=PROJCS["NAD83(HARN) / Virginia North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.199999999999996], PARAMETER["false_easting", 11482916.667], PARAMETER["false_northing", 6561666.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.03333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2924"]]
+2923=PROJCS["NAD83(HARN) / Utah South (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.35], PARAMETER["false_easting", 1640419.9480000003], PARAMETER["false_northing", 9842519.684999999], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.21666666666667], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2923"]]
+2922=PROJCS["NAD83(HARN) / Utah Central (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 40.65], PARAMETER["false_easting", 1640419.9480000003], PARAMETER["false_northing", 6561679.790000001], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.016666666666666], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2922"]]
+2921=PROJCS["NAD83(HARN) / Utah North (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 40.333333333333336], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 1640419.9480000003], PARAMETER["false_northing", 3280839.8950000005], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.71666666666667], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2921"]]
+2920=PROJCS["NAD83(HARN) / Texas South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 25.666666666666668], PARAMETER["standard_parallel_1", 27.833333333333332], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 16404166.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 26.166666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2920"]]
+66656405=GEOGCS["Azores Central 1995 (deg)", DATUM["Azores Central Islands 1995", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-103.088, 162.481, -28.276, 0.167, -0.082, -0.168, -1.504], AUTHORITY["EPSG","6665"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66656405"]]
+2919=PROJCS["NAD83(HARN) / Texas South Central (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 27.833333333333332], PARAMETER["standard_parallel_1", 30.28333333333333], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 13123333.333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 28.383333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2919"]]
+2918=PROJCS["NAD83(HARN) / Texas Central (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 29.666666666666668], PARAMETER["standard_parallel_1", 31.883333333333336], PARAMETER["false_easting", 2296583.333], PARAMETER["false_northing", 9842500.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 30.116666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2918"]]
+2917=PROJCS["NAD83(HARN) / Texas North Central (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 31.666666666666664], PARAMETER["standard_parallel_1", 33.96666666666667], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 6561666.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.13333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2917"]]
+61936405=GEOGCS["Manoca 1962 (deg)", DATUM["Manoca 1962", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-70.9, -151.8, -41.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6193"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61936405"]]
+2916=PROJCS["NAD83(HARN) / Texas North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -101.5], PARAMETER["latitude_of_origin", 34.0], PARAMETER["standard_parallel_1", 36.18333333333333], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 3280833.333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.65], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2916"]]
+2915=PROJCS["NAD83(HARN) / Tennessee (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -86.0], PARAMETER["latitude_of_origin", 34.333333333333336], PARAMETER["standard_parallel_1", 36.416666666666664], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.25], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2915"]]
+2914=PROJCS["NAD83(HARN) / Oregon South (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["standard_parallel_1", 44.0], PARAMETER["false_easting", 4921259.843000001], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.333333333333336], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2914"]]
+2913=PROJCS["NAD83(HARN) / Oregon North (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["standard_parallel_1", 46.0], PARAMETER["false_easting", 8202099.738], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.33333333333333], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2913"]]
+2912=PROJCS["NAD83(HARN) / Oklahoma South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 33.333333333333336], PARAMETER["standard_parallel_1", 35.233333333333334], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.93333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2912"]]
+2911=PROJCS["NAD83(HARN) / Oklahoma North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 35.0], PARAMETER["standard_parallel_1", 36.766666666666666], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.56666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2911"]]
+2910=PROJCS["NAD83(HARN) / North Dakota South (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 45.666666666666664], PARAMETER["standard_parallel_1", 47.483333333333334], PARAMETER["false_easting", 1968503.937], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.18333333333334], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2910"]]
+21037=PROJCS["Arc 1960 / UTM zone 37S", GEOGCS["Arc 1960", DATUM["Arc 1960", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-157.0, -2.0, -299.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6210"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4210"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21037"]]
+62886405=GEOGCS["Loma Quintana (deg)", DATUM["Loma Quintana", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6288"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62886405"]]
+21036=PROJCS["Arc 1960 / UTM zone 36S", GEOGCS["Arc 1960", DATUM["Arc 1960", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-157.0, -2.0, -299.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6210"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4210"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21036"]]
+21035=PROJCS["Arc 1960 / UTM zone 35S", GEOGCS["Arc 1960", DATUM["Arc 1960", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-157.0, -2.0, -299.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6210"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4210"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21035"]]
+2909=PROJCS["NAD83(HARN) / North Dakota North (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 1968503.937], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.43333333333334], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2909"]]
+2908=PROJCS["NAD83(HARN) / New York Long Island (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -74.0], PARAMETER["latitude_of_origin", 40.166666666666664], PARAMETER["standard_parallel_1", 41.03333333333333], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.666666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2908"]]
+2907=PROJCS["NAD83(HARN) / New York West (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -78.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 1148291.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2907"]]
+2906=PROJCS["NAD83(HARN) / New York Central (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -76.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 820208.333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2906"]]
+2905=PROJCS["NAD83(HARN) / New York East (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.5], PARAMETER["latitude_of_origin", 38.833333333333336], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 492125.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2905"]]
+2904=PROJCS["NAD83(HARN) / New Mexico West (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.83333333333334], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999916667], PARAMETER["false_easting", 2723091.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2904"]]
+2903=PROJCS["NAD83(HARN) / New Mexico Central (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -106.25], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2903"]]
+2902=PROJCS["NAD83(HARN) / New Mexico East (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -104.33333333333333], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999909091], PARAMETER["false_easting", 541337.5], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2902"]]
+2901=PROJCS["NAD83(HARN) / Montana (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -109.5], PARAMETER["latitude_of_origin", 44.25], PARAMETER["standard_parallel_1", 49.0], PARAMETER["false_easting", 1968503.937], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2901"]]
+2900=PROJCS["NAD83(HARN) / Mississippi West (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.33333333333333], PARAMETER["latitude_of_origin", 29.5], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 2296583.333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2900"]]
+68146405=GEOGCS["RT38 (Stockholm) (deg)", DATUM["Stockholm 1938 (Stockholm)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6814"]], PRIMEM["Stockholm", 18.058277777777775, AUTHORITY["EPSG","8911"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","68146405"]]
+62726405=GEOGCS["NZGD49 (deg)", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62726405"]]
+63096405=GEOGCS["Yacare (deg)", DATUM["Yacare", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-124.45, 183.74, 44.64, -0.4384, 0.5446, -0.9706, -2.1365], AUTHORITY["EPSG","6309"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63096405"]]
+32560=PROJCS["WGS 72BE / UTM zone 60S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32560"]]
+66166405=GEOGCS["Selvagem Grande (deg)", DATUM["Selvagem Grande", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-289.0, -124.0, 60.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6616"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66166405"]]
+22780=PROJCS["Deir ez Zor / Levant Stereographic", GEOGCS["Deir ez Zor", DATUM["Deir ez Zor", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-83.58, -397.54, 458.78, -17.595, -2.847, 4.256, 3.225], AUTHORITY["EPSG","6227"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4227"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 39.15], PARAMETER["latitude_of_origin", 34.2], PARAMETER["scale_factor", 0.9995341], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22780"]]
+61446405=GEOGCS["Kalianpur 1937 (deg)", DATUM["Kalianpur 1937", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[214.0, 804.0, 268.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6144"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61446405"]]
+32559=PROJCS["WGS 72BE / UTM zone 59S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32559"]]
+32558=PROJCS["WGS 72BE / UTM zone 58S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32558"]]
+32557=PROJCS["WGS 72BE / UTM zone 57S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32557"]]
+32556=PROJCS["WGS 72BE / UTM zone 56S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32556"]]
+32555=PROJCS["WGS 72BE / UTM zone 55S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32555"]]
+62396405=GEOGCS["Indian 1954 (deg)", DATUM["Indian 1954", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[217.0, 823.0, 299.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6239"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62396405"]]
+32554=PROJCS["WGS 72BE / UTM zone 54S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32554"]]
+32553=PROJCS["WGS 72BE / UTM zone 53S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32553"]]
+32552=PROJCS["WGS 72BE / UTM zone 52S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32552"]]
+32551=PROJCS["WGS 72BE / UTM zone 51S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32551"]]
+32550=PROJCS["WGS 72BE / UTM zone 50S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32550"]]
+22770=PROJCS["Deir ez Zor / Syria Lambert", GEOGCS["Deir ez Zor", DATUM["Deir ez Zor", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-83.58, -397.54, 458.78, -17.595, -2.847, 4.256, 3.225], AUTHORITY["EPSG","6227"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4227"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 37.35], PARAMETER["latitude_of_origin", 34.65], PARAMETER["scale_factor", 0.9996256], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22770"]]
+32549=PROJCS["WGS 72BE / UTM zone 49S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32549"]]
+32548=PROJCS["WGS 72BE / UTM zone 48S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32548"]]
+32547=PROJCS["WGS 72BE / UTM zone 47S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32547"]]
+32546=PROJCS["WGS 72BE / UTM zone 46S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32546"]]
+32545=PROJCS["WGS 72BE / UTM zone 45S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32545"]]
+32544=PROJCS["WGS 72BE / UTM zone 44S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32544"]]
+32543=PROJCS["WGS 72BE / UTM zone 43S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32543"]]
+32542=PROJCS["WGS 72BE / UTM zone 42S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32542"]]
+32541=PROJCS["WGS 72BE / UTM zone 41S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32541"]]
+32540=PROJCS["WGS 72BE / UTM zone 40S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32540"]]
+32539=PROJCS["WGS 72BE / UTM zone 39S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32539"]]
+32538=PROJCS["WGS 72BE / UTM zone 38S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32538"]]
+32537=PROJCS["WGS 72BE / UTM zone 37S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32537"]]
+32536=PROJCS["WGS 72BE / UTM zone 36S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32536"]]
+32535=PROJCS["WGS 72BE / UTM zone 35S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32535"]]
+32534=PROJCS["WGS 72BE / UTM zone 34S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32534"]]
+32533=PROJCS["WGS 72BE / UTM zone 33S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32533"]]
+32532=PROJCS["WGS 72BE / UTM zone 32S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32532"]]
+32531=PROJCS["WGS 72BE / UTM zone 31S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32531"]]
+32530=PROJCS["WGS 72BE / UTM zone 30S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32530"]]
+3399=PROJCS["RD/83 / 3-degree Gauss-Kruger zone 5", GEOGCS["RD/83", DATUM["Rauenberg Datum/83", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6745"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4745"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3399"]]
+3398=PROJCS["RD/83 / 3-degree Gauss-Kruger zone 4", GEOGCS["RD/83", DATUM["Rauenberg Datum/83", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6745"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4745"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3398"]]
+3397=PROJCS["PD/83 / 3-degree Gauss-Kruger zone 4", GEOGCS["PD/83", DATUM["Potsdam Datum/83", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6746"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4746"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3397"]]
+3396=PROJCS["PD/83 / 3-degree Gauss-Kruger zone 3", GEOGCS["PD/83", DATUM["Potsdam Datum/83", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6746"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4746"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3396"]]
+3395=PROJCS["WGS 84 / World Mercator", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9804"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3395"]]
+3394=PROJCS["Nahrwan 1934 / Iraq zone", GEOGCS["Nahrwan 1934", DATUM["Nahrwan 1934", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6744"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4744"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 32.5], PARAMETER["scale_factor", 0.9987864078], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 1166200.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3394"]]
+3393=PROJCS["Karbala 1979 / UTM zone 39N", GEOGCS["Karbala 1979", DATUM["Karbala 1979", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[70.995, -335.916, 262.898, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6743"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4743"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3393"]]
+3392=PROJCS["Karbala 1979 / UTM zone 38N", GEOGCS["Karbala 1979", DATUM["Karbala 1979", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[70.995, -335.916, 262.898, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6743"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4743"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3392"]]
+3391=PROJCS["Karbala 1979 / UTM zone 37N", GEOGCS["Karbala 1979", DATUM["Karbala 1979", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[70.995, -335.916, 262.898, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6743"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4743"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3391"]]
+3390=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 60", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 180.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 60500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3390"]]
+32529=PROJCS["WGS 72BE / UTM zone 29S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32529"]]
+61996405=GEOGCS["Egypt 1930 (deg)", DATUM["Egypt 1930", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6199"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61996405"]]
+32528=PROJCS["WGS 72BE / UTM zone 28S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32528"]]
+32527=PROJCS["WGS 72BE / UTM zone 27S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32527"]]
+32526=PROJCS["WGS 72BE / UTM zone 26S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32526"]]
+32525=PROJCS["WGS 72BE / UTM zone 25S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32525"]]
+32524=PROJCS["WGS 72BE / UTM zone 24S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32524"]]
+32523=PROJCS["WGS 72BE / UTM zone 23S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32523"]]
+32522=PROJCS["WGS 72BE / UTM zone 22S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32522"]]
+32521=PROJCS["WGS 72BE / UTM zone 21S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32521"]]
+32520=PROJCS["WGS 72BE / UTM zone 20S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32520"]]
+30340=PROJCS["TC(1948) / UTM zone 40N", GEOGCS["TC(1948)", DATUM["Trucial Coast 1948", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], AUTHORITY["EPSG","6303"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4303"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30340"]]
+3389=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 60", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 180.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 60500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3389"]]
+3388=PROJCS["Pulkovo 1942 / Caspian Sea Mercator", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Mercator_2SP", AUTHORITY["EPSG","9805"]], PARAMETER["standard_parallel_1", 42.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 51.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3388"]]
+3387=PROJCS["KKJ / Finland zone 5", GEOGCS["KKJ", DATUM["Kartastokoordinaattijarjestelma (1966)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-96.062, -82.428, -121.753, 4.801, -0.345, 1.376, 1.496], AUTHORITY["EPSG","6123"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4123"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3387"]]
+3386=PROJCS["KKJ / Finland zone 0", GEOGCS["KKJ", DATUM["Kartastokoordinaattijarjestelma (1966)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-96.062, -82.428, -121.753, 4.801, -0.345, 1.376, 1.496], AUTHORITY["EPSG","6123"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4123"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3386"]]
+3385=PROJCS["GDM2000 / Kelantan Grid", GEOGCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4742"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 102.29524166944445], PARAMETER["latitude_of_origin", 5.972543658333333], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 13227.851], PARAMETER["false_northing", 8739.894], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3385"]]
+3384=PROJCS["GDM2000 / Perak Grid", GEOGCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4742"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 100.81541058611113], PARAMETER["latitude_of_origin", 4.859063022222223], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", -1.769], PARAMETER["false_northing", 133454.779], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3384"]]
+66006405=GEOGCS["Anguilla 1957 (deg)", DATUM["Anguilla 1957", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6600"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66006405"]]
+3383=PROJCS["GDM2000 / Kedah and Perlis Grid", GEOGCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4742"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 100.6363711111111], PARAMETER["latitude_of_origin", 5.9646727138888895], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3383"]]
+3382=PROJCS["GDM2000 / Pinang Grid", GEOGCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4742"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 100.34437696388889], PARAMETER["latitude_of_origin", 5.421517541666668], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", -23.414], PARAMETER["false_northing", 62.283], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3382"]]
+3381=PROJCS["GDM2000 / Terengganu Grid", GEOGCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4742"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 103.07027562500002], PARAMETER["latitude_of_origin", 4.976285199999998], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 19594.245], PARAMETER["false_northing", 3371.895], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3381"]]
+3380=PROJCS["GDM2000 / Selangor Grid", GEOGCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4742"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 101.3891079138889], PARAMETER["latitude_of_origin", 3.684649049999999], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", -34836.161], PARAMETER["false_northing", 56464.049], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3380"]]
+32519=PROJCS["WGS 72BE / UTM zone 19S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32519"]]
+32518=PROJCS["WGS 72BE / UTM zone 18S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32518"]]
+32517=PROJCS["WGS 72BE / UTM zone 17S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32517"]]
+32516=PROJCS["WGS 72BE / UTM zone 16S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32516"]]
+32515=PROJCS["WGS 72BE / UTM zone 15S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32515"]]
+32514=PROJCS["WGS 72BE / UTM zone 14S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32514"]]
+32513=PROJCS["WGS 72BE / UTM zone 13S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32513"]]
+30339=PROJCS["TC(1948) / UTM zone 39N", GEOGCS["TC(1948)", DATUM["Trucial Coast 1948", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], AUTHORITY["EPSG","6303"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4303"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30339"]]
+32512=PROJCS["WGS 72BE / UTM zone 12S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32512"]]
+32511=PROJCS["WGS 72BE / UTM zone 11S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32511"]]
+32510=PROJCS["WGS 72BE / UTM zone 10S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32510"]]
+62236405=GEOGCS["Carthage (deg)", DATUM["Carthage", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-260.1, 5.5, 432.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6223"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62236405"]]
+5559=PROJCS["Ocotepeque 1935 / Guatemala Norte", GEOGCS["Ocotepeque 1935", DATUM["Ocotepeque 1935", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[213.116, 9.358, -74.946, -2.3514187912168985, -0.06146691226163471, 6.394208993659988, -5.22], AUTHORITY["EPSG","1070"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5451"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -90.33333333333333], PARAMETER["latitude_of_origin", 16.816666666666666], PARAMETER["scale_factor", 0.99992226], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 292209.579], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5559"]]
+5556=COMPD_CS["ETRS89 / UTM zone 33N + DHHN92 height", PROJCS["ETRS89 / UTM zone 33N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25833"]], VERT_CS["DHHN92 height", VERT_DATUM["Deutsches Haupthoehennetz 1992", 2005, AUTHORITY["EPSG","5181"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5783"]], AUTHORITY["EPSG","5556"]]
+5555=COMPD_CS["ETRS89 / UTM zone 32N + DHHN92 height", PROJCS["ETRS89 / UTM zone 32N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25832"]], VERT_CS["DHHN92 height", VERT_DATUM["Deutsches Haupthoehennetz 1992", 2005, AUTHORITY["EPSG","5181"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5783"]], AUTHORITY["EPSG","5555"]]
+5554=COMPD_CS["ETRS89 / UTM zone 31N + DHHN92 height", PROJCS["ETRS89 / UTM zone 31N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25831"]], VERT_CS["DHHN92 height", VERT_DATUM["Deutsches Haupthoehennetz 1992", 2005, AUTHORITY["EPSG","5181"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5783"]], AUTHORITY["EPSG","5554"]]
+3379=PROJCS["GDM2000 / PahangGrid", GEOGCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4742"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 102.36829898333332], PARAMETER["latitude_of_origin", 3.7693880888888875], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", -7368.228], PARAMETER["false_northing", 6485.858], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3379"]]
+5552=PROJCS["PNG94 / PNGMG94 zone 56", GEOGCS["PNG94", DATUM["Papua New Guinea Geodetic Datum 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1076"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5546"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5552"]]
+3378=PROJCS["GDM2000 / Sembilan and Melaka Grid", GEOGCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4742"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 101.97490504166664], PARAMETER["latitude_of_origin", 2.6823476361111123], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3673.785], PARAMETER["false_northing", -4240.573], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3378"]]
+5551=PROJCS["PNG94 / PNGMG94 zone 55", GEOGCS["PNG94", DATUM["Papua New Guinea Geodetic Datum 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1076"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5546"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5551"]]
+3377=PROJCS["GDM2000 / Johor Grid", GEOGCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4742"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 103.42793623611111], PARAMETER["latitude_of_origin", 2.1216797444444446], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", -14810.562], PARAMETER["false_northing", 8758.32], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3377"]]
+5550=PROJCS["PNG94 / PNGMG94 zone 54", GEOGCS["PNG94", DATUM["Papua New Guinea Geodetic Datum 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1076"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5546"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5550"]]
+3376=PROJCS["GDM2000 / East Malaysia BRSO", GEOGCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4742"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9812"]], PARAMETER["longitude_of_center", 115.0], PARAMETER["latitude_of_center", 4.0], PARAMETER["azimuth", 53.31580995000001], PARAMETER["scale_factor", 0.99984], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["rectified_grid_angle", 53.13010236111111], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3376"]]
+3375=PROJCS["GDM2000 / Peninsula RSO", GEOGCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4742"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9812"]], PARAMETER["longitude_of_center", 102.25], PARAMETER["latitude_of_center", 4.0], PARAMETER["azimuth", 323.02579646666675], PARAMETER["scale_factor", 0.99984], PARAMETER["false_easting", 804671.0], PARAMETER["false_northing", 0.0], PARAMETER["rectified_grid_angle", 323.130102361111], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3375"]]
+3374=PROJCS["FD54 / UTM zone 29N", GEOGCS["FD54", DATUM["Faroe Datum 1954", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6741"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4741"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3374"]]
+3373=PROJCS["NAD83 / UTM zone 60N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3373"]]
+3372=PROJCS["NAD83 / UTM zone 59N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3372"]]
+3371=PROJCS["NAD27 / UTM zone 60N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3371"]]
+3370=PROJCS["NAD27 / UTM zone 59N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3370"]]
+32509=PROJCS["WGS 72BE / UTM zone 9S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32509"]]
+32508=PROJCS["WGS 72BE / UTM zone 8S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32508"]]
+32507=PROJCS["WGS 72BE / UTM zone 7S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32507"]]
+32506=PROJCS["WGS 72BE / UTM zone 6S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32506"]]
+32505=PROJCS["WGS 72BE / UTM zone 5S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32505"]]
+32504=PROJCS["WGS 72BE / UTM zone 4S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32504"]]
+32503=PROJCS["WGS 72BE / UTM zone 3S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32503"]]
+32502=PROJCS["WGS 72BE / UTM zone 2S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32502"]]
+32501=PROJCS["WGS 72BE / UTM zone 1S", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32501"]]
+5546=GEOGCS["PNG94", DATUM["Papua New Guinea Geodetic Datum 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1076"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5546"]]
+5545=GEOGCS["PNG94", DATUM["Papua New Guinea Geodetic Datum 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1076"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5545"]]
+5544=GEOCCS["PNG94", DATUM["Papua New Guinea Geodetic Datum 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1076"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5544"]]
+3369=PROJCS["IGN Astro 1960 / UTM zone 30N", GEOGCS["IGN Astro 1960", DATUM["IGN Astro 1960", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6700"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4700"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3369"]]
+3368=PROJCS["IGN Astro 1960 / UTM zone 29N", GEOGCS["IGN Astro 1960", DATUM["IGN Astro 1960", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6700"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4700"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3368"]]
+3367=PROJCS["IGN Astro 1960 / UTM zone 28N", GEOGCS["IGN Astro 1960", DATUM["IGN Astro 1960", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6700"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4700"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3367"]]
+3366=PROJCS["Hong Kong 1963 Grid System", GEOGCS["Hong Kong 1963", DATUM["Hong Kong 1963", SPHEROID["Clarke 1858", 6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]], AUTHORITY["EPSG","6738"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4738"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 114.17855555555556], PARAMETER["latitude_of_origin", 22.312133333333335], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 40243.577756042374], PARAMETER["false_northing", 19069.933515125784], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3366"]]
+3365=PROJCS["NAD83(HARN) / Pennsylvania South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.96666666666667], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.93333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3365"]]
+3364=PROJCS["NAD83(HARN) / Pennsylvania South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.96666666666667], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.93333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3364"]]
+3363=PROJCS["NAD83(HARN) / Pennsylvania North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 40.166666666666664], PARAMETER["standard_parallel_1", 41.95], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.88333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3363"]]
+3362=PROJCS["NAD83(HARN) / Pennsylvania North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 40.166666666666664], PARAMETER["standard_parallel_1", 41.95], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.88333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3362"]]
+3361=PROJCS["NAD83(HARN) / South Carolina (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 31.833333333333336], PARAMETER["standard_parallel_1", 34.833333333333336], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.5], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3361"]]
+3360=PROJCS["NAD83(HARN) / South Carolina", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 31.833333333333336], PARAMETER["standard_parallel_1", 34.833333333333336], PARAMETER["false_easting", 609600.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3360"]]
+5539=PROJCS["Corrego Alegre 1961 / UTM zone 24S", GEOGCS["Corrego Alegre 1961", DATUM["Corrego Alegre 1961", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","1074"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5524"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5539"]]
+5538=PROJCS["Corrego Alegre 1961 / UTM zone 23S", GEOGCS["Corrego Alegre 1961", DATUM["Corrego Alegre 1961", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","1074"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5524"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5538"]]
+5537=PROJCS["Corrego Alegre 1961 / UTM zone 22S", GEOGCS["Corrego Alegre 1961", DATUM["Corrego Alegre 1961", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","1074"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5524"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5537"]]
+5536=PROJCS["Corrego Alegre 1961 / UTM zone 21S", GEOGCS["Corrego Alegre 1961", DATUM["Corrego Alegre 1961", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","1074"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5524"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5536"]]
+5535=PROJCS["SAD69(96) / UTM zone 25S", GEOGCS["SAD69(96)", DATUM["South American Datum 1969(96)", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], AUTHORITY["EPSG","1075"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5527"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5535"]]
+5534=PROJCS["SAD69(96) / UTM zone 24S", GEOGCS["SAD69(96)", DATUM["South American Datum 1969(96)", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], AUTHORITY["EPSG","1075"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5527"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5534"]]
+5533=PROJCS["SAD69(96) / UTM zone 23S", GEOGCS["SAD69(96)", DATUM["South American Datum 1969(96)", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], AUTHORITY["EPSG","1075"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5527"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5533"]]
+20539=PROJCS["Afgooye / UTM zone 39N", GEOGCS["Afgooye", DATUM["Afgooye", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-43.0, -163.0, 45.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6205"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4205"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20539"]]
+3359=PROJCS["NAD83(HARN) / North Carolina (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.0], PARAMETER["latitude_of_origin", 33.75], PARAMETER["standard_parallel_1", 36.166666666666664], PARAMETER["false_easting", 2000004.000008], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.333333333333336], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3359"]]
+5532=PROJCS["SAD69(96) / UTM zone 22S", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5532"]]
+20538=PROJCS["Afgooye / UTM zone 38N", GEOGCS["Afgooye", DATUM["Afgooye", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-43.0, -163.0, 45.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6205"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4205"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20538"]]
+3358=PROJCS["NAD83(HARN) / North Carolina", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.0], PARAMETER["latitude_of_origin", 33.75], PARAMETER["standard_parallel_1", 36.166666666666664], PARAMETER["false_easting", 609601.22], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.333333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3358"]]
+5531=PROJCS["SAD69(96) / UTM zone 21S", GEOGCS["SAD69(96)", DATUM["South American Datum 1969(96)", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], AUTHORITY["EPSG","1075"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5527"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5531"]]
+3357=PROJCS["Little Cayman 1961 / UTM zone 17N", GEOGCS["Little Cayman 1961", DATUM["Little Cayman 1961", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[44.4, 109.0, 151.7, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6726"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4726"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3357"]]
+5530=PROJCS["SAD69(96) / Brazil Polyconic", GEOGCS["SAD69(96)", DATUM["South American Datum 1969(96)", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], AUTHORITY["EPSG","1075"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5527"]], PROJECTION["Polyconic", AUTHORITY["EPSG","9818"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", -54.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5000000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5530"]]
+3356=PROJCS["Grand Cayman 1959 / UTM zone 17N", GEOGCS["Grand Cayman 1959", DATUM["Grand Cayman 1959", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[67.8, 106.1, 138.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6723"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4723"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3356"]]
+3355=PROJCS["Egypt Gulf of Suez S-650 TL / Red Belt", GEOGCS["Egypt Gulf of Suez S-650 TL", DATUM["Egypt Gulf of Suez S-650 TL", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], TOWGS84[-146.21, 112.63, 4.05, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6706"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4706"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 31.0], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 615000.0], PARAMETER["false_northing", 810000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3355"]]
+3354=PROJCS["Mhast (offshore) / UTM zone 32S", GEOGCS["Mhast (offshore)", DATUM["Mhast (offshore)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6705"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4705"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3354"]]
+3353=PROJCS["Mhast (onshore) / UTM zone 32S", GEOGCS["Mhast (onshore)", DATUM["Mhast (onshore)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6704"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4704"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3353"]]
+3352=PROJCS["Pulkovo 1942 / CS63 zone C2", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.95], PARAMETER["latitude_of_origin", 0.09999999999999999], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3352"]]
+3351=PROJCS["Pulkovo 1942 / CS63 zone C1", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.95], PARAMETER["latitude_of_origin", 0.09999999999999999], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3351"]]
+3350=PROJCS["Pulkovo 1942 / CS63 zone C0", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.95], PARAMETER["latitude_of_origin", 0.09999999999999999], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3350"]]
+61836405=GEOGCS["Azores Central 1948 (deg)", DATUM["Azores Central Islands 1948", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-104.0, 167.0, -38.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6183"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61836405"]]
+5527=GEOGCS["SAD69(96)", DATUM["South American Datum 1969(96)", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], AUTHORITY["EPSG","1075"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5527"]]
+5524=GEOGCS["Corrego Alegre 1961", DATUM["Corrego Alegre 1961", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","1074"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5524"]]
+5523=PROJCS["WGS 84 / Gabon TM 2011", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 11.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 5500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5523"]]
+3349=PROJCS["WGS 84 / PDC Mercator", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9804"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", -150.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3349"]]
+62786405=GEOGCS["OSGB70 (deg)", DATUM["OSGB 1970 (SN)", SPHEROID["Airy 1830", 6377563.396, 299.3249646, AUTHORITY["EPSG","7001"]], AUTHORITY["EPSG","6278"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62786405"]]
+3348=PROJCS["NAD83(CSRS) / Statistics Canada Lambert", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -91.86666666666667], PARAMETER["latitude_of_origin", 63.390675], PARAMETER["standard_parallel_1", 77.0], PARAMETER["false_easting", 6200000.0], PARAMETER["false_northing", 3000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 49.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3348"]]
+3347=PROJCS["NAD83 / Statistics Canada Lambert", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -91.86666666666667], PARAMETER["latitude_of_origin", 63.390675], PARAMETER["standard_parallel_1", 77.0], PARAMETER["false_easting", 6200000.0], PARAMETER["false_northing", 3000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 49.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3347"]]
+5520=PROJCS["DHDN / 3-degree Gauss-Kruger zone 1", GEOGCS["DHDN", DATUM["Deutsches Hauptdreiecksnetz", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[612.4, 77.0, 440.2, -0.054, 0.057, -2.797, 2.55], AUTHORITY["EPSG","6314"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4314"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5520"]]
+3346=PROJCS["LKS94 / Lithuania TM", GEOGCS["LKS94", DATUM["Lithuania 1994 (ETRS89)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6126"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4669"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9998], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3346"]]
+3345=PROJCS["Mauritania 1999 / UTM zone 30N", GEOGCS["Mauritania 1999", DATUM["Mauritania 1999", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6702"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4702"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3345"]]
+3344=PROJCS["Mauritania 1999 / UTM zone 29N", GEOGCS["Mauritania 1999", DATUM["Mauritania 1999", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6702"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4702"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3344"]]
+3343=PROJCS["Mauritania 1999 / UTM zone 28N", GEOGCS["Mauritania 1999", DATUM["Mauritania 1999", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6702"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4702"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3343"]]
+3342=PROJCS["IGCB 1955 / UTM zone 33S", GEOGCS["IGCB 1955", DATUM["Institut Geographique du Congo Belge 1955", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-79.9, -158.0, -168.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6701"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4701"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3342"]]
+3341=PROJCS["IGCB 1955 / Congo TM zone 16", GEOGCS["IGCB 1955", DATUM["Institut Geographique du Congo Belge 1955", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-79.9, -158.0, -168.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6701"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4701"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 16.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3341"]]
+3340=PROJCS["IGCB 1955 / Congo TM zone 14", GEOGCS["IGCB 1955", DATUM["Institut Geographique du Congo Belge 1955", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-79.9, -158.0, -168.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6701"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4701"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 14.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3340"]]
+5519=PROJCS["CI1979 / Chatham Islands Map Grid", GEOGCS["Chatham Islands 1979", DATUM["Chatham Islands Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[174.05, -25.49, 112.57, -0.0, 0.0, -0.554, 0.2263], AUTHORITY["EPSG","6673"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4673"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -176.5], PARAMETER["latitude_of_origin", -44.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 350000.0], PARAMETER["false_northing", 650000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5519"]]
+5518=PROJCS["CI1971 / Chatham Islands Map Grid", GEOGCS["Chatham Islands 1971", DATUM["Chatham Islands Datum 1971", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[175.0, -38.0, 113.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6672"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4672"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -176.5], PARAMETER["latitude_of_origin", -44.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 350000.0], PARAMETER["false_northing", 650000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5518"]]
+5513=PROJCS["S-JTSK / Krovak", GEOGCS["S-JTSK", DATUM["System Jednotne Trigonometricke Site Katastralni", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[572.213, 85.334, 461.94, 4.9732, -1.529, -5.2484, 3.5378], AUTHORITY["EPSG","6156"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4156"]], PROJECTION["Krovak", AUTHORITY["EPSG","9819"]], PARAMETER["latitude_of_center", 49.5], PARAMETER["longitude_of_center", 24.833333333333332], PARAMETER["azimuth", 30.288139722222223], PARAMETER["pseudo_standard_parallel_1", 78.5], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","5513"]]
+3339=PROJCS["IGCB 1955 / Congo TM zone 12", GEOGCS["IGCB 1955", DATUM["Institut Geographique du Congo Belge 1955", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-79.9, -158.0, -168.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6701"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4701"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3339"]]
+3338=PROJCS["NAD83 / Alaska Albers", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -154.0], PARAMETER["latitude_of_origin", 50.0], PARAMETER["standard_parallel_1", 55.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 65.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3338"]]
+3337=PROJCS["Le Pouce 1934 / Mauritius Grid", GEOGCS["Le Pouce 1934", DATUM["Le Pouce 1934", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-770.1, 158.4, -498.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6699"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4699"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 57.52182777777777], PARAMETER["latitude_of_origin", -20.195069444444446], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3337"]]
+3336=PROJCS["IGN 1962 Kerguelen / UTM zone 42S", GEOGCS["IGN 1962 Kerguelen", DATUM["IGN 1962 Kerguelen", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[145.0, -187.0, 103.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6698"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4698"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3336"]]
+3335=PROJCS["Pulkovo 1942(58) / Gauss-Kruger zone 5", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3335"]]
+3334=PROJCS["Pulkovo 1942(58) / Gauss-Kruger zone 4", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3334"]]
+3333=PROJCS["Pulkovo 1942(58) / Gauss-Kruger zone 3", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3333"]]
+3332=PROJCS["Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 8", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 8500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3332"]]
+3331=PROJCS["Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 7", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3331"]]
+3330=PROJCS["Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 6", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3330"]]
+3329=PROJCS["Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 5", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3329"]]
+3328=PROJCS["Pulkovo 1942(58) / GUGiK-80", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 19.166666666666668], PARAMETER["latitude_of_origin", 52.166666666666664], PARAMETER["scale_factor", 0.999714], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3328"]]
+3327=PROJCS["IGC 1962 / Congo TM zone 30", GEOGCS["IGC 1962 6th Parallel South", DATUM["IGC 1962 Arc of the 6th Parallel South", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6697"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4697"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3327"]]
+3326=PROJCS["IGC 1962 / Congo TM zone 28", GEOGCS["IGC 1962 6th Parallel South", DATUM["IGC 1962 Arc of the 6th Parallel South", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6697"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4697"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 28.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3326"]]
+68046405=GEOGCS["Makassar (Jakarta) (deg)", DATUM["Makassar (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6804"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","68046405"]]
+3325=PROJCS["IGC 1962 / Congo TM zone 26", GEOGCS["IGC 1962 6th Parallel South", DATUM["IGC 1962 Arc of the 6th Parallel South", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6697"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4697"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 26.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3325"]]
+3324=PROJCS["IGC 1962 / Congo TM zone 24", GEOGCS["IGC 1962 6th Parallel South", DATUM["IGC 1962 Arc of the 6th Parallel South", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6697"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4697"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3324"]]
+3323=PROJCS["IGC 1962 / Congo TM zone 22", GEOGCS["IGC 1962 6th Parallel South", DATUM["IGC 1962 Arc of the 6th Parallel South", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6697"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4697"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 22.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3323"]]
+3322=PROJCS["IGC 1962 / Congo TM zone 20", GEOGCS["IGC 1962 6th Parallel South", DATUM["IGC 1962 Arc of the 6th Parallel South", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6697"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4697"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 20.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3322"]]
+3321=PROJCS["IGC 1962 / Congo TM zone 18", GEOGCS["IGC 1962 6th Parallel South", DATUM["IGC 1962 Arc of the 6th Parallel South", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6697"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4697"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3321"]]
+3320=PROJCS["IGC 1962 / Congo TM zone 16", GEOGCS["IGC 1962 6th Parallel South", DATUM["IGC 1962 Arc of the 6th Parallel South", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6697"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4697"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 16.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3320"]]
+3319=PROJCS["IGC 1962 / Congo TM zone 14", GEOGCS["IGC 1962 6th Parallel South", DATUM["IGC 1962 Arc of the 6th Parallel South", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6697"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4697"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 14.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3319"]]
+3318=PROJCS["IGC 1962 / Congo TM zone 12", GEOGCS["IGC 1962 6th Parallel South", DATUM["IGC 1962 Arc of the 6th Parallel South", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6697"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4697"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3318"]]
+3317=PROJCS["Kasai 1953 / Congo TM zone 24", GEOGCS["Kasai 1953", DATUM["Kasai 1953", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6696"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4696"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3317"]]
+3316=PROJCS["Kasai 1953 / Congo TM zone 22", GEOGCS["Kasai 1953", DATUM["Kasai 1953", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6696"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4696"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 22.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3316"]]
+3315=PROJCS["Katanga 1955 / Katanga TM", GEOGCS["Katanga 1955", DATUM["Katanga 1955", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-103.746, -9.614, -255.95, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6695"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4695"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 26.0], PARAMETER["latitude_of_origin", -9.0], PARAMETER["scale_factor", 0.9998], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3315"]]
+3314=PROJCS["Katanga 1955 / Katanga Lambert", GEOGCS["Katanga 1955", DATUM["Katanga 1955", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-103.746, -9.614, -255.95, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6695"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4695"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 26.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", -6.5], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -11.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3314"]]
+3313=PROJCS["RGFG95 / UTM zone 21N", GEOGCS["RGFG95", DATUM["Reseau Geodesique Francais Guyane 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6624"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4624"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3313"]]
+3312=PROJCS["CSG67 / UTM zone 21N", GEOGCS["CSG67", DATUM["Centre Spatial Guyanais 1967", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-186.0, 230.0, 110.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6623"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4623"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3312"]]
+3311=PROJCS["NAD83(HARN) / California Albers", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 34.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", -4000000.0], PARAMETER["standard_parallel_2", 40.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3311"]]
+3310=PROJCS["NAD83 / California Albers", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 34.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", -4000000.0], PARAMETER["standard_parallel_2", 40.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3310"]]
+3309=PROJCS["NAD27 / California Albers", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 34.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", -4000000.0], PARAMETER["standard_parallel_2", 40.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3309"]]
+3308=PROJCS["GDA94 / NSW Lambert", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", -33.25], PARAMETER["standard_parallel_1", -30.75], PARAMETER["false_easting", 9300000.0], PARAMETER["false_northing", 4500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -35.75], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3308"]]
+3307=PROJCS["Nakhl-e Ghanem / UTM zone 39N", GEOGCS["Nakhl-e Ghanem", DATUM["Nakhl-e Ghanem", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, -0.15, 0.68, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6693"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4693"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3307"]]
+3306=PROJCS["Maupiti 83 / UTM zone 5S", GEOGCS["Maupiti 83", DATUM["Maupiti 83", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[217.037, 86.959, 23.956, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6692"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4692"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3306"]]
+3305=PROJCS["Moorea 87 / UTM zone 6S", GEOGCS["Moorea 87", DATUM["Moorea 87", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[215.525, 149.593, 176.229, -3.2624, 1.692, 1.1571, 10.4773], AUTHORITY["EPSG","6691"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4691"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3305"]]
+3304=PROJCS["Tahiti 79 / UTM zone 6S", GEOGCS["Tahiti 79", DATUM["Tahiti 79", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[221.525, 152.948, 176.768, -2.3847, 1.3896, 0.877, 11.4741], AUTHORITY["EPSG","6690"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4690"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3304"]]
+27594=PROJCS["NTF (Paris) / Corse", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 46.85], PARAMETER["scale_factor", 0.99994471], PARAMETER["false_easting", 234.358], PARAMETER["false_northing", 185861.369], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27594"]]
+3303=PROJCS["Fatu Iva 72 / UTM zone 7S", GEOGCS["Fatu Iva 72", DATUM["Fatu Iva 72", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[347.103, 1078.125, 2623.922, -33.8875, -70.6773, 9.3943, 186.074], AUTHORITY["EPSG","6688"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4688"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3303"]]
+62626405=GEOGCS["Massawa (deg)", DATUM["Massawa", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[639.0, 405.0, 60.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6262"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62626405"]]
+27593=PROJCS["NTF (Paris) / Sud France", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 49.0], PARAMETER["scale_factor", 0.999877499], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27593"]]
+3302=PROJCS["IGN63 Hiva Oa / UTM zone 7S", GEOGCS["IGN63 Hiva Oa", DATUM["IGN63 Hiva Oa", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[410.721, 55.049, 80.746, 2.5779, -2.3514, -0.6664, 17.3311], AUTHORITY["EPSG","6689"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4689"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3302"]]
+27592=PROJCS["NTF (Paris) / Centre France", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 52.0], PARAMETER["scale_factor", 0.99987742], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27592"]]
+3301=PROJCS["Estonian Coordinate System of 1997", GEOGCS["EST97", DATUM["Estonia 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6180"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4180"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 57.51755393055556], PARAMETER["standard_parallel_1", 59.333333333333336], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 6375000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 58.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3301"]]
+27591=PROJCS["NTF (Paris) / Nord France", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 55.0], PARAMETER["scale_factor", 0.999877341], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27591"]]
+3300=PROJCS["Estonian Coordinate System of 1992", GEOGCS["EST92", DATUM["Estonia 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.055, -0.541, -0.185, 0.0183, 0.0003, 0.007, -0.014], AUTHORITY["EPSG","6133"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4133"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 57.51755393055556], PARAMETER["standard_parallel_1", 59.333333333333336], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 6375000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 58.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3300"]]
+27584=PROJCS["NTF (Paris) / France IV", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 46.85], PARAMETER["scale_factor", 0.99994471], PARAMETER["false_easting", 234.358], PARAMETER["false_northing", 4185861.369], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27584"]]
+27583=PROJCS["NTF (Paris) / France III", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 49.0], PARAMETER["scale_factor", 0.999877499], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 3200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27583"]]
+27582=PROJCS["NTF (Paris) / France II", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 52.0], PARAMETER["scale_factor", 0.99987742], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 2200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27582"]]
+27581=PROJCS["NTF (Paris) / France I", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 55.0], PARAMETER["scale_factor", 0.999877341], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 1200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27581"]]
+27574=PROJCS["NTF (Paris) / Lambert zone IV", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 46.85], PARAMETER["scale_factor", 0.99994471], PARAMETER["false_easting", 234.358], PARAMETER["false_northing", 4185861.369], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27574"]]
+66066405=GEOGCS["St. Lucia 1955 (deg)", DATUM["St. Lucia 1955", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-149.0, 128.0, 296.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6606"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66066405"]]
+27573=PROJCS["NTF (Paris) / Lambert zone III", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 49.0], PARAMETER["scale_factor", 0.999877499], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 3200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27573"]]
+27572=PROJCS["NTF (Paris) / Lambert zone II", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 52.0], PARAMETER["scale_factor", 0.99987742], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 2200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27572"]]
+27571=PROJCS["NTF (Paris) / Lambert zone I", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 55.0], PARAMETER["scale_factor", 0.999877341], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 1200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27571"]]
+61346405=GEOGCS["PDO Survey Datum 1993 (deg)", DATUM["PDO Survey Datum 1993", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-180.624, -225.516, 173.919, -0.81, -1.898, 8.336, 16.71006], AUTHORITY["EPSG","6134"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61346405"]]
+25395=PROJCS["Luzon 1911 / Philippines zone V", GEOGCS["Luzon 1911", DATUM["Luzon 1911", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-133.0, -77.0, -51.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6253"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4253"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 125.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25395"]]
+25394=PROJCS["Luzon 1911 / Philippines zone IV", GEOGCS["Luzon 1911", DATUM["Luzon 1911", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-133.0, -77.0, -51.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6253"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4253"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25394"]]
+25393=PROJCS["Luzon 1911 / Philippines zone III", GEOGCS["Luzon 1911", DATUM["Luzon 1911", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-133.0, -77.0, -51.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6253"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4253"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 121.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25393"]]
+25392=PROJCS["Luzon 1911 / Philippines zone II", GEOGCS["Luzon 1911", DATUM["Luzon 1911", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-133.0, -77.0, -51.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6253"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4253"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 119.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25392"]]
+25391=PROJCS["Luzon 1911 / Philippines zone I", GEOGCS["Luzon 1911", DATUM["Luzon 1911", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-133.0, -77.0, -51.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6253"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4253"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25391"]]
+62296405=GEOGCS["Egypt 1907 (deg)", DATUM["Egypt 1907", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], TOWGS84[-130.0, 110.0, -13.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6229"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62296405"]]
+27564=PROJCS["NTF (Paris) / Lambert Corse", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 46.85], PARAMETER["scale_factor", 0.99994471], PARAMETER["false_easting", 234.358], PARAMETER["false_northing", 185861.369], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27564"]]
+27563=PROJCS["NTF (Paris) / Lambert Sud France", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 49.0], PARAMETER["scale_factor", 0.999877499], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27563"]]
+27562=PROJCS["NTF (Paris) / Lambert Centre France", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 52.0], PARAMETER["scale_factor", 0.99987742], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27562"]]
+27561=PROJCS["NTF (Paris) / Lambert Nord France", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 55.0], PARAMETER["scale_factor", 0.999877341], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27561"]]
+29739=PROJCS["Tananarive / UTM zone 39S", GEOGCS["Tananarive", DATUM["Tananarive 1925", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-189.0, -242.0, -91.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6297"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4297"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29739"]]
+29738=PROJCS["Tananarive / UTM zone 38S", GEOGCS["Tananarive", DATUM["Tananarive 1925", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-189.0, -242.0, -91.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6297"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4297"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29738"]]
+2899=PROJCS["NAD83(HARN) / Mississippi East (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.83333333333333], PARAMETER["latitude_of_origin", 29.5], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2899"]]
+2898=PROJCS["NAD83(HARN) / Michigan South (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.36666666666666], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.666666666666664], PARAMETER["false_easting", 13123359.580000002], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.1], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2898"]]
+2897=PROJCS["NAD83(HARN) / Michigan Central (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.36666666666666], PARAMETER["latitude_of_origin", 43.31666666666666], PARAMETER["standard_parallel_1", 45.699999999999996], PARAMETER["false_easting", 19685039.369999997], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.18333333333334], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2897"]]
+2896=PROJCS["NAD83(HARN) / Michigan North (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 44.78333333333333], PARAMETER["standard_parallel_1", 47.083333333333336], PARAMETER["false_easting", 26246719.160000004], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.48333333333333], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2896"]]
+2895=PROJCS["NAD83(HARN) / Massachusetts Island (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -70.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 41.483333333333334], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.28333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2895"]]
+2894=PROJCS["NAD83(HARN) / Massachusetts Mainland (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 2460625.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2894"]]
+2893=PROJCS["NAD83(HARN) / Maryland (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.0], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.449999999999996], PARAMETER["false_easting", 1312333.333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.3], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2893"]]
+2892=PROJCS["NAD83(HARN) / Kentucky South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.93333333333333], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.733333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2892"]]
+2891=PROJCS["NAD83(HARN) / Kentucky North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.25], PARAMETER["latitude_of_origin", 37.5], PARAMETER["standard_parallel_1", 38.96666666666667], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.96666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2891"]]
+2890=PROJCS["NAD83(HARN) / Indiana West (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.08333333333333], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 2952750.0], PARAMETER["false_northing", 818125.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2890"]]
+61896413=GEOGCS["REGVEN (3D deg)", DATUM["Red Geodesica Venezolana", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6189"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61896413"]]
+2889=PROJCS["NAD83(HARN) / Indiana East (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.66666666666667], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 328083.333], PARAMETER["false_northing", 818125.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2889"]]
+2888=PROJCS["NAD83(HARN) / Idaho West (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.75], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 2624666.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2888"]]
+2887=PROJCS["NAD83(HARN) / Idaho Central (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -114.0], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2887"]]
+2886=PROJCS["NAD83(HARN) / Idaho East (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -112.16666666666667], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2886"]]
+2885=PROJCS["NAD83(HARN) / Georgia West (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -84.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 2296583.333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2885"]]
+2884=PROJCS["NAD83(HARN) / Georgia East (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2884"]]
+2883=PROJCS["NAD83(HARN) / Florida North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.5], PARAMETER["latitude_of_origin", 29.0], PARAMETER["standard_parallel_1", 30.75], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.583333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2883"]]
+2882=PROJCS["NAD83(HARN) / Florida West (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2882"]]
+2881=PROJCS["NAD83(HARN) / Florida East (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2881"]]
+2880=PROJCS["NAD83(HARN) / Delaware (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.41666666666667], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 0.999995], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2880"]]
+61896405=GEOGCS["REGVEN (deg)", DATUM["Red Geodesica Venezolana", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6189"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61896405"]]
+2879=PROJCS["NAD83(HARN) / Connecticut (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -72.75], PARAMETER["latitude_of_origin", 40.833333333333336], PARAMETER["standard_parallel_1", 41.86666666666669], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.2], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2879"]]
+2878=PROJCS["NAD83(HARN) / Colorado South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.233333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2878"]]
+2877=PROJCS["NAD83(HARN) / Colorado Central (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 37.833333333333336], PARAMETER["standard_parallel_1", 39.75], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.45], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2877"]]
+2876=PROJCS["NAD83(HARN) / Colorado North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.78333333333333], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2876"]]
+2875=PROJCS["NAD83(HARN) / California zone 6 (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -116.25], PARAMETER["latitude_of_origin", 32.166666666666664], PARAMETER["standard_parallel_1", 33.88333333333333], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.78333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2875"]]
+2874=PROJCS["NAD83(HARN) / California zone 5 (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -118.0], PARAMETER["latitude_of_origin", 33.5], PARAMETER["standard_parallel_1", 35.46666666666667], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.03333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2874"]]
+2873=PROJCS["NAD83(HARN) / California zone 4 (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -119.0], PARAMETER["latitude_of_origin", 35.333333333333336], PARAMETER["standard_parallel_1", 37.25], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2873"]]
+2872=PROJCS["NAD83(HARN) / California zone 3 (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 36.5], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.06666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2872"]]
+2871=PROJCS["NAD83(HARN) / California zone 2 (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.833333333333336], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.333333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2871"]]
+2870=PROJCS["NAD83(HARN) / California zone 1 (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 41.666666666666664], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2870"]]
+62136405=GEOGCS["Beduaram (deg)", DATUM["Beduaram", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-106.0, -87.0, 188.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6213"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62136405"]]
+29702=PROJCS["Tananarive (Paris) / Laborde Grid approximation", GEOGCS["Tananarive (Paris)", DATUM["Tananarive 1925 (Paris)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6810"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4810"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9815"]], PARAMETER["longitude_of_center", 49.0], PARAMETER["latitude_of_center", -21.0], PARAMETER["azimuth", 21.0], PARAMETER["scale_factor", 0.9995], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], PARAMETER["rectified_grid_angle", 21.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29702"]]
+29700=PROJCS["Tananarive (Paris) / Laborde Grid", GEOGCS["Tananarive (Paris)", DATUM["Tananarive 1925 (Paris)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6810"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4810"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9815"]], PARAMETER["longitude_of_center", 49.0], PARAMETER["latitude_of_center", -21.0], PARAMETER["azimuth", 21.0], PARAMETER["scale_factor", 0.9995], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], PARAMETER["rectified_grid_angle", 21.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29700"]]
+2869=PROJCS["NAD83(HARN) / Arizona West (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -113.75], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2869"]]
+2868=PROJCS["NAD83(HARN) / Arizona Central (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.91666666666666], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2868"]]
+2867=PROJCS["NAD83(HARN) / Arizona East (ft)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.16666666666667], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2867"]]
+2866=PROJCS["NAD83(HARN) / Puerto Rico and Virgin Is.", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -66.43333333333334], PARAMETER["latitude_of_origin", 17.833333333333332], PARAMETER["standard_parallel_1", 18.433333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 18.033333333333335], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2866"]]
+2865=PROJCS["NAD83(HARN) / Wyoming West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.08333333333333], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 100000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2865"]]
+2864=PROJCS["NAD83(HARN) / Wyoming West Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -108.75], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2864"]]
+2863=PROJCS["NAD83(HARN) / Wyoming East Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.33333333333334], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 100000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2863"]]
+2862=PROJCS["NAD83(HARN) / Wyoming East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.16666666666666], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2862"]]
+2861=PROJCS["NAD83(HARN) / Wisconsin South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 42.0], PARAMETER["standard_parallel_1", 44.06666666666666], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.73333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2861"]]
+2860=PROJCS["NAD83(HARN) / Wisconsin Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.5], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2860"]]
+2859=PROJCS["NAD83(HARN) / Wisconsin North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 45.166666666666664], PARAMETER["standard_parallel_1", 46.766666666666666], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.56666666666666], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2859"]]
+2858=PROJCS["NAD83(HARN) / West Virginia South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 37.0], PARAMETER["standard_parallel_1", 38.88333333333333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.483333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2858"]]
+2857=PROJCS["NAD83(HARN) / West Virginia North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 38.5], PARAMETER["standard_parallel_1", 40.25], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2857"]]
+2856=PROJCS["NAD83(HARN) / Washington South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 45.333333333333336], PARAMETER["standard_parallel_1", 47.33333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.833333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2856"]]
+2855=PROJCS["NAD83(HARN) / Washington North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.83333333333333], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2855"]]
+2854=PROJCS["NAD83(HARN) / Virginia South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.96666666666667], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.766666666666666], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2854"]]
+2853=PROJCS["NAD83(HARN) / Virginia North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.199999999999996], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 2000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.03333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2853"]]
+2852=PROJCS["NAD83(HARN) / Vermont", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -72.5], PARAMETER["latitude_of_origin", 42.5], PARAMETER["scale_factor", 0.999964286], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2852"]]
+2851=PROJCS["NAD83(HARN) / Utah South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.35], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 3000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.21666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2851"]]
+2850=PROJCS["NAD83(HARN) / Utah Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 40.65], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 2000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.016666666666666], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2850"]]
+66456413=GEOGCS["RGNC 1991 (3D deg)", DATUM["Reseau Geodesique Nouvelle Caledonie 1991", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6645"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","66456413"]]
+61736413=GEOGCS["IRENET95 (3D deg)", DATUM["IRENET95", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6173"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61736413"]]
+2849=PROJCS["NAD83(HARN) / Utah North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 40.333333333333336], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2849"]]
+27500=PROJCS["ATF (Paris) / Nord de Guerre", GEOGCS["ATF (Paris)", DATUM["Ancienne Triangulation Francaise (Paris)", SPHEROID["Plessis 1817", 6376523.0, 308.64, AUTHORITY["EPSG","7027"]], AUTHORITY["EPSG","6901"]], PRIMEM["Paris RGS", 2.5968981481481483, AUTHORITY["EPSG","8914"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4901"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 6.0], PARAMETER["latitude_of_origin", 55.0], PARAMETER["scale_factor", 0.99950908], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27500"]]
+2848=PROJCS["NAD83(HARN) / Texas South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 25.666666666666668], PARAMETER["standard_parallel_1", 27.833333333333332], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 5000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 26.166666666666664], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2848"]]
+2847=PROJCS["NAD83(HARN) / Texas South Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 27.833333333333332], PARAMETER["standard_parallel_1", 30.28333333333333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 4000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 28.383333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2847"]]
+2846=PROJCS["NAD83(HARN) / Texas Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 29.666666666666668], PARAMETER["standard_parallel_1", 31.883333333333336], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 3000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 30.116666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2846"]]
+2845=PROJCS["NAD83(HARN) / Texas North Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 31.666666666666664], PARAMETER["standard_parallel_1", 33.96666666666667], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 2000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.13333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2845"]]
+2844=PROJCS["NAD83(HARN) / Texas North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -101.5], PARAMETER["latitude_of_origin", 34.0], PARAMETER["standard_parallel_1", 36.18333333333333], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.65], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2844"]]
+2843=PROJCS["NAD83(HARN) / Tennessee", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -86.0], PARAMETER["latitude_of_origin", 34.333333333333336], PARAMETER["standard_parallel_1", 36.416666666666664], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2843"]]
+2842=PROJCS["NAD83(HARN) / South Dakota South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 42.333333333333336], PARAMETER["standard_parallel_1", 44.4], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.833333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2842"]]
+2841=PROJCS["NAD83(HARN) / South Dakota North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.68333333333334], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.416666666666664], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2841"]]
+2840=PROJCS["NAD83(HARN) / Rhode Island", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.083333333333336], PARAMETER["scale_factor", 0.99999375], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2840"]]
+66456405=GEOGCS["RGNC 1991 (deg)", DATUM["Reseau Geodesique Nouvelle Caledonie 1991", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6645"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66456405"]]
+61736405=GEOGCS["IRENET95 (deg)", DATUM["IRENET95", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6173"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61736405"]]
+62686405=GEOGCS["NAD27 Michigan (deg)", DATUM["NAD27 Michigan", SPHEROID["Clarke 1866 Michigan", 6378450.047548896, 294.978697164674, AUTHORITY["EPSG","7009"]], AUTHORITY["EPSG","6268"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62686405"]]
+2839=PROJCS["NAD83(HARN) / Oregon South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["standard_parallel_1", 44.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.333333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2839"]]
+2838=PROJCS["NAD83(HARN) / Oregon North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["standard_parallel_1", 46.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2838"]]
+2837=PROJCS["NAD83(HARN) / Oklahoma South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 33.333333333333336], PARAMETER["standard_parallel_1", 35.233333333333334], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.93333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2837"]]
+2836=PROJCS["NAD83(HARN) / Oklahoma North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 35.0], PARAMETER["standard_parallel_1", 36.766666666666666], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.56666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2836"]]
+2835=PROJCS["NAD83(HARN) / Ohio South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 38.0], PARAMETER["standard_parallel_1", 40.03333333333333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.733333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2835"]]
+2834=PROJCS["NAD83(HARN) / Ohio North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 39.666666666666664], PARAMETER["standard_parallel_1", 41.7], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.43333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2834"]]
+2833=PROJCS["NAD83(HARN) / North Dakota South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 45.666666666666664], PARAMETER["standard_parallel_1", 47.483333333333334], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.18333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2833"]]
+2832=PROJCS["NAD83(HARN) / North Dakota North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.43333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2832"]]
+2831=PROJCS["NAD83(HARN) / New York Long Island", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -74.0], PARAMETER["latitude_of_origin", 40.166666666666664], PARAMETER["standard_parallel_1", 41.03333333333333], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.666666666666664], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2831"]]
+2830=PROJCS["NAD83(HARN) / New York West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -78.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 350000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2830"]]
+2829=PROJCS["NAD83(HARN) / New York Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -76.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2829"]]
+2828=PROJCS["NAD83(HARN) / New York East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.5], PARAMETER["latitude_of_origin", 38.833333333333336], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2828"]]
+2827=PROJCS["NAD83(HARN) / New Mexico West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.83333333333334], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999916667], PARAMETER["false_easting", 830000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2827"]]
+2826=PROJCS["NAD83(HARN) / New Mexico Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -106.25], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2826"]]
+2825=PROJCS["NAD83(HARN) / New Mexico East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -104.33333333333333], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999909091], PARAMETER["false_easting", 165000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2825"]]
+2824=PROJCS["NAD83(HARN) / New Jersey", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.5], PARAMETER["latitude_of_origin", 38.833333333333336], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2824"]]
+2823=PROJCS["NAD83(HARN) / New Hampshire", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.66666666666667], PARAMETER["latitude_of_origin", 42.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2823"]]
+2822=PROJCS["NAD83(HARN) / Nevada West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -118.58333333333333], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 4000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2822"]]
+2821=PROJCS["NAD83(HARN) / Nevada Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -116.66666666666667], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 6000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2821"]]
+2820=PROJCS["NAD83(HARN) / Nevada East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.58333333333334], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 8000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2820"]]
+2819=PROJCS["NAD83(HARN) / Nebraska", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 39.833333333333336], PARAMETER["standard_parallel_1", 43.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2819"]]
+2818=PROJCS["NAD83(HARN) / Montana", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -109.5], PARAMETER["latitude_of_origin", 44.25], PARAMETER["standard_parallel_1", 49.0], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2818"]]
+2817=PROJCS["NAD83(HARN) / Missouri West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -94.5], PARAMETER["latitude_of_origin", 36.166666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 850000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2817"]]
+2816=PROJCS["NAD83(HARN) / Missouri Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -92.5], PARAMETER["latitude_of_origin", 35.833333333333336], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2816"]]
+2815=PROJCS["NAD83(HARN) / Missouri East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.5], PARAMETER["latitude_of_origin", 35.833333333333336], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2815"]]
+2814=PROJCS["NAD83(HARN) / Mississippi West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.33333333333333], PARAMETER["latitude_of_origin", 29.5], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2814"]]
+63226405=GEOGCS["WGS 72 (deg)", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63226405"]]
+2813=PROJCS["NAD83(HARN) / Mississippi East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.83333333333333], PARAMETER["latitude_of_origin", 29.5], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2813"]]
+2812=PROJCS["NAD83(HARN) / Minnesota South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.0], PARAMETER["latitude_of_origin", 43.0], PARAMETER["standard_parallel_1", 45.21666666666667], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 100000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.78333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2812"]]
+2811=PROJCS["NAD83(HARN) / Minnesota Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.25], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 47.05], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 100000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.61666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2811"]]
+2810=PROJCS["NAD83(HARN) / Minnesota North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.1], PARAMETER["latitude_of_origin", 46.5], PARAMETER["standard_parallel_1", 48.63333333333333], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 100000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.03333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2810"]]
+2809=PROJCS["NAD83(HARN) / Michigan South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.36666666666666], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.666666666666664], PARAMETER["false_easting", 4000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.1], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2809"]]
+2808=PROJCS["NAD83(HARN) / Michigan Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.36666666666666], PARAMETER["latitude_of_origin", 43.31666666666666], PARAMETER["standard_parallel_1", 45.699999999999996], PARAMETER["false_easting", 6000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.18333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2808"]]
+2807=PROJCS["NAD83(HARN) / Michigan North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 44.78333333333333], PARAMETER["standard_parallel_1", 47.083333333333336], PARAMETER["false_easting", 8000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.48333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2807"]]
+2806=PROJCS["NAD83(HARN) / Massachusetts Island", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -70.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 41.483333333333334], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.28333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2806"]]
+2805=PROJCS["NAD83(HARN) / Massachusetts Mainland", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 750000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2805"]]
+2804=PROJCS["NAD83(HARN) / Maryland", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.0], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.449999999999996], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.3], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2804"]]
+2803=PROJCS["NAD83(HARN) / Maine West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.16666666666667], PARAMETER["latitude_of_origin", 42.833333333333336], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 900000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2803"]]
+2802=PROJCS["NAD83(HARN) / Maine East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -68.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2802"]]
+2801=PROJCS["NAD83(HARN) / Louisiana South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -91.33333333333333], PARAMETER["latitude_of_origin", 28.5], PARAMETER["standard_parallel_1", 30.7], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.3], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2801"]]
+2800=PROJCS["NAD83(HARN) / Louisiana North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.5], PARAMETER["latitude_of_origin", 30.5], PARAMETER["standard_parallel_1", 32.666666666666664], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 31.166666666666668], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2800"]]
+62526405=GEOGCS["Lome (deg)", DATUM["Lome", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6252"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62526405"]]
+24893=PROJCS["PSAD56 / Peru east zone", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.5], PARAMETER["latitude_of_origin", -9.5], PARAMETER["scale_factor", 0.99952992], PARAMETER["false_easting", 1324000.0], PARAMETER["false_northing", 1040084.558], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24893"]]
+24892=PROJCS["PSAD56 / Peru central zone", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -76.0], PARAMETER["latitude_of_origin", -9.5], PARAMETER["scale_factor", 0.99932994], PARAMETER["false_easting", 720000.0], PARAMETER["false_northing", 1039979.159], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24892"]]
+24891=PROJCS["PSAD56 / Peru west zone", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -80.5], PARAMETER["latitude_of_origin", -6.0], PARAMETER["scale_factor", 0.99983008], PARAMETER["false_easting", 222000.0], PARAMETER["false_northing", 1426834.743], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24891"]]
+61246405=GEOGCS["RT90 (deg)", DATUM["Rikets koordinatsystem 1990", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[414.1, 41.3, 603.1, -0.855, -2.141, 7.023, 0.0], AUTHORITY["EPSG","6124"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61246405"]]
+24882=PROJCS["PSAD56 / UTM zone 22S", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24882"]]
+24881=PROJCS["PSAD56 / UTM zone 21S", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24881"]]
+24880=PROJCS["PSAD56 / UTM zone 20S", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24880"]]
+62196405=GEOGCS["Bukit Rimpah (deg)", DATUM["Bukit Rimpah", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-384.0, 664.0, -48.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6219"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62196405"]]
+24879=PROJCS["PSAD56 / UTM zone 19S", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24879"]]
+24878=PROJCS["PSAD56 / UTM zone 18S", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24878"]]
+24877=PROJCS["PSAD56 / UTM zone 17S", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24877"]]
+32460=PROJCS["WGS 72BE / UTM zone 60N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32460"]]
+32459=PROJCS["WGS 72BE / UTM zone 59N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32459"]]
+32458=PROJCS["WGS 72BE / UTM zone 58N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32458"]]
+32457=PROJCS["WGS 72BE / UTM zone 57N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32457"]]
+32456=PROJCS["WGS 72BE / UTM zone 56N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32456"]]
+32455=PROJCS["WGS 72BE / UTM zone 55N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32455"]]
+32454=PROJCS["WGS 72BE / UTM zone 54N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32454"]]
+32453=PROJCS["WGS 72BE / UTM zone 53N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32453"]]
+32452=PROJCS["WGS 72BE / UTM zone 52N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32452"]]
+32451=PROJCS["WGS 72BE / UTM zone 51N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32451"]]
+32450=PROJCS["WGS 72BE / UTM zone 50N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32450"]]
+61796405=GEOGCS["Pulkovo 1942(58) (deg)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61796405"]]
+20499=PROJCS["Ain el Abd / Bahrain Grid", GEOGCS["Ain el Abd", DATUM["Ain el Abd 1970", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-85.645, -273.077, -79.708, 2.289, 1.421, -2.532, 3.194], AUTHORITY["EPSG","6204"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4204"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20499"]]
+5490=PROJCS["RGAF09 / UTM zone 20N", GEOGCS["RGAF09", DATUM["Reseau Geodesique des Antilles Francaises 2009", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1073"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5489"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5490"]]
+32449=PROJCS["WGS 72BE / UTM zone 49N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32449"]]
+32448=PROJCS["WGS 72BE / UTM zone 48N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32448"]]
+32447=PROJCS["WGS 72BE / UTM zone 47N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32447"]]
+32446=PROJCS["WGS 72BE / UTM zone 46N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32446"]]
+32445=PROJCS["WGS 72BE / UTM zone 45N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32445"]]
+32444=PROJCS["WGS 72BE / UTM zone 44N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32444"]]
+32443=PROJCS["WGS 72BE / UTM zone 43N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32443"]]
+32442=PROJCS["WGS 72BE / UTM zone 42N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32442"]]
+32441=PROJCS["WGS 72BE / UTM zone 41N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32441"]]
+32440=PROJCS["WGS 72BE / UTM zone 40N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32440"]]
+5489=GEOGCS["RGAF09", DATUM["Reseau Geodesique des Antilles Francaises 2009", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1073"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5489"]]
+5488=GEOGCS["RGAF09", DATUM["Reseau Geodesique des Antilles Francaises 2009", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1073"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5488"]]
+5487=GEOCCS["RGAF09", DATUM["Reseau Geodesique des Antilles Francaises 2009", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1073"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5487"]]
+5482=PROJCS["RSRGD2000 / RSPS2000", GEOGCS["RSRGD2000", DATUM["Ross Sea Region Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6764"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4764"]], PROJECTION["Polar_Stereographic", AUTHORITY["EPSG","9810"]], PARAMETER["central_meridian", 180.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 0.994], PARAMETER["false_easting", 5000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5482"]]
+5481=PROJCS["RSRGD2000 / PCLC2000", GEOGCS["RSRGD2000", DATUM["Ross Sea Region Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6764"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4764"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 166.0], PARAMETER["latitude_of_origin", -71.5], PARAMETER["standard_parallel_1", -70.66666666666667], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -72.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5481"]]
+5480=PROJCS["RSRGD2000 / BCLC2000", GEOGCS["RSRGD2000", DATUM["Ross Sea Region Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6764"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4764"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", -74.5], PARAMETER["standard_parallel_1", -73.66666666666667], PARAMETER["false_easting", 5000000.0], PARAMETER["false_northing", 3000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5480"]]
+62036405=GEOGCS["AGD84 (deg)", DATUM["Australian Geodetic Datum 1984", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-117.763, -51.51, 139.061, 0.292, -0.443, -0.277, -0.191], AUTHORITY["EPSG","6203"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62036405"]]
+32439=PROJCS["WGS 72BE / UTM zone 39N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32439"]]
+32438=PROJCS["WGS 72BE / UTM zone 38N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32438"]]
+32437=PROJCS["WGS 72BE / UTM zone 37N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32437"]]
+32436=PROJCS["WGS 72BE / UTM zone 36N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32436"]]
+32435=PROJCS["WGS 72BE / UTM zone 35N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32435"]]
+32434=PROJCS["WGS 72BE / UTM zone 34N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32434"]]
+32433=PROJCS["WGS 72BE / UTM zone 33N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32433"]]
+32432=PROJCS["WGS 72BE / UTM zone 32N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32432"]]
+32431=PROJCS["WGS 72BE / UTM zone 31N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32431"]]
+32430=PROJCS["WGS 72BE / UTM zone 30N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32430"]]
+5479=PROJCS["RSRGD2000 / MSLC2000", GEOGCS["RSRGD2000", DATUM["Ross Sea Region Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6764"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4764"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 163.0], PARAMETER["latitude_of_origin", -78.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 7000000.0], PARAMETER["false_northing", 5000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5479"]]
+3299=PROJCS["RGPF / UTM zone 8S", GEOGCS["RGPF", DATUM["Reseau Geodesique de la Polynesie Francaise", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.072, -0.507, -0.245, -0.0183, -0.0003, 0.007, -0.0093], AUTHORITY["EPSG","6687"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4687"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3299"]]
+5472=PROJCS["Panama-Colon 1911 / Panama Polyconic", GEOGCS["Panama-Colon 1911", DATUM["Panama-Colon 1911", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","1072"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5467"]], PROJECTION["Polyconic", AUTHORITY["EPSG","9818"]], PARAMETER["latitude_of_origin", 8.25], PARAMETER["central_meridian", -81.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1092972.1], UNIT["m*0.9143917962", 0.9143917962], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5472"]]
+3298=PROJCS["RGPF / UTM zone 7S", GEOGCS["RGPF", DATUM["Reseau Geodesique de la Polynesie Francaise", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.072, -0.507, -0.245, -0.0183, -0.0003, 0.007, -0.0093], AUTHORITY["EPSG","6687"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4687"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3298"]]
+3297=PROJCS["RGPF / UTM zone 6S", GEOGCS["RGPF", DATUM["Reseau Geodesique de la Polynesie Francaise", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.072, -0.507, -0.245, -0.0183, -0.0003, 0.007, -0.0093], AUTHORITY["EPSG","6687"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4687"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3297"]]
+3296=PROJCS["RGPF / UTM zone 5S", GEOGCS["RGPF", DATUM["Reseau Geodesique de la Polynesie Francaise", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.072, -0.507, -0.245, -0.0183, -0.0003, 0.007, -0.0093], AUTHORITY["EPSG","6687"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4687"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3296"]]
+3294=PROJCS["WGS 84 / USGS Transantarctic Mountains", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 162.0], PARAMETER["latitude_of_origin", -78.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3294"]]
+3293=PROJCS["WGS 84 / SCAR IMW SW01-60", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 0.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 90 deg East"], AXIS["Northing", "North along 0 deg"], AUTHORITY["EPSG","3293"]]
+3292=PROJCS["WGS 84 / SCAR IMW SV51-60", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 150.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 120 deg West"], AXIS["Northing", "North along 150 deg East"], AUTHORITY["EPSG","3292"]]
+3291=PROJCS["WGS 84 / SCAR IMW SV41-50", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 90.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 180 deg"], AXIS["Northing", "North along 90 deg East"], AUTHORITY["EPSG","3291"]]
+3290=PROJCS["WGS 84 / SCAR IMW SV31-40", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 30.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 120 deg East"], AXIS["Northing", "North along 30 deg East"], AUTHORITY["EPSG","3290"]]
+32429=PROJCS["WGS 72BE / UTM zone 29N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32429"]]
+32428=PROJCS["WGS 72BE / UTM zone 28N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32428"]]
+32427=PROJCS["WGS 72BE / UTM zone 27N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32427"]]
+32426=PROJCS["WGS 72BE / UTM zone 26N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32426"]]
+32425=PROJCS["WGS 72BE / UTM zone 25N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32425"]]
+32424=PROJCS["WGS 72BE / UTM zone 24N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32424"]]
+32423=PROJCS["WGS 72BE / UTM zone 23N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32423"]]
+32422=PROJCS["WGS 72BE / UTM zone 22N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32422"]]
+32421=PROJCS["WGS 72BE / UTM zone 21N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32421"]]
+32420=PROJCS["WGS 72BE / UTM zone 20N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32420"]]
+5469=PROJCS["Panama-Colon 1911 / Panama Lambert", GEOGCS["Panama-Colon 1911", DATUM["Panama-Colon 1911", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","1072"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5467"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -80.0], PARAMETER["latitude_of_origin", 8.416666666666666], PARAMETER["scale_factor", 0.99989909], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 294865.303], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5469"]]
+24821=PROJCS["PSAD56 / UTM zone 21N", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24821"]]
+24820=PROJCS["PSAD56 / UTM zone 20N", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24820"]]
+5467=GEOGCS["Panama-Colon 1911", DATUM["Panama-Colon 1911", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","1072"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5467"]]
+5466=PROJCS["Sibun Gorge 1922 / Colony Grid", GEOGCS["Sibun Gorge 1922", DATUM["Sibun Gorge 1922", SPHEROID["Clarke 1858", 6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]], AUTHORITY["EPSG","1071"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5464"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.63185750000001], PARAMETER["latitude_of_origin", 17.061241944444443], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 66220.02833082761], PARAMETER["false_northing", 135779.5099885299], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5466"]]
+5464=GEOGCS["Sibun Gorge 1922", DATUM["Sibun Gorge 1922", SPHEROID["Clarke 1858", 6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]], AUTHORITY["EPSG","1071"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5464"]]
+5463=PROJCS["SAD69 / UTM zone 17N", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5463"]]
+3289=PROJCS["WGS 84 / SCAR IMW SV21-30", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", -30.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 60 deg East"], AXIS["Northing", "North along 30 deg West"], AUTHORITY["EPSG","3289"]]
+5462=PROJCS["Ocotepeque 1935 / Nicaragua Sur", GEOGCS["Ocotepeque 1935", DATUM["Ocotepeque 1935", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[213.116, 9.358, -74.946, -2.3514187912168985, -0.06146691226163471, 6.394208993659988, -5.22], AUTHORITY["EPSG","1070"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5451"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -85.5], PARAMETER["latitude_of_origin", 11.733333333333334], PARAMETER["scale_factor", 0.99992228], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 288876.327], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5462"]]
+3288=PROJCS["WGS 84 / SCAR IMW SV11-20", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", -90.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 0 deg"], AXIS["Northing", "North along 90 deg West"], AUTHORITY["EPSG","3288"]]
+5461=PROJCS["Ocotepeque 1935 / Nicaragua Norte", GEOGCS["Ocotepeque 1935", DATUM["Ocotepeque 1935", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[213.116, 9.358, -74.946, -2.3514187912168985, -0.06146691226163471, 6.394208993659988, -5.22], AUTHORITY["EPSG","1070"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5451"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -85.5], PARAMETER["latitude_of_origin", 13.866666666666667], PARAMETER["scale_factor", 0.99990314], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 359891.816], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5461"]]
+3287=PROJCS["WGS 84 / SCAR IMW SV01-10", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", -150.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 60 deg West"], AXIS["Northing", "North along 150 deg West"], AUTHORITY["EPSG","3287"]]
+5460=PROJCS["Ocotepeque 1935 / El Salvador Lambert", GEOGCS["Ocotepeque 1935", DATUM["Ocotepeque 1935", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[213.116, 9.358, -74.946, -2.3514187912168985, -0.06146691226163471, 6.394208993659988, -5.22], AUTHORITY["EPSG","1070"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5451"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -89.0], PARAMETER["latitude_of_origin", 13.783333333333333], PARAMETER["scale_factor", 0.99996704], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 295809.184], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5460"]]
+3286=PROJCS["WGS 84 / SCAR IMW SU56-60", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 165.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 105 deg West"], AXIS["Northing", "North along 165 deg East"], AUTHORITY["EPSG","3286"]]
+3285=PROJCS["WGS 84 / SCAR IMW SU51-55", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 135.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 135 deg West"], AXIS["Northing", "North along 135 deg East"], AUTHORITY["EPSG","3285"]]
+61636413=GEOGCS["Yemen NGN96 (3D deg)", DATUM["Yemen National Geodetic Network 1996", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6163"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61636413"]]
+3284=PROJCS["WGS 84 / SCAR IMW SU46-50", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 105.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 165 deg West"], AXIS["Northing", "North along 105 deg East"], AUTHORITY["EPSG","3284"]]
+3283=PROJCS["WGS 84 / SCAR IMW SU41-45", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 75.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 165 deg East"], AXIS["Northing", "North along 75 deg East"], AUTHORITY["EPSG","3283"]]
+3282=PROJCS["WGS 84 / SCAR IMW SU36-40", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 45.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 135 deg East"], AXIS["Northing", "North along 45 deg East"], AUTHORITY["EPSG","3282"]]
+3281=PROJCS["WGS 84 / SCAR IMW SU31-35", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 15.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 105 deg East"], AXIS["Northing", "North along 15 deg East"], AUTHORITY["EPSG","3281"]]
+3280=PROJCS["WGS 84 / SCAR IMW SU26-30", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", -15.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 75 deg East"], AXIS["Northing", "North along 15 deg West"], AUTHORITY["EPSG","3280"]]
+32419=PROJCS["WGS 72BE / UTM zone 19N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32419"]]
+32418=PROJCS["WGS 72BE / UTM zone 18N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32418"]]
+32417=PROJCS["WGS 72BE / UTM zone 17N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32417"]]
+32416=PROJCS["WGS 72BE / UTM zone 16N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32416"]]
+32415=PROJCS["WGS 72BE / UTM zone 15N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32415"]]
+62586413=GEOGCS["ETRS89 (3D deg)", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","62586413"]]
+24819=PROJCS["PSAD56 / UTM zone 19N", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24819"]]
+32414=PROJCS["WGS 72BE / UTM zone 14N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32414"]]
+24818=PROJCS["PSAD56 / UTM zone 18N", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24818"]]
+32413=PROJCS["WGS 72BE / UTM zone 13N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32413"]]
+24817=PROJCS["PSAD56 / UTM zone 17N", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24817"]]
+32412=PROJCS["WGS 72BE / UTM zone 12N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32412"]]
+32411=PROJCS["WGS 72BE / UTM zone 11N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32411"]]
+32410=PROJCS["WGS 72BE / UTM zone 10N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32410"]]
+5459=PROJCS["Ocotepeque 1935 / Guatemala Sur", GEOGCS["Ocotepeque 1935", DATUM["Ocotepeque 1935", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[213.116, 9.358, -74.946, -2.3514187912168985, -0.06146691226163471, 6.394208993659988, -5.22], AUTHORITY["EPSG","1070"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5451"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -90.33333333333333], PARAMETER["latitude_of_origin", 14.9], PARAMETER["scale_factor", 0.99989906], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 325992.681], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5459"]]
+5458=PROJCS["Ocotepeque 1935 / Guatemala Norte", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -90.33333333333333], PARAMETER["latitude_of_origin", 16.816666666666666], PARAMETER["scale_factor", 0.99992226], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 292209.579], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5458"]]
+5457=PROJCS["Ocotepeque 1935 / Costa Rica Sur", GEOGCS["Ocotepeque 1935", DATUM["Ocotepeque 1935", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[213.116, 9.358, -74.946, -2.3514187912168985, -0.06146691226163471, 6.394208993659988, -5.22], AUTHORITY["EPSG","1070"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5451"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -83.66666666666667], PARAMETER["latitude_of_origin", 9.0], PARAMETER["scale_factor", 0.99995696], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 327987.436], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5457"]]
+5456=PROJCS["Ocotepeque 1935 / Costa Rica Norte", GEOGCS["Ocotepeque 1935", DATUM["Ocotepeque 1935", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[213.116, 9.358, -74.946, -2.3514187912168985, -0.06146691226163471, 6.394208993659988, -5.22], AUTHORITY["EPSG","1070"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5451"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -84.33333333333333], PARAMETER["latitude_of_origin", 10.466666666666667], PARAMETER["scale_factor", 0.99995696], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 271820.522], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5456"]]
+66356405=GEOGCS["ST87 Ouvea (deg)", DATUM["ST87 Ouvea", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-122.383, -188.696, 103.344, 3.5107, -4.9668, -5.7047, 4.4798], AUTHORITY["EPSG","6635"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66356405"]]
+3279=PROJCS["WGS 84 / SCAR IMW SU21-25", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", -45.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 45 deg East"], AXIS["Northing", "North along 45 deg West"], AUTHORITY["EPSG","3279"]]
+3278=PROJCS["WGS 84 / SCAR IMW SU16-20", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", -75.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 15 deg East"], AXIS["Northing", "North along 75 deg West"], AUTHORITY["EPSG","3278"]]
+5451=GEOGCS["Ocotepeque 1935", DATUM["Ocotepeque 1935", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[213.116, 9.358, -74.946, -2.3514187912168985, -0.06146691226163471, 6.394208993659988, -5.22], AUTHORITY["EPSG","1070"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5451"]]
+3277=PROJCS["WGS 84 / SCAR IMW SU11-15", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", -105.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 15 deg West"], AXIS["Northing", "North along 105 deg West"], AUTHORITY["EPSG","3277"]]
+61636405=GEOGCS["Yemen NGN96 (deg)", DATUM["Yemen National Geodetic Network 1996", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6163"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61636405"]]
+3276=PROJCS["WGS 84 / SCAR IMW SU06-10", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", -135.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 45 deg West"], AXIS["Northing", "North along 135 deg West"], AUTHORITY["EPSG","3276"]]
+3275=PROJCS["WGS 84 / SCAR IMW SU01-05", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", -165.0], PARAMETER["Standard_Parallel_1", -80.23861111111114], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 75 deg West"], AXIS["Northing", "North along 165 deg West"], AUTHORITY["EPSG","3275"]]
+3274=PROJCS["WGS 84 / SCAR IMW ST57-60", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 168.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3274"]]
+3273=PROJCS["WGS 84 / SCAR IMW ST53-56", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 144.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3273"]]
+3272=PROJCS["WGS 84 / SCAR IMW ST49-52", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 120.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3272"]]
+3271=PROJCS["WGS 84 / SCAR IMW ST45-48", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 96.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3271"]]
+3270=PROJCS["WGS 84 / SCAR IMW ST41-44", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 72.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3270"]]
+32409=PROJCS["WGS 72BE / UTM zone 9N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32409"]]
+32408=PROJCS["WGS 72BE / UTM zone 8N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32408"]]
+32407=PROJCS["WGS 72BE / UTM zone 7N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32407"]]
+62586405=GEOGCS["ETRS89 (deg)", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62586405"]]
+32406=PROJCS["WGS 72BE / UTM zone 6N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32406"]]
+32405=PROJCS["WGS 72BE / UTM zone 5N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32405"]]
+32404=PROJCS["WGS 72BE / UTM zone 4N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32404"]]
+32403=PROJCS["WGS 72BE / UTM zone 3N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32403"]]
+32402=PROJCS["WGS 72BE / UTM zone 2N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32402"]]
+32401=PROJCS["WGS 72BE / UTM zone 1N", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32401"]]
+3269=PROJCS["WGS 84 / SCAR IMW ST37-40", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 48.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3269"]]
+3268=PROJCS["WGS 84 / SCAR IMW ST33-36", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3268"]]
+3267=PROJCS["WGS 84 / SCAR IMW ST29-32", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3267"]]
+3266=PROJCS["WGS 84 / SCAR IMW ST25-28", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -24.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3266"]]
+3265=PROJCS["WGS 84 / SCAR IMW ST21-24", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -48.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3265"]]
+3264=PROJCS["WGS 84 / SCAR IMW ST17-20", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -72.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3264"]]
+3263=PROJCS["WGS 84 / SCAR IMW ST13-16", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -96.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3263"]]
+3262=PROJCS["WGS 84 / SCAR IMW ST09-12", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3262"]]
+3261=PROJCS["WGS 84 / SCAR IMW ST05-08", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -144.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3261"]]
+20440=PROJCS["Ain el Abd / UTM zone 40N", GEOGCS["Ain el Abd", DATUM["Ain el Abd 1970", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-85.645, -273.077, -79.708, 2.289, 1.421, -2.532, 3.194], AUTHORITY["EPSG","6204"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4204"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20440"]]
+3260=PROJCS["WGS 84 / SCAR IMW ST01-04", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -168.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3260"]]
+20439=PROJCS["Ain el Abd / UTM zone 39N", GEOGCS["Ain el Abd", DATUM["Ain el Abd 1970", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-85.645, -273.077, -79.708, 2.289, 1.421, -2.532, 3.194], AUTHORITY["EPSG","6204"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4204"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20439"]]
+3259=PROJCS["WGS 84 / SCAR IMW SS58-60", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3259"]]
+20438=PROJCS["Ain el Abd / UTM zone 38N", GEOGCS["Ain el Abd", DATUM["Ain el Abd 1970", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-85.645, -273.077, -79.708, 2.289, 1.421, -2.532, 3.194], AUTHORITY["EPSG","6204"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4204"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20438"]]
+3258=PROJCS["WGS 84 / SCAR IMW SS55-57", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3258"]]
+20437=PROJCS["Ain el Abd / UTM zone 37N", GEOGCS["Ain el Abd", DATUM["Ain el Abd 1970", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-85.645, -273.077, -79.708, 2.289, 1.421, -2.532, 3.194], AUTHORITY["EPSG","6204"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4204"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20437"]]
+3257=PROJCS["WGS 84 / SCAR IMW SS52-54", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3257"]]
+20436=PROJCS["Ain el Abd / UTM zone 36N", GEOGCS["Ain el Abd", DATUM["Ain el Abd 1970", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-85.645, -273.077, -79.708, 2.289, 1.421, -2.532, 3.194], AUTHORITY["EPSG","6204"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4204"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20436"]]
+3256=PROJCS["WGS 84 / SCAR IMW SS49-51", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3256"]]
+3255=PROJCS["WGS 84 / SCAR IMW SS46-48", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3255"]]
+3254=PROJCS["WGS 84 / SCAR IMW SS43-45", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3254"]]
+3253=PROJCS["WGS 84 / SCAR IMW SS40-42", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3253"]]
+3252=PROJCS["WGS 84 / SCAR IMW SS37-39", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3252"]]
+3251=PROJCS["WGS 84 / SCAR IMW SS34-36", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3251"]]
+3250=PROJCS["WGS 84 / SCAR IMW SS31-33", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3250"]]
+63126405=GEOGCS["MGI (deg)", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63126405"]]
+30200=PROJCS["Trinidad 1903 / Trinidad Grid", GEOGCS["Trinidad 1903", DATUM["Trinidad 1903", SPHEROID["Clarke 1858", 6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]], TOWGS84[-61.702, 284.488, 472.052, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6302"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4302"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", -61.33333333333333], PARAMETER["latitude_of_origin", 10.441666666666666], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 430000.0], PARAMETER["false_northing", 325000.0], UNIT["m*0.201166195164", 0.201166195164], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30200"]]
+3249=PROJCS["WGS 84 / SCAR IMW SS28-30", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3249"]]
+3248=PROJCS["WGS 84 / SCAR IMW SS25-27", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3248"]]
+3247=PROJCS["WGS 84 / SCAR IMW SS19-21", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3247"]]
+3246=PROJCS["WGS 84 / SCAR IMW SS16-18", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3246"]]
+3245=PROJCS["WGS 84 / SCAR IMW SS13-15", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3245"]]
+3244=PROJCS["WGS 84 / SCAR IMW SS10-12", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3244"]]
+3243=PROJCS["WGS 84 / SCAR IMW SS07-09", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3243"]]
+3242=PROJCS["WGS 84 / SCAR IMW SS04-06", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -72.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -75.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3242"]]
+3241=PROJCS["WGS 84 / SCAR IMW SR59-60", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 174.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3241"]]
+3240=PROJCS["WGS 84 / SCAR IMW SR57-58", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 162.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3240"]]
+3239=PROJCS["WGS 84 / SCAR IMW SR55-56", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 150.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3239"]]
+3238=PROJCS["WGS 84 / SCAR IMW SR53-54", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 138.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3238"]]
+3237=PROJCS["WGS 84 / SCAR IMW SR51-52", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3237"]]
+3236=PROJCS["WGS 84 / SCAR IMW SR49-50", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3236"]]
+3235=PROJCS["WGS 84 / SCAR IMW SR47-48", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3235"]]
+3234=PROJCS["WGS 84 / SCAR IMW SR45-46", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3234"]]
+3233=PROJCS["WGS 84 / SCAR IMW SR43-44", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3233"]]
+3232=PROJCS["WGS 84 / SCAR IMW SR41-42", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 66.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3232"]]
+3231=PROJCS["WGS 84 / SCAR IMW SR39-40", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 54.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3231"]]
+3230=PROJCS["WGS 84 / SCAR IMW SR37-38", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 42.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3230"]]
+62426405=GEOGCS["JAD69 (deg)", DATUM["Jamaica 1969", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-33.722, 153.789, 94.959, -8.581, 4.478, -4.54, 8.95], AUTHORITY["EPSG","6242"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62426405"]]
+31999=PROJCS["SIRGAS 1995 / UTM zone 24S", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31999"]]
+31998=PROJCS["SIRGAS 1995 / UTM zone 23S", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31998"]]
+31997=PROJCS["SIRGAS 1995 / UTM zone 22S", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31997"]]
+31996=PROJCS["SIRGAS 1995 / UTM zone 21S", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31996"]]
+31995=PROJCS["SIRGAS 1995 / UTM zone 20S", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31995"]]
+31994=PROJCS["SIRGAS 1995 / UTM zone 19S", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31994"]]
+31993=PROJCS["SIRGAS 1995 / UTM zone 18S", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31993"]]
+31992=PROJCS["SIRGAS 1995 / UTM zone 17S", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31992"]]
+31991=PROJCS["SIRGAS 1995 / UTM zone 22N", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31991"]]
+31990=PROJCS["SIRGAS 1995 / UTM zone 21N", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31990"]]
+3229=PROJCS["WGS 84 / SCAR IMW SR35-36", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3229"]]
+3228=PROJCS["WGS 84 / SCAR IMW SR33-34", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3228"]]
+3227=PROJCS["WGS 84 / SCAR IMW SR31-32", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 6.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3227"]]
+3226=PROJCS["WGS 84 / SCAR IMW SR29-30", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -6.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3226"]]
+3225=PROJCS["WGS 84 / SCAR IMW SR27-28", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -18.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3225"]]
+3224=PROJCS["WGS 84 / SCAR IMW SR19-20", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -66.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3224"]]
+3223=PROJCS["WGS 84 / SCAR IMW SR17-18", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3223"]]
+3222=PROJCS["WGS 84 / SCAR IMW SR15-16", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3222"]]
+3221=PROJCS["WGS 84 / SCAR IMW SR13-14", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -102.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -68.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -71.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3221"]]
+3220=PROJCS["WGS 84 / SCAR IMW SQ57-58", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 162.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3220"]]
+31989=PROJCS["SIRGAS 1995 / UTM zone 20N", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31989"]]
+31988=PROJCS["SIRGAS 1995 / UTM zone 19N", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31988"]]
+31987=PROJCS["SIRGAS 1995 / UTM zone 18N", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31987"]]
+31986=PROJCS["SIRGAS 1995 / UTM zone 17N", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31986"]]
+31985=PROJCS["SIRGAS 2000 / UTM zone 25S", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31985"]]
+31984=PROJCS["SIRGAS 2000 / UTM zone 24S", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31984"]]
+31983=PROJCS["SIRGAS 2000 / UTM zone 23S", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31983"]]
+31982=PROJCS["SIRGAS 2000 / UTM zone 22S", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31982"]]
+31981=PROJCS["SIRGAS 2000 / UTM zone 21S", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31981"]]
+31980=PROJCS["SIRGAS 2000 / UTM zone 20S", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31980"]]
+3219=PROJCS["WGS 84 / SCAR IMW SQ55-56", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 150.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3219"]]
+3218=PROJCS["WGS 84 / SCAR IMW SQ53-54", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 138.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3218"]]
+3217=PROJCS["WGS 84 / SCAR IMW SQ51-52", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3217"]]
+3216=PROJCS["WGS 84 / SCAR IMW SQ49-50", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3216"]]
+3215=PROJCS["WGS 84 / SCAR IMW SQ47-48", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3215"]]
+3214=PROJCS["WGS 84 / SCAR IMW SQ45-46", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3214"]]
+3213=PROJCS["WGS 84 / SCAR IMW SQ43-44", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3213"]]
+3212=PROJCS["WGS 84 / SCAR IMW SQ41-42", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 66.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3212"]]
+3211=PROJCS["WGS 84 / SCAR IMW SQ39-40", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 54.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3211"]]
+3210=PROJCS["WGS 84 / SCAR IMW SQ37-38", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 42.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3210"]]
+31979=PROJCS["SIRGAS 2000 / UTM zone 19S", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31979"]]
+31978=PROJCS["SIRGAS 2000 / UTM zone 18S", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31978"]]
+31977=PROJCS["SIRGAS 2000 / UTM zone 17S", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31977"]]
+31976=PROJCS["SIRGAS 2000 / UTM zone 22N", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31976"]]
+31975=PROJCS["SIRGAS 2000 / UTM zone 21N", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31975"]]
+31974=PROJCS["SIRGAS 2000 / UTM zone 20N", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31974"]]
+31973=PROJCS["SIRGAS 2000 / UTM zone 19N", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31973"]]
+31972=PROJCS["SIRGAS 2000 / UTM zone 18N", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31972"]]
+31971=PROJCS["SIRGAS 2000 / UTM zone 17N", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31971"]]
+31970=PROJCS["SIRGAS 2000 / UTM zone 16N", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31970"]]
+3209=PROJCS["WGS 84 / SCAR IMW SQ21-22", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -54.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3209"]]
+3208=PROJCS["WGS 84 / SCAR IMW SQ19-20", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -66.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3208"]]
+3207=PROJCS["WGS 84 / SCAR IMW SQ01-02", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -174.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -64.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -67.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3207"]]
+3206=PROJCS["WGS 84 / SCAR IMW SP23-24", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -42.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -60.666666666666664], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -63.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3206"]]
+3205=PROJCS["WGS 84 / SCAR IMW SP21-22", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -54.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -60.666666666666664], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -63.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3205"]]
+3204=PROJCS["WGS 84 / SCAR IMW SP19-20", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -66.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -60.666666666666664], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -63.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3204"]]
+3203=PROJCS["LGD2006 / UTM zone 35N", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3203"]]
+62096405=GEOGCS["Arc 1950 (deg)", DATUM["Arc 1950", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-138.0, -105.0, -289.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6209"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62096405"]]
+27493=PROJCS["Datum 73 / Modified Portuguese Grid", GEOGCS["Datum 73", DATUM["Datum 73", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-239.749, 88.181, 30.488, 0.263, -0.082, -1.211, 2.229], AUTHORITY["EPSG","6274"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4274"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -8.131906111111114], PARAMETER["latitude_of_origin", 39.666666666666664], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 180.598], PARAMETER["false_northing", -86.99], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27493"]]
+3202=PROJCS["LGD2006 / UTM zone 34N", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3202"]]
+27492=PROJCS["Datum 73 / Modified Portuguese Grid", GEOGCS["Datum 73", DATUM["Datum 73", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-239.749, 88.181, 30.488, 0.263, -0.082, -1.211, 2.229], AUTHORITY["EPSG","6274"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4274"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -8.131906111111114], PARAMETER["latitude_of_origin", 39.666666666666664], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 180.598], PARAMETER["false_northing", -86.99], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27492"]]
+3201=PROJCS["LGD2006 / UTM zone 33N", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3201"]]
+3200=PROJCS["FD58 / Iraq zone", GEOGCS["FD58", DATUM["Final Datum 1958", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-239.1, -170.02, 397.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6132"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4132"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 32.5], PARAMETER["scale_factor", 0.9987864078], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 1166200.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3200"]]
+31969=PROJCS["SIRGAS 2000 / UTM zone 15N", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31969"]]
+31968=PROJCS["SIRGAS 2000 / UTM zone 14N", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31968"]]
+31967=PROJCS["SIRGAS 2000 / UTM zone 13N", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31967"]]
+31966=PROJCS["SIRGAS 2000 / UTM zone 12N", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31966"]]
+31965=PROJCS["SIRGAS 2000 / UTM zone 11N", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31965"]]
+62976405=GEOGCS["Tananarive (deg)", DATUM["Tananarive 1925", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-189.0, -242.0, -91.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6297"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62976405"]]
+4999=GEOGCS["RGPF", DATUM["Reseau Geodesique de la Polynesie Francaise", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.072, -0.507, -0.245, -0.0183, -0.0003, 0.007, -0.0093], AUTHORITY["EPSG","6687"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4999"]]
+4998=GEOCCS["RGPF", DATUM["Reseau Geodesique de la Polynesie Francaise", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.072, -0.507, -0.245, -0.0183, -0.0003, 0.007, -0.0093], AUTHORITY["EPSG","6687"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4998"]]
+4997=GEOGCS["MAGNA-SIRGAS", DATUM["Marco Geocentrico Nacional de Referencia", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6686"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4997"]]
+4996=GEOCCS["MAGNA-SIRGAS", DATUM["Marco Geocentrico Nacional de Referencia", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6686"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4996"]]
+4995=GEOGCS["PRS92", DATUM["Philippine Reference System 1992", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-127.62, -67.24, -47.04, -3.068, -4.903, -1.578, -1.06], AUTHORITY["EPSG","6683"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4995"]]
+4994=GEOCCS["PRS92", DATUM["Philippine Reference System 1992", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-127.62, -67.24, -47.04, -3.068, -4.903, -1.578, -1.06], AUTHORITY["EPSG","6683"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4994"]]
+4993=GEOGCS["Lao 1997", DATUM["Lao National Datum 1997", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[44.585, -131.212, -39.544, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6678"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4993"]]
+4992=GEOCCS["Lao 1997", DATUM["Lao National Datum 1997", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[44.585, -131.212, -39.544, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6678"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4992"]]
+4991=GEOGCS["Lao 1993", DATUM["Lao 1993", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","6677"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4991"]]
+4990=GEOCCS["Lao 1993", DATUM["Lao 1993", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","6677"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4990"]]
+4989=GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4989"]]
+4988=GEOCCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4988"]]
+61696405=GEOGCS["American Samoa 1962 (deg)", DATUM["American Samoa 1962", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-115.0, 118.0, 426.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6169"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61696405"]]
+4987=GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4987"]]
+4986=GEOCCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4986"]]
+4985=GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4985"]]
+4984=GEOCCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4984"]]
+4983=GEOGCS["IGM95", DATUM["Istituto Geografico Militaire 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6670"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4983"]]
+4982=GEOCCS["IGM95", DATUM["Istituto Geografico Militaire 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6670"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4982"]]
+4981=GEOGCS["Yemen NGN96", DATUM["Yemen National Geodetic Network 1996", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6163"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4981"]]
+4980=GEOCCS["Yemen NGN96", DATUM["Yemen National Geodetic Network 1996", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6163"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4980"]]
+4979=GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4979"]]
+4978=GEOCCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4978"]]
+4977=GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4977"]]
+4976=GEOCCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4976"]]
+4975=GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4975"]]
+4974=GEOCCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4974"]]
+4973=GEOGCS["RRAF 1991", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6640"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4973"]]
+2799=PROJCS["NAD83(HARN) / Kentucky South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.93333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.733333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2799"]]
+4972=GEOCCS["RRAF 1991", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6640"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4972"]]
+2798=PROJCS["NAD83(HARN) / Kentucky North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.25], PARAMETER["latitude_of_origin", 37.5], PARAMETER["standard_parallel_1", 38.96666666666667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.96666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2798"]]
+4971=GEOGCS["RGR92", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4971"]]
+2797=PROJCS["NAD83(HARN) / Kansas South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.56666666666667], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 400000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.266666666666666], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2797"]]
+4970=GEOCCS["RGR92", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4970"]]
+2796=PROJCS["NAD83(HARN) / Kansas North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 39.78333333333333], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2796"]]
+2795=PROJCS["NAD83(HARN) / Iowa South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 40.0], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.61666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2795"]]
+2794=PROJCS["NAD83(HARN) / Iowa North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.266666666666666], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.06666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2794"]]
+2793=PROJCS["NAD83(HARN) / Indiana West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.08333333333333], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 900000.0], PARAMETER["false_northing", 250000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2793"]]
+2792=PROJCS["NAD83(HARN) / Indiana East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.66666666666667], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 250000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2792"]]
+2791=PROJCS["NAD83(HARN) / Illinois West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.16666666666667], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2791"]]
+2790=PROJCS["NAD83(HARN) / Illinois East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.33333333333333], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999975], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2790"]]
+23095=PROJCS["ED50 / TM 5 NE", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 5.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23095"]]
+23090=PROJCS["ED50 / TM 0 N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23090"]]
+4969=GEOGCS["RGNC 1991", DATUM["Reseau Geodesique Nouvelle Caledonie 1991", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6645"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4969"]]
+4968=GEOCCS["RGNC 1991", DATUM["Reseau Geodesique Nouvelle Caledonie 1991", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6645"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4968"]]
+4967=GEOGCS["RGFG95", DATUM["Reseau Geodesique Francais Guyane 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6624"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4967"]]
+62816405=GEOGCS["Palestine 1923 (deg)", DATUM["Palestine 1923", SPHEROID["Clarke 1880 (Benoit)", 6378300.789, 293.4663155389811, AUTHORITY["EPSG","7010"]], TOWGS84[-275.7224, 94.7824, 340.8944, -8.001, -4.42, -11.821, 1.0], AUTHORITY["EPSG","6281"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62816405"]]
+4966=GEOCCS["RGFG95", DATUM["Reseau Geodesique Francais Guyane 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6624"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4966"]]
+4965=GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4965"]]
+4964=GEOCCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4964"]]
+4963=GEOGCS["REGVEN", DATUM["Red Geodesica Venezolana", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6189"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4963"]]
+2789=PROJCS["NAD83(HARN) / Idaho West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.75], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2789"]]
+4962=GEOCCS["REGVEN", DATUM["Red Geodesica Venezolana", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6189"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4962"]]
+2788=PROJCS["NAD83(HARN) / Idaho Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -114.0], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2788"]]
+4961=GEOGCS["POSGAR 98", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4961"]]
+2787=PROJCS["NAD83(HARN) / Idaho East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -112.16666666666667], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2787"]]
+4960=GEOCCS["POSGAR 98", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4960"]]
+2786=PROJCS["NAD83(HARN) / Hawaii zone 5", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -160.16666666666666], PARAMETER["latitude_of_origin", 21.666666666666668], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2786"]]
+2785=PROJCS["NAD83(HARN) / Hawaii zone 4", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.5], PARAMETER["latitude_of_origin", 21.833333333333332], PARAMETER["scale_factor", 0.99999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2785"]]
+2784=PROJCS["NAD83(HARN) / Hawaii zone 3", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -158.0], PARAMETER["latitude_of_origin", 21.166666666666668], PARAMETER["scale_factor", 0.99999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2784"]]
+2783=PROJCS["NAD83(HARN) / Hawaii zone 2", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -156.66666666666666], PARAMETER["latitude_of_origin", 20.333333333333332], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2783"]]
+2782=PROJCS["NAD83(HARN) / Hawaii zone 1", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -155.5], PARAMETER["latitude_of_origin", 18.833333333333332], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2782"]]
+2781=PROJCS["NAD83(HARN) / Georgia West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -84.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2781"]]
+2780=PROJCS["NAD83(HARN) / Georgia East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2780"]]
+63186405=GEOGCS["NGN (deg)", DATUM["National Geodetic Network", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[-3.2, -5.7, 2.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6318"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63186405"]]
+4959=GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4959"]]
+4958=GEOCCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4958"]]
+4957=GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4957"]]
+4956=GEOCCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4956"]]
+4955=GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4955"]]
+4954=GEOCCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4954"]]
+4953=GEOGCS["Moznet", DATUM["Moznet (ITRF94)", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6130"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4953"]]
+2779=PROJCS["NAD83(HARN) / Florida North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.5], PARAMETER["latitude_of_origin", 29.0], PARAMETER["standard_parallel_1", 30.75], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.583333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2779"]]
+4952=GEOCCS["Moznet", DATUM["Moznet (ITRF94)", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6130"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4952"]]
+2778=PROJCS["NAD83(HARN) / Florida West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2778"]]
+4951=GEOGCS["LKS94", DATUM["Lithuania 1994 (ETRS89)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6126"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4951"]]
+2777=PROJCS["NAD83(HARN) / Florida East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2777"]]
+4950=GEOCCS["LKS94", DATUM["Lithuania 1994 (ETRS89)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6126"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4950"]]
+2776=PROJCS["NAD83(HARN) / Delaware", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.41666666666667], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 0.999995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2776"]]
+2775=PROJCS["NAD83(HARN) / Connecticut", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -72.75], PARAMETER["latitude_of_origin", 40.833333333333336], PARAMETER["standard_parallel_1", 41.86666666666669], PARAMETER["false_easting", 304800.6096], PARAMETER["false_northing", 152400.3048], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.2], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2775"]]
+2774=PROJCS["NAD83(HARN) / Colorado South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 914401.8289], PARAMETER["false_northing", 304800.6096], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.233333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2774"]]
+2773=PROJCS["NAD83(HARN) / Colorado Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 37.833333333333336], PARAMETER["standard_parallel_1", 39.75], PARAMETER["false_easting", 914401.8289], PARAMETER["false_northing", 304800.6096], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.45], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2773"]]
+2772=PROJCS["NAD83(HARN) / Colorado North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.78333333333333], PARAMETER["false_easting", 914401.8289], PARAMETER["false_northing", 304800.6096], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2772"]]
+2771=PROJCS["NAD83(HARN) / California zone 6", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -116.25], PARAMETER["latitude_of_origin", 32.166666666666664], PARAMETER["standard_parallel_1", 33.88333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.78333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2771"]]
+2770=PROJCS["NAD83(HARN) / California zone 5", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -118.0], PARAMETER["latitude_of_origin", 33.5], PARAMETER["standard_parallel_1", 35.46666666666667], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.03333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2770"]]
+31901=PROJCS["KUDAMS / KTM", GEOGCS["KUDAMS", DATUM["Kuwait Utility", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[226.702, -193.337, -35.371, -2.229, 4.391, -9.238, 0.9798], AUTHORITY["EPSG","6319"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4319"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 48.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31901"]]
+31900=PROJCS["KUDAMS / KTM", GEOGCS["KUDAMS", DATUM["Kuwait Utility", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[226.702, -193.337, -35.371, -2.229, 4.391, -9.238, 0.9798], AUTHORITY["EPSG","6319"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4319"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 48.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31900"]]
+27429=PROJCS["Datum 73 / UTM zone 29N", GEOGCS["Datum 73", DATUM["Datum 73", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-239.749, 88.181, 30.488, 0.263, -0.082, -1.211, 2.229], AUTHORITY["EPSG","6274"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4274"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27429"]]
+4949=GEOGCS["LKS92", DATUM["Latvia 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6661"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4949"]]
+4948=GEOCCS["LKS92", DATUM["Latvia 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6661"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4948"]]
+4947=GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4947"]]
+66256405=GEOGCS["Fort Desaix (deg)", DATUM["Martinique 1938", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[126.93, 547.94, 130.41, -2.7867, 5.1612, -0.8584, 13.8227], AUTHORITY["EPSG","6625"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66256405"]]
+4946=GEOCCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4946"]]
+4945=GEOGCS["ISN93", DATUM["Islands Net 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6659"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4945"]]
+4944=GEOCCS["ISN93", DATUM["Islands Net 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6659"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4944"]]
+4943=GEOGCS["IRENET95", DATUM["IRENET95", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6173"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4943"]]
+61536405=GEOGCS["Rassadiran (deg)", DATUM["Rassadiran", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-133.63, -157.5, -158.62, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6153"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61536405"]]
+2769=PROJCS["NAD83(HARN) / California zone 4", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -119.0], PARAMETER["latitude_of_origin", 35.333333333333336], PARAMETER["standard_parallel_1", 37.25], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2769"]]
+4942=GEOCCS["IRENET95", DATUM["IRENET95", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6173"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4942"]]
+2768=PROJCS["NAD83(HARN) / California zone 3", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 36.5], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.06666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2768"]]
+4941=GEOGCS["Hartebeesthoek94", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4941"]]
+2767=PROJCS["NAD83(HARN) / California zone 2", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.833333333333336], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.333333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2767"]]
+4940=GEOCCS["Hartebeesthoek94", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4940"]]
+2766=PROJCS["NAD83(HARN) / California zone 1", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 41.666666666666664], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2766"]]
+2765=PROJCS["NAD83(HARN) / Arkansas South", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 32.666666666666664], PARAMETER["standard_parallel_1", 34.766666666666666], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 400000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.3], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2765"]]
+2764=PROJCS["NAD83(HARN) / Arkansas North", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 34.333333333333336], PARAMETER["standard_parallel_1", 36.233333333333334], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.93333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2764"]]
+2763=PROJCS["NAD83(HARN) / Arizona West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -113.75], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 213360.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2763"]]
+2762=PROJCS["NAD83(HARN) / Arizona Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.91666666666666], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 213360.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2762"]]
+2761=PROJCS["NAD83(HARN) / Arizona East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.16666666666667], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 213360.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2761"]]
+2760=PROJCS["NAD83(HARN) / Alabama West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.5], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2760"]]
+62486405=GEOGCS["PSAD56 (deg)", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62486405"]]
+4939=GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4939"]]
+4938=GEOCCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4938"]]
+4937=GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4937"]]
+4936=GEOCCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4936"]]
+4935=GEOGCS["EST97", DATUM["Estonia 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6180"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4935"]]
+4934=GEOCCS["EST97", DATUM["Estonia 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6180"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4934"]]
+4933=GEOGCS["CHTRF95", DATUM["Swiss Terrestrial Reference Frame 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6151"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4933"]]
+2759=PROJCS["NAD83(HARN) / Alabama East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.83333333333333], PARAMETER["latitude_of_origin", 30.5], PARAMETER["scale_factor", 0.99996], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2759"]]
+4932=GEOCCS["CHTRF95", DATUM["Swiss Terrestrial Reference Frame 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6151"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4932"]]
+2758=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 168W", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -168.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2758"]]
+4931=GEOGCS["Australian Antarctic", DATUM["Australian Antarctic Datum 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6176"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4931"]]
+2757=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 171W", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2757"]]
+4930=GEOCCS["Australian Antarctic", DATUM["Australian Antarctic Datum 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6176"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4930"]]
+2756=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 174W", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -174.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2756"]]
+2755=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 177W", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2755"]]
+2754=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 180E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 180.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2754"]]
+2753=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 177E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2753"]]
+2752=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 174E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 174.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2752"]]
+25231=PROJCS["Lome / UTM zone 31N", GEOGCS["Lome", DATUM["Lome", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6252"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25231"]]
+2751=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 171E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2751"]]
+2750=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 168E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 168.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2750"]]
+4929=GEOGCS["POSGAR 94", DATUM["Posiciones Geodesicas Argentinas 1994", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6694"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4929"]]
+4928=GEOCCS["POSGAR 94", DATUM["Posiciones Geodesicas Argentinas 1994", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6694"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4928"]]
+4927=GEOGCS["Korea 2000", DATUM["Geocentric datum of Korea", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6737"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4927"]]
+4926=GEOCCS["Korea 2000", DATUM["Geocentric datum of Korea", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6737"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4926"]]
+4925=GEOGCS["Mauritania 1999", DATUM["Mauritania 1999", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6702"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4925"]]
+4924=GEOCCS["Mauritania 1999", DATUM["Mauritania 1999", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6702"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4924"]]
+4923=GEOGCS["PZ-90", DATUM["Parametrop Zemp 1990", SPHEROID["PZ-90", 6378136.0, 298.257839303, AUTHORITY["EPSG","7054"]], TOWGS84[-1.08, -0.27, -0.9, -0.0, 0.0, -0.16, -0.12], AUTHORITY["EPSG","6740"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4923"]]
+2749=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 165E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2749"]]
+4922=GEOCCS["PZ-90", DATUM["Parametrop Zemp 1990", SPHEROID["PZ-90", 6378136.0, 298.257839303, AUTHORITY["EPSG","7054"]], TOWGS84[-1.08, -0.27, -0.9, -0.0, 0.0, -0.16, -0.12], AUTHORITY["EPSG","6740"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4922"]]
+2748=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 162E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 162.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2748"]]
+4921=GEOGCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4921"]]
+2747=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 159E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2747"]]
+4920=GEOCCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4920"]]
+2746=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 156E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 156.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2746"]]
+2745=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 153E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2745"]]
+2744=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 150E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 150.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2744"]]
+2743=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 147E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2743"]]
+2742=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 144E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 144.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2742"]]
+2741=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 141E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2741"]]
+2740=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 138E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 138.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2740"]]
+63026405=GEOGCS["Trinidad 1903 (deg)", DATUM["Trinidad 1903", SPHEROID["Clarke 1858", 6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]], TOWGS84[-61.702, 284.488, 472.052, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6302"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63026405"]]
+4919=GEOCCS["ITRF2000", DATUM["International Terrestrial Reference Frame 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6656"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4919"]]
+4918=GEOCCS["ITRF97", DATUM["International Terrestrial Reference Frame 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6655"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4918"]]
+4917=GEOCCS["ITRF96", DATUM["International Terrestrial Reference Frame 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6654"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4917"]]
+4916=GEOCCS["ITRF94", DATUM["International Terrestrial Reference Frame 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6653"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4916"]]
+4915=GEOCCS["ITRF93", DATUM["International Terrestrial Reference Frame 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6652"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4915"]]
+4914=GEOCCS["ITRF92", DATUM["International Terrestrial Reference Frame 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6651"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4914"]]
+4913=GEOCCS["ITRF91", DATUM["International Terrestrial Reference Frame 1991", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6650"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4913"]]
+2739=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 135E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2739"]]
+4912=GEOCCS["ITRF90", DATUM["International Terrestrial Reference Frame 1990", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6649"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4912"]]
+2738=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 132E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2738"]]
+4911=GEOCCS["ITRF89", DATUM["International Terrestrial Reference Frame 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6648"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4911"]]
+2737=PROJCS["Tete / UTM zone 37S", GEOGCS["Tete", DATUM["Tete", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-82.875, -57.097, -156.768, -2.158, -1.524, 0.982, -0.359], AUTHORITY["EPSG","6127"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4127"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2737"]]
+4910=GEOCCS["ITRF88", DATUM["International Terrestrial Reference Frame 1988", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6647"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4910"]]
+2736=PROJCS["Tete / UTM zone 36S", GEOGCS["Tete", DATUM["Tete", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-82.875, -57.097, -156.768, -2.158, -1.524, 0.982, -0.359], AUTHORITY["EPSG","6127"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4127"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2736"]]
+2735=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 129E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2735"]]
+2734=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 126E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2734"]]
+2733=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 123E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2733"]]
+2732=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 120E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2732"]]
+23038=PROJCS["ED50 / UTM zone 38N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23038"]]
+2731=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 117E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2731"]]
+23037=PROJCS["ED50 / UTM zone 37N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23037"]]
+2730=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 114E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2730"]]
+23036=PROJCS["ED50 / UTM zone 36N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23036"]]
+23035=PROJCS["ED50 / UTM zone 35N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23035"]]
+23034=PROJCS["ED50 / UTM zone 34N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23034"]]
+23033=PROJCS["ED50 / UTM zone 33N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23033"]]
+23032=PROJCS["ED50 / UTM zone 32N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23032"]]
+23031=PROJCS["ED50 / UTM zone 31N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23031"]]
+23030=PROJCS["ED50 / UTM zone 30N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23030"]]
+4909=GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4909"]]
+4908=GEOCCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4908"]]
+4907=GEOGCS["RGNC91-93", DATUM["Reseau Geodesique de Nouvelle Caledonie 91-93", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6749"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4907"]]
+4906=GEOCCS["RGNC91-93", DATUM["Reseau Geodesique de Nouvelle Caledonie 91-93", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6749"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4906"]]
+4904=GEOGCS["Lisbon 1890 (Lisbon)", DATUM["Lisbon 1890 (Lisbon)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6904"]], PRIMEM["Lisbon", -9.131906111111114, AUTHORITY["EPSG","8902"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4904"]]
+4903=GEOGCS["Madrid 1870 (Madrid)", DATUM["Madrid 1870 (Madrid)", SPHEROID["Struve 1860", 6378298.3, 294.73, AUTHORITY["EPSG","7028"]], AUTHORITY["EPSG","6903"]], PRIMEM["Madrid", -3.68793888888889, AUTHORITY["EPSG","8905"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4903"]]
+2729=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 111E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2729"]]
+4902=GEOGCS["NDG (Paris)", DATUM["Nord de Guerre (Paris)", SPHEROID["Plessis 1817", 6376523.0, 308.64, AUTHORITY["EPSG","7027"]], AUTHORITY["EPSG","6902"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4902"]]
+2728=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 108E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 108.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2728"]]
+4901=GEOGCS["ATF (Paris)", DATUM["Ancienne Triangulation Francaise (Paris)", SPHEROID["Plessis 1817", 6376523.0, 308.64, AUTHORITY["EPSG","7027"]], AUTHORITY["EPSG","6901"]], PRIMEM["Paris RGS", 2.5968981481481483, AUTHORITY["EPSG","8914"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4901"]]
+2727=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 105E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2727"]]
+4900=GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4900"]]
+2726=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 102E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2726"]]
+2725=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 99E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2725"]]
+2724=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 96E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2724"]]
+2723=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 93E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2723"]]
+23029=PROJCS["ED50 / UTM zone 29N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23029"]]
+2722=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 90E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2722"]]
+23028=PROJCS["ED50 / UTM zone 28N", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23028"]]
+2721=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 87E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2721"]]
+2720=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 84E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2720"]]
+62326405=GEOGCS["Fahud (deg)", DATUM["Fahud", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-346.0, -1.0, 224.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6232"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62326405"]]
+2719=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 81E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2719"]]
+2718=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 78E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2718"]]
+2717=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 75E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2717"]]
+2716=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 72E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 72.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2716"]]
+2715=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 69E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2715"]]
+2714=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 66E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 66.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2714"]]
+2713=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 63E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2713"]]
+2712=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 60E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 60.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2712"]]
+2711=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 57E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2711"]]
+2710=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 54E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 54.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2710"]]
+2709=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 51E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2709"]]
+2708=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 48E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 48.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2708"]]
+2707=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 45E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2707"]]
+26998=PROJCS["NAD83 / Missouri West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -94.5], PARAMETER["latitude_of_origin", 36.166666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 850000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26998"]]
+2706=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 42E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 42.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2706"]]
+26997=PROJCS["NAD83 / Missouri Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -92.5], PARAMETER["latitude_of_origin", 35.833333333333336], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26997"]]
+2705=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 39E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2705"]]
+26996=PROJCS["NAD83 / Missouri East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.5], PARAMETER["latitude_of_origin", 35.833333333333336], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26996"]]
+2704=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 36E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 36.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2704"]]
+26995=PROJCS["NAD83 / Mississippi West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.33333333333333], PARAMETER["latitude_of_origin", 29.5], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26995"]]
+2703=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 33E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2703"]]
+26994=PROJCS["NAD83 / Mississippi East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.83333333333333], PARAMETER["latitude_of_origin", 29.5], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26994"]]
+2702=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 30E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2702"]]
+26993=PROJCS["NAD83 / Minnesota South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.0], PARAMETER["latitude_of_origin", 43.0], PARAMETER["standard_parallel_1", 45.21666666666667], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 100000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.78333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26993"]]
+2701=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 27E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2701"]]
+26992=PROJCS["NAD83 / Minnesota Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.25], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 47.05], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 100000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.61666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26992"]]
+2700=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 24E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2700"]]
+26991=PROJCS["NAD83 / Minnesota North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.1], PARAMETER["latitude_of_origin", 46.5], PARAMETER["standard_parallel_1", 48.63333333333333], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 100000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.03333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26991"]]
+26990=PROJCS["NAD83 / Michigan South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.36666666666666], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.666666666666664], PARAMETER["false_easting", 4000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.1], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26990"]]
+26989=PROJCS["NAD83 / Michigan Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.36666666666666], PARAMETER["latitude_of_origin", 43.31666666666666], PARAMETER["standard_parallel_1", 45.699999999999996], PARAMETER["false_easting", 6000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.18333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26989"]]
+26988=PROJCS["NAD83 / Michigan North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 44.78333333333333], PARAMETER["standard_parallel_1", 47.083333333333336], PARAMETER["false_easting", 8000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.48333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26988"]]
+26987=PROJCS["NAD83 / Massachusetts Island", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -70.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 41.483333333333334], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.28333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26987"]]
+26986=PROJCS["NAD83 / Massachusetts Mainland", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 750000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26986"]]
+26985=PROJCS["NAD83 / Maryland", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.0], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.449999999999996], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.3], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26985"]]
+26984=PROJCS["NAD83 / Maine West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.16666666666667], PARAMETER["latitude_of_origin", 42.833333333333336], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 900000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26984"]]
+26983=PROJCS["NAD83 / Maine East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -68.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26983"]]
+26982=PROJCS["NAD83 / Louisiana South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -91.33333333333333], PARAMETER["latitude_of_origin", 28.5], PARAMETER["standard_parallel_1", 30.7], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.3], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26982"]]
+26981=PROJCS["NAD83 / Louisiana North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.5], PARAMETER["latitude_of_origin", 30.5], PARAMETER["standard_parallel_1", 32.666666666666664], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 31.166666666666668], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26981"]]
+26980=PROJCS["NAD83 / Kentucky South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.93333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.733333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26980"]]
+66646405=GEOGCS["Azores Oriental 1995 (deg)", DATUM["Azores Oriental Islands 1995", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.719, 129.685, 52.092, -0.195, 0.014, -0.327, 0.198], AUTHORITY["EPSG","6664"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66646405"]]
+61926405=GEOGCS["Douala 1948 (deg)", DATUM["Douala 1948", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-206.1, -174.7, -87.7, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6192"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61926405"]]
+26979=PROJCS["NAD83 / Kentucky North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.25], PARAMETER["latitude_of_origin", 37.5], PARAMETER["standard_parallel_1", 37.96666666666667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.96666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26979"]]
+26978=PROJCS["NAD83 / Kansas South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.56666666666667], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 400000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.266666666666666], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26978"]]
+26977=PROJCS["NAD83 / Kansas North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 39.78333333333333], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26977"]]
+26976=PROJCS["NAD83 / Iowa South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 40.0], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.61666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26976"]]
+26975=PROJCS["NAD83 / Iowa North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.266666666666666], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.06666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26975"]]
+26974=PROJCS["NAD83 / Indiana West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.08333333333333], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 900000.0], PARAMETER["false_northing", 250000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26974"]]
+26973=PROJCS["NAD83 / Indiana East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.66666666666667], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 250000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26973"]]
+26972=PROJCS["NAD83 / Illinois West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.16666666666667], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26972"]]
+26971=PROJCS["NAD83 / Illinois East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.33333333333333], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999975], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26971"]]
+26970=PROJCS["NAD83 / Idaho West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.75], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26970"]]
+26969=PROJCS["NAD83 / Idaho Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -114.0], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26969"]]
+26968=PROJCS["NAD83 / Idaho East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -112.16666666666667], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26968"]]
+26967=PROJCS["NAD83 / Georgia West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -84.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26967"]]
+26966=PROJCS["NAD83 / Georgia East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26966"]]
+26965=PROJCS["NAD83 / Hawaii zone 5", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -160.16666666666666], PARAMETER["latitude_of_origin", 21.666666666666668], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26965"]]
+26964=PROJCS["NAD83 / Hawaii zone 4", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.5], PARAMETER["latitude_of_origin", 21.833333333333332], PARAMETER["scale_factor", 0.99999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26964"]]
+26963=PROJCS["NAD83 / Hawaii zone 3", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -158.0], PARAMETER["latitude_of_origin", 21.166666666666668], PARAMETER["scale_factor", 0.99999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26963"]]
+26962=PROJCS["NAD83 / Hawaii zone 2", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -156.66666666666666], PARAMETER["latitude_of_origin", 20.333333333333332], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26962"]]
+26961=PROJCS["NAD83 / Hawaii zone 1", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -155.5], PARAMETER["latitude_of_origin", 18.833333333333332], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26961"]]
+26960=PROJCS["NAD83 / Florida North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.5], PARAMETER["latitude_of_origin", 29.0], PARAMETER["standard_parallel_1", 30.75], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.583333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26960"]]
+68136405=GEOGCS["Batavia (Jakarta) (deg)", DATUM["Batavia (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6813"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","68136405"]]
+61596405=GEOGCS["ELD79 (deg)", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61596405"]]
+26959=PROJCS["NAD83 / Florida West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26959"]]
+26958=PROJCS["NAD83 / Florida East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26958"]]
+26957=PROJCS["NAD83 / Delaware", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.41666666666667], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 0.999995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26957"]]
+26956=PROJCS["NAD83 / Connecticut", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -72.75], PARAMETER["latitude_of_origin", 40.833333333333336], PARAMETER["standard_parallel_1", 41.86666666666669], PARAMETER["false_easting", 304800.6096], PARAMETER["false_northing", 152400.3048], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.2], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26956"]]
+26955=PROJCS["NAD83 / Colorado South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 914401.8289], PARAMETER["false_northing", 304800.6096], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.233333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26955"]]
+26954=PROJCS["NAD83 / Colorado Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 37.833333333333336], PARAMETER["standard_parallel_1", 39.75], PARAMETER["false_easting", 914401.8289], PARAMETER["false_northing", 304800.6096], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.45], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26954"]]
+26953=PROJCS["NAD83 / Colorado North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.78333333333333], PARAMETER["false_easting", 914401.8289], PARAMETER["false_northing", 304800.6096], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26953"]]
+26952=PROJCS["NAD83 / Arkansas South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 32.666666666666664], PARAMETER["standard_parallel_1", 34.766666666666666], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 400000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.3], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26952"]]
+26951=PROJCS["NAD83 / Arkansas North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 34.333333333333336], PARAMETER["standard_parallel_1", 36.233333333333334], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.93333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26951"]]
+26950=PROJCS["NAD83 / Arizona West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -113.75], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 213360.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26950"]]
+26949=PROJCS["NAD83 / Arizona Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.91666666666666], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 213360.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26949"]]
+26948=PROJCS["NAD83 / Arizona East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.16666666666667], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 213360.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26948"]]
+26946=PROJCS["NAD83 / California zone 6", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -116.25], PARAMETER["latitude_of_origin", 32.166666666666664], PARAMETER["standard_parallel_1", 33.88333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.78333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26946"]]
+26945=PROJCS["NAD83 / California zone 5", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -118.0], PARAMETER["latitude_of_origin", 33.5], PARAMETER["standard_parallel_1", 35.46666666666667], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.03333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26945"]]
+26944=PROJCS["NAD83 / California zone 4", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -119.0], PARAMETER["latitude_of_origin", 35.333333333333336], PARAMETER["standard_parallel_1", 37.25], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26944"]]
+26943=PROJCS["NAD83 / California zone 3", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 36.5], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.06666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26943"]]
+26942=PROJCS["NAD83 / California zone 2", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.833333333333336], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.333333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26942"]]
+26941=PROJCS["NAD83 / California zone 1", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 41.666666666666664], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26941"]]
+26940=PROJCS["NAD83 / Alaska zone 10", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -176.0], PARAMETER["latitude_of_origin", 51.0], PARAMETER["standard_parallel_1", 53.833333333333336], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 51.833333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26940"]]
+32360=PROJCS["WGS 72 / UTM zone 60S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32360"]]
+26939=PROJCS["NAD83 / Alaska zone 9", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -170.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26939"]]
+26938=PROJCS["NAD83 / Alaska zone 8", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -166.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26938"]]
+62716405=GEOGCS["Naparima 1972 (deg)", DATUM["Naparima 1972", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-2.0, 374.0, 172.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6271"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62716405"]]
+26937=PROJCS["NAD83 / Alaska zone 7", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -162.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26937"]]
+32359=PROJCS["WGS 72 / UTM zone 59S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32359"]]
+26936=PROJCS["NAD83 / Alaska zone 6", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -158.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26936"]]
+32358=PROJCS["WGS 72 / UTM zone 58S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32358"]]
+26935=PROJCS["NAD83 / Alaska zone 5", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -154.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26935"]]
+32357=PROJCS["WGS 72 / UTM zone 57S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32357"]]
+26934=PROJCS["NAD83 / Alaska zone 4", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -150.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26934"]]
+32356=PROJCS["WGS 72 / UTM zone 56S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32356"]]
+26933=PROJCS["NAD83 / Alaska zone 3", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -146.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26933"]]
+32355=PROJCS["WGS 72 / UTM zone 55S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32355"]]
+26932=PROJCS["NAD83 / Alaska zone 2", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -142.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26932"]]
+32354=PROJCS["WGS 72 / UTM zone 54S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32354"]]
+26931=PROJCS["NAD83 / Alaska zone 1", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9812"]], PARAMETER["longitude_of_center", -133.66666666666666], PARAMETER["latitude_of_center", 57.0], PARAMETER["azimuth", 323.130102361111], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 5000000.0], PARAMETER["false_northing", -5000000.0], PARAMETER["rectified_grid_angle", 323.130102361111], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26931"]]
+32353=PROJCS["WGS 72 / UTM zone 53S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32353"]]
+26930=PROJCS["NAD83 / Alabama West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.5], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26930"]]
+30179=PROJCS["Tokyo / Japan Plane Rectangular CS XIX", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 154.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30179"]]
+32352=PROJCS["WGS 72 / UTM zone 52S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32352"]]
+30178=PROJCS["Tokyo / Japan Plane Rectangular CS XVIII", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 136.0], PARAMETER["latitude_of_origin", 20.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30178"]]
+32351=PROJCS["WGS 72 / UTM zone 51S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32351"]]
+30177=PROJCS["Tokyo / Japan Plane Rectangular CS XVII", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 131.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30177"]]
+32350=PROJCS["WGS 72 / UTM zone 50S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32350"]]
+30176=PROJCS["Tokyo / Japan Plane Rectangular CS XVI", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 124.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30176"]]
+30175=PROJCS["Tokyo / Japan Plane Rectangular CS XV", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 127.5], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30175"]]
+30174=PROJCS["Tokyo / Japan Plane Rectangular CS XIV", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 142.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30174"]]
+30173=PROJCS["Tokyo / Japan Plane Rectangular CS XIII", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 144.25], PARAMETER["latitude_of_origin", 44.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30173"]]
+30172=PROJCS["Tokyo / Japan Plane Rectangular CS XII", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 142.25], PARAMETER["latitude_of_origin", 44.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30172"]]
+5396=PROJCS["SIRGAS 2000 / UTM zone 26S", GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5396"]]
+30171=PROJCS["Tokyo / Japan Plane Rectangular CS XI", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 140.25], PARAMETER["latitude_of_origin", 44.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30171"]]
+30170=PROJCS["Tokyo / Japan Plane Rectangular CS X", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 140.83333333333334], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30170"]]
+63086405=GEOGCS["RT38 (deg)", DATUM["Stockholm 1938", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6308"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63086405"]]
+5393=GEOGCS["SIRGAS_ES2007.8", DATUM["SIRGAS_ES2007.8", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1069"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5393"]]
+5392=GEOGCS["SIRGAS_ES2007.8", DATUM["SIRGAS_ES2007.8", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1069"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5392"]]
+5391=GEOCCS["SIRGAS_ES2007.8", DATUM["SIRGAS_ES2007.8", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1069"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5391"]]
+26929=PROJCS["NAD83 / Alabama East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.83333333333333], PARAMETER["latitude_of_origin", 30.5], PARAMETER["scale_factor", 0.99996], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26929"]]
+32349=PROJCS["WGS 72 / UTM zone 49S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32349"]]
+32348=PROJCS["WGS 72 / UTM zone 48S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32348"]]
+32347=PROJCS["WGS 72 / UTM zone 47S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32347"]]
+32346=PROJCS["WGS 72 / UTM zone 46S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32346"]]
+26923=PROJCS["NAD83 / UTM zone 23N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26923"]]
+32345=PROJCS["WGS 72 / UTM zone 45S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32345"]]
+26922=PROJCS["NAD83 / UTM zone 22N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26922"]]
+32344=PROJCS["WGS 72 / UTM zone 44S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32344"]]
+26921=PROJCS["NAD83 / UTM zone 21N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26921"]]
+32343=PROJCS["WGS 72 / UTM zone 43S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32343"]]
+26920=PROJCS["NAD83 / UTM zone 20N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26920"]]
+30169=PROJCS["Tokyo / Japan Plane Rectangular CS IX", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 139.83333333333334], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30169"]]
+32342=PROJCS["WGS 72 / UTM zone 42S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32342"]]
+30168=PROJCS["Tokyo / Japan Plane Rectangular CS VIII", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 138.5], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30168"]]
+32341=PROJCS["WGS 72 / UTM zone 41S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32341"]]
+30167=PROJCS["Tokyo / Japan Plane Rectangular CS VII", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 137.16666666666666], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30167"]]
+32340=PROJCS["WGS 72 / UTM zone 40S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32340"]]
+30166=PROJCS["Tokyo / Japan Plane Rectangular CS VI", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 136.0], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30166"]]
+30165=PROJCS["Tokyo / Japan Plane Rectangular CS V", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 134.33333333333334], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30165"]]
+5389=PROJCS["Peru96 / UTM zone 19S", GEOGCS["Peru96", DATUM["Peru96", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1067"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5373"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5389"]]
+30164=PROJCS["Tokyo / Japan Plane Rectangular CS IV", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 133.5], PARAMETER["latitude_of_origin", 33.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30164"]]
+5388=PROJCS["Peru96 / UTM zone 17S", GEOGCS["Peru96", DATUM["Peru96", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1067"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5373"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5388"]]
+30163=PROJCS["Tokyo / Japan Plane Rectangular CS III", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.16666666666666], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30163"]]
+5387=PROJCS["Peru96 / UTM zone 18S", GEOGCS["Peru96", DATUM["Peru96", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1067"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5373"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5387"]]
+30162=PROJCS["Tokyo / Japan Plane Rectangular CS II", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 131.0], PARAMETER["latitude_of_origin", 33.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30162"]]
+30161=PROJCS["Tokyo / Japan Plane Rectangular CS I", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.5], PARAMETER["latitude_of_origin", 33.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30161"]]
+5383=PROJCS["SIRGAS-ROU98 / UTM zone 22S", GEOGCS["SIRGAS-ROU98", DATUM["SIRGAS-ROU98", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1068"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5381"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5383"]]
+5382=PROJCS["SIRGAS-ROU98 / UTM zone 21S", GEOGCS["SIRGAS-ROU98", DATUM["SIRGAS-ROU98", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1068"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5381"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5382"]]
+5381=GEOGCS["SIRGAS-ROU98", DATUM["SIRGAS-ROU98", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1068"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5381"]]
+5380=GEOGCS["SIRGAS-ROU98", DATUM["SIRGAS-ROU98", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1068"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5380"]]
+26919=PROJCS["NAD83 / UTM zone 19N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26919"]]
+26918=PROJCS["NAD83 / UTM zone 18N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26918"]]
+66156405=GEOGCS["Porto Santo (deg)", DATUM["Porto Santo 1936", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-499.0, -249.0, 314.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6615"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66156405"]]
+26917=PROJCS["NAD83 / UTM zone 17N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26917"]]
+32339=PROJCS["WGS 72 / UTM zone 39S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32339"]]
+26916=PROJCS["NAD83 / UTM zone 16N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26916"]]
+32338=PROJCS["WGS 72 / UTM zone 38S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32338"]]
+26915=PROJCS["NAD83 / UTM zone 15N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26915"]]
+32337=PROJCS["WGS 72 / UTM zone 37S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32337"]]
+26914=PROJCS["NAD83 / UTM zone 14N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26914"]]
+32336=PROJCS["WGS 72 / UTM zone 36S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32336"]]
+61436405=GEOGCS["Abidjan 1987 (deg)", DATUM["Abidjan 1987", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-124.76, 53.0, 466.79, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6143"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61436405"]]
+26913=PROJCS["NAD83 / UTM zone 13N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26913"]]
+32335=PROJCS["WGS 72 / UTM zone 35S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32335"]]
+26912=PROJCS["NAD83 / UTM zone 12N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26912"]]
+32334=PROJCS["WGS 72 / UTM zone 34S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32334"]]
+26911=PROJCS["NAD83 / UTM zone 11N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26911"]]
+32333=PROJCS["WGS 72 / UTM zone 33S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32333"]]
+26910=PROJCS["NAD83 / UTM zone 10N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26910"]]
+32332=PROJCS["WGS 72 / UTM zone 32S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32332"]]
+32331=PROJCS["WGS 72 / UTM zone 31S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32331"]]
+32330=PROJCS["WGS 72 / UTM zone 30S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32330"]]
+5379=GEOCCS["SIRGAS-ROU98", DATUM["SIRGAS-ROU98", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1068"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5379"]]
+62386405=GEOGCS["ID74 (deg)", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62386405"]]
+5373=GEOGCS["Peru96", DATUM["Peru96", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1067"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5373"]]
+3199=PROJCS["LGD2006 / UTM zone 32N", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3199"]]
+5372=GEOGCS["Peru96", DATUM["Peru96", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1067"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5372"]]
+3198=PROJCS["LGD2006 / Libya TM zone 13", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 25.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3198"]]
+5371=GEOGCS["MACARIO SOLIS", DATUM["Sistema Geodesico Nacional de Panama MACARIO SOLIS", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1066"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5371"]]
+3197=PROJCS["LGD2006 / Libya TM zone 12", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 23.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3197"]]
+5370=GEOGCS["MACARIO SOLIS", DATUM["Sistema Geodesico Nacional de Panama MACARIO SOLIS", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1066"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5370"]]
+3196=PROJCS["LGD2006 / Libya TM zone 11", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3196"]]
+3195=PROJCS["LGD2006 / Libya TM zone 10", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 19.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3195"]]
+3194=PROJCS["LGD2006 / Libya TM zone 9", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 17.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3194"]]
+3193=PROJCS["LGD2006 / Libya TM zone 8", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3193"]]
+3192=PROJCS["LGD2006 / Libya TM zone 7", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 13.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3192"]]
+3191=PROJCS["LGD2006 / Libya TM zone 6", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 11.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3191"]]
+42101=PROJCS["WGS 84 / LCC Canada", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS_1984", 6378137.0, 298.257223563]], PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295], AXIS["Longitude", EAST], AXIS["Latitude", NORTH]], PROJECTION["Lambert_Conformal_Conic_2SP"], PARAMETER["central_meridian", -95.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 77.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", -8000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 49.0], UNIT["m", 1.0], AXIS["x", EAST], AXIS["y", NORTH], AUTHORITY["EPSG","42101"]]
+3190=PROJCS["LGD2006 / Libya TM zone 5", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3190"]]
+26909=PROJCS["NAD83 / UTM zone 9N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26909"]]
+26908=PROJCS["NAD83 / UTM zone 8N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26908"]]
+26907=PROJCS["NAD83 / UTM zone 7N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26907"]]
+32329=PROJCS["WGS 72 / UTM zone 29S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32329"]]
+26906=PROJCS["NAD83 / UTM zone 6N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26906"]]
+32328=PROJCS["WGS 72 / UTM zone 28S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32328"]]
+26905=PROJCS["NAD83 / UTM zone 5N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26905"]]
+32327=PROJCS["WGS 72 / UTM zone 27S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32327"]]
+26904=PROJCS["NAD83 / UTM zone 4N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26904"]]
+32326=PROJCS["WGS 72 / UTM zone 26S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32326"]]
+26903=PROJCS["NAD83 / UTM zone 3N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26903"]]
+32325=PROJCS["WGS 72 / UTM zone 25S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32325"]]
+26902=PROJCS["NAD83 / UTM zone 2N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26902"]]
+32324=PROJCS["WGS 72 / UTM zone 24S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32324"]]
+26901=PROJCS["NAD83 / UTM zone 1N", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26901"]]
+32323=PROJCS["WGS 72 / UTM zone 23S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32323"]]
+32322=PROJCS["WGS 72 / UTM zone 22S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32322"]]
+32321=PROJCS["WGS 72 / UTM zone 21S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32321"]]
+32320=PROJCS["WGS 72 / UTM zone 20S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32320"]]
+5369=GEOCCS["Peru96", DATUM["Peru96", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1067"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5369"]]
+5368=GEOCCS["MACARIO SOLIS", DATUM["Sistema Geodesico Nacional de Panama MACARIO SOLIS", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1066"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5368"]]
+5367=PROJCS["CR05 / CRTM05", GEOGCS["CR05", DATUM["Costa Rica 2005", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1065"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5365"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5367"]]
+24720=PROJCS["La Canoa / UTM zone 20N", GEOGCS["La Canoa", DATUM["La Canoa", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-273.5, 110.6, -357.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6247"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4247"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24720"]]
+5365=GEOGCS["CR05", DATUM["Costa Rica 2005", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1065"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5365"]]
+5364=GEOGCS["CR05", DATUM["Costa Rica 2005", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1065"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5364"]]
+5363=GEOCCS["CR05", DATUM["Costa Rica 2005", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1065"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5363"]]
+3189=PROJCS["GR96 / UTM zone 29N", GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4747"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3189"]]
+5362=PROJCS["SIRGAS-Chile / UTM zone 18S", GEOGCS["SIRGAS-Chile", DATUM["SIRGAS-Chile", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1064"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5360"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5362"]]
+3188=PROJCS["GR96 / UTM zone 28N", GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4747"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3188"]]
+5361=PROJCS["SIRGAS-Chile / UTM zone 19S", GEOGCS["SIRGAS-Chile", DATUM["SIRGAS-Chile", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1064"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5360"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5361"]]
+3187=PROJCS["GR96 / UTM zone 27N", GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4747"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3187"]]
+5360=GEOGCS["SIRGAS-Chile", DATUM["SIRGAS-Chile", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1064"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5360"]]
+3186=PROJCS["GR96 / UTM zone 26N", GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4747"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3186"]]
+3185=PROJCS["GR96 / UTM zone 25N", GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4747"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3185"]]
+3184=PROJCS["GR96 / UTM zone 24N", GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4747"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3184"]]
+3183=PROJCS["GR96 / UTM zone 23N", GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4747"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3183"]]
+3182=PROJCS["GR96 / UTM zone 22N", GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4747"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3182"]]
+3181=PROJCS["GR96 / UTM zone 21N", GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4747"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3181"]]
+3180=PROJCS["GR96 / UTM zone 20N", GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4747"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3180"]]
+32319=PROJCS["WGS 72 / UTM zone 19S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32319"]]
+32318=PROJCS["WGS 72 / UTM zone 18S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32318"]]
+32317=PROJCS["WGS 72 / UTM zone 17S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32317"]]
+32316=PROJCS["WGS 72 / UTM zone 16S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32316"]]
+32315=PROJCS["WGS 72 / UTM zone 15S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32315"]]
+24719=PROJCS["La Canoa / UTM zone 19N", GEOGCS["La Canoa", DATUM["La Canoa", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-273.5, 110.6, -357.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6247"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4247"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24719"]]
+32314=PROJCS["WGS 72 / UTM zone 14S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32314"]]
+24718=PROJCS["La Canoa / UTM zone 18N", GEOGCS["La Canoa", DATUM["La Canoa", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-273.5, 110.6, -357.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6247"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4247"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24718"]]
+32313=PROJCS["WGS 72 / UTM zone 13S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32313"]]
+32312=PROJCS["WGS 72 / UTM zone 12S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32312"]]
+32311=PROJCS["WGS 72 / UTM zone 11S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32311"]]
+32310=PROJCS["WGS 72 / UTM zone 10S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32310"]]
+5359=GEOGCS["SIRGAS-Chile", DATUM["SIRGAS-Chile", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1064"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5359"]]
+5358=GEOCCS["SIRGAS-Chile", DATUM["SIRGAS-Chile", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1064"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5358"]]
+5357=PROJCS["MARGEN / UTM zone 21S", GEOGCS["MARGEN", DATUM["Marco Geodesico Nacional", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1063"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5354"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5357"]]
+5356=PROJCS["MARGEN / UTM zone 19S", GEOGCS["MARGEN", DATUM["Marco Geodesico Nacional", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1063"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5354"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5356"]]
+5355=PROJCS["MARGEN / UTM zone 20S", GEOGCS["MARGEN", DATUM["Marco Geodesico Nacional", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1063"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5354"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5355"]]
+5354=GEOGCS["MARGEN", DATUM["Marco Geodesico Nacional", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1063"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5354"]]
+5353=GEOGCS["MARGEN", DATUM["Marco Geodesico Nacional", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1063"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5353"]]
+3179=PROJCS["GR96 / UTM zone 19N", GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4747"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3179"]]
+5352=GEOCCS["MARGEN", DATUM["Marco Geodesico Nacional", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1063"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5352"]]
+3178=PROJCS["GR96 / UTM zone 18N", GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4747"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3178"]]
+20358=PROJCS["AGD84 / AMG zone 58", GEOGCS["AGD84", DATUM["Australian Geodetic Datum 1984", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-117.763, -51.51, 139.061, 0.292, -0.443, -0.277, -0.191], AUTHORITY["EPSG","6203"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4203"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20358"]]
+3177=PROJCS["LGD2006 / Libya TM", GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 17.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9965], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3177"]]
+20357=PROJCS["AGD84 / AMG zone 57", GEOGCS["AGD84", DATUM["Australian Geodetic Datum 1984", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-117.763, -51.51, 139.061, 0.292, -0.443, -0.277, -0.191], AUTHORITY["EPSG","6203"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4203"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20357"]]
+3176=PROJCS["Indian 1960 / TM 106 NE", GEOGCS["Indian 1960", DATUM["Indian 1960", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[198.0, 881.0, 317.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6131"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4131"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 106.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3176"]]
+20356=PROJCS["AGD84 / AMG zone 56", GEOGCS["AGD84", DATUM["Australian Geodetic Datum 1984", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-117.763, -51.51, 139.061, 0.292, -0.443, -0.277, -0.191], AUTHORITY["EPSG","6203"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4203"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20356"]]
+3175=PROJCS["NAD83 / Great Lakes and St Lawrence Albers", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -83.248627], PARAMETER["latitude_of_origin", 45.568977], PARAMETER["standard_parallel_1", 42.122773999999986], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["standard_parallel_2", 49.015179999999994], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3175"]]
+20355=PROJCS["AGD84 / AMG zone 55", GEOGCS["AGD84", DATUM["Australian Geodetic Datum 1984", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-117.763, -51.51, 139.061, 0.292, -0.443, -0.277, -0.191], AUTHORITY["EPSG","6203"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4203"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20355"]]
+3174=PROJCS["NAD83 / Great Lakes Albers", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -84.45595499999999], PARAMETER["latitude_of_origin", 45.568977], PARAMETER["standard_parallel_1", 42.122773999999986], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["standard_parallel_2", 49.015179999999994], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3174"]]
+20354=PROJCS["AGD84 / AMG zone 54", GEOGCS["AGD84", DATUM["Australian Geodetic Datum 1984", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-117.763, -51.51, 139.061, 0.292, -0.443, -0.277, -0.191], AUTHORITY["EPSG","6203"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4203"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20354"]]
+20353=PROJCS["AGD84 / AMG zone 53", GEOGCS["AGD84", DATUM["Australian Geodetic Datum 1984", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-117.763, -51.51, 139.061, 0.292, -0.443, -0.277, -0.191], AUTHORITY["EPSG","6203"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4203"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20353"]]
+3172=PROJCS["IGN53 Mare / UTM zone 59S", GEOGCS["IGN53 Mare", DATUM["IGN53 Mare", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[287.58, 177.78, -135.41, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6641"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4641"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3172"]]
+20352=PROJCS["AGD84 / AMG zone 52", GEOGCS["AGD84", DATUM["Australian Geodetic Datum 1984", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-117.763, -51.51, 139.061, 0.292, -0.443, -0.277, -0.191], AUTHORITY["EPSG","6203"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4203"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20352"]]
+3171=PROJCS["RGNC91-93 / UTM zone 59S", GEOGCS["RGNC91-93", DATUM["Reseau Geodesique de Nouvelle Caledonie 91-93", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6749"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4749"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3171"]]
+20351=PROJCS["AGD84 / AMG zone 51", GEOGCS["AGD84", DATUM["Australian Geodetic Datum 1984", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-117.763, -51.51, 139.061, 0.292, -0.443, -0.277, -0.191], AUTHORITY["EPSG","6203"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4203"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20351"]]
+3170=PROJCS["RGNC91-93 / UTM zone 58S", GEOGCS["RGNC91-93", DATUM["Reseau Geodesique de Nouvelle Caledonie 91-93", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6749"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4749"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3170"]]
+20350=PROJCS["AGD84 / AMG zone 50", GEOGCS["AGD84", DATUM["Australian Geodetic Datum 1984", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-117.763, -51.51, 139.061, 0.292, -0.443, -0.277, -0.191], AUTHORITY["EPSG","6203"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4203"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20350"]]
+32309=PROJCS["WGS 72 / UTM zone 9S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32309"]]
+32308=PROJCS["WGS 72 / UTM zone 8S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32308"]]
+32307=PROJCS["WGS 72 / UTM zone 7S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32307"]]
+32306=PROJCS["WGS 72 / UTM zone 6S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32306"]]
+32305=PROJCS["WGS 72 / UTM zone 5S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32305"]]
+32304=PROJCS["WGS 72 / UTM zone 4S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32304"]]
+32303=PROJCS["WGS 72 / UTM zone 3S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32303"]]
+32302=PROJCS["WGS 72 / UTM zone 2S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32302"]]
+32301=PROJCS["WGS 72 / UTM zone 1S", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32301"]]
+5349=PROJCS["POSGAR 2007 / Argentina 7", GEOGCS["POSGAR 2007", DATUM["Posiciones Geodesicas Argentinas 2007", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1062"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5340"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -54.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5349"]]
+61986405=GEOGCS["Kousseri (deg)", DATUM["Kousseri", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6198"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61986405"]]
+5348=PROJCS["POSGAR 2007 / Argentina 6", GEOGCS["POSGAR 2007", DATUM["Posiciones Geodesicas Argentinas 2007", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1062"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5340"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5348"]]
+5347=PROJCS["POSGAR 2007 / Argentina 5", GEOGCS["POSGAR 2007", DATUM["Posiciones Geodesicas Argentinas 2007", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1062"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5340"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -60.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5347"]]
+5346=PROJCS["POSGAR 2007 / Argentina 4", GEOGCS["POSGAR 2007", DATUM["Posiciones Geodesicas Argentinas 2007", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1062"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5340"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5346"]]
+5345=PROJCS["POSGAR 2007 / Argentina 3", GEOGCS["POSGAR 2007", DATUM["Posiciones Geodesicas Argentinas 2007", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1062"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5340"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -66.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5345"]]
+22525=PROJCS["Corrego Alegre 1970-72 / UTM zone 25S", GEOGCS["Corrego Alegre 1970-72", DATUM["Corrego Alegre 1970-72", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-206.0, 172.0, -6.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6225"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4225"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22525"]]
+5344=PROJCS["POSGAR 2007 / Argentina 2", GEOGCS["POSGAR 2007", DATUM["Posiciones Geodesicas Argentinas 2007", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1062"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5340"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5344"]]
+22524=PROJCS["Corrego Alegre 1970-72 / UTM zone 24S", GEOGCS["Corrego Alegre 1970-72", DATUM["Corrego Alegre 1970-72", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-206.0, 172.0, -6.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6225"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4225"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22524"]]
+5343=PROJCS["POSGAR 2007 / Argentina 1", GEOGCS["POSGAR 2007", DATUM["Posiciones Geodesicas Argentinas 2007", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1062"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5340"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -72.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5343"]]
+22523=PROJCS["Corrego Alegre 1970-72 / UTM zone 23S", GEOGCS["Corrego Alegre 1970-72", DATUM["Corrego Alegre 1970-72", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-206.0, 172.0, -6.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6225"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4225"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22523"]]
+3169=PROJCS["RGNC91-93 / UTM zone 57S", GEOGCS["RGNC91-93", DATUM["Reseau Geodesique de Nouvelle Caledonie 91-93", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6749"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4749"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3169"]]
+5342=GEOGCS["POSGAR 2007", DATUM["Posiciones Geodesicas Argentinas 2007", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1062"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5342"]]
+20349=PROJCS["AGD84 / AMG zone 49", GEOGCS["AGD84", DATUM["Australian Geodetic Datum 1984", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-117.763, -51.51, 139.061, 0.292, -0.443, -0.277, -0.191], AUTHORITY["EPSG","6203"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4203"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20349"]]
+22522=PROJCS["Corrego Alegre 1970-72 / UTM zone 22S", GEOGCS["Corrego Alegre 1970-72", DATUM["Corrego Alegre 1970-72", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-206.0, 172.0, -6.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6225"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4225"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22522"]]
+3168=PROJCS["Kertau (RSO) / RSO Malaya (m)", GEOGCS["Kertau (RSO)", DATUM["Kertau (RSO)", SPHEROID["Everest 1830 (RSO 1969)", 6377295.664, 300.8017, AUTHORITY["EPSG","7056"]], AUTHORITY["EPSG","6751"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4751"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9812"]], PARAMETER["longitude_of_center", 102.25], PARAMETER["latitude_of_center", 4.0], PARAMETER["azimuth", 323.0257905000001], PARAMETER["scale_factor", 0.99984], PARAMETER["false_easting", 804670.24], PARAMETER["false_northing", 0.0], PARAMETER["rectified_grid_angle", 323.130102361111], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3168"]]
+5341=GEOCCS["POSGAR 2007", DATUM["Posiciones Geodesicas Argentinas 2007", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1062"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5341"]]
+20348=PROJCS["AGD84 / AMG zone 48", GEOGCS["AGD84", DATUM["Australian Geodetic Datum 1984", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-117.763, -51.51, 139.061, 0.292, -0.443, -0.277, -0.191], AUTHORITY["EPSG","6203"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4203"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20348"]]
+22521=PROJCS["Corrego Alegre 1970-72 / UTM zone 21S", GEOGCS["Corrego Alegre 1970-72", DATUM["Corrego Alegre 1970-72", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-206.0, 172.0, -6.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6225"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4225"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22521"]]
+3167=PROJCS["Kertau (RSO) / RSO Malaya (ch)", GEOGCS["Kertau (RSO)", DATUM["Kertau (RSO)", SPHEROID["Everest 1830 (RSO 1969)", 6377295.664, 300.8017, AUTHORITY["EPSG","7056"]], AUTHORITY["EPSG","6751"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4751"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9812"]], PARAMETER["longitude_of_center", 102.25], PARAMETER["latitude_of_center", 4.0], PARAMETER["azimuth", 323.0257905000001], PARAMETER["scale_factor", 0.99984], PARAMETER["false_easting", 40000.0], PARAMETER["false_northing", 0.0], PARAMETER["rectified_grid_angle", 323.130102361111], UNIT["m*20.116756", 20.116756], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3167"]]
+5340=GEOGCS["POSGAR 2007", DATUM["Posiciones Geodesicas Argentinas 2007", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1062"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5340"]]
+3166=PROJCS["NEA74 Noumea / Noumea Lambert 2", GEOGCS["NEA74 Noumea", DATUM["NEA74 Noumea", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-10.18, -350.43, 291.37, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6644"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4644"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 166.44249999999994], PARAMETER["latitude_of_origin", -22.269722222222214], PARAMETER["standard_parallel_1", -22.24472222222223], PARAMETER["false_easting", 8.313], PARAMETER["false_northing", -2.354], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -22.294722222222223], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3166"]]
+3165=PROJCS["NEA74 Noumea / Noumea Lambert", GEOGCS["NEA74 Noumea", DATUM["NEA74 Noumea", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-10.18, -350.43, 291.37, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6644"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4644"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 166.44242574999998], PARAMETER["latitude_of_origin", -22.26969175], PARAMETER["standard_parallel_1", -22.244691749999998], PARAMETER["false_easting", 0.66], PARAMETER["false_northing", 1.02], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -22.29469175], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3165"]]
+3164=PROJCS["ST87 Ouvea / UTM zone 58S", GEOGCS["ST87 Ouvea", DATUM["ST87 Ouvea", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[-56.263, 16.136, -22.856, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6750"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4750"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3164"]]
+3163=PROJCS["RGNC91-93 / Lambert New Caledonia", GEOGCS["RGNC91-93", DATUM["Reseau Geodesique de Nouvelle Caledonie 91-93", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6749"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4749"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 166.0], PARAMETER["latitude_of_origin", -21.5], PARAMETER["standard_parallel_1", -20.666666666666668], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 300000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -22.333333333333332], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3163"]]
+3162=PROJCS["NAD83(CSRS) / Ontario MNR Lambert", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 53.5], PARAMETER["false_easting", 930000.0], PARAMETER["false_northing", 6430000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3162"]]
+3161=PROJCS["NAD83 / Ontario MNR Lambert", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 53.5], PARAMETER["false_easting", 930000.0], PARAMETER["false_northing", 6430000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3161"]]
+3160=PROJCS["NAD83(CSRS) / UTM zone 16N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3160"]]
+5337=PROJCS["Aratu / UTM zone 25S", GEOGCS["Aratu", DATUM["Aratu", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-151.99, 287.04, -147.45, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6208"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4208"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5337"]]
+5336=VERT_CS["Black Sea depth", VERT_DATUM["Black Sea", 2005, AUTHORITY["EPSG","5134"]], UNIT["m", 1.0], AXIS["Gravity-related depth", DOWN], AUTHORITY["EPSG","5336"]]
+3159=PROJCS["NAD83(CSRS) / UTM zone 15N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3159"]]
+5332=GEOCCS["ITRF2008", DATUM["International Terrestrial Reference Frame 2008", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","1061"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5332"]]
+3158=PROJCS["NAD83(CSRS) / UTM zone 14N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3158"]]
+5331=PROJCS["Makassar (Jakarta) / NEIEZ", GEOGCS["Makassar (Jakarta)", DATUM["Makassar (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6804"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4804"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9804"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 3.1922805555555547], PARAMETER["scale_factor", 0.997], PARAMETER["false_easting", 3900000.0], PARAMETER["false_northing", 900000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5331"]]
+3157=PROJCS["NAD83(CSRS) / UTM zone 10N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3157"]]
+5330=PROJCS["Batavia (Jakarta) / NEIEZ", GEOGCS["Batavia (Jakarta)", DATUM["Batavia (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6813"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4813"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9804"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 3.1922805555555547], PARAMETER["scale_factor", 0.997], PARAMETER["false_easting", 3900000.0], PARAMETER["false_northing", 900000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5330"]]
+3156=PROJCS["NAD83(CSRS) / UTM zone 9N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3156"]]
+62226405=GEOGCS["Cape (deg)", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62226405"]]
+3155=PROJCS["NAD83(CSRS) / UTM zone 8N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3155"]]
+3154=PROJCS["NAD83(CSRS) / UTM zone 7N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3154"]]
+3153=PROJCS["NAD83(CSRS) / BC Albers", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -126.0], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 50.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 58.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3153"]]
+3152=PROJCS["ST74", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.057789999999997], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99999425], PARAMETER["false_easting", 100178.1808], PARAMETER["false_northing", -6500614.7836], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3152"]]
+3151=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 18E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3151"]]
+3150=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 6", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3150"]]
+5329=PROJCS["Segara (Jakarta) / NEIEZ", GEOGCS["Segara (Jakarta)", DATUM["Gunung Segara (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6820"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4820"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9804"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 3.1922805555555547], PARAMETER["scale_factor", 0.997], PARAMETER["false_easting", 3900000.0], PARAMETER["false_northing", 900000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5329"]]
+5325=PROJCS["ISN2004 / Lambert 2004", GEOGCS["ISN2004", DATUM["Islands Net 2004", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1060"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5324"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -19.0], PARAMETER["latitude_of_origin", 65.0], PARAMETER["standard_parallel_1", 65.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 300000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 64.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5325"]]
+5324=GEOGCS["ISN2004", DATUM["Islands Net 2004", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1060"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5324"]]
+5323=GEOGCS["ISN2004", DATUM["Islands Net 2004", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1060"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5323"]]
+3149=PROJCS["Indian 1960 / UTM zone 49N", GEOGCS["Indian 1960", DATUM["Indian 1960", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[198.0, 881.0, 317.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6131"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4131"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3149"]]
+5322=GEOCCS["ISN2004", DATUM["Islands Net 2004", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1060"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5322"]]
+3148=PROJCS["Indian 1960 / UTM zone 48N", GEOGCS["Indian 1960", DATUM["Indian 1960", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[198.0, 881.0, 317.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6131"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4131"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3148"]]
+5321=PROJCS["NAD83(CSRS) / Teranet Ontario Lambert", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 54.5], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5321"]]
+3147=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 18E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3147"]]
+5320=PROJCS["NAD83 / Teranet Ontario Lambert", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 54.5], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5320"]]
+3146=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 6", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3146"]]
+3142=PROJCS["Fiji 1956 / UTM zone 1S", GEOGCS["Fiji 1956", DATUM["Fiji 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[265.025, 384.929, -194.046, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6721"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4721"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3142"]]
+404000=LOCAL_CS["Wildcard 2D cartesian plane in metric unit", LOCAL_DATUM["Unknown", 0], UNIT["m", 1.0], AXIS["x", EAST], AXIS["y", NORTH], AUTHORITY["EPSG","404000"]]
+3141=PROJCS["Fiji 1956 / UTM zone 60S", GEOGCS["Fiji 1956", DATUM["Fiji 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[265.025, 384.929, -194.046, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6721"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4721"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3141"]]
+3140=PROJCS["Viti Levu 1912 / Viti Levu Grid", GEOGCS["Viti Levu 1912", DATUM["Viti Levu 1912", SPHEROID["Clarke 1880 (international foot)", 6378306.3696, 293.46630765562986, AUTHORITY["EPSG","7055"]], TOWGS84[51.0, 391.0, -36.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6752"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4752"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 178.0], PARAMETER["latitude_of_origin", -18.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 544000.0], PARAMETER["false_northing", 704000.0], UNIT["m*0.201168", 0.201168], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3140"]]
+5318=COMPD_CS["ETRS89 / Faroe TM + FVR09 height", PROJCS["ETRS89 / Faroe TM", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -7.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.999997], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", -6000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5316"]], VERT_CS["FVR09 height", VERT_DATUM["Faroe Islands Vertical Reference 2009", 2005, AUTHORITY["EPSG","1059"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5317"]], AUTHORITY["EPSG","5318"]]
+5317=VERT_CS["FVR09 height", VERT_DATUM["Faroe Islands Vertical Reference 2009", 2005, AUTHORITY["EPSG","1059"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5317"]]
+5316=PROJCS["ETRS89 / Faroe TM", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -7.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.999997], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", -6000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5316"]]
+3138=PROJCS["ETRS89 / ETRS-GK31FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 31.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3138"]]
+5311=PROJCS["DRUKREF 03 / Zhemgang TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.86666666666667], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5311"]]
+3137=PROJCS["ETRS89 / ETRS-GK30FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3137"]]
+5310=PROJCS["DRUKREF 03 / Yangtse TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 91.56666666666666], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5310"]]
+3136=PROJCS["ETRS89 / ETRS-GK29FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 29.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3136"]]
+3135=PROJCS["ETRS89 / ETRS-GK28FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 28.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3135"]]
+3134=PROJCS["ETRS89 / ETRS-GK27FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3134"]]
+3133=PROJCS["ETRS89 / ETRS-GK26FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 26.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3133"]]
+3132=PROJCS["ETRS89 / ETRS-GK25FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 25.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3132"]]
+3131=PROJCS["ETRS89 / ETRS-GK24FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3131"]]
+3130=PROJCS["ETRS89 / ETRS-GK23FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 23.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3130"]]
+5309=PROJCS["DRUKREF 03 / Wangdue Phodrang TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.11666666666667], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5309"]]
+5308=PROJCS["DRUKREF 03 / Tsirang TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.16666666666667], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5308"]]
+5307=PROJCS["DRUKREF 03 / Trongsa TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5307"]]
+5306=PROJCS["DRUKREF 03 / Trashigang TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 91.75], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5306"]]
+5305=PROJCS["DRUKREF 03 / Thimphu TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 89.55], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5305"]]
+5304=PROJCS["DRUKREF 03 / Sarpang TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.26666666666667], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5304"]]
+5303=PROJCS["DRUKREF 03 / Samtse TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 89.06666666666666], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5303"]]
+61826405=GEOGCS["Azores Occidental 1939 (deg)", DATUM["Azores Occidental Islands 1939", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-422.651, -172.995, 84.02, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6182"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61826405"]]
+3129=PROJCS["ETRS89 / ETRS-GK22FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 22.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3129"]]
+5302=PROJCS["DRUKREF 03 / Samdrup Jongkhar TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 91.56666666666666], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5302"]]
+3128=PROJCS["ETRS89 / ETRS-GK21FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3128"]]
+5301=PROJCS["DRUKREF 03 / Punakha TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 89.85], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5301"]]
+3127=PROJCS["ETRS89 / ETRS-GK20FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 20.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3127"]]
+5300=PROJCS["DRUKREF 03 / Pemagatshel TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 91.35], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5300"]]
+3126=PROJCS["ETRS89 / ETRS-GK19FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 19.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3126"]]
+3125=PROJCS["PRS92 / Philippines zone 5", GEOGCS["PRS92", DATUM["Philippine Reference System 1992", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-127.62, -67.24, -47.04, -3.068, -4.903, -1.578, -1.06], AUTHORITY["EPSG","6683"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4683"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 125.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3125"]]
+3124=PROJCS["PRS92 / Philippines zone 4", GEOGCS["PRS92", DATUM["Philippine Reference System 1992", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-127.62, -67.24, -47.04, -3.068, -4.903, -1.578, -1.06], AUTHORITY["EPSG","6683"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4683"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3124"]]
+3123=PROJCS["PRS92 / Philippines zone 3", GEOGCS["PRS92", DATUM["Philippine Reference System 1992", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-127.62, -67.24, -47.04, -3.068, -4.903, -1.578, -1.06], AUTHORITY["EPSG","6683"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4683"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 121.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3123"]]
+3122=PROJCS["PRS92 / Philippines zone 2", GEOGCS["PRS92", DATUM["Philippine Reference System 1992", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-127.62, -67.24, -47.04, -3.068, -4.903, -1.578, -1.06], AUTHORITY["EPSG","6683"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4683"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 119.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3122"]]
+3121=PROJCS["PRS92 / Philippines zone 1", GEOGCS["PRS92", DATUM["Philippine Reference System 1992", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-127.62, -67.24, -47.04, -3.068, -4.903, -1.578, -1.06], AUTHORITY["EPSG","6683"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4683"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3121"]]
+3120=PROJCS["Pulkovo 1942(58) / Poland zone I", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 21.083333333333332], PARAMETER["latitude_of_origin", 50.625], PARAMETER["scale_factor", 0.9998], PARAMETER["false_easting", 4637000.0], PARAMETER["false_northing", 5467000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3120"]]
+62776405=GEOGCS["OSGB 1936 (deg)", DATUM["OSGB 1936", SPHEROID["Airy 1830", 6377563.396, 299.3249646, AUTHORITY["EPSG","7001"]], TOWGS84[446.448, -125.157, 542.06, 0.15, 0.247, 0.842, -20.489], AUTHORITY["EPSG","6277"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62776405"]]
+3119=PROJCS["Douala 1948 / AEF west", GEOGCS["Douala 1948", DATUM["Douala 1948", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-206.1, -174.7, -87.7, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6192"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4192"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 10.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.999], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3119"]]
+3118=PROJCS["MAGNA-SIRGAS / Colombia East zone", GEOGCS["MAGNA-SIRGAS", DATUM["Marco Geocentrico Nacional de Referencia", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6686"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4686"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -68.07750791666663], PARAMETER["latitude_of_origin", 4.596200416666665], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3118"]]
+3117=PROJCS["MAGNA-SIRGAS / Colombia East Central zone", GEOGCS["MAGNA-SIRGAS", DATUM["Marco Geocentrico Nacional de Referencia", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6686"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4686"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.07750791666665], PARAMETER["latitude_of_origin", 4.596200416666665], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3117"]]
+3116=PROJCS["MAGNA-SIRGAS / Colombia Bogota zone", GEOGCS["MAGNA-SIRGAS", DATUM["Marco Geocentrico Nacional de Referencia", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6686"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4686"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.07750791666663], PARAMETER["latitude_of_origin", 4.596200416666665], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3116"]]
+3115=PROJCS["MAGNA-SIRGAS / Colombia West zone", GEOGCS["MAGNA-SIRGAS", DATUM["Marco Geocentrico Nacional de Referencia", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6686"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4686"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -77.07750791666665], PARAMETER["latitude_of_origin", 4.596200416666665], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3115"]]
+3114=PROJCS["MAGNA-SIRGAS / Colombia Far West zone", GEOGCS["MAGNA-SIRGAS", DATUM["Marco Geocentrico Nacional de Referencia", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6686"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4686"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -80.07750791666663], PARAMETER["latitude_of_origin", 4.596200416666665], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3114"]]
+3113=PROJCS["GDA94 / BCSG02", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", -28.0], PARAMETER["scale_factor", 0.99999], PARAMETER["false_easting", 50000.0], PARAMETER["false_northing", 100000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3113"]]
+3112=PROJCS["GDA94 / Geoscience Australia Lambert", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 134.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", -18.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -36.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3112"]]
+3111=PROJCS["GDA94 / Vicgrid94", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 145.0], PARAMETER["latitude_of_origin", -37.0], PARAMETER["standard_parallel_1", -36.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 2500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -38.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3111"]]
+3110=PROJCS["AGD66 / Vicgrid66", GEOGCS["AGD66", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4202"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 145.0], PARAMETER["latitude_of_origin", -37.0], PARAMETER["standard_parallel_1", -36.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 4500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -38.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3110"]]
+3109=PROJCS["ETRS89 / Jersey Transverse Mercator", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -2.135], PARAMETER["latitude_of_origin", 49.225], PARAMETER["scale_factor", 0.9999999], PARAMETER["false_easting", 40000.0], PARAMETER["false_northing", 70000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3109"]]
+3108=PROJCS["ETRS89 / Guernsey Grid", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -2.4166666666666665], PARAMETER["latitude_of_origin", 49.5], PARAMETER["scale_factor", 0.999997], PARAMETER["false_easting", 47000.0], PARAMETER["false_northing", 50000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3108"]]
+3107=PROJCS["GDA94 / SA Lambert", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", -32.0], PARAMETER["standard_parallel_1", -28.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 2000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -36.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3107"]]
+27398=PROJCS["NGO 1948 (Oslo) / NGO zone VIII", GEOGCS["NGO 1948 (Oslo)", DATUM["NGO 1948 (Oslo)", SPHEROID["Bessel Modified", 6377492.018, 299.1528128, AUTHORITY["EPSG","7005"]], AUTHORITY["EPSG","6817"]], PRIMEM["Oslo", 10.722916666666666, AUTHORITY["EPSG","8913"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4817"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.333333333333332], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27398"]]
+3106=PROJCS["Gulshan 303 / Bangladesh Transverse Mercator", GEOGCS["Gulshan 303", DATUM["Gulshan 303", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[283.7, 735.9, 261.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6682"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4682"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3106"]]
+27397=PROJCS["NGO 1948 (Oslo) / NGO zone VII", GEOGCS["NGO 1948 (Oslo)", DATUM["NGO 1948 (Oslo)", SPHEROID["Bessel Modified", 6377492.018, 299.1528128, AUTHORITY["EPSG","7005"]], AUTHORITY["EPSG","6817"]], PRIMEM["Oslo", 10.722916666666666, AUTHORITY["EPSG","8913"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4817"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 14.166666666666668], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27397"]]
+3105=PROJCS["Mauritania 1999 / UTM zone 30N", GEOGCS["Mauritania 1999", DATUM["Mauritania 1999", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6681"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4681"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3105"]]
+27396=PROJCS["NGO 1948 (Oslo) / NGO zone VI", GEOGCS["NGO 1948 (Oslo)", DATUM["NGO 1948 (Oslo)", SPHEROID["Bessel Modified", 6377492.018, 299.1528128, AUTHORITY["EPSG","7005"]], AUTHORITY["EPSG","6817"]], PRIMEM["Oslo", 10.722916666666666, AUTHORITY["EPSG","8913"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4817"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 10.166666666666666], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27396"]]
+3104=PROJCS["Mauritania 1999 / UTM zone 29N", GEOGCS["Mauritania 1999", DATUM["Mauritania 1999", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6681"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4681"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3104"]]
+27395=PROJCS["NGO 1948 (Oslo) / NGO zone V", GEOGCS["NGO 1948 (Oslo)", DATUM["NGO 1948 (Oslo)", SPHEROID["Bessel Modified", 6377492.018, 299.1528128, AUTHORITY["EPSG","7005"]], AUTHORITY["EPSG","6817"]], PRIMEM["Oslo", 10.722916666666666, AUTHORITY["EPSG","8913"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4817"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 6.166666666666667], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27395"]]
+3103=PROJCS["Mauritania 1999 / UTM zone 28N", GEOGCS["Mauritania 1999", DATUM["Mauritania 1999", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6681"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4681"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3103"]]
+27394=PROJCS["NGO 1948 (Oslo) / NGO zone IV", GEOGCS["NGO 1948 (Oslo)", DATUM["NGO 1948 (Oslo)", SPHEROID["Bessel Modified", 6377492.018, 299.1528128, AUTHORITY["EPSG","7005"]], AUTHORITY["EPSG","6817"]], PRIMEM["Oslo", 10.722916666666666, AUTHORITY["EPSG","8913"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4817"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 2.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27394"]]
+3102=PROJCS["American Samoa 1962 / American Samoa Lambert", GEOGCS["American Samoa 1962", DATUM["American Samoa 1962", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-115.0, 118.0, 426.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6169"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4169"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -170.0], PARAMETER["latitude_of_origin", -14.266666666666666], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 312234.65], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3102"]]
+27393=PROJCS["NGO 1948 (Oslo) / NGO zone III", GEOGCS["NGO 1948 (Oslo)", DATUM["NGO 1948 (Oslo)", SPHEROID["Bessel Modified", 6377492.018, 299.1528128, AUTHORITY["EPSG","7005"]], AUTHORITY["EPSG","6817"]], PRIMEM["Oslo", 10.722916666666666, AUTHORITY["EPSG","8913"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4817"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27393"]]
+3101=PROJCS["JGD2000 / UTM zone 55N", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3101"]]
+27392=PROJCS["NGO 1948 (Oslo) / NGO zone II", GEOGCS["NGO 1948 (Oslo)", DATUM["NGO 1948 (Oslo)", SPHEROID["Bessel Modified", 6377492.018, 299.1528128, AUTHORITY["EPSG","7005"]], AUTHORITY["EPSG","6817"]], PRIMEM["Oslo", 10.722916666666666, AUTHORITY["EPSG","8913"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4817"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -2.3333333333333335], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27392"]]
+3100=PROJCS["JGD2000 / UTM zone 54N", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3100"]]
+27391=PROJCS["NGO 1948 (Oslo) / NGO zone I", GEOGCS["NGO 1948 (Oslo)", DATUM["NGO 1948 (Oslo)", SPHEROID["Bessel Modified", 6377492.018, 299.1528128, AUTHORITY["EPSG","7005"]], AUTHORITY["EPSG","6817"]], PRIMEM["Oslo", 10.722916666666666, AUTHORITY["EPSG","8913"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4817"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -4.666666666666667], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27391"]]
+68036405=GEOGCS["Lisbon (Lisbon) (deg)", DATUM["Lisbon 1937 (Lisbon)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6803"]], PRIMEM["Lisbon", -9.131906111111114, AUTHORITY["EPSG","8902"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","68036405"]]
+61496405=GEOGCS["CH1903 (deg)", DATUM["CH1903", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[674.4, 15.1, 405.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6149"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61496405"]]
+4899=GEOCCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4899"]]
+4898=GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4898"]]
+4897=GEOCCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4897"]]
+4896=GEOCCS["ITRF2005", DATUM["International Terrestrial Reference Frame 2005", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6896"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4896"]]
+4895=GEOGCS["JAD2001", DATUM["Jamaica 2001", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6758"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4895"]]
+4894=GEOCCS["JAD2001", DATUM["Jamaica 2001", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6758"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4894"]]
+4893=GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4893"]]
+4892=GEOCCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4892"]]
+4891=GEOGCS["WGS 66", DATUM["World Geodetic System 1966", SPHEROID["NWL 9D", 6378145.0, 298.25, AUTHORITY["EPSG","7025"]], AUTHORITY["EPSG","6760"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4891"]]
+4890=GEOCCS["WGS 66", DATUM["World Geodetic System 1966", SPHEROID["NWL 9D", 6378145.0, 298.25, AUTHORITY["EPSG","7025"]], AUTHORITY["EPSG","6760"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4890"]]
+62616405=GEOGCS["Merchich (deg)", DATUM["Merchich", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[31.0, 146.0, 47.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6261"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62616405"]]
+4889=GEOGCS["HTRS96", DATUM["Croatian Terrestrial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6761"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4889"]]
+4888=GEOCCS["HTRS96", DATUM["Croatian Terrestrial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6761"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4888"]]
+4887=GEOGCS["BDA2000", DATUM["Bermuda 2000", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6762"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4887"]]
+4886=GEOCCS["BDA2000", DATUM["Bermuda 2000", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6762"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4886"]]
+4885=GEOGCS["RSRGD2000", DATUM["Ross Sea Region Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6764"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4885"]]
+4884=GEOCCS["RSRGD2000", DATUM["Ross Sea Region Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6764"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4884"]]
+4883=GEOGCS["Slovenia 1996", DATUM["Slovenia Geodetic Datum 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6765"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4883"]]
+4882=GEOCCS["Slovenia 1996", DATUM["Slovenia Geodetic Datum 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6765"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4882"]]
+4880=PROJCS["ETRS89 / NTM zone 30", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4880"]]
+31839=PROJCS["NGN / UTM zone 39N", GEOGCS["NGN", DATUM["National Geodetic Network", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[-3.2, -5.7, 2.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6318"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4318"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31839"]]
+31838=PROJCS["NGN / UTM zone 38N", GEOGCS["NGN", DATUM["National Geodetic Network", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[-3.2, -5.7, 2.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6318"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4318"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31838"]]
+4879=PROJCS["ETRS89 / NTM zone 29", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 29.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4879"]]
+4878=PROJCS["ETRS89 / NTM zone 28", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 28.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4878"]]
+4877=PROJCS["ETRS89 / NTM zone 27", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4877"]]
+4876=PROJCS["ETRS89 / NTM zone 26", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 26.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4876"]]
+4875=PROJCS["ETRS89 / NTM zone 25", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 25.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4875"]]
+4874=PROJCS["ETRS89 / NTM zone 24", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4874"]]
+4873=PROJCS["ETRS89 / NTM zone 23", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 23.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4873"]]
+2699=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger CM 21E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2699"]]
+4872=PROJCS["ETRS89 / NTM zone 22", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 22.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4872"]]
+2698=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 64", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -168.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 64500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2698"]]
+4871=PROJCS["ETRS89 / NTM zone 21", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4871"]]
+2697=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 63", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 63500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2697"]]
+4870=PROJCS["ETRS89 / NTM zone 20", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 20.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4870"]]
+2696=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 62", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -174.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 62500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2696"]]
+2695=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 61", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 61500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2695"]]
+2694=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 60", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 180.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 60000000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2694"]]
+2693=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 59", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 59500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2693"]]
+2692=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 58", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 174.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 58500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2692"]]
+2691=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 57", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 57500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2691"]]
+2690=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 56", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 168.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 56500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2690"]]
+66056405=GEOGCS["St. Kitts 1955 (deg)", DATUM["St. Kitts 1955", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[9.0, 183.0, 236.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6605"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66056405"]]
+61336405=GEOGCS["EST92 (deg)", DATUM["Estonia 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.055, -0.541, -0.185, 0.0183, 0.0003, 0.007, -0.014], AUTHORITY["EPSG","6133"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61336405"]]
+4869=PROJCS["ETRS89 / NTM zone 19", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 19.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4869"]]
+4868=PROJCS["ETRS89 / NTM zone 18", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4868"]]
+4867=PROJCS["ETRS89 / NTM zone 17", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 17.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4867"]]
+4866=PROJCS["ETRS89 / NTM zone 16", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 16.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4866"]]
+4865=PROJCS["ETRS89 / NTM zone 15", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4865"]]
+4864=PROJCS["ETRS89 / NTM zone 14", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 14.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4864"]]
+4863=PROJCS["ETRS89 / NTM zone 13", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 13.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4863"]]
+2689=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 55", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 55500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2689"]]
+4862=PROJCS["ETRS89 / NTM zone 12", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4862"]]
+2688=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 54", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 162.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 54500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2688"]]
+4861=PROJCS["ETRS89 / NTM zone 11", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 11.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4861"]]
+2687=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 53", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 53500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2687"]]
+4860=PROJCS["ETRS89 / NTM zone 10", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 10.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4860"]]
+2686=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 52", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 156.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 52500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2686"]]
+2685=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 51", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 51500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2685"]]
+2684=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 50", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 150.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 50500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2684"]]
+2683=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 49", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 49500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2683"]]
+2682=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 48", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 144.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 48500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2682"]]
+2681=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 47", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 47500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2681"]]
+2680=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 46", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 138.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 46500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2680"]]
+4859=PROJCS["ETRS89 / NTM zone 9", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4859"]]
+4858=PROJCS["ETRS89 / NTM zone 8", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 8.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4858"]]
+4857=PROJCS["ETRS89 / NTM zone 7", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 7.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4857"]]
+4856=PROJCS["ETRS89 / NTM zone 6", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 6.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4856"]]
+4855=PROJCS["ETRS89 / NTM zone 5", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 5.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4855"]]
+2679=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 45", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 45500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2679"]]
+2678=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 44", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 44500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2678"]]
+2677=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 43", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 43500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2677"]]
+2676=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 42", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 42500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2676"]]
+2675=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 41", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 41500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2675"]]
+2674=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 40", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 40500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2674"]]
+2673=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 39", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 39500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2673"]]
+2672=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 38", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 38500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2672"]]
+2671=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 37", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 37500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2671"]]
+2670=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 36", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 108.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 36500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2670"]]
+2669=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 35", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 35500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2669"]]
+2668=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 34", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 34500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2668"]]
+2667=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 33", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 33500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2667"]]
+2666=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 32", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 32500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2666"]]
+2665=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 31", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 31500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2665"]]
+2664=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 30", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 30500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2664"]]
+2663=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 29", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 29500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2663"]]
+2662=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 28", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 28500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2662"]]
+2661=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 27", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 27500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2661"]]
+2660=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 26", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 26500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2660"]]
+61886405=GEOGCS["OSNI 1952 (deg)", DATUM["OSNI 1952", SPHEROID["Airy 1830", 6377563.396, 299.3249646, AUTHORITY["EPSG","7001"]], TOWGS84[482.5, -130.6, 564.6, -1.042, -0.214, -0.631, 8.15], AUTHORITY["EPSG","6188"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61886405"]]
+4839=PROJCS["ETRS89 / LCC Germany (N-E)", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 10.5], PARAMETER["latitude_of_origin", 51.0], PARAMETER["standard_parallel_1", 53.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 48.66666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4839"]]
+2659=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 25", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 25500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2659"]]
+2658=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 24", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 72.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 24500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2658"]]
+2657=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 23", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 23500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2657"]]
+2656=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 22", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 66.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 22500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2656"]]
+2655=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 21", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 21500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2655"]]
+2654=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 20", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 60.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 20500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2654"]]
+2653=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 19", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 19500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2653"]]
+2652=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 18", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 54.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 18500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2652"]]
+2651=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 17", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 17500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2651"]]
+2650=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 16", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 48.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 16500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2650"]]
+4826=PROJCS["WGS 84 / Cape Verde National", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -24.0], PARAMETER["latitude_of_origin", 15.833333333333332], PARAMETER["standard_parallel_1", 16.666666666666668], PARAMETER["false_easting", 161587.83], PARAMETER["false_northing", 128511.202], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 15.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4826"]]
+4824=GEOGCS["Principe", DATUM["Principe", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","1046"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4824"]]
+4823=GEOGCS["Sao Tome", DATUM["Sao Tome", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","1044"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4823"]]
+2649=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 15", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 15500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2649"]]
+4822=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 135E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4822"]]
+2648=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 14", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 42.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 14500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2648"]]
+4821=GEOGCS["Voirol 1879 (Paris)", DATUM["Voirol 1879 (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6821"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4821"]]
+62126405=GEOGCS["Barbados 1938 (deg)", DATUM["Barbados 1938", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[31.95, 300.99, 419.19, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6212"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62126405"]]
+2647=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 13", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 13500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2647"]]
+4820=GEOGCS["Segara (Jakarta)", DATUM["Gunung Segara (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6820"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4820"]]
+2646=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 12", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 36.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 12500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2646"]]
+2645=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 11", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 11500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2645"]]
+2644=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 10", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 10500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2644"]]
+2643=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 9", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 9500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2643"]]
+2642=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 8", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 8500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2642"]]
+2641=PROJCS["Pulkovo 1995 / 3-degree Gauss-Kruger zone 7", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2641"]]
+2640=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 168W", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -168.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2640"]]
+4819=GEOGCS["Nord Sahara 1959 (Paris)", DATUM["Nord Sahara 1959 (Paris)", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6819"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4819"]]
+4818=GEOGCS["S-JTSK (Ferro)", DATUM["System Jednotne Trigonometricke Site Katastralni (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6818"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4818"]]
+4817=GEOGCS["NGO 1948 (Oslo)", DATUM["NGO 1948 (Oslo)", SPHEROID["Bessel Modified", 6377492.018, 299.1528128, AUTHORITY["EPSG","7005"]], AUTHORITY["EPSG","6817"]], PRIMEM["Oslo", 10.722916666666666, AUTHORITY["EPSG","8913"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4817"]]
+4816=GEOGCS["Carthage (Paris)", DATUM["Carthage (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6816"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4816"]]
+4815=GEOGCS["Greek (Athens)", DATUM["Greek (Athens)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6815"]], PRIMEM["Athens", 23.7163375, AUTHORITY["EPSG","8912"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4815"]]
+4814=GEOGCS["RT38 (Stockholm)", DATUM["Stockholm 1938 (Stockholm)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6814"]], PRIMEM["Stockholm", 18.058277777777775, AUTHORITY["EPSG","8911"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4814"]]
+4813=GEOGCS["Batavia (Jakarta)", DATUM["Batavia (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6813"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4813"]]
+2639=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 171W", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2639"]]
+4812=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 132E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4812"]]
+2638=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 174W", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -174.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2638"]]
+4811=GEOGCS["Voirol 1875 (Paris)", DATUM["Voirol 1875 (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6811"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4811"]]
+2637=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 177W", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2637"]]
+4810=GEOGCS["Tananarive (Paris)", DATUM["Tananarive 1925 (Paris)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6810"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4810"]]
+2636=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 180E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 180.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2636"]]
+2635=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 177E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2635"]]
+2634=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 174E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 174.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2634"]]
+2633=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 171E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2633"]]
+2632=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 168E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 168.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2632"]]
+68096405=GEOGCS["Belge 1950 (Brussels) (deg)", DATUM["Reseau National Belge 1950 (Brussels)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6809"]], PRIMEM["Brussels", 4.3679749999999995, AUTHORITY["EPSG","8910"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","68096405"]]
+2631=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 165E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2631"]]
+2630=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 162E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 162.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2630"]]
+4809=GEOGCS["Belge 1950 (Brussels)", DATUM["Reseau National Belge 1950 (Brussels)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6809"]], PRIMEM["Brussels", 4.3679749999999995, AUTHORITY["EPSG","8910"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4809"]]
+4808=GEOGCS["Padang (Jakarta)", DATUM["Padang 1884 (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6808"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4808"]]
+4807=GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4807"]]
+4806=GEOGCS["Monte Mario (Rome)", DATUM["Monte Mario (Rome)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6806"]], PRIMEM["Rome", 12.452333333333332, AUTHORITY["EPSG","8906"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4806"]]
+4805=GEOGCS["MGI (Ferro)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4805"]]
+4804=GEOGCS["Makassar (Jakarta)", DATUM["Makassar (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6804"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4804"]]
+4803=GEOGCS["Lisbon (Lisbon)", DATUM["Lisbon 1937 (Lisbon)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6803"]], PRIMEM["Lisbon", -9.131906111111114, AUTHORITY["EPSG","8902"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4803"]]
+2629=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 159E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2629"]]
+4802=GEOGCS["Bogota 1975 (Bogota)", DATUM["Bogota 1975 (Bogota)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6802"]], PRIMEM["Bogota", -74.08091666666668, AUTHORITY["EPSG","8904"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4802"]]
+2628=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 156E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 156.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2628"]]
+4801=GEOGCS["Bern 1898 (Bern)", DATUM["CH1903 (Bern)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6801"]], PRIMEM["Bern", 7.439583333333333, AUTHORITY["EPSG","8907"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4801"]]
+2627=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 153E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2627"]]
+4800=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 129E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4800"]]
+2626=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 150E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 150.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2626"]]
+2625=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 147E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2625"]]
+2624=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 144E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 144.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2624"]]
+2623=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 141E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2623"]]
+2622=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 138E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 138.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2622"]]
+2621=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 135E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2621"]]
+2620=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 132E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2620"]]
+66446405=GEOGCS["NEA74 Noumea (deg)", DATUM["NEA74 Noumea", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-10.18, -350.43, 291.37, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6644"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66446405"]]
+2619=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 129E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2619"]]
+2618=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 126E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2618"]]
+2617=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 123E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2617"]]
+2616=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 120E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2616"]]
+2615=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 117E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2615"]]
+2614=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 114E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2614"]]
+2613=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 111E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2613"]]
+2612=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 108E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 108.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2612"]]
+2611=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 105E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2611"]]
+2610=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 102E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2610"]]
+62676405=GEOGCS["NAD27 (deg)", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62676405"]]
+2609=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 99E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2609"]]
+2608=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 96E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2608"]]
+26899=PROJCS["NAD83(CSRS) / MTM zone 2", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -56.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26899"]]
+2607=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 93E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2607"]]
+26898=PROJCS["NAD83(CSRS) / MTM zone 1", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -53.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26898"]]
+2606=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 90E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2606"]]
+26897=PROJCS["NAD83(CSRS) / MTM zone 17", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26897"]]
+2605=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 87E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2605"]]
+26896=PROJCS["NAD83(CSRS) / MTM zone 16", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26896"]]
+2604=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 84E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2604"]]
+26895=PROJCS["NAD83(CSRS) / MTM zone 15", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26895"]]
+2603=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 81E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2603"]]
+26894=PROJCS["NAD83(CSRS) / MTM zone 14", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26894"]]
+2602=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 78E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2602"]]
+26893=PROJCS["NAD83(CSRS) / MTM zone 13", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26893"]]
+2601=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 75E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2601"]]
+26892=PROJCS["NAD83(CSRS) / MTM zone 12", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26892"]]
+2600=PROJCS["Lietuvos Koordinoei Sistema 1994", GEOGCS["LKS94", DATUM["Lithuania 1994 (ETRS89)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6126"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4669"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9998], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2600"]]
+26891=PROJCS["NAD83(CSRS) / MTM zone 11", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26891"]]
+61396405=GEOGCS["Puerto Rico (deg)", DATUM["Puerto Rico", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[11.0, 72.0, -101.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6139"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61396405"]]
+26870=PROJCS["NAD83(NSRS2007) / West Virginia South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 37.0], PARAMETER["standard_parallel_1", 38.88333333333333], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.483333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26870"]]
+26869=PROJCS["NAD83(NSRS2007) / West Virginia North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 38.5], PARAMETER["standard_parallel_1", 40.25], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26869"]]
+26868=PROJCS["NAD83(NSRS2007) / Nebraska (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 39.833333333333336], PARAMETER["standard_parallel_1", 43.0], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26868"]]
+26867=PROJCS["NAD83(NSRS2007) / Minnesota South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.0], PARAMETER["latitude_of_origin", 43.0], PARAMETER["standard_parallel_1", 45.21666666666667], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 328083.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.78333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26867"]]
+26866=PROJCS["NAD83(NSRS2007) / Minnesota Central (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.25], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 47.05], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 328083.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.61666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26866"]]
+26865=PROJCS["NAD83(NSRS2007) / Minnesota North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.1], PARAMETER["latitude_of_origin", 46.5], PARAMETER["standard_parallel_1", 48.63333333333333], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 328083.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.03333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26865"]]
+26864=PROJCS["NAD83(NSRS2007) / Maine West (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.16666666666667], PARAMETER["latitude_of_origin", 42.833333333333336], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 2952750.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26864"]]
+26863=PROJCS["NAD83(NSRS2007) / Maine East (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -68.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26863"]]
+26862=PROJCS["NAD83(HARN) / West Virginia South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 37.0], PARAMETER["standard_parallel_1", 38.88333333333333], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.483333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26862"]]
+26861=PROJCS["NAD83(HARN) / West Virginia North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 38.5], PARAMETER["standard_parallel_1", 40.25], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26861"]]
+26860=PROJCS["NAD83(HARN) / Nebraska (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 39.833333333333336], PARAMETER["standard_parallel_1", 43.0], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26860"]]
+62516405=GEOGCS["Liberia 1964 (deg)", DATUM["Liberia 1964", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-90.0, 40.0, 88.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6251"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62516405"]]
+26859=PROJCS["NAD83(HARN) / Minnesota South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.0], PARAMETER["latitude_of_origin", 43.0], PARAMETER["standard_parallel_1", 45.21666666666667], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 328083.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.78333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26859"]]
+26858=PROJCS["NAD83(HARN) / Minnesota Central (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.25], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 47.05], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 328083.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.61666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26858"]]
+26857=PROJCS["NAD83(HARN) / Minnesota North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.1], PARAMETER["latitude_of_origin", 46.5], PARAMETER["standard_parallel_1", 48.63333333333333], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 328083.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.03333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26857"]]
+26856=PROJCS["NAD83(HARN) / Maine West (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.16666666666667], PARAMETER["latitude_of_origin", 42.833333333333336], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 2952750.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26856"]]
+26855=PROJCS["NAD83(HARN) / Maine East (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -68.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26855"]]
+26854=PROJCS["NAD83 / West Virginia South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 37.0], PARAMETER["standard_parallel_1", 38.88333333333333], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.483333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26854"]]
+26853=PROJCS["NAD83 / West Virginia North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 38.5], PARAMETER["standard_parallel_1", 40.25], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26853"]]
+26852=PROJCS["NAD83 / Nebraska (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 39.833333333333336], PARAMETER["standard_parallel_1", 43.0], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26852"]]
+26851=PROJCS["NAD83 / Minnesota South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.0], PARAMETER["latitude_of_origin", 43.0], PARAMETER["standard_parallel_1", 45.21666666666667], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 328083.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.78333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26851"]]
+26850=PROJCS["NAD83 / Minnesota Central (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.25], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 47.05], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 328083.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.61666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26850"]]
+26849=PROJCS["NAD83 / Minnesota North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.1], PARAMETER["latitude_of_origin", 46.5], PARAMETER["standard_parallel_1", 48.63333333333333], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 328083.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.03333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26849"]]
+26848=PROJCS["NAD83 / Maine West (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.16666666666667], PARAMETER["latitude_of_origin", 42.833333333333336], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 2952750.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26848"]]
+26847=PROJCS["NAD83 / Maine East (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -68.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26847"]]
+26846=PROJCS["NAD83(NSRS2007) / West Virginia South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 37.0], PARAMETER["standard_parallel_1", 38.88333333333333], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.483333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26846"]]
+26845=PROJCS["NAD83(NSRS2007) / West Virginia North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 38.5], PARAMETER["standard_parallel_1", 40.25], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26845"]]
+26844=PROJCS["NAD83(NSRS2007) / Nebraska (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 39.833333333333336], PARAMETER["standard_parallel_1", 43.0], PARAMETER["false_easting", 500000.0000101601], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26844"]]
+26843=PROJCS["NAD83(NSRS2007) / Minnesota South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.0], PARAMETER["latitude_of_origin", 43.0], PARAMETER["standard_parallel_1", 45.21666666666667], PARAMETER["false_easting", 800000.0000101601], PARAMETER["false_northing", 99999.99998984], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.78333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26843"]]
+26842=PROJCS["NAD83(NSRS2007) / Minnesota Central (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.25], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 47.05], PARAMETER["false_easting", 800000.0000101601], PARAMETER["false_northing", 99999.99998984], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.61666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26842"]]
+26841=PROJCS["NAD83(NSRS2007) / Minnesota North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.1], PARAMETER["latitude_of_origin", 46.5], PARAMETER["standard_parallel_1", 48.63333333333333], PARAMETER["false_easting", 800000.0000101601], PARAMETER["false_northing", 99999.99998984], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.03333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26841"]]
+32260=PROJCS["WGS 72 / UTM zone 60N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32260"]]
+61236405=GEOGCS["KKJ (deg)", DATUM["Kartastokoordinaattijarjestelma (1966)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-96.062, -82.428, -121.753, 4.801, -0.345, 1.376, 1.496], AUTHORITY["EPSG","6123"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61236405"]]
+62186405=GEOGCS["Bogota 1975 (deg)", DATUM["Bogota 1975", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[304.5, 306.5, -318.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6218"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62186405"]]
+26837=PROJCS["NAD83(NSRS2007) / Maine West (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.16666666666667], PARAMETER["latitude_of_origin", 42.833333333333336], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 900000.0000000001], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26837"]]
+32259=PROJCS["WGS 72 / UTM zone 59N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32259"]]
+26836=PROJCS["NAD83(NSRS2007) / Maine East (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -68.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 300000.00000000006], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26836"]]
+32258=PROJCS["WGS 72 / UTM zone 58N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32258"]]
+26835=PROJCS["NAD83(HARN) / West Virginia South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 37.0], PARAMETER["standard_parallel_1", 38.88333333333333], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.483333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26835"]]
+32257=PROJCS["WGS 72 / UTM zone 57N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32257"]]
+26834=PROJCS["NAD83(HARN) / West Virginia North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 38.5], PARAMETER["standard_parallel_1", 40.25], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26834"]]
+32256=PROJCS["WGS 72 / UTM zone 56N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32256"]]
+26833=PROJCS["NAD83(HARN) / Nebraska (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 39.833333333333336], PARAMETER["standard_parallel_1", 43.0], PARAMETER["false_easting", 500000.0000101601], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26833"]]
+32255=PROJCS["WGS 72 / UTM zone 55N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32255"]]
+26832=PROJCS["NAD83(HARN) / Minnesota South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.0], PARAMETER["latitude_of_origin", 43.0], PARAMETER["standard_parallel_1", 45.21666666666667], PARAMETER["false_easting", 800000.0000101601], PARAMETER["false_northing", 99999.99998984], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.78333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26832"]]
+32254=PROJCS["WGS 72 / UTM zone 54N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32254"]]
+26831=PROJCS["NAD83(HARN) / Minnesota Central (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.25], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 47.05], PARAMETER["false_easting", 800000.0000101601], PARAMETER["false_northing", 99999.99998984], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.61666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26831"]]
+32253=PROJCS["WGS 72 / UTM zone 53N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32253"]]
+26830=PROJCS["NAD83(HARN) / Minnesota North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.1], PARAMETER["latitude_of_origin", 46.5], PARAMETER["standard_parallel_1", 48.63333333333333], PARAMETER["false_easting", 800000.0000101601], PARAMETER["false_northing", 99999.99998984], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.03333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26830"]]
+32252=PROJCS["WGS 72 / UTM zone 52N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32252"]]
+32251=PROJCS["WGS 72 / UTM zone 51N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32251"]]
+32250=PROJCS["WGS 72 / UTM zone 50N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32250"]]
+5299=PROJCS["DRUKREF 03 / Paro TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 89.35], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5299"]]
+5298=PROJCS["DRUKREF 03 / Mongar TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 91.23333333333333], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5298"]]
+5297=PROJCS["DRUKREF 03 / Lhuentse TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 91.13333333333333], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5297"]]
+5296=PROJCS["DRUKREF 03 / Ha TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.15], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5296"]]
+5295=PROJCS["DRUKREF 03 / Gasa TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.03333333333335], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5295"]]
+5294=PROJCS["DRUKREF 03 / Dagana TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 89.85], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5294"]]
+5293=PROJCS["DRUKREF 03 / Chhukha TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 89.55], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5293"]]
+5292=PROJCS["DRUKREF 03 / Bumthang TM", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.73333333333333], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", -2500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5292"]]
+32249=PROJCS["WGS 72 / UTM zone 49N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32249"]]
+26826=PROJCS["NAD83(HARN) / Maine West (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.16666666666667], PARAMETER["latitude_of_origin", 42.833333333333336], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 900000.0000000001], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26826"]]
+32248=PROJCS["WGS 72 / UTM zone 48N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32248"]]
+26825=PROJCS["NAD83(HARN) / Maine East (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -68.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 300000.00000000006], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26825"]]
+32247=PROJCS["WGS 72 / UTM zone 47N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32247"]]
+26824=PROJCS["NAD83 / West Virginia South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 37.0], PARAMETER["standard_parallel_1", 38.88333333333333], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.483333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26824"]]
+32246=PROJCS["WGS 72 / UTM zone 46N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32246"]]
+26823=PROJCS["NAD83 / West Virginia North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 38.5], PARAMETER["standard_parallel_1", 40.25], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26823"]]
+32245=PROJCS["WGS 72 / UTM zone 45N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32245"]]
+26822=PROJCS["NAD83 / Nebraska (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 39.833333333333336], PARAMETER["standard_parallel_1", 43.0], PARAMETER["false_easting", 500000.0000101601], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26822"]]
+32244=PROJCS["WGS 72 / UTM zone 44N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32244"]]
+26821=PROJCS["NAD83 / Minnesota South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.0], PARAMETER["latitude_of_origin", 43.0], PARAMETER["standard_parallel_1", 45.21666666666667], PARAMETER["false_easting", 800000.0000101601], PARAMETER["false_northing", 99999.99998984], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.78333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26821"]]
+32243=PROJCS["WGS 72 / UTM zone 43N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32243"]]
+26820=PROJCS["NAD83 / Minnesota Central (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.25], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 47.05], PARAMETER["false_easting", 800000.0000101601], PARAMETER["false_northing", 99999.99998984], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.61666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26820"]]
+32242=PROJCS["WGS 72 / UTM zone 42N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32242"]]
+32241=PROJCS["WGS 72 / UTM zone 41N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32241"]]
+32240=PROJCS["WGS 72 / UTM zone 40N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32240"]]
+26819=PROJCS["NAD83 / Minnesota North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.1], PARAMETER["latitude_of_origin", 46.5], PARAMETER["standard_parallel_1", 48.63333333333333], PARAMETER["false_easting", 800000.0000101601], PARAMETER["false_northing", 99999.99998984], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.03333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26819"]]
+32239=PROJCS["WGS 72 / UTM zone 39N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32239"]]
+32238=PROJCS["WGS 72 / UTM zone 38N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32238"]]
+26815=PROJCS["NAD83 / Maine West (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.16666666666667], PARAMETER["latitude_of_origin", 42.833333333333336], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 900000.0000000001], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26815"]]
+32237=PROJCS["WGS 72 / UTM zone 37N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32237"]]
+26814=PROJCS["NAD83 / Maine East (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -68.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 300000.00000000006], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26814"]]
+32236=PROJCS["WGS 72 / UTM zone 36N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32236"]]
+26813=PROJCS["NAD Michigan / Michigan South", GEOGCS["NAD27 Michigan", DATUM["NAD27 Michigan", SPHEROID["Clarke 1866 Michigan", 6378450.047548896, 294.978697164674, AUTHORITY["EPSG","7009"]], AUTHORITY["EPSG","6268"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4268"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.33333333333333], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.666666666666664], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.1], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26813"]]
+32235=PROJCS["WGS 72 / UTM zone 35N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32235"]]
+26812=PROJCS["NAD Michigan / Michigan Central", GEOGCS["NAD27 Michigan", DATUM["NAD27 Michigan", SPHEROID["Clarke 1866 Michigan", 6378450.047548896, 294.978697164674, AUTHORITY["EPSG","7009"]], AUTHORITY["EPSG","6268"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4268"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.33333333333333], PARAMETER["latitude_of_origin", 43.31666666666666], PARAMETER["standard_parallel_1", 45.699999999999996], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.18333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26812"]]
+32234=PROJCS["WGS 72 / UTM zone 34N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32234"]]
+26811=PROJCS["NAD Michigan / Michigan North", GEOGCS["NAD27 Michigan", DATUM["NAD27 Michigan", SPHEROID["Clarke 1866 Michigan", 6378450.047548896, 294.978697164674, AUTHORITY["EPSG","7009"]], AUTHORITY["EPSG","6268"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4268"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 44.78333333333333], PARAMETER["standard_parallel_1", 47.083333333333336], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.48333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26811"]]
+32233=PROJCS["WGS 72 / UTM zone 33N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32233"]]
+32232=PROJCS["WGS 72 / UTM zone 32N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32232"]]
+32231=PROJCS["WGS 72 / UTM zone 31N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32231"]]
+32230=PROJCS["WGS 72 / UTM zone 30N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32230"]]
+5275=PROJCS["TUREF / 3-degree Gauss-Kruger zone 15", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 15500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5275"]]
+5274=PROJCS["TUREF / 3-degree Gauss-Kruger zone 14", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 42.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 14500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5274"]]
+5273=PROJCS["TUREF / 3-degree Gauss-Kruger zone 13", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 13500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5273"]]
+3099=PROJCS["JGD2000 / UTM zone 53N", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3099"]]
+5272=PROJCS["TUREF / 3-degree Gauss-Kruger zone 12", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 36.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 12500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5272"]]
+3098=PROJCS["JGD2000 / UTM zone 52N", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3098"]]
+5271=PROJCS["TUREF / 3-degree Gauss-Kruger zone 11", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 11500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5271"]]
+3097=PROJCS["JGD2000 / UTM zone 51N", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3097"]]
+5270=PROJCS["TUREF / 3-degree Gauss-Kruger zone 10", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 10500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5270"]]
+3096=PROJCS["Tokyo / UTM zone 55N", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3096"]]
+3095=PROJCS["Tokyo / UTM zone 54N", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3095"]]
+3094=PROJCS["Tokyo / UTM zone 53N", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3094"]]
+3093=PROJCS["Tokyo / UTM zone 52N", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3093"]]
+3092=PROJCS["Tokyo / UTM zone 51N", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3092"]]
+3091=PROJCS["NAD83(HARN) / Kentucky Single Zone (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 38.666666666666664], PARAMETER["false_easting", 4921250.0], PARAMETER["false_northing", 3280833.333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.083333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3091"]]
+61786405=GEOGCS["Pulkovo 1942(83) (deg)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61786405"]]
+3090=PROJCS["NAD83(HARN) / Kentucky Single Zone", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 38.666666666666664], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.083333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3090"]]
+32229=PROJCS["WGS 72 / UTM zone 29N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32229"]]
+32228=PROJCS["WGS 72 / UTM zone 28N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32228"]]
+32227=PROJCS["WGS 72 / UTM zone 27N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32227"]]
+32226=PROJCS["WGS 72 / UTM zone 26N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32226"]]
+26803=PROJCS["NAD Michigan / Michigan West", GEOGCS["NAD27 Michigan", DATUM["NAD27 Michigan", SPHEROID["Clarke 1866 Michigan", 6378450.047548896, 294.978697164674, AUTHORITY["EPSG","7009"]], AUTHORITY["EPSG","6268"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4268"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.75], PARAMETER["latitude_of_origin", 41.5], PARAMETER["scale_factor", 0.999909091], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26803"]]
+32225=PROJCS["WGS 72 / UTM zone 25N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32225"]]
+26802=PROJCS["NAD Michigan / Michigan Old Central", GEOGCS["NAD27 Michigan", DATUM["NAD27 Michigan", SPHEROID["Clarke 1866 Michigan", 6378450.047548896, 294.978697164674, AUTHORITY["EPSG","7009"]], AUTHORITY["EPSG","6268"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4268"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 41.5], PARAMETER["scale_factor", 0.999909091], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26802"]]
+32224=PROJCS["WGS 72 / UTM zone 24N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32224"]]
+26801=PROJCS["NAD Michigan / Michigan East", GEOGCS["NAD27 Michigan", DATUM["NAD27 Michigan", SPHEROID["Clarke 1866 Michigan", 6378450.047548896, 294.978697164674, AUTHORITY["EPSG","7009"]], AUTHORITY["EPSG","6268"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4268"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -83.66666666666667], PARAMETER["latitude_of_origin", 41.5], PARAMETER["scale_factor", 0.999942857], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26801"]]
+32223=PROJCS["WGS 72 / UTM zone 23N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32223"]]
+32222=PROJCS["WGS 72 / UTM zone 22N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32222"]]
+32221=PROJCS["WGS 72 / UTM zone 21N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32221"]]
+32220=PROJCS["WGS 72 / UTM zone 20N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32220"]]
+5269=PROJCS["TUREF / 3-degree Gauss-Kruger zone 9", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 9500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5269"]]
+5266=PROJCS["DRUKREF 03 / Bhutan National Grid", GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5266"]]
+5264=GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5264"]]
+5263=GEOGCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5263"]]
+3089=PROJCS["NAD83 / Kentucky Single Zone (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 38.666666666666664], PARAMETER["false_easting", 4921250.0], PARAMETER["false_northing", 3280833.333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.083333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3089"]]
+5262=GEOCCS["DRUKREF 03", DATUM["Bhutan National Geodetic Datum", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1058"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5262"]]
+3088=PROJCS["NAD83 / Kentucky Single Zone", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 38.666666666666664], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.083333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3088"]]
+3087=PROJCS["NAD83(HARN) / Florida GDL Albers", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -84.0], PARAMETER["latitude_of_origin", 24.0], PARAMETER["standard_parallel_1", 24.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 31.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3087"]]
+3086=PROJCS["NAD83 / Florida GDL Albers", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -84.0], PARAMETER["latitude_of_origin", 24.0], PARAMETER["standard_parallel_1", 24.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 31.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3086"]]
+3085=PROJCS["NAD83(HARN) / Texas Centric Albers Equal Area", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 18.0], PARAMETER["standard_parallel_1", 27.5], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 6000000.0], PARAMETER["standard_parallel_2", 35.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3085"]]
+3084=PROJCS["NAD83(HARN) / Texas Centric Lambert Conformal", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 18.0], PARAMETER["standard_parallel_1", 35.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 5000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 27.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3084"]]
+3083=PROJCS["NAD83 / Texas Centric Albers Equal Area", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 18.0], PARAMETER["standard_parallel_1", 27.5], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 6000000.0], PARAMETER["standard_parallel_2", 35.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3083"]]
+3082=PROJCS["NAD83 / Texas Centric Lambert Conformal", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 18.0], PARAMETER["standard_parallel_1", 35.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 5000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 27.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3082"]]
+3081=PROJCS["NAD83 / Texas State Mapping System", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 31.166666666666668], PARAMETER["standard_parallel_1", 34.916666666666664], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 27.416666666666668], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3081"]]
+3080=PROJCS["NAD27 / Shackleford", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 31.166666666666668], PARAMETER["standard_parallel_1", 34.916666666666664], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 3000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 27.416666666666668], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3080"]]
+32219=PROJCS["WGS 72 / UTM zone 19N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32219"]]
+32218=PROJCS["WGS 72 / UTM zone 18N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32218"]]
+32217=PROJCS["WGS 72 / UTM zone 17N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32217"]]
+32216=PROJCS["WGS 72 / UTM zone 16N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32216"]]
+32215=PROJCS["WGS 72 / UTM zone 15N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32215"]]
+32214=PROJCS["WGS 72 / UTM zone 14N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32214"]]
+62026405=GEOGCS["AGD66 (deg)", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62026405"]]
+32213=PROJCS["WGS 72 / UTM zone 13N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32213"]]
+32212=PROJCS["WGS 72 / UTM zone 12N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32212"]]
+32211=PROJCS["WGS 72 / UTM zone 11N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32211"]]
+32210=PROJCS["WGS 72 / UTM zone 10N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32210"]]
+5259=PROJCS["TUREF / TM45", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5259"]]
+5258=PROJCS["TUREF / TM42", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 42.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5258"]]
+5257=PROJCS["TUREF / TM39", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5257"]]
+5256=PROJCS["TUREF / TM36", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 36.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5256"]]
+5255=PROJCS["TUREF / TM33", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5255"]]
+5254=PROJCS["TUREF / TM30", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5254"]]
+5253=PROJCS["TUREF / TM27", GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5253"]]
+3079=PROJCS["NAD83(HARN) / Michigan Oblique Mercator", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9812"]], PARAMETER["longitude_of_center", -86.0], PARAMETER["latitude_of_center", 45.30916666666668], PARAMETER["azimuth", 337.25555999999995], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 2546731.496], PARAMETER["false_northing", -4354009.816], PARAMETER["rectified_grid_angle", 337.25555999999995], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3079"]]
+5252=GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5252"]]
+3078=PROJCS["NAD83 / Michigan Oblique Mercator", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9812"]], PARAMETER["longitude_of_center", -86.0], PARAMETER["latitude_of_center", 45.30916666666668], PARAMETER["azimuth", 337.25555999999995], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 2546731.496], PARAMETER["false_northing", -4354009.816], PARAMETER["rectified_grid_angle", 337.25555999999995], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3078"]]
+5251=GEOGCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5251"]]
+20258=PROJCS["AGD66 / AMG zone 58", GEOGCS["AGD66", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4202"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20258"]]
+3077=PROJCS["NAD83(HARN) / Maine CS2000 West", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.375], PARAMETER["latitude_of_origin", 42.833333333333336], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3077"]]
+5250=GEOCCS["TUREF", DATUM["Turkish National Reference Frame", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1057"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5250"]]
+20257=PROJCS["AGD66 / AMG zone 57", GEOGCS["AGD66", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4202"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20257"]]
+3076=PROJCS["NAD83(HARN) / Maine CS2000 Central", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.12499999999997], PARAMETER["latitude_of_origin", 43.0], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3076"]]
+20256=PROJCS["AGD66 / AMG zone 56", GEOGCS["AGD66", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4202"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20256"]]
+3075=PROJCS["NAD83(HARN) / Maine CS2000 East", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -67.875], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3075"]]
+20255=PROJCS["AGD66 / AMG zone 55", GEOGCS["AGD66", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4202"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20255"]]
+3074=PROJCS["NAD83 / Maine CS2000 West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.375], PARAMETER["latitude_of_origin", 42.833333333333336], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3074"]]
+20254=PROJCS["AGD66 / AMG zone 54", GEOGCS["AGD66", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4202"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20254"]]
+3073=PROJCS["NAD83 / Maine CS2000 Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.12499999999997], PARAMETER["latitude_of_origin", 43.0], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3073"]]
+20253=PROJCS["AGD66 / AMG zone 53", GEOGCS["AGD66", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4202"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20253"]]
+3072=PROJCS["NAD83 / Maine CS2000 East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -67.875], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["scale_factor", 0.99998], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3072"]]
+20252=PROJCS["AGD66 / AMG zone 52", GEOGCS["AGD66", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4202"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20252"]]
+3071=PROJCS["NAD83(HARN) / Wisconsin Transverse Mercator", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 520000.0], PARAMETER["false_northing", -4480000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3071"]]
+20251=PROJCS["AGD66 / AMG zone 51", GEOGCS["AGD66", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4202"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20251"]]
+3070=PROJCS["NAD83 / Wisconsin Transverse Mercator", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 520000.0], PARAMETER["false_northing", -4480000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3070"]]
+20250=PROJCS["AGD66 / AMG zone 50", GEOGCS["AGD66", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4202"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20250"]]
+32209=PROJCS["WGS 72 / UTM zone 9N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32209"]]
+32208=PROJCS["WGS 72 / UTM zone 8N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32208"]]
+32207=PROJCS["WGS 72 / UTM zone 7N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32207"]]
+32206=PROJCS["WGS 72 / UTM zone 6N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32206"]]
+32205=PROJCS["WGS 72 / UTM zone 5N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32205"]]
+32204=PROJCS["WGS 72 / UTM zone 4N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32204"]]
+32203=PROJCS["WGS 72 / UTM zone 3N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32203"]]
+32202=PROJCS["WGS 72 / UTM zone 2N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32202"]]
+32201=PROJCS["WGS 72 / UTM zone 1N", GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32201"]]
+7422=COMPD_CS["NTF (Paris) / Lambert zone III + NGF IGN69 height", PROJCS["NTF (Paris) / Lambert zone III", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 49.0], PARAMETER["scale_factor", 0.999877499], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 3200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27573"]], VERT_CS["NGF IGN69 height", VERT_DATUM["Nivellement General de la France - IGN69", 2005, AUTHORITY["EPSG","5119"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5720"]], AUTHORITY["EPSG","7422"]]
+7421=COMPD_CS["NTF (Paris) / Lambert zone II + NGF IGN69 height", PROJCS["NTF (Paris) / Lambert zone II", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 52.0], PARAMETER["scale_factor", 0.99987742], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 2200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27572"]], VERT_CS["NGF IGN69 height", VERT_DATUM["Nivellement General de la France - IGN69", 2005, AUTHORITY["EPSG","5119"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5720"]], AUTHORITY["EPSG","7421"]]
+5247=PROJCS["GDBD2009 / Brunei BRSO", GEOGCS["GDBD2009", DATUM["Geocentric Datum Brunei Darussalam 2009", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","1056"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5246"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9812"]], PARAMETER["longitude_of_center", 115.0], PARAMETER["latitude_of_center", 4.0], PARAMETER["azimuth", 53.31580995000001], PARAMETER["scale_factor", 0.99984], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["rectified_grid_angle", 53.13010236111111], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5247"]]
+7420=COMPD_CS["ETRS89 / Kp2000 Bornholm + DVR90 height", PROJCS["ETRS89 / Kp2000 Bornholm", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 900000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2198"]], VERT_CS["DVR90 height", VERT_DATUM["Dansk Vertikal Reference 1990", 2005, AUTHORITY["EPSG","5206"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5799"]], AUTHORITY["EPSG","7420"]]
+24600=PROJCS["KOC Lambert", GEOGCS["KOC", DATUM["Kuwait Oil Company", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-294.7, -200.1, 525.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6246"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4246"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 32.5], PARAMETER["scale_factor", 0.9987864078], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 1166200.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24600"]]
+5246=GEOGCS["GDBD2009", DATUM["Geocentric Datum Brunei Darussalam 2009", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","1056"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5246"]]
+5245=GEOGCS["GDBD2009", DATUM["Geocentric Datum Brunei Darussalam 2009", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","1056"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5245"]]
+5244=GEOCCS["GDBD2009", DATUM["Geocentric Datum Brunei Darussalam 2009", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","1056"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5244"]]
+5243=PROJCS["ETRS89 / LCC Germany (E-N)", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 10.5], PARAMETER["latitude_of_origin", 51.0], PARAMETER["standard_parallel_1", 53.66666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 48.66666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5243"]]
+3069=PROJCS["NAD27 / Wisconsin Transverse Mercator", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", -4500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3069"]]
+20249=PROJCS["AGD66 / AMG zone 49", GEOGCS["AGD66", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4202"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20249"]]
+3068=PROJCS["DHDN / Soldner Berlin", GEOGCS["DHDN", DATUM["Deutsches Hauptdreiecksnetz", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[612.4, 77.0, 440.2, -0.054, 0.057, -2.797, 2.55], AUTHORITY["EPSG","6314"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4314"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 13.627203666666668], PARAMETER["latitude_of_origin", 52.418648277777784], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 40000.0], PARAMETER["false_northing", 10000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3068"]]
+20248=PROJCS["AGD66 / AMG zone 48", GEOGCS["AGD66", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4202"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20248"]]
+3067=PROJCS["ETRS89 / TM35FIN(E,N)", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3067"]]
+3066=PROJCS["ED50 / Jordan TM", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 37.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9998], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", -3000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3066"]]
+3065=PROJCS["IGM95 / UTM zone 33N", GEOGCS["IGM95", DATUM["Istituto Geografico Militaire 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6670"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4670"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3065"]]
+3064=PROJCS["IGM95 / UTM zone 32N", GEOGCS["IGM95", DATUM["Istituto Geografico Militaire 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6670"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4670"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3064"]]
+3063=PROJCS["Azores Central 1995 / UTM zone 26N", GEOGCS["Azores Central 1995", DATUM["Azores Central Islands 1995", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-103.088, 162.481, -28.276, 0.167, -0.082, -0.168, -1.504], AUTHORITY["EPSG","6665"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4665"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3063"]]
+3062=PROJCS["Azores Oriental 1995 / UTM zone 26N", GEOGCS["Azores Oriental 1995", DATUM["Azores Oriental Islands 1995", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.719, 129.685, 52.092, -0.195, 0.014, -0.327, 0.198], AUTHORITY["EPSG","6664"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4664"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3062"]]
+3061=PROJCS["Porto Santo 1995 / UTM zone 28N", GEOGCS["Porto Santo 1995", DATUM["Porto Santo 1995", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-210.502, -66.902, -48.476, 2.094, 15.067, 5.817, 0.485], AUTHORITY["EPSG","6663"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4663"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3061"]]
+3060=PROJCS["IGN72 Grande Terre / UTM zone 58S", GEOGCS["IGN72 Grande Terre", DATUM["IGN72 Grande Terre", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-11.64, -348.6, 291.98, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6634"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4662"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3060"]]
+7419=COMPD_CS["ETRS89 / Kp2000 Zealand + DVR90 height", PROJCS["ETRS89 / Kp2000 Zealand", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2197"]], VERT_CS["DVR90 height", VERT_DATUM["Dansk Vertikal Reference 1990", 2005, AUTHORITY["EPSG","5206"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5799"]], AUTHORITY["EPSG","7419"]]
+7418=COMPD_CS["ETRS89 / Kp2000 Jutland + DVR90 height", PROJCS["ETRS89 / Kp2000 Jutland", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2196"]], VERT_CS["DVR90 height", VERT_DATUM["Dansk Vertikal Reference 1990", 2005, AUTHORITY["EPSG","5206"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5799"]], AUTHORITY["EPSG","7418"]]
+7417=COMPD_CS["ETRS89 / UTM zone 33N + DVR90 height", PROJCS["ETRS89 / UTM zone 33N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25833"]], VERT_CS["DVR90 height", VERT_DATUM["Dansk Vertikal Reference 1990", 2005, AUTHORITY["EPSG","5206"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5799"]], AUTHORITY["EPSG","7417"]]
+7416=COMPD_CS["ETRS89 / UTM zone 32N + DVR90 height", PROJCS["ETRS89 / UTM zone 32N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25832"]], VERT_CS["DVR90 height", VERT_DATUM["Dansk Vertikal Reference 1990", 2005, AUTHORITY["EPSG","5206"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5799"]], AUTHORITY["EPSG","7416"]]
+7415=COMPD_CS["Amersfoort / RD New + NAP height", PROJCS["Amersfoort / RD New", GEOGCS["Amersfoort", DATUM["Amersfoort", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[565.2369, 50.0087, 465.658, -0.40685733032239757, -0.3507326765425626, 1.8703473836067959, 4.0812], AUTHORITY["EPSG","6289"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4289"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 5.387638888888891], PARAMETER["latitude_of_origin", 52.15616055555556], PARAMETER["scale_factor", 0.9999079], PARAMETER["false_easting", 155000.0], PARAMETER["false_northing", 463000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28992"]], VERT_CS["NAP height", VERT_DATUM["Normaal Amsterdams Peil", 2005, AUTHORITY["EPSG","5109"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5709"]], AUTHORITY["EPSG","7415"]]
+7413=COMPD_CS["NTF (Paris) / Lambert zone III + NGF IGN69", PROJCS["NTF (Paris) / Lambert zone III", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 49.0], PARAMETER["scale_factor", 0.999877499], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 3200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27573"]], VERT_CS["NGF Lallemand height", VERT_DATUM["Nivellement General de la France - Lallemand", 2005, AUTHORITY["EPSG","5118"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5719"]], AUTHORITY["EPSG","7413"]]
+7412=COMPD_CS["NTF (Paris) / Lambert zone II + NGF IGN69", PROJCS["NTF (Paris) / Lambert zone II", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 52.0], PARAMETER["scale_factor", 0.99987742], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 2200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27572"]], VERT_CS["NGF Lallemand height", VERT_DATUM["Nivellement General de la France - Lallemand", 2005, AUTHORITY["EPSG","5118"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5719"]], AUTHORITY["EPSG","7412"]]
+7411=COMPD_CS["NTF (Paris) / Lambert zone II + NGF Lallemand height", PROJCS["NTF (Paris) / Lambert zone II", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 52.0], PARAMETER["scale_factor", 0.99987742], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 2200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27572"]], VERT_CS["NGF Lallemand height", VERT_DATUM["Nivellement General de la France - Lallemand", 2005, AUTHORITY["EPSG","5118"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5719"]], AUTHORITY["EPSG","7411"]]
+5237=VERT_CS["SLVD height", VERT_DATUM["Sri Lanka Vertical Datum", 2005, AUTHORITY["EPSG","1054"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5237"]]
+5235=PROJCS["SLD99 / Sri Lanka Grid 1999", GEOGCS["SLD99", DATUM["Sri Lanka Datum 1999", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[-0.293, 766.95, 87.713, 0.195704, -1.695068, -3.473016, -0.039338], AUTHORITY["EPSG","1053"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5233"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 80.77171308333332], PARAMETER["latitude_of_origin", 7.000471527777781], PARAMETER["scale_factor", 0.9999238418], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5235"]]
+5234=PROJCS["Kandawala / Sri Lanka Grid", GEOGCS["Kandawala", DATUM["Kandawala", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[-97.0, 787.0, 86.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6244"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4244"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 80.77171111111112], PARAMETER["latitude_of_origin", 7.0004802777777755], PARAMETER["scale_factor", 0.9999238418], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5234"]]
+5233=GEOGCS["SLD99", DATUM["Sri Lanka Datum 1999", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[-0.293, 766.95, 87.713, 0.195704, -1.695068, -3.473016, -0.039338], AUTHORITY["EPSG","1053"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5233"]]
+3059=PROJCS["LKS92 / Latvia TM", GEOGCS["LKS92", DATUM["Latvia 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6661"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4661"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", -6000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3059"]]
+3058=PROJCS["Helle 1954 / Jan Mayen Grid", GEOGCS["Helle 1954", DATUM["Helle 1954", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[982.6087, 552.753, -540.873, 6.681626625276941, -31.61149240864225, -19.848161004816845, 16.805], AUTHORITY["EPSG","6660"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4660"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -8.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 50000.0], PARAMETER["false_northing", -7800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3058"]]
+3057=PROJCS["ISN93 / Lambert 1993", GEOGCS["ISN93", DATUM["Islands Net 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6659"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4659"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -19.0], PARAMETER["latitude_of_origin", 65.0], PARAMETER["standard_parallel_1", 65.75], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 64.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3057"]]
+3056=PROJCS["Hjorsey 1955 / UTM zone 28N", GEOGCS["Hjorsey 1955", DATUM["Hjorsey 1955", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-73.0, 46.0, -86.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6658"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4658"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3056"]]
+3055=PROJCS["Hjorsey 1955 / UTM zone 27N", GEOGCS["Hjorsey 1955", DATUM["Hjorsey 1955", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-73.0, 46.0, -86.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6658"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4658"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3055"]]
+3054=PROJCS["Hjorsey 1955 / UTM zone 26N", GEOGCS["Hjorsey 1955", DATUM["Hjorsey 1955", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-73.0, 46.0, -86.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6658"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4658"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3054"]]
+3051=PROJCS["ETRS89 / TM39", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3051"]]
+3050=PROJCS["ETRS89 / TM38", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3050"]]
+66346405=GEOGCS["IGN72 Grande Terre (deg)", DATUM["IGN72 Grande Terre", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-11.64, -348.6, 291.98, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6634"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66346405"]]
+61626405=GEOGCS["Korean 1985 (deg)", DATUM["Korean Datum 1985", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6162"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61626405"]]
+7407=COMPD_CS["NAD27 / Texas North + NGVD29 height", PROJCS["NAD27 / Texas North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -101.5], PARAMETER["latitude_of_origin", 34.0], PARAMETER["standard_parallel_1", 36.18333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.65], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32037"]], VERT_CS["NGVD29 height", VERT_DATUM["National Geodetic Vertical Datum 1929", 2005, AUTHORITY["EPSG","5102"]], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5702"]], AUTHORITY["EPSG","7407"]]
+7405=COMPD_CS["OSGB 1936 / British National Grid + ODN height", PROJCS["OSGB 1936 / British National Grid", GEOGCS["OSGB 1936", DATUM["OSGB 1936", SPHEROID["Airy 1830", 6377563.396, 299.3249646, AUTHORITY["EPSG","7001"]], TOWGS84[446.448, -125.157, 542.06, 0.15, 0.247, 0.842, -20.489], AUTHORITY["EPSG","6277"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4277"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -2.0], PARAMETER["latitude_of_origin", 49.0], PARAMETER["scale_factor", 0.9996012717], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", -100000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27700"]], VERT_CS["ODN height", VERT_DATUM["Ordnance Datum Newlyn", 2005, AUTHORITY["EPSG","5101"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5701"]], AUTHORITY["EPSG","7405"]]
+7403=COMPD_CS["NTF (Paris) / France III + NGF IGN69", PROJCS["NTF (Paris) / France III", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 49.0], PARAMETER["scale_factor", 0.999877499], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 3200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27583"]], VERT_CS["NGF IGN69 height", VERT_DATUM["Nivellement General de la France - IGN69", 2005, AUTHORITY["EPSG","5119"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5720"]], AUTHORITY["EPSG","7403"]]
+5229=GEOGCS["S-JTSK/05 (Ferro)", DATUM["System Jednotne Trigonometricke Site Katastralni/05 (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","1055"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5229"]]
+7402=COMPD_CS["NTF (Paris) / France II + NGF IGN69", PROJCS["NTF (Paris) / France II", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 52.0], PARAMETER["scale_factor", 0.99987742], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 2200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27582"]], VERT_CS["NGF IGN69 height", VERT_DATUM["Nivellement General de la France - IGN69", 2005, AUTHORITY["EPSG","5119"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5720"]], AUTHORITY["EPSG","7402"]]
+5228=GEOGCS["S-JTSK/05", DATUM["System Jednotne Trigonometricke Site Katastralni/05", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[572.213, 85.334, 461.94, 4.9732, -1.529, -5.2484, 3.5378], AUTHORITY["EPSG","1052"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5228"]]
+7401=COMPD_CS["NTF (Paris) / France II + NGF Lallemand", PROJCS["NTF (Paris) / France II", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4807"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 52.0], PARAMETER["scale_factor", 0.99987742], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 2200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27582"]], VERT_CS["NGF Lallemand height", VERT_DATUM["Nivellement General de la France - Lallemand", 2005, AUTHORITY["EPSG","5118"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5719"]], AUTHORITY["EPSG","7401"]]
+62576405=GEOGCS["Makassar (deg)", DATUM["Makassar", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-587.8, 519.75, 145.76, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6257"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62576405"]]
+5223=PROJCS["WGS 84 / Gabon TM", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5223"]]
+3049=PROJCS["ETRS89 / TM37", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3049"]]
+3048=PROJCS["ETRS89 / TM36", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3048"]]
+3047=PROJCS["ETRS89 / TM35", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3047"]]
+3046=PROJCS["ETRS89 / TM34", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3046"]]
+3045=PROJCS["ETRS89 / TM33", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3045"]]
+3044=PROJCS["ETRS89 / TM32", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3044"]]
+3043=PROJCS["ETRS89 / TM31", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3043"]]
+3042=PROJCS["ETRS89 / TM30", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3042"]]
+3041=PROJCS["ETRS89 / TM29", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3041"]]
+3040=PROJCS["ETRS89 / TM28", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3040"]]
+5214=VERT_CS["Genoa height", VERT_DATUM["Genoa", 2005, AUTHORITY["EPSG","1051"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5214"]]
+3039=PROJCS["ETRS89 / TM27", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3039"]]
+3038=PROJCS["ETRS89 / TM26", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3038"]]
+3037=PROJCS["Moznet / UTM zone 37S", GEOGCS["Moznet", DATUM["Moznet (ITRF94)", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6130"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4130"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3037"]]
+3036=PROJCS["Moznet / UTM zone 36S", GEOGCS["Moznet", DATUM["Moznet (ITRF94)", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6130"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4130"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3036"]]
+3035=PROJCS["ETRS89 / LAEA Europe", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Lambert_Azimuthal_Equal_Area", AUTHORITY["EPSG","9820"]], PARAMETER["latitude_of_center", 52.0], PARAMETER["longitude_of_center", 10.0], PARAMETER["false_easting", 4321000.0], PARAMETER["false_northing", 3210000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3035"]]
+3034=PROJCS["ETRS89 / LCC Europe", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 10.0], PARAMETER["latitude_of_origin", 52.0], PARAMETER["standard_parallel_1", 65.0], PARAMETER["false_easting", 4000000.0], PARAMETER["false_northing", 2800000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3034"]]
+3033=PROJCS["WGS 84 / Australian Antarctic Lambert", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 70.0], PARAMETER["latitude_of_origin", -50.0], PARAMETER["standard_parallel_1", -68.5], PARAMETER["false_easting", 6000000.0], PARAMETER["false_northing", 6000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -74.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3033"]]
+3032=PROJCS["WGS 84 / Australian Antarctic Polar Stereographic", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 70.0], PARAMETER["Standard_Parallel_1", -71.0], PARAMETER["false_easting", 6000000.0], PARAMETER["false_northing", 6000000.0], UNIT["m", 1.0], AXIS["Easting", "North along 160 deg East"], AXIS["Northing", "North along 70 deg East"], AUTHORITY["EPSG","3032"]]
+3031=PROJCS["WGS 84 / Antarctic Polar Stereographic", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 0.0], PARAMETER["Standard_Parallel_1", -71.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 90 deg East"], AXIS["Northing", "North along 0 deg"], AUTHORITY["EPSG","3031"]]
+3030=PROJCS["RT38 5 gon O", GEOGCS["RT38", DATUM["Stockholm 1938", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6308"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4308"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 22.55827777777777], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3030"]]
+3029=PROJCS["RT38 2.5 gon O", GEOGCS["RT38", DATUM["Stockholm 1938", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6308"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4308"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 20.308277777777786], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3029"]]
+61296405=GEOGCS["Observatario (deg)", DATUM["Observatario", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6129"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61296405"]]
+3028=PROJCS["RT38 0 gon", GEOGCS["RT38", DATUM["Stockholm 1938", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6308"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4308"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.058277777777775], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3028"]]
+3027=PROJCS["RT38 2.5 gon V", GEOGCS["RT38", DATUM["Stockholm 1938", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6308"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4308"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.808277777777775], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3027"]]
+63116405=GEOGCS["Zanderij (deg)", DATUM["Zanderij", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-265.0, 120.0, -358.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6311"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63116405"]]
+3026=PROJCS["RT38 5 gon V", GEOGCS["RT38", DATUM["Stockholm 1938", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6308"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4308"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 13.558277777777773], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3026"]]
+3025=PROJCS["RT38 7.5 gon V", GEOGCS["RT38", DATUM["Stockholm 1938", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6308"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4308"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 11.308277777777777], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3025"]]
+3024=PROJCS["RT90 5 gon O", GEOGCS["RT90", DATUM["Rikets koordinatsystem 1990", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[414.1, 41.3, 603.1, -0.855, -2.141, 7.023, 0.0], AUTHORITY["EPSG","6124"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4124"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 22.55827777777777], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3024"]]
+3023=PROJCS["RT90 2.5 gon O", GEOGCS["RT90", DATUM["Rikets koordinatsystem 1990", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[414.1, 41.3, 603.1, -0.855, -2.141, 7.023, 0.0], AUTHORITY["EPSG","6124"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4124"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 20.308277777777786], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3023"]]
+3022=PROJCS["RT90 0 gon", GEOGCS["RT90", DATUM["Rikets koordinatsystem 1990", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[414.1, 41.3, 603.1, -0.855, -2.141, 7.023, 0.0], AUTHORITY["EPSG","6124"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4124"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.058277777777775], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3022"]]
+3021=PROJCS["RT90 2.5 gon V", GEOGCS["RT90", DATUM["Rikets koordinatsystem 1990", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[414.1, 41.3, 603.1, -0.855, -2.141, 7.023, 0.0], AUTHORITY["EPSG","6124"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4124"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.808277777777775], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3021"]]
+3020=PROJCS["RT90 5 gon V", GEOGCS["RT90", DATUM["Rikets koordinatsystem 1990", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[414.1, 41.3, 603.1, -0.855, -2.141, 7.023, 0.0], AUTHORITY["EPSG","6124"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4124"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 13.558277777777773], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3020"]]
+3019=PROJCS["RT90 7.5 gon V", GEOGCS["RT90", DATUM["Rikets koordinatsystem 1990", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[414.1, 41.3, 603.1, -0.855, -2.141, 7.023, 0.0], AUTHORITY["EPSG","6124"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4124"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 11.308277777777777], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3019"]]
+3018=PROJCS["SWEREF99 23 15", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 23.25], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3018"]]
+3017=PROJCS["SWEREF99 21 45", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.75], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3017"]]
+3016=PROJCS["SWEREF99 20 15", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 20.25], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3016"]]
+3015=PROJCS["SWEREF99 18 45", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.75], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3015"]]
+3014=PROJCS["SWEREF99 17 15", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 17.25], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3014"]]
+3013=PROJCS["SWEREF99 15 45", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.75], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3013"]]
+3012=PROJCS["SWEREF99 14 15", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 14.25], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3012"]]
+3011=PROJCS["SWEREF99 18 00", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3011"]]
+3010=PROJCS["SWEREF99 16 30", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 16.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3010"]]
+3009=PROJCS["SWEREF99 15 00", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3009"]]
+3008=PROJCS["SWEREF99 13 30", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 13.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3008"]]
+62416405=GEOGCS["Jamaica 1875 (deg)", DATUM["Jamaica 1875", SPHEROID["Clarke 1880", 6378249.144808011, 293.46630765562986, AUTHORITY["EPSG","7034"]], AUTHORITY["EPSG","6241"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62416405"]]
+3007=PROJCS["SWEREF99 12 00", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3007"]]
+3006=PROJCS["SWEREF99 TM", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3006"]]
+3005=PROJCS["NAD83 / BC Albers", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -126.0], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 50.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 58.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3005"]]
+3004=PROJCS["Monte Mario / Italy zone 2", GEOGCS["Monte Mario", DATUM["Monte Mario", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-104.1, -49.1, -9.9, 0.971, -2.917, 0.714, -11.68], AUTHORITY["EPSG","6265"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4265"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 2520000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3004"]]
+3003=PROJCS["Monte Mario / Italy zone 1", GEOGCS["Monte Mario", DATUM["Monte Mario", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-104.1, -49.1, -9.9, 0.971, -2.917, 0.714, -11.68], AUTHORITY["EPSG","6265"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4265"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3003"]]
+3002=PROJCS["Makassar / NEIEZ", GEOGCS["Makassar", DATUM["Makassar", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-587.8, 519.75, 145.76, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6257"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4257"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9804"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 110.0], PARAMETER["scale_factor", 0.997], PARAMETER["false_easting", 3900000.0], PARAMETER["false_northing", 900000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3002"]]
+3001=PROJCS["Batavia / NEIEZ", GEOGCS["Batavia", DATUM["Batavia", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-377.7, 675.1, -52.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6211"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4211"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9804"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 110.0], PARAMETER["scale_factor", 0.997], PARAMETER["false_easting", 3900000.0], PARAMETER["false_northing", 900000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3001"]]
+27292=PROJCS["NZGD49 / South Island Grid", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.5], PARAMETER["latitude_of_origin", -44.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], UNIT["m*0.9143984146160287", 0.9143984146160287], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27292"]]
+3000=PROJCS["Segara / NEIEZ", GEOGCS["Segara", DATUM["Gunung Segara", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-404.78, 685.68, 45.47, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6613"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4613"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9804"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 110.0], PARAMETER["scale_factor", 0.997], PARAMETER["false_easting", 3900000.0], PARAMETER["false_northing", 900000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3000"]]
+27291=PROJCS["NZGD49 / North Island Grid", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 175.5], PARAMETER["latitude_of_origin", -39.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 400000.0], UNIT["m*0.9143984146160287", 0.9143984146160287], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27291"]]
+4799=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 126E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4799"]]
+4798=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 123E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4798"]]
+4797=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 120E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4797"]]
+4796=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 117E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4796"]]
+4795=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 114E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4795"]]
+4794=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 111E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4794"]]
+4793=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 108E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 108.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4793"]]
+4792=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 105E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4792"]]
+4791=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 102E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4791"]]
+4790=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 99E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4790"]]
+62086405=GEOGCS["Aratu (deg)", DATUM["Aratu", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-151.99, 287.04, -147.45, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6208"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62086405"]]
+4789=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 96E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4789"]]
+4788=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 93E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4788"]]
+4787=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 90E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4787"]]
+4786=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 87E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4786"]]
+4785=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 84E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4785"]]
+4784=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 81E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4784"]]
+4783=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 78E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4783"]]
+4782=PROJCS["New Beijing / 3-degree Gauss-Kruger CM 75E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4782"]]
+4781=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 45", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 45500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4781"]]
+27260=PROJCS["NZGD49 / UTM zone 60S", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27260"]]
+4780=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 44", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 44500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4780"]]
+27259=PROJCS["NZGD49 / UTM zone 59S", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27259"]]
+4779=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 43", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 43500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4779"]]
+27258=PROJCS["NZGD49 / UTM zone 58S", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27258"]]
+4778=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 42", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 42500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4778"]]
+4777=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 41", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 41500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4777"]]
+4776=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 40", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 40500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4776"]]
+4775=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 39", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 39500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4775"]]
+4774=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 38", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 38500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4774"]]
+4773=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 37", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 37500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4773"]]
+2599=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 72E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 72.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2599"]]
+4772=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 36", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 108.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 36500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4772"]]
+2598=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 69E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2598"]]
+4771=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 35", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 35500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4771"]]
+2597=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 66E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 66.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2597"]]
+4770=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 34", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 34500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4770"]]
+2596=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 63E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2596"]]
+2595=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 60E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 60.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2595"]]
+2594=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 57E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2594"]]
+2593=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 54E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 54.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2593"]]
+2592=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 51E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2592"]]
+2591=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 48E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 48.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2591"]]
+2590=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 45E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2590"]]
+4769=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 33", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 33500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4769"]]
+4768=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 32", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 32500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4768"]]
+4767=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 31", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 31500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4767"]]
+4766=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 30", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 30500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4766"]]
+4765=GEOGCS["Slovenia 1996", DATUM["Slovenia Geodetic Datum 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6765"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4765"]]
+4764=GEOGCS["RSRGD2000", DATUM["Ross Sea Region Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6764"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4764"]]
+4763=GEOGCS["Pitcairn 2006", DATUM["Pitcairn 2006", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6763"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4763"]]
+2589=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 42E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 42.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2589"]]
+4762=GEOGCS["BDA2000", DATUM["Bermuda 2000", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6762"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4762"]]
+2588=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 39E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2588"]]
+4761=GEOGCS["HTRS96", DATUM["Croatian Terrestrial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6761"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4761"]]
+2587=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 36E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 36.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2587"]]
+4760=GEOGCS["WGS 66", DATUM["World Geodetic System 1966", SPHEROID["NWL 9D", 6378145.0, 298.25, AUTHORITY["EPSG","7025"]], AUTHORITY["EPSG","6760"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4760"]]
+2586=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 33E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2586"]]
+2585=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 30E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2585"]]
+2584=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 27E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2584"]]
+2583=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 24E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2583"]]
+61686405=GEOGCS["Accra (deg)", DATUM["Accra", SPHEROID["War Office", 6378300.0, 296.0, AUTHORITY["EPSG","7029"]], TOWGS84[-199.0, 32.0, 322.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6168"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61686405"]]
+2582=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger CM 21E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2582"]]
+2581=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 64", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -168.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 64500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2581"]]
+2580=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 63", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 63500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2580"]]
+4759=GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]]
+4758=GEOGCS["JAD2001", DATUM["Jamaica 2001", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6758"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4758"]]
+4757=GEOGCS["SVY21", DATUM["SVY21", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6757"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4757"]]
+4756=GEOGCS["VN-2000", DATUM["Vietnam 2000", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[-192.873, -39.382, -111.202, -0.00205, 0.0005, -0.00335, 0.0188], AUTHORITY["EPSG","6756"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4756"]]
+4755=GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]]
+4754=GEOGCS["LGD2006", DATUM["Libyan Geodetic Datum 2006", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.4058, -109.8777, -2.5764, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6754"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4754"]]
+4753=GEOGCS["fk89", DATUM["fk89", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6753"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4753"]]
+27232=PROJCS["NZGD49 / Bluff Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 168.342872], PARAMETER["latitude_of_origin", -46.60000961111111], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300002.66], PARAMETER["false_northing", 699999.58], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27232"]]
+2579=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 62", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -174.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 62500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2579"]]
+4752=GEOGCS["Viti Levu 1912", DATUM["Viti Levu 1912", SPHEROID["Clarke 1880 (international foot)", 6378306.3696, 293.46630765562986, AUTHORITY["EPSG","7055"]], TOWGS84[51.0, 391.0, -36.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6752"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4752"]]
+27231=PROJCS["NZGD49 / North Taieri Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 170.28258911111106], PARAMETER["latitude_of_origin", -45.86151336111111], PARAMETER["scale_factor", 0.99996], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27231"]]
+2578=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 61", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 61500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2578"]]
+4751=GEOGCS["Kertau (RSO)", DATUM["Kertau (RSO)", SPHEROID["Everest 1830 (RSO 1969)", 6377295.664, 300.8017, AUTHORITY["EPSG","7056"]], AUTHORITY["EPSG","6751"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4751"]]
+27230=PROJCS["NZGD49 / Observation Point Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 170.62859516666666], PARAMETER["latitude_of_origin", -45.816196611111124], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27230"]]
+2577=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 60", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 180.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 60000000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2577"]]
+4750=GEOGCS["ST87 Ouvea", DATUM["ST87 Ouvea", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[-56.263, 16.136, -22.856, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6750"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4750"]]
+2576=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 59", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 59500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2576"]]
+2575=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 58", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 174.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 58500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2575"]]
+2574=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 57", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 57500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2574"]]
+2573=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 56", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 168.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 56500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2573"]]
+2572=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 55", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 55500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2572"]]
+2571=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 54", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 162.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 54500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2571"]]
+2570=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 53", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 53500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2570"]]
+31700=PROJCS["Dealul Piscului 1970/ Stereo 70", GEOGCS["Dealul Piscului 1970", DATUM["Dealul Piscului 1970", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[28.0, -121.0, -77.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6317"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4317"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 25.0], PARAMETER["latitude_of_origin", 46.0], PARAMETER["scale_factor", 0.99975], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31700"]]
+27229=PROJCS["NZGD49 / Mount York Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 167.73886177777777], PARAMETER["latitude_of_origin", -45.56372616666667], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27229"]]
+4749=GEOGCS["RGNC91-93", DATUM["Reseau Geodesique de Nouvelle Caledonie 91-93", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6749"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4749"]]
+27228=PROJCS["NZGD49 / Mount Nicholas Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 168.3986411944445], PARAMETER["latitude_of_origin", -45.132902583333326], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27228"]]
+4748=GEOGCS["Vanua Levu 1915", DATUM["Vanua Levu 1915", SPHEROID["Clarke 1880 (international foot)", 6378306.3696, 293.46630765562986, AUTHORITY["EPSG","7055"]], TOWGS84[51.0, 391.0, -36.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6748"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4748"]]
+27227=PROJCS["NZGD49 / Lindis Peak Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 169.46775508333334], PARAMETER["latitude_of_origin", -44.735267972222225], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27227"]]
+4747=GEOGCS["GR96", DATUM["Greenland 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6747"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4747"]]
+27226=PROJCS["NZGD49 / Timaru Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.05725083333334], PARAMETER["latitude_of_origin", -44.40222036111112], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27226"]]
+4746=GEOGCS["PD/83", DATUM["Potsdam Datum/83", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6746"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4746"]]
+27225=PROJCS["NZGD49 / Gawler Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.3607484722222], PARAMETER["latitude_of_origin", -43.74871155555556], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27225"]]
+4745=GEOGCS["RD/83", DATUM["Rauenberg Datum/83", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6745"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4745"]]
+27224=PROJCS["NZGD49 / Mount Pleasant Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 172.7271935833334], PARAMETER["latitude_of_origin", -43.590637583333326], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27224"]]
+4744=GEOGCS["Nahrwan 1934", DATUM["Nahrwan 1934", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6744"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4744"]]
+27223=PROJCS["NZGD49 / Jacksons Bay Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 168.60626700000003], PARAMETER["latitude_of_origin", -43.977802888888895], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27223"]]
+4743=GEOGCS["Karbala 1979", DATUM["Karbala 1979", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[70.995, -335.916, 262.898, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6743"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4743"]]
+27222=PROJCS["NZGD49 / Okarito Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 170.26092583333337], PARAMETER["latitude_of_origin", -43.1101281388889], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27222"]]
+2569=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 52", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 156.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 52500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2569"]]
+4742=GEOGCS["GDM2000", DATUM["Geodetic Datum of Malaysia 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6742"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4742"]]
+27221=PROJCS["NZGD49 / Hokitika Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 170.9799935], PARAMETER["latitude_of_origin", -42.88632236111112], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27221"]]
+2568=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 51", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 51500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2568"]]
+4741=GEOGCS["FD54", DATUM["Faroe Datum 1954", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6741"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4741"]]
+27220=PROJCS["NZGD49 / Marlborough Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 173.80207411111112], PARAMETER["latitude_of_origin", -41.54448666666666], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27220"]]
+2567=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 50", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 150.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 50500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2567"]]
+4740=GEOGCS["PZ-90", DATUM["Parametrop Zemp 1990", SPHEROID["PZ-90", 6378136.0, 298.257839303, AUTHORITY["EPSG","7054"]], TOWGS84[-1.08, -0.27, -0.9, -0.0, 0.0, -0.16, -0.12], AUTHORITY["EPSG","6740"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4740"]]
+2566=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 49", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 49500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2566"]]
+2565=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 48", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 144.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 48500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2565"]]
+2564=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 47", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 47500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2564"]]
+2563=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 46", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 138.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 46500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2563"]]
+2562=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 45", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 45500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2562"]]
+62806405=GEOGCS["Padang (deg)", DATUM["Padang 1884", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6280"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62806405"]]
+2561=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 44", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 44500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2561"]]
+2560=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 43", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 43500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2560"]]
+27219=PROJCS["NZGD49 / Amuri Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 173.01013338888893], PARAMETER["latitude_of_origin", -42.689116583333345], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27219"]]
+4739=GEOGCS["Hong Kong 1963(67)", DATUM["Hong Kong 1963(67)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-156.0, -271.0, -189.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6739"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4739"]]
+27218=PROJCS["NZGD49 / Grey Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.54977130555554], PARAMETER["latitude_of_origin", -42.33369427777777], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27218"]]
+4738=GEOGCS["Hong Kong 1963", DATUM["Hong Kong 1963", SPHEROID["Clarke 1858", 6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]], AUTHORITY["EPSG","6738"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4738"]]
+27217=PROJCS["NZGD49 / Buller Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.58126005555556], PARAMETER["latitude_of_origin", -41.81080286111112], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27217"]]
+63176405=GEOGCS["Dealul Piscului 1970 (deg)", DATUM["Dealul Piscului 1970", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[28.0, -121.0, -77.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6317"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63176405"]]
+4737=GEOGCS["Korea 2000", DATUM["Geocentric datum of Korea", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6737"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4737"]]
+27216=PROJCS["NZGD49 / Karamea Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 172.1090281944444], PARAMETER["latitude_of_origin", -41.28991152777776], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27216"]]
+4736=GEOGCS["Deception Island", DATUM["Deception Island", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[260.0, 12.0, -147.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6736"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4736"]]
+27215=PROJCS["NZGD49 / Nelson Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 173.29931680555552], PARAMETER["latitude_of_origin", -41.27454472222222], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27215"]]
+4735=GEOGCS["Kusaie 1951", DATUM["Kusaie 1951", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[647.0, 1777.0, -1124.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6735"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4735"]]
+27214=PROJCS["NZGD49 / Collingwood Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 172.67204649999994], PARAMETER["latitude_of_origin", -40.71475905555556], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27214"]]
+4734=GEOGCS["Tristan 1968", DATUM["Tristan 1968", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-632.0, 438.0, -609.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6734"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4734"]]
+27213=PROJCS["NZGD49 / Wellington Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 174.77662311111112], PARAMETER["latitude_of_origin", -41.301319638888884], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27213"]]
+4733=GEOGCS["Wake Island 1952", DATUM["Wake Island 1952", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[276.0, -57.0, 149.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6733"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4733"]]
+27212=PROJCS["NZGD49 / Wairarapa Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 175.64734966666674], PARAMETER["latitude_of_origin", -40.9255326388889], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27212"]]
+2559=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 42", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 42500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2559"]]
+4732=GEOGCS["Marshall Islands 1960", DATUM["Marshall Islands 1960", SPHEROID["Hough 1960", 6378270.0, 297.0, AUTHORITY["EPSG","7053"]], TOWGS84[102.0, 52.0, -38.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6732"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4732"]]
+27211=PROJCS["NZGD49 / Wanganui Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 175.48809961111115], PARAMETER["latitude_of_origin", -40.24194713888889], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27211"]]
+2558=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 41", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 41500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2558"]]
+4731=GEOGCS["Viti Levu 1916", DATUM["Viti Levu 1916", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[51.0, 391.0, -36.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6731"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4731"]]
+27210=PROJCS["NZGD49 / Tuhirangi Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 175.64003680555558], PARAMETER["latitude_of_origin", -39.51247038888891], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27210"]]
+2557=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 40", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 40500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2557"]]
+4730=GEOGCS["Santo 1965", DATUM["Santo 1965", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[170.0, 42.0, 84.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6730"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4730"]]
+2556=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 39", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 39500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2556"]]
+2555=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 38", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 38500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2555"]]
+2554=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 37", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 37500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2554"]]
+2553=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 36", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 108.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 36500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2553"]]
+2552=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 35", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 35500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2552"]]
+2551=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 34", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 34500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2551"]]
+66246413=GEOGCS["RGFG95 (3D deg)", DATUM["Reseau Geodesique Francais Guyane 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6624"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","66246413"]]
+61526413=GEOGCS["NAD83(HARN) (3D deg)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61526413"]]
+27209=PROJCS["NZGD49 / Taranaki Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 174.22801175000004], PARAMETER["latitude_of_origin", -39.13575830555557], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27209"]]
+4729=GEOGCS["Pitcairn 1967", DATUM["Pitcairn 1967", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[185.0, 165.0, 42.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6729"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4729"]]
+27208=PROJCS["NZGD49 / Hawkes Bay Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 176.6736805277778], PARAMETER["latitude_of_origin", -39.65092930555556], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27208"]]
+4728=GEOGCS["Pico de las Nieves 1984", DATUM["Pico de las Nieves 1984", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.0, -92.0, 127.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6728"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4728"]]
+27207=PROJCS["NZGD49 / Poverty Bay Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.88563627777776], PARAMETER["latitude_of_origin", -38.62470277777778], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27207"]]
+4727=GEOGCS["Midway 1961", DATUM["Midway 1961", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[403.0, -81.0, 277.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6727"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4727"]]
+27206=PROJCS["NZGD49 / Bay of Plenty Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 176.46619724999996], PARAMETER["latitude_of_origin", -37.76124980555554], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27206"]]
+4726=GEOGCS["Little Cayman 1961", DATUM["Little Cayman 1961", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[44.4, 109.0, 151.7, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6726"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4726"]]
+27205=PROJCS["NZGD49 / Mount Eden Circuit", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 174.76433936111113], PARAMETER["latitude_of_origin", -36.87986527777778], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27205"]]
+4725=GEOGCS["Johnston Island 1961", DATUM["Johnston Island 1961", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[189.0, -79.0, -202.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6725"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4725"]]
+4724=GEOGCS["Diego Garcia 1969", DATUM["Diego Garcia 1969", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[208.0, -435.0, -229.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6724"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4724"]]
+4723=GEOGCS["Grand Cayman 1959", DATUM["Grand Cayman 1959", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[67.8, 106.1, 138.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6723"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4723"]]
+2549=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 33", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 33500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2549"]]
+4722=GEOGCS["South Georgia 1968", DATUM["South Georgia 1968", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-794.0, 119.0, -298.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6722"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4722"]]
+2548=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 32", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 32500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2548"]]
+4721=GEOGCS["Fiji 1956", DATUM["Fiji 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[265.025, 384.929, -194.046, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6721"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4721"]]
+27200=PROJCS["NZGD49 / New Zealand Map Grid", GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]], PROJECTION["New_Zealand_Map_Grid", AUTHORITY["EPSG","9811"]], PARAMETER["latitude_of_origin", -41.0], PARAMETER["central_meridian", 173.0], PARAMETER["false_easting", 2510000.0], PARAMETER["false_northing", 6023150.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27200"]]
+2547=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 31", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 31500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2547"]]
+4720=GEOGCS["Fiji 1986", DATUM["Fiji Geodetic Datum 1986", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.2263], AUTHORITY["EPSG","6720"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4720"]]
+2546=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 30", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 30500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2546"]]
+2545=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 29", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 29500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2545"]]
+2544=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 28", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 28500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2544"]]
+2543=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 27", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 27500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2543"]]
+2542=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 26", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 26500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2542"]]
+66246405=GEOGCS["RGFG95 (deg)", DATUM["Reseau Geodesique Francais Guyane 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6624"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66246405"]]
+2541=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 25", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 25500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2541"]]
+2540=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 24", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 72.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 24500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2540"]]
+61526405=GEOGCS["NAD83(HARN) (deg)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61526405"]]
+4719=GEOGCS["Easter Island 1967", DATUM["Easter Island 1967", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[211.0, 147.0, 111.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6719"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4719"]]
+62476405=GEOGCS["La Canoa (deg)", DATUM["La Canoa", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-273.5, 110.6, -357.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6247"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62476405"]]
+4718=GEOGCS["Solomon 1968", DATUM["Solomon 1968", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[252.0, -209.0, -751.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6718"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4718"]]
+4717=GEOGCS["Cape Canaveral", DATUM["Cape Canaveral", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-2.0, 151.0, 181.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6717"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4717"]]
+4716=GEOGCS["Phoenix Islands 1966", DATUM["Phoenix Islands 1966", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[298.0, -304.0, -375.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6716"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4716"]]
+4715=GEOGCS["Camp Area Astro", DATUM["Camp Area Astro", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-104.0, -129.0, 239.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6715"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4715"]]
+4714=GEOGCS["Bellevue", DATUM["Bellevue", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-127.0, -769.0, 472.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6714"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4714"]]
+4713=GEOGCS["Ayabelle Lighthouse", DATUM["Ayabelle Lighthouse", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-79.0, -129.0, 145.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6713"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4713"]]
+2539=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 23", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 23500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2539"]]
+4712=GEOGCS["Ascension Island 1958", DATUM["Ascension Island 1958", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-205.0, 107.0, 53.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6712"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4712"]]
+2538=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 22", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 66.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 22500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2538"]]
+4711=GEOGCS["Marcus Island 1952", DATUM["Marcus Island 1952", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[124.0, -234.0, -25.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6711"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4711"]]
+2537=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 21", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 21500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2537"]]
+4710=GEOGCS["St. Helena 1971", DATUM["St. Helena 1971", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-320.0, 550.0, -494.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6710"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4710"]]
+2536=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 20", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 60.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 20500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2536"]]
+2535=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 19", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 19500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2535"]]
+2534=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 18", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 54.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 18500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2534"]]
+2533=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 17", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 17500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2533"]]
+2532=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 16", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 48.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 16500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2532"]]
+2531=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 15", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 15500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2531"]]
+2530=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 14", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 42.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 14500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2530"]]
+4709=GEOGCS["Iwo Jima 1945", DATUM["Iwo Jima 1945", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[145.0, 75.0, -272.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6709"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4709"]]
+4708=GEOGCS["Cocos Islands 1965", DATUM["Cocos Islands 1965", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-491.0, -22.0, 435.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6708"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4708"]]
+4707=GEOGCS["Tern Island 1961", DATUM["Tern Island 1961", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[114.0, -116.0, -333.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6707"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4707"]]
+4706=GEOGCS["Egypt Gulf of Suez S-650 TL", DATUM["Egypt Gulf of Suez S-650 TL", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], TOWGS84[-146.21, 112.63, 4.05, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6706"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4706"]]
+4705=GEOGCS["Mhast (offshore)", DATUM["Mhast (offshore)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6705"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4705"]]
+4704=GEOGCS["Mhast (onshore)", DATUM["Mhast (onshore)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6704"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4704"]]
+4703=GEOGCS["Mhast 1951", DATUM["Missao Hidrografico Angola y Sao Tome 1951", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6703"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4703"]]
+2529=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 13", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 13500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2529"]]
+4702=GEOGCS["Mauritania 1999", DATUM["Mauritania 1999", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6702"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4702"]]
+2528=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 12", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 36.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 12500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2528"]]
+4701=GEOGCS["IGCB 1955", DATUM["Institut Geographique du Congo Belge 1955", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-79.9, -158.0, -168.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6701"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4701"]]
+28992=PROJCS["Amersfoort / RD New", GEOGCS["Amersfoort", DATUM["Amersfoort", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[565.2369, 50.0087, 465.658, -0.40685733032239757, -0.3507326765425626, 1.8703473836067959, 4.0812], AUTHORITY["EPSG","6289"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4289"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 5.387638888888891], PARAMETER["latitude_of_origin", 52.15616055555556], PARAMETER["scale_factor", 0.9999079], PARAMETER["false_easting", 155000.0], PARAMETER["false_northing", 463000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28992"]]
+2527=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 11", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 11500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2527"]]
+4700=GEOGCS["IGN Astro 1960", DATUM["IGN Astro 1960", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6700"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4700"]]
+28991=PROJCS["Amersfoort / RD Old", GEOGCS["Amersfoort", DATUM["Amersfoort", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[565.2369, 50.0087, 465.658, -0.40685733032239757, -0.3507326765425626, 1.8703473836067959, 4.0812], AUTHORITY["EPSG","6289"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4289"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 5.387638888888891], PARAMETER["latitude_of_origin", 52.15616055555556], PARAMETER["scale_factor", 0.9999079], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28991"]]
+2526=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 10", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 10500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2526"]]
+2525=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 9", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 9500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2525"]]
+2524=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 8", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 8500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2524"]]
+2523=PROJCS["Pulkovo 1942 / 3-degree Gauss-Kruger zone 7", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2523"]]
+2522=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 171W", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2522"]]
+2521=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 177W", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2521"]]
+25000=PROJCS["Leigon / Ghana Metre Grid", GEOGCS["Leigon", DATUM["Leigon", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-130.0, 29.0, 364.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6250"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4250"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -1.0], PARAMETER["latitude_of_origin", 4.666666666666667], PARAMETER["scale_factor", 0.99975], PARAMETER["false_easting", 274319.51], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25000"]]
+2520=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 177E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2520"]]
+2519=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 171E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2519"]]
+63016405=GEOGCS["Tokyo (deg)", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63016405"]]
+2518=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 165E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2518"]]
+2517=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 159E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2517"]]
+2516=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 153E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2516"]]
+2515=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 147E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2515"]]
+2514=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 141E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2514"]]
+2513=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 135E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2513"]]
+2512=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 129E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2512"]]
+2511=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 123E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2511"]]
+2510=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 117E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2510"]]
+2509=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 111E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2509"]]
+2508=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 105E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2508"]]
+26799=PROJCS["NAD27 / California zone VII", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -118.33333333333334], PARAMETER["latitude_of_origin", 34.13333333333333], PARAMETER["standard_parallel_1", 34.416666666666664], PARAMETER["false_easting", 4186692.58], PARAMETER["false_northing", 4160926.74], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.86666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26799"]]
+2507=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 99E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2507"]]
+26798=PROJCS["NAD27 / Missouri West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -94.5], PARAMETER["latitude_of_origin", 36.166666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26798"]]
+2506=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 93E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2506"]]
+26797=PROJCS["NAD27 / Missouri Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -92.5], PARAMETER["latitude_of_origin", 35.833333333333336], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26797"]]
+2505=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 87E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2505"]]
+26796=PROJCS["NAD27 / Missouri East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.5], PARAMETER["latitude_of_origin", 35.833333333333336], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26796"]]
+2504=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 81E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2504"]]
+26795=PROJCS["NAD27 / Mississippi West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.33333333333333], PARAMETER["latitude_of_origin", 30.5], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26795"]]
+2503=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 75E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2503"]]
+26794=PROJCS["NAD27 / Mississippi East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.83333333333333], PARAMETER["latitude_of_origin", 29.666666666666668], PARAMETER["scale_factor", 0.99996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26794"]]
+2502=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 69E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2502"]]
+26793=PROJCS["NAD27 / Minnesota South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.0], PARAMETER["latitude_of_origin", 43.0], PARAMETER["standard_parallel_1", 45.21666666666667], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.78333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26793"]]
+2501=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 63E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2501"]]
+26792=PROJCS["NAD27 / Minnesota Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -94.25], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 47.05], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.61666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26792"]]
+2500=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 57E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2500"]]
+26791=PROJCS["NAD27 / Minnesota North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.1], PARAMETER["latitude_of_origin", 46.5], PARAMETER["standard_parallel_1", 48.63333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.03333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26791"]]
+62316405=GEOGCS["ED87 (deg)", DATUM["European Datum 1987", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-82.981, -99.719, -110.709, -0.10470001565102613, 0.031001600378938583, 0.08040202147511816, -0.3143], AUTHORITY["EPSG","6231"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62316405"]]
+26787=PROJCS["NAD27 / Massachusetts Island", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -70.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 41.483333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.28333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26787"]]
+26786=PROJCS["NAD27 / Massachusetts Mainland", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26786"]]
+26785=PROJCS["NAD27 / Maryland", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.0], PARAMETER["latitude_of_origin", 37.833333333333336], PARAMETER["standard_parallel_1", 39.449999999999996], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.3], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26785"]]
+26784=PROJCS["NAD27 / Maine West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.16666666666667], PARAMETER["latitude_of_origin", 42.833333333333336], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26784"]]
+26783=PROJCS["NAD27 / Maine East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -68.5], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26783"]]
+26782=PROJCS["NAD27 / Louisiana South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -91.33333333333333], PARAMETER["latitude_of_origin", 28.666666666666668], PARAMETER["standard_parallel_1", 30.7], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.3], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26782"]]
+26781=PROJCS["NAD27 / Louisiana North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.5], PARAMETER["latitude_of_origin", 30.666666666666664], PARAMETER["standard_parallel_1", 32.666666666666664], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 31.166666666666668], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26781"]]
+26780=PROJCS["NAD27 / Kentucky South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.93333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.733333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26780"]]
+26779=PROJCS["NAD27 / Kentucky North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.25], PARAMETER["latitude_of_origin", 37.5], PARAMETER["standard_parallel_1", 38.96666666666667], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.96666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26779"]]
+26778=PROJCS["NAD27 / Kansas South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.56666666666667], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.266666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26778"]]
+26777=PROJCS["NAD27 / Kansas North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 39.78333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26777"]]
+32199=PROJCS["NAD83 / Louisiana Offshore", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -91.33333333333333], PARAMETER["latitude_of_origin", 25.5], PARAMETER["standard_parallel_1", 27.833333333333332], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 26.166666666666664], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32199"]]
+26776=PROJCS["NAD27 / Iowa South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 40.0], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.61666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26776"]]
+32198=PROJCS["NAD83 / Quebec Lambert", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -68.5], PARAMETER["latitude_of_origin", 44.0], PARAMETER["standard_parallel_1", 60.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32198"]]
+26775=PROJCS["NAD27 / Iowa North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -93.5], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.266666666666666], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.06666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26775"]]
+32197=PROJCS["NAD83 / MTM zone 17", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32197"]]
+26774=PROJCS["NAD27 / Indiana West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.08333333333333], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26774"]]
+32196=PROJCS["NAD83 / MTM zone 16", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32196"]]
+26773=PROJCS["NAD27 / Indiana East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.66666666666667], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26773"]]
+32195=PROJCS["NAD83 / MTM zone 15", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32195"]]
+26772=PROJCS["NAD27 / Illinois West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.16666666666667], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26772"]]
+32194=PROJCS["NAD83 / MTM zone 14", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32194"]]
+26771=PROJCS["NAD27 / Illinois East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.33333333333333], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["scale_factor", 0.999975], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26771"]]
+32193=PROJCS["NAD83 / MTM zone 13", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32193"]]
+26770=PROJCS["NAD27 / Idaho West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.75], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26770"]]
+32192=PROJCS["NAD83 / MTM zone 12", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32192"]]
+32191=PROJCS["NAD83 / MTM zone 11", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32191"]]
+32190=PROJCS["NAD83 / MTM zone 10", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32190"]]
+26769=PROJCS["NAD27 / Idaho Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -114.0], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26769"]]
+26768=PROJCS["NAD27 / Idaho East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -112.16666666666667], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26768"]]
+26767=PROJCS["NAD27 / Georgia West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -84.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26767"]]
+32189=PROJCS["NAD83 / MTM zone 9", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -76.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32189"]]
+26766=PROJCS["NAD27 / Georgia East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26766"]]
+32188=PROJCS["NAD83 / MTM zone 8", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -73.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32188"]]
+32187=PROJCS["NAD83 / MTM zone 7", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32187"]]
+32186=PROJCS["NAD83 / MTM zone 6", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -67.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32186"]]
+32185=PROJCS["NAD83 / MTM zone 5", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -64.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32185"]]
+32184=PROJCS["NAD83 / MTM zone 4", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -61.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32184"]]
+32183=PROJCS["NAD83 / MTM zone 3", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -58.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32183"]]
+26760=PROJCS["NAD27 / Florida North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.5], PARAMETER["latitude_of_origin", 29.0], PARAMETER["standard_parallel_1", 30.75], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.583333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26760"]]
+32182=PROJCS["NAD83 / MTM zone 2", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -56.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32182"]]
+32181=PROJCS["NAD83 / MTM zone 1", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -53.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32181"]]
+32180=PROJCS["NAD83 / SCoPQ zone 2", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -55.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32180"]]
+66636405=GEOGCS["Porto Santo 1995 (deg)", DATUM["Porto Santo 1995", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-210.502, -66.902, -48.476, 2.094, 15.067, 5.817, 0.485], AUTHORITY["EPSG","6663"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66636405"]]
+61916405=GEOGCS["Albanian 1987 (deg)", DATUM["Albanian 1987", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","6191"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61916405"]]
+26759=PROJCS["NAD27 / Florida West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26759"]]
+26758=PROJCS["NAD27 / Florida East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26758"]]
+26757=PROJCS["NAD27 / Delaware", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.41666666666667], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 0.999995], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26757"]]
+26756=PROJCS["NAD27 / Connecticut", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -72.75], PARAMETER["latitude_of_origin", 40.833333333333336], PARAMETER["standard_parallel_1", 41.86666666666669], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.2], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26756"]]
+26755=PROJCS["NAD27 / Colorado South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.233333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26755"]]
+26754=PROJCS["NAD27 / Colorado Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 37.833333333333336], PARAMETER["standard_parallel_1", 39.75], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.45], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26754"]]
+26753=PROJCS["NAD27 / Colorado North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.78333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26753"]]
+26752=PROJCS["NAD27 / Arkansas South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 32.666666666666664], PARAMETER["standard_parallel_1", 34.766666666666666], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.3], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26752"]]
+62866405=GEOGCS["Qatar 1948 (deg)", DATUM["Qatar 1948", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], AUTHORITY["EPSG","6286"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62866405"]]
+26751=PROJCS["NAD27 / Arkansas North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -92.0], PARAMETER["latitude_of_origin", 34.333333333333336], PARAMETER["standard_parallel_1", 36.233333333333334], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.93333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26751"]]
+26750=PROJCS["NAD27 / Arizona West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -113.75], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26750"]]
+24571=PROJCS["Kertau / R.S.O. Malaya (ch)", GEOGCS["Kertau 1968", DATUM["Kertau 1968", SPHEROID["Everest 1830 Modified", 6377304.063, 300.8017, AUTHORITY["EPSG","7018"]], TOWGS84[-11.0, 851.0, 5.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6245"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4245"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9812"]], PARAMETER["longitude_of_center", 102.25], PARAMETER["latitude_of_center", 4.0], PARAMETER["azimuth", 323.0257905000001], PARAMETER["scale_factor", 0.99984], PARAMETER["false_easting", 40000.0], PARAMETER["false_northing", 0.0], PARAMETER["rectified_grid_angle", 323.130102361111], UNIT["m*20.116782494375872", 20.116782494375872], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24571"]]
+22392=PROJCS["Carthage / Sud Tunisie", GEOGCS["Carthage", DATUM["Carthage", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-260.1, 5.5, 432.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6223"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4223"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 9.9], PARAMETER["latitude_of_origin", 33.3], PARAMETER["scale_factor", 0.999625769], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22392"]]
+22391=PROJCS["Carthage / Nord Tunisie", GEOGCS["Carthage", DATUM["Carthage", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-260.1, 5.5, 432.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6223"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4223"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 9.9], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.999625544], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22391"]]
+26749=PROJCS["NAD27 / Arizona Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.91666666666666], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26749"]]
+26748=PROJCS["NAD27 / Arizona East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.16666666666667], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26748"]]
+26747=PROJCS["NAD27 / California zone VII", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -118.33333333333334], PARAMETER["latitude_of_origin", 34.13333333333333], PARAMETER["standard_parallel_1", 34.416666666666664], PARAMETER["false_easting", 4186692.58], PARAMETER["false_northing", 416926.74], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.86666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26747"]]
+26746=PROJCS["NAD27 / California zone VI", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -116.25], PARAMETER["latitude_of_origin", 32.166666666666664], PARAMETER["standard_parallel_1", 33.88333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.78333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26746"]]
+26745=PROJCS["NAD27 / California zone V", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -118.0], PARAMETER["latitude_of_origin", 33.5], PARAMETER["standard_parallel_1", 35.46666666666667], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.03333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26745"]]
+32167=PROJCS["NAD83 / BLM 17N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32167"]]
+26744=PROJCS["NAD27 / California zone IV", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -119.0], PARAMETER["latitude_of_origin", 35.333333333333336], PARAMETER["standard_parallel_1", 37.25], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26744"]]
+32166=PROJCS["NAD83 / BLM 16N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32166"]]
+26743=PROJCS["NAD27 / California zone III", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 36.5], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.06666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26743"]]
+32165=PROJCS["NAD83 / BLM 15N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32165"]]
+26742=PROJCS["NAD27 / California zone II", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.833333333333336], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.333333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26742"]]
+32164=PROJCS["NAD83 / BLM 14N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32164"]]
+26741=PROJCS["NAD27 / California zone I", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 41.666666666666664], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26741"]]
+26740=PROJCS["NAD27 / Alaska zone 10", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -176.0], PARAMETER["latitude_of_origin", 51.0], PARAMETER["standard_parallel_1", 53.833333333333336], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 51.833333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26740"]]
+32161=PROJCS["NAD83 / Puerto Rico & Virgin Is.", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -66.43333333333334], PARAMETER["latitude_of_origin", 17.833333333333332], PARAMETER["standard_parallel_1", 18.433333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 18.033333333333335], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32161"]]
+26739=PROJCS["NAD27 / Alaska zone 9", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -170.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26739"]]
+26738=PROJCS["NAD27 / Alaska zone 8", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -166.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26738"]]
+26737=PROJCS["NAD27 / Alaska zone 7", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -162.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26737"]]
+26736=PROJCS["NAD27 / Alaska zone 6", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -158.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26736"]]
+32158=PROJCS["NAD83 / Wyoming West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.08333333333333], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 100000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32158"]]
+26735=PROJCS["NAD27 / Alaska zone 5", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -154.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26735"]]
+32157=PROJCS["NAD83 / Wyoming West Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -108.75], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32157"]]
+26734=PROJCS["NAD27 / Alaska zone 4", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -150.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26734"]]
+32156=PROJCS["NAD83 / Wyoming East Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.33333333333334], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 100000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32156"]]
+26733=PROJCS["NAD27 / Alaska zone 3", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -146.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26733"]]
+32155=PROJCS["NAD83 / Wyoming East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.16666666666666], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32155"]]
+26732=PROJCS["NAD27 / Alaska zone 2", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -142.0], PARAMETER["latitude_of_origin", 54.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26732"]]
+32154=PROJCS["NAD83 / Wisconsin South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 42.0], PARAMETER["standard_parallel_1", 44.06666666666666], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.73333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32154"]]
+26731=PROJCS["NAD27 / Alaska zone 1", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9812"]], PARAMETER["longitude_of_center", -133.66666666666666], PARAMETER["latitude_of_center", 57.0], PARAMETER["azimuth", 323.130102361111], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 16404166.670000002], PARAMETER["false_northing", -16404166.670000002], PARAMETER["rectified_grid_angle", 323.130102361111], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26731"]]
+32153=PROJCS["NAD83 / Wisconsin Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.5], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32153"]]
+26730=PROJCS["NAD27 / Alabama West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.5], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26730"]]
+32152=PROJCS["NAD83 / Wisconsin North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 45.166666666666664], PARAMETER["standard_parallel_1", 46.766666666666666], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.56666666666666], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32152"]]
+32151=PROJCS["NAD83 / West Virginia South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 37.0], PARAMETER["standard_parallel_1", 38.88333333333333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.483333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32151"]]
+32150=PROJCS["NAD83 / West Virginia North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 38.5], PARAMETER["standard_parallel_1", 40.25], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32150"]]
+61586405=GEOGCS["Naparima 1955 (deg)", DATUM["Naparima 1955", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-0.465, 372.095, 171.736, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6158"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61586405"]]
+5195=VERT_CS["Trieste height", VERT_DATUM["Trieste", 2005, AUTHORITY["EPSG","1050"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5195"]]
+5193=VERT_CS["Incheon height", VERT_DATUM["Incheon", 2005, AUTHORITY["EPSG","1049"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5193"]]
+26729=PROJCS["NAD27 / Alabama East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.83333333333333], PARAMETER["latitude_of_origin", 30.5], PARAMETER["scale_factor", 0.99996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26729"]]
+32149=PROJCS["NAD83 / Washington South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 45.333333333333336], PARAMETER["standard_parallel_1", 47.33333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.833333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32149"]]
+32148=PROJCS["NAD83 / Washington North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.83333333333333], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32148"]]
+32147=PROJCS["NAD83 / Virginia South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.96666666666667], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.766666666666666], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32147"]]
+32146=PROJCS["NAD83 / Virginia North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.199999999999996], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 2000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.03333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32146"]]
+32145=PROJCS["NAD83 / Vermont", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -72.5], PARAMETER["latitude_of_origin", 42.5], PARAMETER["scale_factor", 0.999964286], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32145"]]
+26722=PROJCS["NAD27 / UTM zone 22N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26722"]]
+32144=PROJCS["NAD83 / Utah South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.35], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 3000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.21666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32144"]]
+24548=PROJCS["Kertau 1968 / UTM zone 48N", GEOGCS["Kertau 1968", DATUM["Kertau 1968", SPHEROID["Everest 1830 Modified", 6377304.063, 300.8017, AUTHORITY["EPSG","7018"]], TOWGS84[-11.0, 851.0, 5.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6245"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4245"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24548"]]
+26721=PROJCS["NAD27 / UTM zone 21N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26721"]]
+32143=PROJCS["NAD83 / Utah Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 40.65], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 2000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.016666666666666], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32143"]]
+24547=PROJCS["Kertau 1968 / UTM zone 47N", GEOGCS["Kertau 1968", DATUM["Kertau 1968", SPHEROID["Everest 1830 Modified", 6377304.063, 300.8017, AUTHORITY["EPSG","7018"]], TOWGS84[-11.0, 851.0, 5.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6245"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4245"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24547"]]
+26720=PROJCS["NAD27 / UTM zone 20N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26720"]]
+32142=PROJCS["NAD83 / Utah North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 40.333333333333336], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32142"]]
+32141=PROJCS["NAD83 / Texas South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 25.666666666666668], PARAMETER["standard_parallel_1", 27.833333333333332], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 5000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 26.166666666666664], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32141"]]
+32140=PROJCS["NAD83 / Texas South Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 27.833333333333332], PARAMETER["standard_parallel_1", 30.28333333333333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 4000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 28.383333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32140"]]
+5188=PROJCS["Korea 2000 / East Sea Belt 2010", GEOGCS["Korea 2000", DATUM["Geocentric datum of Korea", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6737"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4737"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 131.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 600000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5188"]]
+5187=PROJCS["Korea 2000 / East Belt 2010", GEOGCS["Korea 2000", DATUM["Geocentric datum of Korea", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6737"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4737"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 600000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5187"]]
+5186=PROJCS["Korea 2000 / Central Belt 2010", GEOGCS["Korea 2000", DATUM["Geocentric datum of Korea", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6737"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4737"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 127.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 600000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5186"]]
+5185=PROJCS["Korea 2000 / West Belt 2010", GEOGCS["Korea 2000", DATUM["Geocentric datum of Korea", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6737"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4737"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 125.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 600000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5185"]]
+5184=PROJCS["Korea 2000 / East Sea Belt", GEOGCS["Korea 2000", DATUM["Geocentric datum of Korea", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6737"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4737"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 131.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5184"]]
+5183=PROJCS["Korea 2000 / East Belt", GEOGCS["Korea 2000", DATUM["Geocentric datum of Korea", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6737"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4737"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5183"]]
+5182=PROJCS["Korea 2000 / Central Belt Jeju", GEOGCS["Korea 2000", DATUM["Geocentric datum of Korea", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6737"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4737"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 127.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 550000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5182"]]
+5181=PROJCS["Korea 2000 / Central Belt", GEOGCS["Korea 2000", DATUM["Geocentric datum of Korea", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6737"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4737"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 127.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5181"]]
+5180=PROJCS["Korea 2000 / West Belt", GEOGCS["Korea 2000", DATUM["Geocentric datum of Korea", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6737"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4737"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 125.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5180"]]
+26719=PROJCS["NAD27 / UTM zone 19N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26719"]]
+26718=PROJCS["NAD27 / UTM zone 18N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26718"]]
+26717=PROJCS["NAD27 / UTM zone 17N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26717"]]
+32139=PROJCS["NAD83 / Texas Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 29.666666666666668], PARAMETER["standard_parallel_1", 31.883333333333336], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 3000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 30.116666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32139"]]
+26716=PROJCS["NAD27 / UTM zone 16N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26716"]]
+32138=PROJCS["NAD83 / Texas North Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 31.666666666666664], PARAMETER["standard_parallel_1", 33.96666666666667], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 2000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.13333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32138"]]
+26715=PROJCS["NAD27 / UTM zone 15N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26715"]]
+32137=PROJCS["NAD83 / Texas North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -101.5], PARAMETER["latitude_of_origin", 34.0], PARAMETER["standard_parallel_1", 36.18333333333333], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.65], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32137"]]
+26714=PROJCS["NAD27 / UTM zone 14N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26714"]]
+32136=PROJCS["NAD83 / Tennessee", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -86.0], PARAMETER["latitude_of_origin", 34.333333333333336], PARAMETER["standard_parallel_1", 36.416666666666664], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32136"]]
+26713=PROJCS["NAD27 / UTM zone 13N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26713"]]
+32135=PROJCS["NAD83 / South Dakota South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 42.333333333333336], PARAMETER["standard_parallel_1", 44.4], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.833333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32135"]]
+26712=PROJCS["NAD27 / UTM zone 12N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26712"]]
+32134=PROJCS["NAD83 / South Dakota North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.68333333333334], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.416666666666664], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32134"]]
+26711=PROJCS["NAD27 / UTM zone 11N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26711"]]
+32133=PROJCS["NAD83 / South Carolina", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 31.833333333333336], PARAMETER["standard_parallel_1", 34.833333333333336], PARAMETER["false_easting", 609600.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32133"]]
+26710=PROJCS["NAD27 / UTM zone 10N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26710"]]
+32130=PROJCS["NAD83 / Rhode Island", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.083333333333336], PARAMETER["scale_factor", 0.99999375], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32130"]]
+62706405=GEOGCS["Nahrwan 1967 (deg)", DATUM["Nahrwan 1967", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-245.0, -153.9, 382.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6270"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62706405"]]
+5179=PROJCS["Korea 2000 / Unified CS", GEOGCS["Korea 2000", DATUM["Geocentric datum of Korea", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6737"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4737"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 127.5], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 2000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5179"]]
+5178=PROJCS["Korean 1985 / Unified CS", GEOGCS["Korean 1985", DATUM["Korean Datum 1985", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6162"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4162"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 127.5], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 2000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5178"]]
+5177=PROJCS["Korean 1985 / Modified East Sea Belt", GEOGCS["Korean 1985", DATUM["Korean Datum 1985", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6162"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4162"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 131.0028902777777], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5177"]]
+5176=PROJCS["Korean 1985 / Modified East Belt", GEOGCS["Korean 1985", DATUM["Korean Datum 1985", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6162"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4162"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0028902777777], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5176"]]
+5175=PROJCS["Korean 1985 / Modified Central Belt Jeju", GEOGCS["Korean 1985", DATUM["Korean Datum 1985", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6162"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4162"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 127.00289027777775], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 550000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5175"]]
+5174=PROJCS["Korean 1985 / Modified Central Belt", GEOGCS["Korean 1985", DATUM["Korean Datum 1985", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6162"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4162"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 127.00289027777775], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5174"]]
+5173=PROJCS["Korean 1985 / Modified West Belt", GEOGCS["Korean 1985", DATUM["Korean Datum 1985", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6162"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4162"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 125.00289027777778], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5173"]]
+5172=PROJCS["Tokyo 1892 / Korea East Sea Belt", GEOGCS["Tokyo 1892", DATUM["Tokyo 1892", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","1048"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5132"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 131.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5172"]]
+5171=PROJCS["Tokyo 1892 / Korea East Belt", GEOGCS["Tokyo 1892", DATUM["Tokyo 1892", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","1048"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5132"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5171"]]
+5170=PROJCS["Tokyo 1892 / Korea Central Belt", GEOGCS["Tokyo 1892", DATUM["Tokyo 1892", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","1048"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5132"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 127.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5170"]]
+26709=PROJCS["NAD27 / UTM zone 9N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26709"]]
+63076405=GEOGCS["Nord Sahara 1959 (deg)", DATUM["Nord Sahara 1959", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-152.9, 43.8, 358.3, 2.714, 1.386, -2.788, -6.743], AUTHORITY["EPSG","6307"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63076405"]]
+26708=PROJCS["NAD27 / UTM zone 8N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26708"]]
+26707=PROJCS["NAD27 / UTM zone 7N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26707"]]
+32129=PROJCS["NAD83 / Pennsylvania South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.96666666666667], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.93333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32129"]]
+26706=PROJCS["NAD27 / UTM zone 6N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26706"]]
+32128=PROJCS["NAD83 / Pennsylvania North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 40.166666666666664], PARAMETER["standard_parallel_1", 41.95], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.88333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32128"]]
+26705=PROJCS["NAD27 / UTM zone 5N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26705"]]
+32127=PROJCS["NAD83 / Oregon South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["standard_parallel_1", 44.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.333333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32127"]]
+26704=PROJCS["NAD27 / UTM zone 4N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26704"]]
+32126=PROJCS["NAD83 / Oregon North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["standard_parallel_1", 46.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32126"]]
+26703=PROJCS["NAD27 / UTM zone 3N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26703"]]
+32125=PROJCS["NAD83 / Oklahoma South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 33.333333333333336], PARAMETER["standard_parallel_1", 35.233333333333334], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.93333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32125"]]
+26702=PROJCS["NAD27 / UTM zone 2N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26702"]]
+32124=PROJCS["NAD83 / Oklahoma North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 35.0], PARAMETER["standard_parallel_1", 36.766666666666666], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.56666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32124"]]
+26701=PROJCS["NAD27 / UTM zone 1N", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26701"]]
+32123=PROJCS["NAD83 / Ohio South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 38.0], PARAMETER["standard_parallel_1", 40.03333333333333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.733333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32123"]]
+32122=PROJCS["NAD83 / Ohio North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 39.666666666666664], PARAMETER["standard_parallel_1", 41.7], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.43333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32122"]]
+32121=PROJCS["NAD83 / North Dakota South", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 45.666666666666664], PARAMETER["standard_parallel_1", 47.483333333333334], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.18333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32121"]]
+32120=PROJCS["NAD83 / North Dakota North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.43333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32120"]]
+5169=PROJCS["Tokyo 1892 / Korea West Belt", GEOGCS["Tokyo 1892", DATUM["Tokyo 1892", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","1048"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5132"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 125.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5169"]]
+5168=PROJCS["Korean 1985 / Central Belt Jeju", GEOGCS["Korean 1985", DATUM["Korean Datum 1985", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6162"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4162"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 127.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 550000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5168"]]
+5167=PROJCS["Korean 1985 / East Sea Belt", GEOGCS["Korean 1985", DATUM["Korean Datum 1985", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6162"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4162"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 131.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5167"]]
+32119=PROJCS["NAD83 / North Carolina", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.0], PARAMETER["latitude_of_origin", 33.75], PARAMETER["standard_parallel_1", 36.166666666666664], PARAMETER["false_easting", 609601.22], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.333333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32119"]]
+32118=PROJCS["NAD83 / New York Long Island", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -74.0], PARAMETER["latitude_of_origin", 40.166666666666664], PARAMETER["standard_parallel_1", 41.03333333333333], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.666666666666664], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32118"]]
+32117=PROJCS["NAD83 / New York West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -78.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 350000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32117"]]
+32116=PROJCS["NAD83 / New York Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -76.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32116"]]
+32115=PROJCS["NAD83 / New York East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.5], PARAMETER["latitude_of_origin", 38.833333333333336], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32115"]]
+32114=PROJCS["NAD83 / New Mexico West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.83333333333334], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999916667], PARAMETER["false_easting", 830000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32114"]]
+32113=PROJCS["NAD83 / New Mexico Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -106.25], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32113"]]
+32112=PROJCS["NAD83 / New Mexico East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -104.33333333333333], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999909091], PARAMETER["false_easting", 165000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32112"]]
+32111=PROJCS["NAD83 / New Jersey", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.5], PARAMETER["latitude_of_origin", 38.833333333333336], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32111"]]
+32110=PROJCS["NAD83 / New Hampshire", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.66666666666667], PARAMETER["latitude_of_origin", 42.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32110"]]
+66146405=GEOGCS["QND95 (deg)", DATUM["Qatar National Datum 1995", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-119.4248, -303.65872, -11.00061, 1.164298, 0.174458, 1.096259, 3.657065], AUTHORITY["EPSG","6614"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66146405"]]
+61426405=GEOGCS["Locodjo 1965 (deg)", DATUM["Locodjo 1965", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-125.0, 53.0, 467.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6142"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61426405"]]
+22332=PROJCS["Carthage / UTM zone 32N", GEOGCS["Carthage", DATUM["Carthage", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-260.1, 5.5, 432.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6223"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4223"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22332"]]
+62376405=GEOGCS["HD72 (deg)", DATUM["Hungarian Datum 1972", SPHEROID["GRS 1967", 6378160.0, 298.247167427, AUTHORITY["EPSG","7036"]], TOWGS84[52.17, -71.82, -14.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6237"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62376405"]]
+32109=PROJCS["NAD83 / Nevada West", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -118.58333333333333], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 4000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32109"]]
+32108=PROJCS["NAD83 / Nevada Central", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -116.66666666666667], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 6000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32108"]]
+32107=PROJCS["NAD83 / Nevada East", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.58333333333334], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 8000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32107"]]
+32104=PROJCS["NAD83 / Nebraska", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 39.833333333333336], PARAMETER["standard_parallel_1", 43.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32104"]]
+32100=PROJCS["NAD83 / Montana", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -109.5], PARAMETER["latitude_of_origin", 44.25], PARAMETER["standard_parallel_1", 49.0], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32100"]]
+24500=PROJCS["Kertau 1968 / Singapore Grid", GEOGCS["Kertau 1968", DATUM["Kertau 1968", SPHEROID["Everest 1830 Modified", 6377304.063, 300.8017, AUTHORITY["EPSG","7018"]], TOWGS84[-11.0, 851.0, 5.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6245"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4245"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 103.85300222222226], PARAMETER["latitude_of_origin", 1.2876466666666673], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 30000.0], PARAMETER["false_northing", 30000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24500"]]
+5132=GEOGCS["Tokyo 1892", DATUM["Tokyo 1892", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","1048"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5132"]]
+20138=PROJCS["Adindan / UTM zone 38N", GEOGCS["Adindan", DATUM["Adindan", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-165.0, -11.0, 206.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6201"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4201"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20138"]]
+20137=PROJCS["Adindan / UTM zone 37N", GEOGCS["Adindan", DATUM["Adindan", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-165.0, -11.0, 206.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6201"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4201"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20137"]]
+5130=PROJCS["ETRS89 / NTM zone 30", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5130"]]
+20136=PROJCS["Adindan / UTM zone 36N", GEOGCS["Adindan", DATUM["Adindan", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-165.0, -11.0, 206.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6201"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4201"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20136"]]
+20135=PROJCS["Adindan / UTM zone 35N", GEOGCS["Adindan", DATUM["Adindan", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-165.0, -11.0, 206.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6201"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4201"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20135"]]
+5129=PROJCS["ETRS89 / NTM zone 29", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 29.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5129"]]
+5128=PROJCS["ETRS89 / NTM zone 28", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 28.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5128"]]
+5127=PROJCS["ETRS89 / NTM zone 27", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5127"]]
+5126=PROJCS["ETRS89 / NTM zone 26", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 26.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5126"]]
+5125=PROJCS["ETRS89 / NTM zone 25", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 25.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5125"]]
+5124=PROJCS["ETRS89 / NTM zone 24", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5124"]]
+5123=PROJCS["ETRS89 / NTM zone 23", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 23.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5123"]]
+5122=PROJCS["ETRS89 / NTM zone 22", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 22.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5122"]]
+5121=PROJCS["ETRS89 / NTM zone 21", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5121"]]
+5120=PROJCS["ETRS89 / NTM zone 20", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 20.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5120"]]
+61976405=GEOGCS["Garoua (deg)", DATUM["Garoua", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6197"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61976405"]]
+5119=PROJCS["ETRS89 / NTM zone 19", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 19.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5119"]]
+5118=PROJCS["ETRS89 / NTM zone 18", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5118"]]
+5117=PROJCS["ETRS89 / NTM zone 17", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 17.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5117"]]
+5116=PROJCS["ETRS89 / NTM zone 16", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 16.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5116"]]
+5115=PROJCS["ETRS89 / NTM zone 15", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5115"]]
+5114=PROJCS["ETRS89 / NTM zone 14", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 14.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5114"]]
+5113=PROJCS["ETRS89 / NTM zone 13", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 13.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5113"]]
+5112=PROJCS["ETRS89 / NTM zone 12", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5112"]]
+5111=PROJCS["ETRS89 / NTM zone 11", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 11.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5111"]]
+5110=PROJCS["ETRS89 / NTM zone 10", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 10.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5110"]]
+62216405=GEOGCS["Campo Inchauspe (deg)", DATUM["Campo Inchauspe", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-154.5, 150.7, 100.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6221"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62216405"]]
+5109=PROJCS["ETRS89 / NTM zone 9", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5109"]]
+5108=PROJCS["ETRS89 / NTM zone 8", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 8.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5108"]]
+5107=PROJCS["ETRS89 / NTM zone 7", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 7.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5107"]]
+5106=PROJCS["ETRS89 / NTM zone 6", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 6.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5106"]]
+5105=PROJCS["ETRS89 / NTM zone 5", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 5.5], PARAMETER["latitude_of_origin", 58.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5105"]]
+68186405=GEOGCS["S-JTSK (Ferro) (deg)", DATUM["System Jednotne Trigonometricke Site Katastralni (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6818"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","68186405"]]
+29385=PROJCS["Schwarzeck / Lo22/25", GEOGCS["Schwarzeck", DATUM["Schwarzeck", SPHEROID["Bessel Namibia (GLM)", 6377483.865280419, 299.1528128, AUTHORITY["EPSG","7046"]], TOWGS84[616.0, 97.0, -251.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6293"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4293"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 25.0], PARAMETER["latitude_of_origin", -22.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m*1.0000135965", 1.0000135965], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","29385"]]
+29383=PROJCS["Schwarzeck / Lo22/23", GEOGCS["Schwarzeck", DATUM["Schwarzeck", SPHEROID["Bessel Namibia (GLM)", 6377483.865280419, 299.1528128, AUTHORITY["EPSG","7046"]], TOWGS84[616.0, 97.0, -251.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6293"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4293"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 23.0], PARAMETER["latitude_of_origin", -22.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m*1.0000135965", 1.0000135965], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","29383"]]
+29381=PROJCS["Schwarzeck / Lo22/21", GEOGCS["Schwarzeck", DATUM["Schwarzeck", SPHEROID["Bessel Namibia (GLM)", 6377483.865280419, 299.1528128, AUTHORITY["EPSG","7046"]], TOWGS84[616.0, 97.0, -251.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6293"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4293"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", -22.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m*1.0000135965", 1.0000135965], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","29381"]]
+29379=PROJCS["Schwarzeck / Lo22/19", GEOGCS["Schwarzeck", DATUM["Schwarzeck", SPHEROID["Bessel Namibia (GLM)", 6377483.865280419, 299.1528128, AUTHORITY["EPSG","7046"]], TOWGS84[616.0, 97.0, -251.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6293"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4293"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 19.0], PARAMETER["latitude_of_origin", -22.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m*1.0000135965", 1.0000135965], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","29379"]]
+29377=PROJCS["Schwarzeck / Lo22/17", GEOGCS["Schwarzeck", DATUM["Schwarzeck", SPHEROID["Bessel Namibia (GLM)", 6377483.865280419, 299.1528128, AUTHORITY["EPSG","7046"]], TOWGS84[616.0, 97.0, -251.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6293"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4293"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 17.0], PARAMETER["latitude_of_origin", -22.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m*1.0000135965", 1.0000135965], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","29377"]]
+29375=PROJCS["Schwarzeck / Lo22/15", GEOGCS["Schwarzeck", DATUM["Schwarzeck", SPHEROID["Bessel Namibia (GLM)", 6377483.865280419, 299.1528128, AUTHORITY["EPSG","7046"]], TOWGS84[616.0, 97.0, -251.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6293"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4293"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", -22.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m*1.0000135965", 1.0000135965], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","29375"]]
+29373=PROJCS["Schwarzeck / Lo22/13", GEOGCS["Schwarzeck", DATUM["Schwarzeck", SPHEROID["Bessel Namibia (GLM)", 6377483.865280419, 299.1528128, AUTHORITY["EPSG","7046"]], TOWGS84[616.0, 97.0, -251.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6293"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4293"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 13.0], PARAMETER["latitude_of_origin", -22.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m*1.0000135965", 1.0000135965], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","29373"]]
+21899=PROJCS["Bogota 1975 / Colombia East", GEOGCS["Bogota 1975", DATUM["Bogota 1975", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[304.5, 306.5, -318.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6218"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4218"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -68.0809166666667], PARAMETER["latitude_of_origin", 4.599047222222223], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21899"]]
+29371=PROJCS["Schwarzeck / Lo22/11", GEOGCS["Schwarzeck", DATUM["Schwarzeck", SPHEROID["Bessel Namibia (GLM)", 6377483.865280419, 299.1528128, AUTHORITY["EPSG","7046"]], TOWGS84[616.0, 97.0, -251.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6293"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4293"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 11.0], PARAMETER["latitude_of_origin", -22.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m*1.0000135965", 1.0000135965], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","29371"]]
+21898=PROJCS["Bogota 1975 / Colombia East Central zone", GEOGCS["Bogota 1975", DATUM["Bogota 1975", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[304.5, 306.5, -318.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6218"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4218"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.08091666666668], PARAMETER["latitude_of_origin", 4.599047222222223], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21898"]]
+21897=PROJCS["Bogota 1975 / Colombia Bogota zone", GEOGCS["Bogota 1975", DATUM["Bogota 1975", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[304.5, 306.5, -318.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6218"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4218"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.08091666666668], PARAMETER["latitude_of_origin", 4.599047222222223], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21897"]]
+21896=PROJCS["Bogota 1975 / Colombia West zone", GEOGCS["Bogota 1975", DATUM["Bogota 1975", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[304.5, 306.5, -318.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6218"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4218"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -77.08091666666668], PARAMETER["latitude_of_origin", 4.599047222222223], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21896"]]
+21894=PROJCS["Bogota 1975 / Colombia East", GEOGCS["Bogota 1975", DATUM["Bogota 1975", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[304.5, 306.5, -318.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6218"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4218"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -68.0809166666667], PARAMETER["latitude_of_origin", 4.599047222222223], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21894"]]
+21893=PROJCS["Bogota 1975 / Colombia East Central zone", GEOGCS["Bogota 1975", DATUM["Bogota 1975", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[304.5, 306.5, -318.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6218"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4218"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.08091666666668], PARAMETER["latitude_of_origin", 4.599047222222223], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21893"]]
+21892=PROJCS["Bogota 1975 / Colombia Bogota zone", GEOGCS["Bogota 1975", DATUM["Bogota 1975", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[304.5, 306.5, -318.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6218"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4218"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.08091666666668], PARAMETER["latitude_of_origin", 4.599047222222223], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21892"]]
+21891=PROJCS["Bogota 1975 / Colombia West zone", GEOGCS["Bogota 1975", DATUM["Bogota 1975", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[304.5, 306.5, -318.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6218"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4218"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -77.08091666666668], PARAMETER["latitude_of_origin", 4.599047222222223], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21891"]]
+61816405=GEOGCS["Luxembourg 1930 (deg)", DATUM["Luxembourg 1930", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-189.6806, 18.3463, -42.7695, -0.33746, 3.09264, -2.53861, 0.4598], AUTHORITY["EPSG","6181"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61816405"]]
+62766405=GEOGCS["NSWC 9Z-2 (deg)", DATUM["NSWC 9Z-2", SPHEROID["NWL 9D", 6378145.0, 298.25, AUTHORITY["EPSG","7025"]], AUTHORITY["EPSG","6276"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62766405"]]
+61486413=GEOGCS["Hartebeesthoek94 (3D deg)", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61486413"]]
+4699=GEOGCS["Le Pouce 1934", DATUM["Le Pouce 1934", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-770.1, 158.4, -498.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6699"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4699"]]
+4698=GEOGCS["IGN 1962 Kerguelen", DATUM["IGN 1962 Kerguelen", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[145.0, -187.0, 103.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6698"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4698"]]
+4697=GEOGCS["IGC 1962 6th Parallel South", DATUM["IGC 1962 Arc of the 6th Parallel South", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6697"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4697"]]
+4696=GEOGCS["Kasai 1953", DATUM["Kasai 1953", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6696"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4696"]]
+4695=GEOGCS["Katanga 1955", DATUM["Katanga 1955", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-103.746, -9.614, -255.95, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6695"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4695"]]
+4694=GEOGCS["POSGAR 94", DATUM["Posiciones Geodesicas Argentinas 1994", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6694"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4694"]]
+4693=GEOGCS["Nakhl-e Ghanem", DATUM["Nakhl-e Ghanem", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, -0.15, 0.68, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6693"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4693"]]
+4692=GEOGCS["Maupiti 83", DATUM["Maupiti 83", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[217.037, 86.959, 23.956, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6692"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4692"]]
+4691=GEOGCS["Moorea 87", DATUM["Moorea 87", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[215.525, 149.593, 176.229, -3.2624, 1.692, 1.1571, 10.4773], AUTHORITY["EPSG","6691"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4691"]]
+4690=GEOGCS["Tahiti 79", DATUM["Tahiti 79", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[221.525, 152.948, 176.768, -2.3847, 1.3896, 0.877, 11.4741], AUTHORITY["EPSG","6690"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4690"]]
+68026405=GEOGCS["Bogota 1975 (Bogota) (deg)", DATUM["Bogota 1975 (Bogota)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6802"]], PRIMEM["Bogota", -74.08091666666668, AUTHORITY["EPSG","8904"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","68026405"]]
+61486405=GEOGCS["Hartebeesthoek94 (deg)", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61486405"]]
+4689=GEOGCS["IGN63 Hiva Oa", DATUM["IGN63 Hiva Oa", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[410.721, 55.049, 80.746, 2.5779, -2.3514, -0.6664, 17.3311], AUTHORITY["EPSG","6689"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4689"]]
+4688=GEOGCS["Fatu Iva 72", DATUM["Fatu Iva 72", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[347.103, 1078.125, 2623.922, -33.8875, -70.6773, 9.3943, 186.074], AUTHORITY["EPSG","6688"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4688"]]
+4687=GEOGCS["RGPF", DATUM["Reseau Geodesique de la Polynesie Francaise", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.072, -0.507, -0.245, -0.0183, -0.0003, 0.007, -0.0093], AUTHORITY["EPSG","6687"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4687"]]
+4686=GEOGCS["MAGNA-SIRGAS", DATUM["Marco Geocentrico Nacional de Referencia", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6686"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4686"]]
+4685=GEOGCS["Gandajika", DATUM["Gandajika", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6685"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4685"]]
+4684=GEOGCS["Gan 1970", DATUM["Gan 1970", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-133.0, -321.0, 50.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6684"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4684"]]
+4683=GEOGCS["PRS92", DATUM["Philippine Reference System 1992", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-127.62, -67.24, -47.04, -3.068, -4.903, -1.578, -1.06], AUTHORITY["EPSG","6683"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4683"]]
+4682=GEOGCS["Gulshan 303", DATUM["Gulshan 303", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[283.7, 735.9, 261.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6682"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4682"]]
+4681=GEOGCS["Mauritania 1999", DATUM["Mauritania 1999", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6681"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4681"]]
+4680=GEOGCS["Nouakchott 1965", DATUM["Nouakchott 1965", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[124.5, -63.5, -281.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6680"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4680"]]
+29333=PROJCS["Schwarzeck / UTM zone 33S", GEOGCS["Schwarzeck", DATUM["Schwarzeck", SPHEROID["Bessel Namibia (GLM)", 6377483.865280419, 299.1528128, AUTHORITY["EPSG","7046"]], TOWGS84[616.0, 97.0, -251.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6293"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4293"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29333"]]
+4679=GEOGCS["Jouik 1961", DATUM["Jouik 1961", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-80.01, 253.26, 291.19, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6679"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4679"]]
+4678=GEOGCS["Lao 1997", DATUM["Lao National Datum 1997", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[44.585, -131.212, -39.544, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6678"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4678"]]
+4677=GEOGCS["Lao 1993", DATUM["Lao 1993", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","6677"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4677"]]
+4676=GEOGCS["Vientiane 1982", DATUM["Vientiane 1982", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","6676"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4676"]]
+4675=GEOGCS["Guam 1963", DATUM["Guam 1963", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-100.0, -248.0, 259.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6675"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4675"]]
+4674=GEOGCS["SIRGAS 2000", DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6674"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4674"]]
+4673=GEOGCS["Chatham Islands 1979", DATUM["Chatham Islands Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[174.05, -25.49, 112.57, -0.0, 0.0, -0.554, 0.2263], AUTHORITY["EPSG","6673"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4673"]]
+2499=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 51E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2499"]]
+4672=GEOGCS["Chatham Islands 1971", DATUM["Chatham Islands Datum 1971", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[175.0, -38.0, 113.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6672"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4672"]]
+2498=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 45E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2498"]]
+4671=GEOGCS["Voirol 1879", DATUM["Voirol 1879", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6671"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4671"]]
+2497=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 39E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2497"]]
+4670=GEOGCS["IGM95", DATUM["Istituto Geografico Militaire 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6670"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4670"]]
+2496=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 33E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2496"]]
+2495=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 27E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2495"]]
+2494=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 21E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2494"]]
+2493=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 15E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2493"]]
+2492=PROJCS["Pulkovo 1942 / Gauss-Kruger CM 9E", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2492"]]
+2491=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 171W", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2491"]]
+2490=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 177W", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2490"]]
+4669=GEOGCS["LKS94", DATUM["Lithuania 1994 (ETRS89)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6126"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4669"]]
+4668=GEOGCS["ED79", DATUM["European Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-86.0, -98.0, -119.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6668"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4668"]]
+4667=GEOGCS["IKBD-92", DATUM["Iraq-Kuwait Boundary Datum 1992", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6667"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4667"]]
+4666=GEOGCS["Lisbon 1890", DATUM["Lisbon 1890", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[631.392, -66.551, 481.442, 1.09, 4.445, 4.487, -4.43], AUTHORITY["EPSG","6666"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4666"]]
+4665=GEOGCS["Azores Central 1995", DATUM["Azores Central Islands 1995", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-103.088, 162.481, -28.276, 0.167, -0.082, -0.168, -1.504], AUTHORITY["EPSG","6665"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4665"]]
+4664=GEOGCS["Azores Oriental 1995", DATUM["Azores Oriental Islands 1995", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-208.719, 129.685, 52.092, -0.195, 0.014, -0.327, 0.198], AUTHORITY["EPSG","6664"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4664"]]
+4663=GEOGCS["Porto Santo 1995", DATUM["Porto Santo 1995", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-210.502, -66.902, -48.476, 2.094, 15.067, 5.817, 0.485], AUTHORITY["EPSG","6663"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4663"]]
+2489=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 177E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2489"]]
+4662=GEOGCS["IGN72 Grande Terre", DATUM["IGN72 Grande Terre", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-11.64, -348.6, 291.98, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6634"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4662"]]
+2488=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 171E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2488"]]
+4661=GEOGCS["LKS92", DATUM["Latvia 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6661"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4661"]]
+2487=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 165E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2487"]]
+4660=GEOGCS["Helle 1954", DATUM["Helle 1954", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[982.6087, 552.753, -540.873, 6.681626625276941, -31.61149240864225, -19.848161004816845, 16.805], AUTHORITY["EPSG","6660"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4660"]]
+2486=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 159E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2486"]]
+2485=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 153E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2485"]]
+2484=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 147E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2484"]]
+2483=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 141E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2483"]]
+2482=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 135E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2482"]]
+2481=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 129E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2481"]]
+2480=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 123E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2480"]]
+4659=GEOGCS["ISN93", DATUM["Islands Net 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6659"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4659"]]
+4658=GEOGCS["Hjorsey 1955", DATUM["Hjorsey 1955", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-73.0, 46.0, -86.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6658"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4658"]]
+4657=GEOGCS["Reykjavik 1900", DATUM["Reykjavik 1900", SPHEROID["Danish 1876", 6377019.27, 300.0, AUTHORITY["EPSG","7051"]], TOWGS84[-28.0, 199.0, 5.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6657"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4657"]]
+4656=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 29", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 29500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4656"]]
+4655=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 28", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 28500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4655"]]
+4654=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 27", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 27500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4654"]]
+4653=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 26", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 26500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4653"]]
+2479=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 117E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2479"]]
+4652=PROJCS["New Beijing / 3-degree Gauss-Kruger zone 25", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 25500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4652"]]
+2478=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 111E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2478"]]
+2477=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 105E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2477"]]
+2476=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 99E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2476"]]
+2475=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 93E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2475"]]
+2474=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 87E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2474"]]
+2473=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 81E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2473"]]
+2472=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 75E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2472"]]
+2471=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 69E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2471"]]
+2470=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 63E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2470"]]
+31600=PROJCS["Dealul Piscului 1930 / Stereo 33", GEOGCS["Dealul Piscului 1930", DATUM["Dealul Piscului 1930", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[103.25, -100.4, -307.19, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6316"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4316"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 25.392465888888886], PARAMETER["latitude_of_origin", 45.9], PARAMETER["scale_factor", 0.9996667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31600"]]
+66046405=GEOGCS["Montserrat 1958 (deg)", DATUM["Montserrat 1958", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[174.0, 359.0, 365.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6604"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66046405"]]
+4647=PROJCS["ETRS89 / UTM zone N32", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 32500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4647"]]
+61326405=GEOGCS["FD58 (deg)", DATUM["Final Datum 1958", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-239.1, -170.02, 397.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6132"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61326405"]]
+4646=GEOGCS["Grand Comoros", DATUM["Grand Comoros", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-963.0, 510.0, -359.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6646"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4646"]]
+4645=GEOGCS["RGNC 1991", DATUM["Reseau Geodesique Nouvelle Caledonie 1991", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6645"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4645"]]
+4644=GEOGCS["NEA74 Noumea", DATUM["NEA74 Noumea", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-10.18, -350.43, 291.37, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6644"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4644"]]
+4643=GEOGCS["ST71 Belep", DATUM["ST71 Belep", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-480.26, -438.32, -643.429, 16.3119, 20.1721, -4.0349, -111.7002], AUTHORITY["EPSG","6643"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4643"]]
+2469=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 57E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2469"]]
+4642=GEOGCS["ST84 Ile des Pins", DATUM["ST84 Ile des Pins", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-13.0, -348.0, 292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6642"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4642"]]
+27120=PROJCS["Naparima 1972 / UTM zone 20N", GEOGCS["Naparima 1972", DATUM["Naparima 1972", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-2.0, 374.0, 172.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6271"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4271"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27120"]]
+2468=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 51E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2468"]]
+4641=GEOGCS["IGN53 Mare", DATUM["IGN53 Mare", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[287.58, 177.78, -135.41, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6641"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4641"]]
+2467=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 45E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2467"]]
+4640=GEOGCS["RRAF 1991", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6640"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4640"]]
+2466=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 39E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2466"]]
+2465=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 33E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2465"]]
+2464=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 27E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2464"]]
+2463=PROJCS["Pulkovo 1995 / Gauss-Kruger CM 21E", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2463"]]
+2462=PROJCS["Albanian 1987 / Gauss-Kruger zone 4", GEOGCS["Albanian 1987", DATUM["Albanian 1987", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","6191"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4191"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2462"]]
+62276405=GEOGCS["Deir ez Zor (deg)", DATUM["Deir ez Zor", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-83.58, -397.54, 458.78, -17.595, -2.847, 4.256, 3.225], AUTHORITY["EPSG","6227"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62276405"]]
+2461=PROJCS["JGD2000 / Japan Plane Rectangular CS XIX", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 154.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2461"]]
+2460=PROJCS["JGD2000 / Japan Plane Rectangular CS XVIII", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 136.0], PARAMETER["latitude_of_origin", 20.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2460"]]
+4639=GEOGCS["MOP78", DATUM["MOP78", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[253.0, -132.0, -127.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6639"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4639"]]
+21818=PROJCS["Bogota 1975 / UTM zone 18N", GEOGCS["Bogota 1975", DATUM["Bogota 1975", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[304.5, 306.5, -318.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6218"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4218"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21818"]]
+4638=GEOGCS["Saint Pierre et Miquelon 1950", DATUM["Saint Pierre et Miquelon 1950", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[30.0, 430.0, 368.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6638"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4638"]]
+21817=PROJCS["Bogota 1975 / UTM zone 17N", GEOGCS["Bogota 1975", DATUM["Bogota 1975", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[304.5, 306.5, -318.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6218"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4218"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21817"]]
+4637=GEOGCS["Perroud 1950", DATUM["Pointe Geologie Perroud 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[325.0, 154.0, 172.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6637"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4637"]]
+4636=GEOGCS["Petrels 1972", DATUM["Petrels 1972", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[365.0, 194.0, 166.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6636"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4636"]]
+4635=GEOGCS["ST87 Ouvea", DATUM["ST87 Ouvea", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-122.383, -188.696, 103.344, 3.5107, -4.9668, -5.7047, 4.4798], AUTHORITY["EPSG","6635"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4635"]]
+4634=GEOGCS["IGN72 Grand Terre", DATUM["IGN72 Grande Terre", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-11.64, -348.6, 291.98, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6634"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4634"]]
+4633=GEOGCS["IGN56 Lifou", DATUM["IGN56 Lifou", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[335.47, 222.58, -230.94, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6633"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4633"]]
+2459=PROJCS["JGD2000 / Japan Plane Rectangular CS XVII", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 131.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2459"]]
+4632=GEOGCS["Combani 1950", DATUM["Combani 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-382.0, -59.0, -262.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6632"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4632"]]
+2458=PROJCS["JGD2000 / Japan Plane Rectangular CS XVI", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 124.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2458"]]
+4631=GEOGCS["K0 1949", DATUM["K0 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[145.0, -187.0, 103.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6631"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4631"]]
+2457=PROJCS["JGD2000 / Japan Plane Rectangular CS XV", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 127.5], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2457"]]
+4630=GEOGCS["IGN72 Nuku Hiva", DATUM["IGN72 Nuku Hiva", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[165.732, 216.72, 180.505, 0.6434, -0.4512, -0.0791, 7.4204], AUTHORITY["EPSG","6630"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4630"]]
+2456=PROJCS["JGD2000 / Japan Plane Rectangular CS XIV", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 142.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2456"]]
+2455=PROJCS["JGD2000 / Japan Plane Rectangular CS XIII", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 144.25], PARAMETER["latitude_of_origin", 44.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2455"]]
+2454=PROJCS["JGD2000 / Japan Plane Rectangular CS XII", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 142.25], PARAMETER["latitude_of_origin", 44.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2454"]]
+2453=PROJCS["JGD2000 / Japan Plane Rectangular CS XI", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 140.25], PARAMETER["latitude_of_origin", 44.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2453"]]
+2452=PROJCS["JGD2000 / Japan Plane Rectangular CS X", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 140.83333333333334], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2452"]]
+2451=PROJCS["JGD2000 / Japan Plane Rectangular CS IX", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 139.83333333333334], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2451"]]
+2450=PROJCS["JGD2000 / Japan Plane Rectangular CS VIII", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 138.5], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2450"]]
+4629=GEOGCS["Tahaa 54", DATUM["Tahaa 54", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[72.438, 345.918, 79.486, 1.6045, -0.8823, -0.5565, 1.3746], AUTHORITY["EPSG","6629"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4629"]]
+4628=GEOGCS["Tahiti 52", DATUM["Tahiti 52", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[162.0, 117.0, 154.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6628"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4628"]]
+4627=GEOGCS["RGR92", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4627"]]
+4626=GEOGCS["Reunion 1947", DATUM["Reunion 1947", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[94.0, -948.0, -1262.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6626"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4626"]]
+4625=GEOGCS["Martinique 1938", DATUM["Martinique 1938", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[126.93, 547.94, 130.41, -2.7867, 5.1612, -0.8584, 13.8227], AUTHORITY["EPSG","6625"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4625"]]
+4624=GEOGCS["RGFG95", DATUM["Reseau Geodesique Francais Guyane 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6624"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4624"]]
+4623=GEOGCS["CSG67", DATUM["Centre Spatial Guyanais 1967", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-186.0, 230.0, 110.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6623"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4623"]]
+2449=PROJCS["JGD2000 / Japan Plane Rectangular CS VII", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 137.16666666666666], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2449"]]
+4622=GEOGCS["Guadeloupe 1948", DATUM["Guadeloupe 1948", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-472.29, -5.63, -304.12, 0.4362, -0.8374, 0.2563, 1.8984], AUTHORITY["EPSG","6622"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4622"]]
+2448=PROJCS["JGD2000 / Japan Plane Rectangular CS VI", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 136.0], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2448"]]
+4621=GEOGCS["Fort Marigot", DATUM["Fort Marigot", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[137.0, 248.0, -430.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6621"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4621"]]
+66596413=GEOGCS["ISN93 (3D deg)", DATUM["Islands Net 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6659"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","66596413"]]
+2447=PROJCS["JGD2000 / Japan Plane Rectangular CS V", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 134.33333333333334], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2447"]]
+4620=GEOGCS["Point 58", DATUM["Point 58", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-106.0, -129.0, 165.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6620"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4620"]]
+2446=PROJCS["JGD2000 / Japan Plane Rectangular CS IV", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 133.5], PARAMETER["latitude_of_origin", 33.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2446"]]
+2445=PROJCS["JGD2000 / Japan Plane Rectangular CS III", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.16666666666666], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2445"]]
+2444=PROJCS["JGD2000 / Japan Plane Rectangular CS II", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 131.0], PARAMETER["latitude_of_origin", 33.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2444"]]
+2443=PROJCS["JGD2000 / Japan Plane Rectangular CS I", GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.5], PARAMETER["latitude_of_origin", 33.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2443"]]
+2442=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 135E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2442"]]
+2441=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 132E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2441"]]
+2440=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 129E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2440"]]
+4619=GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]]
+4618=GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]]
+4617=GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]]
+4616=GEOGCS["Selvagem Grande", DATUM["Selvagem Grande", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-289.0, -124.0, 60.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6616"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4616"]]
+4615=GEOGCS["Porto Santo", DATUM["Porto Santo 1936", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-499.0, -249.0, 314.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6615"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4615"]]
+4614=GEOGCS["QND95", DATUM["Qatar National Datum 1995", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-119.4248, -303.65872, -11.00061, 1.164298, 0.174458, 1.096259, 3.657065], AUTHORITY["EPSG","6614"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4614"]]
+4613=GEOGCS["Segara", DATUM["Gunung Segara", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-404.78, 685.68, 45.47, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6613"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4613"]]
+66596405=GEOGCS["ISN93 (deg)", DATUM["Islands Net 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6659"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66596405"]]
+2439=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 126E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2439"]]
+4612=GEOGCS["JGD2000", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4612"]]
+2438=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 123E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2438"]]
+4611=GEOGCS["Hong Kong 1980", DATUM["Hong Kong 1980", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-162.619, -276.959, -161.764, 0.067753, -2.243649, -1.158827, -1.094246], AUTHORITY["EPSG","6611"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4611"]]
+2437=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 120E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2437"]]
+4610=GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]]
+2436=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 117E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2436"]]
+2435=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 114E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2435"]]
+2434=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 111E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2434"]]
+2433=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 108E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 108.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2433"]]
+2432=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 105E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2432"]]
+2431=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 102E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2431"]]
+2430=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 99E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2430"]]
+4609=GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]]
+4608=GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]]
+4607=GEOGCS["St. Vincent 1945", DATUM["St. Vincent 1945", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[195.671, 332.517, 274.607, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6607"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4607"]]
+4606=GEOGCS["St. Lucia 1955", DATUM["St. Lucia 1955", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-149.0, 128.0, 296.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6606"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4606"]]
+4605=GEOGCS["St. Kitts 1955", DATUM["St. Kitts 1955", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[9.0, 183.0, 236.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6605"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4605"]]
+4604=GEOGCS["Montserrat 1958", DATUM["Montserrat 1958", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[174.0, 359.0, 365.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6604"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4604"]]
+4603=GEOGCS["Grenada 1953", DATUM["Grenada 1953", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[72.0, 213.7, 93.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6603"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4603"]]
+2429=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 96E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2429"]]
+4602=GEOGCS["Dominica 1945", DATUM["Dominica 1945", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[725.0, 685.0, 536.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6602"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4602"]]
+2428=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 93E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2428"]]
+4601=GEOGCS["Antigua 1943", DATUM["Antigua 1943", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-255.0, -15.0, 71.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6601"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4601"]]
+2427=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 90E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2427"]]
+4600=GEOGCS["Anguilla 1957", DATUM["Anguilla 1957", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6600"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4600"]]
+2426=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 87E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2426"]]
+2425=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 84E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2425"]]
+2424=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 81E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2424"]]
+2423=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 78E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2423"]]
+2422=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger CM 75E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2422"]]
+2421=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 45", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 45500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2421"]]
+2420=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 44", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 44500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2420"]]
+62116405=GEOGCS["Batavia (deg)", DATUM["Batavia", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-377.7, 675.1, -52.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6211"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62116405"]]
+2419=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 43", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 43500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2419"]]
+2418=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 42", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 42500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2418"]]
+2417=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 41", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 41500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2417"]]
+2416=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 40", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 40500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2416"]]
+2415=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 39", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 39500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2415"]]
+2414=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 38", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 38500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2414"]]
+2413=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 37", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 37500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2413"]]
+2412=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 36", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 108.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 36500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2412"]]
+2411=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 35", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 35500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2411"]]
+2410=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 34", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 34500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2410"]]
+68086405=GEOGCS["Padang (Jakarta) (deg)", DATUM["Padang 1884 (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6808"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","68086405"]]
+2409=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 33", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 33500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2409"]]
+2408=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 32", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 32500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2408"]]
+2407=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 31", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 31500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2407"]]
+2406=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 30", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 30500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2406"]]
+2405=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 29", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 29500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2405"]]
+2404=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 28", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 28500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2404"]]
+2403=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 27", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 27500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2403"]]
+2402=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 26", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 26500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2402"]]
+26692=PROJCS["M'poraloko / UTM zone 32S", GEOGCS["M'poraloko", DATUM["M'poraloko", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-80.7, -132.5, 41.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6266"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4266"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26692"]]
+2401=PROJCS["Beijing 1954 / 3-degree Gauss-Kruger zone 25", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 25500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2401"]]
+2400=PROJCS["RT90 2.5 gon W", GEOGCS["RT90", DATUM["Rikets koordinatsystem 1990", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[414.1, 41.3, 603.1, -0.855, -2.141, 7.023, 0.0], AUTHORITY["EPSG","6124"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4124"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.808277777777775], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2400"]]
+61716413=GEOGCS["RGF93 (3D deg)", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61716413"]]
+66436405=GEOGCS["ST71 Belep (deg)", DATUM["ST71 Belep", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-480.26, -438.32, -643.429, 16.3119, 20.1721, -4.0349, -111.7002], AUTHORITY["EPSG","6643"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66436405"]]
+61716405=GEOGCS["RGF93 (deg)", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61716405"]]
+62666405=GEOGCS["M'poraloko (deg)", DATUM["M'poraloko", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-80.7, -132.5, 41.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6266"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62666405"]]
+32099=PROJCS["NAD27 / Louisiana Offshore", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -91.33333333333333], PARAMETER["latitude_of_origin", 25.666666666666668], PARAMETER["standard_parallel_1", 27.833333333333332], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 26.166666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32099"]]
+32098=PROJCS["NAD27 / Quebec Lambert", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -68.5], PARAMETER["latitude_of_origin", 44.0], PARAMETER["standard_parallel_1", 60.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32098"]]
+32086=PROJCS["NAD27 / MTM zone 6", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -67.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32086"]]
+32085=PROJCS["NAD27 / MTM zone 5", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -64.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32085"]]
+32084=PROJCS["NAD27 / MTM zone 4", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -61.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32084"]]
+32083=PROJCS["NAD27 / MTM zone 3", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -58.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32083"]]
+32082=PROJCS["NAD27 / MTM zone 2", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -56.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32082"]]
+32081=PROJCS["NAD27 / MTM zone 1", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -53.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32081"]]
+61386405=GEOGCS["St. George Island (deg)", DATUM["St. George Island", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6138"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61386405"]]
+32077=PROJCS["NAD27 / BLM 17N (feet)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32077"]]
+32076=PROJCS["NAD27 / BLM 16N (feet)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32076"]]
+32075=PROJCS["NAD27 / BLM 15N (feet)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32075"]]
+32074=PROJCS["NAD27 / BLM 14N (feet)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32074"]]
+22293=PROJCS["Cape / Lo33", GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","22293"]]
+22291=PROJCS["Cape / Lo31", GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 31.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","22291"]]
+32067=PROJCS["NAD27 / BLM 17N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32067"]]
+32066=PROJCS["NAD27 / BLM 16N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32066"]]
+32065=PROJCS["NAD27 / BLM 15N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32065"]]
+32064=PROJCS["NAD27 / BLM 14N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32064"]]
+32062=PROJCS["NAD27 / Guatemala Sur", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -90.33333333333333], PARAMETER["latitude_of_origin", 14.9], PARAMETER["scale_factor", 0.99989906], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 325992.681], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32062"]]
+32061=PROJCS["NAD27 / Guatemala Norte", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -90.33333333333333], PARAMETER["latitude_of_origin", 16.816666666666666], PARAMETER["scale_factor", 0.99992226], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 292209.579], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32061"]]
+22289=PROJCS["Cape / Lo29", GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 29.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","22289"]]
+22287=PROJCS["Cape / Lo27", GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","22287"]]
+22285=PROJCS["Cape / Lo25", GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 25.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","22285"]]
+22283=PROJCS["Cape / Lo23", GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 23.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","22283"]]
+22281=PROJCS["Cape / Lo21", GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","22281"]]
+62506405=GEOGCS["Leigon (deg)", DATUM["Leigon", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-130.0, 29.0, 364.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6250"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62506405"]]
+32058=PROJCS["NAD27 / Wyoming West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.08333333333333], PARAMETER["latitude_of_origin", 40.666666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32058"]]
+32057=PROJCS["NAD27 / Wyoming West Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -108.75], PARAMETER["latitude_of_origin", 40.666666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32057"]]
+32056=PROJCS["NAD27 / Wyoming East Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.33333333333334], PARAMETER["latitude_of_origin", 40.666666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32056"]]
+32055=PROJCS["NAD27 / Wyoming East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.16666666666666], PARAMETER["latitude_of_origin", 40.666666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32055"]]
+26632=PROJCS["M'poraloko / UTM zone 32N", GEOGCS["M'poraloko", DATUM["M'poraloko", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-80.7, -132.5, 41.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6266"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4266"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26632"]]
+32054=PROJCS["NAD27 / Wisconsin South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 42.0], PARAMETER["standard_parallel_1", 44.06666666666666], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.73333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32054"]]
+32053=PROJCS["NAD27 / Wisconsin Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.5], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.25], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32053"]]
+32052=PROJCS["NAD27 / Wisconsin North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 45.166666666666664], PARAMETER["standard_parallel_1", 46.766666666666666], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.56666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32052"]]
+32051=PROJCS["NAD27 / West Virginia South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 37.0], PARAMETER["standard_parallel_1", 38.88333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.483333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32051"]]
+32050=PROJCS["NAD27 / West Virginia North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 38.5], PARAMETER["standard_parallel_1", 40.25], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32050"]]
+22279=PROJCS["Cape / Lo19", GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 19.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","22279"]]
+22277=PROJCS["Cape / Lo17", GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 17.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","22277"]]
+22275=PROJCS["Cape / Lo15", GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","22275"]]
+20092=PROJCS["Pulkovo 1995 / Gauss-Kruger 32N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20092"]]
+20091=PROJCS["Pulkovo 1995 / Gauss-Kruger 31N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20091"]]
+20090=PROJCS["Pulkovo 1995 / Gauss-Kruger 30N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20090"]]
+32049=PROJCS["NAD27 / Washington South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 45.333333333333336], PARAMETER["standard_parallel_1", 47.33333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.833333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32049"]]
+32048=PROJCS["NAD27 / Washington North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.83333333333333], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.5], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32048"]]
+32047=PROJCS["NAD27 / Virginia South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.96666666666667], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.766666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32047"]]
+32046=PROJCS["NAD27 / Virginia North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.199999999999996], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.03333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32046"]]
+32045=PROJCS["NAD27 / Vermont", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -72.5], PARAMETER["latitude_of_origin", 42.5], PARAMETER["scale_factor", 0.999964286], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32045"]]
+32044=PROJCS["NAD27 / Utah South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.35], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.21666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32044"]]
+32043=PROJCS["NAD27 / Utah Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 40.65], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.016666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32043"]]
+32042=PROJCS["NAD27 / Utah North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 40.333333333333336], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32042"]]
+32041=PROJCS["NAD27 / Texas South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 25.666666666666668], PARAMETER["standard_parallel_1", 27.833333333333332], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 26.166666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32041"]]
+32040=PROJCS["NAD27 / Texas South Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 27.833333333333332], PARAMETER["standard_parallel_1", 30.28333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 28.383333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32040"]]
+20089=PROJCS["Pulkovo 1995 / Gauss-Kruger 29N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20089"]]
+20088=PROJCS["Pulkovo 1995 / Gauss-Kruger 28N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20088"]]
+20087=PROJCS["Pulkovo 1995 / Gauss-Kruger 27N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20087"]]
+20086=PROJCS["Pulkovo 1995 / Gauss-Kruger 26N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20086"]]
+20085=PROJCS["Pulkovo 1995 / Gauss-Kruger 25N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20085"]]
+20084=PROJCS["Pulkovo 1995 / Gauss-Kruger 24N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20084"]]
+20083=PROJCS["Pulkovo 1995 / Gauss-Kruger 23N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20083"]]
+20082=PROJCS["Pulkovo 1995 / Gauss-Kruger 22N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20082"]]
+20081=PROJCS["Pulkovo 1995 / Gauss-Kruger 21N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20081"]]
+20080=PROJCS["Pulkovo 1995 / Gauss-Kruger 20N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20080"]]
+61226405=GEOGCS["ATS77 (deg)", DATUM["Average Terrestrial System 1977", SPHEROID["Average Terrestrial System 1977", 6378135.0, 298.257, AUTHORITY["EPSG","7041"]], AUTHORITY["EPSG","6122"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61226405"]]
+32039=PROJCS["NAD27 / Texas Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 29.666666666666668], PARAMETER["standard_parallel_1", 31.883333333333336], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 30.116666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32039"]]
+32038=PROJCS["NAD27 / Texas North Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -97.5], PARAMETER["latitude_of_origin", 31.666666666666664], PARAMETER["standard_parallel_1", 33.96666666666667], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.13333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32038"]]
+32037=PROJCS["NAD27 / Texas North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -101.5], PARAMETER["latitude_of_origin", 34.0], PARAMETER["standard_parallel_1", 36.18333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.65], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32037"]]
+32036=PROJCS["NAD27 / Tennessee", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -86.0], PARAMETER["latitude_of_origin", 34.666666666666664], PARAMETER["standard_parallel_1", 36.416666666666664], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.25], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32036"]]
+32035=PROJCS["NAD27 / South Dakota South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 42.333333333333336], PARAMETER["standard_parallel_1", 44.4], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.833333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32035"]]
+32034=PROJCS["NAD27 / South Dakota North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.68333333333334], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.416666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32034"]]
+32033=PROJCS["NAD27 / South Carolina South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 31.833333333333336], PARAMETER["standard_parallel_1", 33.666666666666664], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.333333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32033"]]
+32031=PROJCS["NAD27 / South Carolina North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 33.0], PARAMETER["standard_parallel_1", 34.96666666666667], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.766666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32031"]]
+32030=PROJCS["NAD27 / Rhode Island", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.083333333333336], PARAMETER["scale_factor", 0.9999938], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32030"]]
+20079=PROJCS["Pulkovo 1995 / Gauss-Kruger 19N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20079"]]
+5072=PROJCS["NAD83(NSRS2007) / Conus Albers", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -96.0], PARAMETER["latitude_of_origin", 23.0], PARAMETER["standard_parallel_1", 29.5], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 45.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5072"]]
+20078=PROJCS["Pulkovo 1995 / Gauss-Kruger 18N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20078"]]
+5071=PROJCS["NAD83(HARN) / Conus Albers", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -96.0], PARAMETER["latitude_of_origin", 23.0], PARAMETER["standard_parallel_1", 29.5], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 45.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5071"]]
+20077=PROJCS["Pulkovo 1995 / Gauss-Kruger 17N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20077"]]
+5070=PROJCS["NAD83 / Conus Albers", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -96.0], PARAMETER["latitude_of_origin", 23.0], PARAMETER["standard_parallel_1", 29.5], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 45.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5070"]]
+20076=PROJCS["Pulkovo 1995 / Gauss-Kruger 16N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20076"]]
+20075=PROJCS["Pulkovo 1995 / Gauss-Kruger 15N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20075"]]
+20074=PROJCS["Pulkovo 1995 / Gauss-Kruger 14N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20074"]]
+20073=PROJCS["Pulkovo 1995 / Gauss-Kruger 13N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20073"]]
+20072=PROJCS["Pulkovo 1995 / Gauss-Kruger 12N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20072"]]
+20071=PROJCS["Pulkovo 1995 / Gauss-Kruger 11N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20071"]]
+20070=PROJCS["Pulkovo 1995 / Gauss-Kruger 10N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20070"]]
+32029=PROJCS["NAD27 / Pennsylvania South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.8], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.93333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32029"]]
+32028=PROJCS["NAD27 / Pennsylvania North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 40.166666666666664], PARAMETER["standard_parallel_1", 41.95], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.88333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32028"]]
+32027=PROJCS["NAD27 / Oregon South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["standard_parallel_1", 44.0], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.333333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32027"]]
+32026=PROJCS["NAD27 / Oregon North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["standard_parallel_1", 46.0], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.33333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32026"]]
+32025=PROJCS["NAD27 / Oklahoma South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 33.333333333333336], PARAMETER["standard_parallel_1", 35.233333333333334], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.93333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32025"]]
+32024=PROJCS["NAD27 / Oklahoma North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 35.0], PARAMETER["standard_parallel_1", 36.766666666666666], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.56666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32024"]]
+32023=PROJCS["NAD27 / Ohio South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 38.0], PARAMETER["standard_parallel_1", 40.03333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.733333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32023"]]
+32022=PROJCS["NAD27 / Ohio North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 39.666666666666664], PARAMETER["standard_parallel_1", 41.7], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.43333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32022"]]
+32021=PROJCS["NAD27 / North Dakota South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 45.666666666666664], PARAMETER["standard_parallel_1", 47.483333333333334], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.18333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32021"]]
+32020=PROJCS["NAD27 / North Dakota North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.43333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32020"]]
+5069=PROJCS["NAD27 / Conus Albers", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -96.0], PARAMETER["latitude_of_origin", 23.0], PARAMETER["standard_parallel_1", 29.5], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 45.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5069"]]
+20069=PROJCS["Pulkovo 1995 / Gauss-Kruger 9N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20069"]]
+20068=PROJCS["Pulkovo 1995 / Gauss-Kruger 8N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20068"]]
+20067=PROJCS["Pulkovo 1995 / Gauss-Kruger 7N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20067"]]
+20066=PROJCS["Pulkovo 1995 / Gauss-Kruger 6N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20066"]]
+20065=PROJCS["Pulkovo 1995 / Gauss-Kruger 5N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20065"]]
+20064=PROJCS["Pulkovo 1995 / Gauss-Kruger 4N", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20064"]]
+32019=PROJCS["NAD27 / North Carolina", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.0], PARAMETER["latitude_of_origin", 33.75], PARAMETER["standard_parallel_1", 36.166666666666664], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.333333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32019"]]
+32018=PROJCS["NAD27 / New York Long Island", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -74.0], PARAMETER["latitude_of_origin", 40.5], PARAMETER["standard_parallel_1", 41.03333333333333], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.666666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32018"]]
+32017=PROJCS["NAD27 / New York West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -78.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32017"]]
+32016=PROJCS["NAD27 / New York Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -76.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32016"]]
+32015=PROJCS["NAD27 / New York East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.33333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32015"]]
+32014=PROJCS["NAD27 / New Mexico West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.83333333333334], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999916667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32014"]]
+32013=PROJCS["NAD27 / New Mexico Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -106.25], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32013"]]
+32012=PROJCS["NAD27 / New Mexico East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -104.33333333333333], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999909091], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32012"]]
+32011=PROJCS["NAD27 / New Jersey", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.66666666666667], PARAMETER["latitude_of_origin", 38.833333333333336], PARAMETER["scale_factor", 0.999975], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32011"]]
+32010=PROJCS["NAD27 / New Hampshire", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.66666666666667], PARAMETER["latitude_of_origin", 42.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32010"]]
+22236=PROJCS["Cape / UTM zone 36S", GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22236"]]
+22235=PROJCS["Cape / UTM zone 35S", GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22235"]]
+22234=PROJCS["Cape / UTM zone 34S", GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22234"]]
+32009=PROJCS["NAD27 / Nevada West", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -118.58333333333333], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32009"]]
+32008=PROJCS["NAD27 / Nevada Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -116.66666666666667], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32008"]]
+32007=PROJCS["NAD27 / Nevada East", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.58333333333334], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32007"]]
+32006=PROJCS["NAD27 / Nebraska South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -99.5], PARAMETER["latitude_of_origin", 39.666666666666664], PARAMETER["standard_parallel_1", 41.71666666666667], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.28333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32006"]]
+32005=PROJCS["NAD27 / Nebraska North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 41.333333333333336], PARAMETER["standard_parallel_1", 42.81666666666666], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.85], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32005"]]
+32003=PROJCS["NAD27 / Montana South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -109.5], PARAMETER["latitude_of_origin", 44.0], PARAMETER["standard_parallel_1", 46.4], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.86666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32003"]]
+32002=PROJCS["NAD27 / Montana Central", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -109.5], PARAMETER["latitude_of_origin", 45.833333333333336], PARAMETER["standard_parallel_1", 47.88333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.45], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32002"]]
+32001=PROJCS["NAD27 / Montana North", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -109.5], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.71666666666667], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.85], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32001"]]
+32000=PROJCS["SIRGAS 1995 / UTM zone 25S", GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","32000"]]
+5048=PROJCS["ETRS89 / TM35FIN(N,E)", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5048"]]
+5042=PROJCS["WGS 84 / UPS South (E,N)", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar_Stereographic", AUTHORITY["EPSG","9810"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 0.994], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 2000000.0], UNIT["m", 1.0], AXIS["Easting", "North along 90 deg East"], AXIS["Northing", "North along 0 deg"], AUTHORITY["EPSG","5042"]]
+5041=PROJCS["WGS 84 / UPS North (E,N)", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar_Stereographic", AUTHORITY["EPSG","9810"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 90.0], PARAMETER["scale_factor", 0.994], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 2000000.0], UNIT["m", 1.0], AXIS["Easting", "South along 90 deg East"], AXIS["Northing", "South along 180 deg"], AUTHORITY["EPSG","5041"]]
+62016405=GEOGCS["Adindan (deg)", DATUM["Adindan", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-165.0, -11.0, 206.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6201"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62016405"]]
+63266419=GEOGCS["WGS 84 (3D DMS)", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","63266419"]]
+20032=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 32", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 32500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20032"]]
+20031=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 31", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 31500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20031"]]
+20030=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 30", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 30500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20030"]]
+63266413=GEOGCS["WGS 84 (3D deg)", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","63266413"]]
+63266411=GEOGCS["WGS 84 (DMS)", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63266411"]]
+20029=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 29", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 29500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20029"]]
+20028=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 28", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 28500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20028"]]
+20027=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 27", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 27500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20027"]]
+20026=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 26", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 26500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20026"]]
+20025=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 25", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 25500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20025"]]
+20024=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 24", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 24500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20024"]]
+20023=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 23", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 23500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20023"]]
+20022=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 22", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 22500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20022"]]
+20021=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 21", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 21500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20021"]]
+63266405=GEOGCS["WGS 84 (deg)", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63266405"]]
+20020=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 20", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 20500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20020"]]
+5018=PROJCS["Lisbon / Portuguese Grid New", GEOGCS["Lisbon", DATUM["Lisbon 1937", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-288.885, -91.744, 126.244, -1.691, -0.41, 0.211, -4.598], AUTHORITY["EPSG","6207"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4207"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -8.131906111111114], PARAMETER["latitude_of_origin", 39.666666666666664], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5018"]]
+5016=PROJCS["PTRA08 / UTM zone 28N", GEOGCS["PTRA08", DATUM["Autonomous Regions of Portugal 2008", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1041"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5013"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5016"]]
+5015=PROJCS["PTRA08 / UTM zone 26N", GEOGCS["PTRA08", DATUM["Autonomous Regions of Portugal 2008", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1041"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5013"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5015"]]
+5014=PROJCS["PTRA08 / UTM zone 25N", GEOGCS["PTRA08", DATUM["Autonomous Regions of Portugal 2008", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1041"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5013"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5014"]]
+5013=GEOGCS["PTRA08", DATUM["Autonomous Regions of Portugal 2008", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1041"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","5013"]]
+20019=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 19", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 19500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20019"]]
+5012=GEOGCS["PTRA08", DATUM["Autonomous Regions of Portugal 2008", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1041"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","5012"]]
+20018=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 18", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 18500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20018"]]
+5011=GEOCCS["PTRA08", DATUM["Autonomous Regions of Portugal 2008", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1041"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","5011"]]
+20017=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 17", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 17500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20017"]]
+20016=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 16", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 16500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20016"]]
+20015=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 15", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 15500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20015"]]
+20014=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 14", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 14500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20014"]]
+20013=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 13", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 13500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20013"]]
+20012=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 12", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 12500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20012"]]
+20011=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 11", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 11500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20011"]]
+20010=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 10", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 10500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20010"]]
+66336405=GEOGCS["IGN56 Lifou (deg)", DATUM["IGN56 Lifou", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[335.47, 222.58, -230.94, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6633"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66336405"]]
+61616405=GEOGCS["Pampa del Castillo (deg)", DATUM["Pampa del Castillo", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[27.5, 14.0, 186.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6161"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61616405"]]
+20009=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 9", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 9500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20009"]]
+20008=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 8", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 8500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20008"]]
+20007=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 7", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20007"]]
+20006=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 6", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20006"]]
+20005=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 5", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20005"]]
+20004=PROJCS["Pulkovo 1995 / Gauss-Kruger zone 4", GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20004"]]
+62566405=GEOGCS["Mahe 1971 (deg)", DATUM["Mahe 1971", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[41.0, -220.0, -134.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6256"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62566405"]]
+61286405=GEOGCS["Madzansua (deg)", DATUM["Madzansua", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6128"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61286405"]]
+63106405=GEOGCS["Yoff (deg)", DATUM["Yoff", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6310"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63106405"]]
+21782=PROJCS["CH1903 / LV03C-G", GEOGCS["CH1903", DATUM["CH1903", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[674.4, 15.1, 405.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6149"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4149"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9815"]], PARAMETER["longitude_of_center", 7.439583333333333], PARAMETER["latitude_of_center", 46.952405555555565], PARAMETER["azimuth", 90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["rectified_grid_angle", 90.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21782"]]
+21781=PROJCS["CH1903 / LV03", GEOGCS["CH1903", DATUM["CH1903", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[674.4, 15.1, 405.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6149"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4149"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9815"]], PARAMETER["longitude_of_center", 7.439583333333333], PARAMETER["latitude_of_center", 46.952405555555565], PARAMETER["azimuth", 90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 200000.0], PARAMETER["rectified_grid_angle", 90.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21781"]]
+21780=PROJCS["Bern 1898 (Bern) / LV03C", GEOGCS["Bern 1898 (Bern)", DATUM["CH1903 (Bern)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6801"]], PRIMEM["Bern", 7.439583333333333, AUTHORITY["EPSG","8907"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4801"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9815"]], PARAMETER["longitude_of_center", 0.0], PARAMETER["latitude_of_center", 46.952405555555565], PARAMETER["azimuth", 90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["rectified_grid_angle", 90.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21780"]]
+62406405=GEOGCS["Indian 1975 (deg)", DATUM["Indian 1975", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[204.64, 834.74, 293.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6240"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62406405"]]
+23948=PROJCS["Indian 1954 / UTM zone 48N", GEOGCS["Indian 1954", DATUM["Indian 1954", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[217.0, 823.0, 299.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6239"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4239"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23948"]]
+23947=PROJCS["Indian 1954 / UTM zone 47N", GEOGCS["Indian 1954", DATUM["Indian 1954", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[217.0, 823.0, 299.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6239"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4239"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23947"]]
+23946=PROJCS["Indian 1954 / UTM zone 46N", GEOGCS["Indian 1954", DATUM["Indian 1954", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[217.0, 823.0, 299.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6239"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4239"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23946"]]
+4589=PROJCS["New Beijing / Gauss-Kruger CM 135E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4589"]]
+4588=PROJCS["New Beijing / Gauss-Kruger CM 129E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4588"]]
+4587=PROJCS["New Beijing / Gauss-Kruger CM 123E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4587"]]
+4586=PROJCS["New Beijing / Gauss-Kruger CM 117E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4586"]]
+4585=PROJCS["New Beijing / Gauss-Kruger CM 111E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4585"]]
+4584=PROJCS["New Beijing / Gauss-Kruger CM 105E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4584"]]
+4583=PROJCS["New Beijing / Gauss-Kruger CM 99E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4583"]]
+4582=PROJCS["New Beijing / Gauss-Kruger CM 93E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4582"]]
+4581=PROJCS["New Beijing / Gauss-Kruger CM 87E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4581"]]
+4580=PROJCS["New Beijing / Gauss-Kruger CM 81E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4580"]]
+4579=PROJCS["New Beijing / Gauss-Kruger CM 75E", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4579"]]
+4578=PROJCS["New Beijing / Gauss-Kruger zone 23", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 23500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4578"]]
+4577=PROJCS["New Beijing / Gauss-Kruger zone 22", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 22500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4577"]]
+4576=PROJCS["New Beijing / Gauss-Kruger zone 21", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 21500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4576"]]
+4575=PROJCS["New Beijing / Gauss-Kruger zone 20", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 20500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4575"]]
+4574=PROJCS["New Beijing / Gauss-Kruger zone 19", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 19500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4574"]]
+4573=PROJCS["New Beijing / Gauss-Kruger zone 18", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 18500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4573"]]
+2399=PROJCS["Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 5", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2399"]]
+4572=PROJCS["New Beijing / Gauss-Kruger zone 17", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 17500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4572"]]
+2398=PROJCS["Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 4", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2398"]]
+4571=PROJCS["New Beijing / Gauss-Kruger zone 16", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 16500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4571"]]
+2397=PROJCS["Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 3", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2397"]]
+4570=PROJCS["New Beijing / Gauss-Kruger zone 15", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 15500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4570"]]
+2396=PROJCS["South Yemen / Gauss-Kruger zone 9", GEOGCS["South Yemen", DATUM["South Yemen", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-76.0, -138.0, 67.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6164"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4164"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 9500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2396"]]
+2395=PROJCS["South Yemen / Gauss-Kruger zone 8", GEOGCS["South Yemen", DATUM["South Yemen", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-76.0, -138.0, 67.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6164"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4164"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 8500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2395"]]
+2394=PROJCS["KKJ / Finland zone 4", GEOGCS["KKJ", DATUM["Kartastokoordinaattijarjestelma (1966)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-96.062, -82.428, -121.753, 4.801, -0.345, 1.376, 1.496], AUTHORITY["EPSG","6123"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4123"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2394"]]
+2393=PROJCS["KKJ / Finland Uniform Coordinate System", GEOGCS["KKJ", DATUM["Kartastokoordinaattijarjestelma (1966)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-96.062, -82.428, -121.753, 4.801, -0.345, 1.376, 1.496], AUTHORITY["EPSG","6123"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4123"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2393"]]
+2392=PROJCS["KKJ / Finland zone 2", GEOGCS["KKJ", DATUM["Kartastokoordinaattijarjestelma (1966)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-96.062, -82.428, -121.753, 4.801, -0.345, 1.376, 1.496], AUTHORITY["EPSG","6123"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4123"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2392"]]
+2391=PROJCS["KKJ / Finland zone 1", GEOGCS["KKJ", DATUM["Kartastokoordinaattijarjestelma (1966)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-96.062, -82.428, -121.753, 4.801, -0.345, 1.376, 1.496], AUTHORITY["EPSG","6123"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4123"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2391"]]
+2390=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 135E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2390"]]
+31529=PROJCS["Conakry 1905 / UTM zone 29N", GEOGCS["Conakry 1905", DATUM["Conakry 1905", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-23.0, 259.0, -9.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6315"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4315"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31529"]]
+31528=PROJCS["Conakry 1905 / UTM zone 28N", GEOGCS["Conakry 1905", DATUM["Conakry 1905", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-23.0, 259.0, -9.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6315"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4315"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31528"]]
+62076405=GEOGCS["Lisbon (deg)", DATUM["Lisbon 1937", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-288.885, -91.744, 126.244, -1.691, -0.41, 0.211, -4.598], AUTHORITY["EPSG","6207"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62076405"]]
+29221=PROJCS["Sapper Hill 1943 / UTM zone 21S", GEOGCS["Sapper Hill 1943", DATUM["Sapper Hill 1943", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-355.0, 21.0, 72.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6292"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4292"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29221"]]
+4569=PROJCS["New Beijing / Gauss-Kruger zone 14", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 14500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4569"]]
+29220=PROJCS["Sapper Hill 1943 / UTM zone 20S", GEOGCS["Sapper Hill 1943", DATUM["Sapper Hill 1943", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-355.0, 21.0, 72.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6292"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4292"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29220"]]
+4568=PROJCS["New Beijing / Gauss-Kruger zone 13", GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 13500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4568"]]
+2389=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 132E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2389"]]
+27040=PROJCS["Nahrwan 1967 / UTM zone 40N", GEOGCS["Nahrwan 1967", DATUM["Nahrwan 1967", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-245.0, -153.9, 382.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6270"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4270"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27040"]]
+2388=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 129E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2388"]]
+2387=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 126E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2387"]]
+2386=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 123E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2386"]]
+2385=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 120E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2385"]]
+2384=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 117E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2384"]]
+2383=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 114E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2383"]]
+2382=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 111E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2382"]]
+2381=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 108E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 108.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2381"]]
+2380=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 105E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2380"]]
+62956405=GEOGCS["Serindung (deg)", DATUM["Serindung", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6295"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62956405"]]
+27039=PROJCS["Nahrwan 1967 / UTM zone 39N", GEOGCS["Nahrwan 1967", DATUM["Nahrwan 1967", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-245.0, -153.9, 382.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6270"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4270"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27039"]]
+27038=PROJCS["Nahrwan 1967 / UTM zone 38N", GEOGCS["Nahrwan 1967", DATUM["Nahrwan 1967", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-245.0, -153.9, 382.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6270"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4270"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27038"]]
+4559=PROJCS["RRAF 1991 / UTM zone 20N", GEOGCS["RRAF 1991", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1047"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4558"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4559"]]
+27037=PROJCS["Nahrwan 1967 / UTM zone 37N", GEOGCS["Nahrwan 1967", DATUM["Nahrwan 1967", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-245.0, -153.9, 382.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6270"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4270"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","27037"]]
+4558=GEOGCS["RRAF 1991", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1047"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4558"]]
+4557=GEOGCS["RRAF 1991", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1047"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4557"]]
+4556=GEOCCS["RRAF 1991", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1047"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4556"]]
+4555=GEOGCS["New Beijing", DATUM["New Beijing", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","1045"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4555"]]
+4554=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 135E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4554"]]
+4553=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 132E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4553"]]
+2379=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 102E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2379"]]
+4552=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 129E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4552"]]
+2378=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 99E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2378"]]
+4551=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 126E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4551"]]
+2377=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 96E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2377"]]
+4550=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 123E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4550"]]
+2376=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 93E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2376"]]
+2375=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 90E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2375"]]
+2374=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 87E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2374"]]
+2373=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 84E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2373"]]
+2372=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 81E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2372"]]
+2371=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 78E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2371"]]
+2370=PROJCS["Xian 1980 / 3-degree Gauss-Kruger CM 75E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2370"]]
+61676413=GEOGCS["NZGD2000 (3D deg)", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61676413"]]
+4549=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 120E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4549"]]
+4548=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 117E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4548"]]
+4547=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 114E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4547"]]
+4546=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 111E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4546"]]
+4545=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 108E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 108.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4545"]]
+4544=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 105E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4544"]]
+4543=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 102E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4543"]]
+2369=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 45", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 45500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2369"]]
+4542=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 99E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4542"]]
+2368=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 44", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 44500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2368"]]
+4541=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 96E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4541"]]
+2367=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 43", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 43500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2367"]]
+4540=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 93E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4540"]]
+2366=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 42", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 42500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2366"]]
+2365=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 41", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 41500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2365"]]
+2364=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 40", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 40500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2364"]]
+2363=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 39", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 39500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2363"]]
+2362=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 38", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 38500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2362"]]
+2361=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 37", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 37500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2361"]]
+2360=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 36", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 108.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 36500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2360"]]
+66396405=GEOGCS["MOP78 (deg)", DATUM["MOP78", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[253.0, -132.0, -127.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6639"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66396405"]]
+61676405=GEOGCS["NZGD2000 (deg)", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61676405"]]
+4539=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 90E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4539"]]
+4538=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 87E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4538"]]
+4537=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 84E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4537"]]
+4536=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 81E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4536"]]
+4535=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 78E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4535"]]
+4534=PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 75E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4534"]]
+4533=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 45", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 45500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4533"]]
+2359=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 35", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 35500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2359"]]
+4532=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 44", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 44500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4532"]]
+2358=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 34", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 34500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2358"]]
+4531=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 43", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 43500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4531"]]
+2357=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 33", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 33500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2357"]]
+4530=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 42", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 126.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 42500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4530"]]
+2356=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 32", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 32500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2356"]]
+2355=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 31", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 31500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2355"]]
+2354=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 30", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 30500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2354"]]
+2353=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 29", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 29500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2353"]]
+2352=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 28", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 28500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2352"]]
+2351=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 27", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 27500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2351"]]
+2350=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 26", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 26500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2350"]]
+4529=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 41", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 41500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4529"]]
+4528=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 40", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 40500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4528"]]
+4527=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 39", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 39500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4527"]]
+4526=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 38", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 38500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4526"]]
+4525=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 37", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 37500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4525"]]
+4524=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 36", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 108.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 36500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4524"]]
+4523=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 35", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 35500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4523"]]
+2349=PROJCS["Xian 1980 / 3-degree Gauss-Kruger zone 25", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 25500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2349"]]
+4522=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 34", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 102.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 34500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4522"]]
+2348=PROJCS["Xian 1980 / Gauss-Kruger CM 135E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2348"]]
+4521=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 33", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 33500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4521"]]
+2347=PROJCS["Xian 1980 / Gauss-Kruger CM 129E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2347"]]
+4520=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 32", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 32500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4520"]]
+2346=PROJCS["Xian 1980 / Gauss-Kruger CM 123E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2346"]]
+2345=PROJCS["Xian 1980 / Gauss-Kruger CM 117E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2345"]]
+2344=PROJCS["Xian 1980 / Gauss-Kruger CM 111E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2344"]]
+2343=PROJCS["Xian 1980 / Gauss-Kruger CM 105E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2343"]]
+2342=PROJCS["Xian 1980 / Gauss-Kruger CM 99E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2342"]]
+2341=PROJCS["Xian 1980 / Gauss-Kruger CM 93E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2341"]]
+2340=PROJCS["Xian 1980 / Gauss-Kruger CM 87E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2340"]]
+4519=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 31", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 31500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4519"]]
+4518=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 30", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 30500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4518"]]
+4517=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 29", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 29500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4517"]]
+4516=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 28", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 28500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4516"]]
+4515=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 27", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 27500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4515"]]
+4514=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 26", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 78.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 26500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4514"]]
+4513=PROJCS["CGCS2000 / 3-degree Gauss-Kruger zone 25", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 25500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4513"]]
+2339=PROJCS["Xian 1980 / Gauss-Kruger CM 81E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2339"]]
+4512=PROJCS["CGCS2000 / Gauss-Kruger CM 135E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4512"]]
+2338=PROJCS["Xian 1980 / Gauss-Kruger CM 75E", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2338"]]
+4511=PROJCS["CGCS2000 / Gauss-Kruger CM 129E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4511"]]
+2337=PROJCS["Xian 1980 / Gauss-Kruger zone 23", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 23500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2337"]]
+4510=PROJCS["CGCS2000 / Gauss-Kruger CM 123E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4510"]]
+2336=PROJCS["Xian 1980 / Gauss-Kruger zone 22", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 22500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2336"]]
+2335=PROJCS["Xian 1980 / Gauss-Kruger zone 21", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 21500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2335"]]
+2334=PROJCS["Xian 1980 / Gauss-Kruger zone 20", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 20500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2334"]]
+2333=PROJCS["Xian 1980 / Gauss-Kruger zone 19", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 19500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2333"]]
+63166405=GEOGCS["Dealul Piscului 1933 (deg)", DATUM["Dealul Piscului 1930", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[103.25, -100.4, -307.19, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6316"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63166405"]]
+2332=PROJCS["Xian 1980 / Gauss-Kruger zone 18", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 18500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2332"]]
+2331=PROJCS["Xian 1980 / Gauss-Kruger zone 17", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 17500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2331"]]
+2330=PROJCS["Xian 1980 / Gauss-Kruger zone 16", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 16500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2330"]]
+4509=PROJCS["CGCS2000 / Gauss-Kruger CM 117E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4509"]]
+4508=PROJCS["CGCS2000 / Gauss-Kruger CM 111E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4508"]]
+61516413=GEOGCS["CHTRF95 (3D deg)", DATUM["Swiss Terrestrial Reference Frame 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6151"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61516413"]]
+4507=PROJCS["CGCS2000 / Gauss-Kruger CM 105E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4507"]]
+4506=PROJCS["CGCS2000 / Gauss-Kruger CM 99E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4506"]]
+4505=PROJCS["CGCS2000 / Gauss-Kruger CM 93E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4505"]]
+4504=PROJCS["CGCS2000 / Gauss-Kruger CM 87E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4504"]]
+4503=PROJCS["CGCS2000 / Gauss-Kruger CM 81E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4503"]]
+2329=PROJCS["Xian 1980 / Gauss-Kruger zone 15", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 15500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2329"]]
+4502=PROJCS["CGCS2000 / Gauss-Kruger CM 75E", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4502"]]
+2328=PROJCS["Xian 1980 / Gauss-Kruger zone 14", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 14500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2328"]]
+4501=PROJCS["CGCS2000 / Gauss-Kruger zone 23", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 23500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4501"]]
+2327=PROJCS["Xian 1980 / Gauss-Kruger zone 13", GEOGCS["Xian 1980", DATUM["Xian 1980", SPHEROID["IAG 1975", 6378140.0, 298.257, AUTHORITY["EPSG","7049"]], AUTHORITY["EPSG","6610"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4610"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 13500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2327"]]
+4500=PROJCS["CGCS2000 / Gauss-Kruger zone 22", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 22500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4500"]]
+2326=PROJCS["Hong Kong 1980 Grid System", GEOGCS["Hong Kong 1980", DATUM["Hong Kong 1980", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-162.619, -276.959, -161.764, 0.067753, -2.243649, -1.158827, -1.094246], AUTHORITY["EPSG","6611"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4611"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 114.17855555555556], PARAMETER["latitude_of_origin", 22.312133333333335], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 836694.05], PARAMETER["false_northing", 819069.8], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2326"]]
+2325=PROJCS["ED50 / TM45", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2325"]]
+2324=PROJCS["ED50 / TM42", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 42.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2324"]]
+2323=PROJCS["ED50 / TM39", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2323"]]
+2322=PROJCS["ED50 / TM36", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 36.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2322"]]
+2321=PROJCS["ED50 / TM33", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2321"]]
+2320=PROJCS["ED50 / TM30", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2320"]]
+66236405=GEOGCS["CSG67 (deg)", DATUM["Centre Spatial Guyanais 1967", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-186.0, 230.0, 110.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6623"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66236405"]]
+61516405=GEOGCS["CHTRF95 (deg)", DATUM["Swiss Terrestrial Reference Frame 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6151"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61516405"]]
+2319=PROJCS["ED50 / TM27", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2319"]]
+2318=PROJCS["Ain el Abd / Aramco Lambert", GEOGCS["Ain el Abd", DATUM["Ain el Abd 1970", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-85.645, -273.077, -79.708, 2.289, 1.421, -2.532, 3.194], AUTHORITY["EPSG","6204"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4204"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 48.0], PARAMETER["latitude_of_origin", 25.08951], PARAMETER["standard_parallel_1", 33.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 17.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2318"]]
+2317=PROJCS["PSAD56 / ICN Regional", GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -66.0], PARAMETER["latitude_of_origin", 6.0], PARAMETER["standard_parallel_1", 9.0], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 3.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2317"]]
+2316=PROJCS["Campo Inchauspe / UTM zone 20S", GEOGCS["Campo Inchauspe", DATUM["Campo Inchauspe", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-154.5, 150.7, 100.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6221"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4221"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2316"]]
+2315=PROJCS["Campo Inchauspe / UTM zone 19S", GEOGCS["Campo Inchauspe", DATUM["Campo Inchauspe", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-154.5, 150.7, 100.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6221"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4221"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2315"]]
+2314=PROJCS["Trinidad 1903 / Trinidad Grid (ftCla)", GEOGCS["Trinidad 1903", DATUM["Trinidad 1903", SPHEROID["Clarke 1858", 6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]], TOWGS84[-61.702, 284.488, 472.052, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6302"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4302"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", -61.33333333333333], PARAMETER["latitude_of_origin", 10.441666666666666], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 283800.0], PARAMETER["false_northing", 214500.0], UNIT["m*0.3047972654", 0.3047972654], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2314"]]
+62466405=GEOGCS["KOC (deg)", DATUM["Kuwait Oil Company", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-294.7, -200.1, 525.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6246"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62466405"]]
+2313=PROJCS["Kousseri / UTM zone 33N", GEOGCS["Kousseri", DATUM["Kousseri", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6198"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4198"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2313"]]
+2312=PROJCS["Garoua / UTM zone 33N", GEOGCS["Garoua", DATUM["Garoua", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6197"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4197"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2312"]]
+2311=PROJCS["WGS 84 / TM 6 NE", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 6.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2311"]]
+2310=PROJCS["WGS 84 / TM 132 SE", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2310"]]
+2309=PROJCS["WGS 84 / TM 116 SE", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 116.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2309"]]
+2308=PROJCS["Batavia / TM 109 SE", GEOGCS["Batavia", DATUM["Batavia", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-377.7, 675.1, -52.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6211"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4211"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 109.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2308"]]
+26592=PROJCS["Monte Mario (Rome) / Italy zone 2", GEOGCS["Monte Mario (Rome)", DATUM["Monte Mario (Rome)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6806"]], PRIMEM["Rome", 12.452333333333332, AUTHORITY["EPSG","8906"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4806"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 2520000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26592"]]
+26591=PROJCS["Monte Mario (Rome) / Italy zone 1", GEOGCS["Monte Mario (Rome)", DATUM["Monte Mario (Rome)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6806"]], PRIMEM["Rome", 12.452333333333332, AUTHORITY["EPSG","8906"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4806"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26591"]]
+63006405=GEOGCS["TM75 (deg)", DATUM["Geodetic Datum of 1965", SPHEROID["Airy Modified 1849", 6377340.189, 299.3249646, AUTHORITY["EPSG","7002"]], TOWGS84[482.5, -130.6, 564.6, -1.042, -0.214, -0.631, 8.15], AUTHORITY["EPSG","6300"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63006405"]]
+62306405=GEOGCS["ED50 (deg)", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62306405"]]
+24383=PROJCS["Kalianpur 1975 / India zone IV", GEOGCS["Kalianpur 1975", DATUM["Kalianpur 1975", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], TOWGS84[295.0, 736.0, 257.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6146"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4146"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 80.0], PARAMETER["latitude_of_origin", 12.0], PARAMETER["scale_factor", 0.99878641], PARAMETER["false_easting", 2743195.5], PARAMETER["false_northing", 914398.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24383"]]
+24382=PROJCS["Kalianpur 1880 / India zone IIb", GEOGCS["Kalianpur 1880", DATUM["Kalianpur 1880", SPHEROID["Everest (1830 Definition)", 6377299.36559538, 300.80172554336184, AUTHORITY["EPSG","7042"]], AUTHORITY["EPSG","6243"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4243"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["semi_minor", 6951124.8599999985], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.99878641], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m*0.9143985307444408", 0.9143985307444408], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24382"]]
+24381=PROJCS["Kalianpur 1975 / India zone III", GEOGCS["Kalianpur 1975", DATUM["Kalianpur 1975", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], TOWGS84[295.0, 736.0, 257.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6146"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4146"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 80.0], PARAMETER["latitude_of_origin", 19.0], PARAMETER["scale_factor", 0.99878641], PARAMETER["false_easting", 2743195.5], PARAMETER["false_northing", 914398.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24381"]]
+24380=PROJCS["Kalianpur 1975 / India zone IIb", GEOGCS["Kalianpur 1975", DATUM["Kalianpur 1975", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], TOWGS84[295.0, 736.0, 257.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6146"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4146"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.99878641], PARAMETER["false_easting", 2743195.5], PARAMETER["false_northing", 914398.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24380"]]
+24379=PROJCS["Kalianpur 1975 / India zone IIa", GEOGCS["Kalianpur 1975", DATUM["Kalianpur 1975", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], TOWGS84[295.0, 736.0, 257.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6146"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4146"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 74.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.99878641], PARAMETER["false_easting", 2743195.5], PARAMETER["false_northing", 914398.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24379"]]
+24378=PROJCS["Kalianpur 1975 / India zone I", GEOGCS["Kalianpur 1975", DATUM["Kalianpur 1975", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], TOWGS84[295.0, 736.0, 257.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6146"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4146"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 68.0], PARAMETER["latitude_of_origin", 32.5], PARAMETER["scale_factor", 0.99878641], PARAMETER["false_easting", 2743195.5], PARAMETER["false_northing", 914398.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24378"]]
+24377=PROJCS["Kalianpur 1962 / India zone IIa", GEOGCS["Kalianpur 1962", DATUM["Kalianpur 1962", SPHEROID["Everest 1830 (1962 Definition)", 6377301.243, 300.8017255, AUTHORITY["EPSG","7044"]], TOWGS84[275.57, 676.78, 229.6, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6145"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4145"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 74.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.99878641], PARAMETER["false_easting", 2743196.4], PARAMETER["false_northing", 914398.8], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24377"]]
+24376=PROJCS["Kalianpur 1962 / India zone I", GEOGCS["Kalianpur 1962", DATUM["Kalianpur 1962", SPHEROID["Everest 1830 (1962 Definition)", 6377301.243, 300.8017255, AUTHORITY["EPSG","7044"]], TOWGS84[275.57, 676.78, 229.6, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6145"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4145"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 68.0], PARAMETER["latitude_of_origin", 32.5], PARAMETER["scale_factor", 0.99878641], PARAMETER["false_easting", 2743196.4], PARAMETER["false_northing", 914398.8], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24376"]]
+24375=PROJCS["Kalianpur 1937 / India zone IIb", GEOGCS["Kalianpur 1937", DATUM["Kalianpur 1937", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[214.0, 804.0, 268.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6144"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4144"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 90.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.99878641], PARAMETER["false_easting", 2743185.69], PARAMETER["false_northing", 914395.23], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24375"]]
+24374=PROJCS["Kalianpur 1880 / India zone IV", GEOGCS["Kalianpur 1880", DATUM["Kalianpur 1880", SPHEROID["Everest (1830 Definition)", 6377299.36559538, 300.80172554336184, AUTHORITY["EPSG","7042"]], AUTHORITY["EPSG","6243"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4243"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["semi_minor", 6951124.8599999985], PARAMETER["central_meridian", 80.0], PARAMETER["latitude_of_origin", 12.0], PARAMETER["scale_factor", 0.99878641], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m*0.9143985307444408", 0.9143985307444408], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24374"]]
+24373=PROJCS["Kalianpur 1880 / India zone III", GEOGCS["Kalianpur 1880", DATUM["Kalianpur 1880", SPHEROID["Everest (1830 Definition)", 6377299.36559538, 300.80172554336184, AUTHORITY["EPSG","7042"]], AUTHORITY["EPSG","6243"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4243"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["semi_minor", 6951124.8599999985], PARAMETER["central_meridian", 80.0], PARAMETER["latitude_of_origin", 19.0], PARAMETER["scale_factor", 0.99878641], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m*0.9143985307444408", 0.9143985307444408], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24373"]]
+24372=PROJCS["Kalianpur 1880 / India zone IIa", GEOGCS["Kalianpur 1880", DATUM["Kalianpur 1880", SPHEROID["Everest (1830 Definition)", 6377299.36559538, 300.80172554336184, AUTHORITY["EPSG","7042"]], AUTHORITY["EPSG","6243"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4243"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["semi_minor", 6951124.8599999985], PARAMETER["central_meridian", 74.0], PARAMETER["latitude_of_origin", 26.0], PARAMETER["scale_factor", 0.99878641], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m*0.9143985307444408", 0.9143985307444408], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24372"]]
+24371=PROJCS["Kalianpur 1880 / India zone I", GEOGCS["Kalianpur 1880", DATUM["Kalianpur 1880", SPHEROID["Everest (1830 Definition)", 6377299.36559538, 300.80172554336184, AUTHORITY["EPSG","7042"]], AUTHORITY["EPSG","6243"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4243"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["semi_minor", 6951124.8599999985], PARAMETER["central_meridian", 68.0], PARAMETER["latitude_of_origin", 32.5], PARAMETER["scale_factor", 0.99878641], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m*0.9143985307444408", 0.9143985307444408], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24371"]]
+22197=PROJCS["Campo Inchauspe / Argentina 7", GEOGCS["Campo Inchauspe", DATUM["Campo Inchauspe", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-154.5, 150.7, 100.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6221"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4221"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -54.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22197"]]
+24370=PROJCS["Kalianpur 1880 / India zone 0", GEOGCS["Kalianpur 1880", DATUM["Kalianpur 1880", SPHEROID["Everest (1830 Definition)", 6377299.36559538, 300.80172554336184, AUTHORITY["EPSG","7042"]], AUTHORITY["EPSG","6243"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4243"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["semi_minor", 6951124.8599999985], PARAMETER["central_meridian", 68.0], PARAMETER["latitude_of_origin", 39.5], PARAMETER["scale_factor", 0.99846154], PARAMETER["false_easting", 2355500.0], PARAMETER["false_northing", 2590000.0], UNIT["m*0.9143985307444408", 0.9143985307444408], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24370"]]
+22196=PROJCS["Campo Inchauspe / Argentina 6", GEOGCS["Campo Inchauspe", DATUM["Campo Inchauspe", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-154.5, 150.7, 100.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6221"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4221"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22196"]]
+22195=PROJCS["Campo Inchauspe / Argentina 5", GEOGCS["Campo Inchauspe", DATUM["Campo Inchauspe", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-154.5, 150.7, 100.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6221"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4221"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -60.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22195"]]
+22194=PROJCS["Campo Inchauspe / Argentina 4", GEOGCS["Campo Inchauspe", DATUM["Campo Inchauspe", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-154.5, 150.7, 100.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6221"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4221"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22194"]]
+22193=PROJCS["Campo Inchauspe / Argentina 3", GEOGCS["Campo Inchauspe", DATUM["Campo Inchauspe", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-154.5, 150.7, 100.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6221"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4221"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -66.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22193"]]
+22192=PROJCS["Campo Inchauspe / Argentina 2", GEOGCS["Campo Inchauspe", DATUM["Campo Inchauspe", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-154.5, 150.7, 100.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6221"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4221"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22192"]]
+22191=PROJCS["Campo Inchauspe / Argentina 1", GEOGCS["Campo Inchauspe", DATUM["Campo Inchauspe", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-154.5, 150.7, 100.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6221"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4221"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -72.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22191"]]
+61906413=GEOGCS["POSGAR 98 (3D deg)", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61906413"]]
+22187=PROJCS["POSGAR 94 / Argentina 7", GEOGCS["POSGAR 94", DATUM["Posiciones Geodesicas Argentinas 1994", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6694"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4694"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -54.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22187"]]
+22186=PROJCS["POSGAR 94 / Argentina 6", GEOGCS["POSGAR 94", DATUM["Posiciones Geodesicas Argentinas 1994", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6694"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4694"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22186"]]
+22185=PROJCS["POSGAR 94 / Argentina 5", GEOGCS["POSGAR 94", DATUM["Posiciones Geodesicas Argentinas 1994", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6694"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4694"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -60.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22185"]]
+22184=PROJCS["POSGAR 94 / Argentina 4", GEOGCS["POSGAR 94", DATUM["Posiciones Geodesicas Argentinas 1994", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6694"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4694"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22184"]]
+22183=PROJCS["POSGAR 94 / Argentina 3", GEOGCS["POSGAR 94", DATUM["Posiciones Geodesicas Argentinas 1994", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6694"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4694"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -66.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22183"]]
+22182=PROJCS["POSGAR 94 / Argentina 2", GEOGCS["POSGAR 94", DATUM["Posiciones Geodesicas Argentinas 1994", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6694"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4694"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22182"]]
+22181=PROJCS["POSGAR 94 / Argentina 1", GEOGCS["POSGAR 94", DATUM["Posiciones Geodesicas Argentinas 1994", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6694"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4694"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -72.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22181"]]
+61906405=GEOGCS["POSGAR 98 (deg)", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61906405"]]
+22177=PROJCS["POSGAR 98 / Argentina 7", GEOGCS["POSGAR 98", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4190"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -54.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22177"]]
+22176=PROJCS["POSGAR 98 / Argentina 6", GEOGCS["POSGAR 98", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4190"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22176"]]
+22175=PROJCS["POSGAR 98 / Argentina 5", GEOGCS["POSGAR 98", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4190"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -60.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22175"]]
+22174=PROJCS["POSGAR 98 / Argentina 4", GEOGCS["POSGAR 98", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4190"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22174"]]
+62856405=GEOGCS["Qatar 1974 (deg)", DATUM["Qatar 1974", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-128.16, -282.42, 21.93, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6285"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62856405"]]
+22173=PROJCS["POSGAR 98 / Argentina 3", GEOGCS["POSGAR 98", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4190"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -66.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22173"]]
+22172=PROJCS["POSGAR 98 / Argentina 2", GEOGCS["POSGAR 98", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4190"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22172"]]
+22171=PROJCS["POSGAR 98 / Argentina 1", GEOGCS["POSGAR 98", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4190"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -72.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22171"]]
+24347=PROJCS["Kalianpur 1975 / UTM zone 47N", GEOGCS["Kalianpur 1975", DATUM["Kalianpur 1975", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], TOWGS84[295.0, 736.0, 257.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6146"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4146"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24347"]]
+24346=PROJCS["Kalianpur 1975 / UTM zone 46N", GEOGCS["Kalianpur 1975", DATUM["Kalianpur 1975", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], TOWGS84[295.0, 736.0, 257.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6146"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4146"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24346"]]
+24345=PROJCS["Kalianpur 1975 / UTM zone 45N", GEOGCS["Kalianpur 1975", DATUM["Kalianpur 1975", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], TOWGS84[295.0, 736.0, 257.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6146"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4146"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24345"]]
+24344=PROJCS["Kalianpur 1975 / UTM zone 44N", GEOGCS["Kalianpur 1975", DATUM["Kalianpur 1975", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], TOWGS84[295.0, 736.0, 257.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6146"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4146"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24344"]]
+24343=PROJCS["Kalianpur 1975 / UTM zone 43N", GEOGCS["Kalianpur 1975", DATUM["Kalianpur 1975", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], TOWGS84[295.0, 736.0, 257.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6146"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4146"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24343"]]
+24342=PROJCS["Kalianpur 1975 / UTM zone 42N", GEOGCS["Kalianpur 1975", DATUM["Kalianpur 1975", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], TOWGS84[295.0, 736.0, 257.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6146"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4146"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24342"]]
+66296405=GEOGCS["Tahaa (deg)", DATUM["Tahaa 54", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[72.438, 345.918, 79.486, 1.6045, -0.8823, -0.5565, 1.3746], AUTHORITY["EPSG","6629"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66296405"]]
+61576405=GEOGCS["Mount Dillon (deg)", DATUM["Mount Dillon", SPHEROID["Clarke 1858", 6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]], AUTHORITY["EPSG","6157"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61576405"]]
+24313=PROJCS["Kalianpur 1962 / UTM zone 43N", GEOGCS["Kalianpur 1962", DATUM["Kalianpur 1962", SPHEROID["Everest 1830 (1962 Definition)", 6377301.243, 300.8017255, AUTHORITY["EPSG","7044"]], TOWGS84[275.57, 676.78, 229.6, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6145"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4145"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24313"]]
+24312=PROJCS["Kalianpur 1962 / UTM zone 42N", GEOGCS["Kalianpur 1962", DATUM["Kalianpur 1962", SPHEROID["Everest 1830 (1962 Definition)", 6377301.243, 300.8017255, AUTHORITY["EPSG","7044"]], TOWGS84[275.57, 676.78, 229.6, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6145"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4145"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24312"]]
+24311=PROJCS["Kalianpur 1962 / UTM zone 41N", GEOGCS["Kalianpur 1962", DATUM["Kalianpur 1962", SPHEROID["Everest 1830 (1962 Definition)", 6377301.243, 300.8017255, AUTHORITY["EPSG","7044"]], TOWGS84[275.57, 676.78, 229.6, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6145"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4145"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24311"]]
+24306=PROJCS["Kalianpur 1937 / UTM zone 46N", GEOGCS["Kalianpur 1937", DATUM["Kalianpur 1937", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[214.0, 804.0, 268.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6144"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4144"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24306"]]
+24305=PROJCS["Kalianpur 1937 / UTM zone 45N", GEOGCS["Kalianpur 1937", DATUM["Kalianpur 1937", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[214.0, 804.0, 268.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6144"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4144"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24305"]]
+63066405=GEOGCS["Bern 1938 (deg)", DATUM["Bern 1938", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6306"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63066405"]]
+66136405=GEOGCS["Segara (deg)", DATUM["Gunung Segara", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-404.78, 685.68, 45.47, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6613"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66136405"]]
+61416405=GEOGCS["Israel (deg)", DATUM["Israel", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-48.0, 55.0, 52.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6141"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61416405"]]
+62366405=GEOGCS["Hu Tzu Shan (deg)", DATUM["Hu Tzu Shan 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-637.0, -549.0, -203.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6236"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62366405"]]
+29195=PROJCS["SAD69 / UTM zone 25S", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29195"]]
+29194=PROJCS["SAD69 / UTM zone 24S", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29194"]]
+23894=PROJCS["ID74 / UTM zone 54S", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23894"]]
+29193=PROJCS["SAD69 / UTM zone 23S", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29193"]]
+23893=PROJCS["ID74 / UTM zone 53S", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23893"]]
+29192=PROJCS["SAD69 / UTM zone 22S", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29192"]]
+23892=PROJCS["ID74 / UTM zone 52S", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23892"]]
+29191=PROJCS["SAD69 / UTM zone 21S", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29191"]]
+23891=PROJCS["ID74 / UTM zone 51S", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23891"]]
+29190=PROJCS["SAD69 / UTM zone 20S", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29190"]]
+23890=PROJCS["ID74 / UTM zone 50S", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23890"]]
+61966405=GEOGCS["Ammassalik 1958 (deg)", DATUM["Ammassalik 1958", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-45.0, 417.0, -3.5, 0.0, 0.0, 0.814, -0.6], AUTHORITY["EPSG","6196"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61966405"]]
+29189=PROJCS["SAD69 / UTM zone 19S", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29189"]]
+23889=PROJCS["ID74 / UTM zone 49S", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23889"]]
+29188=PROJCS["SAD69 / UTM zone 18S", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29188"]]
+23888=PROJCS["ID74 / UTM zone 48S", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23888"]]
+29187=PROJCS["SAD69 / UTM zone 17S", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29187"]]
+23887=PROJCS["ID74 / UTM zone 47S", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23887"]]
+23886=PROJCS["ID74 / UTM zone 46S", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23886"]]
+23884=PROJCS["DGN95 / UTM zone 54S", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23884"]]
+23883=PROJCS["DGN95 / UTM zone 53S", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23883"]]
+23882=PROJCS["DGN95 / UTM zone 52S", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23882"]]
+23881=PROJCS["DGN95 / UTM zone 51S", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23881"]]
+23880=PROJCS["DGN95 / UTM zone 50S", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23880"]]
+23879=PROJCS["DGN95 / UTM zone 49S", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23879"]]
+23878=PROJCS["DGN95 / UTM zone 48S", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23878"]]
+62206405=GEOGCS["Camacupa (deg)", DATUM["Camacupa", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-50.9, -347.6, -231.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6220"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62206405"]]
+23877=PROJCS["DGN95 / UTM zone 47S", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23877"]]
+29172=PROJCS["SAD69 / UTM zone 22N", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29172"]]
+23872=PROJCS["DGN95 / UTM zone 52N", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23872"]]
+29171=PROJCS["SAD69 / UTM zone 21N", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29171"]]
+23871=PROJCS["DGN95 / UTM zone 51N", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23871"]]
+29170=PROJCS["SAD69 / UTM zone 20N", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29170"]]
+23870=PROJCS["DGN95 / UTM zone 50N", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23870"]]
+31469=PROJCS["DHDN / 3-degree Gauss-Kruger zone 5", GEOGCS["DHDN", DATUM["Deutsches Hauptdreiecksnetz", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[612.4, 77.0, 440.2, -0.054, 0.057, -2.797, 2.55], AUTHORITY["EPSG","6314"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4314"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31469"]]
+31468=PROJCS["DHDN / 3-degree Gauss-Kruger zone 4", GEOGCS["DHDN", DATUM["Deutsches Hauptdreiecksnetz", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[612.4, 77.0, 440.2, -0.054, 0.057, -2.797, 2.55], AUTHORITY["EPSG","6314"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4314"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31468"]]
+31467=PROJCS["DHDN / 3-degree Gauss-Kruger zone 3", GEOGCS["DHDN", DATUM["Deutsches Hauptdreiecksnetz", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[612.4, 77.0, 440.2, -0.054, 0.057, -2.797, 2.55], AUTHORITY["EPSG","6314"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4314"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31467"]]
+31466=PROJCS["DHDN / 3-degree Gauss-Kruger zone 2", GEOGCS["DHDN", DATUM["Deutsches Hauptdreiecksnetz", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[612.4, 77.0, 440.2, -0.054, 0.057, -2.797, 2.55], AUTHORITY["EPSG","6314"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4314"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 6.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31466"]]
+29169=PROJCS["SAD69 / UTM zone 19N", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29169"]]
+31465=PROJCS["DHDN / 3-degree Gauss zone 5", GEOGCS["DHDN", DATUM["Deutsches Hauptdreiecksnetz", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[612.4, 77.0, 440.2, -0.054, 0.057, -2.797, 2.55], AUTHORITY["EPSG","6314"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4314"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31465"]]
+23869=PROJCS["DGN95 / UTM zone 49N", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23869"]]
+29168=PROJCS["SAD69 / UTM zone 18N", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29168"]]
+31464=PROJCS["DHDN / 3-degree Gauss zone 4", GEOGCS["DHDN", DATUM["Deutsches Hauptdreiecksnetz", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[612.4, 77.0, 440.2, -0.054, 0.057, -2.797, 2.55], AUTHORITY["EPSG","6314"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4314"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31464"]]
+23868=PROJCS["DGN95 / UTM zone 48N", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23868"]]
+31463=PROJCS["DHDN / 3-degree Gauss zone 3", GEOGCS["DHDN", DATUM["Deutsches Hauptdreiecksnetz", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[612.4, 77.0, 440.2, -0.054, 0.057, -2.797, 2.55], AUTHORITY["EPSG","6314"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4314"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31463"]]
+23867=PROJCS["DGN95 / UTM zone 47N", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23867"]]
+31462=PROJCS["DHDN / 3-degree Gauss zone 2", GEOGCS["DHDN", DATUM["Deutsches Hauptdreiecksnetz", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[612.4, 77.0, 440.2, -0.054, 0.057, -2.797, 2.55], AUTHORITY["EPSG","6314"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4314"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 6.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31462"]]
+23866=PROJCS["DGN95 / UTM zone 46N", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23866"]]
+31461=PROJCS["DHDN / 3-degree Gauss zone 1", GEOGCS["DHDN", DATUM["Deutsches Hauptdreiecksnetz", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[612.4, 77.0, 440.2, -0.054, 0.057, -2.797, 2.55], AUTHORITY["EPSG","6314"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4314"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31461"]]
+61806413=GEOGCS["EST97 (3D deg)", DATUM["Estonia 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6180"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61806413"]]
+23853=PROJCS["ID74 / UTM zone 53N", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23853"]]
+23852=PROJCS["ID74 / UTM zone 52N", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23852"]]
+4499=PROJCS["CGCS2000 / Gauss-Kruger zone 21", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 21500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4499"]]
+23851=PROJCS["ID74 / UTM zone 51N", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23851"]]
+4498=PROJCS["CGCS2000 / Gauss-Kruger zone 20", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 20500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4498"]]
+23850=PROJCS["ID74 / UTM zone 50N", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23850"]]
+4497=PROJCS["CGCS2000 / Gauss-Kruger zone 19", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 19500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4497"]]
+4496=PROJCS["CGCS2000 / Gauss-Kruger zone 18", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 18500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4496"]]
+4495=PROJCS["CGCS2000 / Gauss-Kruger zone 17", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 17500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4495"]]
+4494=PROJCS["CGCS2000 / Gauss-Kruger zone 16", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 16500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4494"]]
+4493=PROJCS["CGCS2000 / Gauss-Kruger zone 15", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 15500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4493"]]
+4492=PROJCS["CGCS2000 / Gauss-Kruger zone 14", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 14500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4492"]]
+4491=PROJCS["CGCS2000 / Gauss-Kruger zone 13", GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 13500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4491"]]
+4490=GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4490"]]
+61806405=GEOGCS["EST97 (deg)", DATUM["Estonia 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6180"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61806405"]]
+23849=PROJCS["ID74 / UTM zone 49N", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23849"]]
+23848=PROJCS["ID74 / UTM zone 48N", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23848"]]
+23847=PROJCS["ID74 / UTM zone 47N", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23847"]]
+23846=PROJCS["ID74 / UTM zone 46N", GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23846"]]
+23845=PROJCS["DGN95 / Indonesia TM-3 zone 54.1", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 139.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23845"]]
+23844=PROJCS["DGN95 / Indonesia TM-3 zone 53.2", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 136.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23844"]]
+23843=PROJCS["DGN95 / Indonesia TM-3 zone 53.1", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 133.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23843"]]
+23842=PROJCS["DGN95 / Indonesia TM-3 zone 52.2", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 130.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23842"]]
+4489=PROJCS["Mexican Datum of 1993 / UTM zone 16N", GEOGCS["Mexican Datum of 1993", DATUM["Mexican Datum of 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1042"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4483"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4489"]]
+23841=PROJCS["DGN95 / Indonesia TM-3 zone 52.1", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 127.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23841"]]
+4488=PROJCS["Mexican Datum of 1993 / UTM zone 15N", GEOGCS["Mexican Datum of 1993", DATUM["Mexican Datum of 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1042"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4483"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4488"]]
+23840=PROJCS["DGN95 / Indonesia TM-3 zone 51.2", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 124.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23840"]]
+4487=PROJCS["Mexican Datum of 1993 / UTM zone 14N", GEOGCS["Mexican Datum of 1993", DATUM["Mexican Datum of 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1042"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4483"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4487"]]
+4486=PROJCS["Mexican Datum of 1993 / UTM zone 13N", GEOGCS["Mexican Datum of 1993", DATUM["Mexican Datum of 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1042"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4483"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4486"]]
+62756405=GEOGCS["NTF (deg)", DATUM["Nouvelle Triangulation Francaise", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-168.0, -60.0, 320.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6275"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62756405"]]
+4485=PROJCS["Mexican Datum of 1993 / UTM zone 12N", GEOGCS["Mexican Datum of 1993", DATUM["Mexican Datum of 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1042"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4483"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4485"]]
+4484=PROJCS["Mexican Datum of 1993 / UTM zone 11N", GEOGCS["Mexican Datum of 1993", DATUM["Mexican Datum of 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1042"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4483"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4484"]]
+4483=GEOGCS["Mexican Datum of 1993", DATUM["Mexican Datum of 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1042"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4483"]]
+4482=GEOGCS["Mexican Datum of 1993", DATUM["Mexican Datum of 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1042"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4482"]]
+4481=GEOCCS["Mexican Datum of 1993", DATUM["Mexican Datum of 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1042"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4481"]]
+4480=GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4480"]]
+23839=PROJCS["DGN95 / Indonesia TM-3 zone 51.1", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 121.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23839"]]
+23838=PROJCS["DGN95 / Indonesia TM-3 zone 50.2", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 118.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23838"]]
+23837=PROJCS["DGN95 / Indonesia TM-3 zone 50.1", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 115.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23837"]]
+23836=PROJCS["DGN95 / Indonesia TM-3 zone 49.2", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 112.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23836"]]
+23835=PROJCS["DGN95 / Indonesia TM-3 zone 49.1", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 109.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23835"]]
+23834=PROJCS["DGN95 / Indonesia TM-3 zone 48.2", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 106.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23834"]]
+23833=PROJCS["DGN95 / Indonesia TM-3 zone 48.1", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 103.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23833"]]
+23832=PROJCS["DGN95 / Indonesia TM-3 zone 47.2", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 100.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23832"]]
+4479=GEOCCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4479"]]
+23831=PROJCS["DGN95 / Indonesia TM-3 zone 47.1", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 97.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23831"]]
+23830=PROJCS["DGN95 / Indonesia TM-3 zone 46.2", GEOGCS["DGN95", DATUM["Datum Geodesi Nasional 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6755"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4755"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 94.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23830"]]
+4475=GEOGCS["Cadastre 1997", DATUM["Cadastre 1997", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-381.788, -57.501, -256.673, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1037"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4475"]]
+4474=PROJCS["Cadastre 1997 / UTM zone 38S", GEOGCS["Combani 1950", DATUM["Combani 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-382.0, -59.0, -262.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6632"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4632"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4474"]]
+66196413=GEOGCS["SWEREF99 (3D deg)", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","66196413"]]
+4473=GEOCCS["Cadastre 1997", DATUM["Cadastre 1997", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-381.788, -57.501, -256.673, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1037"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4473"]]
+4472=GEOGCS["Cadastre 1997", DATUM["Cadastre 1997", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-381.788, -57.501, -256.673, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1037"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4472"]]
+4471=PROJCS["RGM04 / UTM zone 38S", GEOGCS["RGM04", DATUM["Reseau Geodesique de Mayotte 2004", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1036"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4470"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4471"]]
+4470=GEOGCS["RGM04", DATUM["Reseau Geodesique de Mayotte 2004", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1036"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4470"]]
+2295=PROJCS["ATS77 / MTM Nova Scotia zone 5", GEOGCS["ATS77", DATUM["Average Terrestrial System 1977", SPHEROID["Average Terrestrial System 1977", 6378135.0, 298.257, AUTHORITY["EPSG","7041"]], AUTHORITY["EPSG","6122"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4122"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -64.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2295"]]
+2294=PROJCS["ATS77 / MTM Nova Scotia zone 4", GEOGCS["ATS77", DATUM["Average Terrestrial System 1977", SPHEROID["Average Terrestrial System 1977", 6378135.0, 298.257, AUTHORITY["EPSG","7041"]], AUTHORITY["EPSG","6122"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4122"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -61.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2294"]]
+2291=PROJCS["NAD83(CSRS98) / Prince Edward Isl. Stereographic (NAD83)", GEOGCS["ATS77", DATUM["Average Terrestrial System 1977", SPHEROID["Average Terrestrial System 1977", 6378135.0, 298.257, AUTHORITY["EPSG","7041"]], AUTHORITY["EPSG","6122"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4122"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 47.25], PARAMETER["scale_factor", 0.999912], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2291"]]
+2290=PROJCS["ATS77 / Prince Edward Isl. Stereographic (ATS77)", GEOGCS["ATS77", DATUM["Average Terrestrial System 1977", SPHEROID["Average Terrestrial System 1977", 6378135.0, 298.257, AUTHORITY["EPSG","7041"]], AUTHORITY["EPSG","6122"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4122"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 47.25], PARAMETER["scale_factor", 0.999912], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 400000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2290"]]
+4469=GEOGCS["RGM04", DATUM["Reseau Geodesique de Mayotte 2004", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1036"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4469"]]
+4468=GEOCCS["RGM04", DATUM["Reseau Geodesique de Mayotte 2004", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1036"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4468"]]
+4467=PROJCS["RGSPM06 / UTM zone 21N", GEOGCS["RGSPM06", DATUM["Reseau Geodesique de Saint Pierre et Miquelon 2006", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1038"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4463"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4467"]]
+4466=GEOGCS["RGSPM06", DATUM["Reseau Geodesique de Saint Pierre et Miquelon 2006", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1038"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4466"]]
+66196405=GEOGCS["SWEREF99 (deg)", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66196405"]]
+4465=GEOCCS["RGSPM06", DATUM["Reseau Geodesique de Saint Pierre et Miquelon 2006", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1038"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4465"]]
+4463=GEOGCS["RGSPM06", DATUM["Reseau Geodesique de Saint Pierre et Miquelon 2006", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1038"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4463"]]
+68016405=GEOGCS["Bern 1898 (Bern) (deg)", DATUM["CH1903 (Bern)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6801"]], PRIMEM["Bern", 7.439583333333333, AUTHORITY["EPSG","8907"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","68016405"]]
+2289=PROJCS["NAD83 / Wisconsin South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 42.0], PARAMETER["standard_parallel_1", 44.06666666666666], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.73333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2289"]]
+4462=PROJCS["WGS 84 / Australian Centre for Remote Sensing Lambert", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 132.0], PARAMETER["latitude_of_origin", -27.0], PARAMETER["standard_parallel_1", -18.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -36.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4462"]]
+61476405=GEOGCS["Hanoi 1972 (deg)", DATUM["Hanoi 1972", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-17.51, -108.32, -62.39, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6147"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61476405"]]
+2288=PROJCS["NAD83 / Wisconsin Central (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.5], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.25], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2288"]]
+2287=PROJCS["NAD83 / Wisconsin North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 45.166666666666664], PARAMETER["standard_parallel_1", 46.766666666666666], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.56666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2287"]]
+2286=PROJCS["NAD83 / Washington South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 45.333333333333336], PARAMETER["standard_parallel_1", 47.33333333333333], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.833333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2286"]]
+2285=PROJCS["NAD83 / Washington North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.83333333333333], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.5], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2285"]]
+2284=PROJCS["NAD83 / Virginia South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.96666666666667], PARAMETER["false_easting", 11482916.667], PARAMETER["false_northing", 3280833.333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.766666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2284"]]
+2283=PROJCS["NAD83 / Virginia North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.199999999999996], PARAMETER["false_easting", 11482916.667], PARAMETER["false_northing", 6561666.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.03333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2283"]]
+2282=PROJCS["NAD83 / Utah South (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.35], PARAMETER["false_easting", 1640419.9480000003], PARAMETER["false_northing", 9842519.684999999], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.21666666666667], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2282"]]
+2281=PROJCS["NAD83 / Utah Central (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 40.65], PARAMETER["false_easting", 1640419.9480000003], PARAMETER["false_northing", 6561679.790000001], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.016666666666666], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2281"]]
+2280=PROJCS["NAD83 / Utah North (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 40.333333333333336], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 1640419.9480000003], PARAMETER["false_northing", 3280839.8950000005], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.71666666666667], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2280"]]
+4458=VERT_CS["Dunedin-Bluff 1960 height", VERT_DATUM["Dunedin-Bluff 1960", 2005, AUTHORITY["EPSG","1040"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","4458"]]
+4457=PROJCS["NAD83 / South Dakota North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.68333333333334], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.416666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4457"]]
+4456=PROJCS["NAD27 / New York Long Island", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -74.0], PARAMETER["latitude_of_origin", 40.5], PARAMETER["standard_parallel_1", 41.03333333333333], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 100000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.666666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4456"]]
+4455=PROJCS["NAD27 / Pennsylvania South", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.96666666666667], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.93333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4455"]]
+2279=PROJCS["NAD83 / Texas South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 25.666666666666668], PARAMETER["standard_parallel_1", 27.833333333333332], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 16404166.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 26.166666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2279"]]
+2278=PROJCS["NAD83 / Texas South Central (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 27.833333333333332], PARAMETER["standard_parallel_1", 30.28333333333333], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 13123333.333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 28.383333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2278"]]
+2277=PROJCS["NAD83 / Texas Central (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 29.666666666666668], PARAMETER["standard_parallel_1", 31.883333333333336], PARAMETER["false_easting", 2296583.333], PARAMETER["false_northing", 9842500.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 30.116666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2277"]]
+2276=PROJCS["NAD83 / Texas North Central (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 31.666666666666664], PARAMETER["standard_parallel_1", 33.96666666666667], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 6561666.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.13333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2276"]]
+2275=PROJCS["NAD83 / Texas North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -101.5], PARAMETER["latitude_of_origin", 34.0], PARAMETER["standard_parallel_1", 36.18333333333333], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 3280833.333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.65], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2275"]]
+2274=PROJCS["NAD83 / Tennessee (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -86.0], PARAMETER["latitude_of_origin", 34.333333333333336], PARAMETER["standard_parallel_1", 36.416666666666664], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.25], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2274"]]
+2273=PROJCS["NAD83 / South Carolina (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 31.833333333333336], PARAMETER["standard_parallel_1", 34.833333333333336], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.5], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2273"]]
+2272=PROJCS["NAD83 / Pennsylvania South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.96666666666667], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.93333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2272"]]
+2271=PROJCS["NAD83 / Pennsylvania North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 40.166666666666664], PARAMETER["standard_parallel_1", 41.95], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.88333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2271"]]
+2270=PROJCS["NAD83 / Oregon South (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["standard_parallel_1", 44.0], PARAMETER["false_easting", 4921259.843000001], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.333333333333336], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2270"]]
+29101=PROJCS["SAD69 / Brazil Polyconic", GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4618"]], PROJECTION["Polyconic", AUTHORITY["EPSG","9818"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", -54.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5000000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","29101"]]
+2269=PROJCS["NAD83 / Oregon North (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["standard_parallel_1", 46.0], PARAMETER["false_easting", 8202099.738], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.33333333333333], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2269"]]
+2268=PROJCS["NAD83 / Oklahoma South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 33.333333333333336], PARAMETER["standard_parallel_1", 35.233333333333334], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.93333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2268"]]
+2267=PROJCS["NAD83 / Oklahoma North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 35.0], PARAMETER["standard_parallel_1", 36.766666666666666], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.56666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2267"]]
+4440=VERT_CS["NZVD2009 height", VERT_DATUM["New Zealand Vertical Datum 2009", 2005, AUTHORITY["EPSG","1039"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","4440"]]
+2266=PROJCS["NAD83 / North Dakota South (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 45.666666666666664], PARAMETER["standard_parallel_1", 47.483333333333334], PARAMETER["false_easting", 1968503.937], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.18333333333334], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2266"]]
+2265=PROJCS["NAD83 / North Dakota North (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 1968503.937], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.43333333333334], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2265"]]
+2264=PROJCS["NAD83 / North Carolina (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.0], PARAMETER["latitude_of_origin", 33.75], PARAMETER["standard_parallel_1", 36.166666666666664], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.333333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2264"]]
+2263=PROJCS["NAD83 / New York Long Island (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -74.0], PARAMETER["latitude_of_origin", 40.166666666666664], PARAMETER["standard_parallel_1", 41.03333333333333], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.666666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2263"]]
+2262=PROJCS["NAD83 / New York West (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -78.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 1148291.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2262"]]
+2261=PROJCS["NAD83 / New York Central (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -76.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 820208.333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2261"]]
+2260=PROJCS["NAD83 / New York East (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.5], PARAMETER["latitude_of_origin", 38.833333333333336], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 492125.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2260"]]
+4439=PROJCS["NAD83 / BLM 19N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4439"]]
+4438=PROJCS["NAD83 / BLM 18N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4438"]]
+4437=PROJCS["NAD83(NSRS2007) / Puerto Rico and Virgin Is.", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -66.43333333333334], PARAMETER["latitude_of_origin", 17.833333333333332], PARAMETER["standard_parallel_1", 18.433333333333334], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 18.033333333333335], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4437"]]
+4434=PROJCS["Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 8", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 8500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4434"]]
+4433=PROJCS["NAD83 / BLM 13N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4433"]]
+2259=PROJCS["NAD83 / New Mexico West (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.83333333333334], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999916667], PARAMETER["false_easting", 2723091.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2259"]]
+4432=PROJCS["NAD83 / BLM 12N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4432"]]
+2258=PROJCS["NAD83 / New Mexico Central (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -106.25], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2258"]]
+4431=PROJCS["NAD83 / BLM 11N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4431"]]
+2257=PROJCS["NAD83 / New Mexico East (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -104.33333333333333], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999909091], PARAMETER["false_easting", 541337.5], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2257"]]
+4430=PROJCS["NAD83 / BLM 10N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4430"]]
+2256=PROJCS["NAD83 / Montana (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -109.5], PARAMETER["latitude_of_origin", 44.25], PARAMETER["standard_parallel_1", 49.0], PARAMETER["false_easting", 1968503.937], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2256"]]
+2255=PROJCS["NAD83 / Mississippi West (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.33333333333333], PARAMETER["latitude_of_origin", 29.5], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 2296583.333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2255"]]
+2254=PROJCS["NAD83 / Mississippi East (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -88.83333333333333], PARAMETER["latitude_of_origin", 29.5], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2254"]]
+2253=PROJCS["NAD83 / Michigan South (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.36666666666666], PARAMETER["latitude_of_origin", 41.5], PARAMETER["standard_parallel_1", 43.666666666666664], PARAMETER["false_easting", 13123359.580000002], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.1], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2253"]]
+2252=PROJCS["NAD83 / Michigan Central (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.36666666666666], PARAMETER["latitude_of_origin", 43.31666666666666], PARAMETER["standard_parallel_1", 45.699999999999996], PARAMETER["false_easting", 19685039.369999997], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.18333333333334], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2252"]]
+2251=PROJCS["NAD83 / Michigan North (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 44.78333333333333], PARAMETER["standard_parallel_1", 47.083333333333336], PARAMETER["false_easting", 26246719.160000004], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.48333333333333], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2251"]]
+2250=PROJCS["NAD83 / Massachusetts Island (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -70.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 41.483333333333334], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.28333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2250"]]
+4429=PROJCS["NAD83 / BLM 9N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4429"]]
+4428=PROJCS["NAD83 / BLM 8N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4428"]]
+4427=PROJCS["NAD83 / BLM 7N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4427"]]
+4426=PROJCS["NAD83 / BLM 6N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4426"]]
+4425=PROJCS["NAD83 / BLM 5N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4425"]]
+4424=PROJCS["NAD83 / BLM 4N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4424"]]
+4423=PROJCS["NAD83 / BLM 3N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4423"]]
+2249=PROJCS["NAD83 / Massachusetts Mainland (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.0], PARAMETER["standard_parallel_1", 42.68333333333334], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 2460625.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2249"]]
+4422=PROJCS["NAD83 / BLM 2N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4422"]]
+2248=PROJCS["NAD83 / Maryland (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.0], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.449999999999996], PARAMETER["false_easting", 1312333.333], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.3], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2248"]]
+4421=PROJCS["NAD83 / BLM 1N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4421"]]
+2247=PROJCS["NAD83 / Kentucky South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -85.75], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.93333333333333], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.733333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2247"]]
+4420=PROJCS["NAD83 / BLM 60N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4420"]]
+66036405=GEOGCS["Grenada 1953 (deg)", DATUM["Grenada 1953", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[72.0, 213.7, 93.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6603"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66036405"]]
+2246=PROJCS["NAD83 / Kentucky North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.25], PARAMETER["latitude_of_origin", 37.5], PARAMETER["standard_parallel_1", 38.96666666666667], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.96666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2246"]]
+2245=PROJCS["NAD83 / Indiana West (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.08333333333333], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 2952750.0], PARAMETER["false_northing", 818125.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2245"]]
+2244=PROJCS["NAD83 / Indiana East (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -85.66666666666667], PARAMETER["latitude_of_origin", 37.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 328083.333], PARAMETER["false_northing", 818125.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2244"]]
+2243=PROJCS["NAD83 / Idaho West (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.75], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 2624666.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2243"]]
+2242=PROJCS["NAD83 / Idaho Central (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -114.0], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2242"]]
+61316405=GEOGCS["Indian 1960 (deg)", DATUM["Indian 1960", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[198.0, 881.0, 317.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6131"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61316405"]]
+2241=PROJCS["NAD83 / Idaho East (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -112.16666666666667], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["scale_factor", 0.999947368], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2241"]]
+2240=PROJCS["NAD83 / Georgia West (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -84.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 2296583.333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2240"]]
+4419=PROJCS["NAD27 / BLM 19N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4419"]]
+4418=PROJCS["NAD27 / BLM 18N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4418"]]
+4417=PROJCS["Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 7", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4417"]]
+4415=PROJCS["Katanga 1955 / Katanga Lambert", GEOGCS["Katanga 1955", DATUM["Katanga 1955", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-103.746, -9.614, -255.95, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6695"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4695"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 26.0], PARAMETER["latitude_of_origin", -9.0], PARAMETER["standard_parallel_1", -6.5], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -11.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4415"]]
+4414=PROJCS["NAD83(HARN) / Guam Map Grid", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 144.75], PARAMETER["latitude_of_origin", 13.5], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4414"]]
+4413=PROJCS["NAD27 / BLM 13N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4413"]]
+2239=PROJCS["NAD83 / Georgia East (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.16666666666667], PARAMETER["latitude_of_origin", 30.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2239"]]
+4412=PROJCS["NAD27 / BLM 12N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4412"]]
+2238=PROJCS["NAD83 / Florida North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.5], PARAMETER["latitude_of_origin", 29.0], PARAMETER["standard_parallel_1", 30.75], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 29.583333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2238"]]
+4411=PROJCS["NAD27 / BLM 11N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4411"]]
+2237=PROJCS["NAD83 / Florida West (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2237"]]
+4410=PROJCS["NAD27 / BLM 10N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4410"]]
+2236=PROJCS["NAD83 / Florida East (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 24.333333333333336], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2236"]]
+2235=PROJCS["NAD83 / Delaware (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.41666666666667], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 0.999995], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2235"]]
+2234=PROJCS["NAD83 / Connecticut (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -72.75], PARAMETER["latitude_of_origin", 40.833333333333336], PARAMETER["standard_parallel_1", 41.86666666666669], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.2], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2234"]]
+2233=PROJCS["NAD83 / Colorado South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.233333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2233"]]
+2232=PROJCS["NAD83 / Colorado Central (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 37.833333333333336], PARAMETER["standard_parallel_1", 39.75], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.45], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2232"]]
+2231=PROJCS["NAD83 / Colorado North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -105.5], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.78333333333333], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2231"]]
+2230=PROJCS["NAD83 / California zone 6 (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -116.25], PARAMETER["latitude_of_origin", 32.166666666666664], PARAMETER["standard_parallel_1", 33.88333333333333], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.78333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2230"]]
+4409=PROJCS["NAD27 / BLM 9N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4409"]]
+4408=PROJCS["NAD27 / BLM 8N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4408"]]
+4407=PROJCS["NAD27 / BLM 7N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4407"]]
+4406=PROJCS["NAD27 / BLM 6N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4406"]]
+4405=PROJCS["NAD27 / BLM 5N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4405"]]
+4404=PROJCS["NAD27 / BLM 4N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4404"]]
+4403=PROJCS["NAD27 / BLM 3N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4403"]]
+2229=PROJCS["NAD83 / California zone 5 (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -118.0], PARAMETER["latitude_of_origin", 33.5], PARAMETER["standard_parallel_1", 35.46666666666667], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.03333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2229"]]
+4402=PROJCS["NAD27 / BLM 2N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4402"]]
+2228=PROJCS["NAD83 / California zone 4 (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -119.0], PARAMETER["latitude_of_origin", 35.333333333333336], PARAMETER["standard_parallel_1", 37.25], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2228"]]
+4401=PROJCS["NAD27 / BLM 1N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4401"]]
+2227=PROJCS["NAD83 / California zone 3 (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 36.5], PARAMETER["standard_parallel_1", 38.43333333333333], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.06666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2227"]]
+4400=PROJCS["NAD27 / BLM 60N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4400"]]
+2226=PROJCS["NAD83 / California zone 2 (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.833333333333336], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.333333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2226"]]
+2225=PROJCS["NAD83 / California zone 1 (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -122.0], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 41.666666666666664], PARAMETER["false_easting", 6561666.667], PARAMETER["false_northing", 1640416.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2225"]]
+2224=PROJCS["NAD83 / Arizona West (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -113.75], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2224"]]
+2223=PROJCS["NAD83 / Arizona Central (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.91666666666666], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2223"]]
+2222=PROJCS["NAD83 / Arizona East (ft)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.16666666666667], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 0.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2222"]]
+2220=PROJCS["ATS77 / UTM zone 20N", GEOGCS["ATS77", DATUM["Average Terrestrial System 1977", SPHEROID["Average Terrestrial System 1977", 6378135.0, 298.257, AUTHORITY["EPSG","7041"]], AUTHORITY["EPSG","6122"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4122"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2220"]]
+2219=PROJCS["ATS77 / UTM zone 19N", GEOGCS["ATS77", DATUM["Average Terrestrial System 1977", SPHEROID["Average Terrestrial System 1977", 6378135.0, 298.257, AUTHORITY["EPSG","7041"]], AUTHORITY["EPSG","6122"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4122"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2219"]]
+2217=PROJCS["Qornoq 1927 / UTM zone 23N", GEOGCS["Qornoq 1927", DATUM["Qornoq 1927", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[163.511, 127.533, -159.789, 0.0, 0.0, 0.814, -0.6], AUTHORITY["EPSG","6194"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4194"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2217"]]
+2216=PROJCS["Qornoq 1927 / UTM zone 22N", GEOGCS["Qornoq 1927", DATUM["Qornoq 1927", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[163.511, 127.533, -159.789, 0.0, 0.0, 0.814, -0.6], AUTHORITY["EPSG","6194"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4194"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2216"]]
+2215=PROJCS["Manoca 1962 / UTM zone 32N", GEOGCS["Manoca 1962", DATUM["Manoca 1962", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-70.9, -151.8, -41.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6193"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4193"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2215"]]
+2214=PROJCS["Douala 1948 / AOF west", GEOGCS["Douala 1948", DATUM["Douala 1948", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-206.1, -174.7, -87.7, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6192"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4192"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 10.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.999], PARAMETER["false_easting", 1000000.0], PARAMETER["false_northing", 1000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2214"]]
+2213=PROJCS["ETRS89 / TM 30 NE", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2213"]]
+2212=PROJCS["ED50 / 3-degree Gauss-Kruger zone 15", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 15500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2212"]]
+2211=PROJCS["ED50 / 3-degree Gauss-Kruger zone 14", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 42.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 14500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2211"]]
+2210=PROJCS["ED50 / 3-degree Gauss-Kruger zone 13", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 13500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2210"]]
+66586405=GEOGCS["Hjorsey 1955 (deg)", DATUM["Hjorsey 1955", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-73.0, 46.0, -86.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6658"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66586405"]]
+2209=PROJCS["ED50 / 3-degree Gauss-Kruger zone 12", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 36.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 12500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2209"]]
+2208=PROJCS["ED50 / 3-degree Gauss-Kruger zone 11", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 11500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2208"]]
+2207=PROJCS["ED50 / 3-degree Gauss-Kruger zone 10", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 10500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2207"]]
+2206=PROJCS["ED50 / 3-degree Gauss-Kruger zone 9", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 9500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2206"]]
+2205=PROJCS["NAD83 / Kentucky North", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -84.25], PARAMETER["latitude_of_origin", 37.5], PARAMETER["standard_parallel_1", 38.96666666666667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.96666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2205"]]
+2204=PROJCS["NAD27 / Tennessee", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -86.0], PARAMETER["latitude_of_origin", 34.666666666666664], PARAMETER["standard_parallel_1", 36.416666666666664], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 100000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.25], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2204"]]
+2203=PROJCS["REGVEN / UTM zone 20N", GEOGCS["REGVEN", DATUM["Red Geodesica Venezolana", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6189"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4189"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2203"]]
+2202=PROJCS["REGVEN / UTM zone 19N", GEOGCS["REGVEN", DATUM["Red Geodesica Venezolana", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6189"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4189"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2202"]]
+2201=PROJCS["REGVEN / UTM zone 18N", GEOGCS["REGVEN", DATUM["Red Geodesica Venezolana", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6189"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4189"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2201"]]
+2200=PROJCS["ATS77 / New Brunswick Stereographic (ATS77)", GEOGCS["ATS77", DATUM["Average Terrestrial System 1977", SPHEROID["Average Terrestrial System 1977", 6378135.0, 298.257, AUTHORITY["EPSG","7041"]], AUTHORITY["EPSG","6122"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4122"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", -66.5], PARAMETER["latitude_of_origin", 46.5], PARAMETER["scale_factor", 0.999912], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2200"]]
+62106405=GEOGCS["Arc 1960 (deg)", DATUM["Arc 1960", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-157.0, -2.0, -299.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6210"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62106405"]]
+3997=PROJCS["WGS 84 / Dubai Local TM", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 55.33333333333333], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3997"]]
+3996=PROJCS["WGS 84 / IBCAO Polar Stereographic", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 0.0], PARAMETER["Standard_Parallel_1", 75.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "South along 90 deg East"], AXIS["Northing", "South along 180 deg"], AUTHORITY["EPSG","3996"]]
+3995=PROJCS["WGS 84 / Arctic Polar Stereographic", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 0.0], PARAMETER["Standard_Parallel_1", 71.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "South along 90 deg East"], AXIS["Northing", "South along 180 deg"], AUTHORITY["EPSG","3995"]]
+3994=PROJCS["WGS 84 / Mercator 41", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator_2SP", AUTHORITY["EPSG","9805"]], PARAMETER["standard_parallel_1", 41.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 100.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3994"]]
+3992=PROJCS["Puerto Rico / St. Croix", GEOGCS["Puerto Rico", DATUM["Puerto Rico", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[11.0, 72.0, -101.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6139"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4139"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -66.43333333333334], PARAMETER["latitude_of_origin", 17.833333333333332], PARAMETER["standard_parallel_1", 18.433333333333334], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 100000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 18.033333333333335], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3992"]]
+3991=PROJCS["Puerto Rico State Plane CS of 1927", GEOGCS["Puerto Rico", DATUM["Puerto Rico", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[11.0, 72.0, -101.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6139"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4139"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -66.43333333333334], PARAMETER["latitude_of_origin", 17.833333333333332], PARAMETER["standard_parallel_1", 18.433333333333334], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 18.033333333333335], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3991"]]
+61706413=GEOGCS["SIRGAS (3D deg)", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61706413"]]
+3989=PROJCS["Katanga 1955 / Katanga Gauss zone D", GEOGCS["Katanga 1955", DATUM["Katanga 1955", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-103.746, -9.614, -255.95, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6695"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4695"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", -9.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3989"]]
+3988=PROJCS["Katanga 1955 / Katanga Gauss zone C", GEOGCS["Katanga 1955", DATUM["Katanga 1955", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-103.746, -9.614, -255.95, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6695"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4695"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 26.0], PARAMETER["latitude_of_origin", -9.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3988"]]
+3987=PROJCS["Katanga 1955 / Katanga Gauss zone B", GEOGCS["Katanga 1955", DATUM["Katanga 1955", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-103.746, -9.614, -255.95, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6695"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4695"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 28.0], PARAMETER["latitude_of_origin", -9.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3987"]]
+3986=PROJCS["Katanga 1955 / Katanga Gauss zone A", GEOGCS["Katanga 1955", DATUM["Katanga 1955", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-103.746, -9.614, -255.95, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6695"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4695"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", -9.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3986"]]
+3985=PROJCS["Katanga 1955 / Katanga Lambert", GEOGCS["Katanga 1955", DATUM["Katanga 1955", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-103.746, -9.614, -255.95, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6695"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4695"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 26.0], PARAMETER["latitude_of_origin", 9.0], PARAMETER["standard_parallel_1", -6.5], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -11.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3985"]]
+66426405=GEOGCS["ST84 Ile des Pins (deg)", DATUM["ST84 Ile des Pins", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-13.0, -348.0, 292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6642"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66426405"]]
+61706405=GEOGCS["SIRGAS (deg)", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61706405"]]
+3979=PROJCS["NAD83(CSRS) / Canada Atlas Lambert", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -95.0], PARAMETER["latitude_of_origin", 49.0], PARAMETER["standard_parallel_1", 77.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 49.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3979"]]
+3978=PROJCS["NAD83 / Canada Atlas Lambert", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -95.0], PARAMETER["latitude_of_origin", 49.0], PARAMETER["standard_parallel_1", 77.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 49.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3978"]]
+62656405=GEOGCS["Monte Mario (deg)", DATUM["Monte Mario", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-104.1, -49.1, -9.9, 0.971, -2.917, 0.714, -11.68], AUTHORITY["EPSG","6265"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62656405"]]
+3976=PROJCS["WGS 84 / NSIDC Sea Ice Polar Stereographic South", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Polar Stereographic (variant B)", AUTHORITY["EPSG","9829"]], PARAMETER["central_meridian", 0.0], PARAMETER["Standard_Parallel_1", -70.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 90 deg East"], AXIS["Northing", "North along 0 deg"], AUTHORITY["EPSG","3976"]]
+3974=PROJCS["WGS 84 / NSIDC EASE-Grid South", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Azimuthal_Equal_Area", AUTHORITY["EPSG","1027"]], PARAMETER["latitude_of_center", -90.0], PARAMETER["longitude_of_center", 0.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "North along 90 deg East"], AXIS["Northing", "North along 0 deg"], AUTHORITY["EPSG","3974"]]
+3973=PROJCS["WGS 84 / NSIDC EASE-Grid North", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Azimuthal_Equal_Area", AUTHORITY["EPSG","1027"]], PARAMETER["latitude_of_center", 90.0], PARAMETER["longitude_of_center", 0.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", "South along 90 deg East"], AXIS["Northing", "South along 180 deg"], AUTHORITY["EPSG","3973"]]
+3970=PROJCS["NAD83(NSRS2007) / Virginia Lambert", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 36.0], PARAMETER["standard_parallel_1", 39.5], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3970"]]
+22092=PROJCS["Camacupa / TM 12 SE", GEOGCS["Camacupa", DATUM["Camacupa", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-50.9, -347.6, -231.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6220"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4220"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22092"]]
+22091=PROJCS["Camacupa / TM 11.30 SE", GEOGCS["Camacupa", DATUM["Camacupa", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-50.9, -347.6, -231.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6220"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4220"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 11.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22091"]]
+3969=PROJCS["NAD83(HARN) / Virginia Lambert", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 36.0], PARAMETER["standard_parallel_1", 39.5], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3969"]]
+3968=PROJCS["NAD83 / Virginia Lambert", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 36.0], PARAMETER["standard_parallel_1", 39.5], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3968"]]
+66096405=GEOGCS["NAD27(CGQ77) (deg)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66096405"]]
+26432=PROJCS["Mhast / UTM zone 32S", GEOGCS["Mhast", DATUM["Mhast", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-252.95, -4.11, -96.38, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6264"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4264"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26432"]]
+61376405=GEOGCS["St. Paul Island (deg)", DATUM["St. Paul Island", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6137"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61376405"]]
+3950=PROJCS["RGF93 / CC50", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 50.0], PARAMETER["standard_parallel_1", 50.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 9200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 49.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3950"]]
+3949=PROJCS["RGF93 / CC49", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 49.0], PARAMETER["standard_parallel_1", 49.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 8200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 48.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3949"]]
+28600=PROJCS["Qatar 1974 / Qatar National Grid", GEOGCS["Qatar 1974", DATUM["Qatar 1974", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-128.16, -282.42, 21.93, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6285"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4285"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.21666666666667], PARAMETER["latitude_of_origin", 24.45], PARAMETER["scale_factor", 0.99999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28600"]]
+3948=PROJCS["RGF93 / CC48", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 48.0], PARAMETER["standard_parallel_1", 48.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 7200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3948"]]
+3947=PROJCS["RGF93 / CC47", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 47.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 6200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3947"]]
+3946=PROJCS["RGF93 / CC46", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 46.0], PARAMETER["standard_parallel_1", 46.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 5200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3946"]]
+3945=PROJCS["RGF93 / CC45", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 45.0], PARAMETER["standard_parallel_1", 45.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 4200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3945"]]
+3944=PROJCS["RGF93 / CC44", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 44.0], PARAMETER["standard_parallel_1", 44.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 3200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3944"]]
+3943=PROJCS["RGF93 / CC43", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 43.0], PARAMETER["standard_parallel_1", 43.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 2200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3943"]]
+3942=PROJCS["RGF93 / CC42", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 42.0], PARAMETER["standard_parallel_1", 42.75], PARAMETER["false_easting", 1700000.0], PARAMETER["false_northing", 1200000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 41.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3942"]]
+3920=PROJCS["Puerto Rico / UTM zone 20N", GEOGCS["Puerto Rico", DATUM["Puerto Rico", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[11.0, 72.0, -101.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6139"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4139"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3920"]]
+3912=PROJCS["MGI 1901 / Slovene National Grid", GEOGCS["MGI 1901", DATUM["MGI 1901", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[551.7, 162.9, 467.9, 6.04, 1.96, -11.38, -4.82], AUTHORITY["EPSG","1031"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3906"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3912"]]
+3911=PROJCS["MGI 1901 / Slovenia Grid", GEOGCS["MGI 1901", DATUM["MGI 1901", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[551.7, 162.9, 467.9, 6.04, 1.96, -11.38, -4.82], AUTHORITY["EPSG","1031"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3906"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3911"]]
+3910=PROJCS["MGI 1901 / Balkans zone 8", GEOGCS["MGI 1901", DATUM["MGI 1901", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[551.7, 162.9, 467.9, 6.04, 1.96, -11.38, -4.82], AUTHORITY["EPSG","1031"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3906"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 8500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3910"]]
+61216405=GEOGCS["GGRS87 (deg)", DATUM["Greek Geodetic Reference System 1987", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-199.87, 74.79, 246.62, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6121"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61216405"]]
+22033=PROJCS["Camacupa / UTM zone 33S", GEOGCS["Camacupa", DATUM["Camacupa", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-50.9, -347.6, -231.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6220"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4220"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22033"]]
+22032=PROJCS["Camacupa / UTM zone 32S", GEOGCS["Camacupa", DATUM["Camacupa", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-50.9, -347.6, -231.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6220"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4220"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","22032"]]
+62166405=GEOGCS["Bermuda 1957 (deg)", DATUM["Bermuda 1957", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-292.295, 248.758, 429.447, 4.9971, -2.99, -6.6906, 1.0289], AUTHORITY["EPSG","6216"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62166405"]]
+3909=PROJCS["MGI 1901 / Balkans zone 7", GEOGCS["MGI 1901", DATUM["MGI 1901", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[551.7, 162.9, 467.9, 6.04, 1.96, -11.38, -4.82], AUTHORITY["EPSG","1031"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3906"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3909"]]
+3908=PROJCS["MGI 1901 / Balkans zone 6", GEOGCS["MGI 1901", DATUM["MGI 1901", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[551.7, 162.9, 467.9, 6.04, 1.96, -11.38, -4.82], AUTHORITY["EPSG","1031"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3906"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3908"]]
+3907=PROJCS["MGI 1901 / Balkans zone 5", GEOGCS["MGI 1901", DATUM["MGI 1901", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[551.7, 162.9, 467.9, 6.04, 1.96, -11.38, -4.82], AUTHORITY["EPSG","1031"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3906"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3907"]]
+3906=GEOGCS["MGI 1901", DATUM["MGI 1901", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[551.7, 162.9, 467.9, 6.04, 1.96, -11.38, -4.82], AUTHORITY["EPSG","1031"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3906"]]
+3900=VERT_CS["N2000 height", VERT_DATUM["N2000", 2005, AUTHORITY["EPSG","1030"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","3900"]]
+24200=PROJCS["JAD69 / Jamaica National Grid", GEOGCS["JAD69", DATUM["Jamaica 1969", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-33.722, 153.789, 94.959, -8.581, 4.478, -4.54, 8.95], AUTHORITY["EPSG","6242"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4242"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -77.0], PARAMETER["latitude_of_origin", 18.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", 150000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24200"]]
+61766413=GEOGCS["Australian Antarctic (3D deg)", DATUM["Australian Antarctic Datum 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6176"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61766413"]]
+61766405=GEOGCS["Australian Antarctic (deg)", DATUM["Australian Antarctic Datum 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6176"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61766405"]]
+62006405=GEOGCS["Pulkovo 1995 (deg)", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62006405"]]
+31370=PROJCS["Belge 1972 / Belgian Lambert 72", GEOGCS["Belge 1972", DATUM["Reseau National Belge 1972", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-106.8686, 52.2978, -103.7239, 0.3366, 0.457, -1.8422, -1.2747], AUTHORITY["EPSG","6313"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4313"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 4.367486666666666], PARAMETER["latitude_of_origin", 90.0], PARAMETER["standard_parallel_1", 51.166667233333335], PARAMETER["false_easting", 150000.013], PARAMETER["false_northing", 5400088.438], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 49.833333900000014], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31370"]]
+66326405=GEOGCS["Combani 1950 (deg)", DATUM["Combani 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-382.0, -59.0, -262.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6632"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66326405"]]
+61606405=GEOGCS["Chos Malal 1914 (deg)", DATUM["Chos Malal 1914", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6160"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61606405"]]
+62556405=GEOGCS["Herat North (deg)", DATUM["Herat North", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-333.0, -222.0, 114.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6255"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62556405"]]
+25932=PROJCS["Malongo 1987 / UTM zone 32S", GEOGCS["Malongo 1987", DATUM["Malongo 1987", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-254.1, -5.36, -100.29, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6259"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4259"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25932"]]
+4399=PROJCS["NAD27 / BLM 59N (ftUS)", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4399"]]
+61276405=GEOGCS["Tete (deg)", DATUM["Tete", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-82.875, -57.097, -156.768, -2.158, -1.524, 0.982, -0.359], AUTHORITY["EPSG","6127"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61276405"]]
+4389=GEOCCS["LKS92 (geocentric)", DATUM["Latvia 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6661"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4389"]]
+4388=GEOGCS["LKS92 (3D)", DATUM["Latvia 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6661"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4388"]]
+4387=GEOCCS["ISN93 (geocentric)", DATUM["Islands Net 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6659"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4387"]]
+4386=GEOGCS["ISN93 (3D)", DATUM["Islands Net 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6659"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4386"]]
+4385=GEOCCS["ITRF2000 (geocentric)", DATUM["International Terrestrial Reference Frame 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6656"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4385"]]
+4384=GEOCCS["RRAF 1991 (geocentric)", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6640"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4384"]]
+4383=GEOGCS["RRAF 1991 (3D)", DATUM["Reseau de Reference des Antilles Francaises 1991", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6640"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4383"]]
+4382=GEOCCS["RGNC 1991 (geocentric)", DATUM["Reseau Geodesique Nouvelle Caledonie 1991", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6645"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4382"]]
+4381=GEOGCS["RGNC 1991 (3D)", DATUM["Reseau Geodesique Nouvelle Caledonie 1991", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6645"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4381"]]
+4380=GEOCCS["Yemen NGN96 (geocentric)", DATUM["Yemen National Geodetic Network 1996", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6163"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4380"]]
+4379=GEOGCS["Yemen NGN96 (3D)", DATUM["Yemen National Geodetic Network 1996", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6163"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4379"]]
+4378=GEOCCS["SWEREF99 (geocentric)", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4378"]]
+4377=GEOGCS["SWEREF99 (3D)", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4377"]]
+4376=GEOCCS["SIRGAS (geocentric)", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4376"]]
+4375=GEOGCS["SIRGAS (3D)", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4375"]]
+4374=GEOCCS["RGR92 (geocentric)", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4374"]]
+4373=GEOGCS["RGR92 (3D)", DATUM["Reseau Geodesique de la Reunion 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6627"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4373"]]
+2199=PROJCS["Albanian 1987 / Gauss Kruger zone 4", GEOGCS["Albanian 1987", DATUM["Albanian 1987", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","6191"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4191"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2199"]]
+4372=GEOCCS["RGFG95 (geocentric)", DATUM["Reseau Geodesique Francais Guyane 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6624"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4372"]]
+2198=PROJCS["ETRS89 / Kp2000 Bornholm", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 900000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2198"]]
+4371=GEOGCS["RGFG95 (3D)", DATUM["Reseau Geodesique Francais Guyane 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6624"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4371"]]
+2197=PROJCS["ETRS89 / Kp2000 Zealand", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2197"]]
+4370=GEOCCS["RGF93 (geocentric)", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4370"]]
+2196=PROJCS["ETRS89 / Kp2000 Jutland", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2196"]]
+2195=PROJCS["NAD83(HARN) / UTM zone 2S", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2195"]]
+2194=PROJCS["American Samoa 1962 / American Samoa Lambert", GEOGCS["American Samoa 1962", DATUM["American Samoa 1962", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-115.0, 118.0, 426.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6169"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4169"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -170.0], PARAMETER["latitude_of_origin", -14.266666666666666], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2194"]]
+2193=PROJCS["NZGD2000 / New Zealand Transverse Mercator 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 173.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1600000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2193"]]
+2192=PROJCS["ED50 / France EuroLambert", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 2.3372291666666656], PARAMETER["latitude_of_origin", 46.8], PARAMETER["scale_factor", 0.99987742], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 2200000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2192"]]
+2190=PROJCS["Azores Oriental 1940 / UTM zone 26N", GEOGCS["Azores Oriental 1940", DATUM["Azores Oriental Islands 1940", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-203.0, 141.0, 53.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6184"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4184"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2190"]]
+4369=GEOGCS["RGF93 (3D)", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4369"]]
+4368=GEOCCS["REGVEN (geocentric)", DATUM["Red Geodesica Venezolana", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6189"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4368"]]
+4367=GEOGCS["REGVEN (3D)", DATUM["Red Geodesica Venezolana", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6189"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4367"]]
+4366=GEOCCS["POSGAR 98 (geocentric)", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4366"]]
+4365=GEOGCS["POSGAR 98 (3D)", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4365"]]
+4364=GEOCCS["NZGD2000 (geocentric)", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4364"]]
+4363=GEOGCS["NZGD2000 (3D)", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4363"]]
+2189=PROJCS["Azores Central 1948 / UTM zone 26N", GEOGCS["Azores Central 1948", DATUM["Azores Central Islands 1948", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-104.0, 167.0, -38.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6183"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4183"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2189"]]
+4362=GEOCCS["NAD83(HARN) (geocentric)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4362"]]
+2188=PROJCS["Azores Occidental 1939 / UTM zone 25N", GEOGCS["Azores Occidental 1939", DATUM["Azores Occidental Islands 1939", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-422.651, -172.995, 84.02, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6182"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4182"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2188"]]
+4361=GEOGCS["NAD83(HARN) (3D)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4361"]]
+4360=GEOCCS["NAD83(CSRS) (geocentric)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4360"]]
+2180=PROJCS["ETRS89 / Poland CS92", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 19.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9993], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", -5300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2180"]]
+4359=GEOGCS["NAD83(CSRS) (3D)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4359"]]
+4358=GEOCCS["Moznet (geocentric)", DATUM["Moznet (ITRF94)", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6130"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4358"]]
+4357=GEOGCS["Moznet (3D)", DATUM["Moznet (ITRF94)", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6130"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4357"]]
+4356=GEOCCS["LKS94 (ETRS89) (geocentric)", DATUM["Lithuania 1994 (ETRS89)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6126"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4356"]]
+4355=GEOGCS["LKS94 (ETRS89) (3D)", DATUM["Lithuania 1994 (ETRS89)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6126"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4355"]]
+4354=GEOCCS["JGD2000 (geocentric)", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4354"]]
+4353=GEOGCS["JGD2000 (3D)", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4353"]]
+2179=PROJCS["ETRS89 / Poland CS2000 zone 8", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.999923], PARAMETER["false_easting", 8500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2179"]]
+4352=GEOCCS["IRENET95 (geocentric)", DATUM["IRENET95", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6173"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4352"]]
+2178=PROJCS["ETRS89 / Poland CS2000 zone 7", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.999923], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2178"]]
+4351=GEOGCS["IRENET95 (3D)", DATUM["IRENET95", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6173"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4351"]]
+2177=PROJCS["ETRS89 / Poland CS2000 zone 6", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.999923], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2177"]]
+4350=GEOCCS["Hartebeesthoek94 (geocentric)", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4350"]]
+2176=PROJCS["ETRS89 / Poland CS2000 zone 5", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.999923], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2176"]]
+2175=PROJCS["Pulkovo 1942(58) / Poland zone V", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.958333333333332], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.999983], PARAMETER["false_easting", 237000.0], PARAMETER["false_northing", -4700000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2175"]]
+2174=PROJCS["Pulkovo 1942(58) / Poland zone IV", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 16.67222222222222], PARAMETER["latitude_of_origin", 51.67083333333333], PARAMETER["scale_factor", 0.9998], PARAMETER["false_easting", 3703000.0], PARAMETER["false_northing", 5627000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2174"]]
+2173=PROJCS["Pulkovo 1942(58) / Poland zone III", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 17.008333333333333], PARAMETER["latitude_of_origin", 53.583333333333336], PARAMETER["scale_factor", 0.9998], PARAMETER["false_easting", 3501000.0], PARAMETER["false_northing", 5999000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2173"]]
+2172=PROJCS["Pulkovo 1942(58) / Poland zone II", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 21.502777777777773], PARAMETER["latitude_of_origin", 53.00194444444445], PARAMETER["scale_factor", 0.9998], PARAMETER["false_easting", 4603000.0], PARAMETER["false_northing", 5806000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2172"]]
+2171=PROJCS["Pulkovo 1942(58) / Poland zone I", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 21.083333333333332], PARAMETER["latitude_of_origin", 50.625], PARAMETER["scale_factor", 0.9998], PARAMETER["false_easting", 4637000.0], PARAMETER["false_northing", 5647000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2171"]]
+2170=PROJCS["MGI / Slovenia Grid", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2170"]]
+31300=PROJCS["Belge 1972 / Belge Lambert 72", GEOGCS["Belge 1972", DATUM["Reseau National Belge 1972", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-106.8686, 52.2978, -103.7239, 0.3366, 0.457, -1.8422, -1.2747], AUTHORITY["EPSG","6313"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4313"]], PROJECTION["Lambert_Conformal_Conic_2SP_Belgium", AUTHORITY["EPSG","9803"]], PARAMETER["central_meridian", 4.356939722222222], PARAMETER["latitude_of_origin", 90.0], PARAMETER["standard_parallel_1", 49.833333333333336], PARAMETER["false_easting", 150000.01256], PARAMETER["false_northing", 5400088.4378], PARAMETER["standard_parallel_2", 51.16666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31300"]]
+4349=GEOGCS["Hartebeesthoek94 (3D)", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4349"]]
+4348=GEOCCS["GDA94 (geocentric)", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4348"]]
+23700=PROJCS["HD72 / EOV", GEOGCS["HD72", DATUM["Hungarian Datum 1972", SPHEROID["GRS 1967", 6378160.0, 298.247167427, AUTHORITY["EPSG","7036"]], TOWGS84[52.17, -71.82, -14.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6237"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4237"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9815"]], PARAMETER["longitude_of_center", 19.048571777777784], PARAMETER["latitude_of_center", 47.14439372222222], PARAMETER["azimuth", 90.0], PARAMETER["scale_factor", 0.99993], PARAMETER["false_easting", 650000.0], PARAMETER["false_northing", 200000.0], PARAMETER["rectified_grid_angle", 90.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","23700"]]
+4347=GEOGCS["GDA94 (3D)", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4347"]]
+4346=GEOCCS["ETRS89 (geocentric)", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4346"]]
+4345=GEOGCS["ETRS89 (3D)", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4345"]]
+4344=GEOCCS["CHTRF95 (geocentric)", DATUM["Swiss Terrestrial Reference Frame 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6151"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4344"]]
+4343=GEOGCS["CHTRF95 (3D)", DATUM["Swiss Terrestrial Reference Frame 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6151"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4343"]]
+2169=PROJCS["Luxembourg 1930 / Gauss", GEOGCS["Luxembourg 1930", DATUM["Luxembourg 1930", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-189.6806, 18.3463, -42.7695, -0.33746, 3.09264, -2.53861, 0.4598], AUTHORITY["EPSG","6181"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4181"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 6.166666666666667], PARAMETER["latitude_of_origin", 49.833333333333336], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 80000.0], PARAMETER["false_northing", 100000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2169"]]
+4342=GEOCCS["EST97 (geocentric)", DATUM["Estonia 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6180"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4342"]]
+2168=PROJCS["Pulkovo 1942(83) / Gauss Kruger zone 5", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2168"]]
+4341=GEOGCS["EST97 (3D)", DATUM["Estonia 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6180"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4341"]]
+2167=PROJCS["Pulkovo 1942(83) / Gauss Kruger zone 4", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2167"]]
+4340=GEOCCS["Australian Antarctic (geocentric)", DATUM["Australian Antarctic Datum 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6176"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4340"]]
+62066405=GEOGCS["Agadez (deg)", DATUM["Agadez", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6206"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62066405"]]
+2166=PROJCS["Pulkovo 1942(83) / Gauss Kruger zone 3", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2166"]]
+2165=PROJCS["Abidjan 1987 / TM 5 NW", GEOGCS["Abidjan 1987", DATUM["Abidjan 1987", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-124.76, 53.0, 466.79, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6143"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4143"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -5.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2165"]]
+2164=PROJCS["Locodjo 1965 / TM 5 NW", GEOGCS["Locodjo 1965", DATUM["Locodjo 1965", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-125.0, 53.0, 467.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6142"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4142"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -5.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2164"]]
+2163=PROJCS["US National Atlas Equal Area", GEOGCS["Unspecified datum based upon the Clarke 1866 Authalic Sphere", DATUM["Not specified (based on Clarke 1866 Authalic Sphere)", SPHEROID["Clarke 1866 Authalic Sphere", 6370997.0, 0.0, AUTHORITY["EPSG","7052"]], AUTHORITY["EPSG","6052"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4052"]], PROJECTION["Lambert_Azimuthal_Equal_Area", AUTHORITY["EPSG","1027"]], PARAMETER["latitude_of_center", 45.0], PARAMETER["longitude_of_center", -100.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2163"]]
+2162=PROJCS["Sierra Leone 1968 / UTM zone 29N", GEOGCS["Sierra Leone 1968", DATUM["Sierra Leone 1968", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-88.0, 4.0, 101.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6175"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4175"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2162"]]
+2161=PROJCS["Sierra Leone 1968 / UTM zone 28N", GEOGCS["Sierra Leone 1968", DATUM["Sierra Leone 1968", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-88.0, 4.0, 101.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6175"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4175"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2161"]]
+2160=PROJCS["Sierra Leone 1924 / New War Office Grid", GEOGCS["Sierra Leone 1924", DATUM["Sierra Leone Colony 1924", SPHEROID["War Office", 6378300.0, 296.0, AUTHORITY["EPSG","7029"]], AUTHORITY["EPSG","6174"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4174"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -12.0], PARAMETER["latitude_of_origin", 6.666666666666667], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 600000.0], UNIT["m*0.3047997101815088", 0.3047997101815088], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2160"]]
+4339=GEOGCS["Australian Antarctic (3D)", DATUM["Australian Antarctic Datum 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6176"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4339"]]
+4338=GEOCCS["ITRF97 (geocentric)", DATUM["International Terrestrial Reference Frame 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6655"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4338"]]
+4337=GEOCCS["ITRF96 (geocentric)", DATUM["International Terrestrial Reference Frame 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6654"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4337"]]
+4336=GEOCCS["ITRF94 (geocentric)", DATUM["International Terrestrial Reference Frame 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6653"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4336"]]
+4335=GEOCCS["ITRF93 (geocentric)", DATUM["International Terrestrial Reference Frame 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6652"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4335"]]
+4334=GEOCCS["ITRF92 (geocentric)", DATUM["International Terrestrial Reference Frame 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6651"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4334"]]
+4333=GEOCCS["ITRF91 (geocentric)", DATUM["International Terrestrial Reference Frame 1991", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6650"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4333"]]
+2159=PROJCS["Sierra Leone 1924 / New Colony Grid", GEOGCS["Sierra Leone 1924", DATUM["Sierra Leone Colony 1924", SPHEROID["War Office", 6378300.0, 296.0, AUTHORITY["EPSG","7029"]], AUTHORITY["EPSG","6174"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4174"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -12.0], PARAMETER["latitude_of_origin", 6.666666666666667], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m*0.3047997101815088", 0.3047997101815088], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2159"]]
+4332=GEOCCS["ITRF90 (geocentric)", DATUM["International Terrestrial Reference Frame 1990", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6649"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4332"]]
+2158=PROJCS["IRENET95 / UTM zone 29N", GEOGCS["IRENET95", DATUM["IRENET95", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6173"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4173"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2158"]]
+4331=GEOCCS["ITRF89 (geocentric)", DATUM["International Terrestrial Reference Frame 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6648"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4331"]]
+2157=PROJCS["IRENET95 / Irish Transverse Mercator", GEOGCS["IRENET95", DATUM["IRENET95", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6173"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4173"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -8.0], PARAMETER["latitude_of_origin", 53.5], PARAMETER["scale_factor", 0.99982], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 750000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2157"]]
+4330=GEOCCS["ITRF88 (geocentric)", DATUM["International Terrestrial Reference Frame 1988", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], AUTHORITY["EPSG","6647"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4330"]]
+2156=PROJCS["NAD83(HARN) / UTM zone 59S", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2156"]]
+2155=PROJCS["American Samoa 1962 / American Samoa Lambert", GEOGCS["American Samoa 1962", DATUM["American Samoa 1962", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-115.0, 118.0, 426.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6169"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4169"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 170.0], PARAMETER["latitude_of_origin", -14.266666666666666], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2155"]]
+2154=PROJCS["RGF93 / Lambert-93", GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 46.5], PARAMETER["standard_parallel_1", 49.0], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 6600000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2154"]]
+4329=GEOGCS["WGS 84 (3D)", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4329"]]
+4328=GEOCCS["WGS 84 (geocentric)", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","4328"]]
+4327=GEOGCS["WGS 84 (geographic 3D)", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","4327"]]
+4326=GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]]
+4324=GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]]
+4322=GEOGCS["WGS 72", DATUM["World Geodetic System 1972", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 4.5, 0.0, 0.0, 0.554, 0.219], AUTHORITY["EPSG","6322"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4322"]]
+21500=PROJCS["Belge 1950 (Brussels) / Belge Lambert 50", GEOGCS["Belge 1950 (Brussels)", DATUM["Reseau National Belge 1950 (Brussels)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6809"]], PRIMEM["Brussels", 4.3679749999999995, AUTHORITY["EPSG","8910"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4809"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 90.0], PARAMETER["standard_parallel_1", 51.16666666666667], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 5400000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 49.833333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21500"]]
+4319=GEOGCS["KUDAMS", DATUM["Kuwait Utility", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[226.702, -193.337, -35.371, -2.229, 4.391, -9.238, 0.9798], AUTHORITY["EPSG","6319"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4319"]]
+4318=GEOGCS["NGN", DATUM["National Geodetic Network", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[-3.2, -5.7, 2.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6318"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4318"]]
+66386405=GEOGCS["Saint Pierre et Miquelon 1950 (deg)", DATUM["Saint Pierre et Miquelon 1950", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[30.0, 430.0, 368.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6638"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66386405"]]
+4317=GEOGCS["Dealul Piscului 1970", DATUM["Dealul Piscului 1970", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[28.0, -121.0, -77.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6317"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4317"]]
+4316=GEOGCS["Dealul Piscului 1930", DATUM["Dealul Piscului 1930", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[103.25, -100.4, -307.19, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6316"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4316"]]
+4315=GEOGCS["Conakry 1905", DATUM["Conakry 1905", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-23.0, 259.0, -9.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6315"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4315"]]
+68206405=GEOGCS["Segara (Jakarta) (deg)", DATUM["Gunung Segara (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6820"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","68206405"]]
+4314=GEOGCS["DHDN", DATUM["Deutsches Hauptdreiecksnetz", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[612.4, 77.0, 440.2, -0.054, 0.057, -2.797, 2.55], AUTHORITY["EPSG","6314"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4314"]]
+4313=GEOGCS["Belge 1972", DATUM["Reseau National Belge 1972", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-106.8686, 52.2978, -103.7239, 0.3366, 0.457, -1.8422, -1.2747], AUTHORITY["EPSG","6313"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4313"]]
+61666405=GEOGCS["Korean 1995 (deg)", DATUM["Korean Datum 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6166"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61666405"]]
+4312=GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]]
+2138=PROJCS["NAD27(CGQ77) / Quebec Lambert", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -68.5], PARAMETER["latitude_of_origin", 44.0], PARAMETER["standard_parallel_1", 60.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2138"]]
+4311=GEOGCS["Zanderij", DATUM["Zanderij", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-265.0, 120.0, -358.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6311"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4311"]]
+2137=PROJCS["Accra / TM 1 NW", GEOGCS["Accra", DATUM["Accra", SPHEROID["War Office", 6378300.0, 296.0, AUTHORITY["EPSG","7029"]], TOWGS84[-199.0, 32.0, 322.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6168"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4168"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -1.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2137"]]
+4310=GEOGCS["Yoff", DATUM["Yoff", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6310"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4310"]]
+2136=PROJCS["Accra / Ghana National Grid", GEOGCS["Accra", DATUM["Accra", SPHEROID["War Office", 6378300.0, 296.0, AUTHORITY["EPSG","7029"]], TOWGS84[-199.0, 32.0, 322.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6168"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4168"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -1.0], PARAMETER["latitude_of_origin", 4.666666666666667], PARAMETER["scale_factor", 0.99975], PARAMETER["false_easting", 900000.0], PARAMETER["false_northing", 0.0], UNIT["m*0.3047997101815088", 0.3047997101815088], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2136"]]
+2135=PROJCS["NZGD2000 / UTM zone 60S", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2135"]]
+2134=PROJCS["NZGD2000 / UTM zone 59S", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2134"]]
+2133=PROJCS["NZGD2000 / UTM zone 58S", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2133"]]
+2132=PROJCS["NZGD2000 / Bluff 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 168.34277777777774], PARAMETER["latitude_of_origin", -46.6], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2132"]]
+2131=PROJCS["NZGD2000 / North Taieri 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 170.28249999999997], PARAMETER["latitude_of_origin", -45.8613888888889], PARAMETER["scale_factor", 0.99996], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2131"]]
+2130=PROJCS["NZGD2000 / Observation Point 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 170.6283333333333], PARAMETER["latitude_of_origin", -45.816111111111105], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2130"]]
+4309=GEOGCS["Yacare", DATUM["Yacare", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-124.45, 183.74, 44.64, -0.4384, 0.5446, -0.9706, -2.1365], AUTHORITY["EPSG","6309"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4309"]]
+4308=GEOGCS["RT38", DATUM["Stockholm 1938", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6308"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4308"]]
+4307=GEOGCS["Nord Sahara 1959", DATUM["Nord Sahara 1959", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-152.9, 43.8, 358.3, 2.714, 1.386, -2.788, -6.743], AUTHORITY["EPSG","6307"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4307"]]
+4306=GEOGCS["Bern 1938", DATUM["Bern 1938", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6306"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4306"]]
+4304=GEOGCS["Voirol 1875", DATUM["Voirol 1875", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-73.0, -247.0, 227.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6304"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4304"]]
+4303=GEOGCS["TC(1948)", DATUM["Trucial Coast 1948", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], AUTHORITY["EPSG","6303"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4303"]]
+2129=PROJCS["NZGD2000 / Mount York 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 167.73861111111114], PARAMETER["latitude_of_origin", -45.56361111111111], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2129"]]
+4302=GEOGCS["Trinidad 1903", DATUM["Trinidad 1903", SPHEROID["Clarke 1858", 6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]], TOWGS84[-61.702, 284.488, 472.052, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6302"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4302"]]
+2128=PROJCS["NZGD2000 / Mount Nicholas 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 168.3986111111111], PARAMETER["latitude_of_origin", -45.132777777777775], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2128"]]
+4301=GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4301"]]
+2127=PROJCS["NZGD2000 / Lindis Peak 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 169.46750000000003], PARAMETER["latitude_of_origin", -44.73500000000001], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2127"]]
+4300=GEOGCS["TM75", DATUM["Geodetic Datum of 1965", SPHEROID["Airy Modified 1849", 6377340.189, 299.3249646, AUTHORITY["EPSG","7002"]], TOWGS84[482.5, -130.6, 564.6, -1.042, -0.214, -0.631, 8.15], AUTHORITY["EPSG","6300"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4300"]]
+2126=PROJCS["NZGD2000 / Timaru 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0572222222222], PARAMETER["latitude_of_origin", -44.40194444444443], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2126"]]
+2125=PROJCS["NZGD2000 / Gawler 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.36055555555555], PARAMETER["latitude_of_origin", -43.74861111111111], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2125"]]
+2124=PROJCS["NZGD2000 / Mount Pleasant 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 172.72694444444437], PARAMETER["latitude_of_origin", -43.590555555555554], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2124"]]
+2123=PROJCS["NZGD2000 / Jacksons Bay 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 168.60611111111112], PARAMETER["latitude_of_origin", -43.977777777777796], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2123"]]
+2122=PROJCS["NZGD2000 / Okarito 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 170.2608333333333], PARAMETER["latitude_of_origin", -43.11], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2122"]]
+2121=PROJCS["NZGD2000 / Hokitika 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 170.97972222222222], PARAMETER["latitude_of_origin", -42.88611111111112], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2121"]]
+2120=PROJCS["NZGD2000 / Marlborough 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 173.8019444444445], PARAMETER["latitude_of_origin", -41.54444444444444], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2120"]]
+2119=PROJCS["NZGD2000 / Amuri 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 173.01], PARAMETER["latitude_of_origin", -42.68888888888889], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2119"]]
+2118=PROJCS["NZGD2000 / Grey 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.54972222222221], PARAMETER["latitude_of_origin", -42.33361111111111], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2118"]]
+2117=PROJCS["NZGD2000 / Buller 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.5811111111111], PARAMETER["latitude_of_origin", -41.81055555555555], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2117"]]
+2116=PROJCS["NZGD2000 / Karamea 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 172.10888888888888], PARAMETER["latitude_of_origin", -41.28972222222223], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2116"]]
+2115=PROJCS["NZGD2000 / Nelson 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 173.29916666666665], PARAMETER["latitude_of_origin", -41.274444444444455], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2115"]]
+2114=PROJCS["NZGD2000 / Collingwood 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 172.6719444444445], PARAMETER["latitude_of_origin", -40.71472222222222], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2114"]]
+2113=PROJCS["NZGD2000 / Wellington 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 174.7763888888889], PARAMETER["latitude_of_origin", -41.30111111111111], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2113"]]
+2112=PROJCS["NZGD2000 / Wairarapa 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 175.6472222222222], PARAMETER["latitude_of_origin", -40.92527777777778], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2112"]]
+2111=PROJCS["NZGD2000 / Wanganui 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 175.48805555555555], PARAMETER["latitude_of_origin", -40.24194444444443], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2111"]]
+2110=PROJCS["NZGD2000 / Tuhirangi 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 175.64], PARAMETER["latitude_of_origin", -39.51222222222223], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2110"]]
+63156405=GEOGCS["Conakry 1905 (deg)", DATUM["Conakry 1905", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-23.0, 259.0, -9.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6315"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63156405"]]
+2109=PROJCS["NZGD2000 / Taranaki 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 174.22777777777776], PARAMETER["latitude_of_origin", -39.13555555555558], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2109"]]
+2108=PROJCS["NZGD2000 / Hawkes Bay 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 176.67361111111114], PARAMETER["latitude_of_origin", -39.65083333333335], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2108"]]
+2107=PROJCS["NZGD2000 / Poverty Bay 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.88555555555558], PARAMETER["latitude_of_origin", -38.62444444444444], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2107"]]
+2106=PROJCS["NZGD2000 / Bay of Plenty 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 176.46611111111113], PARAMETER["latitude_of_origin", -37.76111111111111], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2106"]]
+2105=PROJCS["NZGD2000 / Mount Eden 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 174.7641666666666], PARAMETER["latitude_of_origin", -36.87972222222223], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2105"]]
+2104=PROJCS["Lake / Maracaibo La Rosa Grid", GEOGCS["Lake", DATUM["Lake", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6249"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4249"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -71.6056177777778], PARAMETER["latitude_of_origin", 10.166666666666666], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", -17044.0], PARAMETER["false_northing", -23139.97], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2104"]]
+2103=PROJCS["Lake / Maracaibo Grid M3", GEOGCS["Lake", DATUM["Lake", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6249"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4249"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -71.6056177777778], PARAMETER["latitude_of_origin", 10.166666666666666], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 447315.028], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2103"]]
+26393=PROJCS["Minna / Nigeria East Belt", GEOGCS["Minna", DATUM["Minna", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-111.92, -87.85, 114.5, 1.875, 0.202, 0.219, 0.032], AUTHORITY["EPSG","6263"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4263"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.5], PARAMETER["latitude_of_origin", 4.0], PARAMETER["scale_factor", 0.99975], PARAMETER["false_easting", 1110369.7], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26393"]]
+2102=PROJCS["Lake / Maracaibo Grid", GEOGCS["Lake", DATUM["Lake", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6249"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4249"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -71.6056177777778], PARAMETER["latitude_of_origin", 10.166666666666666], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 147315.028], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2102"]]
+26392=PROJCS["Minna / Nigeria Mid Belt", GEOGCS["Minna", DATUM["Minna", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-111.92, -87.85, 114.5, 1.875, 0.202, 0.219, 0.032], AUTHORITY["EPSG","6263"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4263"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 8.5], PARAMETER["latitude_of_origin", 4.0], PARAMETER["scale_factor", 0.99975], PARAMETER["false_easting", 670553.98], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26392"]]
+2101=PROJCS["Lake / Maracaibo Grid M1", GEOGCS["Lake", DATUM["Lake", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6249"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4249"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -71.6056177777778], PARAMETER["latitude_of_origin", 10.166666666666666], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", -52684.972], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2101"]]
+26391=PROJCS["Minna / Nigeria West Belt", GEOGCS["Minna", DATUM["Minna", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-111.92, -87.85, 114.5, 1.875, 0.202, 0.219, 0.032], AUTHORITY["EPSG","6263"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4263"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 4.5], PARAMETER["latitude_of_origin", 4.0], PARAMETER["scale_factor", 0.99975], PARAMETER["false_easting", 230738.26], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26391"]]
+2100=PROJCS["GGRS87 / Greek Grid", GEOGCS["GGRS87", DATUM["Greek Geodetic Reference System 1987", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-199.87, 74.79, 246.62, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6121"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4121"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2100"]]
+66226405=GEOGCS["Sainte Anne (deg)", DATUM["Guadeloupe 1948", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-472.29, -5.63, -304.12, 0.4362, -0.8374, 0.2563, 1.8984], AUTHORITY["EPSG","6622"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66226405"]]
+61506405=GEOGCS["CH1903+ (deg)", DATUM["CH1903+", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[674.374, 15.056, 405.346, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6150"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61506405"]]
+62456405=GEOGCS["Kertau (deg)", DATUM["Kertau 1968", SPHEROID["Everest 1830 Modified", 6377304.063, 300.8017, AUTHORITY["EPSG","7018"]], TOWGS84[-11.0, 851.0, 5.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6245"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62456405"]]
+3893=PROJCS["ED50 / Iraq National Grid", GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 46.5], PARAMETER["latitude_of_origin", 29.02626833333333], PARAMETER["scale_factor", 0.9994], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3893"]]
+3892=PROJCS["IGRS / UTM zone 39N", GEOGCS["IGRS", DATUM["Iraqi Geospatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1029"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3889"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3892"]]
+3891=PROJCS["IGRS / UTM zone 38N", GEOGCS["IGRS", DATUM["Iraqi Geospatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1029"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3889"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3891"]]
+3890=PROJCS["IGRS / UTM zone 37N", GEOGCS["IGRS", DATUM["Iraqi Geospatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1029"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3889"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3890"]]
+3889=GEOGCS["IGRS", DATUM["Iraqi Geospatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1029"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3889"]]
+3888=GEOGCS["IGRS", DATUM["Iraqi Geospatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1029"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","3888"]]
+3887=GEOCCS["IGRS", DATUM["Iraqi Geospatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1029"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","3887"]]
+3886=VERT_CS["Fao 1979 height", VERT_DATUM["Fao 1979", 2005, AUTHORITY["EPSG","1028"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","3886"]]
+3885=PROJCS["ETRS89 / GK31FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 31.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 31500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3885"]]
+3884=PROJCS["ETRS89 / GK30FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 30500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3884"]]
+3883=PROJCS["ETRS89 / GK29FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 29.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 29500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3883"]]
+3882=PROJCS["ETRS89 / GK28FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 28.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 28500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3882"]]
+3881=PROJCS["ETRS89 / GK27FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 27500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3881"]]
+3880=PROJCS["ETRS89 / GK26FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 26.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 26500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3880"]]
+3879=PROJCS["ETRS89 / GK25FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 25.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 25500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3879"]]
+3878=PROJCS["ETRS89 / GK24FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 24500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3878"]]
+3877=PROJCS["ETRS89 / GK23FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 23.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 23500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3877"]]
+3876=PROJCS["ETRS89 / GK22FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 22.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 22500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3876"]]
+3875=PROJCS["ETRS89 / GK21FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 21500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3875"]]
+3874=PROJCS["ETRS89 / GK20FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 20.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 20500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3874"]]
+3873=PROJCS["ETRS89 / GK19FIN", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 19.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 19500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3873"]]
+3857=PROJCS["WGS 84 / Pseudo-Mercator", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Popular Visualisation Pseudo Mercator", AUTHORITY["EPSG","1024"]], PARAMETER["semi_minor", 6378137.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3857"]]
+3855=VERT_CS["EGM2008 geoid height", VERT_DATUM["EGM2008 geoid", 2005, AUTHORITY["EPSG","1027"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","3855"]]
+3854=PROJCS["County ST74", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.05787], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.99999506], PARAMETER["false_easting", 100182.7406], PARAMETER["false_northing", -6500620.1207], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3854"]]
+26332=PROJCS["Minna / UTM zone 32N", GEOGCS["Minna", DATUM["Minna", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-111.92, -87.85, 114.5, 1.875, 0.202, 0.219, 0.032], AUTHORITY["EPSG","6263"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4263"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26332"]]
+3852=PROJCS["RSRGD2000 / DGLC2000", GEOGCS["RSRGD2000", DATUM["Ross Sea Region Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6764"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4764"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 157.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["standard_parallel_1", -76.66666666666667], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -79.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3852"]]
+26331=PROJCS["Minna / UTM zone 31N", GEOGCS["Minna", DATUM["Minna", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-111.92, -87.85, 114.5, 1.875, 0.202, 0.219, 0.032], AUTHORITY["EPSG","6263"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4263"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26331"]]
+3851=PROJCS["NZGD2000 / NZCS2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 173.0], PARAMETER["latitude_of_origin", -41.0], PARAMETER["standard_parallel_1", -37.5], PARAMETER["false_easting", 3000000.0], PARAMETER["false_northing", 7000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -44.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3851"]]
+3850=PROJCS["SWEREF99 / RT90 5 gon O emulation", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 22.556333333333342], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0000049], PARAMETER["false_easting", 1500121.846], PARAMETER["false_northing", -672.557], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3850"]]
+30800=PROJCS["RT38 2.5 gon W", GEOGCS["RT38", DATUM["Stockholm 1938", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6308"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4308"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.808277777777775], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30800"]]
+3849=PROJCS["SWEREF99 / RT90 2.5 gon O emulation", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 20.306316666666664], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0000052], PARAMETER["false_easting", 1500102.765], PARAMETER["false_northing", -670.706], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3849"]]
+3848=PROJCS["SWEREF99 / RT90 0 gon emulation", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.056299999999997], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0000054], PARAMETER["false_easting", 1500083.521], PARAMETER["false_northing", -668.844], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3848"]]
+3847=PROJCS["SWEREF99 / RT90 2.5 gon V emulation", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.806284529444449], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.00000561024], PARAMETER["false_easting", 1500064.274], PARAMETER["false_northing", -667.711], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3847"]]
+3846=PROJCS["SWEREF99 / RT90 5 gon V emulation", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 13.556266666666666], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0000058], PARAMETER["false_easting", 1500044.695], PARAMETER["false_northing", -667.13], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3846"]]
+3845=PROJCS["SWEREF99 / RT90 7.5 gon V emulation", GEOGCS["SWEREF99", DATUM["SWEREF99", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6619"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4619"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 11.30625], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.000006], PARAMETER["false_easting", 1500025.141], PARAMETER["false_northing", -667.282], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3845"]]
+3844=PROJCS["Pulkovo 1942(58) / Stereo70", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Oblique_Stereographic", AUTHORITY["EPSG","9809"]], PARAMETER["central_meridian", 25.0], PARAMETER["latitude_of_origin", 46.0], PARAMETER["scale_factor", 0.99975], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3844"]]
+3843=PROJCS["Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 8", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3843"]]
+3842=PROJCS["Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 7", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3842"]]
+3841=PROJCS["Pulkovo 1942(83) / 3-degree Gauss-Kruger zone 6", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3841"]]
+3840=PROJCS["Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 10", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 30.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 10500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3840"]]
+66616413=GEOGCS["LKS92 (3D deg)", DATUM["Latvia 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6661"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","66616413"]]
+3839=PROJCS["Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 9", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 9500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3839"]]
+3838=PROJCS["Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 4", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3838"]]
+3837=PROJCS["Pulkovo 1942(58) / 3-degree Gauss-Kruger zone 3", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3837"]]
+3836=PROJCS["Pulkovo 1942(83) / Gauss-Kruger zone 4", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3836"]]
+3835=PROJCS["Pulkovo 1942(83) / Gauss-Kruger zone 3", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3835"]]
+3834=PROJCS["Pulkovo 1942(83) / Gauss-Kruger zone 2", GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3834"]]
+3833=PROJCS["Pulkovo 1942(58) / Gauss-Kruger zone 2", GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3833"]]
+3832=PROJCS["WGS 84 / PDC Mercator", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9804"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 150.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3832"]]
+66616405=GEOGCS["LKS92 (deg)", DATUM["Latvia 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6661"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66616405"]]
+62846405=GEOGCS["Pulkovo 1942 (deg)", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62846405"]]
+3829=PROJCS["Hu Tzu Shan 1950 / UTM zone 51N", GEOGCS["Hu Tzu Shan 1950", DATUM["Hu Tzu Shan 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-637.0, -549.0, -203.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6236"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4236"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3829"]]
+3828=PROJCS["TWD67 / TM2 zone 121", GEOGCS["TWD67", DATUM["Taiwan Datum 1967", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], AUTHORITY["EPSG","1025"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3821"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 121.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3828"]]
+3827=PROJCS["TWD67 / TM2 zone 119", GEOGCS["TWD67", DATUM["Taiwan Datum 1967", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], AUTHORITY["EPSG","1025"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3821"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 119.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3827"]]
+3826=PROJCS["TWD97 / TM2 zone 121", GEOGCS["TWD97", DATUM["Taiwan Datum 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1026"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3824"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 121.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3826"]]
+3825=PROJCS["TWD97 / TM2 zone 119", GEOGCS["TWD97", DATUM["Taiwan Datum 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1026"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3824"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 119.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3825"]]
+3824=GEOGCS["TWD97", DATUM["Taiwan Datum 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1026"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3824"]]
+3823=GEOGCS["TWD97", DATUM["Taiwan Datum 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1026"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","3823"]]
+3822=GEOCCS["TWD97", DATUM["Taiwan Datum 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","1026"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["m", 1.0], AXIS["Geocentric X", GEOCENTRIC_X], AXIS["Geocentric Y", GEOCENTRIC_Y], AXIS["Geocentric Z", GEOCENTRIC_Z], AUTHORITY["EPSG","3822"]]
+3821=GEOGCS["TWD67", DATUM["Taiwan Datum 1967", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], AUTHORITY["EPSG","1025"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3821"]]
+3819=GEOGCS["HD1909", DATUM["Hungarian Datum 1909", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[595.48, 121.69, 515.35, 4.115, 2.9383, -0.853, -3.408], AUTHORITY["EPSG","1024"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","3819"]]
+3816=PROJCS["NAD83(NSRS2007) / Mississippi TM", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -89.75], PARAMETER["latitude_of_origin", 32.5], PARAMETER["scale_factor", 0.9998335], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 1300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3816"]]
+3815=PROJCS["NAD83(HARN) / Mississippi TM", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -89.75], PARAMETER["latitude_of_origin", 32.5], PARAMETER["scale_factor", 0.9998335], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 1300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3815"]]
+3814=PROJCS["NAD83 / Mississippi TM", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -89.75], PARAMETER["latitude_of_origin", 32.5], PARAMETER["scale_factor", 0.9998335], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 1300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3814"]]
+3812=PROJCS["ETRS89 / Belgian Lambert 2008", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 4.359215833333335], PARAMETER["latitude_of_origin", 50.79781500000001], PARAMETER["standard_parallel_1", 51.16666666666667], PARAMETER["false_easting", 649328.0], PARAMETER["false_northing", 665262.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 49.833333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3812"]]
+66286405=GEOGCS["Tahiti (deg)", DATUM["Tahiti 52", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[162.0, 117.0, 154.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6628"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66286405"]]
+61566405=GEOGCS["S-JTSK (deg)", DATUM["System Jednotne Trigonometricke Site Katastralni", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[572.213, 85.334, 461.94, 4.9732, -1.529, -5.2484, 3.5378], AUTHORITY["EPSG","6156"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61566405"]]
+3802=PROJCS["NAD83(CSRS) / Alberta 3TM ref merid 120 W", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3802"]]
+3801=PROJCS["NAD83 / Alberta 3TM ref merid 120 W", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3801"]]
+3800=PROJCS["NAD27 / Alberta 3TM ref merid 120 W", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -120.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3800"]]
+24100=PROJCS["Jamaica 1875 / Jamaica (Old Grid)", GEOGCS["Jamaica 1875", DATUM["Jamaica 1875", SPHEROID["Clarke 1880", 6378249.144808011, 293.46630765562986, AUTHORITY["EPSG","7034"]], AUTHORITY["EPSG","6241"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4241"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -77.0], PARAMETER["latitude_of_origin", 18.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 550000.0], PARAMETER["false_northing", 400000.0], UNIT["m*0.3047972654", 0.3047972654], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24100"]]
+66126413=GEOGCS["JGD2000 (3D deg)", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","66126413"]]
+61406413=GEOGCS["NAD83(CSRS) (3D deg)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61406413"]]
+25884=PROJCS["ETRS89 / TM Baltic93", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25884"]]
+66126405=GEOGCS["JGD2000 (deg)", DATUM["Japanese Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6612"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66126405"]]
+61406405=GEOGCS["NAD83(CSRS) (deg)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61406405"]]
+31297=PROJCS["MGI / Austria Lambert", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 13.333333333333334], PARAMETER["latitude_of_origin", 47.5], PARAMETER["standard_parallel_1", 49.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 400000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31297"]]
+31296=PROJCS["MGI / M34", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 16.333333333333332], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 750000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31296"]]
+31295=PROJCS["MGI / M31", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 13.333333333333334], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 450000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31295"]]
+31294=PROJCS["MGI / M28", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 10.333333333333334], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31294"]]
+31293=PROJCS["MGI (Ferro) / Austria East Zone", GEOGCS["MGI (Ferro)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4805"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 34.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31293"]]
+31292=PROJCS["MGI (Ferro) / Austria Central Zone", GEOGCS["MGI (Ferro)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4805"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 31.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31292"]]
+31291=PROJCS["MGI (Ferro) / Austria West Zone", GEOGCS["MGI (Ferro)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4805"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 28.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31291"]]
+31290=PROJCS["MGI (Ferro) / M34", GEOGCS["MGI (Ferro)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4805"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 34.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 750000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31290"]]
+31289=PROJCS["MGI (Ferro) / M31", GEOGCS["MGI (Ferro)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4805"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 31.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 450000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31289"]]
+31288=PROJCS["MGI (Ferro) / M28", GEOGCS["MGI (Ferro)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4805"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 28.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31288"]]
+31287=PROJCS["MGI / Austria Lambert", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 13.333333333333334], PARAMETER["latitude_of_origin", 47.5], PARAMETER["standard_parallel_1", 49.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 400000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31287"]]
+31286=PROJCS["MGI / Austria M34", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 16.333333333333332], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 750000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31286"]]
+31285=PROJCS["MGI / Austria M31", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 13.333333333333334], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 450000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31285"]]
+31284=PROJCS["MGI / Austria M28", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 10.333333333333334], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31284"]]
+31283=PROJCS["MGI (Ferro) / Austria East Zone", GEOGCS["MGI (Ferro)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4805"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 34.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31283"]]
+31282=PROJCS["MGI (Ferro) / Austria Central Zone", GEOGCS["MGI (Ferro)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4805"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 31.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31282"]]
+31281=PROJCS["MGI (Ferro) / Austria West Zone", GEOGCS["MGI (Ferro)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4805"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 28.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31281"]]
+31279=PROJCS["MGI / Balkans zone 8", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 8500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31279"]]
+31278=PROJCS["MGI / Balkans zone 8", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31278"]]
+31277=PROJCS["MGI / Balkans zone 7", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31277"]]
+31276=PROJCS["MGI / Balkans zone 6", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31276"]]
+31275=PROJCS["MGI / Balkans zone 5", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31275"]]
+31268=PROJCS["MGI / 3-degree Gauss zone 8", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 24.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 8500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31268"]]
+31267=PROJCS["MGI / 3-degree Gauss zone 7", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31267"]]
+31266=PROJCS["MGI / 3-degree Gauss zone 6", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 18.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31266"]]
+31265=PROJCS["MGI / 3-degree Gauss zone 5", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31265"]]
+66676405=GEOGCS["IKBD-92 (deg)", DATUM["Iraq-Kuwait Boundary Datum 1992", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6667"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66676405"]]
+61956405=GEOGCS["Scoresbysund 1952 (deg)", DATUM["Scoresbysund 1952", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[105.0, 326.0, -102.5, 0.0, 0.0, 0.814, -0.6], AUTHORITY["EPSG","6195"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61956405"]]
+21483=PROJCS["Beijing 1954 / Gauss-Kruger 23N", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21483"]]
+21482=PROJCS["Beijing 1954 / Gauss-Kruger 22N", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21482"]]
+21481=PROJCS["Beijing 1954 / Gauss-Kruger 21N", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21481"]]
+21480=PROJCS["Beijing 1954 / Gauss-Kruger 20N", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21480"]]
+25838=PROJCS["ETRS89 / UTM zone 38N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25838"]]
+25837=PROJCS["ETRS89 / UTM zone 37N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25837"]]
+31259=PROJCS["MGI / Austria GK M34", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 16.333333333333332], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 750000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31259"]]
+25836=PROJCS["ETRS89 / UTM zone 36N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25836"]]
+31258=PROJCS["MGI / Austria GK M31", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 13.333333333333334], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 450000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31258"]]
+25835=PROJCS["ETRS89 / UTM zone 35N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25835"]]
+31257=PROJCS["MGI / Austria GK M28", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 10.333333333333334], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31257"]]
+25834=PROJCS["ETRS89 / UTM zone 34N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25834"]]
+31256=PROJCS["MGI / Austria GK East", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 16.333333333333332], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31256"]]
+25833=PROJCS["ETRS89 / UTM zone 33N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25833"]]
+31255=PROJCS["MGI / Austria GK Central", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 13.333333333333334], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31255"]]
+25832=PROJCS["ETRS89 / UTM zone 32N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25832"]]
+31254=PROJCS["MGI / Austria GK West", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 10.333333333333334], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31254"]]
+25831=PROJCS["ETRS89 / UTM zone 31N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25831"]]
+31253=PROJCS["MGI (Ferro) / Austria GK East Zone", GEOGCS["MGI (Ferro)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4805"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 34.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31253"]]
+25830=PROJCS["ETRS89 / UTM zone 30N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25830"]]
+31252=PROJCS["MGI (Ferro) / Austria GK Central Zone", GEOGCS["MGI (Ferro)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4805"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 31.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31252"]]
+31251=PROJCS["MGI (Ferro) / Austria GK West Zone", GEOGCS["MGI (Ferro)", DATUM["Militar-Geographische Institut (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6805"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4805"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 28.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31251"]]
+4299=GEOGCS["TM65", DATUM["TM65", SPHEROID["Airy Modified 1849", 6377340.189, 299.3249646, AUTHORITY["EPSG","7002"]], TOWGS84[482.5, -130.6, 564.6, -1.042, -0.214, -0.631, 8.15], AUTHORITY["EPSG","6299"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4299"]]
+21479=PROJCS["Beijing 1954 / Gauss-Kruger 19N", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21479"]]
+4298=GEOGCS["Timbalai 1948", DATUM["Timbalai 1948", SPHEROID["Everest 1830 (1967 Definition)", 6377298.556, 300.8017, AUTHORITY["EPSG","7016"]], TOWGS84[-689.5937, 623.84046, -65.93566, -0.02331, -1.17094, 0.80054, 5.88536], AUTHORITY["EPSG","6298"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4298"]]
+21478=PROJCS["Beijing 1954 / Gauss-Kruger 18N", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21478"]]
+4297=GEOGCS["Tananarive", DATUM["Tananarive 1925", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-189.0, -242.0, -91.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6297"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4297"]]
+21477=PROJCS["Beijing 1954 / Gauss-Kruger 17N", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21477"]]
+4296=GEOGCS["Sudan", DATUM["Sudan", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6296"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4296"]]
+21476=PROJCS["Beijing 1954 / Gauss-Kruger 16N", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21476"]]
+4295=GEOGCS["Serindung", DATUM["Serindung", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6295"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4295"]]
+21475=PROJCS["Beijing 1954 / Gauss-Kruger 15N", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21475"]]
+4294=GEOGCS["Segora", DATUM["Segora", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-403.0, 684.0, 41.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6294"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4294"]]
+21474=PROJCS["Beijing 1954 / Gauss-Kruger 14N", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21474"]]
+4293=GEOGCS["Schwarzeck", DATUM["Schwarzeck", SPHEROID["Bessel Namibia (GLM)", 6377483.865280419, 299.1528128, AUTHORITY["EPSG","7046"]], TOWGS84[616.0, 97.0, -251.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6293"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4293"]]
+21473=PROJCS["Beijing 1954 / Gauss-Kruger 13N", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21473"]]
+4292=GEOGCS["Sapper Hill 1943", DATUM["Sapper Hill 1943", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-355.0, 21.0, 72.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6292"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4292"]]
+4291=GEOGCS["SAD69", DATUM["South American Datum 1969", SPHEROID["GRS 1967", 6378160.0, 298.247167427, AUTHORITY["EPSG","7036"]], TOWGS84[-57.0, 1.0, -41.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6291"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4291"]]
+25829=PROJCS["ETRS89 / UTM zone 29N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25829"]]
+25828=PROJCS["ETRS89 / UTM zone 28N", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25828"]]
+4289=GEOGCS["Amersfoort", DATUM["Amersfoort", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[565.2369, 50.0087, 465.658, -0.40685733032239757, -0.3507326765425626, 1.8703473836067959, 4.0812], AUTHORITY["EPSG","6289"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4289"]]
+4288=GEOGCS["Loma Quintana", DATUM["Loma Quintana", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6288"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4288"]]
+4287=GEOGCS["Qornoq", DATUM["Qornoq", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[164.0, 138.0, -189.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6287"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4287"]]
+4286=GEOGCS["Qatar 1948", DATUM["Qatar 1948", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], AUTHORITY["EPSG","6286"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4286"]]
+4285=GEOGCS["Qatar 1974", DATUM["Qatar 1974", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-128.16, -282.42, 21.93, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6285"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4285"]]
+4284=GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]]
+4283=GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]]
+21463=PROJCS["Beijing 1954 / Gauss-Kruger CM 135E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21463"]]
+4282=GEOGCS["Pointe Noire", DATUM["Congo 1960 Pointe Noire", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-178.3, -316.7, -131.5, 5.278, 6.077, 10.979, 19.166], AUTHORITY["EPSG","6282"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4282"]]
+21462=PROJCS["Beijing 1954 / Gauss-Kruger CM 129E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21462"]]
+4281=GEOGCS["Palestine 1923", DATUM["Palestine 1923", SPHEROID["Clarke 1880 (Benoit)", 6378300.789, 293.4663155389811, AUTHORITY["EPSG","7010"]], TOWGS84[-275.7224, 94.7824, 340.8944, -8.001, -4.42, -11.821, 1.0], AUTHORITY["EPSG","6281"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4281"]]
+21461=PROJCS["Beijing 1954 / Gauss-Kruger CM 123E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21461"]]
+4280=GEOGCS["Padang", DATUM["Padang 1884", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6280"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4280"]]
+21460=PROJCS["Beijing 1954 / Gauss-Kruger CM 117E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21460"]]
+4279=GEOGCS["OS(SN)80", DATUM["OS (SN) 1980", SPHEROID["Airy 1830", 6377563.396, 299.3249646, AUTHORITY["EPSG","7001"]], AUTHORITY["EPSG","6279"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4279"]]
+21459=PROJCS["Beijing 1954 / Gauss-Kruger CM 111E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21459"]]
+4278=GEOGCS["OSGB70", DATUM["OSGB 1970 (SN)", SPHEROID["Airy 1830", 6377563.396, 299.3249646, AUTHORITY["EPSG","7001"]], AUTHORITY["EPSG","6278"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4278"]]
+21458=PROJCS["Beijing 1954 / Gauss-Kruger CM 105E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21458"]]
+4277=GEOGCS["OSGB 1936", DATUM["OSGB 1936", SPHEROID["Airy 1830", 6377563.396, 299.3249646, AUTHORITY["EPSG","7001"]], TOWGS84[446.448, -125.157, 542.06, 0.15, 0.247, 0.842, -20.489], AUTHORITY["EPSG","6277"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4277"]]
+21457=PROJCS["Beijing 1954 / Gauss-Kruger CM 99E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21457"]]
+4276=GEOGCS["NSWC 9Z-2", DATUM["NSWC 9Z-2", SPHEROID["NWL 9D", 6378145.0, 298.25, AUTHORITY["EPSG","7025"]], AUTHORITY["EPSG","6276"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4276"]]
+21456=PROJCS["Beijing 1954 / Gauss-Kruger CM 93E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21456"]]
+4275=GEOGCS["NTF", DATUM["Nouvelle Triangulation Francaise", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-168.0, -60.0, 320.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6275"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4275"]]
+21455=PROJCS["Beijing 1954 / Gauss-Kruger CM 87E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21455"]]
+4274=GEOGCS["Datum 73", DATUM["Datum 73", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-239.749, 88.181, 30.488, 0.263, -0.082, -1.211, 2.229], AUTHORITY["EPSG","6274"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4274"]]
+21454=PROJCS["Beijing 1954 / Gauss-Kruger CM 81E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21454"]]
+4273=GEOGCS["NGO 1948", DATUM["NGO 1948", SPHEROID["Bessel Modified", 6377492.018, 299.1528128, AUTHORITY["EPSG","7005"]], TOWGS84[278.3, 93.0, 474.5, 7.889, 0.05, -6.61, 6.21], AUTHORITY["EPSG","6273"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4273"]]
+21453=PROJCS["Beijing 1954 / Gauss-Kruger CM 75E", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21453"]]
+2099=PROJCS["Qatar 1948 / Qatar Grid", GEOGCS["Qatar 1948", DATUM["Qatar 1948", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], AUTHORITY["EPSG","6286"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4286"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", 50.761388888888874], PARAMETER["latitude_of_origin", 25.38236111111113], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 100000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2099"]]
+4272=GEOGCS["NZGD49", DATUM["New Zealand Geodetic Datum 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[59.47, -5.04, 187.44, 0.47, 0.1, -1.024, -4.5993], AUTHORITY["EPSG","6272"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4272"]]
+2098=PROJCS["Korean 1985 / West Belt", GEOGCS["Korean 1985", DATUM["Korean Datum 1985", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6162"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4162"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 125.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2098"]]
+4271=GEOGCS["Naparima 1972", DATUM["Naparima 1972", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-2.0, 374.0, 172.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6271"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4271"]]
+2097=PROJCS["Korean 1985 / Central Belt", GEOGCS["Korean 1985", DATUM["Korean Datum 1985", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6162"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4162"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 127.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2097"]]
+4270=GEOGCS["Nahrwan 1967", DATUM["Nahrwan 1967", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-245.0, -153.9, 382.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6270"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4270"]]
+2096=PROJCS["Korean 1985 / East Belt", GEOGCS["Korean 1985", DATUM["Korean Datum 1985", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6162"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4162"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 38.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 500000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2096"]]
+2095=PROJCS["Bissau / UTM zone 28N", GEOGCS["Bissau", DATUM["Bissau", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-173.0, 253.0, 27.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6165"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4165"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2095"]]
+2094=PROJCS["WGS 72BE / TM 106 NE", GEOGCS["WGS 72BE", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4324"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 106.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2094"]]
+2093=PROJCS["Hanoi 1972 / GK 106 NE", GEOGCS["Hanoi 1972", DATUM["Hanoi 1972", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-17.51, -108.32, -62.39, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6147"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4147"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 106.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2093"]]
+2092=PROJCS["South Yemen / Gauss Kruger zone 9", GEOGCS["South Yemen", DATUM["South Yemen", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-76.0, -138.0, 67.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6164"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4164"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 9500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2092"]]
+2091=PROJCS["South Yemen / Gauss Kruger zone 8", GEOGCS["South Yemen", DATUM["South Yemen", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-76.0, -138.0, 67.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6164"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4164"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 8500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2091"]]
+2090=PROJCS["Yemen NGN96 / UTM zone 39N", GEOGCS["Yemen NGN96", DATUM["Yemen National Geodetic Network 1996", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6163"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4163"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2090"]]
+4269=GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]]
+4268=GEOGCS["NAD27 Michigan", DATUM["NAD27 Michigan", SPHEROID["Clarke 1866 Michigan", 6378450.047548896, 294.978697164674, AUTHORITY["EPSG","7009"]], AUTHORITY["EPSG","6268"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4268"]]
+4267=GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]]
+4266=GEOGCS["M'poraloko", DATUM["M'poraloko", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-80.7, -132.5, 41.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6266"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4266"]]
+4265=GEOGCS["Monte Mario", DATUM["Monte Mario", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-104.1, -49.1, -9.9, 0.971, -2.917, 0.714, -11.68], AUTHORITY["EPSG","6265"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4265"]]
+4264=GEOGCS["Mhast", DATUM["Mhast", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-252.95, -4.11, -96.38, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6264"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4264"]]
+4263=GEOGCS["Minna", DATUM["Minna", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-111.92, -87.85, 114.5, 1.875, 0.202, 0.219, 0.032], AUTHORITY["EPSG","6263"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4263"]]
+2089=PROJCS["Yemen NGN96 / UTM zone 38N", GEOGCS["Yemen NGN96", DATUM["Yemen National Geodetic Network 1996", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6163"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4163"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2089"]]
+4262=GEOGCS["Massawa", DATUM["Massawa", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[639.0, 405.0, 60.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6262"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4262"]]
+2088=PROJCS["Carthage / TM 11 NE", GEOGCS["Carthage", DATUM["Carthage", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-260.1, 5.5, 432.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6223"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4223"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 11.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2088"]]
+4261=GEOGCS["Merchich", DATUM["Merchich", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[31.0, 146.0, 47.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6261"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4261"]]
+2087=PROJCS["ELD79 / TM 12 NE", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 12.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2087"]]
+4260=GEOGCS["Manoca", DATUM["Manoca", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-70.9, -151.8, -41.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6260"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4260"]]
+2086=PROJCS["NAD27 / Cuba Sur", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -76.83333333333333], PARAMETER["latitude_of_origin", 20.716666666666665], PARAMETER["scale_factor", 0.99994848], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 229126.939], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2086"]]
+2085=PROJCS["NAD27 / Cuba Norte", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 22.349999999999998], PARAMETER["scale_factor", 0.99993602], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 280296.016], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2085"]]
+2084=PROJCS["Hito XVIII 1963 / UTM zone 19S", GEOGCS["Hito XVIII 1963", DATUM["Hito XVIII 1963", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[18.38, 192.45, 96.82, 0.056, -0.142, -0.2, -0.0013], AUTHORITY["EPSG","6254"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4254"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2084"]]
+2083=PROJCS["Hito XVIII 1963 / Argentina 2", GEOGCS["Hito XVIII 1963", DATUM["Hito XVIII 1963", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[18.38, 192.45, 96.82, 0.056, -0.142, -0.2, -0.0013], AUTHORITY["EPSG","6254"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4254"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2083"]]
+2082=PROJCS["Pampa del Castillo / Argentina 2", GEOGCS["Pampa del Castillo", DATUM["Pampa del Castillo", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[27.5, 14.0, 186.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6161"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4161"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2082"]]
+2081=PROJCS["Chos Malal 1914 / Argentina 2", GEOGCS["Chos Malal 1914", DATUM["Chos Malal 1914", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6160"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4160"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", -90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2081"]]
+62746405=GEOGCS["Datum 73 (deg)", DATUM["Datum 73", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-239.749, 88.181, 30.488, 0.263, -0.082, -1.211, 2.229], AUTHORITY["EPSG","6274"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62746405"]]
+2080=PROJCS["ELD79 / UTM zone 35N", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2080"]]
+4259=GEOGCS["Malongo 1987", DATUM["Malongo 1987", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-254.1, -5.36, -100.29, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6259"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4259"]]
+4258=GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]]
+4257=GEOGCS["Makassar", DATUM["Makassar", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-587.8, 519.75, 145.76, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6257"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4257"]]
+4256=GEOGCS["Mahe 1971", DATUM["Mahe 1971", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[41.0, -220.0, -134.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6256"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4256"]]
+4255=GEOGCS["Herat North", DATUM["Herat North", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-333.0, -222.0, 114.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6255"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4255"]]
+4254=GEOGCS["Hito XVIII 1963", DATUM["Hito XVIII 1963", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[18.38, 192.45, 96.82, 0.056, -0.142, -0.2, -0.0013], AUTHORITY["EPSG","6254"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4254"]]
+4253=GEOGCS["Luzon 1911", DATUM["Luzon 1911", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-133.0, -77.0, -51.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6253"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4253"]]
+2079=PROJCS["ELD79 / UTM zone 34N", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2079"]]
+4252=GEOGCS["Lome", DATUM["Lome", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6252"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4252"]]
+2078=PROJCS["ELD79 / UTM zone 33N", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2078"]]
+4251=GEOGCS["Liberia 1964", DATUM["Liberia 1964", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-90.0, 40.0, 88.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6251"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4251"]]
+2077=PROJCS["ELD79 / UTM zone 32N", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2077"]]
+4250=GEOGCS["Leigon", DATUM["Leigon", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-130.0, 29.0, 364.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6250"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4250"]]
+2076=PROJCS["ELD79 / Libya zone 13", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 25.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2076"]]
+2075=PROJCS["ELD79 / Libya zone 12", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 23.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2075"]]
+2074=PROJCS["ELD79 / Libya zone 11", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2074"]]
+2073=PROJCS["ELD79 / Libya zone 10", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 19.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2073"]]
+2072=PROJCS["ELD79 / Libya zone 9", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 17.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2072"]]
+2071=PROJCS["ELD79 / Libya zone 8", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2071"]]
+2070=PROJCS["ELD79 / Libya zone 7", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 13.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2070"]]
+4249=GEOGCS["Lake", DATUM["Lake", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6249"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4249"]]
+4248=GEOGCS["PSAD56", DATUM["Provisional South American Datum 1956", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-307.7, 265.3, -363.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6248"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4248"]]
+4247=GEOGCS["La Canoa", DATUM["La Canoa", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-273.5, 110.6, -357.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6247"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4247"]]
+4246=GEOGCS["KOC", DATUM["Kuwait Oil Company", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-294.7, -200.1, 525.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6246"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4246"]]
+4245=GEOGCS["Kertau 1968", DATUM["Kertau 1968", SPHEROID["Everest 1830 Modified", 6377304.063, 300.8017, AUTHORITY["EPSG","7018"]], TOWGS84[-11.0, 851.0, 5.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6245"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4245"]]
+4244=GEOGCS["Kandawala", DATUM["Kandawala", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[-97.0, 787.0, 86.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6244"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4244"]]
+4243=GEOGCS["Kalianpur 1880", DATUM["Kalianpur 1880", SPHEROID["Everest (1830 Definition)", 6377299.36559538, 300.80172554336184, AUTHORITY["EPSG","7042"]], AUTHORITY["EPSG","6243"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4243"]]
+21423=PROJCS["Beijing 1954 / Gauss-Kruger zone 23", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 23500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21423"]]
+2069=PROJCS["ELD79 / Libya zone 6", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 11.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2069"]]
+4242=GEOGCS["JAD69", DATUM["Jamaica 1969", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-33.722, 153.789, 94.959, -8.581, 4.478, -4.54, 8.95], AUTHORITY["EPSG","6242"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4242"]]
+21422=PROJCS["Beijing 1954 / Gauss-Kruger zone 22", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 22500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21422"]]
+2068=PROJCS["ELD79 / Libya zone 5", GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2068"]]
+4241=GEOGCS["Jamaica 1875", DATUM["Jamaica 1875", SPHEROID["Clarke 1880", 6378249.144808011, 293.46630765562986, AUTHORITY["EPSG","7034"]], AUTHORITY["EPSG","6241"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4241"]]
+21421=PROJCS["Beijing 1954 / Gauss-Kruger zone 21", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 21500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21421"]]
+2067=PROJCS["Naparima 1955 / UTM zone 20N", GEOGCS["Naparima 1955", DATUM["Naparima 1955", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-0.465, 372.095, 171.736, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6158"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4158"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2067"]]
+4240=GEOGCS["Indian 1975", DATUM["Indian 1975", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[204.64, 834.74, 293.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6240"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4240"]]
+21420=PROJCS["Beijing 1954 / Gauss-Kruger zone 20", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 20500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21420"]]
+2066=PROJCS["Mount Dillon / Tobago Grid", GEOGCS["Mount Dillon", DATUM["Mount Dillon", SPHEROID["Clarke 1858", 6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]], AUTHORITY["EPSG","6157"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4157"]], PROJECTION["Cassini_Soldner", AUTHORITY["EPSG","9806"]], PARAMETER["central_meridian", -60.686008888888885], PARAMETER["latitude_of_origin", 11.252178611111109], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 187500.0], PARAMETER["false_northing", 180000.0], UNIT["m*0.201166195164", 0.201166195164], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2066"]]
+2065=PROJCS["S-JTSK (Ferro) / Krovak", GEOGCS["S-JTSK (Ferro)", DATUM["System Jednotne Trigonometricke Site Katastralni (Ferro)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6818"]], PRIMEM["Ferro", -17.666666666666668, AUTHORITY["EPSG","8909"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4818"]], PROJECTION["Krovak", AUTHORITY["EPSG","9819"]], PARAMETER["latitude_of_center", 49.5], PARAMETER["longitude_of_center", 42.5], PARAMETER["azimuth", 30.288139722222223], PARAMETER["pseudo_standard_parallel_1", 78.5], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","2065"]]
+2064=PROJCS["Dabola 1981 / UTM zone 29N", GEOGCS["Conakry 1905", DATUM["Conakry 1905", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-23.0, 259.0, -9.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6315"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4315"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2064"]]
+2063=PROJCS["Dabola 1981 / UTM zone 28N", GEOGCS["Conakry 1905", DATUM["Conakry 1905", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-23.0, 259.0, -9.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6315"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4315"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2063"]]
+2062=PROJCS["Madrid 1870 (Madrid) / Spain", GEOGCS["Madrid 1870 (Madrid)", DATUM["Madrid 1870 (Madrid)", SPHEROID["Struve 1860", 6378298.3, 294.73, AUTHORITY["EPSG","7028"]], AUTHORITY["EPSG","6903"]], PRIMEM["Madrid", -3.68793888888889, AUTHORITY["EPSG","8905"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4903"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9988085293], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 600000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2062"]]
+2061=PROJCS["ED50(ED77) / UTM zone 41N", GEOGCS["ED50(ED77)", DATUM["European Datum 1950(1977)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-123.02, -158.95, -168.47, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6154"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4154"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2061"]]
+66186405=GEOGCS["SAD69 (deg)", DATUM["South American Datum 1969", SPHEROID["GRS 1967 Modified", 6378160.0, 298.25, AUTHORITY["EPSG","7050"]], TOWGS84[-66.87, 4.37, -38.52, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6618"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66186405"]]
+2060=PROJCS["ED50(ED77) / UTM zone 40N", GEOGCS["ED50(ED77)", DATUM["European Datum 1950(1977)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-123.02, -158.95, -168.47, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6154"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4154"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2060"]]
+61466405=GEOGCS["Kalianpur 1975 (deg)", DATUM["Kalianpur 1975", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], TOWGS84[295.0, 736.0, 257.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6146"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61466405"]]
+4239=GEOGCS["Indian 1954", DATUM["Indian 1954", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[217.0, 823.0, 299.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6239"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4239"]]
+21419=PROJCS["Beijing 1954 / Gauss-Kruger zone 19", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 19500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21419"]]
+4238=GEOGCS["ID74", DATUM["Indonesian Datum 1974", SPHEROID["Indonesian National Spheroid", 6378160.0, 298.247, AUTHORITY["EPSG","7021"]], TOWGS84[-1.977, -13.06, -9.993, 0.364, -0.254, -0.689, -1.037], AUTHORITY["EPSG","6238"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4238"]]
+21418=PROJCS["Beijing 1954 / Gauss-Kruger zone 18", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 18500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21418"]]
+4237=GEOGCS["HD72", DATUM["Hungarian Datum 1972", SPHEROID["GRS 1967", 6378160.0, 298.247167427, AUTHORITY["EPSG","7036"]], TOWGS84[52.17, -71.82, -14.9, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6237"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4237"]]
+21417=PROJCS["Beijing 1954 / Gauss-Kruger zone 17", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 17500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21417"]]
+4236=GEOGCS["Hu Tzu Shan 1950", DATUM["Hu Tzu Shan 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-637.0, -549.0, -203.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6236"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4236"]]
+21416=PROJCS["Beijing 1954 / Gauss-Kruger zone 16", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 16500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21416"]]
+4235=GEOGCS["Guyane Francaise", DATUM["Guyane Francaise", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6235"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4235"]]
+21415=PROJCS["Beijing 1954 / Gauss-Kruger zone 15", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 15500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21415"]]
+4234=GEOGCS["Garoua", DATUM["Garoua", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6234"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4234"]]
+21414=PROJCS["Beijing 1954 / Gauss-Kruger zone 14", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 14500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21414"]]
+4233=GEOGCS["Gandajika 1970", DATUM["Gandajika 1970", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-133.0, -321.0, 50.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6233"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4233"]]
+21413=PROJCS["Beijing 1954 / Gauss-Kruger zone 13", GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 13500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","21413"]]
+2059=PROJCS["ED50(ED77) / UTM zone 39N", GEOGCS["ED50(ED77)", DATUM["European Datum 1950(1977)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-123.02, -158.95, -168.47, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6154"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4154"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2059"]]
+4232=GEOGCS["Fahud", DATUM["Fahud", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-346.0, -1.0, 224.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6232"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4232"]]
+2058=PROJCS["ED50(ED77) / UTM zone 38N", GEOGCS["ED50(ED77)", DATUM["European Datum 1950(1977)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-123.02, -158.95, -168.47, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6154"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4154"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2058"]]
+4231=GEOGCS["ED87", DATUM["European Datum 1987", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-82.981, -99.719, -110.709, -0.10470001565102613, 0.031001600378938583, 0.08040202147511816, -0.3143], AUTHORITY["EPSG","6231"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4231"]]
+2057=PROJCS["Rassadiran / Nakhl e Taqi", GEOGCS["Rassadiran", DATUM["Rassadiran", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-133.63, -157.5, -158.62, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6153"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4153"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9815"]], PARAMETER["longitude_of_center", 52.60353916666668], PARAMETER["latitude_of_center", 27.518828805555568], PARAMETER["azimuth", 0.5716611944444444], PARAMETER["scale_factor", 0.999895934], PARAMETER["false_easting", 658377.437], PARAMETER["false_northing", 3044969.194], PARAMETER["rectified_grid_angle", 0.5716611944444444], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2057"]]
+4230=GEOGCS["ED50", DATUM["European Datum 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-116.641, -56.931, -110.559, 0.893, 0.921, -0.917, -3.52], AUTHORITY["EPSG","6230"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4230"]]
+2056=PROJCS["CH1903+ / LV95", GEOGCS["CH1903+", DATUM["CH1903+", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[674.374, 15.056, 405.346, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6150"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4150"]], PROJECTION["Hotine_Oblique_Mercator", AUTHORITY["EPSG","9815"]], PARAMETER["longitude_of_center", 7.439583333333333], PARAMETER["latitude_of_center", 46.952405555555565], PARAMETER["azimuth", 90.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2600000.0], PARAMETER["false_northing", 1200000.0], PARAMETER["rectified_grid_angle", 90.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2056"]]
+2055=PROJCS["Hartebeesthoek94 / Lo33", GEOGCS["Hartebeesthoek94", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4148"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","2055"]]
+2054=PROJCS["Hartebeesthoek94 / Lo31", GEOGCS["Hartebeesthoek94", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4148"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 31.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","2054"]]
+2053=PROJCS["Hartebeesthoek94 / Lo29", GEOGCS["Hartebeesthoek94", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4148"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 29.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","2053"]]
+2052=PROJCS["Hartebeesthoek94 / Lo27", GEOGCS["Hartebeesthoek94", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4148"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","2052"]]
+2051=PROJCS["Hartebeesthoek94 / Lo25", GEOGCS["Hartebeesthoek94", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4148"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 25.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","2051"]]
+2050=PROJCS["Hartebeesthoek94 / Lo23", GEOGCS["Hartebeesthoek94", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4148"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 23.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","2050"]]
+4229=GEOGCS["Egypt 1907", DATUM["Egypt 1907", SPHEROID["Helmert 1906", 6378200.0, 298.3, AUTHORITY["EPSG","7020"]], TOWGS84[-130.0, 110.0, -13.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6229"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4229"]]
+4228=GEOGCS["Douala", DATUM["Douala", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6228"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4228"]]
+4227=GEOGCS["Deir ez Zor", DATUM["Deir ez Zor", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-83.58, -397.54, 458.78, -17.595, -2.847, 4.256, 3.225], AUTHORITY["EPSG","6227"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4227"]]
+4226=GEOGCS["Cote d'Ivoire", DATUM["Cote d'Ivoire", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6226"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4226"]]
+4225=GEOGCS["Corrego Alegre 1970-72", DATUM["Corrego Alegre 1970-72", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-206.0, 172.0, -6.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6225"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4225"]]
+4224=GEOGCS["Chua", DATUM["Chua", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-144.35, 242.88, -33.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6224"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4224"]]
+4223=GEOGCS["Carthage", DATUM["Carthage", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-260.1, 5.5, 432.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6223"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4223"]]
+2049=PROJCS["Hartebeesthoek94 / Lo21", GEOGCS["Hartebeesthoek94", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4148"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","2049"]]
+4222=GEOGCS["Cape", DATUM["Cape", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-136.0, -108.0, -292.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6222"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4222"]]
+2048=PROJCS["Hartebeesthoek94 / Lo19", GEOGCS["Hartebeesthoek94", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4148"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 19.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","2048"]]
+4221=GEOGCS["Campo Inchauspe", DATUM["Campo Inchauspe", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-154.5, 150.7, 100.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6221"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4221"]]
+2047=PROJCS["Hartebeesthoek94 / Lo17", GEOGCS["Hartebeesthoek94", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4148"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 17.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","2047"]]
+4220=GEOGCS["Camacupa", DATUM["Camacupa", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-50.9, -347.6, -231.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6220"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4220"]]
+2046=PROJCS["Hartebeesthoek94 / Lo15", GEOGCS["Hartebeesthoek94", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4148"]], PROJECTION["Transverse Mercator (South Orientated)", AUTHORITY["EPSG","9808"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Westing", WEST], AXIS["Southing", SOUTH], AUTHORITY["EPSG","2046"]]
+2045=PROJCS["Hanoi 1972 / Gauss-Kruger zone 19", GEOGCS["Hanoi 1972", DATUM["Hanoi 1972", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-17.51, -108.32, -62.39, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6147"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4147"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 19500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2045"]]
+2044=PROJCS["Hanoi 1972 / Gauss-Kruger zone 18", GEOGCS["Hanoi 1972", DATUM["Hanoi 1972", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-17.51, -108.32, -62.39, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6147"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4147"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 18500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2044"]]
+2043=PROJCS["Abidjan 1987 / UTM zone 29N", GEOGCS["Abidjan 1987", DATUM["Abidjan 1987", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-124.76, 53.0, 466.79, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6143"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4143"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2043"]]
+2042=PROJCS["Locodjo 1965 / UTM zone 29N", GEOGCS["Locodjo 1965", DATUM["Locodjo 1965", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-125.0, 53.0, 467.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6142"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4142"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2042"]]
+2041=PROJCS["Abidjan 1987 / UTM zone 30N", GEOGCS["Abidjan 1987", DATUM["Abidjan 1987", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-124.76, 53.0, 466.79, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6143"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4143"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2041"]]
+2040=PROJCS["Locodjo 1965 / UTM zone 30N", GEOGCS["Locodjo 1965", DATUM["Locodjo 1965", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-125.0, 53.0, 467.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6142"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4142"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2040"]]
+4219=GEOGCS["Bukit Rimpah", DATUM["Bukit Rimpah", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-384.0, 664.0, -48.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6219"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4219"]]
+4218=GEOGCS["Bogota 1975", DATUM["Bogota 1975", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[304.5, 306.5, -318.1, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6218"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4218"]]
+4217=PROJCS["NAD83 / BLM 59N (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1640416.67], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4217"]]
+4216=GEOGCS["Bermuda 1957", DATUM["Bermuda 1957", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-292.295, 248.758, 429.447, 4.9971, -2.99, -6.6906, 1.0289], AUTHORITY["EPSG","6216"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4216"]]
+4215=GEOGCS["Belge 1950", DATUM["Reseau National Belge 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6215"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4215"]]
+4214=GEOGCS["Beijing 1954", DATUM["Beijing 1954", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[15.8, -154.4, -82.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6214"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4214"]]
+4213=GEOGCS["Beduaram", DATUM["Beduaram", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-106.0, -87.0, 188.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6213"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4213"]]
+2039=PROJCS["Israel / Israeli TM Grid", GEOGCS["Israel", DATUM["Israel", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-48.0, 55.0, 52.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6141"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4141"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 35.20451694444445], PARAMETER["latitude_of_origin", 31.734393611111106], PARAMETER["scale_factor", 1.0000067], PARAMETER["false_easting", 219529.584], PARAMETER["false_northing", 626907.39], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2039"]]
+4212=GEOGCS["Barbados 1938", DATUM["Barbados 1938", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[31.95, 300.99, 419.19, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6212"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4212"]]
+4211=GEOGCS["Batavia", DATUM["Batavia", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-377.7, 675.1, -52.2, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6211"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4211"]]
+4210=GEOGCS["Arc 1960", DATUM["Arc 1960", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-157.0, -2.0, -299.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6210"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4210"]]
+2035=PROJCS["NAD27(CGQ77) / UTM zone 21N", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2035"]]
+2034=PROJCS["NAD27(CGQ77) / UTM zone 20N", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2034"]]
+2033=PROJCS["NAD27(CGQ77) / UTM zone 19N", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2033"]]
+2032=PROJCS["NAD27(CGQ77) / UTM zone 18N", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2032"]]
+2031=PROJCS["NAD27(CGQ77) / UTM zone 17N", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2031"]]
+2030=PROJCS["NAD27(76) / UTM zone 18N", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2030"]]
+61306413=GEOGCS["Moznet (3D deg)", DATUM["Moznet (ITRF94)", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6130"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61306413"]]
+4209=GEOGCS["Arc 1950", DATUM["Arc 1950", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-138.0, -105.0, -289.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6209"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4209"]]
+4208=GEOGCS["Aratu", DATUM["Aratu", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-151.99, 287.04, -147.45, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6208"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4208"]]
+4207=GEOGCS["Lisbon", DATUM["Lisbon 1937", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-288.885, -91.744, 126.244, -1.691, -0.41, 0.211, -4.598], AUTHORITY["EPSG","6207"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4207"]]
+4206=GEOGCS["Agadez", DATUM["Agadez", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6206"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4206"]]
+4205=GEOGCS["Afgooye", DATUM["Afgooye", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-43.0, -163.0, 45.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6205"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4205"]]
+30792=PROJCS["Nord Sahara 1959 / Voirol Unifie Sud", GEOGCS["Nord Sahara 1959", DATUM["Nord Sahara 1959", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-152.9, 43.8, 358.3, 2.714, 1.386, -2.788, -6.743], AUTHORITY["EPSG","6307"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4307"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 2.7], PARAMETER["latitude_of_origin", 33.3], PARAMETER["scale_factor", 0.999625769], PARAMETER["false_easting", 500135.0], PARAMETER["false_northing", 300090.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30792"]]
+4204=GEOGCS["Ain el Abd", DATUM["Ain el Abd 1970", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-85.645, -273.077, -79.708, 2.289, 1.421, -2.532, 3.194], AUTHORITY["EPSG","6204"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4204"]]
+30791=PROJCS["Nord Sahara 1959 / Voirol Unifie Nord", GEOGCS["Nord Sahara 1959", DATUM["Nord Sahara 1959", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-152.9, 43.8, 358.3, 2.714, 1.386, -2.788, -6.743], AUTHORITY["EPSG","6307"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4307"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", 2.7], PARAMETER["latitude_of_origin", 36.0], PARAMETER["scale_factor", 0.999625544], PARAMETER["false_easting", 500135.0], PARAMETER["false_northing", 300090.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30791"]]
+4203=GEOGCS["AGD84", DATUM["Australian Geodetic Datum 1984", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-117.763, -51.51, 139.061, 0.292, -0.443, -0.277, -0.191], AUTHORITY["EPSG","6203"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4203"]]
+2029=PROJCS["NAD27(76) / UTM zone 17N", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2029"]]
+4202=GEOGCS["AGD66", DATUM["Australian Geodetic Datum 1966", SPHEROID["Australian National Spheroid", 6378160.0, 298.25, AUTHORITY["EPSG","7003"]], TOWGS84[-119.353, -48.301, 139.484, 0.415, -0.26, -0.437, -0.613], AUTHORITY["EPSG","6202"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4202"]]
+2028=PROJCS["NAD27(76) / UTM zone 16N", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2028"]]
+4201=GEOGCS["Adindan", DATUM["Adindan", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-165.0, -11.0, 206.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6201"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4201"]]
+28492=PROJCS["Pulkovo 1942 / Gauss-Kruger 32N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28492"]]
+2027=PROJCS["NAD27(76) / UTM zone 15N", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2027"]]
+4200=GEOGCS["Pulkovo 1995", DATUM["Pulkovo 1995", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.47, -130.89, -81.56, -0.0, 0.0, -0.13, -0.22], AUTHORITY["EPSG","6200"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4200"]]
+28491=PROJCS["Pulkovo 1942 / Gauss-Kruger 31N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28491"]]
+2026=PROJCS["NAD27(76) / MTM zone 17", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -96.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2026"]]
+28490=PROJCS["Pulkovo 1942 / Gauss-Kruger 30N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28490"]]
+2025=PROJCS["NAD27(76) / MTM zone 16", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2025"]]
+2024=PROJCS["NAD27(76) / MTM zone 15", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2024"]]
+2023=PROJCS["NAD27(76) / MTM zone 14", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2023"]]
+2022=PROJCS["NAD27(76) / MTM zone 13", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -84.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2022"]]
+2021=PROJCS["NAD27(76) / MTM zone 12", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2021"]]
+2020=PROJCS["NAD27(76) / MTM zone 11", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2020"]]
+66026405=GEOGCS["Dominica 1945 (deg)", DATUM["Dominica 1945", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[725.0, 685.0, 536.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6602"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66026405"]]
+61306405=GEOGCS["Moznet (deg)", DATUM["Moznet (ITRF94)", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6130"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61306405"]]
+28489=PROJCS["Pulkovo 1942 / Gauss-Kruger 29N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28489"]]
+28488=PROJCS["Pulkovo 1942 / Gauss-Kruger 28N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28488"]]
+28487=PROJCS["Pulkovo 1942 / Gauss-Kruger 27N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28487"]]
+28486=PROJCS["Pulkovo 1942 / Gauss-Kruger 26N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28486"]]
+28485=PROJCS["Pulkovo 1942 / Gauss-Kruger 25N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28485"]]
+28484=PROJCS["Pulkovo 1942 / Gauss-Kruger 24N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28484"]]
+2019=PROJCS["NAD27(76) / MTM zone 10", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2019"]]
+28483=PROJCS["Pulkovo 1942 / Gauss-Kruger 23N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28483"]]
+62256405=GEOGCS["Corrego Alegre (deg)", DATUM["Corrego Alegre 1970-72", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-206.0, 172.0, -6.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6225"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62256405"]]
+2018=PROJCS["NAD27(76) / MTM zone 9", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -76.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2018"]]
+28482=PROJCS["Pulkovo 1942 / Gauss-Kruger 22N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28482"]]
+2017=PROJCS["NAD27(76) / MTM zone 8", GEOGCS["NAD27(76)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4608"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -73.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2017"]]
+28481=PROJCS["Pulkovo 1942 / Gauss-Kruger 21N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28481"]]
+2016=PROJCS["NAD27(CGQ77) / SCoPQ zone 10", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2016"]]
+28480=PROJCS["Pulkovo 1942 / Gauss-Kruger 20N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28480"]]
+2015=PROJCS["NAD27(CGQ77) / SCoPQ zone 9", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -76.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2015"]]
+2014=PROJCS["NAD27(CGQ77) / SCoPQ zone 8", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -73.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2014"]]
+2013=PROJCS["NAD27(CGQ77) / SCoPQ zone 7", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -70.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2013"]]
+2012=PROJCS["NAD27(CGQ77) / SCoPQ zone 6", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -67.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2012"]]
+2011=PROJCS["NAD27(CGQ77) / SCoPQ zone 5", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -64.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2011"]]
+2010=PROJCS["NAD27(CGQ77) / SCoPQ zone 4", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -61.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2010"]]
+28479=PROJCS["Pulkovo 1942 / Gauss-Kruger 19N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28479"]]
+28478=PROJCS["Pulkovo 1942 / Gauss-Kruger 18N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28478"]]
+28477=PROJCS["Pulkovo 1942 / Gauss-Kruger 17N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28477"]]
+28476=PROJCS["Pulkovo 1942 / Gauss-Kruger 16N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28476"]]
+28475=PROJCS["Pulkovo 1942 / Gauss-Kruger 15N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28475"]]
+28474=PROJCS["Pulkovo 1942 / Gauss-Kruger 14N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28474"]]
+2009=PROJCS["NAD27(CGQ77) / SCoPQ zone 3", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -58.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2009"]]
+28473=PROJCS["Pulkovo 1942 / Gauss-Kruger 13N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28473"]]
+2008=PROJCS["NAD27(CGQ77) / SCoPQ zone 2", GEOGCS["NAD27(CGQ77)", DATUM["North American Datum 1927 (CGQ77)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6609"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4609"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -55.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 304800.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2008"]]
+28472=PROJCS["Pulkovo 1942 / Gauss-Kruger 12N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28472"]]
+2007=PROJCS["St. Vincent 45 / British West Indies Grid", GEOGCS["St. Vincent 1945", DATUM["St. Vincent 1945", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[195.671, 332.517, 274.607, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6607"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4607"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -62.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9995], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2007"]]
+28471=PROJCS["Pulkovo 1942 / Gauss-Kruger 11N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28471"]]
+2006=PROJCS["St. Lucia 1955 / British West Indies Grid", GEOGCS["St. Lucia 1955", DATUM["St. Lucia 1955", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-149.0, 128.0, 296.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6606"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4606"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -62.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9995], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2006"]]
+28470=PROJCS["Pulkovo 1942 / Gauss-Kruger 10N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28470"]]
+2005=PROJCS["St. Kitts 1955 / British West Indies Grid", GEOGCS["St. Kitts 1955", DATUM["St. Kitts 1955", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[9.0, 183.0, 236.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6605"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4605"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -62.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9995], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2005"]]
+2004=PROJCS["Montserrat 1958 / British West Indies Grid", GEOGCS["Montserrat 1958", DATUM["Montserrat 1958", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[174.0, 359.0, 365.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6604"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4604"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -62.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9995], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2004"]]
+2003=PROJCS["Grenada 1953 / British West Indies Grid", GEOGCS["Grenada 1953", DATUM["Grenada 1953", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[72.0, 213.7, 93.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6603"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4603"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -62.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9995], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2003"]]
+2002=PROJCS["Dominica 1945 / British West Indies Grid", GEOGCS["Dominica 1945", DATUM["Dominica 1945", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[725.0, 685.0, 536.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6602"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4602"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -62.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9995], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2002"]]
+2001=PROJCS["Antigua 1943 / British West Indies Grid", GEOGCS["Antigua 1943", DATUM["Antigua 1943", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-255.0, -15.0, 71.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6601"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4601"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -62.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9995], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2001"]]
+2000=PROJCS["Anguilla 1957 / British West Indies Grid", GEOGCS["Anguilla 1957", DATUM["Anguilla 1957", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6600"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4600"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -62.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9995], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","2000"]]
+28469=PROJCS["Pulkovo 1942 / Gauss-Kruger 9N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28469"]]
+28468=PROJCS["Pulkovo 1942 / Gauss-Kruger 8N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28468"]]
+28467=PROJCS["Pulkovo 1942 / Gauss-Kruger 7N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28467"]]
+28466=PROJCS["Pulkovo 1942 / Gauss-Kruger 6N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28466"]]
+28465=PROJCS["Pulkovo 1942 / Gauss-Kruger 5N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28465"]]
+28464=PROJCS["Pulkovo 1942 / Gauss-Kruger 4N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28464"]]
+28463=PROJCS["Pulkovo 1942 / Gauss-Kruger 3N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28463"]]
+28462=PROJCS["Pulkovo 1942 / Gauss-Kruger 2N", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28462"]]
+66576405=GEOGCS["Reykjavik 1900 (deg)", DATUM["Reykjavik 1900", SPHEROID["Danish 1876", 6377019.27, 300.0, AUTHORITY["EPSG","7051"]], TOWGS84[-28.0, 199.0, 5.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6657"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66576405"]]
+3799=PROJCS["NAD83(CSRS) / MTQ Lambert", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -70.0], PARAMETER["latitude_of_origin", 44.0], PARAMETER["standard_parallel_1", 50.0], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3799"]]
+3798=PROJCS["NAD83 / MTQ Lambert", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -70.0], PARAMETER["latitude_of_origin", 44.0], PARAMETER["standard_parallel_1", 50.0], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3798"]]
+3797=PROJCS["NAD27 / MTQ Lambert", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -70.0], PARAMETER["latitude_of_origin", 44.0], PARAMETER["standard_parallel_1", 50.0], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3797"]]
+3796=PROJCS["NAD27 / Cuba Sur", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -76.83333333333333], PARAMETER["latitude_of_origin", 20.716666666666665], PARAMETER["standard_parallel_1", 21.3], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 229126.939], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 20.133333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3796"]]
+3795=PROJCS["NAD27 / Cuba Norte", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 22.349999999999998], PARAMETER["standard_parallel_1", 23.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 280296.016], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 21.7], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3795"]]
+3794=PROJCS["Slovenia 1996 / Slovene National Grid", GEOGCS["Slovenia 1996", DATUM["Slovenia Geodetic Datum 1996", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6765"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4765"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3794"]]
+3793=PROJCS["NZGD2000 / Chatham Islands TM 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -176.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3793"]]
+3791=PROJCS["NZGD2000 / Raoul Island TM 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -178.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3791"]]
+3790=PROJCS["NZGD2000 / Antipodes Islands TM 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 179.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3790"]]
+3789=PROJCS["NZGD2000 / Campbell Island TM 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 169.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3789"]]
+3788=PROJCS["NZGD2000 / Auckland Islands TM 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 166.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3788"]]
+3787=PROJCS["MGI / Slovene National Grid", GEOGCS["MGI", DATUM["Militar-Geographische Institut", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[601.705, 84.263, 485.227, 4.7354, -1.3145, -5.393, -2.3887], AUTHORITY["EPSG","6312"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4312"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3787"]]
+3786=PROJCS["World Equidistant Cylindrical (Sphere)", GEOGCS["Unspecified datum based upon the GRS 1980 Authalic Sphere", DATUM["Not specified (based on GRS 1980 Authalic Sphere)", SPHEROID["GRS 1980 Authalic Sphere", 6371007.0, 0.0, AUTHORITY["EPSG","7048"]], AUTHORITY["EPSG","6047"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4047"]], PROJECTION["Equidistant Cylindrical (Spherical)", AUTHORITY["EPSG","9823"]], PARAMETER["central_meridian", 0.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 0.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3786"]]
+3785=PROJCS["Popular Visualisation CRS / Mercator", GEOGCS["Popular Visualisation CRS", DATUM["Popular Visualisation Datum", SPHEROID["Popular Visualisation Sphere", 6378137.0, 0.0, AUTHORITY["EPSG","7059"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6055"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4055"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9841"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3785"]]
+3784=PROJCS["Pitcairn 1967 / UTM zone 9S", GEOGCS["Pitcairn 1967", DATUM["Pitcairn 1967", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[185.0, 165.0, 42.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6729"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4729"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3784"]]
+3783=PROJCS["Pitcairn 2006 / Pitcairn TM 2006", GEOGCS["Pitcairn 2006", DATUM["Pitcairn 2006", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6763"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4763"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -130.11296711111112], PARAMETER["latitude_of_origin", -25.068552611111105], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 14200.0], PARAMETER["false_northing", 15500.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3783"]]
+3781=PROJCS["NAD83(CSRS) / Alberta 3TM ref merid 117 W", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3781"]]
+3780=PROJCS["NAD83(CSRS) / Alberta 3TM ref merid 114 W", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3780"]]
+30732=PROJCS["Nord Sahara 1959 / UTM zone 32N", GEOGCS["Nord Sahara 1959", DATUM["Nord Sahara 1959", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-152.9, 43.8, 358.3, 2.714, 1.386, -2.788, -6.743], AUTHORITY["EPSG","6307"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4307"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30732"]]
+30731=PROJCS["Nord Sahara 1959 / UTM zone 31N", GEOGCS["Nord Sahara 1959", DATUM["Nord Sahara 1959", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-152.9, 43.8, 358.3, 2.714, 1.386, -2.788, -6.743], AUTHORITY["EPSG","6307"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4307"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30731"]]
+30730=PROJCS["Nord Sahara 1959 / UTM zone 30N", GEOGCS["Nord Sahara 1959", DATUM["Nord Sahara 1959", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-152.9, 43.8, 358.3, 2.714, 1.386, -2.788, -6.743], AUTHORITY["EPSG","6307"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4307"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -3.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30730"]]
+28432=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 32", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 32500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28432"]]
+3779=PROJCS["NAD83(CSRS) / Alberta 3TM ref merid 111 W", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3779"]]
+28431=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 31", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 31500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28431"]]
+28430=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 30", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 30500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28430"]]
+3777=PROJCS["NAD83 / Alberta 3TM ref merid 117 W", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3777"]]
+3776=PROJCS["NAD83 / Alberta 3TM ref merid 114 W", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3776"]]
+3775=PROJCS["NAD83 / Alberta 3TM ref merid 111 W", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3775"]]
+3773=PROJCS["NAD27 / Alberta 3TM ref merid 117 W", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3773"]]
+3772=PROJCS["NAD27 / Alberta 3TM ref merid 114 W", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -114.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3772"]]
+3771=PROJCS["NAD27 / Alberta 3TM ref merid 111 W", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.685], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4267"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3771"]]
+3770=PROJCS["BDA2000 / Bermuda 2000 National Grid", GEOGCS["BDA2000", DATUM["Bermuda 2000", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6762"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4762"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -64.75], PARAMETER["latitude_of_origin", 32.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 550000.0], PARAMETER["false_northing", 100000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3770"]]
+68066405=GEOGCS["Monte Mario (Rome) (deg)", DATUM["Monte Mario (Rome)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6806"]], PRIMEM["Rome", 12.452333333333332, AUTHORITY["EPSG","8906"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","68066405"]]
+30729=PROJCS["Nord Sahara 1959 / UTM zone 29N", GEOGCS["Nord Sahara 1959", DATUM["Nord Sahara 1959", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-152.9, 43.8, 358.3, 2.714, 1.386, -2.788, -6.743], AUTHORITY["EPSG","6307"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4307"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","30729"]]
+28429=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 29", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 29500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28429"]]
+28428=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 28", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 28500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28428"]]
+28427=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 27", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 27500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28427"]]
+28426=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 26", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 26500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28426"]]
+28425=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 25", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 25500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28425"]]
+28424=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 24", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 24500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28424"]]
+28423=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 23", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 23500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28423"]]
+28422=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 22", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 22500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28422"]]
+3769=PROJCS["Bermuda 1957 / UTM zone 20N", GEOGCS["Bermuda 1957", DATUM["Bermuda 1957", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-292.295, 248.758, 429.447, 4.9971, -2.99, -6.6906, 1.0289], AUTHORITY["EPSG","6216"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4216"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3769"]]
+28421=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 21", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 21500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28421"]]
+3768=PROJCS["HTRS96 / UTM zone 34N", GEOGCS["HTRS96", DATUM["Croatian Terrestrial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6761"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4761"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3768"]]
+28420=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 20", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 20500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28420"]]
+3767=PROJCS["HTRS96 / UTM zone 33N", GEOGCS["HTRS96", DATUM["Croatian Terrestrial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6761"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4761"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3767"]]
+3766=PROJCS["HTRS96 / Croatia LCC", GEOGCS["HTRS96", DATUM["Croatian Terrestrial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6761"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4761"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", 16.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["standard_parallel_1", 45.91666666666667], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.083333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3766"]]
+3765=PROJCS["HTRS96 / Croatia TM", GEOGCS["HTRS96", DATUM["Croatian Terrestrial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6761"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4761"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 16.5], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3765"]]
+3764=PROJCS["NZGD2000 / Chatham Island Circuit 2000", GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -176.5], PARAMETER["latitude_of_origin", -44.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 800000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3764"]]
+3763=PROJCS["ETRS89 / Portugal TM06", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -8.133108333333334], PARAMETER["latitude_of_origin", 39.66825833333334], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3763"]]
+3762=PROJCS["WGS 84 / South Georgia Lambert", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -37.0], PARAMETER["latitude_of_origin", -55.0], PARAMETER["standard_parallel_1", -54.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", -54.75], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3762"]]
+3761=PROJCS["NAD83(CSRS) / UTM zone 22N", GEOGCS["NAD83(CSRS)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4617"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3761"]]
+3760=PROJCS["NAD83(HARN) / Hawaii zone 3 (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -158.0], PARAMETER["latitude_of_origin", 21.166666666666668], PARAMETER["scale_factor", 0.99999], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3760"]]
+28419=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 19", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 19500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28419"]]
+28418=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 18", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 18500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28418"]]
+28417=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 17", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 17500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28417"]]
+28416=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 16", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 16500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28416"]]
+28415=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 15", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 15500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28415"]]
+66416405=GEOGCS["IGN53 Mare (deg)", DATUM["IGN53 Mare", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[287.58, 177.78, -135.41, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6641"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66416405"]]
+28414=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 14", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 14500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28414"]]
+28413=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 13", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 13500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28413"]]
+28412=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 12", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 12500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28412"]]
+3759=PROJCS["NAD83 / Hawaii zone 3 (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -158.0], PARAMETER["latitude_of_origin", 21.166666666666668], PARAMETER["scale_factor", 0.99999], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3759"]]
+28411=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 11", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 63.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 11500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28411"]]
+3758=PROJCS["NAD83(HARN) / Wyoming West (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.08333333333333], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 328083.3333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3758"]]
+26237=PROJCS["Massawa / UTM zone 37N", GEOGCS["Massawa", DATUM["Massawa", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[639.0, 405.0, 60.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6262"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4262"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26237"]]
+28410=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 10", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 10500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28410"]]
+3757=PROJCS["NAD83(HARN) / Wyoming West Central (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -108.75], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3757"]]
+3756=PROJCS["NAD83(HARN) / Wyoming East Central (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.33333333333334], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 328083.3333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3756"]]
+20936=PROJCS["Arc 1950 / UTM zone 36S", GEOGCS["Arc 1950", DATUM["Arc 1950", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-138.0, -105.0, -289.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6209"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4209"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20936"]]
+3755=PROJCS["NAD83(HARN) / Wyoming East (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.16666666666666], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 656166.6667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3755"]]
+20935=PROJCS["Arc 1950 / UTM zone 35S", GEOGCS["Arc 1950", DATUM["Arc 1950", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-138.0, -105.0, -289.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6209"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4209"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20935"]]
+3754=PROJCS["NAD83(HARN) / Ohio South (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 38.0], PARAMETER["standard_parallel_1", 40.03333333333333], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.733333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3754"]]
+20934=PROJCS["Arc 1950 / UTM zone 34S", GEOGCS["Arc 1950", DATUM["Arc 1950", SPHEROID["Clarke 1880 (Arc)", 6378249.145, 293.4663077, AUTHORITY["EPSG","7013"]], TOWGS84[-138.0, -105.0, -289.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6209"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4209"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20934"]]
+3753=PROJCS["NAD83(HARN) / Ohio North (ftUS)", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 39.666666666666664], PARAMETER["standard_parallel_1", 41.7], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.43333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3753"]]
+3752=PROJCS["WGS 84 / Mercator 41", GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9804"]], PARAMETER["latitude_of_origin", -41.0], PARAMETER["central_meridian", 100.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3752"]]
+3751=PROJCS["NAD83(HARN) / UTM zone 5N", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3751"]]
+3750=PROJCS["NAD83(HARN) / UTM zone 4N", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3750"]]
+62646405=GEOGCS["Mhast (deg)", DATUM["Mhast", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-252.95, -4.11, -96.38, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6264"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62646405"]]
+28409=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 9", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 9500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28409"]]
+28408=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 8", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 8500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28408"]]
+28407=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 7", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 7500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28407"]]
+28406=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 6", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 33.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 6500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28406"]]
+28405=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 5", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 27.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 5500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28405"]]
+28404=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 4", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 21.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 4500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28404"]]
+28403=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 3", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28403"]]
+28402=PROJCS["Pulkovo 1942 / Gauss-Kruger zone 2", GEOGCS["Pulkovo 1942", DATUM["Pulkovo 1942", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-40.595, -18.55, -69.339, 2.508, -1.832, 2.611, -4.299], AUTHORITY["EPSG","6284"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4284"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 9.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28402"]]
+3749=PROJCS["NAD83(HARN) / UTM zone 19N", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3749"]]
+3748=PROJCS["NAD83(HARN) / UTM zone 18N", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3748"]]
+3747=PROJCS["NAD83(HARN) / UTM zone 17N", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3747"]]
+3746=PROJCS["NAD83(HARN) / UTM zone 16N", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3746"]]
+3745=PROJCS["NAD83(HARN) / UTM zone 15N", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3745"]]
+3744=PROJCS["NAD83(HARN) / UTM zone 14N", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3744"]]
+3743=PROJCS["NAD83(HARN) / UTM zone 13N", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3743"]]
+3742=PROJCS["NAD83(HARN) / UTM zone 12N", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3742"]]
+24048=PROJCS["Indian 1975 / UTM zone 48N", GEOGCS["Indian 1975", DATUM["Indian 1975", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[204.64, 834.74, 293.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6240"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4240"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24048"]]
+3741=PROJCS["NAD83(HARN) / UTM zone 11N", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3741"]]
+24047=PROJCS["Indian 1975 / UTM zone 47N", GEOGCS["Indian 1975", DATUM["Indian 1975", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[204.64, 834.74, 293.8, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6240"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4240"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","24047"]]
+3740=PROJCS["NAD83(HARN) / UTM zone 10N", GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3740"]]
+3739=PROJCS["NAD83 / Wyoming West (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.08333333333333], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 328083.3333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3739"]]
+3738=PROJCS["NAD83 / Wyoming West Central (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -108.75], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3738"]]
+3737=PROJCS["NAD83 / Wyoming East Central (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.33333333333334], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 328083.3333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3737"]]
+3736=PROJCS["NAD83 / Wyoming East (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.16666666666666], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 656166.6667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3736"]]
+3735=PROJCS["NAD83 / Ohio South (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 38.0], PARAMETER["standard_parallel_1", 40.03333333333333], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.733333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3735"]]
+3734=PROJCS["NAD83 / Ohio North (ftUS)", GEOGCS["NAD83", DATUM["North American Datum 1983", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4269"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 39.666666666666664], PARAMETER["standard_parallel_1", 41.7], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.43333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3734"]]
+3733=PROJCS["NAD83(NSRS2007) / Wyoming West (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.08333333333333], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 328083.3333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3733"]]
+3732=PROJCS["NAD83(NSRS2007) / Wyoming West Central (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -108.75], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3732"]]
+3731=PROJCS["NAD83(NSRS2007) / Wyoming East Central (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.33333333333334], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 1312333.3333], PARAMETER["false_northing", 328083.3333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3731"]]
+3730=PROJCS["NAD83(NSRS2007) / Wyoming East (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.16666666666666], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 656166.6667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3730"]]
+66086405=GEOGCS["NAD27(76) (deg)", DATUM["North American Datum 1927 (1976)", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6608"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66086405"]]
+61366405=GEOGCS["St. Lawrence Island (deg)", DATUM["St. Lawrence Island", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6136"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61366405"]]
+3729=PROJCS["NAD83(NSRS2007) / Ohio South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 38.0], PARAMETER["standard_parallel_1", 40.03333333333333], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.733333333333334], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3729"]]
+3728=PROJCS["NAD83(NSRS2007) / Ohio North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 39.666666666666664], PARAMETER["standard_parallel_1", 41.7], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.43333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3728"]]
+3727=PROJCS["Reunion 1947 / TM Reunion", GEOGCS["Reunion 1947", DATUM["Reunion 1947", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[94.0, -948.0, -1262.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6626"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4626"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 55.53333333333333], PARAMETER["latitude_of_origin", -21.116666666666667], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 160000.0], PARAMETER["false_northing", 50000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3727"]]
+3726=PROJCS["NAD83(NSRS2007) / UTM zone 19N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -69.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3726"]]
+3725=PROJCS["NAD83(NSRS2007) / UTM zone 18N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -75.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3725"]]
+3724=PROJCS["NAD83(NSRS2007) / UTM zone 17N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3724"]]
+3723=PROJCS["NAD83(NSRS2007) / UTM zone 16N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -87.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3723"]]
+3722=PROJCS["NAD83(NSRS2007) / UTM zone 15N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -93.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3722"]]
+3721=PROJCS["NAD83(NSRS2007) / UTM zone 14N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3721"]]
+3720=PROJCS["NAD83(NSRS2007) / UTM zone 13N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3720"]]
+3719=PROJCS["NAD83(NSRS2007) / UTM zone 12N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3719"]]
+3718=PROJCS["NAD83(NSRS2007) / UTM zone 11N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3718"]]
+3717=PROJCS["NAD83(NSRS2007) / UTM zone 10N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3717"]]
+3716=PROJCS["NAD83(NSRS2007) / UTM zone 9N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3716"]]
+3715=PROJCS["NAD83(NSRS2007) / UTM zone 8N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3715"]]
+3714=PROJCS["NAD83(NSRS2007) / UTM zone 7N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3714"]]
+3713=PROJCS["NAD83(NSRS2007) / UTM zone 6N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3713"]]
+3712=PROJCS["NAD83(NSRS2007) / UTM zone 5N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3712"]]
+3711=PROJCS["NAD83(NSRS2007) / UTM zone 4N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3711"]]
+3710=PROJCS["NAD83(NSRS2007) / UTM zone 3N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3710"]]
+3709=PROJCS["NAD83(NSRS2007) / UTM zone 2N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3709"]]
+3708=PROJCS["NAD83(NSRS2007) / UTM zone 1N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3708"]]
+3707=PROJCS["NAD83(NSRS2007) / UTM zone 60N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 177.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3707"]]
+3706=PROJCS["NAD83(NSRS2007) / UTM zone 59N", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 171.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3706"]]
+3705=PROJCS["NAD83(NSRS2007) / Wyoming West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -110.08333333333333], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 100000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3705"]]
+3704=PROJCS["NAD83(NSRS2007) / Wyoming West Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -108.75], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3704"]]
+3703=PROJCS["NAD83(NSRS2007) / Wyoming East Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.33333333333334], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 100000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3703"]]
+3702=PROJCS["NAD83(NSRS2007) / Wyoming East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -105.16666666666666], PARAMETER["latitude_of_origin", 40.5], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3702"]]
+3701=PROJCS["NAD83(NSRS2007) / Wisconsin Transverse Mercator", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 520000.0], PARAMETER["false_northing", -4480000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3701"]]
+3700=PROJCS["NAD83(NSRS2007) / Wisconsin South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 42.0], PARAMETER["standard_parallel_1", 44.06666666666666], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.73333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3700"]]
+61206405=GEOGCS["Greek (deg)", DATUM["Greek", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6120"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61206405"]]
+62156405=GEOGCS["Belge 1950 (deg)", DATUM["Reseau National Belge 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6215"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62156405"]]
+61756405=GEOGCS["Sierra Leone 1968 (deg)", DATUM["Sierra Leone 1968", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-88.0, 4.0, 101.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6175"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61756405"]]
+31171=PROJCS["Zanderij / Suriname TM", GEOGCS["Zanderij", DATUM["Zanderij", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-265.0, 120.0, -358.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6311"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4311"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -55.68333333333334], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31171"]]
+31170=PROJCS["Zanderij / Suriname Old TM", GEOGCS["Zanderij", DATUM["Zanderij", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-265.0, 120.0, -358.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6311"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4311"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -55.68333333333334], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31170"]]
+63246405=GEOGCS["WGS 72BE (deg)", DATUM["WGS 72 Transit Broadcast Ephemeris", SPHEROID["WGS 72", 6378135.0, 298.26, AUTHORITY["EPSG","7043"]], TOWGS84[0.0, 0.0, 1.9, 0.0, 0.0, 0.814, -0.38], AUTHORITY["EPSG","6324"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63246405"]]
+31154=PROJCS["Zanderij / TM 54 NW", GEOGCS["Zanderij", DATUM["Zanderij", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-265.0, 120.0, -358.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6311"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4311"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -54.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31154"]]
+4199=GEOGCS["Egypt 1930", DATUM["Egypt 1930", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6199"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4199"]]
+4198=GEOGCS["Kousseri", DATUM["Kousseri", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6198"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4198"]]
+4197=GEOGCS["Garoua", DATUM["Garoua", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], AUTHORITY["EPSG","6197"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4197"]]
+4196=GEOGCS["Ammassalik 1958", DATUM["Ammassalik 1958", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-45.0, 417.0, -3.5, 0.0, 0.0, 0.814, -0.6], AUTHORITY["EPSG","6196"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4196"]]
+4195=GEOGCS["Scoresbysund 1952", DATUM["Scoresbysund 1952", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[105.0, 326.0, -102.5, 0.0, 0.0, 0.814, -0.6], AUTHORITY["EPSG","6195"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4195"]]
+4194=GEOGCS["Qornoq 1927", DATUM["Qornoq 1927", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[163.511, 127.533, -159.789, 0.0, 0.0, 0.814, -0.6], AUTHORITY["EPSG","6194"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4194"]]
+4193=GEOGCS["Manoca 1962", DATUM["Manoca 1962", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-70.9, -151.8, -41.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6193"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4193"]]
+4192=GEOGCS["Douala 1948", DATUM["Douala 1948", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-206.1, -174.7, -87.7, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6192"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4192"]]
+4191=GEOGCS["Albanian 1987", DATUM["Albanian 1987", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], AUTHORITY["EPSG","6191"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4191"]]
+4190=GEOGCS["POSGAR 98", DATUM["Posiciones Geodesicas Argentinas 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6190"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4190"]]
+66316405=GEOGCS["K0 1949 (deg)", DATUM["K0 1949", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[145.0, -187.0, 103.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6631"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66316405"]]
+62546405=GEOGCS["Hito XVIII 1963 (deg)", DATUM["Hito XVIII 1963", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[18.38, 192.45, 96.82, 0.056, -0.142, -0.2, -0.0013], AUTHORITY["EPSG","6254"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62546405"]]
+4189=GEOGCS["REGVEN", DATUM["Red Geodesica Venezolana", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6189"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4189"]]
+4188=GEOGCS["OSNI 1952", DATUM["OSNI 1952", SPHEROID["Airy 1830", 6377563.396, 299.3249646, AUTHORITY["EPSG","7001"]], TOWGS84[482.5, -130.6, 564.6, -1.042, -0.214, -0.631, 8.15], AUTHORITY["EPSG","6188"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4188"]]
+4185=GEOGCS["Madeira 1936", DATUM["Madeira 1936", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6185"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4185"]]
+4184=GEOGCS["Azores Oriental 1940", DATUM["Azores Oriental Islands 1940", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-203.0, 141.0, 53.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6184"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4184"]]
+4183=GEOGCS["Azores Central 1948", DATUM["Azores Central Islands 1948", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-104.0, 167.0, -38.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6183"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4183"]]
+4182=GEOGCS["Azores Occidental 1939", DATUM["Azores Occidental Islands 1939", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-422.651, -172.995, 84.02, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6182"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4182"]]
+4181=GEOGCS["Luxembourg 1930", DATUM["Luxembourg 1930", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-189.6806, 18.3463, -42.7695, -0.33746, 3.09264, -2.53861, 0.4598], AUTHORITY["EPSG","6181"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4181"]]
+4180=GEOGCS["EST97", DATUM["Estonia 1997", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6180"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4180"]]
+4179=GEOGCS["Pulkovo 1942(58)", DATUM["Pulkovo 1942(58)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[33.4, -146.6, -76.3, -0.359, -0.053, 0.844, -0.84], AUTHORITY["EPSG","6179"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4179"]]
+4178=GEOGCS["Pulkovo 1942(83)", DATUM["Pulkovo 1942(83)", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[24.0, -123.0, -94.0, 0.02, 0.25, 0.13, 1.1], AUTHORITY["EPSG","6178"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4178"]]
+4176=GEOGCS["Australian Antarctic", DATUM["Australian Antarctic Datum 1998", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6176"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4176"]]
+4175=GEOGCS["Sierra Leone 1968", DATUM["Sierra Leone 1968", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-88.0, 4.0, 101.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6175"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4175"]]
+4174=GEOGCS["Sierra Leone 1924", DATUM["Sierra Leone Colony 1924", SPHEROID["War Office", 6378300.0, 296.0, AUTHORITY["EPSG","7029"]], AUTHORITY["EPSG","6174"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4174"]]
+61266413=GEOGCS["LKS94 (ETRS89) (3D deg)", DATUM["Lithuania 1994 (ETRS89)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6126"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","61266413"]]
+4173=GEOGCS["IRENET95", DATUM["IRENET95", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6173"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4173"]]
+4172=GEOGCS["POSGAR", DATUM["Posiciones Geodesicas Argentinas", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6172"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4172"]]
+4171=GEOGCS["RGF93", DATUM["Reseau Geodesique Francais 1993", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6171"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4171"]]
+4170=GEOGCS["SIRGAS 1995", DATUM["Sistema de Referencia Geocentrico para America del Sur 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6170"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4170"]]
+25700=PROJCS["Makassar (Jakarta) / NEIEZ", GEOGCS["Makassar (Jakarta)", DATUM["Makassar (Jakarta)", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6804"]], PRIMEM["Jakarta", 106.80771944444446, AUTHORITY["EPSG","8908"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4804"]], PROJECTION["Mercator_1SP", AUTHORITY["EPSG","9804"]], PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 110.0], PARAMETER["scale_factor", 0.997], PARAMETER["false_easting", 3900000.0], PARAMETER["false_northing", 900000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","25700"]]
+31121=PROJCS["Zanderij / UTM zone 21N", GEOGCS["Zanderij", DATUM["Zanderij", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-265.0, 120.0, -358.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6311"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4311"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -57.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","31121"]]
+4169=GEOGCS["American Samoa 1962", DATUM["American Samoa 1962", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-115.0, 118.0, 426.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6169"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4169"]]
+4168=GEOGCS["Accra", DATUM["Accra", SPHEROID["War Office", 6378300.0, 296.0, AUTHORITY["EPSG","7029"]], TOWGS84[-199.0, 32.0, 322.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6168"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4168"]]
+4167=GEOGCS["NZGD2000", DATUM["New Zealand Geodetic Datum 2000", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6167"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4167"]]
+4166=GEOGCS["Korean 1995", DATUM["Korean Datum 1995", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6166"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4166"]]
+61266405=GEOGCS["LKS94 (ETRS89) (deg)", DATUM["Lithuania 1994 (ETRS89)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6126"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61266405"]]
+4165=GEOGCS["Bissau", DATUM["Bissau", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-173.0, 253.0, 27.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6165"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4165"]]
+4164=GEOGCS["South Yemen", DATUM["South Yemen", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-76.0, -138.0, 67.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6164"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4164"]]
+4163=GEOGCS["Yemen NGN96", DATUM["Yemen National Geodetic Network 1996", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6163"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4163"]]
+4162=GEOGCS["Korean 1985", DATUM["Korean Datum 1985", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6162"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4162"]]
+4161=GEOGCS["Pampa del Castillo", DATUM["Pampa del Castillo", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[27.5, 14.0, 186.4, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6161"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4161"]]
+4160=GEOGCS["Chos Malal 1914", DATUM["Chos Malal 1914", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], AUTHORITY["EPSG","6160"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4160"]]
+4159=GEOGCS["ELD79", DATUM["European Libyan Datum 1979", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-113.997, -97.076, -152.312, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6159"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4159"]]
+4158=GEOGCS["Naparima 1955", DATUM["Naparima 1955", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-0.465, 372.095, 171.736, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6158"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4158"]]
+4157=GEOGCS["Mount Dillon", DATUM["Mount Dillon", SPHEROID["Clarke 1858", 6378293.645208759, 294.26067636926103, AUTHORITY["EPSG","7007"]], AUTHORITY["EPSG","6157"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4157"]]
+4156=GEOGCS["S-JTSK", DATUM["System Jednotne Trigonometricke Site Katastralni", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[572.213, 85.334, 461.94, 4.9732, -1.529, -5.2484, 3.5378], AUTHORITY["EPSG","6156"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4156"]]
+4155=GEOGCS["Dabola 1981", DATUM["Dabola 1981", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[-83.0, 37.0, 124.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6155"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4155"]]
+4154=GEOGCS["ED50(ED77)", DATUM["European Datum 1950(1977)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-123.02, -158.95, -168.47, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6154"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4154"]]
+4153=GEOGCS["Rassadiran", DATUM["Rassadiran", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-133.63, -157.5, -158.62, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6153"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4153"]]
+4152=GEOGCS["NAD83(HARN)", DATUM["NAD83 (High Accuracy Reference Network)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6152"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4152"]]
+4151=GEOGCS["CHTRF95", DATUM["Swiss Terrestrial Reference Frame 1995", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6151"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4151"]]
+4150=GEOGCS["CH1903+", DATUM["CH1903+", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[674.374, 15.056, 405.346, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6150"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4150"]]
+4149=GEOGCS["CH1903", DATUM["CH1903", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[674.4, 15.1, 405.3, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6149"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4149"]]
+4148=GEOGCS["Hartebeesthoek94", DATUM["Hartebeesthoek94", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6148"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4148"]]
+4147=GEOGCS["Hanoi 1972", DATUM["Hanoi 1972", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-17.51, -108.32, -62.39, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6147"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4147"]]
+4146=GEOGCS["Kalianpur 1975", DATUM["Kalianpur 1975", SPHEROID["Everest 1830 (1975 Definition)", 6377299.151, 300.8017255, AUTHORITY["EPSG","7045"]], TOWGS84[295.0, 736.0, 257.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6146"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4146"]]
+4145=GEOGCS["Kalianpur 1962", DATUM["Kalianpur 1962", SPHEROID["Everest 1830 (1962 Definition)", 6377301.243, 300.8017255, AUTHORITY["EPSG","7044"]], TOWGS84[275.57, 676.78, 229.6, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6145"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4145"]]
+4144=GEOGCS["Kalianpur 1937", DATUM["Kalianpur 1937", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[214.0, 804.0, 268.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6144"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4144"]]
+4143=GEOGCS["Abidjan 1987", DATUM["Abidjan 1987", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-124.76, 53.0, 466.79, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6143"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4143"]]
+4142=GEOGCS["Locodjo 1965", DATUM["Locodjo 1965", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-125.0, 53.0, 467.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6142"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4142"]]
+4141=GEOGCS["Israel", DATUM["Israel", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-48.0, 55.0, 52.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6141"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4141"]]
+4140=GEOGCS["NAD83(CSRS98)", DATUM["NAD83 Canadian Spatial Reference System", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-0.991, 1.9072, 0.5129, 0.0257899075194932, -0.009650098960270402, -0.011659943232342112, 0.0], AUTHORITY["EPSG","6140"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4140"]]
+4139=GEOGCS["Puerto Rico", DATUM["Puerto Rico", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[11.0, 72.0, -101.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6139"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4139"]]
+4138=GEOGCS["St. George Island", DATUM["St. George Island", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6138"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4138"]]
+4137=GEOGCS["St. Paul Island", DATUM["St. Paul Island", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6137"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4137"]]
+4136=GEOGCS["St. Lawrence Island", DATUM["St. Lawrence Island", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6136"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4136"]]
+4135=GEOGCS["Old Hawaiian", DATUM["Old Hawaiian", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[58.0, -283.0, -182.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6135"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4135"]]
+4134=GEOGCS["PSD93", DATUM["PDO Survey Datum 1993", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-180.624, -225.516, 173.919, -0.81, -1.898, 8.336, 16.71006], AUTHORITY["EPSG","6134"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4134"]]
+4133=GEOGCS["EST92", DATUM["Estonia 1992", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.055, -0.541, -0.185, 0.0183, 0.0003, 0.007, -0.014], AUTHORITY["EPSG","6133"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4133"]]
+4132=GEOGCS["FD58", DATUM["Final Datum 1958", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-239.1, -170.02, 397.5, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6132"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4132"]]
+4131=GEOGCS["Indian 1960", DATUM["Indian 1960", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[198.0, 881.0, 317.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6131"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4131"]]
+4130=GEOGCS["Moznet", DATUM["Moznet (ITRF94)", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], TOWGS84[0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6130"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4130"]]
+4129=GEOGCS["Observatario", DATUM["Observatario", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6129"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4129"]]
+4128=GEOGCS["Madzansua", DATUM["Madzansua", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], AUTHORITY["EPSG","6128"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4128"]]
+4127=GEOGCS["Tete", DATUM["Tete", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[-82.875, -57.097, -156.768, -2.158, -1.524, 0.982, -0.359], AUTHORITY["EPSG","6127"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4127"]]
+4126=GEOGCS["LKS94 (ETRS89)", DATUM["Lithuania 1994 (ETRS89)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6126"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4126"]]
+4125=GEOGCS["Samboja", DATUM["Samboja", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-404.78, 685.68, 45.47, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6125"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["DMS", 0.00000484813681109536], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4125"]]
+4124=GEOGCS["RT90", DATUM["Rikets koordinatsystem 1990", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[414.1, 41.3, 603.1, -0.855, -2.141, 7.023, 0.0], AUTHORITY["EPSG","6124"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4124"]]
+4123=GEOGCS["KKJ", DATUM["Kartastokoordinaattijarjestelma (1966)", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-96.062, -82.428, -121.753, 4.801, -0.345, 1.376, 1.496], AUTHORITY["EPSG","6123"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4123"]]
+4122=GEOGCS["ATS77", DATUM["Average Terrestrial System 1977", SPHEROID["Average Terrestrial System 1977", 6378135.0, 298.257, AUTHORITY["EPSG","7041"]], AUTHORITY["EPSG","6122"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4122"]]
+4121=GEOGCS["GGRS87", DATUM["Greek Geodetic Reference System 1987", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[-199.87, 74.79, 246.62, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6121"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4121"]]
+4120=GEOGCS["Greek", DATUM["Greek", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], AUTHORITY["EPSG","6120"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4120"]]
+62056405=GEOGCS["Afgooye (deg)", DATUM["Afgooye", SPHEROID["Krassowsky 1940", 6378245.0, 298.3, AUTHORITY["EPSG","7024"]], TOWGS84[-43.0, -163.0, 45.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6205"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62056405"]]
+62936405=GEOGCS["Schwarzeck (deg)", DATUM["Schwarzeck", SPHEROID["Bessel Namibia (GLM)", 6377483.865280419, 299.1528128, AUTHORITY["EPSG","7046"]], TOWGS84[616.0, 97.0, -251.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6293"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62936405"]]
+4100=COMPD_CS["ETRS89 / DKTM4 + DVR90 height", PROJCS["ETRS89 / DKTM4", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 15.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", -5000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","4096"]], VERT_CS["DVR90 height", VERT_DATUM["Dansk Vertikal Reference 1990", 2005, AUTHORITY["EPSG","5206"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5799"]], AUTHORITY["EPSG","4100"]]
+66376405=GEOGCS["Perroud 1950 (deg)", DATUM["Pointe Geologie Perroud 1950", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[325.0, 154.0, 172.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6637"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66376405"]]
+61656405=GEOGCS["Bissau (deg)", DATUM["Bissau", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-173.0, 253.0, 27.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6165"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","61656405"]]
+26195=PROJCS["Merchich / Sahara Sud", GEOGCS["Merchich", DATUM["Merchich", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[31.0, 146.0, 47.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6261"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4261"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -5.4], PARAMETER["latitude_of_origin", 22.5], PARAMETER["scale_factor", 0.999616437], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 400000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26195"]]
+26194=PROJCS["Merchich / Sahara Nord", GEOGCS["Merchich", DATUM["Merchich", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[31.0, 146.0, 47.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6261"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4261"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -5.4], PARAMETER["latitude_of_origin", 26.1], PARAMETER["scale_factor", 0.999616304], PARAMETER["false_easting", 1200000.0], PARAMETER["false_northing", 400000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26194"]]
+26193=PROJCS["Merchich / Sahara", GEOGCS["Merchich", DATUM["Merchich", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[31.0, 146.0, 47.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6261"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4261"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -5.4], PARAMETER["latitude_of_origin", 26.1], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 1200000.0], PARAMETER["false_northing", 400000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26193"]]
+26192=PROJCS["Merchich / Sud Maroc", GEOGCS["Merchich", DATUM["Merchich", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[31.0, 146.0, 47.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6261"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4261"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -5.4], PARAMETER["latitude_of_origin", 29.7], PARAMETER["scale_factor", 0.999615596], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26192"]]
+26191=PROJCS["Merchich / Nord Maroc", GEOGCS["Merchich", DATUM["Merchich", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], TOWGS84[31.0, 146.0, 47.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6261"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4261"]], PROJECTION["Lambert_Conformal_Conic_1SP", AUTHORITY["EPSG","9801"]], PARAMETER["central_meridian", -5.4], PARAMETER["latitude_of_origin", 33.3], PARAMETER["scale_factor", 0.999625769], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 300000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","26191"]]
+28358=PROJCS["GDA94 / MGA zone 58", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 165.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28358"]]
+28357=PROJCS["GDA94 / MGA zone 57", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 159.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28357"]]
+28356=PROJCS["GDA94 / MGA zone 56", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 153.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28356"]]
+28355=PROJCS["GDA94 / MGA zone 55", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 147.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28355"]]
+28354=PROJCS["GDA94 / MGA zone 54", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 141.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28354"]]
+63146405=GEOGCS["DHDN (deg)", DATUM["Deutsches Hauptdreiecksnetz", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[612.4, 77.0, 440.2, -0.054, 0.057, -2.797, 2.55], AUTHORITY["EPSG","6314"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","63146405"]]
+28353=PROJCS["GDA94 / MGA zone 53", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 135.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28353"]]
+28352=PROJCS["GDA94 / MGA zone 52", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 129.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28352"]]
+3699=PROJCS["NAD83(NSRS2007) / Wisconsin South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 42.0], PARAMETER["standard_parallel_1", 44.06666666666666], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.73333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3699"]]
+28351=PROJCS["GDA94 / MGA zone 51", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 123.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28351"]]
+3698=PROJCS["NAD83(NSRS2007) / Wisconsin North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 45.166666666666664], PARAMETER["standard_parallel_1", 46.766666666666666], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.56666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3698"]]
+28350=PROJCS["GDA94 / MGA zone 50", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 117.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28350"]]
+3697=PROJCS["NAD83(NSRS2007) / Wisconsin North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 45.166666666666664], PARAMETER["standard_parallel_1", 46.766666666666666], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.56666666666666], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3697"]]
+3696=PROJCS["NAD83(NSRS2007) / Wisconsin Central (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.5], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.25], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3696"]]
+3695=PROJCS["NAD83(NSRS2007) / Wisconsin Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -90.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.5], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3695"]]
+3694=PROJCS["NAD83(NSRS2007) / West Virginia South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 37.0], PARAMETER["standard_parallel_1", 38.88333333333333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.483333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3694"]]
+3693=PROJCS["NAD83(NSRS2007) / West Virginia North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.5], PARAMETER["latitude_of_origin", 38.5], PARAMETER["standard_parallel_1", 40.25], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3693"]]
+3692=PROJCS["NAD83(NSRS2007) / Washington South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 45.333333333333336], PARAMETER["standard_parallel_1", 47.33333333333333], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.833333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3692"]]
+3691=PROJCS["NAD83(NSRS2007) / Washington South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 45.333333333333336], PARAMETER["standard_parallel_1", 47.33333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.833333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3691"]]
+3690=PROJCS["NAD83(NSRS2007) / Washington North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.83333333333333], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.5], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3690"]]
+28349=PROJCS["GDA94 / MGA zone 49", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 111.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28349"]]
+28348=PROJCS["GDA94 / MGA zone 48", GEOGCS["GDA94", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4283"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", 105.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","28348"]]
+3689=PROJCS["NAD83(NSRS2007) / Washington North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.83333333333333], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3689"]]
+3688=PROJCS["NAD83(NSRS2007) / Virginia South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.96666666666667], PARAMETER["false_easting", 11482916.667], PARAMETER["false_northing", 3280833.333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.766666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3688"]]
+3687=PROJCS["NAD83(NSRS2007) / Virginia South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 36.333333333333336], PARAMETER["standard_parallel_1", 37.96666666666667], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 36.766666666666666], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3687"]]
+3686=PROJCS["NAD83(NSRS2007) / Virginia North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.199999999999996], PARAMETER["false_easting", 11482916.667], PARAMETER["false_northing", 6561666.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.03333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3686"]]
+3685=PROJCS["NAD83(NSRS2007) / Virginia North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -78.5], PARAMETER["latitude_of_origin", 37.666666666666664], PARAMETER["standard_parallel_1", 39.199999999999996], PARAMETER["false_easting", 3500000.0], PARAMETER["false_northing", 2000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.03333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3685"]]
+3684=PROJCS["NAD83(NSRS2007) / Vermont", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -72.5], PARAMETER["latitude_of_origin", 42.5], PARAMETER["scale_factor", 0.999964286], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3684"]]
+3683=PROJCS["NAD83(NSRS2007) / Utah South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.35], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 9842500.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.21666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3683"]]
+3682=PROJCS["NAD83(NSRS2007) / Utah South (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.35], PARAMETER["false_easting", 1640419.9480000003], PARAMETER["false_northing", 9842519.684999999], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.21666666666667], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3682"]]
+3681=PROJCS["NAD83(NSRS2007) / Utah South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 36.666666666666664], PARAMETER["standard_parallel_1", 38.35], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 3000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 37.21666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3681"]]
+3680=PROJCS["NAD83(NSRS2007) / Utah North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 40.333333333333336], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 3280833.3333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.71666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3680"]]
+66216405=GEOGCS["Fort Marigot (deg)", DATUM["Fort Marigot", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[137.0, 248.0, -430.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6621"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66216405"]]
+62446405=GEOGCS["Kandawala (deg)", DATUM["Kandawala", SPHEROID["Everest 1830 (1937 Adjustment)", 6377276.345, 300.8017, AUTHORITY["EPSG","7015"]], TOWGS84[-97.0, 787.0, 86.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6244"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62446405"]]
+3679=PROJCS["NAD83(NSRS2007) / Utah North (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 40.333333333333336], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 1640419.9480000003], PARAMETER["false_northing", 3280839.8950000005], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.71666666666667], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3679"]]
+3678=PROJCS["NAD83(NSRS2007) / Utah North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 40.333333333333336], PARAMETER["standard_parallel_1", 41.78333333333333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.71666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3678"]]
+3677=PROJCS["NAD83(NSRS2007) / Utah Central (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 40.65], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 6561666.6667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.016666666666666], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3677"]]
+3676=PROJCS["NAD83(NSRS2007) / Utah Central (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 40.65], PARAMETER["false_easting", 1640419.9480000003], PARAMETER["false_northing", 6561679.790000001], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.016666666666666], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3676"]]
+3675=PROJCS["NAD83(NSRS2007) / Utah Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -111.5], PARAMETER["latitude_of_origin", 38.333333333333336], PARAMETER["standard_parallel_1", 40.65], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 2000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.016666666666666], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3675"]]
+3674=PROJCS["NAD83(NSRS2007) / Texas South Central (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 27.833333333333332], PARAMETER["standard_parallel_1", 30.28333333333333], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 13123333.333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 28.383333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3674"]]
+3673=PROJCS["NAD83(NSRS2007) / Texas South Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -99.0], PARAMETER["latitude_of_origin", 27.833333333333332], PARAMETER["standard_parallel_1", 30.28333333333333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 4000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 28.383333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3673"]]
+3672=PROJCS["NAD83(NSRS2007) / Texas South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 25.666666666666668], PARAMETER["standard_parallel_1", 27.833333333333332], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 16404166.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 26.166666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3672"]]
+3671=PROJCS["NAD83(NSRS2007) / Texas South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 25.666666666666668], PARAMETER["standard_parallel_1", 27.833333333333332], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 5000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 26.166666666666664], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3671"]]
+3670=PROJCS["NAD83(NSRS2007) / Texas North Central (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 31.666666666666664], PARAMETER["standard_parallel_1", 33.96666666666667], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 6561666.667], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.13333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3670"]]
+3669=PROJCS["NAD83(NSRS2007) / Texas North Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.5], PARAMETER["latitude_of_origin", 31.666666666666664], PARAMETER["standard_parallel_1", 33.96666666666667], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 2000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.13333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3669"]]
+3668=PROJCS["NAD83(NSRS2007) / Texas North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -101.5], PARAMETER["latitude_of_origin", 34.0], PARAMETER["standard_parallel_1", 36.18333333333333], PARAMETER["false_easting", 656166.6669999999], PARAMETER["false_northing", 3280833.333], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.65], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3668"]]
+3667=PROJCS["NAD83(NSRS2007) / Texas North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -101.5], PARAMETER["latitude_of_origin", 34.0], PARAMETER["standard_parallel_1", 36.18333333333333], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 1000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.65], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3667"]]
+3666=PROJCS["NAD83(NSRS2007) / Texas Centric Lambert Conformal", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 18.0], PARAMETER["standard_parallel_1", 35.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 5000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 27.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3666"]]
+3665=PROJCS["NAD83(NSRS2007) / Texas Centric Albers Equal Area", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Albers_Conic_Equal_Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 18.0], PARAMETER["standard_parallel_1", 27.5], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 6000000.0], PARAMETER["standard_parallel_2", 35.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3665"]]
+3664=PROJCS["NAD83(NSRS2007) / Texas Central (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 29.666666666666668], PARAMETER["standard_parallel_1", 31.883333333333336], PARAMETER["false_easting", 2296583.333], PARAMETER["false_northing", 9842500.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 30.116666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3664"]]
+3663=PROJCS["NAD83(NSRS2007) / Texas Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 29.666666666666668], PARAMETER["standard_parallel_1", 31.883333333333336], PARAMETER["false_easting", 700000.0], PARAMETER["false_northing", 3000000.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 30.116666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3663"]]
+3662=PROJCS["NAD83(NSRS2007) / Tennessee (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -86.0], PARAMETER["latitude_of_origin", 34.333333333333336], PARAMETER["standard_parallel_1", 36.416666666666664], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.25], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3662"]]
+3661=PROJCS["NAD83(NSRS2007) / Tennessee", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -86.0], PARAMETER["latitude_of_origin", 34.333333333333336], PARAMETER["standard_parallel_1", 36.416666666666664], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.25], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3661"]]
+3660=PROJCS["NAD83(NSRS2007) / South Dakota South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 42.333333333333336], PARAMETER["standard_parallel_1", 44.4], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.833333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3660"]]
+3659=PROJCS["NAD83(NSRS2007) / South Dakota South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.33333333333333], PARAMETER["latitude_of_origin", 42.333333333333336], PARAMETER["standard_parallel_1", 44.4], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.833333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3659"]]
+3658=PROJCS["NAD83(NSRS2007) / South Dakota North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.68333333333334], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.416666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3658"]]
+3657=PROJCS["NAD83(NSRS2007) / South Dakota North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 43.833333333333336], PARAMETER["standard_parallel_1", 45.68333333333334], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.416666666666664], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3657"]]
+3656=PROJCS["NAD83(NSRS2007) / South Carolina (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 31.833333333333336], PARAMETER["standard_parallel_1", 34.833333333333336], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.5], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3656"]]
+3655=PROJCS["NAD83(NSRS2007) / South Carolina", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -81.0], PARAMETER["latitude_of_origin", 31.833333333333336], PARAMETER["standard_parallel_1", 34.833333333333336], PARAMETER["false_easting", 609600.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 32.5], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3655"]]
+3654=PROJCS["NAD83(NSRS2007) / Rhode Island (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.083333333333336], PARAMETER["scale_factor", 0.99999375], PARAMETER["false_easting", 328083.3333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3654"]]
+3653=PROJCS["NAD83(NSRS2007) / Rhode Island", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.5], PARAMETER["latitude_of_origin", 41.083333333333336], PARAMETER["scale_factor", 0.99999375], PARAMETER["false_easting", 100000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3653"]]
+3652=PROJCS["NAD83(NSRS2007) / Pennsylvania South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.96666666666667], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.93333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3652"]]
+3651=PROJCS["NAD83(NSRS2007) / Pennsylvania South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 39.333333333333336], PARAMETER["standard_parallel_1", 40.96666666666667], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 39.93333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3651"]]
+3650=PROJCS["NAD83(NSRS2007) / Pennsylvania North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 40.166666666666664], PARAMETER["standard_parallel_1", 41.95], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.88333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3650"]]
+3649=PROJCS["NAD83(NSRS2007) / Pennsylvania North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -77.75], PARAMETER["latitude_of_origin", 40.166666666666664], PARAMETER["standard_parallel_1", 41.95], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.88333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3649"]]
+3648=PROJCS["NAD83(NSRS2007) / Oregon South (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["standard_parallel_1", 44.0], PARAMETER["false_easting", 4921259.843000001], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.333333333333336], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3648"]]
+3647=PROJCS["NAD83(NSRS2007) / Oregon South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 41.666666666666664], PARAMETER["standard_parallel_1", 44.0], PARAMETER["false_easting", 1500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 42.333333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3647"]]
+3646=PROJCS["NAD83(NSRS2007) / Oregon North (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["standard_parallel_1", 46.0], PARAMETER["false_easting", 8202099.738], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.33333333333333], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3646"]]
+3645=PROJCS["NAD83(NSRS2007) / Oregon North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 43.666666666666664], PARAMETER["standard_parallel_1", 46.0], PARAMETER["false_easting", 2500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 44.33333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3645"]]
+3644=PROJCS["NAD83(NSRS2007) / Oregon Lambert (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 41.75], PARAMETER["standard_parallel_1", 45.5], PARAMETER["false_easting", 1312335.9580000003], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3644"]]
+20824=PROJCS["Aratu / UTM zone 24S", GEOGCS["Aratu", DATUM["Aratu", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-151.99, 287.04, -147.45, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6208"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4208"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -39.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20824"]]
+62996405=GEOGCS["TM65 (deg)", DATUM["TM65", SPHEROID["Airy Modified 1849", 6377340.189, 299.3249646, AUTHORITY["EPSG","7002"]], TOWGS84[482.5, -130.6, 564.6, -1.042, -0.214, -0.631, 8.15], AUTHORITY["EPSG","6299"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62996405"]]
+3643=PROJCS["NAD83(NSRS2007) / Oregon Lambert", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -120.5], PARAMETER["latitude_of_origin", 41.75], PARAMETER["standard_parallel_1", 45.5], PARAMETER["false_easting", 400000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 43.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3643"]]
+20823=PROJCS["Aratu / UTM zone 23S", GEOGCS["Aratu", DATUM["Aratu", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-151.99, 287.04, -147.45, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6208"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4208"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -45.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20823"]]
+3642=PROJCS["NAD83(NSRS2007) / Oklahoma South (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 33.333333333333336], PARAMETER["standard_parallel_1", 35.233333333333334], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.93333333333333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3642"]]
+20822=PROJCS["Aratu / UTM zone 22S", GEOGCS["Aratu", DATUM["Aratu", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[-151.99, 287.04, -147.45, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6208"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4208"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -51.0], PARAMETER["latitude_of_origin", 0.0], PARAMETER["scale_factor", 0.9996], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 10000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","20822"]]
+3641=PROJCS["NAD83(NSRS2007) / Oklahoma South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 33.333333333333336], PARAMETER["standard_parallel_1", 35.233333333333334], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 33.93333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3641"]]
+3640=PROJCS["NAD83(NSRS2007) / Oklahoma North (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 35.0], PARAMETER["standard_parallel_1", 36.766666666666666], PARAMETER["false_easting", 1968500.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.56666666666667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3640"]]
+5817=LOCAL_CS["Tombak LNG plant", LOCAL_DATUM["Tombak LNG plant", 0, AUTHORITY["EPSG","9314"]], UNIT["m", 1.0], AXIS["Plant East", NORTH_EAST], AXIS["Plant North", NORTH_WEST], AUTHORITY["EPSG","5817"]]
+5816=LOCAL_CS["Barinas west base", LOCAL_DATUM["Barinas west base", 0, AUTHORITY["EPSG","9311"]], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5816"]]
+5815=LOCAL_CS["Santa Maria de Ipire", LOCAL_DATUM["Santa Maria de Ipire", 0, AUTHORITY["EPSG","9310"]], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5815"]]
+5814=LOCAL_CS["Tucupita", LOCAL_DATUM["Tucupita", 0, AUTHORITY["EPSG","9308"]], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5814"]]
+5813=LOCAL_CS["Dabajuro", LOCAL_DATUM["Dabajuro", 0, AUTHORITY["EPSG","9307"]], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5813"]]
+3639=PROJCS["NAD83(NSRS2007) / Oklahoma North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -98.0], PARAMETER["latitude_of_origin", 35.0], PARAMETER["standard_parallel_1", 36.766666666666666], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 35.56666666666667], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3639"]]
+5812=LOCAL_CS["El Cubo", LOCAL_DATUM["El Cubo", 0, AUTHORITY["EPSG","9306"]], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5812"]]
+3638=PROJCS["NAD83(NSRS2007) / Ohio South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 38.0], PARAMETER["standard_parallel_1", 40.03333333333333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 38.733333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3638"]]
+5811=LOCAL_CS["Mene Grande", LOCAL_DATUM["Mene Grande", 0, AUTHORITY["EPSG","9305"]], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5811"]]
+3637=PROJCS["NAD83(NSRS2007) / Ohio North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -82.5], PARAMETER["latitude_of_origin", 39.666666666666664], PARAMETER["standard_parallel_1", 41.7], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.43333333333333], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3637"]]
+5810=LOCAL_CS["La Rosa Grid", LOCAL_DATUM["La Rosa", 0, AUTHORITY["EPSG","9304"]], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5810"]]
+3636=PROJCS["NAD83(NSRS2007) / North Dakota South (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 45.666666666666664], PARAMETER["standard_parallel_1", 47.483333333333334], PARAMETER["false_easting", 1968503.937], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.18333333333334], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3636"]]
+3635=PROJCS["NAD83(NSRS2007) / North Dakota South", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 45.666666666666664], PARAMETER["standard_parallel_1", 47.483333333333334], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 46.18333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3635"]]
+3634=PROJCS["NAD83(NSRS2007) / North Dakota North (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 1968503.937], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.43333333333334], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3634"]]
+3633=PROJCS["NAD83(NSRS2007) / North Dakota North", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.5], PARAMETER["latitude_of_origin", 47.0], PARAMETER["standard_parallel_1", 48.73333333333333], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 47.43333333333334], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3633"]]
+3632=PROJCS["NAD83(NSRS2007) / North Carolina (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.0], PARAMETER["latitude_of_origin", 33.75], PARAMETER["standard_parallel_1", 36.166666666666664], PARAMETER["false_easting", 2000000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.333333333333336], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3632"]]
+3631=PROJCS["NAD83(NSRS2007) / North Carolina", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -79.0], PARAMETER["latitude_of_origin", 33.75], PARAMETER["standard_parallel_1", 36.166666666666664], PARAMETER["false_easting", 609601.22], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 34.333333333333336], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3631"]]
+3630=PROJCS["NAD83(NSRS2007) / New York West (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -78.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 1148291.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3630"]]
+5809=LOCAL_CS["Maracaibo Cross Grid M5", LOCAL_DATUM["Maracaibo Cross", 0, AUTHORITY["EPSG","9303"]], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5809"]]
+5808=LOCAL_CS["Maracaibo Cross Grid M4", LOCAL_DATUM["Maracaibo Cross", 0, AUTHORITY["EPSG","9303"]], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5808"]]
+5807=LOCAL_CS["EPSG local engineering grid example B", LOCAL_DATUM["EPSG example Platform Y", 0, AUTHORITY["EPSG","9313"]], UNIT["m", 1.0], AXIS["Plant East", NORTH_EAST], AXIS["Plant North", NORTH_WEST], AUTHORITY["EPSG","5807"]]
+5806=LOCAL_CS["EPSG local engineering grid example A", LOCAL_DATUM["EPSG example Platform Y", 0, AUTHORITY["EPSG","9313"]], UNIT["m", 1.0], AXIS["Second local axis", NORTH_EAST], AXIS["First local axis", NORTH_WEST], AUTHORITY["EPSG","5806"]]
+5803=LOCAL_CS["Maturin Grid", LOCAL_DATUM["Maturin", 0, AUTHORITY["EPSG","9302"]], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5803"]]
+3629=PROJCS["NAD83(NSRS2007) / New York West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -78.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 350000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3629"]]
+5802=LOCAL_CS["Barcelona Grid B2", LOCAL_DATUM["Barcelona", 0, AUTHORITY["EPSG","9301"]], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5802"]]
+3628=PROJCS["NAD83(NSRS2007) / New York Long Island (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -74.0], PARAMETER["latitude_of_origin", 40.166666666666664], PARAMETER["standard_parallel_1", 41.03333333333333], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.666666666666664], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3628"]]
+5801=LOCAL_CS["Barcelona Grid B1", LOCAL_DATUM["Barcelona", 0, AUTHORITY["EPSG","9301"]], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","5801"]]
+3627=PROJCS["NAD83(NSRS2007) / New York Long Island", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -74.0], PARAMETER["latitude_of_origin", 40.166666666666664], PARAMETER["standard_parallel_1", 41.03333333333333], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.666666666666664], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3627"]]
+5800=LOCAL_CS["Astra Minas Grid", LOCAL_DATUM["Astra Minas", 0, AUTHORITY["EPSG","9300"]], UNIT["m", 1.0], AXIS["Second local axis", WEST], AXIS["First local axis", NORTH], AUTHORITY["EPSG","5800"]]
+3626=PROJCS["NAD83(NSRS2007) / New York East (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.5], PARAMETER["latitude_of_origin", 38.833333333333336], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 492125.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3626"]]
+3625=PROJCS["NAD83(NSRS2007) / New York East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.5], PARAMETER["latitude_of_origin", 38.833333333333336], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3625"]]
+3624=PROJCS["NAD83(NSRS2007) / New York Central (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -76.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 820208.333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3624"]]
+3623=PROJCS["NAD83(NSRS2007) / New York Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -76.58333333333333], PARAMETER["latitude_of_origin", 40.0], PARAMETER["scale_factor", 0.9999375], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3623"]]
+3622=PROJCS["NAD83(NSRS2007) / New Mexico West (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.83333333333334], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999916667], PARAMETER["false_easting", 2723091.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3622"]]
+3621=PROJCS["NAD83(NSRS2007) / New Mexico West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -107.83333333333334], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999916667], PARAMETER["false_easting", 830000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3621"]]
+3620=PROJCS["NAD83(NSRS2007) / New Mexico East (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -104.33333333333333], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999909091], PARAMETER["false_easting", 541337.5], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3620"]]
+3619=PROJCS["NAD83(NSRS2007) / New Mexico East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -104.33333333333333], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.999909091], PARAMETER["false_easting", 165000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3619"]]
+3618=PROJCS["NAD83(NSRS2007) / New Mexico Central (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -106.25], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 1640416.667], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3618"]]
+3617=PROJCS["NAD83(NSRS2007) / New Mexico Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -106.25], PARAMETER["latitude_of_origin", 31.0], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3617"]]
+3616=PROJCS["NAD83(NSRS2007) / New Jersey (ft US)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.5], PARAMETER["latitude_of_origin", 38.833333333333336], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 492125.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3616"]]
+3615=PROJCS["NAD83(NSRS2007) / New Jersey", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -74.5], PARAMETER["latitude_of_origin", 38.833333333333336], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 150000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3615"]]
+3614=PROJCS["NAD83(NSRS2007) / New Hampshire (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.66666666666667], PARAMETER["latitude_of_origin", 42.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 984250.0], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3614"]]
+3613=PROJCS["NAD83(NSRS2007) / New Hampshire", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -71.66666666666667], PARAMETER["latitude_of_origin", 42.5], PARAMETER["scale_factor", 0.999966667], PARAMETER["false_easting", 300000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3613"]]
+3612=PROJCS["NAD83(NSRS2007) / Nevada West (ft US)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -118.58333333333333], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 2624666.6667], PARAMETER["false_northing", 13123333.3333], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3612"]]
+3611=PROJCS["NAD83(NSRS2007) / Nevada West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -118.58333333333333], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 800000.0], PARAMETER["false_northing", 4000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3611"]]
+3610=PROJCS["NAD83(NSRS2007) / Nevada East (ft US)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.58333333333334], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 656166.6667], PARAMETER["false_northing", 26246666.6667], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3610"]]
+62836413=GEOGCS["GDA94 (3D deg)", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AXIS["Ellipsoidal height", UP], AUTHORITY["EPSG","62836413"]]
+66606405=GEOGCS["Helle 1954 (deg)", DATUM["Helle 1954", SPHEROID["International 1924", 6378388.0, 297.0, AUTHORITY["EPSG","7022"]], TOWGS84[982.6087, 552.753, -540.873, 6.681626625276941, -31.61149240864225, -19.848161004816845, 16.805], AUTHORITY["EPSG","6660"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","66606405"]]
+3609=PROJCS["NAD83(NSRS2007) / Nevada East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -115.58333333333334], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 200000.0], PARAMETER["false_northing", 8000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3609"]]
+3608=PROJCS["NAD83(NSRS2007) / Nevada Central (ft US)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -116.66666666666667], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 1640416.6667], PARAMETER["false_northing", 19685000.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3608"]]
+3607=PROJCS["NAD83(NSRS2007) / Nevada Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -116.66666666666667], PARAMETER["latitude_of_origin", 34.75], PARAMETER["scale_factor", 0.9999], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 6000000.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3607"]]
+3606=PROJCS["NAD83(NSRS2007) / Nebraska", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -100.0], PARAMETER["latitude_of_origin", 39.833333333333336], PARAMETER["standard_parallel_1", 43.0], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 40.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3606"]]
+3605=PROJCS["NAD83(NSRS2007) / Montana (ft)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -109.5], PARAMETER["latitude_of_origin", 44.25], PARAMETER["standard_parallel_1", 49.0], PARAMETER["false_easting", 1968503.937], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.0], UNIT["ft", 0.3048], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3605"]]
+3604=PROJCS["NAD83(NSRS2007) / Montana", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Lambert_Conformal_Conic_2SP", AUTHORITY["EPSG","9802"]], PARAMETER["central_meridian", -109.5], PARAMETER["latitude_of_origin", 44.25], PARAMETER["standard_parallel_1", 49.0], PARAMETER["false_easting", 600000.0], PARAMETER["false_northing", 0.0], PARAMETER["scale_factor", 1.0], PARAMETER["standard_parallel_2", 45.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3604"]]
+3603=PROJCS["NAD83(NSRS2007) / Missouri West", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -94.5], PARAMETER["latitude_of_origin", 36.166666666666664], PARAMETER["scale_factor", 0.999941177], PARAMETER["false_easting", 850000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3603"]]
+3602=PROJCS["NAD83(NSRS2007) / Missouri East", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.5], PARAMETER["latitude_of_origin", 35.833333333333336], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 250000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3602"]]
+3601=PROJCS["NAD83(NSRS2007) / Missouri Central", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -92.5], PARAMETER["latitude_of_origin", 35.833333333333336], PARAMETER["scale_factor", 0.999933333], PARAMETER["false_easting", 500000.0], PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3601"]]
+3600=PROJCS["NAD83(NSRS2007) / Mississippi West (ftUS)", GEOGCS["NAD83(NSRS2007)", DATUM["NAD83 (National Spatial Reference System 2007)", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6759"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4759"]], PROJECTION["Transverse_Mercator", AUTHORITY["EPSG","9807"]], PARAMETER["central_meridian", -90.33333333333333], PARAMETER["latitude_of_origin", 29.5], PARAMETER["scale_factor", 0.99995], PARAMETER["false_easting", 2296583.333], PARAMETER["false_northing", 0.0], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Easting", EAST], AXIS["Northing", NORTH], AUTHORITY["EPSG","3600"]]
+62836405=GEOGCS["GDA94 (deg)", DATUM["Geocentric Datum of Australia 1994", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6283"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","62836405"]]
+#Extra Definitions Supplied from Community
+#Sun Oct 16 14:49:47 CEST 2011
+23433=PROJCS["Garoua / UTM zone 33N",GEOGCS["Garoua",DATUM["Garoua",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],AUTHORITY["EPSG","6234"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4234"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",15],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","23433"]]
+22832=PROJCS["Douala / UTM zone 32N",GEOGCS["Douala",DATUM["Douala",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],AUTHORITY["EPSG","6228"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4228"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",9],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","22832"]]
+2982=PROJCS["IGN72 Grand Terre / UTM zone 58S",GEOGCS["IGN72 Grand Terre",DATUM["IGN72_Grande_Terre",SPHEROID["International 1924",6378388,297,AUTHORITY["EPSG","7022"]],AUTHORITY["EPSG","6634"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4634"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",165],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2982"]]
+100002=PROJCS["NAD83 / Austin",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",31.8833333333333],PARAMETER["standard_parallel_2",30.1166666666667],PARAMETER["latitude_of_origin",29.6666666666667],PARAMETER["central_meridian",-100.333333333333],PARAMETER["false_easting",2296583.333333],PARAMETER["false_northing",9842500.0000000],UNIT["Meter",1],AUTHORITY["EPSG","100002"]]
+100001=GEOGCS["NAD83 / NFIS Seconds",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Second",4.84813681109536e-06],AUTHORITY["EPSG","100001"]]
+42311=PROJCS["NAD83 / LCC Statcan",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-91.866667],PARAMETER["latitude_of_origin",63.390675],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",77],PARAMETER["false_easting",6200000],PARAMETER["false_northing",3000000],UNIT["Meter",1],AUTHORITY["EPSG","42311"]]
+42310=PROJCS["WGS84+GRS80 / Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1],AUTHORITY["EPSG","42310"]]
+42309=PROJCS["NAD 83 / LCC Canada AVHRR-2",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],PARAMETER["false_easting",0.0],PARAMETER["false_northing",0.0],UNIT["Meter",1],AUTHORITY["EPSG","42309"]]
+42308=PROJCS["NAD27 / California Albers",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.978698213901],TOWGS84[-9,151,185]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Albers_conic_equal_area"],PARAMETER["central_meridian",-120.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",34],PARAMETER["standard_parallel_2",40.5],PARAMETER["false_easting",0],PARAMETER["false_northing",-4000000],UNIT["Meter",1],AUTHORITY["EPSG","42308"]]
+42307=PROJCS["NAD83 / Texas Central - feet",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",31.8833333333333],PARAMETER["standard_parallel_2",30.1166666666667],PARAMETER["latitude_of_origin",29.6666666666667],PARAMETER["central_meridian",-100.333333333333],PARAMETER["false_easting",2296583.33333333333333],PARAMETER["false_northing",9842500],UNIT["US_Foot",0.30480060960121924],AUTHORITY["EPSG","42307"]]
+42306=PROJCS["NAD83/QC_LCC",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-68.5],PARAMETER["latitude_of_origin",44],PARAMETER["standard_parallel_1",46],PARAMETER["standard_parallel_2",60],PARAMETER["false_easting",0.0],PARAMETER["false_northing",0.0],UNIT["Meter",1],AUTHORITY["EPSG","42306"]]
+42305=PROJCS["France_II",GEOGCS["GCS_NTF_Paris",DATUM["Nouvelle_Triangulation_Francaise",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Paris",2.337229166666667],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["False_Easting",600000],PARAMETER["False_Northing",2200000],PARAMETER["Central_Meridian",0],PARAMETER["Standard_Parallel_1",45.898918964419],PARAMETER["Standard_Parallel_2",47.696014502038],PARAMETER["Latitude_Of_Origin",46.8],UNIT["Meter",1],AUTHORITY["EPSG","42305"]]
+42304=PROJCS["NAD83 / NRCan LCC Canada",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",49.0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],PARAMETER["false_easting",0.0],PARAMETER["false_northing",0.0],UNIT["Meter",1],AUTHORITY["EPSG","42304"]]
+42303=PROJCS["NAD83 / Albers NorthAm",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Albers_conic_equal_area"],PARAMETER["central_meridian",-96.0],PARAMETER["latitude_of_origin",23],PARAMETER["standard_parallel_1",29.5],PARAMETER["standard_parallel_2",45.5],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1],AUTHORITY["EPSG","42303"]]
+42302=PROJCS["JapanOrtho.09 09",GEOGCS["Lon/Lat.Tokyo Datum",DATUM["Tokyo Datum",SPHEROID["anon",6377397.155,299.15281310608]],PRIMEM["Greenwich",0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",139.833333333333],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Latitude_of_Origin",36],PARAMETER["Scale_Factor",0.9999],UNIT["Meter",1],AUTHORITY["EPSG","42302"]]
+42301=PROJCS["NAD27 / Polar Stereographic / CM\=-98",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.978698213901],TOWGS84[-9,151,185]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Stereographic"],PARAMETER["latitude_of_origin",90],PARAMETER["central_meridian",-98.0],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1],AUTHORITY["EPSG","42301"]]
+22700=PROJCS["Deir ez Zor / Levant Zone",GEOGCS["Deir ez Zor",DATUM["Deir_ez_Zor",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],AUTHORITY["EPSG","6227"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4227"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",34.65],PARAMETER["central_meridian",37.35],PARAMETER["scale_factor",0.9996256],PARAMETER["false_easting",300000],PARAMETER["false_northing",300000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","22700"]]
+104305=GEOGCS["GCS_Voirol_Unifie_1960_Degree",DATUM["D_Voirol_Unifie_1960",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295],AUTHORITY["ESRI","104305"]]
+104304=GEOGCS["GCS_Voirol_1875_Degree",DATUM["D_Voirol_1875",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295],AUTHORITY["ESRI","104304"]]
+104261=GEOGCS["GCS_Merchich_Degree",DATUM["D_Merchich",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295],AUTHORITY["ESRI","104261"]]
+29636=PROJCS["Sudan / UTM zone 36N",GEOGCS["Sudan",DATUM["Sudan",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],AUTHORITY["EPSG","6296"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4296"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",33],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29636"]]
+29635=PROJCS["Sudan / UTM zone 35N",GEOGCS["Sudan",DATUM["Sudan",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936269,AUTHORITY["EPSG","7011"]],AUTHORITY["EPSG","6296"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4296"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",27],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29635"]]
+42105=PROJCS["WGS84 / Merc NorthAm",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",-96],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1],AUTHORITY["EPSG","42105"]]
+42104=PROJCS["NAD83 / MTM zone 8 Qu?bec",GEOGCS["GRS80",DATUM["GRS_1980",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-73.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],PARAMETER["false_northing",0],UNIT["Meter",1],AUTHORITY["EPSG","42104"]]
+42103=PROJCS["WGS 84 / LCC USA",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1978",6378135,298.26]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-100.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",33.0],PARAMETER["standard_parallel_2",45.0],PARAMETER["false_easting",0.0],PARAMETER["false_northing",0.0],UNIT["Meter",1],AUTHORITY["EPSG","42103"]]
+42102=PROJCS["BC_Albers",GEOGCS["GCS_North_American_1983",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Albers_Conic_Equal_Area"],PARAMETER["False_Easting",1000000],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",-126],PARAMETER["Standard_Parallel_1",50],PARAMETER["Standard_Parallel_2",58.5],PARAMETER["Latitude_Of_Origin",45],UNIT["Meter",1],AUTHORITY["EPSG","42102"]]
+18001=PROJCS["Geoscience Australia Standard National Scale Lambert Projection",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1978",6378135,298.26],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",134.0],PARAMETER["latitude_of_origin",0.0],PARAMETER["standard_parallel_1",-18.0],PARAMETER["standard_parallel_2",-36.0],PARAMETER["false_easting",0.0],PARAMETER["false_northing",0.0],UNIT["Meter",1],AUTHORITY["EPSG","18001"]]
+104108=GEOGCS["GCS_NZGD_2000",DATUM["D_NZGD_2000",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295],AUTHORITY["ESRI","104108"]]
+104107=GEOGCS["GCS_RGF_1993",DATUM["D_RGF_1993",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295],AUTHORITY["ESRI","104107"]]
+104106=GEOGCS["GCS_Datum_Lisboa_Hayford",DATUM["D_Datum_Lisboa_Hayford",SPHEROID["International_1924",6378388,297]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295],AUTHORITY["ESRI","104106"]]
+104105=GEOGCS["GCS_Datum_Lisboa_Bessel",DATUM["D_Datum_Lisboa_Bessel",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295],AUTHORITY["ESRI","104105"]]
+104104=GEOGCS["GCS_Hong_Kong_1980",DATUM["D_Hong_Kong_1980",SPHEROID["International_1924",6378388,297]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295],AUTHORITY["ESRI","104104"]]
+104103=GEOGCS["GCS_Sierra_Leone_1960",DATUM["D_Sierra_Leone_1960",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295],AUTHORITY["ESRI","104103"]]
+104102=GEOGCS["GCS_Hermannskogel",DATUM["D_Hermannskogel",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295],AUTHORITY["ESRI","104102"]]
+104101=GEOGCS["GCS_Estonia_1937",DATUM["D_Estonia_1937",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295],AUTHORITY["ESRI","104101"]]
+7423=COMPD_CS["ETRS89 + EVRF2007 height", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], VERT_CS["EVRF2007 height", VERT_DATUM["European Vertical Reference Frame 2007", 2005, AUTHORITY["EPSG","5215"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5621"]], AUTHORITY["EPSG","7423"]]
+7414=COMPD_CS["Tokyo + JSLD height", GEOGCS["Tokyo", DATUM["Tokyo", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[-147.0, 506.0, 687.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6301"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4301"]], VERT_CS["JSLD height", VERT_DATUM["Japanese Standard Levelling Datum 1949", 2005, AUTHORITY["EPSG","5122"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5723"]], AUTHORITY["EPSG","7414"]]
+7410=COMPD_CS["PSHD93", GEOGCS["PSD93", DATUM["PDO Survey Datum 1993", SPHEROID["Clarke 1880 (RGS)", 6378249.145, 293.465, AUTHORITY["EPSG","7012"]], TOWGS84[-191.808, -250.512, 167.861, -0.792, -1.653, 8.558, 4.270300283733636], AUTHORITY["EPSG","6134"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4134"]], VERT_CS["PHD93 height", VERT_DATUM["PDO Height Datum 1993", 2005, AUTHORITY["EPSG","5123"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5724"]], AUTHORITY["EPSG","7410"]]
+7409=COMPD_CS["ETRS89 + EVRF2000 height", GEOGCS["ETRS89", DATUM["European Terrestrial Reference System 1989", SPHEROID["GRS 1980", 6378137.0, 298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], AUTHORITY["EPSG","6258"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4258"]], VERT_CS["EVRF2000 height", VERT_DATUM["European Vertical Reference Frame 2000", 2005, AUTHORITY["EPSG","5129"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5730"]], AUTHORITY["EPSG","7409"]]
+7408=COMPD_CS["RD/NAP", GEOGCS["Amersfoort", DATUM["Amersfoort", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[565.2369, 50.0087, 465.658, -0.40685733032239757, -0.3507326765425626, 1.8703473836067959, 0.8418079272556497], AUTHORITY["EPSG","6289"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4289"]], VERT_CS["NAP height", VERT_DATUM["Normaal Amsterdams Peil", 2005, AUTHORITY["EPSG","5109"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5709"]], AUTHORITY["EPSG","7408"]]
+7406=COMPD_CS["NAD27 + NGVD29 height", GEOGCS["NAD27", DATUM["North American Datum 1927", SPHEROID["Clarke 1866", 6378206.4, 294.9786982138982, AUTHORITY["EPSG","7008"]], TOWGS84[2.478, 149.752, 197.726, 0.526, -0.498, 0.501, 0.14129139227926102], AUTHORITY["EPSG","6267"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4267"]], VERT_CS["NGVD29 height", VERT_DATUM["National Geodetic Vertical Datum 1929", 2005, AUTHORITY["EPSG","5102"]], UNIT["foot_survey_us", 0.30480060960121924], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5702"]], AUTHORITY["EPSG","7406"]]
+7404=COMPD_CS["RT90 + RH70 height", GEOGCS["RT90", DATUM["Rikets koordinatsystem 1990", SPHEROID["Bessel 1841", 6377397.155, 299.1528128, AUTHORITY["EPSG","7004"]], TOWGS84[414.1, 41.3, 603.1, -0.855, -2.141, 7.023, 0.0], AUTHORITY["EPSG","6124"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4124"]], VERT_CS["RH70 height", VERT_DATUM["Rikets hojdsystem 1970", 2005, AUTHORITY["EPSG","5117"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5718"]], AUTHORITY["EPSG","7404"]]
+7400=COMPD_CS["NTF (Paris) + NGF IGN69 height", GEOGCS["NTF (Paris)", DATUM["Nouvelle Triangulation Francaise (Paris)", SPHEROID["Clarke 1880 (IGN)", 6378249.2, 293.4660212936269, AUTHORITY["EPSG","7011"]], AUTHORITY["EPSG","6807"]], PRIMEM["Paris", 2.5969213, AUTHORITY["EPSG","8903"]], UNIT["grade", 0.015707963267948967], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4807"]], VERT_CS["NGF IGN69 height", VERT_DATUM["Nivellement General de la France - IGN69", 2005, AUTHORITY["EPSG","5119"]], UNIT["m", 1.0], AXIS["Gravity-related height", UP], AUTHORITY["EPSG","5720"]], AUTHORITY["EPSG","7400"]]
+104000=GEOGCS["GCS_Assumed_Geographic_1",DATUM["North_American_Datum_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982],TOWGS84[-9,151,185]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295],AUTHORITY["ESRI","104000"]]
+2550=PROJCS["Samboja / UTM zone 50S",GEOGCS["Samboja",DATUM["Samboja",SPHEROID["Bessel 1841",6377397.155,299.1528128,AUTHORITY["EPSG","7004"]],TOWGS84[-404.78,685.68,45.47,0,0,0,0],AUTHORITY["EPSG","6125"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4125"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2550"]]
+29185=PROJCS["SAD69 / UTM zone 25S",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-33],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29185"]]
+29184=PROJCS["SAD69 / UTM zone 24S",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-39],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29184"]]
+29183=PROJCS["SAD69 / UTM zone 23S",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29183"]]
+29182=PROJCS["SAD69 / UTM zone 22S",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-51],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29182"]]
+29181=PROJCS["SAD69 / UTM zone 21S",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-57],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29181"]]
+29180=PROJCS["SAD69 / UTM zone 20S",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29180"]]
+29179=PROJCS["SAD69 / UTM zone 19S",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-69],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29179"]]
+29178=PROJCS["SAD69 / UTM zone 18S",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-75],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29178"]]
+29177=PROJCS["SAD69 / UTM zone 17S",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-81],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29177"]]
+2292=PROJCS["NAD83(CSRS98) / Prince Edward Isl. Stereographic (NAD83)",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Oblique_Stereographic"],PARAMETER["latitude_of_origin",47.25],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.999912],PARAMETER["false_easting",400000],PARAMETER["false_northing",800000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2292"]]
+29122=PROJCS["SAD69 / UTM zone 22N",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-51],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29122"]]
+29121=PROJCS["SAD69 / UTM zone 21N",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-57],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29121"]]
+29120=PROJCS["SAD69 / UTM zone 20N",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29120"]]
+29119=PROJCS["SAD69 / UTM zone 19N",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-69],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29119"]]
+29118=PROJCS["SAD69 / UTM zone 18N",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-75],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29118"]]
+29100=PROJCS["SAD69 / Brazil Polyconic",GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967",6378160,298.247167427,AUTHORITY["EPSG","7036"]],AUTHORITY["EPSG","6291"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4291"]],PROJECTION["Polyconic"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-54],PARAMETER["false_easting",5000000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","29100"]]
+2191=PROJCS["Madeira 1936 / UTM zone 28N",GEOGCS["Madeira 1936",DATUM["Madeira_1936",SPHEROID["International 1924",6378388,297,AUTHORITY["EPSG","7022"]],AUTHORITY["EPSG","6185"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4185"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-15],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2191"]]
+2153=PROJCS["NAD83(CSRS98) / UTM zone 11N",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2153"]]
+2152=PROJCS["NAD83(CSRS98) / UTM zone 12N",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-111],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2152"]]
+2151=PROJCS["NAD83(CSRS98) / UTM zone 13N",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-105],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2151"]]
+2150=PROJCS["NAD83(CSRS98) / UTM zone 17N",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-81],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2150"]]
+2149=PROJCS["NAD83(CSRS98) / UTM zone 18N",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-75],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2149"]]
+2148=PROJCS["NAD83(CSRS98) / UTM zone 21N",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-57],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2148"]]
+2147=PROJCS["NAD83(CSRS98) / MTM zone 10",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-79.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2147"]]
+2146=PROJCS["NAD83(CSRS98) / MTM zone 9",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-76.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2146"]]
+2145=PROJCS["NAD83(CSRS98) / MTM zone 8",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-73.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2145"]]
+2144=PROJCS["NAD83(CSRS98) / MTM zone 7",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-70.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2144"]]
+2143=PROJCS["NAD83(CSRS98) / MTM zone 6",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-67.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2143"]]
+2142=PROJCS["NAD83(CSRS98) / MTM zone 5",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-64.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2142"]]
+2141=PROJCS["NAD83(CSRS98) / MTM zone 4",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-61.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2141"]]
+2140=PROJCS["NAD83(CSRS98) / MTM zone 3",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-58.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2140"]]
+2139=PROJCS["NAD83(CSRS98) / SCoPQ zone 2",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-55.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2139"]]
+41001=PROJCS["WGS84 / Simple Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1],AUTHORITY["EPSG","41001"]]
+2038=PROJCS["NAD83(CSRS98) / UTM zone 20N",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-63],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2038"]]
+2037=PROJCS["NAD83(CSRS98) / UTM zone 19N",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-69],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2037"]]
+2036=PROJCS["NAD83(CSRS98) / New Brunswick Stereo",GEOGCS["NAD83(CSRS98)",DATUM["NAD83_Canadian_Spatial_Reference_System",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0],AUTHORITY["EPSG","6140"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4140"]],PROJECTION["Oblique_Stereographic"],PARAMETER["latitude_of_origin",46.5],PARAMETER["central_meridian",-66.5],PARAMETER["scale_factor",0.999912],PARAMETER["false_easting",2500000],PARAMETER["false_northing",7500000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","2036"]]
Index: /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/DatumAliasesTable.txt
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/DatumAliasesTable.txt	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/DatumAliasesTable.txt	(revision 28000)
@@ -0,0 +1,429 @@
+# Table of Datum aliases. Datum may be geodetic, vertical, temporal, etc.
+# Ellipsoid and prime meridian names may appear in this table as well.
+# The first line shall contains the authority names. All other lines are
+# datum names.
+#
+# (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
+#
+EPSG;OGR;ESRI;Oracle;OGC
+#-----------------------------------------------------------------------
+Ayabelle Lighthouse;;D_Ayabelle
+Abidjan 1987;Abidjan_1987;D_Abidjan_1987
+Accra;Accra;D_Accra
+Adindan;Adindan;D_Adindan;Adindan
+Afgooye;Afgooye;D_Afgooye;Afgooye
+Agadez;Agadez;D_Agadez
+Ain el Abd 1970;Ain_el_Abd_1970;D_Ain_el_Abd_1970;Ain el Abd 1970
+Albanian 1987;Albanian_1987;D_Albanian_1987
+American Samoa 1962;American_Samoa_1962;D_American_Samoa_1962
+Amersfoort;Amersfoort;D_Amersfoort
+Ammassalik 1958;Ammassalik_1958;D_Ammassalik_1958
+Ancienne Triangulation Francaise (Paris);Ancienne_Triangulation_Francaise_Paris;D_ATF
+Anguilla 1957;Anguilla_1957;D_Anguilla_1957
+Antigua 1943;Antigua_1943;D_Antigua_1943
+Aratu;Aratu;D_Aratu
+Arc 1950;Arc_1950;D_Arc_1950;Arc 1950
+Arc 1960;Arc_1960;D_Arc_1960;Arc 1960
+Ascension Island 1958;;D_Ascension_Island_1958;Ascension Island 1958
+Australian Antarctic Datum 1998;Australian_Antarctic_Datum_1998;D_Australian_Antarctic_1998
+Australian Geodetic Datum 1966;Australian_Geodetic_Datum_1966;D_Australian_1966;Australian Geodetic 1966
+Australian Geodetic Datum 1984;Australian_Geodetic_Datum_1984;D_Australian_1984;Australian Geodetic 1984
+Average Terrestrial System 1977;Average_Terrestrial_System_1977;D_ATS_1977
+Azores Central Islands 1948;Azores_Central_Islands_1948;D_Azores_Central_Islands_1948
+Azores Central Islands 1995;Azores_Central_Islands_1995;D_Azores_Central_Islands_1995
+Azores Occidental Islands 1939;Azores_Occidental_Islands_1939;D_Azores_Occidental_Islands_1939
+Azores Oriental Islands 1940;Azores_Oriental_Islands_1940;D_Azores_Oriental_Islands_1940
+Azores Oriental Islands 1995;Azores_Oriental_Islands_1995;D_Azores_Oriental_Islands_1995
+Barbados 1938;Barbados_1938;D_Barbados_1938
+Batavia;Batavia;D_Batavia;Batavia (Jakarta);Batavia_Jakarta;
+Beduaram;Beduaram;D_Beduaram
+Beijing 1954;Beijing_1954;D_Beijing_1954
+Bellevue;;D_Bellevue_IGN;Bellevue (IGN)
+Bermuda 1957;Bermuda_1957;D_Bermuda_1957;Bermuda 1957
+Bern 1938;Bern_1938;D_Bern_1938
+Bissau;Bissau;D_Bissau
+Bogota 1975;Bogota_1975;D_Bogota;Bogota Observatory;Bogota 1975 (Bogota);Bogota_1975_Bogota
+Bukit Rimpah;Bukit_Rimpah;D_Bukit_Rimpah
+Camacupa;Camacupa;D_Camacupa
+Camp Area Astro;;D_Camp_Area
+Campo Inchauspe;Campo_Inchauspe;D_Campo_Inchauspe;Campo Inchauspe
+Cape;Cape;D_Cape;Cape
+Cape Canaveral;;D_Cape_Canaveral
+Carthage;Carthage;D_Carthage;Carthage
+Carthage (Paris);Carthage_Paris
+Centre Spatial Guyanais 1967;Centre_Spatial_Guyanais_1967;D_CSG_1967
+CH1903;CH1903;D_CH1903
+CH1903 (Bern);CH1903_Bern;D_Bern_1898;CH 1903 (Switzerland)
+CH1903+;CH1903+;D_CH1903+
+Chatham Islands Datum 1971;Chatham_Islands_Datum_1971;D_Chatham_Island_1971;Chatham 1971
+Chatham Islands Datum 1979;Chatham_Islands_Datum_1979;D_Chatham_Islands_1979
+Chos Malal 1914;Chos_Malal_1914;D_Chos_Malal_1914
+Chua;Chua;D_Chua;Chua Astro
+Clarke 1880 (IGN);;Clarke_1880_IGN
+Cocos Islands 1965;;D_Anna_1_1965;Anna 1 Astro 1965
+Combani 1950;Combani_1950;D_Combani_1950
+Conakry 1905;Conakry_1905;D_Conakry_1905
+Congo 1960 Pointe Noire;Congo_1960_Pointe_Noire;D_Pointe_Noire
+Corrego Alegre;Corrego_Alegre;D_Corrego_Alegre;Corrego Alegre
+Cote d'Ivoire;Cote_d_Ivoire;D_Cote_d_Ivoire
+Dabola 1981;Dabola_1981;D_Dabola_1981
+Datum 73;Datum_73;D_Datum_73
+Datum Geodesi Nasional 1995;;D_Datum_Geodesi_Nasional_1995
+Dealul Piscului 1930;;D_Dealul_Piscului_1933
+Dealul Piscului 1933;Dealul_Piscului_1933
+Dealul Piscului 1970;Dealul_Piscului_1970;D_Dealul_Piscului_1970
+Deception Island;;D_Deception_Island
+Deir ez Zor;Deir_ez_Zor;D_Deir_ez_Zor
+Deutsches Hauptdreiecksnetz;Deutsches_Hauptdreiecksnetz;D_Deutsches_Hauptdreiecksnetz
+Diego Garcia 1969;;D_ISTS_073_1969
+Dominica 1945;Dominica_1945;D_Dominica_1945
+Douala;Douala;D_Douala
+Douala 1948;Douala_1948;D_Douala_1948
+Easter Island 1967;;D_Easter_Island_1967
+Egypt 1907;Egypt_1907;D_Egypt_1907;Old Egyptian
+Egypt 1930;Egypt_1930;D_Egypt_1930
+Egypt Gulf of Suez S-650 TL;;D_Egypt_Gulf_of_Suez_S-650_TL
+Estonia 1992;Estonia_1992;D_Estonia_1992
+Estonia 1997;Estonia_1997;D_Estonia_1997
+European Datum 1950;European_Datum_1950;D_European_1950;European 1950
+European Datum 1950(1977);European_Datum_1950_1977;D_European_1950_ED77
+European Datum 1979;European_Datum_1979;D_European_1979;European 1979
+European Datum 1987;European_Datum_1987;D_European_1987;European 1987
+European Libyan Datum 1979;European_Libyan_Datum_1979;D_European_Libyan_1979
+European Terrestrial Reference System 1989;European_Terrestrial_Reference_System_1989;D_ETRS_1989;ETRS 89
+Fahud;Fahud;D_Fahud
+Fatu Iva 72;;D_Fatu_Iva_1972
+Faroe Datum 1954;;D_Faroe_Datum_1954
+Fiji 1956;;D_Fiji_1956
+Fiji Geodetic Datum 1986;;D_Fiji_1986
+Final Datum 1958;Final_Datum_1958;D_FD_1958
+Fort Marigot;Fort_Marigot;D_Fort_Marigot
+Gan 1970;;D_Gan_1970
+Gandajika 1970;Gandajika_1970;;Gandajika Base
+Garoua;Garoua;D_Garoua
+Geocentric Datum of Australia 1994;Geocentric_Datum_of_Australia_1994;D_GDA_1994;GDA 94
+Geodetic Datum of 1965;Geodetic_Datum_of_1965;D_TM75
+Geocentric datum of Korea;;D_Korea_2000
+Geodetic Datum of Malaysia 2000;;D_GDM_2000
+Grand Cayman 1959;;D_Grand_Cayman_1959
+Grand Comoros;Grand_Comoros;D_Grand_Comoros
+Greek;Greek;D_Greek
+Greek (Athens);Greek_Athens
+Greek Geodetic Reference System 1987;Greek_Geodetic_Reference_System_1987;D_GGRS_1987
+Greenland 1996;;D_Greenland_1996
+Grenada 1953;Grenada_1953;D_Grenada_1953
+Guadeloupe 1948;Guadeloupe_1948;D_Sainte_Anne
+Guam 1963;Guam_1963;D_Guam_1963;Guam 1963
+Gulshan 303;Gulshan_303;D_Gulshan_303
+Gunung Segara;Gunung_Segara;D_Gunung_Segara
+Gunung Segara (Jakarta);Gunung_Segara_Jakarta
+Guyane Francaise;Guyane_Francaise;D_Guyane_Francaise
+Hanoi 1972;Hanoi_1972;D_Hanoi_1972
+Hartebeesthoek94;Hartebeesthoek94;D_Hartebeesthoek_1994
+Helle 1954;Helle_1954;D_Helle_1954
+Herat North;Herat_North;D_Herat_North
+Hito XVIII 1963;Hito_XVIII_1963;D_Hito_XVIII_1963;Hito XVIII 1963
+Hjorsey 1955;Hjorsey_1955;D_Hjorsey_1955
+Hong Kong 1963;;D_Hong_Kong_1963;Hong Kong 1963
+Hong Kong 1980;Hong_Kong_1980;D_Hong_Kong_1980
+Hu Tzu Shan;Hu_Tzu_Shan;;Hu-Tzu-Shan
+Hungarian Datum 1972;Hungarian_Datum_1972;D_Hungarian_1972
+IERS Terrestrial Reference Frame 1988;IERS_Terrestrial_Reference_Frame_1988;
+IERS Terrestrial Reference Frame 1989;IERS_Terrestrial_Reference_Frame_1989;D_ITRF_1989
+IERS Terrestrial Reference Frame 1990;IERS_Terrestrial_Reference_Frame_1990;D_ITRF_1990
+IERS Terrestrial Reference Frame 1991;IERS_Terrestrial_Reference_Frame_1991;D_ITRF_1991
+IERS Terrestrial Reference Frame 1992;IERS_Terrestrial_Reference_Frame_1992;D_ITRF_1992
+IERS Terrestrial Reference Frame 1993;IERS_Terrestrial_Reference_Frame_1993;D_ITRF_1993
+IERS Terrestrial Reference Frame 1994;IERS_Terrestrial_Reference_Frame_1994;D_ITRF_1994
+IERS Terrestrial Reference Frame 1996;IERS_Terrestrial_Reference_Frame_1996;D_ITRF_1996
+IERS Terrestrial Reference Frame 1997;IERS_Terrestrial_Reference_Frame_1997;D_ITRF_1997
+IERS Terrestrial Reference Frame 2000;IERS_Terrestrial_Reference_Frame_2000;D_ITRF_2000
+IGN53 Mare;IGN53_Mare;D_IGN53_Mare
+IGN56 Lifou;IGN56_Lifou;D_IGN56_Lifou
+IGN72 Grande Terre;IGN72_Grande_Terre;D_IGN72_Grande_Terre
+IGN72 Nuku Hiva;IGN72_Nuku_Hiva;D_IGN72_Nuku_Hiva
+IGC 1962 Arc of the 6th Parallel South;;D_IGC_1962_Arc_of_the_6th_Parallel_South
+IGN 1962 Kerguelen;;D_Kerguelen_Island_1949
+IGN Astro 1960;;D_IGN_Astro_1960
+IGN63 Hiva Oa;;D_IGN63_Hiva_Oa
+Indian 1954;Indian_1954;D_Indian_1954
+Indian 1960;Indian_1960;D_Indian_1960
+Indian 1975;Indian_1975;D_Indian_1975
+Indonesian Datum 1974;Indonesian_Datum_1974;D_Indonesian_1974
+Institut Geographique du Congo Belge 1955;;D_Institut_Geographique_du_Congo_Belge_1955
+International Terrestrial Reference Frame 2005;;D_ITRF_2005
+Iraq-Kuwait Boundary Datum 1992;Iraq-Kuwait_Boundary_Datum_1992;D_Iraq_Kuwait_Boundary_1992
+IRENET95;IRENET95;D_IRENET95
+Islands Network 1993;Islands_Network_1993;D_Islands_Network_1993
+Israel;Israel;D_Israel
+Istituto Geografico Militaire 1995;Istituto_Geografico_Militaire_1995;D_IGM_1995
+Iwo Jima 1945;;D_Beacon_E_1945
+Jamaica 1875;Jamaica_1875;D_Jamaica_1875
+Jamaica 1969;Jamaica_1969;D_Jamaica_1969
+Jamaica 2001;;D_Jamaica_2001
+Japanese Geodetic Datum 2000;Japanese_Geodetic_Datum_2000;D_JGD_2000
+Jednotne Trigonometricke Site Katastralni;Jednotne_Trigonometricke_Site_Katastralni;D_S_JTSK
+Johnston Island 1961;;D_Johnston_Island_1961;Johnston Island 1961
+Jouik 1961;Jouik_1961;D_Jouik_1961
+K0 1949;K0_1949;D_K0_1949
+Kalianpur 1880;Kalianpur_1880;D_Kalianpur_1880
+Kalianpur 1937;Kalianpur_1937;D_Kalianpur_1937
+Kalianpur 1962;Kalianpur_1962;D_Kalianpur_1962
+Kalianpur 1975;Kalianpur_1975;D_Kalianpur_1975
+Kandawala;Kandawala;D_Kandawala;Kandawala
+Karbala 1979;;D_Karbala_1979_Polservice
+Kartastokoordinaattijarjestelma (1966);Kartasto_Koordinaati_Jarjestelma_1966;D_KKJ
+Kasai 1953;;D_Kasai_1955
+Katanga 1955;;D_Katanga_1955
+Kertau;Kertau;D_Kertau;Kertau 1948
+Korean Datum 1985;Korean_Datum_1985;D_Korean_Datum_1985
+Korean Datum 1995;Korean_Datum_1995;D_Korean_Datum_1995
+Kousseri;Kousseri;D_Kousseri
+Kusaie 1951;;D_Kusaie_1951
+Kuwait Oil Company;Kuwait_Oil_Company;D_Kuwait_Oil_Company
+Kuwait Utility;Kuwait_Utility;D_Kuwait_Utility
+La Canoa;La_Canoa;D_La_Canoa
+Lake;Lake;D_Lake
+Lao 1993;Lao_1993;D_Lao_1993
+Lao National Datum 1997;Lao_National_Datum_1997;D_Lao_National_Datum_1997
+Latvia 1992;Latvia_1992;D_Latvia_1992
+Le Pouce 1934;;D_Le_Pouce_1934
+Leigon;Leigon;D_Leigon
+Liberia 1964;Liberia_1964;D_Liberia_1964;Liberia 1964
+Libyan Geodetic Datum 2006;;D_Libyan_Geodetic_Datum_2006
+Lisbon 1890;Lisbon_1890
+Lisbon 1890 (Lisbon);Lisbon_1890_Lisbon;D_Lisbon_1890
+Lisbon 1937;Lisbon_1937;D_Lisbon
+Lisbon 1937 (Lisbon);Lisbon_1937_Lisbon
+Lithuania 1994 (ETRS89);Lithuania_1994_ETRS89;D_Lithuania_1994
+Little Cayman 1961;;D_Little_Cayman_1961
+Locodjo 1965;Locodjo_1965;D_Locodjo_1965
+Loma Quintana;Loma_Quintana;D_Loma_Quintana
+Lome;Lome;D_Lome
+Luxembourg 1930;Luxembourg_1930;D_Luxembourg_1930
+Luzon 1911;Luzon_1911;D_Luzon_1911
+MOLDREF99;;D_International_1967
+Madeira 1936;Madeira_1936;D_Madeira_1936
+Madrid 1870 (Madrid);Madrid_1870_Madrid;D_Madrid_1870
+Madzansua;Madzansua;D_Madzansua
+Marco Geocentrico Nacional de Referencia;;D_MAGNA
+Mahe 1971;Mahe_1971;D_Mahe_1971;Mahe 1971
+Makassar;Makassar;D_Makassar
+Makassar (Jakarta);Makassar_Jakarta
+Malongo 1987;Malongo_1987;D_Malongo_1987
+Manoca;Manoca;D_Manoca
+Manoca 1962;Manoca_1962;D_Manoca_1962
+Marcus Island 1952;;D_Astro_1952
+Marshall Islands 1960;;D_Wake_Eniwetok_1960;Wake-Eniwetok 1960
+Martinique 1938;Martinique_1938;D_Fort_Desaix
+Massawa;Massawa;D_Massawa;Massawa
+Maupiti 83;;D_Maupiti_1983
+Mauritania 1999;Mauritania_1999;D_Mauritania_1999
+Merchich;Merchich;D_Merchich;Merchich
+Mhast;Mhast;D_Mhast
+Mhast (offshore);;D_Mhast_Offshore
+Mhast (onshore);;D_Mhast_Onshore
+Midway 1961;;D_Midway_1961
+Militar-Geographische Institut (Ferro);Militar-Geographische_Institut_Ferro;Militar-Geographische Institut;Militar-Geographische_Institut;D_MGI
+Minna;Minna;D_Minna;Minna
+Missao Hidrografico Angola y Sao Tome 1951;;D_Mhast_1951
+Monte Mario;Monte_Mario;D_Monte_Mario
+Monte Mario (Rome);Monte_Mario_Rome
+Montserrat 1958;Montserrat_1958;D_Montserrat_1958
+Moorea 87;;D_Moorea_1987
+MOP78;MOP78;D_MOP78
+Mount Dillon;Mount_Dillon;D_Mount_Dillon
+Moznet (ITRF94);Moznet_ITRF94;D_Moznet
+M'poraloko;M_poraloko;D_Mporaloko
+NAD Michigan;NAD_Michigan;D_North_American_Michigan
+NAD83 (High Accuracy Regional Network);NAD83_High_Accuracy_Regional_Network;D_North_American_1983_HARN
+NAD83 (National Spatial Reference System 2007);;D_NAD_1983_NSRS2007
+NAD83 Canadian Spatial Reference System;NAD83_Canadian_Spatial_Reference_System;D_North_American_1983_CSRS
+Nahrwan 1934;;D_Nahrwan_1934
+Nahrwan 1967;Nahrwan_1967;D_Nahrwan_1967
+Nakhl-e Ghanem;;D_Nakhl-e_Ghanem
+Naparima 1955;Naparima_1955;D_Naparima_1955
+Naparima 1972;Naparima_1972;D_Naparima_1972;Naparima, BWI
+National Geodetic Network;National_Geodetic_Network;D_NGN
+NEA74 Noumea;NEA74_Noumea;D_NEA74_Noumea
+New Zealand Geodetic Datum 1949;New_Zealand_Geodetic_Datum_1949;D_New_Zealand_1949
+New Zealand Geodetic Datum 2000;New_Zealand_Geodetic_Datum_2000;D_NZGD_2000
+NGO 1948;NGO_1948;D_NGO_1948
+NGO 1948 (Oslo);NGO_1948_Oslo
+Nord de Guerre (Paris);Nord_de_Guerre_Paris;D_Nord_de_Guerre
+Nord Sahara 1959;Nord_Sahara_1959;D_Nord_Sahara_1959
+Nord Sahara 1959 (Paris);Nord_Sahara_1959_Paris
+North American Datum 1927;North_American_Datum_1927;D_North_American_1927;NAD 27 (Continental US)
+North American Datum 1927 (1976);North_American_Datum_1927_1976;D_NAD_1927_Definition_1976
+North American Datum 1927 (CGQ77);North_American_Datum_1927_CGQ77;D_NAD_1927_CGQ77
+North American Datum 1983;North_American_Datum_1983;D_North_American_1983;NAD 83
+Nouakchott 1965;Nouakchott_1965;D_Nouakchott_1965
+Nouvelle Triangulation Francaise;Nouvelle_Triangulation_Francaise;NTF
+Nouvelle Triangulation Francaise (Paris);Nouvelle_Triangulation_Francaise_Paris;D_NTF;NTF (Paris meridian)
+Not specified (based on Airy 1830 ellipsoid);;D_Airy_1830
+Not specified (based on Airy Modified 1849 ellipsoid);;D_Airy_Modified
+Not specified (based on Australian National Spheroid);;D_Australian
+Not specified (based on Authalic Sphere);;D_Sphere
+Not specified (based on Bessel 1841 ellipsoid);;D_Bessel_1841
+Not specified (based on Bessel Modified ellipsoid);;D_Bessel_Modified
+Not specified (based on Bessel Namibia ellipsoid);;D_Bessel_Namibia
+Not specified (based on Clarke 1858 ellipsoid);;D_Clarke_1858
+Not specified (based on Clarke 1866 Authalic Sphere);;D_Sphere_Clarke_1866_Authalic
+Not specified (based on Clarke 1866 Michigan ellipsoid);;D_Clarke_1866_Michigan
+Not specified (based on Clarke 1866 ellipsoid);;D_Clarke_1866
+Not specified (based on Clarke 1880 (Arc) ellipsoid);;D_Clarke_1880_Arc
+Not specified (based on Clarke 1880 (Benoit) ellipsoid);;D_Clarke_1880_Benoit
+Not specified (based on Clarke 1880 (IGN) ellipsoid);;D_Clarke_1880_IGN
+Not specified (based on Clarke 1880 (RGS) ellipsoid);;D_Clarke_1880_RGS
+Not specified (based on Clarke 1880 (SGA 1922) ellipsoid);;D_Clarke_1880_SGA
+Not specified (based on Clarke 1880 ellipsoid);;D_Clarke_1880
+Not specified (based on Everest 1830 (1937 Adjustment) ellipsoid);;D_Everest_Adj_1937
+Not specified (based on Everest 1830 (1962 Definition) ellipsoid);;D_Everest_Def_1962
+Not specified (based on Everest (1830 Definition) ellipsoid);;D_Everest_1830
+Not specified (based on Everest 1830 (1967 Definition) ellipsoid);;D_Everest_Def_1967
+Not specified (based on Everest 1830 (1975 Definition) ellipsoid);;D_Everest_Def_1975
+Not specified (based on Everest 1830 Modified ellipsoid);;D_Everest_Modified
+Not specified (based on GEM 10C ellipsoid);;D_GEM_10C
+Not specified (based on GRS 1967 ellipsoid);;D_GRS_1967
+Not specified (based on GRS 1980 Authalic Sphere);;D_Sphere_GRS_1980_Authalic
+Not specified (based on GRS 1980 ellipsoid);;D_GRS_1980
+Not specified (based on Helmert 1906 ellipsoid);;D_Helmert_1906
+Not specified (based on Hughes 1980 ellipsoid);;D_Hughes_1980
+Not specified (based on Indonesian National Spheroid);;D_Indonesian
+Not specified (based on International 1924 Authalic Sphere);;D_Sphere_International_1924_Authalic
+Not specified (based on International 1924 ellipsoid);;D_International_1924
+Not specified (based on Krassowsky 1940 ellipsoid);;D_Krasovsky_1940
+Not specified (based on NWL 9D ellipsoid);;D_NWL_9D
+Not specified (based on OSU86F ellipsoid);;D_OSU_86F
+Not specified (based on OSU91A ellipsoid);;D_OSU_91A
+Not specified (based on Plessis 1817 ellipsoid);;D_Plessis_1817
+Not specified (based on Struve 1860 ellipsoid);;D_Struve_1860
+Not specified (based on War Office ellipsoid);;D_War_Office
+NSWC 9Z-2;NSWC_9Z-2;D_NSWC_9Z_2
+Observatario;Observatario;D_Observatario;Observatorio 1966
+Old Hawaiian;Old_Hawaiian;D_Old_Hawaiian;Old Hawaiian
+OS (SN) 1980;OS_SN_1980;D_OS_SN_1980
+OSGB 1936;OSGB_1936;D_OSGB_1936
+OSGB 1970 (SN);OSGB_1970_SN;D_OSGB_1970_SN
+OSNI 1952;OSNI_1952;D_OSNI_1952
+Padang 1884;Padang_1884;D_Padang_1884
+Padang 1884 (Jakarta);Padang_1884_Jakarta
+Palestine 1923;Palestine_1923;D_Palestine_1923
+Pampa del Castillo;Pampa_del_Castillo;D_Pampa_del_Castillo
+Parametrop Zemp 1990;;D_Parametrop_Zemp_1990
+PDO Survey Datum 1993;PDO_Survey_Datum_1993;D_PDO_1993
+Petrels 1972;Petrels_1972;D_Petrels_1972
+Philippine Reference System 1992;;D_Philippine_Reference_System_1992
+Phoenix Islands 1966;;D_Canton_1966;Canton Astro 1966
+Pico de las Nieves 1984;;D_Pico_de_Las_Nieves;Pico de las Nieves
+Pitcairn 1967;;D_Pitcairn_1967
+Point 58;Point_58;D_Point_58
+Pointe Geologie Perroud 1950;Pointe_Geologie_Perroud_1950;D_Pointe_Geologie_Perroud_1950
+Porto Santo 1936;Porto_Santo_1936;D_Porto_Santo_1936
+Porto Santo 1995;Porto_Santo_1995;D_Porto_Santo_1995
+Posiciones Geodesicas Argentinas;Posiciones_Geodesicas_Argentinas;D_POSGAR
+Posiciones Geodesicas Argentinas 1998;Posiciones_Geodesicas_Argentinas_1998;D_POSGAR_1998
+Posiciones Geodesicas Argentinas 1994;;D_POSGAR_1994
+Potsdam Datum/83;;D_Potsdam_1983
+Provisional South American Datum 1956;Provisional_South_American_Datum_1956;D_Provisional_S_American_1956;Provisional South American
+Puerto Rico;Puerto_Rico;D_Puerto_Rico;Puerto Rico
+Pulkovo 1942;Pulkovo_1942;D_Pulkovo_1942;Pulkovo 1942
+Pulkovo 1942(58);Pulkovo_1942/58;D_Pulkovo_1942_Adj_1958
+Pulkovo 1942(83);Pulkovo_1942/83;D_Pulkovo_1942_Adj_1983
+Pulkovo 1995;Pulkovo_1995;D_Pulkovo_1995
+Qatar 1948;Qatar_1948;D_Qatar_1948
+Qatar 1974;Qatar_1974;D_Qatar
+Qatar National Datum 1995;Qatar_National_Datum_1995;D_QND_1995;Qatar National
+Qornoq;Qornoq;D_Qornoq;Qornoq
+Qornoq 1927;Qornoq_1927;D_Qornoq_1927
+#
+# NOTE: The two previous lines were:
+#       Qornoq;Qornoq;D_Qornoq;
+#       Qornoq 1927;Qornoq_1927;D_Qornoq_1927;Qornoq
+#       But it introduces a name clash on "Qornoq".
+#
+Rauenberg Datum/83;;D_Rauenberg_1983
+Rassadiran;Rassadiran;D_Rassadiran
+Red Geodesica Venezolana;Red_Geodesica_Venezolana;D_REGVEN
+Reseau de Reference des Antilles Francaises 1991;Reseau_de_Reference_des_Antilles_Francaises_1991;D_RRAF_1991
+Reseau Geodesique de Nouvelle Caledonie 91-93;;D_Reseau_Geodesique_de_Nouvelle_Caledonie_1991-93
+Reseau Geodesique de la Polynesie Francaise;;D_Reseau_Geodesique_de_la_Polynesie_Francaise
+Reseau Geodesique de la Reunion 1992;Reseau_Geodesique_de_la_Reunion_1992;D_RGR_1992
+Reseau Geodesique Francais 1993;Reseau_Geodesique_Francais_1993;D_RGF_1993
+Reseau Geodesique Francais Guyane 1995;Reseau_Geodesique_Francais_Guyane_1995;D_RGFG_1995
+Reseau Geodesique Nouvelle Caledonie 1991;Reseau_Geodesique_Nouvelle_Caledonie_1991;D_RGNC_1991
+Reseau National Belge 1950;Reseau_National_Belge_1950;D_Belge_1950
+Reseau National Belge 1950 (Brussels);Reseau_National_Belge_1950_Brussels
+Reseau National Belge 1972;Reseau_National_Belge_1972;D_Belge_1972
+Reunion 1947;Reunion_1947;D_Reunion_1947;Reunion
+Reykjavik 1900;Reykjavik_1900;D_Reykjavik_1900
+Rikets koordinatsystem 1990;Rikets_koordinatsystem_1990;D_RT_1990;RT 90 (Sweden)
+SVY21;;D_SVY21
+Saint Pierre et Miquelon 1950;Saint_Pierre_et_Miquelon_1950;D_Saint_Pierre_et_Miquelon_1950
+Samboja;Samboja;D_Samboja
+Santo 1965;;D_Santo_DOS_1965;Santo (DOS)
+Sapper Hill 1943;Sapper_Hill_1943;D_Sapper_Hill_1943;Sapper Hill 1943
+Schwarzeck;Schwarzeck;D_Schwarzeck;Schwarzeck
+Scoresbysund 1952;Scoresbysund_1952;D_Scoresbysund_1952
+Segora;Segora;D_Segora
+Selvagem Grande;Selvagem_Grande;D_Selvagem_Grande_1938
+Serindung;Serindung;D_Serindung
+Sierra Leone 1968;Sierra_Leone_1968;D_Sierra_Leone_1968
+Sierra Leone Colony 1924;Sierra_Leone_Colony_1924;D_Sierra_Leone_1924
+Sistema de Referencia Geocentrico para America del Sur 1995;Sistema_de_Referencia_Geocentrico_para_America_del_Sur_1995;D_SIRGAS
+Sistema de Referencia Geocentrico para America del Sur 2000;Sistema_de_Referencia_Geocentrico_para_America_del_Sur_2000;D_SIRGAS_2000
+S-JTSK (Ferro);S-JTSK_Ferro
+Solomon 1968;;D_Solomon_1968
+South American Datum 1969;South_American_Datum_1969;D_South_American_1969;South American 1969
+South American Datum 1969;South_American_Datum_1969;D_South_American_1969;South American 1969
+South Georgia 1968;;D_ISTS_061_1968
+South Yemen;South_Yemen;D_South_Yemen
+St. George Island;St_George_Island;D_St_George_Island
+St. Helena 1971;;D_DOS_71_4
+St. Kitts 1955;St_Kitts_1955;D_St_Kitts_1955
+St. Lawrence Island;St_Lawrence_Island;D_St_Lawrence_Island
+St. Lucia 1955;St_Lucia_1955;D_St_Lucia_1955
+St. Paul Island;St_Paul_Island;D_St_Paul_Island
+St. Vincent 1945;St_Vincent_1945;D_St_Vincent_1945
+ST71 Belep;ST71_Belep;D_ST71_Belep
+ST84 Ile des Pins;ST84_Ile_des_Pins;D_ST84_Ile_des_Pins
+ST87 Ouvea;ST87_Ouvea;D_ST87_Ouvea
+Stockholm 1938;Stockholm_1938;D_Stockholm_1938
+Stockholm 1938 (Stockholm);Stockholm_1938_Stockholm
+Sudan;Sudan;D_Sudan
+SWEREF99;SWEREF99;D_SWEREF99
+Swiss Terrestrial Reference Frame 1995;Swiss_Terrestrial_Reference_Frame_1995;D_Swiss_TRF_1995
+Tahaa;Tahaa;D_Tahaa
+Tahaa 54;;D_Tahaa_1954
+Tahiti;Tahiti;D_Tahiti
+Tahiti 52;;D_Tahiti_1952
+Tahiti 79;;D_Tahiti_1979
+Tananarive 1925;Tananarive_1925;D_Tananarive_1925
+Tananarive 1925 (Paris);Tananarive_1925_Paris
+Tern Island 1961;;D_Tern_Island_1961
+Tete;Tete;D_Tete
+Timbalai 1948;Timbalai_1948;D_Timbalai_1948;Timbalai 1948
+TM65;TM65;D_TM65
+Tokyo;Tokyo;D_Tokyo;Tokyo
+Trinidad 1903;Trinidad_1903;D_Trinidad_1903
+Tristan 1968;;D_Tristan_1968
+Trucial Coast 1948;Trucial_Coast_1948;D_Trucial_Coast_1948
+Vanua Levu 1915;;D_Vanua_Levu_1915
+Vientiane 1982;Vientiane_1982;D_Vientiane_1982
+Vietnam 2000;;D_Vietnam_2000
+Viti Levu 1916;;D_Viti_Levu_1916;Viti Levu 1916
+Voirol 1875;Voirol_1875;D_Voirol_1875
+Voirol 1875 (Paris);Voirol_1875_Paris
+Voirol 1879;Voirol_1879;D_Voirol_1879
+Voirol 1879 (Paris);Voirol_1879_Paris
+WGS 72 Transit Broadcast Ephemeris;WGS_72_Transit_Broadcast_Ephemeris;D_WGS_1972_BE
+Wake Island 1952;;D_Wake_Island_1952
+World Geodetic System 1966;;D_WGS_1966
+World Geodetic System 1972;World_Geodetic_System_1972;D_WGS_1972;WGS 72
+World Geodetic System 1984;World_Geodetic_System_1984;D_WGS_1984;WGS 84;WGS84;WGS_84;WGS 1984;WGS_1984
+Xian 1980;Xian_1980;D_Xian_1980
+Yacare;Yacare;D_Yacare;Yacare
+Yemen National Geodetic Network 1996;Yemen_National_Geodetic_Network_1996;D_Yemen_NGN_1996
+Yoff;Yoff;D_Yoff
+Zanderij;Zanderij;D_Zanderij;Zanderij
+fk89;;D_fk89
Index: /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/epsg/esri.properties
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/epsg/esri.properties	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/epsg/esri.properties	(revision 28000)
@@ -0,0 +1,26 @@
+#
+# Extends the EPSG database with CRS defined by ESRI. Those CRS will be registered
+# both in "ESRI" and "EPSG" name space. If a CRS is found both in this file and in
+# a SQL database, then the later will have precedence. Duplicated values can be
+# found with the following command line:
+#
+#     java -cp gt2-epsg-extension.jar:gt2-epsg-hsql.jar \
+#         org.geotools.referencing.factory.epsg.EsriExtension -test -duplicated
+#
+#
+# Notes on the WKT strings used in this file:
+#   * When not specified, "false_easting" and "false_northing" parameters default to 0.
+#   * The final AUTHORITY["EPSG", <code>] element is optional. We recommand to ommit it
+#     since the WKT parser will automatically synthesize an appropriate one.  Note that
+#     this recommandation doesn't apply to CRS defined outside of this file.
+#   * Do not put AXIS[...] elements. We want the default (longitude,latitude) axis order
+#     in order to construct CRS insensitive to the FORCE_LONGITUDE_FIRST_AXIS_ORDER hint.
+#
+# $Id: esri.properties 38435 2011-12-20 08:11:41Z aaime $
+# $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/epsg-extension/src/main/resources/org/geotools/referencing/factory/epsg/esri.properties $
+#
+# TOWGS84 clause comes from spatialreference.org
+102581=PROJCS["NTF_France_I_degrees",GEOGCS["GCS_NTF",DATUM["D_NTF",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602],TOWGS84[-168,-60,320,0,0,0,0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["False_Northing",1200000.0],PARAMETER["Central_Meridian",2.337229166666667],PARAMETER["Standard_Parallel_1",49.5],PARAMETER["Scale_Factor",0.999877341],PARAMETER["Latitude_Of_Origin",49.5],UNIT["Meter",1.0]]
+102582=PROJCS["NTF_France_II_degrees",GEOGCS["GCS_NTF",DATUM["D_NTF",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602],TOWGS84[-168,-60,320,0,0,0,0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["False_Northing",2200000.0],PARAMETER["Central_Meridian",2.337229166666667],PARAMETER["Standard_Parallel_1",46.8],PARAMETER["Scale_Factor",0.99987742],PARAMETER["Latitude_Of_Origin",46.8],UNIT["Meter",1.0]]
+102583=PROJCS["NTF_France_III_degrees",GEOGCS["GCS_NTF",DATUM["D_NTF",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602],TOWGS84[-168,-60,320,0,0,0,0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["False_Northing",3200000.0],PARAMETER["Central_Meridian",2.337229166666667],PARAMETER["Standard_Parallel_1",44.1],PARAMETER["Scale_Factor",0.999877499],PARAMETER["Latitude_Of_Origin",44.1],UNIT["Meter",1.0]]
+102584=PROJCS["NTF_France_IV_degrees",GEOGCS["GCS_NTF",DATUM["D_NTF",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602],TOWGS84[-168,-60,320,0,0,0,0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",234.358],PARAMETER["False_Northing",185861.369],PARAMETER["Central_Meridian",2.337229166666667],PARAMETER["Standard_Parallel_1",42.165],PARAMETER["Scale_Factor",0.99994471],PARAMETER["Latitude_Of_Origin",42.165],UNIT["Meter",1.0]]
Index: /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/epsg/esri_original.properties
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/epsg/esri_original.properties	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/epsg/esri_original.properties	(revision 28000)
@@ -0,0 +1,831 @@
+#
+# Extends the EPSG database with CRS defined by ESRI. Those CRS will be registered
+# both in "ESRI" and "EPSG" name space. If a CRS is found both in this file and in
+# a SQL database, then the later will have precedence. Duplicated values can be
+# found with the following command line:
+#
+#     java -cp gt2-epsg-extension.jar:gt2-epsg-hsql.jar \
+#         org.geotools.referencing.factory.epsg.EsriExtension -test -duplicated
+#
+#
+# Notes on the WKT strings used in this file:
+#   * When not specified, "false_easting" and "false_northing" parameters default to 0.
+#   * The final AUTHORITY["EPSG", <code>] element is optional. We recommand to ommit it
+#     since the WKT parser will automatically synthesize an appropriate one.  Note that
+#     this recommandation doesn't apply to CRS defined outside of this file.
+#   * Do not put AXIS[...] elements. We want the default (longitude,latitude) axis order
+#     in order to construct CRS insensitive to the FORCE_LONGITUDE_FIRST_AXIS_ORDER hint.
+#
+# $Id: esri.properties 38435 2011-12-20 08:11:41Z aaime $
+# $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/epsg-extension/src/main/resources/org/geotools/referencing/factory/epsg/esri.properties $
+#
+
+# -----------------------------------------------------------------
+# The following values are inside the EPSG reserved code range. For
+# example code 4404 is used for a Cartesian 2D coordinate system.
+# We disable those CRS for now.
+# -----------------------------------------------------------------
+# 4023=GEOGCS["GCS_International_1967",DATUM["D_International_1967",SPHEROID["International_1967",6378160.0,298.25]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+# 4217=GEOGCS["GCS_Bern_1898",DATUM["D_Bern_1898",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+# 4305=GEOGCS["GCS_Voirol_Unifie_1960",DATUM["D_Voirol_Unifie_1960",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Grad",0.01570796326794897]]
+# 4404=GEOGCS["GCS_Montserrat_1958",DATUM["D_Montserrat_1958",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+# 4812=GEOGCS["GCS_Voirol_Unifie_1960_Paris",DATUM["D_Voirol_Unifie_1960",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Paris",2.337229166666667],UNIT["Grad",0.01570796326794897]]
+
+20002=PROJCS["Pulkovo_1995_GK_Zone_2",GEOGCS["GCS_Pulkovo_1995",DATUM["D_Pulkovo_1995",SPHEROID["Krasovsky_1940",6378245.0,298.3]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",2500000.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+20003=PROJCS["Pulkovo_1995_GK_Zone_3",GEOGCS["GCS_Pulkovo_1995",DATUM["D_Pulkovo_1995",SPHEROID["Krasovsky_1940",6378245.0,298.3]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",3500000.0],PARAMETER["Central_Meridian",15.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+20062=PROJCS["Pulkovo_1995_GK_Zone_2N",GEOGCS["GCS_Pulkovo_1995",DATUM["D_Pulkovo_1995",SPHEROID["Krasovsky_1940",6378245.0,298.3]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+20063=PROJCS["Pulkovo_1995_GK_Zone_3N",GEOGCS["GCS_Pulkovo_1995",DATUM["D_Pulkovo_1995",SPHEROID["Krasovsky_1940",6378245.0,298.3]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",15.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+24721=PROJCS["La_Canoa_UTM_Zone_21N",GEOGCS["GCS_La_Canoa",DATUM["D_La_Canoa",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-57.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+26761=PROJCS["NAD_1927_StatePlane_Hawaii_1_FIPS_5101",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-155.5],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",18.83333333333333],UNIT["Foot_US",0.3048006096012192]]
+26762=PROJCS["NAD_1927_StatePlane_Hawaii_2_FIPS_5102",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-156.6666666666667],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",20.33333333333333],UNIT["Foot_US",0.3048006096012192]]
+26763=PROJCS["NAD_1927_StatePlane_Hawaii_3_FIPS_5103",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-158.0],PARAMETER["Scale_Factor",0.99999],PARAMETER["Latitude_Of_Origin",21.16666666666667],UNIT["Foot_US",0.3048006096012192]]
+26764=PROJCS["NAD_1927_StatePlane_Hawaii_4_FIPS_5104",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-159.5],PARAMETER["Scale_Factor",0.99999],PARAMETER["Latitude_Of_Origin",21.83333333333333],UNIT["Foot_US",0.3048006096012192]]
+26765=PROJCS["NAD_1927_StatePlane_Hawaii_5_FIPS_5105",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-160.1666666666667],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",21.66666666666667],UNIT["Foot_US",0.3048006096012192]]
+26788=PROJCS["NAD_1927_StatePlane_Michigan_North_FIPS_2111",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2000000.0],PARAMETER["Central_Meridian",-87.0],PARAMETER["Standard_Parallel_1",45.48333333333333],PARAMETER["Standard_Parallel_2",47.08333333333334],PARAMETER["Latitude_Of_Origin",44.78333333333333],UNIT["Foot_US",0.3048006096012192]]
+26789=PROJCS["NAD_1927_StatePlane_Michigan_Central_FIPS_2112",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2000000.0],PARAMETER["Central_Meridian",-84.33333333333333],PARAMETER["Standard_Parallel_1",44.18333333333333],PARAMETER["Standard_Parallel_2",45.7],PARAMETER["Latitude_Of_Origin",43.31666666666667],UNIT["Foot_US",0.3048006096012192]]
+26790=PROJCS["NAD_1927_StatePlane_Michigan_South_FIPS_2113",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2000000.0],PARAMETER["Central_Meridian",-84.33333333333333],PARAMETER["Standard_Parallel_1",42.1],PARAMETER["Standard_Parallel_2",43.66666666666666],PARAMETER["Latitude_Of_Origin",41.5],UNIT["Foot_US",0.3048006096012192]]
+30591=PROJCS["Nord_Algerie",GEOGCS["GCS_Voirol_Unifie_1960",DATUM["D_Voirol_Unifie_1960",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Grad",0.01570796326794897]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500135.0],PARAMETER["False_Northing",300090.0],PARAMETER["Central_Meridian",3.0],PARAMETER["Standard_Parallel_1",40.0],PARAMETER["Scale_Factor",0.999625544],PARAMETER["Latitude_Of_Origin",40.0],UNIT["Meter",1.0]]
+30592=PROJCS["Sud_Algerie",GEOGCS["GCS_Voirol_Unifie_1960",DATUM["D_Voirol_Unifie_1960",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Grad",0.01570796326794897]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500135.0],PARAMETER["False_Northing",300090.0],PARAMETER["Central_Meridian",3.0],PARAMETER["Standard_Parallel_1",37.0],PARAMETER["Scale_Factor",0.999625769],PARAMETER["Latitude_Of_Origin",37.0],UNIT["Meter",1.0]]
+31491=PROJCS["Germany_Zone_1",GEOGCS["GCS_Deutsche_Hauptdreiecksnetz",DATUM["D_Deutsche_Hauptdreiecksnetz",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1500000.0],PARAMETER["Central_Meridian",3.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+31492=PROJCS["Germany_Zone_2",GEOGCS["GCS_Deutsche_Hauptdreiecksnetz",DATUM["D_Deutsche_Hauptdreiecksnetz",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",2500000.0],PARAMETER["Central_Meridian",6.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+31493=PROJCS["Germany_Zone_3",GEOGCS["GCS_Deutsche_Hauptdreiecksnetz",DATUM["D_Deutsche_Hauptdreiecksnetz",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",3500000.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+31494=PROJCS["Germany_Zone_4",GEOGCS["GCS_Deutsche_Hauptdreiecksnetz",DATUM["D_Deutsche_Hauptdreiecksnetz",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",4500000.0],PARAMETER["Central_Meridian",12.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+31495=PROJCS["Germany_Zone_5",GEOGCS["GCS_Deutsche_Hauptdreiecksnetz",DATUM["D_Deutsche_Hauptdreiecksnetz",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",5500000.0],PARAMETER["Central_Meridian",15.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+31917=PROJCS["SIRGAS_UTM_Zone_17N",GEOGCS["GCS_SIRGAS",DATUM["D_SIRGAS",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-81.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+31918=PROJCS["SIRGAS_UTM_Zone_18N",GEOGCS["GCS_SIRGAS",DATUM["D_SIRGAS",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-75.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+31919=PROJCS["SIRGAS_UTM_Zone_19N",GEOGCS["GCS_SIRGAS",DATUM["D_SIRGAS",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-69.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+31920=PROJCS["SIRGAS_UTM_Zone_20N",GEOGCS["GCS_SIRGAS",DATUM["D_SIRGAS",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-63.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+31921=PROJCS["SIRGAS_UTM_Zone_21N",GEOGCS["GCS_SIRGAS",DATUM["D_SIRGAS",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-57.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+31922=PROJCS["SIRGAS_UTM_Zone_22N",GEOGCS["GCS_SIRGAS",DATUM["D_SIRGAS",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-51.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+32059=PROJCS["NAD_1927_StatePlane_Puerto_Rico_FIPS_5201",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-66.43333333333334],PARAMETER["Standard_Parallel_1",18.03333333333334],PARAMETER["Standard_Parallel_2",18.43333333333333],PARAMETER["Latitude_Of_Origin",17.83333333333333],UNIT["Foot_US",0.3048006096012192]]
+32060=PROJCS["NAD_1927_StatePlane_Virgin_Islands_St_Croix_FIPS_5202",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",100000.0],PARAMETER["Central_Meridian",-66.43333333333334],PARAMETER["Standard_Parallel_1",18.03333333333334],PARAMETER["Standard_Parallel_2",18.43333333333333],PARAMETER["Latitude_Of_Origin",17.83333333333333],UNIT["Foot_US",0.3048006096012192]]
+37001=GEOGCS["GCS_WGS_1966",DATUM["D_WGS_1966",SPHEROID["WGS_1966",6378145.0,298.25]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37002=GEOGCS["GCS_Fischer_1960",DATUM["D_Fischer_1960",SPHEROID["Fischer_1960",6378166.0,298.3]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37003=GEOGCS["GCS_Fischer_1968",DATUM["D_Fischer_1968",SPHEROID["Fischer_1968",6378150.0,298.3]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37004=GEOGCS["GCS_Fischer_Modified",DATUM["D_Fischer_Modified",SPHEROID["Fischer_Modified",6378155.0,298.3]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37005=GEOGCS["GCS_Hough_1960",DATUM["D_Hough_1960",SPHEROID["Hough_1960",6378270.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37006=GEOGCS["GCS_Everest_Modified_1969",DATUM["D_Everest_Modified_1969",SPHEROID["Everest_Modified_1969",6377295.664,300.8017]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37007=GEOGCS["GCS_Walbeck",DATUM["D_Walbeck",SPHEROID["Walbeck",6376896.0,302.78]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37008=GEOGCS["GCS_Sphere_ARC_INFO",DATUM["D_Sphere_ARC_INFO",SPHEROID["Sphere_ARC_INFO",6370997.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37201=GEOGCS["GCS_European_1979",DATUM["D_European_1979",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37202=GEOGCS["GCS_Everest_Bangladesh",DATUM["D_Everest_Bangladesh",SPHEROID["Everest_Adjustment_1937",6377276.345,300.8017]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37203=GEOGCS["GCS_Everest_India_Nepal",DATUM["D_Everest_India_Nepal",SPHEROID["Everest_Definition_1962",6377301.243,300.8017255]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37204=GEOGCS["GCS_Hjorsey_1955",DATUM["D_Hjorsey_1955",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37205=GEOGCS["GCS_Hong_Kong_1963",DATUM["D_Hong_Kong_1963",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37206=GEOGCS["GCS_Oman",DATUM["D_Oman",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37207=GEOGCS["GCS_South_Asia_Singapore",DATUM["D_South_Asia_Singapore",SPHEROID["Fischer_Modified",6378155.0,298.3]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37208=GEOGCS["GCS_Ayabelle",DATUM["D_Ayabelle",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37211=GEOGCS["GCS_Point_58",DATUM["D_Point_58",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37212=GEOGCS["GCS_Beacon_E_1945",DATUM["D_Beacon_E_1945",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37213=GEOGCS["GCS_Tern_Island_1961",DATUM["D_Tern_Island_1961",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37214=GEOGCS["GCS_Astro_1952",DATUM["D_Astro_1952",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37215=GEOGCS["GCS_Bellevue_IGN",DATUM["D_Bellevue_IGN",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37216=GEOGCS["GCS_Canton_1966",DATUM["D_Canton_1966",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37217=GEOGCS["GCS_Chatham_Island_1971",DATUM["D_Chatham_Island_1971",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37218=GEOGCS["GCS_DOS_1968",DATUM["D_DOS_1968",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37219=GEOGCS["GCS_Easter_Island_1967",DATUM["D_Easter_Island_1967",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37220=GEOGCS["GCS_Guam_1963",DATUM["D_Guam_1963",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37221=GEOGCS["GCS_GUX_1",DATUM["D_GUX_1",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37222=GEOGCS["GCS_Johnston_Island_1961",DATUM["D_Johnston_Island_1961",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37223=GEOGCS["GCS_Carthage_Degree",DATUM["D_Carthage",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37224=GEOGCS["GCS_Midway_1961",DATUM["D_Midway_1961",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37226=GEOGCS["GCS_Pitcairn_1967",DATUM["D_Pitcairn_1967",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37227=GEOGCS["GCS_Santo_DOS_1965",DATUM["D_Santo_DOS_1965",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37228=GEOGCS["GCS_Viti_Levu_1916",DATUM["D_Viti_Levu_1916",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37229=GEOGCS["GCS_Wake_Eniwetok_1960",DATUM["D_Wake_Eniwetok_1960",SPHEROID["Hough_1960",6378270.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37230=GEOGCS["GCS_Wake_Island_1952",DATUM["D_Wake_Island_1952",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37231=GEOGCS["GCS_Anna_1_1965",DATUM["D_Anna_1_1965",SPHEROID["Australian",6378160.0,298.25]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37232=GEOGCS["GCS_Gan_1970",DATUM["D_Gan_1970",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37233=GEOGCS["GCS_ISTS_073_1969",DATUM["D_ISTS_073_1969",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37234=GEOGCS["GCS_Kerguelen_Island_1949",DATUM["D_Kerguelen_Island_1949",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37235=GEOGCS["GCS_Reunion",DATUM["D_Reunion",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37237=GEOGCS["GCS_Ascension_Island_1958",DATUM["D_Ascension_Island_1958",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37238=GEOGCS["GCS_DOS_71_4",DATUM["D_DOS_71_4",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37239=GEOGCS["GCS_Cape_Canaveral",DATUM["D_Cape_Canaveral",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37240=GEOGCS["GCS_Fort_Thomas_1955",DATUM["D_Fort_Thomas_1955",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37241=GEOGCS["GCS_Graciosa_Base_SW_1948",DATUM["D_Graciosa_Base_SW_1948",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37242=GEOGCS["GCS_ISTS_061_1968",DATUM["D_ISTS_061_1968",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37243=GEOGCS["GCS_LC5_1961",DATUM["D_LC5_1961",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37245=GEOGCS["GCS_Observ_Meteorologico_1939",DATUM["D_Observ_Meteorologico_1939",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37246=GEOGCS["GCS_Pico_de_Las_Nieves",DATUM["D_Pico_de_Las_Nieves",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37247=GEOGCS["GCS_Porto_Santo_1936",DATUM["D_Porto_Santo_1936",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37249=GEOGCS["GCS_Sao_Braz",DATUM["D_Sao_Braz",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37250=GEOGCS["GCS_Selvagem_Grande_1938",DATUM["D_Selvagem_Grande_1938",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37251=GEOGCS["GCS_Tristan_1968",DATUM["D_Tristan_1968",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37252=GEOGCS["GCS_American_Samoa_1962",DATUM["D_American_Samoa_1962",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37253=GEOGCS["GCS_Camp_Area",DATUM["D_Camp_Area",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37254=GEOGCS["GCS_Deception_Island",DATUM["D_Deception_Island",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37255=GEOGCS["GCS_Gunung_Segara",DATUM["D_Gunung_Segara",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37257=GEOGCS["GCS_S42_Hungary",DATUM["D_S42_Hungary",SPHEROID["Krasovsky_1940",6378245.0,298.3]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37259=GEOGCS["GCS_Kusaie_1951",DATUM["D_Kusaie_1951",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+37260=GEOGCS["GCS_Alaskan_Islands",DATUM["D_Alaskan_Islands",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+42101=PROJCS["WGS 84 / LCC Canada",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],PARAMETER["false_northing",-8000000.0],UNIT["Meter",1]]
+42102=PROJCS["BC_Albers",GEOGCS["GCS_North_American_1983",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Albers_Conic_Equal_Area"],PARAMETER["False_Easting",1000000],PARAMETER["Central_Meridian",-126],PARAMETER["Standard_Parallel_1",50],PARAMETER["Standard_Parallel_2",58.5],PARAMETER["Latitude_Of_Origin",45],UNIT["Meter",1]]
+42103=PROJCS["WGS 84 / LCC USA",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1978",6378135,298.26]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-100.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",33.0],PARAMETER["standard_parallel_2",45.0],UNIT["Meter",1]]
+42104=PROJCS["NAD83 / MTM zone 8 Québec",GEOGCS["GRS80",DATUM["GRS_1980",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-73.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],UNIT["Meter",1]]
+42105=PROJCS["WGS84 / Merc NorthAm",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",-96],UNIT["Meter",1]]
+42106=PROJCS["WGS84 / Lambert Azim Mozambique",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Azimuthal_Equal_Area"],PARAMETER["latitude_of_origin",5],PARAMETER["central_meridian",20],UNIT["Meter",1]]
+42301=PROJCS["NAD27 / Polar Stereographic / CM=-98",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.978698213901],TOWGS84[-9,151,185]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Stereographic"],PARAMETER["latitude_of_origin",90],PARAMETER["central_meridian",-98.0],PARAMETER["scale_factor",0.9996],UNIT["Meter",1]]
+42302=PROJCS["JapanOrtho.09 09",GEOGCS["Lon/Lat.Tokyo Datum",DATUM["Tokyo Datum",SPHEROID["anon",6377397.155,299.15281310608]],PRIMEM["Greenwich",0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",139.833333333333],PARAMETER["Latitude_of_Origin",36],PARAMETER["Scale_Factor",0.9999],UNIT["Meter",1]]
+42303=PROJCS["NAD83 / Albers NorthAm",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Albers_conic_equal_area"],PARAMETER["central_meridian",-96.0],PARAMETER["latitude_of_origin",23],PARAMETER["standard_parallel_1",29.5],PARAMETER["standard_parallel_2",45.5],UNIT["Meter",1]]
+42304=PROJCS["NAD83 / NRCan LCC Canada",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",49.0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],UNIT["Meter",1]]
+42305=PROJCS["France_II",GEOGCS["GCS_NTF_Paris",DATUM["Nouvelle_Triangulation_Francaise",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Paris",2.337229166666667],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["False_Easting",600000],PARAMETER["False_Northing",2200000],PARAMETER["Central_Meridian",0],PARAMETER["Standard_Parallel_1",45.898918964419],PARAMETER["Standard_Parallel_2",47.696014502038],PARAMETER["Latitude_Of_Origin",46.8],UNIT["Meter",1]]
+42306=PROJCS["NAD83/QC_LCC",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-68.5],PARAMETER["latitude_of_origin",44],PARAMETER["standard_parallel_1",46],PARAMETER["standard_parallel_2",60],UNIT["Meter",1]]
+42307=PROJCS["NAD83 / Texas Central - feet",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",31.8833333333333],PARAMETER["standard_parallel_2",30.1166666666667],PARAMETER["latitude_of_origin",29.6666666666667],PARAMETER["central_meridian",-100.333333333333],PARAMETER["false_easting",2296583.33333333333333],PARAMETER["false_northing",9842500],UNIT["US_Foot",0.30480060960121924]]
+42308=PROJCS["NAD27 / California Albers",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.978698213901],TOWGS84[-9,151,185]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Albers_conic_equal_area"],PARAMETER["central_meridian",-120.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",34],PARAMETER["standard_parallel_2",40.5],PARAMETER["false_northing",-4000000],UNIT["Meter",1]]
+42309=PROJCS["NAD 83 / LCC Canada AVHRR-2",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],UNIT["Meter",1]]
+42310=PROJCS["WGS84+GRS80 / Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],UNIT["Meter",1]]
+42311=PROJCS["NAD83 / LCC Statcan",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-91.866667],PARAMETER["latitude_of_origin",63.390675],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",77],PARAMETER["false_easting",6200000],PARAMETER["false_northing",3000000],UNIT["Meter",1]]
+45555=PROJCS["WRF_Lambert_Conformal_Conic 2",GEOGCS["GCS_North_American_1983",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.25722356300003]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943299]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",-97],PARAMETER["Standard_Parallel_1",33],PARAMETER["Standard_Parallel_2",60],PARAMETER["Latitude_Of_Origin",40.003338],UNIT["Meter",1],AUTHORITY["EPSG","45555"]]
+45556=PROJCS["Albers Equal area",GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AUTHORITY["EPSG","4326"]], PROJECTION["Albers Equal Area", AUTHORITY["EPSG","9822"]], PARAMETER["central_meridian", -96.0], PARAMETER["latitude_of_origin", 37.5], PARAMETER["standard_parallel_1", 29.833333333333336], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0], PARAMETER["standard_parallel_2", 45.833333333333336], UNIT["m", 1.0], AUTHORITY["EPSG","45556"]]
+53001=PROJCS["Sphere_Plate_Carree",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Plate_Carree"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53002=PROJCS["Sphere_Equidistant_Cylindrical",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Equidistant_Cylindrical"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",60.0],UNIT["Meter",1.0]]
+53003=PROJCS["Sphere_Miller_Cylindrical",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Miller_Cylindrical"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53004=PROJCS["Sphere_Mercator",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",0.0],UNIT["Meter",1.0]]
+53008=PROJCS["Sphere_Sinusoidal",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Sinusoidal"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53009=PROJCS["Sphere_Mollweide",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mollweide"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53010=PROJCS["Sphere_Eckert_VI",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Eckert_VI"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53011=PROJCS["Sphere_Eckert_V",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Eckert_V"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53012=PROJCS["Sphere_Eckert_IV",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Eckert_IV"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53013=PROJCS["Sphere_Eckert_III",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Eckert_III"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53014=PROJCS["Sphere_Eckert_II",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Eckert_II"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53015=PROJCS["Sphere_Eckert_I",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Eckert_I"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53016=PROJCS["Sphere_Gall_Stereographic",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gall_Stereographic"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53017=PROJCS["Sphere_Behrmann",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Behrmann"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53018=PROJCS["Sphere_Winkel_I",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Winkel_I"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",50.45977625218981],UNIT["Meter",1.0]]
+53019=PROJCS["Sphere_Winkel_II",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Winkel_II"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",50.45977625218981],UNIT["Meter",1.0]]
+53021=PROJCS["Sphere_Polyconic",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Polyconic"],PARAMETER["Central_Meridian",0.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+53022=PROJCS["Sphere_Quartic_Authalic",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Quartic_Authalic"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53023=PROJCS["Sphere_Loximuthal",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Loximuthal"],PARAMETER["Central_Meridian",0.0],PARAMETER["Central_Parallel",40.0],UNIT["Meter",1.0]]
+53024=PROJCS["Sphere_Bonne",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Bonne"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",60.0],UNIT["Meter",1.0]]
+53025=PROJCS["Sphere_Hotine",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Two_Point_Natural_Origin"],PARAMETER["Latitude_Of_1st_Point",0.0],PARAMETER["Latitude_Of_2nd_Point",60.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Longitude_Of_1st_Point",0.0],PARAMETER["Longitude_Of_2nd_Point",60.0],PARAMETER["Latitude_Of_Center",40.0],UNIT["Meter",1.0]]
+53026=PROJCS["Sphere_Stereographic",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Stereographic"],PARAMETER["Central_Meridian",0.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+53027=PROJCS["Sphere_Equidistant_Conic",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Equidistant_Conic"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",60.0],PARAMETER["Standard_Parallel_2",60.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+53028=PROJCS["Sphere_Cassini",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Cassini"],PARAMETER["Central_Meridian",0.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+53029=PROJCS["Sphere_Van_der_Grinten_I",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Van_der_Grinten_I"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53030=PROJCS["Sphere_Robinson",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Robinson"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53031=PROJCS["Sphere_Two_Point_Equidistant",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Two_Point_Equidistant"],PARAMETER["Latitude_Of_1st_Point",0.0],PARAMETER["Latitude_Of_2nd_Point",60.0],PARAMETER["Longitude_Of_1st_Point",0.0],PARAMETER["Longitude_Of_2nd_Point",60.0],UNIT["Meter",1.0]]
+53032=PROJCS["Sphere_Azimuthal_Equidistant",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Azimuthal_Equidistant"],PARAMETER["Central_Meridian",0.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+53034=PROJCS["Sphere_Cylindrical_Equal_Area",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Cylindrical_Equal_Area"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",0.0],UNIT["Meter",1.0]]
+53042=PROJCS["Sphere_Winkel_Tripel_NGS",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Winkel_Tripel"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",50.467],UNIT["Meter",1.0]]
+53043=PROJCS["Sphere_Aitoff",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Aitoff"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53044=PROJCS["Sphere_Hammer_Aitoff",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hammer_Aitoff"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53045=PROJCS["Sphere_Flat_Polar_Quartic",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Flat_Polar_Quartic"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53046=PROJCS["Sphere_Craster_Parabolic",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Craster_Parabolic"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53048=PROJCS["Sphere_Times",GEOGCS["GCS_Sphere",DATUM["D_Sphere",SPHEROID["Sphere",6371000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Times"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+53049=PROJCS["Sphere_Vertical_Perspective",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Vertical_Near_Side_Perspective"],PARAMETER["Longitude_Of_Center",0.0],PARAMETER["Latitude_Of_Center",0.0],PARAMETER["Height",35800000.0],UNIT["Meter",1.0]]
+54001=PROJCS["World_Plate_Carree",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Plate_Carree"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54002=PROJCS["World_Equidistant_Cylindrical",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Equidistant_Cylindrical"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",60.0],UNIT["Meter",1.0]]
+54003=PROJCS["World_Miller_Cylindrical",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Miller_Cylindrical"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54004=PROJCS["World_Mercator",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",0.0],UNIT["Meter",1.0]]
+54008=PROJCS["World_Sinusoidal",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Sinusoidal"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54009=PROJCS["World_Mollweide",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mollweide"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54010=PROJCS["World_Eckert_VI",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Eckert_VI"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54011=PROJCS["World_Eckert_V",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Eckert_V"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54012=PROJCS["World_Eckert_IV",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Eckert_IV"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54013=PROJCS["World_Eckert_III",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Eckert_III"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54014=PROJCS["World_Eckert_II",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Eckert_II"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54015=PROJCS["World_Eckert_I",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Eckert_I"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54016=PROJCS["World_Gall_Stereographic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gall_Stereographic"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54017=PROJCS["World_Behrmann",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Behrmann"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54018=PROJCS["World_Winkel_I",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Winkel_I"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",50.45977625218981],UNIT["Meter",1.0]]
+54019=PROJCS["World_Winkel_II",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Winkel_II"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",50.45977625218981],UNIT["Meter",1.0]]
+54021=PROJCS["World_Polyconic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Polyconic"],PARAMETER["Central_Meridian",0.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+54022=PROJCS["World_Quartic_Authalic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Quartic_Authalic"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54023=PROJCS["World_Loximuthal",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Loximuthal"],PARAMETER["Central_Meridian",0.0],PARAMETER["Central_Parallel",40.0],UNIT["Meter",1.0]]
+54024=PROJCS["World_Bonne",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Bonne"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",60.0],UNIT["Meter",1.0]]
+54025=PROJCS["World_Hotine",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Two_Point_Natural_Origin"],PARAMETER["Latitude_Of_1st_Point",0.0],PARAMETER["Latitude_Of_2nd_Point",60.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Longitude_Of_1st_Point",0.0],PARAMETER["Longitude_Of_2nd_Point",60.0],PARAMETER["Latitude_Of_Center",40.0],UNIT["Meter",1.0]]
+54026=PROJCS["World_Stereographic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Stereographic"],PARAMETER["Central_Meridian",0.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+54027=PROJCS["World_Equidistant_Conic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Equidistant_Conic"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",60.0],PARAMETER["Standard_Parallel_2",60.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+54028=PROJCS["World_Cassini",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Cassini"],PARAMETER["Central_Meridian",0.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+54029=PROJCS["World_Van_der_Grinten_I",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Van_der_Grinten_I"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54030=PROJCS["World_Robinson",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Robinson"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54031=PROJCS["World_Two_Point_Equidistant",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Two_Point_Equidistant"],PARAMETER["Latitude_Of_1st_Point",0.0],PARAMETER["Latitude_Of_2nd_Point",60.0],PARAMETER["Longitude_Of_1st_Point",0.0],PARAMETER["Longitude_Of_2nd_Point",60.0],UNIT["Meter",1.0]]
+54032=PROJCS["World_Azimuthal_Equidistant",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Azimuthal_Equidistant"],PARAMETER["Central_Meridian",0.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+54034=PROJCS["World_Cylindrical_Equal_Area",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Cylindrical_Equal_Area"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",0.0],UNIT["Meter",1.0]]
+54042=PROJCS["World_Winkel_Tripel_NGS",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Winkel_Tripel"],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",50.467],UNIT["Meter",1.0]]
+54043=PROJCS["World_Aitoff",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Aitoff"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54044=PROJCS["World_Hammer_Aitoff",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hammer_Aitoff"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54045=PROJCS["World_Flat_Polar_Quartic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Flat_Polar_Quartic"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54046=PROJCS["World_Craster_Parabolic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Craster_Parabolic"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54048=PROJCS["World_Times",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Times"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]
+54049=PROJCS["World_Vertical_Perspective",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Vertical_Near_Side_Perspective"],PARAMETER["Longitude_Of_Center",0.0],PARAMETER["Latitude_Of_Center",0.0],PARAMETER["Height",35800000.0],UNIT["Meter",1.0]]
+65061=PROJCS["NAD_1927_StatePlane_Guam_FIPS_5400",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Polyconic"],PARAMETER["False_Easting",164041.6666666667],PARAMETER["False_Northing",164041.6666666667],PARAMETER["Central_Meridian",-144.7487507055556],PARAMETER["Latitude_Of_Origin",13.47246635277778],UNIT["Foot_US",0.3048006096012192]]
+65062=PROJCS["American_Samoa_1962_StatePlane_American_Samoa_FIPS_5300",GEOGCS["GCS_American_Samoa_1962",DATUM["D_American_Samoa_1962",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-170.0],PARAMETER["Standard_Parallel_1",-14.26666666666667],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",-14.26666666666667],UNIT["Foot_US",0.3048006096012192]]
+65161=PROJCS["NAD_1983_StatePlane_Guam_FIPS_5400",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Polyconic"],PARAMETER["False_Easting",50000.0],PARAMETER["False_Northing",50000.0],PARAMETER["Central_Meridian",-144.7487507055556],PARAMETER["Latitude_Of_Origin",13.47246635277778],UNIT["Meter",1.0]]
+65163=PROJCS["NAD_1983_StatePlane_Kentucky_FIPS_1600",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1500000.0],PARAMETER["False_Northing",1000000.0],PARAMETER["Central_Meridian",-85.75],PARAMETER["Standard_Parallel_1",37.08333333333334],PARAMETER["Standard_Parallel_2",38.66666666666666],PARAMETER["Latitude_Of_Origin",36.33333333333334],UNIT["Meter",1.0]]
+102001=PROJCS["Canada_Albers_Equal_Area_Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["Central_Meridian",-96.0],PARAMETER["Standard_Parallel_1",50.0],PARAMETER["Standard_Parallel_2",70.0],PARAMETER["Latitude_Of_Origin",40.0],UNIT["Meter",1.0]]
+102002=PROJCS["Canada_Lambert_Conformal_Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["Central_Meridian",-96.0],PARAMETER["Standard_Parallel_1",50.0],PARAMETER["Standard_Parallel_2",70.0],PARAMETER["Latitude_Of_Origin",40.0],UNIT["Meter",1.0]]
+102003=PROJCS["USA_Contiguous_Albers_Equal_Area_Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["Central_Meridian",-96.0],PARAMETER["Standard_Parallel_1",29.5],PARAMETER["Standard_Parallel_2",45.5],PARAMETER["Latitude_Of_Origin",37.5],UNIT["Meter",1.0]]
+102004=PROJCS["USA_Contiguous_Lambert_Conformal_Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["Central_Meridian",-96.0],PARAMETER["Standard_Parallel_1",33.0],PARAMETER["Standard_Parallel_2",45.0],PARAMETER["Latitude_Of_Origin",39.0],UNIT["Meter",1.0]]
+102005=PROJCS["USA_Contiguous_Equidistant_Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Equidistant_Conic"],PARAMETER["Central_Meridian",-96.0],PARAMETER["Standard_Parallel_1",33.0],PARAMETER["Standard_Parallel_2",45.0],PARAMETER["Latitude_Of_Origin",39.0],UNIT["Meter",1.0]]
+102006=PROJCS["Alaska_Albers_Equal_Area_Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["Central_Meridian",-154.0],PARAMETER["Standard_Parallel_1",55.0],PARAMETER["Standard_Parallel_2",65.0],PARAMETER["Latitude_Of_Origin",50.0],UNIT["Meter",1.0]]
+102007=PROJCS["Hawaii_Albers_Equal_Area_Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["Central_Meridian",-157.0],PARAMETER["Standard_Parallel_1",8.0],PARAMETER["Standard_Parallel_2",18.0],PARAMETER["Latitude_Of_Origin",13.0],UNIT["Meter",1.0]]
+102008=PROJCS["North_America_Albers_Equal_Area_Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["Central_Meridian",-96.0],PARAMETER["Standard_Parallel_1",20.0],PARAMETER["Standard_Parallel_2",60.0],PARAMETER["Latitude_Of_Origin",40.0],UNIT["Meter",1.0]]
+102009=PROJCS["North_America_Lambert_Conformal_Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["Central_Meridian",-96.0],PARAMETER["Standard_Parallel_1",20.0],PARAMETER["Standard_Parallel_2",60.0],PARAMETER["Latitude_Of_Origin",40.0],UNIT["Meter",1.0]]
+102010=PROJCS["North_America_Equidistant_Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Equidistant_Conic"],PARAMETER["Central_Meridian",-96.0],PARAMETER["Standard_Parallel_1",20.0],PARAMETER["Standard_Parallel_2",60.0],PARAMETER["Latitude_Of_Origin",40.0],UNIT["Meter",1.0]]
+102011=PROJCS["Africa_Sinusoidal",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Sinusoidal"],PARAMETER["Central_Meridian",15.0],UNIT["Meter",1.0]]
+102012=PROJCS["Asia_Lambert_Conformal_Conic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["Central_Meridian",105.0],PARAMETER["Standard_Parallel_1",30.0],PARAMETER["Standard_Parallel_2",62.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102013=PROJCS["Europe_Albers_Equal_Area_Conic",GEOGCS["GCS_European_1950",DATUM["D_European_1950",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["Central_Meridian",10.0],PARAMETER["Standard_Parallel_1",43.0],PARAMETER["Standard_Parallel_2",62.0],PARAMETER["Latitude_Of_Origin",30.0],UNIT["Meter",1.0]]
+102014=PROJCS["Europe_Lambert_Conformal_Conic",GEOGCS["GCS_European_1950",DATUM["D_European_1950",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["Central_Meridian",10.0],PARAMETER["Standard_Parallel_1",43.0],PARAMETER["Standard_Parallel_2",62.0],PARAMETER["Latitude_Of_Origin",30.0],UNIT["Meter",1.0]]
+102015=PROJCS["South_America_Lambert_Conformal_Conic",GEOGCS["GCS_South_American_1969",DATUM["D_South_American_1969",SPHEROID["GRS_1967_Truncated",6378160.0,298.25]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["Central_Meridian",-60.0],PARAMETER["Standard_Parallel_1",-5.0],PARAMETER["Standard_Parallel_2",-42.0],PARAMETER["Latitude_Of_Origin",-32.0],UNIT["Meter",1.0]]
+102016=PROJCS["North_Pole_Azimuthal_Equidistant",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Azimuthal_Equidistant"],PARAMETER["Central_Meridian",0.0],PARAMETER["Latitude_Of_Origin",90.0],UNIT["Meter",1.0]]
+102017=PROJCS["North_Pole_Lambert_Azimuthal_Equal_Area",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Azimuthal_Equal_Area"],PARAMETER["Central_Meridian",0.0],PARAMETER["Latitude_Of_Origin",90.0],UNIT["Meter",1.0]]
+102018=PROJCS["North_Pole_Stereographic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Stereographic"],PARAMETER["Central_Meridian",0.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",90.0],UNIT["Meter",1.0]]
+102019=PROJCS["South_Pole_Azimuthal_Equidistant",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Azimuthal_Equidistant"],PARAMETER["Central_Meridian",0.0],PARAMETER["Latitude_Of_Origin",-90.0],UNIT["Meter",1.0]]
+102020=PROJCS["South_Pole_Lambert_Azimuthal_Equal_Area",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Azimuthal_Equal_Area"],PARAMETER["Central_Meridian",0.0],PARAMETER["Latitude_Of_Origin",-90.0],UNIT["Meter",1.0]]
+102021=PROJCS["South_Pole_Stereographic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Stereographic"],PARAMETER["Central_Meridian",0.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",-90.0],UNIT["Meter",1.0]]
+102022=PROJCS["Africa_Albers_Equal_Area_Conic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["Central_Meridian",25.0],PARAMETER["Standard_Parallel_1",20.0],PARAMETER["Standard_Parallel_2",-23.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102023=PROJCS["Africa_Equidistant_Conic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Equidistant_Conic"],PARAMETER["Central_Meridian",25.0],PARAMETER["Standard_Parallel_1",20.0],PARAMETER["Standard_Parallel_2",-23.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102024=PROJCS["Africa_Lambert_Conformal_Conic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["Central_Meridian",25.0],PARAMETER["Standard_Parallel_1",20.0],PARAMETER["Standard_Parallel_2",-23.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102025=PROJCS["Asia_North_Albers_Equal_Area_Conic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["Central_Meridian",95.0],PARAMETER["Standard_Parallel_1",15.0],PARAMETER["Standard_Parallel_2",65.0],PARAMETER["Latitude_Of_Origin",30.0],UNIT["Meter",1.0]]
+102026=PROJCS["Asia_North_Equidistant_Conic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Equidistant_Conic"],PARAMETER["Central_Meridian",95.0],PARAMETER["Standard_Parallel_1",15.0],PARAMETER["Standard_Parallel_2",65.0],PARAMETER["Latitude_Of_Origin",30.0],UNIT["Meter",1.0]]
+102027=PROJCS["Asia_North_Lambert_Conformal_Conic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["Central_Meridian",95.0],PARAMETER["Standard_Parallel_1",15.0],PARAMETER["Standard_Parallel_2",65.0],PARAMETER["Latitude_Of_Origin",30.0],UNIT["Meter",1.0]]
+102028=PROJCS["Asia_South_Albers_Equal_Area_Conic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["Central_Meridian",125.0],PARAMETER["Standard_Parallel_1",7.0],PARAMETER["Standard_Parallel_2",-32.0],PARAMETER["Latitude_Of_Origin",-15.0],UNIT["Meter",1.0]]
+102029=PROJCS["Asia_South_Equidistant_Conic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Equidistant_Conic"],PARAMETER["Central_Meridian",125.0],PARAMETER["Standard_Parallel_1",7.0],PARAMETER["Standard_Parallel_2",-32.0],PARAMETER["Latitude_Of_Origin",-15.0],UNIT["Meter",1.0]]
+102030=PROJCS["Asia_South_Lambert_Conformal_Conic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["Central_Meridian",125.0],PARAMETER["Standard_Parallel_1",7.0],PARAMETER["Standard_Parallel_2",-32.0],PARAMETER["Latitude_Of_Origin",-15.0],UNIT["Meter",1.0]]
+102031=PROJCS["Europe_Equidistant_Conic",GEOGCS["GCS_European_1950",DATUM["D_European_1950",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Equidistant_Conic"],PARAMETER["Central_Meridian",10.0],PARAMETER["Standard_Parallel_1",43.0],PARAMETER["Standard_Parallel_2",62.0],PARAMETER["Latitude_Of_Origin",30.0],UNIT["Meter",1.0]]
+102032=PROJCS["South_America_Equidistant_Conic",GEOGCS["GCS_South_American_1969",DATUM["D_South_American_1969",SPHEROID["GRS_1967_Truncated",6378160.0,298.25]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Equidistant_Conic"],PARAMETER["Central_Meridian",-60.0],PARAMETER["Standard_Parallel_1",-5.0],PARAMETER["Standard_Parallel_2",-42.0],PARAMETER["Latitude_Of_Origin",-32.0],UNIT["Meter",1.0]]
+102033=PROJCS["South_America_Albers_Equal_Area_Conic",GEOGCS["GCS_South_American_1969",DATUM["D_South_American_1969",SPHEROID["GRS_1967_Truncated",6378160.0,298.25]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["Central_Meridian",-60.0],PARAMETER["Standard_Parallel_1",-5.0],PARAMETER["Standard_Parallel_2",-42.0],PARAMETER["Latitude_Of_Origin",-32.0],UNIT["Meter",1.0]]
+102034=PROJCS["North_Pole_Gnomonic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gnomonic"],PARAMETER["Longitude_Of_Center",0.0],PARAMETER["Latitude_Of_Center",90.0],UNIT["Meter",1.0]]
+102035=PROJCS["North_Pole_Orthographic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Orthographic"],PARAMETER["Longitude_Of_Center",0.0],PARAMETER["Latitude_Of_Center",90.0],UNIT["Meter",1.0]]
+102036=PROJCS["South_Pole_Gnomonic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gnomonic"],PARAMETER["Longitude_Of_Center",0.0],PARAMETER["Latitude_Of_Center",-90.0],UNIT["Meter",1.0]]
+102037=PROJCS["South_Pole_Orthographic",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Orthographic"],PARAMETER["Longitude_Of_Center",0.0],PARAMETER["Latitude_Of_Center",-90.0],UNIT["Meter",1.0]]
+102038=PROJCS["The_World_From_Space",GEOGCS["GCS_Sphere_ARC_INFO",DATUM["D_Sphere_ARC_INFO",SPHEROID["Sphere_ARC_INFO",6370997.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Orthographic"],PARAMETER["Longitude_Of_Center",-72.5333333334],PARAMETER["Latitude_Of_Center",42.5333333333],UNIT["Meter",1.0]]
+102039=PROJCS["USA_Contiguous_Albers_Equal_Area_Conic_USGS_version",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["Central_Meridian",-96.0],PARAMETER["Standard_Parallel_1",29.5],PARAMETER["Standard_Parallel_2",45.5],PARAMETER["Latitude_Of_Origin",23.0],UNIT["Meter",1.0]]
+102065=PROJCS["S-JTSK_Krovak",GEOGCS["GCS_S_JTSK",DATUM["D_S_JTSK",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Krovak"],PARAMETER["Pseudo_Standard_Parallel_1",78.5],PARAMETER["Scale_Factor",0.9999],PARAMETER["Azimuth",30.28813975277778],PARAMETER["Longitude_Of_Center",24.83333333333333],PARAMETER["Latitude_Of_Center",49.5],PARAMETER["X_Scale",1.0],PARAMETER["Y_Scale",1.0],PARAMETER["XY_Plane_Rotation",0.0],UNIT["Meter",1.0]]
+102066=PROJCS["S-JTSK_Ferro_Krovak_East_North",GEOGCS["GCS_S_JTSK_Ferro",DATUM["D_S_JTSK",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Ferro",-17.66666666666667],UNIT["Degree",0.0174532925199433]],PROJECTION["Krovak"],PARAMETER["Pseudo_Standard_Parallel_1",78.5],PARAMETER["Scale_Factor",0.9999],PARAMETER["Azimuth",30.28813975277778],PARAMETER["Longitude_Of_Center",42.5],PARAMETER["Latitude_Of_Center",49.5],PARAMETER["X_Scale",-1.0],PARAMETER["Y_Scale",1.0],PARAMETER["XY_Plane_Rotation",90.0],UNIT["Meter",1.0]]
+102067=PROJCS["S-JTSK_Krovak_East_North",GEOGCS["GCS_S_JTSK",DATUM["D_S_JTSK",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Krovak"],PARAMETER["Pseudo_Standard_Parallel_1",78.5],PARAMETER["Scale_Factor",0.9999],PARAMETER["Azimuth",30.28813975277778],PARAMETER["Longitude_Of_Center",24.83333333333333],PARAMETER["Latitude_Of_Center",49.5],PARAMETER["X_Scale",-1.0],PARAMETER["Y_Scale",1.0],PARAMETER["XY_Plane_Rotation",90.0],UNIT["Meter",1.0]]
+102091=PROJCS["Monte_Mario_Italy_1",GEOGCS["GCS_Monte_Mario",DATUM["D_Monte_Mario",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1500000.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102092=PROJCS["Monte_Mario_Italy_2",GEOGCS["GCS_Monte_Mario",DATUM["D_Monte_Mario",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",2520000.0],PARAMETER["Central_Meridian",15.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102101=PROJCS["NGO_1948_Norway_Zone_1",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",6.05625],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",58.0],UNIT["Meter",1.0]]
+102102=PROJCS["NGO_1948_Norway_Zone_2",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",8.389583333333333],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",58.0],UNIT["Meter",1.0]]
+102103=PROJCS["NGO_1948_Norway_Zone_3",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",10.72291666666667],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",58.0],UNIT["Meter",1.0]]
+102104=PROJCS["NGO_1948_Norway_Zone_4",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",13.22291666666667],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",58.0],UNIT["Meter",1.0]]
+102105=PROJCS["NGO_1948_Norway_Zone_5",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",16.88958333333333],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",58.0],UNIT["Meter",1.0]]
+102106=PROJCS["NGO_1948_Norway_Zone_6",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",20.88958333333333],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",58.0],UNIT["Meter",1.0]]
+102107=PROJCS["NGO_1948_Norway_Zone_7",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",24.88958333333333],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",58.0],UNIT["Meter",1.0]]
+102108=PROJCS["NGO_1948_Norway_Zone_8",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",29.05625],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",58.0],UNIT["Meter",1.0]]
+102110=PROJCS["RGF_1993_Lambert_93",GEOGCS["GCS_RGF_1993",DATUM["D_RGF_1993",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",700000.0],PARAMETER["False_Northing",6600000.0],PARAMETER["Central_Meridian",3.0],PARAMETER["Standard_Parallel_1",44.0],PARAMETER["Standard_Parallel_2",49.0],PARAMETER["Latitude_Of_Origin",46.5],UNIT["Meter",1.0]]
+102114=PROJCS["Old_Hawaiian_UTM_Zone_4N",GEOGCS["GCS_Old_Hawaiian",DATUM["D_Old_Hawaiian",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-159.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102115=PROJCS["Old_Hawaiian_UTM_Zone_5N",GEOGCS["GCS_Old_Hawaiian",DATUM["D_Old_Hawaiian",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-153.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102120=PROJCS["NAD_1927_Michigan_GeoRef_Feet_US",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Natural_Origin"],PARAMETER["False_Easting",8355401.583],PARAMETER["False_Northing",-14284780.538],PARAMETER["Scale_Factor",0.9996],PARAMETER["Azimuth",337.255555555556],PARAMETER["Longitude_Of_Center",-86.0],PARAMETER["Latitude_Of_Center",45.30916666666666],UNIT["Foot_US",0.3048006096012192]]
+102121=PROJCS["NAD_1983_Michigan_GeoRef_Feet_US",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Natural_Origin"],PARAMETER["False_Easting",8355401.583],PARAMETER["False_Northing",-14284780.538],PARAMETER["Scale_Factor",0.9996],PARAMETER["Azimuth",337.255555555556],PARAMETER["Longitude_Of_Center",-86.0],PARAMETER["Latitude_Of_Center",45.30916666666666],UNIT["Foot_US",0.3048006096012192]]
+102122=PROJCS["NAD_1927_Michigan_GeoRef_Meters",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Natural_Origin"],PARAMETER["False_Easting",2546731.496],PARAMETER["False_Northing",-4354009.816],PARAMETER["Scale_Factor",0.9996],PARAMETER["Azimuth",337.255555555556],PARAMETER["Longitude_Of_Center",-86.0],PARAMETER["Latitude_Of_Center",45.30916666666666],UNIT["Meter",1.0]]
+102123=PROJCS["NAD_1983_Michigan_GeoRef_Meters",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Natural_Origin"],PARAMETER["False_Easting",2546731.496],PARAMETER["False_Northing",-4354009.816],PARAMETER["Scale_Factor",0.9996],PARAMETER["Azimuth",337.255555555556],PARAMETER["Longitude_Of_Center",-86.0],PARAMETER["Latitude_Of_Center",45.30916666666666],UNIT["Meter",1.0]]
+102132=PROJCS["NGO_1948_UTM_Zone_32N",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102133=PROJCS["NGO_1948_UTM_Zone_33N",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",15.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102134=PROJCS["NGO_1948_UTM_Zone_34N",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",21.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102135=PROJCS["NGO_1948_UTM_Zone_35N",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",27.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102136=PROJCS["NGO_1948_Baerum_Kommune",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",19999.32],PARAMETER["False_Northing",-202977.79],PARAMETER["Central_Meridian",10.72291666666667],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",58.0],UNIT["Meter",1.0]]
+102137=PROJCS["NGO_1948_Bergenhalvoen",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",100000.0],PARAMETER["False_Northing",-200000.0],PARAMETER["Central_Meridian",6.05625],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",58.0],UNIT["Meter",1.0]]
+102138=PROJCS["NGO_1948_Oslo_Kommune",GEOGCS["GCS_NGO_1948",DATUM["D_NGO_1948",SPHEROID["Bessel_Modified",6377492.018,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Northing",-212979.18],PARAMETER["Central_Meridian",10.72291666666667],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",58.0],UNIT["Meter",1.0]]
+102140=PROJCS["Hong_Kong_1980_Grid",GEOGCS["GCS_Hong_Kong_1980",DATUM["D_Hong_Kong_1980",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",836694.05],PARAMETER["False_Northing",819069.8],PARAMETER["Central_Meridian",114.1785555555556],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",22.31213333333334],UNIT["Meter",1.0]]
+102141=PROJCS["Hong_Kong_1980_UTM_Zone_49N",GEOGCS["GCS_Hong_Kong_1980",DATUM["D_Hong_Kong_1980",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",111.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102142=PROJCS["Hong_Kong_1980_UTM_Zone_50N",GEOGCS["GCS_Hong_Kong_1980",DATUM["D_Hong_Kong_1980",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",117.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102151=PROJCS["Tokyo_UTM_Zone_51N",GEOGCS["GCS_Tokyo",DATUM["D_Tokyo",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",123.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102152=PROJCS["Tokyo_UTM_Zone_52N",GEOGCS["GCS_Tokyo",DATUM["D_Tokyo",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",129.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102153=PROJCS["Tokyo_UTM_Zone_53N",GEOGCS["GCS_Tokyo",DATUM["D_Tokyo",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",135.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102154=PROJCS["Tokyo_UTM_Zone_54N",GEOGCS["GCS_Tokyo",DATUM["D_Tokyo",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",141.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102155=PROJCS["Tokyo_UTM_Zone_55N",GEOGCS["GCS_Tokyo",DATUM["D_Tokyo",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",147.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102156=PROJCS["Tokyo_UTM_Zone_56N",GEOGCS["GCS_Tokyo",DATUM["D_Tokyo",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",153.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102160=PROJCS["Datum_73_Hayford_Gauss_IGeoE",GEOGCS["GCS_Datum_73",DATUM["D_Datum_73",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",200180.598],PARAMETER["False_Northing",299913.01],PARAMETER["Central_Meridian",-8.131906111111112],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",39.66666666666666],UNIT["Meter",1.0]]
+102161=PROJCS["Datum_73_Hayford_Gauss_IPCC",GEOGCS["GCS_Datum_73",DATUM["D_Datum_73",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",180.598],PARAMETER["False_Northing",-86.99],PARAMETER["Central_Meridian",-8.131906111111112],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",39.66666666666666],UNIT["Meter",1.0]]
+102162=PROJCS["Graciosa_Base_SW_1948_UTM_Zone_26N",GEOGCS["GCS_Graciosa_Base_SW_1948",DATUM["D_Graciosa_Base_SW_1948",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-27.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102163=PROJCS["Lisboa_Bessel_Bonne",GEOGCS["GCS_Datum_Lisboa_Bessel",DATUM["D_Datum_Lisboa_Bessel",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Bonne"],PARAMETER["Central_Meridian",-8.131906111111112],PARAMETER["Standard_Parallel_1",39.66666666666666],UNIT["Meter",1.0]]
+102164=PROJCS["Lisboa_Hayford_Gauss_IGeoE",GEOGCS["GCS_Datum_Lisboa_Hayford",DATUM["D_Datum_Lisboa_Hayford",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",200000.0],PARAMETER["False_Northing",300000.0],PARAMETER["Central_Meridian",-8.131906111111112],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",39.66666666666666],UNIT["Meter",1.0]]
+102165=PROJCS["Lisboa_Hayford_Gauss_IPCC",GEOGCS["GCS_Datum_Lisboa_Hayford",DATUM["D_Datum_Lisboa_Hayford",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",-8.131906111111112],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",39.66666666666666],UNIT["Meter",1.0]]
+102166=PROJCS["Observ_Meteorologico_1939_UTM_Zone_25N",GEOGCS["GCS_Observ_Meteorologico_1939",DATUM["D_Observ_Meteorologico_1939",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-33.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102167=PROJCS["Porto_Santo_1936_UTM_Zone_28N",GEOGCS["GCS_Porto_Santo_1936",DATUM["D_Porto_Santo_1936",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-15.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102168=PROJCS["Sao_Braz_UTM_Zone_26N",GEOGCS["GCS_Sao_Braz",DATUM["D_Sao_Braz",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-27.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102169=PROJCS["Selvagem_Grande_1938_UTM_Zone_28N",GEOGCS["GCS_Selvagem_Grande_1938",DATUM["D_Selvagem_Grande_1938",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-15.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102170=PROJCS["AGD_1966_VICGRID",GEOGCS["GCS_Australian_1966",DATUM["D_Australian_1966",SPHEROID["Australian",6378160.0,298.25]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2500000.0],PARAMETER["False_Northing",4500000.0],PARAMETER["Central_Meridian",145.0],PARAMETER["Standard_Parallel_1",-36.0],PARAMETER["Standard_Parallel_2",-38.0],PARAMETER["Latitude_Of_Origin",-37.0],UNIT["Meter",1.0]]
+102171=PROJCS["GDA_1994_VICGRID94",GEOGCS["GCS_GDA_1994",DATUM["D_GDA_1994",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2500000.0],PARAMETER["False_Northing",2500000.0],PARAMETER["Central_Meridian",145.0],PARAMETER["Standard_Parallel_1",-36.0],PARAMETER["Standard_Parallel_2",-38.0],PARAMETER["Latitude_Of_Origin",-37.0],UNIT["Meter",1.0]]
+102172=PROJCS["GDA_1994_South_Australia_Lambert",GEOGCS["GCS_GDA_1994",DATUM["D_GDA_1994",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1000000.0],PARAMETER["False_Northing",2000000.0],PARAMETER["Central_Meridian",135.0],PARAMETER["Standard_Parallel_1",-28.0],PARAMETER["Standard_Parallel_2",-36.0],PARAMETER["Latitude_Of_Origin",-32.5],UNIT["Meter",1.0]]
+102178=PROJCS["NAD_1927_10TM_AEP_Forest",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-115.0],PARAMETER["Scale_Factor",0.9992],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102179=PROJCS["NAD_1927_10TM_AEP_Resource",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",-115.0],PARAMETER["Scale_Factor",0.9992],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102180=PROJCS["NAD_1927_3TM_111",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",-111.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102181=PROJCS["NAD_1927_3TM_114",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",-114.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102182=PROJCS["NAD_1927_3TM_117",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",-117.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102183=PROJCS["NAD_1927_3TM_120",GEOGCS["GCS_North_American_1927",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",-120.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102184=PROJCS["NAD_1983_10TM_AEP_Forest",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-115.0],PARAMETER["Scale_Factor",0.9992],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102185=PROJCS["NAD_1983_10TM_AEP_Resource",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",-115.0],PARAMETER["Scale_Factor",0.9992],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102186=PROJCS["NAD_1983_3TM_111",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",-111.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102187=PROJCS["NAD_1983_3TM_114",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",-114.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102188=PROJCS["NAD_1983_3TM_117",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",-117.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102189=PROJCS["NAD_1983_3TM_120",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",-120.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102190=PROJCS["NAD_1983_BC_Albers",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["False_Easting",1000000.0],PARAMETER["Central_Meridian",-126.0],PARAMETER["Standard_Parallel_1",50.0],PARAMETER["Standard_Parallel_2",58.5],PARAMETER["Latitude_Of_Origin",45.0],UNIT["Meter",1.0]]
+102191=PROJCS["Nord_Maroc_Degree",GEOGCS["GCS_Merchich_Degree",DATUM["D_Merchich",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",300000.0],PARAMETER["Central_Meridian",-5.4],PARAMETER["Standard_Parallel_1",33.3],PARAMETER["Scale_Factor",0.999625769],PARAMETER["Latitude_Of_Origin",33.3],UNIT["Meter",1.0]]
+102192=PROJCS["Sud_Maroc_Degree",GEOGCS["GCS_Merchich_Degree",DATUM["D_Merchich",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",300000.0],PARAMETER["Central_Meridian",-5.4],PARAMETER["Standard_Parallel_1",29.7],PARAMETER["Scale_Factor",0.999615596],PARAMETER["Latitude_Of_Origin",29.7],UNIT["Meter",1.0]]
+102193=PROJCS["Sahara_Degree",GEOGCS["GCS_Merchich_Degree",DATUM["D_Merchich",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1200000.0],PARAMETER["False_Northing",400000.0],PARAMETER["Central_Meridian",-5.4],PARAMETER["Standard_Parallel_1",26.1],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",26.1],UNIT["Meter",1.0]]
+102194=PROJCS["UWPP_1992",GEOGCS["GCS_ETRF_1989",DATUM["D_ETRF_1989",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",-5300000.0],PARAMETER["Central_Meridian",19.0],PARAMETER["Scale_Factor",0.9993],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102195=PROJCS["UWPP_2000_PAS_5",GEOGCS["GCS_ETRF_1989",DATUM["D_ETRF_1989",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",5500000.0],PARAMETER["Central_Meridian",15.0],PARAMETER["Scale_Factor",0.999923],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102196=PROJCS["UWPP_2000_PAS_6",GEOGCS["GCS_ETRF_1989",DATUM["D_ETRF_1989",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",6500000.0],PARAMETER["Central_Meridian",18.0],PARAMETER["Scale_Factor",0.999923],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102197=PROJCS["UWPP_2000_PAS_7",GEOGCS["GCS_ETRF_1989",DATUM["D_ETRF_1989",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",7500000.0],PARAMETER["Central_Meridian",21.0],PARAMETER["Scale_Factor",0.999923],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102198=PROJCS["UWPP_2000_PAS_8",GEOGCS["GCS_ETRF_1989",DATUM["D_ETRF_1989",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",8500000.0],PARAMETER["Central_Meridian",24.0],PARAMETER["Scale_Factor",0.999923],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102200=PROJCS["NAD_1983_HARN_UTM_Zone_2S",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",10000000.0],PARAMETER["Central_Meridian",-171.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
+102201=PROJCS["NAD_1983_HARN_Guam_Map_Grid",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",100000.0],PARAMETER["False_Northing",200000.0],PARAMETER["Central_Meridian",144.75],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",13.5],UNIT["Meter",1.0]]
+102229=PROJCS["NAD_1983_HARN_StatePlane_Alabama_East_FIPS_0101",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",200000.0],PARAMETER["Central_Meridian",-85.83333333333333],PARAMETER["Scale_Factor",0.99996],PARAMETER["Latitude_Of_Origin",30.5],UNIT["Meter",1.0]]
+102230=PROJCS["NAD_1983_HARN_StatePlane_Alabama_West_FIPS_0102",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-87.5],PARAMETER["Scale_Factor",0.9999333333333333],PARAMETER["Latitude_Of_Origin",30.0],UNIT["Meter",1.0]]
+102241=PROJCS["NAD_1983_HARN_StatePlane_California_I_FIPS_0401",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2000000.0],PARAMETER["False_Northing",500000.0],PARAMETER["Central_Meridian",-122.0],PARAMETER["Standard_Parallel_1",40.0],PARAMETER["Standard_Parallel_2",41.66666666666666],PARAMETER["Latitude_Of_Origin",39.33333333333334],UNIT["Meter",1.0]]
+102242=PROJCS["NAD_1983_HARN_StatePlane_California_II_FIPS_0402",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2000000.0],PARAMETER["False_Northing",500000.0],PARAMETER["Central_Meridian",-122.0],PARAMETER["Standard_Parallel_1",38.33333333333334],PARAMETER["Standard_Parallel_2",39.83333333333334],PARAMETER["Latitude_Of_Origin",37.66666666666666],UNIT["Meter",1.0]]
+102243=PROJCS["NAD_1983_HARN_StatePlane_California_III_FIPS_0403",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2000000.0],PARAMETER["False_Northing",500000.0],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",37.06666666666667],PARAMETER["Standard_Parallel_2",38.43333333333333],PARAMETER["Latitude_Of_Origin",36.5],UNIT["Meter",1.0]]
+102244=PROJCS["NAD_1983_HARN_StatePlane_California_IV_FIPS_0404",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2000000.0],PARAMETER["False_Northing",500000.0],PARAMETER["Central_Meridian",-119.0],PARAMETER["Standard_Parallel_1",36.0],PARAMETER["Standard_Parallel_2",37.25],PARAMETER["Latitude_Of_Origin",35.33333333333334],UNIT["Meter",1.0]]
+102245=PROJCS["NAD_1983_HARN_StatePlane_California_V_FIPS_0405",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2000000.0],PARAMETER["False_Northing",500000.0],PARAMETER["Central_Meridian",-118.0],PARAMETER["Standard_Parallel_1",34.03333333333333],PARAMETER["Standard_Parallel_2",35.46666666666667],PARAMETER["Latitude_Of_Origin",33.5],UNIT["Meter",1.0]]
+102246=PROJCS["NAD_1983_HARN_StatePlane_California_VI_FIPS_0406",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2000000.0],PARAMETER["False_Northing",500000.0],PARAMETER["Central_Meridian",-116.25],PARAMETER["Standard_Parallel_1",32.78333333333333],PARAMETER["Standard_Parallel_2",33.88333333333333],PARAMETER["Latitude_Of_Origin",32.16666666666666],UNIT["Meter",1.0]]
+102248=PROJCS["NAD_1983_HARN_StatePlane_Arizona_East_FIPS_0201",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",213360.0],PARAMETER["Central_Meridian",-110.1666666666667],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",31.0],UNIT["Meter",1.0]]
+102249=PROJCS["NAD_1983_HARN_StatePlane_Arizona_Central_FIPS_0202",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",213360.0],PARAMETER["Central_Meridian",-111.9166666666667],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",31.0],UNIT["Meter",1.0]]
+102250=PROJCS["NAD_1983_HARN_StatePlane_Arizona_West_FIPS_0203",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",213360.0],PARAMETER["Central_Meridian",-113.75],PARAMETER["Scale_Factor",0.9999333333333333],PARAMETER["Latitude_Of_Origin",31.0],UNIT["Meter",1.0]]
+102251=PROJCS["NAD_1983_HARN_StatePlane_Arkansas_North_FIPS_0301",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",400000.0],PARAMETER["Central_Meridian",-92.0],PARAMETER["Standard_Parallel_1",34.93333333333333],PARAMETER["Standard_Parallel_2",36.23333333333333],PARAMETER["Latitude_Of_Origin",34.33333333333334],UNIT["Meter",1.0]]
+102252=PROJCS["NAD_1983_HARN_StatePlane_Arkansas_South_FIPS_0302",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",400000.0],PARAMETER["False_Northing",400000.0],PARAMETER["Central_Meridian",-92.0],PARAMETER["Standard_Parallel_1",33.3],PARAMETER["Standard_Parallel_2",34.76666666666667],PARAMETER["Latitude_Of_Origin",32.66666666666666],UNIT["Meter",1.0]]
+102253=PROJCS["NAD_1983_HARN_StatePlane_Colorado_North_FIPS_0501",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",914401.8289],PARAMETER["False_Northing",304800.6096],PARAMETER["Central_Meridian",-105.5],PARAMETER["Standard_Parallel_1",39.71666666666667],PARAMETER["Standard_Parallel_2",40.78333333333333],PARAMETER["Latitude_Of_Origin",39.33333333333334],UNIT["Meter",1.0]]
+102254=PROJCS["NAD_1983_HARN_StatePlane_Colorado_Central_FIPS_0502",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",914401.8289],PARAMETER["False_Northing",304800.6096],PARAMETER["Central_Meridian",-105.5],PARAMETER["Standard_Parallel_1",38.45],PARAMETER["Standard_Parallel_2",39.75],PARAMETER["Latitude_Of_Origin",37.83333333333334],UNIT["Meter",1.0]]
+102255=PROJCS["NAD_1983_HARN_StatePlane_Colorado_South_FIPS_0503",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",914401.8289],PARAMETER["False_Northing",304800.6096],PARAMETER["Central_Meridian",-105.5],PARAMETER["Standard_Parallel_1",37.23333333333333],PARAMETER["Standard_Parallel_2",38.43333333333333],PARAMETER["Latitude_Of_Origin",36.66666666666666],UNIT["Meter",1.0]]
+102256=PROJCS["NAD_1983_HARN_StatePlane_Connecticut_FIPS_0600",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",304800.6096],PARAMETER["False_Northing",152400.3048],PARAMETER["Central_Meridian",-72.75],PARAMETER["Standard_Parallel_1",41.2],PARAMETER["Standard_Parallel_2",41.86666666666667],PARAMETER["Latitude_Of_Origin",40.83333333333334],UNIT["Meter",1.0]]
+102257=PROJCS["NAD_1983_HARN_StatePlane_Delaware_FIPS_0700",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",200000.0],PARAMETER["Central_Meridian",-75.41666666666667],PARAMETER["Scale_Factor",0.999995],PARAMETER["Latitude_Of_Origin",38.0],UNIT["Meter",1.0]]
+102258=PROJCS["NAD_1983_HARN_StatePlane_Florida_East_FIPS_0901",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",200000.0],PARAMETER["Central_Meridian",-81.0],PARAMETER["Scale_Factor",0.9999411764705882],PARAMETER["Latitude_Of_Origin",24.33333333333333],UNIT["Meter",1.0]]
+102259=PROJCS["NAD_1983_HARN_StatePlane_Florida_West_FIPS_0902",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",200000.0],PARAMETER["Central_Meridian",-82.0],PARAMETER["Scale_Factor",0.9999411764705882],PARAMETER["Latitude_Of_Origin",24.33333333333333],UNIT["Meter",1.0]]
+102260=PROJCS["NAD_1983_HARN_StatePlane_Florida_North_FIPS_0903",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-84.5],PARAMETER["Standard_Parallel_1",29.58333333333333],PARAMETER["Standard_Parallel_2",30.75],PARAMETER["Latitude_Of_Origin",29.0],UNIT["Meter",1.0]]
+102261=PROJCS["NAD_1983_HARN_StatePlane_Hawaii_1_FIPS_5101",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-155.5],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",18.83333333333333],UNIT["Meter",1.0]]
+102262=PROJCS["NAD_1983_HARN_StatePlane_Hawaii_2_FIPS_5102",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-156.6666666666667],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",20.33333333333333],UNIT["Meter",1.0]]
+102263=PROJCS["NAD_1983_HARN_StatePlane_Hawaii_3_FIPS_5103",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-158.0],PARAMETER["Scale_Factor",0.99999],PARAMETER["Latitude_Of_Origin",21.16666666666667],UNIT["Meter",1.0]]
+102264=PROJCS["NAD_1983_HARN_StatePlane_Hawaii_4_FIPS_5104",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-159.5],PARAMETER["Scale_Factor",0.99999],PARAMETER["Latitude_Of_Origin",21.83333333333333],UNIT["Meter",1.0]]
+102265=PROJCS["NAD_1983_HARN_StatePlane_Hawaii_5_FIPS_5105",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-160.1666666666667],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",21.66666666666667],UNIT["Meter",1.0]]
+102266=PROJCS["NAD_1983_HARN_StatePlane_Georgia_East_FIPS_1001",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",200000.0],PARAMETER["Central_Meridian",-82.16666666666667],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",30.0],UNIT["Meter",1.0]]
+102267=PROJCS["NAD_1983_HARN_StatePlane_Georgia_West_FIPS_1002",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",700000.0],PARAMETER["Central_Meridian",-84.16666666666667],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",30.0],UNIT["Meter",1.0]]
+102268=PROJCS["NAD_1983_HARN_StatePlane_Idaho_East_FIPS_1101",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",200000.0],PARAMETER["Central_Meridian",-112.1666666666667],PARAMETER["Scale_Factor",0.9999473684210526],PARAMETER["Latitude_Of_Origin",41.66666666666666],UNIT["Meter",1.0]]
+102269=PROJCS["NAD_1983_HARN_StatePlane_Idaho_Central_FIPS_1102",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-114.0],PARAMETER["Scale_Factor",0.9999473684210526],PARAMETER["Latitude_Of_Origin",41.66666666666666],UNIT["Meter",1.0]]
+102270=PROJCS["NAD_1983_HARN_StatePlane_Idaho_West_FIPS_1103",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",800000.0],PARAMETER["Central_Meridian",-115.75],PARAMETER["Scale_Factor",0.9999333333333333],PARAMETER["Latitude_Of_Origin",41.66666666666666],UNIT["Meter",1.0]]
+102271=PROJCS["NAD_1983_HARN_StatePlane_Illinois_East_FIPS_1201",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",300000.0],PARAMETER["Central_Meridian",-88.33333333333333],PARAMETER["Scale_Factor",0.999975],PARAMETER["Latitude_Of_Origin",36.66666666666666],UNIT["Meter",1.0]]
+102272=PROJCS["NAD_1983_HARN_StatePlane_Illinois_West_FIPS_1202",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",700000.0],PARAMETER["Central_Meridian",-90.16666666666667],PARAMETER["Scale_Factor",0.9999411764705882],PARAMETER["Latitude_Of_Origin",36.66666666666666],UNIT["Meter",1.0]]
+102273=PROJCS["NAD_1983_HARN_StatePlane_Indiana_East_FIPS_1301",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",100000.0],PARAMETER["False_Northing",250000.0],PARAMETER["Central_Meridian",-85.66666666666667],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",37.5],UNIT["Meter",1.0]]
+102274=PROJCS["NAD_1983_HARN_StatePlane_Indiana_West_FIPS_1302",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",900000.0],PARAMETER["False_Northing",250000.0],PARAMETER["Central_Meridian",-87.08333333333333],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",37.5],UNIT["Meter",1.0]]
+102277=PROJCS["NAD_1983_HARN_StatePlane_Kansas_North_FIPS_1501",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",400000.0],PARAMETER["Central_Meridian",-98.0],PARAMETER["Standard_Parallel_1",38.71666666666667],PARAMETER["Standard_Parallel_2",39.78333333333333],PARAMETER["Latitude_Of_Origin",38.33333333333334],UNIT["Meter",1.0]]
+102278=PROJCS["NAD_1983_HARN_StatePlane_Kansas_South_FIPS_1502",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",400000.0],PARAMETER["False_Northing",400000.0],PARAMETER["Central_Meridian",-98.5],PARAMETER["Standard_Parallel_1",37.26666666666667],PARAMETER["Standard_Parallel_2",38.56666666666667],PARAMETER["Latitude_Of_Origin",36.66666666666666],UNIT["Meter",1.0]]
+102279=PROJCS["NAD_1983_HARN_StatePlane_Kentucky_North_FIPS_1601",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-84.25],PARAMETER["Standard_Parallel_1",37.96666666666667],PARAMETER["Standard_Parallel_2",38.96666666666667],PARAMETER["Latitude_Of_Origin",37.5],UNIT["Meter",1.0]]
+102280=PROJCS["NAD_1983_HARN_StatePlane_Kentucky_South_FIPS_1602",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",500000.0],PARAMETER["Central_Meridian",-85.75],PARAMETER["Standard_Parallel_1",36.73333333333333],PARAMETER["Standard_Parallel_2",37.93333333333333],PARAMETER["Latitude_Of_Origin",36.33333333333334],UNIT["Meter",1.0]]
+102281=PROJCS["NAD_1983_HARN_StatePlane_Louisiana_North_FIPS_1701",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1000000.0],PARAMETER["Central_Meridian",-92.5],PARAMETER["Standard_Parallel_1",31.16666666666667],PARAMETER["Standard_Parallel_2",32.66666666666666],PARAMETER["Latitude_Of_Origin",30.5],UNIT["Meter",1.0]]
+102282=PROJCS["NAD_1983_HARN_StatePlane_Louisiana_South_FIPS_1702",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1000000.0],PARAMETER["Central_Meridian",-91.33333333333333],PARAMETER["Standard_Parallel_1",29.3],PARAMETER["Standard_Parallel_2",30.7],PARAMETER["Latitude_Of_Origin",28.5],UNIT["Meter",1.0]]
+102283=PROJCS["NAD_1983_HARN_StatePlane_Maine_East_FIPS_1801",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",300000.0],PARAMETER["Central_Meridian",-68.5],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",43.66666666666666],UNIT["Meter",1.0]]
+102284=PROJCS["NAD_1983_HARN_StatePlane_Maine_West_FIPS_1802",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",900000.0],PARAMETER["Central_Meridian",-70.16666666666667],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",42.83333333333334],UNIT["Meter",1.0]]
+102285=PROJCS["NAD_1983_HARN_StatePlane_Maryland_FIPS_1900",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",400000.0],PARAMETER["Central_Meridian",-77.0],PARAMETER["Standard_Parallel_1",38.3],PARAMETER["Standard_Parallel_2",39.45],PARAMETER["Latitude_Of_Origin",37.66666666666666],UNIT["Meter",1.0]]
+102286=PROJCS["NAD_1983_HARN_StatePlane_Massachusetts_Mainland_FIPS_2001",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",200000.0],PARAMETER["False_Northing",750000.0],PARAMETER["Central_Meridian",-71.5],PARAMETER["Standard_Parallel_1",41.71666666666667],PARAMETER["Standard_Parallel_2",42.68333333333333],PARAMETER["Latitude_Of_Origin",41.0],UNIT["Meter",1.0]]
+102287=PROJCS["NAD_1983_HARN_StatePlane_Massachusetts_Island_FIPS_2002",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-70.5],PARAMETER["Standard_Parallel_1",41.28333333333333],PARAMETER["Standard_Parallel_2",41.48333333333333],PARAMETER["Latitude_Of_Origin",41.0],UNIT["Meter",1.0]]
+102288=PROJCS["NAD_1983_HARN_StatePlane_Michigan_North_FIPS_2111",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",8000000.0],PARAMETER["Central_Meridian",-87.0],PARAMETER["Standard_Parallel_1",45.48333333333333],PARAMETER["Standard_Parallel_2",47.08333333333334],PARAMETER["Latitude_Of_Origin",44.78333333333333],UNIT["Meter",1.0]]
+102289=PROJCS["NAD_1983_HARN_StatePlane_Michigan_Central_FIPS_2112",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6000000.0],PARAMETER["Central_Meridian",-84.36666666666666],PARAMETER["Standard_Parallel_1",44.18333333333333],PARAMETER["Standard_Parallel_2",45.7],PARAMETER["Latitude_Of_Origin",43.31666666666667],UNIT["Meter",1.0]]
+102290=PROJCS["NAD_1983_HARN_StatePlane_Michigan_South_FIPS_2113",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",4000000.0],PARAMETER["Central_Meridian",-84.36666666666666],PARAMETER["Standard_Parallel_1",42.1],PARAMETER["Standard_Parallel_2",43.66666666666666],PARAMETER["Latitude_Of_Origin",41.5],UNIT["Meter",1.0]]
+102291=PROJCS["NAD_1983_HARN_StatePlane_Minnesota_North_FIPS_2201",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",800000.0],PARAMETER["False_Northing",100000.0],PARAMETER["Central_Meridian",-93.1],PARAMETER["Standard_Parallel_1",47.03333333333333],PARAMETER["Standard_Parallel_2",48.63333333333333],PARAMETER["Latitude_Of_Origin",46.5],UNIT["Meter",1.0]]
+102292=PROJCS["NAD_1983_HARN_StatePlane_Minnesota_Central_FIPS_2202",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",800000.0],PARAMETER["False_Northing",100000.0],PARAMETER["Central_Meridian",-94.25],PARAMETER["Standard_Parallel_1",45.61666666666667],PARAMETER["Standard_Parallel_2",47.05],PARAMETER["Latitude_Of_Origin",45.0],UNIT["Meter",1.0]]
+102293=PROJCS["NAD_1983_HARN_StatePlane_Minnesota_South_FIPS_2203",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",800000.0],PARAMETER["False_Northing",100000.0],PARAMETER["Central_Meridian",-94.0],PARAMETER["Standard_Parallel_1",43.78333333333333],PARAMETER["Standard_Parallel_2",45.21666666666667],PARAMETER["Latitude_Of_Origin",43.0],UNIT["Meter",1.0]]
+102294=PROJCS["NAD_1983_HARN_StatePlane_Mississippi_East_FIPS_2301",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",300000.0],PARAMETER["Central_Meridian",-88.83333333333333],PARAMETER["Scale_Factor",0.99995],PARAMETER["Latitude_Of_Origin",29.5],UNIT["Meter",1.0]]
+102295=PROJCS["NAD_1983_HARN_StatePlane_Mississippi_West_FIPS_2302",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",700000.0],PARAMETER["Central_Meridian",-90.33333333333333],PARAMETER["Scale_Factor",0.99995],PARAMETER["Latitude_Of_Origin",29.5],UNIT["Meter",1.0]]
+102296=PROJCS["NAD_1983_HARN_StatePlane_Missouri_East_FIPS_2401",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",250000.0],PARAMETER["Central_Meridian",-90.5],PARAMETER["Scale_Factor",0.9999333333333333],PARAMETER["Latitude_Of_Origin",35.83333333333334],UNIT["Meter",1.0]]
+102297=PROJCS["NAD_1983_HARN_StatePlane_Missouri_Central_FIPS_2402",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-92.5],PARAMETER["Scale_Factor",0.9999333333333333],PARAMETER["Latitude_Of_Origin",35.83333333333334],UNIT["Meter",1.0]]
+102298=PROJCS["NAD_1983_HARN_StatePlane_Missouri_West_FIPS_2403",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",850000.0],PARAMETER["Central_Meridian",-94.5],PARAMETER["Scale_Factor",0.9999411764705882],PARAMETER["Latitude_Of_Origin",36.16666666666666],UNIT["Meter",1.0]]
+102300=PROJCS["NAD_1983_HARN_StatePlane_Montana_FIPS_2500",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-109.5],PARAMETER["Standard_Parallel_1",45.0],PARAMETER["Standard_Parallel_2",49.0],PARAMETER["Latitude_Of_Origin",44.25],UNIT["Meter",1.0]]
+102304=PROJCS["NAD_1983_HARN_StatePlane_Nebraska_FIPS_2600",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-100.0],PARAMETER["Standard_Parallel_1",40.0],PARAMETER["Standard_Parallel_2",43.0],PARAMETER["Latitude_Of_Origin",39.83333333333334],UNIT["Meter",1.0]]
+102307=PROJCS["NAD_1983_HARN_StatePlane_Nevada_East_FIPS_2701",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",200000.0],PARAMETER["False_Northing",8000000.0],PARAMETER["Central_Meridian",-115.5833333333333],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",34.75],UNIT["Meter",1.0]]
+102308=PROJCS["NAD_1983_HARN_StatePlane_Nevada_Central_FIPS_2702",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",6000000.0],PARAMETER["Central_Meridian",-116.6666666666667],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",34.75],UNIT["Meter",1.0]]
+102309=PROJCS["NAD_1983_HARN_StatePlane_Nevada_West_FIPS_2703",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",800000.0],PARAMETER["False_Northing",4000000.0],PARAMETER["Central_Meridian",-118.5833333333333],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",34.75],UNIT["Meter",1.0]]
+102310=PROJCS["NAD_1983_HARN_StatePlane_New_Hampshire_FIPS_2800",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",300000.0],PARAMETER["Central_Meridian",-71.66666666666667],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",42.5],UNIT["Meter",1.0]]
+102311=PROJCS["NAD_1983_HARN_StatePlane_New_Jersey_FIPS_2900",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",150000.0],PARAMETER["Central_Meridian",-74.5],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",38.83333333333334],UNIT["Meter",1.0]]
+102312=PROJCS["NAD_1983_HARN_StatePlane_New_Mexico_East_FIPS_3001",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",165000.0],PARAMETER["Central_Meridian",-104.3333333333333],PARAMETER["Scale_Factor",0.9999090909090909],PARAMETER["Latitude_Of_Origin",31.0],UNIT["Meter",1.0]]
+102313=PROJCS["NAD_1983_HARN_StatePlane_New_Mexico_Central_FIPS_3002",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-106.25],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",31.0],UNIT["Meter",1.0]]
+102314=PROJCS["NAD_1983_HARN_StatePlane_New_Mexico_West_FIPS_3003",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",830000.0],PARAMETER["Central_Meridian",-107.8333333333333],PARAMETER["Scale_Factor",0.9999166666666667],PARAMETER["Latitude_Of_Origin",31.0],UNIT["Meter",1.0]]
+102315=PROJCS["NAD_1983_HARN_StatePlane_New_York_East_FIPS_3101",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",150000.0],PARAMETER["Central_Meridian",-74.5],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",38.83333333333334],UNIT["Meter",1.0]]
+102316=PROJCS["NAD_1983_HARN_StatePlane_New_York_Central_FIPS_3102",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",250000.0],PARAMETER["Central_Meridian",-76.58333333333333],PARAMETER["Scale_Factor",0.9999375],PARAMETER["Latitude_Of_Origin",40.0],UNIT["Meter",1.0]]
+102317=PROJCS["NAD_1983_HARN_StatePlane_New_York_West_FIPS_3103",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",350000.0],PARAMETER["Central_Meridian",-78.58333333333333],PARAMETER["Scale_Factor",0.9999375],PARAMETER["Latitude_Of_Origin",40.0],UNIT["Meter",1.0]]
+102318=PROJCS["NAD_1983_HARN_StatePlane_New_York_Long_Island_FIPS_3104",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",300000.0],PARAMETER["Central_Meridian",-74.0],PARAMETER["Standard_Parallel_1",40.66666666666666],PARAMETER["Standard_Parallel_2",41.03333333333333],PARAMETER["Latitude_Of_Origin",40.16666666666666],UNIT["Meter",1.0]]
+102320=PROJCS["NAD_1983_HARN_StatePlane_North_Dakota_North_FIPS_3301",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-100.5],PARAMETER["Standard_Parallel_1",47.43333333333333],PARAMETER["Standard_Parallel_2",48.73333333333333],PARAMETER["Latitude_Of_Origin",47.0],UNIT["Meter",1.0]]
+102321=PROJCS["NAD_1983_HARN_StatePlane_North_Dakota_South_FIPS_3302",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-100.5],PARAMETER["Standard_Parallel_1",46.18333333333333],PARAMETER["Standard_Parallel_2",47.48333333333333],PARAMETER["Latitude_Of_Origin",45.66666666666666],UNIT["Meter",1.0]]
+102322=PROJCS["NAD_1983_HARN_StatePlane_Ohio_North_FIPS_3401",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-82.5],PARAMETER["Standard_Parallel_1",40.43333333333333],PARAMETER["Standard_Parallel_2",41.7],PARAMETER["Latitude_Of_Origin",39.66666666666666],UNIT["Meter",1.0]]
+102323=PROJCS["NAD_1983_HARN_StatePlane_Ohio_South_FIPS_3402",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-82.5],PARAMETER["Standard_Parallel_1",38.73333333333333],PARAMETER["Standard_Parallel_2",40.03333333333333],PARAMETER["Latitude_Of_Origin",38.0],UNIT["Meter",1.0]]
+102324=PROJCS["NAD_1983_HARN_StatePlane_Oklahoma_North_FIPS_3501",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-98.0],PARAMETER["Standard_Parallel_1",35.56666666666667],PARAMETER["Standard_Parallel_2",36.76666666666667],PARAMETER["Latitude_Of_Origin",35.0],UNIT["Meter",1.0]]
+102325=PROJCS["NAD_1983_HARN_StatePlane_Oklahoma_South_FIPS_3502",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-98.0],PARAMETER["Standard_Parallel_1",33.93333333333333],PARAMETER["Standard_Parallel_2",35.23333333333333],PARAMETER["Latitude_Of_Origin",33.33333333333334],UNIT["Meter",1.0]]
+102326=PROJCS["NAD_1983_HARN_StatePlane_Oregon_North_FIPS_3601",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2500000.0],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",44.33333333333334],PARAMETER["Standard_Parallel_2",46.0],PARAMETER["Latitude_Of_Origin",43.66666666666666],UNIT["Meter",1.0]]
+102327=PROJCS["NAD_1983_HARN_StatePlane_Oregon_South_FIPS_3602",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1500000.0],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",42.33333333333334],PARAMETER["Standard_Parallel_2",44.0],PARAMETER["Latitude_Of_Origin",41.66666666666666],UNIT["Meter",1.0]]
+102330=PROJCS["NAD_1983_HARN_StatePlane_Rhode_Island_FIPS_3800",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",100000.0],PARAMETER["Central_Meridian",-71.5],PARAMETER["Scale_Factor",0.99999375],PARAMETER["Latitude_Of_Origin",41.08333333333334],UNIT["Meter",1.0]]
+102334=PROJCS["NAD_1983_HARN_StatePlane_South_Dakota_North_FIPS_4001",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-100.0],PARAMETER["Standard_Parallel_1",44.41666666666666],PARAMETER["Standard_Parallel_2",45.68333333333333],PARAMETER["Latitude_Of_Origin",43.83333333333334],UNIT["Meter",1.0]]
+102335=PROJCS["NAD_1983_HARN_StatePlane_South_Dakota_South_FIPS_4002",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-100.3333333333333],PARAMETER["Standard_Parallel_1",42.83333333333334],PARAMETER["Standard_Parallel_2",44.4],PARAMETER["Latitude_Of_Origin",42.33333333333334],UNIT["Meter",1.0]]
+102336=PROJCS["NAD_1983_HARN_StatePlane_Tennessee_FIPS_4100",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-86.0],PARAMETER["Standard_Parallel_1",35.25],PARAMETER["Standard_Parallel_2",36.41666666666666],PARAMETER["Latitude_Of_Origin",34.33333333333334],UNIT["Meter",1.0]]
+102337=PROJCS["NAD_1983_HARN_StatePlane_Texas_North_FIPS_4201",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",200000.0],PARAMETER["False_Northing",1000000.0],PARAMETER["Central_Meridian",-101.5],PARAMETER["Standard_Parallel_1",34.65],PARAMETER["Standard_Parallel_2",36.18333333333333],PARAMETER["Latitude_Of_Origin",34.0],UNIT["Meter",1.0]]
+102338=PROJCS["NAD_1983_HARN_StatePlane_Texas_North_Central_FIPS_4202",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["False_Northing",2000000.0],PARAMETER["Central_Meridian",-98.5],PARAMETER["Standard_Parallel_1",32.13333333333333],PARAMETER["Standard_Parallel_2",33.96666666666667],PARAMETER["Latitude_Of_Origin",31.66666666666667],UNIT["Meter",1.0]]
+102339=PROJCS["NAD_1983_HARN_StatePlane_Texas_Central_FIPS_4203",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",700000.0],PARAMETER["False_Northing",3000000.0],PARAMETER["Central_Meridian",-100.3333333333333],PARAMETER["Standard_Parallel_1",30.11666666666667],PARAMETER["Standard_Parallel_2",31.88333333333333],PARAMETER["Latitude_Of_Origin",29.66666666666667],UNIT["Meter",1.0]]
+102340=PROJCS["NAD_1983_HARN_StatePlane_Texas_South_Central_FIPS_4204",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["False_Northing",4000000.0],PARAMETER["Central_Meridian",-99.0],PARAMETER["Standard_Parallel_1",28.38333333333333],PARAMETER["Standard_Parallel_2",30.28333333333334],PARAMETER["Latitude_Of_Origin",27.83333333333333],UNIT["Meter",1.0]]
+102341=PROJCS["NAD_1983_HARN_StatePlane_Texas_South_FIPS_4205",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",300000.0],PARAMETER["False_Northing",5000000.0],PARAMETER["Central_Meridian",-98.5],PARAMETER["Standard_Parallel_1",26.16666666666667],PARAMETER["Standard_Parallel_2",27.83333333333333],PARAMETER["Latitude_Of_Origin",25.66666666666667],UNIT["Meter",1.0]]
+102342=PROJCS["NAD_1983_HARN_StatePlane_Utah_North_FIPS_4301",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",1000000.0],PARAMETER["Central_Meridian",-111.5],PARAMETER["Standard_Parallel_1",40.71666666666667],PARAMETER["Standard_Parallel_2",41.78333333333333],PARAMETER["Latitude_Of_Origin",40.33333333333334],UNIT["Meter",1.0]]
+102343=PROJCS["NAD_1983_HARN_StatePlane_Utah_Central_FIPS_4302",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",2000000.0],PARAMETER["Central_Meridian",-111.5],PARAMETER["Standard_Parallel_1",39.01666666666667],PARAMETER["Standard_Parallel_2",40.65],PARAMETER["Latitude_Of_Origin",38.33333333333334],UNIT["Meter",1.0]]
+102344=PROJCS["NAD_1983_HARN_StatePlane_Utah_South_FIPS_4303",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",3000000.0],PARAMETER["Central_Meridian",-111.5],PARAMETER["Standard_Parallel_1",37.21666666666667],PARAMETER["Standard_Parallel_2",38.35],PARAMETER["Latitude_Of_Origin",36.66666666666666],UNIT["Meter",1.0]]
+102345=PROJCS["NAD_1983_HARN_StatePlane_Vermont_FIPS_4400",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-72.5],PARAMETER["Scale_Factor",0.9999642857142858],PARAMETER["Latitude_Of_Origin",42.5],UNIT["Meter",1.0]]
+102346=PROJCS["NAD_1983_HARN_StatePlane_Virginia_North_FIPS_4501",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",3500000.0],PARAMETER["False_Northing",2000000.0],PARAMETER["Central_Meridian",-78.5],PARAMETER["Standard_Parallel_1",38.03333333333333],PARAMETER["Standard_Parallel_2",39.2],PARAMETER["Latitude_Of_Origin",37.66666666666666],UNIT["Meter",1.0]]
+102347=PROJCS["NAD_1983_HARN_StatePlane_Virginia_South_FIPS_4502",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",3500000.0],PARAMETER["False_Northing",1000000.0],PARAMETER["Central_Meridian",-78.5],PARAMETER["Standard_Parallel_1",36.76666666666667],PARAMETER["Standard_Parallel_2",37.96666666666667],PARAMETER["Latitude_Of_Origin",36.33333333333334],UNIT["Meter",1.0]]
+102348=PROJCS["NAD_1983_HARN_StatePlane_Washington_North_FIPS_4601",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-120.8333333333333],PARAMETER["Standard_Parallel_1",47.5],PARAMETER["Standard_Parallel_2",48.73333333333333],PARAMETER["Latitude_Of_Origin",47.0],UNIT["Meter",1.0]]
+102349=PROJCS["NAD_1983_HARN_StatePlane_Washington_South_FIPS_4602",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",45.83333333333334],PARAMETER["Standard_Parallel_2",47.33333333333334],PARAMETER["Latitude_Of_Origin",45.33333333333334],UNIT["Meter",1.0]]
+102350=PROJCS["NAD_1983_HARN_StatePlane_West_Virginia_North_FIPS_4701",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-79.5],PARAMETER["Standard_Parallel_1",39.0],PARAMETER["Standard_Parallel_2",40.25],PARAMETER["Latitude_Of_Origin",38.5],UNIT["Meter",1.0]]
+102351=PROJCS["NAD_1983_HARN_StatePlane_West_Virginia_South_FIPS_4702",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-81.0],PARAMETER["Standard_Parallel_1",37.48333333333333],PARAMETER["Standard_Parallel_2",38.88333333333333],PARAMETER["Latitude_Of_Origin",37.0],UNIT["Meter",1.0]]
+102352=PROJCS["NAD_1983_HARN_StatePlane_Wisconsin_North_FIPS_4801",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-90.0],PARAMETER["Standard_Parallel_1",45.56666666666667],PARAMETER["Standard_Parallel_2",46.76666666666667],PARAMETER["Latitude_Of_Origin",45.16666666666666],UNIT["Meter",1.0]]
+102353=PROJCS["NAD_1983_HARN_StatePlane_Wisconsin_Central_FIPS_4802",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-90.0],PARAMETER["Standard_Parallel_1",44.25],PARAMETER["Standard_Parallel_2",45.5],PARAMETER["Latitude_Of_Origin",43.83333333333334],UNIT["Meter",1.0]]
+102354=PROJCS["NAD_1983_HARN_StatePlane_Wisconsin_South_FIPS_4803",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-90.0],PARAMETER["Standard_Parallel_1",42.73333333333333],PARAMETER["Standard_Parallel_2",44.06666666666667],PARAMETER["Latitude_Of_Origin",42.0],UNIT["Meter",1.0]]
+102355=PROJCS["NAD_1983_HARN_StatePlane_Wyoming_East_FIPS_4901",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",200000.0],PARAMETER["Central_Meridian",-105.1666666666667],PARAMETER["Scale_Factor",0.9999375],PARAMETER["Latitude_Of_Origin",40.5],UNIT["Meter",1.0]]
+102356=PROJCS["NAD_1983_HARN_StatePlane_Wyoming_East_Central_FIPS_4902",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",400000.0],PARAMETER["False_Northing",100000.0],PARAMETER["Central_Meridian",-107.3333333333333],PARAMETER["Scale_Factor",0.9999375],PARAMETER["Latitude_Of_Origin",40.5],UNIT["Meter",1.0]]
+102357=PROJCS["NAD_1983_HARN_StatePlane_Wyoming_West_Central_FIPS_4903",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",600000.0],PARAMETER["Central_Meridian",-108.75],PARAMETER["Scale_Factor",0.9999375],PARAMETER["Latitude_Of_Origin",40.5],UNIT["Meter",1.0]]
+102358=PROJCS["NAD_1983_HARN_StatePlane_Wyoming_West_FIPS_4904",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",800000.0],PARAMETER["False_Northing",100000.0],PARAMETER["Central_Meridian",-110.0833333333333],PARAMETER["Scale_Factor",0.9999375],PARAMETER["Latitude_Of_Origin",40.5],UNIT["Meter",1.0]]
+102361=PROJCS["NAD_1983_HARN_StatePlane_Puerto_Rico_Virgin_Islands_FIPS_5200",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",200000.0],PARAMETER["False_Northing",200000.0],PARAMETER["Central_Meridian",-66.43333333333334],PARAMETER["Standard_Parallel_1",18.03333333333334],PARAMETER["Standard_Parallel_2",18.43333333333333],PARAMETER["Latitude_Of_Origin",17.83333333333333],UNIT["Meter",1.0]]
+102363=PROJCS["NAD_1983_HARN_StatePlane_Kentucky_FIPS_1600",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1500000.0],PARAMETER["False_Northing",1000000.0],PARAMETER["Central_Meridian",-85.75],PARAMETER["Standard_Parallel_1",37.08333333333334],PARAMETER["Standard_Parallel_2",38.66666666666666],PARAMETER["Latitude_Of_Origin",36.33333333333334],UNIT["Meter",1.0]]
+102491=PROJCS["Nord_Algerie_Ancienne_Degree",GEOGCS["GCS_Voirol_1875_Degree",DATUM["D_Voirol_1875",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",300000.0],PARAMETER["Central_Meridian",2.7],PARAMETER["Standard_Parallel_1",36.0],PARAMETER["Scale_Factor",0.999625544],PARAMETER["Latitude_Of_Origin",36.0],UNIT["Meter",1.0]]
+102492=PROJCS["Sud_Algerie_Ancienne_Degree",GEOGCS["GCS_Voirol_1875_Degree",DATUM["D_Voirol_1875",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",300000.0],PARAMETER["Central_Meridian",2.7],PARAMETER["Standard_Parallel_1",33.3],PARAMETER["Scale_Factor",0.999625769],PARAMETER["Latitude_Of_Origin",33.3],UNIT["Meter",1.0]]
+102581=PROJCS["NTF_France_I_degrees",GEOGCS["GCS_NTF",DATUM["D_NTF",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["False_Northing",1200000.0],PARAMETER["Central_Meridian",2.337229166666667],PARAMETER["Standard_Parallel_1",49.5],PARAMETER["Scale_Factor",0.999877341],PARAMETER["Latitude_Of_Origin",49.5],UNIT["Meter",1.0]]
+102582=PROJCS["NTF_France_II_degrees",GEOGCS["GCS_NTF",DATUM["D_NTF",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["False_Northing",2200000.0],PARAMETER["Central_Meridian",2.337229166666667],PARAMETER["Standard_Parallel_1",46.8],PARAMETER["Scale_Factor",0.99987742],PARAMETER["Latitude_Of_Origin",46.8],UNIT["Meter",1.0]]
+102583=PROJCS["NTF_France_III_degrees",GEOGCS["GCS_NTF",DATUM["D_NTF",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["False_Northing",3200000.0],PARAMETER["Central_Meridian",2.337229166666667],PARAMETER["Standard_Parallel_1",44.1],PARAMETER["Scale_Factor",0.999877499],PARAMETER["Latitude_Of_Origin",44.1],UNIT["Meter",1.0]]
+102584=PROJCS["NTF_France_IV_degrees",GEOGCS["GCS_NTF",DATUM["D_NTF",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",234.358],PARAMETER["False_Northing",185861.369],PARAMETER["Central_Meridian",2.337229166666667],PARAMETER["Standard_Parallel_1",42.165],PARAMETER["Scale_Factor",0.99994471],PARAMETER["Latitude_Of_Origin",42.165],UNIT["Meter",1.0]]
+102591=PROJCS["Nord_Algerie_Degree",GEOGCS["GCS_Voirol_Unifie_1960_Degree",DATUM["D_Voirol_Unifie_1960",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500135.0],PARAMETER["False_Northing",300090.0],PARAMETER["Central_Meridian",2.7],PARAMETER["Standard_Parallel_1",36.0],PARAMETER["Scale_Factor",0.999625544],PARAMETER["Latitude_Of_Origin",36.0],UNIT["Meter",1.0]]
+102592=PROJCS["Sud_Algerie_Degree",GEOGCS["GCS_Voirol_Unifie_1960_Degree",DATUM["D_Voirol_Unifie_1960",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500135.0],PARAMETER["False_Northing",300090.0],PARAMETER["Central_Meridian",2.7],PARAMETER["Standard_Parallel_1",33.3],PARAMETER["Scale_Factor",0.999625769],PARAMETER["Latitude_Of_Origin",33.3],UNIT["Meter",1.0]]
+102629=PROJCS["NAD_1983_StatePlane_Alabama_East_FIPS_0101_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",656166.6666666665],PARAMETER["Central_Meridian",-85.83333333333333],PARAMETER["Scale_Factor",0.99996],PARAMETER["Latitude_Of_Origin",30.5],UNIT["Foot_US",0.3048006096012192]]
+102630=PROJCS["NAD_1983_StatePlane_Alabama_West_FIPS_0102_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-87.5],PARAMETER["Scale_Factor",0.9999333333333333],PARAMETER["Latitude_Of_Origin",30.0],UNIT["Foot_US",0.3048006096012192]]
+102631=PROJCS["NAD_1983_StatePlane_Alaska_1_FIPS_5001_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Natural_Origin"],PARAMETER["False_Easting",16404166.66666666],PARAMETER["False_Northing",-16404166.66666666],PARAMETER["Scale_Factor",0.9999],PARAMETER["Azimuth",-36.86989764583333],PARAMETER["Longitude_Of_Center",-133.6666666666667],PARAMETER["Latitude_Of_Center",57.0],UNIT["Foot_US",0.3048006096012192]]
+102632=PROJCS["NAD_1983_StatePlane_Alaska_2_FIPS_5002_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-142.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",54.0],UNIT["Foot_US",0.3048006096012192]]
+102633=PROJCS["NAD_1983_StatePlane_Alaska_3_FIPS_5003_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-146.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",54.0],UNIT["Foot_US",0.3048006096012192]]
+102634=PROJCS["NAD_1983_StatePlane_Alaska_4_FIPS_5004_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-150.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",54.0],UNIT["Foot_US",0.3048006096012192]]
+102635=PROJCS["NAD_1983_StatePlane_Alaska_5_FIPS_5005_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-154.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",54.0],UNIT["Foot_US",0.3048006096012192]]
+102636=PROJCS["NAD_1983_StatePlane_Alaska_6_FIPS_5006_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-158.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",54.0],UNIT["Foot_US",0.3048006096012192]]
+102637=PROJCS["NAD_1983_StatePlane_Alaska_7_FIPS_5007_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-162.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",54.0],UNIT["Foot_US",0.3048006096012192]]
+102638=PROJCS["NAD_1983_StatePlane_Alaska_8_FIPS_5008_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-166.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",54.0],UNIT["Foot_US",0.3048006096012192]]
+102639=PROJCS["NAD_1983_StatePlane_Alaska_9_FIPS_5009_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-170.0],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",54.0],UNIT["Foot_US",0.3048006096012192]]
+102640=PROJCS["NAD_1983_StatePlane_Alaska_10_FIPS_5010_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",3280833.333333333],PARAMETER["Central_Meridian",-176.0],PARAMETER["Standard_Parallel_1",51.83333333333334],PARAMETER["Standard_Parallel_2",53.83333333333334],PARAMETER["Latitude_Of_Origin",51.0],UNIT["Foot_US",0.3048006096012192]]
+102641=PROJCS["NAD_1983_StatePlane_California_I_FIPS_0401_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-122.0],PARAMETER["Standard_Parallel_1",40.0],PARAMETER["Standard_Parallel_2",41.66666666666666],PARAMETER["Latitude_Of_Origin",39.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102642=PROJCS["NAD_1983_StatePlane_California_II_FIPS_0402_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-122.0],PARAMETER["Standard_Parallel_1",38.33333333333334],PARAMETER["Standard_Parallel_2",39.83333333333334],PARAMETER["Latitude_Of_Origin",37.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102643=PROJCS["NAD_1983_StatePlane_California_III_FIPS_0403_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",37.06666666666667],PARAMETER["Standard_Parallel_2",38.43333333333333],PARAMETER["Latitude_Of_Origin",36.5],UNIT["Foot_US",0.3048006096012192]]
+102644=PROJCS["NAD_1983_StatePlane_California_IV_FIPS_0404_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-119.0],PARAMETER["Standard_Parallel_1",36.0],PARAMETER["Standard_Parallel_2",37.25],PARAMETER["Latitude_Of_Origin",35.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102645=PROJCS["NAD_1983_StatePlane_California_V_FIPS_0405_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-118.0],PARAMETER["Standard_Parallel_1",34.03333333333333],PARAMETER["Standard_Parallel_2",35.46666666666667],PARAMETER["Latitude_Of_Origin",33.5],UNIT["Foot_US",0.3048006096012192]]
+102646=PROJCS["NAD_1983_StatePlane_California_VI_FIPS_0406_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-116.25],PARAMETER["Standard_Parallel_1",32.78333333333333],PARAMETER["Standard_Parallel_2",33.88333333333333],PARAMETER["Latitude_Of_Origin",32.16666666666666],UNIT["Foot_US",0.3048006096012192]]
+102648=PROJCS["NAD_1983_StatePlane_Arizona_East_FIPS_0201_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",699998.6],PARAMETER["Central_Meridian",-110.1666666666667],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",31.0],UNIT["Foot_US",0.3048006096012192]]
+102649=PROJCS["NAD_1983_StatePlane_Arizona_Central_FIPS_0202_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",699998.6],PARAMETER["Central_Meridian",-111.9166666666667],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",31.0],UNIT["Foot_US",0.3048006096012192]]
+102650=PROJCS["NAD_1983_StatePlane_Arizona_West_FIPS_0203_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",699998.6],PARAMETER["Central_Meridian",-113.75],PARAMETER["Scale_Factor",0.9999333333333333],PARAMETER["Latitude_Of_Origin",31.0],UNIT["Foot_US",0.3048006096012192]]
+102651=PROJCS["NAD_1983_StatePlane_Arkansas_North_FIPS_0301_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1312333.333333333],PARAMETER["Central_Meridian",-92.0],PARAMETER["Standard_Parallel_1",34.93333333333333],PARAMETER["Standard_Parallel_2",36.23333333333333],PARAMETER["Latitude_Of_Origin",34.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102652=PROJCS["NAD_1983_StatePlane_Arkansas_South_FIPS_0302_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1312333.333333333],PARAMETER["False_Northing",1312333.333333333],PARAMETER["Central_Meridian",-92.0],PARAMETER["Standard_Parallel_1",33.3],PARAMETER["Standard_Parallel_2",34.76666666666667],PARAMETER["Latitude_Of_Origin",32.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102653=PROJCS["NAD_1983_StatePlane_Colorado_North_FIPS_0501_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",3000000.000316083],PARAMETER["False_Northing",999999.999996],PARAMETER["Central_Meridian",-105.5],PARAMETER["Standard_Parallel_1",39.71666666666667],PARAMETER["Standard_Parallel_2",40.78333333333333],PARAMETER["Latitude_Of_Origin",39.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102654=PROJCS["NAD_1983_StatePlane_Colorado_Central_FIPS_0502_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",3000000.000316083],PARAMETER["False_Northing",999999.999996],PARAMETER["Central_Meridian",-105.5],PARAMETER["Standard_Parallel_1",38.45],PARAMETER["Standard_Parallel_2",39.75],PARAMETER["Latitude_Of_Origin",37.83333333333334],UNIT["Foot_US",0.3048006096012192]]
+102655=PROJCS["NAD_1983_StatePlane_Colorado_South_FIPS_0503_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",3000000.000316083],PARAMETER["False_Northing",999999.999996],PARAMETER["Central_Meridian",-105.5],PARAMETER["Standard_Parallel_1",37.23333333333333],PARAMETER["Standard_Parallel_2",38.43333333333333],PARAMETER["Latitude_Of_Origin",36.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102656=PROJCS["NAD_1983_StatePlane_Connecticut_FIPS_0600_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",999999.999996],PARAMETER["False_Northing",499999.999998],PARAMETER["Central_Meridian",-72.75],PARAMETER["Standard_Parallel_1",41.2],PARAMETER["Standard_Parallel_2",41.86666666666667],PARAMETER["Latitude_Of_Origin",40.83333333333334],UNIT["Foot_US",0.3048006096012192]]
+102657=PROJCS["NAD_1983_StatePlane_Delaware_FIPS_0700_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",656166.6666666665],PARAMETER["Central_Meridian",-75.41666666666667],PARAMETER["Scale_Factor",0.999995],PARAMETER["Latitude_Of_Origin",38.0],UNIT["Foot_US",0.3048006096012192]]
+102658=PROJCS["NAD_1983_StatePlane_Florida_East_FIPS_0901_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",656166.6666666665],PARAMETER["Central_Meridian",-81.0],PARAMETER["Scale_Factor",0.9999411764705882],PARAMETER["Latitude_Of_Origin",24.33333333333333],UNIT["Foot_US",0.3048006096012192]]
+102659=PROJCS["NAD_1983_StatePlane_Florida_West_FIPS_0902_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",656166.6666666665],PARAMETER["Central_Meridian",-82.0],PARAMETER["Scale_Factor",0.9999411764705882],PARAMETER["Latitude_Of_Origin",24.33333333333333],UNIT["Foot_US",0.3048006096012192]]
+102660=PROJCS["NAD_1983_StatePlane_Florida_North_FIPS_0903_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-84.5],PARAMETER["Standard_Parallel_1",29.58333333333333],PARAMETER["Standard_Parallel_2",30.75],PARAMETER["Latitude_Of_Origin",29.0],UNIT["Foot_US",0.3048006096012192]]
+102661=PROJCS["NAD_1983_StatePlane_Hawaii_1_FIPS_5101_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-155.5],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",18.83333333333333],UNIT["Foot_US",0.3048006096012192]]
+102662=PROJCS["NAD_1983_StatePlane_Hawaii_2_FIPS_5102_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-156.6666666666667],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",20.33333333333333],UNIT["Foot_US",0.3048006096012192]]
+102663=PROJCS["NAD_1983_StatePlane_Hawaii_3_FIPS_5103_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-158.0],PARAMETER["Scale_Factor",0.99999],PARAMETER["Latitude_Of_Origin",21.16666666666667],UNIT["Foot_US",0.3048006096012192]]
+102664=PROJCS["NAD_1983_StatePlane_Hawaii_4_FIPS_5104_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-159.5],PARAMETER["Scale_Factor",0.99999],PARAMETER["Latitude_Of_Origin",21.83333333333333],UNIT["Foot_US",0.3048006096012192]]
+102665=PROJCS["NAD_1983_StatePlane_Hawaii_5_FIPS_5105_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-160.1666666666667],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",21.66666666666667],UNIT["Foot_US",0.3048006096012192]]
+102666=PROJCS["NAD_1983_StatePlane_Georgia_East_FIPS_1001_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",656166.6666666665],PARAMETER["Central_Meridian",-82.16666666666667],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",30.0],UNIT["Foot_US",0.3048006096012192]]
+102667=PROJCS["NAD_1983_StatePlane_Georgia_West_FIPS_1002_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",2296583.333333333],PARAMETER["Central_Meridian",-84.16666666666667],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",30.0],UNIT["Foot_US",0.3048006096012192]]
+102668=PROJCS["NAD_1983_StatePlane_Idaho_East_FIPS_1101_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",656166.6666666665],PARAMETER["Central_Meridian",-112.1666666666667],PARAMETER["Scale_Factor",0.9999473684210526],PARAMETER["Latitude_Of_Origin",41.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102669=PROJCS["NAD_1983_StatePlane_Idaho_Central_FIPS_1102_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-114.0],PARAMETER["Scale_Factor",0.9999473684210526],PARAMETER["Latitude_Of_Origin",41.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102670=PROJCS["NAD_1983_StatePlane_Idaho_West_FIPS_1103_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",2624666.666666666],PARAMETER["Central_Meridian",-115.75],PARAMETER["Scale_Factor",0.9999333333333333],PARAMETER["Latitude_Of_Origin",41.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102671=PROJCS["NAD_1983_StatePlane_Illinois_East_FIPS_1201_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",984250.0],PARAMETER["Central_Meridian",-88.33333333333333],PARAMETER["Scale_Factor",0.999975],PARAMETER["Latitude_Of_Origin",36.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102672=PROJCS["NAD_1983_StatePlane_Illinois_West_FIPS_1202_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",2296583.333333333],PARAMETER["Central_Meridian",-90.16666666666667],PARAMETER["Scale_Factor",0.9999411764705882],PARAMETER["Latitude_Of_Origin",36.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102673=PROJCS["NAD_1983_StatePlane_Indiana_East_FIPS_1301_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",328083.3333333333],PARAMETER["False_Northing",820208.3333333333],PARAMETER["Central_Meridian",-85.66666666666667],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",37.5],UNIT["Foot_US",0.3048006096012192]]
+102674=PROJCS["NAD_1983_StatePlane_Indiana_West_FIPS_1302_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",2952750.0],PARAMETER["False_Northing",820208.3333333333],PARAMETER["Central_Meridian",-87.08333333333333],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",37.5],UNIT["Foot_US",0.3048006096012192]]
+102675=PROJCS["NAD_1983_StatePlane_Iowa_North_FIPS_1401_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",4921250.0],PARAMETER["False_Northing",3280833.333333333],PARAMETER["Central_Meridian",-93.5],PARAMETER["Standard_Parallel_1",42.06666666666667],PARAMETER["Standard_Parallel_2",43.26666666666667],PARAMETER["Latitude_Of_Origin",41.5],UNIT["Foot_US",0.3048006096012192]]
+102676=PROJCS["NAD_1983_StatePlane_Iowa_South_FIPS_1402_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-93.5],PARAMETER["Standard_Parallel_1",40.61666666666667],PARAMETER["Standard_Parallel_2",41.78333333333333],PARAMETER["Latitude_Of_Origin",40.0],UNIT["Foot_US",0.3048006096012192]]
+102677=PROJCS["NAD_1983_StatePlane_Kansas_North_FIPS_1501_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1312333.333333333],PARAMETER["Central_Meridian",-98.0],PARAMETER["Standard_Parallel_1",38.71666666666667],PARAMETER["Standard_Parallel_2",39.78333333333333],PARAMETER["Latitude_Of_Origin",38.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102678=PROJCS["NAD_1983_StatePlane_Kansas_South_FIPS_1502_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1312333.333333333],PARAMETER["False_Northing",1312333.333333333],PARAMETER["Central_Meridian",-98.5],PARAMETER["Standard_Parallel_1",37.26666666666667],PARAMETER["Standard_Parallel_2",38.56666666666667],PARAMETER["Latitude_Of_Origin",36.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102679=PROJCS["NAD_1983_StatePlane_Kentucky_North_FIPS_1601_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-84.25],PARAMETER["Standard_Parallel_1",37.96666666666667],PARAMETER["Standard_Parallel_2",38.96666666666667],PARAMETER["Latitude_Of_Origin",37.5],UNIT["Foot_US",0.3048006096012192]]
+102680=PROJCS["NAD_1983_StatePlane_Kentucky_South_FIPS_1602_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-85.75],PARAMETER["Standard_Parallel_1",36.73333333333333],PARAMETER["Standard_Parallel_2",37.93333333333333],PARAMETER["Latitude_Of_Origin",36.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102681=PROJCS["NAD_1983_StatePlane_Louisiana_North_FIPS_1701_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",3280833.333333333],PARAMETER["Central_Meridian",-92.5],PARAMETER["Standard_Parallel_1",31.16666666666667],PARAMETER["Standard_Parallel_2",32.66666666666666],PARAMETER["Latitude_Of_Origin",30.5],UNIT["Foot_US",0.3048006096012192]]
+102682=PROJCS["NAD_1983_StatePlane_Louisiana_South_FIPS_1702_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",3280833.333333333],PARAMETER["Central_Meridian",-91.33333333333333],PARAMETER["Standard_Parallel_1",29.3],PARAMETER["Standard_Parallel_2",30.7],PARAMETER["Latitude_Of_Origin",28.5],UNIT["Foot_US",0.3048006096012192]]
+102683=PROJCS["NAD_1983_StatePlane_Maine_East_FIPS_1801_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",984250.0],PARAMETER["Central_Meridian",-68.5],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",43.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102684=PROJCS["NAD_1983_StatePlane_Maine_West_FIPS_1802_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",2952750.0],PARAMETER["Central_Meridian",-70.16666666666667],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",42.83333333333334],UNIT["Foot_US",0.3048006096012192]]
+102685=PROJCS["NAD_1983_StatePlane_Maryland_FIPS_1900_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1312333.333333333],PARAMETER["Central_Meridian",-77.0],PARAMETER["Standard_Parallel_1",38.3],PARAMETER["Standard_Parallel_2",39.45],PARAMETER["Latitude_Of_Origin",37.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102686=PROJCS["NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",656166.6666666665],PARAMETER["False_Northing",2460625.0],PARAMETER["Central_Meridian",-71.5],PARAMETER["Standard_Parallel_1",41.71666666666667],PARAMETER["Standard_Parallel_2",42.68333333333333],PARAMETER["Latitude_Of_Origin",41.0],UNIT["Foot_US",0.3048006096012192]]
+102687=PROJCS["NAD_1983_StatePlane_Massachusetts_Island_FIPS_2002_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-70.5],PARAMETER["Standard_Parallel_1",41.28333333333333],PARAMETER["Standard_Parallel_2",41.48333333333333],PARAMETER["Latitude_Of_Origin",41.0],UNIT["Foot_US",0.3048006096012192]]
+102688=PROJCS["NAD_1983_StatePlane_Michigan_North_FIPS_2111_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",26246666.66666666],PARAMETER["Central_Meridian",-87.0],PARAMETER["Standard_Parallel_1",45.48333333333333],PARAMETER["Standard_Parallel_2",47.08333333333334],PARAMETER["Latitude_Of_Origin",44.78333333333333],UNIT["Foot_US",0.3048006096012192]]
+102689=PROJCS["NAD_1983_StatePlane_Michigan_Central_FIPS_2112_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",19685000.0],PARAMETER["Central_Meridian",-84.36666666666666],PARAMETER["Standard_Parallel_1",44.18333333333333],PARAMETER["Standard_Parallel_2",45.7],PARAMETER["Latitude_Of_Origin",43.31666666666667],UNIT["Foot_US",0.3048006096012192]]
+102690=PROJCS["NAD_1983_StatePlane_Michigan_South_FIPS_2113_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",13123333.33333333],PARAMETER["Central_Meridian",-84.36666666666666],PARAMETER["Standard_Parallel_1",42.1],PARAMETER["Standard_Parallel_2",43.66666666666666],PARAMETER["Latitude_Of_Origin",41.5],UNIT["Foot_US",0.3048006096012192]]
+102691=PROJCS["NAD_1983_StatePlane_Minnesota_North_FIPS_2201_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2624666.666666666],PARAMETER["False_Northing",328083.3333333333],PARAMETER["Central_Meridian",-93.1],PARAMETER["Standard_Parallel_1",47.03333333333333],PARAMETER["Standard_Parallel_2",48.63333333333333],PARAMETER["Latitude_Of_Origin",46.5],UNIT["Foot_US",0.3048006096012192]]
+102692=PROJCS["NAD_1983_StatePlane_Minnesota_Central_FIPS_2202_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2624666.666666666],PARAMETER["False_Northing",328083.3333333333],PARAMETER["Central_Meridian",-94.25],PARAMETER["Standard_Parallel_1",45.61666666666667],PARAMETER["Standard_Parallel_2",47.05],PARAMETER["Latitude_Of_Origin",45.0],UNIT["Foot_US",0.3048006096012192]]
+102693=PROJCS["NAD_1983_StatePlane_Minnesota_South_FIPS_2203_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2624666.666666666],PARAMETER["False_Northing",328083.3333333333],PARAMETER["Central_Meridian",-94.0],PARAMETER["Standard_Parallel_1",43.78333333333333],PARAMETER["Standard_Parallel_2",45.21666666666667],PARAMETER["Latitude_Of_Origin",43.0],UNIT["Foot_US",0.3048006096012192]]
+102694=PROJCS["NAD_1983_StatePlane_Mississippi_East_FIPS_2301_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",984250.0],PARAMETER["Central_Meridian",-88.83333333333333],PARAMETER["Scale_Factor",0.99995],PARAMETER["Latitude_Of_Origin",29.5],UNIT["Foot_US",0.3048006096012192]]
+102695=PROJCS["NAD_1983_StatePlane_Mississippi_West_FIPS_2302_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",2296583.333333333],PARAMETER["Central_Meridian",-90.33333333333333],PARAMETER["Scale_Factor",0.99995],PARAMETER["Latitude_Of_Origin",29.5],UNIT["Foot_US",0.3048006096012192]]
+102696=PROJCS["NAD_1983_StatePlane_Missouri_East_FIPS_2401_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",820208.3333333333],PARAMETER["Central_Meridian",-90.5],PARAMETER["Scale_Factor",0.9999333333333333],PARAMETER["Latitude_Of_Origin",35.83333333333334],UNIT["Foot_US",0.3048006096012192]]
+102697=PROJCS["NAD_1983_StatePlane_Missouri_Central_FIPS_2402_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-92.5],PARAMETER["Scale_Factor",0.9999333333333333],PARAMETER["Latitude_Of_Origin",35.83333333333334],UNIT["Foot_US",0.3048006096012192]]
+102698=PROJCS["NAD_1983_StatePlane_Missouri_West_FIPS_2403_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",2788708.333333333],PARAMETER["Central_Meridian",-94.5],PARAMETER["Scale_Factor",0.9999411764705882],PARAMETER["Latitude_Of_Origin",36.16666666666666],UNIT["Foot_US",0.3048006096012192]]
+102700=PROJCS["NAD_1983_StatePlane_Montana_FIPS_2500_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-109.5],PARAMETER["Standard_Parallel_1",45.0],PARAMETER["Standard_Parallel_2",49.0],PARAMETER["Latitude_Of_Origin",44.25],UNIT["Foot_US",0.3048006096012192]]
+102704=PROJCS["NAD_1983_StatePlane_Nebraska_FIPS_2600_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-100.0],PARAMETER["Standard_Parallel_1",40.0],PARAMETER["Standard_Parallel_2",43.0],PARAMETER["Latitude_Of_Origin",39.83333333333334],UNIT["Foot_US",0.3048006096012192]]
+102707=PROJCS["NAD_1983_StatePlane_Nevada_East_FIPS_2701_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",656166.6666666665],PARAMETER["False_Northing",26246666.66666666],PARAMETER["Central_Meridian",-115.5833333333333],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",34.75],UNIT["Foot_US",0.3048006096012192]]
+102708=PROJCS["NAD_1983_StatePlane_Nevada_Central_FIPS_2702_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["False_Northing",19685000.0],PARAMETER["Central_Meridian",-116.6666666666667],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",34.75],UNIT["Foot_US",0.3048006096012192]]
+102709=PROJCS["NAD_1983_StatePlane_Nevada_West_FIPS_2703_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",2624666.666666666],PARAMETER["False_Northing",13123333.33333333],PARAMETER["Central_Meridian",-118.5833333333333],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",34.75],UNIT["Foot_US",0.3048006096012192]]
+102710=PROJCS["NAD_1983_StatePlane_New_Hampshire_FIPS_2800_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",984250.0],PARAMETER["Central_Meridian",-71.66666666666667],PARAMETER["Scale_Factor",0.9999666666666667],PARAMETER["Latitude_Of_Origin",42.5],UNIT["Foot_US",0.3048006096012192]]
+102711=PROJCS["NAD_1983_StatePlane_New_Jersey_FIPS_2900_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",492125.0],PARAMETER["Central_Meridian",-74.5],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",38.83333333333334],UNIT["Foot_US",0.3048006096012192]]
+102712=PROJCS["NAD_1983_StatePlane_New_Mexico_East_FIPS_3001_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",541337.5],PARAMETER["Central_Meridian",-104.3333333333333],PARAMETER["Scale_Factor",0.9999090909090909],PARAMETER["Latitude_Of_Origin",31.0],UNIT["Foot_US",0.3048006096012192]]
+102713=PROJCS["NAD_1983_StatePlane_New_Mexico_Central_FIPS_3002_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-106.25],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",31.0],UNIT["Foot_US",0.3048006096012192]]
+102714=PROJCS["NAD_1983_StatePlane_New_Mexico_West_FIPS_3003_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",2723091.666666666],PARAMETER["Central_Meridian",-107.8333333333333],PARAMETER["Scale_Factor",0.9999166666666667],PARAMETER["Latitude_Of_Origin",31.0],UNIT["Foot_US",0.3048006096012192]]
+102715=PROJCS["NAD_1983_StatePlane_New_York_East_FIPS_3101_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",492125.0],PARAMETER["Central_Meridian",-74.5],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",38.83333333333334],UNIT["Foot_US",0.3048006096012192]]
+102716=PROJCS["NAD_1983_StatePlane_New_York_Central_FIPS_3102_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",820208.3333333333],PARAMETER["Central_Meridian",-76.58333333333333],PARAMETER["Scale_Factor",0.9999375],PARAMETER["Latitude_Of_Origin",40.0],UNIT["Foot_US",0.3048006096012192]]
+102717=PROJCS["NAD_1983_StatePlane_New_York_West_FIPS_3103_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1148291.666666667],PARAMETER["Central_Meridian",-78.58333333333333],PARAMETER["Scale_Factor",0.9999375],PARAMETER["Latitude_Of_Origin",40.0],UNIT["Foot_US",0.3048006096012192]]
+102718=PROJCS["NAD_1983_StatePlane_New_York_Long_Island_FIPS_3104_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",984250.0],PARAMETER["Central_Meridian",-74.0],PARAMETER["Standard_Parallel_1",40.66666666666666],PARAMETER["Standard_Parallel_2",41.03333333333333],PARAMETER["Latitude_Of_Origin",40.16666666666666],UNIT["Foot_US",0.3048006096012192]]
+102719=PROJCS["NAD_1983_StatePlane_North_Carolina_FIPS_3200_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2000000.002616666],PARAMETER["Central_Meridian",-79.0],PARAMETER["Standard_Parallel_1",34.33333333333334],PARAMETER["Standard_Parallel_2",36.16666666666666],PARAMETER["Latitude_Of_Origin",33.75],UNIT["Foot_US",0.3048006096012192]]
+102720=PROJCS["NAD_1983_StatePlane_North_Dakota_North_FIPS_3301_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-100.5],PARAMETER["Standard_Parallel_1",47.43333333333333],PARAMETER["Standard_Parallel_2",48.73333333333333],PARAMETER["Latitude_Of_Origin",47.0],UNIT["Foot_US",0.3048006096012192]]
+102721=PROJCS["NAD_1983_StatePlane_North_Dakota_South_FIPS_3302_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-100.5],PARAMETER["Standard_Parallel_1",46.18333333333333],PARAMETER["Standard_Parallel_2",47.48333333333333],PARAMETER["Latitude_Of_Origin",45.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102722=PROJCS["NAD_1983_StatePlane_Ohio_North_FIPS_3401_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-82.5],PARAMETER["Standard_Parallel_1",40.43333333333333],PARAMETER["Standard_Parallel_2",41.7],PARAMETER["Latitude_Of_Origin",39.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102723=PROJCS["NAD_1983_StatePlane_Ohio_South_FIPS_3402_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-82.5],PARAMETER["Standard_Parallel_1",38.73333333333333],PARAMETER["Standard_Parallel_2",40.03333333333333],PARAMETER["Latitude_Of_Origin",38.0],UNIT["Foot_US",0.3048006096012192]]
+102724=PROJCS["NAD_1983_StatePlane_Oklahoma_North_FIPS_3501_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-98.0],PARAMETER["Standard_Parallel_1",35.56666666666667],PARAMETER["Standard_Parallel_2",36.76666666666667],PARAMETER["Latitude_Of_Origin",35.0],UNIT["Foot_US",0.3048006096012192]]
+102725=PROJCS["NAD_1983_StatePlane_Oklahoma_South_FIPS_3502_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-98.0],PARAMETER["Standard_Parallel_1",33.93333333333333],PARAMETER["Standard_Parallel_2",35.23333333333333],PARAMETER["Latitude_Of_Origin",33.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102726=PROJCS["NAD_1983_StatePlane_Oregon_North_FIPS_3601_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",8202083.333333332],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",44.33333333333334],PARAMETER["Standard_Parallel_2",46.0],PARAMETER["Latitude_Of_Origin",43.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102727=PROJCS["NAD_1983_StatePlane_Oregon_South_FIPS_3602_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",4921250.0],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",42.33333333333334],PARAMETER["Standard_Parallel_2",44.0],PARAMETER["Latitude_Of_Origin",41.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102728=PROJCS["NAD_1983_StatePlane_Pennsylvania_North_FIPS_3701_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-77.75],PARAMETER["Standard_Parallel_1",40.88333333333333],PARAMETER["Standard_Parallel_2",41.95],PARAMETER["Latitude_Of_Origin",40.16666666666666],UNIT["Foot_US",0.3048006096012192]]
+102729=PROJCS["NAD_1983_StatePlane_Pennsylvania_South_FIPS_3702_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-77.75],PARAMETER["Standard_Parallel_1",39.93333333333333],PARAMETER["Standard_Parallel_2",40.96666666666667],PARAMETER["Latitude_Of_Origin",39.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102730=PROJCS["NAD_1983_StatePlane_Rhode_Island_FIPS_3800_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",328083.3333333333],PARAMETER["Central_Meridian",-71.5],PARAMETER["Scale_Factor",0.99999375],PARAMETER["Latitude_Of_Origin",41.08333333333334],UNIT["Foot_US",0.3048006096012192]]
+102733=PROJCS["NAD_1983_StatePlane_South_Carolina_FIPS_3900_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1999996.0],PARAMETER["Central_Meridian",-81.0],PARAMETER["Standard_Parallel_1",32.5],PARAMETER["Standard_Parallel_2",34.83333333333334],PARAMETER["Latitude_Of_Origin",31.83333333333333],UNIT["Foot_US",0.3048006096012192]]
+102734=PROJCS["NAD_1983_StatePlane_South_Dakota_North_FIPS_4001_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-100.0],PARAMETER["Standard_Parallel_1",44.41666666666666],PARAMETER["Standard_Parallel_2",45.68333333333333],PARAMETER["Latitude_Of_Origin",43.83333333333334],UNIT["Foot_US",0.3048006096012192]]
+102735=PROJCS["NAD_1983_StatePlane_South_Dakota_South_FIPS_4002_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-100.3333333333333],PARAMETER["Standard_Parallel_1",42.83333333333334],PARAMETER["Standard_Parallel_2",44.4],PARAMETER["Latitude_Of_Origin",42.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102736=PROJCS["NAD_1983_StatePlane_Tennessee_FIPS_4100_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-86.0],PARAMETER["Standard_Parallel_1",35.25],PARAMETER["Standard_Parallel_2",36.41666666666666],PARAMETER["Latitude_Of_Origin",34.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102737=PROJCS["NAD_1983_StatePlane_Texas_North_FIPS_4201_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",656166.6666666665],PARAMETER["False_Northing",3280833.333333333],PARAMETER["Central_Meridian",-101.5],PARAMETER["Standard_Parallel_1",34.65],PARAMETER["Standard_Parallel_2",36.18333333333333],PARAMETER["Latitude_Of_Origin",34.0],UNIT["Foot_US",0.3048006096012192]]
+102738=PROJCS["NAD_1983_StatePlane_Texas_North_Central_FIPS_4202_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["False_Northing",6561666.666666666],PARAMETER["Central_Meridian",-98.5],PARAMETER["Standard_Parallel_1",32.13333333333333],PARAMETER["Standard_Parallel_2",33.96666666666667],PARAMETER["Latitude_Of_Origin",31.66666666666667],UNIT["Foot_US",0.3048006096012192]]
+102739=PROJCS["NAD_1983_StatePlane_Texas_Central_FIPS_4203_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",2296583.333333333],PARAMETER["False_Northing",9842500.0],PARAMETER["Central_Meridian",-100.3333333333333],PARAMETER["Standard_Parallel_1",30.11666666666667],PARAMETER["Standard_Parallel_2",31.88333333333333],PARAMETER["Latitude_Of_Origin",29.66666666666667],UNIT["Foot_US",0.3048006096012192]]
+102740=PROJCS["NAD_1983_StatePlane_Texas_South_Central_FIPS_4204_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["False_Northing",13123333.33333333],PARAMETER["Central_Meridian",-99.0],PARAMETER["Standard_Parallel_1",28.38333333333333],PARAMETER["Standard_Parallel_2",30.28333333333334],PARAMETER["Latitude_Of_Origin",27.83333333333333],UNIT["Foot_US",0.3048006096012192]]
+102741=PROJCS["NAD_1983_StatePlane_Texas_South_FIPS_4205_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",984250.0],PARAMETER["False_Northing",16404166.66666666],PARAMETER["Central_Meridian",-98.5],PARAMETER["Standard_Parallel_1",26.16666666666667],PARAMETER["Standard_Parallel_2",27.83333333333333],PARAMETER["Latitude_Of_Origin",25.66666666666667],UNIT["Foot_US",0.3048006096012192]]
+102742=PROJCS["NAD_1983_StatePlane_Utah_North_FIPS_4301_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["False_Northing",3280833.333333333],PARAMETER["Central_Meridian",-111.5],PARAMETER["Standard_Parallel_1",40.71666666666667],PARAMETER["Standard_Parallel_2",41.78333333333333],PARAMETER["Latitude_Of_Origin",40.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102743=PROJCS["NAD_1983_StatePlane_Utah_Central_FIPS_4302_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["False_Northing",6561666.666666666],PARAMETER["Central_Meridian",-111.5],PARAMETER["Standard_Parallel_1",39.01666666666667],PARAMETER["Standard_Parallel_2",40.65],PARAMETER["Latitude_Of_Origin",38.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102744=PROJCS["NAD_1983_StatePlane_Utah_South_FIPS_4303_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["False_Northing",9842500.0],PARAMETER["Central_Meridian",-111.5],PARAMETER["Standard_Parallel_1",37.21666666666667],PARAMETER["Standard_Parallel_2",38.35],PARAMETER["Latitude_Of_Origin",36.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102745=PROJCS["NAD_1983_StatePlane_Vermont_FIPS_4400_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-72.5],PARAMETER["Scale_Factor",0.9999642857142858],PARAMETER["Latitude_Of_Origin",42.5],UNIT["Foot_US",0.3048006096012192]]
+102746=PROJCS["NAD_1983_StatePlane_Virginia_North_FIPS_4501_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",11482916.66666666],PARAMETER["False_Northing",6561666.666666666],PARAMETER["Central_Meridian",-78.5],PARAMETER["Standard_Parallel_1",38.03333333333333],PARAMETER["Standard_Parallel_2",39.2],PARAMETER["Latitude_Of_Origin",37.66666666666666],UNIT["Foot_US",0.3048006096012192]]
+102747=PROJCS["NAD_1983_StatePlane_Virginia_South_FIPS_4502_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",11482916.66666666],PARAMETER["False_Northing",3280833.333333333],PARAMETER["Central_Meridian",-78.5],PARAMETER["Standard_Parallel_1",36.76666666666667],PARAMETER["Standard_Parallel_2",37.96666666666667],PARAMETER["Latitude_Of_Origin",36.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102748=PROJCS["NAD_1983_StatePlane_Washington_North_FIPS_4601_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-120.8333333333333],PARAMETER["Standard_Parallel_1",47.5],PARAMETER["Standard_Parallel_2",48.73333333333333],PARAMETER["Latitude_Of_Origin",47.0],UNIT["Foot_US",0.3048006096012192]]
+102749=PROJCS["NAD_1983_StatePlane_Washington_South_FIPS_4602_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1640416.666666667],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",45.83333333333334],PARAMETER["Standard_Parallel_2",47.33333333333334],PARAMETER["Latitude_Of_Origin",45.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102750=PROJCS["NAD_1983_StatePlane_West_Virginia_North_FIPS_4701_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-79.5],PARAMETER["Standard_Parallel_1",39.0],PARAMETER["Standard_Parallel_2",40.25],PARAMETER["Latitude_Of_Origin",38.5],UNIT["Foot_US",0.3048006096012192]]
+102751=PROJCS["NAD_1983_StatePlane_West_Virginia_South_FIPS_4702_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-81.0],PARAMETER["Standard_Parallel_1",37.48333333333333],PARAMETER["Standard_Parallel_2",38.88333333333333],PARAMETER["Latitude_Of_Origin",37.0],UNIT["Foot_US",0.3048006096012192]]
+102752=PROJCS["NAD_1983_StatePlane_Wisconsin_North_FIPS_4801_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-90.0],PARAMETER["Standard_Parallel_1",45.56666666666667],PARAMETER["Standard_Parallel_2",46.76666666666667],PARAMETER["Latitude_Of_Origin",45.16666666666666],UNIT["Foot_US",0.3048006096012192]]
+102753=PROJCS["NAD_1983_StatePlane_Wisconsin_Central_FIPS_4802_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-90.0],PARAMETER["Standard_Parallel_1",44.25],PARAMETER["Standard_Parallel_2",45.5],PARAMETER["Latitude_Of_Origin",43.83333333333334],UNIT["Foot_US",0.3048006096012192]]
+102754=PROJCS["NAD_1983_StatePlane_Wisconsin_South_FIPS_4803_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-90.0],PARAMETER["Standard_Parallel_1",42.73333333333333],PARAMETER["Standard_Parallel_2",44.06666666666667],PARAMETER["Latitude_Of_Origin",42.0],UNIT["Foot_US",0.3048006096012192]]
+102755=PROJCS["NAD_1983_StatePlane_Wyoming_East_FIPS_4901_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",656166.6666666665],PARAMETER["Central_Meridian",-105.1666666666667],PARAMETER["Scale_Factor",0.9999375],PARAMETER["Latitude_Of_Origin",40.5],UNIT["Foot_US",0.3048006096012192]]
+102756=PROJCS["NAD_1983_StatePlane_Wyoming_East_Central_FIPS_4902_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1312333.333333333],PARAMETER["False_Northing",328083.3333333333],PARAMETER["Central_Meridian",-107.3333333333333],PARAMETER["Scale_Factor",0.9999375],PARAMETER["Latitude_Of_Origin",40.5],UNIT["Foot_US",0.3048006096012192]]
+102757=PROJCS["NAD_1983_StatePlane_Wyoming_West_Central_FIPS_4903_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1968500.0],PARAMETER["Central_Meridian",-108.75],PARAMETER["Scale_Factor",0.9999375],PARAMETER["Latitude_Of_Origin",40.5],UNIT["Foot_US",0.3048006096012192]]
+102758=PROJCS["NAD_1983_StatePlane_Wyoming_West_FIPS_4904_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",2624666.666666666],PARAMETER["False_Northing",328083.3333333333],PARAMETER["Central_Meridian",-110.0833333333333],PARAMETER["Scale_Factor",0.9999375],PARAMETER["Latitude_Of_Origin",40.5],UNIT["Foot_US",0.3048006096012192]]
+102761=PROJCS["NAD_1983_StatePlane_Puerto_Rico_Virgin_Islands_FIPS_5200_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",656166.6666666665],PARAMETER["False_Northing",656166.6666666665],PARAMETER["Central_Meridian",-66.43333333333334],PARAMETER["Standard_Parallel_1",18.03333333333334],PARAMETER["Standard_Parallel_2",18.43333333333333],PARAMETER["Latitude_Of_Origin",17.83333333333333],UNIT["Foot_US",0.3048006096012192]]
+102763=PROJCS["NAD_1983_StatePlane_Kentucky_FIPS_1600_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",4921250.0],PARAMETER["False_Northing",3280833.333333333],PARAMETER["Central_Meridian",-85.75],PARAMETER["Standard_Parallel_1",37.08333333333334],PARAMETER["Standard_Parallel_2",38.66666666666666],PARAMETER["Latitude_Of_Origin",36.33333333333334],UNIT["Foot_US",0.3048006096012192]]
+102766=PROJCS["NAD_1983_StatePlane_Guam_FIPS_5400_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Polyconic"],PARAMETER["False_Easting",164041.6666666666],PARAMETER["False_Northing",164041.6666666666],PARAMETER["Central_Meridian",-144.7487507055556],PARAMETER["Latitude_Of_Origin",13.47246635277778],UNIT["Foot_US",0.3048006096012192]]
+103300=PROJCS["Belge_Lambert_1972",GEOGCS["GCS_Belge_1972",DATUM["D_Belge_1972",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",150000.01256],PARAMETER["False_Northing",5400088.4378],PARAMETER["Central_Meridian",4.367486666666666],PARAMETER["Standard_Parallel_1",49.8333339],PARAMETER["Standard_Parallel_2",51.16666723333333],PARAMETER["Latitude_Of_Origin",90.0],UNIT["Meter",1.0]]
+104000=GEOGCS["GCS_Assumed_Geographic_1",DATUM["D_North_American_1927",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104101=GEOGCS["GCS_Estonia_1937",DATUM["D_Estonia_1937",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104102=GEOGCS["GCS_Hermannskogel",DATUM["D_Hermannskogel",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104103=GEOGCS["GCS_Sierra_Leone_1960",DATUM["D_Sierra_Leone_1960",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104104=GEOGCS["GCS_Hong_Kong_1980",DATUM["D_Hong_Kong_1980",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104105=GEOGCS["GCS_Datum_Lisboa_Bessel",DATUM["D_Datum_Lisboa_Bessel",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104106=GEOGCS["GCS_Datum_Lisboa_Hayford",DATUM["D_Datum_Lisboa_Hayford",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104107=GEOGCS["GCS_RGF_1993",DATUM["D_RGF_1993",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104108=GEOGCS["GCS_NZGD_2000",DATUM["D_NZGD_2000",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104109=GEOGCS["GCS_Pohnpei",DATUM["D_Pohnpei",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104110=GEOGCS["GCS_REGVEN",DATUM["D_REGVEN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104111=GEOGCS["GCS_JGD_2000",DATUM["D_JGD_2000",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104112=GEOGCS["GCS_Bab_South",DATUM["D_Bab_South",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104113=GEOGCS["GCS_Majuro",DATUM["D_Majuro",SPHEROID["Clarke_1866",6378206.4,294.9786982]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104114=GEOGCS["GCS_Bermuda_2000",DATUM["D_Bermuda_2000",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104115=GEOGCS["GCS_ITRF_1988",DATUM["D_ITRF_1988",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104116=GEOGCS["GCS_ITRF_1989",DATUM["D_ITRF_1989",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104117=GEOGCS["GCS_ITRF_1990",DATUM["D_ITRF_1990",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104118=GEOGCS["GCS_ITRF_1991",DATUM["D_ITRF_1991",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104119=GEOGCS["GCS_ITRF_1992",DATUM["D_ITRF_1992",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104120=GEOGCS["GCS_ITRF_1993",DATUM["D_ITRF_1993",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104121=GEOGCS["GCS_ITRF_1994",DATUM["D_ITRF_1994",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104122=GEOGCS["GCS_ITRF_1996",DATUM["D_ITRF_1996",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104123=GEOGCS["GCS_ITRF_1997",DATUM["D_ITRF_1997",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104124=GEOGCS["GCS_ITRF_2000",DATUM["D_ITRF_2000",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104125=GEOGCS["GCS_Chatham_Islands_1979",DATUM["D_Chatham_Islands_1979",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104126=GEOGCS["GCS_Observatorio_Meteorologico_1965",DATUM["D_Observatorio_Meteorologico_1965",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104127=GEOGCS["GCS_Roma_1940",DATUM["D_Roma_1940",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104128=GEOGCS["GCS_Sphere_EMEP",DATUM["D_Sphere_EMEP",SPHEROID["Sphere_EMEP",6370000.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104129=GEOGCS["GCS_EUREF_FIN",DATUM["D_ETRS_1989",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104130=GEOGCS["GCS_Jordan",DATUM["D_Jordan",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104258=GEOGCS["GCS_ETRF_1989",DATUM["D_ETRF_1989",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104261=GEOGCS["GCS_Merchich_Degree",DATUM["D_Merchich",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104304=GEOGCS["GCS_Voirol_1875_Degree",DATUM["D_Voirol_1875",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104305=GEOGCS["GCS_Voirol_Unifie_1960_Degree",DATUM["D_Voirol_Unifie_1960",SPHEROID["Clarke_1880_RGS",6378249.145,293.465]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104700=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Anoka",DATUM["D_NAD_1983_HARN_Adj_MN_Anoka",SPHEROID["S_GRS_1980_Adj_MN_Anoka",6378418.941,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104701=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Becker",DATUM["D_NAD_1983_HARN_Adj_MN_Becker",SPHEROID["S_GRS_1980_Adj_MN_Becker",6378586.581,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104702=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Beltrami_North",DATUM["D_NAD_1983_HARN_Adj_MN_Beltrami_North",SPHEROID["S_GRS_1980_Adj_MN_Beltrami_North",6378505.809,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104703=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Beltrami_South",DATUM["D_NAD_1983_HARN_Adj_MN_Beltrami_South",SPHEROID["S_GRS_1980_Adj_MN_Beltrami_South",6378544.823,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104704=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Benton",DATUM["D_NAD_1983_HARN_Adj_MN_Benton",SPHEROID["S_GRS_1980_Adj_MN_Benton",6378490.569,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104705=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Big_Stone",DATUM["D_NAD_1983_HARN_Adj_MN_Big_Stone",SPHEROID["S_GRS_1980_Adj_MN_Big_Stone",6378470.757,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104706=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Blue_Earth",DATUM["D_NAD_1983_HARN_Adj_MN_Blue_Earth",SPHEROID["S_GRS_1980_Adj_MN_Blue_Earth",6378403.701,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104707=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Brown",DATUM["D_NAD_1983_HARN_Adj_MN_Brown",SPHEROID["S_GRS_1980_Adj_MN_Brown",6378434.181,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104708=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Carlton",DATUM["D_NAD_1983_HARN_Adj_MN_Carlton",SPHEROID["S_GRS_1980_Adj_MN_Carlton",6378454.907,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104709=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Carver",DATUM["D_NAD_1983_HARN_Adj_MN_Carver",SPHEROID["S_GRS_1980_Adj_MN_Carver",6378400.653,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104710=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Cass_North",DATUM["D_NAD_1983_HARN_Adj_MN_Cass_North",SPHEROID["S_GRS_1980_Adj_MN_Cass_North",6378567.378,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104711=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Cass_South",DATUM["D_NAD_1983_HARN_Adj_MN_Cass_South",SPHEROID["S_GRS_1980_Adj_MN_Cass_South",6378546.957,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104712=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Chippewa",DATUM["D_NAD_1983_HARN_Adj_MN_Chippewa",SPHEROID["S_GRS_1980_Adj_MN_Chippewa",6378476.853,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104713=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Chisago",DATUM["D_NAD_1983_HARN_Adj_MN_Chisago",SPHEROID["S_GRS_1980_Adj_MN_Chisago",6378411.321,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104714=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Cook_North",DATUM["D_NAD_1983_HARN_Adj_MN_Cook_North",SPHEROID["S_GRS_1980_Adj_MN_Cook_North",6378647.541,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104715=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Cook_South",DATUM["D_NAD_1983_HARN_Adj_MN_Cook_South",SPHEROID["S_GRS_1980_Adj_MN_Cook_South",6378647.541,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104716=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Cottonwood",DATUM["D_NAD_1983_HARN_Adj_MN_Cottonwood",SPHEROID["S_GRS_1980_Adj_MN_Cottonwood",6378514.953,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104717=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Crow_Wing",DATUM["D_NAD_1983_HARN_Adj_MN_Crow_Wing",SPHEROID["S_GRS_1980_Adj_MN_Crow_Wing",6378546.957,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104718=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Dakota",DATUM["D_NAD_1983_HARN_Adj_MN_Dakota",SPHEROID["S_GRS_1980_Adj_MN_Dakota",6378421.989,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104719=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Dodge",DATUM["D_NAD_1983_HARN_Adj_MN_Dodge",SPHEROID["S_GRS_1980_Adj_MN_Dodge",6378481.425,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104720=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Douglas",DATUM["D_NAD_1983_HARN_Adj_MN_Douglas",SPHEROID["S_GRS_1980_Adj_MN_Douglas",6378518.001,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104721=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Faribault",DATUM["D_NAD_1983_HARN_Adj_MN_Faribault",SPHEROID["S_GRS_1980_Adj_MN_Faribault",6378521.049,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104722=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Fillmore",DATUM["D_NAD_1983_HARN_Adj_MN_Fillmore",SPHEROID["S_GRS_1980_Adj_MN_Fillmore",6378464.661,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104723=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Freeborn",DATUM["D_NAD_1983_HARN_Adj_MN_Freeborn",SPHEROID["S_GRS_1980_Adj_MN_Freeborn",6378521.049,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104724=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Goodhue",DATUM["D_NAD_1983_HARN_Adj_MN_Goodhue",SPHEROID["S_GRS_1980_Adj_MN_Goodhue",6378434.181,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104725=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Grant",DATUM["D_NAD_1983_HARN_Adj_MN_Grant",SPHEROID["S_GRS_1980_Adj_MN_Grant",6378518.001,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104726=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Hennepin",DATUM["D_NAD_1983_HARN_Adj_MN_Hennepin",SPHEROID["S_GRS_1980_Adj_MN_Hennepin",6378418.941,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104727=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Houston",DATUM["D_NAD_1983_HARN_Adj_MN_Houston",SPHEROID["S_GRS_1980_Adj_MN_Houston",6378436.619,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104728=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Isanti",DATUM["D_NAD_1983_HARN_Adj_MN_Isanti",SPHEROID["S_GRS_1980_Adj_MN_Isanti",6378411.321,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104729=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Itasca_North",DATUM["D_NAD_1983_HARN_Adj_MN_Itasca_North",SPHEROID["S_GRS_1980_Adj_MN_Itasca_North",6378574.389,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104730=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Itasca_South",DATUM["D_NAD_1983_HARN_Adj_MN_Itasca_South",SPHEROID["S_GRS_1980_Adj_MN_Itasca_South",6378574.389,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104731=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Jackson",DATUM["D_NAD_1983_HARN_Adj_MN_Jackson",SPHEROID["S_GRS_1980_Adj_MN_Jackson",6378521.049,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104732=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Kanabec",DATUM["D_NAD_1983_HARN_Adj_MN_Kanabec",SPHEROID["S_GRS_1980_Adj_MN_Kanabec",6378472.281,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104733=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Kandiyohi",DATUM["D_NAD_1983_HARN_Adj_MN_Kandiyohi",SPHEROID["S_GRS_1980_Adj_MN_Kandiyohi",6378498.189,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104734=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Kittson",DATUM["D_NAD_1983_HARN_Adj_MN_Kittson",SPHEROID["S_GRS_1980_Adj_MN_Kittson",6378449.421,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104735=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Koochiching",DATUM["D_NAD_1983_HARN_Adj_MN_Koochiching",SPHEROID["S_GRS_1980_Adj_MN_Koochiching",6378525.621,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104736=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Lac_Qui_Parle",DATUM["D_NAD_1983_HARN_Adj_MN_Lac_Qui_Parle",SPHEROID["S_GRS_1980_Adj_MN_Lac_Qui_Parle",6378476.853,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104737=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Lake_of_the_Woods_North",DATUM["D_NAD_1983_HARN_Adj_MN_Lake_of_the_Woods_North",SPHEROID["S_GRS_1980_Adj_MN_Lake_of_the_Woods_North",6378466.185,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104738=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Lake_of_the_Woods_South",DATUM["D_NAD_1983_HARN_Adj_MN_Lake_of_the_Woods_South",SPHEROID["S_GRS_1980_Adj_MN_Lake_of_the_Woods_South",6378496.665,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104739=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Le_Sueur",DATUM["D_NAD_1983_HARN_Adj_MN_Le_Sueur",SPHEROID["S_GRS_1980_Adj_MN_Le_Sueur",6378434.181,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104740=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Lincoln",DATUM["D_NAD_1983_HARN_Adj_MN_Lincoln",SPHEROID["S_GRS_1980_Adj_MN_Lincoln",6378643.579,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104741=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Lyon",DATUM["D_NAD_1983_HARN_Adj_MN_Lyon",SPHEROID["S_GRS_1980_Adj_MN_Lyon",6378559.758,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104742=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_McLeod",DATUM["D_NAD_1983_HARN_Adj_MN_McLeod",SPHEROID["S_GRS_1980_Adj_MN_McLeod",6378414.369,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104743=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Mahnomen",DATUM["D_NAD_1983_HARN_Adj_MN_Mahnomen",SPHEROID["S_GRS_1980_Adj_MN_Mahnomen",6378586.581,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104744=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Marshall",DATUM["D_NAD_1983_HARN_Adj_MN_Marshall",SPHEROID["S_GRS_1980_Adj_MN_Marshall",6378441.801,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104745=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Martin",DATUM["D_NAD_1983_HARN_Adj_MN_Martin",SPHEROID["S_GRS_1980_Adj_MN_Martin",6378521.049,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104746=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Meeker",DATUM["D_NAD_1983_HARN_Adj_MN_Meeker",SPHEROID["S_GRS_1980_Adj_MN_Meeker",6378498.189,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104747=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Morrison",DATUM["D_NAD_1983_HARN_Adj_MN_Morrison",SPHEROID["S_GRS_1980_Adj_MN_Morrison",6378502.761,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104748=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Mower",DATUM["D_NAD_1983_HARN_Adj_MN_Mower",SPHEROID["S_GRS_1980_Adj_MN_Mower",6378521.049,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104749=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Murray",DATUM["D_NAD_1983_HARN_Adj_MN_Murray",SPHEROID["S_GRS_1980_Adj_MN_Murray",6378617.061,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104750=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Nicollet",DATUM["D_NAD_1983_HARN_Adj_MN_Nicollet",SPHEROID["S_GRS_1980_Adj_MN_Nicollet",6378403.701,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104751=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Nobles",DATUM["D_NAD_1983_HARN_Adj_MN_Nobles",SPHEROID["S_GRS_1980_Adj_MN_Nobles",6378624.681,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104752=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Norman",DATUM["D_NAD_1983_HARN_Adj_MN_Norman",SPHEROID["S_GRS_1980_Adj_MN_Norman",6378468.623,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104753=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Olmsted",DATUM["D_NAD_1983_HARN_Adj_MN_Olmsted",SPHEROID["S_GRS_1980_Adj_MN_Olmsted",6378481.425,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104754=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Ottertail",DATUM["D_NAD_1983_HARN_Adj_MN_Ottertail",SPHEROID["S_GRS_1980_Adj_MN_Ottertail",6378525.621,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104755=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Pennington",DATUM["D_NAD_1983_HARN_Adj_MN_Pennington",SPHEROID["S_GRS_1980_Adj_MN_Pennington",6378445.763,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104756=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Pine",DATUM["D_NAD_1983_HARN_Adj_MN_Pine",SPHEROID["S_GRS_1980_Adj_MN_Pine",6378472.281,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104757=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Pipestone",DATUM["D_NAD_1983_HARN_Adj_MN_Pipestone",SPHEROID["S_GRS_1980_Adj_MN_Pipestone",6378670.401,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104758=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Polk",DATUM["D_NAD_1983_HARN_Adj_MN_Polk",SPHEROID["S_GRS_1980_Adj_MN_Polk",6378445.763,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104759=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Pope",DATUM["D_NAD_1983_HARN_Adj_MN_Pope",SPHEROID["S_GRS_1980_Adj_MN_Pope",6378502.761,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104760=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Ramsey",DATUM["D_NAD_1983_HARN_Adj_MN_Ramsey",SPHEROID["S_GRS_1980_Adj_MN_Ramsey",6378418.941,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104761=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Red_Lake",DATUM["D_NAD_1983_HARN_Adj_MN_Red_Lake",SPHEROID["S_GRS_1980_Adj_MN_Red_Lake",6378445.763,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104762=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Redwood",DATUM["D_NAD_1983_HARN_Adj_MN_Redwood",SPHEROID["S_GRS_1980_Adj_MN_Redwood",6378438.753,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104763=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Renville",DATUM["D_NAD_1983_HARN_Adj_MN_Renville",SPHEROID["S_GRS_1980_Adj_MN_Renville",6378414.369,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104764=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Rice",DATUM["D_NAD_1983_HARN_Adj_MN_Rice",SPHEROID["S_GRS_1980_Adj_MN_Rice",6378434.181,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104765=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Rock",DATUM["D_NAD_1983_HARN_Adj_MN_Rock",SPHEROID["S_GRS_1980_Adj_MN_Rock",6378624.681,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104766=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Roseau",DATUM["D_NAD_1983_HARN_Adj_MN_Roseau",SPHEROID["S_GRS_1980_Adj_MN_Roseau",6378449.421,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104767=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_St_Louis_North",DATUM["D_NAD_1983_HARN_Adj_MN_St_Louis_North",SPHEROID["S_GRS_1980_Adj_MN_St_Louis_North",6378543.909,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104768=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_St_Louis_Central",DATUM["D_NAD_1983_HARN_Adj_MN_St_Louis_Central",SPHEROID["S_GRS_1980_Adj_MN_St_Louis_Central",6378605.783,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104769=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_St_Louis_South",DATUM["D_NAD_1983_HARN_Adj_MN_St_Louis_South",SPHEROID["S_GRS_1980_Adj_MN_St_Louis_South",6378540.861,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104770=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Scott",DATUM["D_NAD_1983_HARN_Adj_MN_Scott",SPHEROID["S_GRS_1980_Adj_MN_Scott",6378421.989,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104771=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Sherburne",DATUM["D_NAD_1983_HARN_Adj_MN_Sherburne",SPHEROID["S_GRS_1980_Adj_MN_Sherburne",6378443.325,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104772=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Sibley",DATUM["D_NAD_1983_HARN_Adj_MN_Sibley",SPHEROID["S_GRS_1980_Adj_MN_Sibley",6378414.369,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104773=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Stearns",DATUM["D_NAD_1983_HARN_Adj_MN_Stearns",SPHEROID["S_GRS_1980_Adj_MN_Stearns",6378502.761,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104774=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Steele",DATUM["D_NAD_1983_HARN_Adj_MN_Steele",SPHEROID["S_GRS_1980_Adj_MN_Steele",6378481.425,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104775=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Stevens",DATUM["D_NAD_1983_HARN_Adj_MN_Stevens",SPHEROID["S_GRS_1980_Adj_MN_Stevens",6378502.761,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104776=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Swift",DATUM["D_NAD_1983_HARN_Adj_MN_Swift",SPHEROID["S_GRS_1980_Adj_MN_Swift",6378470.757,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104777=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Todd",DATUM["D_NAD_1983_HARN_Adj_MN_Todd",SPHEROID["S_GRS_1980_Adj_MN_Todd",6378548.481,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104778=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Traverse",DATUM["D_NAD_1983_HARN_Adj_MN_Traverse",SPHEROID["S_GRS_1980_Adj_MN_Traverse",6378463.746,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104779=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Wabasha",DATUM["D_NAD_1983_HARN_Adj_MN_Wabasha",SPHEROID["S_GRS_1980_Adj_MN_Wabasha",6378426.561,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104780=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Wadena",DATUM["D_NAD_1983_HARN_Adj_MN_Wadena",SPHEROID["S_GRS_1980_Adj_MN_Wadena",6378546.957,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104781=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Waseca",DATUM["D_NAD_1983_HARN_Adj_MN_Waseca",SPHEROID["S_GRS_1980_Adj_MN_Waseca",6378481.425,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104782=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Watonwan",DATUM["D_NAD_1983_HARN_Adj_MN_Watonwan",SPHEROID["S_GRS_1980_Adj_MN_Watonwan",6378514.953,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104783=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Winona",DATUM["D_NAD_1983_HARN_Adj_MN_Winona",SPHEROID["S_GRS_1980_Adj_MN_Winona",6378453.688,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104784=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Wright",DATUM["D_NAD_1983_HARN_Adj_MN_Wright",SPHEROID["S_GRS_1980_Adj_MN_Wright",6378443.325,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104785=GEOGCS["GCS_NAD_1983_HARN_Adj_MN_Yellow_Medicine",DATUM["D_NAD_1983_HARN_Adj_MN_Yellow_Medicine",SPHEROID["S_GRS_1980_Adj_MN_Yellow_Medicine",6378530.193,298.2572221008827]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104800=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Adams",DATUM["D_NAD_1983_HARN_Adj_WI_AD_JN",SPHEROID["GRS_1980_Adj_WI_AD_JN",6378376.271,298.268410995005]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104801=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Ashland",DATUM["D_NAD_1983_HARN_Adj_WI_AL",SPHEROID["GRS_1980_Adj_WI_AL",6378471.92,298.272883775229]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104802=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Barron",DATUM["D_NAD_1983_HARN_Adj_WI_BA",SPHEROID["GRS_1980_Adj_WI_BA",6378472.931,298.272931052052]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104803=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Bayfield",DATUM["D_NAD_1983_HARN_Adj_WI_BF",SPHEROID["GRS_1980_Adj_WI_BF",6378411.351,298.270051421254]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104804=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Brown",DATUM["D_NAD_1983_HARN_Adj_WI_BR",SPHEROID["GRS_1980_Adj_WI_BR",6378137.0,298.257222100225]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104805=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Buffalo",DATUM["D_NAD_1983_HARN_Adj_WI_BU",SPHEROID["GRS_1980_Adj_WI_BU",6378380.991,298.268631713702]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104806=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Burnett",DATUM["D_NAD_1983_HARN_Adj_WI_BN",SPHEROID["GRS_1980_Adj_WI_BN",6378414.96,298.270220186885]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104807=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Calumet",DATUM["D_NAD_1983_HARN_Adj_WI_CL_FL_OG_WN",SPHEROID["GRS_1980_Adj_WI_CL_FL_OG_WN",6378345.09,298.266952895494]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104808=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Chippewa",DATUM["D_NAD_1983_HARN_Adj_WI_CP",SPHEROID["GRS_1980_Adj_WI_CP",6378412.542,298.270107115315]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104809=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Clark",DATUM["D_NAD_1983_HARN_Adj_WI_CK",SPHEROID["GRS_1980_Adj_WI_CK",6378470.401,298.272812743089]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104810=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Columbia",DATUM["D_NAD_1983_HARN_Adj_WI_CO",SPHEROID["GRS_1980_Adj_WI_CO",6378376.331,298.268413800752]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104811=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Crawford",DATUM["D_NAD_1983_HARN_Adj_WI_CR",SPHEROID["GRS_1980_Adj_WI_CR",6378379.031,298.268540059328]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104812=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Dane",DATUM["D_NAD_1983_HARN_Adj_WI_DN",SPHEROID["GRS_1980_Adj_WI_DN",6378407.621,298.269876997368]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104813=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Dodge",DATUM["D_NAD_1983_HARN_Adj_WI_DD_JF",SPHEROID["GRS_1980_Adj_WI_DD_JF",6378376.811,298.268436246721]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104814=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Door",DATUM["D_NAD_1983_HARN_Adj_WI_DR",SPHEROID["GRS_1980_Adj_WI_DR",6378313.92,298.26549531037]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104815=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Douglas",DATUM["D_NAD_1983_HARN_Adj_WI_DG",SPHEROID["GRS_1980_Adj_WI_DG",6378414.93,298.270218784012]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104816=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Dunn",DATUM["D_NAD_1983_HARN_Adj_WI_DU",SPHEROID["GRS_1980_Adj_WI_DU",6378413.021,298.270129514522]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104817=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_EauClaire",DATUM["D_NAD_1983_HARN_Adj_WI_EC",SPHEROID["GRS_1980_Adj_WI_EC",6378380.381,298.268603188617]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104818=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Florence",DATUM["D_NAD_1983_HARN_Adj_WI_FN",SPHEROID["GRS_1980_Adj_WI_FN",6378530.851,298.275639532334]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104819=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_FondduLac",DATUM["D_NAD_1983_HARN_Adj_WI_CL_FL_OG_WN",SPHEROID["GRS_1980_Adj_WI_CL_FL_OG_WN",6378345.09,298.266952895494]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104820=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Forest",DATUM["D_NAD_1983_HARN_Adj_WI_FR",SPHEROID["GRS_1980_Adj_WI_FR",6378591.521,298.278476609315]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104821=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Grant",DATUM["D_NAD_1983_HARN_Adj_WI_GT",SPHEROID["GRS_1980_Adj_WI_GT",6378378.881,298.268533044963]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104822=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Green",DATUM["D_NAD_1983_HARN_Adj_WI_GR_LF",SPHEROID["GRS_1980_Adj_WI_GR_LF",6378408.481,298.269917213063]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104823=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_GreenLake",DATUM["D_NAD_1983_HARN_Adj_WI_GL_MQ",SPHEROID["GRS_1980_Adj_WI_GL_MQ",6378375.601,298.268379664173]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104824=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Iowa",DATUM["D_NAD_1983_HARN_Adj_WI_IA",SPHEROID["GRS_1980_Adj_WI_IA",6378408.041,298.269896637591]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104825=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Iron",DATUM["D_NAD_1983_HARN_Adj_WI_IR",SPHEROID["GRS_1980_Adj_WI_IR",6378655.071,298.281448362111]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104826=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Jackson",DATUM["D_NAD_1983_HARN_Adj_WI_JA",SPHEROID["GRS_1980_Adj_WI_JA",6378409.151,298.269948543895]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104827=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Jefferson",DATUM["D_NAD_1983_HARN_Adj_WI_DD_JF",SPHEROID["GRS_1980_Adj_WI_DD_JF",6378376.811,298.268436246721]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104828=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Juneau",DATUM["D_NAD_1983_HARN_Adj_WI_AD_JN",SPHEROID["GRS_1980_Adj_WI_AD_JN",6378376.271,298.268410995005]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104829=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Kenosha",DATUM["D_NAD_1983_HARN_Adj_WI_KN_MW_OZ_RA",SPHEROID["GRS_1980_Adj_WI_KN_MW_OZ_RA",6378315.7,298.265578547505]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104830=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Kewaunee",DATUM["D_NAD_1983_HARN_Adj_WI_KW_MT_SG",SPHEROID["GRS_1980_Adj_WI_KW_MT_SG",6378285.86,298.264183156421]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104831=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_LaCrosse",DATUM["D_NAD_1983_HARN_Adj_WI_LC",SPHEROID["GRS_1980_Adj_WI_LC",6378379.301,298.268552685186]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104832=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Lafayette",DATUM["D_NAD_1983_HARN_Adj_WI_GR_LF",SPHEROID["GRS_1980_Adj_WI_GR_LF",6378408.481,298.269917213063]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104833=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Langlade",DATUM["D_NAD_1983_HARN_Adj_WI_LG",SPHEROID["GRS_1980_Adj_WI_LG",6378560.121,298.277008268831]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104834=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Lincoln",DATUM["D_NAD_1983_HARN_Adj_WI_LN",SPHEROID["GRS_1980_Adj_WI_LN",6378531.821,298.275684891897]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104835=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Manitowoc",DATUM["D_NAD_1983_HARN_Adj_WI_KW_MT_SG",SPHEROID["GRS_1980_Adj_WI_KW_MT_SG",6378285.86,298.264183156421]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104836=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Marathon",DATUM["D_NAD_1983_HARN_Adj_WI_MA",SPHEROID["GRS_1980_Adj_WI_MA",6378500.6,298.274224921888]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104837=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Marinette",DATUM["D_NAD_1983_HARN_Adj_WI_MN",SPHEROID["GRS_1980_Adj_WI_MN",6378376.041,298.268400239645]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104838=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Marquette",DATUM["D_NAD_1983_HARN_Adj_WI_GL_MQ",SPHEROID["GRS_1980_Adj_WI_GL_MQ",6378375.601,298.268379664173]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104839=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Menominee",DATUM["D_NAD_1983_HARN_Adj_WI_ME",SPHEROID["GRS_1980_Adj_WI_ME",6378406.601,298.269829299684]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104840=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Milwaukee",DATUM["D_NAD_1983_HARN_Adj_WI_KN_MW_OZ_RA",SPHEROID["GRS_1980_Adj_WI_KN_MW_OZ_RA",6378315.7,298.265578547505]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104841=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Monroe",DATUM["D_NAD_1983_HARN_Adj_WI_MR",SPHEROID["GRS_1980_Adj_WI_MR",6378438.991,298.27134393498]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104842=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Oconto",DATUM["D_NAD_1983_HARN_Adj_WI_OC",SPHEROID["GRS_1980_Adj_WI_OC",6378345.42,298.266968327098]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104843=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Oneida",DATUM["D_NAD_1983_HARN_Adj_WI_ON",SPHEROID["GRS_1980_Adj_WI_ON",6378593.86,298.278585986653]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104844=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Outagamie",DATUM["D_NAD_1983_HARN_Adj_WI_CL_FL_OG_WN",SPHEROID["GRS_1980_Adj_WI_CL_FL_OG_WN",6378345.09,298.266952895494]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104845=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Ozaukee",DATUM["D_NAD_1983_HARN_Adj_WI_KN_MW_OZ_RA",SPHEROID["GRS_1980_Adj_WI_KN_MW_OZ_RA",6378315.7,298.265578547505]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104846=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Pepin",DATUM["D_NAD_1983_HARN_Adj_WI_PP_PC",SPHEROID["GRS_1980_Adj_WI_PP_PC",6378381.271,298.268644807185]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104847=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Pierce",DATUM["D_NAD_1983_HARN_Adj_WI_PP_PC",SPHEROID["GRS_1980_Adj_WI_PP_PC",6378381.271,298.268644807185]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104848=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Polk",DATUM["D_NAD_1983_HARN_Adj_WI_PK",SPHEROID["GRS_1980_Adj_WI_PK",6378413.671,298.270159910105]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104849=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Portage",DATUM["D_NAD_1983_HARN_Adj_WI_PT",SPHEROID["GRS_1980_Adj_WI_PT",6378344.377,298.266919538913]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104850=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Price",DATUM["D_NAD_1983_HARN_Adj_WI_PR",SPHEROID["GRS_1980_Adj_WI_PR",6378563.891,298.277184563214]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104851=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Racine",DATUM["D_NAD_1983_HARN_Adj_WI_KN_MW_OZ_RA",SPHEROID["GRS_1980_Adj_WI_KN_MW_OZ_RA",6378315.7,298.265578547505]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104852=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Richland",DATUM["D_NAD_1983_HARN_Adj_WI_RC",SPHEROID["GRS_1980_Adj_WI_RC",6378408.091,298.269898975713]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104853=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Rock",DATUM["D_NAD_1983_HARN_Adj_WI_RK",SPHEROID["GRS_1980_Adj_WI_RK",6378377.671,298.268476462415]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104854=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Rusk",DATUM["D_NAD_1983_HARN_Adj_WI_RS",SPHEROID["GRS_1980_Adj_WI_RS",6378472.751,298.272922634813]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104855=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_StCroix",DATUM["D_NAD_1983_HARN_Adj_WI_SC",SPHEROID["GRS_1980_Adj_WI_SC",6378412.511,298.270105665679]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104856=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Sauk",DATUM["D_NAD_1983_HARN_Adj_WI_SK",SPHEROID["GRS_1980_Adj_WI_SK",6378407.281,298.26986109814]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104857=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Sawyer",DATUM["D_NAD_1983_HARN_Adj_WI_SW",SPHEROID["GRS_1980_Adj_WI_SW",6378534.451,298.275807877103]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104858=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Shawano",DATUM["D_NAD_1983_HARN_Adj_WI_SH",SPHEROID["GRS_1980_Adj_WI_SH",6378406.051,298.269803580344]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104859=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Sheboygan",DATUM["D_NAD_1983_HARN_Adj_WI_KW_MT_SG",SPHEROID["GRS_1980_Adj_WI_KW_MT_SG",6378285.86,298.264183156421]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104860=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Taylor",DATUM["D_NAD_1983_HARN_Adj_WI_TA",SPHEROID["GRS_1980_Adj_WI_TA",6378532.921,298.275736330576]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104861=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Trempealeau",DATUM["D_NAD_1983_HARN_Adj_WI_TR",SPHEROID["GRS_1980_Adj_WI_TR",6378380.091,298.26858962751]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104862=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Vernon",DATUM["D_NAD_1983_HARN_Adj_WI_VR",SPHEROID["GRS_1980_Adj_WI_VR",6378408.941,298.269938723784]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104863=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Vilas",DATUM["D_NAD_1983_HARN_Adj_WI_VI",SPHEROID["GRS_1980_Adj_WI_VI",6378624.171,298.280003402845]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104864=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Walworth",DATUM["D_NAD_1983_HARN_Adj_WI_WW",SPHEROID["GRS_1980_Adj_WI_WW",6378377.411,298.268464304182]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104865=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Washburn",DATUM["D_NAD_1983_HARN_Adj_WI_WB",SPHEROID["GRS_1980_Adj_WI_WB",6378474.591,298.273008677695]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104866=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Washington",DATUM["D_NAD_1983_HARN_Adj_WI_WA",SPHEROID["GRS_1980_Adj_WI_WA",6378407.141,298.269854551399]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104867=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Waukesha",DATUM["D_NAD_1983_HARN_Adj_WI_WK",SPHEROID["GRS_1980_Adj_WI_WK",6378376.871,298.268439052467]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104868=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Waupaca",DATUM["D_NAD_1983_HARN_Adj_WI_WP",SPHEROID["GRS_1980_Adj_WI_WP",6378375.251,298.268363297321]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104869=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Waushara",DATUM["D_NAD_1983_HARN_Adj_WI_WS",SPHEROID["GRS_1980_Adj_WI_WS",6378405.971,298.269799839349]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104870=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Winnebago",DATUM["D_NAD_1983_HARN_Adj_WI_CL_FL_OG_WN",SPHEROID["GRS_1980_Adj_WI_CL_FL_OG_WN",6378345.09,298.266952895494]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104871=GEOGCS["GCS_NAD_1983_HARN_Adj_WI_Wood",DATUM["D_NAD_1983_HARN_Adj_WI_WD",SPHEROID["GRS_1980_Adj_WI_WD",6378437.651,298.271281273316]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
+104900=GEOGCS["GCS_Mercury_2000",DATUM["D_Mercury_2000",SPHEROID["Mercury_2000_IAU_IAG",2439700.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104901=GEOGCS["GCS_Venus_1985",DATUM["D_Venus_1985",SPHEROID["Venus_1985_IAU_IAG_COSPAR",6051000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104902=GEOGCS["GCS_Venus_2000",DATUM["D_Venus_2000",SPHEROID["Venus_2000_IAU_IAG",6051800.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104903=GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104904=GEOGCS["GCS_Mars_1979",DATUM["D_Mars_1979",SPHEROID["Mars_1979_IAU_IAG",3393400.0,192.0430107526882]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104905=GEOGCS["GCS_Mars_2000",DATUM["D_Mars_2000",SPHEROID["Mars_2000_IAU_IAG",3396190.0,169.8944472236118]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104906=GEOGCS["D_Deimos_2000",DATUM["D_Deimos_2000",SPHEROID["Deimos_2000_IAU_IAG",6200.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104907=GEOGCS["D_Phobos_2000",DATUM["D_Phobos_2000",SPHEROID["Phobos_2000_IAU_IAG",11100.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104908=GEOGCS["GCS_Jupiter_2000",DATUM["D_Jupiter_2000",SPHEROID["Jupiter_2000_IAU_IAG",71492000.0,15.41440275981026]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104909=GEOGCS["GCS_Adrastea_2000",DATUM["D_Adrastea_2000",SPHEROID["Adrastea_2000_IAU_IAG",8200.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104910=GEOGCS["GCS_Amalthea_2000",DATUM["D_Amalthea_2000",SPHEROID["Amalthea_2000_IAU_IAG",83500.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104911=GEOGCS["GCS_Ananke_2000",DATUM["D_Ananke_2000",SPHEROID["Ananke_2000_IAU_IAG",10000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104912=GEOGCS["GCS_Callisto_2000",DATUM["D_Callisto_2000",SPHEROID["Callisto_2000_IAU_IAG",2409300.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104913=GEOGCS["GCS_Carme_2000",DATUM["D_Carme_2000",SPHEROID["Carme_2000_IAU_IAG",15000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104914=GEOGCS["GCS_Elara_2000",DATUM["D_Elara_2000",SPHEROID["Elara_2000_IAU_IAG",40000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104915=GEOGCS["GCS_Europa_2000",DATUM["D_Europa_2000",SPHEROID["Europa_2000_IAU_IAG",1562090.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104916=GEOGCS["GCS_Ganymede_2000",DATUM["D_Ganymede_2000",SPHEROID["Ganymede_2000_IAU_IAG",2632345.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104917=GEOGCS["GCS_Himalia_2000",DATUM["D_Himalia_2000",SPHEROID["Himalia_2000_IAU_IAG",85000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104918=GEOGCS["GCS_Io_2000",DATUM["D_Io_2000",SPHEROID["Io_2000_IAU_IAG",1821460.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104919=GEOGCS["D_Leda_2000",DATUM["D_Leda_2000",SPHEROID["Leda_2000_IAU_IAG",5000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104920=GEOGCS["GCS_Lysithea_2000",DATUM["D_Lysithea_2000",SPHEROID["Lysithea_2000_IAU_IAG",12000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104921=GEOGCS["GCS_Metis_2000",DATUM["D_Metis_2000",SPHEROID["Metis_2000_IAU_IAG",30000.0,3.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104922=GEOGCS["GCS_Pasiphae_2000",DATUM["D_Pasiphae_2000",SPHEROID["Pasiphae_2000_IAU_IAG",18000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104923=GEOGCS["GCS_Sinope_2000",DATUM["D_Sinope_2000",SPHEROID["Sinope_2000_IAU_IAG",14000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104924=GEOGCS["GCS_Thebe_2000",DATUM["D_Thebe_2000",SPHEROID["Thebe_2000_IAU_IAG",49300.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104925=GEOGCS["GCS_Saturn_2000",DATUM["D_Saturn_2000",SPHEROID["Saturn_2000_IAU_IAG",60268000.0,10.2079945799458]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104926=GEOGCS["GCS_Atlas_2000",DATUM["D_Atlas_2000",SPHEROID["Atlas_2000_IAU_IAG",16000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104927=GEOGCS["GCS_Calypso_2000",DATUM["D_Calypso_2000",SPHEROID["Calypso_2000_IAU_IAG",9500.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104928=GEOGCS["GCS_Dione_2000",DATUM["D_Dione_2000",SPHEROID["Dione_2000_IAU_IAG",560000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104929=GEOGCS["GCS_Enceladus_2000",DATUM["D_Enceladus_2000",SPHEROID["Enceladus_2000_IAU_IAG",249400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104930=GEOGCS["GCS_Epimetheus_2000",DATUM["D_Epimetheus_2000",SPHEROID["Epimetheus_2000_IAU_IAG",59500.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104931=GEOGCS["GCS_Helene_2000",DATUM["D_Helene_2000",SPHEROID["Helene_2000_IAU_IAG",17500.0,1.041666666666667]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104932=GEOGCS["GCS_Hyperion_2000",DATUM["D_Hyperion_2000",SPHEROID["Hyperion_2000_IAU_IAG",133000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104933=GEOGCS["GCS_Iapetus_2000",DATUM["D_Iapetus_2000",SPHEROID["Iapetus_2000_IAU_IAG",718000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104934=GEOGCS["GCS_Janus_2000",DATUM["D_Janus_2000",SPHEROID["Janus_2000_IAU_IAG",888000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104935=GEOGCS["GCS_Mimas_2000",DATUM["D_Mimas_2000",SPHEROID["Mimas_2000_IAU_IAG",1986300.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104936=GEOGCS["GCS_Pan_2000",DATUM["D_Pan_2000",SPHEROID["Pan_2000_IAU_IAG",10000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104937=GEOGCS["GCS_Pandora_2000",DATUM["D_Pandora_2000",SPHEROID["Pandora_2000_IAU_IAG",41900.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104938=GEOGCS["GCS_Phoebe_2000",DATUM["D_Phoebe_2000",SPHEROID["Phoebe_2000_IAU_IAG",110000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104939=GEOGCS["GCS_Prometheus_2000",DATUM["D_Prometheus_2000",SPHEROID["Prometheus_2000_IAU_IAG",50100.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104940=GEOGCS["GCS_Rhea_2000",DATUM["D_Rhea_2000",SPHEROID["Rhea_2000_IAU_IAG",764000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104941=GEOGCS["GCS_Telesto_2000",DATUM["D_Telesto_2000",SPHEROID["Telesto_2000_IAU_IAG",11000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104942=GEOGCS["GCS_Tethys_2000",DATUM["D_Tethys_2000",SPHEROID["Tethys_2000_IAU_IAG",529800.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104943=GEOGCS["GCS_Titan_2000",DATUM["D_Titan_2000",SPHEROID["Titan_2000_IAU_IAG",2575000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104944=GEOGCS["GCS_Uranus_2000",DATUM["D_Uranus_2000",SPHEROID["Uranus_2000_IAU_IAG",25559000.0,43.61604095563141]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104945=GEOGCS["GCS_Ariel_2000",DATUM["D_Ariel_2000",SPHEROID["Ariel_2000_IAU_IAG",578900.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104946=GEOGCS["GCS_Belinda_2000",DATUM["D_Belinda_2000",SPHEROID["Belinda_2000_IAU_IAG",33000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104947=GEOGCS["GCS_Bianca_2000",DATUM["D_Bianca_2000",SPHEROID["Bianca_2000_IAU_IAG",21000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104948=GEOGCS["GCS_Cordelia_2000",DATUM["D_Cordelia_2000",SPHEROID["Cordelia_2000_IAU_IAG",13000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104949=GEOGCS["GCS_Cressida_2000",DATUM["D_Cressida_2000",SPHEROID["Cressida_2000_IAU_IAG",31000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104950=GEOGCS["GCS_Desdemona_2000",DATUM["D_Desdemona_2000",SPHEROID["Desdemona_2000_IAU_IAG",27000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104951=GEOGCS["GCS_Juliet_2000",DATUM["D_Juliet_2000",SPHEROID["Juliet_2000_IAU_IAG",42000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104952=GEOGCS["GCS_Miranda_2000",DATUM["D_Miranda_2000",SPHEROID["Miranda_2000_IAU_IAG",235800.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104953=GEOGCS["GCS_Oberon_2000",DATUM["D_Oberon_2000",SPHEROID["Oberon_2000_IAU_IAG",761400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104954=GEOGCS["GCS_Ophelia_2000",DATUM["D_Ophelia_2000",SPHEROID["Ophelia_2000_IAU_IAG",15000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104955=GEOGCS["GCS_Portia_2000",DATUM["D_Portia_2000",SPHEROID["Portia_2000_IAU_IAG",54000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104956=GEOGCS["GCS_Puck_2000",DATUM["D_Puck_2000",SPHEROID["Puck_2000_IAU_IAG",77000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104957=GEOGCS["GCS_Rosalind_2000",DATUM["D_Rosalind_2000",SPHEROID["Rosalind_2000_IAU_IAG",27000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104958=GEOGCS["GCS_Titania_2000",DATUM["D_Titania_2000",SPHEROID["Titania_2000_IAU_IAG",788900.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104959=GEOGCS["GCS_Umbriel_2000",DATUM["D_Umbriel_2000",SPHEROID["Umbriel_2000_IAU_IAG",584700.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104960=GEOGCS["GCS_Neptune_2000",DATUM["D_Neptune_2000",SPHEROID["Neptune_2000_IAU_IAG",24764000.0,58.54373522458629]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104961=GEOGCS["GCS_Despina_2000",DATUM["D_Despina_2000",SPHEROID["Despina_2000_IAU_IAG",74000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104962=GEOGCS["GCS_Galatea_2000",DATUM["D_Galatea_2000",SPHEROID["Galatea_2000_IAU_IAG",79000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104963=GEOGCS["GCS_Larissa_2000",DATUM["D_Larissa_2000",SPHEROID["Larissa_2000_IAU_IAG",104000.0,6.933333333333334]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104964=GEOGCS["GCS_Naiad_2000",DATUM["D_Naiad_2000",SPHEROID["Naiad_2000_IAU_IAG",29000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104965=GEOGCS["GCS_Nereid_2000",DATUM["D_Nereid_2000",SPHEROID["Nereid_2000_IAU_IAG",170000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104966=GEOGCS["GCS_Proteus_2000",DATUM["D_Proteus_2000",SPHEROID["Proteus_2000_IAU_IAG",208000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104967=GEOGCS["GCS_Thalassa_2000",DATUM["D_Thalassa_2000",SPHEROID["Thalassa_2000_IAU_IAG",40000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104968=GEOGCS["GCS_Triton_2000",DATUM["D_Triton_2000",SPHEROID["Triton_2000_IAU_IAG",1352600.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104969=GEOGCS["GCS_Pluto_2000",DATUM["D_Pluto_2000",SPHEROID["Pluto_2000_IAU_IAG",1195000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
+104970=GEOGCS["GCS_Charon_2000",DATUM["D_Charon_2000",SPHEROID["Charon_2000_IAU_IAG",593000.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]]
Index: /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/epsg/unnamed.properties
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/epsg/unnamed.properties	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/epsg/unnamed.properties	(revision 28000)
@@ -0,0 +1,32 @@
+#
+# Additional CRS to provide in the "EPSG" name space.  It is technically possible
+# to provide in this file most CRS defined in the EPSG database, thus providing a
+# way to create CRS from an EPSG code without JDBC connection to an EPSG database.
+# However the main purpose of this file is rather to provide additional CRS in
+# common use while not defined in the official database. If a CRS is found both in
+# this file and in a SQL database, then the later will have precedence. Duplicated
+# values can be found with the following command line:
+#
+#     java -cp gt2-epsg-extension.jar:gt2-epsg-hsql.jar \
+#         org.geotools.referencing.factory.epsg.FactoryUsingWKT -test -duplicated
+#
+#
+# Notes on the WKT strings used in this file:
+#   * When not specified, "false_easting" and "false_northing" parameters default to 0.
+#   * The final AUTHORITY["EPSG", <code>] element is optional. We recommand to ommit it
+#     since the WKT parser will automatically synthesize an appropriate one.  Note that
+#     this recommandation doesn't apply to CRS defined outside of this file.
+#   * Do not put AXIS[...] elements. We want the default (longitude,latitude) axis order
+#     in order to construct CRS insensitive to the FORCE_LONGITUDE_FIRST_AXIS_ORDER hint.
+#
+# $Id: unnamed.properties 36543 2011-02-07 20:56:44Z aaime $
+# $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/epsg-extension/src/main/resources/org/geotools/referencing/factory/epsg/unnamed.properties $
+#
+
+# ESRI ArcGIS 9.3 NTF projections based on Greenwich meridian. They do not have any official code, "99999x" is an arbitrary choice.
+# See http://support.esrifrance.fr/Documents/ArcGIS/projectionsArcGIS10/ArcGis_10_Comprendre_les_nouveaut%E9s_des_projections_fran%E7aises_OK.pdf
+# TOWGS84 clause comes from spatialreference.org
+999996=PROJCS["NTF_Lambert_Zone_I",GEOGCS["GCS_NTF",DATUM["D_NTF",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602],TOWGS84[-168,-60,320,0,0,0,0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["False_Northing",200000.0],PARAMETER["Central_Meridian",2.3372291667],PARAMETER["Standard_Parallel_1",48.5985227778],PARAMETER["Standard_Parallel_2",50.3959116667],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",49.5],UNIT["Meter",1.0]]
+999997=PROJCS["NTF_Lambert_Zone_II",GEOGCS["GCS_NTF",DATUM["D_NTF",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602],TOWGS84[-168,-60,320,0,0,0,0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["False_Northing",200000.0],PARAMETER["Central_Meridian",2.3372291667],PARAMETER["Standard_Parallel_1",45.8989188889],PARAMETER["Standard_Parallel_2",47.6960144444],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",46.8],UNIT["Meter",1.0]]
+999998=PROJCS["NTF_Lambert_Zone_III",GEOGCS["GCS_NTF",DATUM["D_NTF",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602],TOWGS84[-168,-60,320,0,0,0,0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",600000.0],PARAMETER["False_Northing",200000.0],PARAMETER["Central_Meridian",2.3372291667],PARAMETER["Standard_Parallel_1",43.1992913889],PARAMETER["Standard_Parallel_2",44.9960938889],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",44.1],UNIT["Meter",1.0]]
+999999=PROJCS["NTF_Lambert_Zone_IV",GEOGCS["GCS_NTF",DATUM["D_NTF",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602],TOWGS84[-168,-60,320,0,0,0,0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",234.358],PARAMETER["False_Northing",185861.369],PARAMETER["Central_Meridian",2.3372291667],PARAMETER["Standard_Parallel_1",41.5603877778],PARAMETER["Standard_Parallel_2",42.7676633333],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",42.165],UNIT["Meter",1.0]]
Index: /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/epsg/unnamed_original.properties
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/epsg/unnamed_original.properties	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/org/geotools/referencing/factory/epsg/unnamed_original.properties	(revision 28000)
@@ -0,0 +1,53 @@
+#
+# Additional CRS to provide in the "EPSG" name space.  It is technically possible
+# to provide in this file most CRS defined in the EPSG database, thus providing a
+# way to create CRS from an EPSG code without JDBC connection to an EPSG database.
+# However the main purpose of this file is rather to provide additional CRS in
+# common use while not defined in the official database. If a CRS is found both in
+# this file and in a SQL database, then the later will have precedence. Duplicated
+# values can be found with the following command line:
+#
+#     java -cp gt2-epsg-extension.jar:gt2-epsg-hsql.jar \
+#         org.geotools.referencing.factory.epsg.FactoryUsingWKT -test -duplicated
+#
+#
+# Notes on the WKT strings used in this file:
+#   * When not specified, "false_easting" and "false_northing" parameters default to 0.
+#   * The final AUTHORITY["EPSG", <code>] element is optional. We recommand to ommit it
+#     since the WKT parser will automatically synthesize an appropriate one.  Note that
+#     this recommandation doesn't apply to CRS defined outside of this file.
+#   * Do not put AXIS[...] elements. We want the default (longitude,latitude) axis order
+#     in order to construct CRS insensitive to the FORCE_LONGITUDE_FIRST_AXIS_ORDER hint.
+#
+# $Id: unnamed.properties 36543 2011-02-07 20:56:44Z aaime $
+# $URL: http://svn.osgeo.org/geotools/branches/2.7.x/modules/plugin/epsg-extension/src/main/resources/org/geotools/referencing/factory/epsg/unnamed.properties $
+#
+
+# -----------------------------------------------------------------
+# The following values are inside the EPSG reserved code range. The
+# code 18001 is used for "Austria Gauss-Kruger West Zone" conversion.
+# We disable those CRS for now.
+# -----------------------------------------------------------------
+# 18001=PROJCS["Geoscience Australia Standard National Scale Lambert Projection",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1978",6378135,298.26],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",134.0],PARAMETER["latitude_of_origin",0.0],PARAMETER["standard_parallel_1",-18.0],PARAMETER["standard_parallel_2",-36.0],UNIT["Meter",1]]
+
+41001=PROJCS["WGS84 / Simple Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],UNIT["Meter",1]]
+42101=PROJCS["WGS 84 / LCC Canada",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],PARAMETER["false_northing",-8000000.0],UNIT["Meter",1]]
+42102=PROJCS["BC_Albers",GEOGCS["GCS_North_American_1983",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Albers_Conic_Equal_Area"],PARAMETER["False_Easting",1000000],PARAMETER["Central_Meridian",-126],PARAMETER["Standard_Parallel_1",50],PARAMETER["Standard_Parallel_2",58.5],PARAMETER["Latitude_Of_Origin",45],UNIT["Meter",1]]
+42103=PROJCS["WGS 84 / LCC USA",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1978",6378135,298.26]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-100.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",33.0],PARAMETER["standard_parallel_2",45.0],UNIT["Meter",1]]
+42104=PROJCS["NAD83 / MTM zone 8 Québec",GEOGCS["GRS80",DATUM["GRS_1980",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-73.5],PARAMETER["scale_factor",0.9999],PARAMETER["false_easting",304800],UNIT["Meter",1]]
+42105=PROJCS["WGS84 / Merc NorthAm",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",-96],UNIT["Meter",1]]
+42106=PROJCS["WGS84 / Lambert Azim Mozambique",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Azimuthal_Equal_Area"],PARAMETER["latitude_of_origin",5],PARAMETER["central_meridian",20],UNIT["Meter",1]]
+42301=PROJCS["NAD27 / Polar Stereographic / CM=-98",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.978698213901],TOWGS84[-9,151,185]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Stereographic"],PARAMETER["latitude_of_origin",90],PARAMETER["central_meridian",-98.0],PARAMETER["scale_factor",0.9996],UNIT["Meter",1]]
+42302=PROJCS["JapanOrtho.09 09",GEOGCS["Lon/Lat.Tokyo Datum",DATUM["Tokyo Datum",SPHEROID["anon",6377397.155,299.15281310608]],PRIMEM["Greenwich",0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["Central_Meridian",139.833333333333],PARAMETER["Latitude_of_Origin",36],PARAMETER["Scale_Factor",0.9999],UNIT["Meter",1]]
+42303=PROJCS["NAD83 / Albers NorthAm",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Albers_conic_equal_area"],PARAMETER["central_meridian",-96.0],PARAMETER["latitude_of_origin",23],PARAMETER["standard_parallel_1",29.5],PARAMETER["standard_parallel_2",45.5],UNIT["Meter",1]]
+42304=PROJCS["NAD83 / NRCan LCC Canada",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",49.0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],UNIT["Meter",1]]
+42305=PROJCS["France_II",GEOGCS["GCS_NTF_Paris",DATUM["Nouvelle_Triangulation_Francaise",SPHEROID["Clarke_1880_IGN",6378249.2,293.46602]],PRIMEM["Paris",2.337229166666667],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["False_Easting",600000],PARAMETER["False_Northing",2200000],PARAMETER["Central_Meridian",0],PARAMETER["Standard_Parallel_1",45.898918964419],PARAMETER["Standard_Parallel_2",47.696014502038],PARAMETER["Latitude_Of_Origin",46.8],UNIT["Meter",1]]
+42306=PROJCS["NAD83/QC_LCC",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-68.5],PARAMETER["latitude_of_origin",44],PARAMETER["standard_parallel_1",46],PARAMETER["standard_parallel_2",60],UNIT["Meter",1]]
+42307=PROJCS["NAD83 / Texas Central - feet",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",31.8833333333333],PARAMETER["standard_parallel_2",30.1166666666667],PARAMETER["latitude_of_origin",29.6666666666667],PARAMETER["central_meridian",-100.333333333333],PARAMETER["false_easting",2296583.33333333333333],PARAMETER["false_northing",9842500],UNIT["US_Foot",0.30480060960121924]]
+42308=PROJCS["NAD27 / California Albers",GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.978698213901],TOWGS84[-9,151,185]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Albers_conic_equal_area"],PARAMETER["central_meridian",-120.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",34],PARAMETER["standard_parallel_2",40.5],PARAMETER["false_northing",-4000000],UNIT["Meter",1]]
+42309=PROJCS["NAD 83 / LCC Canada AVHRR-2",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-95.0],PARAMETER["latitude_of_origin",0],PARAMETER["standard_parallel_1",49.0],PARAMETER["standard_parallel_2",77.0],UNIT["Meter",1]]
+42310=PROJCS["WGS84+GRS80 / Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],UNIT["Meter",1]]
+42311=PROJCS["NAD83 / LCC Statcan",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["central_meridian",-91.866667],PARAMETER["latitude_of_origin",63.390675],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",77],PARAMETER["false_easting",6200000],PARAMETER["false_northing",3000000],UNIT["Meter",1]]
+100001=GEOGCS["NAD83 / NFIS Seconds",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["Decimal_Second",4.84813681109536e-06]]
+100002=PROJCS["NAD83 / Austin",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101],TOWGS84[0,0,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",31.8833333333333],PARAMETER["standard_parallel_2",30.1166666666667],PARAMETER["latitude_of_origin",29.6666666666667],PARAMETER["central_meridian",-100.333333333333],PARAMETER["false_easting",2296583.333333],PARAMETER["false_northing",9842500.0000000],UNIT["Meter",1]]
+900913=PROJCS["Google Projection",GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]],UNIT["degree", 0.017453292519943295],AXIS["Geodetic longitude", EAST],AXIS["Geodetic latitude", NORTH],AUTHORITY["EPSG","4326"]],PROJECTION["Popular Visualisation Pseudo Mercator", AUTHORITY["EPSG","1024"]],PARAMETER["semi_minor", 6378137.0],PARAMETER["latitude_of_origin", 0.0],PARAMETER["central_meridian", 0.0],PARAMETER["scale_factor", 1.0],PARAMETER["false_easting", 0.0],PARAMETER["false_northing", 0.0],UNIT["m", 1.0]]
Index: /applications/editors/josm/plugins/opendata/resources/org/openstreetmap/josm/plugins/opendata/core/resources/dictionary.fr.csv
===================================================================
--- /applications/editors/josm/plugins/opendata/resources/org/openstreetmap/josm/plugins/opendata/core/resources/dictionary.fr.csv	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/resources/org/openstreetmap/josm/plugins/opendata/core/resources/dictionary.fr.csv	(revision 28000)
@@ -0,0 +1,68 @@
+"Nom";"Correction"
+"Aeropostale";"Aéropostale"
+"Appliquees";"Appliquées"
+"Arc En Ciel";"Arc-en-ciel"
+"Aries";"Ariès"
+"arret";"arrêt"
+"Barriere";"Barrière"
+"Bibliotheque";"Bibliothèque"
+"Bienes";"Biénès"
+"C.n.r.s.";"CNRS"
+"Cdt";"Commandant"
+"Cel";"Colonel"
+"Cevennes";"Cévennes"
+"Chateau";"Château"
+"Chenes";"Chênes"
+"Cite";"Cité"
+"Cre";"Commissaire"
+"Crx";"Croix"
+"D'";"d'"
+"De";"de"
+"Deodat";"Déodat"
+"Departement";"Département"
+"Des";"des"
+"Dr";"Docteur"
+"Du";"du"
+"E.n.a.c.";"ENAC"
+"Ecole";"École"
+"Edouard";"Édouard"
+"Eglise";"Église"
+"Emile";"Émile"
+"Et";"et"
+"Etats";"États"
+"Etienne";"Étienne"
+"Faculte";"Faculté"
+"Francois";"François"
+"Frederic";"Frédéric"
+"Gen";"Général"
+"General";"Général"
+"I.n.s.a.";"INSA"
+"Ii";"II"
+"Iii";"III"
+"Ile";"Île"
+"Itineraire";"Itinéraire"
+"Iut";"IUT"
+"Iv";"IV"
+"Jaures";"Jaurès"
+"Journees";"Journées"
+"Lt";"Lieutenant"
+"Mayssonnie";"Mayssonnié"
+"Metro";"Métro"
+"Mgr";"Monseigneur"
+"Osete";"Osète"
+"Pdt";"Président"
+"Pere";"Père"
+"Pr";"Professeur"
+"President";"Président"
+"Rene";"René"
+"Republique";"République"
+"Routiere";"Routière"
+"St";"Saint"
+"Ste";"Sainte"
+"Universite";"Université"
+"Ups";"UPS"
+"Urss";"URSS"
+"Vi";"VI"
+"Vii";"VII"
+"Viii";"VIII"
+"Y";"y"
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/OdPlugin.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/OdPlugin.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/OdPlugin.java	(revision 28000)
@@ -0,0 +1,123 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.ExtensionFileFilter;
+import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
+import org.openstreetmap.josm.plugins.Plugin;
+import org.openstreetmap.josm.plugins.PluginInformation;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.gui.OdDialog;
+import org.openstreetmap.josm.plugins.opendata.core.gui.OdPreferenceSetting;
+import org.openstreetmap.josm.plugins.opendata.core.io.AbstractImporter;
+import org.openstreetmap.josm.plugins.opendata.core.io.archive.ZipImporter;
+import org.openstreetmap.josm.plugins.opendata.core.io.geographic.KmlKmzImporter;
+import org.openstreetmap.josm.plugins.opendata.core.io.geographic.MifTabImporter;
+import org.openstreetmap.josm.plugins.opendata.core.io.geographic.ShpImporter;
+import org.openstreetmap.josm.plugins.opendata.core.io.tabular.CsvImporter;
+import org.openstreetmap.josm.plugins.opendata.core.io.tabular.OdsImporter;
+import org.openstreetmap.josm.plugins.opendata.core.io.tabular.XlsImporter;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleHandler;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleInformation;
+
+public final class OdPlugin extends Plugin implements OdConstants {
+
+	private static OdPlugin instance;
+	
+	public OdPlugin(PluginInformation info) { // NO_UCD
+		super(info);
+		if (instance == null) {
+			instance = this;
+		} else {
+			throw new IllegalAccessError("Cannot instantiate plugin twice !");
+		}
+        // Allow JOSM to import more files
+		for (AbstractImporter importer : Arrays.asList(new AbstractImporter[]{
+				new CsvImporter(), new OdsImporter(), new XlsImporter(), // Tabular file formats
+				new KmlKmzImporter(), new ShpImporter(), new MifTabImporter(), // Geographic file formats
+				new ZipImporter() // Archive containing any of the others
+		})) {
+			ExtensionFileFilter.importers.add(importer);
+		}
+        // Load modules
+        loadModules();
+	}
+	
+	public static final OdPlugin getInstance() {
+		return instance;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.Plugin#mapFrameInitialized(org.openstreetmap.josm.gui.MapFrame, org.openstreetmap.josm.gui.MapFrame)
+	 */
+	@Override
+	public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
+		if (newFrame != null) {
+			newFrame.addToggleDialog(new OdDialog());
+		}
+	}
+	
+    /* (non-Javadoc)
+     * @see org.openstreetmap.josm.plugins.Plugin#getPreferenceSetting()
+     */
+    @Override
+    public PreferenceSetting getPreferenceSetting() {
+        return new OdPreferenceSetting();
+    }
+    
+    private final void loadModules() {
+        List<ModuleInformation> modulesToLoad = ModuleHandler.buildListOfModulesToLoad(Main.parent);
+        if (!modulesToLoad.isEmpty() && ModuleHandler.checkAndConfirmModuleUpdate(Main.parent)) {
+            modulesToLoad = ModuleHandler.updateModules(Main.parent, modulesToLoad, null);
+        }
+
+        ModuleHandler.installDownloadedModules(true);
+    	ModuleHandler.loadModules(Main.parent, modulesToLoad, null);
+    }
+    
+    private final File getSubDirectory(String name) {
+    	File dir = new File(getPluginDir()+File.separator+name);
+        if (!dir.exists()) {
+            dir.mkdirs();
+        }
+        return dir;
+    }
+    
+    public final File getModulesDirectory() {
+    	return getSubDirectory("modules");
+    }
+
+    public final File getResourcesDirectory() {
+    	return getSubDirectory("resources");
+    }
+
+    /*
+    private static final void fixUcDetectorTest() {
+    	FilterFactoryImpl n1 = new FilterFactoryImpl();
+    	DatumAliases n2 = new DatumAliases();
+    	EPSGCRSAuthorityFactory n3 = new EPSGCRSAuthorityFactory();
+    	DefaultFunctionFactory n4 = new DefaultFunctionFactory();
+    	ShapefileDirectoryFactory n5 = new ShapefileDirectoryFactory();
+    	ReferencingObjectFactory n6 = new ReferencingObjectFactory();
+    	BufferedCoordinateOperationFactory n7 = new BufferedCoordinateOperationFactory();
+    }*/
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/OdConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/OdConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/OdConstants.java	(revision 28000)
@@ -0,0 +1,154 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.openstreetmap.josm.actions.ExtensionFileFilter;
+import org.openstreetmap.josm.data.projection.BelgianLambert1972;
+import org.openstreetmap.josm.data.projection.BelgianLambert2008;
+import org.openstreetmap.josm.data.projection.Epsg4326;
+import org.openstreetmap.josm.data.projection.Lambert93;
+import org.openstreetmap.josm.plugins.opendata.core.io.LambertCC9ZonesProjectionPatterns;
+import org.openstreetmap.josm.plugins.opendata.core.io.ProjectionPatterns;
+
+public interface OdConstants {
+	
+	/**
+	 * Encodings
+	 */
+	public static final String UTF8 = "UTF-8";
+	public static final String ISO8859_15 = "ISO-8859-15";
+	public static final String CP1252 = "Cp1252";
+	public static final String MAC_ROMAN = "MacRoman";
+	
+	/**
+	 * Patterns
+	 */
+	public static final String PATTERN_LANG = "{lang}";
+	
+	/**
+	 * Preferences
+	 */
+/*	public static final String PREF_COORDINATES = "opendata.coordinates";
+	public static final String VALUE_CC9ZONES = "cc9zones";
+	public static final String VALUE_WGS84 = "wgs84";*/
+
+	public static final String PREF_OAPI = "opendata.oapi";
+    public static final String DEFAULT_OAPI = "http://www.overpass-api.de/api/interpreter?";
+    
+	public static final String PREF_XAPI = "opendata.xapi";
+    public static final String DEFAULT_XAPI = "http://www.overpass-api.de/api/xapi?";
+
+	public static final String PREF_RAWDATA = "opendata.rawdata";
+    public static final boolean DEFAULT_RAWDATA = false;
+
+	public static final String PREF_MAXDISTANCE = "opendata.maxdistance";
+    public static final double DEFAULT_MAXDISTANCE = 10;
+
+    public static final String PREF_MODULES = "opendata.modules";
+    public static final String PREF_MODULES_SITES = "opendata.modules.sites";
+    public final static String GOOGLE_SITE = "http://josm-toulouse-data.googlecode.com/svn/trunk/";
+    public final static String OSM_SITE = "http://svn.openstreetmap.org/applications/editors/josm/plugins/opendata/";
+    public final static String[] DEFAULT_MODULE_SITES = {GOOGLE_SITE + "modules.txt%<?modules=>"};//FIXME switch to osm when published
+
+    public static final String PREF_CRS_COMPARISON_TOLERANCE = "opendata.crs.comparison_tolerance";
+    public static final Double DEFAULT_CRS_COMPARISON_TOLERANCE = 0.00000001;
+
+    public static final String PREF_CRS_COMPARISON_DEBUG = "opendata.crs.comparison_debug";
+
+	/**
+	 * Icons
+	 */
+	public static final String ICON_CORE_16 = "o16.png";
+	public static final String ICON_CORE_24 = "o24.png";
+	public static final String ICON_CORE_48 = "o48.png";
+	
+	public static final String ICON_OSM_16 = "osm16.png";
+	public static final String ICON_OSM_24 = "osm24.png";
+
+    /**
+     * File extensions.
+     */
+    public static final String CSV_EXT = "csv";
+    public static final String KML_EXT = "kml";
+    public static final String KMZ_EXT = "kmz";
+    public static final String XLS_EXT = "xls";
+    public static final String ODS_EXT = "ods";
+    public static final String SHP_EXT = "shp";
+    public static final String MIF_EXT = "mif";
+    public static final String TAB_EXT = "tab";
+    public static final String MAPCSS_EXT = "mapcss";
+    public static final String ZIP_EXT = "zip";
+    public static final String JAR_EXT = "jar";
+    
+    /**
+     * Protocols
+     */
+    public static final String PROTO_FILE = "file://";
+    public static final String PROTO_RSRC = "resource://";
+    
+    /**
+     * File filter used in import/export dialogs.
+     */
+    public static final ExtensionFileFilter CSV_FILE_FILTER = new ExtensionFileFilter(CSV_EXT, CSV_EXT, tr("CSV files") + " (*."+CSV_EXT+")");
+    public static final ExtensionFileFilter XLS_FILE_FILTER = new ExtensionFileFilter(XLS_EXT, XLS_EXT, tr("XLS files") + " (*."+XLS_EXT+")");
+    public static final ExtensionFileFilter ODS_FILE_FILTER = new ExtensionFileFilter(ODS_EXT, ODS_EXT, tr("ODS files") + " (*."+ODS_EXT+")");
+    public static final ExtensionFileFilter SHP_FILE_FILTER = new ExtensionFileFilter(SHP_EXT, SHP_EXT, tr("Shapefiles") + " (*."+SHP_EXT+")");
+    public static final ExtensionFileFilter MIF_TAB_FILE_FILTER = new ExtensionFileFilter(MIF_EXT+","+TAB_EXT, MIF_EXT, tr("MapInfo files") + " (*."+MIF_EXT+",*."+TAB_EXT+")");
+    public static final ExtensionFileFilter KML_KMZ_FILE_FILTER = new ExtensionFileFilter(KML_EXT+","+KMZ_EXT, KMZ_EXT, tr("KML/KMZ files") + " (*."+KML_EXT+",*."+KMZ_EXT+")");
+    public static final ExtensionFileFilter ZIP_FILE_FILTER = new ExtensionFileFilter(ZIP_EXT, ZIP_EXT, tr("Zip Files") + " (*."+ZIP_EXT+")");
+    
+    /**
+     * Coordinates fields
+     */
+    public static final String X_STRING = "X|LON|LONGI|LONGITUDE";
+    public static final String Y_STRING = "Y|LAT|LATI|LATITUDE";
+    
+    // The list of all ProjectionPatterns (filled at each constrcutor call)
+    public static final Collection<ProjectionPatterns> PROJECTIONS = new ArrayList<ProjectionPatterns>();
+    
+    public static final ProjectionPatterns PRJ_UNKNOWN = new ProjectionPatterns("");
+    public static final ProjectionPatterns PRJ_WGS84 = new ProjectionPatterns("GPS|WGS84|°décimaux", new Epsg4326());
+    public static final ProjectionPatterns PRJ_LAMBERT_93 = new ProjectionPatterns("LAMB93|L93", new Lambert93());
+    public static final ProjectionPatterns PRJ_LAMBERT_CC_9_ZONES = new LambertCC9ZonesProjectionPatterns("LAMBZ|CC(42|43|44|45|46|47|48|49|50)");
+
+    public static final ProjectionPatterns PRJ_LAMBERT_1972 = new ProjectionPatterns("LAMB72|LAMB1972", new BelgianLambert1972());
+    public static final ProjectionPatterns PRJ_LAMBERT_2008 = new ProjectionPatterns("LAMB08|LAMB2008", new BelgianLambert2008());
+
+    /**
+     * KML tags
+     */
+    public static final String KML_PLACEMARK   = "Placemark";
+    public static final String KML_NAME	       = "name";
+    public static final String KML_COLOR       = "color";
+    public static final String KML_SIMPLE_DATA = "SimpleData";
+    public static final String KML_LINE_STRING = "LineString";
+    public static final String KML_POINT       = "Point";
+    public static final String KML_POLYGON     = "Polygon";
+    public static final String KML_OUTER_BOUND = "outerBoundaryIs";
+    public static final String KML_INNER_BOUND = "innerBoundaryIs";
+    public static final String KML_LINEAR_RING = "LinearRing";
+    public static final String KML_COORDINATES = "coordinates";
+    
+    /**
+     * Resources
+     */
+    public static final String DICTIONARY_FR = "/org/openstreetmap/josm/plugins/opendata/core/resources/dictionary.fr.csv";
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/actions/OpenLinkAction.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/actions/OpenLinkAction.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/actions/OpenLinkAction.java	(revision 28000)
@@ -0,0 +1,59 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.actions;
+
+import java.awt.event.ActionEvent;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLEncoder;
+
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.tools.OpenBrowser;
+
+@SuppressWarnings("serial")
+public class OpenLinkAction extends JosmAction implements OdConstants {
+
+    private URL url;
+    
+    public OpenLinkAction(URL url, String icon24Name, String title, String description) {
+        super(title, icon24Name, description, null, false);
+        this.url = url;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        try {
+        	System.out.println("Opening "+url);
+			OpenBrowser.displayUrl(url.toURI());
+		} catch (URISyntaxException e1) {
+			try {
+				System.err.println(e1.getLocalizedMessage());
+				int index = e1.getIndex();
+				if (index > -1) {
+					String s = url.toString().substring(index, index+1);
+					s = url.toString().replace(s, URLEncoder.encode(s, UTF8));
+					URI uri = new URI(s);
+		        	System.out.println("Opening "+uri);
+					OpenBrowser.displayUrl(uri);
+				}
+			} catch (Exception e2) {
+				e2.printStackTrace();
+			}
+		}
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/AbstractDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/AbstractDataSetHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/AbstractDataSetHandler.java	(revision 28000)
@@ -0,0 +1,497 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.datasets;
+
+import java.io.File;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.crs.AbstractDerivedCRS;
+import org.geotools.referencing.datum.DefaultEllipsoid;
+import org.geotools.referencing.operation.projection.LambertConformal;
+import org.geotools.referencing.operation.projection.LambertConformal1SP;
+import org.geotools.referencing.operation.projection.LambertConformal2SP;
+import org.geotools.referencing.operation.projection.MapProjection.AbstractProvider;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.datum.GeodeticDatum;
+import org.opengis.referencing.operation.MathTransform;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.IPrimitive;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.projection.AbstractProjection;
+import org.openstreetmap.josm.data.projection.Ellipsoid;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.data.projection.Projections;
+import org.openstreetmap.josm.data.projection.proj.LambertConformalConic;
+import org.openstreetmap.josm.data.projection.proj.LambertConformalConic.Parameters;
+import org.openstreetmap.josm.data.projection.proj.LambertConformalConic.Parameters1SP;
+import org.openstreetmap.josm.data.projection.proj.LambertConformalConic.Parameters2SP;
+import org.openstreetmap.josm.gui.preferences.SourceEditor.ExtendedSourceEntry;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.util.NamesFrUtils;
+import org.openstreetmap.josm.tools.Pair;
+
+public abstract class AbstractDataSetHandler implements OdConstants {
+	public abstract boolean acceptsFilename(String filename);
+	public abstract void updateDataSet(DataSet ds);
+
+	public void checkDataSetSource(DataSet ds) {
+		if (ds != null) {
+			for (OsmPrimitive p : ds.allPrimitives()) {
+				if (p.hasKeys() || p.getReferrers().isEmpty()) {
+					if (getSource() != null && p.get("source") == null) {
+						p.put("source", getSource());
+					}
+					if (sourceDate != null && p.get("source:date") == null) {
+						p.put("source:date", sourceDate);
+					}
+				}
+			}
+		}
+	}
+	
+	public void checkNames(DataSet ds) {
+		if (ds != null) {
+			for (OsmPrimitive p : ds.allPrimitives()) {
+				if (p.get("name") != null) {
+					p.put("name", NamesFrUtils.checkDictionary(p.get("name")));
+				}
+			}
+		}
+	}
+
+	private String sourceDate;
+	private File associatedFile;
+
+	public AbstractDataSetHandler() {
+	}
+	
+	private final boolean acceptsFilename(String filename, String[] expected, String ... extensions ) {
+		if (filename != null) {
+			for (String name : expected) {
+				for (String ext : extensions) {
+					if (Pattern.compile(name+"\\."+ext, Pattern.CASE_INSENSITIVE).matcher(filename).matches()) {
+					//if (filename.equalsIgnoreCase(name+"."+ext)) {
+						return true;
+					}
+				}
+			}
+		}
+		return false;
+	}
+	
+	protected final boolean acceptsCsvFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, CSV_EXT);
+	}
+
+	protected final boolean acceptsXlsFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, XLS_EXT);
+	}
+
+	protected final boolean acceptsOdsFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, ODS_EXT);
+	}
+
+	protected final boolean acceptsShpFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, SHP_EXT);
+	}
+
+	protected final boolean acceptsMifFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, MIF_EXT);
+	}
+
+	protected final boolean acceptsMifTabFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, MIF_EXT, TAB_EXT);
+	}
+
+	protected final boolean acceptsShpMifFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, SHP_EXT, MIF_EXT);
+	}
+
+	protected final boolean acceptsKmlFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, KML_EXT);
+	}
+
+	protected final boolean acceptsKmzFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, KMZ_EXT);
+	}
+
+	protected final boolean acceptsKmzTabFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, KMZ_EXT, TAB_EXT);
+	}
+
+	protected final boolean acceptsZipFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, ZIP_EXT);
+	}
+
+	protected final boolean acceptsCsvKmzFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, CSV_EXT, KMZ_EXT);
+	}
+
+	protected final boolean acceptsCsvKmzTabFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, CSV_EXT, KMZ_EXT, TAB_EXT);
+	}
+	
+	protected final boolean acceptsCsvXlsFilename(String filename, String ... expected) {
+		return acceptsFilename(filename, expected, CSV_EXT, XLS_EXT);
+	}
+	
+	public URL getWikiURL() {return null;}
+	
+	public abstract URL getLocalPortalURL();
+	public abstract URL getNationalPortalURL();
+
+	public final Collection<String> getOsmXapiRequests(Bounds bounds) {
+		return getOsmXapiRequests(
+				LatLon.roundToOsmPrecisionStrict(bounds.getMin().lon())+","+
+				LatLon.roundToOsmPrecisionStrict(bounds.getMin().lat())+","+
+				LatLon.roundToOsmPrecisionStrict(bounds.getMax().lon())+","+
+				LatLon.roundToOsmPrecisionStrict(bounds.getMax().lat()));
+	}
+	
+	protected Collection<String> getOsmXapiRequests(String bbox) {return null;}
+	
+	public final String getOverpassApiRequest(Bounds bounds) {
+		return getOverpassApiRequest(
+				"w=\""+LatLon.roundToOsmPrecisionStrict(bounds.getMin().lon())+"\" "+
+				"s=\""+LatLon.roundToOsmPrecisionStrict(bounds.getMin().lat())+"\" "+
+				"e=\""+LatLon.roundToOsmPrecisionStrict(bounds.getMax().lon())+"\" "+
+				"n=\""+LatLon.roundToOsmPrecisionStrict(bounds.getMax().lat())+"\"");
+	}
+
+	public enum OaQueryType {
+		NODE ("node"),
+		WAY ("way"),
+		RELATION ("relation");
+		@Override
+		public String toString() { return this.value; }
+		private OaQueryType(final String value) { this.value = value; }
+		private final String value;
+	}
+
+	public enum OaRecurseType {
+		RELATION_RELATION ("relation-relation"),
+		RELATION_BACKWARDS ("relation-backwards"),
+		RELATION_WAY ("relation-way"),
+		RELATION_NODE ("relation-node"),
+		WAY_NODE ("way-node"),
+		WAY_RELATION ("way-relation"),
+		NODE_RELATION ("node-relation"),
+		NODE_WAY ("node-way");
+		@Override
+		public String toString() { return this.value; }
+		private OaRecurseType(final String value) { this.value = value; }
+		private final String value;
+	}
+
+	protected String getOverpassApiRequest(String bbox) {return null;}
+	
+	protected final String oaUnion(String ... queries) {
+		String result = "<union>\n";
+		for (String query : queries) {
+			if (query != null) {
+				result += query + "\n";
+			}
+		}
+		result += "</union>";
+		return result;
+	}
+	
+	protected final String oaQuery(String bbox, OaQueryType type, String ... conditions) {
+		String result = "<query type=\""+type+"\" >\n";
+		if (bbox != null) {
+			result += "<bbox-query "+bbox+"/>\n";
+		}
+		for (String condition : conditions) {
+			if (condition != null) {
+				result += condition + "\n";
+			}
+		}
+		result += "</query>";
+		return result;
+	}
+
+	protected final String oaRecurse(OaRecurseType type, String into) {
+		return "<recurse type=\""+type+"\" into=\""+into+"\"/>\n";
+	}
+
+	protected final String oaRecurse(OaRecurseType ... types) {
+		String result = "";
+		for (OaRecurseType type : types) {
+			result += "<recurse type=\""+type+"\"/>\n";
+		}
+		return result;
+	}
+	
+	protected final String oaPrint() {
+		return "<print mode=\"meta\"/>";
+	}
+	
+	protected final String oaHasKey(String key) {
+		return oaHasKey(key, null);
+	}
+
+	protected final String oaHasKey(String key, String value) {
+		return "<has-kv k=\""+key+"\" "+(value != null && !value.isEmpty() ? "v=\""+value+"\"" : "")+" />";
+	}
+
+	public boolean equals(IPrimitive p1, IPrimitive p2) {return false;}
+	
+	public boolean isRelevant(IPrimitive p) {return false;}
+	
+	public final Collection<IPrimitive> extractRelevantPrimitives(DataSet ds) {
+		ArrayList<IPrimitive> result = new ArrayList<IPrimitive>();
+		for (IPrimitive p : ds.allPrimitives()) {
+			if (isRelevant(p)) {
+				result.add(p);
+			}
+		}
+		return result;
+	}
+	
+	public boolean isForbidden(IPrimitive p) {return false;}
+	
+	public boolean hasForbiddenTags() {return false;}
+	
+	public interface ValueReplacer {
+		public String replace(String value);
+	}
+	
+	protected final void replace(IPrimitive p, String dataKey, String osmKey) {
+		addOrReplace(p, dataKey, osmKey, null, null, null, true);
+	}
+
+	protected final void replace(IPrimitive p, String dataKey, String osmKey, ValueReplacer replacer) {
+		addOrReplace(p, dataKey, osmKey, null, null, replacer, true);
+	}
+
+	protected final void replace(IPrimitive p, String dataKey, String osmKey, String[] dataValues, String[] osmValues) {
+		addOrReplace(p, dataKey, osmKey, dataValues, osmValues, null, true);
+	}
+	
+	protected final void add(IPrimitive p, String dataKey, String osmKey, ValueReplacer replacer) {
+		addOrReplace(p, dataKey, osmKey, null, null, replacer, false);
+	}
+
+	protected final void add(IPrimitive p, String dataKey, String osmKey, String[] dataValues, String[] osmValues) {
+		addOrReplace(p, dataKey, osmKey, dataValues, osmValues, null, false);
+	}
+	
+	private final void addOrReplace(IPrimitive p, String dataKey, String osmKey, String[] dataValues, String[] osmValues, ValueReplacer replacer, boolean replace) {
+		String value = p.get(dataKey);
+		if (value != null) {
+			int index = -1;
+			for (int i = 0; dataValues != null && index == -1 && i < dataValues.length; i++) {
+				if (Pattern.compile(dataValues[i], Pattern.CASE_INSENSITIVE).matcher(value).matches()) {
+					index = i;
+				}
+				/*if (value.equalsIgnoreCase(csvValues[i])) {
+					index = i;
+				}*/
+			}
+			if (index > -1 && osmValues != null) {
+				doAddReplace(p, dataKey, osmKey, osmValues[index], replace);
+			} else if (replacer != null) {
+				doAddReplace(p, dataKey, osmKey, replacer.replace(value), replace);
+			} else if (dataValues == null || osmValues == null) {
+				doAddReplace(p, dataKey, osmKey, value, replace);
+			}
+		}
+	}
+	
+	private final void doAddReplace(IPrimitive p, String dataKey, String osmKey, String osmValue, boolean replace) {
+		if (replace) {
+			p.remove(dataKey);
+		}
+		p.put(osmKey, osmValue);
+	}
+
+	/**
+	 * @return the source
+	 */
+	public String getSource() {
+		return null;
+	}
+		
+	/**
+	 * @return the sourceDate
+	 */
+	public final String getSourceDate() {
+		return sourceDate;
+	}
+	
+	/**
+	 * @param sourceDate the sourceDate to set
+	 */
+	public final void setSourceDate(String sourceDate) {
+		this.sourceDate = sourceDate;
+	}
+	
+	public String getLocalPortalIconName() {
+		return ICON_CORE_24;
+	}
+		
+	public String getNationalPortalIconName() {
+		return ICON_CORE_24;
+	}
+		
+	public String getDataLayerIconName() {
+		return ICON_CORE_16;
+	}
+	
+	public boolean handlesSpreadSheetProjection() {
+		return false;
+	}
+	
+	public List<Projection> getSpreadSheetProjections() {
+		return null;
+	}
+
+	public LatLon getSpreadSheetCoor(EastNorth en, String[] fields) {
+		return null;
+	}
+	
+	public Charset getCsvCharset() {
+		return null;
+	}
+	
+	public String getCsvSeparator() {
+		return null;
+	}
+	
+	public int getSheetNumber() {
+		return -1;
+	}
+	
+	public ExtendedSourceEntry getMapPaintStyle() {
+		return null;
+	}
+
+	public ExtendedSourceEntry getTaggingPreset() {
+		return null;
+	}
+
+	protected final ExtendedSourceEntry getMapPaintStyle(String displayName) {
+		return getMapPaintStyle(displayName, this.getClass().getSimpleName().replace("Handler", ""));
+	}
+
+	protected final ExtendedSourceEntry getMapPaintStyle(String displayName, String fileNameWithoutExtension) {
+		return new ExtendedSourceEntry(displayName,	PROTO_RSRC+//"/"+
+				this.getClass().getPackage().getName().replace(".", "/")+"/"+
+				fileNameWithoutExtension+"."+MAPCSS_EXT);
+	}
+	
+	public boolean preferMultipolygonToSimpleWay() {
+		return false;
+	}
+	
+	public final void setAssociatedFile(File associatedFile) {
+		this.associatedFile = associatedFile;
+	}
+
+	public final File getAssociatedFile() {
+		return this.associatedFile;
+	}
+	
+	private static final List<Pair<org.opengis.referencing.datum.Ellipsoid, Ellipsoid>> 
+		ellipsoids = new ArrayList<Pair<org.opengis.referencing.datum.Ellipsoid, Ellipsoid>>();
+	static {
+		ellipsoids.add(new Pair<org.opengis.referencing.datum.Ellipsoid, Ellipsoid>(DefaultEllipsoid.GRS80, Ellipsoid.GRS80));
+		ellipsoids.add(new Pair<org.opengis.referencing.datum.Ellipsoid, Ellipsoid>(DefaultEllipsoid.WGS84, Ellipsoid.WGS84));
+	}
+	
+	private static final Double get(ParameterValueGroup values, ParameterDescriptor desc) {
+		return (Double) values.parameter(desc.getName().getCode()).getValue();
+	}
+	
+	private static final boolean equals(Double a, Double b) {
+		boolean res = Math.abs(a - b) <= Main.pref.getDouble(PREF_CRS_COMPARISON_TOLERANCE, DEFAULT_CRS_COMPARISON_TOLERANCE);
+		if (Main.pref.getBoolean(PREF_CRS_COMPARISON_DEBUG, false)) {
+			System.out.println("Comparing "+a+" and "+b+" -> "+res);
+		}
+		return res; 
+	}
+	
+	public MathTransform findMathTransform(CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS, boolean lenient) throws FactoryException {
+		if (sourceCRS instanceof AbstractDerivedCRS && sourceCRS.getName().getCode().equalsIgnoreCase("Lambert_Conformal_Conic")) {
+			List<MathTransform> result = new ArrayList<MathTransform>();
+			AbstractDerivedCRS crs = (AbstractDerivedCRS) sourceCRS;
+			MathTransform transform = crs.getConversionFromBase().getMathTransform();
+			if (transform instanceof LambertConformal && crs.getDatum() instanceof GeodeticDatum) {
+				LambertConformal lambert = (LambertConformal) transform;
+				GeodeticDatum geo = (GeodeticDatum) crs.getDatum();
+				for (Projection p : Projections.getProjections()) {
+					if (p instanceof AbstractProjection) {
+						AbstractProjection ap = (AbstractProjection) p;
+						if (ap.getProj() instanceof LambertConformalConic) {
+							for (Pair<org.opengis.referencing.datum.Ellipsoid, Ellipsoid> pair : ellipsoids) {
+								if (pair.a.equals(geo.getEllipsoid()) && pair.b.equals(ap.getEllipsoid())) {
+									boolean ok = true;
+									ParameterValueGroup values = lambert.getParameterValues();
+									Parameters params = ((LambertConformalConic) ap.getProj()).getParameters();
+									
+									ok = ok ? equals(get(values, AbstractProvider.LATITUDE_OF_ORIGIN), params.latitudeOrigin) : ok;
+									ok = ok ? equals(get(values, AbstractProvider.CENTRAL_MERIDIAN), ap.getCentralMeridian()) : ok;
+									ok = ok ? equals(get(values, AbstractProvider.SCALE_FACTOR), ap.getScaleFactor()) : ok;
+									ok = ok ? equals(get(values, AbstractProvider.FALSE_EASTING), ap.getFalseEasting()) : ok;
+									ok = ok ? equals(get(values, AbstractProvider.FALSE_NORTHING), ap.getFalseNorthing()) : ok;
+									
+									if (lambert instanceof LambertConformal2SP && params instanceof Parameters2SP) {
+										Parameters2SP param = (Parameters2SP) params;
+										ok = ok ? equals(Math.min(get(values, AbstractProvider.STANDARD_PARALLEL_1),get(values, AbstractProvider.STANDARD_PARALLEL_2)), 
+														 Math.min(param.standardParallel1, param.standardParallel2)) : ok;
+										ok = ok ? equals(Math.max(get(values, AbstractProvider.STANDARD_PARALLEL_1), get(values, AbstractProvider.STANDARD_PARALLEL_2)),
+												         Math.max(param.standardParallel1, param.standardParallel2)) : ok;
+										
+									} else if (!(lambert instanceof LambertConformal1SP && params instanceof Parameters1SP)) {
+										ok = false;
+									}
+
+									if (ok) {
+										try {
+											result.add(CRS.findMathTransform(CRS.decode(p.toCode()), targetCRS, lenient));
+										} catch (FactoryException e) {
+											System.err.println(e.getMessage());
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+			if (!result.isEmpty()) {
+				if (result.size() > 1) {
+					System.err.println("Found multiple projections !"); // TODO: something
+				}
+				return result.get(0);
+			}
+		}
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/SimpleDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/SimpleDataSetHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/SimpleDataSetHandler.java	(revision 28000)
@@ -0,0 +1,209 @@
+package org.openstreetmap.josm.plugins.opendata.core.datasets;
+
+import static org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler.OaQueryType.NODE;
+import static org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler.OaQueryType.WAY;
+import static org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler.OaQueryType.RELATION;
+import static org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler.OaRecurseType.NODE_RELATION;
+import static org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler.OaRecurseType.RELATION_WAY;
+import static org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler.OaRecurseType.WAY_NODE;
+import static org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler.OaRecurseType.WAY_RELATION;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.openstreetmap.josm.data.osm.IPrimitive;
+import org.openstreetmap.josm.data.osm.Tag;
+import org.openstreetmap.josm.data.projection.Projection;
+
+public abstract class SimpleDataSetHandler extends AbstractDataSetHandler {
+
+	protected static final Projection wgs84 = PRJ_WGS84.getProjection();
+
+	private final List<Tag> relevantTags = new ArrayList<Tag>();
+	private final List<Tag> forbiddenTags = new ArrayList<Tag>();
+	
+	private final boolean relevantUnion;
+	
+	public SimpleDataSetHandler() {
+		this.relevantUnion = false;
+	}
+			
+	public SimpleDataSetHandler(String relevantTag) {
+		addRelevantTag(relevantTag);
+		this.relevantUnion = false;
+	}
+	
+	public SimpleDataSetHandler(boolean relevantUnion, String ... relevantTags) {
+		addRelevantTag(relevantTags);
+		this.relevantUnion = relevantUnion;
+	}
+
+	public SimpleDataSetHandler(String ... relevantTags) {
+		this(false, relevantTags);
+	}
+
+	public SimpleDataSetHandler(Tag relevantTag) {
+		addRelevantTag(relevantTag);
+		this.relevantUnion = false;
+	}
+	
+	public SimpleDataSetHandler(boolean relevantUnion, Tag ... relevantTags) {
+		addRelevantTag(relevantTags);
+		this.relevantUnion = relevantUnion;
+	}
+
+	public SimpleDataSetHandler(Tag ... relevantTags) {
+		this(false, relevantTags);
+	}
+
+	public void addRelevantTag(String ... relevantTags) {
+		addTags(this.relevantTags, relevantTags);
+	}
+
+	public void addRelevantTag(Tag ... relevantTags) {
+		addTags(this.relevantTags, relevantTags);
+	}
+
+	public void addForbiddenTag(String ... forbiddenTags) {
+		addTags(this.forbiddenTags, forbiddenTags);
+	}
+
+	public void addForbiddenTag(Tag ... forbiddenTags) {
+		addTags(this.forbiddenTags, forbiddenTags);
+	}
+	
+	private final void addTags(final List<Tag> list, String ... tags) {
+		if (tags != null) {
+			for (String tag : tags) {
+				if (tag != null) {
+					if (tag.contains("=")) {
+						String[] tab = tag.split("=");
+						list.add(new Tag(tab[0], tab[1]));
+					} else {
+						list.add(new Tag(tag));
+					}
+				}
+			}
+		}
+	}
+
+	private final void addTags(final List<Tag> list, Tag ... tags) {
+		if (tags != null) {
+			for (Tag tag : tags) {
+				if (tag != null) {
+					list.add(tag);
+				}
+			}
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.fr.opendata.data.AbstractConverter#equals(org.openstreetmap.josm.data.osm.IPrimitive, org.openstreetmap.josm.data.osm.IPrimitive)
+	 */
+	@Override
+	public boolean equals(IPrimitive p1, IPrimitive p2) {
+		for (Tag tag : this.relevantTags) {
+			if (!p1.get(tag.getKey()).equals(p2.get(tag.getKey()))) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.fr.opendata.data.AbstractConverter#isRelevant(org.openstreetmap.josm.data.osm.IPrimitive)
+	 */
+	@Override
+	public boolean isRelevant(IPrimitive p) {
+		for (Tag tag : this.relevantTags) {
+			String value = p.get(tag.getKey());
+			if (value == null || (tag.getValue() != null && !tag.getValue().equals(value))) {
+				return false;
+			}
+		}
+		if (isForbidden(p)) {
+			return false;
+		}
+		return true;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.fr.opendata.datasets.AbstractDataSetHandler#isForbidden(org.openstreetmap.josm.data.osm.IPrimitive)
+	 */
+	@Override
+	public boolean isForbidden(IPrimitive p) {
+		for (Tag tag : this.forbiddenTags) {
+			String value = p.get(tag.getKey());
+			if (value != null && (tag.getValue() == null || tag.getValue().equals(value))) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.fr.opendata.datasets.AbstractDataSetHandler#hasForbiddenTags()
+	 */
+	@Override
+	public boolean hasForbiddenTags() {
+		return !this.forbiddenTags.isEmpty();
+	}
+
+	protected final String[] getOverpassApiConditions() {
+		List<String> conditions = new ArrayList<String>();
+		for (Tag tag : this.relevantTags) {
+			conditions.add(oaHasKey(tag.getKey(), tag.getValue()));
+		}
+		return conditions.toArray(new String[0]);
+	}
+
+	protected String getOverpassApiQueries(String bbox, String ... conditions) {
+		String[] mpconditions = new String[conditions.length+1];
+		mpconditions[0] = oaHasKey("type", "multipolygon");
+		for (int i=0; i<conditions.length; i++) {
+			mpconditions[i+1] = conditions[i];
+		}
+		return oaQuery(bbox, NODE, conditions) + "\n" + // Nodes 
+				oaRecurse(NODE_RELATION, RELATION_WAY, WAY_NODE) + "\n" +
+				oaQuery(bbox, WAY, conditions) + "\n" + // Full ways and their full relations 
+				oaRecurse(WAY_NODE, "nodes") + "\n" +
+				oaRecurse(WAY_RELATION, RELATION_WAY, WAY_NODE) + "\n" +
+				oaQuery(bbox, RELATION, mpconditions) + "\n" + // Full multipolygons
+				oaRecurse(RELATION_WAY, WAY_NODE);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.fr.opendata.datasets.AbstractDataSetHandler#getOverpassApiRequest(java.lang.String)
+	 */
+	@Override
+	protected String getOverpassApiRequest(String bbox) {
+		String result = "";
+		if (this.relevantUnion) {
+			for (Tag tag : this.relevantTags) {
+				result += getOverpassApiQueries(bbox, oaHasKey(tag.getKey(), tag.getValue())); 
+			}
+			result = oaUnion(result);
+		} else {
+			result = oaUnion(getOverpassApiQueries(bbox, getOverpassApiConditions()));
+		}
+		return result + oaPrint();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.fr.opendata.data.AbstractConverter#getOsmDataUrls(java.lang.String)
+	 */
+	@Override
+	protected Collection<String> getOsmXapiRequests(String bbox) {
+		String relevantTags = "";
+		for (Tag tag : this.relevantTags) {
+			relevantTags += "["+tag.getKey()+"="+(tag.getValue() == null ? "*" : tag.getValue())+"]";
+		}
+		String forbiddenTags = "";
+		for (Tag tag : this.forbiddenTags) {
+			forbiddenTags += "[not("+tag.getKey()+"="+(tag.getValue() == null ? "*" : tag.getValue())+")]";
+		}
+		return Collections.singleton("*[bbox="+bbox+"]"+relevantTags+forbiddenTags+"[@meta]");
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/be/BelgianConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/be/BelgianConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/be/BelgianConstants.java	(revision 28000)
@@ -0,0 +1,31 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.datasets.be;
+
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+
+public interface BelgianConstants extends OdConstants {
+
+	/**
+	 * Portal
+	 */
+	public static final String BELGIAN_PORTAL = "http://data.gov.be/"+PATTERN_LANG+"/dataset/";
+	
+	/**
+	 * Icon
+	 */
+	public static final String ICON_BE_24 = "be24.png";
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/be/BelgianDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/be/BelgianDataSetHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/be/BelgianDataSetHandler.java	(revision 28000)
@@ -0,0 +1,150 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.datasets.be;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.Tag;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.SimpleDataSetHandler;
+
+public abstract class BelgianDataSetHandler extends SimpleDataSetHandler implements BelgianConstants {
+
+	private Projection singleProjection;
+
+	private String nationalPortalPathDe;
+	private String nationalPortalPathEn;
+	private String nationalPortalPathFr;
+	private String nationalPortalPathNl;
+
+	protected static final Projection lambert1972 = PRJ_LAMBERT_1972.getProjection();
+	protected static final Projection lambert2008 = PRJ_LAMBERT_2008.getProjection();
+	
+	protected static final Projection[] projections = new Projection[]{
+		lambert1972,
+		lambert2008
+	};
+
+	public BelgianDataSetHandler() {
+		
+	}
+
+	public BelgianDataSetHandler(String relevantTag) {
+		super(relevantTag);
+	}
+
+	public BelgianDataSetHandler(boolean relevantUnion, String[] relevantTags) {
+		super(relevantUnion, relevantTags);
+	}
+
+	public BelgianDataSetHandler(boolean relevantUnion, Tag[] relevantTags) {
+		super(relevantUnion, relevantTags);
+	}
+	
+	protected final void setNationalPortalPath(String nationalPortalPathDe, String nationalPortalPathEn, String nationalPortalPathFr, String nationalPortalPathNl) {
+		this.nationalPortalPathDe = nationalPortalPathDe;
+		this.nationalPortalPathEn = nationalPortalPathEn;
+		this.nationalPortalPathFr = nationalPortalPathFr;
+		this.nationalPortalPathNl = nationalPortalPathNl;
+	}
+
+	protected final void setSingleProjection(Projection singleProjection) {
+		this.singleProjection = singleProjection;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getNationalPortalURL()
+	 */
+	@Override
+	public URL getNationalPortalURL() {
+		try {
+			String nationalPortalPath = "";
+			String lang = Main.pref.get("language");
+			if (lang == null || lang.isEmpty()) {
+				lang = Locale.getDefault().toString();
+			}
+				
+			if (lang.startsWith("de") && nationalPortalPathDe != null) {
+				nationalPortalPath = nationalPortalPathDe;
+			} else if (lang.startsWith("fr") && nationalPortalPathFr != null) {
+				nationalPortalPath = nationalPortalPathFr;
+			} else if (lang.startsWith("nl") && nationalPortalPathNl != null) {
+				nationalPortalPath = nationalPortalPathNl;
+			} else {
+				nationalPortalPath = nationalPortalPathEn;
+			}
+			return new URL(BELGIAN_PORTAL.replace(PATTERN_LANG, lang.substring(0, 2))+nationalPortalPath);//FIXME
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getLocalPortalIconName()
+	 */
+	@Override
+	public String getLocalPortalIconName() {
+		return ICON_BE_24;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getNationalPortalIconName()
+	 */
+	@Override
+	public String getNationalPortalIconName() {
+		return ICON_BE_24;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#handlesCsvProjection()
+	 */
+	@Override
+	public boolean handlesSpreadSheetProjection() {
+		return singleProjection != null ? true : super.handlesSpreadSheetProjection();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getCsvProjections()
+	 */
+	@Override
+	public List<Projection> getSpreadSheetProjections() {
+		if (singleProjection != null) {
+			return Arrays.asList(new Projection[]{singleProjection});
+		} else {
+			return Arrays.asList(projections);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getCsvCoor(org.openstreetmap.josm.data.coor.EastNorth, java.lang.String[])
+	 */
+	@Override
+	public LatLon getSpreadSheetCoor(EastNorth en, String[] fields) {
+		if (singleProjection != null) {
+			return singleProjection.eastNorth2latlon(en);
+		} else {
+			return super.getSpreadSheetCoor(en, fields);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/fr/FrenchConstants.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/fr/FrenchConstants.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/fr/FrenchConstants.java	(revision 28000)
@@ -0,0 +1,31 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.datasets.fr;
+
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+
+public interface FrenchConstants extends OdConstants {
+
+	/**
+	 * Portal
+	 */
+	public static final String FRENCH_PORTAL = "http://www.data.gouv.fr/donnees/view/";
+	
+	/**
+	 * Icon
+	 */
+	public static final String ICON_FR_24 = "fr24.png";
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/fr/FrenchDataSetHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/fr/FrenchDataSetHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/datasets/fr/FrenchDataSetHandler.java	(revision 28000)
@@ -0,0 +1,275 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.datasets.fr;
+
+import static org.openstreetmap.josm.plugins.opendata.core.io.LambertCC9ZonesProjectionPatterns.lambertCC9Zones;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.geotools.referencing.CRS;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Tag;
+import org.openstreetmap.josm.data.projection.Lambert;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.data.projection.UTM;
+import org.openstreetmap.josm.data.projection.UTM.Hemisphere;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.SimpleDataSetHandler;
+
+public abstract class FrenchDataSetHandler extends SimpleDataSetHandler implements FrenchConstants {
+
+	private Projection singleProjection;
+
+	private String nationalPortalPath;
+
+	protected static final Projection lambert93 = PRJ_LAMBERT_93.getProjection(); // France metropolitaine
+	protected static final UTM utm20 = new UTM(20, Hemisphere.North, false); // Guadeloupe, Martinique
+	protected static final UTM utm22 = new UTM(22, Hemisphere.North, false); // Guyane
+	protected static final UTM utm38 = new UTM(38, Hemisphere.South, false); // Mayotte
+	protected static final UTM utm40 = new UTM(40, Hemisphere.South, false); // Reunion
+	
+	protected static final Lambert[] lambert4Zones = new Lambert[4];
+	static {
+		for (int i=0; i<lambert4Zones.length; i++) {
+			lambert4Zones[i] = new Lambert();
+			lambert4Zones[i].setPreferences(Arrays.asList(Integer.toString(i+1)));
+		}
+	}
+
+	protected static final Projection[] projections = new Projection[]{
+		lambert93, // France metropolitaine
+		utm20, // Guadeloupe, Martinique
+		utm22, // Guyane
+		utm38, // Mayotte
+		utm40, // Reunion
+	};
+
+	public FrenchDataSetHandler() {
+		
+	}
+
+	public FrenchDataSetHandler(String relevantTag) {
+		super(relevantTag);
+	}
+
+	public FrenchDataSetHandler(boolean relevantUnion, String[] relevantTags) {
+		super(relevantUnion, relevantTags);
+	}
+
+	public FrenchDataSetHandler(boolean relevantUnion, Tag[] relevantTags) {
+		super(relevantUnion, relevantTags);
+	}
+	
+	protected final void setNationalPortalPath(String nationalPortalPath) {
+		this.nationalPortalPath = nationalPortalPath;
+	}
+
+	protected final void setSingleProjection(Projection singleProjection) {
+		this.singleProjection = singleProjection;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getNationalPortalURL()
+	 */
+	@Override
+	public URL getNationalPortalURL() {
+		try {
+			if (nationalPortalPath != null && !nationalPortalPath.isEmpty()) {
+				return new URL(FRENCH_PORTAL + nationalPortalPath);
+			}
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getLocalPortalIconName()
+	 */
+	@Override
+	public String getLocalPortalIconName() {
+		return ICON_FR_24;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getNationalPortalIconName()
+	 */
+	@Override
+	public String getNationalPortalIconName() {
+		return ICON_FR_24;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#handlesCsvProjection()
+	 */
+	@Override
+	public boolean handlesSpreadSheetProjection() {
+		return singleProjection != null ? true : super.handlesSpreadSheetProjection();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getCsvProjections()
+	 */
+	@Override
+	public List<Projection> getSpreadSheetProjections() {
+		if (singleProjection != null) {
+			return Arrays.asList(new Projection[]{singleProjection});
+		} else {
+			return Arrays.asList(projections);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#getCsvCoor(org.openstreetmap.josm.data.coor.EastNorth, java.lang.String[])
+	 */
+	@Override
+	public LatLon getSpreadSheetCoor(EastNorth en, String[] fields) {
+		if (singleProjection != null) {
+			return singleProjection.eastNorth2latlon(en);
+		} else {
+			return super.getSpreadSheetCoor(en, fields);
+		}
+	}
+	
+	protected static final LatLon getLatLonByDptCode(EastNorth en, String dpt, boolean useCC9) {
+		if (dpt.equals("971") || dpt.equals("972") || dpt.equals("977") || dpt.equals("978")) {	// Antilles
+			return utm20.eastNorth2latlon(en);
+		} else if (dpt.equals("973")) {	// Guyane
+			return utm22.eastNorth2latlon(en);
+		} else if (dpt.equals("974")) {	// La Réunion
+			return utm40.eastNorth2latlon(en);
+		} else if (dpt.equals("976") || dpt.equals("985")) { // 985 = ancien code de Mayotte ? (présent dans geofla)
+			return utm38.eastNorth2latlon(en);
+		} else if (!useCC9) {
+			return lambert93.eastNorth2latlon(en);
+		} else if (dpt.endsWith("2A") || dpt.endsWith("2B") || dpt.endsWith("20")) {
+			return lambertCC9Zones[0].eastNorth2latlon(en);
+		} else if (dpt.endsWith("64") || dpt.endsWith("65") || dpt.endsWith("31") || dpt.endsWith("09") || dpt.endsWith("11") || dpt.endsWith("66") || dpt.endsWith("34") || dpt.endsWith("83")) {
+			return lambertCC9Zones[1].eastNorth2latlon(en);
+		} else if (dpt.endsWith("40") || dpt.endsWith("32") || dpt.endsWith("47") || dpt.endsWith("82") || dpt.endsWith("81") || dpt.endsWith("12") || dpt.endsWith("48") || dpt.endsWith("30") || dpt.endsWith("13") || dpt.endsWith("84") || dpt.endsWith("04") || dpt.endsWith("06")) {
+			return lambertCC9Zones[2].eastNorth2latlon(en);
+		} else if (dpt.endsWith("33") || dpt.endsWith("24") || dpt.endsWith("46") || dpt.endsWith("19") || dpt.endsWith("15") || dpt.endsWith("43") || dpt.endsWith("07") || dpt.endsWith("26") || dpt.endsWith("05") || dpt.endsWith("38") || dpt.endsWith("73")) {
+			return lambertCC9Zones[3].eastNorth2latlon(en);
+		} else if (dpt.endsWith("17") || dpt.endsWith("16") || dpt.endsWith("87") || dpt.endsWith("23") || dpt.endsWith("63") || dpt.endsWith("03") || dpt.endsWith("42") || dpt.endsWith("69") || dpt.endsWith("01") || dpt.endsWith("74")) {
+			return lambertCC9Zones[4].eastNorth2latlon(en);
+		} else if (dpt.endsWith("44") || dpt.endsWith("85") || dpt.endsWith("49") || dpt.endsWith("79") || dpt.endsWith("37") || dpt.endsWith("86") || dpt.endsWith("36") || dpt.endsWith("18") || dpt.endsWith("58") || dpt.endsWith("71") || dpt.endsWith("21") || dpt.endsWith("39") || dpt.endsWith("25")) {
+			return lambertCC9Zones[5].eastNorth2latlon(en);
+		} else if (dpt.endsWith("29") || dpt.endsWith("56") || dpt.endsWith("22") || dpt.endsWith("35") || dpt.endsWith("53") || dpt.endsWith("72") || dpt.endsWith("41") || dpt.endsWith("28") || dpt.endsWith("45") || dpt.endsWith("89") || dpt.endsWith("10") || dpt.endsWith("52") || dpt.endsWith("70") || dpt.endsWith("88") || dpt.endsWith("68") || dpt.endsWith("90")) {
+			return lambertCC9Zones[6].eastNorth2latlon(en);
+		} else if (dpt.endsWith("50") || dpt.endsWith("14") || dpt.endsWith("61") || dpt.endsWith("27") || dpt.endsWith("60") || dpt.endsWith("95") || dpt.endsWith("78") || dpt.endsWith("91") || dpt.endsWith("92") || dpt.endsWith("93") || dpt.endsWith("94") || dpt.endsWith("75") || dpt.endsWith("77") || dpt.endsWith("60") || dpt.endsWith("02") || dpt.endsWith("51") || dpt.endsWith("55") || dpt.endsWith("54") || dpt.endsWith("57") || dpt.endsWith("67")) {
+			return lambertCC9Zones[7].eastNorth2latlon(en);
+		} else if (dpt.endsWith("76") || dpt.endsWith("80") || dpt.endsWith("62") || dpt.endsWith("59") || dpt.endsWith("08")) {
+			return lambertCC9Zones[8].eastNorth2latlon(en);
+		} else {
+			throw new IllegalArgumentException("Unsupported department code: "+dpt);
+		}
+	}
+
+	private void replaceFaxPhone(OsmPrimitive p, String dataKey, String osmKey) {
+		String phone = p.get(dataKey);
+		if (phone != null) {
+			p.put(osmKey, phone.replace(" ", "").replace(".", "").replaceFirst("0", "+33"));
+			p.remove(dataKey);
+		}
+	}
+
+	protected void replaceFax(OsmPrimitive p, String dataKey) {
+		replaceFaxPhone(p, dataKey, "contact:fax");
+	}
+	
+	protected void replacePhone(OsmPrimitive p, String dataKey) {
+		replaceFaxPhone(p, dataKey, "contact:phone");
+	}
+	
+	private static final String dayFr = "L|Lu|M|Ma|Me|J|Je|V|Ve|S|Sa|D|Di";
+	private static final String dayEn = "Mo|Mo|Tu|Tu|We|Th|Th|Fr|Fr|Sa|Sa|Su|Su";
+	
+	private static final String[] dayFrSplit = dayFr.split("\\|");
+	private static final String[] dayEnSplit = dayEn.split("\\|");
+	
+	protected void replaceOpeningHours(OsmPrimitive p, String dataKey) {
+		String hours = p.get(dataKey);
+		if (hours != null) {
+			hours = hours.replace("h", ":").replace(": ", ":00 ");
+			hours = hours.replace(" - ", "-").replace(" au ", "-").replace(" à ", "-");
+			hours = hours.replace(" et ", ",").replace("/", ",");
+			hours = hours.replace(" (sf vacances)", "; PH off");
+			if (hours.endsWith(":")) {
+				hours += "00";
+			}
+			String dayGroup = "("+dayFr+")";
+			String dayNcGroup = "(?:"+dayFr+")";
+			// FIXME: this doesn't work yet
+			for (String sep : new String[]{"-",","}) {
+				boolean finished = false;
+				while (!finished) {
+					Matcher m = Pattern.compile(".*("+dayNcGroup+"(?:"+sep+dayNcGroup+")+).*").matcher(hours);
+					if (m.matches()) {
+						String range = m.group(1);
+						Matcher m2 = Pattern.compile(dayGroup+"(?:"+sep+dayGroup+")+").matcher(range);
+						if (m2.matches()) {
+							String replacement = "";
+							for (int i=0; i<m2.groupCount(); i++) {
+								if (i > 0) {
+									replacement += sep;
+								}
+								replacement += getEnDay(m2.group(i+1));
+							}
+							hours = hours.replace(range, replacement);
+						}
+					} else {
+						finished = true;
+					}
+				}
+			}
+			p.put("opening_hours", hours);
+			p.remove(dataKey);
+		}
+	}
+	
+	private String getEnDay(String frDay) {
+		for (int i=0; i<dayFrSplit.length; i++) {
+			if (dayFrSplit[i].equals(frDay)) {
+				return dayEnSplit[i];
+			}
+		}
+		return "";
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler#findMathTransform(org.opengis.referencing.crs.CoordinateReferenceSystem, org.opengis.referencing.crs.CoordinateReferenceSystem, boolean)
+	 */
+	@Override
+	public MathTransform findMathTransform(CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS, boolean lenient)
+			throws FactoryException {
+		if (sourceCRS.getName().getCode().equalsIgnoreCase("RGM04")) {
+			return CRS.findMathTransform(CRS.decode("EPSG:4471"), targetCRS, lenient);
+		} else if (sourceCRS.getName().getCode().equalsIgnoreCase("RGFG95_UTM_Zone_22N")) {
+			return CRS.findMathTransform(CRS.decode("EPSG:2972"), targetCRS, lenient);
+		} else {
+			return super.findMathTransform(sourceCRS, targetCRS, lenient);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/ModuleListPanel.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/ModuleListPanel.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/ModuleListPanel.java	(revision 28000)
@@ -0,0 +1,163 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.gui;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.SwingConstants;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkEvent.EventType;
+import javax.swing.event.HyperlinkListener;
+
+import org.openstreetmap.josm.gui.widgets.HtmlPanel;
+import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleInformation;
+import org.openstreetmap.josm.tools.OpenBrowser;
+
+/**
+ * TODO
+ *
+ */
+public class ModuleListPanel extends VerticallyScrollablePanel{
+    private ModulePreferencesModel model;
+
+    public ModuleListPanel() {
+        model = new ModulePreferencesModel();
+        setLayout(new GridBagLayout());
+    }
+
+    public ModuleListPanel(ModulePreferencesModel model) {
+        this.model = model;
+        setLayout(new GridBagLayout());
+    }
+
+    protected String formatModuleRemoteVersion(ModuleInformation pi) {
+        StringBuilder sb = new StringBuilder();
+        if (pi.version == null || pi.version.trim().equals("")) {
+            sb.append(tr("unknown"));
+        } else {
+            sb.append(pi.version);
+        }
+        return sb.toString();
+    }
+
+    protected String formatModuleLocalVersion(ModuleInformation pi) {
+        if (pi == null) return tr("unknown");
+        if (pi.localversion == null || pi.localversion.trim().equals(""))
+            return tr("unknown");
+        return pi.localversion;
+    }
+
+    protected String formatCheckboxTooltipText(ModuleInformation pi) {
+        if (pi == null) return "";
+        if (pi.downloadlink == null)
+            return tr("Module bundled with opendata plugin");
+        else
+            return pi.downloadlink;
+    }
+
+    public void displayEmptyModuleListInformation() {
+        GridBagConstraints gbc = new GridBagConstraints();
+        gbc.gridx = 0;
+        gbc.anchor = GridBagConstraints.CENTER;
+        gbc.fill = GridBagConstraints.BOTH;
+        gbc.insets = new Insets(40,0,40,0);
+        gbc.weightx = 1.0;
+        gbc.weighty = 1.0;
+
+        HtmlPanel hint = new HtmlPanel();
+        hint.setText(
+                "<html>"
+                + tr("Please click on <strong>Download list</strong> to download and display a list of available plugins.")
+                + "</html>"
+        );
+        add(hint, gbc);
+    }
+
+    public void refreshView() {
+        List<ModuleInformation> displayedModules = model.getDisplayedModules();
+        removeAll();
+
+        GridBagConstraints gbc = new GridBagConstraints();
+        gbc.gridx = 0;
+        gbc.anchor = GridBagConstraints.NORTHWEST;
+        gbc.fill = GridBagConstraints.HORIZONTAL;
+        gbc.weightx = 1.0;
+
+        if (displayedModules.isEmpty()) {
+            displayEmptyModuleListInformation();
+            return;
+        }
+
+        int row = -1;
+        for (final ModuleInformation pi : displayedModules) {
+            boolean selected = model.isSelectedModule(pi.getName());
+            String remoteversion = formatModuleRemoteVersion(pi);
+            String localversion = formatModuleLocalVersion(model.getModuleInformation(pi.getName()));
+
+            final JCheckBox cbModule = new JCheckBox();
+            cbModule.setSelected(selected);
+            cbModule.setToolTipText(formatCheckboxTooltipText(pi));
+            cbModule.addActionListener(new ActionListener(){
+                public void actionPerformed(ActionEvent e) {
+                    model.setModuleSelected(pi.getName(), cbModule.isSelected());
+                }
+            });
+            JLabel lblModule = new JLabel(
+                    tr("{0}: Version {1} (local: {2})", pi.getName(), remoteversion, localversion),
+                    pi.getScaledIcon(),
+                    SwingConstants.LEFT);
+
+            gbc.gridx = 0;
+            gbc.gridy = ++row;
+            gbc.insets = new Insets(5,5,0,5);
+            gbc.weighty = 0.0;
+            gbc.weightx = 0.0;
+            add(cbModule, gbc);
+
+            gbc.gridx = 1;
+            gbc.weightx = 1.0;
+            add(lblModule, gbc);
+
+            HtmlPanel description = new HtmlPanel();
+            description.setText(pi.getDescriptionAsHtml());
+            description.getEditorPane().addHyperlinkListener(new HyperlinkListener() {
+                public void hyperlinkUpdate(HyperlinkEvent e) {
+                    if(e.getEventType() == EventType.ACTIVATED) {
+                        OpenBrowser.displayUrl(e.getURL().toString());
+                    }
+                }
+            });
+
+            gbc.gridx = 1;
+            gbc.gridy = ++row;
+            gbc.insets = new Insets(3,25,5,5);
+            gbc.weighty = 1.0;
+            add(description, gbc);
+        }
+        revalidate();
+        repaint();
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/ModulePreference.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/ModulePreference.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/ModulePreference.java	(revision 28000)
@@ -0,0 +1,531 @@
+package org.openstreetmap.josm.plugins.opendata.core.gui;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+import static org.openstreetmap.josm.tools.I18n.trn;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.GridLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.HelpAwareOptionPane;
+import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
+import org.openstreetmap.josm.gui.help.HelpUtil;
+import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
+import org.openstreetmap.josm.gui.preferences.SubPreferenceSetting;
+import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting;
+import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleDownloadTask;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleInformation;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ReadLocalModuleInformationTask;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ReadRemoteModuleInformationTask;
+import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+public class ModulePreference implements SubPreferenceSetting, OdConstants {
+    /*public static class Factory implements PreferenceSettingFactory {
+        public PreferenceSetting createPreferenceSetting() {
+            return new ModulePreference();
+        }
+    }*/
+    
+    public static String buildDownloadSummary(ModuleDownloadTask task) {
+        Collection<ModuleInformation> downloaded = task.getDownloadedModules();
+        Collection<ModuleInformation> failed = task.getFailedModules();
+        StringBuilder sb = new StringBuilder();
+        if (! downloaded.isEmpty()) {
+            sb.append(trn(
+                    "The following module has been downloaded <strong>successfully</strong>:",
+                    "The following {0} modules have been downloaded <strong>successfully</strong>:",
+                    downloaded.size(),
+                    downloaded.size()
+            ));
+            sb.append("<ul>");
+            for(ModuleInformation pi: downloaded) {
+                sb.append("<li>").append(pi.name).append(" (").append(pi.version).append(")").append("</li>");
+            }
+            sb.append("</ul>");
+        }
+        if (! failed.isEmpty()) {
+            sb.append(trn(
+                    "Downloading the following module has <strong>failed</strong>:",
+                    "Downloading the following {0} modules has <strong>failed</strong>:",
+                    failed.size(),
+                    failed.size()
+            ));
+            sb.append("<ul>");
+            for(ModuleInformation pi: failed) {
+                sb.append("<li>").append(pi.name).append("</li>");
+            }
+            sb.append("</ul>");
+        }
+        return sb.toString();
+    }
+
+    private JTextField tfFilter;
+    private ModuleListPanel pnlModulePreferences;
+    private ModulePreferencesModel model;
+    private JScrollPane spModulePreferences;
+
+    /**
+     * is set to true if this preference pane has been selected
+     * by the user
+     */
+    private boolean modulePreferencesActivated = false;
+
+    protected JPanel buildSearchFieldPanel() {
+        JPanel pnl  = new JPanel(new GridBagLayout());
+        pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+        GridBagConstraints gc = new GridBagConstraints();
+
+        gc.anchor = GridBagConstraints.NORTHWEST;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.weightx = 0.0;
+        gc.insets = new Insets(0,0,0,3);
+        pnl.add(new JLabel(tr("Search:")), gc);
+
+        gc.gridx = 1;
+        gc.weightx = 1.0;
+        pnl.add(tfFilter = new JTextField(), gc);
+        tfFilter.setToolTipText(tr("Enter a search expression"));
+        SelectAllOnFocusGainedDecorator.decorate(tfFilter);
+        tfFilter.getDocument().addDocumentListener(new SearchFieldAdapter());
+        return pnl;
+    }
+
+    protected JPanel buildActionPanel() {
+        JPanel pnl = new JPanel(new GridLayout(1,3));
+
+        pnl.add(new JButton(new DownloadAvailableModulesAction()));
+        pnl.add(new JButton(new UpdateSelectedModulesAction()));
+        pnl.add(new JButton(new ConfigureSitesAction()));
+        return pnl;
+    }
+
+    protected JPanel buildModuleListPanel() {
+        JPanel pnl = new JPanel(new BorderLayout());
+        pnl.add(buildSearchFieldPanel(), BorderLayout.NORTH);
+        model  = new ModulePreferencesModel();
+        spModulePreferences = new JScrollPane(pnlModulePreferences = new ModuleListPanel(model));
+        spModulePreferences.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+        spModulePreferences.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+        spModulePreferences.getVerticalScrollBar().addComponentListener(
+                new ComponentAdapter(){
+                    @Override
+                    public void componentShown(ComponentEvent e) {
+                        spModulePreferences.setBorder(UIManager.getBorder("ScrollPane.border"));
+                    }
+                    @Override
+                    public void componentHidden(ComponentEvent e) {
+                        spModulePreferences.setBorder(null);
+                    }
+                }
+        );
+
+        pnl.add(spModulePreferences, BorderLayout.CENTER);
+        pnl.add(buildActionPanel(), BorderLayout.SOUTH);
+        return pnl;
+    }
+
+    public void addGui(final PreferenceTabbedPane gui) {
+        GridBagConstraints gc = new GridBagConstraints();
+        gc.weightx = 1.0;
+        gc.weighty = 1.0;
+        gc.anchor = GridBagConstraints.NORTHWEST;
+        gc.fill = GridBagConstraints.BOTH;
+        OdPreferenceSetting settings = gui.getSetting(OdPreferenceSetting.class);
+        settings.tabPane.addTab(tr("Modules"), buildModuleListPanel());
+        pnlModulePreferences.refreshView();
+        gui.addChangeListener(new ModulePreferenceActivationListener(settings.masterPanel));
+    }
+
+    private void configureSites() {
+        ButtonSpec[] options = new ButtonSpec[] {
+                new ButtonSpec(
+                        tr("OK"),
+                        ImageProvider.get("ok"),
+                        tr("Accept the new module sites and close the dialog"),
+                        null /* no special help topic */
+                ),
+                new ButtonSpec(
+                        tr("Cancel"),
+                        ImageProvider.get("cancel"),
+                        tr("Close the dialog"),
+                        null /* no special help topic */
+                )
+        };
+        ModuleConfigurationSitesPanel pnl = new ModuleConfigurationSitesPanel();
+
+        int answer = HelpAwareOptionPane.showOptionDialog(
+                pnlModulePreferences,
+                pnl,
+                tr("Configure Module Sites"),
+                JOptionPane.QUESTION_MESSAGE,
+                null,
+                options,
+                options[0],
+                null /* no help topic */
+        );
+        if (answer != 0 /* OK */)
+            return;
+        List<String> sites = pnl.getUpdateSites();
+        OdPreferenceSetting.setModuleSites(sites);
+    }
+
+    /**
+     * Replies the list of modules waiting for update or download
+     *
+     * @return the list of modules waiting for update or download
+     */
+    /*public List<ModuleInformation> getModulesScheduledForUpdateOrDownload() {
+        return model != null ? model.getModulesScheduledForUpdateOrDownload() : null;
+    }*/
+
+    public boolean ok() {
+        if (! modulePreferencesActivated)
+            return false;
+        if (model.isActiveModulesChanged()) {
+            LinkedList<String> l = new LinkedList<String>(model.getSelectedModuleNames());
+            Collections.sort(l);
+            Main.pref.putCollection(PREF_MODULES, l);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Reads locally available information about modules from the local file system.
+     * Scans cached module lists from module download sites and locally available
+     * module jar files.
+     *
+     */
+    public void readLocalModuleInformation() {
+        final ReadLocalModuleInformationTask task = new ReadLocalModuleInformationTask();
+        Runnable r = new Runnable() {
+            public void run() {
+                if (task.isCanceled()) return;
+                SwingUtilities.invokeLater(new Runnable() {
+                    public void run() {
+                        model.setAvailableModules(task.getAvailableModules());
+                        pnlModulePreferences.refreshView();
+                    }
+                });
+            }
+        };
+        Main.worker.submit(task);
+        Main.worker.submit(r);
+    }
+
+    /**
+     * The action for downloading the list of available modules
+     *
+     */
+    class DownloadAvailableModulesAction extends AbstractAction {
+
+        public DownloadAvailableModulesAction() {
+            putValue(NAME,tr("Download list"));
+            putValue(SHORT_DESCRIPTION, tr("Download the list of available modules"));
+            putValue(SMALL_ICON, ImageProvider.get("download"));
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            final ReadRemoteModuleInformationTask task = new ReadRemoteModuleInformationTask(OdPreferenceSetting.getModuleSites());
+            Runnable continuation = new Runnable() {
+                public void run() {
+                    if (task.isCanceled()) return;
+                    SwingUtilities.invokeLater(new Runnable() {
+                        public void run() {
+                            model.updateAvailableModules(task.getAvailabeModules());
+                            pnlModulePreferences.refreshView();
+                        }
+                    });
+                }
+            };
+            Main.worker.submit(task);
+            Main.worker.submit(continuation);
+        }
+    }
+
+    /**
+     * The action for downloading the list of available modules
+     *
+     */
+    class UpdateSelectedModulesAction extends AbstractAction {
+        public UpdateSelectedModulesAction() {
+            putValue(NAME,tr("Update modules"));
+            putValue(SHORT_DESCRIPTION, tr("Update the selected modules"));
+            putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh"));
+        }
+
+        protected void notifyDownloadResults(ModuleDownloadTask task) {
+            Collection<ModuleInformation> downloaded = task.getDownloadedModules();
+            Collection<ModuleInformation> failed = task.getFailedModules();
+            StringBuilder sb = new StringBuilder();
+            sb.append("<html>");
+            sb.append(buildDownloadSummary(task));
+            if (!downloaded.isEmpty()) {
+                sb.append(tr("Please restart JOSM to activate the downloaded modules."));
+            }
+            sb.append("</html>");
+            HelpAwareOptionPane.showOptionDialog(
+                    pnlModulePreferences,
+                    sb.toString(),
+                    tr("Update modules"),
+                    !failed.isEmpty() ? JOptionPane.WARNING_MESSAGE : JOptionPane.INFORMATION_MESSAGE,
+                            HelpUtil.ht("/Preferences/Modules")
+            );
+        }
+
+        protected void alertNothingToUpdate() {
+            HelpAwareOptionPane.showOptionDialog(
+                    pnlModulePreferences,
+                    tr("All installed modules are up to date. JOSM does not have to download newer versions."),
+                    tr("Modules up to date"),
+                    JOptionPane.INFORMATION_MESSAGE,
+                    null // FIXME: provide help context
+            );
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            final List<ModuleInformation> toUpdate = model.getSelectedModules();
+            // the async task for downloading modules
+            final ModuleDownloadTask moduleDownloadTask = new ModuleDownloadTask(
+                    pnlModulePreferences,
+                    toUpdate,
+                    tr("Update modules")
+            );
+            // the async task for downloading module information
+            final ReadRemoteModuleInformationTask moduleInfoDownloadTask = new ReadRemoteModuleInformationTask(OdPreferenceSetting.getModuleSites());
+
+            // to be run asynchronously after the module download
+            //
+            final Runnable moduleDownloadContinuation = new Runnable() {
+                public void run() {
+                    if (moduleDownloadTask.isCanceled())
+                        return;
+                    notifyDownloadResults(moduleDownloadTask);
+                    model.refreshLocalModuleVersion(moduleDownloadTask.getDownloadedModules());
+                    model.clearPendingModules(moduleDownloadTask.getDownloadedModules());
+                    pnlModulePreferences.refreshView();
+                }
+            };
+
+            // to be run asynchronously after the module list download
+            //
+            final Runnable moduleInfoDownloadContinuation = new Runnable() {
+                public void run() {
+                    if (moduleInfoDownloadTask.isCanceled())
+                        return;
+                    model.updateAvailableModules(moduleInfoDownloadTask.getAvailabeModules());
+                    // select modules which actually have to be updated
+                    //
+                    Iterator<ModuleInformation> it = toUpdate.iterator();
+                    while(it.hasNext()) {
+                        ModuleInformation pi = it.next();
+                        if (!pi.isUpdateRequired()) {
+                            it.remove();
+                        }
+                    }
+                    if (toUpdate.isEmpty()) {
+                        alertNothingToUpdate();
+                        return;
+                    }
+                    moduleDownloadTask.setModulesToDownload(toUpdate);
+                    Main.worker.submit(moduleDownloadTask);
+                    Main.worker.submit(moduleDownloadContinuation);
+                }
+            };
+
+            Main.worker.submit(moduleInfoDownloadTask);
+            Main.worker.submit(moduleInfoDownloadContinuation);
+        }
+    }
+
+
+    /**
+     * The action for configuring the module download sites
+     *
+     */
+    class ConfigureSitesAction extends AbstractAction {
+        public ConfigureSitesAction() {
+            putValue(NAME,tr("Configure sites..."));
+            putValue(SHORT_DESCRIPTION, tr("Configure the list of sites where modules are downloaded from"));
+            putValue(SMALL_ICON, ImageProvider.get("dialogs", "settings"));
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            configureSites();
+        }
+    }
+
+    /**
+     * Listens to the activation of the module preferences tab. On activation it
+     * reloads module information from the local file system.
+     *
+     */
+    class ModulePreferenceActivationListener implements ChangeListener {
+        private Component pane;
+        public ModulePreferenceActivationListener(Component preferencesPane) {
+            pane = preferencesPane;
+        }
+
+        public void stateChanged(ChangeEvent e) {
+            JTabbedPane tp = (JTabbedPane)e.getSource();
+            if (tp.getSelectedComponent() == pane) {
+                readLocalModuleInformation();
+                modulePreferencesActivated = true;
+            }
+        }
+    }
+
+    /**
+     * Applies the current filter condition in the filter text field to the
+     * model
+     */
+    class SearchFieldAdapter implements DocumentListener {
+        public void filter() {
+            String expr = tfFilter.getText().trim();
+            if (expr.equals("")) {
+                expr = null;
+            }
+            model.filterDisplayedModules(expr);
+            pnlModulePreferences.refreshView();
+        }
+
+        public void changedUpdate(DocumentEvent arg0) {
+            filter();
+        }
+
+        public void insertUpdate(DocumentEvent arg0) {
+            filter();
+        }
+
+        public void removeUpdate(DocumentEvent arg0) {
+            filter();
+        }
+    }
+
+    static private class ModuleConfigurationSitesPanel extends JPanel {
+
+        private DefaultListModel model;
+
+        protected void build() {
+            setLayout(new GridBagLayout());
+            add(new JLabel(tr("Add Open Data Module description URL.")), GBC.eol());
+            model = new DefaultListModel();
+            for (String s : OdPreferenceSetting.getModuleSites()) {
+                model.addElement(s);
+            }
+            final JList list = new JList(model);
+            add(new JScrollPane(list), GBC.std().fill());
+            JPanel buttons = new JPanel(new GridBagLayout());
+            buttons.add(new JButton(new AbstractAction(tr("Add")){
+                public void actionPerformed(ActionEvent e) {
+                    String s = JOptionPane.showInputDialog(
+                            JOptionPane.getFrameForComponent(ModuleConfigurationSitesPanel.this),
+                            tr("Add Open Data Module description URL."),
+                            tr("Enter URL"),
+                            JOptionPane.QUESTION_MESSAGE
+                    );
+                    if (s != null) {
+                        model.addElement(s);
+                    }
+                }
+            }), GBC.eol().fill(GBC.HORIZONTAL));
+            buttons.add(new JButton(new AbstractAction(tr("Edit")){
+                public void actionPerformed(ActionEvent e) {
+                    if (list.getSelectedValue() == null) {
+                        JOptionPane.showMessageDialog(
+                                JOptionPane.getFrameForComponent(ModuleConfigurationSitesPanel.this),
+                                tr("Please select an entry."),
+                                tr("Warning"),
+                                JOptionPane.WARNING_MESSAGE
+                        );
+                        return;
+                    }
+                    String s = (String)JOptionPane.showInputDialog(
+                            Main.parent,
+                            tr("Edit Open Data Module description URL."),
+                            tr("Open Data Module description URL"),
+                            JOptionPane.QUESTION_MESSAGE,
+                            null,
+                            null,
+                            list.getSelectedValue()
+                    );
+                    if (s != null) {
+                        model.setElementAt(s, list.getSelectedIndex());
+                    }
+                }
+            }), GBC.eol().fill(GBC.HORIZONTAL));
+            buttons.add(new JButton(new AbstractAction(tr("Delete")){
+                public void actionPerformed(ActionEvent event) {
+                    if (list.getSelectedValue() == null) {
+                        JOptionPane.showMessageDialog(
+                                JOptionPane.getFrameForComponent(ModuleConfigurationSitesPanel.this),
+                                tr("Please select an entry."),
+                                tr("Warning"),
+                                JOptionPane.WARNING_MESSAGE
+                        );
+                        return;
+                    }
+                    model.removeElement(list.getSelectedValue());
+                }
+            }), GBC.eol().fill(GBC.HORIZONTAL));
+            add(buttons, GBC.eol());
+        }
+
+        public ModuleConfigurationSitesPanel() {
+            build();
+        }
+
+        public List<String> getUpdateSites() {
+            if (model.getSize() == 0) return Collections.emptyList();
+            List<String> ret = new ArrayList<String>(model.getSize());
+            for (int i=0; i< model.getSize();i++){
+                ret.add((String)model.get(i));
+            }
+            return ret;
+        }
+    }
+
+	@Override
+	public boolean isExpert() {
+		return false;
+	}
+
+	@Override
+	public TabPreferenceSetting getTabPreferenceSetting(PreferenceTabbedPane gui) {
+		return gui.getSetting(OdPreferenceSetting.class);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/ModulePreferencesModel.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/ModulePreferencesModel.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/ModulePreferencesModel.java	(revision 28000)
@@ -0,0 +1,380 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.gui;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Observable;
+import java.util.Set;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.plugins.opendata.OdPlugin;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleException;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleInformation;
+
+/**
+ * TODO
+ *
+ */
+public class ModulePreferencesModel extends Observable implements OdConstants {
+    private final ArrayList<ModuleInformation> availableModules = new ArrayList<ModuleInformation>();
+    private final ArrayList<ModuleInformation> displayedModules = new ArrayList<ModuleInformation>();
+    private final HashMap<ModuleInformation, Boolean> selectedModulesMap = new HashMap<ModuleInformation, Boolean>();
+    private Set<String> pendingDownloads = new HashSet<String>();
+    private String filterExpression;
+    private final Set<String> currentActiveModules;
+
+    protected Collection<String> getModules(Collection<String> def) {
+    	return Main.pref.getCollection(PREF_MODULES, def);
+    }
+    
+    public ModulePreferencesModel() {
+    	currentActiveModules = new HashSet<String>();
+    	currentActiveModules.addAll(getModules(currentActiveModules));
+    }
+
+    public void filterDisplayedModules(String filter) {
+        if (filter == null) {
+            displayedModules.clear();
+            displayedModules.addAll(availableModules);
+            this.filterExpression = null;
+            return;
+        }
+        displayedModules.clear();
+        for (ModuleInformation pi: availableModules) {
+            if (pi.matches(filter)) {
+                displayedModules.add(pi);
+            }
+        }
+        filterExpression = filter;
+        clearChanged();
+        notifyObservers();
+    }
+
+    public void setAvailableModules(Collection<ModuleInformation> available) {
+        availableModules.clear();
+        if (available != null) {
+            availableModules.addAll(available);
+        }
+        sort();
+        filterDisplayedModules(filterExpression);
+        Set<String> activeModules = new HashSet<String>();
+        activeModules.addAll(getModules(activeModules));
+        for (ModuleInformation pi: availableModules) {
+            if (selectedModulesMap.get(pi) == null) {
+                if (activeModules.contains(pi.name)) {
+                    selectedModulesMap.put(pi, true);
+                }
+            }
+        }
+        clearChanged();
+        notifyObservers();
+    }
+
+    protected  void updateAvailableModule(ModuleInformation other) {
+        if (other == null) return;
+        ModuleInformation pi = getModuleInformation(other.name);
+        if (pi == null) {
+            availableModules.add(other);
+            return;
+        }
+        pi.updateFromModuleSite(other);
+    }
+
+    /**
+     * Updates the list of module information objects with new information from
+     * module update sites.
+     *
+     * @param fromModuleSite module information read from module update sites
+     */
+    public void updateAvailableModules(Collection<ModuleInformation> fromModuleSite) {
+        for (ModuleInformation other: fromModuleSite) {
+            updateAvailableModule(other);
+        }
+        sort();
+        filterDisplayedModules(filterExpression);
+        Set<String> activeModules = new HashSet<String>();
+        activeModules.addAll(getModules(activeModules));
+        for (ModuleInformation pi: availableModules) {
+            if (selectedModulesMap.get(pi) == null) {
+                if (activeModules.contains(pi.name)) {
+                    selectedModulesMap.put(pi, true);
+                }
+            }
+        }
+        clearChanged();
+        notifyObservers();
+    }
+
+    /**
+     * Replies the list of selected module information objects
+     *
+     * @return the list of selected module information objects
+     */
+    public List<ModuleInformation> getSelectedModules() {
+        List<ModuleInformation> ret = new LinkedList<ModuleInformation>();
+        for (ModuleInformation pi: availableModules) {
+            if (selectedModulesMap.get(pi) == null) {
+                continue;
+            }
+            if (selectedModulesMap.get(pi)) {
+                ret.add(pi);
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Replies the list of selected module information objects
+     *
+     * @return the list of selected module information objects
+     */
+    public Set<String> getSelectedModuleNames() {
+        Set<String> ret = new HashSet<String>();
+        for (ModuleInformation pi: getSelectedModules()) {
+            ret.add(pi.name);
+        }
+        return ret;
+    }
+
+    /**
+     * Sorts the list of available modules
+     */
+    protected void sort() {
+        Collections.sort(
+                availableModules,
+                new Comparator<ModuleInformation>() {
+                    public int compare(ModuleInformation o1, ModuleInformation o2) {
+                        String n1 = o1.getName() == null ? "" : o1.getName().toLowerCase();
+                        String n2 = o2.getName() == null ? "" : o2.getName().toLowerCase();
+                        return n1.compareTo(n2);
+                    }
+                }
+        );
+    }
+
+    /**
+     * Replies the list of module informations to display
+     *
+     * @return the list of module informations to display
+     */
+    public List<ModuleInformation> getDisplayedModules() {
+        return displayedModules;
+    }
+
+
+    /**
+     * Replies the list of modules waiting for update or download
+     *
+     * @return the list of modules waiting for update or download
+     */
+    /*public List<ModuleInformation> getModulesScheduledForUpdateOrDownload() {
+        List<ModuleInformation> ret = new ArrayList<ModuleInformation>();
+        for (String module: pendingDownloads) {
+            ModuleInformation pi = getModuleInformation(module);
+            if (pi == null) {
+                continue;
+            }
+            ret.add(pi);
+        }
+        return ret;
+    }*/
+
+    /**
+     * Sets whether the module is selected or not.
+     *
+     * @param name the name of the module
+     * @param selected true, if selected; false, otherwise
+     */
+    public void setModuleSelected(String name, boolean selected) {
+        ModuleInformation pi = getModuleInformation(name);
+        if (pi != null) {
+            selectedModulesMap.put(pi,selected);
+            if (pi.isUpdateRequired()) {
+                pendingDownloads.add(pi.name);
+            }
+        }
+        if (!selected) {
+            pendingDownloads.remove(name);
+        }
+    }
+
+    /**
+     * Removes all the module in {@code modules} from the list of modules
+     * with a pending download
+     *
+     * @param modules the list of modules to clear for a pending download
+     */
+    public void clearPendingModules(Collection<ModuleInformation> modules){
+        if (modules == null || modules.isEmpty()) return;
+        for(ModuleInformation pi: modules) {
+            pendingDownloads.remove(pi.name);
+        }
+    }
+
+    /**
+     * Replies the module info with the name <code>name</code>. null, if no
+     * such module info exists.
+     *
+     * @param name the name. If null, replies null.
+     * @return the module info.
+     */
+    public ModuleInformation getModuleInformation(String name) {
+        for (ModuleInformation pi: availableModules) {
+            if (pi.getName() != null && pi.getName().equals(name))
+                return pi;
+        }
+        return null;
+    }
+
+    /**
+     * Initializes the model from preferences
+     */
+    /*public void initFromPreferences() {
+        Collection<String> enabledModules = getModules(null);
+        if (enabledModules == null) {
+            this.selectedModulesMap.clear();
+            return;
+        }
+        for (String name: enabledModules) {
+            ModuleInformation pi = getModuleInformation(name);
+            if (pi == null) {
+                continue;
+            }
+            setModuleSelected(name, true);
+        }
+    }*/
+
+    /**
+     * Replies true if the module with name <code>name</code> is currently
+     * selected in the module model
+     *
+     * @param name the module name
+     * @return true if the module is selected; false, otherwise
+     */
+    public boolean isSelectedModule(String name) {
+        ModuleInformation pi = getModuleInformation(name);
+        if (pi == null) return false;
+        if (selectedModulesMap.get(pi) == null) return false;
+        return selectedModulesMap.get(pi);
+    }
+
+    /**
+     * Replies the set of modules which have been added by the user to
+     * the set of activated modules.
+     *
+     * @return the set of newly deactivated modules
+     */
+    /*public List<ModuleInformation> getNewlyActivatedModules() {
+        List<ModuleInformation> ret = new LinkedList<ModuleInformation>();
+        for (Entry<ModuleInformation, Boolean> entry: selectedModulesMap.entrySet()) {
+            ModuleInformation pi = entry.getKey();
+            boolean selected = entry.getValue();
+            if (selected && ! currentActiveModules.contains(pi.name)) {
+                ret.add(pi);
+            }
+        }
+        return ret;
+    }*/
+
+    /**
+     * Replies the set of modules which have been removed by the user from
+     * the set of activated modules.
+     *
+     * @return the set of newly deactivated modules
+     */
+    /*public List<ModuleInformation> getNewlyDeactivatedModules() {
+        List<ModuleInformation> ret = new LinkedList<ModuleInformation>();
+        for (ModuleInformation pi: availableModules) {
+            if (!currentActiveModules.contains(pi.name)) {
+                continue;
+            }
+            if (selectedModulesMap.get(pi) == null || ! selectedModulesMap.get(pi)) {
+                ret.add(pi);
+            }
+        }
+        return ret;
+    }*/
+
+    /**
+     * Replies the set of module names which have been added by the user to
+     * the set of activated modules.
+     *
+     * @return the set of newly activated module names
+     */
+    /*public Set<String> getNewlyActivatedModuleNames() {
+        Set<String> ret = new HashSet<String>();
+        List<ModuleInformation> modules = getNewlyActivatedModules();
+        for (ModuleInformation pi: modules) {
+            ret.add(pi.name);
+        }
+        return ret;
+    }*/
+
+    /**
+     * Replies true if the set of active modules has been changed by the user
+     * in this preference model. He has either added modules or removed modules
+     * being active before.
+     *
+     * @return true if the collection of active modules has changed
+     */
+    public boolean isActiveModulesChanged() {
+        Set<String> newActiveModules = getSelectedModuleNames();
+        return ! newActiveModules.equals(currentActiveModules);
+    }
+
+    /**
+     * Refreshes the local version field on the modules in <code>modules</code> with
+     * the version in the manifest of the downloaded "jar.new"-file for this module.
+     *
+     * @param modules the collections of modules to refresh
+     */
+    public void refreshLocalModuleVersion(Collection<ModuleInformation> modules) {
+        if (modules == null) return;
+        File moduleDir = OdPlugin.getInstance().getModulesDirectory();
+        for (ModuleInformation pi : modules) {
+            // Find the downloaded file. We have tried to install the downloaded modules
+            // (ModuleHandler.installDownloadedModules). This succeeds depending on the
+            // platform.
+            File downloadedModuleFile = new File(moduleDir, pi.name + ".jar.new");
+            if (!(downloadedModuleFile.exists() && downloadedModuleFile.canRead())) {
+                downloadedModuleFile = new File(moduleDir, pi.name + ".jar");
+                if (!(downloadedModuleFile.exists() && downloadedModuleFile.canRead())) {
+                    continue;
+                }
+            }
+            try {
+                ModuleInformation newinfo = new ModuleInformation(downloadedModuleFile, pi.name);
+                ModuleInformation oldinfo = getModuleInformation(pi.name);
+                if (oldinfo == null) {
+                    // should not happen
+                    continue;
+                }
+                oldinfo.localversion = newinfo.version;
+            } catch(ModuleException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/OdDialog.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/OdDialog.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/OdDialog.java	(revision 28000)
@@ -0,0 +1,135 @@
+package org.openstreetmap.josm.plugins.opendata.core.gui;
+
+import static org.openstreetmap.josm.tools.I18n.marktr;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.JTree;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeModel;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
+import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
+import org.openstreetmap.josm.gui.SideButton;
+import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.layers.OdDataLayer;
+import org.openstreetmap.josm.plugins.opendata.core.layers.OdLayer;
+import org.openstreetmap.josm.tools.Shortcut;
+
+@SuppressWarnings("serial")
+public class OdDialog extends ToggleDialog implements OdConstants, LayerChangeListener, EditLayerChangeListener {
+
+    private final SideButton selectButton;
+    private final SideButton downloadButton;
+    private final SideButton diffButton;
+    
+    private final List<SideButton> buttons;
+    
+    private final TreeModel treeModel;
+    
+    private OdDataLayer dataLayer;
+    
+    private class DownloadAction extends JosmAction {
+		public DownloadAction() {
+			super(marktr("Download"), "download", tr("Download OSM data corresponding to the current data set."), null, false);
+		}
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			if (Main.main.getEditLayer() instanceof OdLayer) {
+				dataLayer.downloadOsmData();
+				diffButton.setEnabled(dataLayer.osmLayer != null);
+			}
+		}
+    }
+
+    private class SelectAction extends JosmAction {
+		public SelectAction() {
+			super(marktr("Select"), "dialogs/select", tr("Set the selected elements on the map to the selected items in the list above."), null, false);
+		}
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			// TODO
+		}
+    }
+
+    private class DiffAction extends JosmAction {
+		public DiffAction() {
+			super(marktr("Diff"), "dialogs/diff", tr("Perform diff between current data set and existing OSM data."), null, false);
+		}
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			if (Main.main.getEditLayer() instanceof OdLayer) {
+				dataLayer.makeDiff();
+			}
+		}
+    }
+
+	public OdDialog() {
+		super("OpenData", ICON_CORE_24, tr("Open the OpenData window."), 
+				Shortcut.registerShortcut("subwindow:opendata", tr("Toggle: {0}", "OpenData"),
+						KeyEvent.VK_A, Shortcut.ALT_CTRL_SHIFT), 150);
+		
+		this.buttons = Arrays.asList(new SideButton[] {
+				selectButton = new SideButton(new SelectAction()), 
+				downloadButton = new SideButton(new DownloadAction()), 
+				diffButton = new SideButton(new DiffAction())
+        });
+		
+		disableAllButtons();
+		
+		this.treeModel = new DefaultTreeModel(null); // TODO: treeNode
+		this.dataLayer = null;
+		
+		createLayout(new JTree(treeModel), true, buttons);
+		
+		MapView.addEditLayerChangeListener(this);
+	}
+	
+	private void disableAllButtons() {
+		for (SideButton button : buttons) {
+			button.setEnabled(false);
+		}
+	}
+
+	@Override
+	public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
+		activeLayerChange(oldLayer, newLayer);
+	}
+
+	@Override
+	public void activeLayerChange(Layer oldLayer, Layer newLayer) {
+		if (newLayer instanceof OdLayer) {
+			dataLayer = ((OdLayer) newLayer).getDataLayer();
+		} else {
+			dataLayer = null;
+		}
+		
+		if (dataLayer != null) {
+			if (dataLayer.osmLayer == null) {
+				downloadButton.setEnabled(true);
+			} else if (dataLayer.diffLayer == null) {
+				diffButton.setEnabled(true);
+			}
+		} else {
+			disableAllButtons();
+		}
+	}
+
+	@Override
+	public void layerAdded(Layer newLayer) {
+	}
+
+	@Override
+	public void layerRemoved(Layer oldLayer) {
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/OdPreferenceSetting.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/OdPreferenceSetting.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/gui/OdPreferenceSetting.java	(revision 28000)
@@ -0,0 +1,151 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.gui;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.GridBagLayout;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSeparator;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextField;
+import javax.swing.SwingConstants;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting;
+import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.tools.GBC;
+
+public class OdPreferenceSetting extends DefaultTabPreferenceSetting implements OdConstants {
+
+    //private final JRadioButton rbCC43 = new JRadioButton(tr("CC43"));
+    //private final JRadioButton rbWGS84 = new JRadioButton(tr("WGS84"));
+    
+    private final JTextField oapi = new JTextField();
+    private final JTextField xapi = new JTextField();
+    
+    private final JCheckBox rawData = new JCheckBox(tr("Raw data"));
+    
+    public final JTabbedPane tabPane = new JTabbedPane();
+    public JPanel masterPanel;
+    
+    private final ModulePreference modulePref = new ModulePreference();
+
+    public OdPreferenceSetting() {
+    	super(ICON_CORE_48, tr("OpenData Preferences"),
+                tr("A special handler for various Open Data portals<br/><br/>"+
+                        "Please read the Terms and Conditions of Use of each portal<br/>"+
+                        "before any upload of data loaded by this plugin."));
+    }
+    
+    /**
+     * Replies the collection of module site URLs from where module lists can be downloaded
+     *
+     * @return
+     */
+    public static final Collection<String> getModuleSites() {
+        return Main.pref.getCollection(PREF_MODULES_SITES, Arrays.asList(DEFAULT_MODULE_SITES));
+    }
+
+    /**
+     * Sets the collection of module site URLs.
+     *
+     * @param sites the site URLs
+     */
+	public static void setModuleSites(List<String> sites) {
+		Main.pref.putCollection(PREF_MODULES_SITES, sites);
+    }
+    
+    @Override
+    public void addGui(PreferenceTabbedPane gui) {
+        masterPanel = gui.createPreferenceTab(this);
+        modulePref.addGui(gui);
+        tabPane.add(createGeneralSettings());
+        
+        JScrollPane scrollpane = new JScrollPane(tabPane);
+        scrollpane.setBorder(BorderFactory.createEmptyBorder( 0, 0, 0, 0 ));
+        masterPanel.add(scrollpane, GBC.eol().fill(GBC.BOTH));
+    }
+
+	protected JPanel createGeneralSettings() {
+        JPanel general = new JPanel(new GridBagLayout());
+        general.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
+        general.setName(tr("General settings"));
+
+        // option to enable raw data
+        rawData.setSelected(Main.pref.getBoolean(PREF_RAWDATA, DEFAULT_RAWDATA));
+        rawData.setToolTipText(tr("Import only raw data (i.e. do not add/delete tags or replace them by standard OSM tags)"));
+        general.add(rawData, GBC.eop().insets(0, 0, 0, 0));
+        
+        // separator
+        general.add(new JSeparator(SwingConstants.HORIZONTAL), GBC.eol().fill(GBC.HORIZONTAL));
+        
+        // option to select the coordinates to use
+/*        JLabel jLabelRes = new JLabel(tr("Coordinates system to read in CSV files:"));
+        p.add(jLabelRes, GBC.std().insets(0, 5, 10, 0));
+        ButtonGroup bgCoordinates = new ButtonGroup();
+        rbCC43.setToolTipText(tr("CC43"));
+        rbWGS84.setToolTipText(tr("WGS84"));
+        bgCoordinates.add(rbCC43);
+        bgCoordinates.add(rbWGS84);
+        String currentCoordinates = Main.pref.get(PREF_COORDINATES, VALUE_CC9ZONES);
+        if (currentCoordinates.equals(VALUE_WGS84))
+        	rbWGS84.setSelected(true);
+        else
+        	rbCC43.setSelected(true);
+        p.add(rbCC43, GBC.std().insets(5, 0, 5, 0));
+        p.add(rbWGS84, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 5, 0, 5));*/
+
+        // option to set the Overpass API server
+        JLabel jLabelOapi = new JLabel(tr("Overpass API server:"));
+        oapi.setText(Main.pref.get(PREF_OAPI, DEFAULT_OAPI));
+        oapi.setToolTipText(tr("Overpass API server used to download OSM data"));
+        general.add(jLabelOapi, GBC.std().insets(0, 5, 10, 0));
+        general.add(oapi, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 5, 200, 5));
+        
+        // option to set the XAPI server
+        JLabel jLabelXapi = new JLabel(tr("XAPI server:"));
+        xapi.setText(Main.pref.get(PREF_XAPI, DEFAULT_XAPI));
+        xapi.setToolTipText(tr("XAPI server used to download OSM data when Overpass API is not available"));
+        general.add(jLabelXapi, GBC.std().insets(0, 5, 10, 0));
+        general.add(xapi, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 5, 200, 5));
+        
+        // end of dialog, scroll bar
+        general.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
+        
+        return general;
+    }
+    
+    @Override
+    public boolean ok() {
+    	modulePref.ok();
+   		//Main.pref.put(PREF_COORDINATES, rbWGS84.isSelected() ? VALUE_WGS84 : VALUE_CC9ZONES);
+   		Main.pref.put(PREF_OAPI, oapi.getText());
+   		Main.pref.put(PREF_XAPI, xapi.getText());
+   		Main.pref.put(PREF_RAWDATA, rawData.isSelected());
+        return false;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/AbstractImporter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/AbstractImporter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/AbstractImporter.java	(revision 28000)
@@ -0,0 +1,86 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.ExtensionFileFilter;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.io.OsmImporter;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.core.layers.OdDataLayer;
+import org.openstreetmap.josm.plugins.opendata.core.modules.Module;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleHandler;
+
+public abstract class AbstractImporter extends OsmImporter implements OdConstants {
+	
+	protected AbstractDataSetHandler handler;
+	
+	protected File file;
+	
+    public AbstractImporter(ExtensionFileFilter filter) {
+        super(filter);
+    }
+    
+    protected final AbstractDataSetHandler findDataSetHandler(String fileName) {
+    	for (Module module : ModuleHandler.moduleList) {
+			for (AbstractDataSetHandler dsh : module.getHandlers()) {
+				if (dsh.acceptsFilename(fileName)) {
+					return dsh;
+				}
+			}
+		}
+    	return null;
+    }
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.io.OsmImporter#importData(java.io.File, org.openstreetmap.josm.gui.progress.ProgressMonitor)
+	 */
+	@Override
+	public void importData(File file, ProgressMonitor progressMonitor)
+			throws IOException, IllegalDataException {
+		if (file != null) {
+			this.file = file;
+			this.handler = findDataSetHandler(file.getName());
+		}
+		super.importData(file, progressMonitor);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.io.OsmImporter#createLayer(org.openstreetmap.josm.data.osm.DataSet, java.io.File, java.lang.String)
+	 */
+	@Override
+	protected OsmDataLayer createLayer(DataSet dataSet, File associatedFile, String layerName) {
+		if (handler != null) {
+			handler.setAssociatedFile(associatedFile);
+			handler.setSourceDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date(associatedFile.lastModified())));
+			if (!Main.pref.getBoolean(PREF_RAWDATA)) {
+				handler.updateDataSet(dataSet);
+			}
+			handler.checkDataSetSource(dataSet);
+			handler.checkNames(dataSet);
+		}
+		return new OdDataLayer(dataSet, layerName, associatedFile, handler);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/LambertCC9ZonesProjectionPatterns.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/LambertCC9ZonesProjectionPatterns.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/LambertCC9ZonesProjectionPatterns.java	(revision 28000)
@@ -0,0 +1,40 @@
+package org.openstreetmap.josm.plugins.opendata.core.io;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.regex.Matcher;
+
+import org.openstreetmap.josm.data.projection.LambertCC9Zones;
+import org.openstreetmap.josm.data.projection.Projection;
+
+public class LambertCC9ZonesProjectionPatterns extends ProjectionPatterns {
+	
+	public static final LambertCC9Zones[] lambertCC9Zones = new LambertCC9Zones[9];
+	static {
+		for (int i=0; i<lambertCC9Zones.length; i++) {
+			lambertCC9Zones[i] = new LambertCC9Zones(i);
+		}
+	}
+
+	public LambertCC9ZonesProjectionPatterns(String proj) {
+		super(proj);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.io.CoordinatePatterns#getProjection(java.lang.String, java.lang.String)
+	 */
+	@Override
+	public Projection getProjection(String xFieldName, String yFieldName) {
+
+		Matcher mx = getXPattern().matcher(xFieldName);
+		Matcher my = getYPattern().matcher(yFieldName);
+		mx.find();
+		my.find();
+		String ccx = mx.group(1);
+		String ccy = mx.group(1);
+		if (!ccx.equals(ccy)) {
+			throw new IllegalArgumentException(tr("''Lambert CC 9 zones'' coordinates found with different zone codes for X and Y: "+xFieldName+", "+yFieldName));
+		}
+		return lambertCC9Zones[Integer.parseInt(ccx)-42];
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/OsmDownloader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/OsmDownloader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/OsmDownloader.java	(revision 28000)
@@ -0,0 +1,48 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Collection;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+
+public class OsmDownloader implements OdConstants {
+	
+	public static final void downloadOapi(String oapiReq) {
+		if (oapiReq != null) {
+			try {
+				String oapiServer = Main.pref.get(PREF_OAPI, DEFAULT_OAPI);
+				System.out.println(oapiReq);
+				String oapiReqEnc = URLEncoder.encode(oapiReq, UTF8);
+				Main.main.menu.openLocation.openUrl(false, oapiServer+"data="+oapiReqEnc);
+			} catch (UnsupportedEncodingException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	public static final void downloadXapi(Collection<String> xapiReqs) {
+		if (xapiReqs != null) {
+			String xapiServer = Main.pref.get(PREF_XAPI, DEFAULT_XAPI);
+			for (String xapiReq : xapiReqs) {
+				Main.main.menu.openLocation.openUrl(false, xapiServer+xapiReq);
+			}
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/ProjectionChooser.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/ProjectionChooser.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/ProjectionChooser.java	(revision 28000)
@@ -0,0 +1,68 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Component;
+import java.awt.GridBagLayout;
+
+import javax.swing.BorderFactory;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.data.projection.Projections;
+import org.openstreetmap.josm.gui.ExtendedDialog;
+import org.openstreetmap.josm.tools.GBC;
+
+@SuppressWarnings("serial")
+public class ProjectionChooser extends ExtendedDialog {
+
+    /**
+     * This is the panel holding all projection preferences
+     */
+    private final JPanel projPanel = new JPanel(new GridBagLayout());
+    
+    /**
+     * Combobox with all projections available
+     */
+    private final JComboBox projectionCombo = new JComboBox(Projections.getProjections().toArray());
+
+	public ProjectionChooser(Component parent) {
+		this(parent, tr("Projection method"), new String[] {tr("OK"), tr("Cancel")});
+	}
+	
+	protected ProjectionChooser(Component parent, String title,
+			String[] buttonTexts) {
+		super(parent, title, buttonTexts);
+		addGui();
+	}
+	
+	public void addGui() {
+        projPanel.setBorder(BorderFactory.createEmptyBorder( 0, 0, 0, 0 ));
+        projPanel.setLayout(new GridBagLayout());
+        projPanel.add(new JLabel(tr("Projection method")), GBC.std().insets(5,5,0,5));
+        projPanel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
+        projPanel.add(projectionCombo, GBC.eop().fill(GBC.HORIZONTAL).insets(0,5,5,5));
+        setContent(projPanel);
+	}
+	
+	public Projection getProjection() {
+		return (Projection) projectionCombo.getSelectedItem();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/ProjectionPatterns.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/ProjectionPatterns.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/ProjectionPatterns.java	(revision 28000)
@@ -0,0 +1,67 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io;
+
+import java.util.regex.Pattern;
+
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+
+public class ProjectionPatterns implements OdConstants {
+
+	private final Pattern xPattern;
+	private final Pattern yPattern;
+	private final Projection projection;
+	
+	public ProjectionPatterns(Pattern xPattern, Pattern yPattern, Projection projection) {
+		this.xPattern = xPattern;
+		this.yPattern = yPattern;
+		this.projection = projection;
+		PROJECTIONS.add(this);
+	}
+
+	public ProjectionPatterns(Pattern xPattern, Pattern yPattern) {
+		this(xPattern, yPattern, null);
+	}
+
+	public ProjectionPatterns(String proj, Projection projection) {
+		this(getCoordinatePattern(X_STRING, proj), getCoordinatePattern(Y_STRING, proj), projection);
+	}
+
+	public ProjectionPatterns(String proj) {
+		this(getCoordinatePattern(X_STRING, proj), getCoordinatePattern(Y_STRING, proj), null);
+	}
+	
+	public final Pattern getXPattern() {
+		return xPattern;
+	}
+	
+	public final Pattern getYPattern() {
+		return yPattern;
+	}
+
+	public Projection getProjection(String xFieldName, String yFieldName) {
+		return getProjection();
+	}
+
+	public final Projection getProjection() {
+		return projection;
+	}
+
+	public static final Pattern getCoordinatePattern(String coor, String proj) {
+    	return Pattern.compile("(?:.*(?:"+coor+").*(?:"+proj+").*)|(?:.*("+proj+").*(?:"+coor+").*)", Pattern.CASE_INSENSITIVE);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/CandidateChooser.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/CandidateChooser.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/CandidateChooser.java	(revision 28000)
@@ -0,0 +1,100 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.archive;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Component;
+import java.awt.GridBagLayout;
+import java.io.File;
+import java.util.List;
+
+import javax.swing.BorderFactory;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+
+import org.openstreetmap.josm.gui.ExtendedDialog;
+import org.openstreetmap.josm.tools.GBC;
+
+@SuppressWarnings("serial")
+public class CandidateChooser extends ExtendedDialog {
+
+    /**
+     * This is the panel holding all candidate files
+     */
+    private final JPanel projPanel = new JPanel(new GridBagLayout());
+
+    //private final Map<JCheckBox, File> checkBoxes = new HashMap<JCheckBox, File>();
+    private final JComboBox fileCombo;
+
+	public CandidateChooser(Component parent, List<File> candidates) {
+		this(parent, tr("File to load"), new String[] {tr("OK"), tr("Cancel")}, candidates);
+	}
+	
+	private class Renderer extends DefaultListCellRenderer {
+
+		/* (non-Javadoc)
+		 * @see javax.swing.DefaultListCellRenderer#getListCellRendererComponent(javax.swing.JList, java.lang.Object, int, boolean, boolean)
+		 */
+		@Override
+		public Component getListCellRendererComponent(JList list, Object value,
+				int index, boolean isSelected, boolean cellHasFocus) {
+			super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+			if (value instanceof File) {
+				setText(((File)value).getName());
+			}
+			return this;
+		}
+	}
+	
+	protected CandidateChooser(Component parent, String title, String[] buttonTexts, List<File> candidates) {
+		super(parent, title, buttonTexts);
+		this.fileCombo = new JComboBox(candidates.toArray());
+		this.fileCombo.setRenderer(new Renderer());
+		addGui(candidates);
+	}
+	
+	public void addGui(List<File> candidates) {
+        projPanel.setBorder(BorderFactory.createEmptyBorder( 0, 0, 0, 0 ));
+        projPanel.setLayout(new GridBagLayout());
+        projPanel.add(new JLabel(tr("File to load")), GBC.std().insets(5,5,0,5));
+        projPanel.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
+        /*for (File file : candidates) {
+        	JCheckBox cbox = new JCheckBox(file.getName());
+        	checkBoxes.put(cbox, file);
+        	projPanel.add(cbox, GBC.eop().fill(GBC.HORIZONTAL).insets(0,5,5,5));
+        }*/
+        projPanel.add(fileCombo, GBC.eop().fill(GBC.HORIZONTAL).insets(0,5,5,5));
+        setContent(projPanel);
+	}
+	
+	/*public List<File> getSelectedFiles() {
+		List<File> result = new ArrayList<File>();
+		for (JCheckBox cbox : checkBoxes.keySet()) {
+			if (cbox.isSelected()) {
+				result.add(checkBoxes.get(cbox));
+			}
+		}
+		return result;
+	}*/
+	
+	public File getSelectedFile() {
+		return (File) fileCombo.getSelectedItem();
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/ZipImporter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/ZipImporter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/ZipImporter.java	(revision 28000)
@@ -0,0 +1,40 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.archive;
+
+import java.io.InputStream;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.plugins.opendata.core.io.AbstractImporter;
+
+public class ZipImporter extends AbstractImporter {
+
+	public ZipImporter() {
+		super(ZIP_FILE_FILTER);
+	}
+
+	@Override
+	protected DataSet parseDataSet(InputStream in, ProgressMonitor instance)
+			throws IllegalDataException {
+		try {
+			return ZipReader.parseDataSet(in, handler, instance);
+		} catch (Exception e) {
+			throw new IllegalDataException(e);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/ZipReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/ZipReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/archive/ZipReader.java	(revision 28000)
@@ -0,0 +1,153 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.archive;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import javax.xml.stream.FactoryConfigurationError;
+import javax.xml.stream.XMLStreamException;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.AbstractReader;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.core.io.geographic.KmlReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.geographic.KmzReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.geographic.MifReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.geographic.ShpReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.geographic.TabReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.tabular.CsvReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.tabular.OdsReader;
+import org.openstreetmap.josm.plugins.opendata.core.io.tabular.XlsReader;
+
+public class ZipReader extends AbstractReader implements OdConstants {
+
+	private final ZipInputStream zis;
+	private final AbstractDataSetHandler handler;
+    
+    public ZipReader(ZipInputStream zis, AbstractDataSetHandler handler) {
+        this.zis = zis;
+        this.handler = handler;
+    }
+
+	public static DataSet parseDataSet(InputStream in, AbstractDataSetHandler handler, ProgressMonitor instance) throws IOException, XMLStreamException, FactoryConfigurationError {
+		return new ZipReader(new ZipInputStream(in), handler).parseDoc(instance);
+	}
+	
+	private static final File createTempDir() throws IOException {
+	    final File temp = File.createTempFile("josm_opendata_temp_", Long.toString(System.nanoTime()));
+
+	    if(!temp.delete()) {
+	        throw new IOException("Could not delete temp file: " + temp.getAbsolutePath());
+	    }
+
+	    if (!temp.mkdir()) {
+	        throw new IOException("Could not create temp directory: " + temp.getAbsolutePath());
+	    }
+	    
+	    return temp;
+	}
+	
+	private static final void deleteDir(File dir) {
+        for (File file : dir.listFiles()) {
+            file.delete();
+        }
+		dir.delete();
+	}
+
+	private DataSet parseDoc(ProgressMonitor instance) throws IOException, XMLStreamException, FactoryConfigurationError  {
+		
+	    final File temp = createTempDir();
+	    final List<File> candidates = new ArrayList<File>();
+	    
+	    try {
+			ZipEntry entry;
+			while ((entry = zis.getNextEntry()) != null) {
+				File file = new File(temp + File.separator + entry.getName());
+				if (!file.createNewFile()) {
+					throw new IOException("Could not create temp file: " + file.getAbsolutePath());
+				}
+				FileOutputStream fos = new FileOutputStream(file);
+				byte[] buffer = new byte[8192];
+				int count = 0;
+				while ((count = zis.read(buffer, 0, buffer.length)) > 0) {
+					fos.write(buffer, 0, count);
+				}
+				fos.close();
+				for (String ext : new String[] {
+						CSV_EXT, KML_EXT, KMZ_EXT, XLS_EXT, ODS_EXT, SHP_EXT, MIF_EXT, TAB_EXT
+				}) {
+					if (entry.getName().toLowerCase().endsWith("."+ext)) {
+						candidates.add(file);
+						System.out.println(entry.getName());
+						break;
+					}
+				}
+			}
+			
+			File file = null;
+			
+			if (candidates.size() > 1) {
+				CandidateChooser dialog = (CandidateChooser) new CandidateChooser(instance.getWindowParent(), candidates).showDialog();
+				if (dialog.getValue() != 1) {
+					return null; // User clicked Cancel
+				}
+				file = dialog.getSelectedFile();
+			} else if (candidates.size() == 1) {
+				file = candidates.get(0);
+			}
+			
+			if (file != null) {
+				DataSet from = null;
+				FileInputStream in = new FileInputStream(file);
+				if (file.getName().toLowerCase().endsWith(CSV_EXT)) {
+					from = CsvReader.parseDataSet(in, handler, instance);
+				} else if (file.getName().toLowerCase().endsWith(KML_EXT)) {
+					from = KmlReader.parseDataSet(in, instance);
+				} else if (file.getName().toLowerCase().endsWith(KMZ_EXT)) {
+					from = KmzReader.parseDataSet(in, instance);
+				} else if (file.getName().toLowerCase().endsWith(XLS_EXT)) {
+					from = XlsReader.parseDataSet(in, handler, instance);
+				} else if (file.getName().toLowerCase().endsWith(ODS_EXT)) {
+					from = OdsReader.parseDataSet(in, handler, instance);
+				} else if (file.getName().toLowerCase().endsWith(SHP_EXT)) {
+					from = ShpReader.parseDataSet(in, file, handler, instance);
+				} else if (file.getName().toLowerCase().endsWith(MIF_EXT)) {
+					from = MifReader.parseDataSet(in, file, handler, instance);
+				} else if (file.getName().toLowerCase().endsWith(TAB_EXT)) {
+					from = TabReader.parseDataSet(in, file, handler, instance);
+				}
+				if (from != null) {
+					ds.mergeFrom(from);
+				}
+			}
+			
+	    } finally {
+	    	deleteDir(temp);
+	    }
+		
+		return ds;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/AbstractMapInfoReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/AbstractMapInfoReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/AbstractMapInfoReader.java	(revision 28000)
@@ -0,0 +1,93 @@
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openstreetmap.josm.io.AbstractReader;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+
+public abstract class AbstractMapInfoReader extends AbstractReader implements OdConstants {
+
+	protected static final String VERSION_1 = "1";
+	protected static final String VERSION_2 = "2";
+	protected static final String VERSION_300 = "300";
+	protected static final String VERSION_450 = "450";
+
+	protected static final String CHARSET_WINDOWS = "WindowsLatin1";
+	protected static final String CHARSET_NEUTRAL = "Neutral";
+	protected static final String CHARSET_MAC     = "MacRoman";
+	
+	protected BufferedReader headerReader;
+
+	protected String line;
+	protected int lineNum = 0;
+
+	protected String version;
+
+	// Columns
+	protected int numcolumns = -1;
+	protected List<String> columns;
+
+	protected final File getDataFile(File headerFile, String extension) {
+		String filename = headerFile.getName().substring(0, headerFile.getName().lastIndexOf('.'));
+		File dataFile = new File(headerFile.getParent() + File.separator + filename + extension.toUpperCase());
+		if (!dataFile.exists()) {
+			dataFile = new File(headerFile.getParent() + File.separator + filename + extension.toLowerCase());
+		}
+		return dataFile;
+	}
+	
+	protected final BufferedReader getDataReader(File headerFile, String extension, Charset charset) throws FileNotFoundException {
+		File dataFile = getDataFile(headerFile, extension);
+		return dataFile.exists() ? new BufferedReader(new InputStreamReader(new FileInputStream(dataFile), charset)) : null;
+	}
+
+	protected Charset parseCharset(String[] words) {
+		return parseCharset(words, 1);
+	}
+
+	protected Charset parseCharset(String[] words, int index) {
+		words[index] = words[index].replace("\"", "");
+		if (words[index].equalsIgnoreCase(CHARSET_WINDOWS)) {
+			return Charset.forName(CP1252);
+		} else if (words[index].equalsIgnoreCase(CHARSET_NEUTRAL)) {
+			return Charset.forName(ISO8859_15);
+		} else if (words[index].equalsIgnoreCase(CHARSET_MAC)) {
+			return Charset.forName(MAC_ROMAN);
+		} else {
+			System.err.println("Line "+lineNum+". Unknown charset detected: "+line);
+			return Charset.forName(words[index]);
+		}
+	}
+
+	protected void parseVersion(String[] words) {
+		version = words[1];
+	}
+	
+	protected void parseColumns(String[] words) {
+		columns = new ArrayList<String>();
+		numcolumns = Integer.parseInt(words[1]);
+	}
+
+	protected final void parseHeader() throws IOException {
+		while ((line = headerReader.readLine()) != null) {
+			lineNum++;
+			while (line.contains("  ")) {
+				line = line.replace("  ", " ");
+			}
+			String [] words = line.isEmpty() ? null : line.trim().split(" ");
+			if (words != null && words.length > 0) {
+				parseHeaderLine(words);
+			}
+		}
+	}
+	
+	protected abstract void parseHeaderLine(String[] words) throws IOException;
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/KmlKmzImporter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/KmlKmzImporter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/KmlKmzImporter.java	(revision 28000)
@@ -0,0 +1,44 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+import java.io.InputStream;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.plugins.opendata.core.io.AbstractImporter;
+
+public class KmlKmzImporter extends AbstractImporter {
+	
+    public KmlKmzImporter() {
+        super(KML_KMZ_FILE_FILTER);
+    }
+
+	@Override
+	protected DataSet parseDataSet(InputStream in, ProgressMonitor instance)
+			throws IllegalDataException {
+		try {
+			if (file.getName().toLowerCase().endsWith(KML_EXT)) {
+				return KmlReader.parseDataSet(in, instance);
+			} else {
+				return KmzReader.parseDataSet(in, instance);
+			}
+		} catch (Exception e) {
+			throw new IllegalDataException(e);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/KmlReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/KmlReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/KmlReader.java	(revision 28000)
@@ -0,0 +1,152 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.stream.FactoryConfigurationError;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.AbstractReader;
+import org.openstreetmap.josm.io.UTFInputStreamReader;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.io.ProjectionPatterns;
+
+public class KmlReader extends AbstractReader implements OdConstants {
+
+    private XMLStreamReader parser;
+    private Map<LatLon, Node> nodes = new HashMap<LatLon, Node>();
+    
+    public KmlReader(XMLStreamReader parser) {
+        this.parser = parser;
+    }
+
+	public static DataSet parseDataSet(InputStream in, ProgressMonitor instance) throws IOException, XMLStreamException, FactoryConfigurationError {
+        InputStreamReader ir = UTFInputStreamReader.create(in, UTF8);
+        XMLStreamReader parser = XMLInputFactory.newInstance().createXMLStreamReader(ir);
+        return new KmlReader(parser).parseDoc();
+	}
+
+	private DataSet parseDoc() throws XMLStreamException {
+		DataSet ds = new DataSet();
+		while (parser.hasNext()) {
+            int event = parser.next();
+            if (event == XMLStreamConstants.START_ELEMENT) {
+                if (parser.getLocalName().equals(KML_PLACEMARK)) {
+                	parsePlaceMark(ds);
+                }
+            }
+		}
+		return ds;
+	}
+	
+	private static boolean keyIsIgnored(String key) {
+		for (ProjectionPatterns pp : PROJECTIONS) {
+			if (pp.getXPattern().matcher(key).matches() || pp.getYPattern().matcher(key).matches()) {
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	private void parsePlaceMark(DataSet ds) throws XMLStreamException {
+		List<OsmPrimitive> list = new ArrayList<OsmPrimitive>();
+		Way way = null;
+		Node node = null;
+		Relation relation = null;
+		String role = "";
+		Map<String, String> tags = new HashMap<String, String>();
+		while (parser.hasNext()) {
+            int event = parser.next();
+            if (event == XMLStreamConstants.START_ELEMENT) {
+            	if (parser.getLocalName().equals(KML_COLOR)) {
+            		String s = parser.getElementText();
+            		// KML color format is aabbggrr, convert it to OSM (web) format: #rrggbb
+            		String rgbColor = '#'+s.substring(6,8)+s.substring(4,6)+s.substring(2,4);
+            		tags.put(KML_COLOR, rgbColor);
+            	} else if (parser.getLocalName().equals(KML_NAME)) {
+                	tags.put(KML_NAME, parser.getElementText());
+            	} else if (parser.getLocalName().equals(KML_SIMPLE_DATA)) {
+            		String key = parser.getAttributeValue(null, "name");
+            		if (!keyIsIgnored(key)) {
+            			tags.put(key, parser.getElementText());
+            		}
+            	} else if (parser.getLocalName().equals(KML_POLYGON)) {
+            		ds.addPrimitive(relation = new Relation());
+            		relation.put("type", "multipolygon");
+            		list.add(relation);
+            	} else if (parser.getLocalName().equals(KML_OUTER_BOUND)) {
+            		role = "outer";
+            	} else if (parser.getLocalName().equals(KML_INNER_BOUND)) {
+            		role = "inner";
+            	} else if (parser.getLocalName().equals(KML_LINEAR_RING)) {
+            		if (relation != null) {
+            			ds.addPrimitive(way = new Way());
+            			relation.addMember(new RelationMember(role, way));
+            		}
+            	} else if (parser.getLocalName().equals(KML_LINE_STRING)) {
+            		ds.addPrimitive(way = new Way());
+            		list.add(way);
+            	} else if (parser.getLocalName().equals(KML_COORDINATES)) {
+            		String[] tab = parser.getElementText().split(" ");
+            		for (int i = 0; i < tab.length; i ++) {
+            			String[] values = tab[i].split(","); 
+            			LatLon ll = new LatLon(Double.valueOf(values[1]), Double.valueOf(values[0])).getRoundedToOsmPrecisionStrict();
+            			node = nodes.get(ll);
+            			if (node == null) {
+            				ds.addPrimitive(node = new Node(ll));
+            				nodes.put(ll, node);
+            				if (values.length > 2 && !values[2].equals("0")) {
+            					node.put("ele", values[2]);
+            				}
+            			}
+            			if (way != null) {
+            				way.addNode(node);
+            			}
+            		}
+            	}
+            } else if (event == XMLStreamConstants.END_ELEMENT) {
+                if (parser.getLocalName().equals(KML_PLACEMARK)) {
+                	break;
+                } else if (parser.getLocalName().equals(KML_POINT)) {
+                	list.add(node);
+                }
+            }
+		}
+		for (OsmPrimitive p : list) {
+			for (String key : tags.keySet()) {
+				p.put(key, tags.get(key));
+			}
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/KmzReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/KmzReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/KmzReader.java	(revision 28000)
@@ -0,0 +1,54 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipInputStream;
+
+import javax.xml.stream.FactoryConfigurationError;
+import javax.xml.stream.XMLStreamException;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.AbstractReader;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+
+public class KmzReader extends AbstractReader implements OdConstants {
+
+	private ZipInputStream zis;
+    
+    public KmzReader(ZipInputStream zis) {
+        this.zis = zis;
+    }
+
+	public static DataSet parseDataSet(InputStream in, ProgressMonitor instance) throws IOException, XMLStreamException, FactoryConfigurationError {
+		return new KmzReader(new ZipInputStream(in)).parseDoc(instance);
+	}
+
+	private DataSet parseDoc(ProgressMonitor instance) throws IOException, XMLStreamException, FactoryConfigurationError  {
+		long size = zis.getNextEntry().getSize();
+		byte[] buffer = new byte[(int) size];
+		int off = 0;
+		int count = 0;
+		while ((count = zis.read(buffer, off, (int)size)) > 0) {
+			off += count;
+			size -= count;
+		}
+		return KmlReader.parseDataSet(new ByteArrayInputStream(buffer), instance);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifDatum.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifDatum.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifDatum.java	(revision 28000)
@@ -0,0 +1,165 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+import static org.openstreetmap.josm.plugins.opendata.core.io.geographic.MifEllipsoid.*;
+
+// TODO: finish
+public enum MifDatum {
+	Adindan(1, Clarke_1880),
+	Afgooye(2, Krassovsky),
+	Ain_el_Abd_1970(3, International),
+	Anna_1_Astro_1965(4, Australian_National),
+	Arc_1950(5, Clarke_1880),
+	Arc_1960(6, Clarke_1880),
+	Ascension_Island_1958(7, International),
+	Astro_Beacon_E(8, International),
+	Astro_B4_Sorol_Atoll(9, International),
+	Astro_DOS_71_4(10, International),
+	Astronomic_Station_1952(11, International),
+	Australian_Geodetic_1966_AGD_66(12, Australian_National),
+	Australian_Geodetic_1984_AGD_84(13, Australian_National),
+	Belgium(110, International),
+	Bellevue_IGN(14, International),
+	Bermuda_1957(15, Clarke_1866),
+	Bogota_Observatory(16, International),
+//17 Campo_Inchauspe Argentina International),
+//18 Canton_Astro_1966 Phoenix Islands International),
+//19 Cape South Africa Clarke_1880),
+//20 Cape Canaveral Florida and Bahama Islands Clarke_1866),
+//21 Carthage Tunisia Clarke_1880),
+//22 Chatham 1971 Chatham Island (New Zealand) International),
+//23 Chua Astro Paraguay International),
+//24 Corrego Alegre Brazil International),
+//1000 Deutsches 	Hauptdreicksnetz 	(DHDN) 	Germany Bessel),
+//25 Djakarta (Batavia) Sumatra Island (Indonesia) Bessel 1841),
+//26 DOS 1968 Gizo Island (New Georgia Islands) International),
+//27 Easter Island 1967 Easter Island International),
+	European_1950_ED_50(28, International),
+	European_1979_ED_79(29, International),
+	European_1987_ED_87(108, International),
+	Gandajika_Base(30, International),
+	Geodetic_Datum_1949(31, International),
+	Geodetic_Reference_System_1967_GRS_67(32, GRS_67),
+	Geodetic_Reference_System_1980_GRS_80(33, GRS_80),
+//34 Guam 1963 Guam Island Clarke_1866),
+//35 GUX 1 Astro Guadalcanal Island International),
+//36 Hito XVIII 1963 South Chile (near 53°S) International),
+//37 Hjorsey 1955 Iceland International),
+//38 Hong Kong 1963 Hong Kong International),
+//39 Hu–Tzu–Shan Taiwan International),
+//40 Indian Thailand and Vietnam Everest),
+//41 Indian Bangladesh, India, Nepal Everest),
+//42 Ireland 1965 Ireland Modified Airy),
+//43 ISTS 073 Astro 1969 Diego Garcia International),
+//44 Johnston Island 1961 Johnston Island International),
+//45 Kandawala Sri Lanka Everest),
+//46 Kerguelen Island Kerguelen Island International),
+//47 Kertau 1948 West Malaysia and Singapore Modified Everest),
+//48 L.C. 5 Astro Cayman Brac Island Clarke_1866),
+//49 Liberia 1964 Liberia Clarke_1880),
+//113 Lisboa (DLx) Portugal International),
+//50 Luzon Philippines (excluding Mindanao Island) Clarke_1866),
+//51 Luzon Mindanao Island Clarke_1866),
+//52 Mahe 1971 Mahe Island Clarke_1880),
+//53 Marco Astro Salvage Islands International),
+//54 Massawa Eritrea (Ethiopia) Bessel 1841),
+//114 Melrica 1973 (D73) Portugal International),
+//55 Merchich Morocco Clarke_1880),
+//56 Midway Astro 1961 Midway Island International),
+//57 Minna Nigeria Clarke_1880),
+//58 Nahrwan Masirah Island (Oman) Clarke_1880),
+//59 Nahrwan United Arab Emirates Clarke_1880),
+//60 Nahrwan Saudi Arabia Clarke_1880),
+//61 Naparima, BWI Trinidad and Tobago International),
+//109 Netherlands Netherlands Bessel),
+	North_American_1927_NAD_27_CONTINENTAL(62, Clarke_1866),
+	North_American_1927_NAD_27_ALASKA(63, Clarke_1866),
+	North_American_1927_NAD_27_BAHAMAS(64, Clarke_1866),
+	North_American_1927_NAD_27_SAN_SALVADOR(65, Clarke_1866),
+	North_American_1927_NAD_27_CANADA(66, Clarke_1866),
+	North_American_1927_NAD_27_CANAL_ZONE(67, Clarke_1866),
+	North_American_1927_NAD_27_CARIBBEAN(68, Clarke_1866),
+	North_American_1927_NAD_27_CENTRAL_AMERICA(69, Clarke_1866),
+	North_American_1927_NAD_27_CUBA(70, Clarke_1866),
+	North_American_1927_NAD_27_GREENLAND(71, Clarke_1866),
+	North_American_1927_NAD_27_MEXICO(72, Clarke_1866),
+	North_American_1927_NAD_27_MICHIGAN(73, Modified_Clarke_1866),
+	North_American_1983_NAD_83(74, GRS_80),
+	Nouvelle_Triangulation_Francaise_NTF(107, Clarke_1880),
+	Nouvelle_Triangulation_Francaise_NTF_Greenwich_Prime_Meridian(1002, Clarke_1880),
+	NWGL_10(111, WGS_72),
+//75 Observatorio 1966 Corvo and Flores Islands (Azores) International),
+//76 Old Egyptian Egypt Helmert 1906),
+//77 Old Hawaiian Hawaii Clarke_1866),
+//78 Oman Oman Clarke_1880),
+//79 Ordnance Survey of Great Britain 1936 England, Isle of Man, Scotland, Shetland Islands, Wales Airy),
+//80 Pico de las Nieves Canary Islands International),
+//81 Pitcairn Astro 1967 Pitcairn Island International),
+//1000 Potsdam Germany Bessel),
+//36 Provisional South Chilean 1963 South Chile (near 53°S) International),
+//82 Provisional South American 1956 Bolivia, Chile, Colombia, Ecuador, Guyana, Peru, Venezuela International),
+//83 Puerto Rico Puerto Rico and Virgin Islands Clarke_1866),
+//1001 Pulkovo 1942 Germany Krassovsky),
+//84 Qatar National Qatar International),
+//85 Qornoq South Greenland International),
+//1000 Rauenberg Germany Bessel),
+//86 Reunion Mascarene Island International),
+//112 Rikets Triangulering 1990 (RT 90) Sweden Bessel),
+//87 Rome 1940 Sardinia Island International),
+//88 Santo (DOS) Espirito Santo Island International),
+//89 São Braz São Miguel, Santa Maria Islands (Azores) International),
+//90 Sapper Hill 1943 East Falkland Island International),
+//91 Schwarzeck Namibia Modified Bessel 1841),
+//92 South American 1969 Argentina, Bolivia, Brazil, Chile, Colombia, Ecuador, Guyana, Paraguay, Peru, Venezuela, Trinidad, and Tobago South American 1969),
+//93 South Asia Singapore Modified Fischer 1960),
+//94 Southeast Base Porto Santo and Madeira Islands International),
+//95 Southwest Base Faial, Graciosa, Pico, Sao Jorge, Terceira Islands (Azores) International),
+//1003 Switzerland (CH 1903) Switzerland Bessel),
+//96 Timbalai 1948 Brunei and East Malaysia (Sarawak and Sabah) Everest),
+//97 Tokyo Japan, Korea, Okinawa Bessel 1841),
+//98 Tristan Astro 1968 Tristan da Cunha International),
+//99 Viti Levu 1916 Viti Levu Island (Fiji Islands) Clarke_1880),
+	Wake_Eniwetok_1960(100, Hough),
+	World_Geodetic_System_1960_WGS_60(101, WGS_60),
+	World_Geodetic_System_1966_WGS_66(102, WGS_66),
+	World_Geodetic_System_1972_WGS_72(103, WGS_72),
+	World_Geodetic_System_1984_WGS_84(104, WGS_84),
+	Yacare(105, International),
+	Zanderij(106, International),
+	Custom(999, null);
+	
+	private final Integer code;
+	private final MifEllipsoid ellipsoid;
+	private MifDatum(Integer code, MifEllipsoid ellipsoid) {
+		this.code = code;
+		this.ellipsoid = ellipsoid;
+	}
+	public final Integer getCode() {
+		return code;
+	}
+	public final MifEllipsoid getEllipsoid() {
+		return ellipsoid;
+	}
+	public static MifDatum forCode(Integer code) {
+		for (MifDatum p : values()) {
+			if (p.getCode().equals(code)) {
+				return p;
+			}
+		}
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifEllipsoid.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifEllipsoid.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifEllipsoid.java	(revision 28000)
@@ -0,0 +1,42 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+public enum MifEllipsoid {
+	Airy,
+	Modified_Airy,
+	Australian_National,
+	Bessel,
+	Bessel_1841,
+	Clarke_1866,
+	Modified_Clarke_1866,
+	Clarke_1880,
+	Modified_Clarke_1880,
+	Everest,
+	Modified_Fischer_1960,
+	Helmert_1906,
+	Hough,
+	Modified_Everest,
+	GRS_67,
+	GRS_80,
+	International,
+	Krassovsky,
+	South_American_1969,
+	WGS_60,
+	WGS_66,
+	WGS_72,
+	WGS_84
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifProjection.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifProjection.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifProjection.java	(revision 28000)
@@ -0,0 +1,62 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+public enum MifProjection {
+	Albers_Equal_Area_Conic(9),
+	Azimuthal_Equidistant_polar_aspect_only(5),
+	Cylindrical_Equal_Area(2),
+	Eckert_IV(14),
+	Eckert_VI(15),
+	Equidistant_Conic_also_known_as_Simple_Conic(6),
+	Gall(17),
+	Hotine_Oblique_Mercator(7),
+	Lambert_Azimuthal_Equal_Area_polar_aspect_only(4),
+	Lambert_Conformal_Conic(3),
+	Lambert_Conformal_Conic_modified_for_Belgium_1972(19),
+	Longitude_Latitude(1),
+	Mercator(10),
+	Miller_Cylindrical(11),
+	New_Zealand_Map_Grid(18),
+	Mollweide(13),
+	Polyconic(27),
+	Regional_Mercator(26),
+	Robinson(12),
+	Sinusoidal(16),
+	Stereographic(20),
+	Swiss_Oblique_Mercator(25),
+	Transverse_Mercator_also_known_as_Gauss_Kruger(8),
+	Transverse_Mercator_modified_for_Danish_System_34_Jylland_Fyn(21),
+	Transverse_Mercator_modified_for_Sjaelland(22),
+	Transverse_Mercator_modified_for_Danish_System_45_Bornholm(23),
+	Transverse_Mercator_modified_for_Finnish_KKJ(24);
+	
+	private final Integer code;
+	private MifProjection(Integer code) {
+		this.code = code;
+	}
+	public final Integer getCode() {
+		return code;
+	}
+	public static MifProjection forCode(Integer code) {
+		for (MifProjection p : values()) {
+			if (p.getCode().equals(code)) {
+				return p;
+			}
+		}
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifReader.java	(revision 28000)
@@ -0,0 +1,491 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+import static org.openstreetmap.josm.plugins.opendata.core.io.geographic.MifDatum.Custom;
+import static org.openstreetmap.josm.plugins.opendata.core.io.geographic.MifDatum.Geodetic_Reference_System_1980_GRS_80;
+import static org.openstreetmap.josm.plugins.opendata.core.io.geographic.MifProjection.Hotine_Oblique_Mercator;
+import static org.openstreetmap.josm.plugins.opendata.core.io.geographic.MifProjection.Longitude_Latitude;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.projection.Epsg4326;
+import org.openstreetmap.josm.data.projection.Lambert93;
+import org.openstreetmap.josm.data.projection.LambertCC9Zones;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.core.util.OdUtils;
+
+/**
+ * MapInfo Interchange File (MIF) reader, based on this specification:
+ * http://www.gissky.com/Download/Download/DataFormat/Mapinfo_Mif.pdf
+ *
+ */
+public class MifReader extends AbstractMapInfoReader {
+
+	private enum State {
+		UNKNOWN,
+		READING_COLUMNS,
+		START_POLYGON,
+		READING_POINTS,
+		END_POLYGON,
+		START_POLYLINE,
+		END_POLYLINE
+	}
+
+	protected BufferedReader midReader;
+
+	private Character delimiter = '\t';
+	
+	private State state = State.UNKNOWN;
+	
+	private Projection josmProj;
+	private DataSet ds;
+	private Relation region;
+	private Way polygon;
+	private Node node;
+	private Way polyline;
+
+	// CoordSys clause
+	private MifProjection proj;
+	private MifDatum datum;
+	private String units;
+	private Double originLon;
+	private Double originLat;
+	private Double stdP1;
+	private Double stdP2;
+	private Double azimuth;
+	private Double scaleFactor;
+	private Double falseEasting;
+	private Double falseNorthing;
+	private Double range;
+	
+	// Region clause
+	private int numpolygons = -1;
+	private int numpts = -1;
+	
+	public static DataSet parseDataSet(InputStream in, File file,
+			AbstractDataSetHandler handler, ProgressMonitor instance) throws IOException {
+		return new MifReader().parse(in, file, instance, Charset.forName(ISO8859_15));
+	}
+
+	private void parseDelimiter(String[] words) {
+		delimiter = words[1].charAt(1);
+	}
+
+	private void parseUnique(String[] words) {
+		// TODO
+		System.err.println("TODO: "+line);
+	}
+
+	private void parseIndex(String[] words) {
+		// TODO
+		System.err.println("TODO: "+line);
+	}
+
+	private void parseCoordSys(String[] words) {
+		for (int i = 0; i<words.length; i++) {
+			words[i] = words[i].replace(",", "");
+		}
+		if (words[1].equalsIgnoreCase("Earth")) {
+			proj = MifProjection.forCode(Integer.parseInt(words[3]));
+			datum = MifDatum.forCode(Integer.parseInt(words[4]));
+
+			// Custom datum: TODO: use custom decalage values
+			int offset = datum == Custom ? 4 : 0;
+
+			if (proj == Longitude_Latitude) {
+				josmProj = new Epsg4326();
+				return;
+			}
+			
+			// Units
+			units = words[5+offset];
+			
+			// Origin, longitude
+			originLon = Double.parseDouble(words[6+offset]);
+			
+			// Origin, latitude
+			switch(proj) {
+			case Albers_Equal_Area_Conic:
+			case Azimuthal_Equidistant_polar_aspect_only:
+			case Equidistant_Conic_also_known_as_Simple_Conic:
+			case Hotine_Oblique_Mercator:
+			case Lambert_Azimuthal_Equal_Area_polar_aspect_only:
+			case Lambert_Conformal_Conic:
+			case Lambert_Conformal_Conic_modified_for_Belgium_1972:
+			case New_Zealand_Map_Grid:
+			case Stereographic:
+			case Swiss_Oblique_Mercator:
+			case Transverse_Mercator_also_known_as_Gauss_Kruger:
+			case Transverse_Mercator_modified_for_Danish_System_34_Jylland_Fyn:
+			case Transverse_Mercator_modified_for_Danish_System_45_Bornholm:
+			case Transverse_Mercator_modified_for_Finnish_KKJ:
+			case Transverse_Mercator_modified_for_Sjaelland:
+			case Polyconic:
+				originLat = Double.parseDouble(words[7+offset]);
+				break;
+			}
+			
+			// Standard Parallel 1
+			switch (proj) {
+			case Cylindrical_Equal_Area:
+			case Regional_Mercator:
+				stdP1 = Double.parseDouble(words[7+offset]);
+				break;
+			case Albers_Equal_Area_Conic:
+			case Equidistant_Conic_also_known_as_Simple_Conic:
+			case Lambert_Conformal_Conic:
+			case Lambert_Conformal_Conic_modified_for_Belgium_1972:
+				stdP1 = Double.parseDouble(words[8+offset]);
+				break;
+			}
+
+			// Standard Parallel 2
+			switch (proj) {
+			case Albers_Equal_Area_Conic:
+			case Equidistant_Conic_also_known_as_Simple_Conic:
+			case Lambert_Conformal_Conic:
+			case Lambert_Conformal_Conic_modified_for_Belgium_1972:
+				stdP2 = Double.parseDouble(words[9+offset]);
+				break;
+			}
+			
+			// Azimuth
+			if (proj == Hotine_Oblique_Mercator) {
+				azimuth = Double.parseDouble(words[8+offset]);
+			}
+
+			// Scale Factor
+			switch (proj) {
+			case Hotine_Oblique_Mercator:
+				scaleFactor = Double.parseDouble(words[9+offset]);
+				break;
+			case Stereographic:
+			case Transverse_Mercator_also_known_as_Gauss_Kruger:
+			case Transverse_Mercator_modified_for_Danish_System_34_Jylland_Fyn:
+			case Transverse_Mercator_modified_for_Danish_System_45_Bornholm:
+			case Transverse_Mercator_modified_for_Finnish_KKJ:
+			case Transverse_Mercator_modified_for_Sjaelland:
+				scaleFactor = Double.parseDouble(words[8+offset]);
+				break;
+			}
+			
+			// False Easting/Northing
+			switch (proj) {
+			case Albers_Equal_Area_Conic:
+			case Equidistant_Conic_also_known_as_Simple_Conic:
+			case Hotine_Oblique_Mercator:
+			case Lambert_Conformal_Conic:
+			case Lambert_Conformal_Conic_modified_for_Belgium_1972:
+				falseEasting = Double.parseDouble(words[10+offset]);
+				falseNorthing = Double.parseDouble(words[11+offset]);
+				break;
+			case Stereographic:
+			case Transverse_Mercator_also_known_as_Gauss_Kruger:
+			case Transverse_Mercator_modified_for_Danish_System_34_Jylland_Fyn:
+			case Transverse_Mercator_modified_for_Danish_System_45_Bornholm:
+			case Transverse_Mercator_modified_for_Finnish_KKJ:
+			case Transverse_Mercator_modified_for_Sjaelland:
+				falseEasting = Double.parseDouble(words[9+offset]);
+				falseNorthing = Double.parseDouble(words[10+offset]);
+				break;
+			case New_Zealand_Map_Grid:
+			case Swiss_Oblique_Mercator:
+			case Polyconic:
+				falseEasting = Double.parseDouble(words[8+offset]);
+				falseNorthing = Double.parseDouble(words[9+offset]);
+				break;
+			}
+										
+			// Range
+			switch (proj) {
+			case Azimuthal_Equidistant_polar_aspect_only:
+			case Lambert_Azimuthal_Equal_Area_polar_aspect_only:
+				range = Double.parseDouble(words[8+offset]);
+			}
+
+			switch (proj) {
+			case Lambert_Conformal_Conic:
+				if ((datum == Geodetic_Reference_System_1980_GRS_80 || datum == Custom) && equals(originLon, 3.0)) {
+					// This sounds good for Lambert 93 or Lambert CC 9
+					if (equals(originLat, 46.5) && equals(stdP1, 44.0) && equals(stdP2, 49.0) && equals(falseEasting, 700000.0) && equals(falseNorthing, 6600000.0)) {
+						josmProj = new Lambert93();
+					} else if (equals(falseEasting, 1700000.0)) {
+						for (int i=0; josmProj == null && i<9; i++) {
+							if (equals(originLat, 42.0+i) && equals(stdP1, 41.25+i) && equals(stdP2, 42.75+i) && equals(falseNorthing, (i+1)*1000000.0 + 200000.0)) {
+								josmProj = new LambertCC9Zones(i);
+							}
+						}
+					}
+				}
+				break;
+			default:
+				// TODO
+				System.err.println("TODO: "+line);
+			}
+			
+		} else if (words[1].equalsIgnoreCase("Nonearth")) {
+			// TODO
+			System.err.println("TODO: "+line);
+		} else if (words[1].equalsIgnoreCase("Layout")) {
+			// TODO
+			System.err.println("TODO: "+line);
+		} else if (words[1].equalsIgnoreCase("Table")) {
+			// TODO
+			System.err.println("TODO: "+line);
+		} else if (words[1].equalsIgnoreCase("Window")) {
+			// TODO
+			System.err.println("TODO: "+line);
+		} else {
+			System.err.println("Line "+lineNum+". Invalid CoordSys clause: "+line);
+		}
+	}
+
+	private void parseTransform(String[] words) {
+		// TODO
+		System.err.println("TODO: "+line);
+	}
+
+	@Override
+	protected void parseColumns(String[] words) {
+		super.parseColumns(words);
+		state = State.READING_COLUMNS;
+	}
+
+	private void parseData(String[] words) {
+		if (ds == null) {
+			ds = new DataSet();
+		}
+	}
+	
+	private void parsePoint(String[] words) throws IOException {
+		readAttributes(createNode(words[1], words[2]));
+	}
+
+	private void parseLine(String[] words) {
+		// TODO
+		System.err.println("TODO: "+line);
+	}
+	
+	private void parsePLine(String[] words) throws IOException {
+		if (words.length > 2) {
+			// TODO: pline with multiple sections
+			polyline = new Way();
+			ds.addPrimitive(polyline);
+			readAttributes(polyline);
+			numpts = Integer.parseInt(words[1]); // Not described in PDF but found in real files: PLINE XX, with XX = numpoints
+			state = State.READING_POINTS;
+		} else {
+			numpts = -1;
+			state = State.START_POLYLINE;
+		}
+	}
+
+	private void parseRegion(String[] words) throws IOException {
+		region = new Relation();
+		region.put("type", "multipolygon");
+		ds.addPrimitive(region);
+		readAttributes(region);
+		numpolygons = Integer.parseInt(words[1]);
+		state = State.START_POLYGON;
+	}
+
+	private void parseArc(String[] words) {
+		// TODO
+		System.err.println("TODO: "+line);
+	}
+
+	private void parseText(String[] words) {
+		// TODO
+		System.err.println("TODO: "+line);
+	}
+
+	private void parseRect(String[] words) {
+		// TODO
+		System.err.println("TODO: "+line);
+	}
+
+	private void parseRoundRect(String[] words) {
+		// TODO
+		System.err.println("TODO: "+line);
+	}
+
+	private void parseEllipse(String[] words) {
+		// TODO
+		System.err.println("TODO: "+line);
+	}
+
+	private DataSet parse(InputStream in, File file, ProgressMonitor instance, Charset charset) throws IOException {
+		try {
+			headerReader = new BufferedReader(new InputStreamReader(in, charset));
+			midReader = getDataReader(file, ".mid", charset);
+			parseHeader();
+			if (midReader != null) {
+				midReader.close();
+			}
+			return ds;
+		} catch (UnsupportedEncodingException e) {
+			throw new IOException(e);
+		}
+	}
+
+	@Override
+	protected void parseHeaderLine(String[] words) throws IOException {
+		if (words[0].equalsIgnoreCase("Version")) {
+			parseVersion(words);
+		} else if (words[0].equalsIgnoreCase("Charset")) {
+			parseCharset(words);
+		} else if (words[0].equalsIgnoreCase("Delimiter")) {
+			parseDelimiter(words);
+		} else if (words[0].equalsIgnoreCase("Unique")) {
+			parseUnique(words);
+		} else if (words[0].equalsIgnoreCase("Index")) {
+			parseIndex(words);
+		} else if (words[0].equalsIgnoreCase("CoordSys")) {
+			parseCoordSys(words);
+		} else if (words[0].equalsIgnoreCase("Transform")) {
+			parseTransform(words);
+		} else if (words[0].equalsIgnoreCase("Columns")) {
+			parseColumns(words);
+		} else if (words[0].equalsIgnoreCase("Data")) {
+			parseData(words);
+		} else if (ds != null) {
+			if (state == State.START_POLYGON) {
+				numpts = Integer.parseInt(words[0]);
+				polygon = new Way();
+				ds.addPrimitive(polygon);
+				region.addMember(new RelationMember("outer", polygon));
+				state = State.READING_POINTS;
+				
+			} else if (state == State.START_POLYLINE) {
+				numpts = Integer.parseInt(words[0]);
+				polyline = new Way();
+				ds.addPrimitive(polyline);
+				readAttributes(polyline);
+				state = State.READING_POINTS;
+				
+			} else if (state == State.READING_POINTS && numpts > 0) {
+				if (josmProj != null) {
+					node = createNode(words[0], words[1]);
+					if (polygon != null) {
+						polygon.addNode(node);
+					} else if (polyline != null) {
+						polyline.addNode(node);
+					}
+				}
+				if (--numpts == 0) {
+					if (numpolygons > -1) {
+						if (--numpolygons > 0) {
+							state = State.START_POLYGON;
+						} else {
+							state = State.END_POLYGON;
+							polygon = null;
+						}
+					} else if (polyline != null) {
+						state = State.UNKNOWN;
+						polyline = null;
+					}
+				}
+			} else if (words[0].equalsIgnoreCase("Point")) {
+				parsePoint(words);
+			} else if (words[0].equalsIgnoreCase("Line")) {
+				parseLine(words);
+			} else if (words[0].equalsIgnoreCase("PLine")) {
+				parsePLine(words);
+			} else if (words[0].equalsIgnoreCase("Region")) {
+				parseRegion(words);
+			} else if (words[0].equalsIgnoreCase("Arc")) {
+				parseArc(words);
+			} else if (words[0].equalsIgnoreCase("Text")) {
+				parseText(words);
+			} else if (words[0].equalsIgnoreCase("Rect")) {
+				parseRect(words);
+			} else if (words[0].equalsIgnoreCase("RoundRect")) {
+				parseRoundRect(words);
+			} else if (words[0].equalsIgnoreCase("Ellipse")) {
+				parseEllipse(words);
+			} else if (words[0].equalsIgnoreCase("Pen")) {
+				// Do nothing
+			} else if (words[0].equalsIgnoreCase("Brush")) {
+				// Do nothing
+			} else if (words[0].equalsIgnoreCase("Center")) {
+				// Do nothing
+			} else if (words[0].equalsIgnoreCase("Symbol")) {
+				// Do nothing
+			} else if (words[0].equalsIgnoreCase("Font")) {
+				// Do nothing
+			} else if (!words[0].isEmpty()) {
+				System.err.println("Line "+lineNum+". Unknown clause in data section: "+line);
+			}
+		} else if (state == State.READING_COLUMNS && numcolumns > 0) {
+			columns.add(words[0]);
+			if (--numcolumns == 0) {
+				state = State.UNKNOWN;
+			}
+		} else if (!line.isEmpty()) {
+			System.err.println("Line "+lineNum+". Unknown clause in header: "+line);
+		}
+	}
+	
+	protected void readAttributes(OsmPrimitive p) throws IOException {
+		if (midReader != null) { 
+			String midLine = midReader.readLine();
+			if (midLine != null) {
+				String[] fields = OdUtils.stripQuotes(midLine.split(delimiter.toString()), delimiter.toString());
+				if (columns.size() != fields.length) {
+					System.err.println("Error: Incoherence between MID and MIF files ("+columns.size()+" columns vs "+fields.length+" fields)");
+				}
+				for (int i=0; i<Math.min(columns.size(), fields.length); i++) {
+					String field = fields[i].trim();
+					/*if (field.startsWith("\"") && field.endsWith("\"")) {
+						field = fields[i].substring(fields[i].indexOf('"')+1, fields[i].lastIndexOf('"'));
+					}*/
+					if (!field.isEmpty()) {
+						p.put(columns.get(i), field);
+					}
+				}
+			}
+		}
+	}
+	
+	protected final Node createNode(String x, String y) {
+		Node node = new Node(josmProj.eastNorth2latlon(new EastNorth(Double.parseDouble(x), Double.parseDouble(y))));
+		ds.addPrimitive(node);
+		return node;
+	}
+	
+	/** Compare two doubles within a default epsilon */
+	public static boolean equals(Double a, Double b) {
+		if (a==b) return true;
+		// If the difference is less than epsilon, treat as equal.
+		return Math.abs(a - b) < 0.0000001;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifTabImporter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifTabImporter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifTabImporter.java	(revision 28000)
@@ -0,0 +1,45 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.plugins.opendata.core.io.AbstractImporter;
+
+public class MifTabImporter extends AbstractImporter {
+	
+    public MifTabImporter() {
+        super(MIF_TAB_FILE_FILTER);
+    }
+
+	@Override
+	protected DataSet parseDataSet(InputStream in, ProgressMonitor instance)
+			throws IllegalDataException {
+		try {
+			if (file.getName().toLowerCase().endsWith(MIF_EXT)) {
+				return MifReader.parseDataSet(in, file, handler, instance);
+			} else {
+				return TabReader.parseDataSet(in, file, handler, instance);
+			}
+		} catch (IOException e) {
+			throw new IllegalDataException(e);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifUnit.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifUnit.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifUnit.java	(revision 28000)
@@ -0,0 +1,48 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+public enum MifUnit {
+	Centimeters(6),
+	Chains(31),
+	Feet(3),
+	Inches(2),
+	Kilometers(1),
+	Links(30),
+	Meters(7),
+	Miles(0),
+	Millimeters(5),
+	Nautical_Miles(9),
+	Rods(32),
+	US_Survey_Feet(8),
+	Yards(4);
+		
+	private final Integer code;
+	private MifUnit(Integer code) {
+		this.code = code;
+	}
+	public final Integer getCode() {
+		return code;
+	}
+	public static MifUnit forCode(Integer code) {
+		for (MifUnit p : values()) {
+			if (p.getCode().equals(code)) {
+				return p;
+			}
+		}
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpImporter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpImporter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpImporter.java	(revision 28000)
@@ -0,0 +1,41 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.plugins.opendata.core.io.AbstractImporter;
+
+public class ShpImporter extends AbstractImporter {
+	
+    public ShpImporter() {
+        super(SHP_FILE_FILTER);
+    }
+
+	@Override
+	protected DataSet parseDataSet(InputStream in, ProgressMonitor instance)
+			throws IllegalDataException {
+		try {
+			return ShpReader.parseDataSet(in, file, handler, instance);
+		} catch (IOException e) {
+			throw new IllegalDataException(e);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpReader.java	(revision 28000)
@@ -0,0 +1,416 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Component;
+import java.awt.Image;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JOptionPane;
+
+import org.geotools.data.FeatureSource;
+import org.geotools.data.FileDataStore;
+import org.geotools.data.FileDataStoreFinder;
+import org.geotools.factory.Hints;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.geometry.jts.JTS;
+import org.geotools.referencing.AbstractIdentifiedObject;
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.crs.AbstractCRS;
+import org.geotools.referencing.crs.AbstractDerivedCRS;
+import org.geotools.referencing.crs.AbstractSingleCRS;
+import org.opengis.feature.Feature;
+import org.opengis.feature.GeometryAttribute;
+import org.opengis.feature.Property;
+import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.feature.type.Name;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.datum.Datum;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.OperationNotFoundException;
+import org.opengis.referencing.operation.TransformException;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.gui.ExtendedDialog;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.AbstractReader;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+
+public class ShpReader extends AbstractReader implements OdConstants {
+
+	private final AbstractDataSetHandler handler;
+	
+	private final CoordinateReferenceSystem wgs84;
+	private final Map<String, Node> nodes;
+
+	private DataSet result;
+	private CoordinateReferenceSystem crs;
+	private MathTransform transform;
+	
+	public ShpReader(AbstractDataSetHandler handler) throws NoSuchAuthorityCodeException, FactoryException {
+		this.handler = handler;
+		this.wgs84 = CRS.decode("EPSG:4326");
+		this.nodes = new HashMap<String, Node>();
+	}
+
+	public static DataSet parseDataSet(InputStream in, File file,
+			AbstractDataSetHandler handler, ProgressMonitor instance) throws IOException {
+		if (in != null) {
+			in.close();
+		}
+		try {
+			return new ShpReader(handler).parse(file, instance);
+		} catch (IOException e) {
+			throw e;
+		} catch (Throwable t) {
+			throw new IOException(t);
+		}
+	}
+	
+	private static final void compareDebug(CoordinateReferenceSystem crs1, CoordinateReferenceSystem crs2) {
+		System.out.println("-- COMPARING "+crs1.getName()+" WITH "+crs2.getName()+" --");
+		compareDebug("class", crs1.getClass(), crs2.getClass());
+		CoordinateSystem cs1 = crs1.getCoordinateSystem();
+		CoordinateSystem cs2 = crs2.getCoordinateSystem();
+		if (!compareDebug("cs", cs1, cs2)) {
+			Integer dim1 = cs1.getDimension();
+			Integer dim2 = cs2.getDimension();
+			if (compareDebug("cs.dim", dim1, dim2)) {
+				for (int i = 0; i<dim1; i++) {
+					compareDebug("cs.axis"+i, cs1.getAxis(i), cs1.getAxis(i));
+				}
+			}
+		}
+		if (crs1 instanceof AbstractSingleCRS) {
+			Datum datum1 = ((AbstractSingleCRS) crs1).getDatum();
+			Datum datum2 = ((AbstractSingleCRS) crs2).getDatum();
+			if (!compareDebug("datum", datum1, datum2)) {
+				AbstractIdentifiedObject adatum1 = (AbstractIdentifiedObject) datum1;
+				AbstractIdentifiedObject adatum2 = (AbstractIdentifiedObject) datum2;
+				compareDebug("datum.name1", adatum1.nameMatches(adatum2.getName().getCode()), adatum1.getName(), adatum2.getName());
+				compareDebug("datum.name2", adatum2.nameMatches(adatum1.getName().getCode()), adatum2.getName(), adatum1.getName());
+			}
+			if (crs1 instanceof AbstractDerivedCRS) {
+				AbstractDerivedCRS adcrs1 = (AbstractDerivedCRS) crs1;
+				AbstractDerivedCRS adcrs2 = (AbstractDerivedCRS) crs2;
+				compareDebug("baseCRS", adcrs1.getBaseCRS(), adcrs2.getBaseCRS());
+				compareDebug("conversionFromBase", adcrs1.getConversionFromBase(), adcrs2.getConversionFromBase());
+			}
+		}
+		System.out.println("-- COMPARING FINISHED --");
+	}
+	
+	private static final boolean compareDebug(String text, Object o1, Object o2) {
+		return compareDebug(text, o1.equals(o2), o1, o2);
+	}
+	
+	private static final boolean compareDebug(String text, IdentifiedObject o1, IdentifiedObject o2) {
+		return compareDebug(text, (AbstractIdentifiedObject)o1, (AbstractIdentifiedObject)o2);
+	}
+	
+	private static final boolean compareDebug(String text, AbstractIdentifiedObject o1, AbstractIdentifiedObject o2) {
+		return compareDebug(text, o1.equals(o2, false), o1, o2);
+	}
+
+	private static final boolean compareDebug(String text, boolean result, Object o1, Object o2) {
+		System.out.println(text + ": " + result + "("+o1+", "+o2+")");
+		return result;
+	}
+
+	public DataSet parse(File file, ProgressMonitor instance) throws IOException {
+		result = null;
+		crs = null;
+		transform = null;
+		try {
+			if (file != null) { 
+				FileDataStore dataStore = FileDataStoreFinder.getDataStore(file);
+				if (dataStore == null) {
+					throw new IOException(tr("Unable to find a data store for file {0}", file.getName()));
+				}
+				
+				String[] typeNames = dataStore.getTypeNames();
+				String typeName = typeNames[0];
+	
+				FeatureSource<?,?> featureSource = dataStore.getFeatureSource(typeName);
+				FeatureCollection<?,?> collection = featureSource.getFeatures();
+				FeatureIterator<?> iterator = collection.features();
+					
+				result = new DataSet();
+				
+				try {
+					while (iterator.hasNext()) {
+						Feature feature = iterator.next();
+						GeometryAttribute geometry = feature.getDefaultGeometryProperty();
+						if (geometry != null) {
+
+							GeometryDescriptor desc = geometry.getDescriptor();
+							
+							if (crs == null && desc != null && desc.getCoordinateReferenceSystem() != null) {
+								crs = desc.getCoordinateReferenceSystem();
+								try {
+									transform = CRS.findMathTransform(crs, wgs84);
+								} catch (OperationNotFoundException e) {
+									System.out.println(crs.getName()+": "+e.getMessage()); // Bursa wolf parameters required.
+									
+									List<CoordinateReferenceSystem> candidates = new ArrayList<CoordinateReferenceSystem>();
+									
+									// Find matching CRS with Bursa Wolf parameters in EPSG database
+									for (String code : CRS.getAuthorityFactory(false).getAuthorityCodes(ProjectedCRS.class)) {
+										CoordinateReferenceSystem candidate = CRS.decode(code);
+										if (candidate instanceof AbstractCRS && crs instanceof AbstractIdentifiedObject) {
+											
+											Hints.putSystemDefault(Hints.COMPARISON_TOLERANCE, 
+													Main.pref.getDouble(PREF_CRS_COMPARISON_TOLERANCE, DEFAULT_CRS_COMPARISON_TOLERANCE));
+											if (((AbstractCRS)candidate).equals((AbstractIdentifiedObject)crs, false)) {
+												System.out.println("Found a potential CRS: "+candidate.getName());
+												candidates.add(candidate);
+											} else if (Main.pref.getBoolean(PREF_CRS_COMPARISON_DEBUG, false)) {
+												compareDebug(crs, candidate);
+											}
+											Hints.removeSystemDefault(Hints.COMPARISON_TOLERANCE);
+										}
+									}
+									
+									if (candidates.size() > 1) {
+										System.err.println("Found several potential CRS.");//TODO: ask user which one to use
+									}
+									
+									if (candidates.size() > 0) {
+										CoordinateReferenceSystem newCRS = candidates.get(0);
+										try {
+											transform = CRS.findMathTransform(newCRS, wgs84, false);
+										} catch (OperationNotFoundException ex) {
+											System.err.println(newCRS.getName()+": "+e.getMessage());
+										}
+									}
+									
+									if (transform == null) {
+										if (handler != null) {
+											// ask handler if it can provide a math transform
+											transform = handler.findMathTransform(crs, wgs84, false);
+										}
+										if (transform == null) {
+											// ask user before trying lenient method
+											if (warnLenientMethod(instance.getWindowParent(), crs)) {
+												// User canceled
+												return result;
+											}
+											System.out.println("Searching for a lenient math transform.");
+											transform = CRS.findMathTransform(crs, wgs84, true);
+										}
+									}
+								}
+								if (transform == null) {
+									System.err.println("Unable to find math transform !");
+									// TODO: something
+									return result;
+								}
+							} else if (crs == null) {
+								System.err.println("Unable to detect CRS !");
+								// TODO: ask projection
+								return result;
+							}
+							
+							OsmPrimitive primitive = null;
+							
+							if (geometry.getValue() instanceof Point) {
+								primitive = createOrGetNode((Point) geometry.getValue());
+								
+							} else if (geometry.getValue() instanceof GeometryCollection) { // Deals with both MultiLineString and MultiPolygon
+								GeometryCollection mp = (GeometryCollection) geometry.getValue();
+								int nGeometries = mp.getNumGeometries(); 
+								if (nGeometries < 1) {
+									System.err.println("Error: empty geometry collection found");
+								} else {
+									Relation r = null;
+									Way w = null;
+									
+									for (int i=0; i<nGeometries; i++) {
+										Geometry g = mp.getGeometryN(i);
+										if (g instanceof Polygon) {
+											Polygon p = (Polygon) g;
+											// Do not create relation if there's only one polygon without interior ring
+											// except if handler prefers it
+											if (r == null && (nGeometries > 1 || p.getNumInteriorRing() > 0 || (handler != null && handler.preferMultipolygonToSimpleWay()))) {
+												r = createMultipolygon();
+											}
+											w = createWay(p.getExteriorRing());
+											if (r != null) {
+												addWayToMp(r, "outer", w);
+												for (int j=0; j<p.getNumInteriorRing(); j++) {
+													addWayToMp(r, "inner", createWay(p.getInteriorRingN(j)));
+												}
+											}
+										} else if (g instanceof LineString) {
+											w = createWay((LineString) g);
+										} else if (g instanceof Point) {
+											// Some belgian data sets hold points into collections ?!
+											readNonGeometricAttributes(feature, createOrGetNode((Point) g));
+										} else {
+											System.err.println("Error: unsupported geometry : "+g);
+										}
+									}
+									primitive = r != null ? r : w;
+								}
+							} else {
+								// Debug unknown geometry
+								System.out.println("\ttype: "+geometry.getType());
+								System.out.println("\tbounds: "+geometry.getBounds());
+								System.out.println("\tdescriptor: "+desc);
+								System.out.println("\tname: "+geometry.getName());
+								System.out.println("\tvalue: "+geometry.getValue());
+								System.out.println("\tid: "+geometry.getIdentifier());
+								System.out.println("-------------------------------------------------------------");
+							}
+							
+							if (primitive != null) {
+								// Read primitive non geometric attributes
+								readNonGeometricAttributes(feature, primitive);
+							}
+						}
+					}
+				} finally {
+					iterator.close();
+					nodes.clear();
+				}
+			}
+		} catch (IOException e) {
+			throw e;
+		} catch (Throwable t) {
+			throw new IOException(t);
+		}
+		return result;
+	}
+	
+    /**
+     * returns true if the user wants to cancel, false if they
+     * want to continue
+     */
+    private static final boolean warnLenientMethod(Component parent, CoordinateReferenceSystem crs) {
+        ExtendedDialog dlg = new ExtendedDialog(parent,
+                tr("Cannot transform to WGS84"),
+                new String[] {tr("Cancel"), tr("Continue")});
+        dlg.setContent("<html>" +
+                tr("JOSM was unable to find a strict mathematical transformation between ''{0}'' and WGS84.<br /><br />"+
+                        "Do you want to try a <i>lenient</i> method, which will perform a non-precise transformation (<b>with location errors up to 1 km</b>) ?<br/><br/>"+
+                        "If so, <b>do NOT upload</b> such data to OSM !", crs.getName())+
+                "</html>");
+        dlg.setButtonIcons(new Icon[] {
+                ImageProvider.get("cancel"),
+                ImageProvider.overlay(
+                        ImageProvider.get("ok"),
+                        new ImageIcon(ImageProvider.get("warning-small").getImage().getScaledInstance(10 , 10, Image.SCALE_SMOOTH)),
+                        ImageProvider.OverlayPosition.SOUTHEAST)});
+        dlg.setToolTipTexts(new String[] {
+                tr("Cancel"),
+                tr("Try lenient method")});
+        dlg.setIcon(JOptionPane.WARNING_MESSAGE);
+        dlg.setCancelButton(1);
+        return dlg.showDialog().getValue() != 2;
+    }
+	
+	private static final void readNonGeometricAttributes(Feature feature, OsmPrimitive primitive) {
+		for (Property prop : feature.getProperties()) {
+			if (!(prop instanceof GeometryAttribute)) {
+				Name name = prop.getName();
+				Object value = prop.getValue();
+				if (name != null && value != null) {
+					String sName = name.toString();
+					String sValue = value.toString();
+					if (!sName.isEmpty() && !sValue.isEmpty()) {
+						primitive.put(sName, sValue);
+					}
+				}
+			}
+		}
+	}
+	
+	private Node createOrGetNode(Point p) throws MismatchedDimensionException, TransformException {
+		if (transform != null) {
+			Point p2 = (Point) JTS.transform(p, transform);
+			String key = p2.getX()+"/"+p2.getY();
+			Node n = nodes.get(key);
+			if (n == null) {
+				nodes.put(key, n = new Node(new LatLon(p2.getY(), p2.getX())));
+				result.addPrimitive(n);
+			}
+			return n;
+		} else {
+			EastNorth en = new EastNorth(p.getX(), p.getY());
+			// TODO: something to transform coordinates
+			return new Node(en);
+		}
+	}
+	
+	private Way createWay(LineString ls) {
+		Way w = new Way();
+		if (ls != null) {
+			for (int i=0; i<ls.getNumPoints(); i++) {
+				try {
+					w.addNode(createOrGetNode(ls.getPointN(i)));
+				} catch (Exception e) {
+					System.err.println(e.getMessage());
+				}
+			}
+		}
+		result.addPrimitive(w);
+		return w;
+	}
+
+	private Relation createMultipolygon() {
+		Relation r = new Relation();
+		r.put("type", "multipolygon");
+		result.addPrimitive(r);
+		return r;
+	}
+
+	private void addWayToMp(Relation r, String role, Way w) {
+		//result.addPrimitive(w);
+		r.addMember(new RelationMember(role, w));
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/TabReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/TabReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/TabReader.java	(revision 28000)
@@ -0,0 +1,154 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.geotools.data.DataUtilities;
+import org.geotools.data.shapefile.ShpFileType;
+import org.geotools.data.shapefile.ShpFiles;
+import org.geotools.data.shapefile.dbf.DbaseFileReader;
+import org.geotools.data.shapefile.dbf.DbaseFileReader.Row;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.core.io.tabular.SpreadSheetReader;
+
+/**
+ * MapInfo TAB reader
+ *
+ */
+public class TabReader extends AbstractMapInfoReader {
+
+	private Charset datCharset;
+	private final AbstractDataSetHandler handler;
+	
+	public TabReader(AbstractDataSetHandler handler) {
+		this.handler = handler;
+	}
+
+	public static DataSet parseDataSet(InputStream in, File file,
+			AbstractDataSetHandler handler, ProgressMonitor instance) throws IOException {
+		return new TabReader(handler).parse(in, file, instance, Charset.forName(ISO8859_15));
+	}
+	
+	private class TabFiles extends ShpFiles {
+		public TabFiles(File headerFile, File dataFile) throws IllegalArgumentException {
+			super(DataUtilities.fileToURL(headerFile));
+			urls.put(ShpFileType.DBF, DataUtilities.fileToURL(dataFile));
+		}
+		
+		@Override
+	    protected String baseName(Object obj) {
+            if (obj instanceof URL) {
+                return toBase(((URL) obj).toExternalForm());
+            }
+            return null;
+	    }
+	    
+	    private String toBase(String path) {
+	        return path.substring(0, path.toLowerCase().lastIndexOf(".tab"));
+	    }
+	}
+	
+	private class TabOsmReader extends SpreadSheetReader {
+
+		private final DbaseFileReader dbfReader;
+		public TabOsmReader(AbstractDataSetHandler handler, TabFiles tabFiles) throws IOException {
+			super(handler);
+			this.dbfReader = new DbaseFileReader(tabFiles, false, datCharset, null);
+		}
+
+		@Override
+		protected void initResources(InputStream in,
+				ProgressMonitor progressMonitor) throws IOException {
+		}
+
+		@Override
+		protected String[] readLine(ProgressMonitor progressMonitor)
+				throws IOException {
+			if (!dbfReader.hasNext()) {
+				return null;
+			}
+        	List<String> result = new ArrayList<String>();
+			Row row = dbfReader.readRow();
+        	for (int i=0; i<columns.size(); i++) {
+        		Object o = row.read(i);
+        		if (o != null) {
+        			result.add(o.toString());
+        		} else {
+        			result.add("");
+        		}
+        	}
+        	return result.toArray(new String[0]);
+		}
+	}
+
+	private DataSet parse(InputStream in, File file, ProgressMonitor instance, Charset charset) throws IOException {
+		headerReader = new BufferedReader(new InputStreamReader(in, charset));
+		parseHeader();
+        try {
+        	File dataFile = getDataFile(file, ".dat");
+        	ds.mergeFrom(new TabOsmReader(handler, new TabFiles(file, dataFile)).
+        			doParse(columns.toArray(new String[0]), instance));
+        } catch (IOException e) {
+        	System.err.println(e.getMessage());
+        }
+		return ds;
+	}
+
+	@Override
+	protected void parseHeaderLine(String[] words) throws IOException {
+		if (words[0].equalsIgnoreCase("!table")) {
+			// Do nothing
+		} else if (words[0].equalsIgnoreCase("!version")) {
+			parseVersion(words);
+		} else if (words[0].equalsIgnoreCase("!charset")) {
+			parseCharset(words);
+		} else if (numcolumns > 0) {
+			parseField(words);
+		} else if (words[0].equalsIgnoreCase("Definition")) {
+			// Do nothing
+		} else if (words[0].equalsIgnoreCase("Type")) {
+			parseType(words);
+		} else if (words[0].equalsIgnoreCase("Fields")) {
+			parseColumns(words);
+		} else if (!line.isEmpty()) {
+			System.err.println("Line "+lineNum+". Unknown clause in header: "+line);
+		}
+	}
+
+	private void parseField(String[] words) {
+		columns.add(words[0]);
+		--numcolumns;
+	}
+
+	private void parseType(String[] words) {
+		if (words[1].equalsIgnoreCase("NATIVE") && words[2].equalsIgnoreCase("Charset")) {
+			datCharset = parseCharset(words, 3);
+		} else {
+			System.err.println("Line "+lineNum+". Unknown Type clause in header: "+line);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/CsvImporter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/CsvImporter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/CsvImporter.java	(revision 28000)
@@ -0,0 +1,41 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.tabular;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.plugins.opendata.core.io.AbstractImporter;
+
+public class CsvImporter extends AbstractImporter {
+	
+    public CsvImporter() {
+        super(CSV_FILE_FILTER);
+    }
+
+	@Override
+	protected DataSet parseDataSet(InputStream in, ProgressMonitor instance)
+			throws IllegalDataException {
+		try {
+			return CsvReader.parseDataSet(in, handler, instance);
+		} catch (IOException e) {
+			throw new IllegalDataException(e);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/CsvReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/CsvReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/CsvReader.java	(revision 28000)
@@ -0,0 +1,63 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.tabular;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.core.util.OdUtils;
+
+public class CsvReader extends SpreadSheetReader {
+
+	private final Charset charset;
+	private final String sep;
+	
+	private BufferedReader reader;
+	private String line;
+	
+	public CsvReader(AbstractDataSetHandler handler) {
+		super(handler);
+		this.charset = handler != null && handler.getCsvCharset() != null ? handler.getCsvCharset() : Charset.forName(UTF8);
+		this.sep = handler != null && handler.getCsvSeparator() != null ? handler.getCsvSeparator() : ";";
+	}
+	
+	public static DataSet parseDataSet(InputStream in, AbstractDataSetHandler handler, ProgressMonitor instance) throws IOException {
+		return new CsvReader(handler).parse(in, instance);
+	}
+
+	@Override
+	protected void initResources(InputStream in, ProgressMonitor progressMonitor) throws IOException {
+		System.out.println("Parsing CSV file using charset "+charset+" and separator '"+sep+"'");
+
+		reader = new BufferedReader(new InputStreamReader(in, charset));
+	}
+
+	@Override
+	protected String[] readLine(ProgressMonitor progressMonitor) throws IOException {
+		line = reader.readLine();
+		if (line != null) {
+			return OdUtils.stripQuotes(line.split(sep), sep);
+		} else {
+			return null;
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/OdsDocument.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/OdsDocument.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/OdsDocument.java	(revision 28000)
@@ -0,0 +1,73 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.tabular;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.jopendocument.io.SaxContentUnmarshaller;
+import org.jopendocument.model.OpenDocument;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+public class OdsDocument extends OpenDocument implements OdConstants {
+
+	public OdsDocument(InputStream in) {
+		loadFrom(in);
+	}
+	
+	private InputSource getEntryInputSource(ZipInputStream zis) throws IOException {
+        int n = -1;
+		final byte[] buffer = new byte[4096];
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        while ((n = zis.read(buffer, 0, buffer.length)) != -1) {
+        	baos.write(buffer, 0, n);
+        }
+		return new InputSource(new ByteArrayInputStream(baos.toByteArray()));
+	}
+
+    public void loadFrom(final InputStream in) {
+        final SaxContentUnmarshaller contentHandler = new SaxContentUnmarshaller();
+
+        try {
+            final ZipInputStream zis = new ZipInputStream(in);
+            final XMLReader rdr = XMLReaderFactory.createXMLReader();
+            
+            ZipEntry entry = null;
+            boolean contentParsed = false;
+            
+            while (!contentParsed && (entry = zis.getNextEntry()) != null) {
+            	if (entry.getName().equals("content.xml")) {
+                    rdr.setContentHandler(contentHandler);
+                    System.out.println("Parsing content.xml");
+                    rdr.parse(getEntryInputSource(zis));
+            		contentParsed = true;
+            	}
+            }
+            
+        } catch (final Exception e) {
+            e.printStackTrace();
+        }
+        
+        init(contentHandler.getBody());
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/OdsImporter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/OdsImporter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/OdsImporter.java	(revision 28000)
@@ -0,0 +1,41 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.tabular;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.plugins.opendata.core.io.AbstractImporter;
+
+public class OdsImporter extends AbstractImporter {
+	
+    public OdsImporter() {
+        super(ODS_FILE_FILTER);
+    }
+
+	@Override
+	protected DataSet parseDataSet(InputStream in, ProgressMonitor instance)
+			throws IllegalDataException {
+		try {
+			return OdsReader.parseDataSet(in, handler, instance);
+		} catch (IOException e) {
+			throw new IllegalDataException(e);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/OdsReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/OdsReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/OdsReader.java	(revision 28000)
@@ -0,0 +1,92 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.tabular;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jopendocument.model.OpenDocument;
+import org.jopendocument.model.office.OfficeSpreadsheet;
+import org.jopendocument.model.table.TableTable;
+import org.jopendocument.model.table.TableTableRow;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+
+public class OdsReader extends SpreadSheetReader {
+
+	private OpenDocument doc;
+	private TableTable sheet;
+	private List<TableTableRow> rows;
+	private int rowIndex;
+	
+	private static final String SEP = "TextP:\\[";
+	
+	public OdsReader(AbstractDataSetHandler handler) {
+		super(handler);
+	}
+
+	public static DataSet parseDataSet(InputStream in,
+			AbstractDataSetHandler handler, ProgressMonitor instance) throws IOException {
+		return new OdsReader(handler).parse(in, instance);
+	}
+
+	@Override
+	protected void initResources(InputStream in, ProgressMonitor progressMonitor) throws IOException {
+		try {
+			System.out.println("Parsing ODS file");
+			doc = new OdsDocument(in);
+			List<OfficeSpreadsheet> spreadsheets = doc.getBody().getOfficeSpreadsheets();
+			if (spreadsheets != null && spreadsheets.size() > 0) {
+				List<TableTable> tables = spreadsheets.get(0).getTables();
+				if (tables != null && tables.size() > 0) {
+					sheet = tables.get(getSheetNumber());
+					if (sheet != null) {
+						rows = sheet.getRows();
+					}
+				}
+			}
+			rowIndex = 0;
+		} catch (Exception e) {
+			throw new IOException(e);
+		}
+	}
+
+	@Override
+	protected String[] readLine(ProgressMonitor progressMonitor) throws IOException {
+		if (rows != null && rowIndex < rows.size()) {
+			TableTableRow row = rows.get(rowIndex++);
+
+			if (rowIndex % 5000 == 0) {
+				System.out.println("Lines read: "+rowIndex);
+			}
+
+			List<String> result = new ArrayList<String>();
+			boolean allFieldsBlank = true;
+			for (String text : row.getText().replaceFirst(SEP, "").replaceAll("\\]", "").replaceAll("null", SEP).split(SEP)) {
+				result.add(text);
+				if (allFieldsBlank && !text.isEmpty()) {
+					allFieldsBlank = false;
+				}
+			}
+			
+			return rowIndex == 1 || !allFieldsBlank ? result.toArray(new String[0]) : null;
+		}
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/SpreadSheetReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/SpreadSheetReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/SpreadSheetReader.java	(revision 28000)
@@ -0,0 +1,201 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.tabular;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.projection.LambertCC9Zones;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.AbstractReader;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.core.io.ProjectionChooser;
+import org.openstreetmap.josm.plugins.opendata.core.io.ProjectionPatterns;
+
+public abstract class SpreadSheetReader extends AbstractReader implements OdConstants {
+	
+	private static final NumberFormat formatFrance = NumberFormat.getInstance(Locale.FRANCE);
+	private static final NumberFormat formatUK = NumberFormat.getInstance(Locale.UK);
+	
+	protected static final LambertCC9Zones[] projLambCC9Zones = new LambertCC9Zones[9];
+	static {
+		for (int i=0; i<projLambCC9Zones.length; i++) {
+			projLambCC9Zones[i] = new LambertCC9Zones(i);
+		}
+	}
+
+	protected final AbstractDataSetHandler handler;
+
+	public SpreadSheetReader(AbstractDataSetHandler handler) {
+		this.handler = handler;
+	}
+
+	protected static double parseDouble(String value) throws ParseException {
+		if (value.contains(",")) { 
+			return formatFrance.parse(value.replace(" ", "")).doubleValue();
+		} else {
+			return formatUK.parse(value.replace(" ", "")).doubleValue();
+		}
+	}
+	
+	protected abstract void initResources(InputStream in, ProgressMonitor progressMonitor) throws IOException;
+	
+	protected abstract String[] readLine(ProgressMonitor progressMonitor) throws IOException;
+	
+	protected final int getSheetNumber() {
+		return handler != null && handler.getSheetNumber() > -1 ? handler.getSheetNumber() : 0;
+	}
+	
+	private class CoordinateColumns {
+		public int xCol = -1;
+		public int yCol = -1;
+		public final boolean isOk() {
+			return xCol > -1 && yCol > -1;
+		}
+	}
+	
+	public DataSet doParse(String[] header, ProgressMonitor progressMonitor) throws IOException {
+		System.out.println("Header: "+Arrays.toString(header));
+		
+		Map<ProjectionPatterns, CoordinateColumns> projColumns = new HashMap<ProjectionPatterns, CoordinateColumns>();
+		
+		// TODO: faire une liste de coordonnees pour les cas ou plusieurs coordonnées dans la meme projection sont présentes (ex assainissement) 
+		for (int i = 0; i<header.length; i++) {
+			for (ProjectionPatterns pp : PROJECTIONS) {
+				CoordinateColumns col = projColumns.get(pp);
+				if (pp.getXPattern().matcher(header[i]).matches()) {
+					if (col == null) {
+						projColumns.put(pp, col = new CoordinateColumns());
+					}
+					col.xCol = i;
+				} else if (pp.getYPattern().matcher(header[i]).matches()) {
+					if (col == null) {
+						projColumns.put(pp, col = new CoordinateColumns());
+					}
+					col.yCol = i;
+				}
+			}
+		}
+
+		Projection proj = null;
+		CoordinateColumns columns = null;
+		Collection<Integer> allProjIndexes = new ArrayList<Integer>();
+		
+		for (ProjectionPatterns pp : projColumns.keySet()) {
+			CoordinateColumns col = projColumns.get(pp);
+			if (col.isOk()) {
+				if (proj == null) {
+					proj = pp.getProjection(header[col.xCol], header[col.yCol]);
+					columns = col;
+				}
+				allProjIndexes.add(col.xCol);
+				allProjIndexes.add(col.yCol);
+			}
+		}
+
+		final boolean handlerOK = handler != null && handler.handlesSpreadSheetProjection();
+
+		if (proj != null) {
+			// projection identified, do nothing
+		} else if (columns != null) {
+			if (!handlerOK) {
+				// TODO: filter proposed projections with min/max values ?
+				ProjectionChooser dialog = (ProjectionChooser) new ProjectionChooser(progressMonitor.getWindowParent()).showDialog();
+				if (dialog.getValue() != 1) {
+					return null; // User clicked Cancel
+				}
+				proj = dialog.getProjection();
+			}
+			
+		} else {
+			throw new IllegalArgumentException(tr("No valid coordinates have been found."));
+		}
+
+		System.out.println("Loading data using projection "+proj+" ("+header[columns.xCol]+", "+header[columns.yCol]+")");
+				
+		final DataSet ds = new DataSet();
+		int lineNumber = 1;
+		
+		String[] fields;
+		while ((fields = readLine(progressMonitor)) != null) {
+			lineNumber++;
+			EastNorth en = new EastNorth(Double.NaN, Double.NaN);
+			Node n = new Node();
+			for (int i = 0; i<fields.length; i++) {
+				try {
+					if (i >= header.length) {
+						throw new IllegalArgumentException(tr("Invalid file. Bad length on line {0}. Expected {1} columns, got {2}.", lineNumber, header.length, i+1));
+					} else if (i == columns.xCol) {
+						en.setLocation(parseDouble(fields[i]), en.north());
+					} else if (i == columns.yCol) {
+						en.setLocation(en.east(), parseDouble(fields[i]));
+					} else if (!allProjIndexes.contains(i)) {
+						if (!fields[i].isEmpty()) {
+							n.put(header[i], fields[i]);
+						}
+					}
+				} catch (ParseException e) {
+					System.err.println("Warning: Parsing error on line "+lineNumber+": "+e.getMessage());
+				}
+			}
+			if (en.isValid()) {
+				n.setCoor(proj != null && !handlerOK ? proj.eastNorth2latlon(en) : handler.getSpreadSheetCoor(en, fields));
+			} else {
+				System.err.println("Warning: Skipping line "+lineNumber+" because no valid coordinates have been found.");
+			}
+			if (n.getCoor() != null) {
+				ds.addPrimitive(n);
+			}
+		}
+		
+		return ds;
+	}
+	
+	public final DataSet parse(InputStream in, ProgressMonitor progressMonitor) throws IOException {
+		
+		initResources(in, progressMonitor);
+		
+		String[] header = null;
+		int length = 0;
+		
+		while (header == null || length == 0) {
+			header = readLine(progressMonitor);
+			length = 0;
+			if (header == null) {
+				return null;
+			} else for (String field : header) {
+				length += field.length();
+			}
+		}
+		
+		return doParse(header, progressMonitor);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/XlsImporter.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/XlsImporter.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/XlsImporter.java	(revision 28000)
@@ -0,0 +1,41 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.tabular;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.plugins.opendata.core.io.AbstractImporter;
+
+public class XlsImporter extends AbstractImporter {
+	
+    public XlsImporter() {
+        super(XLS_FILE_FILTER);
+    }
+
+	@Override
+	protected DataSet parseDataSet(InputStream in, ProgressMonitor instance)
+			throws IllegalDataException {
+		try {
+			return XlsReader.parseDataSet(in, handler, instance);
+		} catch (IOException e) {
+			throw new IllegalDataException(e);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/XlsReader.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/XlsReader.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/tabular/XlsReader.java	(revision 28000)
@@ -0,0 +1,100 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.io.tabular;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.DateUtil;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+
+public class XlsReader extends SpreadSheetReader {
+
+	private Workbook wb;
+	private Sheet sheet;
+	private int rowIndex;
+	
+	public XlsReader(AbstractDataSetHandler handler) {
+		super(handler);
+	}
+
+	public static DataSet parseDataSet(InputStream in,
+			AbstractDataSetHandler handler, ProgressMonitor instance) throws IOException {
+		return new XlsReader(handler).parse(in, instance);
+	}
+
+	@Override
+	protected void initResources(InputStream in, ProgressMonitor progressMonitor) throws IOException {
+		System.out.println("Parsing XLS file");
+		try {
+			wb = new HSSFWorkbook(new POIFSFileSystem(in));
+			sheet = wb.getSheetAt(getSheetNumber());
+			rowIndex = 0;
+		} catch (ExceptionInInitializerError e) {
+			Throwable ex = e.getException();
+			if (ex != null && ex.getMessage() != null) {
+				System.err.println(ex.getClass()+": "+ex.getMessage());
+			}
+			throw new IOException(e);
+	    } catch (Throwable t) {
+			throw new IOException(t);
+		}
+	}
+
+	@Override
+	protected String[] readLine(ProgressMonitor progressMonitor) throws IOException {
+		if (sheet != null) {
+			Row row = sheet.getRow(rowIndex++);
+			if (row != null) {
+				List<String> result = new ArrayList<String>();
+				for (Cell cell : row) {
+		            switch (cell.getCellType()) {
+		                case Cell.CELL_TYPE_STRING:
+		                    result.add(cell.getRichStringCellValue().getString());
+		                    break;
+		                case Cell.CELL_TYPE_NUMERIC:
+		                    if (DateUtil.isCellDateFormatted(cell)) {
+		                    	result.add(cell.getDateCellValue().toString());
+		                    } else {
+		                    	result.add(Double.toString(cell.getNumericCellValue()));
+		                    }
+		                    break;
+		                case Cell.CELL_TYPE_BOOLEAN:
+		                	result.add(Boolean.toString(cell.getBooleanCellValue()));
+		                    break;
+		                case Cell.CELL_TYPE_FORMULA:
+		                	result.add(cell.getCellFormula());
+		                    break;
+		                default:
+		                    result.add("");
+	                }
+				}
+				return result.toArray(new String[0]);
+			}
+		}
+		return null;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/layers/OdDataLayer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/layers/OdDataLayer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/layers/OdDataLayer.java	(revision 28000)
@@ -0,0 +1,171 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.layers;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.swing.Action;
+import javax.swing.Icon;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.actions.OpenLinkAction;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+import org.openstreetmap.josm.plugins.opendata.core.io.OsmDownloader;
+import org.openstreetmap.josm.plugins.opendata.core.modules.ModuleHandler;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+public class OdDataLayer extends OsmDataLayer implements OdConstants, OdLayer, LayerChangeListener {
+
+	public OdDiffLayer diffLayer;
+	public OdOsmDataLayer osmLayer;
+	
+	public final AbstractDataSetHandler handler;
+	
+	private Bounds bounds;
+	
+	public OdDataLayer(DataSet data, String name, File associatedFile, AbstractDataSetHandler handler) {
+		super(data, name, associatedFile);
+		setUploadDiscouraged(true);
+		this.handler = handler;
+		for (Node node : data.getNodes()) {
+			if (this.bounds == null) {
+				this.bounds = new Bounds(node.getCoor());
+			} else {
+				this.bounds.extend(node.getCoor());
+			}
+		}
+		MapView.addLayerChangeListener(this);
+	}
+	
+    @Override public Icon getBaseIcon() {
+    	return new ImageProvider(handler != null ? handler.getDataLayerIconName() : ICON_CORE_16).get(ModuleHandler.getResourceClassLoaders());
+    }
+
+    public void addOsmLayer(OdOsmDataLayer layer) {
+    	removeOsmLayer();
+    	osmLayer = layer;
+    	Main.main.addLayer(osmLayer);
+    }
+
+    public void removeOsmLayer() {
+    	if (osmLayer != null) {
+	    	Main.main.removeLayer(osmLayer);
+	    	osmLayer = null;
+    	}
+    }
+    
+    public void addDiffLayer(OdDiffLayer layer) {
+    	removeDiffLayer();
+    	diffLayer = layer;
+    	Main.main.addLayer(diffLayer);
+    }
+    
+    public void removeDiffLayer() {
+    	if (diffLayer != null) {
+	    	Main.main.removeLayer(diffLayer);
+	    	diffLayer = null;
+    	}
+    }
+    
+	public final void downloadOsmData() {
+		String oapiReq = handler.getOverpassApiRequest(bounds);
+		Collection<String> xapiReqs = handler.getOsmXapiRequests(bounds);
+		if (oapiReq != null || xapiReqs != null) {
+			DataSet dataSet = new DataSet();
+			final OdOsmDataLayer layer = new OdOsmDataLayer(this, dataSet, getName()+"/OSM");
+			addOsmLayer(layer);
+			Main.map.mapView.setActiveLayer(osmLayer);
+			if (oapiReq != null) {
+				OsmDownloader.downloadOapi(oapiReq);
+				// Overpass API does not allow to exclude tags :(
+				layer.removeForbiddenTags();
+			} else {
+				OsmDownloader.downloadXapi(xapiReqs);
+			}
+		}
+	}
+
+	@Override
+	public void activeLayerChange(Layer oldLayer, Layer newLayer) {
+	}
+
+	@Override
+	public void layerAdded(Layer newLayer) {
+	}
+
+	@Override
+	public void layerRemoved(Layer oldLayer) {
+		if (oldLayer == this) {
+			removeOsmLayer();
+			removeDiffLayer();
+		} else if (oldLayer == osmLayer) {
+			osmLayer = null;
+		} else if (oldLayer == diffLayer) {
+			diffLayer = null;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.gui.layer.OsmDataLayer#getMenuEntries()
+	 */
+	@Override
+	public Action[] getMenuEntries() {
+		List<Action> result = new ArrayList<Action>();
+		for (Action entry : super.getMenuEntries()) {
+			result.add(entry);
+		}
+		if (this.handler.getWikiURL() != null || this.handler.getLocalPortalURL() != null || this.handler.getNationalPortalURL() != null) { 
+			result.add(SeparatorLayerAction.INSTANCE);
+		}
+		if (this.handler.getWikiURL() != null) { 
+			result.add(new OpenLinkAction(this.handler.getWikiURL(), ICON_OSM_24, 
+					tr("View OSM Wiki page"), tr("Launch browser to the OSM Wiki page of the selected data set")));
+		}
+		if (this.handler.getLocalPortalURL() != null) { 
+			result.add(new OpenLinkAction(this.handler.getLocalPortalURL(), this.handler.getLocalPortalIconName(), 
+					tr("View Local Portal page"), tr("Launch browser to the local portal page of the selected data set")));
+		}
+		if (this.handler.getNationalPortalURL() != null) { 
+			result.add(new OpenLinkAction(this.handler.getNationalPortalURL(), this.handler.getNationalPortalIconName(), 
+					tr("View National Portal page"), tr("Launch browser to the national portal page of the selected data set")));
+		}
+		return result.toArray(new Action[0]);
+	}
+
+	@Override
+	public OdDataLayer getDataLayer() {
+		return this;
+	}
+
+	public void makeDiff() {
+		final OdDiffLayer layer = new OdDiffLayer(this, getName()+"/Diff");
+		addDiffLayer(layer);
+		Main.map.mapView.setActiveLayer(diffLayer);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/layers/OdDiffLayer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/layers/OdDiffLayer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/layers/OdDiffLayer.java	(revision 28000)
@@ -0,0 +1,149 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.layers;
+
+import java.awt.Graphics2D;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.Action;
+import javax.swing.Icon;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Pair;
+
+public class OdDiffLayer extends Layer implements OdLayer, OdConstants {
+
+	private final OdDataLayer dataLayer;
+	
+	public final List<Pair<OsmPrimitive,OsmPrimitive>> differentPrimitives;
+	public final List<OsmPrimitive> onlyInTlsPrimitives;
+	public final List<OsmPrimitive> onlyInOsmPrimitives;
+	
+	public OdDiffLayer(OdDataLayer dataLayer, String name) {
+		super(name);
+		this.dataLayer = dataLayer;
+		this.differentPrimitives = new ArrayList<Pair<OsmPrimitive,OsmPrimitive>>();
+		this.onlyInTlsPrimitives = new ArrayList<OsmPrimitive>();
+		this.onlyInOsmPrimitives = new ArrayList<OsmPrimitive>();
+		initDiff(dataLayer.data, dataLayer.osmLayer.data);
+	}
+	
+	private void initDiff(DataSet tlsData, DataSet osmData) {
+		for (OsmPrimitive p1 : tlsData.allPrimitives()) {
+			if (dataLayer.handler.isRelevant(p1)) {
+				OsmPrimitive p2 = findPrimitiveAt(osmData, p1);
+				if (p2 == null) {
+					onlyInTlsPrimitives.add(p1);
+				} else if (!dataLayer.handler.equals(p1, p2)) {
+					differentPrimitives.add(new Pair<OsmPrimitive, OsmPrimitive>(p1, p2));
+				}
+			}
+		}
+		for (OsmPrimitive p1 : osmData.allPrimitives()) {
+			if (dataLayer.handler.isRelevant(p1)) {
+				if (findPrimitiveAt(tlsData, p1) == null) {
+					onlyInOsmPrimitives.add(p1);
+				}
+			}
+		}
+	}
+	
+	private double distance(OsmPrimitive p1, OsmPrimitive p2) {
+		return p1.getBBox().getCenter().greatCircleDistance(p2.getBBox().getCenter());
+	}
+	
+	private OsmPrimitive findPrimitiveAt(DataSet dataSet, OsmPrimitive source) {
+		double maxDistance = Main.pref.getDouble(PREF_MAXDISTANCE, DEFAULT_MAXDISTANCE);
+		//List<OsmPrimitive> samePrimitives = new ArrayList<OsmPrimitive>();
+		OsmPrimitive nearestSamePrimitive = null;
+		//List<OsmPrimitive> potentialPrimitives = new ArrayList<OsmPrimitive>();
+		OsmPrimitive nearestPotentialPrimitive = null;
+		for (OsmPrimitive p : dataSet.allPrimitives()) {
+			if (dataLayer.handler.isRelevant(p)) {
+				double dist = distance(source, p); 
+				if (dist <= maxDistance) {
+					if (dataLayer.handler.equals(p, source)) {
+						//samePrimitives.add(p);
+						if (nearestSamePrimitive == null || distance(p, nearestSamePrimitive) > dist) {
+							nearestSamePrimitive = p;
+						}
+					} else {
+						//potentialPrimitives.add(p);
+						if (nearestPotentialPrimitive == null || distance(p, nearestPotentialPrimitive) > dist) {
+							nearestPotentialPrimitive = p;
+						}
+					}
+				}
+			}
+		}
+		return nearestSamePrimitive != null ? nearestSamePrimitive : nearestPotentialPrimitive;
+	}
+
+	@Override
+	public void paint(Graphics2D g, MapView mv, Bounds box) {
+		// TODO Auto-generated method stub
+	}
+
+	@Override
+	public Icon getIcon() {
+		return ImageProvider.get("layer", "diff");
+	}
+
+	@Override
+	public String getToolTipText() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void mergeFrom(Layer from) {
+	}
+
+	@Override
+	public boolean isMergable(Layer other) {
+		return false;
+	}
+
+	@Override
+	public void visitBoundingBox(BoundingXYVisitor v) {
+		// TODO Auto-generated method stub
+	}
+
+	@Override
+	public Object getInfoComponent() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Action[] getMenuEntries() {
+		return null;
+	}
+
+	@Override
+	public OdDataLayer getDataLayer() {
+		return dataLayer;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/layers/OdLayer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/layers/OdLayer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/layers/OdLayer.java	(revision 28000)
@@ -0,0 +1,20 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.layers;
+
+public interface OdLayer {
+	public OdDataLayer getDataLayer();
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/layers/OdOsmDataLayer.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/layers/OdOsmDataLayer.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/layers/OdOsmDataLayer.java	(revision 28000)
@@ -0,0 +1,88 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.layers;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+
+public class OdOsmDataLayer extends OsmDataLayer implements OdLayer {
+
+	private final OdDataLayer dataLayer;
+
+	public OdOsmDataLayer(OdDataLayer dataLayer, DataSet data, String name) {
+		super(data, name, null);
+		this.dataLayer = dataLayer;
+	}
+	
+    public final void removeForbiddenTags() {
+		if (dataLayer != null && dataLayer.handler != null && dataLayer.handler.hasForbiddenTags()) {
+			Main.worker.submit(new Runnable() {
+				@Override
+				public void run() {
+					data.clearSelection();
+					for (Iterator<OsmPrimitive> it = data.allPrimitives().iterator(); it.hasNext();) {
+						OsmPrimitive p = it.next();
+						if (dataLayer.handler.isForbidden(p)) {
+							data.addSelected(p);
+							
+							List<Node> nodes = null;
+							if (p instanceof Way) {
+								nodes = ((Way) p).getNodes();
+							}
+							//data.removePrimitive(p);
+							if (nodes != null) {
+								for (Node n : nodes) {
+									List<OsmPrimitive> refferingAllowedWays = new ArrayList<OsmPrimitive>();
+									for (OsmPrimitive referrer : n.getReferrers()) {
+										if (referrer instanceof Way && !dataLayer.handler.isForbidden(referrer)) {
+											refferingAllowedWays.add(referrer);
+										}
+									}
+									
+									if (refferingAllowedWays.isEmpty()) {
+										//data.removePrimitive(n);
+										data.addSelected(n);
+									}
+								}
+							}
+							/*for (OsmPrimitive referrer : p.getReferrers()) {
+								System.out.println(referrer);
+							}*/
+						}
+					}
+					Collection<OsmPrimitive> sel = data.getSelected();
+					if (!sel.isEmpty()) {
+						Main.main.menu.purge.actionPerformed(null);
+					}
+				}
+			});
+		}
+    }
+
+	@Override
+	public OdDataLayer getDataLayer() {
+		return dataLayer;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/AbstractModule.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/AbstractModule.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/AbstractModule.java	(revision 28000)
@@ -0,0 +1,117 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.modules;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.openstreetmap.josm.gui.preferences.SourceEditor.ExtendedSourceEntry;
+import org.openstreetmap.josm.gui.preferences.SourceEntry;
+import org.openstreetmap.josm.gui.preferences.SourceProvider;
+import org.openstreetmap.josm.plugins.opendata.OdPlugin;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+
+public abstract class AbstractModule implements Module, OdConstants {
+
+	protected final List<AbstractDataSetHandler> handlers = new ArrayList<AbstractDataSetHandler>();
+	
+	protected final ModuleInformation info;
+	
+	public AbstractModule(ModuleInformation info) {
+		this.info = info;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.modules.Module#getModuleInformation()
+	 */
+	@Override
+	public ModuleInformation getModuleInformation() {
+		return info;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.modules.Module#getHandlers()
+	 */
+	@Override
+	public List<AbstractDataSetHandler> getHandlers() {
+		return handlers;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.modules.Module#getMapPaintStyleSourceProvider()
+	 */
+	@Override
+	public SourceProvider getMapPaintStyleSourceProvider() {
+		final List<SourceEntry> sources = new ArrayList<SourceEntry>();
+		for (AbstractDataSetHandler handler : handlers) {
+			ExtendedSourceEntry src;
+			if (handler != null && (src = handler.getMapPaintStyle()) != null) {
+				try {
+					// Copy style sheet to disk to allow JOSM to load it at startup (even making the plugin "early" does not allow it)
+					String path = OdPlugin.getInstance().getResourcesDirectory()+File.separator+src.url.replace(PROTO_RSRC, "").replace('/', File.separatorChar);
+					
+					int n = 0;
+					byte[] buffer = new byte[4096];
+					InputStream in = getClass().getResourceAsStream(src.url.substring(PROTO_RSRC.length()-1));
+					new File(path.substring(0, path.lastIndexOf(File.separatorChar))).mkdirs();
+					FileOutputStream out = new FileOutputStream(path);
+					while ((n = in.read(buffer)) > 0) {
+						out.write(buffer, 0, n);
+					}
+					out.close();
+					in.close();
+
+					// Add source pointing to the local file
+					src.url = PROTO_FILE+path;
+					sources.add(src);
+				} catch (IOException e) {
+					System.err.println(e.getMessage());
+				}
+			}
+		}
+		return sources.isEmpty() ? null : new SourceProvider() {
+			@Override
+			public Collection<SourceEntry> getSources() {
+				return sources;
+			}
+		};
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.opendata.core.modules.Module#getPresetSourceProvider()
+	 */
+	@Override
+	public SourceProvider getPresetSourceProvider() {
+		final List<SourceEntry> sources = new ArrayList<SourceEntry>();
+		for (AbstractDataSetHandler handler : handlers) {
+			if (handler != null && handler.getTaggingPreset() != null) {
+				sources.add(handler.getTaggingPreset());
+			}
+		}
+		return sources.isEmpty() ? null : new SourceProvider() {
+			@Override
+			public Collection<SourceEntry> getSources() {
+				return sources;
+			}
+		};
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/Module.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/Module.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/Module.java	(revision 28000)
@@ -0,0 +1,32 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.modules;
+
+import java.util.List;
+
+import org.openstreetmap.josm.gui.preferences.SourceProvider;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
+
+public interface Module {
+
+	public List<AbstractDataSetHandler> getHandlers();
+	
+	public SourceProvider getMapPaintStyleSourceProvider();
+	
+	public SourceProvider getPresetSourceProvider();
+	
+	public ModuleInformation getModuleInformation();
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleDownloadException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleDownloadException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleDownloadException.java	(revision 28000)
@@ -0,0 +1,35 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.modules;
+
+public class ModuleDownloadException extends Exception {
+
+    public ModuleDownloadException() {
+        super();
+    }
+
+    public ModuleDownloadException(String message, Throwable cause) { // NO_UCD
+        super(message, cause);
+    }
+
+    public ModuleDownloadException(String message) {
+        super(message);
+    }
+
+    public ModuleDownloadException(Throwable cause) {
+        super(cause);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleDownloadTask.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleDownloadTask.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleDownloadTask.java	(revision 28000)
@@ -0,0 +1,189 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.opendata.core.modules;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Component;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.openstreetmap.josm.data.Version;
+import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.plugins.opendata.OdPlugin;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Utils;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Asynchronous task for downloading a collection of modules.
+ *
+ * When the task is finished {@see #getDownloadedModules()} replies the list of downloaded modules
+ * and {@see #getFailedModules()} replies the list of failed modules.
+ *
+ */
+public class ModuleDownloadTask extends PleaseWaitRunnable{
+    private final Collection<ModuleInformation> toUpdate = new LinkedList<ModuleInformation>();
+    private final Collection<ModuleInformation> failed = new LinkedList<ModuleInformation>();
+    private final Collection<ModuleInformation> downloaded = new LinkedList<ModuleInformation>();
+    //private Exception lastException;
+    private boolean canceled;
+    private HttpURLConnection downloadConnection;
+
+    /**
+     * Creates the download task
+     *
+     * @param parent the parent component relative to which the {@see PleaseWaitDialog} is displayed
+     * @param toUpdate a collection of module descriptions for modules to update/download. Must not be null.
+     * @param title the title to display in the {@see PleaseWaitDialog}
+     * @throws IllegalArgumentException thrown if toUpdate is null
+     */
+    public ModuleDownloadTask(Component parent, Collection<ModuleInformation> toUpdate, String title) throws IllegalArgumentException{
+        super(parent, title == null ? "" : title, false /* don't ignore exceptions */);
+        CheckParameterUtil.ensureParameterNotNull(toUpdate, "toUpdate");
+        this.toUpdate.addAll(toUpdate);
+    }
+
+    /**
+     * Creates the task
+     *
+     * @param monitor a progress monitor. Defaults to {@see NullProgressMonitor#INSTANCE} if null
+     * @param toUpdate a collection of module descriptions for modules to update/download. Must not be null.
+     * @param title the title to display in the {@see PleaseWaitDialog}
+     * @throws IllegalArgumentException thrown if toUpdate is null
+     */
+    public ModuleDownloadTask(ProgressMonitor monitor, Collection<ModuleInformation> toUpdate, String title) {
+        super(title, monitor == null? NullProgressMonitor.INSTANCE: monitor, false /* don't ignore exceptions */);
+        CheckParameterUtil.ensureParameterNotNull(toUpdate, "toUpdate");
+        this.toUpdate.addAll(toUpdate);
+    }
+
+    /**
+     * Sets the collection of modules to update.
+     *
+     * @param toUpdate the collection of modules to update. Must not be null.
+     * @throws IllegalArgumentException thrown if toUpdate is null
+     */
+    public void setModulesToDownload(Collection<ModuleInformation> toUpdate) throws IllegalArgumentException{
+        CheckParameterUtil.ensureParameterNotNull(toUpdate, "toUpdate");
+        this.toUpdate.clear();
+        this.toUpdate.addAll(toUpdate);
+    }
+
+    @Override protected void cancel() {
+        this.canceled = true;
+        synchronized(this) {
+            if (downloadConnection != null) {
+                downloadConnection.disconnect();
+            }
+        }
+    }
+
+    @Override protected void finish() {}
+
+    protected void download(ModuleInformation pi, File file) throws ModuleDownloadException{
+        OutputStream out = null;
+        InputStream in = null;
+        try {
+            if (pi.downloadlink == null) {
+                String msg = tr("Warning: Cannot download module ''{0}''. Its download link is not known. Skipping download.", pi.name);
+                System.err.println(msg);
+                throw new ModuleDownloadException(msg);
+            }
+            URL url = new URL(pi.downloadlink);
+            synchronized(this) {
+                downloadConnection = (HttpURLConnection)url.openConnection();
+                downloadConnection.setRequestProperty("Cache-Control", "no-cache");
+                downloadConnection.setRequestProperty("User-Agent",Version.getInstance().getAgentString());
+                downloadConnection.setRequestProperty("Host", url.getHost());
+                downloadConnection.connect();
+            }
+            in = downloadConnection.getInputStream();
+            out = new FileOutputStream(file);
+            byte[] buffer = new byte[8192];
+            for (int read = in.read(buffer); read != -1; read = in.read(buffer)) {
+                out.write(buffer, 0, read);
+            }
+            out.close();
+            in.close();
+        } catch(MalformedURLException e) {
+            String msg = tr("Warning: Cannot download module ''{0}''. Its download link ''{1}'' is not a valid URL. Skipping download.", pi.name, pi.downloadlink);
+            System.err.println(msg);
+            throw new ModuleDownloadException(msg);
+        } catch (IOException e) {
+            if (canceled)
+                return;
+            throw new ModuleDownloadException(e);
+        } finally {
+            Utils.close(in);
+            synchronized(this) {
+                downloadConnection = null;
+            }
+            Utils.close(out);
+        }
+    }
+
+    @Override protected void realRun() throws SAXException, IOException {
+        File moduleDir = OdPlugin.getInstance().getModulesDirectory();
+        if (!moduleDir.exists()) {
+            if (!moduleDir.mkdirs()) {
+                //lastException = new ModuleDownloadException(tr("Failed to create module directory ''{0}''", moduleDir.toString()));
+                failed.addAll(toUpdate);
+                return;
+            }
+        }
+        getProgressMonitor().setTicksCount(toUpdate.size());
+        for (ModuleInformation d : toUpdate) {
+            if (canceled) return;
+            progressMonitor.subTask(tr("Downloading Module {0}...", d.name));
+            progressMonitor.worked(1);
+            File moduleFile = new File(moduleDir, d.name + ".jar.new");
+            try {
+                download(d, moduleFile);
+            } catch(ModuleDownloadException e) {
+                e.printStackTrace();
+                failed.add(d);
+                continue;
+            }
+            downloaded.add(d);
+        }
+        ModuleHandler.installDownloadedModules(false);
+    }
+
+    /**
+     * Replies true if the task was canceled by the user
+     *
+     * @return
+     */
+    public boolean isCanceled() {
+        return canceled;
+    }
+
+    /**
+     * Replies the list of successfully downloaded modules
+     *
+     * @return the list of successfully downloaded modules
+     */
+    public Collection<ModuleInformation> getFailedModules() {
+        return failed;
+    }
+
+    /**
+     * Replies the list of modules whose download has failed
+     *
+     * @return the list of modules whose download has failed
+     */
+    public Collection<ModuleInformation> getDownloadedModules() {
+        return downloaded;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleException.java	(revision 28000)
@@ -0,0 +1,48 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.modules;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+/**
+ * Exception that wraps any exception thrown by modules. It is used in the JOSM main system
+ * and there is no particular reason to use this within the module itself (although there
+ * is also no reason against this.. ;)
+ *
+ * @author Immanuel.Scholz
+ */
+public class ModuleException extends Exception {
+    public final Module module; // NO_UCD
+    public final String name;
+
+    public ModuleException(Module module, String name, Throwable cause) { // NO_UCD
+        super(tr("An error occurred in module {0}", name), cause);
+        this.module = module;
+        this.name = name;
+    }
+
+    public ModuleException(String name, String message) {
+        super(message);
+        this.module = null;
+        this.name = name;
+    }
+
+    public ModuleException(String name, Throwable cause) {
+        super(tr("An error occurred in module {0}", name), cause);
+        this.module = null;
+        this.name = name;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleHandler.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleHandler.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleHandler.java	(revision 28000)
@@ -0,0 +1,794 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.modules;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+import static org.openstreetmap.josm.tools.I18n.trn;
+
+import java.awt.Component;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import javax.swing.JCheckBox;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.HelpAwareOptionPane;
+import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
+import org.openstreetmap.josm.gui.JMultilineLabel;
+import org.openstreetmap.josm.gui.help.HelpUtil;
+import org.openstreetmap.josm.gui.preferences.SourceProvider;
+import org.openstreetmap.josm.gui.preferences.map.MapPaintPreference;
+import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
+import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.plugins.opendata.OdPlugin;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.gui.OdPreferenceSetting;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.I18n;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+/**
+ * ModuleHandler is basically a collection of static utility functions used to bootstrap
+ * and manage the loaded modules.
+ *
+ */
+public class ModuleHandler implements OdConstants {
+
+    /**
+     * All installed and loaded modules (resp. their main classes)
+     */
+    public final static Collection<Module> moduleList = new LinkedList<Module>();
+
+    /**
+     * Add here all ClassLoader whose resource should be searched.
+     */
+    private static final List<ClassLoader> sources = new LinkedList<ClassLoader>();
+
+    static {
+        try {
+            sources.add(ClassLoader.getSystemClassLoader());
+            sources.add(org.openstreetmap.josm.gui.MainApplication.class.getClassLoader());
+        } catch (SecurityException ex) {
+            sources.add(ImageProvider.class.getClassLoader());
+        }
+    }
+
+    public static Collection<ClassLoader> getResourceClassLoaders() {
+        return Collections.unmodifiableCollection(sources);
+    }
+
+    /**
+     * Checks whether the locally available modules should be updated and
+     * asks the user if running an update is OK. An update is advised if
+     * JOSM was updated to a new version since the last module updates or
+     * if the modules were last updated a long time ago.
+     *
+     * @param parent the parent window relative to which the confirmation dialog
+     * is to be displayed
+     * @return true if a module update should be run; false, otherwise
+     */
+    public static boolean checkAndConfirmModuleUpdate(Component parent) {
+        String message = null;
+        String togglePreferenceKey = null;
+        long tim = System.currentTimeMillis();
+        long last = Main.pref.getLong("opendata.modulemanager.lastupdate", 0);
+        Integer maxTime = Main.pref.getInteger("opendata.modulemanager.time-based-update.interval", 60);
+        long d = (tim - last) / (24 * 60 * 60 * 1000l);
+        if ((last <= 0) || (maxTime <= 0)) {
+            Main.pref.put("opendata.modulemanager.lastupdate", Long.toString(tim));
+        } else if (d > maxTime) {
+            message =
+                "<html>"
+                + tr("Last module update more than {0} days ago.", d)
+                + "</html>";
+            togglePreferenceKey = "opendata.modulemanager.time-based-update.policy";
+        }
+        if (message == null) return false;
+
+        ButtonSpec [] options = new ButtonSpec[] {
+                new ButtonSpec(
+                        tr("Update modules"),
+                        ImageProvider.get("dialogs", "refresh"),
+                        tr("Click to update the activated modules"),
+                        null /* no specific help context */
+                ),
+                new ButtonSpec(
+                        tr("Skip update"),
+                        ImageProvider.get("cancel"),
+                        tr("Click to skip updating the activated modules"),
+                        null /* no specific help context */
+                )
+        };
+
+        UpdateModulesMessagePanel pnlMessage = new UpdateModulesMessagePanel();
+        pnlMessage.setMessage(message);
+        pnlMessage.initDontShowAgain(togglePreferenceKey);
+
+        // check whether automatic update at startup was disabled
+        //
+        String policy = Main.pref.get(togglePreferenceKey, "ask");
+        policy = policy.trim().toLowerCase();
+        if (policy.equals("never")) {
+            if ("opendata.modulemanager.time-based-update.policy".equals(togglePreferenceKey)) {
+                System.out.println(tr("Skipping module update after elapsed update interval. Automatic update at startup is disabled."));
+            }
+            return false;
+        }
+
+        if (policy.equals("always")) {
+            if ("opendata.modulemanager.time-based-update.policy".equals(togglePreferenceKey)) {
+                System.out.println(tr("Running module update after elapsed update interval. Automatic update at startup is disabled."));
+            }
+            return true;
+        }
+
+        if (!policy.equals("ask")) {
+            System.err.println(tr("Unexpected value ''{0}'' for preference ''{1}''. Assuming value ''ask''.", policy, togglePreferenceKey));
+        }
+        int ret = HelpAwareOptionPane.showOptionDialog(
+                parent,
+                pnlMessage,
+                tr("Update modules"),
+                JOptionPane.WARNING_MESSAGE,
+                null,
+                options,
+                options[0],
+                null
+        );
+
+        if (pnlMessage.isRememberDecision()) {
+            switch(ret) {
+            case 0:
+                Main.pref.put(togglePreferenceKey, "always");
+                break;
+            case JOptionPane.CLOSED_OPTION:
+            case 1:
+                Main.pref.put(togglePreferenceKey, "never");
+                break;
+            }
+        } else {
+            Main.pref.put(togglePreferenceKey, "ask");
+        }
+        return ret == 0;
+    }
+
+    /**
+     * Checks whether all preconditions for loading the module <code>module</code> are met. The
+     * current JOSM version must be compatible with the module and no other modules this module
+     * depends on should be missing.
+     *
+     * @param modules the collection of all loaded modules
+     * @param module the module for which preconditions are checked
+     * @return true, if the preconditions are met; false otherwise
+     */
+    public static boolean checkLoadPreconditions(Component parent, Collection<ModuleInformation> modules, ModuleInformation module) {
+        return true;
+    }
+
+    /**
+     * Creates a class loader for loading module code.
+     *
+     * @param modules the collection of modules which are going to be loaded with this
+     * class loader
+     * @return the class loader
+     */
+    public static ClassLoader createClassLoader(Collection<ModuleInformation> modules) {
+        // iterate all modules and collect all libraries of all modules:
+        List<URL> allModuleLibraries = new LinkedList<URL>();
+        File moduleDir = OdPlugin.getInstance().getModulesDirectory();
+        for (ModuleInformation info : modules) {
+            if (info.libraries == null) {
+                continue;
+            }
+            allModuleLibraries.addAll(info.libraries);
+            File moduleJar = new File(moduleDir, info.name + ".jar");
+            I18n.addTexts(moduleJar);
+            URL moduleJarUrl = ModuleInformation.fileToURL(moduleJar);
+            allModuleLibraries.add(moduleJarUrl);
+        }
+
+        // create a classloader for all modules:
+        return new URLClassLoader(allModuleLibraries.toArray(new URL[0]), OdPlugin.class.getClassLoader());
+    }
+
+    /**
+     * Loads and instantiates the module described by <code>module</code> using
+     * the class loader <code>moduleClassLoader</code>.
+     *
+     * @param module the module
+     * @param moduleClassLoader the module class loader
+     */
+    public static void loadModule(Component parent, ModuleInformation module, ClassLoader moduleClassLoader) {
+        String msg = tr("Could not load module {0}. Delete from preferences?", module.name);
+        try {
+            Class<? extends Module> klass = module.loadClass(moduleClassLoader);
+            if (klass != null) {
+                System.out.println(tr("loading module ''{0}'' (version {1})", module.name, module.localversion));
+                Module mod = module.load(klass);
+                if (moduleList.add(mod)) {
+                	SourceProvider styleProvider = mod.getMapPaintStyleSourceProvider();
+                	if (styleProvider != null) {
+                		MapPaintPreference.registerSourceProvider(styleProvider);
+                	}
+                	SourceProvider presetProvider = mod.getPresetSourceProvider();
+                	if (presetProvider != null) {
+                		TaggingPresetPreference.registerSourceProvider(presetProvider);
+                	}
+                }
+            }
+            msg = null;
+        } catch (ModuleException e) {
+            e.printStackTrace();
+            if (e.getCause() instanceof ClassNotFoundException) {
+                msg = tr("<html>Could not load module {0} because the module<br>main class ''{1}'' was not found.<br>"
+                        + "Delete from preferences?</html>", module.name, module.className);
+            }
+        }  catch (Throwable e) {
+            e.printStackTrace();
+        }
+        if (msg != null && confirmDisableModule(parent, msg, module.name)) {
+            Main.pref.removeFromCollection(PREF_MODULES, module.name);
+        }
+    }
+
+    /**
+     * Loads the module in <code>modules</code> from locally available jar files into
+     * memory.
+     *
+     * @param modules the list of modules
+     * @param monitor the progress monitor. Defaults to {@see NullProgressMonitor#INSTANCE} if null.
+     */
+    public static void loadModules(Component parent, Collection<ModuleInformation> modules, ProgressMonitor monitor) {
+        if (monitor == null) {
+            monitor = NullProgressMonitor.INSTANCE;
+        }
+        try {
+            monitor.beginTask(tr("Loading modules ..."));
+            monitor.subTask(tr("Checking module preconditions..."));
+            List<ModuleInformation> toLoad = new LinkedList<ModuleInformation>();
+            for (ModuleInformation pi: modules) {
+                if (checkLoadPreconditions(parent, modules, pi)) {
+                    toLoad.add(pi);
+                }
+            }
+            if (toLoad.isEmpty())
+                return;
+
+            ClassLoader moduleClassLoader = createClassLoader(toLoad);
+            sources.add(0, moduleClassLoader);
+            monitor.setTicksCount(toLoad.size());
+            for (ModuleInformation info : toLoad) {
+                monitor.setExtraText(tr("Loading module ''{0}''...", info.name));
+                loadModule(parent, info, moduleClassLoader);
+                monitor.worked(1);
+            }
+        } finally {
+            monitor.finishTask();
+        }
+    }
+
+    /**
+     * Loads locally available module information from local module jars and from cached
+     * module lists.
+     *
+     * @param monitor the progress monitor. Defaults to {@see NullProgressMonitor#INSTANCE} if null.
+     * @return the list of locally available module information
+     *
+     */
+    private static Map<String, ModuleInformation> loadLocallyAvailableModuleInformation(ProgressMonitor monitor) {
+        if (monitor == null) {
+            monitor = NullProgressMonitor.INSTANCE;
+        }
+        try {
+            ReadLocalModuleInformationTask task = new ReadLocalModuleInformationTask(monitor);
+            ExecutorService service = Executors.newSingleThreadExecutor();
+            Future<?> future = service.submit(task);
+            try {
+                future.get();
+            } catch(ExecutionException e) {
+                e.printStackTrace();
+                return null;
+            } catch(InterruptedException e) {
+                e.printStackTrace();
+                return null;
+            }
+            HashMap<String, ModuleInformation> ret = new HashMap<String, ModuleInformation>();
+            for (ModuleInformation pi: task.getAvailableModules()) {
+                ret.put(pi.name, pi);
+            }
+            return ret;
+        } finally {
+            monitor.finishTask();
+        }
+    }
+
+    private static void alertMissingModuleInformation(Component parent, Collection<String> modules) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("<html>");
+        sb.append(trn("JOSM could not find information about the following module:",
+                "JOSM could not find information about the following modules:",
+                modules.size()));
+        sb.append("<ul>");
+        for (String module: modules) {
+            sb.append("<li>").append(module).append("</li>");
+        }
+        sb.append("</ul>");
+        sb.append(trn("The module is not going to be loaded.",
+                "The modules are not going to be loaded.",
+                modules.size()));
+        sb.append("</html>");
+        HelpAwareOptionPane.showOptionDialog(
+                parent,
+                sb.toString(),
+                tr("Warning"),
+                JOptionPane.WARNING_MESSAGE,
+                HelpUtil.ht("/Module/Loading#MissingModuleInfos")
+        );
+    }
+
+    /**
+     * Builds the set of modules to load. Deprecated and unmaintained modules are filtered
+     * out. This involves user interaction. This method displays alert and confirmation
+     * messages.
+     *
+     * @return the set of modules to load (as set of module names)
+     */
+    public static List<ModuleInformation> buildListOfModulesToLoad(Component parent) {
+        Set<String> modules = new HashSet<String>();
+        modules.addAll(Main.pref.getCollection(PREF_MODULES,  new LinkedList<String>()));
+        if (System.getProperty("josm."+PREF_MODULES) != null) {
+            modules.addAll(Arrays.asList(System.getProperty("josm."+PREF_MODULES).split(",")));
+        }
+        Map<String, ModuleInformation> infos = loadLocallyAvailableModuleInformation(null);
+        List<ModuleInformation> ret = new LinkedList<ModuleInformation>();
+        for (Iterator<String> it = modules.iterator(); it.hasNext();) {
+            String module = it.next();
+            if (infos.containsKey(module)) {
+                ret.add(infos.get(module));
+                it.remove();
+            }
+        }
+        if (!modules.isEmpty()) {
+            alertMissingModuleInformation(parent, modules);
+        }
+        return ret;
+    }
+
+    private static void alertFailedModuleUpdate(Component parent, Collection<ModuleInformation> modules) {
+        StringBuffer sb = new StringBuffer();
+        sb.append("<html>");
+        sb.append(trn(
+                "Updating the following module has failed:",
+                "Updating the following modules has failed:",
+                modules.size()
+        )
+        );
+        sb.append("<ul>");
+        for (ModuleInformation pi: modules) {
+            sb.append("<li>").append(pi.name).append("</li>");
+        }
+        sb.append("</ul>");
+        sb.append(trn(
+                "Please open the Preference Dialog after JOSM has started and try to update it manually.",
+                "Please open the Preference Dialog after JOSM has started and try to update them manually.",
+                modules.size()
+        ));
+        sb.append("</html>");
+        HelpAwareOptionPane.showOptionDialog(
+                parent,
+                sb.toString(),
+                tr("Module update failed"),
+                JOptionPane.ERROR_MESSAGE,
+                HelpUtil.ht("/Module/Loading#FailedModuleUpdated")
+        );
+    }
+
+    /**
+     * Updates the modules in <code>modules</code>.
+     *
+     * @param parent the parent window for message boxes
+     * @param modules the collection of modules to update. Must not be null.
+     * @param monitor the progress monitor. Defaults to {@see NullProgressMonitor#INSTANCE} if null.
+     * @throws IllegalArgumentException thrown if modules is null
+     */
+    public static List<ModuleInformation>  updateModules(Component parent,
+            List<ModuleInformation> modules, ProgressMonitor monitor)
+            throws IllegalArgumentException{
+        CheckParameterUtil.ensureParameterNotNull(modules, "modules");
+        if (monitor == null) {
+            monitor = NullProgressMonitor.INSTANCE;
+        }
+        try {
+            monitor.beginTask("");
+            ExecutorService service = Executors.newSingleThreadExecutor();
+
+            // try to download the module lists
+            //
+            ReadRemoteModuleInformationTask task1 = new ReadRemoteModuleInformationTask(
+                    monitor.createSubTaskMonitor(1,false),
+                    OdPreferenceSetting.getModuleSites()
+            );
+            Future<?> future = service.submit(task1);
+            try {
+                future.get();
+                modules = buildListOfModulesToLoad(parent);
+            } catch(ExecutionException e) {
+                System.out.println(tr("Warning: failed to download module information list"));
+                e.printStackTrace();
+                // don't abort in case of error, continue with downloading modules below
+            } catch(InterruptedException e) {
+                System.out.println(tr("Warning: failed to download module information list"));
+                e.printStackTrace();
+                // don't abort in case of error, continue with downloading modules below
+            }
+
+            // filter modules which actually have to be updated
+            //
+            Collection<ModuleInformation> modulesToUpdate = new ArrayList<ModuleInformation>();
+            for(ModuleInformation pi: modules) {
+                if (pi.isUpdateRequired()) {
+                    modulesToUpdate.add(pi);
+                }
+            }
+
+            if (!modulesToUpdate.isEmpty()) {
+                // try to update the locally installed modules
+                //
+                ModuleDownloadTask task2 = new ModuleDownloadTask(
+                        monitor.createSubTaskMonitor(1,false),
+                        modulesToUpdate,
+                        tr("Update modules")
+                );
+
+                future = service.submit(task2);
+                try {
+                    future.get();
+                } catch(ExecutionException e) {
+                    e.printStackTrace();
+                    alertFailedModuleUpdate(parent, modulesToUpdate);
+                    return modules;
+                } catch(InterruptedException e) {
+                    e.printStackTrace();
+                    alertFailedModuleUpdate(parent, modulesToUpdate);
+                    return modules;
+                }
+                // notify user if downloading a locally installed module failed
+                //
+                if (! task2.getFailedModules().isEmpty()) {
+                    alertFailedModuleUpdate(parent, task2.getFailedModules());
+                    return modules;
+                }
+            }
+        } finally {
+            monitor.finishTask();
+        }
+        // remember the update because it was successful
+        //
+        Main.pref.put("opendata.modulemanager.lastupdate", Long.toString(System.currentTimeMillis()));
+        return modules;
+    }
+
+    /**
+     * Ask the user for confirmation that a module shall be disabled.
+     *
+     * @param reason the reason for disabling the module
+     * @param name the module name
+     * @return true, if the module shall be disabled; false, otherwise
+     */
+    public static boolean confirmDisableModule(Component parent, String reason, String name) {
+        ButtonSpec [] options = new ButtonSpec[] {
+                new ButtonSpec(
+                        tr("Disable module"),
+                        ImageProvider.get("dialogs", "delete"),
+                        tr("Click to delete the module ''{0}''", name),
+                        null /* no specific help context */
+                ),
+                new ButtonSpec(
+                        tr("Keep module"),
+                        ImageProvider.get("cancel"),
+                        tr("Click to keep the module ''{0}''", name),
+                        null /* no specific help context */
+                )
+        };
+        int ret = HelpAwareOptionPane.showOptionDialog(
+                parent,
+                reason,
+                tr("Disable module"),
+                JOptionPane.WARNING_MESSAGE,
+                null,
+                options,
+                options[0],
+                null // FIXME: add help topic
+        );
+        return ret == 0;
+    }
+
+    /*public static Module getModule(String name) {
+        for (Module module : moduleList)
+            if (module.getModuleInformation().name.equals(name))
+                return module;
+        return null;
+    }*/
+
+    /**
+     * Installs downloaded modules. Moves files with the suffix ".jar.new" to the corresponding
+     * ".jar" files.
+     *
+     * If {@code dowarn} is true, this methods emits warning messages on the console if a downloaded
+     * but not yet installed module .jar can't be be installed. If {@code dowarn} is false, the
+     * installation of the respective module is sillently skipped.
+     *
+     * @param dowarn if true, warning messages are displayed; false otherwise
+     */
+    public static void installDownloadedModules(boolean dowarn) {
+        File moduleDir = OdPlugin.getInstance().getModulesDirectory();
+        if (! moduleDir.exists() || ! moduleDir.isDirectory() || ! moduleDir.canWrite())
+            return;
+
+        final File[] files = moduleDir.listFiles(new FilenameFilter() {
+            public boolean accept(File dir, String name) {
+                return name.endsWith(".jar.new");
+            }});
+
+        for (File updatedModule : files) {
+            final String filePath = updatedModule.getPath();
+            File module = new File(filePath.substring(0, filePath.length() - 4));
+            String moduleName = updatedModule.getName().substring(0, updatedModule.getName().length() - 8);
+            if (module.exists()) {
+                if (!module.delete() && dowarn) {
+                    System.err.println(tr("Warning: failed to delete outdated module ''{0}''.", module.toString()));
+                    System.err.println(tr("Warning: failed to install already downloaded module ''{0}''. Skipping installation. JOSM is still going to load the old module version.", moduleName));
+                    continue;
+                }
+            }
+            if (!updatedModule.renameTo(module) && dowarn) {
+                System.err.println(tr("Warning: failed to install module ''{0}'' from temporary download file ''{1}''. Renaming failed.", module.toString(), updatedModule.toString()));
+                System.err.println(tr("Warning: failed to install already downloaded module ''{0}''. Skipping installation. JOSM is still going to load the old module version.", moduleName));
+            }
+        }
+        return;
+    }
+
+    /*private static boolean confirmDeactivatingModuleAfterException(Module module) {
+        ButtonSpec [] options = new ButtonSpec[] {
+                new ButtonSpec(
+                        tr("Disable module"),
+                        ImageProvider.get("dialogs", "delete"),
+                        tr("Click to disable the module ''{0}''", module.getModuleInformation().name),
+                        null // no specific help context
+                ),
+                new ButtonSpec(
+                        tr("Keep module"),
+                        ImageProvider.get("cancel"),
+                        tr("Click to keep the module ''{0}''",module.getModuleInformation().name),
+                        null // no specific help context
+                )
+        };
+
+        StringBuffer msg = new StringBuffer();
+        msg.append("<html>");
+        msg.append(tr("An unexpected exception occurred that may have come from the ''{0}'' module.", module.getModuleInformation().name));
+        msg.append("<br>");
+        if(module.getModuleInformation().author != null) {
+            msg.append(tr("According to the information within the module, the author is {0}.", module.getModuleInformation().author));
+            msg.append("<br>");
+        }
+        msg.append(tr("Try updating to the newest version of this module before reporting a bug."));
+        msg.append("<br>");
+        msg.append(tr("Should the module be disabled?"));
+        msg.append("</html>");
+
+        int ret = HelpAwareOptionPane.showOptionDialog(
+                Main.parent,
+                msg.toString(),
+                tr("Update modules"),
+                JOptionPane.QUESTION_MESSAGE,
+                null,
+                options,
+                options[0],
+                null
+        );
+        return ret == 0;
+    }*/
+
+    /**
+     * Replies the module which most likely threw the exception <code>ex</code>.
+     *
+     * @param ex the exception
+     * @return the module; null, if the exception probably wasn't thrown from a module
+     */
+    /*private static Module getModuleCausingException(Throwable ex) {
+        Module err = null;
+        StackTraceElement[] stack = ex.getStackTrace();
+        // remember the error position, as multiple modules may be involved,
+        //  we search the topmost one
+        int pos = stack.length;
+        for (Module p : moduleList) {
+            String baseClass = p.getModuleInformation().className;
+            baseClass = baseClass.substring(0, baseClass.lastIndexOf("."));
+            for (int elpos = 0; elpos < pos; ++elpos) {
+                if (stack[elpos].getClassName().startsWith(baseClass)) {
+                    pos = elpos;
+                    err = p;
+                }
+            }
+        }
+        return err;
+    }*/
+
+    /**
+     * Checks whether the exception <code>e</code> was thrown by a module. If so,
+     * conditionally deactivates the module, but asks the user first.
+     *
+     * @param e the exception
+     */
+    /*public static void disableModuleAfterException(Throwable e) {
+        Module module = null;
+        // Check for an explicit problem when calling a module function
+        if (e instanceof ModuleException) {
+            module = ((ModuleException) e).module;
+        }
+        if (module == null) {
+            module = getModuleCausingException(e);
+        }
+        if (module == null)
+            // don't know what module threw the exception
+            return;
+
+        Set<String> modules = new HashSet<String>(
+                Main.pref.getCollection(PREF_MODULES, Collections.<String> emptySet())
+        );
+        if (! modules.contains(module.getModuleInformation().name))
+            // module not activated ? strange in this context but anyway, don't bother
+            // the user with dialogs, skip conditional deactivation
+            return;
+
+        if (!confirmDeactivatingModuleAfterException(module))
+            // user doesn't want to deactivate the module
+            return;
+
+        // deactivate the module
+        modules.remove(module.getModuleInformation().name);
+        Main.pref.putCollection(PREF_MODULES, modules);
+        JOptionPane.showMessageDialog(
+                Main.parent,
+                tr("The module has been removed from the configuration. Please restart JOSM to unload the module."),
+                tr("Information"),
+                JOptionPane.INFORMATION_MESSAGE
+        );
+        return;
+    }*/
+
+    /*public static String getBugReportText() {
+        String text = "";
+        LinkedList <String> pl = new LinkedList<String>(Main.pref.getCollection(PREF_MODULES, new LinkedList<String>()));
+        for (final Module pp : moduleList) {
+            ModuleInformation pi = pp.getModuleInformation();
+            pl.remove(pi.name);
+            pl.add(pi.name + " (" + (pi.localversion != null && !pi.localversion.equals("")
+                    ? pi.localversion : "unknown") + ")");
+        }
+        Collections.sort(pl);
+        for (String s : pl) {
+            text += "Module: " + s + "\n";
+        }
+        return text;
+    }*/
+
+    /*public static JPanel getInfoPanel() {
+        JPanel moduleTab = new JPanel(new GridBagLayout());
+        for (final Module p : moduleList) {
+            final ModuleInformation info = p.getModuleInformation();
+            String name = info.name
+            + (info.version != null && !info.version.equals("") ? " Version: " + info.version : "");
+            moduleTab.add(new JLabel(name), GBC.std());
+            moduleTab.add(Box.createHorizontalGlue(), GBC.std().fill(GBC.HORIZONTAL));
+            moduleTab.add(new JButton(new AbstractAction(tr("Information")) {
+                public void actionPerformed(ActionEvent event) {
+                    StringBuilder b = new StringBuilder();
+                    for (Entry<String, String> e : info.attr.entrySet()) {
+                        b.append(e.getKey());
+                        b.append(": ");
+                        b.append(e.getValue());
+                        b.append("\n");
+                    }
+                    JTextArea a = new JTextArea(10, 40);
+                    a.setEditable(false);
+                    a.setText(b.toString());
+                    JOptionPane.showMessageDialog(Main.parent, new JScrollPane(a), tr("Module information"),
+                            JOptionPane.INFORMATION_MESSAGE);
+                }
+            }), GBC.eol());
+
+            JTextArea description = new JTextArea((info.description == null ? tr("no description available")
+                    : info.description));
+            description.setEditable(false);
+            description.setFont(new JLabel().getFont().deriveFont(Font.ITALIC));
+            description.setLineWrap(true);
+            description.setWrapStyleWord(true);
+            description.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0));
+            description.setBackground(UIManager.getColor("Panel.background"));
+
+            moduleTab.add(description, GBC.eop().fill(GBC.HORIZONTAL));
+        }
+        return moduleTab;
+    }*/
+
+    static private class UpdateModulesMessagePanel extends JPanel {
+        private JMultilineLabel lblMessage;
+        private JCheckBox cbDontShowAgain;
+
+        protected void build() {
+            setLayout(new GridBagLayout());
+            GridBagConstraints gc = new GridBagConstraints();
+            gc.anchor = GridBagConstraints.NORTHWEST;
+            gc.fill = GridBagConstraints.BOTH;
+            gc.weightx = 1.0;
+            gc.weighty = 1.0;
+            gc.insets = new Insets(5,5,5,5);
+            add(lblMessage = new JMultilineLabel(""), gc);
+            lblMessage.setFont(lblMessage.getFont().deriveFont(Font.PLAIN));
+
+            gc.gridy = 1;
+            gc.fill = GridBagConstraints.HORIZONTAL;
+            gc.weighty = 0.0;
+            add(cbDontShowAgain = new JCheckBox(tr("Do not ask again and remember my decision (go to Preferences->Modules to change it later)")), gc);
+            cbDontShowAgain.setFont(cbDontShowAgain.getFont().deriveFont(Font.PLAIN));
+        }
+
+        public UpdateModulesMessagePanel() {
+            build();
+        }
+
+        public void setMessage(String message) {
+            lblMessage.setText(message);
+        }
+
+        public void initDontShowAgain(String preferencesKey) {
+            String policy = Main.pref.get(preferencesKey, "ask");
+            policy = policy.trim().toLowerCase();
+            cbDontShowAgain.setSelected(! policy.equals("ask"));
+        }
+
+        public boolean isRememberDecision() {
+            return cbDontShowAgain.isSelected();
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleInformation.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleInformation.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleInformation.java	(revision 28000)
@@ -0,0 +1,364 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.modules;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Image;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.jar.Attributes;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import javax.swing.ImageIcon;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.plugins.opendata.OdPlugin;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.LanguageInfo;
+
+/**
+ * Encapsulate general information about a module. This information is available
+ * without the need of loading any class from the module jar file.
+ */
+public class ModuleInformation implements OdConstants {
+    public File file = null;
+    public String name = null;
+    public String className = null;
+    public String link = null;
+    public String description = null;
+    public String author = null;
+    public String version = null;
+    public String localversion = null;
+    public String downloadlink = null;
+    public String iconPath;
+    public ImageIcon icon;
+    public List<URL> libraries = new LinkedList<URL>();
+    public final Map<String, String> attr = new TreeMap<String, String>();
+
+    /**
+     * Creates a module information object by reading the module information from
+     * the manifest in the module jar.
+     *
+     * The module name is derived from the file name.
+     *
+     * @param file the module jar file
+     * @throws ModuleException if reading the manifest fails
+     */
+    /*public ModuleInformation(File file) throws ModuleException {
+        this(file, file.getName().substring(0, file.getName().length()-4));
+    }*/
+
+    /**
+     * Creates a module information object for the module with name {@code name}.
+     * Information about the module is extracted from the manifest file in the module jar
+     * {@code file}.
+     * @param file the module jar
+     * @param name the module name
+     * @throws ModuleException thrown if reading the manifest file fails
+     */
+    public ModuleInformation(File file, String name) throws ModuleException{
+        this.name = name;
+        this.file = file;
+        FileInputStream fis = null;
+        JarInputStream jar = null;
+        try {
+            fis = new FileInputStream(file);
+            jar = new JarInputStream(fis);
+            Manifest manifest = jar.getManifest();
+            if (manifest == null)
+                throw new ModuleException(name, tr("The module file ''{0}'' does not include a Manifest.", file.toString()));
+            scanManifest(manifest);
+            libraries.add(0, fileToURL(file));
+        } catch (IOException e) {
+            throw new ModuleException(name, e);
+        } finally {
+            if (jar != null) {
+                try {
+                    jar.close();
+                } catch(IOException e) { /* ignore */ }
+            }
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch(IOException e) { /* ignore */ }
+            }
+        }
+    }
+
+    /**
+     * Creates a module information object by reading module information in Manifest format
+     * from the input stream {@code manifestStream}.
+     *
+     * @param manifestStream the stream to read the manifest from
+     * @param name the module name
+     * @param url the download URL for the module
+     * @throws ModuleException thrown if the module information can't be read from the input stream
+     */
+    public ModuleInformation(InputStream manifestStream, String name, String url) throws ModuleException {
+        this.name = name;
+        try {
+            Manifest manifest = new Manifest();
+            manifest.read(manifestStream);
+            if(url != null) {
+                downloadlink = url;
+            }
+            scanManifest(manifest);
+        } catch (IOException e) {
+            throw new ModuleException(name, e);
+        }
+    }
+
+    /**
+     * Updates the module information of this module information object with the
+     * module information in a module information object retrieved from a module
+     * update site.
+     *
+     * @param other the module information object retrieved from the update
+     * site
+     */
+    public void updateFromModuleSite(ModuleInformation other) {
+        this.className = other.className;
+        this.link = other.link;
+        this.description = other.description;
+        this.author = other.author;
+        this.version = other.version;
+        this.downloadlink = other.downloadlink;
+        this.icon = other.icon;
+        this.iconPath = other.iconPath;
+        this.libraries = other.libraries;
+        this.attr.clear();
+        this.attr.putAll(other.attr);
+    }
+    
+    private static final ImageIcon extractIcon(String iconPath, File jarFile, boolean warn) {
+    	return new ImageProvider(iconPath).setArchive(jarFile).setMaxWidth(24).setMaxHeight(24).setOptional(true).get(warn);
+    }
+
+    private void scanManifest(Manifest manifest) {
+        String lang = LanguageInfo.getLanguageCodeManifest();
+        Attributes attr = manifest.getMainAttributes();
+        className = attr.getValue("Module-Class");
+        String s = attr.getValue(lang+"Module-Link");
+        if (s == null) {
+            s = attr.getValue("Module-Link");
+        }
+        if (s != null) {
+            try {
+                @SuppressWarnings("unused")
+				URL url = new URL(s);
+            } catch (MalformedURLException e) {
+                System.out.println(tr("Invalid URL ''{0}'' in module {1}", s, name));
+                s = null;
+            }
+        }
+        link = s;
+        s = attr.getValue(lang+"Module-Description");
+        if(s == null)
+        {
+            s = attr.getValue("Module-Description");
+            if(s != null) {
+                s = tr(s);
+            }
+        }
+        description = s;
+        version = attr.getValue("Module-Version");
+        author = attr.getValue("Author");
+        iconPath = attr.getValue("Module-Icon");
+        if (iconPath != null && file != null) {
+            // extract icon from the module jar file
+            icon = extractIcon(iconPath, file, false);
+            // if not found, extract icon from the plugin jar file
+            if (icon == null) {
+            	icon = extractIcon(iconPath, OdPlugin.getInstance().getPluginInformation().file, true);
+            }
+        }
+
+        String classPath = attr.getValue(Attributes.Name.CLASS_PATH);
+        if (classPath != null) {
+            for (String entry : classPath.split(" ")) {
+                File entryFile;
+                if (new File(entry).isAbsolute() || file == null) {
+                    entryFile = new File(entry);
+                } else {
+                    entryFile = new File(file.getParent(), entry);
+                }
+
+                libraries.add(fileToURL(entryFile));
+            }
+        }
+        for (Object o : attr.keySet()) {
+            this.attr.put(o.toString(), attr.getValue(o.toString()));
+        }
+    }
+
+    /**
+     * Replies the description as HTML document, including a link to a web page with
+     * more information, provided such a link is available.
+     *
+     * @return the description as HTML document
+     */
+    public String getDescriptionAsHtml() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("<html><body>");
+        sb.append(description == null ? tr("no description available") : description);
+        if (link != null) {
+            sb.append(" <a href=\"").append(link).append("\">").append(tr("More info...")).append("</a>");
+        }
+        if (downloadlink != null && !downloadlink.startsWith(OSM_SITE+"dist/") && !downloadlink.startsWith(GOOGLE_SITE+"dist/")) {
+            sb.append("<p>&nbsp;</p><p>"+tr("<b>Module provided by an external source:</b> {0}", downloadlink)+"</p>");
+        }
+        sb.append("</body></html>");
+        return sb.toString();
+    }
+
+    /**
+     * Load and instantiate the module
+     *
+     * @param the module class
+     * @return the instantiated and initialized module
+     */
+    public Module load(Class<? extends Module> klass) throws ModuleException {
+        try {
+            return klass.getConstructor(ModuleInformation.class).newInstance(this);
+        } catch (Throwable t) {
+            throw new ModuleException(name, t);
+        }
+    }
+
+    /**
+     * Load the class of the module
+     *
+     * @param classLoader the class loader to use
+     * @return the loaded class
+     */
+    public Class<? extends Module> loadClass(ClassLoader classLoader) throws ModuleException {
+        if (className == null)
+            return null;
+        try{
+            return (Class<? extends Module>) Class.forName(className, true, classLoader);
+        } catch (Throwable t) {
+            throw new ModuleException(name, t);
+        }
+    }
+
+    public static URL fileToURL(File f) {
+        try {
+            return f.toURI().toURL();
+        } catch (MalformedURLException ex) {
+            return null;
+        }
+    }
+
+    public static Collection<String> getModuleLocations() {
+        Collection<String> locations = Main.pref.getAllPossiblePreferenceDirs();
+        Collection<String> all = new ArrayList<String>(locations.size());
+        for (String s : locations) {
+            all.add(s+"plugins/opendata/modules");
+        }
+        return all;
+    }
+
+    /**
+     * Replies true if the module with the given information is most likely outdated with
+     * respect to the referenceVersion.
+     *
+     * @param referenceVersion the reference version. Can be null if we don't know a
+     * reference version
+     *
+     * @return true, if the module needs to be updated; false, otherweise
+     */
+    public boolean isUpdateRequired(String referenceVersion) {
+        if (this.downloadlink == null) return false;
+        if (this.version == null && referenceVersion!= null)
+            return true;
+        if (this.version != null && !this.version.equals(referenceVersion))
+            return true;
+        return false;
+    }
+
+    /**
+     * Replies true if this this module should be updated/downloaded because either
+     * it is not available locally (its local version is null) or its local version is
+     * older than the available version on the server.
+     *
+     * @return true if the module should be updated
+     */
+    public boolean isUpdateRequired() {
+        if (this.downloadlink == null) return false;
+        if (this.localversion == null) return true;
+        return isUpdateRequired(this.localversion);
+    }
+
+    protected boolean matches(String filter, String value) {
+        if (filter == null) return true;
+        if (value == null) return false;
+        return value.toLowerCase().contains(filter.toLowerCase());
+    }
+
+    /**
+     * Replies true if either the name, the description, or the version match (case insensitive)
+     * one of the words in filter. Replies true if filter is null.
+     *
+     * @param filter the filter expression
+     * @return true if this module info matches with the filter
+     */
+    public boolean matches(String filter) {
+        if (filter == null) return true;
+        String words[] = filter.split("\\s+");
+        for (String word: words) {
+            if (matches(word, name)
+                    || matches(word, description)
+                    || matches(word, version)
+                    || matches(word, localversion))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Replies the name of the module
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets the name
+     * @param name
+     */
+    /*public void setName(String name) {
+        this.name = name;
+    }*/
+
+    public ImageIcon getScaledIcon() {
+        if (icon == null)
+            return null;
+        return new ImageIcon(icon.getImage().getScaledInstance(24, 24, Image.SCALE_SMOOTH));
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleListParseException.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleListParseException.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleListParseException.java	(revision 28000)
@@ -0,0 +1,34 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.modules;
+
+public class ModuleListParseException extends Exception {
+    public ModuleListParseException() {
+        super();
+    }
+
+    public ModuleListParseException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public ModuleListParseException(String message) { // NO_UCD
+        super(message);
+    }
+
+    public ModuleListParseException(Throwable cause) {
+        super(cause);
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleListParser.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleListParser.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ModuleListParser.java	(revision 28000)
@@ -0,0 +1,135 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.modules;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A parser for the module list provided by an opendata Module Download Site.
+ *
+ * See <a href="http://josm.openstreetmap.de/module">http://josm.openstreetmap.de/module</a>
+ * for a sample of the document. The format is a custom format, kind of mix of CSV and RFC822 style
+ * name/value-pairs.
+ *
+ */
+public class ModuleListParser {
+
+    /**
+     * Creates the module information object
+     *
+     * @param name the module name
+     * @param url the module download url
+     * @param manifest the module manifest
+     * @return a module information object
+     * @throws ModuleListParseException
+     */
+    protected ModuleInformation createInfo(String name, String url, String manifest) throws ModuleListParseException{
+        try {
+            return new ModuleInformation(
+                    new ByteArrayInputStream(manifest.getBytes("utf-8")),
+                    name.substring(0, name.length() - 4),
+                    url
+            );
+        } catch(UnsupportedEncodingException e) {
+            throw new ModuleListParseException(tr("Failed to create module information from manifest for module ''{0}''", name), e);
+        } catch (ModuleException e) {
+            throw new ModuleListParseException(tr("Failed to create module information from manifest for module ''{0}''", name), e);
+        }
+    }
+
+    /**
+     * Parses a module information document and replies a list of module information objects.
+     *
+     * See <a href="http://josm.openstreetmap.de/module">http://josm.openstreetmap.de/module</a>
+     * for a sample of the document. The format is a custom format, kind of mix of CSV and RFC822 style
+     * name/value-pairs.
+     *
+     * @param in the input stream from which to parse
+     * @return the list of module information objects
+     * @throws ModuleListParseException thrown if something goes wrong while parsing
+     */
+    public List<ModuleInformation> parse(InputStream in) throws ModuleListParseException{
+        List<ModuleInformation> ret = new LinkedList<ModuleInformation>();
+        BufferedReader r = null;
+        try {
+            r = new BufferedReader(new InputStreamReader(in, "utf-8"));
+            String name = null;
+            String url = null;
+            StringBuilder manifest = new StringBuilder();
+            /*
+            code structure:
+                for () {
+                    A;
+                    B;
+                    C;
+                }
+                B;
+            */
+            for (String line = r.readLine(); line != null; line = r.readLine()) {
+                if (line.startsWith("\t")) {
+                    line = line.substring(1);
+                    if (line.length() > 70) {
+                        manifest.append(line.substring(0, 70)).append("\n");
+                        line = " " + line.substring(70);
+                    }
+                    manifest.append(line).append("\n");
+                    continue;
+                }
+                if (name != null) {
+                    ModuleInformation info = createInfo(name, url, manifest.toString());
+                    if (info != null) {
+                        for (Module module : ModuleHandler.moduleList) {
+                            if (module.getModuleInformation().name.equals(info.getName())) {
+                                info.localversion = module.getModuleInformation().localversion;
+                            }
+                        }
+                        ret.add(info);
+                    }
+                }
+                String x[] = line.split(";");
+                if(x.length != 2)
+                  throw new IOException(tr("Illegal entry in module list."));
+                name = x[0];
+                url = x[1];
+                manifest = new StringBuilder();
+
+            }
+            if (name != null) {
+                ModuleInformation info = createInfo(name, url, manifest.toString());
+                if (info != null) {
+                    for (Module module : ModuleHandler.moduleList) {
+                        if (module.getModuleInformation().name.equals(info.getName())) {
+                            info.localversion = module.getModuleInformation().localversion;
+                        }
+                    }
+                    ret.add(info);
+                }
+            }
+            return ret;
+        } catch (IOException e) {
+            throw new ModuleListParseException(e);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ReadLocalModuleInformationTask.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ReadLocalModuleInformationTask.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ReadLocalModuleInformationTask.java	(revision 28000)
@@ -0,0 +1,256 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.modules;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Utils;
+import org.xml.sax.SAXException;
+
+/**
+ * This is an asynchronous task for reading module information from the files
+ * in the local module repositories.
+ *
+ * It scans the files in the local modules repository (see {@see Preferences#getModulesDirectory()}
+ * and extracts module information from three kind of files:
+ * <ul>
+ *   <li>.jar-files, assuming that they represent module jars</li>
+ *   <li>.jar.new-files, assuming that these are downloaded but not yet installed modules</li>
+ *   <li>cached lists of available modules, downloaded for instance from
+ *   <a href="http://josm.openstreetmap.de/modules">http://josm.openstreetmap.de/modules</a></li>
+ * </ul>
+ *
+ */
+public class ReadLocalModuleInformationTask extends PleaseWaitRunnable {
+    private Map<String, ModuleInformation> availableModules;
+    private boolean canceled;
+
+    public ReadLocalModuleInformationTask() {
+        super(tr("Reading local module information.."), false);
+        availableModules = new HashMap<String, ModuleInformation>();
+    }
+
+    public ReadLocalModuleInformationTask(ProgressMonitor monitor) {
+        super(tr("Reading local module information.."),monitor, false);
+        availableModules = new HashMap<String, ModuleInformation>();
+    }
+
+    @Override
+    protected void cancel() {
+        canceled = true;
+    }
+
+    @Override
+    protected void finish() {}
+
+    protected void processJarFile(File f, String moduleName) throws ModuleException{
+        ModuleInformation info = new ModuleInformation(
+                f,
+                moduleName
+        );
+        if (!availableModules.containsKey(info.getName())) {
+            info.localversion = info.version;
+            availableModules.put(info.getName(), info);
+        } else {
+            ModuleInformation current = availableModules.get(info.getName());
+            current.localversion = info.version;
+            if (info.icon != null) {
+                current.icon = info.icon;
+            }
+            current.className = info.className;
+            current.libraries = info.libraries;
+        }
+    }
+
+    protected void scanSiteCacheFiles(ProgressMonitor monitor, File modulesDirectory) {
+        File[] siteCacheFiles = modulesDirectory.listFiles(
+                new FilenameFilter() {
+                    public boolean accept(File dir, String name) {
+                        return name.matches("^([0-9]+-)?site.*\\.txt$");
+                    }
+                }
+        );
+        if (siteCacheFiles == null || siteCacheFiles.length == 0)
+            return;
+        monitor.subTask(tr("Processing module site cache files..."));
+        monitor.setTicksCount(siteCacheFiles.length);
+        for (File f: siteCacheFiles) {
+            String fname = f.getName();
+            monitor.setCustomText(tr("Processing file ''{0}''", fname));
+            try {
+                processLocalModuleInformationFile(f);
+            } catch (ModuleListParseException e) {
+                System.err.println(tr("Warning: Failed to scan file ''{0}'' for module information. Skipping.", fname));
+                e.printStackTrace();
+            }
+            monitor.worked(1);
+        }
+    }
+
+    protected void scanIconCacheFiles(ProgressMonitor monitor, File modulesDirectory) {
+        File[] siteCacheFiles = modulesDirectory.listFiles(
+                new FilenameFilter() {
+                    public boolean accept(File dir, String name) {
+                        return name.matches("^([0-9]+-)?site.*modules-icons\\.zip$");
+                    }
+                }
+        );
+        if (siteCacheFiles == null || siteCacheFiles.length == 0)
+            return;
+        monitor.subTask(tr("Processing module site cache icon files..."));
+        monitor.setTicksCount(siteCacheFiles.length);
+        for (File f: siteCacheFiles) {
+            String fname = f.getName();
+            monitor.setCustomText(tr("Processing file ''{0}''", fname));
+            for (ModuleInformation pi : availableModules.values()) {
+                if (pi.icon == null && pi.iconPath != null) {
+                    pi.icon = new ImageProvider(pi.name+".jar/"+pi.iconPath)
+                                    .setArchive(f)
+                                    .setMaxWidth(24)
+                                    .setMaxHeight(24)
+                                    .setOptional(true).get();
+                }
+            }
+            monitor.worked(1);
+        }
+    }
+
+    protected void scanModuleFiles(ProgressMonitor monitor, File modulesDirectory) {
+        File[] moduleFiles = modulesDirectory.listFiles(
+                new FilenameFilter() {
+                    public boolean accept(File dir, String name) {
+                        return name.endsWith(".jar") || name.endsWith(".jar.new");
+                    }
+                }
+        );
+        if (moduleFiles == null || moduleFiles.length == 0)
+            return;
+        monitor.subTask(tr("Processing module files..."));
+        monitor.setTicksCount(moduleFiles.length);
+        for (File f: moduleFiles) {
+            String fname = f.getName();
+            monitor.setCustomText(tr("Processing file ''{0}''", fname));
+            try {
+                if (fname.endsWith(".jar")) {
+                    String moduleName = fname.substring(0, fname.length() - 4);
+                    processJarFile(f, moduleName);
+                } else if (fname.endsWith(".jar.new")) {
+                    String moduleName = fname.substring(0, fname.length() - 8);
+                    processJarFile(f, moduleName);
+                }
+            } catch(ModuleException e){
+                System.err.println(tr("Warning: Failed to scan file ''{0}'' for module information. Skipping.", fname));
+                e.printStackTrace();
+            }
+            monitor.worked(1);
+        }
+    }
+
+    protected void scanLocalModuleRepository(ProgressMonitor monitor, File modulesDirectory) {
+        if (modulesDirectory == null) return;
+        try {
+            monitor.beginTask("");
+            scanSiteCacheFiles(monitor, modulesDirectory);
+            scanIconCacheFiles(monitor, modulesDirectory);
+            scanModuleFiles(monitor, modulesDirectory);
+        } finally {
+            monitor.setCustomText("");
+            monitor.finishTask();
+        }
+    }
+
+    protected void processLocalModuleInformationFile(File file) throws ModuleListParseException{
+        FileInputStream fin = null;
+        try {
+            fin = new FileInputStream(file);
+            List<ModuleInformation> pis = new ModuleListParser().parse(fin);
+            for (ModuleInformation pi : pis) {
+                // we always keep module information from a module site because it
+                // includes information not available in the module jars Manifest, i.e.
+                // the download link or localized descriptions
+                //
+                availableModules.put(pi.name, pi);
+            }
+        } catch(IOException e) {
+            throw new ModuleListParseException(e);
+        } finally {
+            Utils.close(fin);
+        }
+    }
+
+    protected void analyseInProcessModules() {
+        for (Module module : ModuleHandler.moduleList) {
+            ModuleInformation info = module.getModuleInformation();
+            if (canceled)return;
+            if (!availableModules.containsKey(info.name)) {
+                availableModules.put(info.name, info);
+            } else {
+                availableModules.get(info.name).localversion = info.localversion;
+            }
+        }
+    }
+
+    @Override
+    protected void realRun() throws SAXException, IOException, OsmTransferException {
+        Collection<String> moduleLocations = ModuleInformation.getModuleLocations();
+        getProgressMonitor().setTicksCount(moduleLocations.size() + 2);
+        if (canceled) return;
+        for (String location : moduleLocations) {
+            scanLocalModuleRepository(
+                    getProgressMonitor().createSubTaskMonitor(1, false),
+                    new File(location)
+            );
+            getProgressMonitor().worked(1);
+            if (canceled)return;
+        }
+        analyseInProcessModules();
+        getProgressMonitor().worked(1);
+        if (canceled)return;
+        getProgressMonitor().worked(1);
+    }
+
+    /**
+     * Replies information about available modules detected by this task.
+     *
+     * @return information about available modules detected by this task.
+     */
+    public List<ModuleInformation> getAvailableModules() {
+        return new ArrayList<ModuleInformation>(availableModules.values());
+    }
+
+    /**
+     * Replies true if the task was canceled by the user
+     *
+     * @return true if the task was canceled by the user
+     */
+    public boolean isCanceled() {
+        return canceled;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ReadRemoteModuleInformationTask.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ReadRemoteModuleInformationTask.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/modules/ReadRemoteModuleInformationTask.java	(revision 28000)
@@ -0,0 +1,383 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.modules;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Version;
+import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.plugins.opendata.OdPlugin;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Utils;
+import org.xml.sax.SAXException;
+
+/**
+ * An asynchronous task for downloading module lists from the configured module download
+ * sites.
+ *
+ */
+public class ReadRemoteModuleInformationTask extends PleaseWaitRunnable implements OdConstants {
+
+    private Collection<String> sites;
+    private boolean canceled;
+    private HttpURLConnection connection;
+    private List<ModuleInformation> availableModules;
+
+    protected enum CacheType {PLUGIN_LIST, ICON_LIST}
+
+    protected void init(Collection<String> sites){
+        this.sites = sites;
+        if (sites == null) {
+            this.sites = Collections.emptySet();
+        }
+        availableModules = new LinkedList<ModuleInformation>();
+
+    }
+    /**
+     * Creates the task
+     *
+     * @param sites the collection of download sites. Defaults to the empty collection if null.
+     */
+    public ReadRemoteModuleInformationTask(Collection<String> sites) {
+        super(tr("Download module list..."), false /* don't ignore exceptions */);
+        init(sites);
+    }
+
+    /**
+     * Creates the task
+     *
+     * @param monitor the progress monitor. Defaults to {@see NullProgressMonitor#INSTANCE} if null
+     * @param sites the collection of download sites. Defaults to the empty collection if null.
+     */
+    public ReadRemoteModuleInformationTask(ProgressMonitor monitor, Collection<String> sites) {
+        super(tr("Download module list..."), monitor == null ? NullProgressMonitor.INSTANCE: monitor, false /* don't ignore exceptions */);
+        init(sites);
+    }
+
+
+    @Override
+    protected void cancel() {
+        canceled = true;
+        synchronized(this) {
+            if (connection != null) {
+                connection.disconnect();
+            }
+        }
+    }
+
+    @Override
+    protected void finish() {}
+
+    /**
+     * Creates the file name for the cached module list and the icon cache
+     * file.
+     *
+     * @param site the name of the site
+     * @param type icon cache or module list cache
+     * @return the file name for the cache file
+     */
+    protected File createSiteCacheFile(File moduleDir, String site, CacheType type) {
+        String name;
+        try {
+            site = site.replaceAll("%<(.*)>", "");
+            URL url = new URL(site);
+            StringBuilder sb = new StringBuilder();
+            sb.append("site-");
+            sb.append(url.getHost()).append("-");
+            if (url.getPort() != -1) {
+                sb.append(url.getPort()).append("-");
+            }
+            String path = url.getPath();
+            for (int i =0;i<path.length()-4; i++) {
+                char c = path.charAt(i);
+                if (Character.isLetterOrDigit(c)) {
+                    sb.append(c);
+                } else {
+                    sb.append("_");
+                }
+            }
+            switch (type) {
+            case PLUGIN_LIST:
+                sb.append(".txt");
+                break;
+            case ICON_LIST:
+                sb.append("-icons.zip");
+                break;
+            }
+            name = sb.toString();
+        } catch(MalformedURLException e) {
+            name = "site-unknown.txt";
+        }
+        return new File(moduleDir, name);
+    }
+
+    /**
+     * Downloads the list from a remote location
+     *
+     * @param site the site URL
+     * @param monitor a progress monitor
+     * @return the downloaded list
+     */
+    protected String downloadModuleList(String site, ProgressMonitor monitor) {
+        BufferedReader in = null;
+        StringBuilder sb = new StringBuilder();
+        try {
+            /* replace %<x> with empty string or x=modules (separated with comma) */
+            String pl = Utils.join(",", Main.pref.getCollection(PREF_MODULES));
+            String printsite = site.replaceAll("%<(.*)>", "");
+            if(pl != null && pl.length() != 0) {
+                site = site.replaceAll("%<(.*)>", "$1"+pl);
+            } else {
+                site = printsite;
+            }
+
+            monitor.beginTask("");
+            monitor.indeterminateSubTask(tr("Downloading module list from ''{0}''", printsite));
+
+            URL url = new URL(site);
+            synchronized(this) {
+                connection = (HttpURLConnection)url.openConnection();
+                connection.setRequestProperty("Cache-Control", "no-cache");
+                connection.setRequestProperty("User-Agent",Version.getInstance().getAgentString());
+                connection.setRequestProperty("Host", url.getHost());
+                connection.setRequestProperty("Accept-Charset", "utf-8");
+            }
+            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
+            String line;
+            while((line = in.readLine()) != null) {
+                sb.append(line).append("\n");
+            }
+            return sb.toString();
+        } catch(MalformedURLException e) {
+            if (canceled) return null;
+            e.printStackTrace();
+            return null;
+        } catch(IOException e) {
+            if (canceled) return null;
+            e.printStackTrace();
+            return null;
+        } finally {
+            synchronized(this) {
+                if (connection != null) {
+                    connection.disconnect();
+                }
+                connection = null;
+            }
+            Utils.close(in);
+            monitor.finishTask();
+        }
+    }
+
+    /**
+     * Downloads the icon archive from a remote location
+     *
+     * @param site the site URL
+     * @param monitor a progress monitor
+     */
+    protected void downloadModuleIcons(String site, File destFile, ProgressMonitor monitor) {
+        InputStream in = null;
+        OutputStream out = null;
+        try {
+            site = site.replaceAll("%<(.*)>", "");
+
+            monitor.beginTask("");
+            monitor.indeterminateSubTask(tr("Downloading module list from ''{0}''", site));
+
+            URL url = new URL(site);
+            synchronized(this) {
+                connection = (HttpURLConnection)url.openConnection();
+                connection.setRequestProperty("Cache-Control", "no-cache");
+                connection.setRequestProperty("User-Agent",Version.getInstance().getAgentString());
+                connection.setRequestProperty("Host", url.getHost());
+            }
+            in = connection.getInputStream();
+            out = new FileOutputStream(destFile);
+            byte[] buffer = new byte[8192];
+            for (int read = in.read(buffer); read != -1; read = in.read(buffer)) {
+                out.write(buffer, 0, read);
+            }
+            out.close();
+            in.close();
+        } catch(MalformedURLException e) {
+            if (canceled) return;
+            e.printStackTrace();
+            return;
+        } catch(IOException e) {
+            if (canceled) return;
+            e.printStackTrace();
+            return;
+        } finally {
+            synchronized(this) {
+                if (connection != null) {
+                    connection.disconnect();
+                }
+                connection = null;
+            }
+            Utils.close(in);
+            monitor.finishTask();
+        }
+        for (ModuleInformation pi : availableModules) {
+            if (pi.icon == null && pi.iconPath != null) {
+                pi.icon = new ImageProvider(pi.name+".jar/"+pi.iconPath)
+                                .setArchive(destFile)
+                                .setMaxWidth(24)
+                                .setMaxHeight(24)
+                                .setOptional(true).get();
+            }
+        }
+    }
+
+    /**
+     * Writes the list of modules to a cache file
+     *
+     * @param site the site from where the list was downloaded
+     * @param list the downloaded list
+     */
+    protected void cacheModuleList(String site, String list) {
+        PrintWriter writer = null;
+        try {
+            File moduleDir = OdPlugin.getInstance().getModulesDirectory();
+            if (!moduleDir.exists()) {
+                if (! moduleDir.mkdirs()) {
+                    System.err.println(tr("Warning: failed to create module directory ''{0}''. Cannot cache module list from module site ''{1}''.", moduleDir.toString(), site));
+                }
+            }
+            File cacheFile = createSiteCacheFile(moduleDir, site, CacheType.PLUGIN_LIST);
+            getProgressMonitor().subTask(tr("Writing module list to local cache ''{0}''", cacheFile.toString()));
+            writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(cacheFile), "utf-8"));
+            writer.write(list);
+        } catch (IOException e) {
+            // just failed to write the cache file. No big deal, but log the exception anyway
+            e.printStackTrace();
+        } finally {
+            if (writer != null) {
+                writer.flush();
+                writer.close();
+            }
+        }
+    }
+
+    /**
+     * Parses the module list
+     *
+     * @param site the site from where the list was downloaded
+     * @param doc the document with the module list
+     */
+    protected void parseModuleListDocument(String site, String doc) {
+        try {
+            getProgressMonitor().subTask(tr("Parsing module list from site ''{0}''", site));
+            InputStream in = new ByteArrayInputStream(doc.getBytes("UTF-8"));
+            availableModules.addAll(new ModuleListParser().parse(in));
+        } catch(UnsupportedEncodingException e) {
+            System.err.println(tr("Failed to parse module list document from site ''{0}''. Skipping site. Exception was: {1}", site, e.toString()));
+            e.printStackTrace();
+        } catch(ModuleListParseException e) {
+            System.err.println(tr("Failed to parse module list document from site ''{0}''. Skipping site. Exception was: {1}", site, e.toString()));
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    protected void realRun() throws SAXException, IOException, OsmTransferException {
+        if (sites == null) return;
+        getProgressMonitor().setTicksCount(sites.size() * 3);
+        File moduleDir = OdPlugin.getInstance().getModulesDirectory();
+
+        // collect old cache files and remove if no longer in use
+        List<File> siteCacheFiles = new LinkedList<File>();
+        for (String location : ModuleInformation.getModuleLocations()) {
+            File [] f = new File(location).listFiles(
+                    new FilenameFilter() {
+                        public boolean accept(File dir, String name) {
+                            return name.matches("^([0-9]+-)?site.*\\.txt$") ||
+                            name.matches("^([0-9]+-)?site.*-icons\\.zip$");
+                        }
+                    }
+            );
+            if(f != null && f.length > 0) {
+                siteCacheFiles.addAll(Arrays.asList(f));
+            }
+        }
+
+        for (String site: sites) {
+            String printsite = site.replaceAll("%<(.*)>", "");
+            getProgressMonitor().subTask(tr("Processing module list from site ''{0}''", printsite));
+            String list = downloadModuleList(site, getProgressMonitor().createSubTaskMonitor(0, false));
+            if (canceled) return;
+            siteCacheFiles.remove(createSiteCacheFile(moduleDir, site, CacheType.PLUGIN_LIST));
+            siteCacheFiles.remove(createSiteCacheFile(moduleDir, site, CacheType.ICON_LIST));
+            if(list != null)
+            {
+                getProgressMonitor().worked(1);
+                cacheModuleList(site, list);
+                if (canceled) return;
+                getProgressMonitor().worked(1);
+                parseModuleListDocument(site, list);
+                if (canceled) return;
+                getProgressMonitor().worked(1);
+                if (canceled) return;
+            }
+            downloadModuleIcons(site.replace(".txt", "")+"-icons.zip", createSiteCacheFile(moduleDir, site, CacheType.ICON_LIST), getProgressMonitor().createSubTaskMonitor(0, false));
+        }
+        for (File file: siteCacheFiles) /* remove old stuff or whole update process is broken */
+        {
+            file.delete();
+        }
+    }
+
+    /**
+     * Replies true if the task was canceled
+     * @return
+     */
+    public boolean isCanceled() {
+        return canceled;
+    }
+
+    /**
+     * Replies the list of modules described in the downloaded module lists
+     *
+     * @return  the list of modules
+     */
+    public List<ModuleInformation> getAvailabeModules() {
+        return availableModules;
+    }
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/util/NamesFrUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/util/NamesFrUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/util/NamesFrUtils.java	(revision 28000)
@@ -0,0 +1,280 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.text.WordUtils;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
+import org.openstreetmap.josm.plugins.opendata.core.datasets.SimpleDataSetHandler;
+
+public abstract class NamesFrUtils implements OdConstants {
+	
+	private static Map<String, String> dictionary = initDictionary();
+
+	public static final String checkDictionary(String value) {
+		String result = "";
+		for (String word : value.split(" ")) {
+			if (!result.isEmpty()) {
+				result += " ";
+			}
+			result += dictionary.containsKey(word) ?  dictionary.get(word) : word;
+		}
+		return result;
+	}
+	
+	private static Map<String, String> initDictionary() {
+		Map<String, String> result = new HashMap<String, String>();
+		try {
+			BufferedReader reader = new BufferedReader(new InputStreamReader(
+					SimpleDataSetHandler.class.getResourceAsStream(DICTIONARY_FR), UTF8));
+			String line = reader.readLine(); // Skip first line
+			while ((line = reader.readLine()) != null) {
+				String[] tab = line.split(";");
+				result.put(tab[0].replace("\"", ""), tab[1].replace("\"", ""));
+			}
+			reader.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return result;
+	}
+
+	public static final String getStreetLabel(String label) {
+		if (label == null) {
+			return label;
+		} else if (label.equals("All")) {
+			return "Allée";
+		} else if (label.equals("Autoroute")) {
+			return label;
+		} else if (label.startsWith("Anc")) { // Anc, Ancien
+			return "Ancien";
+		} else if (label.equals("Av")) {
+			return "Avenue";
+		} else if (label.equals("Bd")) {
+			return "Boulevard";
+		} else if (label.equals("Bre")) {
+			return "Bré";
+		} else if (label.equals("Caminot")) {
+			return label;
+		} else if (label.equals("Carrefour")) {
+			return label;
+		} else if (label.startsWith("Che")) { // Che, Chem
+			return "Chemin";
+		} else if (label.equals("Cite")) {
+			return "Cité";
+		} else if (label.equals("Clos")) {
+			return label;
+		} else if (label.equals("Cote")) {
+			return "Côte";
+		} else if (label.equals("Cours")) {
+			return label;
+		} else if (label.equals("Dom")) {
+			return "Domaine";
+		} else if (label.equals("Dsc")) {
+			return "Descente";
+		} else if (label.equals("Esp")) {
+			return "Esplanade";
+		} else if (label.equals("Espa")) {
+			return "Espace";
+		} else if (label.equals("Giratoire")) {
+			return label;
+		} else if (label.equals("Grande-rue")) {
+			return label;
+		} else if (label.equals("Hameau")) {
+			return label;
+		} else if (label.equals("Imp")) {
+			return "Impasse";
+		} else if (label.equals("Itineraire")) {
+			return "Itinéraire";
+		} else if (label.equals("Jardin")) {
+			return label;
+		} else if (label.startsWith("L'") || label.equals("La") || label.equals("Le") || label.equals("Les") || label.equals("Saint")) { // Lieux-dits
+			return label;
+		} else if (label.equals("Lot")) {
+			return "Lotissement";
+		} else if (label.equals("Mail")) {
+			return label;
+		} else if (label.equals("Mas")) {
+			return label;
+		} else if (label.equals("Parc")) {
+			return label;
+		} else if (label.equals("Pas")) {
+			return "Passage";
+		} else if (label.equals("Passerelle")) {
+			return label;
+		} else if (label.equals("Pch")) {
+			return "Petit Chemin";
+		} else if (label.equals("Petit")) {
+			return label;
+		} else if (label.equals("Petite-allée")) {
+			return label;
+		} else if (label.equals("Petite-rue")) {
+			return label;
+		} else if (label.equals("Pl")) {
+			return "Place";
+		} else if (label.equals("Plan")) {
+			return label;
+		} else if (label.equals("Pont")) {
+			return label;
+		} else if (label.equals("Port")) {
+			return label;
+		} else if (label.equals("Porte")) {
+			return label;
+		} else if (label.equals("Prom")) {
+			return "Promenade";
+		} else if (label.equals("Prv")) {
+			return "Parvis";
+		} else if (label.equals("Qu")) {
+			return "Quai";
+		} else if (label.equals("Rampe")) {
+			return label;
+		} else if (label.equals("Residence")) {
+			return "Résidence";
+		} else if (label.equals("Rocade")) {
+			return label;
+		} else if (label.equals("Rpt")) {
+			return "Rond-Point";
+		} else if (label.equals("Rte")) {
+			return "Route";
+		} else if (label.equals("Rue")) {
+			return label;
+		} else if (label.equals("Sentier")) {
+			return label;
+		} else if (label.equals("Sq")) {
+			return "Square";
+		} else if (label.equals("Tra")) {
+			return "Traverse";
+		} else if (label.equals("Vieux")) {
+			return label;
+		} else if (label.equals("Voie")) {
+			return label;
+		} else if (label.equals("Zone")) {
+			return label;
+		} else {
+			System.err.println("Warning: unknown street label: "+label);
+			return label;
+		}
+	}
+
+	public static final String checkStreetName(OsmPrimitive p, String key) {
+		String value = null;
+		if (p != null) {
+			value = p.get(key);
+			if (value != null) {
+				value = WordUtils.capitalizeFully(value);
+				// Cas particuliers 
+				if (value.equals("Boulingrin")) { // square Boulingrin, mal formé
+					value = "Sq Boulingrin";
+				} else if (value.matches("A[0-9]+")) { // Autoroutes sans le mot "Autoroute"
+					value = "Autoroute "+value;
+				} else if (value.equals("All A61")) { // A61 qualifiée d'Allée ?
+					value = "Autoroute A61";
+				} else if (value.startsWith("Che Vieux Che")) { // "Che" redondant
+					value = value.replaceFirst("Che ", "");
+				} else if (value.startsWith("Petite Allee ")) { // Tiret, comme grand-rue, petite-rue
+					value = value.replaceFirst("Petite Allee ", "Petite-allée ");
+				} else if (value.startsWith("Ld De ")) { // Lieux-dit
+					value = value.replaceFirst("Ld De ", "");
+				}
+				while (value.startsWith("Ld ")) { // Lieux-dit, inutile. Plus le cas avec "Ld Ld"
+					value = value.replaceFirst("Ld ", "");
+				}
+				if (value.startsWith("L ")) {
+					value = value.replaceFirst("L ", "L'");
+				}
+				String[] words = value.split(" ");
+				if (words.length > 0) {
+					value = "";
+					List<String> list = Arrays.asList(words);
+					words[0] = getStreetLabel(words[0]);
+					if (words[0].equals("Ancien") && words.length > 1 && words[1].equals("Che")) {
+						words[1] = "Chemin";
+					}
+					for (int i = 0; i < words.length; i++) {
+						if (i > 0) {
+							value += " ";
+							// Prénoms/Noms propres abrégés
+							if (words[i].equals("A") && list.contains("Bernard")) {
+								words[i] = "Arnaud";
+							} else if (words[i].equals("A") && list.contains("Passerieu")) {
+								words[i] = "Ariste";
+							} else if (words[i].equals("A") && list.contains("Bougainville")) {
+								words[i] = "Antoine";
+							} else if (words[i].equals("Ch") && list.contains("Leconte")) {
+								words[i] = "Charles";
+							} else if (words[i].equals("Frs") && list.contains("Dugua")) {
+								words[i] = "François";
+							} else if (words[i].equals("G") && list.contains("Latecoere")) {
+								words[i] = "Georges";
+							} else if (words[i].equals("H") && list.contains("Lautrec")) {
+								words[i] = "Henri";
+							} else if (words[i].equals("J") && list.contains("Dieulafoy")) {
+								words[i] = "Jane";
+							} else if (words[i].equals("J") && (list.contains("Champollion") || list.contains("Stanislas"))) {
+								words[i] = "Jean";
+							} else if (words[i].equals("L") && list.contains("Zamenhof")) {
+								words[i] = "Ludwik";
+							} else if (words[i].equals("L") && list.contains("Sacha")) {
+								words[i] = "Lucien";
+								if (!list.contains("Et")) {
+									words[i] += " et";
+								}
+							} else if (words[i].equals("L") && (list.contains("Vauquelin") || list.contains("Bougainville"))) {
+								words[i] = "Louis";
+							} else if (words[i].equals("M") && list.contains("Dieulafoy")) {
+								words[i] = "Marcel";
+							} else if (words[i].equals("M") && list.contains("Arifat")) {
+								words[i] = "Marie";
+							} else if (words[i].equals("N") && list.contains("Djamena")) {
+								words[i] = "N'";
+							} else if (words[i].equals("Oo")) {
+								words[i] = "Oô";
+							} else if (words[i].equals("Ph") && list.contains("Ravary")) {
+								words[i] = "Philippe";
+							} else if (words[i].equals("R") && list.contains("Folliot")) {
+								words[i] = "Raphaël";
+							} else if (words[i].equals("W") && list.contains("Booth")) {
+								words[i] = "William";
+							// Mots de liaison non couverts par le dictionnaire
+							} else if (words[i].equals("A")) {
+								words[i] = "à";
+							} else if (words[i].equals("D") || words[i].equals("L")) {
+								words[i] = words[i].toLowerCase()+"'";
+							} else if (words[i].equals("La") || words[i].equals("Le")) {
+								words[i] = words[i].toLowerCase();
+							}
+						}
+						value += words[i];
+					}
+				}
+				// Ponctuation
+				value = value.replace("' ", "'");
+				// Dictionnaire
+				value = checkDictionary(value);
+				p.put(key, value);
+			}
+		}
+		return value;
+	}
+}
Index: /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/util/OdUtils.java
===================================================================
--- /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/util/OdUtils.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/util/OdUtils.java	(revision 28000)
@@ -0,0 +1,52 @@
+//    JOSM opendata plugin.
+//    Copyright (C) 2011-2012 Don-vip
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+package org.openstreetmap.josm.plugins.opendata.core.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+
+public abstract class OdUtils {
+	
+    public static final boolean isMultipolygon(OsmPrimitive p) {
+        return p instanceof Relation && ((Relation) p).isMultipolygon();
+    }
+    
+	public static final String[] stripQuotes(String[] split, String sep) {
+		List<String> result = new ArrayList<String>();
+		boolean append = false;
+		for (int i = 0; i<split.length; i++) {
+			if (append) {
+				int index = result.size()-1;
+				if (split[i].endsWith("\"") && StringUtils.countMatches(split[i], "\"") % 2 == 1) {
+					append = false;
+				}
+				result.set(index, result.get(index)+sep+split[i].replaceAll("\"", ""));
+			} else if (split[i].startsWith("\"")) {
+				if (!(split[i].endsWith("\"") && StringUtils.countMatches(split[i], "\"") % 2 == 0)) {
+					append = true;
+				}
+				result.add(split[i].replaceAll("\"", ""));
+			} else {
+				result.add(split[i]);
+			}
+		}
+		return result.toArray(new String[0]);
+	}
+}
Index: /applications/editors/josm/plugins/opendata/util/opendata/ModuleListGenerator.java
===================================================================
--- /applications/editors/josm/plugins/opendata/util/opendata/ModuleListGenerator.java	(revision 28000)
+++ /applications/editors/josm/plugins/opendata/util/opendata/ModuleListGenerator.java	(revision 28000)
@@ -0,0 +1,97 @@
+package opendata;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+public class ModuleListGenerator {
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		final String url = "http://josm-toulouse-data.googlecode.com/svn/trunk/dist/";
+		String baseDir = "";
+		if (args.length > 0) {
+			baseDir = args[0];
+		}
+		try {
+			BufferedWriter list = new BufferedWriter(new FileWriter(baseDir+"modules.txt"));
+			ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(baseDir+"modules-icons.zip"));
+			for (File file : new File(baseDir+"dist").listFiles(new FilenameFilter() {
+				@Override
+				public boolean accept(File dir, String name) {
+					return name.endsWith(".jar");
+				}
+			})) {
+				try {
+					String filename = file.getName();
+					System.out.println("Processing "+filename);
+					list.write(filename+";"+url+filename); list.newLine();
+					Manifest mf = new JarFile(file).getManifest();
+					for (Object att : mf.getMainAttributes().keySet()) {
+						Object value = mf.getMainAttributes().get(att);
+						if (value != null) {
+							list.write("\t"+att+": "+value.toString()); list.newLine();
+							if (att.toString().equals("Module-Icon")) {
+								// Directory with jar name, including extension
+								String name = filename+"/";
+								zip.putNextEntry(new ZipEntry(name));
+								// Directory tree to image
+								String[] items = value.toString().split("/");
+								for (int i=0; i<items.length-1; i++) {
+									zip.putNextEntry(new ZipEntry(name += items[i]+"/"));
+								}
+								// Image file
+								zip.putNextEntry(new ZipEntry(name += items[items.length-1]));
+								try {
+									FileInputStream in;
+									try {
+										in = new FileInputStream(baseDir+"modules/"+filename.replace(".jar", "/")+value.toString());
+									} catch (FileNotFoundException e) {
+										// If not in module dir, may be in main images directory
+										if (value.toString().startsWith("images/")) {
+											in = new FileInputStream(baseDir+value.toString());
+										} else {
+											throw e;
+										}
+									}
+									try {
+										byte[] buffer = new byte[4096];
+										int n = -1;
+										while ((n = in.read(buffer)) > 0) {
+											zip.write(buffer, 0, n);
+										}
+									} finally {
+										in.close();
+									}
+								} catch (IOException e) {
+									System.err.println("Cannot load Image-Icon: "+value.toString());
+								} finally {
+									zip.closeEntry();
+								}
+							}
+						}
+					}
+					
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+			System.out.println("Done");
+			zip.close();
+			list.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+}
